Compare commits

..

30 Commits

Author SHA1 Message Date
Michael Stangl 6ee33eb085 Beispiel-/Doku-Ausgaben neu erzeugt
Regenerierte SVG-Doku-Bilder und die hochzeit-Beispielausgaben
(TischePersonen.txt / PersonenTische.csv) nach den aktuellen Aenderungen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 10:11:38 +02:00
Michael Stangl cded317a40 Doku: Farbprofile (--farben, cfg/farben.cfg, libs/Farben.py)
CLAUDE.md dokumentiert das neue SVG-Farbprofil-Feature: den Schalter
--farben, die Profile in cfg/farben.cfg (palette / kategorien) und das
Modul libs/Farben.py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 10:11:25 +02:00
Michael Stangl c6e0b95d81 Web-GUI: fixierte Gruppen anzeigen, Strafprofil waehlen, Farben nutzen
CSVConfig.HandleGaesteliste liefert zusaetzlich FixierteGruppen (Name ->
Tisch/Anzahl), damit fest platzierte Gaeste in der Gaesteliste sichtbar
(grau hinterlegt) erscheinen. Durchgaengig "VIP" -> "fixiert" umbenannt.

Backend: Strafprofile werden gecacht geladen, neuer Endpoint /strafprofile
und Query-Parameter strafen an /berechnen, damit sich Profile (default vs.
locker) in der GUI vergleichen lassen. SVG-Ausgabe nutzt das Farbschema aus
farben.cfg (Rueckfall auf Palette).

Frontend: tische.ini und CSV werden bei Auswahl sofort geladen, Auswahl der
fixierten Gruppen und des Optimierungsprofils in der Oberflaeche.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 10:10:41 +02:00
Michael Stangl d19913a53d SVG-Farbprofile: --farben mit palette- und kategorien-Modus
Neues Modul libs/Farben.py mit Farbschema, das Gruppen Farben zuordnet,
gesteuert durch Profile aus cfg/farben.cfg. Zwei Modi: "palette" (Farbliste
zyklisch je Gruppe, Profil grosse_gruppen) und "kategorien" (Hochzeit:
Familie/Verein/VIP getrennt ueber Farbverlaeufe, Profil hochzeit).

Sitzplatzverteilung.alsSVG bekommt Parameter Farbschema; Farben werden nun
fest fuer die vollstaendige Gruppenliste (nach Id) vergeben statt lazy in
Zeichenreihenfolge, damit jede Gruppe variantenuebergreifend dieselbe Farbe
hat. platz.py bekommt Schalter --farben (Vorgabe grosse_gruppen).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 10:10:23 +02:00
Michael Stangl d4844ded67 Loesungs-Dedup: getGruppenId/getPersonenId, keine doppelten Sitzordnungen
- getGruppenId (Gruppen-Ebene, personen-unabhaengig: welche Gruppen mit
  welcher Anzahl je Tisch) und getPersonenId (Personen-Ebene: alphabetische
  Namen je Tisch) an Sitzplatzverteilung; Basis-Methoden an Loesung. Gleiche
  Gruppen-Verteilung -> gleiche getGruppenId und damit gleiche Wertigkeit,
  egal welche Personen die geteilten Plaetze einnehmen.
- Farm verwirft nach jeder Erzeugung/Mutation Loesungen mit schon gesehener
  getGruppenId, so dass dieselbe Sitzordnung nicht mehrfach gehalten und
  bewertet wird (defensiv: Klassen ohne getGruppenId bleiben unberuehrt,
  Tests unveraendert).
- Web: Varianten-Vergleich ueber getGruppenId statt der person-basierten
  _Signatur; gruppenId und personenId zusaetzlich im Ergebnis-JSON.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 18:10:23 +02:00
Michael Stangl b29b3b22d4 SVG-Raumplan: Platzzahl je Tisch, Hover-Infos und Bild vor der Liste
- Platzzahl unter der Tischnummer im SVG
- Personenkreise mit <title> (Name - Gruppe) und data-Attributen
  (gruppe/name/gid); im Web den Raumplan inline statt als <img>
  einbetten, dazu ein Kasten mit der Gruppen-Namensliste und
  Hervorhebung der Gruppe beim Hover
- Ausgabe: Raumplan vor der Tabellenliste (schneller Varianten-Vergleich)
- SVG als UTF-8 schreiben (Umlaute/Gedankenstrich sonst ungueltig)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 17:30:33 +02:00
Michael Stangl 4a059f32c5 Strafen können durch benannte Profile festgelegt werden 2026-07-15 17:05:13 +02:00
Michael Stangl db69f3498d Funktion zum relode der Tische aus der Session und der Gäste laden 2026-07-12 17:03:23 +02:00
Michael Stangl f880ae1c97 in der Roademap weitergemacht 2026-07-12 17:02:14 +02:00
Michael Stangl dd84293c36 Bestellungen als .csv eingecheckt 2026-07-12 15:11:19 +02:00
Michael Stangl b4f957a028 Allein-Strafe nicht mehr fuer alleinreisende Gaeste (Einer-Gruppen)
LeuteAllein meldete eine Gruppe schon dann als 'allein', wenn nur eine
ihrer Personen am Tisch sass. Fuer eine Gruppe der Groesse 1 (alleinreisender
Gast) ist das immer der Fall - der Gast bekam die -30-Strafe, egal ob er mit
anderen an einem vollen Tisch sass oder wirklich allein. Das war ein
struktureller Fehlposten, der jede Loesung deckelte.

'Allein' meint aber: von der (mehrkoepfigen) Gruppe getrennt, ohne
Gruppenmitglied am Tisch. Eine Einer-Gruppe hat kein Gruppenmitglied, das
fehlen koennte, und wird daher ausgenommen (sie darf mit anderen am Tisch
sitzen; der leere-Tisch-Fall bleibt ueber die Tischbesetzungs-Strafe erfasst).

Wirkung Hochzeit: bester Wert -78.7 -> -48.7 (die -30 entfaellt). Beispiele
hochzeit und innenhoefe (die einzigen mit Einer-Gruppen) neu berechnet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 23:08:54 +02:00
Michael Stangl c42aae7c49 Umfeld.svg: kaputtes cp1252-Byte reparieren (als UTF-8 deklariert)
Die Datei deklariert encoding="UTF-8", enthielt aber an 3 Stellen das
Windows-1252-Byte 0x97 (Gedankenstrich). In UTF-8 ist das ein ungueltiges
Start-Byte, weshalb strikte SVG/XML-Parser die Datei nicht darstellen. Die
3 Bytes durch ASCII-Bindestrich ersetzt; Datei ist jetzt gueltiges UTF-8.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 23:07:27 +02:00
Michael Stangl 740c420900 Loesungs-Ids wieder als fortlaufende Nummern 1..N (Vorgaenger separat)
- Farm._WurzelId/_KindId ersetzt durch _NeueId: jede Loesung bekommt eine
  einfache fortlaufende Nummer (Wurzeln wie Mutationskinder gleich)
- die Abstammung steckt nicht mehr in der Id, sondern im schon vorher
  gemerkten Vorgaenger (Abstammung-Knoten 'eltern'); der Baum und die
  Hervorhebung des Sieger-Astes funktionieren unveraendert
- Tests auf das neue Id-Schema umgestellt (Nummern 1..N, Abstammung ueber
  Vorgaenger), README/CLAUDE.md aktualisiert
- Beispiele neu berechnet

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 22:48:49 +02:00
Michael Stangl 6710d4f06a Bessere Verteilung: Strafen/Mutation, plus Abstammungsbaum mit Id-Herkunft
Weniger vermeidbare Gruppentrennungen:
- strafen.cfg: Tischbesetzung bestraft jetzt gestaffelt nach freien
  Plaetzen (teilbelegte Tische am teuersten, mit Fallback auf den
  naechstkleineren Eintrag), Trennungsstrafen deutlich erhoeht - so
  werden Gruppen nicht mehr getrennt, obwohl leere Tische danebenstehen
- gibPunkte('Tischbesetzung') mit Naechst-kleiner-Fallback
- mutieren() setzt geraeumte Gruppen groesste-zuerst neu
  (GruppenSetzen(GrosseZuerst=True)), damit grosse Gruppen die frei
  gewordenen ganzen Tische bekommen und wieder zusammenkommen
  (uebrig bleiben nur physisch unvermeidbare Trennungen, Gruppe > Tisch)

Abstammungsbaum (neuer Schalter --show-lineage -> Abstammung.svg):
- neue Klasse ga.Abstammung zeichnet den vollen Mutationsbaum aller
  Loesungen; der Ast der finalen besten Loesung ist hervorgehoben und
  mit ihrer Id beschriftet
- hierarchische Loesungs-Ids (Farm._WurzelId/_KindId): Wurzel '7',
  Mutationskind '7.2', dessen Kind '7.2.1' - die ganze Abstammung ist
  direkt aus der Id ablesbar

Tests (15 gruen), README und CLAUDE.md aktualisiert; Beispiele mit den
neuen Strafen und beiden Grafiken neu berechnet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 22:38:43 +02:00
Michael Stangl 644f61ef6b Adaptiver GA-Zyklus, Pool-Groessen-Panel, Konfig direkt aus cfg-Dateien
Zyklus/Farm:
- neuer adaptiver Modus: grosse Startpopulation, die je Generation
  schrumpft (Start/Schrumpfung/MinPopulation) und bei Konvergenz stoppt
  (Geduld Generationen ohne Verbesserung >= Schwelle, max MaxGenerationen)
- Zyklus.laden erkennt adaptives Profil am Feld 'Start' (Modus adaptiv),
  sonst klassisch (Abfolge/Anzahl); Farm._LaufStatisch/_LaufAdaptiv
- neue Trunkierungs-Selektion Farm.PopulationBegrenzen
- [Adaptiv]-Profil in zyklus.cfg (dokumentiert)

Entwicklungsgrafik:
- zweites Panel unter dem Verlauf zeigt die Anzahl erzeugter
  Verteilungen im Pool je Schritt (gemeinsame Zeitachse)

Konfiguration:
- platz.cfg entfernt; zyklus.cfg/strafen.cfg werden direkt aus
  $PLATZ_CFG geladen
- neuer Schalter --zyklus-art (Default Adaptiv) waehlt das GA-Profil
- web/main.py analog: direktes Laden, Profil via PLATZ_ZYKLUSART

Doku (README.md, CLAUDE.md) und Tests entsprechend aktualisiert;
Beispiele mit dem Adaptiv-Default neu berechnet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 14:31:59 +02:00
Michael Stangl 4f87895303 Abstandsstrafe fuer getrennte Gruppen + Verbindungslinien-Optionen
- strafen.cfg: neuer optionaler Abschnitt [Abstand] mit Faktor je
  normierter Abstandseinheit (0..100, bezogen auf die max. Ausdehnung
  der Tischanordnung)
- Strukturdaten.py: Strafliste.AbstandFaktor, gibPunkte('Abstand',...),
  bewerten() bestraft den max. Tisch-Tisch-Abstand getrennter Gruppen;
  abwaertskompatibel (fehlt der Abschnitt -> Faktor 0)
- platz.py: --show-/--hide-connections steuern die Verbindungslinien
  getrennter Gruppen in der SVG
- work/*, doc/images/*: Beispiele neu durchgerechnet

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 13:47:49 +02:00
Michael Stangl 98b1dc4f36 per Skript alle im work liegenden Beispiele aufrufen. 2026-07-11 13:45:51 +02:00
Michael Stangl 9de80d2f2a Web-M1-Ausbau: JSON-Gaesteliste, GA-Verlauf, Python-Serversteuerung, tische.ini-Upload
- bestellung.xml -> bestellung.json: neuer JSONConfig (loest XMLConfig ab),
  alle work-Beispiele konvertiert, Doku (CLAUDE/README/dateiformate) umgestellt
- ga.py: Beobachtungsobjekt Entwicklung zeichnet den Loesungsverlauf auf,
  neuer Schalter --show-development erzeugt Entwicklung.svg (beste/mittlere/
  schlechteste Wertigkeit ueber die Zyklus-Aktionen)
- web/main.py: neuer Endpunkt /tische-datei (tische.ini-Upload, ast.literal_eval),
  Frontend kann jetzt eine tische.ini laden
- libs/webserver.py: plattformunabhaengige start/stop/status-Steuerung der
  Web-Testinstanz (ersetzt run_web_helper.ps1), raeumt auch verwaiste
  --reload-Prozessbaeume zuverlaessig auf
- Sicherheit/Modernisierung: eval() -> ast.literal_eval in Tische/Strafliste,
  sicherer Mini-Auswerter fuer die String-Ausdruecke in zyklus.cfg,
  defaultdict(set) in Plaetze
- SVG: Tischnummer fett zentriert im Tischkreis statt "Tisch x" darueber
- Tests: JSONConfig, Entwicklung und der Zyklus-Auswerter abgedeckt (9 Tests)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 12:49:42 +02:00
Michael Stangl 00dffc59eb Web-MVP (M1): FastAPI-API, Testoberflaeche, tische.ini-Upload, zwei neue Beispiele
- web/main.py: Session-basierte REST-API um den GA-Kern (POST /sitzung,
  .../tische, .../tische-datei, .../personen, .../berechnen,
  GET .../ergebnis[.svg]); Sessions in-memory mit 24h-TTL
- web/static/index.html: einfache Browser-Testoberflaeche (Tisch-Tabelle
  mit Presets, tische.ini-Upload, CSV-Gaesteliste, Kennzahlen, SVG)
- bin/run_web.bat/.sh + run_web_helper.ps1: start/stop/status inkl.
  Aufraeumen verwaister uvicorn-Reload-Kindprozesse (Zombie-Sockets)
- work/hochzeit: 120 Hochzeitsgaeste, Ehrentafel, Kindertisch/Teenager-
  Tisch fest gesetzt, Kinderalter normalverteilt, ~85% Auslastung
- work/innenhoefe: 300 Gaeste in zwei trapezfoermigen Innenhoefen mit
  4er-Tischen, 12 VIPs vor der Buehne, Umfeld.svg mit Tanzflaeche/Band
- Roadmap: Konzeptentscheidungen 1-11 (Zielgruppe, Einmalzahlung, MoR,
  Hetzner, Zwei-Marken-Strategie Sitz&Platz/SeatWonder), Namensrecherche
  im Anhang, M1-Fortschritt und GA-Lasttest-Datenpunkt dokumentiert

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:21:45 +02:00
Michael Stangl 5124b7fab6 PErsonendaten auch als .csv Einlesen 2026-07-11 10:00:13 +02:00
Michael Stangl c4c690bd78 weitere Details in die Roadmap ergänzt 2026-07-10 22:44:49 +02:00
Michael Stangl 4c9f57db5a Add market research on existing seating-chart competitors to roadmap
Surveys wedding/event seating tools currently available: most are
pure drag-and-drop editors with no optimization algorithm, while a
smaller group (notably PerfectTablePlan) uses the same genetic
algorithm / scoring approach as this project. Documents pricing
patterns and identifies the gap this project could fill: a
web-native SaaS with real optimization and a German/EU-focused,
GDPR-friendly hosting story, which none of the surveyed competitors
currently offer together.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 13:13:58 +02:00
Michael Stangl 3dd26ec651 Add roadmap for offering platz as a web service
Documents a 5-milestone path (foundation, MVP web tool, variant
generation, accounts/persistence, monetization) to turn the
existing GA seating solver into a hosted service for wedding/event
seating, including effort estimates, GDPR considerations once real
guest data is stored long-term, and why a freemium/one-time-payment
model fits this use case better than advertising.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 13:09:16 +02:00
Michael Stangl 74e08f389c Add --tosvg switch to render seating as SVG, plus test images and docs
Sitzplatzverteilung.alsSVG() (libs/Strukturdaten.py) draws tables as
white circles and people as colored circles inside their table's
circle, colored by group membership. Table radius is derived from
the number of seats so all person-circles fit without touching; the
table-to-table grid spacing is derived from the largest table radius
so tables never overlap regardless of their Koordinaten values.

libs/platz.py gains a --tosvg switch that writes
<indir>/Sitzplatzverteilung.svg alongside the existing text/CSV
output.

The three unittest scenarios now each write their rendering to
doc/images/, and doc/docu_tests.md explains the three configurations
and what each test actually verifies (including why the "split
groups land on true neighbor tables" property only holds for a
specifically chosen seed in the circle scenario, not in general).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 12:55:32 +02:00
Michael Stangl 0232e54f37 Add run_tests.bat/.sh to run the unittest suite via bin/
Follows the same setenv-based convention as the other bin/ scripts
and runs python -m unittest discover against tests/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 12:44:36 +02:00
Michael Stangl 9a52fe5550 Add unittest suite for Sitzplatzverteilung with three scenarios
Covers three concrete seating layouts to exercise the GA's group
placement and splitting logic:
- three tables chained pairwise (2 seats each), three couples ->
  no group gets split, optimal score of 0.
- four tables in a line (2 seats each), two groups of four -> each
  group ends up split across one contiguous table pair (T1+T2 or
  T3+T4), never mixed across the middle seam.
- six tables in a circle (2 seats each), four groups of three ->
  each group is split exactly once (2+1), since no table has three
  seats; with the fixed seed the split pairs are also true circle
  neighbors.

Also documents how to run the suite in README.md, including the
PYTHONPATH workaround needed when a stray global env var shadows
the stdlib "tests" package name with an unrelated project's tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 12:42:45 +02:00
Michael Stangl 405319b075 Document Abfolge/Anzahl action letters in zyklus.cfg header
Adds a comment header explaining what e/s/S/m/j/z mean in the
Abfolge sequence, referencing the corresponding Farm actions in
libs/ga.py.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 12:28:42 +02:00
Michael Stangl 6e3649ed27 Port codebase from Python 2 to Python 3
Replace Python 2-only constructs throughout libs/: print statements,
ConfigParser -> configparser, sets.Set -> builtin set, string.split ->
str.split, xrange -> range, dict.has_key()/.iteritems() -> in/.items(),
old-style raise Exception, "msg" syntax, and __cmp__ -> __eq__/__lt__
via functools.total_ordering (Python 3 dropped cmp()/__cmp__, which
max()/.sort() rely on). Also cleaned up mixed tab/space indentation
that Python 3's stricter tokenizer rejects.

Fixed two latent bugs that only surfaced once end-to-end runs were
possible under Python 3's stricter error handling:
- HandleBestellung() compared G.Anzahl (a bound method) to an int
  instead of calling G.Anzahl() - silently "worked" under Python 2's
  permissive cross-type ordering, raises TypeError under Python 3.
- LeuteAllein() raised KeyError for VIP-group members, who are never
  added to the regular Gruppen container; now skips people with no
  group entry instead of crashing.

Verified end-to-end: bin/platz.sh --indir work/test1 and --indir
work/test2 (VIP group included) both run to completion and produce
correctly formatted output.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 12:27:27 +02:00
Michael Stangl 1e2eedc62b Replace fixed input/output paths in platz.cfg with --indir switch
Tischedatei, XMLdatei_Bestellung, AusgabeTischePersonen and
AusgabePersonTisch are no longer configured in platz.cfg. Instead,
platz.py now requires a --indir <dir> command-line switch pointing
at a directory that must contain tische.ini and bestellung.xml, and
into which TischePersonen.txt/PersonenTische.csv are written - e.g.
work/test1 or work/test2. This makes it trivial to run against
different guest lists without editing platz.cfg. platz.bat/platz.sh
forward extra arguments so --indir can be passed through.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 12:13:17 +02:00
Michael Stangl e8911df7e9 Use setenv in launcher scripts, add requirements.txt and missing .sh scripts
platz.bat/platz.sh now derive PLATZ via setenv instead of hardcoded
paths, matching the Standard Programm Template already applied to
setenv/install_py/activate_venv/get_cmd. Added the missing .sh
counterparts to those .bat scripts, an empty requirements.txt for
install_py to install (project only uses the stdlib), and ignore
entries for .venv/, out/, .vscode/, *.swp.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 11:57:05 +02:00
73 changed files with 13702 additions and 763 deletions
+5
View File
@@ -2,3 +2,8 @@
__pycache__/
*.pyo
work/ausgabe.txt
.venv/
out/
.vscode/
*.swp
/log/
+160 -46
View File
@@ -10,44 +10,136 @@ sizes/neighbor relationships, and a penalty scheme. It reads an XML order/guest
table layout, runs a small custom GA framework to search for a good seating, and writes the
result to text/CSV output files.
**This is Python 2 code** (print statements, `ConfigParser`, `sets.Set`, `UserList`,
`string.split`, old-style `raise Exception, "msg"`, `xrange`, `dict.has_key`,
`dict.iteritems`). It will not run under Python 3 without a 2to3-style port. There is no
`requirements.txt`, build system, test suite, or linter configured in this repo — a Python 2
interpreter with only the standard library is sufficient to run it.
**This is Python 3 code**, migrated from an original Python 2 implementation (the git
history / old comments may still say "Python 2" — that's now stale). Notable migration
artifacts to be aware of when touching this code:
- `Gruppe`, `Loesung`, and `Sitzplatzverteilung` use `@functools.total_ordering` with
`__eq__`/`__lt__` instead of the old Python 2 `__cmp__` (Python 3 dropped `__cmp__` and
`cmp()` entirely; `max()`/`.sort()` need rich comparisons).
- `sets.Set` → builtin `set`; `ConfigParser``configparser`; `string.split`
`str.split`; `xrange``range`; `dict.has_key(k)``k in dict`; `dict.iteritems()`
`dict.items()`; old-style `raise Exception, "msg"``raise Exception("msg")`.
- `Strukturdaten.LeuteAllein()` was fixed to skip people with no entry in
`self.Gruppen.GvonPid` (e.g. VIP-group members who were never added to the regular
`Gruppen` container) instead of letting `GruppeVonPid` raise `KeyError` — this was a
latent bug that only surfaced once VIP data (`work/test2`) was actually exercised
end-to-end.
- `HandleBestellung()` had a `G.Anzahl` comparison (`G.Anzahl > 0`) that used to silently
compare a bound method to an int under Python 2's permissive cross-type ordering;
Python 3 raises `TypeError` for that, which is what surfaced it. Fixed to call
`G.Anzahl()`.
There is no build system or linter configured in this repo. A `tests/` unittest suite
exists (see below); `requirements.txt` is still empty/commented — everything used is
standard library — it's there only so `bin/install_py.*` has something to install into the
`.venv`.
## Running the program
Entry point is `libs/platz.py`, invoked via the wrapper scripts in `bin/`, which set up
environment variables and `PYTHONPATH` before calling it — the scripts never take a script
argument, they just launch `platz.py`:
Entry point is `libs/platz.py`, invoked via the scripts in `bin/` (each provided as a
`.bat`/`.sh` pair, following the "Standard Programm Template" convention — see
`~/.claude/CLAUDE.md` for the template rules):
- `bin/run` (bash, for Linux/macOS) — hardcodes `PLATZ=/Users/sm/develop/python/platz`
- `bin/run.bat` (Windows) — hardcodes `PLATZ=h:\develop\python\platz` and a Python 2.4 interpreter path
- `bin/setenv.bat` / `bin/setenv.sh` — derives `PLATZ` from the script's own location (no
path editing needed), sets `PLATZ_BIN`, `PLATZ_CFG`, `PLATZ_LIBS`, `PLATZ_WORK`,
`PLATZ_IN`, `PLATZ_OUT`, adds `PLATZ_LIBS` to `PYTHONPATH` (idempotently), and creates
missing folders. Sourced by every other script; not normally invoked directly. The `.sh`
variant must be sourced (`source bin/setenv.sh`), not executed.
- `bin/install_py.bat` / `bin/install_py.sh` — calls `setenv`, then creates `.venv` (via
`py -m venv` / `python3 -m venv`) and `pip install -r requirements.txt` if `.venv` doesn't
already exist.
- `bin/activate_venv.bat` / `bin/activate_venv.sh` — calls `setenv`, then activates the
existing `.venv` (errors out if `install_py` hasn't been run yet).
- `bin/get_cmd.bat` / `bin/get_cmd.sh` — calls `setenv`, then opens a new shell with the
`PLATZ_*` environment already set.
- `bin/platz.bat` / `bin/platz.sh` — calls `setenv`, then runs `python
"$PLATZ_LIBS/platz.py"`. This is the actual program entry point (replaces the old
`bin/run` / `bin/run.bat`, which hardcoded absolute paths and have been removed).
Both scripts set `PLATZ_CFG`, `PLATZ_LIBS`, `PLATZ_WORK` and add `PLATZ_LIBS` to
`PYTHONPATH`, then run `python $PLATZ_LIBS/platz.py`. **The hardcoded paths at the top of
these scripts must be edited to match wherever this repo is actually checked out** before
they will work.
`libs/platz.py` requires a command-line switch `--indir <dir>` (parsed with `optparse`)
pointing at a directory that holds the per-run input files and
receives the output files — e.g. `work/test1/`, `work/test2/`, or any new folder following
the same layout:
- `tische.ini` — table definitions: id, `Nummer`, `Hof` (venue/court), `Plaetze` (seats),
`Nachbarliste` (neighbor table ids), `Koordinaten`.
- `bestellung.json` — the guest order: `{ "gruppen": [ ... ] }`, each group holding a
`"personen"` list (each with `vorname`/`nachname`/optional `titel`), an optional
`"anzahl"` (reservation count — expands every person in the group into that many identical
bookings), an optional `"name"` (display label), and an optional `"tisch"` to pin a VIP
group to a specific table. Replaces the old `bestellung.xml`/`XMLConfig`.
- Output (written back into the same `--indir` directory): `TischePersonen.txt` (table →
seated people) and `PersonenTische.csv` (person → table, sorted).
Configuration is driven by `cfg/platz.cfg`, which points (via `$PLATZ_CFG`/`$PLATZ_WORK`
env-var expansion) to:
- `cfg/zyklus.cfg` — defines the GA run schedule ("Zyklus"): a sequence of actions
(`e`=erzeugen/create, `s`=selektieren/select-best, `S`=random-select, `m`=mutieren/mutate,
`j`=behalten/keep parents, `z`=neue Generation/advance generation) each with a count.
- `cfg/strafen.cfg` — the penalty ("Strafpunkte") table: cost of splitting a group across
tables (by group size and number of splits), cost of a lone person, and per-table
under-utilization penalties.
- A per-run working directory under `work/<name>/` (e.g. `work/test1/`, `work/test2/`)
containing:
- `tische.ini` — table definitions: id, `Nummer`, `Hof` (venue/court), `Plaetze` (seats),
`Nachbarliste` (neighbor table ids), `Koordinaten`.
- `bestellung.xml` — the guest order: `<Gruppe>` blocks containing `<Person>` (with
`Vorname`/`Nachname`/optional `Titel`) and an `<Anzahl>` (reservation count per person
template — this expands into that many identical bookings), plus optional `<Tisch>` to
pin a VIP group to a specific table.
- Output: `TischePersonen.txt` (table → seated people) and `PersonenTische.csv`
(person → table, sorted).
The GA cycle and penalty scheme are read directly from `$PLATZ_CFG/zyklus.cfg` and
`$PLATZ_CFG/strafen.cfg` (independent of `--indir`). There is no `platz.cfg` indirection any
more — it was removed; `zyklus.cfg`/`strafen.cfg` are loaded straight from `$PLATZ_CFG`, the
GA profile is chosen by the `--zyklus-art <name>` switch (default `Adaptiv`), the penalty
profile by the `--strafen <name>` switch (default `default`), and the SVG colour profile by
the `--farben <name>` switch (default `grosse_gruppen`).
- `cfg/zyklus.cfg` — defines the GA profiles. Two flavours: **static** profiles (`Easy`,
`Simple`) give an explicit sequence of actions (`e`=erzeugen/create, `s`=selektieren/
select-best, `S`=random-select, `m`=mutieren/mutate, `j`=behalten/keep parents, `z`=neue
Generation/advance generation) each with a count (`Abfolge`/`Anzahl`). The **adaptive**
profile (`Adaptiv`, the default) is recognised by a `Start` field and has no fixed action
list: `Zyklus.Modus` becomes `'adaptiv'` and `Farm._LaufAdaptiv()` runs a generation loop
with a shrinking population (`Start`, `Schrumpfung`, `MinPopulation`) and a convergence
stop (`Geduld` generations without an improvement of at least `Schwelle`, capped by
`MaxGenerationen`). Static profiles run via `Farm._LaufStatisch()`.
- `cfg/strafen.cfg` — the penalty ("Strafpunkte") profiles. Each section is one complete
profile ("Vorgehen") in a single namespace, chosen by `--strafen <section>` (default
`default`); this lets several scoring strategies live in one file (the shipped file also
has a `locker` example with cheaper splits). Keys per profile: `Anzahl_Trennungen_N`
(`{groupsize:points}` for a group split across `N+1` tables, i.e. `N` splits — recursing to
smaller sizes when no exact entry), `NichtNachbar` (no group-mate at a neighbouring table),
`Allein` (a lone person), optional `TischWertigkeiten` (`{freeseats:points}` under-utilization,
with a nearest-lower-key fallback; absent = free seats not penalised, as in the `locker`
profile), and optional `AbstandFaktor` (per spatial-distance unit
between split-off parts; absent = distance not penalised). `Strafliste.laden(FileName,
Sektion='default')` parses one section; the old `[Trennung]`/`[Globals]`/`[Abstand]`
three-section layout is gone.
- `cfg/farben.cfg` — SVG colour profiles, chosen by `--farben <section>` (default
`grosse_gruppen`) / env `PLATZ_FARBENART`, parsed by `Farben.Farbschema.laden()` (in
`libs/Farben.py`) and passed into `Sitzplatzverteilung.alsSVG(..., Farbschema=...)`. Two
modes: `Modus = palette` (a `Palette` colour list cycled per group by sorted group id — the
`grosse_gruppen` profile) and `Modus = kategorien` (the `hochzeit` profile — splits groups
into **Familie** = members mostly share a surname, coloured along `FamilienVerlaeufe`
gradients blue→green / yellow→orange, one gradient bucket per surname; **Verein** = any
other named group, along `VereinVerlauf` violet→grey; **VIP** = fixed-table people with no
GA group, the start of `VIPVerlauf`, red). Gradient syntax `"start -> end"`. Anonymous bulk
bookings (all members identical, e.g. an `anzahl`-expanded "Gast Musikverein") are *not*
treated as a family. Absent/invalid config falls back to the built-in palette
(`Farbschema=None`), so the SVG always renders.
`tische.ini`/`bestellung.json`/`TischePersonen.txt`/`PersonenTische.csv` are fixed filenames
resolved as `os.path.join(indir, ...)` in `platz.py`.
Pass `--tosvg` to additionally write `<indir>/Sitzplatzverteilung.svg` via
`Sitzplatzverteilung.alsSVG()` (see below). `--show-development` writes
`<indir>/Entwicklung.svg` (value curves + pool-size panel), and `--show-lineage` writes
`<indir>/Abstammung.svg` — the full mutation tree of every solution, with the final best
solution's ancestral branch highlighted and labelled with its id. Every solution gets a plain
running number (`Farm._NeueId`, `1..N`); the ancestry is not encoded in the id but recorded
via each node's stored predecessor (parent id) and followed back along the highlighted branch.
Pass `--seed <int>` to make a run fully reproducible: `platz.py` calls `random.seed()` with
it before any GA action, so the same seed always yields the same seating (for support
questions like "why is Aunt Erna seated there?" — rerun with the same seed to get the exact
same plan). Reproducibility needs more than seeding the RNG: `Person` defines an Id-based
`__hash__`/`__eq__` (each booking has a unique running integer Id) so that the `set()` of
people in a `Gruppe` iterates/`pop()`s in a process-stable order — otherwise the order would
hinge on object memory addresses (and, for string-keyed containers, `PYTHONHASHSEED`), leaving
the run non-reproducible even with `--seed`. Integer Ids aren't affected by `PYTHONHASHSEED`,
so no environment tweaking is required.
`Farm.TopN(n)` returns the `n` best solutions (descending), clamped to `[0, len(Pool)]` — the
list generalisation of `Farm.Bester()` (single best), for surfacing several good alternatives.
Run the test suite with `bin/run_tests.bat` / `bin/run_tests.sh` (or directly: `python -m
unittest discover -s tests -p "test_*.py" -v`). A stray global `PYTHONPATH` entry on this
machine points at an unrelated project that also defines a `tests` package — this shadows
`import tests` but does not affect `unittest discover`, which is what the run_tests
scripts use.
## Architecture
@@ -63,7 +155,14 @@ Domain-agnostic and reusable in principle:
- `Farm` — owns the population (`Pool`/`PoolNeu`), and executes a `Zyklus` action-by-action
against instances of a given solution class (passed as `Klasse` plus its constructor
args/kwargs). `Bester()` returns the fittest (`max()`) solution found; solutions are ordered
via `__cmp__` on `self.value`.
via `__eq__`/`__lt__` (`@total_ordering`) on `self.value`. The Farm also tags every solution
with a hierarchical lineage id (`_absid`; `_WurzelId`/`_KindId`) and records the mutation
tree into `self.Abstammung`.
- `Entwicklung` ("Development") — observer that records one measurement per cycle action
(best/avg/worst value + pool size); `alsSVG()` draws the value curves plus a pool-size panel.
- `Abstammung` ("Lineage") — observer that records the mutation tree (each solution's id,
parent id, generation, value); `alsSVG(HervorId=...)` draws the tree and highlights/labels
the ancestral branch of the given (usually the best) solution.
### `Strukturdaten.py` — domain model for this specific seating problem
- `Person`, `Gruppe` (group — a `Set` of people, splittable via `teilen()`), `Tisch` (table —
@@ -76,27 +175,42 @@ Domain-agnostic and reusable in principle:
a group (`gibPunkte('Trennung', ...)`, recursing to smaller group sizes if no exact rule is
configured), a person sitting with no group-mate at their table (`'allein'`), a person having
no group-mate at a *neighboring* table (`'nichtNachbar'`), and poor seat utilization at a
table (`'Tischbesetzung'`).
table (`'Tischbesetzung'` — the penalty rises with the number of free seats, with a nearest-
lower-key fallback, so partly-filled tables are penalised most and groups get pulled onto a
single table instead of being split next to empty ones).
- `Sitzplatzverteilung` ("Seating arrangement") — the actual `Loesung` subclass bred by the GA.
Constructor seats VIPs first at pinned tables, then randomly seats groups either
largest-first or smallest-first (coin flip), splitting a group across two neighboring tables
when no single table has enough free seats, recursively splitting further if needed, then
calls `bewerten()` to score the arrangement per `Strafliste`. `mutieren()` picks the
worst-scoring groups (`SchlechteGruppenTopX`), evicts them, and reseats them, hoping for a
better score. `speichern()` writes the two output files.
- `XMLConfig` — parses `bestellung.xml` into `Personen`/`Gruppen`/VIP-group/VIP-seat-map,
expanding each `<Person>` template by its sibling `<Anzahl>` into that many individual
bookings, and treating any `<Gruppe>` containing a `<Tisch>` tag as a VIP group pinned to
that table rather than going through normal GA placement.
worst-scoring groups (`SchlechteGruppenTopX`), evicts them, and reseats them largest-first
(`GruppenSetzen(..., GrosseZuerst=True)`) so big groups grab the now-freed whole tables and
come back together instead of being re-split; the initial constructor placement still uses
the random largest/smallest coin flip (`GrosseZuerst=False`). `speichern()` writes the two output files. `alsSVG()` renders the layout to
SVG: tables as white circles sized to fit all their seats' person-circles without
touching, people as colored circles (color = group, via `SVGGruppenFarben`) placed evenly
around the inside of their table's circle. The table-to-table grid spacing is derived
from the largest table radius so tables never overlap regardless of their `Koordinaten`.
- `JSONConfig` — parses `bestellung.json` into
`Personen`/`Gruppen`/VIP-group/VIP-seat-map/group-names, expanding each person by the
group's `"anzahl"` into that many individual bookings, and treating any group with a
`"tisch"` key as a VIP group pinned to that table rather than going through normal GA
placement. Returns a 5th element (`GruppenNamen`, `{Gid: display name}`) that the older
`XMLConfig` did not; `CSVConfig` (the web CSV adapter) returns the same 5-tuple.
### Data flow through `platz.py` (`__main__`)
1. Read `platz.cfg` to locate the other config/data files (env-var expansion via
`os.path.expandvars`).
2. Load `Zyklus` (GA schedule), `Strafliste` (penalties), `Tische` (table layout).
3. Load `bestellung.xml` via `XMLConfig` → people, groups, VIP group, VIP seat map.
4. Build a `Farm(Zyklus, Sitzplatzverteilung, Tische=..., Gruppen=..., Strafen=...,
1. Parse `--indir` (required) and `--zyklus-art` (default `Adaptiv`) from the command line
via `optparse`.
2. Resolve `zyklus.cfg`/`strafen.cfg` directly as `os.path.join($PLATZ_CFG, ...)`.
3. Load `Zyklus` (GA profile named by `--zyklus-art`), `Strafliste` (penalties), `Tische`
(table layout, from `<indir>/tische.ini`).
4. Load `<indir>/bestellung.json` via `JSONConfig` → people, groups, VIP group, VIP seat
map, group names.
5. Build a `Farm(Zyklus, Sitzplatzverteilung, Tische=..., Gruppen=..., Strafen=...,
VIPListe=..., VIPs=...)`, which runs the whole GA cycle in its constructor.
5. Take `Farm.Bester()` and call `.speichern(...)` to write the output files.
6. Take `Farm.Bester()` and call `.speichern(...)` to write `<indir>/TischePersonen.txt` and
`<indir>/PersonenTische.csv`.
Both `libs/platz.py` and `libs/Strukturdaten.py` also have self-test code under
`if __name__ == '__main__':` that exercises the classes directly with hardcoded sample data —
+90 -44
View File
@@ -5,83 +5,116 @@ given group memberships, table sizes/neighbor relationships, and a configurable
scheme. It reads a guest list (XML) and a table layout (INI), searches for a good seating
using a small custom GA framework, and writes the result to text/CSV output files.
**This is Python 2 code** (print statements, `ConfigParser`, `sets.Set`, `UserList`,
`string.split`, old-style `raise Exception, "msg"`, `xrange`, `dict.has_key`,
`dict.iteritems`). It needs a Python 2 interpreter; there are no third-party dependencies
(standard library only).
**This is Python 3 code** (migrated from an original Python 2 implementation). There are no
third-party dependencies (standard library only), so `requirements.txt` is empty — it
exists only so `bin/install_py` has something to install.
## Project structure
```
platz/
├── bin/ # launcher scripts (bash + Windows batch)
├── bin/ # environment + launcher scripts (.bat + .sh pairs)
├── cfg/ # GA cycle definition and penalty scheme
├── libs/ # the two Python modules (ga.py, Strukturdaten.py, platz.py)
├── tests/ # unittest suite for Strukturdaten.py
└── work/ # per-run input (table layout, guest list) and output
├── test1/
└── test2/
```
- `libs/platz.py` — entry point; wires together config, input data, and the GA run.
- `libs/ga.py` — generic genetic-algorithm scaffolding (`Loesung`, `Zyklus`, `Farm`).
- `libs/ga.py` — generic genetic-algorithm scaffolding (`Loesung`, `Zyklus`, `Farm`,
`Entwicklung`).
- `libs/Strukturdaten.py` — domain model for the seating problem (`Person`, `Gruppe`,
`Tisch`, `Strafliste`, `Sitzplatzverteilung`, `XMLConfig`).
`Tisch`, `Strafliste`, `Sitzplatzverteilung`, `JSONConfig`).
## Running the tests
```bash
python -m unittest discover -s tests -p "test_*.py" -v
```
If a stray global `PYTHONPATH` entry shadows the standard-library `tests` package name
(unrelated to this project), clear it for the command, e.g. `PYTHONPATH= python -m
unittest discover -s tests -p "test_*.py" -v`.
## Setup
1. Install a Python 2 interpreter (2.4+; no `pip install` needed, standard library only).
2. Edit the hardcoded paths at the top of the launcher script for your platform:
- `bin/run` (bash): `PLATZ=/Users/sm/develop/python/platz`
- `bin/run.bat` (Windows): `PLATZ=h:\develop\python\platz` and `PYTHONSHELL=l:\tools\i486_nt\python24`
1. Install a Python interpreter (`py` on Windows / `python3` on Linux/macOS must be on
`PATH`).
2. Run the installer for your platform to create a `.venv` and install `requirements.txt`:
Point `PLATZ` at wherever you checked out this repository.
```bat
:: Windows
bin\install_py.bat
```
```bash
# Linux/macOS
bin/install_py.sh
```
All `bin/` scripts derive `PLATZ` automatically from their own location (no path editing
required) by calling `setenv.bat`/`setenv.sh` first.
## Running
From a shell:
```bat
:: Windows
bin\activate_venv.bat
bin\platz.bat --indir work\test1
```
```bash
# Linux/macOS
source bin/run
source bin/activate_venv.sh
bin/platz.sh --indir work/test1
```
```bat
:: Windows
bin\run.bat
```
`bin/platz.bat` / `bin/platz.sh` call `setenv` to set `PLATZ`, `PLATZ_CFG`, `PLATZ_LIBS`,
`PLATZ_WORK`, `PLATZ_IN`, `PLATZ_OUT`, add `PLATZ_LIBS` to `PYTHONPATH`, and then run
`libs/platz.py`, forwarding any extra arguments (like `--indir`) to it.
The launcher sets `PLATZ_CFG`, `PLATZ_LIBS`, `PLATZ_WORK`, adds `PLATZ_LIBS` to
`PYTHONPATH`, and runs `libs/platz.py`.
Other helper scripts (`bin/setenv.*`, `bin/get_cmd.*`) follow the same environment
convention:
- `setenv` — sets all `PLATZ_*` environment variables and creates missing folders; sourced
by every other script, not normally called directly.
- `activate_venv` — activates the `.venv` created by `install_py`.
- `get_cmd` — opens a new shell with the `PLATZ_*` environment already set.
### Configuring a run
`cfg/platz.cfg` selects which cycle/penalty config and which working directory
(`work/<name>/`) to use for a given run:
```ini
[Config]
Zyklusdatei=$PLATZ_CFG/zyklus.cfg
Zyklusart=Easy
Strafendatei=$PLATZ_CFG/strafen.cfg
Tischedatei=$PLATZ_WORK/test1/tische.ini
XMLdatei_Bestellung=$PLATZ_WORK/test1/bestellung.xml
AusgabeTischePersonen=$PLATZ_WORK/test1/TischePersonen.txt
AusgabePersonTisch=$PLATZ_WORK/test1/PersonenTische.csv
```
To run against a different dataset, point the `Tischedatei`/`XMLdatei_Bestellung`/output
entries at another `work/<name>/` folder, or add a new one following the same layout:
`--indir <dir>` is required and points at a directory containing the input files and
receiving the output files for one run — e.g. `work/test1/` or `work/test2/`:
- `tische.ini` — one section per table: `Nummer`, `Hof` (venue/court), `Plaetze` (seat
count), `Nachbarliste` (neighboring table ids), `Koordinaten`.
- `bestellung.xml``<Gruppe>` blocks, each with a `<Person>` template
(`Vorname`/`Nachname`/optional `Titel`) and an `<Anzahl>` (how many bookings to expand
that template into). A `<Gruppe>` containing a `<Tisch>` tag is treated as a VIP group
pinned to that table instead of being placed by the GA.
- `bestellung.json` — `{ "gruppen": [ ... ] }`, each group with a `"personen"` list
(`vorname`/`nachname`/optional `titel`), an optional `"anzahl"` (how many bookings to
expand each person into), an optional `"name"` (display label) and an optional `"tisch"`
(pins the group as a VIP group to that table instead of placing it via the GA).
`cfg/zyklus.cfg` defines the GA run schedule ("Zyklus") as an `Abfolge` (sequence of
actions) and matching `Anzahl` (counts): `e` create, `s` select best, `S` select randomly,
`m` mutate, `j` keep parents, `z` advance generation.
To run against a different dataset, create a new folder with a `tische.ini` and
`bestellung.json` following the same layout and pass it via `--indir`.
The GA cycle and penalty scheme are read directly from `$PLATZ_CFG/zyklus.cfg` and
`$PLATZ_CFG/strafen.cfg` (independent of `--indir`); there is no longer a `platz.cfg`
indirection. The GA profile is selected with the `--zyklus-art <name>` switch (default:
`Adaptiv`).
`cfg/zyklus.cfg` defines the GA profiles. Two styles exist:
- **static** profiles (`Easy`, `Simple`) give an explicit `Abfolge` (sequence of actions)
and matching `Anzahl` (counts): `e` create, `s` select best, `S` select randomly, `m`
mutate, `j` keep parents, `z` advance generation.
- the **adaptive** profile (`Adaptiv`, the default) has no fixed action list. It is
recognised by a `Start` field and runs a generation loop: a large starting population
that shrinks each generation (`Schrumpfung`, down to `MinPopulation`) and stops once the
best score fails to improve by at least `Schwelle` for `Geduld` generations (or after
`MaxGenerationen`).
Select a different profile per run, e.g. `bin/platz.bat --indir work/test2 --zyklus-art Easy`.
`cfg/strafen.cfg` defines the penalty scheme: cost of splitting a group across tables (by
group size and number of splits), cost of a person sitting alone or without a group-mate at
@@ -89,11 +122,24 @@ a neighboring table, and per-table seat-utilization penalties.
### Output
A run writes two files into the configured working directory:
A run writes two files into the `--indir` directory:
- `TischePersonen.txt` — table → seated people, with venue/table/seat numbers.
- `PersonenTische.csv` — person → table, sorted alphabetically by name.
Pass `--tosvg` to additionally write `Sitzplatzverteilung.svg` into the `--indir`
directory: tables are drawn as white circles, people as colored circles inside their
table's circle (color = group). See `doc/docu_tests.md` for example renderings.
Two more optional graphs go into the `--indir` directory:
- `--show-development` → `Entwicklung.svg`: the course of the search (best/average/worst
value over time, plus a panel with the number of solutions in the pool per step).
- `--show-lineage` → `Abstammung.svg`: the mutation tree of every solution. The final best
solution's ancestral branch is highlighted and labelled with its id. Every solution gets a
plain running number (`1..N`); the ancestry is recorded via each node's stored predecessor
(parent id), not encoded in the id itself, and is followed back along the highlighted branch.
## Further details
See `CLAUDE.md` for a deeper architectural walkthrough of the GA framework and domain
+20
View File
@@ -0,0 +1,20 @@
@echo off
REM ================================================================
REM TEST - Python Virtual Environment aktivieren
REM ================================================================
call "%~dp0setenv.bat"
if not exist "%PLATZ%\.venv" (
echo FEHLER: Virtual environment nicht gefunden.
echo Bitte zuerst bin\install_py.bat ausfuehren.
exit /b 1
)
call "%PLATZ%\.venv\Scripts\activate.bat"
echo Virtuelle Umgebung aktiviert.
echo Python-Version:
python --version
echo.
echo Installierte Pakete:
pip list
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
# ================================================================
# Python Virtual Environment aktivieren
# ================================================================
source "$(dirname "${BASH_SOURCE[0]}")/setenv.sh"
if [ ! -d "$PLATZ/.venv" ]; then
echo "FEHLER: Virtual environment nicht gefunden."
echo "Bitte zuerst bin/install_py.sh ausfuehren."
return 1 2>/dev/null || exit 1
fi
source "$PLATZ/.venv/bin/activate"
echo "Virtuelle Umgebung aktiviert."
echo "Python-Version:"
python --version
echo ""
echo "Installierte Pakete:"
pip list
+7
View File
@@ -0,0 +1,7 @@
@echo off
REM ================================================================
REM TEST - Shell mit gesetzten Umgebungsvariablen oeffnen
REM ================================================================
call "%~dp0setenv.bat"
start cmd /k "echo TEST Umgebung aktiv. && echo PLATZ=%PLATZ%"
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
# ================================================================
# Shell mit gesetzten Umgebungsvariablen oeffnen
# ================================================================
source "$(dirname "${BASH_SOURCE[0]}")/setenv.sh"
exec "$SHELL"
+21
View File
@@ -0,0 +1,21 @@
@echo off
REM ================================================================
REM TEST - Python Virtual Environment einrichten
REM ================================================================
call "%~dp0setenv.bat"
if not exist "%PLATZ%\.venv" (
echo Initialisiere Python virtual environment...
py -m venv "%PLATZ%\.venv" --upgrade-deps
echo Erfolgreich.
call "%PLATZ%\.venv\Scripts\activate.bat"
echo Installiere erforderliche Python Packages...
pip install -r "%PLATZ%\requirements.txt" -q
echo Erfolgreich.
deactivate
) else (
echo Erforderliche Python Packages bereits installiert!
)
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
# ================================================================
# Python Virtual Environment einrichten
# ================================================================
source "$(dirname "${BASH_SOURCE[0]}")/setenv.sh"
if [ ! -d "$PLATZ/.venv" ]; then
echo "Initialisiere Python virtual environment..."
python3 -m venv "$PLATZ/.venv" --upgrade-deps
echo "Erfolgreich."
source "$PLATZ/.venv/bin/activate"
echo "Installiere erforderliche Python Packages..."
pip install -r "$PLATZ/requirements.txt" -q
echo "Erfolgreich."
deactivate
else
echo "Erforderliche Python Packages bereits installiert!"
fi
+8
View File
@@ -0,0 +1,8 @@
@echo off
REM ================================================================
REM Startet das Sitzplatzprogramm
REM ================================================================
call "%~dp0setenv.bat"
python "%PLATZ_LIBS%\platz.py" %*
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
# ================================================================
# Startet das Sitzplatzprogramm
# ================================================================
source "$(dirname "${BASH_SOURCE[0]}")/setenv.sh"
python "$PLATZ_LIBS/platz.py" "$@"
-17
View File
@@ -1,17 +0,0 @@
#!/bin/bash
# -------------------------------------
# Wo ist das Programm hinkopiert
export PLATZ=/Users/sm/develop/python/platz
echo $PLATZ
# -------------------------------------
# Umgebung setzen
export PLATZ_CFG=$PLATZ/cfg
export PLATZ_LIBS=$PLATZ/libs
export PLATZ_WORK=$PLATZ/work
# Wo sind die Pythonskripte ?
export PYTHONPATH=$PYTHONPATH:$PLATZ_LIBS
# Startet das Sitzplatzprogramm
python $PLATZ_LIBS/platz.py
-21
View File
@@ -1,21 +0,0 @@
echo off
REM Hier die Umgebung anpassen
REM -------------------------------------
REM Wo ist das Programm hinkopiert
set PLATZ=h:\develop\python\platz
REM Wo liegt der Interpreter
set PYTHONSHELL=l:\tools\i486_nt\python24
REM -------------------------------------
REM Umgebung setzen
set PLATZ_CFG=%PLATZ%\cfg
set PLATZ_LIBS=%PLATZ%\libs
set PLATZ_WORK=%PLATZ%\work
set PATH=%PYTHONSHELL%;%PATH%
REM Wo sind die Pythonskripte ?
set PYTHONPATH=%PLATZ_LIBS%
REM Startet das Sitzplatzprogramm
python %PLATZ_LIBS%\platz.py
+17
View File
@@ -0,0 +1,17 @@
@echo off
REM ================================================================
REM Rechnet alle Beispiele in work\ neu durch.
REM Jedes Unterverzeichnis mit einer tische.ini wird als Eingabe-
REM verzeichnis an platz.py uebergeben (inkl. --tosvg fuer die SVGs).
REM Zusaetzliche Argumente werden an jeden Lauf durchgereicht.
REM ================================================================
call "%~dp0setenv.bat"
for /d %%D in ("%PLATZ_WORK%\*") do (
if exist "%%D\tische.ini" (
echo.
echo === %%~nxD ===
python "%PLATZ_LIBS%\platz.py" --indir "%%D" --tosvg %*
)
)
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# ================================================================
# Rechnet alle Beispiele in work/ neu durch.
# Jedes Unterverzeichnis mit einer tische.ini wird als Eingabe-
# verzeichnis an platz.py uebergeben (inkl. --tosvg fuer die SVGs).
# Zusaetzliche Argumente werden an jeden Lauf durchgereicht.
# ================================================================
source "$(dirname "${BASH_SOURCE[0]}")/setenv.sh"
for dir in "$PLATZ_WORK"/*/; do
if [ -f "${dir}tische.ini" ]; then
echo
echo "=== $(basename "$dir") ==="
python "$PLATZ_LIBS/platz.py" --indir "$dir" --tosvg "$@"
fi
done
+8
View File
@@ -0,0 +1,8 @@
@echo off
REM ================================================================
REM Fuehrt die unittest-Suite in tests/ aus
REM ================================================================
call "%~dp0setenv.bat"
python -m unittest discover -s "%PLATZ%\tests" -p "test_*.py" -v
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
# ================================================================
# Fuehrt die unittest-Suite in tests/ aus
# ================================================================
source "$(dirname "${BASH_SOURCE[0]}")/setenv.sh"
python -m unittest discover -s "$PLATZ/tests" -p "test_*.py" -v
+27
View File
@@ -0,0 +1,27 @@
@echo off
REM ================================================================
REM Verwaltet die lokale Web-Testinstanz (FastAPI/uvicorn, M1)
REM
REM run_web.bat start - startet den Server im Hintergrund
REM run_web.bat stop - beendet den Server
REM run_web.bat status - zeigt ob und unter welcher PID er laeuft
REM run_web.bat - startet im Vordergrund mit Auto-Reload
REM (Strg+C zum Beenden)
REM
REM http://localhost:8000 Testoberflaeche
REM http://localhost:8000/docs interaktive API-Doku (Swagger)
REM
REM Die eigentliche Prozessverwaltung liegt plattformunabhaengig in
REM libs/webserver.py (laeuft unverandert auch unter Linux).
REM ================================================================
call "%~dp0setenv.bat" > nul
if not exist "%PLATZ%\.venv\Scripts\activate.bat" (
echo FEHLER: kein .venv gefunden - bitte zuerst bin\install_py.bat ausfuehren
exit /b 1
)
call "%PLATZ%\.venv\Scripts\activate.bat"
python "%PLATZ_LIBS%\webserver.py" %*
exit /b %errorlevel%
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
# ================================================================
# Verwaltet die lokale Web-Testinstanz (FastAPI/uvicorn, M1)
#
# run_web.sh start - startet den Server im Hintergrund
# run_web.sh stop - beendet den Server
# run_web.sh status - zeigt ob und unter welcher PID er laeuft
# run_web.sh - startet im Vordergrund mit Auto-Reload
# (Strg+C zum Beenden)
#
# http://localhost:8000 Testoberflaeche
# http://localhost:8000/docs interaktive API-Doku (Swagger)
#
# Die eigentliche Prozessverwaltung liegt plattformunabhaengig in
# libs/webserver.py (laeuft unveraendert auch unter Windows).
# ================================================================
source "$(dirname "${BASH_SOURCE[0]}")/setenv.sh" > /dev/null
if [ ! -f "$PLATZ/.venv/bin/activate" ]; then
echo "FEHLER: kein .venv gefunden - bitte zuerst bin/install_py.sh ausfuehren"
exit 1
fi
source "$PLATZ/.venv/bin/activate"
exec python "$PLATZ_LIBS/webserver.py" "$@"
+35
View File
@@ -0,0 +1,35 @@
@echo off
REM -------------------------------------
REM Wo ist das Programm hinkopiert
for %%I in ("%~dp0..") do set PLATZ=%%~fI
echo %PLATZ%
REM -------------------------------------
REM Umgebung setzen
set PLATZ_BIN=%PLATZ%\bin
set PLATZ_CFG=%PLATZ%\cfg
set PLATZ_LIBS=%PLATZ%\libs
set PLATZ_WORK=%PLATZ%\work
set PLATZ_IN=%PLATZ%\in
set PLATZ_OUT=%PLATZ%\out
REM Wo sind die Pythonskripte ?
if "%PYTHONPATH%"=="" (
set PYTHONPATH=%PLATZ_LIBS%
) else (
echo %PYTHONPATH% | find /I "%PLATZ_LIBS%" > nul
if errorlevel 1 set PYTHONPATH=%PYTHONPATH%;%PLATZ_LIBS%
)
if not exist "%PLATZ_WORK%" mkdir "%PLATZ_WORK%"
if not exist "%PLATZ_OUT%" mkdir "%PLATZ_OUT%"
echo PLATZ=%PLATZ%
echo PLATZ_BIN=%PLATZ_BIN%
echo PLATZ_CFG=%PLATZ_CFG%
echo PLATZ_LIBS=%PLATZ_LIBS%
echo PLATZ_WORK=%PLATZ_WORK%
echo PLATZ_IN=%PLATZ_IN%
echo PLATZ_OUT=%PLATZ_OUT%
echo PYTHONPATH=%PYTHONPATH%
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
# -------------------------------------
# Wo ist das Programm hinkopiert
export PLATZ="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
echo $PLATZ
# -------------------------------------
# Umgebung setzen
export PLATZ_BIN=$PLATZ/bin
export PLATZ_CFG=$PLATZ/cfg
export PLATZ_LIBS=$PLATZ/libs
export PLATZ_WORK=$PLATZ/work
export PLATZ_IN=$PLATZ/in
export PLATZ_OUT=$PLATZ/out
# Wo sind die Pythonskripte ?
case ":$PYTHONPATH:" in
*":$PLATZ_LIBS:"*) ;;
*) export PYTHONPATH=$PYTHONPATH:$PLATZ_LIBS ;;
esac
mkdir -p "$PLATZ_WORK"
mkdir -p "$PLATZ_OUT"
echo PLATZ=$PLATZ
echo PLATZ_BIN=$PLATZ_BIN
echo PLATZ_CFG=$PLATZ_CFG
echo PLATZ_LIBS=$PLATZ_LIBS
echo PLATZ_WORK=$PLATZ_WORK
echo PLATZ_IN=$PLATZ_IN
echo PLATZ_OUT=$PLATZ_OUT
echo PYTHONPATH=$PYTHONPATH
+44
View File
@@ -0,0 +1,44 @@
# Farbprofile fuer die SVG-Ausgabe (Sitzplatzverteilung.alsSVG).
#
# Jede Sektion ist ein Farbprofil, waehlbar per --farben <Sektion> (libs/platz.py,
# Vorgabe: grosse_gruppen) bzw. ueber PLATZ_FARBENART (Web). So laesst sich je
# Anlass ein anderes Farbschema vorwaehlen.
#
# Modus = palette
# Eine Farbliste (Palette), die zyklisch je Gruppe (nach Gruppen-Id sortiert)
# vergeben wird. Gut fuer viele/grosse Gruppen, wo es nur auf klare
# Unterscheidbarkeit ankommt.
#
# Modus = kategorien
# Trennt die Gruppen nach Art und faerbt sie unterschiedlich ein - gedacht
# fuer Hochzeiten:
# - Familie: eine Gruppe, deren Mitglieder mehrheitlich denselben
# Nachnamen tragen. Jeder Nachname bekommt einen Farbverlauf
# (abwechselnd aus FamilienVerlaeufe), Untergruppen desselben
# Nachnamens laufen den Verlauf entlang (z.B. Blau -> Gruen).
# - Verein: jede sonstige benannte Gruppe (Freunde, Kollegen, Vereine);
# laeuft ueber VereinVerlauf (z.B. Violett -> Grau).
# - VIP: fest gesetzte Gaeste ohne GA-Gruppe (Ehrentafel, Kindertisch);
# bekommen die Startfarbe von VIPVerlauf (Rot).
#
# Farbverlauf-Syntax: "Startfarbe -> Endfarbe"; mehrere Verlaeufe kommagetrennt.
# Fuer grosse Veranstaltungen mit vielen Gruppen: reine Palette, zyklisch.
[grosse_gruppen]
Modus = palette
Palette = #e6194b, #3cb44b, #4363d8, #f58231, #911eb4, #42d4f4, #f032e6,
#bfef45, #fabed4, #469990, #dcbeff, #9a6324, #800000, #aaffc3,
#000075, #808000, #ffd8b1, #f58231, #46f0f0, #d2f53c
# Fuer Hochzeiten: nach Familie / Verein / VIP getrennt.
[hochzeit]
Modus = kategorien
# Familien: abwechselnd Blau -> Gruen und Gelb -> Orange (je Nachname ein
# Verlauf, damit sich verschiedene Familien unterscheiden).
FamilienVerlaeufe = #1f4e9c -> #2fae5f, #f2c200 -> #e8590c
# Vereine / gemischte Gruppen: Violett -> Grau.
VereinVerlauf = #7b2fbf -> #9aa0a6
# VIPs (feste Platzierung): Rot.
VIPVerlauf = #e63946 -> #8b0000
-10
View File
@@ -1,10 +0,0 @@
[Config]
Zyklusdatei=$PLATZ_CFG/zyklus.cfg
Zyklusart=Easy
Strafendatei=$PLATZ_CFG/strafen.cfg
Tischedatei=$PLATZ_WORK/test1/tische.ini
XMLdatei_Bestellung=$PLATZ_WORK/test1/bestellung.xml
AusgabeTischePersonen=$PLATZ_WORK/test1/TischePersonen.txt
AusgabePersonTisch=$PLATZ_WORK/test1/PersonenTische.csv
+52 -15
View File
@@ -1,19 +1,56 @@
# Strafpunkte fuer die Trennung einer Gruppe:
# Aufbau: Anzahl der Trennungen = { Gruppengroesse:Strafpunkte, .. }
[Trennung]
1={ 2:-10, 3:-8, 4:-6, 6:-4, 10:-2 }
2={ 3:-20, 4:-8, 6:-6, 10:-4 }
3={ 4:-30, 6:-10, 10:-6 }
# Strafpunkte-Profile ("Vorgehen") fuer die Bewertung einer Sitzplatzverteilung.
#
# Jede Sektion ist EIN vollstaendiges Bewertungsprofil mit allen Angaben. So
# lassen sich mehrere Vorgehensweisen nebeneinander pflegen und speichern. Per
# Schalter --strafen <Sektionsname> waehlt man ein Profil; ohne Schalter wird
# [default] verwendet.
#
# Schluessel je Profil:
# Anzahl_Trennungen_N = { Gruppengroesse:Strafpunkte, .. }
# Strafpunkte fuer das Aufteilen einer Gruppe (N = Anzahl der Trennungen,
# also auf N+1 Tische verteilt), gestaffelt nach Gruppengroesse. Fehlt ein
# exakter Gruppengroessen-Eintrag, wird auf die naechstkleinere Groesse
# zurueckgegriffen. Mindestens Anzahl_Trennungen_1 sollte gesetzt sein.
# NichtNachbar = Strafe, wenn zwei Gruppenteile nicht am Nachbartisch sitzen
# Allein = Strafe, wenn eine Person ohne Gruppenmitglied am Tisch sitzt
# TischWertigkeiten = { freiePlaetze:Strafpunkte, .. } fuer freie Sitze an einem
# (teil-)belegten Tisch. Fehlt ein exakter Eintrag, gilt der
# naechstkleinere. Teilbelegte Tische sind am schlechtesten
# (dort passt keine ganze Gruppe mehr hin), daher steigt die
# Strafe mit den freien Plaetzen; ein komplett leerer Tisch
# (hoechster Schluessel) ist etwas besser, aber nicht gratis,
# damit sich das Zusammenziehen von Gruppen lohnt.
# Optional; fehlt der ganze Schluessel, werden freie Plaetze
# gar nicht bestraft -> mehr Teilbelegungen moeglich.
# AbstandFaktor = Strafpunkte je normierter Abstandseinheit (0..100) zwischen
# getrennten Teilen einer Gruppe. Der Abstand ist auf die
# maximale Ausdehnung der Tischanordnung normiert (100 =
# ein Teil ganz links/oben, der andere ganz rechts/unten).
# AbstandFaktor=-0.2 kostet den Maximalabstand also -20.
# Optional; fehlt der Schluessel, wird der Abstand nicht
# bestraft (Faktor 0).
# Wieviele Strafpunkte bekommt man
# wenn zwei Gruppen nicht am Nachbartisch sitzen
# wenn einer aus einer Gruppe allein sitzen muss
[Globals]
# Standardprofil: Trennungen sind bewusst teuer, damit eine Gruppe lieber
# zusammen an einem teilbelegten Tisch sitzt, als neben einem leeren getrennt zu
# werden.
[default]
Anzahl_Trennungen_1={ 2:-25, 3:-22, 4:-18, 6:-14, 8:-12, 10:-10 }
Anzahl_Trennungen_2={ 3:-40, 4:-30, 6:-22, 8:-18, 10:-14 }
Anzahl_Trennungen_3={ 4:-60, 6:-40, 8:-30, 10:-20 }
NichtNachbar=-3
Allein=-30
TischWertigkeiten={ 1:-3, 2:-2, 3:-1 }
TischWertigkeiten={ 1:-3, 2:-3, 4:-5, 6:-6, 8:-4 }
AbstandFaktor=-0.2
# TischWertigkeiten sind Strafpunkte fuer schlechte Ausnutzung der
# freien Sitze an einem Tisch.
# An einem Tisch, der bis auf einen Platz voll besetzt ist,
# kann niemand mehr gut dazu. wenn zwei Plaetze frei sind, ist das etwas besser.
# Beispiel fuer ein alternatives Vorgehen: Trennungen sind guenstiger, der
# Abstand wird nicht bestraft, und freie Plaetze werden gar nicht bestraft
# (TischWertigkeiten fehlt bewusst) — so sind mehr Teilbelegungen moeglich.
# Nuetzlich fuer grosse Saele, in denen sich Gruppen kaum ungeteilt platzieren
# lassen. Aufruf: --strafen locker
[locker]
Anzahl_Trennungen_1={ 2:-12, 3:-10, 4:-8, 6:-6, 8:-5, 10:-4 }
Anzahl_Trennungen_2={ 3:-20, 4:-16, 6:-12, 8:-9, 10:-7 }
Anzahl_Trennungen_3={ 4:-30, 6:-22, 8:-16, 10:-12 }
NichtNachbar=-2
Allein=-20
AbstandFaktor=0.0
+44 -6
View File
@@ -1,8 +1,46 @@
# Abfolge: Kommagetrennte Liste von Aktionsbuchstaben, die den Ablauf
# eines GA-Zyklus definieren. Jede Aktion greift auf den
# aktuellen Loesungspool zu (siehe Farm in libs/ga.py):
# e = erzeugen (neue zufaellige Loesungen erzeugen)
# s = selektieren (die besten Loesungen auswaehlen)
# S = zufaellig auswaehlen (zufaellige Loesungen auswaehlen)
# m = mutieren (bestehende Loesungen mutieren)
# j = behalten (alten Loesungspool als Eltern behalten)
# z = neue Generation (Pool durch die neu erzeugten Loesungen ersetzen)
#
# Anzahl: Kommagetrennte Liste von Zahlen, die zu jeder Aktion in der
# Abfolge gehoert und angibt, wie viele Loesungen davon
# betroffen sind ('x' = Aktion braucht keine Anzahl, z.B. j/z).
#
[Easy]
Abfolge='e,'+'s,z,m,j,z,'*3+'s'
Anzahl='10,'+'5,x,2,x,x,'*3+'1'
Abfolge='e,'+'s,z,m,j,z,'*3+'s'
Anzahl='10,'+'5,x,2,x,x,'*3+'1'
[Simple]
Abfolge='e,s'
Anzahl='20,1'
Abfolge='e,s'
Anzahl='20,1'
# Adaptives Profil: keine feste Aktionsliste, sondern eine Generationen-
# schleife (siehe Farm._LaufAdaptiv in libs/ga.py). Erkannt wird es am Feld
# 'Start'. Es wird nicht mit harten Zahlen je Aktion gearbeitet, sondern nur
# mit einem Anfangswert und einem Abbruchkriterium:
# Start = Groesse der Startpopulation (viele Verteilungen zu
# Beginn; sie schrumpft dann von Generation zu Generation)
# MutationProLoesung = wie oft jede Loesung je Generation mutiert wird
# Schrumpfung = Faktor (<1), um den die behaltene Population je
# Generation kleiner wird (0.85 = -15 %% pro Generation)
# MinPopulation = untere Schranke, damit die Population nicht auf 1 faellt
# MaxGenerationen = harte Obergrenze der Generationen
# Geduld = nach so vielen Generationen ohne nennenswerte
# Verbesserung wird abgebrochen (dein "nach 3 Zyklen")
# Schwelle = um so viel muss sich der beste Wert mindestens
# verbessern, damit es als Verbesserung zaehlt
[Adaptiv]
Start=40
MutationProLoesung=2
Schrumpfung=0.85
MinPopulation=5
MaxGenerationen=50
Geduld=3
Schwelle=1.0
+82 -92
View File
@@ -3,6 +3,14 @@
Referenz fuer die Eingabe- und Ausgabedateien eines `platz`-Laufs, mit Beispielen aus
`work/test1/` und `work/test2/`.
Alle vier Dateien liegen unter dem mit `--indir <dir>` angegebenen Verzeichnis (z.B.
`work/test1/` oder `work/test2/`) unter festen Namen: `tische.ini`, `bestellung.json` als
Eingabe, `TischePersonen.txt` und `PersonenTische.csv` als Ausgabe. Beispielaufruf:
```bash
bin/platz.sh --indir work/test1
```
## Tischaufstellung: `tische.ini`
Ein INI-File mit einer Sektion pro Tisch. Sektionsname ist die Tisch-Id.
@@ -59,108 +67,90 @@ Werte wie `Nachbarliste` und `Koordinaten` werden mit `eval()` geladen (siehe
`Tische.laden()` in `libs/Strukturdaten.py`) — es steht also echter Python-Ausdruckscode im
File, keine reine INI-Syntax.
## Gaesteliste: `bestellung.xml`
## Gaesteliste: `bestellung.json`
Ein `<Bestellung>` mit mehreren `<Gruppe>`-Bloecken. Jede Gruppe enthaelt:
Ein JSON-Objekt mit dem Schluessel `"gruppen"`, einer Liste von Gruppen-Objekten. Jede
Gruppe enthaelt:
- ein oder mehrere `<Person>`-Elemente mit `<Vorname>`, `<Nachname>` und optionalem
`<Titel>`
- optional `<Anzahl>N</Anzahl>`, um die zuletzt beschriebene Person zu einer Sammelbuchung
von `N` (anonymen/gleichnamigen) Personen zu vervielfaeltigen
- optional `<Tisch>Id</Tisch>`, um die Gruppe als VIP-Gruppe fest an den angegebenen Tisch
zu binden (sie wird dann **nicht** vom GA platziert)
- `"personen"`: Liste von Personen-Objekten mit `"vorname"`, `"nachname"` und optionalem
`"titel"` (Pflicht: Vor- und Nachname)
- optional `"name"`: Anzeigename der Gruppe (z.B. `"Familie Huber"`); nur fuer Ausgabe und
Web-Anzeige, nicht fuer die Optimierung relevant
- optional `"anzahl"`: N, um **jede** Person der Gruppe zu einer Sammelbuchung von N
(gleichnamigen) Buchungen zu vervielfaeltigen — praktisch fuer anonyme Kontingente
- optional `"tisch"`: Tisch-Id, um die Gruppe als VIP-Gruppe fest an diesen Tisch zu binden
(sie wird dann **nicht** vom GA platziert)
XML-Kommentare (`<!-- ... -->`) sind erlaubt und werden beim Parsen ignoriert.
Geladen wird das File von `JSONConfig` in `libs/Strukturdaten.py` (Nachfolger des frueheren
`XMLConfig`; das alte `bestellung.xml`-Format wurde vollstaendig durch JSON abgeloest).
Die Datei sollte UTF-8 sein; ein evtl. vorhandenes BOM (Excel) wird geschluckt.
Minimalbeispiel mit Sammelbuchungen, aus `work/test1/bestellung.xml`:
Minimalbeispiel mit Sammelbuchungen, aus `work/test1/bestellung.json`:
```xml
<Bestellung>
<Gruppe>
<Person>
<Vorname>A</Vorname>
<Nachname>AA</Nachname>
<Titel>Dipl. Ing.</Titel>
</Person>
<Anzahl>10</Anzahl>
</Gruppe>
<Gruppe>
<Person>
<Vorname>B</Vorname>
<Nachname>BB</Nachname>
<Titel>Prof.</Titel>
</Person>
<Anzahl>4</Anzahl>
</Gruppe>
<Gruppe>
<Person>
<Vorname>C</Vorname>
<Nachname>CC</Nachname>
<Titel>Dr.</Titel>
</Person>
<Anzahl>5</Anzahl>
</Gruppe>
</Bestellung>
```json
{
"gruppen": [
{
"anzahl": 10,
"personen": [
{ "vorname": "A", "nachname": "AA", "titel": "Dipl. Ing." }
]
},
{
"anzahl": 4,
"personen": [
{ "vorname": "B", "nachname": "BB", "titel": "Prof." }
]
},
{
"anzahl": 5,
"personen": [
{ "vorname": "C", "nachname": "CC", "titel": "Dr." }
]
}
]
}
```
Umfangreicheres Beispiel mit benannten Personen und einer VIP-Gruppe, aus
`work/test2/bestellung.xml`:
Umfangreicheres Beispiel mit benannten Gruppen und einer VIP-Gruppe, aus
`work/test2/bestellung.json`:
```xml
<Bestellung>
<!-- einfache Gruppe aus drei Personen
mit festem Wunsch fuer einen Tisch-->
<Gruppe>
<Person>
<Vorname>Michael</Vorname>
<Nachname>Stangl</Nachname>
<Titel>Dipl. Ing.</Titel>
</Person>
<Person>
<Vorname>Magnus</Vorname>
<Nachname>Mueller</Nachname>
<Titel>Professor</Titel>
</Person>
<Person>
<Vorname>Bernd Robert</Vorname>
<Nachname>Hoehn</Nachname>
<Titel>Professor</Titel>
</Person>
<Tisch>1</Tisch>
</Gruppe>
<!-- einfache Gruppe aus zwei Personen -->
<Gruppe>
<Person>
<Vorname>Heinz</Vorname>
<Nachname>Bruegge</Nachname>
</Person>
<Person>
<Vorname>Hubert</Vorname>
<Nachname>K</Nachname>
</Person>
</Gruppe>
<!--Gruppe aus drei anonymen Personen-->
<Gruppe>
<Person>
<Vorname>Bestelli</Vorname>
<Nachname>Bloedkopf</Nachname>
</Person>
<Anzahl>3</Anzahl>
</Gruppe>
</Bestellung>
```json
{
"gruppen": [
{
"name": "einfache Gruppe aus drei Personen mit festem Wunsch fuer einen Tisch",
"tisch": 1,
"personen": [
{ "vorname": "Michael", "nachname": "Stangl", "titel": "Dipl. Ing." },
{ "vorname": "Magnus", "nachname": "Mueller", "titel": "Professor" },
{ "vorname": "Bernd Robert", "nachname": "Hoehn", "titel": "Professor" }
]
},
{
"name": "einfache Gruppe aus zwei Personen",
"personen": [
{ "vorname": "Heinz", "nachname": "Bruegge" },
{ "vorname": "Hubert", "nachname": "K" }
]
},
{
"name": "Gruppe aus drei anonymen Personen",
"anzahl": 3,
"personen": [
{ "vorname": "Bestelli", "nachname": "Bloedkopf" }
]
}
]
}
```
Die erste Gruppe hier ist per `<Tisch>1</Tisch>` fest an Tisch 1 gebunden (VIP-Gruppe); die
letzte Gruppe erzeugt ueber `<Anzahl>3</Anzahl>` drei gleichnamige "Bestelli Bloedkopf"
Buchungen.
Die erste Gruppe hier ist per `"tisch": 1` fest an Tisch 1 gebunden (VIP-Gruppe); die letzte
Gruppe erzeugt ueber `"anzahl": 3` drei gleichnamige "Bestelli Bloedkopf" Buchungen.
> Fuer den Web-Weg (Meilenstein 1) gibt es zusaetzlich einen CSV-Import (`libs/CSVConfig.py`,
> Spalten `Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl`) — inhaltlich aequivalent, nur
> flach statt verschachtelt.
## Ausgabe: `TischePersonen.txt`
+84
View File
@@ -0,0 +1,84 @@
# Dokumentation der Unittest-Szenarien
Die drei Testfaelle in `tests/test_sitzplatzverteilung.py` pruefen die Platzierungs- und
Trennungslogik von `Sitzplatzverteilung` (in `libs/Strukturdaten.py`) anhand konkreter,
handgebauter Tisch-/Gruppenkonfigurationen. Jeder Test schreibt zusaetzlich eine
SVG-Visualisierung nach `doc/images/` (erzeugt mit `Sitzplatzverteilung.alsSVG()`, das auch
ueber den `--tosvg`-Schalter von `bin/platz.bat`/`bin/platz.sh` erreichbar ist). Tische
werden darin als weisse Kreise dargestellt, Personen als farbige Kreise innerhalb ihres
Tischkreises; alle Personen derselben Gruppe haben dieselbe Farbe.
## Szenario 1: Drei Tische in einer Kette, drei Paare
`TestDreiTischeKettePaare` in `tests/test_sitzplatzverteilung.py`
- Drei Tische `T1-T2-T3` (Kette: T1 nur mit T2 benachbart, T3 nur mit T2 benachbart), je
2 Plaetze.
- Drei Gruppen zu je 2 Personen (Paare).
Da jeder Tisch exakt so viele Plaetze hat wie eine Gruppe Personen, passt jedes Paar
komplett an einen Tisch. Der Test prueft, dass keine Gruppe getrennt wird
(`GruppenTeilungGet(G) == 0` fuer alle drei Gruppen) und dass die optimale Wertigkeit
(`SV.value == 0`, keine Strafpunkte) erreicht wird.
![Drei Tische in einer Kette, drei Paare](images/drei_tische_kette_paare.svg)
## Szenario 2: Vier Tische in einer Linie, zwei Vierergruppen
`TestVierTischeLinieViergruppen` in `tests/test_sitzplatzverteilung.py`
- Vier Tische `T1-T2-T3-T4` in einer Linie (T1↔T2↔T3↔T4), je 2 Plaetze.
- Zwei Gruppen zu je 4 Personen.
Da kein Tisch 4 Plaetze hat, muss jede Vierergruppe auf zwei Tische aufgeteilt werden. Der
Test prueft, dass jede Gruppe genau einmal geteilt wird (`GruppenTeilungGet(G) == 1`) und
dass die beiden Teiltische pro Gruppe ein zusammenhaengendes Nachbarpaar bilden — entweder
`{T1,T2}` oder `{T3,T4}}`, nie ueber die mittlere Naht zwischen T2 und T3 hinweg vermischt.
Ausserdem sind am Ende alle vier Tische voll besetzt.
![Vier Tische in einer Linie, zwei Vierergruppen](images/vier_tische_linie_viergruppen.svg)
## Szenario 3: Sechs Tische im Kreis, vier Dreiergruppen
`TestSechsTischeKreisDreiergruppen` in `tests/test_sitzplatzverteilung.py`
- Sechs Tische `T1..T6`, im Kreis angeordnet (jeder Tisch hat genau zwei Nachbarn: z.B. T1
ist mit T2 und T6 benachbart), je 2 Plaetze.
- Vier Gruppen zu je 3 Personen (12 Personen auf 6×2 = 12 Plaetzen — exakt ausgelastet).
Da kein Tisch 3 Plaetze hat, muss jede Dreiergruppe auf zwei Tische aufgeteilt werden
(2+1). Der Test prueft zwei Arten von Eigenschaften:
- **Immer gueltig, unabhaengig vom Zufalls-Seed:** Bei exakt ausgelasteten 12 Plaetzen fuer
12 Personen bleibt keine andere Aufteilung uebrig — jede Gruppe wird also garantiert
genau einmal geteilt (`GruppenTeilungGet(G) == 1`), und am Ende sind alle sechs Tische
voll besetzt.
- **Nur mit dem hier fest gewaehlten Seed zusaetzlich beobachtet:** Die beiden Teiltische
jeder Gruppe sind tatsaechlich echte Nachbarn im Kreis. Das ist keine Garantie des
Algorithmus fuer jeden beliebigen Seed — bei sehr knapper Auslastung kann der
GA-Platzierungsfallback (`Sitzplatzverteilung.GruppeSetzen`, wenn `NachbarTische` keine
passenden Nachbarn mehr findet) auch nicht benachbarte Tische fuer die beiden Teile einer
Gruppe waehlen. Mit einem grossen Stichprobentest ueber viele Seeds trat das in gut zwei
Dritteln der Faelle auf; der im Test verwendete Seed wurde bewusst so gewaehlt, dass
zusaetzlich die Nachbarschaftseigenschaft zutrifft, um sie hier sichtbar zu machen.
Die `Koordinaten` der sechs Tische in diesem Test sind bewusst auf einem Kreis im
mathematischen Sinn angeordnet (Winkel gleichmaessig verteilt), damit auch die
SVG-Visualisierung die Kreisform erkennen laesst — die tatsaechliche Nachbarschaft, die der
Algorithmus fuer die Platzierung nutzt, kommt aber ausschliesslich aus der
`Nachbarliste`/`Nachbarn`-Angabe jedes Tisches, nicht aus den Koordinaten.
![Sechs Tische im Kreis, vier Dreiergruppen](images/sechs_tische_kreis_dreiergruppen.svg)
## Bilder neu erzeugen
Die drei SVGs in `doc/images/` werden beim Ausfuehren der Testsuite automatisch neu
geschrieben:
```bash
bin/run_tests.sh
```
```bat
bin\run_tests.bat
```
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="251.2" height="90.4" viewBox="0 0 251.2 90.4">
<rect width="100%" height="100%" fill="white"/>
<circle cx="45.2" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname1 Nachname1" cx="45.2" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname1 Nachname1 — Gruppe 1</title></circle>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname2 Nachname2" cx="45.2" cy="58.4" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname2 Nachname2 — Gruppe 1</title></circle>
<ellipse cx="45.2" cy="45.2" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="45.2" y="40.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="45.2" y="53.6" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="125.6" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname3 Nachname3" cx="125.6" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname3 Nachname3 — Gruppe 2</title></circle>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname4 Nachname4" cx="125.6" cy="58.4" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname4 Nachname4 — Gruppe 2</title></circle>
<ellipse cx="125.6" cy="45.2" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="125.6" y="40.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="125.6" y="53.6" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="206" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="3" data-gruppe="Gruppe 3" data-name="Vorname5 Nachname5" cx="206" cy="32" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Vorname5 Nachname5 — Gruppe 3</title></circle>
<circle class="person" data-gid="3" data-gruppe="Gruppe 3" data-name="Vorname6 Nachname6" cx="206" cy="58.4" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Vorname6 Nachname6 — Gruppe 3</title></circle>
<ellipse cx="206" cy="45.2" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="206" y="40.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="206" y="53.6" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="251.2" height="412" viewBox="0 0 251.2 412">
<rect width="100%" height="100%" fill="white"/>
<polyline points="125.6,353.6 206,286.4" fill="none" stroke="#f58231" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="125.6,380 45.2,286.4" fill="none" stroke="#4363d8" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="206,125.6 125.6,32" fill="none" stroke="#e6194b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="125.6,58.4 45.2,125.6" fill="none" stroke="#3cb44b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<circle cx="125.6" cy="366.8" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="4" data-gruppe="Gruppe 4" data-name="Vorname10 Nachname10" cx="125.6" cy="353.6" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Vorname10 Nachname10 — Gruppe 4</title></circle>
<circle class="person" data-gid="3" data-gruppe="Gruppe 3" data-name="Vorname7 Nachname7" cx="125.6" cy="380" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Vorname7 Nachname7 — Gruppe 3</title></circle>
<ellipse cx="125.6" cy="366.8" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="125.6" y="362" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="125.6" y="375.2" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="206" cy="286.4" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="4" data-gruppe="Gruppe 4" data-name="Vorname11 Nachname11" cx="206" cy="273.2" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Vorname11 Nachname11 — Gruppe 4</title></circle>
<circle class="person" data-gid="4" data-gruppe="Gruppe 4" data-name="Vorname12 Nachname12" cx="206" cy="299.6" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Vorname12 Nachname12 — Gruppe 4</title></circle>
<ellipse cx="206" cy="286.4" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="206" y="281.6" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="206" y="294.8" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="206" cy="125.6" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname2 Nachname2" cx="206" cy="112.4" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname2 Nachname2 — Gruppe 1</title></circle>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname3 Nachname3" cx="206" cy="138.8" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname3 Nachname3 — Gruppe 1</title></circle>
<ellipse cx="206" cy="125.6" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="206" y="120.8" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="206" y="134" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="125.6" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname1 Nachname1" cx="125.6" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname1 Nachname1 — Gruppe 1</title></circle>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname4 Nachname4" cx="125.6" cy="58.4" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname4 Nachname4 — Gruppe 2</title></circle>
<ellipse cx="125.6" cy="45.2" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="125.6" y="40.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="125.6" y="53.6" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="45.2" cy="125.6" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname5 Nachname5" cx="45.2" cy="112.4" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname5 Nachname5 — Gruppe 2</title></circle>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname6 Nachname6" cx="45.2" cy="138.8" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname6 Nachname6 — Gruppe 2</title></circle>
<ellipse cx="45.2" cy="125.6" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="45.2" y="120.8" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="45.2" y="134" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="45.2" cy="286.4" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="3" data-gruppe="Gruppe 3" data-name="Vorname8 Nachname8" cx="45.2" cy="273.2" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Vorname8 Nachname8 — Gruppe 3</title></circle>
<circle class="person" data-gid="3" data-gruppe="Gruppe 3" data-name="Vorname9 Nachname9" cx="45.2" cy="299.6" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Vorname9 Nachname9 — Gruppe 3</title></circle>
<ellipse cx="45.2" cy="286.4" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="45.2" y="281.6" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="45.2" y="294.8" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="340" viewBox="0 0 1200 340" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="600" y="30" text-anchor="middle" font-size="16" fill="#333">Abstammung der Loesungen (Mutationsbaum)</text>
<line x1="60.0" y1="60.0" x2="60.0" y2="150.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="420.0" y1="60.0" x2="214.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="780.0" y1="60.0" x2="368.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1140.0" y1="60.0" x2="522.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="60.0" x2="677.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="420.0" y1="60.0" x2="831.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="780.0" y1="60.0" x2="985.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1140.0" y1="60.0" x2="1140.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="150.0" x2="60.0" y2="240.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="214.3" y1="150.0" x2="214.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="368.6" y1="150.0" x2="368.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="522.9" y1="150.0" x2="522.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="150.0" x2="677.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="214.3" y1="150.0" x2="831.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="368.6" y1="150.0" x2="985.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="522.9" y1="150.0" x2="1140.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<circle cx="60.0" cy="60.0" r="7" fill="#c83232" stroke="#c04040" stroke-width="2"><title>Id 1, Wert -100.0</title></circle>
<circle cx="420.0" cy="60.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 2, Wert -100.0</title></circle>
<circle cx="780.0" cy="60.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 3, Wert -100.0</title></circle>
<circle cx="1140.0" cy="60.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 4, Wert -100.0</title></circle>
<circle cx="60.0" cy="150.0" r="7" fill="#785f41" stroke="#c04040" stroke-width="2"><title>Id 5, Wert -99.0</title></circle>
<circle cx="214.3" cy="150.0" r="5" fill="#785f41" stroke="#333" stroke-width="0.5"><title>Id 6, Wert -99.0</title></circle>
<circle cx="368.6" cy="150.0" r="5" fill="#785f41" stroke="#333" stroke-width="0.5"><title>Id 7, Wert -99.0</title></circle>
<circle cx="522.9" cy="150.0" r="5" fill="#785f41" stroke="#333" stroke-width="0.5"><title>Id 8, Wert -99.0</title></circle>
<circle cx="677.1" cy="150.0" r="5" fill="#785f41" stroke="#333" stroke-width="0.5"><title>Id 9, Wert -99.0</title></circle>
<circle cx="831.4" cy="150.0" r="5" fill="#785f41" stroke="#333" stroke-width="0.5"><title>Id 10, Wert -99.0</title></circle>
<circle cx="985.7" cy="150.0" r="5" fill="#785f41" stroke="#333" stroke-width="0.5"><title>Id 11, Wert -99.0</title></circle>
<circle cx="1140.0" cy="150.0" r="5" fill="#785f41" stroke="#333" stroke-width="0.5"><title>Id 12, Wert -99.0</title></circle>
<circle cx="60.0" cy="240.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 13, Wert -98.0</title></circle>
<circle cx="214.3" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 14, Wert -98.0</title></circle>
<circle cx="368.6" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 15, Wert -98.0</title></circle>
<circle cx="522.9" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 16, Wert -98.0</title></circle>
<circle cx="677.1" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 17, Wert -98.0</title></circle>
<circle cx="831.4" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 18, Wert -98.0</title></circle>
<circle cx="985.7" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 19, Wert -98.0</title></circle>
<circle cx="1140.0" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 20, Wert -98.0</title></circle>
<text x="60.0" y="262.0" text-anchor="middle" font-size="12" font-weight="bold" fill="#c04040">13</text>
<text x="48" y="64.0" text-anchor="end" font-size="11" fill="#666">Gen 0</text>
<text x="48" y="154.0" text-anchor="end" font-size="11" fill="#666">Gen 1</text>
<text x="48" y="244.0" text-anchor="end" font-size="11" fill="#666">Gen 2</text>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="650" viewBox="0 0 900 650" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="450" y="30" text-anchor="middle" font-size="16" fill="#333">Entwicklung der Loesungsfindung</text>
<line x1="60" y1="60" x2="60" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="394.0" text-anchor="end" font-size="11" fill="#666">-200</text>
<line x1="60" y1="324.0" x2="840" y2="324.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="328.0" text-anchor="end" font-size="11" fill="#666">-168</text>
<line x1="60" y1="258.0" x2="840" y2="258.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="262.0" text-anchor="end" font-size="11" fill="#666">-136</text>
<line x1="60" y1="192.0" x2="840" y2="192.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="196.0" text-anchor="end" font-size="11" fill="#666">-104</text>
<line x1="60" y1="126.0" x2="840" y2="126.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="130.0" text-anchor="end" font-size="11" fill="#666">-72</text>
<line x1="60" y1="60.0" x2="840" y2="60.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="64.0" text-anchor="end" font-size="11" fill="#666">-40</text>
<text x="18" y="225.0" text-anchor="middle" font-size="12" fill="#333" transform="rotate(-90 18 225.0)">Wertigkeit (hoeher = besser)</text>
<polyline points="60.0,163.1 450.0,121.9 840.0,60.0" fill="none" stroke="#2f6f4f" stroke-width="2"/>
<polyline points="60.0,280.0 450.0,142.5 840.0,90.9" fill="none" stroke="#c08a2d" stroke-width="2"/>
<polyline points="60.0,390.0 450.0,163.1 840.0,121.9" fill="none" stroke="#a03030" stroke-width="2"/>
<line x1="680" y1="70" x2="704" y2="70" stroke="#2f6f4f" stroke-width="2"/>
<text x="710" y="74" font-size="11" fill="#333">beste Loesung</text>
<line x1="680" y1="88" x2="704" y2="88" stroke="#c08a2d" stroke-width="2"/>
<text x="710" y="92" font-size="11" fill="#333">Durchschnitt</text>
<line x1="680" y1="106" x2="704" y2="106" stroke="#a03030" stroke-width="2"/>
<text x="710" y="110" font-size="11" fill="#333">schlechteste Loesung</text>
<text x="450" y="428.0" text-anchor="middle" font-size="13" fill="#333">Anzahl erzeugter Verteilungen im Pool</text>
<line x1="60" y1="440.0" x2="60" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="594.0" text-anchor="end" font-size="11" fill="#666">0</text>
<line x1="60" y1="540.0" x2="840" y2="540.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="544.0" text-anchor="end" font-size="11" fill="#666">1</text>
<line x1="60" y1="440.0" x2="840" y2="440.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="444.0" text-anchor="end" font-size="11" fill="#666">3</text>
<polyline points="60.0,440.0 450.0,490.0 840.0,490.0" fill="none" stroke="#4060a0" stroke-width="2"/>
<text x="60.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">e</text>
<text x="450.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="840.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="450" y="638" text-anchor="middle" font-size="12" fill="#333">Zyklus-Aktion (Zeit)</text>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="331.6" height="90.4" viewBox="0 0 331.6 90.4">
<rect width="100%" height="100%" fill="white"/>
<polyline points="45.2,45.2 125.6,45.2" fill="none" stroke="#3cb44b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="206,45.2 286.4,45.2" fill="none" stroke="#e6194b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<circle cx="45.2" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname8 Nachname8" cx="45.2" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname8 Nachname8 — Gruppe 2</title></circle>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname5 Nachname5" cx="45.2" cy="58.4" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname5 Nachname5 — Gruppe 2</title></circle>
<ellipse cx="45.2" cy="45.2" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="45.2" y="40.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="45.2" y="53.6" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="125.6" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname6 Nachname6" cx="125.6" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname6 Nachname6 — Gruppe 2</title></circle>
<circle class="person" data-gid="2" data-gruppe="Gruppe 2" data-name="Vorname7 Nachname7" cx="125.6" cy="58.4" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Vorname7 Nachname7 — Gruppe 2</title></circle>
<ellipse cx="125.6" cy="45.2" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="125.6" y="40.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="125.6" y="53.6" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="206" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname3 Nachname3" cx="206" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname3 Nachname3 — Gruppe 1</title></circle>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname4 Nachname4" cx="206" cy="58.4" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname4 Nachname4 — Gruppe 1</title></circle>
<ellipse cx="206" cy="45.2" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="206" y="40.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="206" y="53.6" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
<circle cx="286.4" cy="45.2" r="35.2" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname1 Nachname1" cx="286.4" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname1 Nachname1 — Gruppe 1</title></circle>
<circle class="person" data-gid="1" data-gruppe="Gruppe 1" data-name="Vorname2 Nachname2" cx="286.4" cy="58.4" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Vorname2 Nachname2 — Gruppe 1</title></circle>
<ellipse cx="286.4" cy="45.2" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="286.4" y="40.4" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">0</text>
<text x="286.4" y="53.6" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">2 Pl.</text>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

+599
View File
@@ -0,0 +1,599 @@
# Platz als Web-Dienst — Roadmap
*Sitzplatz-Optimierung für Hochzeiten & Events als SaaS*
---
## Status Quo (verifiziert 2026-07-09)
Der bestehende Python-Kern verarbeitet **bereits vollständig echte Personendaten**:
- `work/test2/bestellung.xml` enthält reale Einzelpersonen (Name, Vorname, Titel), eine
VIP-Gruppe mit fest zugewiesenem Tisch, und eine anonyme Sammelbuchung — alle Pfade
wurden end-to-end getestet und funktionieren korrekt.
- Output (`TischePersonen.txt`, `PersonenTische.csv`, `Sitzplatzverteilung.svg`) enthält
korrekt durchgereichte Namen inkl. Titel.
**Das ist also kein offener Kern-Bug** — die Lücke liegt woanders:
| Was schon geht | Was fehlt für den Web-Dienst |
|---|---|
| Personen mit Namen/Titel/Gruppe verarbeiten | Web-Formular / CSV-Import statt Hand-XML |
| GA erzeugt eine gute Sitzordnung | Mehrere Varianten parallel vergleichen |
| SVG-Visualisierung einer Verteilung | Interaktiver Tisch-Editor (Drag & Drop) |
| CLI + Dateisystem (`work/<name>/`) | Multi-User, Projekte, Accounts, DB |
| — | Bezahlmodell, DSGVO-Konformität |
---
## Marktübersicht — wer bietet das schon an? (recherchiert 2026-07-09)
Der Markt für Sitzplan-/Seating-Tools für Hochzeiten und Events ist bereits gut besetzt.
Wichtigste Erkenntnis: **die meisten Tools sind reine Drag-&-Drop-Editoren ohne
Optimierungsalgorithmus** — der Nutzer platziert Gäste manuell selbst. Ein kleiner Teil
nutzt tatsächlich einen Optimierungsalgorithmus wie unser Programm (genetischer Algorithmus
mit Punktebewertung), das ist also der eigentliche Differenzierungspunkt, nicht der
Drag-&-Drop-Editor an sich (den bieten praktisch alle).
### Reine Drag-&-Drop-Tools (kein Optimierungsalgorithmus, nur manuelle Platzierung)
| Anbieter | Markt | Modell | Besonderheit |
|---|---|---|---|
| [WeddingWire Seating Chart Tool](https://www.weddingwire.com/wedding-planning/wedding-seating-tables.html) | US, Hochzeit | kostenlos | Teil einer grossen Hochzeitsplaner-Plattform, Gästelisten-Import |
| [Wedding Studio](https://www.wedding.studio/seating-chart) | US, Hochzeit | kostenlos, kein Login | 7 Vorlagen, unbegrenzte Gäste |
| [Zola Seating Chart](https://www.zola.com/wedding-planning/seating-chart) | US, Hochzeit | kostenlos (Teil von Zola-Ökosystem) | RSVP-Integration |
| [Wedibox](https://www.wedibox.com/tools/wedding-seating-chart-maker) | US, Hochzeit | kostenlos | Rund-/Rechtecktische, 416 Plätze konfigurierbar |
| [SeatPlan.io](https://seatplan.io/) | International | Freemium, Designer $8 einmalig, Event Manager $25/Monat | CSV-Import, Echtzeit-Kollaboration, PWA |
| [Simplify Tables](https://www.simplifytables.com/) | International | 30 Gäste kostenlos, danach $9.99/Event | Sitzplan per QR-Code mit Gästen teilen |
| [Seating Chart Creator](https://seatingchartcreator.com/) | International | 50 Gäste/5 Tische kostenlos, danach bezahlt | — |
| [Canva Seating Chart Maker](https://www.canva.com/create/seating-charts/) | International | Freemium (Teil von Canva) | Design-fokussiert, keine Optimierung |
| [Find Your Seat](https://www.findyourseat.de/) | Deutschland | 20 Gäste kostenlos | RSVP-Verwaltung, deutschsprachig |
| [Hochzeit Sitzplaner](https://hochzeitssitzplaner.de/) | Deutschland | kostenlos | einfaches deutsches Tool |
| [Ja.de Sitzordnung-Planer](https://www.ja.de/hochzeits-planung/Planer-fuer-die-Sitzordnung_seating) | Deutschland | kostenlos (Teil von ja.de-Portal) | U-/E-/T-Form-Tischanordnungen |
### Tools mit echtem Optimierungsalgorithmus (direkteste Konkurrenz zu unserem GA-Ansatz)
| Anbieter | Algorithmus | Modell | Bemerkung |
|---|---|---|---|
| [PerfectTablePlan](https://www.perfecttableplan.com/) | **Genetischer Algorithmus mit Punktebewertung** — methodisch praktisch identisch zu unserem Ansatz (`Strafliste`/`Sitzplatzverteilung`) | Desktop-Software, $29.95 einmalig pro Nutzer:in | Erklärt selbst öffentlich, [warum GA statt Brute-Force](https://www.perfecttableplan.com/html/genetic_algorithm.html) nötig ist (kombinatorische Explosion) — deckt sich mit unserer eigenen Begründung. Kein Web-Dienst, sondern lokale Windows/Mac-App. |
| [tableplan.io](https://www.tableplan.io/) | vermutlich verwandt/Web-Ableger von PerfectTablePlan | Abo-basiert | Web-Variante desselben Anbieters |
| [Automated Seating](https://www.automatedseating.com/) | automatisierte Zuordnung | — | spezialisiert auf automatische Zuordnung |
| [Social Tables / Cvent Event Diagramming](https://www.socialtables.com/) | eher Enterprise-Event-Diagramming als GA-Optimierung | Enterprise/B2B | Fokus auf grosse Konferenzen/Events, nicht speziell Hochzeit |
| GitHub: [meganstiles/Seating_Chart](https://github.com/meganstiles/Seating_Chart) | Genetischer Algorithmus (Studienprojekt) | Open Source, kein Produkt | Bestätigt: GA-Ansatz für Hochzeits-Sitzpläne ist ein bekanntes, dokumentiertes Muster, nicht nur unsere Idee |
### Einordnung für die eigene Positionierung
- **Der GA-Ansatz selbst ist kein Alleinstellungsmerkmal** — PerfectTablePlan macht das
methodisch sehr ähnlich und ist seit Jahren am Markt etabliert (Desktop, kein Web-SaaS).
Das validiert aber den Ansatz: ein etablierter Wettbewerber löst dasselbe Problem mit
derselben Technik.
- **Lücke am Markt:** ein **Web-natives SaaS mit echtem Optimierungsalgorithmus** (nicht
nur Drag & Drop) und **europäischem/deutschem Fokus inkl. DSGVO-Hosting** scheint es
aktuell nicht zu geben — die deutschen Anbieter (Find Your Seat, Hochzeit Sitzplaner,
Ja.de) bieten nur manuelle Drag-&-Drop-Tools, die Optimierungs-Tools (PerfectTablePlan,
tableplan.io) sind englischsprachig und teils Desktop-only.
- **Eigene Stärken aus dem bestehenden Code**, die sich als Verkaufsargument eignen:
VIP-Fixplätze (`<Tisch>`-Bindung), differenzierte Strafpunkte für Gruppentrennung nach
Gruppengrösse (`Strafliste.GruppenTrennen`), Nachbartisch-Bewertung
(`nichtNachbar`-Strafe) — das geht über simples "möglichst wenig Trennungen" hinaus und
ist detaillierter als das, was in den öffentlichen Beschreibungen der Konkurrenz
auftaucht.
- Preise der Konkurrenz als Orientierung für M4: kostenlose Kontingente liegen meist bei
2050 Gästen, Einmalzahlungen bei $830, Abo-Modelle bei ~$25/Monat für
professionelle Nutzer:innen (Event-Planer:innen, nicht Privatpersonen).
- Referenz-Preistabelle von [automatedseating.com](https://www.automatedseating.com/)
(Abo-Modell, **nicht** unser Modell — siehe Konzeptentscheidungen unten):
| Plan | Description | Price | Features |
|---|---|---:|---|
| Free | Perfect for trying out | $0/month | 1 event; Up to 40 guests |
| Starter | Perfect for occasional events | $20/month | 1 event; Max 300 guests; Export PDF and Excel |
| Pro | Unlimited events and no guest limit | $40/month | Unlimited events; Unlimited guests; Export to PDF and Excel |
| Enterprise | Tailored solutions | Custom | Everything in Pro; Unlimited guests; Custom features; White-labeled solutions and exports; On-premise option |
---
## Konzeptentscheidungen (festgelegt 2026-07-10)
Die folgenden Grundsatzfragen sind entschieden und gelten für alle Meilensteine:
1. **Zielgruppe für den Launch: Brautpaare (B2C, DACH).** Deutschsprachige UI,
niedrigschwellige Preise, DSGVO/deutsches Hosting als zentrales Verkaufsargument —
passt zur identifizierten Marktlücke. B2B (Wedding-Planner, Locations) bleibt eine
spätere Ausbaustufe (siehe M4), verwässert aber nicht den MVP-Fokus.
2. **Bezahlmodell: Einmalzahlung pro Event, kein Abo.** Der frühere Widerspruch zur
Abo-Preistabelle (automatedseating.com-Vorbild, siehe Marktübersicht) ist damit
aufgelöst: die Tabelle dient nur noch als Konkurrenz-Referenz. Ein Abo passt nicht
zum B2C-Nutzungsmuster (einmalige Hochzeit, 23 Monate Planungszeitraum).
3. **Payment über einen Merchant of Record** (Paddle oder Lemon Squeezy statt
Stripe/Mollie direkt): Der MoR tritt als Verkäufer auf und übernimmt EU-VAT/OSS,
Rechnungsstellung und Steuer-Compliance komplett — bei etwas höheren Gebühren
(~5 %) minimaler Verwaltungsaufwand, ideal für Solo-Betrieb.
4. **Free-Tier: bis 40 Gäste, 1 Event**, Export mit Wasserzeichen. (Ersetzt die ältere
"z.B. 30"-Angabe in M4.)
5. **Konkrete Preispunkte: bewusst noch offen.** Rahmen: Einmalzahlung im Korridor
~1545 €, ein oder zwei Stufen; Festlegung erst bei M4-Start per Test/Umfrage.
6. **Hosting: Hetzner** (deutsches Unternehmen, Rechenzentren in DE/FI, AVV vorhanden,
Cloud-VPS ab ~5 €/Monat). Deckt das Differenzierungsmerkmal "DSGVO-Hosting in
Deutschland" ab; Single-Server-MVP (M1) und spätere Skalierung möglich.
7. **Rechtsform: Betrieb über die bestehende MiSta GmbH** (steht im Impressum) — keine
Neugründung nötig, Haftungsbegrenzung besteht damit ab Tag 1. Falls der Dienst gut
läuft, kann später eine eigene GmbH aus der Holding ausgegründet werden. Die
Namensfrage (Produktname/Domain) bleibt als M0-Punkt offen.
8. **M1 wird zu zweit parallel entwickelt** (Frontend/Backend-Split): eine Person
Backend-API + CSV-Import, eine Person Tisch-Editor. Verkürzt M1 entsprechend der
Parallelisierungs-Option aus der Gesamtschätzung.
9. **App-Store-Präsenz erst nach M4:** Die PWA-Fähigkeit (Manifest, Service Worker,
Touch, responsive) wird in M1 von Anfang an mitgebaut, der Capacitor-Store-Wrapper
aber erst nach der Monetarisierung angegangen — spart Store-Gebühren/Review-Aufwand
in der MVP-Phase; Gäste kommen ohnehin per QR-Link ohne Store-Installation.
10. **Personen-Vorlieben ("wen mag X nicht / besonders gern") kommen ins Backlog
(M4+):** Die im Gäste-Screen skizzierten CSV-Vorlieben-Spalten erfordern eine echte
Kern-Erweiterung der `Strafliste` um Personenpaar-Regeln. Erst Kernprodukt
validieren; danach als Premium-Feature zum Event-Pass denkbar. Das CSV-Format aus
M1 sieht die Spalten bereits vor (werden bis dahin ignoriert), damit später kein
Formatbruch nötig ist.
11. **Produktname: Zwei-Marken-Strategie** (festgelegt 2026-07-10):
- **Deutschland (Hauptmarkt B2C): "Sitz & Platz"** — Wortspiel mit den
Hundekommandos, kurz und merkfähig. Domains `sitzundplatz.de` und
`sitzundplatz.com` waren zum Prüfzeitpunkt frei.
- **Europa/international: "Sitzwunder" / "SeatWonder"** — ein Markenkern, je
Markt übersetzt. Domains `sitzwunder.de`, `sitzwunder.com`, `seatwonder.de`
und `seatwonder.com` waren zum Prüfzeitpunkt frei. "Sitzwunder" wird bisher
nur generisch für Sitzmöbel verwendet, ein Markenauftritt existiert nicht.
- Das englische Pendant des Hundekommando-Witzes ("Sit & Stay") ist als Domain
vergeben (Pet-Branche) — daher international SeatWonder statt einer
1:1-Übersetzung von Sitz & Platz.
- Geprüfte Alternativen (frei, als Fallback notiert): Platzharmonie (.de/.com),
Sitzfee (.de/.com), Tafelplan (.de — Nähe zu tableplan.io), Tafelwunder,
Platzzauber, Platzmagie; englisch: theseatinggame.com, seatwhisperer.com,
seatedeverafter.com, mindtheseat.com, seatingsorted.com. Claim-/Kampagnen-Ideen:
"Wo sitzt Tante Erna?" (wositzttanteerna.de frei), "nie wieder Reise nach
Jerusalem". Naheliegende Namen (sitzplan.de, platzplan.de, sitzordnung.de, …)
sind sämtlich vergeben.
---
## Meilenstein 0 — Fundament (kein neues Feature, Vorbereitung)
**Ziel:** Der bestehende Kern läuft stabil, testbar und ist bereit für eine API-Hülle.
- [x] Python 2 → 3 Migration (bereits erledigt)
- [x] Unittest-Suite mit Kernszenarien (bereits erledigt)
- [x] `Farm` erweitern: `TopN()` statt nur `Bester()` — Grundlage für "mehrere Varianten"
später. Umgesetzt in `libs/ga.py` (`Farm.TopN(n)`: die `n` besten Lösungen absteigend,
geclamped auf `[0, len(Pool)]`).
- [x] Determinismus-Option: `random.seed()` als Parameter durchreichen, damit ein Ergebnis
bei Bedarf reproduzierbar ist (Support-Anfragen: "warum sitzt Tante Erna da?").
Umgesetzt als `--seed <int>` in `libs/platz.py`. **Wichtig:** der RNG-Seed allein
reichte nicht — `Person` hasht im `set()` einer `Gruppe` sonst über `id()`
(Speicheradresse), wodurch `set.pop()`-Reihenfolge in `Gruppe.teilen()` pro Prozess
variierte. Behoben durch Id-basiertes `__hash__`/`__eq__` an `Person`
(`libs/Strukturdaten.py`); Integer-Ids sind zudem `PYTHONHASHSEED`-unabhängig. Auf
`work/hochzeit` verifiziert: gleicher Seed → bytegleicher Plan, anderer Seed → abweichend.
- [x] Rechtsform geklärt: Betrieb über die bestehende **MiSta GmbH** (Impressum), keine
Neugründung — Ausgründung aus der Holding erst bei Erfolg (Konzeptentscheidung Nr. 7)
- [x] Namensfrage geklärt: **"Sitz & Platz"** für Deutschland, **Sitzwunder/SeatWonder**
für Europa/international (Konzeptentscheidung Nr. 11; Kandidaten-Recherche und
Domain-Verfügbarkeit geprüft 2026-07-10)
- [ ] Domains zeitnah registrieren (alle am 2026-07-10 frei — Verfügbarkeit ist
flüchtig, nicht bis M4 warten): `sitzundplatz.de`, `sitzundplatz.com`,
`sitzwunder.de`, `sitzwunder.com`, `seatwonder.de`, `seatwonder.com`
- [ ] Markenregister-Check auf "Sitz & Platz" und "Sitzwunder"/"SeatWonder" in den
relevanten Klassen (Software/SaaS, Kl. 9/42): DPMA (dpma.de-Registerauskunft)
für Deutschland, EUIPO (eSearch) für die EU-weite Variante — bevor Geld in
Branding fließt
**Aufwand:** ~1 Woche. **Kein Nutzer sieht das noch.**
---
## Meilenstein 1 — MVP: Single-User Web-Tool, keine Accounts
**Ziel:** Eine Person kann übers Web eine Hochzeit planen, ohne Login. Ergebnis: PDF/SVG-Export.
Session-basiert, nichts wird dauerhaft gespeichert (schont Datenschutz-Aufwand in dieser Phase).
- [x] REST-API um den bestehenden Kern (FastAPI) — umgesetzt in `web/main.py`,
Start per `bin/run_web.bat`/`.sh` (uvicorn --reload, Port 8000), Swagger unter `/docs`
- `POST /sitzung` — legt eine Arbeits-Session an (in-memory, TTL 24h)
- `POST /sitzung/{id}/tische` — Tisch-Layout als JSON (Ersatz für `tische.ini`);
Nachbarliste wird aus räumlicher Nähe der Koordinaten abgeleitet
- `POST /sitzung/{id}/personen` — CSV-Upload (Ersatz für `bestellung.xml`)
- `POST /sitzung/{id}/berechnen` — startet die GA-Optimierung (jeder Aufruf = neue Variante)
- `GET /sitzung/{id}/ergebnis` + `GET /sitzung/{id}/ergebnis.svg` — Ergebnis als JSON/SVG
- [x] **CSV-Format definiert und Parser gebaut**`libs/CSVConfig.py` (Adapter analog
`XMLConfig`): Spalten `Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl`; `Tisch` = VIP-
Fixplatz, `Anzahl` = Sammelbuchungs-Expansion, leere `Gruppe` = Einzelgast;
`MagNicht`/`MagGern` werden akzeptiert aber noch ignoriert (Konzeptentscheidung Nr. 10)
- [x] Einfache Browser-Testoberfläche (`web/static/index.html`): Tisch-Tabelle mit
Presets, CSV-Textfeld/-Upload, Berechnen-Button, Kennzahlen + SVG-Anzeige —
Zwischenschritt, wird durch den Konva-Tisch-Editor (unten) abgelöst
- [x] **Interaktiver Tisch-Editor** (Frontend): Kreise per Drag & Drop platzieren,
Kapazität einstellen (+//Direkteingabe), Tische hinzufügen/löschen, Nachbarschaft
live aus räumlicher Nähe abgeleitet (gleiche Radius-Logik wie `_NachbarnAbleiten`
im Backend, Radius per Slider). Umgesetzt als `web/static/editor.html`
**buildfrei, Inline-SVG + Vanilla-JS** statt React/Konva, weil das bestehende
Frontend keine Build-Toolchain (npm/package.json) hat; das State-Modell
(`{id, plaetze, x, y}`) ist dasselbe wie für eine spätere Konva-Portierung.
Backend um `GET /sitzung/{id}/tische` (Layout-Round-Trip) ergänzt, Session wird
per `localStorage` mit der Testoberfläche geteilt. Nebenbei behoben: fehlender
`import configparser` in `web/main.py` (der `/tische-datei`-Upload wäre sonst mit
`NameError` abgestürzt).
- Baut direkt auf `alsSVG()`-Geometrie auf (Radius-Berechnung ist bereits da)
- [x] **Undo/Redo** im Editor: Snapshot-History (Stapel je Vor-Zustand von `state.tische`),
ein Drag zählt als ein Schritt; Tastatur `Strg+Z` / `Strg+Y` (bzw. `Strg+Shift+Z`),
`Entf` löscht den ausgewählten Tisch. "Variante neu berechnen" liegt bereits als
wiederholter `POST .../berechnen` in der Testoberfläche vor (jeder Klick = neue Variante).
- [ ] Hosting: einfacher Single-Server-Betrieb bei **Hetzner** reicht (Konzeptentscheidung
Nr. 6 — kein Kubernetes-Overkill für MVP)
**Aufwand:** ~68 Wochen für 1 Entwickler:in (Backend-API + einfaches Frontend).
Beschlossen ist die Umsetzung **zu zweit parallel** (Konzeptentscheidung Nr. 8):
Backend-API + CSV-Import und Tisch-Editor laufen gleichzeitig, realistisch also
~45 Wochen Kalenderzeit.
**Rechtlich:** Solange keine Daten dauerhaft gespeichert werden (nur Session-Storage,
TTL von z.B. 24h), ist der DSGVO-Aufwand überschaubar (kein Account = kein
Personenbezug zum Betreiber über die Sitzung hinaus). Trotzdem: Auftragsverarbeitungsvertrag
mit Hosting-Provider und eine Datenschutzerklärung sind Pflicht, sobald IP-Adressen
verarbeitet werden (was bei jedem Webserver der Fall ist).
---
## Meilenstein 2 — Varianten-Generierung für größere Säle
**Ziel:** Nutzer bekommt mehrere Vorschläge statt einer festen Lösung, kann vergleichen.
- [x] `Farm.TopN(n)` nutzen, um z.B. 35 unterschiedliche gute Lösungen zurückzugeben:
`POST /berechnen?varianten=N` (15, Default 3) nimmt `TopN` über den ganzen Endpool
und dedupliziert über eine Sitzordnungs-Signatur (`frozenset` aus Tisch-Id ×
Personen-Ids), damit Mutations-Verwandte mit identischer Sitzordnung nicht als
"Varianten" zählen. Liefert der Pool weniger unterschiedliche Sitzordnungen, kommen
weniger zurück; ein weiterer Berechnen-Klick startet einen frischen Lauf.
Seed-parallele Läufe für noch mehr Diversität ("ggf.") waren nicht nötig —
ein Lauf liefert im Test bereits 3 paarweise verschiedene Varianten.
`GET /ergebnis.svg?variante=k` rendert jede Variante einzeln.
- [x] Vergleichsansicht im Frontend: Varianten-Karten nebeneinander mit Kennzahlen
(Wertigkeit, getrennte Gruppen + Teilungen gesamt, allein sitzende Personen —
letzteres via `LeuteAllein()`, zählt nur Personen aus mehrköpfigen Gruppen ohne
Gruppenmitglied am Tisch); Klick auf eine Karte schaltet Tische-/Gruppen-Tabellen
und den SVG-Raumplan auf die Variante um.
- [x] Performance: Lasttest erledigt (2026-07-12) — `work/innenhoefe` (300 Gäste,
88 Tische) rechnet mit dem **Adaptiv**-Profil (Web-Default) in ~1,71,9 s
(57 Generationen, inkl. Python-Start), Easy in ~0,3 s. Beides weit unter der
5-s-Schwelle → `Zyklus`-Parameter-Kopplung an die Problemgröße ist **nicht nötig**;
erst wieder prüfen, falls Zyklen deutlich vergrößert werden (siehe Risiko Nr. 2).
- [x] Optional: Hintergrund-Job-Queue (z.B. Celery/RQ), falls Berechnung >5s dauert —
**entfällt nach dem Lasttest** (s.o.): Adaptiv bleibt bei ~2 s, der Webserver
blockiert nicht spürbar. Entscheidung dokumentiert, bei Bedarf reaktivierbar.
**Tech-Debt / Modernisierung (Code-Review 2026-07-11):** Beim Umbau bereits erledigt sind
`eval()``ast.literal_eval` (bzw. ein sicherer Mini-Auswerter für die String-Ausdrücke
in `zyklus.cfg`) und `defaultdict(set)` in `Plaetze`. Bewusst *nicht* umgesetzt, für M2 zu
prüfen: **GA-Kern auf [DEAP](https://deap.readthedocs.io/) umstellen** (fertige
Population/Selektion/Statistik — würde das eigene `Farm`/`Entwicklung`-Gerüst ablösen und
`TopN` sowie die Diversitäts-Seeds quasi geschenkt liefern); **SVG-Erzeugung** in
`Sitzplatzverteilung.alsSVG`/`Entwicklung.alsSVG` von String-Konkatenation auf `svgwrite`
oder Jinja2-Templates; **Container-/Datenklassen** (`Person`, `Gruppe`, …) als
`@dataclass`. `Sitzplatzverteilung.TopX` bleibt bewusst handgeschrieben (die monoton
sinkende Schwelle prägt das Mutationsverhalten, siehe Kommentar im Code).
**Aufwand:** ~34 Wochen, aufbauend auf Meilenstein 1.
---
## Meilenstein 3 — Accounts & dauerhafte Personendaten
**Ziel:** Registrierte Nutzer:innen können Projekte speichern, später weiterbearbeiten,
Gäste-CSV wiederverwenden (z.B. für mehrere Event-Teile: Trauung, Feier).
- [ ] Nutzerkonten (E-Mail/Passwort oder OAuth), Projekt-Persistenz in einer DB
(Postgres passt gut: Tische/Gruppen/Personen als relationale Tabellen)
- [ ] **Datenschutz wird jetzt zentral, nicht mehr nebensächlich:**
- Betroffene sind Dritte (Hochzeitsgäste), nicht der Account-Inhaber → besondere
Sorgfaltspflicht, da die Gäste dem Dienst nie selbst zugestimmt haben
- Löschkonzept: automatische Löschung X Monate nach dem Event-Datum anbieten
- Datenexport/-löschung auf Anfrage (Art. 15/17 DSGVO)
- Verschlüsselung ruhender Daten, falls sensible Zusatzfelder (Allergien,
Sitzwünsche mit Konfliktpotential) erfasst werden
- AVV mit Hosting-Provider — Hetzner ist als Hoster beschlossen (Konzeptentscheidung
Nr. 6); EU-Hosting vermeidet die Standardvertragsklauseln-Diskussion bei US-Anbietern
- [ ] Sharing: Account-Inhaber:in lädt Co-Planer:in (Partner, Wedding-Planner) mit
eingeschränkten Rechten ein
**Aufwand:** ~46 Wochen Entwicklung + juristische Beratung (Datenschutzerklärung,
ggf. Verarbeitungsverzeichnis) einplanen, bevor das live geht.
---
## Meilenstein 4 — Monetarisierung
**Freemium statt Werbung** (Begründung siehe unten), Details siehe Konzeptentscheidungen
oben: Einmalzahlung pro Event, Merchant of Record, Free-Grenze 40 Gäste.
- [ ] Kostenlos: bis 40 Gäste und 1 Event/gespeichertes Projekt, mit Wasserzeichen
auf PDF-Export (Konzeptentscheidung Nr. 4)
- [ ] Bezahlt (einmalig pro Event, nicht Abo — Konzeptentscheidung Nr. 2; konkrete
Preisstufen bei M4-Start festlegen, Korridor ~1545 €, Konzeptentscheidung Nr. 5):
- Größere Gästezahlen
- Mehrere Varianten gleichzeitig
- PDF/Druckvorlagen ohne Wasserzeichen, Tischkarten-Export
- Priorisierte Berechnung (schneller bei Stoßzeiten)
- [ ] Payment über Merchant of Record integrieren (Paddle oder Lemon Squeezy,
Konzeptentscheidung Nr. 3 — übernimmt EU-VAT/OSS und Rechnungsstellung;
Einmalzahlung reicht, kein Abo-Billing nötig)
- [ ] Später denkbar: B2B-Lizenz für Hochzeitsplaner:innen/Locations (mehrere Events,
White-Label, dann ggf. als Abo) — deutlich höherer Wert pro Kunde als Einzelnutzer;
bewusst *nicht* Teil des Launch-Fokus (Zielgruppe B2C, Konzeptentscheidung Nr. 1)
**Warum nicht Werbung:**
Hochzeitsplanung ist eine seltene, emotional hochwertige Nutzung (im Schnitt einmal
im Leben, wenige Sitzungen über Wochen verteilt). Das ergibt sehr wenige Ad-Impressions
pro Nutzer:in — Werbenetzwerke zahlen nach Impressions/Klicks, hier fehlt schlicht
das Volumen für nennenswerte Einnahmen. Gleichzeitig wirkt Werbung in einem emotional
aufgeladenen Kontext (Hochzeit) unpassend und schadet eher der Zahlungsbereitschaft
für ein Freemium-Upgrade. Eine kleine, spitze Zielgruppe mit klarem Zahlungsanlass
(einmal fürs eigene Fest) passt besser zu Einmalzahlungen als zu Werbe-Reichweite.
**Aufwand:** ~23 Wochen für Payment-Integration + Plan-Limits im Backend.
---
## Zeitliche Gesamtschätzung (1 Entwickler:in, Vollzeit)
| Meilenstein | Dauer | Kumuliert |
|---|---|---|
| M0 Fundament | 1 Woche | 1 Woche |
| M1 MVP (Web, kein Account) | 68 Wochen | ~2 Monate |
| M2 Varianten | 34 Wochen | ~3 Monate |
| M3 Accounts + DSGVO | 46 Wochen | ~4,5 Monate |
| M4 Monetarisierung | 23 Wochen | ~5 Monate |
**Realistischer Fahrplan bis zum ersten zahlenden Kunden: ~56 Monate.** Der
Frontend/Backend-Split mit einem zweiten Paar Hände ist beschlossen (Konzeptentscheidung
Nr. 8), M1 verkürzt sich damit auf ~45 Wochen Kalenderzeit und M2 kann teilweise
parallel anlaufen — eher ~44,5 Monate bis M4-Abschluss.
---
## Wichtigste Risiken
1. **Datenschutz wird unterschätzt** — sobald echte Gästelisten dauerhaft gespeichert
werden (ab M3), ist das kein Nebenthema mehr. Frühzeitig Rechtsberatung einholen,
nicht erst kurz vor Launch.
2. **GA-Performance bei großen Sälen** — erster Datenpunkt (2026-07-11): das Beispiel
`work/innenhoefe` mit 300 Gästen an 88 Tischen rechnet mit dem Easy-Zyklus in ~0,4 s
durch — weit unter der 5-s-Schwelle, ab der M2 eine Job-Queue vorsieht. Zweiter
Datenpunkt (2026-07-12, M2-Lasttest): dasselbe Beispiel mit dem **Adaptiv**-Profil
(Web-Default) braucht ~1,71,9 s (57 Generationen, 3 Seeds, inkl. Python-Start) —
Job-Queue und Parameter-Kopplung bleiben unnötig. Weiter offen ist nur die
Lösungsgüte-Frage: bei 4er-Tischen mit großen Gruppen (Wertigkeit ~560) legen die
vielen Trennungen nahe, dass mehr GA-Iterationen (größere `Geduld`/`Start`-Werte)
bessere Pläne liefern könnten — das würde die Laufzeit dann wieder Richtung
5-s-Schwelle schieben und wäre neu zu messen.
3. **Wettbewerb ist real und etabliert** — siehe Abschnitt "Marktübersicht" oben.
PerfectTablePlan verfolgt seit Jahren denselben GA-Ansatz, allerdings als Desktop-Tool.
Differenzierung muss über Web-nativ + DSGVO-Hosting + detailliertere Regeln
(Gruppentrennungs-Strafalgorithmus, VIP-Fixplätze, Nachbartisch-Bewertung) laufen,
nicht über "wir haben einen Algorithmus" allein.
## Pricing
**Entschieden: Einmalzahlung pro Event statt Abo** (siehe Konzeptentscheidungen Nr. 2/4/5).
Die frühere Abo-Tabelle nach dem Vorbild von automatedseating.com steht jetzt als
Konkurrenz-Referenz in der Marktübersicht und ist **nicht** unser Modell.
| Plan | Preis | Leistung |
|---|---:|---|
| Free | 0 € | 1 Event, bis 40 Gäste, Export mit Wasserzeichen |
| Event-Pass | einmalig, Korridor ~1545 € (Stufen offen, Nr. 5) | unbegrenzte Gäste, mehrere Varianten, PDF/Excel/Tischkarten ohne Wasserzeichen, priorisierte Berechnung |
| B2B (später) | offen, ggf. Abo | Wedding-Planner/Locations: mehrere Events, White-Label — nach dem B2C-Launch |
---
## Anhang: Namensrecherche (Stand 2026-07-10)
Vollständige Kandidatenliste zur Namensentscheidung (Konzeptentscheidung Nr. 11).
Verfügbarkeit geprüft am 2026-07-10 per DNS-NXDOMAIN (.de — DENIC verlangt für
registrierte Domains funktionierende Nameserver) bzw. Verisign-RDAP (.com) —
Verfügbarkeit ist flüchtig, vor Registrierung erneut prüfen.
### Entschiedene Marken
| Markt | Marke | Domains (frei am 2026-07-10) |
|---|---|---|
| Deutschland (B2C-Hauptmarkt) | **Sitz & Platz** | sitzundplatz.de, sitzundplatz.com |
| Europa/international | **Sitzwunder / SeatWonder** | sitzwunder.de, sitzwunder.com, seatwonder.de, seatwonder.com |
### Deutsche Kandidaten (seriös)
| Name | .de | .com | Bemerkung |
|---|---|---|---|
| Sitzwunder | frei | frei | → gewählt für Europa-Variante; bisher nur generischer Möbel-Begriff, kein Markenauftritt |
| Platzharmonie | frei | frei | beschreibt das Optimierungsziel, Fallback Nr. 1 |
| Sitzfee | frei | frei | charmant, evtl. zu verspielt für B2B |
| Tafelplan | frei | vergeben | seriös, aber Nähe zum Wettbewerber tableplan.io |
| Tafelwunder | frei | frei | — |
| Platzzauber | frei | frei | — |
| Platzmagie | frei | frei | — |
| Sitzharmonie / Tischharmonie | frei | ungeprüft | — |
| Sitzmagie | frei | ungeprüft | — |
| Sitzplatzwunder | frei | ungeprüft | lang |
| Gutgesetzt | frei | frei | — |
| Gaesteplatz | frei | frei | Umschreibung wegen Umlaut-Domain |
| Feintafel | frei | frei | — |
| Sitzo / Setzo | frei | vergeben | Kunstwort, SaaS-Klang |
| sitzplan.de, platzplan.de, sitzordnung.de, tischordnung.de, sitzplaner.de, tischplaner.de, platzwunder.de, platzkarte.de, tischlein.de, … | vergeben | — | alle naheliegenden beschreibenden Namen sind weg |
### Witzige deutsche Namen (Film-/Kultur-Anspielungen)
| Name | Anspielung | .de | Bemerkung |
|---|---|---|---|
| **Sitz & Platz** | Hundekommandos | frei | → gewählt als deutsche Hauptmarke |
| Ein Platz an der Tafel | "Ein Platz an der Sonne" | einplatzandertafel.de + platzandertafel.de frei | auch als Claim stark |
| Wo sitzt Tante Erna? | Insider aus dieser Roadmap (M0, Determinismus-Option) | wositzttanteerna.de frei | Kampagnen-/Claim-Material |
| Herr der Tische | "Der Herr der Ringe" (Doppelbezug: Trauringe) | herrdertische.de + derherrdertische.de frei | Markenrecht-Risiko (Middle-earth Enterprises) |
| Game of Tables | Game of Thrones ("Red Wedding") | frei | Markenrecht-Risiko (HBO), nur Blog/Kampagne |
| Tischpate | "Der Pate" | frei | — |
| Vier Hochzeiten | "4 Hochzeiten und ein Todesfall" | frei | Kollision mit VOX-Show "4 Hochzeiten und eine Traumreise" |
| Wer sitzt denn da? | Quizshow-Klang | frei | — |
| Und ewig sitzt die Tante | "Und ewig grüßt das Murmeltier" | frei | — |
| Reise nach Jerusalem, Tischgeflüster, Platz da!, Tante Erna, Tafelrunde, Dinner for All, Setzkasten | — | vergeben | die wären gut gewesen |
### Englische Kandidaten (.com)
| Name | Anspielung | Status | Bemerkung |
|---|---|---|---|
| **SeatWonder** | Zwilling von Sitzwunder | seatwonder.com + .de + seatingwonder.com frei | → gewählt als internationale Marke |
| The Seating Game | "The Dating Game" / "The Crying Game" | frei | verspielt-ironisch |
| Seat Whisperer | "Der Pferdeflüsterer" | frei | — |
| Seated Ever After | "…happily ever after" | frei | hochzeitlichste Variante |
| Mind the Seat | "Mind the Gap" | frei | britisch-trocken |
| Seating Sorted | britisches "Sorted!" | frei | eher B2B-Ton |
| Seat and Smile | "Meet & Greet"-Nachbarschaft | frei | generisch |
| Sit & Stay (sitandstay.com, sitstay.com) | Hundekommandos — 1:1-Pendant zu Sitz & Platz | vergeben (Pet-Branche) | Grund für SeatWonder statt Übersetzung |
| pleasebeseated, haveaseat, takeyourseat, beseated, seatyourself, sithappens, seatandgreet, seatmagic, seatharmony, seatcupid, happilyseated, seatfairy, … | — | vergeben | alle klassischen Usher-Phrasen/Puns sind weg |
### Chinesische Pendants (Fun Fact, kein Roadmap-Ziel)
| Ausdruck | Pinyin | Bedeutung | Eignung |
|---|---|---|---|
| 对号入座 | duì hào rù zuò | "Nummer abgleichen, Platz einnehmen" — feststehende Redewendung fürs Finden des zugewiesenen Sitzplatzes; übertragen: "sich angesprochen fühlen" | Das idiomatische Pendant zu "Sitz & Platz" — als Name eines Seating-Tools für Muttersprachler sofort witzig |
| 坐 / 座 | zuò / zuò | "sitzen" / "Sitzplatz" — perfekte Homophone (座 ist historisch aus 坐 entstanden) | eingebautes Wortspiel für Claims/Wortmarken |
| 坐下 / 别动 | zuòxià / bié dòng | Hundekommandos "Sitz!" / "Bleib!" | 1:1-Übertragung des Hundekommando-Witzes scheitert: 别动 hat keine Sitzplatz-Bedeutung |
| 婚宴座位表 | hūnyàn zuòwèi biǎo | "Hochzeitsbankett-Sitzplan" (Fachbegriff) | SEO-/Suchbegriff, kein Markenname |
Ein China-Launch wäre ein eigenes Vorhaben (ICP-Lizenz, Datenlokalisierung nach PIPL,
WeChat-Mini-Programm statt PWA) und ist bewusst **nicht** Teil dieser Roadmap.
## Wichtige Features
### Screen zur Eingabe der Tische
- Vordefinierte Auswahl von Räumen und fertigen Konfigurationen, Räume mit einer Bühne und Musik daneben, Sitze im Halbkreis, Sitze im Parallelen zur Bühne und aussen im Kreis, Zentrale Bühne mit Tischen drum herum, Eingänge rechts, links oben unten per Klick und zum Verschieben an der Wand, Hufeisen Tafel, normale Tafel etc. -> Auswahl bzw. Verschiebung der Elemente. Verlängerung oder Verkürzung der Tische
- Die Bühne ist in Ausdehnung und Breite ebenfalls anpassbar. Mehrere Bühnen sind möglich (z.B. Tanzfläche, separat davon die Band)
- Vordefinierte Auswahl von Tischen, Gerade mit n - Sitzen, einreihig bestuhlt, zweireihig bestuhlt, M-Form (rechteckig zueinander gestellt), Kreissegment mit Radius R und N Sitzen darauf, Elliptische Sitze, Runde Sitze, Rechteckige Sitze
- Anzahl der Stühle durch Anwahl einer Tischkante definierbar, durch Auswahl des ganzen Tisches, Selektion einer Reihe oder einzelner Stühle und dann löschbar
- Einzelne Platzierung von Stühlen an einem Tisch siehe auch https://www.perfecttableplan.com/html/tour.html
#### Technische Umsetzung (beantwortet 2026-07-09)
Inline-`<svg>` im DOM, nicht `<img src="...svg">` (statisch, nicht klickbar) und nicht
reines Canvas (pixelbasiert, kein Objekt pro Tisch/Stuhl im DOM). Jeder Tisch/Stuhl/jede
Bühne ist ein eigenes SVG-Element, das Klick-/Drag-Events, Selektions-Highlighting per
Style-Attribut bekommt und sich geometrisch an `alsSVG()` aus `Strukturdaten.py` anlehnt
(Radius-/Platzierungsberechnung ist server-seitig schon vorhanden und dient als
Ausgangslayout).
- **State-getrieben rendern:** Ein JS-Array von Tisch-Objekten
(`{id, typ, x, y, radius, plaetze, rotation, nachbarn}`) ist die Wahrheit; das SVG wird
aus diesem State erzeugt, nicht umgekehrt aus dem SVG gelesen.
- **React + SVG als JSX** für die Komponentenstruktur (`<Tisch>`, `<Buehne>`, `<Stuhl>`),
State-Changes rendern automatisch neu.
- Für Drag/Resize/Rotate/Selektion **nicht bei Null anfangen**, sondern eine Bibliothek
nutzen: [Konva](https://konvajs.org/)/`react-konva` (Canvas-basiert, bringt
Drag/Resize/Rotate fertig mit) oder [svg.js](https://svgjs.dev/)/[interact.js](https://interactjs.io/)
(bleiben bei echtem SVG als gemeinsamer Quelle für Editor UND Export).
- **Vordefinierte Layouts/Formen** (Hufeisen, M-Form, Kreissegment, Bühne mittig, …) sind
reine **Presets, die den State vorbefüllen** — kein Sonderfall im Rendering, nur
unterschiedliche Ausgangs-Arrays von Tisch-Objekten.
- **Speichern:** Der State wird als JSON an `POST /sitzung/{id}/tische` geschickt — direkter
Ersatz für die heutige `tische.ini`; "Nachbarliste" wird aus der räumlichen Nähe der
Koordinaten abgeleitet statt manuell gepflegt.
- **Ergebnis-Anzeige nach der GA-Berechnung** ist dagegen bewusst *kein* editierbarer
Canvas-State mehr, sondern das serverseitig generierte `alsSVG()` — reine
Anzeige/Export, direkt einbettbar oder als `<img>`. Damit gibt es zwei klar getrennte
Pfade: einer zum Bearbeiten (Konva/SVG+JS im Frontend), einer zum Anzeigen/Drucken
(`alsSVG()` server-seitig) — kein Aufwand, den Editor-State rückwärts in druckfähiges
SVG zu konvertieren.
**Empfehlung:** React + react-konva für den editierbaren Tisch-Editor, plus
Weiterverwendung von `alsSVG()` für read-only Ergebnisdarstellung und Druck-Export.
### Screen zur Eingabe der Gäste
- als anonyme Gruppe mit einer Menge von enthaltenen Leuten
- als benannte Gruppe (Familie Heiner)
- als Liste von einzelnen Personen die eine Gruppe sind und gemeinsam sitzen wollen
- als csv Liste mit einer eigenen Spalte mit der Angabe mit Vorliebe der Gäste (wen diese
Person nicht mag und einer Spalte wen sie besonders mag, Kommasepariert).
**Backlog M4+ (Konzeptentscheidung Nr. 10):** die Auswertung dieser Spalten erfordert
eine Kern-Erweiterung der `Strafliste` um Personenpaar-Regeln; das CSV-Format sieht die
Spalten ab M1 vor, ausgewertet werden sie erst später (Premium-Feature-Kandidat).
### VIP Angabe
- Das Brautpaar und die Brauteltern oder spezielle Gäste haben fixe Sitzplätze die sich nicht ändern sollen
### Visualisierung des Ergebnisses
Raumplan mit Gruppen, Familien, VIP in mehreren Farben
Mehrere Pläne durch Umschalten im Vergleich (Anzahl der gefundenen Lösungen und Rankings werden angezeigt)
### druckbare Ergebnis Listen
- alphabetische Liste der Gäste und welcher Tisch
- Alphabetische Liste der Gruppennamen und welche Tisch(e)
- Liste der Tische und zugehörige Liste der Namen
- QR Code für das Event und die zugehörige App, welche zu einem Namen den Tisch verrät
- Tischkarten mit vordefinierten Designbereichen (Bild, Namen, Mittig) und verschiedenen Fonts
- vordefinierten Designs die automatisch befüllt werden. Font anpassbar
### Kuchendiagramme im Dashboard für die Orga
- Verteilung Männlich/Weiblich, Alter
- befüllte unbefüllte Tische
- noch nicht zugewiesene Gäste/ freie Sitze
## Technik Fragen (beantwortet 2026-07-09)
### Eine Webseite, per App (iOS/Android) UND Browser nutzbar
Empfehlung: **kein separater App-Code**, sondern die Web-App (aus M1) als **installierbare
PWA** bauen und zusätzlich per **WebView-Wrapper** (z.B. [Capacitor](https://capacitorjs.com/))
in den App Store / Play Store bringen. Capacitor packt eine bestehende Web-App 1:1 in eine
native Hülle — dieselbe Codebasis, kein Flutter/React-Native-Zweitprojekt.
- Praktische Konsequenz für M1: Frontend von Anfang an PWA-fähig auslegen (Manifest,
Service Worker, responsives Layout, Touch-Bedienung für den Tisch-Editor testen) —
nachträglich draufzusetzen ist deutlich teurer als von Beginn an mitzudenken.
- QR-Code-Feature (siehe "druckbare Ergebnis Listen") passt gut dazu: Link öffnet die PWA
im Browser oder in der installierten App, kein Store-Zwang für Gäste.
- Store-Present (native Wrapper-App) macht vor allem für den **Organisator/Wedding-Planner**
Sinn (regelmäßige Nutzung, Push-Benachrichtigungen bei Änderungen); Gäste kommen i.d.R.
einmalig über den QR-Link und brauchen keine Store-Installation.
- Aufwand Capacitor-Wrapper: klein (~13 Tage) *sobald* die PWA steht.
**Beschlossen (Konzeptentscheidung Nr. 9): der Store-Wrapper kommt erst nach M4**
bis dahin nur PWA. Achtung bei der späteren Umsetzung: das Gebühren-/In-App-Purchase-
Modell von Apple/Google kollidiert ggf. mit der Einmalzahlung im Web (Kauf dann nur
im Browser anbieten, App als reiner Viewer).
### Lokale Testinstanz für FastAPI (Hugo-Server-Äquivalent)
Ja, das geht direkt und ohne Docker:
```bash
uvicorn main:app --reload
```
`--reload` beobachtet Dateiänderungen und lädt automatisch neu, läuft standardmäßig auf
`localhost:8000`. FastAPI liefert zusätzlich unter `/docs` eine interaktive Swagger-UI, mit
der sich alle Endpunkte (`POST /sitzung`, `.../tische`, `.../personen`, `.../berechnen`, …)
ohne eigenes Frontend durchklicken/testen lassen — praktisch für die Backend-Entwicklung in
M1, bevor der Tisch-Editor existiert.
**Docker ist für die lokale Testinstanz nicht nötig** — erst relevant, sobald:
- eine echte DB (Postgres, ab M3) oder weitere Services (Redis/Celery, ab M2 bei
Hintergrund-Jobs) lokal mit reproduzierbarem Setup laufen sollen,
- die Produktionsumgebung 1:1 nachgebildet werden soll (Nginx davor, gleiche
Python-Version wie im Deployment),
- mehrere Entwickler:innen ein identisches Setup brauchen.
Aufwand dann: ein `Dockerfile` für FastAPI (~10 Zeilen) + `docker-compose.yml` für
DB/Redis (~2030 Zeilen) — überschaubar, aber erst ab M2/M3 sinnvoll, nicht für M1.
**Empfehlung für M0/M1:** `uvicorn --reload` reicht für die gesamte MVP-Phase (M1, keine
Accounts/DB). Docker-Compose erst einführen, wenn M2 (Job-Queue) oder M3 (Postgres)
ansteht.
+201
View File
@@ -0,0 +1,201 @@
"""
Liest eine Gaesteliste im CSV-Format ein — der Web-Ersatz fuer bestellung.json
(Meilenstein 1 der Roadmap, Adapter analog zu JSONConfig in Strukturdaten.py).
CSV-Format (Kopfzeile noetig, Spaltenreihenfolge egal, Trennzeichen ; oder ,):
Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl
- Vorname, Nachname: Pflicht
- Titel: optional (z.B. "Dr.")
- Gruppe: Gruppenname — Personen mit demselben Gruppennamen gehoeren
zusammen und sollen moeglichst zusammen sitzen.
Leer = Einzelperson (bildet eine eigene Ein-Personen-Gruppe).
- Tisch: optionale Tischnummer — die Person ist VIP und wird fest an
diesen Tisch gesetzt (wie "tisch" in bestellung.json).
VIPs laufen nicht durch die GA-Platzierung.
- Anzahl: optionale Reservierungsanzahl — expandiert die Zeile in so
viele identische Buchungen (wie "anzahl" in bestellung.json,
z.B. fuer anonyme Sammelbuchungen). Leer = 1.
Zusaetzlich werden die Spalten "MagNicht" und "MagGern" akzeptiert,
aber noch ignoriert (reserviert fuer Personenpaar-Regeln, siehe
Roadmap-Konzeptentscheidung Nr. 10) — so entsteht spaeter kein
Formatbruch.
"""
__author__ = "Michael Stangl"
__copyright__ = "Copyright (c) 2026 Michael Stangl"
__license__ = "Python"
import csv
import io
from Strukturdaten import Person, Personen, Gruppe, Gruppen
class CSVConfig:
"""aus CSV Text/Datei alles einlesen (Rueckgabe wie JSONConfig.laden,
plus Gruppennamen fuer die Anzeige im Web-Frontend)"""
PflichtSpalten = ['vorname', 'nachname']
BekannteSpalten = ['vorname', 'nachname', 'titel', 'gruppe',
'tisch', 'anzahl', 'magnicht', 'maggern']
def HandleGaesteliste(self, Text):
"""parst den CSV-Text und baut Personen/Gruppen/VIPs auf
Rueckgabe: [ PN, GN, VIPGruppe, VipHash, GruppenNamen ]
- PN: Personen-Container (ohne VIPs, wie JSONConfig)
- GN: Gruppen-Container (ohne VIP-Gruppe, wie JSONConfig)
- VIPGruppe: Gruppe(0) mit allen fest gesetzten Personen
- VipHash: { PersonId: Tischnummer } fuer VIPsSetzen()
- GruppenNamen: { GruppenId: Anzeigename }
"""
# Trennzeichen automatisch bestimmen: die Kopfzeile entscheidet
Kopfzeile = Text.lstrip('').splitlines()[0] if Text.strip() else ''
Trenner = ';' if Kopfzeile.count(';') >= Kopfzeile.count(',') else ','
Leser = csv.DictReader( io.StringIO(Text.lstrip('')), delimiter=Trenner )
if Leser.fieldnames is None:
raise ValueError("CSV ist leer — Kopfzeile mit mindestens "
"Vorname/Nachname erwartet")
# Spaltennamen normalisieren (Gross/Klein egal, Leerzeichen weg)
SpaltenMap = {}
for Feld in Leser.fieldnames:
if Feld is None:
continue
SpaltenMap[Feld] = Feld.strip().lower()
for Pflicht in self.PflichtSpalten:
if Pflicht not in SpaltenMap.values():
raise ValueError("CSV-Kopfzeile: Pflichtspalte '%s' fehlt "
"(gefunden: %s)" % (Pflicht, Leser.fieldnames))
def Wert(Zeile, Name):
for Original, Normiert in SpaltenMap.items():
if Normiert == Name:
Inhalt = Zeile.get(Original)
return (Inhalt or '').strip()
return ''
PN = Personen()
GN = Gruppen()
VIPGruppe = Gruppe( 0 )
VipHash = {}
GruppenNamen = {}
# fest platzierte ("fixierte") Gruppen fuer die Anzeige: Name ->
# {'tisch': Tischnummer, 'anzahl': Personenzahl}. VIPs laufen nicht
# durch die GA-Platzierung, sollen in der Gaesteliste aber sichtbar
# (grau hinterlegt) erscheinen.
FixierteGruppen = {}
# Gruppen entstehen beim ersten Auftreten ihres Namens;
# Einzelpersonen (leerer Gruppenname) bekommen eine eigene Gruppe
GruppeVonName = {}
PID = 0
GID = 0
ZeilenNr = 1
for Zeile in Leser:
ZeilenNr = ZeilenNr + 1
Vorname = Wert(Zeile, 'vorname')
Nachname = Wert(Zeile, 'nachname')
if Vorname == '' and Nachname == '':
continue # Leerzeile
if Vorname == '' or Nachname == '':
raise ValueError("Zeile %d: Vorname und Nachname sind Pflicht"
% ZeilenNr)
Titel = Wert(Zeile, 'titel')
GruppenName = Wert(Zeile, 'gruppe')
TischFeld = Wert(Zeile, 'tisch')
AnzahlFeld = Wert(Zeile, 'anzahl')
try:
AnzahlReservierungen = int(AnzahlFeld) if AnzahlFeld else 1
except ValueError:
raise ValueError("Zeile %d: Anzahl '%s' ist keine Zahl"
% (ZeilenNr, AnzahlFeld))
if AnzahlReservierungen < 1:
raise ValueError("Zeile %d: Anzahl muss >= 1 sein" % ZeilenNr)
TischNr = None
if TischFeld != '':
try:
TischNr = int(TischFeld)
except ValueError:
raise ValueError("Zeile %d: Tisch '%s' ist keine "
"Tischnummer" % (ZeilenNr, TischFeld))
for i in range(AnzahlReservierungen):
PID = PID + 1
P = Person( PID, Vorname, Nachname, Titel )
if TischNr is not None:
# fixiert: fester Tisch, keine GA-Platzierung
VipHash[ PID ] = TischNr
VIPGruppe.Person_dazu( P )
Name = GruppenName if GruppenName else 'Fixiert Tisch %d' % TischNr
Eintrag = FixierteGruppen.setdefault(
Name, { 'tisch': TischNr, 'anzahl': 0 } )
Eintrag['anzahl'] = Eintrag['anzahl'] + 1
else:
PN.PersonAdd( P )
if GruppenName == '':
# Einzelperson: eigene Ein-Personen-Gruppe,
# komplett befuellen und dann registrieren
GID = GID + 1
G = Gruppe( GID )
G.Person_dazu( P )
GruppenNamen[ GID ] = '%s %s' % (Vorname, Nachname)
GN.Gruppe_dazu( G )
else:
if GruppenName not in GruppeVonName:
GID = GID + 1
G = Gruppe( GID )
GruppeVonName[ GruppenName ] = G
GruppenNamen[ GID ] = GruppenName
else:
G = GruppeVonName[ GruppenName ]
G.Person_dazu( P )
# benannte Gruppen erst jetzt registrieren, wenn sie komplett sind
# (Gruppen.Gruppe_dazu uebernimmt Mitglieder und zaehlt NLeute)
for GruppenName, G in GruppeVonName.items():
if G.Anzahl() > 0:
GN.Gruppe_dazu( G )
return [ PN, GN, VIPGruppe, VipHash, GruppenNamen, FixierteGruppen ]
def laden(self, FileName):
"""lese alle Eingangsdaten aus einer CSV-Datei ein"""
# utf-8-sig schluckt das BOM, das Excel beim CSV-Export voranstellt
fsock = open( FileName, 'r', encoding='utf-8-sig' )
Text = fsock.read()
fsock.close()
return self.HandleGaesteliste( Text )
if __name__ == '__main__':
Beispiel = """Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl
Britta;Beispiel;;Brautpaar;1;
Bernd;Beispiel;Dr.;Brautpaar;1;
Anna;Huber;;Familie Huber;;
Berta;Huber;;Familie Huber;;
Carl;Huber;;Familie Huber;;
Gast;Kollege;;Kollegen;;4
Einzel;Gast;;;;
"""
print("\n-- Parse Beispiel-CSV:")
C = CSVConfig()
[ PN, GN, VIPGruppe, VipHash, GruppenNamen, FixierteGruppen ] = \
C.HandleGaesteliste( Beispiel )
print(PN)
print(GN)
print(VIPGruppe)
print(VipHash)
print(GruppenNamen)
print(FixierteGruppen)
else:
pass
+165
View File
@@ -0,0 +1,165 @@
"""
Farbschema fuer die SVG-Ausgabe (Sitzplatzverteilung.alsSVG).
Laedt ein Farbprofil aus cfg/farben.cfg und ordnet jeder Gruppe eine Farbe zu.
Zwei Modi (siehe cfg/farben.cfg fuer Details):
- 'palette': eine Farbliste, zyklisch je Gruppe (nach Gruppen-Id sortiert)
- 'kategorien': trennt nach Art (Hochzeit) in Familie / Verein / VIP und
faerbt sie ueber je einen Farbverlauf ein.
Waehlbar per --farben <Sektion> (libs/platz.py) bzw. PLATZ_FARBENART (web).
"""
__author__ = "Michael Stangl"
__copyright__ = "Copyright (c) 2026 Michael Stangl"
__license__ = "Python"
import configparser
import os
from collections import Counter, defaultdict
def _hex_zu_rgb(h):
h = h.strip().lstrip('#')
return tuple( int(h[i:i+2], 16) for i in (0, 2, 4) )
def _rgb_zu_hex(rgb):
return '#%02x%02x%02x' % tuple( max(0, min(255, int(round(c)))) for c in rgb )
def _verlauf(start, ende, t):
"""Farbe im linearen RGB-Verlauf start->ende an Position t in [0,1]"""
a, b = _hex_zu_rgb(start), _hex_zu_rgb(ende)
return _rgb_zu_hex( tuple( a[i] + (b[i] - a[i]) * t for i in range(3) ) )
def _verlauf_liste(start, ende, n):
"""n Farben gleichmaessig ueber den Verlauf start->ende (n>=1)"""
if n <= 1:
return [ _verlauf(start, ende, 0.0) ]
return [ _verlauf(start, ende, j / (n - 1)) for j in range(n) ]
class Farbschema:
"""ordnet Gruppen Farben zu, gesteuert durch ein Profil aus farben.cfg"""
# Rueckfall-Palette, falls keine Config / kein gueltiges Profil geladen wurde
Standard = [
'#e6194b', '#3cb44b', '#4363d8', '#f58231', '#911eb4',
'#42d4f4', '#f032e6', '#bfef45', '#fabed4', '#469990',
'#dcbeff', '#9a6324', '#800000', '#aaffc3', '#000075' ]
def __init__(self):
self.Modus = 'palette'
self.Palette = list(self.Standard)
self.FamilienVerlaeufe = [ ('#1f4e9c', '#2fae5f'), ('#f2c200', '#e8590c') ]
self.VereinVerlauf = ('#7b2fbf', '#9aa0a6')
self.VIPVerlauf = ('#e63946', '#8b0000')
def laden(self, FileName, Sektion='grosse_gruppen'):
config = configparser.ConfigParser()
config.read( os.path.expanduser(FileName) )
if not config.has_section( Sektion ):
raise ValueError(
"Farbprofil '%s' nicht in %s gefunden (vorhanden: %s)"
% ( Sektion, FileName, ', '.join(config.sections()) or '-' ) )
self.Modus = config.get( Sektion, 'Modus', fallback='palette' ).strip()
if config.has_option( Sektion, 'Palette' ):
self.Palette = self._farbliste( config.get( Sektion, 'Palette' ) )
if config.has_option( Sektion, 'FamilienVerlaeufe' ):
self.FamilienVerlaeufe = self._verlaeufe(
config.get( Sektion, 'FamilienVerlaeufe' ) )
if config.has_option( Sektion, 'VereinVerlauf' ):
self.VereinVerlauf = self._verlaeufe( config.get( Sektion, 'VereinVerlauf' ) )[0]
if config.has_option( Sektion, 'VIPVerlauf' ):
self.VIPVerlauf = self._verlaeufe( config.get( Sektion, 'VIPVerlauf' ) )[0]
return self
@staticmethod
def _farbliste(text):
return [ f.strip() for f in text.replace('\n', ',').split(',') if f.strip() ]
@staticmethod
def _verlaeufe(text):
"""'A -> B, C -> D' -> [(A,B),(C,D)]; ein einzelner Wert wird zu (v,v)"""
ergebnis = []
for teil in text.replace('\n', ',').split(','):
teil = teil.strip()
if not teil:
continue
if '->' in teil:
a, b = teil.split('->', 1)
ergebnis.append( (a.strip(), b.strip()) )
else:
ergebnis.append( (teil, teil) )
return ergebnis or [ ('#888888', '#888888') ]
def farben(self, Gruppen):
"""ordnet den Gruppen Farben zu.
Rueckgabe: (GidZuFarbe {Gruppen-Id: hexfarbe}, VIPFarbe hexfarbe).
VIPFarbe gilt fuer Personen ohne GA-Gruppe (feste Platzierung)."""
GruppenListe = sorted( Gruppen, key=lambda g: g.Id )
if self.Modus == 'kategorien':
return self._kategorien( GruppenListe )
return self._palette( GruppenListe )
def _palette(self, GruppenListe):
pal = self.Palette or self.Standard
GidZuFarbe = { G.Id: pal[i % len(pal)] for i, G in enumerate(GruppenListe) }
return GidZuFarbe, '#888888'
@staticmethod
def _nachname(G):
"""dominanter Nachname der Gruppe, wenn ihn die Mehrheit traegt (bei
>= 2 Mitgliedern) - sonst None (dann gilt die Gruppe als Verein/
gemischt). Anonyme Sammelbuchungen (alle Mitglieder derselbe Name,
z.B. 13x 'Gast Musikverein') sind keine Familie, sondern gelten als
Verein - daher werden mindestens zwei VERSCHIEDENE Personen verlangt."""
personen = list( G )
if len(personen) < 2:
return None
if len({ (P._Vorname, P._Name) for P in personen }) < 2:
return None # anonymer Block (alle identisch) -> kein Familienname
namen = [ P._Name for P in personen ]
name, anzahl = Counter(namen).most_common(1)[0]
return name if anzahl * 2 > len(namen) else None
def _kategorien(self, GruppenListe):
# 1. klassifizieren: Familien (nach Nachname) vs. Vereine
familien = defaultdict(list) # Nachname -> [Gruppen]
vereine = []
for G in GruppenListe:
nn = self._nachname( G )
if nn is not None:
familien[nn].append( G )
else:
vereine.append( G )
GidZuFarbe = {}
# 2. Familien: jeder Nachname kommt (alphabetisch, abwechselnd) in einen
# Farbbereich - Blau->Gruen ODER Gelb->Orange. Innerhalb eines
# Bereichs werden ALLE zugehoerigen Familiengruppen ueber den Verlauf
# gespreizt, damit verschiedene Familien verschiedene Toene haben;
# Gruppen desselben Nachnamens bleiben benachbart (ein zusammen-
# haengendes Band). So laeuft z.B. eine mehrteilige Familie Brandt
# ueber benachbarte Gelb->Orange-Toene, waehrend Familie Peters einen
# anderen Blau->Gruen-Ton bekommt.
Nachnamen = sorted( familien )
Bereich = { nn: i % len(self.FamilienVerlaeufe)
for i, nn in enumerate(Nachnamen) }
GruppenImBereich = defaultdict(list)
for nn in Nachnamen:
for G in sorted( familien[nn], key=lambda g: g.Id ):
GruppenImBereich[ Bereich[nn] ].append( G )
for b, gruppen in GruppenImBereich.items():
start, ende = self.FamilienVerlaeufe[b]
for farbe, G in zip( _verlauf_liste(start, ende, len(gruppen)), gruppen ):
GidZuFarbe[G.Id] = farbe
# 3. Vereine: ein Verlauf (z.B. Violett -> Grau) ueber alle Vereine
vstart, vende = self.VereinVerlauf
for farbe, G in zip( _verlauf_liste(vstart, vende, len(vereine)),
sorted(vereine, key=lambda g: g.Id) ):
GidZuFarbe[G.Id] = farbe
# 4. VIP-Farbe: Startfarbe des VIP-Verlaufs (i.d.R. Rot)
return GidZuFarbe, self.VIPVerlauf[0]
+696 -287
View File
File diff suppressed because it is too large Load Diff
+607 -68
View File
@@ -4,9 +4,37 @@ Enthaelt alle Datenstrukturen um die einen genetischen Algorithmus darzustellen
"""
from random import *
from itertools import chain
from string import split
from copy import deepcopy
import ConfigParser, os
from functools import total_ordering
import ast
import configparser, os
def _StringAusdruck(text):
"""wertet einen einfachen String-Ausdruck sicher aus.
zyklus.cfg nutzt kompakte Schreibweisen wie
'e,'+'s,z,m,j,z,'*3+'s'
also String-Literale, mit '+' verkettet und mit '*' vervielfacht.
ast.literal_eval kann das nicht (nur reine Literale), eval() waere
unsicher. Dieser Mini-Auswerter erlaubt ausschliesslich str-Literale,
ganze Zahlen sowie die Operatoren + und * - kein Funktionsaufruf,
keine Namen, kein beliebiger Code.
"""
knoten = ast.parse(text, mode='eval').body
def rechne(n):
if isinstance(n, ast.Constant) and isinstance(n.value, (str, int)):
return n.value
if isinstance(n, ast.BinOp) and isinstance(n.op, (ast.Add, ast.Mult)):
links, rechts = rechne(n.left), rechne(n.right)
return links + rechts if isinstance(n.op, ast.Add) else links * rechts
raise ValueError("unerlaubter Ausdruck in zyklus.cfg: %r" % text)
ergebnis = rechne(knoten)
if not isinstance(ergebnis, str):
raise ValueError("zyklus.cfg-Ausdruck ergibt keinen String: %r" % text)
return ergebnis
__author__ = "Michael Stangl"
@@ -15,29 +43,39 @@ __date__ = "$Date: $"
__copyright__ = "Copyright (c) 2005 Michael Stangl"
__license__ = "Python"
@total_ordering
class Loesung:
"""ein einfaches Loesungsobjekt. Taugt um es als Superklasse zu ueberladen"""
def __init__(self, *Argumente, **keywords):
self.Id = -1 * randint(1,100)
self.value = self.Id
print " initialisiere Loesung " + repr(self.Id)
print(" initialisiere Loesung " + repr(self.Id))
def mutieren(self):
print " mutiere Loesung " + repr(self.Id)
print(" mutiere Loesung " + repr(self.Id))
self.Id = -1 * randint(1,100)
self.value = self.Id
return self
def kreuzen(self,obj):
print " kreuze Loesung " + repr(self.Id)
print(" kreuze Loesung " + repr(self.Id))
def laden(self):
print " lade Loesung " + repr(self.Id)
print(" lade Loesung " + repr(self.Id))
def speichern(self):
print " speichere Loesung " + repr(self.Id)
print(" speichere Loesung " + repr(self.Id))
def getGruppenId(self):
"""Id fuer den Dedup-Vergleich (Basis: jede Loesung eigenstaendig).
Unterklassen ueberladen dies mit einer inhaltlichen Signatur, so
dass gleiche Loesungen dieselbe Id bekommen und nicht mehrfach
gehalten werden."""
return id(self)
def getPersonenId(self):
"""feinere Id fuer wirklich identische Loesungen (Basis: eigenstaendig)"""
return id(self)
def __repr__(self):
return ' L '+ repr(self.Id)
def __cmp__(self,other):
if self.value < other.value: return -1
elif self.value == other.value: return 0
else: return 1
return ' L '+ repr(self.Id)
def __eq__(self,other):
return self.value == other.value
def __lt__(self,other):
return self.value < other.value
class Zyklus:
"""Definiert wie ein Zyklus ablaufen soll:
@@ -45,46 +83,444 @@ class Zyklus:
wann sollen Objekte generiert, gekreuzt, mutiert und selektiert werden
wieviele sind davon jeweils betroffen
"""
def __init__(self, Name='default',
Abfolge='e,m,s',
# adaptive Vorgaben, falls das Profil kein eigenes Feld setzt
AdaptivDefaults = {
'Start': 40, # Groesse der Startpopulation (Anfangswert)
'MutationProLoesung': 2,# wie oft jede Loesung je Generation mutiert wird
'Schrumpfung': 0.85, # Faktor, um den die Population je Generation faellt
'MinPopulation': 5, # untere Schranke der Population
'MaxGenerationen': 50, # harte Obergrenze der Generationen
'Geduld': 3, # Generationen ohne Verbesserung bis zum Abbruch
'Schwelle': 1.0 } # als Verbesserung zaehlende Mindestdifferenz
def __init__(self, Name='default',
Abfolge='e,m,s',
Anzahl='10,10,10'):
self.Name = Name
self.Abfolge = split(Abfolge, ',')
self.Anzahl = split(Anzahl,',')
self.Abfolge = Abfolge.split(',')
self.Anzahl = Anzahl.split(',')
# 'statisch' = klassische Abfolge/Anzahl abspielen;
# 'adaptiv' = Generationen-Schleife mit Abbruch bei Konvergenz.
self.Modus = 'statisch'
self.Adaptiv = {}
def __repr__(self):
if self.Modus == 'adaptiv':
return( "Zyklus: %s (adaptiv)\n"
" Parameter: %s\n" % ( self.Name, self.Adaptiv ) )
return( "Zyklus: %s\n"
" Zyklusabfolge: %s\n"
" Anzahl : %s\n"
% ( self.Name,
self.Abfolge,
% ( self.Name,
self.Abfolge,
self.Anzahl ) )
def laden(self, FileName, ZyklusName):
config = ConfigParser.ConfigParser()
ZyklusPath= os.path.split( FileName )
ZyklusPath= os.path.join( FileName )
config = configparser.ConfigParser()
ZyklusPath= os.path.split( FileName )
ZyklusPath= os.path.join( FileName )
config.read( ZyklusPath )
self.Name = ZyklusName
Abfolge = eval( config.get( ZyklusName, 'Abfolge' ))
Anzahl = eval( config.get( ZyklusName, 'Anzahl' ))
# Adaptives Profil, sobald ein 'Start'-Feld vorhanden ist. Dann wird
# die Aktionsabfolge nicht aus der Config gelesen, sondern von der
# Farm generationenweise erzeugt (mit Abbruch bei Konvergenz).
if config.has_option( ZyklusName, 'Start' ):
self.Modus = 'adaptiv'
self.Adaptiv = dict(self.AdaptivDefaults)
for Feld in self.AdaptivDefaults:
if config.has_option( ZyklusName, Feld ):
self.Adaptiv[Feld] = ast.literal_eval(
config.get( ZyklusName, Feld ) )
return
self.Modus = 'statisch'
Abfolge = _StringAusdruck( config.get( ZyklusName, 'Abfolge' ))
Anzahl = _StringAusdruck( config.get( ZyklusName, 'Anzahl' ))
self.Abfolge = Abfolge.split(',')
self.Anzahl = Anzahl.split(',')
pass
class Entwicklung:
"""Beobachtungsobjekt: zeichnet den Verlauf der Loesungsfindung auf.
Nach jeder Zyklus-Aktion wird ein Messpunkt erfasst (bester,
durchschnittlicher und schlechtester Wert im aktuellen Pool).
alsSVG() zeichnet daraus eine Verlaufsgrafik: Zeitachse (Aktions-
index) nach rechts, Wertigkeit auf der Y-Achse. Domaenen-agnostisch;
funktioniert mit jeder Loesung, die ein Attribut .value hat.
"""
# Buchstaben der Zyklus-Abfolge -> lesbare Namen fuer die Beschriftung
AktionsNamen = {
'e': 'erzeugen', 'm': 'mutieren', 's': 'selektieren',
'S': 'zufaellig', 'j': 'behalten', 'z': 'Generation' }
def __init__(self):
# je Messpunkt: (Schrittindex, Aktion, bester, schnitt, schlechtester, N)
self.Punkte = []
def erfassen(self, Aktion, Pool):
"""einen Messpunkt aus dem aktuellen Pool aufnehmen"""
if not Pool:
return
Werte = [ L.value for L in Pool ]
self.Punkte.append( (
len(self.Punkte),
Aktion,
max(Werte),
sum(Werte) / len(Werte),
min(Werte),
len(Werte) ) )
def __repr__(self):
r = "-- Entwicklung (%d Messpunkte):\n" % len(self.Punkte)
for (i, Aktion, best, schnitt, schlecht, n) in self.Punkte:
r = r + (" %3d %-12s best=%s schnitt=%.1f schlecht=%s (N=%d)\n"
% (i, self.AktionsNamen.get(Aktion, Aktion),
best, schnitt, schlecht, n))
return r
def alsSVG(self, OutputSVG, Breite=900, Hoehe=650, Rand=60, PoolHoehe=150):
"""zeichnet den aufgezeichneten Verlauf als SVG-Liniendiagramm
Oberes Panel: Wertigkeit (beste/durchschnittliche/schlechteste
Loesung) ueber die Zyklus-Aktionen. Unteres Panel (PoolHoehe hoch):
Anzahl der erzeugten Verteilungen im Pool je Schritt, auf derselben
Zeitachse. Beide Panels teilen sich die X-Achse.
"""
if not self.Punkte:
raise ValueError("keine Messpunkte aufgezeichnet")
AlleWerte = []
for (_i, _a, best, schnitt, schlecht, _n) in self.Punkte:
AlleWerte.extend( (best, schnitt, schlecht) )
WMin, WMax = min(AlleWerte), max(AlleWerte)
if WMax == WMin:
WMax = WMin + 1 # flache Linie nicht auf den Rand kleben
# Pool-Groessen (N je Messpunkt, Index 5)
NMax = max( p[5] for p in self.Punkte )
if NMax == 0:
NMax = 1
N = len(self.Punkte)
PlotBreite = Breite - 2 * Rand
# Oberes Panel (Wertigkeit) reicht von Rand bis kurz vor das
# untere Panel; dazwischen ein kleiner Zwischenraum (Luecke).
Luecke = 50
OberUnten = Hoehe - Rand - PoolHoehe - Luecke # Unterkante oberes Panel
OberHoehe = OberUnten - Rand
UnterOben = OberUnten + Luecke # Oberkante unteres Panel
UnterUnten = Hoehe - Rand # Unterkante unteres Panel
def X(i):
if N == 1:
return Rand + PlotBreite / 2
return Rand + PlotBreite * i / (N - 1)
def Y(wert):
# hoher (besserer) Wert oben, niedriger unten
return Rand + OberHoehe * (WMax - wert) / (WMax - WMin)
def YPool(n):
# 0 an der Unterkante des unteren Panels, NMax an der Oberkante
return UnterUnten - (UnterUnten - UnterOben) * n / NMax
def Polyline(Index, Farbe, Beschriftung):
punkte = ' '.join( '%.1f,%.1f' % (X(i), Y(p[Index]))
for i, p in enumerate(self.Punkte) )
return ('<polyline points="%s" fill="none" stroke="%s" '
'stroke-width="2"/>\n' % (punkte, Farbe), Beschriftung, Farbe)
Teile = []
Teile.append( '<?xml version="1.0" encoding="UTF-8"?>\n' )
Teile.append(
'<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d" '
'viewBox="0 0 %d %d" font-family="sans-serif">\n'
% (Breite, Hoehe, Breite, Hoehe) )
Teile.append( '<rect width="100%" height="100%" fill="white"/>\n' )
Teile.append(
'<text x="%d" y="30" text-anchor="middle" font-size="16" '
'fill="#333">Entwicklung der Loesungsfindung</text>\n'
% (Breite // 2) )
# --- Oberes Panel: Wertigkeit ---
# Achsen
Teile.append(
'<line x1="%d" y1="%d" x2="%d" y2="%.1f" stroke="#333" '
'stroke-width="1.5"/>\n' % (Rand, Rand, Rand, OberUnten) )
Teile.append(
'<line x1="%d" y1="%.1f" x2="%d" y2="%.1f" stroke="#333" '
'stroke-width="1.5"/>\n'
% (Rand, OberUnten, Breite - Rand, OberUnten) )
# Y-Gitter + Beschriftung (5 Linien)
for k in range(6):
wert = WMin + (WMax - WMin) * k / 5
y = Y(wert)
Teile.append(
'<line x1="%d" y1="%.1f" x2="%d" y2="%.1f" stroke="#eee" '
'stroke-width="1"/>\n' % (Rand, y, Breite - Rand, y) )
Teile.append(
'<text x="%d" y="%.1f" text-anchor="end" font-size="11" '
'fill="#666">%.0f</text>\n' % (Rand - 8, y + 4, wert) )
Teile.append(
'<text x="18" y="%.1f" text-anchor="middle" font-size="12" '
'fill="#333" transform="rotate(-90 18 %.1f)">Wertigkeit '
'(hoeher = besser)</text>\n'
% ((Rand + OberUnten) / 2, (Rand + OberUnten) / 2) )
# die drei Kurven
Kurven = [
Polyline(2, '#2f6f4f', 'beste Loesung'),
Polyline(3, '#c08a2d', 'Durchschnitt'),
Polyline(4, '#a03030', 'schlechteste Loesung') ]
for (svg, _besch, _farbe) in Kurven:
Teile.append( svg )
# Legende oben rechts
LegX = Breite - Rand - 160
LegY = Rand + 10
for k, (_svg, besch, farbe) in enumerate(Kurven):
y = LegY + k * 18
Teile.append(
'<line x1="%d" y1="%d" x2="%d" y2="%d" stroke="%s" '
'stroke-width="2"/>\n' % (LegX, y, LegX + 24, y, farbe) )
Teile.append(
'<text x="%d" y="%d" font-size="11" fill="#333">%s</text>\n'
% (LegX + 30, y + 4, besch) )
# --- Unteres Panel: Anzahl erzeugter Verteilungen (Pool-Groesse) ---
Teile.append(
'<text x="%d" y="%.1f" text-anchor="middle" font-size="13" '
'fill="#333">Anzahl erzeugter Verteilungen im Pool</text>\n'
% (Breite // 2, UnterOben - 12) )
# Achsen
Teile.append(
'<line x1="%d" y1="%.1f" x2="%d" y2="%.1f" stroke="#333" '
'stroke-width="1.5"/>\n' % (Rand, UnterOben, Rand, UnterUnten) )
Teile.append(
'<line x1="%d" y1="%.1f" x2="%d" y2="%.1f" stroke="#333" '
'stroke-width="1.5"/>\n'
% (Rand, UnterUnten, Breite - Rand, UnterUnten) )
# Y-Gitter + Beschriftung (0, Mitte, Max)
for n in (0, NMax // 2, NMax):
y = YPool(n)
Teile.append(
'<line x1="%d" y1="%.1f" x2="%d" y2="%.1f" stroke="#eee" '
'stroke-width="1"/>\n' % (Rand, y, Breite - Rand, y) )
Teile.append(
'<text x="%d" y="%.1f" text-anchor="end" font-size="11" '
'fill="#666">%d</text>\n' % (Rand - 8, y + 4, n) )
# Poolgroessen-Kurve
punkte = ' '.join( '%.1f,%.1f' % (X(i), YPool(p[5]))
for i, p in enumerate(self.Punkte) )
Teile.append(
'<polyline points="%s" fill="none" stroke="#4060a0" '
'stroke-width="2"/>\n' % punkte )
# X-Beschriftung: Aktionsbuchstaben unter dem unteren Panel (bei
# wenigen Punkten alle, sonst ausgeduennt, damit die Achse lesbar
# bleibt)
Schritt = max(1, N // 30)
for i, p in enumerate(self.Punkte):
if i % Schritt == 0 or i == N - 1:
Teile.append(
'<text x="%.1f" y="%.1f" text-anchor="middle" font-size="10" '
'fill="#999">%s</text>\n' % (X(i), UnterUnten + 16, p[1]) )
Teile.append(
'<text x="%d" y="%d" text-anchor="middle" font-size="12" '
'fill="#333">Zyklus-Aktion (Zeit)</text>\n'
% (Breite // 2, Hoehe - 12) )
Teile.append( '</svg>\n' )
fout = open( OutputSVG, 'w' )
fout.writelines( Teile )
fout.close()
class Abstammung:
"""Beobachtungsobjekt: zeichnet den Stammbaum aller Loesungen auf.
Jede Loesung bekommt von der Farm eine fortlaufende Abstammungs-Id.
Jede Loesung hat eine fortlaufende Nummer (Id 1..N); die Abstammung
ergibt sich aus dem gemerkten Vorgaenger (Eltern-Id), nicht aus der Id
selbst. Beim Erzeugen entsteht ein Wurzelknoten (keine Eltern), beim
Mutieren ein Kindknoten mit Verweis auf die Eltern-Id. alsSVG() zeichnet
daraus einen Baum: Generationen als Zeilen (oben Start, nach unten
spaeter), Knoten als Punkte (Farbe = Wertigkeit), Mutationskanten
Eltern->Kind. Domaenen-agnostisch; funktioniert mit jeder Loesung, die
.value hat.
"""
def __init__(self):
# je Knoten: Id -> dict(eltern, generation, value, aktion)
self.Knoten = {}
def erfassen(self, Id, Eltern, Generation, value, Aktion):
self.Knoten[Id] = { 'eltern': Eltern, 'generation': Generation,
'value': value, 'aktion': Aktion }
def __repr__(self):
return "-- Abstammung (%d Loesungen)\n" % len(self.Knoten)
def alsSVG(self, OutputSVG, HervorId=None, Breite=1200, Rand=60,
KnotenAbstand=26, ZeilenHoehe=90):
"""zeichnet den aufgezeichneten Stammbaum als SVG.
HervorId (optional): Id der hervorzuhebenden Loesung (z.B. der
finalen besten). Ihr Ast (die Kette ihrer Vorgaenger) wird kraeftig
gezeichnet und der Knoten mit seiner Nummer beschriftet, so dass man
die ganze Abstammung im Baum verfolgen kann."""
if not self.Knoten:
raise ValueError("keine Abstammung aufgezeichnet")
# Ahnenkette der hervorgehobenen Loesung bestimmen (fuer die
# kraeftige Darstellung ihres Astes)
Ahnen = set()
Id = HervorId
while Id is not None and Id in self.Knoten:
Ahnen.add(Id)
Id = self.Knoten[Id]['eltern']
# Knoten nach Generation gruppieren
Generationen = {}
for Id, K in self.Knoten.items():
Generationen.setdefault( K['generation'], [] ).append(Id)
GenListe = sorted(Generationen)
# je Generation die Knoten stabil sortieren (nach Id), damit das Bild
# reproduzierbar ist
for g in Generationen:
Generationen[g].sort()
MaxBreiteKnoten = max( len(v) for v in Generationen.values() )
PlotBreite = max( Breite - 2 * Rand, MaxBreiteKnoten * KnotenAbstand )
Breite = PlotBreite + 2 * Rand
Hoehe = Rand * 2 + (len(GenListe) - 1) * ZeilenHoehe + 40
# Position (x,y) je Knoten-Id bestimmen
Pos = {}
for gi, g in enumerate(GenListe):
Ids = Generationen[g]
n = len(Ids)
y = Rand + gi * ZeilenHoehe
for k, Id in enumerate(Ids):
# horizontal mittig ausrichten
if n == 1:
x = Rand + PlotBreite / 2
else:
x = Rand + PlotBreite * k / (n - 1)
Pos[Id] = (x, y)
# Wertebereich fuer die Knotenfarbe (gut = gruen, schlecht = rot)
Werte = [ K['value'] for K in self.Knoten.values() ]
WMin, WMax = min(Werte), max(Werte)
if WMax == WMin:
WMax = WMin + 1
def Farbe(v):
t = (v - WMin) / (WMax - WMin) # 0 schlecht .. 1 gut
r = int(200 * (1 - t) + 40 * t)
gg = int(50 * (1 - t) + 140 * t)
b = int(50 * (1 - t) + 80 * t)
return '#%02x%02x%02x' % (r, gg, b)
Teile = []
Teile.append( '<?xml version="1.0" encoding="UTF-8"?>\n' )
Teile.append(
'<svg xmlns="http://www.w3.org/2000/svg" width="%d" height="%d" '
'viewBox="0 0 %d %d" font-family="sans-serif">\n'
% (Breite, Hoehe, Breite, Hoehe) )
Teile.append( '<rect width="100%" height="100%" fill="white"/>\n' )
Teile.append(
'<text x="%d" y="30" text-anchor="middle" font-size="16" '
'fill="#333">Abstammung der Loesungen (Mutationsbaum)</text>\n'
% (Breite // 2) )
# zuerst die Kanten Eltern -> Kind (darunter liegend). Kanten entlang
# des hervorgehobenen Astes kraeftig, der Rest blass.
for Id, K in self.Knoten.items():
Eltern = K['eltern']
if Eltern is None or Eltern not in Pos or Id not in Pos:
continue
x1, y1 = Pos[Eltern]
x2, y2 = Pos[Id]
ImAst = Id in Ahnen and Eltern in Ahnen
Stil = ('stroke="#c04040" stroke-width="2.5"' if ImAst
else 'stroke="#bbb" stroke-width="1"')
Teile.append(
'<line x1="%.1f" y1="%.1f" x2="%.1f" y2="%.1f" %s/>\n'
% (x1, y1, x2, y2, Stil) )
# dann die Knoten
for Id, K in self.Knoten.items():
if Id not in Pos:
continue
x, y = Pos[Id]
r = 7 if Id in Ahnen else 5
Rahmen = ('stroke="#c04040" stroke-width="2"' if Id in Ahnen
else 'stroke="#333" stroke-width="0.5"')
Teile.append(
'<circle cx="%.1f" cy="%.1f" r="%d" fill="%s" %s>'
'<title>Id %s, Wert %.1f</title></circle>\n'
% (x, y, r, Farbe(K['value']), Rahmen, Id, K['value']) )
# die hervorgehobene Loesung mit ihrer sprechenden Abstammungs-Id
# beschriften (aus ihr laesst sich die ganze Herkunft ablesen)
if HervorId in Pos:
x, y = Pos[HervorId]
Teile.append(
'<text x="%.1f" y="%.1f" text-anchor="middle" font-size="12" '
'font-weight="bold" fill="#c04040">%s</text>\n'
% (x, y + 22, HervorId) )
# Generationsbeschriftung links
for gi, g in enumerate(GenListe):
y = Rand + gi * ZeilenHoehe
Teile.append(
'<text x="%d" y="%.1f" text-anchor="end" font-size="11" '
'fill="#666">Gen %s</text>\n' % (Rand - 12, y + 4, g) )
Teile.append( '</svg>\n' )
fout = open( OutputSVG, 'w' )
fout.writelines( Teile )
fout.close()
class Farm:
"""enthaelt und pflegt Loesungsobjekte, kreuzt, mutiert, selektiert sie"""
def __init__(self, Zyklus, Klasse, *Arguments, **keywords):
"""initialisiere die Farm
mit einem definerten Zyklus fuer die Zucht und dem gewunschten zu Zuchtobjekt
Beobachtung: self.Entwicklung zeichnet nach jeder Zyklus-Aktion
den Pool-Zustand auf und laesst sich per alsSVG() visualisieren.
"""
self.Position = 0
self.Pool = []
self.PoolNeu = []
self.Zyklus = Zyklus
self.Klasse = Klasse
for Aktion, Zahl in zip(Zyklus.Abfolge,Zyklus.Anzahl):
#print 'Aktion:',Aktion
#print 'Zahl:',Zahl
self.Entwicklung = Entwicklung()
# Abstammung: jede Loesung bekommt eine fortlaufende _absid; die
# aktuelle Generationsnummer waechst mit jedem Erzeugen/Mutieren.
self.Abstammung = Abstammung()
self._AbsZaehler = 0 # vergibt fortlaufende Loesungs-Ids 1..N
self._Generation = 0
# schon gesehene Loesungs-Signaturen (getGruppenId), damit dieselbe
# Sitzordnung nicht mehrfach gehalten und bewertet wird.
self._GeseheneGruppenIds = set()
if getattr(Zyklus, 'Modus', 'statisch') == 'adaptiv':
self._LaufAdaptiv(Klasse, *Arguments, **keywords)
else:
self._LaufStatisch(Klasse, *Arguments, **keywords)
def _Aufzeichnen(self, Aktion):
"""nach einer Aktion den aktuellen Pool-Zustand fuer die
Entwicklungsgrafik erfassen. Der beobachtete Pool ist der, in dem
gerade die Loesungen liegen: PoolNeu, sobald dort etwas gesammelt
wurde, sonst Pool."""
self.Entwicklung.erfassen(
Aktion, self.PoolNeu if self.PoolNeu else self.Pool )
def _LaufStatisch(self, Klasse, *Arguments, **keywords):
"""klassischer Ablauf: die Abfolge/Anzahl aus zyklus.cfg abspielen."""
for Aktion, Zahl in zip(self.Zyklus.Abfolge, self.Zyklus.Anzahl):
self.Position = self.Position + 1
if Aktion == 'e':
self.LoesungenErzeugen(int(Zahl), Klasse, *Arguments, **keywords)
@@ -100,95 +536,198 @@ class Farm:
self.NeueGeneration()
else:
pass
self._Aufzeichnen(Aktion)
def _LaufAdaptiv(self, Klasse, *Arguments, **keywords):
"""adaptiver Ablauf: viele Startloesungen, dann Generationen mit
schrumpfender Population; Abbruch, sobald sich die beste Bewertung
ueber 'Geduld' Generationen um weniger als 'Schwelle' verbessert."""
P = self.Zyklus.Adaptiv
Population = max( int(P['Start']), int(P['MinPopulation']) )
# Startpopulation erzeugen (der 'maximale Anfangswert')
self.LoesungenErzeugen(Population, Klasse, *Arguments, **keywords)
self._Aufzeichnen('e')
BesterWert = max(self.Pool).value
OhneVerbesserung = 0
for Gen in range(int(P['MaxGenerationen'])):
self.Position = self.Position + 1
# Mutationskinder erzeugen (in PoolNeu) und die Eltern (Pool)
# dazunehmen, so dass PoolNeu Eltern + Kinder als Kandidaten haelt.
self.LoesungenMutieren( int(P['MutationProLoesung']) )
self._Aufzeichnen('m')
self.LoesungenBehalten() # PoolNeu += Pool
self.NeueGeneration() # Pool = PoolNeu (Kandidaten), PoolNeu leer
self._Aufzeichnen('j')
# Population fuer die naechste Generation schrumpfen (nie unter
# MinPopulation) und den Kandidatenpool auf die besten K trunkieren.
Population = max( int(P['MinPopulation']),
int(Population * float(P['Schrumpfung'])) )
self.PopulationBegrenzen( Population )
self._Aufzeichnen('s')
# Konvergenz pruefen
AktuellBest = max(self.Pool).value
if AktuellBest - BesterWert >= float(P['Schwelle']):
OhneVerbesserung = 0
else:
OhneVerbesserung = OhneVerbesserung + 1
if AktuellBest > BesterWert:
BesterWert = AktuellBest
print("+ Generation %d: bester Wert %.1f, Population %d, "
"ohne Verbesserung %d" % (Gen + 1, AktuellBest, len(self.Pool),
OhneVerbesserung))
if OhneVerbesserung >= int(P['Geduld']):
print("+ Abbruch: %d Generationen ohne nennenswerte "
"Verbesserung" % OhneVerbesserung)
break
def _NeueId(self):
"""neue Id fuer eine Loesung: eine fortlaufende Nummer 1..N ueber
alle je erzeugten Loesungen (Wurzeln wie Mutationskinder gleich).
Die Abstammung ergibt sich nicht aus der Id, sondern aus dem
separat gemerkten Vorgaenger (siehe erfassen(..., Eltern))."""
self._AbsZaehler = self._AbsZaehler + 1
return self._AbsZaehler
def _LoesungIstNeu(self, L):
"""Kontrolle nach jeder Erzeugung: True, wenn die Loesung eine bisher
ungesehene Sitzordnung hat (Vergleich ueber getGruppenId, also auf
Gruppen-Ebene) - und merkt sie dann vor. Duplikate (gleiche Sitz-
ordnung) werden so nicht noch einmal gehalten und bewertet.
Loesungen ohne getGruppenId gelten immer als neu (kein Dedup)."""
Hole = getattr(L, 'getGruppenId', None)
if Hole is None:
return True
Gid = Hole()
if Gid in self._GeseheneGruppenIds:
return False
self._GeseheneGruppenIds.add(Gid)
return True
def LoesungenErzeugen(self, N, Klasse, *Arguments, **keywords):
""" Erzeuge Loesungen"""
for i in xrange(N):
""" Erzeuge Loesungen (bereits gesehene Sitzordnungen werden verworfen)"""
for i in range(N):
L = Klasse( *Arguments, **keywords )
if not self._LoesungIstNeu(L):
continue # gleiche Sitzordnung schon vorhanden -> nicht behalten
L._absid = self._NeueId() # Wurzel: kein Vorgaenger
self.Abstammung.erfassen(
L._absid, None, self._Generation, getattr(L, 'value', 0), 'e' )
self.Pool.append(L)
#print repr(len(self.Pool)) + ' Loesungsobjekte erzeugt'
#print(repr(len(self.Pool)) + ' Loesungsobjekte erzeugt')
def LoesungenKreuzen(self,N):
"""mache aus zwei Loesungen eine neue"""
#print "+ Loesungen kreuzen"
for i in xrange(N):
#print("+ Loesungen kreuzen")
for i in range(N):
self.Pool.append(self.Pool[i].kreuzen())
def LoesungenMutieren(self, N):
"""veraendere die Loesung, so dass sie hoffentlich besser wird"""
print "+ Loesungen mutieren: ", N
for n in xrange(N):
#print " -"+repr(n+1)+" mal"
print("+ Loesungen mutieren: ", N)
self._Generation = self._Generation + 1
for n in range(N):
#print(" -"+repr(n+1)+" mal")
for L in chain(self.Pool):
O = deepcopy(L)
self.PoolNeu.append(O.mutieren())
#print self
Kind = O.mutieren()
if not self._LoesungIstNeu(Kind):
continue # gleiche Sitzordnung schon gesehen -> verwerfen
# Kind bekommt eine neue fortlaufende Nummer; der Vorgaenger
# (Eltern-Id) wird separat in der Abstammung gemerkt.
ElternId = getattr(L, '_absid', None)
Kind._absid = self._NeueId()
self.Abstammung.erfassen(
Kind._absid, ElternId, self._Generation,
getattr(Kind, 'value', 0), 'm' )
self.PoolNeu.append(Kind)
#print(self)
def LoesungenBehalten(self):
"""Behalte alle Eltern aus dem alten Pool"""
print "+ alten Loesungspool behalten"
print("+ alten Loesungspool behalten")
self.PoolNeu = self.PoolNeu + self.Pool
#print self
#print(self)
def NeueGeneration(self):
"""Loesche alle bisherigen Eltern und mache einen neuen Zyklus"""
print "+ Neue Generation erzeugen"
print("+ Neue Generation erzeugen")
self.Pool = self.PoolNeu
self.PoolNeu = []
#print self
#print "---------------"
#print(self)
#print("---------------")
def LoesungenAuswaehlen(self, N):
"""Selektiere die besten Loesungen"""
print "+ die besten -", repr(N) +" - Loesungen auswaehlen -"
for i in xrange(N):
print("+ die besten -", repr(N) +" - Loesungen auswaehlen -")
for i in range(N):
L = max(self.Pool)
self.PoolNeu.append(L)
self.Pool.remove(L)
#print self
#print(self)
def PopulationBegrenzen(self, K):
"""Trunkierungs-Selektion: behalte im Pool nur die K besten
Loesungen und verwirf den Rest. Anders als LoesungenAuswaehlen
(das additiv nach PoolNeu verschiebt) veraendert dies den Pool an
Ort und Stelle - fuer die adaptive Generationenschleife, damit die
Population wirklich schrumpft."""
K = max( 0, min( K, len(self.Pool) ) )
self.Pool = sorted( self.Pool, reverse=True )[:K]
print("+ Population auf %d beste begrenzt" % K)
def LoesungenZufaelligAuswaehlen(self, N):
"""Selektiere zufaellig Loesungen"""
print "+ zufaellig auswaehlen -"+ repr(N) + "-"
for i in xrange(N):
print("+ zufaellig auswaehlen -"+ repr(N) + "-")
for i in range(N):
self.PoolNeu.append(choice(self.Pool))
#print self
#print(self)
def __repr__(self):
"""Drucke die Farm am Bildschirm aus"""
return( " gewaehlte Objekte (%d): %s\n"
" Elternobjekte (%d) : %s\n"
% ( len(self.PoolNeu), self.PoolNeu,
% ( len(self.PoolNeu), self.PoolNeu,
len(self.Pool), self.Pool))
def laden(self):
print "+ laden"
print("+ laden")
def speichern(self):
print "+ speichern"
print("+ speichern")
def Bester(self):
return max(self.Pool)
return max(self.Pool)
def TopN(self, N):
"""die N besten Loesungen, absteigend nach Wertigkeit sortiert.
Erweiterung von Bester() (das nur die einzelne beste liefert): gibt
eine Liste der bis zu N besten Loesungen zurueck, damit sich mehrere
gute Alternativen betrachten lassen. N wird auf [0, len(Pool)]
begrenzt; bei N >= Poolgroesse ist es der ganze Pool (sortiert)."""
N = max( 0, min( N, len(self.Pool) ) )
return sorted( self.Pool, reverse=True )[:N]
if __name__ == '__main__':
print "\n-- Erzeuge Zyklus:"
#Z = Zyklus( Name='Easy',
print("\n-- Erzeuge Zyklus:")
#Z = Zyklus( Name='Easy',
#Abfolge='e,s,+,m,j,S,+',
#Anzahl='10,5,x,2,x,5,x'
#)
Z = Zyklus( Name='Easy',
Abfolge='e,'+'s,z,m,j,z,'*3+'s',
Anzahl='10,'+'5,x,2,x,x,'*3+'1'
Z = Zyklus( Name='Easy',
Abfolge='e,'+'s,z,m,j,z,'*3+'s',
Anzahl='10,'+'5,x,2,x,x,'*3+'1'
)
print Z
print(Z)
print "\n-- Erzeuge Loesungen:"
print("\n-- Erzeuge Loesungen:")
L1 = Loesung()
L2 = Loesung()
L3 = Loesung()
print L1, L2, L3
print 'L1 > L2 =', L1 > L2
print 'L2 > L3 =', L2 > L3
print 'L1 > L3 =', L1 > L3
print(L1, L2, L3)
print('L1 > L2 =', L1 > L2)
print('L2 > L3 =', L2 > L3)
print('L1 > L3 =', L1 > L3)
A=2
B=3
print "\n-- Erzeuge Farm:"
print("\n-- Erzeuge Farm:")
F1 = Farm( Z, Loesung, Arg1=A, Arg2=B, Arg3=L1 )
print F1
print(F1)
else:
pass
+118 -35
View File
@@ -11,63 +11,146 @@ __license__ = "Python"
from ga import *
from Strukturdaten import *
import ConfigParser
from Farben import Farbschema
import optparse
import random
if __name__ == '__main__':
# lade Vorgaben fuer Optimierungszyklus und
config = ConfigParser.ConfigParser()
ConfigPath= os.path.join( os.getenv('PLATZ_CFG'), 'platz.cfg')
config.read( os.path.expandvars( ConfigPath ))
# Kommandozeilenoption --indir: Verzeichnis mit den Eingabedateien
# (tische.ini, bestellung.json) und Ziel fuer die Ausgabedateien
# (TischePersonen.txt, PersonenTische.csv)
parser = optparse.OptionParser()
parser.add_option( "--indir", dest="indir", default=None,
help="Verzeichnis mit tische.ini und bestellung.json; "
"dort werden auch TischePersonen.txt und PersonenTische.csv abgelegt" )
parser.add_option( "--tosvg", dest="tosvg", action="store_true", default=False,
help="zusaetzlich eine Sitzplatzverteilung.svg im --indir Verzeichnis "
"erzeugen (Tische als weisse Kreise, Personen als farbige "
"Kreise je Gruppe)" )
parser.add_option( "--show-connections", dest="showconn", action="store_true",
default=True,
help="in der Sitzplatzverteilung.svg jede ueber mehrere Tische "
"getrennte Gruppe mit einer Linie in ihrer Gruppenfarbe "
"verbinden (Vorgabe: an; nur mit --tosvg wirksam)" )
parser.add_option( "--hide-connections", dest="showconn",
action="store_false",
help="die Verbindungslinien getrennter Gruppen in der "
"Sitzplatzverteilung.svg nicht zeichnen" )
parser.add_option( "--show-development", dest="showdev", action="store_true",
default=False,
help="zusaetzlich eine Entwicklung.svg im --indir Verzeichnis "
"erzeugen: Verlauf der Loesungsfindung (Zeitachse nach rechts, "
"beste/durchschnittliche/schlechteste Wertigkeit auf der Y-Achse)" )
parser.add_option( "--show-lineage", dest="showlineage", action="store_true",
default=False,
help="zusaetzlich eine Abstammung.svg im --indir Verzeichnis "
"erzeugen: Stammbaum aller Loesungen (Mutationsbaum); der Ast der "
"finalen besten Loesung ist hervorgehoben und mit ihrer "
"Abstammungs-Id beschriftet" )
parser.add_option( "--zyklus-art", dest="zyklusart", default="Adaptiv",
help="Name des GA-Profils in zyklus.cfg (Vorgabe: Adaptiv). "
"Weitere mitgelieferte Profile: Easy, Simple" )
parser.add_option( "--strafen", dest="strafen", default="default",
help="Name des Strafpunkte-Profils (Sektion in strafen.cfg; "
"Vorgabe: default). Erlaubt mehrere Bewertungs-Vorgehen in einer "
"Datei, z.B. --strafen locker" )
parser.add_option( "--farben", dest="farben", default="grosse_gruppen",
help="Name des Farbprofils fuer die SVG-Ausgabe (Sektion in "
"farben.cfg; Vorgabe: grosse_gruppen). Fuer Hochzeiten: "
"--farben hochzeit (Familien/Vereine/VIPs getrennt)" )
parser.add_option( "--seed", dest="seed", type="int", default=None,
help="Zufalls-Startwert (int) fuer random.seed(), macht den Lauf "
"reproduzierbar. Ohne Angabe laeuft der GA nichtdeterministisch. "
"Fuer Support-Rueckfragen ('warum sitzt Tante Erna dort?') mit "
"demselben --seed exakt denselben Sitzplan erneut erzeugen" )
(options, args) = parser.parse_args()
Zyklusconfig = os.path.normpath( config.get( 'Config', 'Zyklusdatei' ))
Zyklusconfig = os.path.expandvars( Zyklusconfig )
Zyklusart = config.get( 'Config', 'Zyklusart' )
# Determinismus auf Wunsch: den globalen Zufallsgenerator seeden, bevor
# irgendeine GA-Aktion laeuft. Der gesamte Algorithmus (ga.py und
# Strukturdaten.py nutzen 'from random import *') zieht aus demselben
# Modul-RNG, daher genuegt ein einziges random.seed() hier.
if options.seed is not None:
random.seed( options.seed )
print( "Determinismus: random.seed(%d) - Lauf ist reproduzierbar"
% options.seed )
Strafenconfig = os.path.normpath(config.get( 'Config', 'Strafendatei' ))
Strafenconfig = os.path.expandvars( Strafenconfig )
## print Strafenconfig
if options.indir is None:
parser.error( "--indir ist erforderlich" )
InDir = os.path.expandvars( os.path.expanduser( options.indir ) )
if not os.path.isdir( InDir ):
parser.error( "--indir '%s' ist kein Verzeichnis" % InDir )
# zyklus.cfg (GA-Profile) und strafen.cfg (Strafpunkte) direkt aus dem
# per $PLATZ_CFG bestimmten cfg-Verzeichnis laden. Das GA-Profil waehlt
# der Schalter --zyklus-art (Vorgabe: Adaptiv).
CfgDir = os.getenv('PLATZ_CFG')
if not CfgDir:
parser.error( "Umgebungsvariable PLATZ_CFG ist nicht gesetzt "
"(bin/setenv aufrufen)" )
Zyklusconfig = os.path.join( CfgDir, 'zyklus.cfg' )
Zyklusart = options.zyklusart
Strafenconfig = os.path.join( CfgDir, 'strafen.cfg' )
Strafenart = options.strafen
Farbenconfig = os.path.join( CfgDir, 'farben.cfg' )
Farbenart = options.farben
# lade Eingabedateien
Tischconfig = os.path.normpath(config.get( 'Config', 'Tischedatei' ))
Tischconfig = os.path.expandvars(Tischconfig)
Bestellung = os.path.normpath(config.get( 'Config', 'XMLdatei_Bestellung' ))
Bestellung = os.path.expandvars( Bestellung )
Tischconfig = os.path.join( InDir, 'tische.ini' )
Bestellung = os.path.join( InDir, 'bestellung.json' )
# lade Ausgabedateien
AusgabeTP= os.path.normpath(config.get( 'Config', 'AusgabeTischePersonen' ))
AusgabeTP = os.path.expandvars(AusgabeTP)
AusgabePT = os.path.normpath(config.get( 'Config', 'AusgabePersonTisch' ))
AusgabePT = os.path.expandvars(AusgabePT)
AusgabeTP= os.path.join( InDir, 'TischePersonen.txt' )
AusgabePT = os.path.join( InDir, 'PersonenTische.csv' )
AusgabeSVG = os.path.join( InDir, 'Sitzplatzverteilung.svg' )
AusgabeEntwicklung = os.path.join( InDir, 'Entwicklung.svg' )
AusgabeAbstammung = os.path.join( InDir, 'Abstammung.svg' )
Z = Zyklus()
Z.laden( Zyklusconfig, Zyklusart )
print Z
print(Z)
SL = Strafliste()
SL.laden( Strafenconfig )
print SL
try:
SL.laden( Strafenconfig, Strafenart )
except ValueError as Fehler:
parser.error( str(Fehler) )
print(SL)
FS = Farbschema()
try:
FS.laden( Farbenconfig, Farbenart )
except ValueError as Fehler:
parser.error( str(Fehler) )
TE = Tische()
TE.laden( Tischconfig )
print TE
print(TE)
InputFile = XMLConfig()
[ PN, GN, VIPGruppe, VIPListePT ] = InputFile.laden( Bestellung )
print PN
print GN
print VIPGruppe
print VIPListePT
InputFile = JSONConfig()
[ PN, GN, VIPGruppe, VIPListePT, GruppenNamen ] = InputFile.laden( Bestellung )
print(PN)
print(GN)
print(VIPGruppe)
print(VIPListePT)
print "\n-- Erzeuge Farm:"
print("\n-- Erzeuge Farm:")
F1 = Farm( Z, Sitzplatzverteilung, Tische=TE, Gruppen=GN, Strafen=SL, VIPListe=VIPListePT, VIPs=VIPGruppe )
#print F1
#print(F1)
S = F1.Bester()
print S
print(S)
S.speichern( AusgabeTP, AusgabePT )
if options.tosvg:
S.alsSVG( AusgabeSVG, Verbindungen=options.showconn,
GruppenNamen=GruppenNamen, Farbschema=FS )
if options.showdev:
F1.Entwicklung.alsSVG( AusgabeEntwicklung )
print( "Entwicklungsverlauf geschrieben:", AusgabeEntwicklung )
if options.showlineage:
F1.Abstammung.alsSVG( AusgabeAbstammung,
HervorId=getattr(S, '_absid', None) )
print( "Abstammungsbaum geschrieben:", AusgabeAbstammung )
else:
pass
+376
View File
@@ -0,0 +1,376 @@
"""
Plattformunabhaengige Prozessverwaltung fuer die Web-Testinstanz
(ersetzt die fruehere PowerShell-Loesung run_web_helper.ps1, damit
dasselbe Skript unter Windows und Linux funktioniert).
Aufruf (ueber bin/run_web.bat bzw. bin/run_web.sh oder direkt):
python libs/webserver.py start # Server im Hintergrund starten
python libs/webserver.py stop # Server beenden
python libs/webserver.py status # laeuft er? PID? Port?
python libs/webserver.py run # im Vordergrund (Strg+C beendet)
python libs/webserver.py # wie "run"
--port N weicht vom Standardport 8000 ab
Designentscheidung gegen Zombie-Prozesse: Im Hintergrundbetrieb
("start") laeuft uvicorn OHNE --reload als ein einzelner Prozess,
der per PID-Datei sauber beendet werden kann. Der Auto-Reload
(--reload) startet Arbeitsprozesse als multiprocessing-Spawn-Kinder,
die bei unsanftem Ende des Reloaders MIT geerbtem Server-Socket
weiterleben und den Port unsichtbar weiterbedienen koennen (unter
Windows tauchen sie weder als Socket-Besitzer noch mit "uvicorn" in
der Kommandozeile auf). Deshalb gibt es --reload nur im
Vordergrundmodus ("run"), wo Strg+C alles gemeinsam beendet.
"""
__author__ = "Michael Stangl"
__copyright__ = "Copyright (c) 2026 Michael Stangl"
__license__ = "Python"
import argparse
import json
import os
import signal
import socket
import subprocess
import sys
import time
import urllib.request
BASISDIR = os.path.dirname( os.path.dirname( os.path.abspath( __file__ ) ) )
WEBDIR = os.path.join( BASISDIR, 'web' )
LOGDIR = os.path.join( BASISDIR, 'log' )
PIDDATEI = os.path.join( LOGDIR, 'run_web.pid' )
LOGDATEI = os.path.join( LOGDIR, 'run_web.log' )
HOST = '127.0.0.1'
STANDARDPORT = 8000
APPTITEL = 'Sitz & Platz' # steht im OpenAPI-Titel von web/main.py
# ---------------------------------------------------------------- Sonden
def PortOffen(Port):
"""True, wenn auf dem Port etwas Verbindungen annimmt"""
with socket.socket( socket.AF_INET, socket.SOCK_STREAM ) as s:
s.settimeout( 1.0 )
return s.connect_ex( (HOST, Port) ) == 0
def IstUnsereApp(Port):
"""True/False, ob auf dem Port unsere FastAPI-App antwortet;
None, wenn keine (verwertbare) Antwort kommt"""
try:
with urllib.request.urlopen(
'http://%s:%d/openapi.json' % (HOST, Port), timeout=3 ) as antwort:
daten = json.load( antwort )
return APPTITEL in daten.get( 'info', {} ).get( 'title', '' )
except Exception:
return None
def PidLebt(Pid):
"""True, wenn der Prozess existiert (portabel)"""
if Pid is None or Pid <= 0:
return False
if sys.platform == 'win32':
# os.kill(pid, 0) ist unter Windows unbrauchbar (wirft WinError 87
# statt zu pruefen). Stattdessen im Toolhelp-Snapshot nachsehen.
return Pid in _ProzessTabelle()
try:
os.kill( Pid, 0 )
return True
except PermissionError:
return True # existiert, gehoert aber jemand anderem
except OSError:
return False
# ------------------------------------------------------------- PID-Datei
def PidLesen():
try:
with open( PIDDATEI ) as f:
return int( f.read().strip() )
except (OSError, ValueError):
return None
def PidSchreiben(Pid):
os.makedirs( LOGDIR, exist_ok=True )
with open( PIDDATEI, 'w' ) as f:
f.write( '%d\n' % Pid )
def PidLoeschen():
try:
os.remove( PIDDATEI )
except OSError:
pass
def ListenerPid(Port):
"""PID des Prozesses, der auf dem Port lauscht (Fallback, wenn die
PID-Datei fehlt); None wenn nicht feststellbar"""
try:
if sys.platform == 'win32':
ausgabe = subprocess.run(
['netstat', '-ano', '-p', 'tcp'],
capture_output=True, text=True, timeout=10 ).stdout
for zeile in ausgabe.splitlines():
teile = zeile.split()
# Zustandsspalte NICHT auf "LISTENING" pruefen - netstat
# ist lokalisiert (deutsch: "ABHOEREN"). Ein Listener ist
# an der Gegenstelle 0.0.0.0:0 erkennbar; PID = letzte Spalte.
if ( len(teile) >= 5 and teile[0] == 'TCP'
and teile[1].endswith( ':%d' % Port )
and teile[2] in ('0.0.0.0:0', '[::]:0') ):
return int( teile[-1] )
else:
ausgabe = subprocess.run(
['ss', '-tlnp'],
capture_output=True, text=True, timeout=10 ).stdout
for zeile in ausgabe.splitlines():
if ':%d ' % Port in zeile and 'pid=' in zeile:
return int( zeile.split('pid=')[1].split(',')[0] )
except (OSError, ValueError, subprocess.SubprocessError):
pass
return None
# ------------------------------------------------- Prozessbaum-Hilfen
def _ProzessTabelle():
"""{ Pid: (ElternPid, Prozessname) } aller laufenden Prozesse -
Windows ueber einen Toolhelp-Snapshot (ctypes, Standardbibliothek),
Linux ueber /proc"""
tabelle = {}
if sys.platform == 'win32':
import ctypes
import ctypes.wintypes as wt
class PROCESSENTRY32(ctypes.Structure):
_fields_ = [
('dwSize', wt.DWORD), ('cntUsage', wt.DWORD),
('th32ProcessID', wt.DWORD),
('th32DefaultHeapID', ctypes.POINTER( ctypes.c_ulong )),
('th32ModuleID', wt.DWORD), ('cntThreads', wt.DWORD),
('th32ParentProcessID', wt.DWORD),
('pcPriClassBase', ctypes.c_long),
('dwFlags', wt.DWORD), ('szExeFile', ctypes.c_char * 260) ]
TH32CS_SNAPPROCESS = 0x2
k32 = ctypes.windll.kernel32
schnappschuss = k32.CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 )
if schnappschuss == -1:
return tabelle
eintrag = PROCESSENTRY32()
eintrag.dwSize = ctypes.sizeof( PROCESSENTRY32 )
if k32.Process32First( schnappschuss, ctypes.byref( eintrag ) ):
while True:
tabelle[ int(eintrag.th32ProcessID) ] = (
int(eintrag.th32ParentProcessID),
eintrag.szExeFile.decode( errors='replace' ).lower() )
if not k32.Process32Next( schnappschuss,
ctypes.byref( eintrag ) ):
break
k32.CloseHandle( schnappschuss )
else:
for name in os.listdir( '/proc' ):
if not name.isdigit():
continue
try:
with open( '/proc/%s/stat' % name ) as f:
stat = f.read()
# Format: pid (comm) zustand ppid ... - comm kann
# Leerzeichen enthalten, daher an der Klammer trennen
kommando = stat[ stat.index('(') + 1 : stat.rindex(')') ]
felder = stat[ stat.rindex(')') + 2 : ].split()
tabelle[ int(name) ] = ( int(felder[1]), kommando.lower() )
except (OSError, ValueError, IndexError):
continue
return tabelle
def ProzessWurzel(Pid):
"""laeuft vom Prozess die Elternkette hoch, solange die Eltern auch
Python-Prozesse sind, und liefert die Wurzel des Python-Baums.
Noetig fuer fremde/alte --reload-Server: wird nur der Arbeits-
prozess beendet, startet der Reloader ihn sofort neu."""
tabelle = _ProzessTabelle()
aktuell = Pid
for _ in range( 10 ): # Schutz gegen Zyklen
eintrag = tabelle.get( aktuell )
if eintrag is None:
break
eltern, _name = eintrag
elternEintrag = tabelle.get( eltern )
if elternEintrag is None or not elternEintrag[1].startswith( 'python' ):
break
aktuell = eltern
return aktuell
# ------------------------------------------------------------- Aktionen
def UvicornKommando(Port, Reload):
Kommando = [ sys.executable, '-m', 'uvicorn', 'main:app',
'--app-dir', WEBDIR, '--port', str(Port) ]
if Reload:
Kommando.append( '--reload' )
return Kommando
def Starten(Port):
if PortOffen( Port ):
if IstUnsereApp( Port ):
print( 'Server laeuft bereits: http://localhost:%d' % Port )
else:
print( 'FEHLER: Port %d ist von einem fremden Programm belegt.' % Port )
return 1
os.makedirs( LOGDIR, exist_ok=True )
logdatei = open( LOGDATEI, 'w' )
# vom Terminal abkoppeln, damit der Server das Schliessen der
# Konsole ueberlebt; eigene Prozessgruppe fuer sauberes Beenden
if sys.platform == 'win32':
flags = ( subprocess.DETACHED_PROCESS
| subprocess.CREATE_NEW_PROCESS_GROUP )
prozess = subprocess.Popen(
UvicornKommando( Port, Reload=False ),
stdout=logdatei, stderr=subprocess.STDOUT,
cwd=BASISDIR, creationflags=flags )
else:
prozess = subprocess.Popen(
UvicornKommando( Port, Reload=False ),
stdout=logdatei, stderr=subprocess.STDOUT,
cwd=BASISDIR, start_new_session=True )
PidSchreiben( prozess.pid )
# warten bis der Port antwortet (oder der Prozess frueh stirbt)
for _ in range( 30 ):
if prozess.poll() is not None:
print( 'FEHLER: Server sofort wieder beendet - siehe %s' % LOGDATEI )
PidLoeschen()
return 1
if PortOffen( Port ):
print( 'Server laeuft: http://localhost:%d (PID %d, Log: %s)'
% (Port, prozess.pid, os.path.relpath( LOGDATEI, BASISDIR )) )
print( 'Hinweis: Hintergrundbetrieb ohne Auto-Reload - fuer '
'Entwicklung mit Reload "run" im Vordergrund nutzen.' )
return 0
time.sleep( 0.5 )
print( 'FEHLER: Server antwortet nicht auf Port %d - siehe %s'
% (Port, LOGDATEI) )
return 1
def BaumBeenden(Pid):
"""beendet einen Prozess samt Kindprozessen (portabel)"""
if sys.platform == 'win32':
subprocess.run( ['taskkill', '/PID', str(Pid), '/T', '/F'],
capture_output=True )
else:
try:
os.killpg( os.getpgid( Pid ), signal.SIGTERM )
except (ProcessLookupError, PermissionError, OSError):
try:
os.kill( Pid, signal.SIGTERM )
except OSError:
pass
# kurze Gnadenfrist, dann hart nachsetzen
for _ in range( 10 ):
if not PidLebt( Pid ):
return
time.sleep( 0.3 )
try:
os.killpg( os.getpgid( Pid ), signal.SIGKILL )
except (ProcessLookupError, PermissionError, OSError):
pass
def Stoppen(Port):
gefunden = False
Pid = PidLesen()
if Pid is not None and PidLebt( Pid ):
BaumBeenden( Pid )
gefunden = True
# Fallback: PID-Datei fehlt/veraltet, aber es lauscht noch jemand -
# dann die Wurzel des Python-Prozessbaums beenden (sonst startet ein
# --reload-Elternprozess den abgeschossenen Worker sofort neu)
if PortOffen( Port ):
LPid = ListenerPid( Port )
if LPid is not None and PidLebt( LPid ):
BaumBeenden( ProzessWurzel( LPid ) )
gefunden = True
# nachpruefen, ob der Port wirklich frei geworden ist
for _ in range( 10 ):
if not PortOffen( Port ):
break
time.sleep( 0.3 )
PidLoeschen()
if PortOffen( Port ):
print( 'WARNUNG: Auf Port %d antwortet immer noch etwas. Moeglicher '
'verwaister Prozess mit geerbtem Socket - Kandidaten mit '
'"netstat -ano" (Windows) bzw. "ss -tlnp" (Linux) suchen.'
% Port )
return 1
print( 'Beendet.' if gefunden else 'Es lief nichts.' )
return 0
def Status(Port):
Pid = PidLesen()
if PortOffen( Port ):
Zusatz = ''
if Pid is not None and PidLebt( Pid ):
# uvicorn haelt den Port oft in einem Kindprozess des in der
# PID-Datei vermerkten Hauptprozesses - das ist derselbe Server
Zusatz = ' (PID %d)' % Pid
elif ( LPid := ListenerPid( Port ) ) is not None:
Zusatz = ' (Listener-PID %d, keine PID-Datei)' % LPid
if IstUnsereApp( Port ):
print( 'LAEUFT: http://localhost:%d%s' % (Port, Zusatz) )
return 0
print( 'BELEGT: Port %d antwortet, aber nicht mit unserer App%s'
% (Port, Zusatz) )
return 1
if Pid is not None and PidLebt( Pid ):
print( 'UNKLAR: Prozess %d aus der PID-Datei lebt, aber Port %d '
'antwortet nicht (Startphase oder haengt?)' % (Pid, Port) )
return 1
print( 'GESTOPPT: kein Server auf Port %d' % Port )
return 1
def Vordergrund(Port):
print( 'Starte Web-Testinstanz im Vordergrund mit Auto-Reload '
'(Strg+C zum Beenden) ...' )
try:
return subprocess.call( UvicornKommando( Port, Reload=True ),
cwd=BASISDIR )
except KeyboardInterrupt:
return 0
# ------------------------------------------------------------------ Main
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='verwaltet die lokale Web-Testinstanz (FastAPI/uvicorn)' )
parser.add_argument( 'aktion', nargs='?', default='run',
choices=['start', 'stop', 'status', 'run'],
help='start=Hintergrund, stop=beenden, status=anzeigen, '
'run=Vordergrund mit Auto-Reload (Standard)' )
parser.add_argument( '--port', type=int, default=STANDARDPORT,
help='Port der Testinstanz (Standard: %d)' % STANDARDPORT )
argumente = parser.parse_args()
if argumente.aktion == 'start':
sys.exit( Starten( argumente.port ) )
elif argumente.aktion == 'stop':
sys.exit( Stoppen( argumente.port ) )
elif argumente.aktion == 'status':
sys.exit( Status( argumente.port ) )
else:
sys.exit( Vordergrund( argumente.port ) )
+7
View File
@@ -0,0 +1,7 @@
# Python-Abhaengigkeiten fuer platz
#
# Der Kern (libs/) verwendet nur die Standardbibliothek.
# Die folgenden Pakete braucht nur die Web-API (web/main.py, Roadmap M1):
fastapi>=0.110
uvicorn[standard]>=0.29
python-multipart>=0.0.9
+409
View File
@@ -0,0 +1,409 @@
"""
Unittests fuer Sitzplatzverteilung anhand von drei einfachen Szenarien:
1. Drei Tische in einer Kette (je 2 Plaetze), drei Paare
-> jedes Paar passt exakt an einen Tisch, keine Gruppe wird getrennt.
2. Vier Tische in einer Linie (je 2 Plaetze), zwei Vierergruppen
-> jede Vierergruppe verteilt sich auf ein zusammenhaengendes
Tischpaar (T1+T2 bzw. T3+T4), nie ueber die mittlere Naht hinweg.
3. Sechs Tische im Kreis (je 2 Plaetze), vier Dreiergruppen
-> jede Dreiergruppe wird genau einmal auf zwei Nachbartische
aufgeteilt (2+1), da kein Tisch drei Plaetze hat.
"""
import os
import random
import sys
import unittest
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'libs'))
from Strukturdaten import Gruppe, Gruppen, JSONConfig, Person, Sitzplatzverteilung, Strafliste, Tisch, Tische
from ga import Abstammung, Entwicklung, Farm, Zyklus, _StringAusdruck
IMAGES_DIR = os.path.join(os.path.dirname(__file__), '..', 'doc', 'images')
def erzeuge_personen(anzahl, start_id=1):
return [Person(i, 'Vorname%d' % i, 'Nachname%d' % i) for i in range(start_id, start_id + anzahl)]
class TestDreiTischeKettePaare(unittest.TestCase):
"""Drei Tische paarweise benachbart (Kette T1-T2-T3), je 2 Plaetze, 3 Paare."""
def setUp(self):
random.seed(1)
self.T1 = Tisch(1, Plaetze=2, Koordinaten=(1, 1), Nachbarliste=[2])
self.T2 = Tisch(2, Plaetze=2, Koordinaten=(2, 1), Nachbarliste=[1, 3])
self.T3 = Tisch(3, Plaetze=2, Koordinaten=(3, 1), Nachbarliste=[2])
self.Tische = Tische([self.T1, self.T2, self.T3])
Personen = erzeuge_personen(6)
self.G1 = Gruppe(1, Personen[0:2])
self.G2 = Gruppe(2, Personen[2:4])
self.G3 = Gruppe(3, Personen[4:6])
self.Gruppen = Gruppen([self.G1, self.G2, self.G3])
self.Strafen = Strafliste(
GruppenTrennen={1: {2: -10}, 2: {}, 3: {}},
NichtNachbar=-3, Allein=-30, TischWert={1: -3, 2: -2} )
def test_alle_paare_komplett_an_einem_tisch(self):
SV = Sitzplatzverteilung( Tische=self.Tische, Gruppen=self.Gruppen,
Strafen=self.Strafen, VIPListe={}, VIPs=Gruppe(0) )
SV.alsSVG( os.path.join(IMAGES_DIR, 'drei_tische_kette_paare.svg') )
for G in (self.G1, self.G2, self.G3):
self.assertEqual( SV.GruppenTeilungGet(G), 0,
"Paar %s haette nicht getrennt werden duerfen" % G.Id )
# jeder der drei Tische ist von genau einem Paar voll besetzt
Tid_zu_Gid = {}
for Gid, Tids in SV.Gid_Tid.items():
self.assertEqual( len(Tids), 1 )
Tid_zu_Gid[next(iter(Tids))] = Gid
self.assertEqual( set(Tid_zu_Gid.keys()), {1, 2, 3} )
# optimale Verteilung: keine Strafpunkte
self.assertEqual( SV.value, 0 )
class TestVierTischeLinieViergruppen(unittest.TestCase):
"""Vier Tische in einer Linie (T1-T2-T3-T4), je 2 Plaetze, 2 Vierergruppen."""
def setUp(self):
random.seed(1)
self.T1 = Tisch(1, Plaetze=2, Koordinaten=(1, 1), Nachbarliste=[2])
self.T2 = Tisch(2, Plaetze=2, Koordinaten=(2, 1), Nachbarliste=[1, 3])
self.T3 = Tisch(3, Plaetze=2, Koordinaten=(3, 1), Nachbarliste=[2, 4])
self.T4 = Tisch(4, Plaetze=2, Koordinaten=(4, 1), Nachbarliste=[3])
self.Tische = Tische([self.T1, self.T2, self.T3, self.T4])
Personen = erzeuge_personen(8)
self.G1 = Gruppe(1, Personen[0:4])
self.G2 = Gruppe(2, Personen[4:8])
self.Gruppen = Gruppen([self.G1, self.G2])
self.Strafen = Strafliste(
GruppenTrennen={1: {4: -6}, 2: {}, 3: {}},
NichtNachbar=-3, Allein=-30, TischWert={1: -3, 2: -2} )
def test_viergruppen_bleiben_auf_zusammenhaengendem_tischpaar(self):
SV = Sitzplatzverteilung( Tische=self.Tische, Gruppen=self.Gruppen,
Strafen=self.Strafen, VIPListe={}, VIPs=Gruppe(0) )
SV.alsSVG( os.path.join(IMAGES_DIR, 'vier_tische_linie_viergruppen.svg') )
# jede Gruppe wird genau einmal geteilt (2 Tische a 2 Plaetze)
self.assertEqual( SV.GruppenTeilungGet(self.G1), 1 )
self.assertEqual( SV.GruppenTeilungGet(self.G2), 1 )
Tids_G1 = SV.Gid_Tid[self.G1.Id]
Tids_G2 = SV.Gid_Tid[self.G2.Id]
# jede Gruppe liegt auf genau einem der beiden erwarteten Nachbarpaare,
# nie ueber die mittlere Naht (T2-T3) hinweg vermischt
erwartete_paare = ({1, 2}, {3, 4})
self.assertIn( Tids_G1, erwartete_paare )
self.assertIn( Tids_G2, erwartete_paare )
self.assertNotEqual( Tids_G1, Tids_G2 )
# alle Tische sind voll besetzt, es sitzt niemand allein
# (SV.Tische ist eine Kopie der urspruenglichen Tische, siehe
# Sitzplatzverteilung.__init__ -> Tische.deepcopy())
for T in SV.Tische:
self.assertTrue( T.istvoll() )
class TestSechsTischeKreisDreiergruppen(unittest.TestCase):
"""Sechs Tische im Kreis (T1..T6), je 2 Plaetze, 4 Dreiergruppen."""
def setUp(self):
random.seed(2)
self.T1 = Tisch(1, Plaetze=2, Koordinaten=(0, 2), Nachbarliste=[2, 6])
self.T2 = Tisch(2, Plaetze=2, Koordinaten=(1, 1), Nachbarliste=[1, 3])
self.T3 = Tisch(3, Plaetze=2, Koordinaten=(1, -1), Nachbarliste=[2, 4])
self.T4 = Tisch(4, Plaetze=2, Koordinaten=(0, -2), Nachbarliste=[3, 5])
self.T5 = Tisch(5, Plaetze=2, Koordinaten=(-1, -1), Nachbarliste=[4, 6])
self.T6 = Tisch(6, Plaetze=2, Koordinaten=(-1, 1), Nachbarliste=[5, 1])
self.Tische = Tische([self.T1, self.T2, self.T3, self.T4, self.T5, self.T6])
self.NachbarnVonTid = {
1: {2, 6}, 2: {1, 3}, 3: {2, 4}, 4: {3, 5}, 5: {4, 6}, 6: {5, 1} }
Personen = erzeuge_personen(12)
self.G1 = Gruppe(1, Personen[0:3])
self.G2 = Gruppe(2, Personen[3:6])
self.G3 = Gruppe(3, Personen[6:9])
self.G4 = Gruppe(4, Personen[9:12])
self.Gruppen = Gruppen([self.G1, self.G2, self.G3, self.G4])
self.Strafen = Strafliste(
GruppenTrennen={1: {3: -8}, 2: {}, 3: {}},
NichtNachbar=-3, Allein=-30, TischWert={1: -3, 2: -2} )
def test_dreiergruppen_je_einmal_auf_nachbartische_geteilt(self):
SV = Sitzplatzverteilung( Tische=self.Tische, Gruppen=self.Gruppen,
Strafen=self.Strafen, VIPListe={}, VIPs=Gruppe(0) )
SV.alsSVG( os.path.join(IMAGES_DIR, 'sechs_tische_kreis_dreiergruppen.svg') )
# 4 Dreiergruppen = 12 Personen auf 6x2 = 12 Plaetzen -> alle Tische voll.
# (SV.Tische ist eine Kopie der urspruenglichen Tische, siehe
# Sitzplatzverteilung.__init__ -> Tische.deepcopy())
for T in SV.Tische:
self.assertTrue( T.istvoll() )
# da kein Tisch 3 Plaetze hat, muss jede Dreiergruppe genau einmal
# auf zwei Tische aufgeteilt werden (2+1); dies gilt unabhaengig
# vom Zufalls-Seed, da bei voller Auslastung (12 Personen auf
# 12 Plaetzen) keine andere Aufteilung uebrig bleibt.
for G in (self.G1, self.G2, self.G3, self.G4):
self.assertEqual( SV.GruppenTeilungGet(G), 1 )
Tids = SV.Gid_Tid[G.Id]
self.assertEqual( len(Tids), 2 )
# mit dem hier fest gewaehlten Seed sitzen alle geteilten Gruppen
# zusaetzlich tatsaechlich an zwei benachbarten Tischen (der
# GA-Fallback duerfte bei knapper Auslastung im Kreis im
# Allgemeinen auch nicht-benachbarte Tische waehlen)
for G in (self.G1, self.G2, self.G3, self.G4):
Tid_a, Tid_b = tuple(SV.Gid_Tid[G.Id])
self.assertIn( Tid_b, self.NachbarnVonTid[Tid_a],
"Tische %s der Gruppe %s sind keine Nachbarn" % (SV.Gid_Tid[G.Id], G.Id) )
class TestJSONConfig(unittest.TestCase):
"""Parsen der bestellung.json: Gruppen, VIP-Bindung, Anzahl-Expansion."""
def test_gruppen_vips_und_sammelbuchung(self):
Daten = {
"gruppen": [
{
"name": "Brautpaar",
"tisch": 1,
"personen": [
{"vorname": "Julia", "nachname": "Brandt"},
{"vorname": "Daniel", "nachname": "Sommer", "titel": "Dr."},
],
},
{
"name": "Familie Huber",
"personen": [
{"vorname": "Anna", "nachname": "Huber"},
{"vorname": "Berta", "nachname": "Huber"},
],
},
{
"name": "Musikverein",
"anzahl": 5,
"personen": [ {"vorname": "Gast", "nachname": "Musikverein"} ],
},
]
}
PN, GN, VIPGruppe, VipHash, GruppenNamen = JSONConfig().HandleBestellung(Daten)
# VIP-Gruppe: beide ans Tisch 1 gebunden, nicht in den GA-Gruppen
self.assertEqual( VIPGruppe.Anzahl(), 2 )
self.assertEqual( set(VipHash.values()), {1} )
self.assertEqual( len(VipHash), 2 )
# regulaere Gruppen: Familie Huber (2) + Musikverein (5x expandiert) = 7
self.assertEqual( GN.NLeute, 7 )
self.assertEqual( len(GN.GruppenListe), 2 )
# Sammelbuchung: die eine Musikverein-Person wurde 5x vervielfacht
Groessen = sorted( G.Anzahl() for G in GN.GruppenListe )
self.assertEqual( Groessen, [2, 5] )
# Anzeigenamen kommen durch
self.assertIn( "Familie Huber", GruppenNamen.values() )
self.assertIn( "Musikverein", GruppenNamen.values() )
def test_fehlende_pflichtfelder_werfen_fehler(self):
with self.assertRaises(ValueError):
JSONConfig().HandleBestellung( {"keine_gruppen": []} )
with self.assertRaises(ValueError):
JSONConfig().HandleBestellung(
{"gruppen": [ {"personen": [ {"vorname": "Nur"} ]} ]} )
class TestStringAusdruck(unittest.TestCase):
"""Der sichere Zyklus-Ausdruck-Auswerter (Ersatz fuer eval)."""
def test_verkettung_und_vervielfachung(self):
self.assertEqual(
_StringAusdruck("'e,'+'s,z,m,j,z,'*3+'s'"),
'e,s,z,m,j,z,s,z,m,j,z,s,z,m,j,z,s' )
self.assertEqual( _StringAusdruck("'e,s'"), 'e,s' )
def test_lehnt_code_ab(self):
# kein Funktionsaufruf, keine Namen, kein Import
for boese in ("__import__('os')", "open('x')", "1+1", "a+'b'"):
with self.assertRaises(ValueError):
_StringAusdruck(boese)
class TestEntwicklung(unittest.TestCase):
"""Das Beobachtungsobjekt zeichnet den Verlauf auf und rendert SVG."""
class _L:
def __init__(self, value):
self.value = value
def test_erfassen_und_svg(self):
E = Entwicklung()
E.erfassen( 'e', [self._L(-200), self._L(-150), self._L(-90)] )
E.erfassen( 's', [self._L(-90), self._L(-70)] )
E.erfassen( 'm', [self._L(-70), self._L(-40)] )
self.assertEqual( len(E.Punkte), 3 )
# je Punkt: (index, aktion, best, schnitt, schlecht, N)
_i, aktion, best, schnitt, schlecht, n = E.Punkte[0]
self.assertEqual( aktion, 'e' )
self.assertEqual( best, -90 )
self.assertEqual( schlecht, -200 )
self.assertEqual( n, 3 )
Pfad = os.path.join( IMAGES_DIR, 'test_entwicklung.svg' )
E.alsSVG( Pfad )
with open(Pfad) as f:
svg = f.read()
self.assertIn( '<svg', svg )
# 3 Wertigkeitskurven (best/schnitt/schlecht) + 1 Pool-Groessenkurve
self.assertEqual( svg.count('<polyline'), 4 )
# das zweite Panel zeigt die Anzahl erzeugter Verteilungen im Pool
self.assertIn( 'Anzahl erzeugter Verteilungen im Pool', svg )
self.assertIn( 'stroke="#4060a0"', svg ) # Pool-Kurve
def test_leere_entwicklung_wirft_beim_svg(self):
with self.assertRaises(ValueError):
Entwicklung().alsSVG( os.path.join(IMAGES_DIR, 'leer.svg') )
class TestAdaptiverZyklus(unittest.TestCase):
"""Der adaptive Zyklus startet mit vielen Loesungen, laesst die
Population schrumpfen und bricht bei Konvergenz ab."""
class _L:
"""minimale GA-Loesung: fester Wert, Mutation aendert nichts (so
konvergiert der beste Wert sofort -> Abbruch nach 'Geduld')."""
def __init__(self, *a, **k):
self.value = -100
def mutieren(self):
return self
def __eq__(self, other):
return self.value == other.value
def __lt__(self, other):
return self.value < other.value
def _zyklus(self, **params):
Z = Zyklus()
Z.Modus = 'adaptiv'
Z.Adaptiv = dict(Zyklus.AdaptivDefaults)
Z.Adaptiv.update(params)
return Z
def test_population_schrumpft_und_bricht_bei_konvergenz_ab(self):
Z = self._zyklus( Start=40, Schrumpfung=0.85, MinPopulation=5,
MaxGenerationen=50, Geduld=3, Schwelle=1.0 )
F = Farm( Z, self._L )
# Pool-Groessen je 's'-Aufzeichnung (Ende jeder Generation)
pop_pro_gen = [ p[5] for p in F.Entwicklung.Punkte if p[1] == 's' ]
# monoton fallend (Population schrumpft) ...
self.assertTrue( all( a >= b for a, b in zip(pop_pro_gen, pop_pro_gen[1:]) ),
"Population muss von Generation zu Generation schrumpfen: %s"
% pop_pro_gen )
self.assertLess( pop_pro_gen[-1], pop_pro_gen[0] )
# ... und da nichts besser wird, nach Geduld(=3) Generationen Abbruch,
# also klar vor MaxGenerationen(=50).
self.assertLessEqual( len(pop_pro_gen), 4 )
def test_population_faellt_nicht_unter_min(self):
Z = self._zyklus( Start=8, Schrumpfung=0.5, MinPopulation=5,
MaxGenerationen=10, Geduld=99, Schwelle=1.0 )
F = Farm( Z, self._L )
pop_pro_gen = [ p[5] for p in F.Entwicklung.Punkte if p[1] == 's' ]
self.assertTrue( all( n >= 5 for n in pop_pro_gen ),
"MinPopulation=5 darf nicht unterschritten werden: %s"
% pop_pro_gen )
class TestAbstammung(unittest.TestCase):
"""Der Stammbaum vergibt hierarchische Ids, aus denen sich die Abstammung
ablesen laesst, und zeichnet einen Baum."""
class _L:
"""GA-Loesung, deren Mutation den Wert leicht verbessert (damit ueber
Generationen ein mehrstufiger Ast entsteht)."""
def __init__(self, *a, **k):
self.value = -100
def mutieren(self):
self.value = self.value + 1
return self
def __eq__(self, other):
return self.value == other.value
def __lt__(self, other):
return self.value < other.value
def _zyklus(self, **params):
Z = Zyklus()
Z.Modus = 'adaptiv'
Z.Adaptiv = dict(Zyklus.AdaptivDefaults)
Z.Adaptiv.update(params)
return Z
def test_fortlaufende_nummern_ids(self):
Z = self._zyklus( Start=5, Schrumpfung=1.0, MinPopulation=5,
MaxGenerationen=3, Geduld=99, Schwelle=0.0 )
F = Farm( Z, self._L )
Knoten = F.Abstammung.Knoten
# alle Ids sind fortlaufende Nummern 1..N ueber alle Loesungen
Ids = sorted(Knoten)
self.assertTrue( all( isinstance(Id, int) for Id in Ids ) )
self.assertEqual( Ids, list(range(1, len(Ids) + 1)) )
# genau die 5 Startloesungen sind Wurzeln (kein Vorgaenger),
# alle uebrigen haben einen Vorgaenger, der als Knoten existiert
wurzeln = [ Id for Id, K in Knoten.items() if K['eltern'] is None ]
self.assertEqual( len(wurzeln), 5 )
for Id, K in Knoten.items():
if K['eltern'] is None:
continue
self.assertIn( K['eltern'], Knoten )
self.assertNotEqual( K['eltern'], Id )
def test_abstammung_ueber_vorgaenger(self):
# Abstammung wird ueber den gemerkten Vorgaenger verfolgt, nicht ueber
# die Id selbst (Ids sind schlichte Nummern)
A = Abstammung()
A.erfassen( 1, None, 0, -100, 'e' )
A.erfassen( 2, 1, 1, -99, 'm' )
A.erfassen( 3, 2, 2, -98, 'm' )
kette = []
Id = 3
while Id is not None:
kette.append(Id)
Id = A.Knoten[Id]['eltern']
self.assertEqual( kette, [3, 2, 1] )
def test_svg_hebt_beste_hervor(self):
Z = self._zyklus( Start=4, Schrumpfung=1.0, MinPopulation=4,
MaxGenerationen=2, Geduld=99, Schwelle=0.0 )
F = Farm( Z, self._L )
Bester = F.Bester()
Pfad = os.path.join( IMAGES_DIR, 'test_abstammung.svg' )
F.Abstammung.alsSVG( Pfad, HervorId=Bester._absid )
with open(Pfad) as f:
svg = f.read()
self.assertIn( '<svg', svg )
self.assertIn( 'Abstammung der Loesungen', svg )
# die Id der besten Loesung ist als Beschriftung enthalten
self.assertIn( '>%s</text>' % Bester._absid, svg )
def test_leere_abstammung_wirft_beim_svg(self):
with self.assertRaises(ValueError):
Abstammung().alsSVG( os.path.join(IMAGES_DIR, 'leer_abst.svg') )
if __name__ == '__main__':
unittest.main()
+584
View File
@@ -0,0 +1,584 @@
"""
REST-API um den bestehenden Sitzplatz-Kern (Meilenstein 1 der Roadmap).
Session-basiert, nichts wird dauerhaft gespeichert: jede Sitzung lebt
im Speicher des Servers und verfaellt nach 24 Stunden (TTL) — bewusst
ohne Accounts/DB, siehe Roadmap M1 ("schont Datenschutz-Aufwand").
Endpunkte (siehe auch /docs — interaktive Swagger-UI von FastAPI):
POST /sitzung — legt eine Arbeits-Session an
GET /sitzung/{id} — Status der Session
POST /sitzung/{id}/tische — Tisch-Layout als JSON (Ersatz tische.ini)
POST /sitzung/{id}/personen — Gaesteliste als CSV-Upload (Ersatz bestellung.json)
POST /sitzung/{id}/berechnen — startet die GA-Optimierung; liefert bis zu
?varianten=N unterschiedliche Loesungen (M2)
GET /sitzung/{id}/ergebnis — alle Varianten des letzten Laufs als JSON
GET /sitzung/{id}/ergebnis.svg — eine Variante als SVG (?variante=k, 1 = beste)
Start (lokale Testinstanz, siehe bin/run_web.bat / bin/run_web.sh):
python -m uvicorn main:app --reload --app-dir web
"""
import ast
import configparser
import math
import os
import sys
import tempfile
import threading
import time
import uuid
# Projektwurzel und Pfade robust aus der eigenen Lage ableiten, damit der
# Server auch ohne vorheriges setenv laeuft (PLATZ_* hat Vorrang, falls gesetzt)
BASISDIR = os.path.dirname( os.path.dirname( os.path.abspath( __file__ ) ) )
LIBSDIR = os.environ.get( 'PLATZ_LIBS', os.path.join( BASISDIR, 'libs' ) )
CFGDIR = os.environ.get( 'PLATZ_CFG', os.path.join( BASISDIR, 'cfg' ) )
if LIBSDIR not in sys.path:
sys.path.insert( 0, LIBSDIR )
from fastapi import FastAPI, File, HTTPException, Query, UploadFile
from fastapi.responses import Response
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel, Field
from ga import Farm, Zyklus
from CSVConfig import CSVConfig
from Farben import Farbschema
from Strukturdaten import Sitzplatzverteilung, Strafliste, Tisch, Tische
app = FastAPI(
title='Sitz & Platz — API',
description='Sitzplatz-Optimierung per genetischem Algorithmus '
'(Meilenstein 1: Session-basiert, ohne Accounts)',
version='0.1.0' )
# ---------------------------------------------------------------- GA-Konfig
# Zyklus und Strafliste einmal beim Start laden (wie in libs/platz.py):
# zyklus.cfg und strafen.cfg direkt aus dem cfg-Verzeichnis (PLATZ_CFG bzw.
# Projekt-cfg). GA-Profil per Umgebungsvariable PLATZ_ZYKLUSART (Vorgabe:
# Adaptiv), Strafpunkte-Profil per PLATZ_STRAFENART (Vorgabe: default) —
# analog zum Schalter --strafen in libs/platz.py.
ZYKLUSDATEI = os.path.join( CFGDIR, 'zyklus.cfg' )
STRAFENDATEI = os.path.join( CFGDIR, 'strafen.cfg' )
ZYKLUSART = os.environ.get( 'PLATZ_ZYKLUSART', 'Adaptiv' )
STRAFENART = os.environ.get( 'PLATZ_STRAFENART', 'default' )
FARBENDATEI = os.path.join( CFGDIR, 'farben.cfg' )
FARBENART = os.environ.get( 'PLATZ_FARBENART', 'grosse_gruppen' )
GAZyklus = Zyklus()
GAZyklus.laden( ZYKLUSDATEI, ZYKLUSART )
# Strafprofile werden bei Bedarf geladen und gecacht, damit sich in der GUI
# verschiedene Profile (z.B. 'default' vs 'locker') auswaehlen und vergleichen
# lassen. Das Default-Profil wird schon beim Start geladen (faellt frueh auf,
# falls die Datei/Sektion kaputt ist).
StrafProfile = {}
def strafprofil(Name):
"""liefert (gecacht) die Strafliste einer Sektion aus strafen.cfg;
wirft ValueError bei unbekannter Sektion"""
if Name not in StrafProfile:
SL = Strafliste()
SL.laden( STRAFENDATEI, Name )
StrafProfile[Name] = SL
return StrafProfile[Name]
def strafprofil_namen():
"""alle in strafen.cfg vorhandenen Profilnamen (fuer die GUI-Auswahl)"""
cfg = configparser.ConfigParser()
cfg.read( STRAFENDATEI )
return cfg.sections()
strafprofil( STRAFENART ) # Default vorwaermen / frueh scheitern
# Farbprofil fuer die SVG-Ausgabe; faellt bei fehlender Datei/Sektion auf die
# eingebaute Palette zurueck (Farbschema=None), damit der Server trotzdem laeuft.
try:
Farben = Farbschema().laden( FARBENDATEI, FARBENART )
except (ValueError, OSError):
Farben = None
# ---------------------------------------------------------------- Sessions
SESSION_TTL_SEKUNDEN = 24 * 3600
Sessions = {}
SessionsLock = threading.Lock()
def _SessionsAufraeumen():
"""Sessions loeschen, deren TTL abgelaufen ist (Datenschutz per Design)"""
Jetzt = time.time()
with SessionsLock:
Abgelaufen = [ Sid for Sid, S in Sessions.items()
if Jetzt - S['erzeugt'] > SESSION_TTL_SEKUNDEN ]
for Sid in Abgelaufen:
del Sessions[Sid]
def _GibSession(SitzungsId):
_SessionsAufraeumen()
with SessionsLock:
S = Sessions.get( SitzungsId )
if S is None:
raise HTTPException( status_code=404,
detail='Sitzung nicht gefunden oder abgelaufen (TTL 24h)' )
return S
# ------------------------------------------------------------ API-Modelle
class TischEingabe(BaseModel):
"""ein Tisch aus dem Frontend (Ersatz fuer eine tische.ini-Section)"""
id: int | None = Field( default=None, description='Tisch-Id; leer = fortlaufend' )
nummer: int | None = Field( default=None, description='Anzeigenummer; leer = wie Id' )
hof: int = Field( default=1, description='Hof/Raum-Nummer' )
plaetze: int = Field( gt=0, le=100, description='Anzahl Sitzplaetze' )
x: float = Field( description='X-Koordinate im Raster' )
y: float = Field( description='Y-Koordinate im Raster' )
nachbarn: list[int] | None = Field( default=None,
description='explizite Nachbar-Tisch-Ids; leer = aus Naehe ableiten' )
class TischLayout(BaseModel):
tische: list[TischEingabe] = Field( min_length=1 )
nachbarRadius: float = Field( default=1.5, gt=0,
description='max. Rasterabstand, bis zu dem zwei Tische als '
'Nachbarn gelten (nur fuer Tische ohne explizite Liste)' )
# --------------------------------------------------------------- Hilfen
def _NachbarnAbleiten(TischListe, Radius):
"""Nachbarliste aus raeumlicher Naehe der Koordinaten ableiten
(Roadmap M1: Ersatz fuer manuelle Nachbarliste-Pflege).
Explizit angegebene Nachbarn bleiben erhalten und werden
beidseitig ergaenzt."""
Nachbarn = { T.id: set( T.nachbarn or [] ) for T in TischListe }
for T1 in TischListe:
for T2 in TischListe:
if T1.id == T2.id:
continue
if T1.nachbarn is None or T2.nachbarn is None:
Abstand = math.dist( (T1.x, T1.y), (T2.x, T2.y) )
if Abstand <= Radius:
Nachbarn[T1.id].add( T2.id )
Nachbarn[T2.id].add( T1.id )
# expliziten Angaben beidseitig machen
for Tid, Menge in Nachbarn.items():
for NachbarId in Menge:
if NachbarId in Nachbarn:
Nachbarn[NachbarId].add( Tid )
return { Tid: sorted(Menge) for Tid, Menge in Nachbarn.items() }
def _TischeBauen(S):
"""baut aus dem gespeicherten Layout frische Tisch-Objekte
(pro Berechnung neu, damit keine Reste vorheriger Laeufe kleben)"""
TE = Tische( [] )
for T in S['tische']:
TE.Tisch_dazu( Tisch(
T['id'],
Plaetze=T['plaetze'],
Koordinaten=( T['x'], T['y'] ),
Nachbarliste=T['nachbarn'],
Hof=T['hof'],
Nummer=T['nummer'] ) )
return TE
def _VarianteJSON(SV, GruppenNamen, Nr):
"""baut die JSON-Darstellung EINER Loesung (eine Variante)"""
def GruppeVonPerson(P):
try:
G = SV.Gruppen.GruppeVonPid( P.Id )
return GruppenNamen.get( G.Id, 'Gruppe %s' % G.Id )
except KeyError:
return 'fixiert'
TischListe = []
for T in SV.Tische:
Personen = [ {
'titel': P._Titel,
'vorname': P._Vorname,
'nachname': P._Name,
'gruppe': GruppeVonPerson( P ),
} for P in T ]
Personen.sort( key=lambda p: (p['gruppe'], p['nachname'], p['vorname']) )
TischListe.append( {
'id': T.Id,
'nummer': T.Nummer,
'hof': T.Hof,
'plaetze': T.Plaetze,
'besetzt': T.besetztePlaetze(),
'frei': T.freiePlaetze(),
'wert': SV.TischWertGet( T ),
'personen': Personen,
} )
TischListe.sort( key=lambda t: t['id'] )
GruppenListe = []
for G in SV.Gruppen:
GruppenListe.append( {
'id': G.Id,
'name': GruppenNamen.get( G.Id, 'Gruppe %s' % G.Id ),
'anzahl': G.Anzahl(),
'teilungen': SV.GruppenTeilungGet( G ),
'wert': SV.GruppenWertGet( G ),
} )
GruppenListe.sort( key=lambda g: g['id'] )
# Vergleichs-Kennzahlen (Roadmap M2: Wertigkeit, Gruppentrennungen,
# allein sitzende Personen — LeuteAllein zaehlt nur Personen aus
# mehrkoepfigen Gruppen ohne Gruppenmitglied am Tisch)
Kennzahlen = {
'wertigkeit': SV.value,
'getrennteGruppen': sum( 1 for G in GruppenListe if G['teilungen'] > 0 ),
'teilungenGesamt': sum( G['teilungen'] for G in GruppenListe ),
'alleinePersonen': sum( len( SV.LeuteAllein(T) ) for T in SV.Tische ),
}
return {
'nr': Nr,
'wertigkeit': SV.value,
'gruppenId': SV.getGruppenId(),
'personenId': SV.getPersonenId(),
'kennzahlen': Kennzahlen,
'tische': TischListe,
'gruppen': GruppenListe,
}
def _ErgebnisJSON(S):
"""baut die JSON-Darstellung aller Varianten des letzten Laufs"""
GruppenNamen = S.get( 'gruppenNamen', {} )
return {
'lauf': S['laeufe'],
'strafen': S.get( 'strafen', STRAFENART ), # verwendetes Strafprofil
'varianten': [ _VarianteJSON( SV, GruppenNamen, Nr + 1 )
for Nr, SV in enumerate( S['ergebnisse'] ) ],
}
# --------------------------------------------------------------- Endpunkte
@app.post( '/sitzung', status_code=201 )
def SitzungAnlegen():
"""legt eine neue Arbeits-Session an (TTL 24h, nur im Speicher)"""
_SessionsAufraeumen()
SitzungsId = uuid.uuid4().hex
with SessionsLock:
Sessions[SitzungsId] = {
'erzeugt': time.time(),
'tische': None,
'personen': None,
'ergebnisse': [], # Varianten des letzten Laufs (beste zuerst)
'laeufe': 0, # wie oft .../berechnen aufgerufen wurde
}
return { 'id': SitzungsId, 'ttlStunden': SESSION_TTL_SEKUNDEN // 3600 }
@app.get( '/sitzung/{SitzungsId}' )
def SitzungStatus(SitzungsId: str):
"""Status: was ist schon da, was fehlt noch"""
S = _GibSession( SitzungsId )
return {
'id': SitzungsId,
'tische': len( S['tische'] ) if S['tische'] else 0,
'personen': S['personen']['nLeute'] if S['personen'] else 0,
'vips': S['personen']['nVips'] if S['personen'] else 0,
'berechnet': len( S['ergebnisse'] ) > 0,
'laeufe': S['laeufe'],
'varianten': len( S['ergebnisse'] ),
}
@app.post( '/sitzung/{SitzungsId}/tische' )
def TischeSetzen(SitzungsId: str, Layout: TischLayout):
"""Tisch-Layout uebernehmen (JSON-Ersatz fuer tische.ini);
Nachbarschaft wird aus raeumlicher Naehe abgeleitet"""
S = _GibSession( SitzungsId )
# Ids vergeben/pruefen
NaechsteId = 1
Vergeben = set()
for T in Layout.tische:
if T.id is None:
while NaechsteId in Vergeben:
NaechsteId = NaechsteId + 1
T.id = NaechsteId
if T.id in Vergeben:
raise HTTPException( status_code=400,
detail='Tisch-Id %d ist doppelt' % T.id )
Vergeben.add( T.id )
Nachbarn = _NachbarnAbleiten( Layout.tische, Layout.nachbarRadius )
S['tische'] = [ {
'id': T.id,
'nummer': T.nummer if T.nummer is not None else T.id,
'hof': T.hof,
'plaetze': T.plaetze,
'x': T.x,
'y': T.y,
'nachbarn': Nachbarn[T.id],
} for T in Layout.tische ]
# Nachbar-Radius fuer den Rueckweg merken (GET .../tische), damit der
# grafische Editor dasselbe Layout inkl. Radius wieder laden kann.
S['nachbarRadius'] = Layout.nachbarRadius
S['ergebnisse'] = []
return {
'tische': S['tische'],
'plaetzeGesamt': sum( T['plaetze'] for T in S['tische'] ),
}
@app.get( '/sitzung/{SitzungsId}/tische' )
def TischeHolen(SitzungsId: str):
"""das gespeicherte Tisch-Layout zurueckgeben (fuer den grafischen
Editor: Layout aus einer geteilten Session wieder aufnehmen).
Die abgeleitete Nachbarliste ist pro Tisch enthalten; der zuletzt
verwendete nachbarRadius kommt separat mit (Vorgabe 1.5)."""
S = _GibSession( SitzungsId )
return {
'tische': S['tische'] or [],
'nachbarRadius': S.get( 'nachbarRadius', 1.5 ),
}
@app.post( '/sitzung/{SitzungsId}/tische-datei' )
def TischDateiHochladen(SitzungsId: str, datei: UploadFile = File(...)):
"""bestehende tische.ini hochladen (gleiches Format wie fuer die CLI,
z.B. work/hochzeit/tische.ini); die Nachbarliste aus der Datei
wird unveraendert uebernommen, nichts wird neu abgeleitet"""
S = _GibSession( SitzungsId )
Rohdaten = datei.file.read()
try:
Text = Rohdaten.decode( 'utf-8-sig' )
except UnicodeDecodeError:
Text = Rohdaten.decode( 'cp1252' )
config = configparser.ConfigParser()
try:
config.read_string( Text )
except configparser.Error as Fehler:
raise HTTPException( status_code=400,
detail='tische.ini nicht lesbar: %s' % Fehler )
if not config.sections():
raise HTTPException( status_code=400,
detail='tische.ini enthaelt keine Tisch-Sektionen ([1], [2], ...)' )
# gleiche Feldsemantik wie Tische.laden() in Strukturdaten.py,
# aber mit ast.literal_eval statt eval (Upload = fremde Eingabe)
TischListe = []
for Sektion in config.sections():
try:
Tid = int( Sektion )
Plaetze = int( ast.literal_eval( config.get( Sektion, 'Plaetze' ) ) )
Koords = ast.literal_eval( config.get( Sektion, 'Koordinaten' ) )
Nachbarn = list( ast.literal_eval(
config.get( Sektion, 'Nachbarliste' ) ) )
Nummer = int( ast.literal_eval(
config.get( Sektion, 'Nummer', fallback=Sektion ) ) )
Hof = int( ast.literal_eval(
config.get( Sektion, 'Hof', fallback='1' ) ) )
except (ValueError, SyntaxError, configparser.Error) as Fehler:
raise HTTPException( status_code=400,
detail='tische.ini, Sektion [%s]: %s' % (Sektion, Fehler) )
if Plaetze < 1:
raise HTTPException( status_code=400,
detail='tische.ini, Sektion [%s]: Plaetze muss >= 1 sein'
% Sektion )
TischListe.append( {
'id': Tid,
'nummer': Nummer,
'hof': Hof,
'plaetze': Plaetze,
'x': float( Koords[0] ),
'y': float( Koords[1] ),
'nachbarn': sorted( int(N) for N in Nachbarn ),
} )
Ids = [ T['id'] for T in TischListe ]
if len( Ids ) != len( set( Ids ) ):
raise HTTPException( status_code=400,
detail='tische.ini enthaelt doppelte Tisch-Ids' )
S['tische'] = TischListe
S['ergebnisse'] = []
return {
'tische': S['tische'],
'plaetzeGesamt': sum( T['plaetze'] for T in S['tische'] ),
}
@app.post( '/sitzung/{SitzungsId}/personen' )
def PersonenHochladen(SitzungsId: str, datei: UploadFile = File(...)):
"""Gaesteliste als CSV hochladen (Ersatz fuer bestellung.json);
Format siehe libs/CSVConfig.py"""
S = _GibSession( SitzungsId )
Rohdaten = datei.file.read()
try:
Text = Rohdaten.decode( 'utf-8-sig' )
except UnicodeDecodeError:
Text = Rohdaten.decode( 'cp1252' ) # Excel/Windows-Fallback
try:
[ PN, GN, VIPGruppe, VipHash, GruppenNamen, FixierteGruppen ] = \
CSVConfig().HandleGaesteliste( Text )
except ValueError as Fehler:
raise HTTPException( status_code=400, detail=str(Fehler) )
S['personen'] = {
'PN': PN,
'GN': GN,
'VIPGruppe': VIPGruppe,
'VipHash': VipHash,
'nLeute': GN.NLeute,
'nVips': VIPGruppe.Anzahl(),
}
S['gruppenNamen'] = GruppenNamen
S['ergebnisse'] = []
return {
'personen': GN.NLeute,
'fixiert': VIPGruppe.Anzahl(),
'gruppen': [ {
'id': G.Id,
'name': GruppenNamen.get( G.Id, 'Gruppe %s' % G.Id ),
'anzahl': G.Anzahl(),
} for G in GN ],
# fest platzierte Gruppen (fuer die grau hinterlegte Anzeige)
'fixierte': [ { 'name': Name, 'tisch': Info['tisch'], 'anzahl': Info['anzahl'] }
for Name, Info in FixierteGruppen.items() ],
}
@app.post( '/sitzung/{SitzungsId}/berechnen' )
def Berechnen(SitzungsId: str,
varianten: int = Query( default=3, ge=1, le=5,
description='wieviele unterschiedliche Varianten der Lauf '
'zurueckgeben soll (aus Farm.TopN, dedupliziert)' ),
strafen: str = Query( default=STRAFENART,
description='Name des Strafpunkte-Profils (Sektion in strafen.cfg), '
'z.B. default oder locker - zum Vergleich waehlbar' )):
"""startet die GA-Optimierung; jeder Aufruf ist ein neuer Lauf und
liefert bis zu 'varianten' unterschiedliche gute Sitzordnungen. Das
Strafpunkte-Profil ('strafen') steuert die Bewertung waehrend der
Optimierung - so lassen sich z.B. default und locker vergleichen."""
S = _GibSession( SitzungsId )
if S['tische'] is None:
raise HTTPException( status_code=400,
detail='Erst das Tisch-Layout setzen (POST .../tische)' )
if S['personen'] is None:
raise HTTPException( status_code=400,
detail='Erst die Gaesteliste hochladen (POST .../personen)' )
TE = _TischeBauen( S )
P = S['personen']
# Vorab-Pruefungen mit klaren Fehlermeldungen (der Kern wirft sonst
# nur IndexError/AttributeError tief aus der Platzierung heraus)
GesamtLeute = P['nLeute'] + P['nVips']
if GesamtLeute > TE.NStuehle:
raise HTTPException( status_code=400,
detail='Zu wenig Stuehle: %d Personen, aber nur %d Plaetze'
% (GesamtLeute, TE.NStuehle) )
VIPsProTisch = {}
for Pid, Tid in P['VipHash'].items():
VIPsProTisch[Tid] = VIPsProTisch.get( Tid, 0 ) + 1
for Tid, AnzahlVIPs in VIPsProTisch.items():
T = TE.vonId( Tid )
if T is None:
raise HTTPException( status_code=400,
detail='VIP-Tisch %d existiert nicht im Layout' % Tid )
if AnzahlVIPs > T.Plaetze:
raise HTTPException( status_code=400,
detail='Tisch %d hat %d Plaetze, aber %d VIPs sind '
'dort fest gesetzt' % (Tid, T.Plaetze, AnzahlVIPs) )
try:
SL = strafprofil( strafen )
except ValueError as Fehler:
raise HTTPException( status_code=400, detail=str(Fehler) )
try:
GAFarm = Farm( GAZyklus, Sitzplatzverteilung,
Tische=TE, Gruppen=P['GN'], Strafen=SL,
VIPListe=P['VipHash'], VIPs=P['VIPGruppe'] )
except IndexError as Fehler:
raise HTTPException( status_code=400, detail=str(Fehler) )
# Roadmap M2: nicht nur den Besten, sondern bis zu 'varianten'
# UNTERSCHIEDLICHE gute Loesungen aus dem Endpool — Farm.TopN liefert
# absteigend sortiert. Der Vergleich der Loesungen laeuft ueber die
# getGruppenId (Gruppen-Ebene): dieselbe Sitzordnung zaehlt nicht mehrfach
# als eigene Variante. Der GA-Pool ist ohnehin schon per getGruppenId
# dedupliziert; das hier ist die zusaetzliche Absicherung fuer die Ausgabe.
# Liefert der Pool weniger unterschiedliche Sitzordnungen, kommen eben
# weniger zurueck (ein weiterer Klick auf Berechnen erzeugt einen frischen Lauf).
Ergebnisse, Gesehen = [], set()
for SV in GAFarm.TopN( len( GAFarm.Pool ) ):
Sig = SV.getGruppenId()
if Sig in Gesehen:
continue
Gesehen.add( Sig )
Ergebnisse.append( SV )
if len( Ergebnisse ) == varianten:
break
S['ergebnisse'] = Ergebnisse
S['laeufe'] = S['laeufe'] + 1
S['strafen'] = strafen # fuer die Anzeige, welches Profil den Lauf ergab
return _ErgebnisJSON( S )
@app.get( '/strafprofile' )
def Strafprofile():
"""verfuegbare Strafpunkte-Profile (Sektionen in strafen.cfg) fuer die
Auswahl in der GUI; 'vorgabe' ist das voreingestellte Profil."""
return { 'profile': strafprofil_namen(), 'vorgabe': STRAFENART }
@app.get( '/sitzung/{SitzungsId}/ergebnis' )
def Ergebnis(SitzungsId: str):
"""alle Varianten des letzten Laufs als JSON (beste zuerst)"""
S = _GibSession( SitzungsId )
if not S['ergebnisse']:
raise HTTPException( status_code=404,
detail='Noch nichts berechnet (POST .../berechnen)' )
return _ErgebnisJSON( S )
@app.get( '/sitzung/{SitzungsId}/ergebnis.svg' )
def ErgebnisSVG(SitzungsId: str,
variante: int = Query( default=1, ge=1,
description='Nummer der Variante (1 = beste)' )):
"""eine berechnete Variante als SVG (alsSVG aus dem Kern)"""
S = _GibSession( SitzungsId )
if not S['ergebnisse']:
raise HTTPException( status_code=404,
detail='Noch nichts berechnet (POST .../berechnen)' )
if variante > len( S['ergebnisse'] ):
raise HTTPException( status_code=404,
detail='Variante %d gibt es nicht (letzter Lauf hat %d)'
% (variante, len( S['ergebnisse'] )) )
# alsSVG schreibt in eine Datei -> Tempdatei schreiben, lesen, loeschen
Handle, TempPfad = tempfile.mkstemp( suffix='.svg' )
os.close( Handle )
try:
S['ergebnisse'][variante - 1].alsSVG( TempPfad,
GruppenNamen=S.get( 'gruppenNamen', {} ), Farbschema=Farben )
fsock = open( TempPfad, 'r' )
SVG = fsock.read()
fsock.close()
finally:
os.remove( TempPfad )
return Response( content=SVG, media_type='image/svg+xml' )
# statisches Test-Frontend unter / (muss nach den API-Routen gemountet sein)
app.mount( '/', StaticFiles(
directory=os.path.join( os.path.dirname( os.path.abspath( __file__ ) ),
'static' ),
html=True ), name='static' )
+472
View File
@@ -0,0 +1,472 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sitz &amp; Platz — Tisch-Editor (M1)</title>
<style>
:root {
--akzent: #2f6f4f;
--akzent-hell: #e6f0ea;
--rand: #d9d4c8;
--hintergrund: #faf8f3;
}
* { box-sizing: border-box; }
body {
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
margin: 0; background: var(--hintergrund); color: #2a2a24; line-height: 1.5;
}
header { background: var(--akzent); color: white; padding: 1rem 1.5rem; }
header h1 { margin: 0; font-size: 1.3rem; }
header p { margin: .2rem 0 0; opacity: .85; font-size: .85rem; }
header a { color: #d6eade; }
main { max-width: 68rem; margin: 0 auto; padding: 1rem 1.5rem 4rem; }
.werkzeug {
display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
background: white; border: 1px solid var(--rand); border-radius: 8px;
padding: .6rem .75rem; margin-bottom: 1rem;
}
.werkzeug .trenner { width: 1px; height: 1.6rem; background: var(--rand); margin: 0 .3rem; }
.werkzeug label { font-size: .82rem; color: #6b6557; display: inline-flex; align-items: center; gap: .3rem; }
button {
background: var(--akzent); color: white; border: 0; border-radius: 4px;
padding: .42rem .8rem; font-size: .88rem; cursor: pointer;
}
button.sekundaer { background: #8b8577; }
button.geist { background: white; color: var(--akzent); border: 1px solid var(--rand); }
button:disabled { background: #cfcabc; color: #f3f0e8; cursor: not-allowed; }
.buehne {
display: grid; grid-template-columns: 1fr 15rem; gap: 1rem; align-items: start;
}
@media (max-width: 48rem) { .buehne { grid-template-columns: 1fr; } }
#leinwand {
background: white; border: 1px solid var(--rand); border-radius: 8px;
overflow: auto; touch-action: none; min-height: 24rem;
}
#leinwand svg { display: block; }
.circle-tisch { cursor: grab; }
.circle-tisch:active { cursor: grabbing; }
aside {
background: white; border: 1px solid var(--rand); border-radius: 8px;
padding: 1rem; font-size: .9rem;
}
aside h2 { font-size: 1rem; margin: 0 0 .6rem; color: var(--akzent); }
aside .feld { margin: .5rem 0; }
aside input[type=number] { width: 4rem; }
.zahl { display: inline-block; background: #f1eee6; border-radius: 4px;
padding: .25rem .6rem; margin: .1rem .3rem .1rem 0; font-size: .85rem; }
.zahl b { color: var(--akzent); }
.status { font-size: .85rem; margin-top: .6rem; min-height: 1.2rem; }
.status.ok { color: var(--akzent); }
.status.fehler { color: #a03030; white-space: pre-wrap; }
.hinweis { font-size: .8rem; color: #6b6557; }
kbd { background: #f1eee6; border: 1px solid var(--rand); border-bottom-width: 2px;
border-radius: 3px; padding: 0 .3rem; font-size: .78rem; }
</style>
</head>
<body>
<header>
<h1>Sitz &amp; Platz <small style="font-weight:normal">— Interaktiver Tisch-Editor (Meilenstein 1)</small></h1>
<p>Tische per Drag &amp; Drop platzieren; Nachbarschaft wird aus der Nähe abgeleitet.
Sitzung: <code id="sitzungsId"></code> · weiter zu <a href="/">Gäste &amp; Berechnung</a></p>
</header>
<main>
<div class="werkzeug">
<button id="btnUndo" title="Rückgängig (Strg+Z)" disabled>↶ Rückgängig</button>
<button id="btnRedo" title="Wiederholen (Strg+Y)" disabled>↷ Wiederholen</button>
<span class="trenner"></span>
<button id="btnAdd" class="geist">+ Tisch</button>
<button id="btnReihe" class="sekundaer">Preset: 4er-Reihe</button>
<button id="btnRaster" class="sekundaer">Preset: 3×3-Raster</button>
<span class="trenner"></span>
<label>Nachbar-Radius
<input type="range" id="radius" min="0.5" max="3" step="0.1" value="1.5">
<b id="radiusWert">1,5</b>
</label>
<label>Raster
<select id="raster">
<option value="0.5" selected>0,5</option>
<option value="1">1</option>
<option value="1.5">1,5</option>
<option value="2">2</option>
</select>
</label>
<span class="trenner"></span>
<label>tische.ini <input type="file" id="iniDatei" accept=".ini,text/plain"></label>
<button id="btnIni" class="geist">laden</button>
<span class="trenner"></span>
<button id="btnSpeichern">Layout speichern</button>
</div>
<div class="buehne">
<div id="leinwand"></div>
<aside>
<h2>Ausgewählter Tisch</h2>
<div id="inspektor"><p class="hinweis">Kein Tisch ausgewählt. Auf einen Tisch
klicken, um Plätze zu ändern oder ihn zu löschen. Ziehen zum Verschieben.</p></div>
<hr style="border:0;border-top:1px solid var(--rand);margin:.8rem 0">
<div id="zahlen"></div>
<p class="hinweis" style="margin-top:.6rem">Tastatur: <kbd>Strg</kbd>+<kbd>Z</kbd> /
<kbd>Strg</kbd>+<kbd>Y</kbd> Undo/Redo · <kbd>Entf</kbd> löscht den
ausgewählten Tisch.</p>
</aside>
</div>
<div class="status" id="status"></div>
</main>
<script>
'use strict';
/* ============================================================ Zustand
state.tische ist die einzige Wahrheit; das SVG wird daraus gezeichnet
(state-getrieben, nie umgekehrt). Der Nachbar-Radius ist bewusst KEIN
Teil der Undo-History (Undo/Redo betrifft Tischgeometrie/-kapazität,
nicht diese Ableitungs-Einstellung), wird aber mitgespeichert. */
const state = { tische: [] };
let radius = 1.5;
let rasterSchritt = 0.5;
const ZIEH_TEMPO = 0.5; // Ziehgeschwindigkeit: Tisch folgt dem Zeiger halb so schnell
let selectedId = null;
let sitzung = null;
/* Undo/Redo: Schnappschuss-Stapel. Ein Schnappschuss ist ein tiefer Klon
von state.tische. Vor jeder verändernden Aktion wird der aktuelle
Zustand auf undoStack gelegt und redoStack geleert. */
const undoStack = [];
const redoStack = [];
const HIST_MAX = 200;
const klon = (t) => JSON.parse(JSON.stringify(t));
function pushHistory() {
undoStack.push(klon(state.tische));
if (undoStack.length > HIST_MAX) undoStack.shift();
redoStack.length = 0;
knoepfe();
}
function undo() {
if (!undoStack.length) return;
redoStack.push(klon(state.tische));
state.tische = undoStack.pop();
nachZustandswechsel();
}
function redo() {
if (!redoStack.length) return;
undoStack.push(klon(state.tische));
state.tische = redoStack.pop();
nachZustandswechsel();
}
function nachZustandswechsel() {
if (selectedId !== null && !tischVonId(selectedId)) selectedId = null;
knoepfe(); zeichne(); inspektor();
}
function knoepfe() {
document.getElementById('btnUndo').disabled = undoStack.length === 0;
document.getElementById('btnRedo').disabled = redoStack.length === 0;
}
/* ============================================================ Helfer */
const tischVonId = (id) => state.tische.find(t => t.id === id);
function neueId() {
return state.tische.reduce((m, t) => Math.max(m, t.id), 0) + 1;
}
function snap(v) { return Math.round( Math.round(v / rasterSchritt) * rasterSchritt * 100 ) / 100; }
function radiusPx(plaetze) {
// Kreisgroesse waechst mit der Platzzahl (analog alsSVG im Kern)
return Math.max(18, Math.min(48, 15 + plaetze * 1.5));
}
/* ============================================================ Geometrie
Grid-Koordinaten (wie tische.ini) <-> Pixel. Bei jeder Zeichnung neu
bestimmt und in Modulvariablen abgelegt, damit pointerGrid() umrechnen
kann. */
const SCALE = 72, MARGIN = 34, PAD = 1;
let viewMinX = 0, viewMinY = 0, curW = 600, curH = 400;
function grenzen() {
if (!state.tische.length) return { minX: 0, maxX: 3, minY: 0, maxY: 2 };
const xs = state.tische.map(t => t.x), ys = state.tische.map(t => t.y);
return { minX: Math.min(...xs), maxX: Math.max(...xs),
minY: Math.min(...ys), maxY: Math.max(...ys) };
}
const px = (gx, min) => MARGIN + (gx - min) * SCALE;
function pointerGrid(e) {
const svg = document.querySelector('#leinwand svg');
const r = svg.getBoundingClientRect();
const sx = curW / r.width, sy = curH / r.height;
const X = (e.clientX - r.left) * sx, Y = (e.clientY - r.top) * sy;
return { x: (X - MARGIN) / SCALE + viewMinX, y: (Y - MARGIN) / SCALE + viewMinY };
}
/* ============================================================ Zeichnen */
function nachbarPaare() {
const paare = [];
for (let i = 0; i < state.tische.length; i++)
for (let j = i + 1; j < state.tische.length; j++) {
const a = state.tische[i], b = state.tische[j];
if (Math.hypot(a.x - b.x, a.y - b.y) <= radius) paare.push([a, b]);
}
return paare;
}
function zeichne() {
const g = grenzen();
viewMinX = g.minX - PAD; viewMinY = g.minY - PAD;
curW = Math.max(480, MARGIN * 2 + (g.maxX - g.minX + 2 * PAD) * SCALE);
curH = Math.max(320, MARGIN * 2 + (g.maxY - g.minY + 2 * PAD) * SCALE);
let s = `<svg xmlns="http://www.w3.org/2000/svg" width="${curW}" height="${curH}" `
+ `viewBox="0 0 ${curW} ${curH}" font-family="sans-serif">`;
s += `<rect width="100%" height="100%" fill="white"/>`;
// feines Grid an ganzzahligen Rasterlinien
for (let gx = Math.ceil(viewMinX); px(gx, viewMinX) <= curW; gx++)
s += `<line x1="${px(gx, viewMinX)}" y1="0" x2="${px(gx, viewMinX)}" y2="${curH}" stroke="#f0ede5"/>`;
for (let gy = Math.ceil(viewMinY); px(gy, viewMinY) <= curH; gy++)
s += `<line x1="0" y1="${px(gy, viewMinY)}" x2="${curW}" y2="${px(gy, viewMinY)}" stroke="#f0ede5"/>`;
// Nachbar-Linien (aus der Naehe abgeleitet, wie im Backend)
for (const [a, b] of nachbarPaare())
s += `<line x1="${px(a.x, viewMinX)}" y1="${px(a.y, viewMinY)}" `
+ `x2="${px(b.x, viewMinX)}" y2="${px(b.y, viewMinY)}" `
+ `stroke="#bcd3c6" stroke-width="2"/>`;
// Tische als Kreise
for (const t of state.tische) {
const cx = px(t.x, viewMinX), cy = px(t.y, viewMinY), r = radiusPx(t.plaetze);
const gewaehlt = t.id === selectedId;
s += `<g class="circle-tisch" data-id="${t.id}">`;
if (gewaehlt)
s += `<circle cx="${cx}" cy="${cy}" r="${r + 5}" fill="none" `
+ `stroke="#2f6f4f" stroke-width="2" stroke-dasharray="4 3"/>`;
s += `<circle cx="${cx}" cy="${cy}" r="${r}" `
+ `fill="${gewaehlt ? '#e6f0ea' : 'white'}" stroke="#2f6f4f" stroke-width="2"/>`;
s += `<text x="${cx}" y="${cy - 1}" text-anchor="middle" font-size="15" `
+ `font-weight="bold" fill="#2f6f4f">${t.id}</text>`;
s += `<text x="${cx}" y="${cy + 13}" text-anchor="middle" font-size="10" `
+ `fill="#6b6557">${t.plaetze} Pl.</text>`;
s += `</g>`;
}
s += `</svg>`;
document.getElementById('leinwand').innerHTML = s;
// Kennzahlen
const plaetze = state.tische.reduce((m, t) => m + t.plaetze, 0);
document.getElementById('zahlen').innerHTML =
`<span class="zahl">Tische: <b>${state.tische.length}</b></span>` +
`<span class="zahl">Plätze: <b>${plaetze}</b></span>` +
`<span class="zahl">Nachbar-Paare: <b>${nachbarPaare().length}</b></span>`;
}
/* ============================================================ Inspektor */
function inspektor() {
const el = document.getElementById('inspektor');
const t = selectedId !== null ? tischVonId(selectedId) : null;
if (!t) {
el.innerHTML = '<p class="hinweis">Kein Tisch ausgewählt. Auf einen Tisch ' +
'klicken, um Plätze zu ändern oder ihn zu löschen. Ziehen zum Verschieben.</p>';
return;
}
el.innerHTML =
`<div class="feld"><b>Tisch ${t.id}</b></div>` +
`<div class="feld">Plätze: ` +
`<button class="geist" id="plMinus"></button> ` +
`<input type="number" id="plaetze" min="1" max="100" value="${t.plaetze}"> ` +
`<button class="geist" id="plPlus">+</button></div>` +
`<div class="feld hinweis">Position: x=${t.x}, y=${t.y}</div>` +
`<div class="feld"><button class="sekundaer" id="loeschen">Tisch löschen</button></div>`;
document.getElementById('plMinus').onclick = () => plaetzeSetzen(t.plaetze - 1);
document.getElementById('plPlus').onclick = () => plaetzeSetzen(t.plaetze + 1);
document.getElementById('plaetze').onchange = (e) => plaetzeSetzen(parseInt(e.target.value, 10));
document.getElementById('loeschen').onclick = tischLoeschen;
}
function plaetzeSetzen(wert) {
const t = tischVonId(selectedId);
if (!t || isNaN(wert)) return;
wert = Math.max(1, Math.min(100, wert));
if (wert === t.plaetze) return;
pushHistory(); t.plaetze = wert; zeichne(); inspektor();
}
/* ============================================================ Auswahl */
function auswaehlen(id) { selectedId = id; zeichne(); inspektor(); }
/* ============================================================ Aktionen */
function tischHinzufuegen() {
const g = grenzen();
const x = state.tische.length ? snap((g.minX + g.maxX) / 2) : 0;
const y = state.tische.length ? snap((g.minY + g.maxY) / 2) : 0;
pushHistory();
const id = neueId();
state.tische.push({ id, plaetze: 8, x, y });
auswaehlen(id);
melde('Tisch ' + id + ' hinzugefügt.', 'ok');
}
function tischLoeschen() {
if (selectedId === null) return;
pushHistory();
state.tische = state.tische.filter(t => t.id !== selectedId);
const weg = selectedId; selectedId = null;
zeichne(); inspektor();
melde('Tisch ' + weg + ' gelöscht.', 'ok');
}
function presetReihe() {
pushHistory();
state.tische = [1, 2, 3, 4].map(i => ({ id: i, plaetze: 5, x: i - 1, y: 0 }));
selectedId = null; zeichne(); inspektor();
}
function presetRaster() {
pushHistory();
state.tische = [];
let id = 1;
for (let y = 0; y < 3; y++)
for (let x = 0; x < 3; x++) state.tische.push({ id: id++, plaetze: 8, x, y });
selectedId = null; zeichne(); inspektor();
}
/* ============================================================ Drag & Drop */
let dragId = null, dragMoved = false, dragStart = null;
let ankerPtr = null, ankerPos = null; // Zeiger- und Tischposition bei Zugbeginn
document.getElementById('leinwand').addEventListener('pointerdown', (e) => {
const el = e.target.closest('[data-id]');
if (!el) { if (selectedId !== null) auswaehlen(null); return; }
const id = parseInt(el.dataset.id, 10);
auswaehlen(id);
const gpt = pointerGrid(e), t = tischVonId(id);
dragId = id; dragMoved = false; dragStart = klon(state.tische);
// Anker merken: der Tisch wandert ab hier um ZIEH_TEMPO * Zeigerweg
ankerPtr = { x: gpt.x, y: gpt.y };
ankerPos = { x: t.x, y: t.y };
e.preventDefault();
});
window.addEventListener('pointermove', (e) => {
if (dragId === null) return;
const gpt = pointerGrid(e);
// halbe Geschwindigkeit: Verschiebung des Tisches = halber Zeigerweg
const nx = snap(ankerPos.x + (gpt.x - ankerPtr.x) * ZIEH_TEMPO);
const ny = snap(ankerPos.y + (gpt.y - ankerPtr.y) * ZIEH_TEMPO);
const t = tischVonId(dragId);
if (t && (t.x !== nx || t.y !== ny)) { t.x = nx; t.y = ny; dragMoved = true; zeichne(); inspektor(); }
});
window.addEventListener('pointerup', () => {
if (dragId === null) return;
if (dragMoved) {
// den ganzen Zug als EINEN Undo-Schritt ablegen (Vor-Zustand)
undoStack.push(dragStart);
if (undoStack.length > HIST_MAX) undoStack.shift();
redoStack.length = 0; knoepfe();
}
dragId = null; dragStart = null;
});
/* ============================================================ Tastatur */
window.addEventListener('keydown', (e) => {
const tippt = /^(INPUT|TEXTAREA)$/.test(document.activeElement.tagName);
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'z' && !e.shiftKey) {
e.preventDefault(); undo();
} else if ((e.ctrlKey || e.metaKey) && (e.key.toLowerCase() === 'y' ||
(e.key.toLowerCase() === 'z' && e.shiftKey))) {
e.preventDefault(); redo();
} else if ((e.key === 'Delete' || e.key === 'Backspace') && selectedId !== null && !tippt) {
e.preventDefault(); tischLoeschen();
}
});
/* ============================================================ Backend */
function melde(text, klasse) {
const el = document.getElementById('status');
el.textContent = text; el.className = 'status ' + (klasse || '');
}
async function api(pfad, optionen) {
const antwort = await fetch(pfad, optionen);
const daten = await antwort.json().catch(() => null);
if (!antwort.ok) {
const d = daten && daten.detail
? (typeof daten.detail === 'string' ? daten.detail : JSON.stringify(daten.detail))
: antwort.statusText;
throw new Error(d);
}
return daten;
}
async function sitzungHolen() {
// Session mit der Testoberflaeche (index.html) ueber localStorage teilen
let id = localStorage.getItem('platzSitzung');
if (id) {
const ok = await fetch('/sitzung/' + id).then(r => r.ok).catch(() => false);
if (ok) return id;
}
const r = await api('/sitzung', { method: 'POST' });
localStorage.setItem('platzSitzung', r.id);
return r.id;
}
async function layoutSpeichern() {
if (!state.tische.length) { melde('Mindestens ein Tisch nötig.', 'fehler'); return; }
const tische = state.tische.map(t => ({ id: t.id, plaetze: t.plaetze, x: t.x, y: t.y }));
try {
const r = await api('/sitzung/' + sitzung + '/tische', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ tische, nachbarRadius: radius }),
});
melde('✓ ' + r.tische.length + ' Tische, ' + r.plaetzeGesamt +
' Plätze gespeichert. Weiter mit „Gäste & Berechnung“.', 'ok');
} catch (e) { melde('Fehler: ' + e.message, 'fehler'); }
}
async function iniLaden() {
const eingabe = document.getElementById('iniDatei');
if (!eingabe.files.length) { melde('Bitte zuerst eine tische.ini auswählen.', 'fehler'); return; }
const form = new FormData(); form.append('datei', eingabe.files[0]);
try {
const r = await api('/sitzung/' + sitzung + '/tische-datei', { method: 'POST', body: form });
pushHistory();
state.tische = r.tische.map(t => ({ id: t.id, plaetze: t.plaetze, x: t.x, y: t.y }));
selectedId = null; zeichne(); inspektor();
melde('✓ ' + r.tische.length + ' Tische aus Datei geladen.', 'ok');
} catch (e) { melde('Fehler: ' + e.message, 'fehler'); }
}
async function layoutLaden() {
// bereits in der (geteilten) Session gespeichertes Layout uebernehmen
try {
const r = await api('/sitzung/' + sitzung + '/tische');
if (r.tische && r.tische.length) {
state.tische = r.tische.map(t => ({ id: t.id, plaetze: t.plaetze, x: t.x, y: t.y }));
radius = r.nachbarRadius || 1.5;
document.getElementById('radius').value = radius;
document.getElementById('radiusWert').textContent = radius.toFixed(1).replace('.', ',');
return true;
}
} catch (e) { /* neue Session ohne Layout — Preset zeigen */ }
return false;
}
/* ============================================================ Verdrahtung */
document.getElementById('btnUndo').onclick = undo;
document.getElementById('btnRedo').onclick = redo;
document.getElementById('btnAdd').onclick = tischHinzufuegen;
document.getElementById('btnReihe').onclick = presetReihe;
document.getElementById('btnRaster').onclick = presetRaster;
document.getElementById('btnSpeichern').onclick = layoutSpeichern;
document.getElementById('btnIni').onclick = iniLaden;
document.getElementById('raster').onchange = (e) => { rasterSchritt = parseFloat(e.target.value); };
const radiusInput = document.getElementById('radius');
radiusInput.oninput = (e) => {
radius = parseFloat(e.target.value);
document.getElementById('radiusWert').textContent = radius.toFixed(1).replace('.', ',');
zeichne();
};
/* ============================================================ Start */
window.addEventListener('DOMContentLoaded', async () => {
try {
sitzung = await sitzungHolen();
document.getElementById('sitzungsId').textContent = sitzung;
} catch (e) {
document.getElementById('sitzungsId').textContent = 'Fehler: ' + e.message;
}
const geladen = sitzung ? await layoutLaden() : false;
if (!geladen) state.tische = [1, 2, 3, 4].map(i => ({ id: i, plaetze: 5, x: i - 1, y: 0 }));
knoepfe(); zeichne(); inspektor();
});
</script>
</body>
</html>
+499
View File
@@ -0,0 +1,499 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sitz &amp; Platz — Testoberfläche (M1)</title>
<style>
:root {
--akzent: #2f6f4f;
--rand: #d9d4c8;
--hintergrund: #faf8f3;
}
* { box-sizing: border-box; }
body {
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
margin: 0; background: var(--hintergrund); color: #2a2a24;
line-height: 1.5;
}
header {
background: var(--akzent); color: white;
padding: 1rem 1.5rem;
}
header h1 { margin: 0; font-size: 1.3rem; }
header p { margin: .2rem 0 0; opacity: .85; font-size: .85rem; }
main { max-width: 60rem; margin: 0 auto; padding: 1rem 1.5rem 4rem; }
section {
background: white; border: 1px solid var(--rand);
border-radius: 8px; padding: 1rem 1.25rem; margin-top: 1.25rem;
}
h2 { font-size: 1.05rem; margin: 0 0 .75rem; color: var(--akzent); }
table { border-collapse: collapse; width: 100%; font-size: .9rem; }
th, td { border: 1px solid var(--rand); padding: .3rem .5rem; text-align: left; }
th { background: #f1eee6; }
input[type=number] { width: 4.5rem; }
textarea {
width: 100%; min-height: 11rem; font-family: ui-monospace, monospace;
font-size: .85rem; border: 1px solid var(--rand); border-radius: 4px;
padding: .5rem;
}
button {
background: var(--akzent); color: white; border: 0;
border-radius: 4px; padding: .45rem .9rem; font-size: .9rem;
cursor: pointer; margin: .25rem .35rem .25rem 0;
}
button.sekundaer { background: #8b8577; }
button:disabled { background: #b9b4a6; cursor: not-allowed; }
.status { font-size: .85rem; margin-top: .5rem; min-height: 1.2rem; }
.status.ok { color: var(--akzent); }
.status.fehler { color: #a03030; white-space: pre-wrap; }
#svgPlan { margin-top: .75rem; border: 1px solid var(--rand); border-radius: 4px;
background: white; overflow: auto; }
#svgPlan svg { max-width: 100%; height: auto; display: block; }
#svgPlan .person { cursor: pointer; }
#svgPlan .person.aktiv { stroke: #111; stroke-width: 3; }
#gruppeBox { position: fixed; z-index: 1000; pointer-events: none; display: none;
background: #2a2a24; color: white; border-radius: 6px;
padding: .5rem .7rem; font-size: .8rem; max-width: 18rem;
line-height: 1.35; box-shadow: 0 2px 10px rgba(0,0,0,.35); }
#gruppeBox b { display: block; margin-bottom: .3rem; color: var(--akzent-hell, #d6eade); }
.kennzahl { display: inline-block; background: #f1eee6; border-radius: 4px;
padding: .3rem .7rem; margin: .15rem .3rem .15rem 0; font-size: .9rem; }
.kennzahl b { color: var(--akzent); }
.hinweis { font-size: .8rem; color: #6b6557; }
#gruppenUebersicht tr.fixiert td { background: #e6e3dc; color: #555; }
.varianten { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .6rem; }
.variante {
border: 1px solid var(--rand); border-radius: 6px; background: white;
padding: .5rem .8rem; cursor: pointer; font-size: .85rem; text-align: left;
color: #2a2a24; min-width: 11rem;
}
.variante.aktiv { border-color: var(--akzent); background: #e6f0ea;
box-shadow: 0 0 0 1px var(--akzent); }
.variante b { color: var(--akzent); font-size: 1rem; }
.variante .zeile { display: block; color: #6b6557; }
</style>
</head>
<body>
<header>
<h1>Sitz &amp; Platz <small style="font-weight:normal">— Testoberfläche (Meilenstein 1)</small></h1>
<p>Session-basiert, nichts wird dauerhaft gespeichert (TTL 24 h). Sitzung: <code id="sitzungsId">wird angelegt…</code>
· <a href="/editor.html" style="color:#d6eade">grafischer Tisch-Editor</a></p>
</header>
<main>
<section>
<h2>1. Tische definieren</h2>
<p class="hinweis">Koordinaten sind Rasterpositionen (wie in tische.ini). Tische, die
näher als der Nachbar-Radius (1,5 Rastereinheiten) beieinander liegen, gelten
automatisch als Nachbarn — Gruppen, die geteilt werden müssen, kommen bevorzugt
an Nachbartische.</p>
<table id="tischTabelle">
<thead>
<tr><th>Tisch-Nr.</th><th>Plätze</th><th>X</th><th>Y</th><th></th></tr>
</thead>
<tbody></tbody>
</table>
<button type="button" onclick="tischZeile()">+ Tisch hinzufügen</button>
<button type="button" class="sekundaer" onclick="presetReihe()">Preset: 4er-Reihe</button>
<button type="button" class="sekundaer" onclick="presetRaster()">Preset: 3×3-Raster</button>
<br>
<label class="hinweis">Oder eine bestehende <code>tische.ini</code> auswählen
(z.&nbsp;B. aus <code>work/hochzeit</code>) — wird sofort geladen:</label>
<input type="file" id="tischDatei" accept=".ini,text/plain" onchange="tischDateiLaden()">
<br>
<button type="button" onclick="tischeSpeichern()">Tische speichern</button>
<div class="status" id="tischStatus"></div>
</section>
<section>
<h2>2. Gästeliste (CSV)</h2>
<p class="hinweis">Spalten: <code>Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl</code>
<code>Gruppe</code> hält Personen zusammen (leer = Einzelgast),
<code>Tisch</code> fixiert Gäste an einem Tisch (z.&nbsp;B. Brautpaar an Tisch 1),
<code>Anzahl</code> expandiert eine Zeile in mehrere Buchungen
(anonyme Sammelbuchung). Eine Datei auswählen (wird sofort übernommen)
<em>oder</em> hier direkt bearbeiten und übernehmen:</p>
<textarea id="csvText"></textarea>
<br>
<input type="file" id="csvDatei" accept=".csv,text/csv">
<br>
<button type="button" onclick="gaesteHochladen()">Gästeliste übernehmen</button>
<div class="status" id="gaesteStatus"></div>
<div id="gruppenUebersicht"></div>
</section>
<section>
<h2>3. Sitzordnung berechnen &amp; Varianten vergleichen</h2>
<p class="hinweis">Ein Lauf liefert bis zu drei <em>unterschiedliche</em> gute
Sitzordnungen zum Vergleich — die Wertigkeit (0 = perfekt, negativer = schlechter),
die Zahl getrennter Gruppen und allein sitzende Personen machen sie vergleichbar.
Variante anklicken, um Tische und Raumplan umzuschalten; jeder weitere Klick auf
„Berechnen“ startet einen frischen Lauf. Über das <em>Optimierungsprofil</em> lassen sich
Bewertungs-Vorgehen vergleichen (z.&nbsp;B. <code>default</code> vs.
<code>locker</code>): Profil wählen und neu berechnen.</p>
<label class="hinweis">Optimierungsprofil:
<select id="strafenWahl"></select></label>
<button type="button" id="berechnenKnopf" onclick="berechnen()" disabled>Sitzordnung berechnen</button>
<div class="status" id="rechnenStatus"></div>
<div class="varianten" id="variantenListe"></div>
<div id="kennzahlen"></div>
<p class="hinweis" style="margin-bottom:0">Im Raumplan mit der Maus über eine Person
fahren: Tooltip zeigt Name &amp; Gruppe, ein Kasten listet alle Namen dieser Gruppe,
und die Gruppe wird im Plan hervorgehoben.</p>
<div id="svgPlan"></div>
<div id="ergebnisTabellen"></div>
</section>
<div id="gruppeBox"></div>
</main>
<script>
'use strict';
let sitzung = null;
async function api(pfad, optionen) {
const antwort = await fetch(pfad, optionen);
const daten = await antwort.json().catch(() => null);
if (!antwort.ok) {
const detail = daten && daten.detail
? (typeof daten.detail === 'string' ? daten.detail : JSON.stringify(daten.detail, null, 2))
: antwort.statusText;
throw new Error(detail);
}
return daten;
}
function status(id, text, klasse) {
const el = document.getElementById(id);
el.textContent = text;
el.className = 'status ' + (klasse || '');
}
/* ------------------------------------------------ 1. Tische */
let geladenerRadius = 1.5; // zuletzt aus der Session geladener Nachbar-Radius
async function tischeAusSessionLaden() {
// Sektion 1 aus dem serverseitigen Session-Layout fuellen (z.B. was der
// grafische Editor gespeichert hat) statt fest das Preset zu zeigen.
try {
const r = await api('/sitzung/' + sitzung + '/tische');
if (r.tische && r.tische.length) {
tischeLeeren();
for (const t of r.tische) tischZeile(t.plaetze, t.x, t.y, t.id);
geladenerRadius = r.nachbarRadius || 1.5;
return;
}
} catch (e) { /* frische/abgelaufene Session — Preset als Fallback */ }
presetReihe();
}
function tischZeile(plaetze, x, y, tid) {
const tbody = document.querySelector('#tischTabelle tbody');
const nr = tid ?? tbody.children.length + 1;
const tr = document.createElement('tr');
if (tid !== undefined) tr.dataset.tid = tid; // echte Id aus tische.ini behalten
tr.innerHTML =
'<td class="tischNr">' + nr + '</td>' +
'<td><input type="number" min="1" max="100" value="' + (plaetze ?? 8) + '" class="plaetze"></td>' +
'<td><input type="number" step="1" value="' + (x ?? nr) + '" class="x"></td>' +
'<td><input type="number" step="1" value="' + (y ?? 1) + '" class="y"></td>' +
'<td><button type="button" class="sekundaer" onclick="this.closest(\'tr\').remove(); nummerieren()">✕</button></td>';
tbody.appendChild(tr);
}
function nummerieren() {
document.querySelectorAll('#tischTabelle tbody tr').forEach((tr, i) => {
if (tr.dataset.tid === undefined)
tr.querySelector('.tischNr').textContent = i + 1;
});
}
function tischeLeeren() {
document.querySelector('#tischTabelle tbody').innerHTML = '';
}
function presetReihe() {
tischeLeeren();
for (let i = 1; i <= 4; i++) tischZeile(5, i, 1);
}
function presetRaster() {
tischeLeeren();
for (let y = 1; y <= 3; y++)
for (let x = 1; x <= 3; x++)
tischZeile(8, x, y);
}
async function tischeSpeichern() {
const zeilen = [...document.querySelectorAll('#tischTabelle tbody tr')];
if (zeilen.length === 0) { status('tischStatus', 'Mindestens ein Tisch nötig.', 'fehler'); return; }
// Zeilen aus einer geladenen tische.ini behalten ihre echte Id
// (wichtig fuer VIP-Bindungen wie "Tisch 16"); neue Zeilen bekommen
// die naechste freie Id
const vergeben = new Set(zeilen.map(tr => parseInt(tr.dataset.tid, 10)).filter(n => !isNaN(n)));
let naechste = 1;
const freieId = () => { while (vergeben.has(naechste)) naechste++; vergeben.add(naechste); return naechste; };
const tische = zeilen.map(tr => ({
id: tr.dataset.tid !== undefined ? parseInt(tr.dataset.tid, 10) : freieId(),
plaetze: parseInt(tr.querySelector('.plaetze').value, 10),
x: parseFloat(tr.querySelector('.x').value),
y: parseFloat(tr.querySelector('.y').value),
}));
try {
const r = await api('/sitzung/' + sitzung + '/tische', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ tische, nachbarRadius: geladenerRadius }),
});
const nachbarn = r.tische.map(t => 'Tisch ' + t.id + ' ↔ [' + t.nachbarn.join(', ') + ']').join(' ');
status('tischStatus', '✓ ' + r.tische.length + ' Tische, ' + r.plaetzeGesamt +
' Plätze gesamt. Abgeleitete Nachbarn: ' + nachbarn, 'ok');
berechnenFreigeben();
} catch (e) { status('tischStatus', 'Fehler: ' + e.message, 'fehler'); }
}
async function tischDateiLaden() {
const eingabe = document.getElementById('tischDatei');
if (eingabe.files.length === 0) {
status('tischStatus', 'Bitte zuerst eine tische.ini auswählen.', 'fehler');
return;
}
const form = new FormData();
form.append('datei', eingabe.files[0]);
try {
const r = await api('/sitzung/' + sitzung + '/tische-datei', { method: 'POST', body: form });
tischeLeeren();
for (const t of r.tische) tischZeile(t.plaetze, t.x, t.y, t.id);
status('tischStatus', '✓ ' + r.tische.length + ' Tische aus Datei übernommen (' +
r.plaetzeGesamt + ' Plätze) — Layout ist bereits gespeichert, ' +
'„Tische speichern“ ist nur nach Änderungen nötig.', 'ok');
berechnenFreigeben();
} catch (e) { status('tischStatus', 'Fehler: ' + e.message, 'fehler'); }
finally { eingabe.value = ''; } // damit dieselbe Datei erneut auswählbar ist
}
/* ------------------------------------------------ 2. Gäste */
const beispielCSV = `Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl
Britta;Beispiel;;Brautpaar;1;
Bernd;Beispiel;Dr.;Brautpaar;1;
Anna;Huber;;Familie Huber;;
Berta;Huber;;Familie Huber;;
Carl;Huber;;Familie Huber;;
Doris;Huber;;Familie Huber;;
Emil;Meier;;Familie Meier;;
Frieda;Meier;;Familie Meier;;
Gustav;Meier;;Familie Meier;;
Hanna;Schmidt;;Studienfreunde;;
Igor;Petrov;;Studienfreunde;;
Julia;Weber;;Studienfreunde;;
Gast;Kollegium;;Kollegen;;4
Karl;Einzelgast;;;;
`;
async function csvDateiGewaehlt(ev) {
// Ausgewaehlte CSV sofort sichtbar in die Textarea laden (Single Source):
// dekodieren wie das Backend (utf-8-sig, sonst cp1252), BOM strippen.
const datei = ev.target.files[0];
if (!datei) return;
const puffer = await datei.arrayBuffer();
let text;
try {
text = new TextDecoder('utf-8', { fatal: true }).decode(puffer);
} catch (e) {
text = new TextDecoder('windows-1252').decode(puffer); // Excel/Windows
}
text = text.replace(/^/, '');
document.getElementById('csvText').value = text;
ev.target.value = ''; // damit dieselbe Datei erneut auswählbar ist
// direkt uebernehmen: die ausgewaehlte Datei wird sofort geladen (die
// Textarea ist bereits befuellt und dient gaesteHochladen als Quelle)
await gaesteHochladen();
}
async function gaesteHochladen() {
// immer die (ggf. aus einer Datei befuellte) Textarea senden
const blob = new Blob([document.getElementById('csvText').value], { type: 'text/csv' });
const form = new FormData();
form.append('datei', blob, 'gaeste.csv');
try {
const r = await api('/sitzung/' + sitzung + '/personen', { method: 'POST', body: form });
status('gaesteStatus', '✓ ' + r.personen + ' Personen in ' + r.gruppen.length +
' Gruppen' + (r.fixiert ? ', dazu ' + r.fixiert +
' fixierte Personen an festen Tischen' : '') + '.', 'ok');
// regulaere Gruppen, danach die fest platzierten ("fixierten") Gruppen
// grau hinterlegt
const regulaer = r.gruppen.map(g =>
'<tr><td>' + g.name + '</td><td>' + g.anzahl + '</td></tr>').join('');
const fixiert = (r.fixierte || []).map(f =>
'<tr class="fixiert"><td>' + f.name +
' <span class="hinweis">(fixiert an Tisch ' + f.tisch + ')</span></td><td>' +
f.anzahl + '</td></tr>').join('');
const html = '<table><thead><tr><th>Gruppe</th><th>Personen</th></tr></thead><tbody>' +
regulaer + fixiert + '</tbody></table>';
document.getElementById('gruppenUebersicht').innerHTML = html;
berechnenFreigeben();
} catch (e) { status('gaesteStatus', 'Fehler: ' + e.message, 'fehler'); }
}
/* ------------------------------------------------ 3. Berechnen */
async function strafprofileLaden() {
// Auswahl der Strafprofile aus strafen.cfg fuellen (z.B. default, locker)
try {
const r = await api('/strafprofile');
const sel = document.getElementById('strafenWahl');
sel.innerHTML = r.profile.map(p =>
'<option value="' + p + '"' + (p === r.vorgabe ? ' selected' : '') +
'>' + p + '</option>').join('');
} catch (e) { /* Auswahl bleibt leer -> Backend nutzt sein Default */ }
}
async function berechnenFreigeben() {
try {
const s = await api('/sitzung/' + sitzung);
document.getElementById('berechnenKnopf').disabled = !(s.tische > 0 && s.personen > 0);
} catch (e) { /* Session ggf. abgelaufen — beim Berechnen gemeldet */ }
}
let letzterLauf = null; // Antwort des letzten Berechnen-Laufs (mit Varianten)
async function berechnen() {
const knopf = document.getElementById('berechnenKnopf');
knopf.disabled = true;
status('rechnenStatus', 'Der genetische Algorithmus läuft…');
try {
const profil = document.getElementById('strafenWahl').value || 'default';
const r = await api('/sitzung/' + sitzung + '/berechnen?varianten=3&strafen=' +
encodeURIComponent(profil), { method: 'POST' });
letzterLauf = r;
status('rechnenStatus', '✓ Lauf ' + r.lauf + ' (Optimierungsprofil „' + r.strafen + '“): ' +
r.varianten.length +
(r.varianten.length === 1
? ' Variante gefunden (der Lauf konvergierte auf eine Sitzordnung).'
: ' unterschiedliche Varianten zum Vergleich.'), 'ok');
knopf.textContent = 'Neuen Lauf berechnen';
zeigeVariantenListe(r);
await zeigeVariante(0);
} catch (e) {
status('rechnenStatus', 'Fehler: ' + e.message, 'fehler');
} finally {
knopf.disabled = false;
}
}
function zeigeVariantenListe(r) {
document.getElementById('variantenListe').innerHTML = r.varianten.map((v, i) =>
'<button type="button" class="variante" data-i="' + i + '" onclick="zeigeVariante(' + i + ')">' +
'<b>Variante ' + v.nr + '</b>' +
'<span class="zeile">Wertigkeit: ' + v.kennzahlen.wertigkeit + '</span>' +
'<span class="zeile">getrennte Gruppen: ' + v.kennzahlen.getrennteGruppen +
' (' + v.kennzahlen.teilungenGesamt + ' Teilungen)</span>' +
'<span class="zeile">allein sitzend: ' + v.kennzahlen.alleinePersonen + '</span>' +
'</button>').join('');
}
async function zeigeVariante(i) {
if (!letzterLauf || !letzterLauf.varianten[i]) return;
const v = letzterLauf.varianten[i];
document.querySelectorAll('#variantenListe .variante').forEach(el =>
el.classList.toggle('aktiv', parseInt(el.dataset.i, 10) === i));
document.getElementById('kennzahlen').innerHTML =
'<span class="kennzahl">Variante: <b>' + v.nr + '</b> (Lauf ' + letzterLauf.lauf + ')</span>' +
'<span class="kennzahl">Optimierungsprofil: <b>' + letzterLauf.strafen + '</b></span>' +
'<span class="kennzahl">Wertigkeit: <b>' + v.kennzahlen.wertigkeit + '</b></span>' +
'<span class="kennzahl">getrennte Gruppen: <b>' + v.kennzahlen.getrennteGruppen + '</b></span>' +
'<span class="kennzahl">allein sitzend: <b>' + v.kennzahlen.alleinePersonen + '</b></span>';
let html = '<table><thead><tr><th>Tisch</th><th>Belegung</th><th>Gäste (Gruppe)</th></tr></thead><tbody>';
for (const t of v.tische) {
const gaeste = t.personen.map(p =>
((p.titel ? p.titel + ' ' : '') + p.vorname + ' ' + p.nachname +
' <span class="hinweis">(' + p.gruppe + ')</span>')).join(', ');
html += '<tr><td>Tisch ' + t.nummer + '</td><td>' + t.besetzt + '/' + t.plaetze +
'</td><td>' + gaeste + '</td></tr>';
}
html += '</tbody></table>';
html += '<h2 style="margin-top:1rem">Gruppen</h2>' +
'<table><thead><tr><th>Gruppe</th><th>Personen</th><th>Teilungen</th><th>Strafpunkte</th></tr></thead><tbody>' +
v.gruppen.map(g => '<tr><td>' + g.name + '</td><td>' + g.anzahl + '</td><td>' +
g.teilungen + '</td><td>' + g.wert + '</td></tr>').join('') +
'</tbody></table>';
document.getElementById('ergebnisTabellen').innerHTML = html;
// Raumplan der gewaehlten Variante — inline einbetten (nicht als <img>),
// damit die <title>-Tooltips und das Gruppen-Hover funktionieren
try {
const antwort = await fetch('/sitzung/' + sitzung + '/ergebnis.svg?variante=' + v.nr);
const svgText = await antwort.text();
const plan = document.getElementById('svgPlan');
plan.innerHTML = svgText.replace(/<\?xml[^>]*\?>/, ''); // XML-Prolog raus
gruppeInteraktion(plan.querySelector('svg'));
} catch (e) { /* SVG optional — Tabellen stehen schon da */ }
}
function escHtml(s) {
return (s || '').replace(/[&<>"]/g, c =>
({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]));
}
// Hover ueber einen Personenkreis: alle Kreise derselben Gruppe hervorheben
// und einen Kasten mit der Namensliste dieser Gruppe zeigen. Die Namen kommen
// direkt aus den data-name/data-gruppe-Attributen der SVG (vom Kern erzeugt).
function gruppeInteraktion(svg) {
if (!svg) return;
const box = document.getElementById('gruppeBox');
let markiert = null;
svg.querySelectorAll('.person').forEach(kreis => {
kreis.addEventListener('mouseenter', () => {
const gruppe = kreis.dataset.gruppe || '';
const gleiche = svg.querySelectorAll(
'.person[data-gruppe="' + (window.CSS ? CSS.escape(gruppe) : gruppe) + '"]');
gleiche.forEach(k => k.classList.add('aktiv'));
markiert = gleiche;
const namen = [...gleiche].map(k => k.dataset.name || '');
box.innerHTML = '<b>' + escHtml(gruppe) + ' (' + namen.length + ')</b>' +
namen.map(escHtml).join('<br>');
box.style.display = 'block';
});
kreis.addEventListener('mouseleave', () => {
if (markiert) markiert.forEach(k => k.classList.remove('aktiv'));
markiert = null;
box.style.display = 'none';
});
});
svg.addEventListener('mousemove', e => {
box.style.left = (e.clientX + 14) + 'px';
box.style.top = (e.clientY + 14) + 'px';
});
}
/* ------------------------------------------------ Start */
window.addEventListener('DOMContentLoaded', async () => {
document.getElementById('csvText').value = beispielCSV;
document.getElementById('csvDatei').addEventListener('change', csvDateiGewaehlt);
strafprofileLaden();
try {
sitzung = await sitzungHolen();
document.getElementById('sitzungsId').textContent = sitzung;
// Tische aus der (ggf. mit dem Editor geteilten) Session laden;
// Preset nur, wenn die Session noch keine Tische hat
await tischeAusSessionLaden();
berechnenFreigeben();
} catch (e) {
document.getElementById('sitzungsId').textContent = 'Fehler: ' + e.message;
presetReihe();
}
});
// Session mit dem grafischen Editor (editor.html) ueber localStorage teilen:
// eine bestehende, noch gueltige Sitzung wiederverwenden statt jedes Mal
// eine neue anzulegen — so wirkt ein im Editor gebautes Layout hier weiter.
async function sitzungHolen() {
let id = localStorage.getItem('platzSitzung');
if (id) {
const ok = await fetch('/sitzung/' + id).then(r => r.ok).catch(() => false);
if (ok) return id;
}
const r = await api('/sitzung', { method: 'POST' });
localStorage.setItem('platzSitzung', r.id);
return r.id;
}
</script>
</body>
</html>
+458
View File
@@ -0,0 +1,458 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="2200" height="430" viewBox="0 0 2200 430" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="1100" y="30" text-anchor="middle" font-size="16" fill="#333">Abstammung der Loesungen (Mutationsbaum)</text>
<line x1="60.0" y1="60.0" x2="60.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="86.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="166.7" y1="60.0" x2="112.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="139.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="165.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="191.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="380.0" y1="60.0" x2="218.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="433.3" y1="60.0" x2="244.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="270.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="540.0" y1="60.0" x2="297.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="323.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="349.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="700.0" y1="60.0" x2="375.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="753.3" y1="60.0" x2="402.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="428.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="454.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="481.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="507.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="533.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1073.3" y1="60.0" x2="560.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="586.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1180.0" y1="60.0" x2="612.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1233.3" y1="60.0" x2="639.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="665.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1340.0" y1="60.0" x2="691.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="718.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="744.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="770.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="797.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="823.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1660.0" y1="60.0" x2="849.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="876.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="902.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1820.0" y1="60.0" x2="928.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1873.3" y1="60.0" x2="955.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1926.7" y1="60.0" x2="981.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1980.0" y1="60.0" x2="1007.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="1034.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="1060.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="60.0" x2="1086.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="60.0" x2="1113.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="1139.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="166.7" y1="60.0" x2="1165.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="1192.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="1218.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="1244.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="380.0" y1="60.0" x2="1271.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="433.3" y1="60.0" x2="1297.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="1323.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="540.0" y1="60.0" x2="1350.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="1376.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="1402.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="700.0" y1="60.0" x2="1429.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="753.3" y1="60.0" x2="1455.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="1481.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="1508.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="1534.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="1560.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="1587.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1073.3" y1="60.0" x2="1613.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="1639.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1180.0" y1="60.0" x2="1666.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1233.3" y1="60.0" x2="1692.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="1718.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1340.0" y1="60.0" x2="1745.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="1771.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="1797.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="1824.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="1850.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="1876.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1660.0" y1="60.0" x2="1903.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="1929.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="1955.7" y2="150.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="1820.0" y1="60.0" x2="1982.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1873.3" y1="60.0" x2="2008.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1926.7" y1="60.0" x2="2034.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1980.0" y1="60.0" x2="2061.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="2087.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="2113.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="60.0" x2="2140.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1955.7" y1="150.0" x2="60.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="91.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="122.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="507.6" y1="150.0" x2="153.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1560.8" y1="150.0" x2="184.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="215.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="246.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1323.8" y1="150.0" x2="277.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1508.1" y1="150.0" x2="308.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="339.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="370.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="401.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="86.3" y1="150.0" x2="432.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="349.6" y1="150.0" x2="463.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="612.9" y1="150.0" x2="494.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1192.2" y1="150.0" x2="525.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1244.8" y1="150.0" x2="556.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1402.8" y1="150.0" x2="587.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1771.4" y1="150.0" x2="618.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="649.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="680.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="711.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="533.9" y1="150.0" x2="743.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="902.5" y1="150.0" x2="774.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1666.1" y1="150.0" x2="805.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1745.1" y1="150.0" x2="836.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1876.7" y1="150.0" x2="867.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1086.8" y1="150.0" x2="898.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1534.4" y1="150.0" x2="929.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="960.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="428.6" y1="150.0" x2="991.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="1022.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="297.0" y1="150.0" x2="1053.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1350.1" y1="150.0" x2="1084.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1955.7" y1="150.0" x2="1115.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="1146.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="1177.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="507.6" y1="150.0" x2="1208.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1560.8" y1="150.0" x2="1239.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="1270.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="1301.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1323.8" y1="150.0" x2="1332.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1508.1" y1="150.0" x2="1363.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="1394.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="1426.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="1457.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="86.3" y1="150.0" x2="1488.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="349.6" y1="150.0" x2="1519.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="612.9" y1="150.0" x2="1550.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1192.2" y1="150.0" x2="1581.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1244.8" y1="150.0" x2="1612.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1402.8" y1="150.0" x2="1643.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1771.4" y1="150.0" x2="1674.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="1705.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="1736.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="1767.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="533.9" y1="150.0" x2="1798.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="902.5" y1="150.0" x2="1829.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1666.1" y1="150.0" x2="1860.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1745.1" y1="150.0" x2="1891.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1876.7" y1="150.0" x2="1922.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1086.8" y1="150.0" x2="1953.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1534.4" y1="150.0" x2="1984.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="2015.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="428.6" y1="150.0" x2="2046.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="2077.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="297.0" y1="150.0" x2="2109.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1350.1" y1="150.0" x2="2140.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="774.0" y1="240.0" x2="60.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1955.7" y1="150.0" x2="97.8" y2="330.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="1766.7" y1="60.0" x2="135.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="240.0" x2="173.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="91.0" y1="240.0" x2="211.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1146.6" y1="240.0" x2="249.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1239.7" y1="240.0" x2="286.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="324.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="960.3" y1="240.0" x2="362.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1177.6" y1="240.0" x2="400.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1674.3" y1="240.0" x2="438.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="507.6" y1="150.0" x2="476.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1560.8" y1="150.0" x2="513.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="618.8" y1="240.0" x2="551.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1270.7" y1="240.0" x2="589.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="627.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="246.3" y1="240.0" x2="665.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="867.2" y1="240.0" x2="702.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1922.7" y1="240.0" x2="740.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="778.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="277.3" y1="240.0" x2="816.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="370.4" y1="240.0" x2="854.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="401.5" y1="240.0" x2="892.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1426.0" y1="240.0" x2="929.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1457.0" y1="240.0" x2="967.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1323.8" y1="150.0" x2="1005.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1508.1" y1="150.0" x2="1043.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="1081.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="774.0" y1="240.0" x2="1118.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1955.7" y1="150.0" x2="1156.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="1194.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="240.0" x2="1232.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="91.0" y1="240.0" x2="1270.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1146.6" y1="240.0" x2="1308.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1239.7" y1="240.0" x2="1345.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="1383.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="960.3" y1="240.0" x2="1421.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1177.6" y1="240.0" x2="1459.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1674.3" y1="240.0" x2="1497.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="507.6" y1="150.0" x2="1534.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1560.8" y1="150.0" x2="1572.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="618.8" y1="240.0" x2="1610.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1270.7" y1="240.0" x2="1648.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="1686.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="246.3" y1="240.0" x2="1724.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="867.2" y1="240.0" x2="1761.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1922.7" y1="240.0" x2="1799.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="1837.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="277.3" y1="240.0" x2="1875.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="370.4" y1="240.0" x2="1913.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="401.5" y1="240.0" x2="1950.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1426.0" y1="240.0" x2="1988.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1457.0" y1="240.0" x2="2026.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1323.8" y1="150.0" x2="2064.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1508.1" y1="150.0" x2="2102.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="2140.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<circle cx="60.0" cy="60.0" r="5" fill="#577147" stroke="#333" stroke-width="0.5"><title>Id 1, Wert -83.7</title></circle>
<circle cx="113.3" cy="60.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 2, Wert -54.7</title></circle>
<circle cx="166.7" cy="60.0" r="5" fill="#5b6f46" stroke="#333" stroke-width="0.5"><title>Id 3, Wert -86.3</title></circle>
<circle cx="220.0" cy="60.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 4, Wert -57.7</title></circle>
<circle cx="273.3" cy="60.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 5, Wert -59.3</title></circle>
<circle cx="326.7" cy="60.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 6, Wert -60.3</title></circle>
<circle cx="380.0" cy="60.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 7, Wert -84.7</title></circle>
<circle cx="433.3" cy="60.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 8, Wert -59.3</title></circle>
<circle cx="486.7" cy="60.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 9, Wert -53.7</title></circle>
<circle cx="540.0" cy="60.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 10, Wert -57.7</title></circle>
<circle cx="593.3" cy="60.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 11, Wert -63.3</title></circle>
<circle cx="646.7" cy="60.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 12, Wert -84.7</title></circle>
<circle cx="700.0" cy="60.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 13, Wert -57.7</title></circle>
<circle cx="753.3" cy="60.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 14, Wert -84.7</title></circle>
<circle cx="806.7" cy="60.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 15, Wert -64.0</title></circle>
<circle cx="860.0" cy="60.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 16, Wert -53.7</title></circle>
<circle cx="913.3" cy="60.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 17, Wert -54.7</title></circle>
<circle cx="966.7" cy="60.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 18, Wert -50.7</title></circle>
<circle cx="1020.0" cy="60.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 19, Wert -57.0</title></circle>
<circle cx="1073.3" cy="60.0" r="5" fill="#5f6c45" stroke="#333" stroke-width="0.5"><title>Id 20, Wert -89.3</title></circle>
<circle cx="1126.7" cy="60.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 21, Wert -53.7</title></circle>
<circle cx="1180.0" cy="60.0" r="5" fill="#537347" stroke="#333" stroke-width="0.5"><title>Id 22, Wert -80.7</title></circle>
<circle cx="1233.3" cy="60.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 23, Wert -57.7</title></circle>
<circle cx="1286.7" cy="60.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 24, Wert -59.3</title></circle>
<circle cx="1340.0" cy="60.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 25, Wert -63.3</title></circle>
<circle cx="1393.3" cy="60.0" r="5" fill="#636a44" stroke="#333" stroke-width="0.5"><title>Id 26, Wert -92.7</title></circle>
<circle cx="1446.7" cy="60.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 27, Wert -60.9</title></circle>
<circle cx="1500.0" cy="60.0" r="5" fill="#5d6e46" stroke="#333" stroke-width="0.5"><title>Id 28, Wert -87.7</title></circle>
<circle cx="1553.3" cy="60.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 29, Wert -54.7</title></circle>
<circle cx="1606.7" cy="60.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 30, Wert -56.3</title></circle>
<circle cx="1660.0" cy="60.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 31, Wert -60.3</title></circle>
<circle cx="1713.3" cy="60.0" r="5" fill="#686743" stroke="#333" stroke-width="0.5"><title>Id 32, Wert -95.7</title></circle>
<circle cx="1766.7" cy="60.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 33, Wert -48.7</title></circle>
<circle cx="1820.0" cy="60.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 34, Wert -58.7</title></circle>
<circle cx="1873.3" cy="60.0" r="5" fill="#5a6f46" stroke="#333" stroke-width="0.5"><title>Id 35, Wert -85.9</title></circle>
<circle cx="1926.7" cy="60.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 36, Wert -60.3</title></circle>
<circle cx="1980.0" cy="60.0" r="5" fill="#447b4a" stroke="#333" stroke-width="0.5"><title>Id 37, Wert -69.7</title></circle>
<circle cx="2033.3" cy="60.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 38, Wert -123.6</title></circle>
<circle cx="2086.7" cy="60.0" r="5" fill="#89553d" stroke="#333" stroke-width="0.5"><title>Id 39, Wert -120.3</title></circle>
<circle cx="2140.0" cy="60.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 40, Wert -59.3</title></circle>
<circle cx="60.0" cy="150.0" r="5" fill="#577147" stroke="#333" stroke-width="0.5"><title>Id 41, Wert -83.7</title></circle>
<circle cx="86.3" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 42, Wert -54.7</title></circle>
<circle cx="112.7" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 43, Wert -52.0</title></circle>
<circle cx="139.0" cy="150.0" r="5" fill="#2d884e" stroke="#333" stroke-width="0.5"><title>Id 44, Wert -53.0</title></circle>
<circle cx="165.3" cy="150.0" r="5" fill="#39824c" stroke="#333" stroke-width="0.5"><title>Id 45, Wert -61.7</title></circle>
<circle cx="191.6" cy="150.0" r="5" fill="#427c4a" stroke="#333" stroke-width="0.5"><title>Id 46, Wert -68.3</title></circle>
<circle cx="218.0" cy="150.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 47, Wert -60.0</title></circle>
<circle cx="244.3" cy="150.0" r="5" fill="#547247" stroke="#333" stroke-width="0.5"><title>Id 48, Wert -81.7</title></circle>
<circle cx="270.6" cy="150.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 49, Wert -59.7</title></circle>
<circle cx="297.0" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 50, Wert -57.7</title></circle>
<circle cx="323.3" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 51, Wert -100.6</title></circle>
<circle cx="349.6" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 52, Wert -54.7</title></circle>
<circle cx="375.9" cy="150.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 53, Wert -60.0</title></circle>
<circle cx="402.3" cy="150.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 54, Wert -84.7</title></circle>
<circle cx="428.6" cy="150.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 55, Wert -57.0</title></circle>
<circle cx="454.9" cy="150.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 56, Wert -59.7</title></circle>
<circle cx="481.3" cy="150.0" r="5" fill="#3b814c" stroke="#333" stroke-width="0.5"><title>Id 57, Wert -62.7</title></circle>
<circle cx="507.6" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 58, Wert -51.7</title></circle>
<circle cx="533.9" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 59, Wert -55.0</title></circle>
<circle cx="560.3" cy="150.0" r="5" fill="#805a3f" stroke="#333" stroke-width="0.5"><title>Id 60, Wert -113.4</title></circle>
<circle cx="586.6" cy="150.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 61, Wert -85.0</title></circle>
<circle cx="612.9" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 62, Wert -54.7</title></circle>
<circle cx="639.2" cy="150.0" r="5" fill="#5d6d45" stroke="#333" stroke-width="0.5"><title>Id 63, Wert -88.0</title></circle>
<circle cx="665.6" cy="150.0" r="5" fill="#5f6c45" stroke="#333" stroke-width="0.5"><title>Id 64, Wert -89.3</title></circle>
<circle cx="691.9" cy="150.0" r="5" fill="#676844" stroke="#333" stroke-width="0.5"><title>Id 65, Wert -94.9</title></circle>
<circle cx="718.2" cy="150.0" r="5" fill="#636a44" stroke="#333" stroke-width="0.5"><title>Id 66, Wert -92.6</title></circle>
<circle cx="744.6" cy="150.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 67, Wert -84.7</title></circle>
<circle cx="770.9" cy="150.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 68, Wert -84.7</title></circle>
<circle cx="797.2" cy="150.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 69, Wert -60.0</title></circle>
<circle cx="823.5" cy="150.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 70, Wert -84.7</title></circle>
<circle cx="849.9" cy="150.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 71, Wert -63.3</title></circle>
<circle cx="876.2" cy="150.0" r="5" fill="#686743" stroke="#333" stroke-width="0.5"><title>Id 72, Wert -95.7</title></circle>
<circle cx="902.5" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 73, Wert -55.0</title></circle>
<circle cx="928.9" cy="150.0" r="5" fill="#3b814c" stroke="#333" stroke-width="0.5"><title>Id 74, Wert -62.7</title></circle>
<circle cx="955.2" cy="150.0" r="5" fill="#3f7f4b" stroke="#333" stroke-width="0.5"><title>Id 75, Wert -65.6</title></circle>
<circle cx="981.5" cy="150.0" r="5" fill="#5e6d45" stroke="#333" stroke-width="0.5"><title>Id 76, Wert -89.0</title></circle>
<circle cx="1007.8" cy="150.0" r="5" fill="#8d523c" stroke="#333" stroke-width="0.5"><title>Id 77, Wert -123.3</title></circle>
<circle cx="1034.2" cy="150.0" r="5" fill="#6d6442" stroke="#333" stroke-width="0.5"><title>Id 78, Wert -99.6</title></circle>
<circle cx="1060.5" cy="150.0" r="5" fill="#4a7849" stroke="#333" stroke-width="0.5"><title>Id 79, Wert -74.3</title></circle>
<circle cx="1086.8" cy="150.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 80, Wert -56.3</title></circle>
<circle cx="1113.2" cy="150.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 81, Wert -59.0</title></circle>
<circle cx="1139.5" cy="150.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 82, Wert -59.7</title></circle>
<circle cx="1165.8" cy="150.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 83, Wert -59.0</title></circle>
<circle cx="1192.2" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 84, Wert -54.7</title></circle>
<circle cx="1218.5" cy="150.0" r="5" fill="#9c4a3a" stroke="#333" stroke-width="0.5"><title>Id 85, Wert -134.0</title></circle>
<circle cx="1244.8" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 86, Wert -54.7</title></circle>
<circle cx="1271.1" cy="150.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 87, Wert -60.0</title></circle>
<circle cx="1297.5" cy="150.0" r="5" fill="#547247" stroke="#333" stroke-width="0.5"><title>Id 88, Wert -81.7</title></circle>
<circle cx="1323.8" cy="150.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 89, Wert -53.7</title></circle>
<circle cx="1350.1" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 90, Wert -57.7</title></circle>
<circle cx="1376.5" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 91, Wert -75.5</title></circle>
<circle cx="1402.8" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 92, Wert -54.7</title></circle>
<circle cx="1429.1" cy="150.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 93, Wert -60.0</title></circle>
<circle cx="1455.4" cy="150.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 94, Wert -60.0</title></circle>
<circle cx="1481.8" cy="150.0" r="5" fill="#6a6643" stroke="#333" stroke-width="0.5"><title>Id 95, Wert -97.6</title></circle>
<circle cx="1508.1" cy="150.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 96, Wert -53.7</title></circle>
<circle cx="1534.4" cy="150.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 97, Wert -56.3</title></circle>
<circle cx="1560.8" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 98, Wert -51.7</title></circle>
<circle cx="1587.1" cy="150.0" r="5" fill="#417d4b" stroke="#333" stroke-width="0.5"><title>Id 99, Wert -67.3</title></circle>
<circle cx="1613.4" cy="150.0" r="5" fill="#3e7f4b" stroke="#333" stroke-width="0.5"><title>Id 100, Wert -65.0</title></circle>
<circle cx="1639.7" cy="150.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 101, Wert -59.0</title></circle>
<circle cx="1666.1" cy="150.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 102, Wert -55.3</title></circle>
<circle cx="1692.4" cy="150.0" r="5" fill="#3b814c" stroke="#333" stroke-width="0.5"><title>Id 103, Wert -62.7</title></circle>
<circle cx="1718.7" cy="150.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 104, Wert -59.0</title></circle>
<circle cx="1745.1" cy="150.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 105, Wert -56.0</title></circle>
<circle cx="1771.4" cy="150.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 106, Wert -54.7</title></circle>
<circle cx="1797.7" cy="150.0" r="5" fill="#9c4a3a" stroke="#333" stroke-width="0.5"><title>Id 107, Wert -134.1</title></circle>
<circle cx="1824.1" cy="150.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 108, Wert -60.0</title></circle>
<circle cx="1850.4" cy="150.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 109, Wert -60.0</title></circle>
<circle cx="1876.7" cy="150.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 110, Wert -56.0</title></circle>
<circle cx="1903.0" cy="150.0" r="5" fill="#437c4a" stroke="#333" stroke-width="0.5"><title>Id 111, Wert -68.9</title></circle>
<circle cx="1929.4" cy="150.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 112, Wert -72.0</title></circle>
<circle cx="1955.7" cy="150.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 113, Wert -48.7</title></circle>
<circle cx="1982.0" cy="150.0" r="5" fill="#5f6c45" stroke="#333" stroke-width="0.5"><title>Id 114, Wert -89.7</title></circle>
<circle cx="2008.4" cy="150.0" r="5" fill="#9d4939" stroke="#333" stroke-width="0.5"><title>Id 115, Wert -135.3</title></circle>
<circle cx="2034.7" cy="150.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 116, Wert -166.1</title></circle>
<circle cx="2061.0" cy="150.0" r="5" fill="#8d523c" stroke="#333" stroke-width="0.5"><title>Id 117, Wert -123.3</title></circle>
<circle cx="2087.3" cy="150.0" r="5" fill="#6a6643" stroke="#333" stroke-width="0.5"><title>Id 118, Wert -97.6</title></circle>
<circle cx="2113.7" cy="150.0" r="5" fill="#666944" stroke="#333" stroke-width="0.5"><title>Id 119, Wert -94.3</title></circle>
<circle cx="2140.0" cy="150.0" r="5" fill="#5e6d45" stroke="#333" stroke-width="0.5"><title>Id 120, Wert -88.3</title></circle>
<circle cx="60.0" cy="240.0" r="5" fill="#298a4f" stroke="#333" stroke-width="0.5"><title>Id 121, Wert -50.0</title></circle>
<circle cx="91.0" cy="240.0" r="5" fill="#298a4f" stroke="#333" stroke-width="0.5"><title>Id 122, Wert -50.0</title></circle>
<circle cx="122.1" cy="240.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 123, Wert -58.7</title></circle>
<circle cx="153.1" cy="240.0" r="5" fill="#587046" stroke="#333" stroke-width="0.5"><title>Id 124, Wert -84.3</title></circle>
<circle cx="184.2" cy="240.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 125, Wert -58.7</title></circle>
<circle cx="215.2" cy="240.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 126, Wert -59.0</title></circle>
<circle cx="246.3" cy="240.0" r="5" fill="#2d884e" stroke="#333" stroke-width="0.5"><title>Id 127, Wert -53.0</title></circle>
<circle cx="277.3" cy="240.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 128, Wert -53.7</title></circle>
<circle cx="308.4" cy="240.0" r="5" fill="#567147" stroke="#333" stroke-width="0.5"><title>Id 129, Wert -83.0</title></circle>
<circle cx="339.4" cy="240.0" r="5" fill="#567147" stroke="#333" stroke-width="0.5"><title>Id 130, Wert -83.0</title></circle>
<circle cx="370.4" cy="240.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 131, Wert -53.7</title></circle>
<circle cx="401.5" cy="240.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 132, Wert -53.7</title></circle>
<circle cx="432.5" cy="240.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 133, Wert -85.0</title></circle>
<circle cx="463.6" cy="240.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 134, Wert -57.0</title></circle>
<circle cx="494.6" cy="240.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 135, Wert -55.3</title></circle>
<circle cx="525.7" cy="240.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 136, Wert -84.7</title></circle>
<circle cx="556.7" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 137, Wert -54.7</title></circle>
<circle cx="587.8" cy="240.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 138, Wert -80.0</title></circle>
<circle cx="618.8" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 139, Wert -52.0</title></circle>
<circle cx="649.9" cy="240.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 140, Wert -60.0</title></circle>
<circle cx="680.9" cy="240.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 141, Wert -56.3</title></circle>
<circle cx="711.9" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 142, Wert -54.7</title></circle>
<circle cx="743.0" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 143, Wert -55.0</title></circle>
<circle cx="774.0" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 144, Wert -48.7</title></circle>
<circle cx="805.1" cy="240.0" r="5" fill="#537347" stroke="#333" stroke-width="0.5"><title>Id 145, Wert -80.7</title></circle>
<circle cx="836.1" cy="240.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 146, Wert -56.0</title></circle>
<circle cx="867.2" cy="240.0" r="5" fill="#2d884e" stroke="#333" stroke-width="0.5"><title>Id 147, Wert -53.0</title></circle>
<circle cx="898.2" cy="240.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 148, Wert -58.3</title></circle>
<circle cx="929.3" cy="240.0" r="5" fill="#5e6d45" stroke="#333" stroke-width="0.5"><title>Id 149, Wert -88.3</title></circle>
<circle cx="960.3" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 150, Wert -51.7</title></circle>
<circle cx="991.3" cy="240.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 151, Wert -80.0</title></circle>
<circle cx="1022.4" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 152, Wert -55.0</title></circle>
<circle cx="1053.4" cy="240.0" r="5" fill="#3e7f4b" stroke="#333" stroke-width="0.5"><title>Id 153, Wert -65.0</title></circle>
<circle cx="1084.5" cy="240.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 154, Wert -57.7</title></circle>
<circle cx="1115.5" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 155, Wert -55.0</title></circle>
<circle cx="1146.6" cy="240.0" r="5" fill="#298a4f" stroke="#333" stroke-width="0.5"><title>Id 156, Wert -50.0</title></circle>
<circle cx="1177.6" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 157, Wert -51.7</title></circle>
<circle cx="1208.7" cy="240.0" r="5" fill="#587046" stroke="#333" stroke-width="0.5"><title>Id 158, Wert -84.3</title></circle>
<circle cx="1239.7" cy="240.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 159, Wert -50.7</title></circle>
<circle cx="1270.7" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 160, Wert -52.0</title></circle>
<circle cx="1301.8" cy="240.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 161, Wert -80.0</title></circle>
<circle cx="1332.8" cy="240.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 162, Wert -84.7</title></circle>
<circle cx="1363.9" cy="240.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 163, Wert -84.7</title></circle>
<circle cx="1394.9" cy="240.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 164, Wert -84.7</title></circle>
<circle cx="1426.0" cy="240.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 165, Wert -53.7</title></circle>
<circle cx="1457.0" cy="240.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 166, Wert -53.7</title></circle>
<circle cx="1488.1" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 167, Wert -54.7</title></circle>
<circle cx="1519.1" cy="240.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 168, Wert -80.0</title></circle>
<circle cx="1550.1" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 169, Wert -54.7</title></circle>
<circle cx="1581.2" cy="240.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 170, Wert -84.7</title></circle>
<circle cx="1612.2" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 171, Wert -54.7</title></circle>
<circle cx="1643.3" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 172, Wert -54.7</title></circle>
<circle cx="1674.3" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 173, Wert -51.7</title></circle>
<circle cx="1705.4" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 174, Wert -54.7</title></circle>
<circle cx="1736.4" cy="240.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 175, Wert -59.7</title></circle>
<circle cx="1767.5" cy="240.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 176, Wert -60.0</title></circle>
<circle cx="1798.5" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 177, Wert -55.0</title></circle>
<circle cx="1829.6" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 178, Wert -55.0</title></circle>
<circle cx="1860.6" cy="240.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 179, Wert -55.3</title></circle>
<circle cx="1891.6" cy="240.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 180, Wert -56.0</title></circle>
<circle cx="1922.7" cy="240.0" r="5" fill="#2d884e" stroke="#333" stroke-width="0.5"><title>Id 181, Wert -53.0</title></circle>
<circle cx="1953.7" cy="240.0" r="5" fill="#5c6e46" stroke="#333" stroke-width="0.5"><title>Id 182, Wert -87.3</title></circle>
<circle cx="1984.8" cy="240.0" r="5" fill="#3b814c" stroke="#333" stroke-width="0.5"><title>Id 183, Wert -62.7</title></circle>
<circle cx="2015.8" cy="240.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 184, Wert -54.7</title></circle>
<circle cx="2046.9" cy="240.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 185, Wert -57.0</title></circle>
<circle cx="2077.9" cy="240.0" r="5" fill="#88553d" stroke="#333" stroke-width="0.5"><title>Id 186, Wert -119.7</title></circle>
<circle cx="2109.0" cy="240.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 187, Wert -57.7</title></circle>
<circle cx="2140.0" cy="240.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 188, Wert -57.7</title></circle>
<circle cx="60.0" cy="330.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 189, Wert -79.0</title></circle>
<circle cx="97.8" cy="330.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 190, Wert -48.7</title></circle>
<circle cx="135.6" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 191, Wert -48.7</title></circle>
<circle cx="173.5" cy="330.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 192, Wert -79.0</title></circle>
<circle cx="211.3" cy="330.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 193, Wert -55.0</title></circle>
<circle cx="249.1" cy="330.0" r="5" fill="#298a4f" stroke="#333" stroke-width="0.5"><title>Id 194, Wert -50.0</title></circle>
<circle cx="286.9" cy="330.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 195, Wert -50.7</title></circle>
<circle cx="324.7" cy="330.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 196, Wert -50.7</title></circle>
<circle cx="362.5" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 197, Wert -51.7</title></circle>
<circle cx="400.4" cy="330.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 198, Wert -58.7</title></circle>
<circle cx="438.2" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 199, Wert -52.0</title></circle>
<circle cx="476.0" cy="330.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 200, Wert -50.7</title></circle>
<circle cx="513.8" cy="330.0" r="5" fill="#587046" stroke="#333" stroke-width="0.5"><title>Id 201, Wert -84.3</title></circle>
<circle cx="551.6" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 202, Wert -52.0</title></circle>
<circle cx="589.5" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 203, Wert -52.0</title></circle>
<circle cx="627.3" cy="330.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 204, Wert -60.7</title></circle>
<circle cx="665.1" cy="330.0" r="5" fill="#2d884e" stroke="#333" stroke-width="0.5"><title>Id 205, Wert -53.0</title></circle>
<circle cx="702.9" cy="330.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 206, Wert -80.0</title></circle>
<circle cx="740.7" cy="330.0" r="5" fill="#2d884e" stroke="#333" stroke-width="0.5"><title>Id 207, Wert -53.0</title></circle>
<circle cx="778.5" cy="330.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 208, Wert -57.0</title></circle>
<circle cx="816.4" cy="330.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 209, Wert -53.7</title></circle>
<circle cx="854.2" cy="330.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 210, Wert -53.7</title></circle>
<circle cx="892.0" cy="330.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 211, Wert -60.7</title></circle>
<circle cx="929.8" cy="330.0" r="5" fill="#567147" stroke="#333" stroke-width="0.5"><title>Id 212, Wert -83.0</title></circle>
<circle cx="967.6" cy="330.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 213, Wert -53.7</title></circle>
<circle cx="1005.5" cy="330.0" r="5" fill="#567147" stroke="#333" stroke-width="0.5"><title>Id 214, Wert -83.0</title></circle>
<circle cx="1043.3" cy="330.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 215, Wert -59.7</title></circle>
<circle cx="1081.1" cy="330.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 216, Wert -53.7</title></circle>
<circle cx="1118.9" cy="330.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 217, Wert -79.0</title></circle>
<circle cx="1156.7" cy="330.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 218, Wert -79.0</title></circle>
<circle cx="1194.5" cy="330.0" r="5" fill="#298a4f" stroke="#333" stroke-width="0.5"><title>Id 219, Wert -50.0</title></circle>
<circle cx="1232.4" cy="330.0" r="5" fill="#298a4f" stroke="#333" stroke-width="0.5"><title>Id 220, Wert -50.0</title></circle>
<circle cx="1270.2" cy="330.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 221, Wert -55.0</title></circle>
<circle cx="1308.0" cy="330.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 222, Wert -55.0</title></circle>
<circle cx="1345.8" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 223, Wert -51.7</title></circle>
<circle cx="1383.6" cy="330.0" r="5" fill="#587046" stroke="#333" stroke-width="0.5"><title>Id 224, Wert -84.3</title></circle>
<circle cx="1421.5" cy="330.0" r="5" fill="#597046" stroke="#333" stroke-width="0.5"><title>Id 225, Wert -84.7</title></circle>
<circle cx="1459.3" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 226, Wert -51.7</title></circle>
<circle cx="1497.1" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 227, Wert -52.0</title></circle>
<circle cx="1534.9" cy="330.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 228, Wert -58.7</title></circle>
<circle cx="1572.7" cy="330.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 229, Wert -50.7</title></circle>
<circle cx="1610.5" cy="330.0" r="5" fill="#577147" stroke="#333" stroke-width="0.5"><title>Id 230, Wert -83.7</title></circle>
<circle cx="1648.4" cy="330.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 231, Wert -60.7</title></circle>
<circle cx="1686.2" cy="330.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 232, Wert -59.0</title></circle>
<circle cx="1724.0" cy="330.0" r="5" fill="#2d884e" stroke="#333" stroke-width="0.5"><title>Id 233, Wert -53.0</title></circle>
<circle cx="1761.8" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 234, Wert -48.7</title></circle>
<circle cx="1799.6" cy="330.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 235, Wert -56.0</title></circle>
<circle cx="1837.5" cy="330.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 236, Wert -57.0</title></circle>
<circle cx="1875.3" cy="330.0" r="5" fill="#567147" stroke="#333" stroke-width="0.5"><title>Id 237, Wert -83.0</title></circle>
<circle cx="1913.1" cy="330.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 238, Wert -59.7</title></circle>
<circle cx="1950.9" cy="330.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 239, Wert -53.7</title></circle>
<circle cx="1988.7" cy="330.0" r="5" fill="#567147" stroke="#333" stroke-width="0.5"><title>Id 240, Wert -83.0</title></circle>
<circle cx="2026.5" cy="330.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 241, Wert -59.0</title></circle>
<circle cx="2064.4" cy="330.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 242, Wert -59.7</title></circle>
<circle cx="2102.2" cy="330.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 243, Wert -59.7</title></circle>
<circle cx="2140.0" cy="330.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 244, Wert -59.7</title></circle>
<text x="97.8" y="352.0" text-anchor="middle" font-size="12" font-weight="bold" fill="#c04040">190</text>
<text x="48" y="64.0" text-anchor="end" font-size="11" fill="#666">Gen 0</text>
<text x="48" y="154.0" text-anchor="end" font-size="11" fill="#666">Gen 1</text>
<text x="48" y="244.0" text-anchor="end" font-size="11" fill="#666">Gen 2</text>
<text x="48" y="334.0" text-anchor="end" font-size="11" fill="#666">Gen 3</text>
</svg>

After

Width:  |  Height:  |  Size: 48 KiB

+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="650" viewBox="0 0 900 650" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="450" y="30" text-anchor="middle" font-size="16" fill="#333">Entwicklung der Loesungsfindung</text>
<line x1="60" y1="60" x2="60" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="394.0" text-anchor="end" font-size="11" fill="#666">-166</text>
<line x1="60" y1="324.0" x2="840" y2="324.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="328.0" text-anchor="end" font-size="11" fill="#666">-143</text>
<line x1="60" y1="258.0" x2="840" y2="258.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="262.0" text-anchor="end" font-size="11" fill="#666">-119</text>
<line x1="60" y1="192.0" x2="840" y2="192.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="196.0" text-anchor="end" font-size="11" fill="#666">-96</text>
<line x1="60" y1="126.0" x2="840" y2="126.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="130.0" text-anchor="end" font-size="11" fill="#666">-72</text>
<line x1="60" y1="60.0" x2="840" y2="60.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="64.0" text-anchor="end" font-size="11" fill="#666">-49</text>
<text x="18" y="225.0" text-anchor="middle" font-size="12" fill="#333" transform="rotate(-90 18 225.0)">Wertigkeit (hoeher = besser)</text>
<polyline points="60.0,60.0 146.7,60.0 233.3,60.0 320.0,60.0 406.7,60.0 493.3,60.0 580.0,60.0 666.7,60.0 753.3,60.0 840.0,60.0" fill="none" stroke="#2f6f4f" stroke-width="2"/>
<polyline points="60.0,117.6 146.7,130.2 233.3,126.0 320.0,75.9 406.7,100.7 493.3,92.4 580.0,69.1 666.7,94.1 753.3,85.7 840.0,64.3" fill="none" stroke="#c08a2d" stroke-width="2"/>
<polyline points="60.0,270.5 146.7,390.0 233.3,390.0 320.0,85.3 406.7,259.4 493.3,259.4 580.0,74.0 666.7,161.1 753.3,161.1 840.0,68.4" fill="none" stroke="#a03030" stroke-width="2"/>
<line x1="680" y1="70" x2="704" y2="70" stroke="#2f6f4f" stroke-width="2"/>
<text x="710" y="74" font-size="11" fill="#333">beste Loesung</text>
<line x1="680" y1="88" x2="704" y2="88" stroke="#c08a2d" stroke-width="2"/>
<text x="710" y="92" font-size="11" fill="#333">Durchschnitt</text>
<line x1="680" y1="106" x2="704" y2="106" stroke="#a03030" stroke-width="2"/>
<text x="710" y="110" font-size="11" fill="#333">schlechteste Loesung</text>
<text x="450" y="428.0" text-anchor="middle" font-size="13" fill="#333">Anzahl erzeugter Verteilungen im Pool</text>
<line x1="60" y1="440.0" x2="60" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="594.0" text-anchor="end" font-size="11" fill="#666">0</text>
<line x1="60" y1="515.0" x2="840" y2="515.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="519.0" text-anchor="end" font-size="11" fill="#666">60</text>
<line x1="60" y1="440.0" x2="840" y2="440.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="444.0" text-anchor="end" font-size="11" fill="#666">120</text>
<polyline points="60.0,540.0 146.7,490.0 233.3,440.0 320.0,547.5 406.7,505.0 493.3,462.5 580.0,555.0 666.7,520.0 753.3,485.0 840.0,561.2" fill="none" stroke="#4060a0" stroke-width="2"/>
<text x="60.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">e</text>
<text x="146.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="233.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="320.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="406.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="493.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="580.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="666.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="753.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="840.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="450" y="638" text-anchor="middle" font-size="12" fill="#333">Zyklus-Aktion (Zeit)</text>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

+120
View File
@@ -0,0 +1,120 @@
Aksoy, Rainer, = Hof 1, Tisch 1, Nummer 13
Aksoy, Renate, = Hof 1, Tisch 1, Nummer 10
Aydin, Horst, = Hof 1, Tisch 15, Nummer 4
Aydin, Ursula, = Hof 1, Tisch 15, Nummer 5
Barth, Hannelore, = Hof 1, Tisch 9, Nummer 3
Berger, Sergej, = Hof 1, Tisch 8, Nummer 3
Brandt, Andreas, = Hof 1, Tisch 14, Nummer 2
Brandt, Anja, = Hof 1, Tisch 14, Nummer 6
Brandt, Anton, = Hof 1, Tisch 16, Nummer 9
Brandt, Ben, = Hof 1, Tisch 17, Nummer 2
Brandt, Daniel, = Hof 1, Tisch 11, Nummer 8
Brandt, Felix, = Hof 1, Tisch 16, Nummer 7
Brandt, Frieda, = Hof 1, Tisch 16, Nummer 10
Brandt, Greta, = Hof 1, Tisch 16, Nummer 12
Brandt, Helga, = Hof 1, Tisch 1, Nummer 5
Brandt, Julia, = Hof 1, Tisch 1, Nummer 2
Brandt, Kathrin, = Hof 1, Tisch 11, Nummer 9
Brandt, Lena, = Hof 1, Tisch 14, Nummer 3
Brandt, Milan, = Hof 1, Tisch 14, Nummer 5
Brandt, Paul, = Hof 1, Tisch 17, Nummer 3
Brandt, Sofia, = Hof 1, Tisch 14, Nummer 7
Brandt, Theo, = Hof 1, Tisch 14, Nummer 4
Brandt, Werner, = Hof 1, Tisch 1, Nummer 4
Busch, Stefanie, = Hof 1, Tisch 8, Nummer 7
Demir, Elif, = Hof 1, Tisch 10, Nummer 2
Demir, Hannelore, = Hof 1, Tisch 13, Nummer 4
Demir, Ingrid, = Hof 1, Tisch 13, Nummer 2
Demir, Monika, = Hof 1, Tisch 13, Nummer 3
Dietrich, Jennifer, = Hof 1, Tisch 2, Nummer 5
Dietrich, Nicole, = Hof 1, Tisch 12, Nummer 7
Erdem, Erika, = Hof 1, Tisch 15, Nummer 7
Erdem, Gerhard, = Hof 1, Tisch 9, Nummer 5
Erdem, Rainer, = Hof 1, Tisch 9, Nummer 6
Esposito, Christian, = Hof 1, Tisch 12, Nummer 4
Esposito, Gisela, = Hof 1, Tisch 9, Nummer 7
Esposito, Julia, = Hof 1, Tisch 2, Nummer 4
Fischer, Heinz, = Hof 1, Tisch 3, Nummer 3
Fischer, Helga, = Hof 1, Tisch 3, Nummer 2
Fischer, Nicole, = Hof 1, Tisch 12, Nummer 2
Fischer, Sven, = Hof 1, Tisch 4, Nummer 9
Frank, Erika, = Hof 1, Tisch 9, Nummer 4
Frank, Nadine, = Hof 1, Tisch 11, Nummer 2
Frank, Timo, = Hof 1, Tisch 10, Nummer 6
Frank, Tobias, = Hof 1, Tisch 1, Nummer 9
Franke, Brigitte, = Hof 1, Tisch 9, Nummer 8
Hansen, Olga, = Hof 1, Tisch 11, Nummer 5
Hansen, Wolfgang, = Hof 1, Tisch 9, Nummer 2
Hoffmann, Lena, = Hof 1, Tisch 12, Nummer 5
Horn, Daniel, = Hof 1, Tisch 11, Nummer 6
Horn, Svenja, = Hof 1, Tisch 2, Nummer 7
Klein, Stefan, = Hof 1, Tisch 10, Nummer 5
Koch, Andreas, = Hof 1, Tisch 8, Nummer 8
Koch, Giovanna, = Hof 1, Tisch 2, Nummer 3
Kovac, Giovanna, = Hof 1, Tisch 8, Nummer 4
Kraus, Dennis, = Hof 1, Tisch 12, Nummer 8
Kraus, Matteo, = Hof 1, Tisch 16, Nummer 8
Kraus, Melanie, = Hof 1, Tisch 12, Nummer 9
Kuhn, Leni, = Hof 1, Tisch 16, Nummer 2
Kuhn, Sarah, = Hof 1, Tisch 14, Nummer 9
Kuhn, Stefan, = Hof 1, Tisch 2, Nummer 9
Kuhn, Timo, = Hof 1, Tisch 14, Nummer 8
Lange, Milan, = Hof 1, Tisch 11, Nummer 7
Meyer, Anton, = Hof 1, Tisch 17, Nummer 4
Meyer, Christian, = Hof 1, Tisch 2, Nummer 6
Meyer, Ida, = Hof 1, Tisch 17, Nummer 5
Meyer, Marco, = Hof 1, Tisch 5, Nummer 8
Meyer, Mila, = Hof 1, Tisch 16, Nummer 11
Meyer, Sandra, = Hof 1, Tisch 5, Nummer 9
Meyer, Wolfgang, = Hof 1, Tisch 9, Nummer 9
Musikverein, Gast, = Hof 1, Tisch 4, Nummer 2
Musikverein, Gast, = Hof 1, Tisch 4, Nummer 3
Musikverein, Gast, = Hof 1, Tisch 4, Nummer 4
Musikverein, Gast, = Hof 1, Tisch 4, Nummer 5
Musikverein, Gast, = Hof 1, Tisch 4, Nummer 6
Musikverein, Gast, = Hof 1, Tisch 4, Nummer 7
Musikverein, Gast, = Hof 1, Tisch 4, Nummer 8
Musikverein, Gast, = Hof 1, Tisch 5, Nummer 2
Musikverein, Gast, = Hof 1, Tisch 5, Nummer 3
Musikverein, Gast, = Hof 1, Tisch 5, Nummer 4
Musikverein, Gast, = Hof 1, Tisch 5, Nummer 5
Musikverein, Gast, = Hof 1, Tisch 5, Nummer 6
Musikverein, Gast, = Hof 1, Tisch 5, Nummer 7
Peters, Melanie, = Hof 1, Tisch 8, Nummer 9
Peters, Yusuf, = Hof 1, Tisch 8, Nummer 2
Polat, Matthias, = Hof 1, Tisch 12, Nummer 3
Roth, Stefanie, = Hof 1, Tisch 2, Nummer 8
Schmidt, Dennis, = Hof 1, Tisch 8, Nummer 5
Schmitt, Markus, = Hof 1, Tisch 11, Nummer 3
Schwarz, Elias, = Hof 1, Tisch 16, Nummer 6
Schwarz, Guenter, = Hof 1, Tisch 1, Nummer 12
Schwarz, Liam, = Hof 1, Tisch 16, Nummer 5
Schwarz, Sarah, = Hof 1, Tisch 15, Nummer 3
Schwarz, Yusuf, = Hof 1, Tisch 15, Nummer 2
Simon, Jennifer, = Hof 1, Tisch 10, Nummer 3
Simon, Patrick, = Hof 1, Tisch 8, Nummer 6
Simon, Stefanie, = Hof 1, Tisch 10, Nummer 8
Sommer, Daniel, = Hof 1, Tisch 1, Nummer 3
Sommer, Dennis, = Hof 1, Tisch 13, Nummer 7
Sommer, Dennis, = Hof 1, Tisch 15, Nummer 8
Sommer, Dieter, = Hof 1, Tisch 1, Nummer 6
Sommer, Emil, = Hof 1, Tisch 16, Nummer 3
Sommer, Ida, = Hof 1, Tisch 16, Nummer 4
Sommer, Jennifer, = Hof 1, Tisch 15, Nummer 9
Sommer, Lina, = Hof 1, Tisch 13, Nummer 9
Sommer, Max, = Hof 1, Tisch 16, Nummer 14
Sommer, Nicole, = Hof 1, Tisch 13, Nummer 8
Sommer, Renate, = Hof 1, Tisch 1, Nummer 7
Sommer, Theo, = Hof 1, Tisch 16, Nummer 13
Stein, Andreas, = Hof 1, Tisch 10, Nummer 4
Stein, Werner, = Hof 1, Tisch 1, Nummer 11
Tran, Heinz, = Hof 1, Tisch 15, Nummer 6
Vogel, Anton, = Hof 1, Tisch 17, Nummer 6
Vogel, Max, = Hof 1, Tisch 17, Nummer 7
Vogel, Sandra, = Hof 1, Tisch 13, Nummer 6
Vogel, Svenja, = Hof 1, Tisch 2, Nummer 2
Vogel, Yusuf, = Hof 1, Tisch 13, Nummer 5
Wagner, Daniel, = Hof 1, Tisch 10, Nummer 7
Wagner, Timo, = Hof 1, Tisch 12, Nummer 6
Winkler, Sarah, = Hof 1, Tisch 1, Nummer 8
Yilmaz, Olga, = Hof 1, Tisch 11, Nummer 4
1 Aksoy Rainer = Hof 1 Tisch 1 Nummer 13
2 Aksoy Renate = Hof 1 Tisch 1 Nummer 10
3 Aydin Horst = Hof 1 Tisch 15 Nummer 4
4 Aydin Ursula = Hof 1 Tisch 15 Nummer 5
5 Barth Hannelore = Hof 1 Tisch 9 Nummer 3
6 Berger Sergej = Hof 1 Tisch 8 Nummer 3
7 Brandt Andreas = Hof 1 Tisch 14 Nummer 2
8 Brandt Anja = Hof 1 Tisch 14 Nummer 6
9 Brandt Anton = Hof 1 Tisch 16 Nummer 9
10 Brandt Ben = Hof 1 Tisch 17 Nummer 2
11 Brandt Daniel = Hof 1 Tisch 11 Nummer 8
12 Brandt Felix = Hof 1 Tisch 16 Nummer 7
13 Brandt Frieda = Hof 1 Tisch 16 Nummer 10
14 Brandt Greta = Hof 1 Tisch 16 Nummer 12
15 Brandt Helga = Hof 1 Tisch 1 Nummer 5
16 Brandt Julia = Hof 1 Tisch 1 Nummer 2
17 Brandt Kathrin = Hof 1 Tisch 11 Nummer 9
18 Brandt Lena = Hof 1 Tisch 14 Nummer 3
19 Brandt Milan = Hof 1 Tisch 14 Nummer 5
20 Brandt Paul = Hof 1 Tisch 17 Nummer 3
21 Brandt Sofia = Hof 1 Tisch 14 Nummer 7
22 Brandt Theo = Hof 1 Tisch 14 Nummer 4
23 Brandt Werner = Hof 1 Tisch 1 Nummer 4
24 Busch Stefanie = Hof 1 Tisch 8 Nummer 7
25 Demir Elif = Hof 1 Tisch 10 Nummer 2
26 Demir Hannelore = Hof 1 Tisch 13 Nummer 4
27 Demir Ingrid = Hof 1 Tisch 13 Nummer 2
28 Demir Monika = Hof 1 Tisch 13 Nummer 3
29 Dietrich Jennifer = Hof 1 Tisch 2 Nummer 5
30 Dietrich Nicole = Hof 1 Tisch 12 Nummer 7
31 Erdem Erika = Hof 1 Tisch 15 Nummer 7
32 Erdem Gerhard = Hof 1 Tisch 9 Nummer 5
33 Erdem Rainer = Hof 1 Tisch 9 Nummer 6
34 Esposito Christian = Hof 1 Tisch 12 Nummer 4
35 Esposito Gisela = Hof 1 Tisch 9 Nummer 7
36 Esposito Julia = Hof 1 Tisch 2 Nummer 4
37 Fischer Heinz = Hof 1 Tisch 3 Nummer 3
38 Fischer Helga = Hof 1 Tisch 3 Nummer 2
39 Fischer Nicole = Hof 1 Tisch 12 Nummer 2
40 Fischer Sven = Hof 1 Tisch 4 Nummer 9
41 Frank Erika = Hof 1 Tisch 9 Nummer 4
42 Frank Nadine = Hof 1 Tisch 11 Nummer 2
43 Frank Timo = Hof 1 Tisch 10 Nummer 6
44 Frank Tobias = Hof 1 Tisch 1 Nummer 9
45 Franke Brigitte = Hof 1 Tisch 9 Nummer 8
46 Hansen Olga = Hof 1 Tisch 11 Nummer 5
47 Hansen Wolfgang = Hof 1 Tisch 9 Nummer 2
48 Hoffmann Lena = Hof 1 Tisch 12 Nummer 5
49 Horn Daniel = Hof 1 Tisch 11 Nummer 6
50 Horn Svenja = Hof 1 Tisch 2 Nummer 7
51 Klein Stefan = Hof 1 Tisch 10 Nummer 5
52 Koch Andreas = Hof 1 Tisch 8 Nummer 8
53 Koch Giovanna = Hof 1 Tisch 2 Nummer 3
54 Kovac Giovanna = Hof 1 Tisch 8 Nummer 4
55 Kraus Dennis = Hof 1 Tisch 12 Nummer 8
56 Kraus Matteo = Hof 1 Tisch 16 Nummer 8
57 Kraus Melanie = Hof 1 Tisch 12 Nummer 9
58 Kuhn Leni = Hof 1 Tisch 16 Nummer 2
59 Kuhn Sarah = Hof 1 Tisch 14 Nummer 9
60 Kuhn Stefan = Hof 1 Tisch 2 Nummer 9
61 Kuhn Timo = Hof 1 Tisch 14 Nummer 8
62 Lange Milan = Hof 1 Tisch 11 Nummer 7
63 Meyer Anton = Hof 1 Tisch 17 Nummer 4
64 Meyer Christian = Hof 1 Tisch 2 Nummer 6
65 Meyer Ida = Hof 1 Tisch 17 Nummer 5
66 Meyer Marco = Hof 1 Tisch 5 Nummer 8
67 Meyer Mila = Hof 1 Tisch 16 Nummer 11
68 Meyer Sandra = Hof 1 Tisch 5 Nummer 9
69 Meyer Wolfgang = Hof 1 Tisch 9 Nummer 9
70 Musikverein Gast = Hof 1 Tisch 4 Nummer 2
71 Musikverein Gast = Hof 1 Tisch 4 Nummer 3
72 Musikverein Gast = Hof 1 Tisch 4 Nummer 4
73 Musikverein Gast = Hof 1 Tisch 4 Nummer 5
74 Musikverein Gast = Hof 1 Tisch 4 Nummer 6
75 Musikverein Gast = Hof 1 Tisch 4 Nummer 7
76 Musikverein Gast = Hof 1 Tisch 4 Nummer 8
77 Musikverein Gast = Hof 1 Tisch 5 Nummer 2
78 Musikverein Gast = Hof 1 Tisch 5 Nummer 3
79 Musikverein Gast = Hof 1 Tisch 5 Nummer 4
80 Musikverein Gast = Hof 1 Tisch 5 Nummer 5
81 Musikverein Gast = Hof 1 Tisch 5 Nummer 6
82 Musikverein Gast = Hof 1 Tisch 5 Nummer 7
83 Peters Melanie = Hof 1 Tisch 8 Nummer 9
84 Peters Yusuf = Hof 1 Tisch 8 Nummer 2
85 Polat Matthias = Hof 1 Tisch 12 Nummer 3
86 Roth Stefanie = Hof 1 Tisch 2 Nummer 8
87 Schmidt Dennis = Hof 1 Tisch 8 Nummer 5
88 Schmitt Markus = Hof 1 Tisch 11 Nummer 3
89 Schwarz Elias = Hof 1 Tisch 16 Nummer 6
90 Schwarz Guenter = Hof 1 Tisch 1 Nummer 12
91 Schwarz Liam = Hof 1 Tisch 16 Nummer 5
92 Schwarz Sarah = Hof 1 Tisch 15 Nummer 3
93 Schwarz Yusuf = Hof 1 Tisch 15 Nummer 2
94 Simon Jennifer = Hof 1 Tisch 10 Nummer 3
95 Simon Patrick = Hof 1 Tisch 8 Nummer 6
96 Simon Stefanie = Hof 1 Tisch 10 Nummer 8
97 Sommer Daniel = Hof 1 Tisch 1 Nummer 3
98 Sommer Dennis = Hof 1 Tisch 13 Nummer 7
99 Sommer Dennis = Hof 1 Tisch 15 Nummer 8
100 Sommer Dieter = Hof 1 Tisch 1 Nummer 6
101 Sommer Emil = Hof 1 Tisch 16 Nummer 3
102 Sommer Ida = Hof 1 Tisch 16 Nummer 4
103 Sommer Jennifer = Hof 1 Tisch 15 Nummer 9
104 Sommer Lina = Hof 1 Tisch 13 Nummer 9
105 Sommer Max = Hof 1 Tisch 16 Nummer 14
106 Sommer Nicole = Hof 1 Tisch 13 Nummer 8
107 Sommer Renate = Hof 1 Tisch 1 Nummer 7
108 Sommer Theo = Hof 1 Tisch 16 Nummer 13
109 Stein Andreas = Hof 1 Tisch 10 Nummer 4
110 Stein Werner = Hof 1 Tisch 1 Nummer 11
111 Tran Heinz = Hof 1 Tisch 15 Nummer 6
112 Vogel Anton = Hof 1 Tisch 17 Nummer 6
113 Vogel Max = Hof 1 Tisch 17 Nummer 7
114 Vogel Sandra = Hof 1 Tisch 13 Nummer 6
115 Vogel Svenja = Hof 1 Tisch 2 Nummer 2
116 Vogel Yusuf = Hof 1 Tisch 13 Nummer 5
117 Wagner Daniel = Hof 1 Tisch 10 Nummer 7
118 Wagner Timo = Hof 1 Tisch 12 Nummer 6
119 Winkler Sarah = Hof 1 Tisch 1 Nummer 8
120 Yilmaz Olga = Hof 1 Tisch 11 Nummer 4
+194
View File
@@ -0,0 +1,194 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="995.887" height="667.258" viewBox="0 0 995.887 667.258">
<rect width="100%" height="100%" fill="white"/>
<polyline points="239.695,263.249 374.577,76.1153" fill="none" stroke="#bfef45" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="419.271,254.956 589.915,255.537" fill="none" stroke="#fabed4" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<circle cx="87.1573" cy="415.786" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<ellipse cx="87.1573" cy="415.786" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="87.1573" y="410.986" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">7</text>
<text x="87.1573" y="424.186" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="415.786" cy="415.786" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<ellipse cx="415.786" cy="415.786" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="415.786" y="410.986" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">9</text>
<text x="415.786" y="424.186" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="744.415" cy="251.472" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="12" data-gruppe="Onkel und Tante (Braut-Seite)" data-name="Horst Aydin" cx="744.415" cy="216.979" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Horst Aydin — Onkel und Tante (Braut-Seite)</title></circle>
<circle class="person" data-gid="12" data-gruppe="Onkel und Tante (Braut-Seite)" data-name="Ursula Aydin" cx="744.415" cy="285.965" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Ursula Aydin — Onkel und Tante (Braut-Seite)</title></circle>
<ellipse cx="744.415" cy="251.472" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="744.415" y="246.672" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">6</text>
<text x="744.415" y="259.872" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="908.73" cy="415.786" r="48.4" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Ben Brandt" cx="908.73" cy="389.386" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Ben Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Paul Brandt" cx="931.593" cy="402.586" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Paul Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Anton Meyer" cx="931.593" cy="428.986" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Anton Meyer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Ida Meyer" cx="908.73" cy="442.186" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Ida Meyer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Anton Vogel" cx="885.867" cy="428.986" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Anton Vogel — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Max Vogel" cx="885.867" cy="402.586" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Max Vogel — VIP / feste Platzierung</title></circle>
<ellipse cx="908.73" cy="415.786" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="908.73" y="410.986" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">17</text>
<text x="908.73" y="424.186" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">6 Pl.</text>
<circle cx="580.101" cy="415.786" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="18" data-gruppe="Arbeitskolleginnen der Braut" data-name="Elif Demir" cx="580.101" cy="381.293" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Elif Demir — Arbeitskolleginnen der Braut</title></circle>
<circle class="person" data-gid="18" data-gruppe="Arbeitskolleginnen der Braut" data-name="Jennifer Simon" cx="607.069" cy="394.28" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Jennifer Simon — Arbeitskolleginnen der Braut</title></circle>
<circle class="person" data-gid="18" data-gruppe="Arbeitskolleginnen der Braut" data-name="Andreas Stein" cx="613.729" cy="423.462" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Andreas Stein — Arbeitskolleginnen der Braut</title></circle>
<circle class="person" data-gid="18" data-gruppe="Arbeitskolleginnen der Braut" data-name="Stefan Klein" cx="595.067" cy="446.864" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Stefan Klein — Arbeitskolleginnen der Braut</title></circle>
<circle class="person" data-gid="18" data-gruppe="Arbeitskolleginnen der Braut" data-name="Timo Frank" cx="565.135" cy="446.864" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Timo Frank — Arbeitskolleginnen der Braut</title></circle>
<circle class="person" data-gid="18" data-gruppe="Arbeitskolleginnen der Braut" data-name="Daniel Wagner" cx="546.472" cy="423.462" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Daniel Wagner — Arbeitskolleginnen der Braut</title></circle>
<circle class="person" data-gid="18" data-gruppe="Arbeitskolleginnen der Braut" data-name="Stefanie Simon" cx="553.133" cy="394.28" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Stefanie Simon — Arbeitskolleginnen der Braut</title></circle>
<ellipse cx="580.101" cy="415.786" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="580.101" y="410.986" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">10</text>
<text x="580.101" y="424.186" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="87.1573" cy="251.472" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="11" data-gruppe="Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch" data-name="Yusuf Schwarz" cx="87.1573" cy="216.979" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Yusuf Schwarz — Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="11" data-gruppe="Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch" data-name="Sarah Schwarz" cx="111.548" cy="227.081" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Sarah Schwarz — Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="14" data-gruppe="Onkel und Tante (Braeutigam-Seite)" data-name="Heinz Fischer" cx="121.651" cy="251.472" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Heinz Fischer — Onkel und Tante (Braeutigam-Seite)</title></circle>
<circle class="person" data-gid="14" data-gruppe="Onkel und Tante (Braeutigam-Seite)" data-name="Helga Fischer" cx="111.548" cy="275.862" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Helga Fischer — Onkel und Tante (Braeutigam-Seite)</title></circle>
<circle class="person" data-gid="15" data-gruppe="Grosstante mit Begleitung" data-name="Heinz Tran" cx="87.1573" cy="285.965" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Heinz Tran — Grosstante mit Begleitung</title></circle>
<circle class="person" data-gid="15" data-gruppe="Grosstante mit Begleitung" data-name="Erika Erdem" cx="62.7669" cy="275.862" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Erika Erdem — Grosstante mit Begleitung</title></circle>
<circle class="person" data-gid="10" data-gruppe="Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch" data-name="Dennis Sommer" cx="52.664" cy="251.472" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Dennis Sommer — Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="10" data-gruppe="Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch" data-name="Jennifer Sommer" cx="62.7669" cy="227.081" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Jennifer Sommer — Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch</title></circle>
<ellipse cx="87.1573" cy="251.472" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="87.1573" y="246.672" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">2</text>
<text x="87.1573" y="259.872" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="251.472" cy="251.472" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="13" data-gruppe="Onkel und Tante mit Cousine (Braut-Seite)" data-name="Ingrid Demir" cx="251.472" cy="216.979" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Ingrid Demir — Onkel und Tante mit Cousine (Braut-Seite)</title></circle>
<circle class="person" data-gid="13" data-gruppe="Onkel und Tante mit Cousine (Braut-Seite)" data-name="Monika Demir" cx="275.862" cy="227.081" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Monika Demir — Onkel und Tante mit Cousine (Braut-Seite)</title></circle>
<circle class="person" data-gid="13" data-gruppe="Onkel und Tante mit Cousine (Braut-Seite)" data-name="Hannelore Demir" cx="285.965" cy="251.472" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Hannelore Demir — Onkel und Tante mit Cousine (Braut-Seite)</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Svenja Vogel" cx="275.862" cy="275.862" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Svenja Vogel — Fussballverein des Braeutigams</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Andreas Koch" cx="251.472" cy="285.965" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Andreas Koch — Fussballverein des Braeutigams</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Stefanie Busch" cx="227.081" cy="275.862" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Stefanie Busch — Fussballverein des Braeutigams</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Giovanna Koch" cx="216.979" cy="251.472" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Giovanna Koch — Fussballverein des Braeutigams</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Julia Esposito" cx="227.081" cy="227.081" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Julia Esposito — Fussballverein des Braeutigams</title></circle>
<ellipse cx="251.472" cy="251.472" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="251.472" y="246.672" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">3</text>
<text x="251.472" y="259.872" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="415.786" cy="251.472" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="415.786" cy="216.979" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="440.177" cy="227.081" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="450.28" cy="251.472" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="440.177" cy="275.862" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="415.786" cy="285.965" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="391.396" cy="275.862" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="381.293" cy="251.472" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="24" data-gruppe="alleinreisender Gast" data-name="Sven Fischer" cx="391.396" cy="227.081" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Sven Fischer — alleinreisender Gast</title></circle>
<ellipse cx="415.786" cy="251.472" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="415.786" y="246.672" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">4</text>
<text x="415.786" y="259.872" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="580.101" cy="251.472" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="580.101" cy="216.979" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="604.491" cy="227.081" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="614.594" cy="251.472" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="604.491" cy="275.862" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="580.101" cy="285.965" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="23" data-gruppe="Musikverein (anonyme Sammelbuchung, 13 Karten)" data-name="Gast Musikverein" cx="555.711" cy="275.862" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Gast Musikverein — Musikverein (anonyme Sammelbuchung, 13 Karten)</title></circle>
<circle class="person" data-gid="3" data-gruppe="Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch" data-name="Dennis Kraus" cx="545.608" cy="251.472" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Dennis Kraus — Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="3" data-gruppe="Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch" data-name="Melanie Kraus" cx="555.711" cy="227.081" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Melanie Kraus — Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch</title></circle>
<ellipse cx="580.101" cy="251.472" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="580.101" y="246.672" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">5</text>
<text x="580.101" y="259.872" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="251.472" cy="415.786" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="17" data-gruppe="Kegelclub des Brautvaters" data-name="Wolfgang Hansen" cx="251.472" cy="381.293" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Wolfgang Hansen — Kegelclub des Brautvaters</title></circle>
<circle class="person" data-gid="17" data-gruppe="Kegelclub des Brautvaters" data-name="Hannelore Barth" cx="275.862" cy="391.396" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Hannelore Barth — Kegelclub des Brautvaters</title></circle>
<circle class="person" data-gid="17" data-gruppe="Kegelclub des Brautvaters" data-name="Erika Frank" cx="285.965" cy="415.786" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Erika Frank — Kegelclub des Brautvaters</title></circle>
<circle class="person" data-gid="17" data-gruppe="Kegelclub des Brautvaters" data-name="Gerhard Erdem" cx="275.862" cy="440.177" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Gerhard Erdem — Kegelclub des Brautvaters</title></circle>
<circle class="person" data-gid="17" data-gruppe="Kegelclub des Brautvaters" data-name="Rainer Erdem" cx="251.472" cy="450.28" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Rainer Erdem — Kegelclub des Brautvaters</title></circle>
<circle class="person" data-gid="17" data-gruppe="Kegelclub des Brautvaters" data-name="Gisela Esposito" cx="227.081" cy="440.177" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Gisela Esposito — Kegelclub des Brautvaters</title></circle>
<circle class="person" data-gid="17" data-gruppe="Kegelclub des Brautvaters" data-name="Brigitte Franke" cx="216.979" cy="415.786" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Brigitte Franke — Kegelclub des Brautvaters</title></circle>
<circle class="person" data-gid="17" data-gruppe="Kegelclub des Brautvaters" data-name="Wolfgang Meyer" cx="227.081" cy="391.396" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Wolfgang Meyer — Kegelclub des Brautvaters</title></circle>
<ellipse cx="251.472" cy="415.786" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="251.472" y="410.986" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">8</text>
<text x="251.472" y="424.186" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="744.415" cy="415.786" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="19" data-gruppe="Arbeitskollegen des Braeutigams" data-name="Nadine Frank" cx="744.415" cy="381.293" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Nadine Frank — Arbeitskollegen des Braeutigams</title></circle>
<circle class="person" data-gid="19" data-gruppe="Arbeitskollegen des Braeutigams" data-name="Markus Schmitt" cx="768.806" cy="391.396" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Markus Schmitt — Arbeitskollegen des Braeutigams</title></circle>
<circle class="person" data-gid="19" data-gruppe="Arbeitskollegen des Braeutigams" data-name="Olga Yilmaz" cx="778.909" cy="415.786" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Olga Yilmaz — Arbeitskollegen des Braeutigams</title></circle>
<circle class="person" data-gid="19" data-gruppe="Arbeitskollegen des Braeutigams" data-name="Olga Hansen" cx="768.806" cy="440.177" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Olga Hansen — Arbeitskollegen des Braeutigams</title></circle>
<circle class="person" data-gid="19" data-gruppe="Arbeitskollegen des Braeutigams" data-name="Daniel Horn" cx="744.415" cy="450.28" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Daniel Horn — Arbeitskollegen des Braeutigams</title></circle>
<circle class="person" data-gid="19" data-gruppe="Arbeitskollegen des Braeutigams" data-name="Milan Lange" cx="720.025" cy="440.177" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Milan Lange — Arbeitskollegen des Braeutigams</title></circle>
<circle class="person" data-gid="1" data-gruppe="Familie Peters (Braut-Seite, Geschwister Melanie)" data-name="Yusuf Peters" cx="709.922" cy="415.786" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Yusuf Peters — Familie Peters (Braut-Seite, Geschwister Melanie)</title></circle>
<circle class="person" data-gid="1" data-gruppe="Familie Peters (Braut-Seite, Geschwister Melanie)" data-name="Melanie Peters" cx="720.025" cy="391.396" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Melanie Peters — Familie Peters (Braut-Seite, Geschwister Melanie)</title></circle>
<ellipse cx="744.415" cy="415.786" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="744.415" y="410.986" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">11</text>
<text x="744.415" y="424.186" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="87.1573" cy="580.101" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="16" data-gruppe="Studienfreunde der Braut" data-name="Nicole Fischer" cx="87.1573" cy="545.608" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Nicole Fischer — Studienfreunde der Braut</title></circle>
<circle class="person" data-gid="16" data-gruppe="Studienfreunde der Braut" data-name="Matthias Polat" cx="111.548" cy="555.711" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Matthias Polat — Studienfreunde der Braut</title></circle>
<circle class="person" data-gid="16" data-gruppe="Studienfreunde der Braut" data-name="Christian Esposito" cx="121.651" cy="580.101" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Christian Esposito — Studienfreunde der Braut</title></circle>
<circle class="person" data-gid="16" data-gruppe="Studienfreunde der Braut" data-name="Lena Hoffmann" cx="111.548" cy="604.491" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Lena Hoffmann — Studienfreunde der Braut</title></circle>
<circle class="person" data-gid="16" data-gruppe="Studienfreunde der Braut" data-name="Timo Wagner" cx="87.1573" cy="614.594" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Timo Wagner — Studienfreunde der Braut</title></circle>
<circle class="person" data-gid="16" data-gruppe="Studienfreunde der Braut" data-name="Nicole Dietrich" cx="62.7669" cy="604.491" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Nicole Dietrich — Studienfreunde der Braut</title></circle>
<circle class="person" data-gid="2" data-gruppe="Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch" data-name="Daniel Brandt" cx="52.664" cy="580.101" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Daniel Brandt — Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch</title></circle>
<circle class="person" data-gid="2" data-gruppe="Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch" data-name="Kathrin Brandt" cx="62.7669" cy="555.711" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Kathrin Brandt — Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch</title></circle>
<ellipse cx="87.1573" cy="580.101" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="87.1573" y="575.301" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">12</text>
<text x="87.1573" y="588.501" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="251.472" cy="580.101" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="22" data-gruppe="Freundinnen aus der Schulzeit" data-name="Jennifer Dietrich" cx="251.472" cy="545.608" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Jennifer Dietrich — Freundinnen aus der Schulzeit</title></circle>
<circle class="person" data-gid="22" data-gruppe="Freundinnen aus der Schulzeit" data-name="Christian Meyer" cx="275.862" cy="555.711" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Christian Meyer — Freundinnen aus der Schulzeit</title></circle>
<circle class="person" data-gid="22" data-gruppe="Freundinnen aus der Schulzeit" data-name="Svenja Horn" cx="285.965" cy="580.101" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Svenja Horn — Freundinnen aus der Schulzeit</title></circle>
<circle class="person" data-gid="22" data-gruppe="Freundinnen aus der Schulzeit" data-name="Stefanie Roth" cx="275.862" cy="604.491" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Stefanie Roth — Freundinnen aus der Schulzeit</title></circle>
<circle class="person" data-gid="22" data-gruppe="Freundinnen aus der Schulzeit" data-name="Stefan Kuhn" cx="251.472" cy="614.594" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Stefan Kuhn — Freundinnen aus der Schulzeit</title></circle>
<circle class="person" data-gid="8" data-gruppe="Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch" data-name="Dennis Sommer" cx="227.081" cy="604.491" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Dennis Sommer — Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="8" data-gruppe="Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch" data-name="Nicole Sommer" cx="216.979" cy="580.101" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Nicole Sommer — Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="8" data-gruppe="Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch" data-name="Lina Sommer" cx="227.081" cy="555.711" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Lina Sommer — Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch</title></circle>
<ellipse cx="251.472" cy="580.101" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="251.472" y="575.301" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">13</text>
<text x="251.472" y="588.501" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="415.786" cy="580.101" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="20" data-gruppe="Nachbarn der Brauteltern" data-name="Guenter Schwarz" cx="415.786" cy="545.608" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Guenter Schwarz — Nachbarn der Brauteltern</title></circle>
<circle class="person" data-gid="20" data-gruppe="Nachbarn der Brauteltern" data-name="Rainer Aksoy" cx="440.177" cy="555.711" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Rainer Aksoy — Nachbarn der Brauteltern</title></circle>
<circle class="person" data-gid="20" data-gruppe="Nachbarn der Brauteltern" data-name="Renate Aksoy" cx="450.28" cy="580.101" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Renate Aksoy — Nachbarn der Brauteltern</title></circle>
<circle class="person" data-gid="20" data-gruppe="Nachbarn der Brauteltern" data-name="Werner Stein" cx="440.177" cy="604.491" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Werner Stein — Nachbarn der Brauteltern</title></circle>
<circle class="person" data-gid="5" data-gruppe="Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch" data-name="Marco Meyer" cx="415.786" cy="614.594" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Marco Meyer — Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch</title></circle>
<circle class="person" data-gid="5" data-gruppe="Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch" data-name="Sandra Meyer" cx="391.396" cy="604.491" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Sandra Meyer — Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch</title></circle>
<circle class="person" data-gid="7" data-gruppe="Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch" data-name="Yusuf Vogel" cx="381.293" cy="580.101" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Yusuf Vogel — Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch</title></circle>
<circle class="person" data-gid="7" data-gruppe="Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch" data-name="Sandra Vogel" cx="391.396" cy="555.711" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Sandra Vogel — Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch</title></circle>
<ellipse cx="415.786" cy="580.101" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="415.786" y="575.301" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">14</text>
<text x="415.786" y="588.501" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="580.101" cy="580.101" r="56.4933" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="4" data-gruppe="Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch" data-name="Andreas Brandt" cx="580.101" cy="545.608" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Andreas Brandt — Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch</title></circle>
<circle class="person" data-gid="4" data-gruppe="Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch" data-name="Lena Brandt" cx="604.491" cy="555.711" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Lena Brandt — Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch</title></circle>
<circle class="person" data-gid="4" data-gruppe="Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch" data-name="Theo Brandt" cx="614.594" cy="580.101" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Theo Brandt — Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch</title></circle>
<circle class="person" data-gid="6" data-gruppe="Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch" data-name="Milan Brandt" cx="604.491" cy="604.491" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Milan Brandt — Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="6" data-gruppe="Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch" data-name="Anja Brandt" cx="580.101" cy="614.594" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Anja Brandt — Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="6" data-gruppe="Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch" data-name="Sofia Brandt" cx="555.711" cy="604.491" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Sofia Brandt — Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="9" data-gruppe="Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch" data-name="Timo Kuhn" cx="545.608" cy="580.101" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Timo Kuhn — Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch</title></circle>
<circle class="person" data-gid="9" data-gruppe="Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch" data-name="Sarah Kuhn" cx="555.711" cy="555.711" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Sarah Kuhn — Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch</title></circle>
<ellipse cx="580.101" cy="580.101" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="580.101" y="575.301" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">15</text>
<text x="580.101" y="588.501" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">8 Pl.</text>
<circle cx="415.786" cy="87.1573" r="73.0009" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Julia Brandt" cx="415.786" cy="36.1564" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Julia Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Daniel Sommer" cx="441.287" cy="42.9892" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Daniel Sommer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Werner Brandt" cx="459.954" cy="61.6568" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Werner Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Helga Brandt" cx="466.787" cy="87.1573" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Helga Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Dieter Sommer" cx="459.954" cy="112.658" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Dieter Sommer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Renate Sommer" cx="441.287" cy="131.325" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Renate Sommer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Sarah Winkler" cx="415.786" cy="138.158" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Sarah Winkler — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Tobias Frank" cx="390.286" cy="131.325" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Tobias Frank — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Giovanna Kovac" cx="371.618" cy="112.658" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Giovanna Kovac — Fussballverein des Braeutigams</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Sergej Berger" cx="364.785" cy="87.1573" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Sergej Berger — Fussballverein des Braeutigams</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Dennis Schmidt" cx="371.618" cy="61.6568" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Dennis Schmidt — Fussballverein des Braeutigams</title></circle>
<circle class="person" data-gid="21" data-gruppe="Fussballverein des Braeutigams" data-name="Patrick Simon" cx="390.286" cy="42.9892" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Patrick Simon — Fussballverein des Braeutigams</title></circle>
<ellipse cx="415.786" cy="87.1573" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="415.786" y="82.3573" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">1</text>
<text x="415.786" y="95.5573" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">12 Pl.</text>
<circle cx="908.73" cy="251.472" r="77.1573" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Leni Kuhn" cx="908.73" cy="196.315" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Leni Kuhn — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Emil Sommer" cx="934.363" cy="202.632" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Emil Sommer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Ida Sommer" cx="954.124" cy="220.139" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Ida Sommer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Liam Schwarz" cx="963.485" cy="244.823" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Liam Schwarz — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Elias Schwarz" cx="960.303" cy="271.031" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Elias Schwarz — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Felix Brandt" cx="945.306" cy="292.758" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Felix Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Matteo Kraus" cx="921.93" cy="305.026" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Matteo Kraus — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Anton Brandt" cx="895.53" cy="305.026" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Anton Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Frieda Brandt" cx="872.154" cy="292.758" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Frieda Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Mila Meyer" cx="857.157" cy="271.031" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Mila Meyer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Greta Brandt" cx="853.975" cy="244.823" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Greta Brandt — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Theo Sommer" cx="863.336" cy="220.139" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Theo Sommer — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Max Sommer" cx="883.097" cy="202.632" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Max Sommer — VIP / feste Platzierung</title></circle>
<ellipse cx="908.73" cy="251.472" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="908.73" y="246.672" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">16</text>
<text x="908.73" y="259.872" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">13 Pl.</text>
</svg>

After

Width:  |  Height:  |  Size: 42 KiB

+154
View File
@@ -0,0 +1,154 @@
[1]
Julia Brandt = Hof 1, Tisch 1, Nummer 1
Daniel Sommer = Hof 1, Tisch 1, Nummer 2
Werner Brandt = Hof 1, Tisch 1, Nummer 3
Helga Brandt = Hof 1, Tisch 1, Nummer 4
Dieter Sommer = Hof 1, Tisch 1, Nummer 5
Renate Sommer = Hof 1, Tisch 1, Nummer 6
Sarah Winkler = Hof 1, Tisch 1, Nummer 7
Tobias Frank = Hof 1, Tisch 1, Nummer 8
Renate Aksoy = Hof 1, Tisch 1, Nummer 9
Werner Stein = Hof 1, Tisch 1, Nummer 10
Guenter Schwarz = Hof 1, Tisch 1, Nummer 11
Rainer Aksoy = Hof 1, Tisch 1, Nummer 12
[2]
Svenja Vogel = Hof 1, Tisch 2, Nummer 1
Giovanna Koch = Hof 1, Tisch 2, Nummer 2
Julia Esposito = Hof 1, Tisch 2, Nummer 3
Jennifer Dietrich = Hof 1, Tisch 2, Nummer 4
Christian Meyer = Hof 1, Tisch 2, Nummer 5
Svenja Horn = Hof 1, Tisch 2, Nummer 6
Stefanie Roth = Hof 1, Tisch 2, Nummer 7
Stefan Kuhn = Hof 1, Tisch 2, Nummer 8
[3]
Helga Fischer = Hof 1, Tisch 3, Nummer 1
Heinz Fischer = Hof 1, Tisch 3, Nummer 2
[4]
Gast Musikverein = Hof 1, Tisch 4, Nummer 1
Gast Musikverein = Hof 1, Tisch 4, Nummer 2
Gast Musikverein = Hof 1, Tisch 4, Nummer 3
Gast Musikverein = Hof 1, Tisch 4, Nummer 4
Gast Musikverein = Hof 1, Tisch 4, Nummer 5
Gast Musikverein = Hof 1, Tisch 4, Nummer 6
Gast Musikverein = Hof 1, Tisch 4, Nummer 7
Sven Fischer = Hof 1, Tisch 4, Nummer 8
[5]
Gast Musikverein = Hof 1, Tisch 5, Nummer 1
Gast Musikverein = Hof 1, Tisch 5, Nummer 2
Gast Musikverein = Hof 1, Tisch 5, Nummer 3
Gast Musikverein = Hof 1, Tisch 5, Nummer 4
Gast Musikverein = Hof 1, Tisch 5, Nummer 5
Gast Musikverein = Hof 1, Tisch 5, Nummer 6
Marco Meyer = Hof 1, Tisch 5, Nummer 7
Sandra Meyer = Hof 1, Tisch 5, Nummer 8
[6]
[7]
[8]
Yusuf Peters = Hof 1, Tisch 8, Nummer 1
Sergej Berger = Hof 1, Tisch 8, Nummer 2
Giovanna Kovac = Hof 1, Tisch 8, Nummer 3
Dennis Schmidt = Hof 1, Tisch 8, Nummer 4
Patrick Simon = Hof 1, Tisch 8, Nummer 5
Stefanie Busch = Hof 1, Tisch 8, Nummer 6
Andreas Koch = Hof 1, Tisch 8, Nummer 7
Melanie Peters = Hof 1, Tisch 8, Nummer 8
[9]
Wolfgang Hansen = Hof 1, Tisch 9, Nummer 1
Hannelore Barth = Hof 1, Tisch 9, Nummer 2
Erika Frank = Hof 1, Tisch 9, Nummer 3
Gerhard Erdem = Hof 1, Tisch 9, Nummer 4
Rainer Erdem = Hof 1, Tisch 9, Nummer 5
Gisela Esposito = Hof 1, Tisch 9, Nummer 6
Brigitte Franke = Hof 1, Tisch 9, Nummer 7
Wolfgang Meyer = Hof 1, Tisch 9, Nummer 8
[10]
Elif Demir = Hof 1, Tisch 10, Nummer 1
Jennifer Simon = Hof 1, Tisch 10, Nummer 2
Andreas Stein = Hof 1, Tisch 10, Nummer 3
Stefan Klein = Hof 1, Tisch 10, Nummer 4
Timo Frank = Hof 1, Tisch 10, Nummer 5
Daniel Wagner = Hof 1, Tisch 10, Nummer 6
Stefanie Simon = Hof 1, Tisch 10, Nummer 7
[11]
Nadine Frank = Hof 1, Tisch 11, Nummer 1
Markus Schmitt = Hof 1, Tisch 11, Nummer 2
Olga Yilmaz = Hof 1, Tisch 11, Nummer 3
Olga Hansen = Hof 1, Tisch 11, Nummer 4
Daniel Horn = Hof 1, Tisch 11, Nummer 5
Milan Lange = Hof 1, Tisch 11, Nummer 6
Daniel Brandt = Hof 1, Tisch 11, Nummer 7
Kathrin Brandt = Hof 1, Tisch 11, Nummer 8
[12]
Nicole Fischer = Hof 1, Tisch 12, Nummer 1
Matthias Polat = Hof 1, Tisch 12, Nummer 2
Christian Esposito = Hof 1, Tisch 12, Nummer 3
Lena Hoffmann = Hof 1, Tisch 12, Nummer 4
Timo Wagner = Hof 1, Tisch 12, Nummer 5
Nicole Dietrich = Hof 1, Tisch 12, Nummer 6
Dennis Kraus = Hof 1, Tisch 12, Nummer 7
Melanie Kraus = Hof 1, Tisch 12, Nummer 8
[13]
Ingrid Demir = Hof 1, Tisch 13, Nummer 1
Monika Demir = Hof 1, Tisch 13, Nummer 2
Hannelore Demir = Hof 1, Tisch 13, Nummer 3
Yusuf Vogel = Hof 1, Tisch 13, Nummer 4
Sandra Vogel = Hof 1, Tisch 13, Nummer 5
Dennis Sommer = Hof 1, Tisch 13, Nummer 6
Nicole Sommer = Hof 1, Tisch 13, Nummer 7
Lina Sommer = Hof 1, Tisch 13, Nummer 8
[14]
Andreas Brandt = Hof 1, Tisch 14, Nummer 1
Lena Brandt = Hof 1, Tisch 14, Nummer 2
Theo Brandt = Hof 1, Tisch 14, Nummer 3
Milan Brandt = Hof 1, Tisch 14, Nummer 4
Anja Brandt = Hof 1, Tisch 14, Nummer 5
Sofia Brandt = Hof 1, Tisch 14, Nummer 6
Timo Kuhn = Hof 1, Tisch 14, Nummer 7
Sarah Kuhn = Hof 1, Tisch 14, Nummer 8
[15]
Yusuf Schwarz = Hof 1, Tisch 15, Nummer 1
Sarah Schwarz = Hof 1, Tisch 15, Nummer 2
Horst Aydin = Hof 1, Tisch 15, Nummer 3
Ursula Aydin = Hof 1, Tisch 15, Nummer 4
Heinz Tran = Hof 1, Tisch 15, Nummer 5
Erika Erdem = Hof 1, Tisch 15, Nummer 6
Dennis Sommer = Hof 1, Tisch 15, Nummer 7
Jennifer Sommer = Hof 1, Tisch 15, Nummer 8
[16]
Leni Kuhn = Hof 1, Tisch 16, Nummer 1
Emil Sommer = Hof 1, Tisch 16, Nummer 2
Ida Sommer = Hof 1, Tisch 16, Nummer 3
Liam Schwarz = Hof 1, Tisch 16, Nummer 4
Elias Schwarz = Hof 1, Tisch 16, Nummer 5
Felix Brandt = Hof 1, Tisch 16, Nummer 6
Matteo Kraus = Hof 1, Tisch 16, Nummer 7
Anton Brandt = Hof 1, Tisch 16, Nummer 8
Frieda Brandt = Hof 1, Tisch 16, Nummer 9
Mila Meyer = Hof 1, Tisch 16, Nummer 10
Greta Brandt = Hof 1, Tisch 16, Nummer 11
Theo Sommer = Hof 1, Tisch 16, Nummer 12
Max Sommer = Hof 1, Tisch 16, Nummer 13
[17]
Ben Brandt = Hof 1, Tisch 17, Nummer 1
Paul Brandt = Hof 1, Tisch 17, Nummer 2
Anton Meyer = Hof 1, Tisch 17, Nummer 3
Ida Meyer = Hof 1, Tisch 17, Nummer 4
Anton Vogel = Hof 1, Tisch 17, Nummer 5
Max Vogel = Hof 1, Tisch 17, Nummer 6
+109
View File
@@ -0,0 +1,109 @@
Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl
Julia;Brandt;;Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1);1;
Daniel;Sommer;;Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1);1;
Werner;Brandt;;Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1);1;
Helga;Brandt;;Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1);1;
Dieter;Sommer;;Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1);1;
Renate;Sommer;;Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1);1;
Sarah;Winkler;;Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1);1;
Tobias;Frank;;Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1);1;
Yusuf;Peters;;Familie Peters (Braut-Seite, Geschwister Melanie);;
Melanie;Peters;;Familie Peters (Braut-Seite, Geschwister Melanie);;
Daniel;Brandt;;"Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch";;
Kathrin;Brandt;;"Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch";;
Dennis;Kraus;;Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch;;
Melanie;Kraus;;Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch;;
Andreas;Brandt;;"Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch";;
Lena;Brandt;;"Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch";;
Theo;Brandt;;"Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch";;
Marco;Meyer;;"Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch";;
Sandra;Meyer;;"Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch";;
Milan;Brandt;;"Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch";;
Anja;Brandt;;"Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch";;
Sofia;Brandt;;"Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch";;
Yusuf;Vogel;;"Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch";;
Sandra;Vogel;;"Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch";;
Dennis;Sommer;;"Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch";;
Nicole;Sommer;;"Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch";;
Lina;Sommer;;"Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch";;
Timo;Kuhn;;Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch;;
Sarah;Kuhn;;Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch;;
Dennis;Sommer;;"Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch";;
Jennifer;Sommer;;"Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch";;
Yusuf;Schwarz;;"Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch";;
Sarah;Schwarz;;"Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch";;
Horst;Aydin;;Onkel und Tante (Braut-Seite);;
Ursula;Aydin;;Onkel und Tante (Braut-Seite);;
Ingrid;Demir;;Onkel und Tante mit Cousine (Braut-Seite);;
Monika;Demir;;Onkel und Tante mit Cousine (Braut-Seite);;
Hannelore;Demir;;Onkel und Tante mit Cousine (Braut-Seite);;
Heinz;Fischer;;Onkel und Tante (Braeutigam-Seite);;
Helga;Fischer;;Onkel und Tante (Braeutigam-Seite);;
Heinz;Tran;;Grosstante mit Begleitung;;
Erika;Erdem;;Grosstante mit Begleitung;;
Nicole;Fischer;;Studienfreunde der Braut;;
Matthias;Polat;;Studienfreunde der Braut;;
Christian;Esposito;;Studienfreunde der Braut;;
Lena;Hoffmann;;Studienfreunde der Braut;;
Timo;Wagner;;Studienfreunde der Braut;;
Nicole;Dietrich;;Studienfreunde der Braut;;
Wolfgang;Hansen;;Kegelclub des Brautvaters;;
Hannelore;Barth;;Kegelclub des Brautvaters;;
Erika;Frank;;Kegelclub des Brautvaters;;
Gerhard;Erdem;;Kegelclub des Brautvaters;;
Rainer;Erdem;;Kegelclub des Brautvaters;;
Gisela;Esposito;;Kegelclub des Brautvaters;;
Brigitte;Franke;;Kegelclub des Brautvaters;;
Wolfgang;Meyer;;Kegelclub des Brautvaters;;
Elif;Demir;;Arbeitskolleginnen der Braut;;
Jennifer;Simon;;Arbeitskolleginnen der Braut;;
Andreas;Stein;;Arbeitskolleginnen der Braut;;
Stefan;Klein;;Arbeitskolleginnen der Braut;;
Timo;Frank;;Arbeitskolleginnen der Braut;;
Daniel;Wagner;;Arbeitskolleginnen der Braut;;
Stefanie;Simon;;Arbeitskolleginnen der Braut;;
Nadine;Frank;;Arbeitskollegen des Braeutigams;;
Markus;Schmitt;;Arbeitskollegen des Braeutigams;;
Olga;Yilmaz;;Arbeitskollegen des Braeutigams;;
Olga;Hansen;;Arbeitskollegen des Braeutigams;;
Daniel;Horn;;Arbeitskollegen des Braeutigams;;
Milan;Lange;;Arbeitskollegen des Braeutigams;;
Guenter;Schwarz;;Nachbarn der Brauteltern;;
Rainer;Aksoy;;Nachbarn der Brauteltern;;
Renate;Aksoy;;Nachbarn der Brauteltern;;
Werner;Stein;;Nachbarn der Brauteltern;;
Sergej;Berger;;Fussballverein des Braeutigams;;
Giovanna;Kovac;;Fussballverein des Braeutigams;;
Dennis;Schmidt;;Fussballverein des Braeutigams;;
Patrick;Simon;;Fussballverein des Braeutigams;;
Stefanie;Busch;;Fussballverein des Braeutigams;;
Andreas;Koch;;Fussballverein des Braeutigams;;
Svenja;Vogel;;Fussballverein des Braeutigams;;
Giovanna;Koch;;Fussballverein des Braeutigams;;
Julia;Esposito;;Fussballverein des Braeutigams;;
Jennifer;Dietrich;;Freundinnen aus der Schulzeit;;
Christian;Meyer;;Freundinnen aus der Schulzeit;;
Svenja;Horn;;Freundinnen aus der Schulzeit;;
Stefanie;Roth;;Freundinnen aus der Schulzeit;;
Stefan;Kuhn;;Freundinnen aus der Schulzeit;;
Felix;Brandt;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Matteo;Kraus;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Anton;Brandt;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Frieda;Brandt;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Mila;Meyer;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Greta;Brandt;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Theo;Sommer;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Max;Sommer;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Leni;Kuhn;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Emil;Sommer;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Ida;Sommer;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Liam;Schwarz;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Elias;Schwarz;;Kindertisch (5-12 Jahre, fest an Tisch 16);16;
Ben;Brandt;;Teenager-Tisch (13-19 Jahre, fest an Tisch 17);17;
Paul;Brandt;;Teenager-Tisch (13-19 Jahre, fest an Tisch 17);17;
Anton;Meyer;;Teenager-Tisch (13-19 Jahre, fest an Tisch 17);17;
Ida;Meyer;;Teenager-Tisch (13-19 Jahre, fest an Tisch 17);17;
Anton;Vogel;;Teenager-Tisch (13-19 Jahre, fest an Tisch 17);17;
Max;Vogel;;Teenager-Tisch (13-19 Jahre, fest an Tisch 17);17;
Gast;Musikverein;;Musikverein (anonyme Sammelbuchung, 13 Karten);;13
Sven;Fischer;;alleinreisender Gast;;
1 Vorname Nachname Titel Gruppe Tisch Anzahl
2 Julia Brandt Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1) 1
3 Daniel Sommer Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1) 1
4 Werner Brandt Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1) 1
5 Helga Brandt Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1) 1
6 Dieter Sommer Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1) 1
7 Renate Sommer Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1) 1
8 Sarah Winkler Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1) 1
9 Tobias Frank Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1) 1
10 Yusuf Peters Familie Peters (Braut-Seite, Geschwister Melanie)
11 Melanie Peters Familie Peters (Braut-Seite, Geschwister Melanie)
12 Daniel Brandt Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch
13 Kathrin Brandt Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch
14 Dennis Kraus Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch
15 Melanie Kraus Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch
16 Andreas Brandt Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch
17 Lena Brandt Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch
18 Theo Brandt Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch
19 Marco Meyer Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch
20 Sandra Meyer Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch
21 Milan Brandt Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch
22 Anja Brandt Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch
23 Sofia Brandt Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch
24 Yusuf Vogel Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch
25 Sandra Vogel Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch
26 Dennis Sommer Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch
27 Nicole Sommer Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch
28 Lina Sommer Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch
29 Timo Kuhn Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch
30 Sarah Kuhn Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch
31 Dennis Sommer Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch
32 Jennifer Sommer Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch
33 Yusuf Schwarz Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch
34 Sarah Schwarz Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch
35 Horst Aydin Onkel und Tante (Braut-Seite)
36 Ursula Aydin Onkel und Tante (Braut-Seite)
37 Ingrid Demir Onkel und Tante mit Cousine (Braut-Seite)
38 Monika Demir Onkel und Tante mit Cousine (Braut-Seite)
39 Hannelore Demir Onkel und Tante mit Cousine (Braut-Seite)
40 Heinz Fischer Onkel und Tante (Braeutigam-Seite)
41 Helga Fischer Onkel und Tante (Braeutigam-Seite)
42 Heinz Tran Grosstante mit Begleitung
43 Erika Erdem Grosstante mit Begleitung
44 Nicole Fischer Studienfreunde der Braut
45 Matthias Polat Studienfreunde der Braut
46 Christian Esposito Studienfreunde der Braut
47 Lena Hoffmann Studienfreunde der Braut
48 Timo Wagner Studienfreunde der Braut
49 Nicole Dietrich Studienfreunde der Braut
50 Wolfgang Hansen Kegelclub des Brautvaters
51 Hannelore Barth Kegelclub des Brautvaters
52 Erika Frank Kegelclub des Brautvaters
53 Gerhard Erdem Kegelclub des Brautvaters
54 Rainer Erdem Kegelclub des Brautvaters
55 Gisela Esposito Kegelclub des Brautvaters
56 Brigitte Franke Kegelclub des Brautvaters
57 Wolfgang Meyer Kegelclub des Brautvaters
58 Elif Demir Arbeitskolleginnen der Braut
59 Jennifer Simon Arbeitskolleginnen der Braut
60 Andreas Stein Arbeitskolleginnen der Braut
61 Stefan Klein Arbeitskolleginnen der Braut
62 Timo Frank Arbeitskolleginnen der Braut
63 Daniel Wagner Arbeitskolleginnen der Braut
64 Stefanie Simon Arbeitskolleginnen der Braut
65 Nadine Frank Arbeitskollegen des Braeutigams
66 Markus Schmitt Arbeitskollegen des Braeutigams
67 Olga Yilmaz Arbeitskollegen des Braeutigams
68 Olga Hansen Arbeitskollegen des Braeutigams
69 Daniel Horn Arbeitskollegen des Braeutigams
70 Milan Lange Arbeitskollegen des Braeutigams
71 Guenter Schwarz Nachbarn der Brauteltern
72 Rainer Aksoy Nachbarn der Brauteltern
73 Renate Aksoy Nachbarn der Brauteltern
74 Werner Stein Nachbarn der Brauteltern
75 Sergej Berger Fussballverein des Braeutigams
76 Giovanna Kovac Fussballverein des Braeutigams
77 Dennis Schmidt Fussballverein des Braeutigams
78 Patrick Simon Fussballverein des Braeutigams
79 Stefanie Busch Fussballverein des Braeutigams
80 Andreas Koch Fussballverein des Braeutigams
81 Svenja Vogel Fussballverein des Braeutigams
82 Giovanna Koch Fussballverein des Braeutigams
83 Julia Esposito Fussballverein des Braeutigams
84 Jennifer Dietrich Freundinnen aus der Schulzeit
85 Christian Meyer Freundinnen aus der Schulzeit
86 Svenja Horn Freundinnen aus der Schulzeit
87 Stefanie Roth Freundinnen aus der Schulzeit
88 Stefan Kuhn Freundinnen aus der Schulzeit
89 Felix Brandt Kindertisch (5-12 Jahre, fest an Tisch 16) 16
90 Matteo Kraus Kindertisch (5-12 Jahre, fest an Tisch 16) 16
91 Anton Brandt Kindertisch (5-12 Jahre, fest an Tisch 16) 16
92 Frieda Brandt Kindertisch (5-12 Jahre, fest an Tisch 16) 16
93 Mila Meyer Kindertisch (5-12 Jahre, fest an Tisch 16) 16
94 Greta Brandt Kindertisch (5-12 Jahre, fest an Tisch 16) 16
95 Theo Sommer Kindertisch (5-12 Jahre, fest an Tisch 16) 16
96 Max Sommer Kindertisch (5-12 Jahre, fest an Tisch 16) 16
97 Leni Kuhn Kindertisch (5-12 Jahre, fest an Tisch 16) 16
98 Emil Sommer Kindertisch (5-12 Jahre, fest an Tisch 16) 16
99 Ida Sommer Kindertisch (5-12 Jahre, fest an Tisch 16) 16
100 Liam Schwarz Kindertisch (5-12 Jahre, fest an Tisch 16) 16
101 Elias Schwarz Kindertisch (5-12 Jahre, fest an Tisch 16) 16
102 Ben Brandt Teenager-Tisch (13-19 Jahre, fest an Tisch 17) 17
103 Paul Brandt Teenager-Tisch (13-19 Jahre, fest an Tisch 17) 17
104 Anton Meyer Teenager-Tisch (13-19 Jahre, fest an Tisch 17) 17
105 Ida Meyer Teenager-Tisch (13-19 Jahre, fest an Tisch 17) 17
106 Anton Vogel Teenager-Tisch (13-19 Jahre, fest an Tisch 17) 17
107 Max Vogel Teenager-Tisch (13-19 Jahre, fest an Tisch 17) 17
108 Gast Musikverein Musikverein (anonyme Sammelbuchung, 13 Karten) 13
109 Sven Fischer alleinreisender Gast
+575
View File
@@ -0,0 +1,575 @@
{
"gruppen": [
{
"name": "Ehrentafel: Brautpaar, Brauteltern, Braeutigameltern, Trauzeugen (fest an Tisch 1)",
"tisch": 1,
"personen": [
{
"vorname": "Julia",
"nachname": "Brandt"
},
{
"vorname": "Daniel",
"nachname": "Sommer"
},
{
"vorname": "Werner",
"nachname": "Brandt"
},
{
"vorname": "Helga",
"nachname": "Brandt"
},
{
"vorname": "Dieter",
"nachname": "Sommer"
},
{
"vorname": "Renate",
"nachname": "Sommer"
},
{
"vorname": "Sarah",
"nachname": "Winkler"
},
{
"vorname": "Tobias",
"nachname": "Frank"
}
]
},
{
"name": "Familie Peters (Braut-Seite, Geschwister Melanie)",
"personen": [
{
"vorname": "Yusuf",
"nachname": "Peters"
},
{
"vorname": "Melanie",
"nachname": "Peters"
}
]
},
{
"name": "Familie Brandt (Braut-Seite, Geschwister Daniel): Felix (12 J.) am Kindertisch; Ben (13 J.) am Teenager-Tisch",
"personen": [
{
"vorname": "Daniel",
"nachname": "Brandt"
},
{
"vorname": "Kathrin",
"nachname": "Brandt"
}
]
},
{
"name": "Familie Kraus (Braut-Seite, Geschwister Melanie): Matteo (9 J.) am Kindertisch",
"personen": [
{
"vorname": "Dennis",
"nachname": "Kraus"
},
{
"vorname": "Melanie",
"nachname": "Kraus"
}
]
},
{
"name": "Familie Brandt (Braut-Seite, Geschwister Andreas): Theo (3 J.) sitzt bei den Eltern; Anton (10 J.) am Kindertisch; Frieda (12 J.) am Kindertisch; Paul (19 J.) am Teenager-Tisch",
"personen": [
{
"vorname": "Andreas",
"nachname": "Brandt"
},
{
"vorname": "Lena",
"nachname": "Brandt"
},
{
"vorname": "Theo",
"nachname": "Brandt"
}
]
},
{
"name": "Familie Meyer (Braut-Seite, Geschwister Sandra): Mila (10 J.) am Kindertisch; Anton (16 J.) am Teenager-Tisch; Ida (16 J.) am Teenager-Tisch",
"personen": [
{
"vorname": "Marco",
"nachname": "Meyer"
},
{
"vorname": "Sandra",
"nachname": "Meyer"
}
]
},
{
"name": "Familie Brandt (Braut-Seite, Geschwister Milan): Sofia (2 J.) sitzt bei den Eltern; Greta (7 J.) am Kindertisch",
"personen": [
{
"vorname": "Milan",
"nachname": "Brandt"
},
{
"vorname": "Anja",
"nachname": "Brandt"
},
{
"vorname": "Sofia",
"nachname": "Brandt"
}
]
},
{
"name": "Familie Vogel (Braut-Seite, Geschwister Sandra): Anton (14 J.) am Teenager-Tisch; Max (15 J.) am Teenager-Tisch",
"personen": [
{
"vorname": "Yusuf",
"nachname": "Vogel"
},
{
"vorname": "Sandra",
"nachname": "Vogel"
}
]
},
{
"name": "Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Lina (3 J.) sitzt bei den Eltern; Theo (8 J.) am Kindertisch; Max (12 J.) am Kindertisch",
"personen": [
{
"vorname": "Dennis",
"nachname": "Sommer"
},
{
"vorname": "Nicole",
"nachname": "Sommer"
},
{
"vorname": "Lina",
"nachname": "Sommer"
}
]
},
{
"name": "Familie Kuhn (Braeutigam-Seite, Geschwister Sarah): Leni (10 J.) am Kindertisch",
"personen": [
{
"vorname": "Timo",
"nachname": "Kuhn"
},
{
"vorname": "Sarah",
"nachname": "Kuhn"
}
]
},
{
"name": "Familie Sommer (Braeutigam-Seite, Geschwister Dennis): Emil (8 J.) am Kindertisch; Ida (8 J.) am Kindertisch",
"personen": [
{
"vorname": "Dennis",
"nachname": "Sommer"
},
{
"vorname": "Jennifer",
"nachname": "Sommer"
}
]
},
{
"name": "Familie Schwarz (Braeutigam-Seite, Geschwister Sarah): Liam (8 J.) am Kindertisch; Elias (8 J.) am Kindertisch",
"personen": [
{
"vorname": "Yusuf",
"nachname": "Schwarz"
},
{
"vorname": "Sarah",
"nachname": "Schwarz"
}
]
},
{
"name": "Onkel und Tante (Braut-Seite)",
"personen": [
{
"vorname": "Horst",
"nachname": "Aydin"
},
{
"vorname": "Ursula",
"nachname": "Aydin"
}
]
},
{
"name": "Onkel und Tante mit Cousine (Braut-Seite)",
"personen": [
{
"vorname": "Ingrid",
"nachname": "Demir"
},
{
"vorname": "Monika",
"nachname": "Demir"
},
{
"vorname": "Hannelore",
"nachname": "Demir"
}
]
},
{
"name": "Onkel und Tante (Braeutigam-Seite)",
"personen": [
{
"vorname": "Heinz",
"nachname": "Fischer"
},
{
"vorname": "Helga",
"nachname": "Fischer"
}
]
},
{
"name": "Grosstante mit Begleitung",
"personen": [
{
"vorname": "Heinz",
"nachname": "Tran"
},
{
"vorname": "Erika",
"nachname": "Erdem"
}
]
},
{
"name": "Studienfreunde der Braut",
"personen": [
{
"vorname": "Nicole",
"nachname": "Fischer"
},
{
"vorname": "Matthias",
"nachname": "Polat"
},
{
"vorname": "Christian",
"nachname": "Esposito"
},
{
"vorname": "Lena",
"nachname": "Hoffmann"
},
{
"vorname": "Timo",
"nachname": "Wagner"
},
{
"vorname": "Nicole",
"nachname": "Dietrich"
}
]
},
{
"name": "Kegelclub des Brautvaters",
"personen": [
{
"vorname": "Wolfgang",
"nachname": "Hansen"
},
{
"vorname": "Hannelore",
"nachname": "Barth"
},
{
"vorname": "Erika",
"nachname": "Frank"
},
{
"vorname": "Gerhard",
"nachname": "Erdem"
},
{
"vorname": "Rainer",
"nachname": "Erdem"
},
{
"vorname": "Gisela",
"nachname": "Esposito"
},
{
"vorname": "Brigitte",
"nachname": "Franke"
},
{
"vorname": "Wolfgang",
"nachname": "Meyer"
}
]
},
{
"name": "Arbeitskolleginnen der Braut",
"personen": [
{
"vorname": "Elif",
"nachname": "Demir"
},
{
"vorname": "Jennifer",
"nachname": "Simon"
},
{
"vorname": "Andreas",
"nachname": "Stein"
},
{
"vorname": "Stefan",
"nachname": "Klein"
},
{
"vorname": "Timo",
"nachname": "Frank"
},
{
"vorname": "Daniel",
"nachname": "Wagner"
},
{
"vorname": "Stefanie",
"nachname": "Simon"
}
]
},
{
"name": "Arbeitskollegen des Braeutigams",
"personen": [
{
"vorname": "Nadine",
"nachname": "Frank"
},
{
"vorname": "Markus",
"nachname": "Schmitt"
},
{
"vorname": "Olga",
"nachname": "Yilmaz"
},
{
"vorname": "Olga",
"nachname": "Hansen"
},
{
"vorname": "Daniel",
"nachname": "Horn"
},
{
"vorname": "Milan",
"nachname": "Lange"
}
]
},
{
"name": "Nachbarn der Brauteltern",
"personen": [
{
"vorname": "Guenter",
"nachname": "Schwarz"
},
{
"vorname": "Rainer",
"nachname": "Aksoy"
},
{
"vorname": "Renate",
"nachname": "Aksoy"
},
{
"vorname": "Werner",
"nachname": "Stein"
}
]
},
{
"name": "Fussballverein des Braeutigams",
"personen": [
{
"vorname": "Sergej",
"nachname": "Berger"
},
{
"vorname": "Giovanna",
"nachname": "Kovac"
},
{
"vorname": "Dennis",
"nachname": "Schmidt"
},
{
"vorname": "Patrick",
"nachname": "Simon"
},
{
"vorname": "Stefanie",
"nachname": "Busch"
},
{
"vorname": "Andreas",
"nachname": "Koch"
},
{
"vorname": "Svenja",
"nachname": "Vogel"
},
{
"vorname": "Giovanna",
"nachname": "Koch"
},
{
"vorname": "Julia",
"nachname": "Esposito"
}
]
},
{
"name": "Freundinnen aus der Schulzeit",
"personen": [
{
"vorname": "Jennifer",
"nachname": "Dietrich"
},
{
"vorname": "Christian",
"nachname": "Meyer"
},
{
"vorname": "Svenja",
"nachname": "Horn"
},
{
"vorname": "Stefanie",
"nachname": "Roth"
},
{
"vorname": "Stefan",
"nachname": "Kuhn"
}
]
},
{
"name": "Kindertisch (5-12 Jahre, fest an Tisch 16)",
"tisch": 16,
"personen": [
{
"vorname": "Felix",
"nachname": "Brandt"
},
{
"vorname": "Matteo",
"nachname": "Kraus"
},
{
"vorname": "Anton",
"nachname": "Brandt"
},
{
"vorname": "Frieda",
"nachname": "Brandt"
},
{
"vorname": "Mila",
"nachname": "Meyer"
},
{
"vorname": "Greta",
"nachname": "Brandt"
},
{
"vorname": "Theo",
"nachname": "Sommer"
},
{
"vorname": "Max",
"nachname": "Sommer"
},
{
"vorname": "Leni",
"nachname": "Kuhn"
},
{
"vorname": "Emil",
"nachname": "Sommer"
},
{
"vorname": "Ida",
"nachname": "Sommer"
},
{
"vorname": "Liam",
"nachname": "Schwarz"
},
{
"vorname": "Elias",
"nachname": "Schwarz"
}
]
},
{
"name": "Teenager-Tisch (13-19 Jahre, fest an Tisch 17)",
"tisch": 17,
"personen": [
{
"vorname": "Ben",
"nachname": "Brandt"
},
{
"vorname": "Paul",
"nachname": "Brandt"
},
{
"vorname": "Anton",
"nachname": "Meyer"
},
{
"vorname": "Ida",
"nachname": "Meyer"
},
{
"vorname": "Anton",
"nachname": "Vogel"
},
{
"vorname": "Max",
"nachname": "Vogel"
}
]
},
{
"name": "Musikverein (anonyme Sammelbuchung, 13 Karten)",
"anzahl": 13,
"personen": [
{
"vorname": "Gast",
"nachname": "Musikverein"
}
]
},
{
"name": "alleinreisender Gast",
"personen": [
{
"vorname": "Sven",
"nachname": "Fischer"
}
]
}
]
}
+118
View File
@@ -0,0 +1,118 @@
[1]
Nummer=1
Hof=1
Plaetze=12
Nachbarliste=[3, 4, 5]
Koordinaten=(2,0)
[2]
Nummer=2
Hof=1
Plaetze=8
Nachbarliste=[3, 7, 8]
Koordinaten=(0,1)
[3]
Nummer=3
Hof=1
Plaetze=8
Nachbarliste=[1, 2, 4, 7, 8, 9]
Koordinaten=(1,1)
[4]
Nummer=4
Hof=1
Plaetze=8
Nachbarliste=[1, 3, 5, 8, 9, 10]
Koordinaten=(2,1)
[5]
Nummer=5
Hof=1
Plaetze=8
Nachbarliste=[1, 4, 6, 9, 10, 11]
Koordinaten=(3,1)
[6]
Nummer=6
Hof=1
Plaetze=8
Nachbarliste=[5, 10, 11, 16, 17]
Koordinaten=(4,1)
[7]
Nummer=7
Hof=1
Plaetze=8
Nachbarliste=[2, 3, 8, 12, 13]
Koordinaten=(0,2)
[8]
Nummer=8
Hof=1
Plaetze=8
Nachbarliste=[2, 3, 4, 7, 9, 12, 13, 14]
Koordinaten=(1,2)
[9]
Nummer=9
Hof=1
Plaetze=8
Nachbarliste=[3, 4, 5, 8, 10, 13, 14, 15]
Koordinaten=(2,2)
[10]
Nummer=10
Hof=1
Plaetze=8
Nachbarliste=[4, 5, 6, 9, 11, 14, 15]
Koordinaten=(3,2)
[11]
Nummer=11
Hof=1
Plaetze=8
Nachbarliste=[5, 6, 10, 15, 16, 17]
Koordinaten=(4,2)
[12]
Nummer=12
Hof=1
Plaetze=8
Nachbarliste=[7, 8, 13]
Koordinaten=(0,3)
[13]
Nummer=13
Hof=1
Plaetze=8
Nachbarliste=[7, 8, 9, 12, 14]
Koordinaten=(1,3)
[14]
Nummer=14
Hof=1
Plaetze=8
Nachbarliste=[8, 9, 10, 13, 15]
Koordinaten=(2,3)
[15]
Nummer=15
Hof=1
Plaetze=8
Nachbarliste=[9, 10, 11, 14]
Koordinaten=(3,3)
[16]
Nummer=16
Hof=1
Plaetze=13
Nachbarliste=[6, 11, 17]
Koordinaten=(5,1)
[17]
Nummer=17
Hof=1
Plaetze=6
Nachbarliste=[6, 11, 16]
Koordinaten=(5,2)
+746
View File
@@ -0,0 +1,746 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="2200" height="790" viewBox="0 0 2200 790" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="1100" y="30" text-anchor="middle" font-size="16" fill="#333">Abstammung der Loesungen (Mutationsbaum)</text>
<line x1="60.0" y1="60.0" x2="60.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="86.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="166.7" y1="60.0" x2="112.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="139.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="165.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="191.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="380.0" y1="60.0" x2="218.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="433.3" y1="60.0" x2="244.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="270.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="540.0" y1="60.0" x2="297.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="323.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="349.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="700.0" y1="60.0" x2="375.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="753.3" y1="60.0" x2="402.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="428.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="454.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="481.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="507.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="533.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1073.3" y1="60.0" x2="560.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="586.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1180.0" y1="60.0" x2="612.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1233.3" y1="60.0" x2="639.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="665.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1340.0" y1="60.0" x2="691.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="718.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="744.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="770.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="797.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="823.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1660.0" y1="60.0" x2="849.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="876.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="902.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1820.0" y1="60.0" x2="928.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1873.3" y1="60.0" x2="955.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1926.7" y1="60.0" x2="981.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1980.0" y1="60.0" x2="1007.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="1034.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="1060.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="60.0" x2="1086.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="60.0" x2="1113.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="1139.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="166.7" y1="60.0" x2="1165.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="1192.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="1218.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="1244.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="380.0" y1="60.0" x2="1271.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="433.3" y1="60.0" x2="1297.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="1323.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="540.0" y1="60.0" x2="1350.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="1376.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="1402.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="700.0" y1="60.0" x2="1429.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="753.3" y1="60.0" x2="1455.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="1481.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="1508.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="1534.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="1560.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="1587.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1073.3" y1="60.0" x2="1613.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="1639.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1180.0" y1="60.0" x2="1666.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1233.3" y1="60.0" x2="1692.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="1718.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1340.0" y1="60.0" x2="1745.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="1771.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="1797.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="1824.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="1850.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="1876.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1660.0" y1="60.0" x2="1903.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="1929.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="1955.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1820.0" y1="60.0" x2="1982.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1873.3" y1="60.0" x2="2008.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1926.7" y1="60.0" x2="2034.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1980.0" y1="60.0" x2="2061.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="2087.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="2113.7" y2="150.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="2140.0" y1="60.0" x2="2140.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="718.2" y1="150.0" x2="60.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1929.4" y1="150.0" x2="91.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="560.3" y1="150.0" x2="122.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1613.4" y1="150.0" x2="153.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1587.1" y1="150.0" x2="184.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2113.7" y1="150.0" x2="215.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1666.1" y1="150.0" x2="246.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="150.0" x2="277.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="454.9" y1="150.0" x2="308.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1086.8" y1="150.0" x2="339.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="876.2" y1="150.0" x2="370.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="612.9" y1="150.0" x2="401.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1060.5" y1="150.0" x2="432.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1508.1" y1="150.0" x2="463.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1771.4" y1="150.0" x2="494.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1560.8" y1="150.0" x2="525.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1402.8" y1="150.0" x2="556.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1639.7" y1="150.0" x2="587.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="618.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="533.9" y1="150.0" x2="649.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="402.3" y1="150.0" x2="680.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1007.8" y1="150.0" x2="711.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="349.6" y1="150.0" x2="743.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="774.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="805.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1376.5" y1="150.0" x2="836.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1455.4" y1="150.0" x2="867.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="770.9" y1="150.0" x2="898.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="929.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1429.1" y1="150.0" x2="960.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="507.6" y1="150.0" x2="991.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2061.0" y1="150.0" x2="1022.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1218.5" y1="150.0" x2="1053.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="375.9" y1="150.0" x2="1084.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="718.2" y1="150.0" x2="1115.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1929.4" y1="150.0" x2="1146.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="560.3" y1="150.0" x2="1177.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1613.4" y1="150.0" x2="1208.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1587.1" y1="150.0" x2="1239.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2113.7" y1="150.0" x2="1270.7" y2="240.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="1666.1" y1="150.0" x2="1301.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="150.0" x2="1332.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="454.9" y1="150.0" x2="1363.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1086.8" y1="150.0" x2="1394.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="876.2" y1="150.0" x2="1426.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="612.9" y1="150.0" x2="1457.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1060.5" y1="150.0" x2="1488.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1508.1" y1="150.0" x2="1519.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1771.4" y1="150.0" x2="1550.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1560.8" y1="150.0" x2="1581.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1402.8" y1="150.0" x2="1612.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1639.7" y1="150.0" x2="1643.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="1674.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="533.9" y1="150.0" x2="1705.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="402.3" y1="150.0" x2="1736.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1007.8" y1="150.0" x2="1767.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="349.6" y1="150.0" x2="1798.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="1829.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="1860.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1376.5" y1="150.0" x2="1891.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1455.4" y1="150.0" x2="1922.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="770.9" y1="150.0" x2="1953.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="1984.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1429.1" y1="150.0" x2="2015.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="507.6" y1="150.0" x2="2046.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2061.0" y1="150.0" x2="2077.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1218.5" y1="150.0" x2="2109.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="375.9" y1="150.0" x2="2140.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="240.0" x2="60.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="215.2" y1="240.0" x2="97.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="122.1" y1="240.0" x2="135.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1115.5" y1="240.0" x2="173.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1394.9" y1="240.0" x2="211.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="184.2" y1="240.0" x2="249.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1426.0" y1="240.0" x2="286.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="308.4" y1="240.0" x2="324.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1332.8" y1="240.0" x2="362.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1457.0" y1="240.0" x2="400.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="153.1" y1="240.0" x2="438.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1177.6" y1="240.0" x2="476.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1270.7" y1="240.0" x2="513.8" y2="330.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="836.1" y1="240.0" x2="551.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="525.7" y1="240.0" x2="589.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1581.2" y1="240.0" x2="627.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="718.2" y1="150.0" x2="665.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1519.1" y1="240.0" x2="702.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="960.3" y1="240.0" x2="740.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1146.6" y1="240.0" x2="778.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="370.4" y1="240.0" x2="816.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1929.4" y1="150.0" x2="854.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="91.0" y1="240.0" x2="892.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1643.3" y1="240.0" x2="929.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1860.6" y1="240.0" x2="967.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1674.3" y1="240.0" x2="1005.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="560.3" y1="150.0" x2="1043.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1613.4" y1="150.0" x2="1081.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="240.0" x2="1118.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="215.2" y1="240.0" x2="1156.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="122.1" y1="240.0" x2="1194.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1115.5" y1="240.0" x2="1232.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1394.9" y1="240.0" x2="1270.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="184.2" y1="240.0" x2="1308.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1426.0" y1="240.0" x2="1345.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="308.4" y1="240.0" x2="1383.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1332.8" y1="240.0" x2="1421.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1457.0" y1="240.0" x2="1459.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="153.1" y1="240.0" x2="1497.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1177.6" y1="240.0" x2="1534.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1270.7" y1="240.0" x2="1572.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="836.1" y1="240.0" x2="1610.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="525.7" y1="240.0" x2="1648.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1581.2" y1="240.0" x2="1686.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="718.2" y1="150.0" x2="1724.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1519.1" y1="240.0" x2="1761.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="960.3" y1="240.0" x2="1799.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1146.6" y1="240.0" x2="1837.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="370.4" y1="240.0" x2="1875.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1929.4" y1="150.0" x2="1913.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="91.0" y1="240.0" x2="1950.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1643.3" y1="240.0" x2="1988.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1860.6" y1="240.0" x2="2026.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1674.3" y1="240.0" x2="2064.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="560.3" y1="150.0" x2="2102.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1613.4" y1="150.0" x2="2140.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1837.5" y1="330.0" x2="60.0" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1950.9" y1="330.0" x2="106.2" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="286.9" y1="330.0" x2="152.4" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="330.0" x2="198.7" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1118.9" y1="330.0" x2="244.9" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1308.0" y1="330.0" x2="291.1" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="816.4" y1="330.0" x2="337.3" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1610.5" y1="330.0" x2="383.6" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1799.6" y1="330.0" x2="429.8" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1043.3" y1="330.0" x2="476.0" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="173.5" y1="330.0" x2="522.2" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1232.4" y1="330.0" x2="568.4" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="240.0" x2="614.7" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="330.0" x2="660.9" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1459.3" y1="330.0" x2="707.1" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="513.8" y1="330.0" x2="753.3" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="215.2" y1="240.0" x2="799.6" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="2026.5" y1="330.0" x2="845.8" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1534.9" y1="330.0" x2="892.0" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1988.7" y1="330.0" x2="938.2" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1345.8" y1="330.0" x2="984.4" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="362.5" y1="330.0" x2="1030.7" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1005.5" y1="330.0" x2="1076.9" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1837.5" y1="330.0" x2="1123.1" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1950.9" y1="330.0" x2="1169.3" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="286.9" y1="330.0" x2="1215.6" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="330.0" x2="1261.8" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1118.9" y1="330.0" x2="1308.0" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1308.0" y1="330.0" x2="1354.2" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="816.4" y1="330.0" x2="1400.4" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1610.5" y1="330.0" x2="1446.7" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1799.6" y1="330.0" x2="1492.9" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1043.3" y1="330.0" x2="1539.1" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="173.5" y1="330.0" x2="1585.3" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1232.4" y1="330.0" x2="1631.6" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="240.0" x2="1677.8" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="330.0" x2="1724.0" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1459.3" y1="330.0" x2="1770.2" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="513.8" y1="330.0" x2="1816.4" y2="420.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="215.2" y1="240.0" x2="1862.7" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="2026.5" y1="330.0" x2="1908.9" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1534.9" y1="330.0" x2="1955.1" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1988.7" y1="330.0" x2="2001.3" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1345.8" y1="330.0" x2="2047.6" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="362.5" y1="330.0" x2="2093.8" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1005.5" y1="330.0" x2="2140.0" y2="420.0" stroke="#bbb" stroke-width="1"/>
<line x1="1816.4" y1="420.0" x2="60.0" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="244.9" y1="420.0" x2="116.2" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="420.0" x2="172.4" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1261.8" y1="420.0" x2="228.6" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1308.0" y1="420.0" x2="284.9" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1837.5" y1="330.0" x2="341.1" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1950.9" y1="330.0" x2="397.3" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1215.6" y1="420.0" x2="453.5" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1400.4" y1="420.0" x2="509.7" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="291.1" y1="420.0" x2="565.9" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="2047.6" y1="420.0" x2="622.2" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="286.9" y1="330.0" x2="678.4" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="614.7" y1="420.0" x2="734.6" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1677.8" y1="420.0" x2="790.8" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="330.0" x2="847.0" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1118.9" y1="330.0" x2="903.2" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="420.0" x2="959.5" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1123.1" y1="420.0" x2="1015.7" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="383.6" y1="420.0" x2="1071.9" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1816.4" y1="420.0" x2="1128.1" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="244.9" y1="420.0" x2="1184.3" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="420.0" x2="1240.5" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1261.8" y1="420.0" x2="1296.8" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1308.0" y1="420.0" x2="1353.0" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1837.5" y1="330.0" x2="1409.2" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1950.9" y1="330.0" x2="1465.4" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1215.6" y1="420.0" x2="1521.6" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1400.4" y1="420.0" x2="1577.8" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="291.1" y1="420.0" x2="1634.1" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="2047.6" y1="420.0" x2="1690.3" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="286.9" y1="330.0" x2="1746.5" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="614.7" y1="420.0" x2="1802.7" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1677.8" y1="420.0" x2="1858.9" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="330.0" x2="1915.1" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1118.9" y1="330.0" x2="1971.4" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="420.0" x2="2027.6" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1123.1" y1="420.0" x2="2083.8" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="383.6" y1="420.0" x2="2140.0" y2="510.0" stroke="#bbb" stroke-width="1"/>
<line x1="1816.4" y1="420.0" x2="60.0" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="172.4" y1="510.0" x2="127.1" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="734.6" y1="510.0" x2="194.2" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1184.3" y1="510.0" x2="261.3" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1971.4" y1="510.0" x2="328.4" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="244.9" y1="420.0" x2="395.5" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="420.0" x2="462.6" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="228.6" y1="510.0" x2="529.7" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1261.8" y1="420.0" x2="596.8" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="903.2" y1="510.0" x2="663.9" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1308.0" y1="420.0" x2="731.0" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="2027.6" y1="510.0" x2="798.1" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1577.8" y1="510.0" x2="865.2" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="565.9" y1="510.0" x2="932.3" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1837.5" y1="330.0" x2="999.4" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1950.9" y1="330.0" x2="1066.5" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1816.4" y1="420.0" x2="1133.5" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="172.4" y1="510.0" x2="1200.6" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="734.6" y1="510.0" x2="1267.7" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1184.3" y1="510.0" x2="1334.8" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1971.4" y1="510.0" x2="1401.9" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="244.9" y1="420.0" x2="1469.0" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="420.0" x2="1536.1" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="228.6" y1="510.0" x2="1603.2" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1261.8" y1="420.0" x2="1670.3" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="903.2" y1="510.0" x2="1737.4" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1308.0" y1="420.0" x2="1804.5" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="2027.6" y1="510.0" x2="1871.6" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1577.8" y1="510.0" x2="1938.7" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="565.9" y1="510.0" x2="2005.8" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1837.5" y1="330.0" x2="2072.9" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1950.9" y1="330.0" x2="2140.0" y2="600.0" stroke="#bbb" stroke-width="1"/>
<line x1="1816.4" y1="420.0" x2="60.0" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1200.6" y1="600.0" x2="143.2" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="172.4" y1="510.0" x2="226.4" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="734.6" y1="510.0" x2="309.6" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="261.3" y1="600.0" x2="392.8" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1184.3" y1="510.0" x2="476.0" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1971.4" y1="510.0" x2="559.2" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="244.9" y1="420.0" x2="642.4" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="420.0" x2="725.6" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="596.8" y1="600.0" x2="808.8" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1603.2" y1="600.0" x2="892.0" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="228.6" y1="510.0" x2="975.2" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1261.8" y1="420.0" x2="1058.4" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1816.4" y1="420.0" x2="1141.6" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1200.6" y1="600.0" x2="1224.8" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="172.4" y1="510.0" x2="1308.0" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="734.6" y1="510.0" x2="1391.2" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="261.3" y1="600.0" x2="1474.4" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1184.3" y1="510.0" x2="1557.6" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1971.4" y1="510.0" x2="1640.8" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="244.9" y1="420.0" x2="1724.0" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="420.0" x2="1807.2" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="596.8" y1="600.0" x2="1890.4" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1603.2" y1="600.0" x2="1973.6" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="228.6" y1="510.0" x2="2056.8" y2="690.0" stroke="#bbb" stroke-width="1"/>
<line x1="1261.8" y1="420.0" x2="2140.0" y2="690.0" stroke="#bbb" stroke-width="1"/>
<circle cx="60.0" cy="60.0" r="5" fill="#a04839" stroke="#333" stroke-width="0.5"><title>Id 1, Wert -959.0</title></circle>
<circle cx="113.3" cy="60.0" r="5" fill="#a84337" stroke="#333" stroke-width="0.5"><title>Id 2, Wert -985.9</title></circle>
<circle cx="166.7" cy="60.0" r="5" fill="#944e3b" stroke="#333" stroke-width="0.5"><title>Id 3, Wert -920.5</title></circle>
<circle cx="220.0" cy="60.0" r="5" fill="#a94237" stroke="#333" stroke-width="0.5"><title>Id 4, Wert -991.9</title></circle>
<circle cx="273.3" cy="60.0" r="5" fill="#7b5d40" stroke="#333" stroke-width="0.5"><title>Id 5, Wert -835.1</title></circle>
<circle cx="326.7" cy="60.0" r="5" fill="#9b4a3a" stroke="#333" stroke-width="0.5"><title>Id 6, Wert -945.0</title></circle>
<circle cx="380.0" cy="60.0" r="5" fill="#9f4839" stroke="#333" stroke-width="0.5"><title>Id 7, Wert -956.7</title></circle>
<circle cx="433.3" cy="60.0" r="5" fill="#a44638" stroke="#333" stroke-width="0.5"><title>Id 8, Wert -972.3</title></circle>
<circle cx="486.7" cy="60.0" r="5" fill="#c03633" stroke="#333" stroke-width="0.5"><title>Id 9, Wert -1067.6</title></circle>
<circle cx="540.0" cy="60.0" r="5" fill="#8f513c" stroke="#333" stroke-width="0.5"><title>Id 10, Wert -903.2</title></circle>
<circle cx="593.3" cy="60.0" r="5" fill="#7d5b3f" stroke="#333" stroke-width="0.5"><title>Id 11, Wert -842.3</title></circle>
<circle cx="646.7" cy="60.0" r="5" fill="#746141" stroke="#333" stroke-width="0.5"><title>Id 12, Wert -810.7</title></circle>
<circle cx="700.0" cy="60.0" r="5" fill="#765f41" stroke="#333" stroke-width="0.5"><title>Id 13, Wert -818.5</title></circle>
<circle cx="753.3" cy="60.0" r="5" fill="#6d6442" stroke="#333" stroke-width="0.5"><title>Id 14, Wert -789.3</title></circle>
<circle cx="806.7" cy="60.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 15, Wert -1093.3</title></circle>
<circle cx="860.0" cy="60.0" r="5" fill="#686743" stroke="#333" stroke-width="0.5"><title>Id 16, Wert -772.5</title></circle>
<circle cx="913.3" cy="60.0" r="5" fill="#7f5a3f" stroke="#333" stroke-width="0.5"><title>Id 17, Wert -849.7</title></circle>
<circle cx="966.7" cy="60.0" r="5" fill="#785e40" stroke="#333" stroke-width="0.5"><title>Id 18, Wert -824.8</title></circle>
<circle cx="1020.0" cy="60.0" r="5" fill="#7f5a3f" stroke="#333" stroke-width="0.5"><title>Id 19, Wert -849.4</title></circle>
<circle cx="1073.3" cy="60.0" r="5" fill="#696643" stroke="#333" stroke-width="0.5"><title>Id 20, Wert -776.8</title></circle>
<circle cx="1126.7" cy="60.0" r="5" fill="#606b45" stroke="#333" stroke-width="0.5"><title>Id 21, Wert -746.5</title></circle>
<circle cx="1180.0" cy="60.0" r="5" fill="#706342" stroke="#333" stroke-width="0.5"><title>Id 22, Wert -798.5</title></circle>
<circle cx="1233.3" cy="60.0" r="5" fill="#7b5d40" stroke="#333" stroke-width="0.5"><title>Id 23, Wert -835.3</title></circle>
<circle cx="1286.7" cy="60.0" r="5" fill="#90503c" stroke="#333" stroke-width="0.5"><title>Id 24, Wert -908.0</title></circle>
<circle cx="1340.0" cy="60.0" r="5" fill="#9c4a3a" stroke="#333" stroke-width="0.5"><title>Id 25, Wert -946.0</title></circle>
<circle cx="1393.3" cy="60.0" r="5" fill="#5c6e46" stroke="#333" stroke-width="0.5"><title>Id 26, Wert -730.3</title></circle>
<circle cx="1446.7" cy="60.0" r="5" fill="#954e3b" stroke="#333" stroke-width="0.5"><title>Id 27, Wert -922.8</title></circle>
<circle cx="1500.0" cy="60.0" r="5" fill="#80593f" stroke="#333" stroke-width="0.5"><title>Id 28, Wert -854.2</title></circle>
<circle cx="1553.3" cy="60.0" r="5" fill="#8f513c" stroke="#333" stroke-width="0.5"><title>Id 29, Wert -904.8</title></circle>
<circle cx="1606.7" cy="60.0" r="5" fill="#954e3b" stroke="#333" stroke-width="0.5"><title>Id 30, Wert -922.3</title></circle>
<circle cx="1660.0" cy="60.0" r="5" fill="#a94337" stroke="#333" stroke-width="0.5"><title>Id 31, Wert -989.2</title></circle>
<circle cx="1713.3" cy="60.0" r="5" fill="#616b45" stroke="#333" stroke-width="0.5"><title>Id 32, Wert -747.7</title></circle>
<circle cx="1766.7" cy="60.0" r="5" fill="#a64538" stroke="#333" stroke-width="0.5"><title>Id 33, Wert -979.6</title></circle>
<circle cx="1820.0" cy="60.0" r="5" fill="#a84337" stroke="#333" stroke-width="0.5"><title>Id 34, Wert -987.6</title></circle>
<circle cx="1873.3" cy="60.0" r="5" fill="#b53c35" stroke="#333" stroke-width="0.5"><title>Id 35, Wert -1030.5</title></circle>
<circle cx="1926.7" cy="60.0" r="5" fill="#9d4a3a" stroke="#333" stroke-width="0.5"><title>Id 36, Wert -949.0</title></circle>
<circle cx="1980.0" cy="60.0" r="5" fill="#795e40" stroke="#333" stroke-width="0.5"><title>Id 37, Wert -828.0</title></circle>
<circle cx="2033.3" cy="60.0" r="5" fill="#7e5b3f" stroke="#333" stroke-width="0.5"><title>Id 38, Wert -846.7</title></circle>
<circle cx="2086.7" cy="60.0" r="7" fill="#626b45" stroke="#c04040" stroke-width="2"><title>Id 39, Wert -751.9</title></circle>
<circle cx="2140.0" cy="60.0" r="5" fill="#775f41" stroke="#333" stroke-width="0.5"><title>Id 40, Wert -821.5</title></circle>
<circle cx="60.0" cy="150.0" r="5" fill="#8c533d" stroke="#333" stroke-width="0.5"><title>Id 41, Wert -892.9</title></circle>
<circle cx="86.3" cy="150.0" r="5" fill="#805a3f" stroke="#333" stroke-width="0.5"><title>Id 42, Wert -852.3</title></circle>
<circle cx="112.7" cy="150.0" r="5" fill="#7d5c40" stroke="#333" stroke-width="0.5"><title>Id 43, Wert -842.0</title></circle>
<circle cx="139.0" cy="150.0" r="5" fill="#944e3b" stroke="#333" stroke-width="0.5"><title>Id 44, Wert -921.3</title></circle>
<circle cx="165.3" cy="150.0" r="5" fill="#706342" stroke="#333" stroke-width="0.5"><title>Id 45, Wert -799.9</title></circle>
<circle cx="191.6" cy="150.0" r="5" fill="#9d4a3a" stroke="#333" stroke-width="0.5"><title>Id 46, Wert -949.5</title></circle>
<circle cx="218.0" cy="150.0" r="5" fill="#8d523c" stroke="#333" stroke-width="0.5"><title>Id 47, Wert -897.9</title></circle>
<circle cx="244.3" cy="150.0" r="5" fill="#9a4b3a" stroke="#333" stroke-width="0.5"><title>Id 48, Wert -938.8</title></circle>
<circle cx="270.6" cy="150.0" r="5" fill="#a64438" stroke="#333" stroke-width="0.5"><title>Id 49, Wert -980.4</title></circle>
<circle cx="297.0" cy="150.0" r="5" fill="#6d6442" stroke="#333" stroke-width="0.5"><title>Id 50, Wert -789.5</title></circle>
<circle cx="323.3" cy="150.0" r="5" fill="#6d6442" stroke="#333" stroke-width="0.5"><title>Id 51, Wert -789.6</title></circle>
<circle cx="349.6" cy="150.0" r="5" fill="#606c45" stroke="#333" stroke-width="0.5"><title>Id 52, Wert -743.7</title></circle>
<circle cx="375.9" cy="150.0" r="5" fill="#676844" stroke="#333" stroke-width="0.5"><title>Id 53, Wert -767.0</title></circle>
<circle cx="402.3" cy="150.0" r="5" fill="#5d6e46" stroke="#333" stroke-width="0.5"><title>Id 54, Wert -733.7</title></circle>
<circle cx="428.6" cy="150.0" r="5" fill="#a04739" stroke="#333" stroke-width="0.5"><title>Id 55, Wert -962.0</title></circle>
<circle cx="454.9" cy="150.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 56, Wert -693.1</title></circle>
<circle cx="481.3" cy="150.0" r="5" fill="#6d6543" stroke="#333" stroke-width="0.5"><title>Id 57, Wert -787.6</title></circle>
<circle cx="507.6" cy="150.0" r="5" fill="#636a44" stroke="#333" stroke-width="0.5"><title>Id 58, Wert -756.7</title></circle>
<circle cx="533.9" cy="150.0" r="5" fill="#5c6e46" stroke="#333" stroke-width="0.5"><title>Id 59, Wert -732.1</title></circle>
<circle cx="560.3" cy="150.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 60, Wert -662.4</title></circle>
<circle cx="586.6" cy="150.0" r="5" fill="#6a6643" stroke="#333" stroke-width="0.5"><title>Id 61, Wert -779.6</title></circle>
<circle cx="612.9" cy="150.0" r="5" fill="#527448" stroke="#333" stroke-width="0.5"><title>Id 62, Wert -698.2</title></circle>
<circle cx="639.2" cy="150.0" r="5" fill="#686743" stroke="#333" stroke-width="0.5"><title>Id 63, Wert -772.5</title></circle>
<circle cx="665.6" cy="150.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 64, Wert -808.9</title></circle>
<circle cx="691.9" cy="150.0" r="5" fill="#7e5b3f" stroke="#333" stroke-width="0.5"><title>Id 65, Wert -845.8</title></circle>
<circle cx="718.2" cy="150.0" r="5" fill="#437c4a" stroke="#333" stroke-width="0.5"><title>Id 66, Wert -648.6</title></circle>
<circle cx="744.6" cy="150.0" r="5" fill="#775f41" stroke="#333" stroke-width="0.5"><title>Id 67, Wert -823.1</title></circle>
<circle cx="770.9" cy="150.0" r="5" fill="#616b45" stroke="#333" stroke-width="0.5"><title>Id 68, Wert -748.9</title></circle>
<circle cx="797.2" cy="150.0" r="5" fill="#795e40" stroke="#333" stroke-width="0.5"><title>Id 69, Wert -827.7</title></circle>
<circle cx="823.5" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 70, Wert -793.0</title></circle>
<circle cx="849.9" cy="150.0" r="5" fill="#9b4a3a" stroke="#333" stroke-width="0.5"><title>Id 71, Wert -943.9</title></circle>
<circle cx="876.2" cy="150.0" r="5" fill="#527448" stroke="#333" stroke-width="0.5"><title>Id 72, Wert -696.9</title></circle>
<circle cx="902.5" cy="150.0" r="5" fill="#89553d" stroke="#333" stroke-width="0.5"><title>Id 73, Wert -881.8</title></circle>
<circle cx="928.9" cy="150.0" r="5" fill="#994c3a" stroke="#333" stroke-width="0.5"><title>Id 74, Wert -936.9</title></circle>
<circle cx="955.2" cy="150.0" r="5" fill="#a54538" stroke="#333" stroke-width="0.5"><title>Id 75, Wert -976.9</title></circle>
<circle cx="981.5" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 76, Wert -901.5</title></circle>
<circle cx="1007.8" cy="150.0" r="5" fill="#5e6d45" stroke="#333" stroke-width="0.5"><title>Id 77, Wert -737.7</title></circle>
<circle cx="1034.2" cy="150.0" r="5" fill="#775f41" stroke="#333" stroke-width="0.5"><title>Id 78, Wert -821.2</title></circle>
<circle cx="1060.5" cy="150.0" r="5" fill="#557247" stroke="#333" stroke-width="0.5"><title>Id 79, Wert -707.3</title></circle>
<circle cx="1086.8" cy="150.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 80, Wert -695.2</title></circle>
<circle cx="1113.2" cy="150.0" r="5" fill="#8d533d" stroke="#333" stroke-width="0.5"><title>Id 81, Wert -895.4</title></circle>
<circle cx="1139.5" cy="150.0" r="5" fill="#81593f" stroke="#333" stroke-width="0.5"><title>Id 82, Wert -856.3</title></circle>
<circle cx="1165.8" cy="150.0" r="5" fill="#84583e" stroke="#333" stroke-width="0.5"><title>Id 83, Wert -865.0</title></circle>
<circle cx="1192.2" cy="150.0" r="5" fill="#8b533d" stroke="#333" stroke-width="0.5"><title>Id 84, Wert -891.3</title></circle>
<circle cx="1218.5" cy="150.0" r="5" fill="#666844" stroke="#333" stroke-width="0.5"><title>Id 85, Wert -766.9</title></circle>
<circle cx="1244.8" cy="150.0" r="5" fill="#7b5c40" stroke="#333" stroke-width="0.5"><title>Id 86, Wert -837.5</title></circle>
<circle cx="1271.1" cy="150.0" r="5" fill="#7e5b3f" stroke="#333" stroke-width="0.5"><title>Id 87, Wert -846.5</title></circle>
<circle cx="1297.5" cy="150.0" r="5" fill="#86573e" stroke="#333" stroke-width="0.5"><title>Id 88, Wert -871.3</title></circle>
<circle cx="1323.8" cy="150.0" r="5" fill="#b43c35" stroke="#333" stroke-width="0.5"><title>Id 89, Wert -1028.5</title></circle>
<circle cx="1350.1" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 90, Wert -793.5</title></circle>
<circle cx="1376.5" cy="150.0" r="5" fill="#616b45" stroke="#333" stroke-width="0.5"><title>Id 91, Wert -748.2</title></circle>
<circle cx="1402.8" cy="150.0" r="5" fill="#587046" stroke="#333" stroke-width="0.5"><title>Id 92, Wert -718.6</title></circle>
<circle cx="1429.1" cy="150.0" r="5" fill="#636a44" stroke="#333" stroke-width="0.5"><title>Id 93, Wert -756.5</title></circle>
<circle cx="1455.4" cy="150.0" r="5" fill="#616b45" stroke="#333" stroke-width="0.5"><title>Id 94, Wert -748.9</title></circle>
<circle cx="1481.8" cy="150.0" r="5" fill="#ab4137" stroke="#333" stroke-width="0.5"><title>Id 95, Wert -997.9</title></circle>
<circle cx="1508.1" cy="150.0" r="5" fill="#567247" stroke="#333" stroke-width="0.5"><title>Id 96, Wert -710.1</title></circle>
<circle cx="1534.4" cy="150.0" r="5" fill="#756041" stroke="#333" stroke-width="0.5"><title>Id 97, Wert -814.8</title></circle>
<circle cx="1560.8" cy="150.0" r="5" fill="#587046" stroke="#333" stroke-width="0.5"><title>Id 98, Wert -717.4</title></circle>
<circle cx="1587.1" cy="150.0" r="5" fill="#4f7548" stroke="#333" stroke-width="0.5"><title>Id 99, Wert -688.7</title></circle>
<circle cx="1613.4" cy="150.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 100, Wert -662.4</title></circle>
<circle cx="1639.7" cy="150.0" r="5" fill="#5a6f46" stroke="#333" stroke-width="0.5"><title>Id 101, Wert -726.5</title></circle>
<circle cx="1666.1" cy="150.0" r="5" fill="#507548" stroke="#333" stroke-width="0.5"><title>Id 102, Wert -691.2</title></circle>
<circle cx="1692.4" cy="150.0" r="5" fill="#6d6543" stroke="#333" stroke-width="0.5"><title>Id 103, Wert -787.7</title></circle>
<circle cx="1718.7" cy="150.0" r="5" fill="#726242" stroke="#333" stroke-width="0.5"><title>Id 104, Wert -805.3</title></circle>
<circle cx="1745.1" cy="150.0" r="5" fill="#8c533d" stroke="#333" stroke-width="0.5"><title>Id 105, Wert -893.3</title></circle>
<circle cx="1771.4" cy="150.0" r="5" fill="#577147" stroke="#333" stroke-width="0.5"><title>Id 106, Wert -715.1</title></circle>
<circle cx="1797.7" cy="150.0" r="5" fill="#8a543d" stroke="#333" stroke-width="0.5"><title>Id 107, Wert -885.5</title></circle>
<circle cx="1824.1" cy="150.0" r="5" fill="#83583e" stroke="#333" stroke-width="0.5"><title>Id 108, Wert -862.6</title></circle>
<circle cx="1850.4" cy="150.0" r="5" fill="#7a5d40" stroke="#333" stroke-width="0.5"><title>Id 109, Wert -831.0</title></circle>
<circle cx="1876.7" cy="150.0" r="5" fill="#86573e" stroke="#333" stroke-width="0.5"><title>Id 110, Wert -871.3</title></circle>
<circle cx="1903.0" cy="150.0" r="5" fill="#9d4939" stroke="#333" stroke-width="0.5"><title>Id 111, Wert -951.6</title></circle>
<circle cx="1929.4" cy="150.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 112, Wert -654.9</title></circle>
<circle cx="1955.7" cy="150.0" r="5" fill="#a64538" stroke="#333" stroke-width="0.5"><title>Id 113, Wert -979.4</title></circle>
<circle cx="1982.0" cy="150.0" r="5" fill="#83583e" stroke="#333" stroke-width="0.5"><title>Id 114, Wert -861.8</title></circle>
<circle cx="2008.4" cy="150.0" r="5" fill="#9d4939" stroke="#333" stroke-width="0.5"><title>Id 115, Wert -949.9</title></circle>
<circle cx="2034.7" cy="150.0" r="5" fill="#8d523c" stroke="#333" stroke-width="0.5"><title>Id 116, Wert -897.1</title></circle>
<circle cx="2061.0" cy="150.0" r="5" fill="#656944" stroke="#333" stroke-width="0.5"><title>Id 117, Wert -762.8</title></circle>
<circle cx="2087.3" cy="150.0" r="5" fill="#775f41" stroke="#333" stroke-width="0.5"><title>Id 118, Wert -821.3</title></circle>
<circle cx="2113.7" cy="150.0" r="7" fill="#4f7548" stroke="#c04040" stroke-width="2"><title>Id 119, Wert -689.0</title></circle>
<circle cx="2140.0" cy="150.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 120, Wert -693.1</title></circle>
<circle cx="60.0" cy="240.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 121, Wert -595.6</title></circle>
<circle cx="91.0" cy="240.0" r="5" fill="#467b4a" stroke="#333" stroke-width="0.5"><title>Id 122, Wert -656.3</title></circle>
<circle cx="122.1" cy="240.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 123, Wert -621.8</title></circle>
<circle cx="153.1" cy="240.0" r="5" fill="#407e4b" stroke="#333" stroke-width="0.5"><title>Id 124, Wert -636.7</title></circle>
<circle cx="184.2" cy="240.0" r="5" fill="#3d7f4b" stroke="#333" stroke-width="0.5"><title>Id 125, Wert -626.9</title></circle>
<circle cx="215.2" cy="240.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 126, Wert -599.9</title></circle>
<circle cx="246.3" cy="240.0" r="5" fill="#507548" stroke="#333" stroke-width="0.5"><title>Id 127, Wert -691.6</title></circle>
<circle cx="277.3" cy="240.0" r="5" fill="#5a6f46" stroke="#333" stroke-width="0.5"><title>Id 128, Wert -724.1</title></circle>
<circle cx="308.4" cy="240.0" r="5" fill="#3f7e4b" stroke="#333" stroke-width="0.5"><title>Id 129, Wert -633.9</title></circle>
<circle cx="339.4" cy="240.0" r="5" fill="#5a6f46" stroke="#333" stroke-width="0.5"><title>Id 130, Wert -724.7</title></circle>
<circle cx="370.4" cy="240.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 131, Wert -654.9</title></circle>
<circle cx="401.5" cy="240.0" r="5" fill="#4a7849" stroke="#333" stroke-width="0.5"><title>Id 132, Wert -669.8</title></circle>
<circle cx="432.5" cy="240.0" r="5" fill="#567147" stroke="#333" stroke-width="0.5"><title>Id 133, Wert -711.9</title></circle>
<circle cx="463.6" cy="240.0" r="5" fill="#4b7849" stroke="#333" stroke-width="0.5"><title>Id 134, Wert -673.2</title></circle>
<circle cx="494.6" cy="240.0" r="5" fill="#547347" stroke="#333" stroke-width="0.5"><title>Id 135, Wert -703.9</title></circle>
<circle cx="525.7" cy="240.0" r="5" fill="#437c4a" stroke="#333" stroke-width="0.5"><title>Id 136, Wert -647.3</title></circle>
<circle cx="556.7" cy="240.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 137, Wert -695.2</title></circle>
<circle cx="587.8" cy="240.0" r="5" fill="#537347" stroke="#333" stroke-width="0.5"><title>Id 138, Wert -700.5</title></circle>
<circle cx="618.8" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 139, Wert -677.0</title></circle>
<circle cx="649.9" cy="240.0" r="5" fill="#487949" stroke="#333" stroke-width="0.5"><title>Id 140, Wert -665.6</title></circle>
<circle cx="680.9" cy="240.0" r="5" fill="#5a6f46" stroke="#333" stroke-width="0.5"><title>Id 141, Wert -725.2</title></circle>
<circle cx="711.9" cy="240.0" r="5" fill="#507548" stroke="#333" stroke-width="0.5"><title>Id 142, Wert -690.5</title></circle>
<circle cx="743.0" cy="240.0" r="5" fill="#577147" stroke="#333" stroke-width="0.5"><title>Id 143, Wert -715.4</title></circle>
<circle cx="774.0" cy="240.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 144, Wert -752.5</title></circle>
<circle cx="805.1" cy="240.0" r="5" fill="#4d7648" stroke="#333" stroke-width="0.5"><title>Id 145, Wert -680.9</title></circle>
<circle cx="836.1" cy="240.0" r="5" fill="#427c4a" stroke="#333" stroke-width="0.5"><title>Id 146, Wert -645.5</title></circle>
<circle cx="867.2" cy="240.0" r="5" fill="#4d7749" stroke="#333" stroke-width="0.5"><title>Id 147, Wert -679.7</title></circle>
<circle cx="898.2" cy="240.0" r="5" fill="#616b45" stroke="#333" stroke-width="0.5"><title>Id 148, Wert -748.6</title></circle>
<circle cx="929.3" cy="240.0" r="5" fill="#487949" stroke="#333" stroke-width="0.5"><title>Id 149, Wert -664.3</title></circle>
<circle cx="960.3" cy="240.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 150, Wert -653.7</title></circle>
<circle cx="991.3" cy="240.0" r="5" fill="#4b7849" stroke="#333" stroke-width="0.5"><title>Id 151, Wert -674.5</title></circle>
<circle cx="1022.4" cy="240.0" r="5" fill="#4e7648" stroke="#333" stroke-width="0.5"><title>Id 152, Wert -683.8</title></circle>
<circle cx="1053.4" cy="240.0" r="5" fill="#686743" stroke="#333" stroke-width="0.5"><title>Id 153, Wert -771.8</title></circle>
<circle cx="1084.5" cy="240.0" r="5" fill="#547247" stroke="#333" stroke-width="0.5"><title>Id 154, Wert -705.9</title></circle>
<circle cx="1115.5" cy="240.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 155, Wert -622.4</title></circle>
<circle cx="1146.6" cy="240.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 156, Wert -654.6</title></circle>
<circle cx="1177.6" cy="240.0" r="5" fill="#407e4b" stroke="#333" stroke-width="0.5"><title>Id 157, Wert -636.7</title></circle>
<circle cx="1208.7" cy="240.0" r="5" fill="#487949" stroke="#333" stroke-width="0.5"><title>Id 158, Wert -663.4</title></circle>
<circle cx="1239.7" cy="240.0" r="5" fill="#4f7548" stroke="#333" stroke-width="0.5"><title>Id 159, Wert -687.9</title></circle>
<circle cx="1270.7" cy="240.0" r="7" fill="#417d4b" stroke="#c04040" stroke-width="2"><title>Id 160, Wert -642.0</title></circle>
<circle cx="1301.8" cy="240.0" r="5" fill="#487949" stroke="#333" stroke-width="0.5"><title>Id 161, Wert -664.6</title></circle>
<circle cx="1332.8" cy="240.0" r="5" fill="#3f7e4b" stroke="#333" stroke-width="0.5"><title>Id 162, Wert -634.2</title></circle>
<circle cx="1363.9" cy="240.0" r="5" fill="#4a7849" stroke="#333" stroke-width="0.5"><title>Id 163, Wert -669.8</title></circle>
<circle cx="1394.9" cy="240.0" r="5" fill="#3d804c" stroke="#333" stroke-width="0.5"><title>Id 164, Wert -625.8</title></circle>
<circle cx="1426.0" cy="240.0" r="5" fill="#3f7f4b" stroke="#333" stroke-width="0.5"><title>Id 165, Wert -632.6</title></circle>
<circle cx="1457.0" cy="240.0" r="5" fill="#3f7e4b" stroke="#333" stroke-width="0.5"><title>Id 166, Wert -634.8</title></circle>
<circle cx="1488.1" cy="240.0" r="5" fill="#567147" stroke="#333" stroke-width="0.5"><title>Id 167, Wert -711.3</title></circle>
<circle cx="1519.1" cy="240.0" r="5" fill="#447c4a" stroke="#333" stroke-width="0.5"><title>Id 168, Wert -650.2</title></circle>
<circle cx="1550.1" cy="240.0" r="5" fill="#547347" stroke="#333" stroke-width="0.5"><title>Id 169, Wert -703.9</title></circle>
<circle cx="1581.2" cy="240.0" r="5" fill="#437c4a" stroke="#333" stroke-width="0.5"><title>Id 170, Wert -647.3</title></circle>
<circle cx="1612.2" cy="240.0" r="5" fill="#527448" stroke="#333" stroke-width="0.5"><title>Id 171, Wert -696.9</title></circle>
<circle cx="1643.3" cy="240.0" r="5" fill="#467b4a" stroke="#333" stroke-width="0.5"><title>Id 172, Wert -656.3</title></circle>
<circle cx="1674.3" cy="240.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 173, Wert -662.3</title></circle>
<circle cx="1705.4" cy="240.0" r="5" fill="#4f7548" stroke="#333" stroke-width="0.5"><title>Id 174, Wert -688.7</title></circle>
<circle cx="1736.4" cy="240.0" r="5" fill="#4e7648" stroke="#333" stroke-width="0.5"><title>Id 175, Wert -683.8</title></circle>
<circle cx="1767.5" cy="240.0" r="5" fill="#656944" stroke="#333" stroke-width="0.5"><title>Id 176, Wert -760.6</title></circle>
<circle cx="1798.5" cy="240.0" r="5" fill="#497949" stroke="#333" stroke-width="0.5"><title>Id 177, Wert -666.4</title></circle>
<circle cx="1829.6" cy="240.0" r="5" fill="#5b6e46" stroke="#333" stroke-width="0.5"><title>Id 178, Wert -729.7</title></circle>
<circle cx="1860.6" cy="240.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 179, Wert -661.1</title></circle>
<circle cx="1891.6" cy="240.0" r="5" fill="#5a6f46" stroke="#333" stroke-width="0.5"><title>Id 180, Wert -725.9</title></circle>
<circle cx="1922.7" cy="240.0" r="5" fill="#4e7648" stroke="#333" stroke-width="0.5"><title>Id 181, Wert -683.8</title></circle>
<circle cx="1953.7" cy="240.0" r="5" fill="#517448" stroke="#333" stroke-width="0.5"><title>Id 182, Wert -693.8</title></circle>
<circle cx="1984.8" cy="240.0" r="5" fill="#507548" stroke="#333" stroke-width="0.5"><title>Id 183, Wert -690.9</title></circle>
<circle cx="2015.8" cy="240.0" r="5" fill="#5a6f46" stroke="#333" stroke-width="0.5"><title>Id 184, Wert -724.5</title></circle>
<circle cx="2046.9" cy="240.0" r="5" fill="#4a7849" stroke="#333" stroke-width="0.5"><title>Id 185, Wert -671.5</title></circle>
<circle cx="2077.9" cy="240.0" r="5" fill="#646944" stroke="#333" stroke-width="0.5"><title>Id 186, Wert -758.6</title></circle>
<circle cx="2109.0" cy="240.0" r="5" fill="#537347" stroke="#333" stroke-width="0.5"><title>Id 187, Wert -702.3</title></circle>
<circle cx="2140.0" cy="240.0" r="5" fill="#487949" stroke="#333" stroke-width="0.5"><title>Id 188, Wert -664.5</title></circle>
<circle cx="60.0" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 189, Wert -569.7</title></circle>
<circle cx="97.8" cy="330.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 190, Wert -653.6</title></circle>
<circle cx="135.6" cy="330.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 191, Wert -620.8</title></circle>
<circle cx="173.5" cy="330.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 192, Wert -595.5</title></circle>
<circle cx="211.3" cy="330.0" r="5" fill="#3e7f4b" stroke="#333" stroke-width="0.5"><title>Id 193, Wert -629.6</title></circle>
<circle cx="249.1" cy="330.0" r="5" fill="#3d7f4b" stroke="#333" stroke-width="0.5"><title>Id 194, Wert -626.7</title></circle>
<circle cx="286.9" cy="330.0" r="5" fill="#2b894f" stroke="#333" stroke-width="0.5"><title>Id 195, Wert -568.2</title></circle>
<circle cx="324.7" cy="330.0" r="5" fill="#3f7e4b" stroke="#333" stroke-width="0.5"><title>Id 196, Wert -633.8</title></circle>
<circle cx="362.5" cy="330.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 197, Wert -608.1</title></circle>
<circle cx="400.4" cy="330.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 198, Wert -622.3</title></circle>
<circle cx="438.2" cy="330.0" r="5" fill="#407e4b" stroke="#333" stroke-width="0.5"><title>Id 199, Wert -636.7</title></circle>
<circle cx="476.0" cy="330.0" r="5" fill="#407e4b" stroke="#333" stroke-width="0.5"><title>Id 200, Wert -636.8</title></circle>
<circle cx="513.8" cy="330.0" r="7" fill="#35844d" stroke="#c04040" stroke-width="2"><title>Id 201, Wert -599.9</title></circle>
<circle cx="551.6" cy="330.0" r="5" fill="#427c4a" stroke="#333" stroke-width="0.5"><title>Id 202, Wert -645.7</title></circle>
<circle cx="589.5" cy="330.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 203, Wert -621.3</title></circle>
<circle cx="627.3" cy="330.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 204, Wert -611.1</title></circle>
<circle cx="665.1" cy="330.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 205, Wert -622.4</title></circle>
<circle cx="702.9" cy="330.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 206, Wert -625.4</title></circle>
<circle cx="740.7" cy="330.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 207, Wert -653.7</title></circle>
<circle cx="778.5" cy="330.0" r="5" fill="#3e7f4b" stroke="#333" stroke-width="0.5"><title>Id 208, Wert -631.8</title></circle>
<circle cx="816.4" cy="330.0" r="5" fill="#32854d" stroke="#333" stroke-width="0.5"><title>Id 209, Wert -591.5</title></circle>
<circle cx="854.2" cy="330.0" r="5" fill="#3f7e4b" stroke="#333" stroke-width="0.5"><title>Id 210, Wert -634.3</title></circle>
<circle cx="892.0" cy="330.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 211, Wert -654.9</title></circle>
<circle cx="929.8" cy="330.0" r="5" fill="#3e7f4b" stroke="#333" stroke-width="0.5"><title>Id 212, Wert -630.4</title></circle>
<circle cx="967.6" cy="330.0" r="5" fill="#3d7f4b" stroke="#333" stroke-width="0.5"><title>Id 213, Wert -628.8</title></circle>
<circle cx="1005.5" cy="330.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 214, Wert -610.2</title></circle>
<circle cx="1043.3" cy="330.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 215, Wert -594.8</title></circle>
<circle cx="1081.1" cy="330.0" r="5" fill="#407e4b" stroke="#333" stroke-width="0.5"><title>Id 216, Wert -637.8</title></circle>
<circle cx="1118.9" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 217, Wert -569.7</title></circle>
<circle cx="1156.7" cy="330.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 218, Wert -623.6</title></circle>
<circle cx="1194.5" cy="330.0" r="5" fill="#437c4a" stroke="#333" stroke-width="0.5"><title>Id 219, Wert -647.7</title></circle>
<circle cx="1232.4" cy="330.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 220, Wert -595.5</title></circle>
<circle cx="1270.2" cy="330.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 221, Wert -652.9</title></circle>
<circle cx="1308.0" cy="330.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 222, Wert -585.7</title></circle>
<circle cx="1345.8" cy="330.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 223, Wert -607.9</title></circle>
<circle cx="1383.6" cy="330.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 224, Wert -610.9</title></circle>
<circle cx="1421.5" cy="330.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 225, Wert -661.3</title></circle>
<circle cx="1459.3" cy="330.0" r="5" fill="#34844d" stroke="#333" stroke-width="0.5"><title>Id 226, Wert -596.9</title></circle>
<circle cx="1497.1" cy="330.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 227, Wert -610.8</title></circle>
<circle cx="1534.9" cy="330.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 228, Wert -601.8</title></circle>
<circle cx="1572.7" cy="330.0" r="5" fill="#4f7548" stroke="#333" stroke-width="0.5"><title>Id 229, Wert -689.0</title></circle>
<circle cx="1610.5" cy="330.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 230, Wert -592.8</title></circle>
<circle cx="1648.4" cy="330.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 231, Wert -621.3</title></circle>
<circle cx="1686.2" cy="330.0" r="5" fill="#437c4a" stroke="#333" stroke-width="0.5"><title>Id 232, Wert -647.2</title></circle>
<circle cx="1724.0" cy="330.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 233, Wert -622.6</title></circle>
<circle cx="1761.8" cy="330.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 234, Wert -625.4</title></circle>
<circle cx="1799.6" cy="330.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 235, Wert -594.3</title></circle>
<circle cx="1837.5" cy="330.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 236, Wert -564.7</title></circle>
<circle cx="1875.3" cy="330.0" r="5" fill="#467b4a" stroke="#333" stroke-width="0.5"><title>Id 237, Wert -656.3</title></circle>
<circle cx="1913.1" cy="330.0" r="5" fill="#457b4a" stroke="#333" stroke-width="0.5"><title>Id 238, Wert -654.0</title></circle>
<circle cx="1950.9" cy="330.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 239, Wert -564.7</title></circle>
<circle cx="1988.7" cy="330.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 240, Wert -603.5</title></circle>
<circle cx="2026.5" cy="330.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 241, Wert -601.8</title></circle>
<circle cx="2064.4" cy="330.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 242, Wert -610.2</title></circle>
<circle cx="2102.2" cy="330.0" r="5" fill="#407e4b" stroke="#333" stroke-width="0.5"><title>Id 243, Wert -637.8</title></circle>
<circle cx="2140.0" cy="330.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 244, Wert -595.6</title></circle>
<circle cx="60.0" cy="420.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 245, Wert -576.5</title></circle>
<circle cx="106.2" cy="420.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 246, Wert -598.8</title></circle>
<circle cx="152.4" cy="420.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 247, Wert -588.2</title></circle>
<circle cx="198.7" cy="420.0" r="5" fill="#3d7f4b" stroke="#333" stroke-width="0.5"><title>Id 248, Wert -628.0</title></circle>
<circle cx="244.9" cy="420.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 249, Wert -555.3</title></circle>
<circle cx="291.1" cy="420.0" r="5" fill="#2b894f" stroke="#333" stroke-width="0.5"><title>Id 250, Wert -567.8</title></circle>
<circle cx="337.3" cy="420.0" r="5" fill="#32854d" stroke="#333" stroke-width="0.5"><title>Id 251, Wert -591.5</title></circle>
<circle cx="383.6" cy="420.0" r="5" fill="#2f874e" stroke="#333" stroke-width="0.5"><title>Id 252, Wert -579.3</title></circle>
<circle cx="429.8" cy="420.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 253, Wert -594.3</title></circle>
<circle cx="476.0" cy="420.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 254, Wert -595.9</title></circle>
<circle cx="522.2" cy="420.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 255, Wert -595.5</title></circle>
<circle cx="568.4" cy="420.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 256, Wert -595.5</title></circle>
<circle cx="614.7" cy="420.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 257, Wert -569.7</title></circle>
<circle cx="660.9" cy="420.0" r="5" fill="#3c804c" stroke="#333" stroke-width="0.5"><title>Id 258, Wert -622.7</title></circle>
<circle cx="707.1" cy="420.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 259, Wert -609.3</title></circle>
<circle cx="753.3" cy="420.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 260, Wert -581.9</title></circle>
<circle cx="799.6" cy="420.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 261, Wert -581.9</title></circle>
<circle cx="845.8" cy="420.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 262, Wert -589.6</title></circle>
<circle cx="892.0" cy="420.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 263, Wert -602.4</title></circle>
<circle cx="938.2" cy="420.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 264, Wert -602.2</title></circle>
<circle cx="984.4" cy="420.0" r="5" fill="#37834d" stroke="#333" stroke-width="0.5"><title>Id 265, Wert -607.9</title></circle>
<circle cx="1030.7" cy="420.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 266, Wert -583.1</title></circle>
<circle cx="1076.9" cy="420.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 267, Wert -583.2</title></circle>
<circle cx="1123.1" cy="420.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 268, Wert -576.5</title></circle>
<circle cx="1169.3" cy="420.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 269, Wert -588.2</title></circle>
<circle cx="1215.6" cy="420.0" r="5" fill="#2b8a4f" stroke="#333" stroke-width="0.5"><title>Id 270, Wert -565.5</title></circle>
<circle cx="1261.8" cy="420.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 271, Wert -558.2</title></circle>
<circle cx="1308.0" cy="420.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 272, Wert -558.3</title></circle>
<circle cx="1354.2" cy="420.0" r="5" fill="#3b814c" stroke="#333" stroke-width="0.5"><title>Id 273, Wert -619.5</title></circle>
<circle cx="1400.4" cy="420.0" r="5" fill="#2b8a4f" stroke="#333" stroke-width="0.5"><title>Id 274, Wert -565.5</title></circle>
<circle cx="1446.7" cy="420.0" r="5" fill="#2f874e" stroke="#333" stroke-width="0.5"><title>Id 275, Wert -579.3</title></circle>
<circle cx="1492.9" cy="420.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 276, Wert -594.3</title></circle>
<circle cx="1539.1" cy="420.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 277, Wert -621.9</title></circle>
<circle cx="1585.3" cy="420.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 278, Wert -595.5</title></circle>
<circle cx="1631.6" cy="420.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 279, Wert -595.5</title></circle>
<circle cx="1677.8" cy="420.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 280, Wert -569.7</title></circle>
<circle cx="1724.0" cy="420.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 281, Wert -596.7</title></circle>
<circle cx="1770.2" cy="420.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 282, Wert -609.3</title></circle>
<circle cx="1816.4" cy="420.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 283, Wert -554.9</title></circle>
<circle cx="1862.7" cy="420.0" r="5" fill="#30864e" stroke="#333" stroke-width="0.5"><title>Id 284, Wert -584.9</title></circle>
<circle cx="1908.9" cy="420.0" r="5" fill="#3d7f4b" stroke="#333" stroke-width="0.5"><title>Id 285, Wert -628.8</title></circle>
<circle cx="1955.1" cy="420.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 286, Wert -601.8</title></circle>
<circle cx="2001.3" cy="420.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 287, Wert -603.5</title></circle>
<circle cx="2047.6" cy="420.0" r="5" fill="#2b894f" stroke="#333" stroke-width="0.5"><title>Id 288, Wert -568.2</title></circle>
<circle cx="2093.8" cy="420.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 289, Wert -610.5</title></circle>
<circle cx="2140.0" cy="420.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 290, Wert -557.2</title></circle>
<circle cx="60.0" cy="510.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 291, Wert -590.3</title></circle>
<circle cx="116.2" cy="510.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 292, Wert -592.3</title></circle>
<circle cx="172.4" cy="510.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 293, Wert -555.1</title></circle>
<circle cx="228.6" cy="510.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 294, Wert -558.2</title></circle>
<circle cx="284.9" cy="510.0" r="5" fill="#39814c" stroke="#333" stroke-width="0.5"><title>Id 295, Wert -615.3</title></circle>
<circle cx="341.1" cy="510.0" r="5" fill="#36844d" stroke="#333" stroke-width="0.5"><title>Id 296, Wert -602.2</title></circle>
<circle cx="397.3" cy="510.0" r="5" fill="#39814c" stroke="#333" stroke-width="0.5"><title>Id 297, Wert -615.3</title></circle>
<circle cx="453.5" cy="510.0" r="5" fill="#2b894f" stroke="#333" stroke-width="0.5"><title>Id 298, Wert -567.0</title></circle>
<circle cx="509.7" cy="510.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 299, Wert -588.2</title></circle>
<circle cx="565.9" cy="510.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 300, Wert -564.3</title></circle>
<circle cx="622.2" cy="510.0" r="5" fill="#2b8a4f" stroke="#333" stroke-width="0.5"><title>Id 301, Wert -565.5</title></circle>
<circle cx="678.4" cy="510.0" r="5" fill="#2b8a4f" stroke="#333" stroke-width="0.5"><title>Id 302, Wert -565.5</title></circle>
<circle cx="734.6" cy="510.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 303, Wert -555.2</title></circle>
<circle cx="790.8" cy="510.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 304, Wert -595.6</title></circle>
<circle cx="847.0" cy="510.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 305, Wert -621.9</title></circle>
<circle cx="903.2" cy="510.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 306, Wert -558.3</title></circle>
<circle cx="959.5" cy="510.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 307, Wert -589.6</title></circle>
<circle cx="1015.7" cy="510.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 308, Wert -589.6</title></circle>
<circle cx="1071.9" cy="510.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 309, Wert -592.9</title></circle>
<circle cx="1128.1" cy="510.0" r="5" fill="#2f874e" stroke="#333" stroke-width="0.5"><title>Id 310, Wert -581.8</title></circle>
<circle cx="1184.3" cy="510.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 311, Wert -555.3</title></circle>
<circle cx="1240.5" cy="510.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 312, Wert -609.2</title></circle>
<circle cx="1296.8" cy="510.0" r="5" fill="#39814c" stroke="#333" stroke-width="0.5"><title>Id 313, Wert -615.2</title></circle>
<circle cx="1353.0" cy="510.0" r="5" fill="#30864e" stroke="#333" stroke-width="0.5"><title>Id 314, Wert -585.2</title></circle>
<circle cx="1409.2" cy="510.0" r="5" fill="#2e884e" stroke="#333" stroke-width="0.5"><title>Id 315, Wert -576.5</title></circle>
<circle cx="1465.4" cy="510.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 316, Wert -598.8</title></circle>
<circle cx="1521.6" cy="510.0" r="5" fill="#2b894f" stroke="#333" stroke-width="0.5"><title>Id 317, Wert -567.0</title></circle>
<circle cx="1577.8" cy="510.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 318, Wert -564.0</title></circle>
<circle cx="1634.1" cy="510.0" r="5" fill="#32854d" stroke="#333" stroke-width="0.5"><title>Id 319, Wert -591.2</title></circle>
<circle cx="1690.3" cy="510.0" r="5" fill="#39824c" stroke="#333" stroke-width="0.5"><title>Id 320, Wert -614.3</title></circle>
<circle cx="1746.5" cy="510.0" r="5" fill="#2b8a4f" stroke="#333" stroke-width="0.5"><title>Id 321, Wert -565.5</title></circle>
<circle cx="1802.7" cy="510.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 322, Wert -595.6</title></circle>
<circle cx="1858.9" cy="510.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 323, Wert -586.8</title></circle>
<circle cx="1915.1" cy="510.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 324, Wert -587.9</title></circle>
<circle cx="1971.4" cy="510.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 325, Wert -555.3</title></circle>
<circle cx="2027.6" cy="510.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 326, Wert -562.7</title></circle>
<circle cx="2083.8" cy="510.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 327, Wert -589.6</title></circle>
<circle cx="2140.0" cy="510.0" r="5" fill="#2f874e" stroke="#333" stroke-width="0.5"><title>Id 328, Wert -578.9</title></circle>
<circle cx="60.0" cy="600.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 329, Wert -558.2</title></circle>
<circle cx="127.1" cy="600.0" r="5" fill="#3b814c" stroke="#333" stroke-width="0.5"><title>Id 330, Wert -618.9</title></circle>
<circle cx="194.2" cy="600.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 331, Wert -592.2</title></circle>
<circle cx="261.3" cy="600.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 332, Wert -555.3</title></circle>
<circle cx="328.4" cy="600.0" r="5" fill="#36834d" stroke="#333" stroke-width="0.5"><title>Id 333, Wert -602.8</title></circle>
<circle cx="395.5" cy="600.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 334, Wert -611.6</title></circle>
<circle cx="462.6" cy="600.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 335, Wert -582.2</title></circle>
<circle cx="529.7" cy="600.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 336, Wert -596.7</title></circle>
<circle cx="596.8" cy="600.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 337, Wert -558.2</title></circle>
<circle cx="663.9" cy="600.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 338, Wert -558.3</title></circle>
<circle cx="731.0" cy="600.0" r="5" fill="#30864e" stroke="#333" stroke-width="0.5"><title>Id 339, Wert -585.2</title></circle>
<circle cx="798.1" cy="600.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 340, Wert -593.2</title></circle>
<circle cx="865.2" cy="600.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 341, Wert -589.6</title></circle>
<circle cx="932.3" cy="600.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 342, Wert -589.0</title></circle>
<circle cx="999.4" cy="600.0" r="5" fill="#39814c" stroke="#333" stroke-width="0.5"><title>Id 343, Wert -615.3</title></circle>
<circle cx="1066.5" cy="600.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 344, Wert -598.8</title></circle>
<circle cx="1133.5" cy="600.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 345, Wert -558.2</title></circle>
<circle cx="1200.6" cy="600.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 346, Wert -555.1</title></circle>
<circle cx="1267.7" cy="600.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 347, Wert -611.5</title></circle>
<circle cx="1334.8" cy="600.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 348, Wert -585.9</title></circle>
<circle cx="1401.9" cy="600.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 349, Wert -584.5</title></circle>
<circle cx="1469.0" cy="600.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 350, Wert -592.3</title></circle>
<circle cx="1536.1" cy="600.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 351, Wert -582.2</title></circle>
<circle cx="1603.2" cy="600.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 352, Wert -558.2</title></circle>
<circle cx="1670.3" cy="600.0" r="5" fill="#34844d" stroke="#333" stroke-width="0.5"><title>Id 353, Wert -598.6</title></circle>
<circle cx="1737.4" cy="600.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 354, Wert -587.9</title></circle>
<circle cx="1804.5" cy="600.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 355, Wert -562.2</title></circle>
<circle cx="1871.6" cy="600.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 356, Wert -588.4</title></circle>
<circle cx="1938.7" cy="600.0" r="5" fill="#2a8a4f" stroke="#333" stroke-width="0.5"><title>Id 357, Wert -564.0</title></circle>
<circle cx="2005.8" cy="600.0" r="5" fill="#35844d" stroke="#333" stroke-width="0.5"><title>Id 358, Wert -601.1</title></circle>
<circle cx="2072.9" cy="600.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 359, Wert -589.6</title></circle>
<circle cx="2140.0" cy="600.0" r="5" fill="#39814c" stroke="#333" stroke-width="0.5"><title>Id 360, Wert -615.3</title></circle>
<circle cx="60.0" cy="690.0" r="5" fill="#32864e" stroke="#333" stroke-width="0.5"><title>Id 361, Wert -590.3</title></circle>
<circle cx="143.2" cy="690.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 362, Wert -582.1</title></circle>
<circle cx="226.4" cy="690.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 363, Wert -609.1</title></circle>
<circle cx="309.6" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 364, Wert -555.2</title></circle>
<circle cx="392.8" cy="690.0" r="5" fill="#38824c" stroke="#333" stroke-width="0.5"><title>Id 365, Wert -611.6</title></circle>
<circle cx="476.0" cy="690.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 366, Wert -592.3</title></circle>
<circle cx="559.2" cy="690.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 367, Wert -592.3</title></circle>
<circle cx="642.4" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 368, Wert -555.2</title></circle>
<circle cx="725.6" cy="690.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 369, Wert -582.2</title></circle>
<circle cx="808.8" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 370, Wert -558.2</title></circle>
<circle cx="892.0" cy="690.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 371, Wert -587.8</title></circle>
<circle cx="975.2" cy="690.0" r="5" fill="#31864e" stroke="#333" stroke-width="0.5"><title>Id 372, Wert -585.8</title></circle>
<circle cx="1058.4" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 373, Wert -558.2</title></circle>
<circle cx="1141.6" cy="690.0" r="5" fill="#2f874e" stroke="#333" stroke-width="0.5"><title>Id 374, Wert -581.8</title></circle>
<circle cx="1224.8" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 375, Wert -555.1</title></circle>
<circle cx="1308.0" cy="690.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 376, Wert -593.6</title></circle>
<circle cx="1391.2" cy="690.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 377, Wert -592.7</title></circle>
<circle cx="1474.4" cy="690.0" r="5" fill="#33854d" stroke="#333" stroke-width="0.5"><title>Id 378, Wert -592.3</title></circle>
<circle cx="1557.6" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 379, Wert -555.3</title></circle>
<circle cx="1640.8" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 380, Wert -555.3</title></circle>
<circle cx="1724.0" cy="690.0" r="5" fill="#30874e" stroke="#333" stroke-width="0.5"><title>Id 381, Wert -584.5</title></circle>
<circle cx="1807.2" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 382, Wert -556.2</title></circle>
<circle cx="1890.4" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 383, Wert -558.2</title></circle>
<circle cx="1973.6" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 384, Wert -558.2</title></circle>
<circle cx="2056.8" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 385, Wert -558.2</title></circle>
<circle cx="2140.0" cy="690.0" r="5" fill="#288b4f" stroke="#333" stroke-width="0.5"><title>Id 386, Wert -558.2</title></circle>
<text x="1816.4" y="442.0" text-anchor="middle" font-size="12" font-weight="bold" fill="#c04040">283</text>
<text x="48" y="64.0" text-anchor="end" font-size="11" fill="#666">Gen 0</text>
<text x="48" y="154.0" text-anchor="end" font-size="11" fill="#666">Gen 1</text>
<text x="48" y="244.0" text-anchor="end" font-size="11" fill="#666">Gen 2</text>
<text x="48" y="334.0" text-anchor="end" font-size="11" fill="#666">Gen 3</text>
<text x="48" y="424.0" text-anchor="end" font-size="11" fill="#666">Gen 4</text>
<text x="48" y="514.0" text-anchor="end" font-size="11" fill="#666">Gen 5</text>
<text x="48" y="604.0" text-anchor="end" font-size="11" fill="#666">Gen 6</text>
<text x="48" y="694.0" text-anchor="end" font-size="11" fill="#666">Gen 7</text>
</svg>

After

Width:  |  Height:  |  Size: 78 KiB

+62
View File
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="650" viewBox="0 0 900 650" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="450" y="30" text-anchor="middle" font-size="16" fill="#333">Entwicklung der Loesungsfindung</text>
<line x1="60" y1="60" x2="60" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="394.0" text-anchor="end" font-size="11" fill="#666">-1093</text>
<line x1="60" y1="324.0" x2="840" y2="324.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="328.0" text-anchor="end" font-size="11" fill="#666">-986</text>
<line x1="60" y1="258.0" x2="840" y2="258.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="262.0" text-anchor="end" font-size="11" fill="#666">-878</text>
<line x1="60" y1="192.0" x2="840" y2="192.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="196.0" text-anchor="end" font-size="11" fill="#666">-770</text>
<line x1="60" y1="126.0" x2="840" y2="126.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="130.0" text-anchor="end" font-size="11" fill="#666">-663</text>
<line x1="60" y1="60.0" x2="840" y2="60.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="64.0" text-anchor="end" font-size="11" fill="#666">-555</text>
<text x="18" y="225.0" text-anchor="middle" font-size="12" fill="#333" transform="rotate(-90 18 225.0)">Wertigkeit (hoeher = besser)</text>
<polyline points="60.0,167.5 97.1,117.4 134.3,117.4 171.4,117.4 208.6,84.9 245.7,84.9 282.9,84.9 320.0,66.0 357.1,66.0 394.3,66.0 431.4,60.0 468.6,60.0 505.7,60.0 542.9,60.1 580.0,60.0 617.1,60.0 654.3,60.1 691.4,60.0 728.6,60.0 765.7,60.1 802.9,60.0 840.0,60.0" fill="none" stroke="#2f6f4f" stroke-width="2"/>
<polyline points="60.0,263.3 97.1,218.5 134.3,233.5 171.4,160.6 208.6,135.5 245.7,143.9 282.9,113.1 320.0,99.0 357.1,103.7 394.3,82.5 431.4,81.0 468.6,81.5 505.7,67.0 542.9,77.4 580.0,73.9 617.1,62.4 654.3,78.8 691.4,73.4 728.6,60.8 765.7,72.5 802.9,68.6 840.0,60.2" fill="none" stroke="#c08a2d" stroke-width="2"/>
<polyline points="60.0,390.0 97.1,350.3 134.3,390.0 171.4,190.0 208.6,193.0 245.7,193.0 282.9,125.9 320.0,142.2 357.1,142.2 394.3,93.9 431.4,105.3 468.6,105.3 505.7,75.0 542.9,101.0 580.0,101.0 617.1,66.0 654.3,99.2 691.4,99.2 728.6,62.0 765.7,94.7 802.9,94.7 840.0,60.2" fill="none" stroke="#a03030" stroke-width="2"/>
<line x1="680" y1="70" x2="704" y2="70" stroke="#2f6f4f" stroke-width="2"/>
<text x="710" y="74" font-size="11" fill="#333">beste Loesung</text>
<line x1="680" y1="88" x2="704" y2="88" stroke="#c08a2d" stroke-width="2"/>
<text x="710" y="92" font-size="11" fill="#333">Durchschnitt</text>
<line x1="680" y1="106" x2="704" y2="106" stroke="#a03030" stroke-width="2"/>
<text x="710" y="110" font-size="11" fill="#333">schlechteste Loesung</text>
<text x="450" y="428.0" text-anchor="middle" font-size="13" fill="#333">Anzahl erzeugter Verteilungen im Pool</text>
<line x1="60" y1="440.0" x2="60" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="594.0" text-anchor="end" font-size="11" fill="#666">0</text>
<line x1="60" y1="515.0" x2="840" y2="515.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="519.0" text-anchor="end" font-size="11" fill="#666">60</text>
<line x1="60" y1="440.0" x2="840" y2="440.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="444.0" text-anchor="end" font-size="11" fill="#666">120</text>
<polyline points="60.0,540.0 97.1,490.0 134.3,440.0 171.4,547.5 208.6,505.0 245.7,462.5 282.9,555.0 320.0,520.0 357.1,485.0 394.3,561.2 431.4,532.5 468.6,503.8 505.7,566.2 542.9,542.5 580.0,518.8 617.1,570.0 654.3,550.0 691.4,530.0 728.6,573.8 765.7,557.5 802.9,541.2 840.0,576.2" fill="none" stroke="#4060a0" stroke-width="2"/>
<text x="60.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">e</text>
<text x="97.1" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="134.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="171.4" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="208.6" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="245.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="282.9" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="320.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="357.1" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="394.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="431.4" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="468.6" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="505.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="542.9" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="580.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="617.1" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="654.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="691.4" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="728.6" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="765.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="802.9" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="840.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="450" y="638" text-anchor="middle" font-size="12" fill="#333">Zyklus-Aktion (Zeit)</text>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

+300
View File
@@ -0,0 +1,300 @@
Aksoy, Luca, = Hof 1, Tisch 33, Nummer 2
Aksoy, Marie, = Hof 1, Tisch 25, Nummer 4
Aksoy, Marija, = Hof 2, Tisch 59, Nummer 5
Aksoy, Michael, Dr. = Hof 2, Tisch 53, Nummer 3
Aksoy, Nadine, = Hof 1, Tisch 25, Nummer 2
Aksoy, Nicole, = Hof 2, Tisch 57, Nummer 4
Aksoy, Sergej, = Hof 1, Tisch 33, Nummer 4
Aksoy, Sofia, = Hof 1, Tisch 33, Nummer 3
Aksoy, Thomas, = Hof 1, Tisch 25, Nummer 3
Albrecht, Andreas, = Hof 1, Tisch 12, Nummer 4
Albrecht, Emre, Prof. Dr. = Hof 2, Tisch 82, Nummer 3
Albrecht, Sarah, = Hof 1, Tisch 12, Nummer 3
Albrecht, Yusuf, Prof. Dr. = Hof 1, Tisch 13, Nummer 2
Arnold, Christian, = Hof 1, Tisch 35, Nummer 3
Arnold, Jennifer, = Hof 1, Tisch 43, Nummer 2
Arnold, Jennifer, Dr. = Hof 2, Tisch 88, Nummer 3
Arnold, Leni, = Hof 1, Tisch 35, Nummer 2
Arnold, Mila, = Hof 1, Tisch 35, Nummer 4
Arnold, Nadine, = Hof 2, Tisch 65, Nummer 2
Arnold, Patrick, = Hof 1, Tisch 43, Nummer 3
Barth, Lina, = Hof 2, Tisch 74, Nummer 5
Barth, Markus, = Hof 1, Tisch 39, Nummer 2
Barth, Nadine, = Hof 2, Tisch 74, Nummer 3
Barth, Patrick, = Hof 2, Tisch 74, Nummer 2
Barth, Timo, = Hof 2, Tisch 74, Nummer 4
Bauer, Dragana, = Hof 1, Tisch 45, Nummer 4
Bauer, Yusuf, = Hof 1, Tisch 4, Nummer 4
Becker, Jan, = Hof 1, Tisch 14, Nummer 3
Becker, Marija, = Hof 2, Tisch 76, Nummer 3
Becker, Nicole, = Hof 1, Tisch 14, Nummer 2
Becker, Sandra, = Hof 1, Tisch 14, Nummer 4
Berger, Andreas, = Hof 1, Tisch 24, Nummer 2
Berger, Anton, = Hof 1, Tisch 32, Nummer 3
Berger, Jennifer, = Hof 1, Tisch 32, Nummer 2
Berger, Layla, = Hof 1, Tisch 32, Nummer 4
Berger, Nadine, Dr. = Hof 1, Tisch 26, Nummer 3
Berger, Stefan, = Hof 1, Tisch 32, Nummer 5
Berger, Svenja, = Hof 1, Tisch 24, Nummer 5
Bianchi, Jan, Dr. = Hof 1, Tisch 4, Nummer 5
Bianchi, Mia, = Hof 2, Tisch 54, Nummer 4
Bianchi, Sandra, = Hof 2, Tisch 54, Nummer 2
Bianchi, Thomas, = Hof 2, Tisch 54, Nummer 3
Bianchi, Thomas, = Hof 2, Tisch 82, Nummer 4
Braun, Christian, = Hof 1, Tisch 42, Nummer 4
Braun, Dragana, = Hof 1, Tisch 42, Nummer 3
Braun, Jan, = Hof 1, Tisch 42, Nummer 2
Braun, Julia, = Hof 1, Tisch 41, Nummer 2
Braun, Milan, = Hof 1, Tisch 41, Nummer 3
Braun, Nadine, = Hof 1, Tisch 41, Nummer 4
Busch, Emre, = Hof 2, Tisch 56, Nummer 3
Busch, Marie, = Hof 2, Tisch 56, Nummer 4
Busch, Michael, = Hof 2, Tisch 56, Nummer 5
Busch, Olga, = Hof 2, Tisch 56, Nummer 2
Busch, Patrick, = Hof 2, Tisch 64, Nummer 3
Celik, Elif, = Hof 1, Tisch 24, Nummer 4
Celik, Patrick, = Hof 1, Tisch 24, Nummer 3
Dallmann, Charlotte, = Hof 1, Tisch 7, Nummer 5
Dallmann, Heinrich, = Hof 1, Tisch 7, Nummer 2
Dallmann, Margarete, = Hof 1, Tisch 7, Nummer 3
Dallmann, Maximilian, = Hof 1, Tisch 7, Nummer 4
Demir, Sandra, Dr. = Hof 1, Tisch 28, Nummer 3
Dietrich, Dragana, Prof. Dr. = Hof 2, Tisch 53, Nummer 2
Dietrich, Jennifer, = Hof 1, Tisch 27, Nummer 2
Dietrich, Marco, = Hof 1, Tisch 27, Nummer 3
Dietrich, Sofia, = Hof 1, Tisch 27, Nummer 4
Engel, Anja, = Hof 1, Tisch 21, Nummer 3
Engel, Anton, = Hof 1, Tisch 20, Nummer 5
Engel, Julia, = Hof 1, Tisch 20, Nummer 4
Engel, Nicole, = Hof 1, Tisch 21, Nummer 2
Engel, Yusuf, = Hof 1, Tisch 21, Nummer 4
Esposito, Jan, Dr. = Hof 1, Tisch 17, Nummer 3
Esposito, Yusuf, Prof. Dr. = Hof 2, Tisch 76, Nummer 2
Frank, Dennis, = Hof 2, Tisch 88, Nummer 5
Frank, Finn, = Hof 2, Tisch 87, Nummer 4
Frank, Lena, = Hof 2, Tisch 87, Nummer 2
Frank, Marie, = Hof 2, Tisch 87, Nummer 3
Frank, Nadine, = Hof 2, Tisch 88, Nummer 4
Franke, Amira, = Hof 2, Tisch 69, Nummer 3
Franke, Julia, = Hof 2, Tisch 78, Nummer 5
Franke, Marco, = Hof 2, Tisch 69, Nummer 4
Franke, Michael, = Hof 2, Tisch 78, Nummer 4
Franke, Olga, = Hof 2, Tisch 69, Nummer 2
Freifrau von Waldeck, Antonia, = Hof 1, Tisch 6, Nummer 4
Freiherr von Waldeck, Konstantin, Dr. = Hof 1, Tisch 6, Nummer 3
Grothe, Alexander, Dr. h.c. = Hof 1, Tisch 5, Nummer 2
Grothe, Beate, = Hof 1, Tisch 5, Nummer 3
Haas, Jennifer, Dr. = Hof 1, Tisch 31, Nummer 3
Haas, Patrick, = Hof 1, Tisch 45, Nummer 2
Hansen, Giovanna, = Hof 1, Tisch 8, Nummer 2
Hansen, Markus, = Hof 1, Tisch 8, Nummer 3
Hansen, Nicole, Dr. = Hof 1, Tisch 38, Nummer 2
Hansen, Olga, = Hof 1, Tisch 8, Nummer 4
Hansen, Thomas, = Hof 1, Tisch 16, Nummer 2
Hartmann, Deniz, = Hof 2, Tisch 78, Nummer 2
Hartmann, Marija, = Hof 2, Tisch 84, Nummer 2
Hartmann, Nadine, = Hof 2, Tisch 78, Nummer 3
Hartmann, Olga, = Hof 2, Tisch 84, Nummer 4
Hartmann, Thomas, = Hof 2, Tisch 84, Nummer 3
Hoffmann, Emre, = Hof 2, Tisch 64, Nummer 4
Hoffmann, Patrick, Prof. Dr. = Hof 2, Tisch 65, Nummer 4
Hoffmann, Thomas, Dr. = Hof 2, Tisch 51, Nummer 3
Horn, Kathrin, = Hof 2, Tisch 79, Nummer 2
Horn, Layla, = Hof 2, Tisch 79, Nummer 4
Horn, Leon, = Hof 2, Tisch 79, Nummer 5
Horn, Michael, = Hof 2, Tisch 79, Nummer 3
Kaya, Christina, = Hof 2, Tisch 77, Nummer 3
Kaya, Luca, = Hof 2, Tisch 77, Nummer 2
Kaya, Nicole, = Hof 2, Tisch 77, Nummer 4
Kaya, Patrick, Dr. = Hof 1, Tisch 3, Nummer 3
Kaya, Timo, Prof. Dr. = Hof 1, Tisch 28, Nummer 2
Kessler, Ferdinand, Dr. = Hof 1, Tisch 5, Nummer 4
Kessler, Viktoria, = Hof 1, Tisch 5, Nummer 5
Klein, Emre, = Hof 1, Tisch 3, Nummer 2
Klein, Lina, = Hof 1, Tisch 18, Nummer 4
Klein, Markus, = Hof 2, Tisch 57, Nummer 5
Klein, Milan, = Hof 1, Tisch 18, Nummer 3
Klein, Olga, Dr. = Hof 2, Tisch 88, Nummer 2
Klein, Stefanie, = Hof 1, Tisch 18, Nummer 2
Koch, Emil, = Hof 2, Tisch 48, Nummer 3
Koch, Jan, = Hof 2, Tisch 49, Nummer 3
Koch, Kathrin, Dr. = Hof 2, Tisch 52, Nummer 4
Koch, Marie, = Hof 2, Tisch 49, Nummer 4
Koch, Michael, = Hof 2, Tisch 48, Nummer 2
Koch, Olga, = Hof 2, Tisch 48, Nummer 4
Koch, Sarah, = Hof 2, Tisch 49, Nummer 2
Kovac, Anja, = Hof 1, Tisch 36, Nummer 3
Kovac, Henry, = Hof 1, Tisch 36, Nummer 4
Kovac, Lena, = Hof 1, Tisch 28, Nummer 4
Kovac, Luca, = Hof 2, Tisch 62, Nummer 2
Kovac, Marco, = Hof 1, Tisch 36, Nummer 2
Kovac, Marija, = Hof 1, Tisch 36, Nummer 5
Kovac, Matthias, = Hof 2, Tisch 76, Nummer 4
Kovac, Tobias, = Hof 1, Tisch 28, Nummer 5
Kraus, Markus, = Hof 1, Tisch 11, Nummer 4
Kraus, Patrick, Dr. = Hof 2, Tisch 67, Nummer 3
Krause, Andreas, = Hof 2, Tisch 63, Nummer 2
Krause, Arda, = Hof 2, Tisch 63, Nummer 4
Krause, Christina, Dr. = Hof 1, Tisch 3, Nummer 4
Krause, Daniel, = Hof 2, Tisch 57, Nummer 3
Krause, Dragana, Dr. = Hof 2, Tisch 62, Nummer 3
Krause, Emma, = Hof 2, Tisch 63, Nummer 3
Krause, Julia, = Hof 2, Tisch 63, Nummer 5
Krause, Matthias, = Hof 2, Tisch 58, Nummer 3
Krause, Thomas, = Hof 1, Tisch 38, Nummer 3
Kuhn, Julia, Dr. = Hof 2, Tisch 52, Nummer 5
Lange, Dragana, = Hof 1, Tisch 43, Nummer 4
Lange, Jan, = Hof 1, Tisch 44, Nummer 2
Lange, Michael, = Hof 1, Tisch 43, Nummer 5
Lange, Sergej, = Hof 2, Tisch 64, Nummer 5
Lange, Sofia, = Hof 1, Tisch 44, Nummer 4
Lange, Svenja, = Hof 1, Tisch 44, Nummer 3
Lehmann, Giovanna, = Hof 1, Tisch 13, Nummer 3
Lehmann, Layla, = Hof 1, Tisch 2, Nummer 2
Lehmann, Markus, = Hof 1, Tisch 2, Nummer 5
Lehmann, Milan, = Hof 1, Tisch 13, Nummer 4
Lehmann, Nicole, = Hof 1, Tisch 2, Nummer 4
Lehmann, Patrick, = Hof 1, Tisch 26, Nummer 4
Lehmann, Thomas, = Hof 1, Tisch 2, Nummer 3
Ludwig, Aylin, Dr. = Hof 2, Tisch 67, Nummer 4
Ludwig, Elias, = Hof 1, Tisch 9, Nummer 5
Ludwig, Elif, = Hof 1, Tisch 9, Nummer 4
Ludwig, Emre, = Hof 1, Tisch 9, Nummer 3
Ludwig, Emre, Prof. Dr. = Hof 2, Tisch 57, Nummer 2
Ludwig, Giovanna, = Hof 1, Tisch 9, Nummer 2
Maier, Arda, = Hof 2, Tisch 61, Nummer 5
Maier, Christian, = Hof 2, Tisch 61, Nummer 3
Maier, Olga, = Hof 2, Tisch 61, Nummer 4
Maier, Sarah, = Hof 2, Tisch 61, Nummer 2
Neumann, Jennifer, = Hof 2, Tisch 73, Nummer 2
Neumann, Lina, = Hof 2, Tisch 73, Nummer 4
Neumann, Matteo, = Hof 2, Tisch 73, Nummer 5
Neumann, Thomas, = Hof 2, Tisch 73, Nummer 3
Nguyen, Anja, = Hof 1, Tisch 15, Nummer 2
Nguyen, Daniel, = Hof 1, Tisch 15, Nummer 3
Nguyen, Julia, = Hof 1, Tisch 16, Nummer 4
Nguyen, Sofia, = Hof 1, Tisch 15, Nummer 4
Nowak, Aylin, = Hof 1, Tisch 37, Nummer 2
Nowak, Felix, = Hof 1, Tisch 29, Nummer 2
Nowak, Kathrin, = Hof 1, Tisch 29, Nummer 5
Nowak, Lina, = Hof 1, Tisch 37, Nummer 4
Nowak, Markus, = Hof 1, Tisch 37, Nummer 3
Nowak, Noah, = Hof 1, Tisch 37, Nummer 5
Ott, Daniel, = Hof 2, Tisch 80, Nummer 5
Ott, Hannah, = Hof 2, Tisch 72, Nummer 3
Ott, Luca, = Hof 2, Tisch 71, Nummer 2
Ott, Matthias, = Hof 2, Tisch 72, Nummer 2
Ott, Melanie, = Hof 2, Tisch 80, Nummer 4
Ott, Olga, = Hof 2, Tisch 72, Nummer 4
Ott, Sergej, Prof. Dr. = Hof 1, Tisch 45, Nummer 3
Ott, Yusuf, Prof. Dr. = Hof 1, Tisch 26, Nummer 2
Peters, Christian, = Hof 1, Tisch 10, Nummer 5
Peters, Nicole, = Hof 1, Tisch 45, Nummer 5
Petrov, Giovanna, = Hof 1, Tisch 10, Nummer 2
Petrov, Kathrin, = Hof 1, Tisch 38, Nummer 4
Petrov, Kathrin, Prof. Dr. = Hof 1, Tisch 11, Nummer 2
Petrov, Matthias, = Hof 1, Tisch 39, Nummer 3
Petrov, Milan, = Hof 1, Tisch 38, Nummer 5
Petrov, Sergej, = Hof 2, Tisch 59, Nummer 3
Pohl, Dragana, = Hof 2, Tisch 75, Nummer 2
Pohl, Emre, = Hof 2, Tisch 75, Nummer 3
Pohl, Mia, = Hof 2, Tisch 75, Nummer 4
Pohl, Theo, = Hof 2, Tisch 75, Nummer 5
Polat, Kathrin, = Hof 2, Tisch 59, Nummer 4
Polat, Katrin, = Hof 2, Tisch 81, Nummer 4
Polat, Marija, = Hof 2, Tisch 65, Nummer 5
Polat, Markus, = Hof 2, Tisch 81, Nummer 3
Polat, Sarah, = Hof 2, Tisch 81, Nummer 2
Polat, Stefan, = Hof 2, Tisch 80, Nummer 3
Polat, Stefanie, = Hof 2, Tisch 80, Nummer 2
Popescu, Matthias, = Hof 1, Tisch 12, Nummer 2
Richter, Anja, = Hof 2, Tisch 50, Nummer 2
Richter, Anja, Prof. Dr. = Hof 1, Tisch 22, Nummer 2
Richter, Anton, = Hof 2, Tisch 50, Nummer 5
Richter, Greta, = Hof 2, Tisch 50, Nummer 4
Richter, Julia, Prof. Dr. = Hof 1, Tisch 31, Nummer 2
Richter, Marco, = Hof 2, Tisch 65, Nummer 3
Richter, Matthias, = Hof 2, Tisch 50, Nummer 3
Richter, Stefan, = Hof 2, Tisch 71, Nummer 4
Rossi, Emilia, = Hof 1, Tisch 40, Nummer 4
Rossi, Luca, = Hof 1, Tisch 40, Nummer 3
Rossi, Melanie, = Hof 1, Tisch 40, Nummer 2
Roth, Christian, = Hof 1, Tisch 23, Nummer 3
Roth, Julia, Prof. Dr. = Hof 1, Tisch 17, Nummer 4
Roth, Olga, = Hof 2, Tisch 82, Nummer 2
Roth, Sarah, = Hof 1, Tisch 23, Nummer 2
Roth, Sofia, = Hof 1, Tisch 23, Nummer 4
Sahin, Kathrin, = Hof 2, Tisch 60, Nummer 4
Sahin, Markus, = Hof 2, Tisch 60, Nummer 3
Sahin, Nicole, = Hof 2, Tisch 60, Nummer 2
Sahin, Patrick, = Hof 2, Tisch 60, Nummer 5
Sahin, Thomas, = Hof 1, Tisch 22, Nummer 4
Schmidt, Giovanna, = Hof 2, Tisch 85, Nummer 4
Schmidt, Marie, = Hof 2, Tisch 85, Nummer 3
Schmidt, Matthias, = Hof 2, Tisch 85, Nummer 2
Schmidt, Nicole, = Hof 1, Tisch 16, Nummer 3
Schmitt, Dennis, Prof. Dr. = Hof 2, Tisch 62, Nummer 4
Schmitt, Markus, = Hof 1, Tisch 10, Nummer 4
Schmitt, Markus, = Hof 2, Tisch 47, Nummer 3
Schmitt, Sarah, = Hof 2, Tisch 47, Nummer 2
Schmitt, Sofia, = Hof 2, Tisch 47, Nummer 4
Schmitt, Stefan, Prof. Dr. = Hof 2, Tisch 52, Nummer 2
Schwarz, Giovanna, = Hof 2, Tisch 58, Nummer 4
Seidel, Anja, Dr. = Hof 2, Tisch 51, Nummer 5
Seidel, Markus, Dr. = Hof 1, Tisch 11, Nummer 3
Seidel, Yusuf, Prof. Dr. = Hof 1, Tisch 4, Nummer 3
Seifert, Elif, = Hof 1, Tisch 20, Nummer 3
Seifert, Leni, = Hof 1, Tisch 19, Nummer 4
Seifert, Marco, Prof. Dr. = Hof 2, Tisch 58, Nummer 2
Seifert, Nicole, = Hof 1, Tisch 19, Nummer 2
Seifert, Stefanie, Dr. = Hof 1, Tisch 16, Nummer 5
Seifert, Timo, = Hof 1, Tisch 20, Nummer 2
Seifert, Yusuf, = Hof 1, Tisch 19, Nummer 3
Simon, Andreas, = Hof 2, Tisch 66, Nummer 5
Simon, Emma, = Hof 2, Tisch 66, Nummer 4
Simon, Lena, = Hof 2, Tisch 66, Nummer 2
Simon, Markus, = Hof 2, Tisch 66, Nummer 3
Simon, Svenja, = Hof 1, Tisch 13, Nummer 5
Stein, Ben, = Hof 2, Tisch 86, Nummer 4
Stein, Emilia, = Hof 2, Tisch 86, Nummer 3
Stein, Giovanna, = Hof 2, Tisch 86, Nummer 5
Stein, Markus, Prof. Dr. = Hof 1, Tisch 12, Nummer 5
Stein, Nadine, Dr. = Hof 1, Tisch 10, Nummer 3
Stein, Thomas, = Hof 2, Tisch 86, Nummer 2
Steinbach, Elisabeth, = Hof 1, Tisch 6, Nummer 2
Steinbach, Georg, = Hof 1, Tisch 6, Nummer 5
Thiel, Christina, = Hof 2, Tisch 46, Nummer 3
Thiel, Jan, Dr. = Hof 1, Tisch 22, Nummer 3
Thiel, Julia, = Hof 2, Tisch 46, Nummer 4
Thiel, Yusuf, = Hof 2, Tisch 46, Nummer 2
Tran, Marija, = Hof 2, Tisch 52, Nummer 3
Tran, Olga, = Hof 2, Tisch 51, Nummer 4
Tran, Thomas, Prof. Dr. = Hof 2, Tisch 59, Nummer 2
Wagner, Henry, = Hof 2, Tisch 68, Nummer 5
Wagner, Marco, = Hof 2, Tisch 68, Nummer 3
Wagner, Nicole, = Hof 2, Tisch 68, Nummer 2
Wagner, Sarah, = Hof 2, Tisch 68, Nummer 4
Weber, Andreas, = Hof 1, Tisch 39, Nummer 4
Weber, Julia, = Hof 1, Tisch 3, Nummer 5
Weber, Katrin, = Hof 2, Tisch 53, Nummer 4
Weber, Yusuf, = Hof 2, Tisch 67, Nummer 2
Werner, Andreas, = Hof 2, Tisch 55, Nummer 3
Werner, Dennis, Prof. Dr. = Hof 2, Tisch 51, Nummer 2
Werner, Katrin, = Hof 2, Tisch 64, Nummer 2
Werner, Luca, = Hof 2, Tisch 53, Nummer 5
Werner, Marco, = Hof 2, Tisch 55, Nummer 5
Werner, Nadine, = Hof 2, Tisch 55, Nummer 4
Werner, Sandra, = Hof 2, Tisch 55, Nummer 2
Winkler, Lena, = Hof 1, Tisch 29, Nummer 3
Winkler, Marco, = Hof 1, Tisch 4, Nummer 2
Winkler, Patrick, = Hof 1, Tisch 29, Nummer 4
Winkler, Thomas, = Hof 1, Tisch 17, Nummer 2
Wolf, Ben, = Hof 2, Tisch 83, Nummer 3
Wolf, Emma, = Hof 2, Tisch 83, Nummer 2
Wolf, Julia, = Hof 2, Tisch 83, Nummer 4
Wolf, Thomas, = Hof 2, Tisch 83, Nummer 5
Zimmermann, Jan, = Hof 2, Tisch 70, Nummer 3
Zimmermann, Markus, = Hof 2, Tisch 70, Nummer 5
Zimmermann, Mia, = Hof 2, Tisch 70, Nummer 4
Zimmermann, Patrick, = Hof 2, Tisch 71, Nummer 3
Zimmermann, Svenja, = Hof 2, Tisch 70, Nummer 2
1 Aksoy Luca = Hof 1 Tisch 33 Nummer 2
2 Aksoy Marie = Hof 1 Tisch 25 Nummer 4
3 Aksoy Marija = Hof 2 Tisch 59 Nummer 5
4 Aksoy Michael Dr. = Hof 2 Tisch 53 Nummer 3
5 Aksoy Nadine = Hof 1 Tisch 25 Nummer 2
6 Aksoy Nicole = Hof 2 Tisch 57 Nummer 4
7 Aksoy Sergej = Hof 1 Tisch 33 Nummer 4
8 Aksoy Sofia = Hof 1 Tisch 33 Nummer 3
9 Aksoy Thomas = Hof 1 Tisch 25 Nummer 3
10 Albrecht Andreas = Hof 1 Tisch 12 Nummer 4
11 Albrecht Emre Prof. Dr. = Hof 2 Tisch 82 Nummer 3
12 Albrecht Sarah = Hof 1 Tisch 12 Nummer 3
13 Albrecht Yusuf Prof. Dr. = Hof 1 Tisch 13 Nummer 2
14 Arnold Christian = Hof 1 Tisch 35 Nummer 3
15 Arnold Jennifer = Hof 1 Tisch 43 Nummer 2
16 Arnold Jennifer Dr. = Hof 2 Tisch 88 Nummer 3
17 Arnold Leni = Hof 1 Tisch 35 Nummer 2
18 Arnold Mila = Hof 1 Tisch 35 Nummer 4
19 Arnold Nadine = Hof 2 Tisch 65 Nummer 2
20 Arnold Patrick = Hof 1 Tisch 43 Nummer 3
21 Barth Lina = Hof 2 Tisch 74 Nummer 5
22 Barth Markus = Hof 1 Tisch 39 Nummer 2
23 Barth Nadine = Hof 2 Tisch 74 Nummer 3
24 Barth Patrick = Hof 2 Tisch 74 Nummer 2
25 Barth Timo = Hof 2 Tisch 74 Nummer 4
26 Bauer Dragana = Hof 1 Tisch 45 Nummer 4
27 Bauer Yusuf = Hof 1 Tisch 4 Nummer 4
28 Becker Jan = Hof 1 Tisch 14 Nummer 3
29 Becker Marija = Hof 2 Tisch 76 Nummer 3
30 Becker Nicole = Hof 1 Tisch 14 Nummer 2
31 Becker Sandra = Hof 1 Tisch 14 Nummer 4
32 Berger Andreas = Hof 1 Tisch 24 Nummer 2
33 Berger Anton = Hof 1 Tisch 32 Nummer 3
34 Berger Jennifer = Hof 1 Tisch 32 Nummer 2
35 Berger Layla = Hof 1 Tisch 32 Nummer 4
36 Berger Nadine Dr. = Hof 1 Tisch 26 Nummer 3
37 Berger Stefan = Hof 1 Tisch 32 Nummer 5
38 Berger Svenja = Hof 1 Tisch 24 Nummer 5
39 Bianchi Jan Dr. = Hof 1 Tisch 4 Nummer 5
40 Bianchi Mia = Hof 2 Tisch 54 Nummer 4
41 Bianchi Sandra = Hof 2 Tisch 54 Nummer 2
42 Bianchi Thomas = Hof 2 Tisch 54 Nummer 3
43 Bianchi Thomas = Hof 2 Tisch 82 Nummer 4
44 Braun Christian = Hof 1 Tisch 42 Nummer 4
45 Braun Dragana = Hof 1 Tisch 42 Nummer 3
46 Braun Jan = Hof 1 Tisch 42 Nummer 2
47 Braun Julia = Hof 1 Tisch 41 Nummer 2
48 Braun Milan = Hof 1 Tisch 41 Nummer 3
49 Braun Nadine = Hof 1 Tisch 41 Nummer 4
50 Busch Emre = Hof 2 Tisch 56 Nummer 3
51 Busch Marie = Hof 2 Tisch 56 Nummer 4
52 Busch Michael = Hof 2 Tisch 56 Nummer 5
53 Busch Olga = Hof 2 Tisch 56 Nummer 2
54 Busch Patrick = Hof 2 Tisch 64 Nummer 3
55 Celik Elif = Hof 1 Tisch 24 Nummer 4
56 Celik Patrick = Hof 1 Tisch 24 Nummer 3
57 Dallmann Charlotte = Hof 1 Tisch 7 Nummer 5
58 Dallmann Heinrich = Hof 1 Tisch 7 Nummer 2
59 Dallmann Margarete = Hof 1 Tisch 7 Nummer 3
60 Dallmann Maximilian = Hof 1 Tisch 7 Nummer 4
61 Demir Sandra Dr. = Hof 1 Tisch 28 Nummer 3
62 Dietrich Dragana Prof. Dr. = Hof 2 Tisch 53 Nummer 2
63 Dietrich Jennifer = Hof 1 Tisch 27 Nummer 2
64 Dietrich Marco = Hof 1 Tisch 27 Nummer 3
65 Dietrich Sofia = Hof 1 Tisch 27 Nummer 4
66 Engel Anja = Hof 1 Tisch 21 Nummer 3
67 Engel Anton = Hof 1 Tisch 20 Nummer 5
68 Engel Julia = Hof 1 Tisch 20 Nummer 4
69 Engel Nicole = Hof 1 Tisch 21 Nummer 2
70 Engel Yusuf = Hof 1 Tisch 21 Nummer 4
71 Esposito Jan Dr. = Hof 1 Tisch 17 Nummer 3
72 Esposito Yusuf Prof. Dr. = Hof 2 Tisch 76 Nummer 2
73 Frank Dennis = Hof 2 Tisch 88 Nummer 5
74 Frank Finn = Hof 2 Tisch 87 Nummer 4
75 Frank Lena = Hof 2 Tisch 87 Nummer 2
76 Frank Marie = Hof 2 Tisch 87 Nummer 3
77 Frank Nadine = Hof 2 Tisch 88 Nummer 4
78 Franke Amira = Hof 2 Tisch 69 Nummer 3
79 Franke Julia = Hof 2 Tisch 78 Nummer 5
80 Franke Marco = Hof 2 Tisch 69 Nummer 4
81 Franke Michael = Hof 2 Tisch 78 Nummer 4
82 Franke Olga = Hof 2 Tisch 69 Nummer 2
83 Freifrau von Waldeck Antonia = Hof 1 Tisch 6 Nummer 4
84 Freiherr von Waldeck Konstantin Dr. = Hof 1 Tisch 6 Nummer 3
85 Grothe Alexander Dr. h.c. = Hof 1 Tisch 5 Nummer 2
86 Grothe Beate = Hof 1 Tisch 5 Nummer 3
87 Haas Jennifer Dr. = Hof 1 Tisch 31 Nummer 3
88 Haas Patrick = Hof 1 Tisch 45 Nummer 2
89 Hansen Giovanna = Hof 1 Tisch 8 Nummer 2
90 Hansen Markus = Hof 1 Tisch 8 Nummer 3
91 Hansen Nicole Dr. = Hof 1 Tisch 38 Nummer 2
92 Hansen Olga = Hof 1 Tisch 8 Nummer 4
93 Hansen Thomas = Hof 1 Tisch 16 Nummer 2
94 Hartmann Deniz = Hof 2 Tisch 78 Nummer 2
95 Hartmann Marija = Hof 2 Tisch 84 Nummer 2
96 Hartmann Nadine = Hof 2 Tisch 78 Nummer 3
97 Hartmann Olga = Hof 2 Tisch 84 Nummer 4
98 Hartmann Thomas = Hof 2 Tisch 84 Nummer 3
99 Hoffmann Emre = Hof 2 Tisch 64 Nummer 4
100 Hoffmann Patrick Prof. Dr. = Hof 2 Tisch 65 Nummer 4
101 Hoffmann Thomas Dr. = Hof 2 Tisch 51 Nummer 3
102 Horn Kathrin = Hof 2 Tisch 79 Nummer 2
103 Horn Layla = Hof 2 Tisch 79 Nummer 4
104 Horn Leon = Hof 2 Tisch 79 Nummer 5
105 Horn Michael = Hof 2 Tisch 79 Nummer 3
106 Kaya Christina = Hof 2 Tisch 77 Nummer 3
107 Kaya Luca = Hof 2 Tisch 77 Nummer 2
108 Kaya Nicole = Hof 2 Tisch 77 Nummer 4
109 Kaya Patrick Dr. = Hof 1 Tisch 3 Nummer 3
110 Kaya Timo Prof. Dr. = Hof 1 Tisch 28 Nummer 2
111 Kessler Ferdinand Dr. = Hof 1 Tisch 5 Nummer 4
112 Kessler Viktoria = Hof 1 Tisch 5 Nummer 5
113 Klein Emre = Hof 1 Tisch 3 Nummer 2
114 Klein Lina = Hof 1 Tisch 18 Nummer 4
115 Klein Markus = Hof 2 Tisch 57 Nummer 5
116 Klein Milan = Hof 1 Tisch 18 Nummer 3
117 Klein Olga Dr. = Hof 2 Tisch 88 Nummer 2
118 Klein Stefanie = Hof 1 Tisch 18 Nummer 2
119 Koch Emil = Hof 2 Tisch 48 Nummer 3
120 Koch Jan = Hof 2 Tisch 49 Nummer 3
121 Koch Kathrin Dr. = Hof 2 Tisch 52 Nummer 4
122 Koch Marie = Hof 2 Tisch 49 Nummer 4
123 Koch Michael = Hof 2 Tisch 48 Nummer 2
124 Koch Olga = Hof 2 Tisch 48 Nummer 4
125 Koch Sarah = Hof 2 Tisch 49 Nummer 2
126 Kovac Anja = Hof 1 Tisch 36 Nummer 3
127 Kovac Henry = Hof 1 Tisch 36 Nummer 4
128 Kovac Lena = Hof 1 Tisch 28 Nummer 4
129 Kovac Luca = Hof 2 Tisch 62 Nummer 2
130 Kovac Marco = Hof 1 Tisch 36 Nummer 2
131 Kovac Marija = Hof 1 Tisch 36 Nummer 5
132 Kovac Matthias = Hof 2 Tisch 76 Nummer 4
133 Kovac Tobias = Hof 1 Tisch 28 Nummer 5
134 Kraus Markus = Hof 1 Tisch 11 Nummer 4
135 Kraus Patrick Dr. = Hof 2 Tisch 67 Nummer 3
136 Krause Andreas = Hof 2 Tisch 63 Nummer 2
137 Krause Arda = Hof 2 Tisch 63 Nummer 4
138 Krause Christina Dr. = Hof 1 Tisch 3 Nummer 4
139 Krause Daniel = Hof 2 Tisch 57 Nummer 3
140 Krause Dragana Dr. = Hof 2 Tisch 62 Nummer 3
141 Krause Emma = Hof 2 Tisch 63 Nummer 3
142 Krause Julia = Hof 2 Tisch 63 Nummer 5
143 Krause Matthias = Hof 2 Tisch 58 Nummer 3
144 Krause Thomas = Hof 1 Tisch 38 Nummer 3
145 Kuhn Julia Dr. = Hof 2 Tisch 52 Nummer 5
146 Lange Dragana = Hof 1 Tisch 43 Nummer 4
147 Lange Jan = Hof 1 Tisch 44 Nummer 2
148 Lange Michael = Hof 1 Tisch 43 Nummer 5
149 Lange Sergej = Hof 2 Tisch 64 Nummer 5
150 Lange Sofia = Hof 1 Tisch 44 Nummer 4
151 Lange Svenja = Hof 1 Tisch 44 Nummer 3
152 Lehmann Giovanna = Hof 1 Tisch 13 Nummer 3
153 Lehmann Layla = Hof 1 Tisch 2 Nummer 2
154 Lehmann Markus = Hof 1 Tisch 2 Nummer 5
155 Lehmann Milan = Hof 1 Tisch 13 Nummer 4
156 Lehmann Nicole = Hof 1 Tisch 2 Nummer 4
157 Lehmann Patrick = Hof 1 Tisch 26 Nummer 4
158 Lehmann Thomas = Hof 1 Tisch 2 Nummer 3
159 Ludwig Aylin Dr. = Hof 2 Tisch 67 Nummer 4
160 Ludwig Elias = Hof 1 Tisch 9 Nummer 5
161 Ludwig Elif = Hof 1 Tisch 9 Nummer 4
162 Ludwig Emre = Hof 1 Tisch 9 Nummer 3
163 Ludwig Emre Prof. Dr. = Hof 2 Tisch 57 Nummer 2
164 Ludwig Giovanna = Hof 1 Tisch 9 Nummer 2
165 Maier Arda = Hof 2 Tisch 61 Nummer 5
166 Maier Christian = Hof 2 Tisch 61 Nummer 3
167 Maier Olga = Hof 2 Tisch 61 Nummer 4
168 Maier Sarah = Hof 2 Tisch 61 Nummer 2
169 Neumann Jennifer = Hof 2 Tisch 73 Nummer 2
170 Neumann Lina = Hof 2 Tisch 73 Nummer 4
171 Neumann Matteo = Hof 2 Tisch 73 Nummer 5
172 Neumann Thomas = Hof 2 Tisch 73 Nummer 3
173 Nguyen Anja = Hof 1 Tisch 15 Nummer 2
174 Nguyen Daniel = Hof 1 Tisch 15 Nummer 3
175 Nguyen Julia = Hof 1 Tisch 16 Nummer 4
176 Nguyen Sofia = Hof 1 Tisch 15 Nummer 4
177 Nowak Aylin = Hof 1 Tisch 37 Nummer 2
178 Nowak Felix = Hof 1 Tisch 29 Nummer 2
179 Nowak Kathrin = Hof 1 Tisch 29 Nummer 5
180 Nowak Lina = Hof 1 Tisch 37 Nummer 4
181 Nowak Markus = Hof 1 Tisch 37 Nummer 3
182 Nowak Noah = Hof 1 Tisch 37 Nummer 5
183 Ott Daniel = Hof 2 Tisch 80 Nummer 5
184 Ott Hannah = Hof 2 Tisch 72 Nummer 3
185 Ott Luca = Hof 2 Tisch 71 Nummer 2
186 Ott Matthias = Hof 2 Tisch 72 Nummer 2
187 Ott Melanie = Hof 2 Tisch 80 Nummer 4
188 Ott Olga = Hof 2 Tisch 72 Nummer 4
189 Ott Sergej Prof. Dr. = Hof 1 Tisch 45 Nummer 3
190 Ott Yusuf Prof. Dr. = Hof 1 Tisch 26 Nummer 2
191 Peters Christian = Hof 1 Tisch 10 Nummer 5
192 Peters Nicole = Hof 1 Tisch 45 Nummer 5
193 Petrov Giovanna = Hof 1 Tisch 10 Nummer 2
194 Petrov Kathrin = Hof 1 Tisch 38 Nummer 4
195 Petrov Kathrin Prof. Dr. = Hof 1 Tisch 11 Nummer 2
196 Petrov Matthias = Hof 1 Tisch 39 Nummer 3
197 Petrov Milan = Hof 1 Tisch 38 Nummer 5
198 Petrov Sergej = Hof 2 Tisch 59 Nummer 3
199 Pohl Dragana = Hof 2 Tisch 75 Nummer 2
200 Pohl Emre = Hof 2 Tisch 75 Nummer 3
201 Pohl Mia = Hof 2 Tisch 75 Nummer 4
202 Pohl Theo = Hof 2 Tisch 75 Nummer 5
203 Polat Kathrin = Hof 2 Tisch 59 Nummer 4
204 Polat Katrin = Hof 2 Tisch 81 Nummer 4
205 Polat Marija = Hof 2 Tisch 65 Nummer 5
206 Polat Markus = Hof 2 Tisch 81 Nummer 3
207 Polat Sarah = Hof 2 Tisch 81 Nummer 2
208 Polat Stefan = Hof 2 Tisch 80 Nummer 3
209 Polat Stefanie = Hof 2 Tisch 80 Nummer 2
210 Popescu Matthias = Hof 1 Tisch 12 Nummer 2
211 Richter Anja = Hof 2 Tisch 50 Nummer 2
212 Richter Anja Prof. Dr. = Hof 1 Tisch 22 Nummer 2
213 Richter Anton = Hof 2 Tisch 50 Nummer 5
214 Richter Greta = Hof 2 Tisch 50 Nummer 4
215 Richter Julia Prof. Dr. = Hof 1 Tisch 31 Nummer 2
216 Richter Marco = Hof 2 Tisch 65 Nummer 3
217 Richter Matthias = Hof 2 Tisch 50 Nummer 3
218 Richter Stefan = Hof 2 Tisch 71 Nummer 4
219 Rossi Emilia = Hof 1 Tisch 40 Nummer 4
220 Rossi Luca = Hof 1 Tisch 40 Nummer 3
221 Rossi Melanie = Hof 1 Tisch 40 Nummer 2
222 Roth Christian = Hof 1 Tisch 23 Nummer 3
223 Roth Julia Prof. Dr. = Hof 1 Tisch 17 Nummer 4
224 Roth Olga = Hof 2 Tisch 82 Nummer 2
225 Roth Sarah = Hof 1 Tisch 23 Nummer 2
226 Roth Sofia = Hof 1 Tisch 23 Nummer 4
227 Sahin Kathrin = Hof 2 Tisch 60 Nummer 4
228 Sahin Markus = Hof 2 Tisch 60 Nummer 3
229 Sahin Nicole = Hof 2 Tisch 60 Nummer 2
230 Sahin Patrick = Hof 2 Tisch 60 Nummer 5
231 Sahin Thomas = Hof 1 Tisch 22 Nummer 4
232 Schmidt Giovanna = Hof 2 Tisch 85 Nummer 4
233 Schmidt Marie = Hof 2 Tisch 85 Nummer 3
234 Schmidt Matthias = Hof 2 Tisch 85 Nummer 2
235 Schmidt Nicole = Hof 1 Tisch 16 Nummer 3
236 Schmitt Dennis Prof. Dr. = Hof 2 Tisch 62 Nummer 4
237 Schmitt Markus = Hof 1 Tisch 10 Nummer 4
238 Schmitt Markus = Hof 2 Tisch 47 Nummer 3
239 Schmitt Sarah = Hof 2 Tisch 47 Nummer 2
240 Schmitt Sofia = Hof 2 Tisch 47 Nummer 4
241 Schmitt Stefan Prof. Dr. = Hof 2 Tisch 52 Nummer 2
242 Schwarz Giovanna = Hof 2 Tisch 58 Nummer 4
243 Seidel Anja Dr. = Hof 2 Tisch 51 Nummer 5
244 Seidel Markus Dr. = Hof 1 Tisch 11 Nummer 3
245 Seidel Yusuf Prof. Dr. = Hof 1 Tisch 4 Nummer 3
246 Seifert Elif = Hof 1 Tisch 20 Nummer 3
247 Seifert Leni = Hof 1 Tisch 19 Nummer 4
248 Seifert Marco Prof. Dr. = Hof 2 Tisch 58 Nummer 2
249 Seifert Nicole = Hof 1 Tisch 19 Nummer 2
250 Seifert Stefanie Dr. = Hof 1 Tisch 16 Nummer 5
251 Seifert Timo = Hof 1 Tisch 20 Nummer 2
252 Seifert Yusuf = Hof 1 Tisch 19 Nummer 3
253 Simon Andreas = Hof 2 Tisch 66 Nummer 5
254 Simon Emma = Hof 2 Tisch 66 Nummer 4
255 Simon Lena = Hof 2 Tisch 66 Nummer 2
256 Simon Markus = Hof 2 Tisch 66 Nummer 3
257 Simon Svenja = Hof 1 Tisch 13 Nummer 5
258 Stein Ben = Hof 2 Tisch 86 Nummer 4
259 Stein Emilia = Hof 2 Tisch 86 Nummer 3
260 Stein Giovanna = Hof 2 Tisch 86 Nummer 5
261 Stein Markus Prof. Dr. = Hof 1 Tisch 12 Nummer 5
262 Stein Nadine Dr. = Hof 1 Tisch 10 Nummer 3
263 Stein Thomas = Hof 2 Tisch 86 Nummer 2
264 Steinbach Elisabeth = Hof 1 Tisch 6 Nummer 2
265 Steinbach Georg = Hof 1 Tisch 6 Nummer 5
266 Thiel Christina = Hof 2 Tisch 46 Nummer 3
267 Thiel Jan Dr. = Hof 1 Tisch 22 Nummer 3
268 Thiel Julia = Hof 2 Tisch 46 Nummer 4
269 Thiel Yusuf = Hof 2 Tisch 46 Nummer 2
270 Tran Marija = Hof 2 Tisch 52 Nummer 3
271 Tran Olga = Hof 2 Tisch 51 Nummer 4
272 Tran Thomas Prof. Dr. = Hof 2 Tisch 59 Nummer 2
273 Wagner Henry = Hof 2 Tisch 68 Nummer 5
274 Wagner Marco = Hof 2 Tisch 68 Nummer 3
275 Wagner Nicole = Hof 2 Tisch 68 Nummer 2
276 Wagner Sarah = Hof 2 Tisch 68 Nummer 4
277 Weber Andreas = Hof 1 Tisch 39 Nummer 4
278 Weber Julia = Hof 1 Tisch 3 Nummer 5
279 Weber Katrin = Hof 2 Tisch 53 Nummer 4
280 Weber Yusuf = Hof 2 Tisch 67 Nummer 2
281 Werner Andreas = Hof 2 Tisch 55 Nummer 3
282 Werner Dennis Prof. Dr. = Hof 2 Tisch 51 Nummer 2
283 Werner Katrin = Hof 2 Tisch 64 Nummer 2
284 Werner Luca = Hof 2 Tisch 53 Nummer 5
285 Werner Marco = Hof 2 Tisch 55 Nummer 5
286 Werner Nadine = Hof 2 Tisch 55 Nummer 4
287 Werner Sandra = Hof 2 Tisch 55 Nummer 2
288 Winkler Lena = Hof 1 Tisch 29 Nummer 3
289 Winkler Marco = Hof 1 Tisch 4 Nummer 2
290 Winkler Patrick = Hof 1 Tisch 29 Nummer 4
291 Winkler Thomas = Hof 1 Tisch 17 Nummer 2
292 Wolf Ben = Hof 2 Tisch 83 Nummer 3
293 Wolf Emma = Hof 2 Tisch 83 Nummer 2
294 Wolf Julia = Hof 2 Tisch 83 Nummer 4
295 Wolf Thomas = Hof 2 Tisch 83 Nummer 5
296 Zimmermann Jan = Hof 2 Tisch 70 Nummer 3
297 Zimmermann Markus = Hof 2 Tisch 70 Nummer 5
298 Zimmermann Mia = Hof 2 Tisch 70 Nummer 4
299 Zimmermann Patrick = Hof 2 Tisch 71 Nummer 3
300 Zimmermann Svenja = Hof 2 Tisch 70 Nummer 2
+682
View File
@@ -0,0 +1,682 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="2476.05" height="466.676" viewBox="0 0 2476.05 466.676">
<rect width="100%" height="100%" fill="white"/>
<polyline points="187.67,324.673 233.338,416.009" fill="none" stroke="#e6194b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="964.02,50.6676 872.685,50.6676" fill="none" stroke="#4363d8" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="553.011,142.003 461.676,142.003" fill="none" stroke="#42d4f4" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="735.682,142.003 836.351,132.669" fill="none" stroke="#bfef45" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="918.352,142.003 817.683,151.337" fill="none" stroke="#fabed4" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="416.009,233.338 370.341,324.673" fill="none" stroke="#9a6324" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="553.011,324.673 608.013,406.675" fill="none" stroke="#000075" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="416.009,416.009 507.344,416.009" fill="none" stroke="#3cb44b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="690.014,416.009 589.345,425.342" fill="none" stroke="#4363d8" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="1694.7,50.6676 1786.04,50.6676" fill="none" stroke="#42d4f4" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="1649.03,142.003 1603.37,233.338" fill="none" stroke="#bfef45" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="2014.38,142.003 1968.71,233.338" fill="none" stroke="#fabed4" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="1786.04,233.338 1822.37,334.007" fill="none" stroke="#469990" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="2060.04,233.338 2005.04,334.007" fill="none" stroke="#dcbeff" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="2105.71,324.673 2023.71,315.34" fill="none" stroke="#aaffc3" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="2197.05,324.673 2160.71,406.675" fill="none" stroke="#000075" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="1786.04,416.009 1841.04,315.34" fill="none" stroke="#e6194b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="2060.04,416.009 2142.04,425.342" fill="none" stroke="#4363d8" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="142.003,50.6676 197.004,151.337" fill="none" stroke="#f58231" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="239.561,50.6676 324.673,50.6676" fill="none" stroke="#911eb4" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="315.34,224.004 279.006,324.673" fill="none" stroke="#dcbeff" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="680.68,242.672 644.347,324.673" fill="none" stroke="#aaffc3" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="772.016,224.004 735.682,324.673" fill="none" stroke="#000075" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="836.351,315.34 781.35,416.009" fill="none" stroke="#3cb44b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="2060.04,50.6676 2142.04,60.0014" fill="none" stroke="#42d4f4" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<polyline points="2160.71,41.3338 2197.05,142.003" fill="none" stroke="#f032e6" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<circle cx="50.6676" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<ellipse cx="50.6676" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="50.6676" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">1</text>
<text x="50.6676" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="872.685" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<ellipse cx="872.685" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="872.685" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">30</text>
<text x="872.685" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="461.676" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<ellipse cx="461.676" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="461.676" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">34</text>
<text x="461.676" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="187.67" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="7" data-gruppe="Lehrstuhl Thermodynamik" data-name="Prof. Dr. Julia Richter" cx="187.67" cy="306.006" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Prof. Dr. Julia Richter — Lehrstuhl Thermodynamik</title></circle>
<circle class="person" data-gid="7" data-gruppe="Lehrstuhl Thermodynamik" data-name="Dr. Jennifer Haas" cx="187.67" cy="343.341" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Dr. Jennifer Haas — Lehrstuhl Thermodynamik</title></circle>
<ellipse cx="187.67" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="187.67" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">31</text>
<text x="187.67" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="690.014" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="53" data-gruppe="Familie Hansen (Studierenden-Familie 33)" data-name="Giovanna Hansen" cx="690.014" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Giovanna Hansen — Familie Hansen (Studierenden-Familie 33)</title></circle>
<circle class="person" data-gid="53" data-gruppe="Familie Hansen (Studierenden-Familie 33)" data-name="Markus Hansen" cx="706.181" cy="60.0014" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Markus Hansen — Familie Hansen (Studierenden-Familie 33)</title></circle>
<circle class="person" data-gid="53" data-gruppe="Familie Hansen (Studierenden-Familie 33)" data-name="Olga Hansen" cx="673.848" cy="60.0014" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Olga Hansen — Familie Hansen (Studierenden-Familie 33)</title></circle>
<ellipse cx="690.014" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="690.014" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">8</text>
<text x="690.014" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="964.02" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="16" data-gruppe="Lehrstuhl Mathematik" data-name="Prof. Dr. Kathrin Petrov" cx="964.02" cy="32" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Prof. Dr. Kathrin Petrov — Lehrstuhl Mathematik</title></circle>
<circle class="person" data-gid="16" data-gruppe="Lehrstuhl Mathematik" data-name="Dr. Markus Seidel" cx="980.187" cy="60.0014" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Dr. Markus Seidel — Lehrstuhl Mathematik</title></circle>
<circle class="person" data-gid="16" data-gruppe="Lehrstuhl Mathematik" data-name="Markus Kraus" cx="947.853" cy="60.0014" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Markus Kraus — Lehrstuhl Mathematik</title></circle>
<ellipse cx="964.02" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="964.02" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">11</text>
<text x="964.02" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="279.006" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="15" data-gruppe="Familie Becker (Studierenden-Familie 8)" data-name="Nicole Becker" cx="279.006" cy="123.335" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Nicole Becker — Familie Becker (Studierenden-Familie 8)</title></circle>
<circle class="person" data-gid="15" data-gruppe="Familie Becker (Studierenden-Familie 8)" data-name="Jan Becker" cx="295.172" cy="151.337" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Jan Becker — Familie Becker (Studierenden-Familie 8)</title></circle>
<circle class="person" data-gid="15" data-gruppe="Familie Becker (Studierenden-Familie 8)" data-name="Sandra Becker" cx="262.839" cy="151.337" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Sandra Becker — Familie Becker (Studierenden-Familie 8)</title></circle>
<ellipse cx="279.006" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="279.006" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">14</text>
<text x="279.006" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="370.341" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="17" data-gruppe="Familie Nguyen (Studierenden-Familie 9)" data-name="Anja Nguyen" cx="370.341" cy="123.335" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Anja Nguyen — Familie Nguyen (Studierenden-Familie 9)</title></circle>
<circle class="person" data-gid="17" data-gruppe="Familie Nguyen (Studierenden-Familie 9)" data-name="Daniel Nguyen" cx="386.508" cy="151.337" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Daniel Nguyen — Familie Nguyen (Studierenden-Familie 9)</title></circle>
<circle class="person" data-gid="17" data-gruppe="Familie Nguyen (Studierenden-Familie 9)" data-name="Sofia Nguyen" cx="354.174" cy="151.337" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Sofia Nguyen — Familie Nguyen (Studierenden-Familie 9)</title></circle>
<ellipse cx="370.341" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="370.341" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">15</text>
<text x="370.341" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="553.011" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="14" data-gruppe="Institut fuer Elektrotechnik" data-name="Thomas Winkler" cx="553.011" cy="123.335" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Thomas Winkler — Institut fuer Elektrotechnik</title></circle>
<circle class="person" data-gid="14" data-gruppe="Institut fuer Elektrotechnik" data-name="Dr. Jan Esposito" cx="569.178" cy="151.337" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Dr. Jan Esposito — Institut fuer Elektrotechnik</title></circle>
<circle class="person" data-gid="14" data-gruppe="Institut fuer Elektrotechnik" data-name="Prof. Dr. Julia Roth" cx="536.845" cy="151.337" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Prof. Dr. Julia Roth — Institut fuer Elektrotechnik</title></circle>
<ellipse cx="553.011" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="553.011" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">17</text>
<text x="553.011" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="644.347" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="19" data-gruppe="Familie Klein (Studierenden-Familie 11)" data-name="Stefanie Klein" cx="644.347" cy="123.335" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Stefanie Klein — Familie Klein (Studierenden-Familie 11)</title></circle>
<circle class="person" data-gid="19" data-gruppe="Familie Klein (Studierenden-Familie 11)" data-name="Milan Klein" cx="660.513" cy="151.337" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Milan Klein — Familie Klein (Studierenden-Familie 11)</title></circle>
<circle class="person" data-gid="19" data-gruppe="Familie Klein (Studierenden-Familie 11)" data-name="Lina Klein" cx="628.18" cy="151.337" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Lina Klein — Familie Klein (Studierenden-Familie 11)</title></circle>
<ellipse cx="644.347" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="644.347" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">18</text>
<text x="644.347" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="735.682" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="3" data-gruppe="Familie Seifert (Studierenden-Familie 3)" data-name="Nicole Seifert" cx="735.682" cy="123.335" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Nicole Seifert — Familie Seifert (Studierenden-Familie 3)</title></circle>
<circle class="person" data-gid="3" data-gruppe="Familie Seifert (Studierenden-Familie 3)" data-name="Yusuf Seifert" cx="751.849" cy="151.337" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Yusuf Seifert — Familie Seifert (Studierenden-Familie 3)</title></circle>
<circle class="person" data-gid="3" data-gruppe="Familie Seifert (Studierenden-Familie 3)" data-name="Leni Seifert" cx="719.515" cy="151.337" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Leni Seifert — Familie Seifert (Studierenden-Familie 3)</title></circle>
<ellipse cx="735.682" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="735.682" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">19</text>
<text x="735.682" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="918.352" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="22" data-gruppe="Familie Engel (Studierenden-Familie 13)" data-name="Nicole Engel" cx="918.352" cy="123.335" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Nicole Engel — Familie Engel (Studierenden-Familie 13)</title></circle>
<circle class="person" data-gid="22" data-gruppe="Familie Engel (Studierenden-Familie 13)" data-name="Anja Engel" cx="934.519" cy="151.337" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Anja Engel — Familie Engel (Studierenden-Familie 13)</title></circle>
<circle class="person" data-gid="22" data-gruppe="Familie Engel (Studierenden-Familie 13)" data-name="Yusuf Engel" cx="902.186" cy="151.337" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Yusuf Engel — Familie Engel (Studierenden-Familie 13)</title></circle>
<ellipse cx="918.352" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="918.352" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">21</text>
<text x="918.352" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="142.003" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="32" data-gruppe="Doktorandenrunde Robotik" data-name="Prof. Dr. Anja Richter" cx="142.003" cy="214.67" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Prof. Dr. Anja Richter — Doktorandenrunde Robotik</title></circle>
<circle class="person" data-gid="32" data-gruppe="Doktorandenrunde Robotik" data-name="Dr. Jan Thiel" cx="158.169" cy="242.672" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Dr. Jan Thiel — Doktorandenrunde Robotik</title></circle>
<circle class="person" data-gid="32" data-gruppe="Doktorandenrunde Robotik" data-name="Thomas Sahin" cx="125.836" cy="242.672" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Thomas Sahin — Doktorandenrunde Robotik</title></circle>
<ellipse cx="142.003" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="142.003" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">22</text>
<text x="142.003" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="233.338" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="28" data-gruppe="Familie Roth (Studierenden-Familie 16)" data-name="Sarah Roth" cx="233.338" cy="214.67" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Sarah Roth — Familie Roth (Studierenden-Familie 16)</title></circle>
<circle class="person" data-gid="28" data-gruppe="Familie Roth (Studierenden-Familie 16)" data-name="Christian Roth" cx="249.505" cy="242.672" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Christian Roth — Familie Roth (Studierenden-Familie 16)</title></circle>
<circle class="person" data-gid="28" data-gruppe="Familie Roth (Studierenden-Familie 16)" data-name="Sofia Roth" cx="217.171" cy="242.672" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Sofia Roth — Familie Roth (Studierenden-Familie 16)</title></circle>
<ellipse cx="233.338" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="233.338" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">23</text>
<text x="233.338" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="416.009" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="52" data-gruppe="Familie Aksoy (Studierenden-Familie 32)" data-name="Nadine Aksoy" cx="416.009" cy="214.67" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Nadine Aksoy — Familie Aksoy (Studierenden-Familie 32)</title></circle>
<circle class="person" data-gid="52" data-gruppe="Familie Aksoy (Studierenden-Familie 32)" data-name="Thomas Aksoy" cx="432.175" cy="242.672" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Thomas Aksoy — Familie Aksoy (Studierenden-Familie 32)</title></circle>
<circle class="person" data-gid="52" data-gruppe="Familie Aksoy (Studierenden-Familie 32)" data-name="Marie Aksoy" cx="399.842" cy="242.672" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Marie Aksoy — Familie Aksoy (Studierenden-Familie 32)</title></circle>
<ellipse cx="416.009" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="416.009" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">25</text>
<text x="416.009" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="507.344" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="37" data-gruppe="Institut fuer Luftfahrttechnik" data-name="Prof. Dr. Yusuf Ott" cx="507.344" cy="214.67" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Prof. Dr. Yusuf Ott — Institut fuer Luftfahrttechnik</title></circle>
<circle class="person" data-gid="37" data-gruppe="Institut fuer Luftfahrttechnik" data-name="Dr. Nadine Berger" cx="523.51" cy="242.672" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Dr. Nadine Berger — Institut fuer Luftfahrttechnik</title></circle>
<circle class="person" data-gid="37" data-gruppe="Institut fuer Luftfahrttechnik" data-name="Patrick Lehmann" cx="491.177" cy="242.672" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Patrick Lehmann — Institut fuer Luftfahrttechnik</title></circle>
<ellipse cx="507.344" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="507.344" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">26</text>
<text x="507.344" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="598.679" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="39" data-gruppe="Familie Dietrich (Studierenden-Familie 19)" data-name="Jennifer Dietrich" cx="598.679" cy="214.67" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Jennifer Dietrich — Familie Dietrich (Studierenden-Familie 19)</title></circle>
<circle class="person" data-gid="39" data-gruppe="Familie Dietrich (Studierenden-Familie 19)" data-name="Marco Dietrich" cx="614.846" cy="242.672" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Marco Dietrich — Familie Dietrich (Studierenden-Familie 19)</title></circle>
<circle class="person" data-gid="39" data-gruppe="Familie Dietrich (Studierenden-Familie 19)" data-name="Sofia Dietrich" cx="582.512" cy="242.672" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Sofia Dietrich — Familie Dietrich (Studierenden-Familie 19)</title></circle>
<ellipse cx="598.679" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="598.679" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">27</text>
<text x="598.679" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="370.341" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="52" data-gruppe="Familie Aksoy (Studierenden-Familie 32)" data-name="Luca Aksoy" cx="370.341" cy="306.006" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Luca Aksoy — Familie Aksoy (Studierenden-Familie 32)</title></circle>
<circle class="person" data-gid="52" data-gruppe="Familie Aksoy (Studierenden-Familie 32)" data-name="Sofia Aksoy" cx="386.508" cy="334.007" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Sofia Aksoy — Familie Aksoy (Studierenden-Familie 32)</title></circle>
<circle class="person" data-gid="52" data-gruppe="Familie Aksoy (Studierenden-Familie 32)" data-name="Sergej Aksoy" cx="354.174" cy="334.007" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Sergej Aksoy — Familie Aksoy (Studierenden-Familie 32)</title></circle>
<ellipse cx="370.341" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="370.341" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">33</text>
<text x="370.341" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="553.011" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="2" data-gruppe="Familie Arnold (Studierenden-Familie 2)" data-name="Leni Arnold" cx="553.011" cy="306.006" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Leni Arnold — Familie Arnold (Studierenden-Familie 2)</title></circle>
<circle class="person" data-gid="2" data-gruppe="Familie Arnold (Studierenden-Familie 2)" data-name="Christian Arnold" cx="569.178" cy="334.007" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Christian Arnold — Familie Arnold (Studierenden-Familie 2)</title></circle>
<circle class="person" data-gid="2" data-gruppe="Familie Arnold (Studierenden-Familie 2)" data-name="Mila Arnold" cx="536.845" cy="334.007" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Mila Arnold — Familie Arnold (Studierenden-Familie 2)</title></circle>
<ellipse cx="553.011" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="553.011" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">35</text>
<text x="553.011" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="233.338" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="7" data-gruppe="Lehrstuhl Thermodynamik" data-name="Markus Barth" cx="233.338" cy="397.341" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Markus Barth — Lehrstuhl Thermodynamik</title></circle>
<circle class="person" data-gid="7" data-gruppe="Lehrstuhl Thermodynamik" data-name="Matthias Petrov" cx="249.505" cy="425.342" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Matthias Petrov — Lehrstuhl Thermodynamik</title></circle>
<circle class="person" data-gid="7" data-gruppe="Lehrstuhl Thermodynamik" data-name="Andreas Weber" cx="217.171" cy="425.342" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Andreas Weber — Lehrstuhl Thermodynamik</title></circle>
<ellipse cx="233.338" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="233.338" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">39</text>
<text x="233.338" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="324.673" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="43" data-gruppe="Familie Rossi (Studierenden-Familie 23)" data-name="Melanie Rossi" cx="324.673" cy="397.341" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Melanie Rossi — Familie Rossi (Studierenden-Familie 23)</title></circle>
<circle class="person" data-gid="43" data-gruppe="Familie Rossi (Studierenden-Familie 23)" data-name="Luca Rossi" cx="340.84" cy="425.342" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Luca Rossi — Familie Rossi (Studierenden-Familie 23)</title></circle>
<circle class="person" data-gid="43" data-gruppe="Familie Rossi (Studierenden-Familie 23)" data-name="Emilia Rossi" cx="308.507" cy="425.342" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Emilia Rossi — Familie Rossi (Studierenden-Familie 23)</title></circle>
<ellipse cx="324.673" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="324.673" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">40</text>
<text x="324.673" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="416.009" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="44" data-gruppe="Familie Braun (Studierenden-Familie 24)" data-name="Julia Braun" cx="416.009" cy="397.341" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Julia Braun — Familie Braun (Studierenden-Familie 24)</title></circle>
<circle class="person" data-gid="44" data-gruppe="Familie Braun (Studierenden-Familie 24)" data-name="Milan Braun" cx="432.175" cy="425.342" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Milan Braun — Familie Braun (Studierenden-Familie 24)</title></circle>
<circle class="person" data-gid="44" data-gruppe="Familie Braun (Studierenden-Familie 24)" data-name="Nadine Braun" cx="399.842" cy="425.342" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Nadine Braun — Familie Braun (Studierenden-Familie 24)</title></circle>
<ellipse cx="416.009" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="416.009" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">41</text>
<text x="416.009" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="507.344" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="44" data-gruppe="Familie Braun (Studierenden-Familie 24)" data-name="Jan Braun" cx="507.344" cy="397.341" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Jan Braun — Familie Braun (Studierenden-Familie 24)</title></circle>
<circle class="person" data-gid="44" data-gruppe="Familie Braun (Studierenden-Familie 24)" data-name="Dragana Braun" cx="523.51" cy="425.342" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Dragana Braun — Familie Braun (Studierenden-Familie 24)</title></circle>
<circle class="person" data-gid="44" data-gruppe="Familie Braun (Studierenden-Familie 24)" data-name="Christian Braun" cx="491.177" cy="425.342" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Christian Braun — Familie Braun (Studierenden-Familie 24)</title></circle>
<ellipse cx="507.344" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="507.344" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">42</text>
<text x="507.344" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="690.014" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="64" data-gruppe="Familie Lange (Studierenden-Familie 44)" data-name="Jan Lange" cx="690.014" cy="397.341" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Jan Lange — Familie Lange (Studierenden-Familie 44)</title></circle>
<circle class="person" data-gid="64" data-gruppe="Familie Lange (Studierenden-Familie 44)" data-name="Svenja Lange" cx="706.181" cy="425.342" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Svenja Lange — Familie Lange (Studierenden-Familie 44)</title></circle>
<circle class="person" data-gid="64" data-gruppe="Familie Lange (Studierenden-Familie 44)" data-name="Sofia Lange" cx="673.848" cy="425.342" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Sofia Lange — Familie Lange (Studierenden-Familie 44)</title></circle>
<ellipse cx="690.014" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="690.014" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">44</text>
<text x="690.014" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1512.03" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="40" data-gruppe="Familie Thiel (Studierenden-Familie 20)" data-name="Yusuf Thiel" cx="1512.03" cy="32" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Yusuf Thiel — Familie Thiel (Studierenden-Familie 20)</title></circle>
<circle class="person" data-gid="40" data-gruppe="Familie Thiel (Studierenden-Familie 20)" data-name="Christina Thiel" cx="1528.2" cy="60.0014" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Christina Thiel — Familie Thiel (Studierenden-Familie 20)</title></circle>
<circle class="person" data-gid="40" data-gruppe="Familie Thiel (Studierenden-Familie 20)" data-name="Julia Thiel" cx="1495.86" cy="60.0014" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Julia Thiel — Familie Thiel (Studierenden-Familie 20)</title></circle>
<ellipse cx="1512.03" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1512.03" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">46</text>
<text x="1512.03" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1603.37" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="41" data-gruppe="Familie Schmitt (Studierenden-Familie 21)" data-name="Sarah Schmitt" cx="1603.37" cy="32" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Sarah Schmitt — Familie Schmitt (Studierenden-Familie 21)</title></circle>
<circle class="person" data-gid="41" data-gruppe="Familie Schmitt (Studierenden-Familie 21)" data-name="Markus Schmitt" cx="1619.53" cy="60.0014" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Markus Schmitt — Familie Schmitt (Studierenden-Familie 21)</title></circle>
<circle class="person" data-gid="41" data-gruppe="Familie Schmitt (Studierenden-Familie 21)" data-name="Sofia Schmitt" cx="1587.2" cy="60.0014" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Sofia Schmitt — Familie Schmitt (Studierenden-Familie 21)</title></circle>
<ellipse cx="1603.37" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1603.37" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">47</text>
<text x="1603.37" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1694.7" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="33" data-gruppe="Familie Koch (Studierenden-Familie 17)" data-name="Michael Koch" cx="1694.7" cy="32" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Michael Koch — Familie Koch (Studierenden-Familie 17)</title></circle>
<circle class="person" data-gid="33" data-gruppe="Familie Koch (Studierenden-Familie 17)" data-name="Emil Koch" cx="1710.87" cy="60.0014" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Emil Koch — Familie Koch (Studierenden-Familie 17)</title></circle>
<circle class="person" data-gid="33" data-gruppe="Familie Koch (Studierenden-Familie 17)" data-name="Olga Koch" cx="1678.54" cy="60.0014" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Olga Koch — Familie Koch (Studierenden-Familie 17)</title></circle>
<ellipse cx="1694.7" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1694.7" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">48</text>
<text x="1694.7" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1786.04" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="33" data-gruppe="Familie Koch (Studierenden-Familie 17)" data-name="Sarah Koch" cx="1786.04" cy="32" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Sarah Koch — Familie Koch (Studierenden-Familie 17)</title></circle>
<circle class="person" data-gid="33" data-gruppe="Familie Koch (Studierenden-Familie 17)" data-name="Jan Koch" cx="1802.2" cy="60.0014" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Jan Koch — Familie Koch (Studierenden-Familie 17)</title></circle>
<circle class="person" data-gid="33" data-gruppe="Familie Koch (Studierenden-Familie 17)" data-name="Marie Koch" cx="1769.87" cy="60.0014" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Marie Koch — Familie Koch (Studierenden-Familie 17)</title></circle>
<ellipse cx="1786.04" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1786.04" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">49</text>
<text x="1786.04" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2242.71" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="1" data-gruppe="Familie Bianchi (Studierenden-Familie 1)" data-name="Sandra Bianchi" cx="2242.71" cy="32" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Sandra Bianchi — Familie Bianchi (Studierenden-Familie 1)</title></circle>
<circle class="person" data-gid="1" data-gruppe="Familie Bianchi (Studierenden-Familie 1)" data-name="Thomas Bianchi" cx="2258.88" cy="60.0014" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Thomas Bianchi — Familie Bianchi (Studierenden-Familie 1)</title></circle>
<circle class="person" data-gid="1" data-gruppe="Familie Bianchi (Studierenden-Familie 1)" data-name="Mia Bianchi" cx="2226.55" cy="60.0014" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Mia Bianchi — Familie Bianchi (Studierenden-Familie 1)</title></circle>
<ellipse cx="2242.71" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2242.71" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">54</text>
<text x="2242.71" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1649.03" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="29" data-gruppe="Institut fuer Bauingenieurwesen" data-name="Prof. Dr. Marco Seifert" cx="1649.03" cy="123.335" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Prof. Dr. Marco Seifert — Institut fuer Bauingenieurwesen</title></circle>
<circle class="person" data-gid="29" data-gruppe="Institut fuer Bauingenieurwesen" data-name="Matthias Krause" cx="1665.2" cy="151.337" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Matthias Krause — Institut fuer Bauingenieurwesen</title></circle>
<circle class="person" data-gid="29" data-gruppe="Institut fuer Bauingenieurwesen" data-name="Giovanna Schwarz" cx="1632.87" cy="151.337" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Giovanna Schwarz — Institut fuer Bauingenieurwesen</title></circle>
<ellipse cx="1649.03" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1649.03" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">58</text>
<text x="1649.03" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2014.38" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="24" data-gruppe="Institut fuer Chemie" data-name="Luca Kovac" cx="2014.38" cy="123.335" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Luca Kovac — Institut fuer Chemie</title></circle>
<circle class="person" data-gid="24" data-gruppe="Institut fuer Chemie" data-name="Dr. Dragana Krause" cx="2030.54" cy="151.337" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Dr. Dragana Krause — Institut fuer Chemie</title></circle>
<circle class="person" data-gid="24" data-gruppe="Institut fuer Chemie" data-name="Prof. Dr. Dennis Schmitt" cx="1998.21" cy="151.337" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Prof. Dr. Dennis Schmitt — Institut fuer Chemie</title></circle>
<ellipse cx="2014.38" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2014.38" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">62</text>
<text x="2014.38" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1603.37" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="29" data-gruppe="Institut fuer Bauingenieurwesen" data-name="Yusuf Weber" cx="1603.37" cy="214.67" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Yusuf Weber — Institut fuer Bauingenieurwesen</title></circle>
<circle class="person" data-gid="29" data-gruppe="Institut fuer Bauingenieurwesen" data-name="Dr. Patrick Kraus" cx="1619.53" cy="242.672" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Dr. Patrick Kraus — Institut fuer Bauingenieurwesen</title></circle>
<circle class="person" data-gid="29" data-gruppe="Institut fuer Bauingenieurwesen" data-name="Dr. Aylin Ludwig" cx="1587.2" cy="242.672" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Dr. Aylin Ludwig — Institut fuer Bauingenieurwesen</title></circle>
<ellipse cx="1603.37" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1603.37" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">67</text>
<text x="1603.37" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1786.04" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="55" data-gruppe="Familie Franke (Studierenden-Familie 35)" data-name="Olga Franke" cx="1786.04" cy="214.67" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Olga Franke — Familie Franke (Studierenden-Familie 35)</title></circle>
<circle class="person" data-gid="55" data-gruppe="Familie Franke (Studierenden-Familie 35)" data-name="Amira Franke" cx="1802.2" cy="242.672" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Amira Franke — Familie Franke (Studierenden-Familie 35)</title></circle>
<circle class="person" data-gid="55" data-gruppe="Familie Franke (Studierenden-Familie 35)" data-name="Marco Franke" cx="1769.87" cy="242.672" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Marco Franke — Familie Franke (Studierenden-Familie 35)</title></circle>
<ellipse cx="1786.04" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1786.04" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">69</text>
<text x="1786.04" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1968.71" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="24" data-gruppe="Institut fuer Chemie" data-name="Luca Ott" cx="1968.71" cy="214.67" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Luca Ott — Institut fuer Chemie</title></circle>
<circle class="person" data-gid="24" data-gruppe="Institut fuer Chemie" data-name="Patrick Zimmermann" cx="1984.87" cy="242.672" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Patrick Zimmermann — Institut fuer Chemie</title></circle>
<circle class="person" data-gid="24" data-gruppe="Institut fuer Chemie" data-name="Stefan Richter" cx="1952.54" cy="242.672" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Stefan Richter — Institut fuer Chemie</title></circle>
<ellipse cx="1968.71" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1968.71" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">71</text>
<text x="1968.71" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2060.04" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="49" data-gruppe="Familie Ott (Studierenden-Familie 29)" data-name="Matthias Ott" cx="2060.04" cy="214.67" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Matthias Ott — Familie Ott (Studierenden-Familie 29)</title></circle>
<circle class="person" data-gid="49" data-gruppe="Familie Ott (Studierenden-Familie 29)" data-name="Hannah Ott" cx="2076.21" cy="242.672" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Hannah Ott — Familie Ott (Studierenden-Familie 29)</title></circle>
<circle class="person" data-gid="49" data-gruppe="Familie Ott (Studierenden-Familie 29)" data-name="Olga Ott" cx="2043.88" cy="242.672" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Olga Ott — Familie Ott (Studierenden-Familie 29)</title></circle>
<ellipse cx="2060.04" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2060.04" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">72</text>
<text x="2060.04" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1649.03" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="5" data-gruppe="Institut fuer Maschinenwesen" data-name="Prof. Dr. Yusuf Esposito" cx="1649.03" cy="306.006" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Prof. Dr. Yusuf Esposito — Institut fuer Maschinenwesen</title></circle>
<circle class="person" data-gid="5" data-gruppe="Institut fuer Maschinenwesen" data-name="Marija Becker" cx="1665.2" cy="334.007" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Marija Becker — Institut fuer Maschinenwesen</title></circle>
<circle class="person" data-gid="5" data-gruppe="Institut fuer Maschinenwesen" data-name="Matthias Kovac" cx="1632.87" cy="334.007" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Matthias Kovac — Institut fuer Maschinenwesen</title></circle>
<ellipse cx="1649.03" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1649.03" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">76</text>
<text x="1649.03" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1740.37" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="6" data-gruppe="Familie Kaya (Studierenden-Familie 5)" data-name="Luca Kaya" cx="1740.37" cy="306.006" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Luca Kaya — Familie Kaya (Studierenden-Familie 5)</title></circle>
<circle class="person" data-gid="6" data-gruppe="Familie Kaya (Studierenden-Familie 5)" data-name="Christina Kaya" cx="1756.54" cy="334.007" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Christina Kaya — Familie Kaya (Studierenden-Familie 5)</title></circle>
<circle class="person" data-gid="6" data-gruppe="Familie Kaya (Studierenden-Familie 5)" data-name="Nicole Kaya" cx="1724.2" cy="334.007" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Nicole Kaya — Familie Kaya (Studierenden-Familie 5)</title></circle>
<ellipse cx="1740.37" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1740.37" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">77</text>
<text x="1740.37" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2105.71" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="54" data-gruppe="Familie Polat (Studierenden-Familie 34)" data-name="Sarah Polat" cx="2105.71" cy="306.006" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Sarah Polat — Familie Polat (Studierenden-Familie 34)</title></circle>
<circle class="person" data-gid="54" data-gruppe="Familie Polat (Studierenden-Familie 34)" data-name="Markus Polat" cx="2121.88" cy="334.007" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Markus Polat — Familie Polat (Studierenden-Familie 34)</title></circle>
<circle class="person" data-gid="54" data-gruppe="Familie Polat (Studierenden-Familie 34)" data-name="Katrin Polat" cx="2089.54" cy="334.007" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Katrin Polat — Familie Polat (Studierenden-Familie 34)</title></circle>
<ellipse cx="2105.71" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2105.71" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">81</text>
<text x="2105.71" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2197.05" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="10" data-gruppe="Institut fuer Informatik" data-name="Olga Roth" cx="2197.05" cy="306.006" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Olga Roth — Institut fuer Informatik</title></circle>
<circle class="person" data-gid="10" data-gruppe="Institut fuer Informatik" data-name="Prof. Dr. Emre Albrecht" cx="2213.21" cy="334.007" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Prof. Dr. Emre Albrecht — Institut fuer Informatik</title></circle>
<circle class="person" data-gid="10" data-gruppe="Institut fuer Informatik" data-name="Thomas Bianchi" cx="2180.88" cy="334.007" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Thomas Bianchi — Institut fuer Informatik</title></circle>
<ellipse cx="2197.05" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2197.05" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">82</text>
<text x="2197.05" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1786.04" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="42" data-gruppe="Familie Hartmann (Studierenden-Familie 22)" data-name="Marija Hartmann" cx="1786.04" cy="397.341" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Marija Hartmann — Familie Hartmann (Studierenden-Familie 22)</title></circle>
<circle class="person" data-gid="42" data-gruppe="Familie Hartmann (Studierenden-Familie 22)" data-name="Thomas Hartmann" cx="1802.2" cy="425.342" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Thomas Hartmann — Familie Hartmann (Studierenden-Familie 22)</title></circle>
<circle class="person" data-gid="42" data-gruppe="Familie Hartmann (Studierenden-Familie 22)" data-name="Olga Hartmann" cx="1769.87" cy="425.342" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Olga Hartmann — Familie Hartmann (Studierenden-Familie 22)</title></circle>
<ellipse cx="1786.04" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1786.04" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">84</text>
<text x="1786.04" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1877.37" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="8" data-gruppe="Familie Schmidt (Studierenden-Familie 6)" data-name="Matthias Schmidt" cx="1877.37" cy="397.341" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Matthias Schmidt — Familie Schmidt (Studierenden-Familie 6)</title></circle>
<circle class="person" data-gid="8" data-gruppe="Familie Schmidt (Studierenden-Familie 6)" data-name="Marie Schmidt" cx="1893.54" cy="425.342" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Marie Schmidt — Familie Schmidt (Studierenden-Familie 6)</title></circle>
<circle class="person" data-gid="8" data-gruppe="Familie Schmidt (Studierenden-Familie 6)" data-name="Giovanna Schmidt" cx="1861.21" cy="425.342" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Giovanna Schmidt — Familie Schmidt (Studierenden-Familie 6)</title></circle>
<ellipse cx="1877.37" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1877.37" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">85</text>
<text x="1877.37" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2060.04" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="26" data-gruppe="Familie Frank (Studierenden-Familie 14)" data-name="Lena Frank" cx="2060.04" cy="397.341" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Lena Frank — Familie Frank (Studierenden-Familie 14)</title></circle>
<circle class="person" data-gid="26" data-gruppe="Familie Frank (Studierenden-Familie 14)" data-name="Marie Frank" cx="2076.21" cy="425.342" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Marie Frank — Familie Frank (Studierenden-Familie 14)</title></circle>
<circle class="person" data-gid="26" data-gruppe="Familie Frank (Studierenden-Familie 14)" data-name="Finn Frank" cx="2043.88" cy="425.342" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Finn Frank — Familie Frank (Studierenden-Familie 14)</title></circle>
<ellipse cx="2060.04" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2060.04" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">87</text>
<text x="2060.04" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="142.003" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="65" data-gruppe="Familie Lehmann (Studierenden-Familie 45)" data-name="Layla Lehmann" cx="142.003" cy="32" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Layla Lehmann — Familie Lehmann (Studierenden-Familie 45)</title></circle>
<circle class="person" data-gid="65" data-gruppe="Familie Lehmann (Studierenden-Familie 45)" data-name="Thomas Lehmann" cx="160.67" cy="50.6676" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Thomas Lehmann — Familie Lehmann (Studierenden-Familie 45)</title></circle>
<circle class="person" data-gid="65" data-gruppe="Familie Lehmann (Studierenden-Familie 45)" data-name="Nicole Lehmann" cx="142.003" cy="69.3352" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Nicole Lehmann — Familie Lehmann (Studierenden-Familie 45)</title></circle>
<circle class="person" data-gid="65" data-gruppe="Familie Lehmann (Studierenden-Familie 45)" data-name="Markus Lehmann" cx="123.335" cy="50.6676" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Markus Lehmann — Familie Lehmann (Studierenden-Familie 45)</title></circle>
<ellipse cx="142.003" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="142.003" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">2</text>
<text x="142.003" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="233.338" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="25" data-gruppe="Lehrstuhl Fahrzeugtechnik" data-name="Emre Klein" cx="233.338" cy="32" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Emre Klein — Lehrstuhl Fahrzeugtechnik</title></circle>
<circle class="person" data-gid="25" data-gruppe="Lehrstuhl Fahrzeugtechnik" data-name="Dr. Patrick Kaya" cx="252.006" cy="50.6676" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Dr. Patrick Kaya — Lehrstuhl Fahrzeugtechnik</title></circle>
<circle class="person" data-gid="25" data-gruppe="Lehrstuhl Fahrzeugtechnik" data-name="Dr. Christina Krause" cx="233.338" cy="69.3352" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Dr. Christina Krause — Lehrstuhl Fahrzeugtechnik</title></circle>
<circle class="person" data-gid="69" data-gruppe="Familie Weber (Studierenden-Familie 49)" data-name="Julia Weber" cx="214.67" cy="50.6676" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Julia Weber — Familie Weber (Studierenden-Familie 49)</title></circle>
<ellipse cx="233.338" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="233.338" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">3</text>
<text x="233.338" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="324.673" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="25" data-gruppe="Lehrstuhl Fahrzeugtechnik" data-name="Marco Winkler" cx="324.673" cy="32" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Marco Winkler — Lehrstuhl Fahrzeugtechnik</title></circle>
<circle class="person" data-gid="25" data-gruppe="Lehrstuhl Fahrzeugtechnik" data-name="Prof. Dr. Yusuf Seidel" cx="343.341" cy="50.6676" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Prof. Dr. Yusuf Seidel — Lehrstuhl Fahrzeugtechnik</title></circle>
<circle class="person" data-gid="25" data-gruppe="Lehrstuhl Fahrzeugtechnik" data-name="Yusuf Bauer" cx="324.673" cy="69.3352" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Yusuf Bauer — Lehrstuhl Fahrzeugtechnik</title></circle>
<circle class="person" data-gid="25" data-gruppe="Lehrstuhl Fahrzeugtechnik" data-name="Dr. Jan Bianchi" cx="306.006" cy="50.6676" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Dr. Jan Bianchi — Lehrstuhl Fahrzeugtechnik</title></circle>
<ellipse cx="324.673" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="324.673" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">4</text>
<text x="324.673" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="416.009" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Dr. h.c. Alexander Grothe" cx="416.009" cy="32" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Dr. h.c. Alexander Grothe — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Beate Grothe" cx="434.676" cy="50.6676" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Beate Grothe — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Dr. Ferdinand Kessler" cx="416.009" cy="69.3352" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Dr. Ferdinand Kessler — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Viktoria Kessler" cx="397.341" cy="50.6676" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Viktoria Kessler — VIP / feste Platzierung</title></circle>
<ellipse cx="416.009" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="416.009" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">5</text>
<text x="416.009" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="507.344" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Elisabeth Steinbach" cx="507.344" cy="32" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Elisabeth Steinbach — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Dr. Konstantin Freiherr von Waldeck" cx="526.011" cy="50.6676" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Dr. Konstantin Freiherr von Waldeck — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Antonia Freifrau von Waldeck" cx="507.344" cy="69.3352" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Antonia Freifrau von Waldeck — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Georg Steinbach" cx="488.676" cy="50.6676" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Georg Steinbach — VIP / feste Platzierung</title></circle>
<ellipse cx="507.344" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="507.344" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">6</text>
<text x="507.344" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="598.679" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Heinrich Dallmann" cx="598.679" cy="32" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Heinrich Dallmann — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Margarete Dallmann" cx="617.347" cy="50.6676" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Margarete Dallmann — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Maximilian Dallmann" cx="598.679" cy="69.3352" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Maximilian Dallmann — VIP / feste Platzierung</title></circle>
<circle class="person" data-gid="-1" data-gruppe="VIP / feste Platzierung" data-name="Charlotte Dallmann" cx="580.011" cy="50.6676" r="12" fill="#888888" stroke="black" stroke-width="1"><title>Charlotte Dallmann — VIP / feste Platzierung</title></circle>
<ellipse cx="598.679" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="598.679" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">7</text>
<text x="598.679" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="781.35" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="68" data-gruppe="Familie Ludwig (Studierenden-Familie 48)" data-name="Giovanna Ludwig" cx="781.35" cy="32" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Giovanna Ludwig — Familie Ludwig (Studierenden-Familie 48)</title></circle>
<circle class="person" data-gid="68" data-gruppe="Familie Ludwig (Studierenden-Familie 48)" data-name="Emre Ludwig" cx="800.017" cy="50.6676" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Emre Ludwig — Familie Ludwig (Studierenden-Familie 48)</title></circle>
<circle class="person" data-gid="68" data-gruppe="Familie Ludwig (Studierenden-Familie 48)" data-name="Elif Ludwig" cx="781.35" cy="69.3352" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Elif Ludwig — Familie Ludwig (Studierenden-Familie 48)</title></circle>
<circle class="person" data-gid="68" data-gruppe="Familie Ludwig (Studierenden-Familie 48)" data-name="Elias Ludwig" cx="762.682" cy="50.6676" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Elias Ludwig — Familie Ludwig (Studierenden-Familie 48)</title></circle>
<ellipse cx="781.35" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="781.35" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">9</text>
<text x="781.35" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="872.685" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="16" data-gruppe="Lehrstuhl Mathematik" data-name="Giovanna Petrov" cx="872.685" cy="32" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Giovanna Petrov — Lehrstuhl Mathematik</title></circle>
<circle class="person" data-gid="16" data-gruppe="Lehrstuhl Mathematik" data-name="Dr. Nadine Stein" cx="891.352" cy="50.6676" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Dr. Nadine Stein — Lehrstuhl Mathematik</title></circle>
<circle class="person" data-gid="16" data-gruppe="Lehrstuhl Mathematik" data-name="Markus Schmitt" cx="872.685" cy="69.3352" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Markus Schmitt — Lehrstuhl Mathematik</title></circle>
<circle class="person" data-gid="16" data-gruppe="Lehrstuhl Mathematik" data-name="Christian Peters" cx="854.017" cy="50.6676" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Christian Peters — Lehrstuhl Mathematik</title></circle>
<ellipse cx="872.685" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="872.685" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">10</text>
<text x="872.685" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="96.3352" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="12" data-gruppe="Institut fuer Werkstoffkunde" data-name="Matthias Popescu" cx="96.3352" cy="123.335" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Matthias Popescu — Institut fuer Werkstoffkunde</title></circle>
<circle class="person" data-gid="4" data-gruppe="Familie Albrecht (Studierenden-Familie 4)" data-name="Sarah Albrecht" cx="115.003" cy="142.003" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Sarah Albrecht — Familie Albrecht (Studierenden-Familie 4)</title></circle>
<circle class="person" data-gid="4" data-gruppe="Familie Albrecht (Studierenden-Familie 4)" data-name="Andreas Albrecht" cx="96.3352" cy="160.67" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Andreas Albrecht — Familie Albrecht (Studierenden-Familie 4)</title></circle>
<circle class="person" data-gid="12" data-gruppe="Institut fuer Werkstoffkunde" data-name="Prof. Dr. Markus Stein" cx="77.6676" cy="142.003" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Prof. Dr. Markus Stein — Institut fuer Werkstoffkunde</title></circle>
<ellipse cx="96.3352" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="96.3352" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">12</text>
<text x="96.3352" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="187.67" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="13" data-gruppe="Lehrstuhl Stroemungsmechanik" data-name="Prof. Dr. Yusuf Albrecht" cx="187.67" cy="123.335" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Prof. Dr. Yusuf Albrecht — Lehrstuhl Stroemungsmechanik</title></circle>
<circle class="person" data-gid="65" data-gruppe="Familie Lehmann (Studierenden-Familie 45)" data-name="Giovanna Lehmann" cx="206.338" cy="142.003" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Giovanna Lehmann — Familie Lehmann (Studierenden-Familie 45)</title></circle>
<circle class="person" data-gid="65" data-gruppe="Familie Lehmann (Studierenden-Familie 45)" data-name="Milan Lehmann" cx="187.67" cy="160.67" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Milan Lehmann — Familie Lehmann (Studierenden-Familie 45)</title></circle>
<circle class="person" data-gid="13" data-gruppe="Lehrstuhl Stroemungsmechanik" data-name="Svenja Simon" cx="169.003" cy="142.003" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Svenja Simon — Lehrstuhl Stroemungsmechanik</title></circle>
<ellipse cx="187.67" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="187.67" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">13</text>
<text x="187.67" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="461.676" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="14" data-gruppe="Institut fuer Elektrotechnik" data-name="Thomas Hansen" cx="461.676" cy="123.335" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Thomas Hansen — Institut fuer Elektrotechnik</title></circle>
<circle class="person" data-gid="14" data-gruppe="Institut fuer Elektrotechnik" data-name="Nicole Schmidt" cx="480.344" cy="142.003" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Nicole Schmidt — Institut fuer Elektrotechnik</title></circle>
<circle class="person" data-gid="14" data-gruppe="Institut fuer Elektrotechnik" data-name="Julia Nguyen" cx="461.676" cy="160.67" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Julia Nguyen — Institut fuer Elektrotechnik</title></circle>
<circle class="person" data-gid="14" data-gruppe="Institut fuer Elektrotechnik" data-name="Dr. Stefanie Seifert" cx="443.009" cy="142.003" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Dr. Stefanie Seifert — Institut fuer Elektrotechnik</title></circle>
<ellipse cx="461.676" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="461.676" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">16</text>
<text x="461.676" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="827.017" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="3" data-gruppe="Familie Seifert (Studierenden-Familie 3)" data-name="Timo Seifert" cx="827.017" cy="123.335" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Timo Seifert — Familie Seifert (Studierenden-Familie 3)</title></circle>
<circle class="person" data-gid="3" data-gruppe="Familie Seifert (Studierenden-Familie 3)" data-name="Elif Seifert" cx="845.685" cy="142.003" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Elif Seifert — Familie Seifert (Studierenden-Familie 3)</title></circle>
<circle class="person" data-gid="22" data-gruppe="Familie Engel (Studierenden-Familie 13)" data-name="Julia Engel" cx="827.017" cy="160.67" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Julia Engel — Familie Engel (Studierenden-Familie 13)</title></circle>
<circle class="person" data-gid="22" data-gruppe="Familie Engel (Studierenden-Familie 13)" data-name="Anton Engel" cx="808.35" cy="142.003" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Anton Engel — Familie Engel (Studierenden-Familie 13)</title></circle>
<ellipse cx="827.017" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="827.017" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">20</text>
<text x="827.017" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="324.673" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="61" data-gruppe="Familie Berger (Studierenden-Familie 41)" data-name="Andreas Berger" cx="324.673" cy="214.67" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Andreas Berger — Familie Berger (Studierenden-Familie 41)</title></circle>
<circle class="person" data-gid="18" data-gruppe="Familie Celik (Studierenden-Familie 10)" data-name="Patrick Celik" cx="343.341" cy="233.338" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Patrick Celik — Familie Celik (Studierenden-Familie 10)</title></circle>
<circle class="person" data-gid="18" data-gruppe="Familie Celik (Studierenden-Familie 10)" data-name="Elif Celik" cx="324.673" cy="252.006" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Elif Celik — Familie Celik (Studierenden-Familie 10)</title></circle>
<circle class="person" data-gid="61" data-gruppe="Familie Berger (Studierenden-Familie 41)" data-name="Svenja Berger" cx="306.006" cy="233.338" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Svenja Berger — Familie Berger (Studierenden-Familie 41)</title></circle>
<ellipse cx="324.673" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="324.673" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">24</text>
<text x="324.673" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="690.014" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="36" data-gruppe="Lehrstuhl Mechatronik" data-name="Prof. Dr. Timo Kaya" cx="690.014" cy="214.67" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Prof. Dr. Timo Kaya — Lehrstuhl Mechatronik</title></circle>
<circle class="person" data-gid="36" data-gruppe="Lehrstuhl Mechatronik" data-name="Dr. Sandra Demir" cx="708.682" cy="233.338" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Dr. Sandra Demir — Lehrstuhl Mechatronik</title></circle>
<circle class="person" data-gid="56" data-gruppe="Familie Kovac (Studierenden-Familie 36)" data-name="Lena Kovac" cx="690.014" cy="252.006" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Lena Kovac — Familie Kovac (Studierenden-Familie 36)</title></circle>
<circle class="person" data-gid="56" data-gruppe="Familie Kovac (Studierenden-Familie 36)" data-name="Tobias Kovac" cx="671.347" cy="233.338" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Tobias Kovac — Familie Kovac (Studierenden-Familie 36)</title></circle>
<ellipse cx="690.014" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="690.014" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">28</text>
<text x="690.014" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="781.35" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="47" data-gruppe="Familie Nowak (Studierenden-Familie 27)" data-name="Felix Nowak" cx="781.35" cy="214.67" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Felix Nowak — Familie Nowak (Studierenden-Familie 27)</title></circle>
<circle class="person" data-gid="57" data-gruppe="Familie Winkler (Studierenden-Familie 37)" data-name="Lena Winkler" cx="800.017" cy="233.338" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Lena Winkler — Familie Winkler (Studierenden-Familie 37)</title></circle>
<circle class="person" data-gid="57" data-gruppe="Familie Winkler (Studierenden-Familie 37)" data-name="Patrick Winkler" cx="781.35" cy="252.006" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Patrick Winkler — Familie Winkler (Studierenden-Familie 37)</title></circle>
<circle class="person" data-gid="47" data-gruppe="Familie Nowak (Studierenden-Familie 27)" data-name="Kathrin Nowak" cx="762.682" cy="233.338" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Kathrin Nowak — Familie Nowak (Studierenden-Familie 27)</title></circle>
<ellipse cx="781.35" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="781.35" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">29</text>
<text x="781.35" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="279.006" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="61" data-gruppe="Familie Berger (Studierenden-Familie 41)" data-name="Jennifer Berger" cx="279.006" cy="306.006" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Jennifer Berger — Familie Berger (Studierenden-Familie 41)</title></circle>
<circle class="person" data-gid="61" data-gruppe="Familie Berger (Studierenden-Familie 41)" data-name="Anton Berger" cx="297.673" cy="324.673" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Anton Berger — Familie Berger (Studierenden-Familie 41)</title></circle>
<circle class="person" data-gid="61" data-gruppe="Familie Berger (Studierenden-Familie 41)" data-name="Layla Berger" cx="279.006" cy="343.341" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Layla Berger — Familie Berger (Studierenden-Familie 41)</title></circle>
<circle class="person" data-gid="61" data-gruppe="Familie Berger (Studierenden-Familie 41)" data-name="Stefan Berger" cx="260.338" cy="324.673" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Stefan Berger — Familie Berger (Studierenden-Familie 41)</title></circle>
<ellipse cx="279.006" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="279.006" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">32</text>
<text x="279.006" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="644.347" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="56" data-gruppe="Familie Kovac (Studierenden-Familie 36)" data-name="Marco Kovac" cx="644.347" cy="306.006" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Marco Kovac — Familie Kovac (Studierenden-Familie 36)</title></circle>
<circle class="person" data-gid="56" data-gruppe="Familie Kovac (Studierenden-Familie 36)" data-name="Anja Kovac" cx="663.014" cy="324.673" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Anja Kovac — Familie Kovac (Studierenden-Familie 36)</title></circle>
<circle class="person" data-gid="56" data-gruppe="Familie Kovac (Studierenden-Familie 36)" data-name="Henry Kovac" cx="644.347" cy="343.341" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Henry Kovac — Familie Kovac (Studierenden-Familie 36)</title></circle>
<circle class="person" data-gid="56" data-gruppe="Familie Kovac (Studierenden-Familie 36)" data-name="Marija Kovac" cx="625.679" cy="324.673" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Marija Kovac — Familie Kovac (Studierenden-Familie 36)</title></circle>
<ellipse cx="644.347" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="644.347" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">36</text>
<text x="644.347" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="735.682" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="47" data-gruppe="Familie Nowak (Studierenden-Familie 27)" data-name="Aylin Nowak" cx="735.682" cy="306.006" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Aylin Nowak — Familie Nowak (Studierenden-Familie 27)</title></circle>
<circle class="person" data-gid="47" data-gruppe="Familie Nowak (Studierenden-Familie 27)" data-name="Markus Nowak" cx="754.35" cy="324.673" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Markus Nowak — Familie Nowak (Studierenden-Familie 27)</title></circle>
<circle class="person" data-gid="47" data-gruppe="Familie Nowak (Studierenden-Familie 27)" data-name="Lina Nowak" cx="735.682" cy="343.341" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Lina Nowak — Familie Nowak (Studierenden-Familie 27)</title></circle>
<circle class="person" data-gid="47" data-gruppe="Familie Nowak (Studierenden-Familie 27)" data-name="Noah Nowak" cx="717.014" cy="324.673" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Noah Nowak — Familie Nowak (Studierenden-Familie 27)</title></circle>
<ellipse cx="735.682" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="735.682" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">37</text>
<text x="735.682" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="827.017" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="35" data-gruppe="Institut fuer Verfahrenstechnik" data-name="Dr. Nicole Hansen" cx="827.017" cy="306.006" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Dr. Nicole Hansen — Institut fuer Verfahrenstechnik</title></circle>
<circle class="person" data-gid="35" data-gruppe="Institut fuer Verfahrenstechnik" data-name="Thomas Krause" cx="845.685" cy="324.673" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Thomas Krause — Institut fuer Verfahrenstechnik</title></circle>
<circle class="person" data-gid="58" data-gruppe="Familie Petrov (Studierenden-Familie 38)" data-name="Kathrin Petrov" cx="827.017" cy="343.341" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Kathrin Petrov — Familie Petrov (Studierenden-Familie 38)</title></circle>
<circle class="person" data-gid="58" data-gruppe="Familie Petrov (Studierenden-Familie 38)" data-name="Milan Petrov" cx="808.35" cy="324.673" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Milan Petrov — Familie Petrov (Studierenden-Familie 38)</title></circle>
<ellipse cx="827.017" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="827.017" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">38</text>
<text x="827.017" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="598.679" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="2" data-gruppe="Familie Arnold (Studierenden-Familie 2)" data-name="Jennifer Arnold" cx="598.679" cy="397.341" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Jennifer Arnold — Familie Arnold (Studierenden-Familie 2)</title></circle>
<circle class="person" data-gid="2" data-gruppe="Familie Arnold (Studierenden-Familie 2)" data-name="Patrick Arnold" cx="617.347" cy="416.009" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Patrick Arnold — Familie Arnold (Studierenden-Familie 2)</title></circle>
<circle class="person" data-gid="64" data-gruppe="Familie Lange (Studierenden-Familie 44)" data-name="Dragana Lange" cx="598.679" cy="434.676" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Dragana Lange — Familie Lange (Studierenden-Familie 44)</title></circle>
<circle class="person" data-gid="64" data-gruppe="Familie Lange (Studierenden-Familie 44)" data-name="Michael Lange" cx="580.011" cy="416.009" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Michael Lange — Familie Lange (Studierenden-Familie 44)</title></circle>
<ellipse cx="598.679" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="598.679" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">43</text>
<text x="598.679" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="781.35" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="35" data-gruppe="Institut fuer Verfahrenstechnik" data-name="Patrick Haas" cx="781.35" cy="397.341" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Patrick Haas — Institut fuer Verfahrenstechnik</title></circle>
<circle class="person" data-gid="35" data-gruppe="Institut fuer Verfahrenstechnik" data-name="Prof. Dr. Sergej Ott" cx="800.017" cy="416.009" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Prof. Dr. Sergej Ott — Institut fuer Verfahrenstechnik</title></circle>
<circle class="person" data-gid="35" data-gruppe="Institut fuer Verfahrenstechnik" data-name="Dragana Bauer" cx="781.35" cy="434.676" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Dragana Bauer — Institut fuer Verfahrenstechnik</title></circle>
<circle class="person" data-gid="35" data-gruppe="Institut fuer Verfahrenstechnik" data-name="Nicole Peters" cx="762.682" cy="416.009" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Nicole Peters — Institut fuer Verfahrenstechnik</title></circle>
<ellipse cx="781.35" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="781.35" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">45</text>
<text x="781.35" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1877.37" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="9" data-gruppe="Familie Richter (Studierenden-Familie 7)" data-name="Anja Richter" cx="1877.37" cy="32" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Anja Richter — Familie Richter (Studierenden-Familie 7)</title></circle>
<circle class="person" data-gid="9" data-gruppe="Familie Richter (Studierenden-Familie 7)" data-name="Matthias Richter" cx="1896.04" cy="50.6676" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Matthias Richter — Familie Richter (Studierenden-Familie 7)</title></circle>
<circle class="person" data-gid="9" data-gruppe="Familie Richter (Studierenden-Familie 7)" data-name="Greta Richter" cx="1877.37" cy="69.3352" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Greta Richter — Familie Richter (Studierenden-Familie 7)</title></circle>
<circle class="person" data-gid="9" data-gruppe="Familie Richter (Studierenden-Familie 7)" data-name="Anton Richter" cx="1858.7" cy="50.6676" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Anton Richter — Familie Richter (Studierenden-Familie 7)</title></circle>
<ellipse cx="1877.37" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1877.37" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">50</text>
<text x="1877.37" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1968.71" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="11" data-gruppe="Lehrstuhl Regelungstechnik" data-name="Prof. Dr. Dennis Werner" cx="1968.71" cy="32" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Prof. Dr. Dennis Werner — Lehrstuhl Regelungstechnik</title></circle>
<circle class="person" data-gid="11" data-gruppe="Lehrstuhl Regelungstechnik" data-name="Dr. Thomas Hoffmann" cx="1987.38" cy="50.6676" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Dr. Thomas Hoffmann — Lehrstuhl Regelungstechnik</title></circle>
<circle class="person" data-gid="11" data-gruppe="Lehrstuhl Regelungstechnik" data-name="Olga Tran" cx="1968.71" cy="69.3352" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Olga Tran — Lehrstuhl Regelungstechnik</title></circle>
<circle class="person" data-gid="11" data-gruppe="Lehrstuhl Regelungstechnik" data-name="Dr. Anja Seidel" cx="1950.04" cy="50.6676" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Dr. Anja Seidel — Lehrstuhl Regelungstechnik</title></circle>
<ellipse cx="1968.71" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1968.71" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">51</text>
<text x="1968.71" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2060.04" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="21" data-gruppe="Institut fuer Physik" data-name="Prof. Dr. Stefan Schmitt" cx="2060.04" cy="32" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Prof. Dr. Stefan Schmitt — Institut fuer Physik</title></circle>
<circle class="person" data-gid="21" data-gruppe="Institut fuer Physik" data-name="Marija Tran" cx="2078.71" cy="50.6676" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Marija Tran — Institut fuer Physik</title></circle>
<circle class="person" data-gid="21" data-gruppe="Institut fuer Physik" data-name="Dr. Kathrin Koch" cx="2060.04" cy="69.3352" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Dr. Kathrin Koch — Institut fuer Physik</title></circle>
<circle class="person" data-gid="21" data-gruppe="Institut fuer Physik" data-name="Dr. Julia Kuhn" cx="2041.38" cy="50.6676" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Dr. Julia Kuhn — Institut fuer Physik</title></circle>
<ellipse cx="2060.04" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2060.04" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">52</text>
<text x="2060.04" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2151.38" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="31" data-gruppe="Doktorandenrunde Energietechnik" data-name="Prof. Dr. Dragana Dietrich" cx="2151.38" cy="32" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Prof. Dr. Dragana Dietrich — Doktorandenrunde Energietechnik</title></circle>
<circle class="person" data-gid="31" data-gruppe="Doktorandenrunde Energietechnik" data-name="Dr. Michael Aksoy" cx="2170.05" cy="50.6676" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Dr. Michael Aksoy — Doktorandenrunde Energietechnik</title></circle>
<circle class="person" data-gid="21" data-gruppe="Institut fuer Physik" data-name="Katrin Weber" cx="2151.38" cy="69.3352" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Katrin Weber — Institut fuer Physik</title></circle>
<circle class="person" data-gid="21" data-gruppe="Institut fuer Physik" data-name="Luca Werner" cx="2132.71" cy="50.6676" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Luca Werner — Institut fuer Physik</title></circle>
<ellipse cx="2151.38" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2151.38" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">53</text>
<text x="2151.38" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2334.05" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="27" data-gruppe="Familie Werner (Studierenden-Familie 15)" data-name="Sandra Werner" cx="2334.05" cy="32" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Sandra Werner — Familie Werner (Studierenden-Familie 15)</title></circle>
<circle class="person" data-gid="27" data-gruppe="Familie Werner (Studierenden-Familie 15)" data-name="Andreas Werner" cx="2352.72" cy="50.6676" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Andreas Werner — Familie Werner (Studierenden-Familie 15)</title></circle>
<circle class="person" data-gid="27" data-gruppe="Familie Werner (Studierenden-Familie 15)" data-name="Nadine Werner" cx="2334.05" cy="69.3352" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Nadine Werner — Familie Werner (Studierenden-Familie 15)</title></circle>
<circle class="person" data-gid="27" data-gruppe="Familie Werner (Studierenden-Familie 15)" data-name="Marco Werner" cx="2315.38" cy="50.6676" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Marco Werner — Familie Werner (Studierenden-Familie 15)</title></circle>
<ellipse cx="2334.05" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2334.05" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">55</text>
<text x="2334.05" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2425.38" cy="50.6676" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="20" data-gruppe="Familie Busch (Studierenden-Familie 12)" data-name="Olga Busch" cx="2425.38" cy="32" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Olga Busch — Familie Busch (Studierenden-Familie 12)</title></circle>
<circle class="person" data-gid="20" data-gruppe="Familie Busch (Studierenden-Familie 12)" data-name="Emre Busch" cx="2444.05" cy="50.6676" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Emre Busch — Familie Busch (Studierenden-Familie 12)</title></circle>
<circle class="person" data-gid="20" data-gruppe="Familie Busch (Studierenden-Familie 12)" data-name="Marie Busch" cx="2425.38" cy="69.3352" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Marie Busch — Familie Busch (Studierenden-Familie 12)</title></circle>
<circle class="person" data-gid="20" data-gruppe="Familie Busch (Studierenden-Familie 12)" data-name="Michael Busch" cx="2406.72" cy="50.6676" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Michael Busch — Familie Busch (Studierenden-Familie 12)</title></circle>
<ellipse cx="2425.38" cy="50.6676" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2425.38" y="45.8676" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">56</text>
<text x="2425.38" y="59.0676" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1557.7" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="23" data-gruppe="Lehrstuhl Produktionstechnik" data-name="Prof. Dr. Emre Ludwig" cx="1557.7" cy="123.335" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Prof. Dr. Emre Ludwig — Lehrstuhl Produktionstechnik</title></circle>
<circle class="person" data-gid="23" data-gruppe="Lehrstuhl Produktionstechnik" data-name="Daniel Krause" cx="1576.37" cy="142.003" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Daniel Krause — Lehrstuhl Produktionstechnik</title></circle>
<circle class="person" data-gid="23" data-gruppe="Lehrstuhl Produktionstechnik" data-name="Nicole Aksoy" cx="1557.7" cy="160.67" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Nicole Aksoy — Lehrstuhl Produktionstechnik</title></circle>
<circle class="person" data-gid="23" data-gruppe="Lehrstuhl Produktionstechnik" data-name="Markus Klein" cx="1539.03" cy="142.003" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Markus Klein — Lehrstuhl Produktionstechnik</title></circle>
<ellipse cx="1557.7" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1557.7" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">57</text>
<text x="1557.7" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1740.37" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="34" data-gruppe="Emeriti-Stammtisch" data-name="Prof. Dr. Thomas Tran" cx="1740.37" cy="123.335" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Prof. Dr. Thomas Tran — Emeriti-Stammtisch</title></circle>
<circle class="person" data-gid="34" data-gruppe="Emeriti-Stammtisch" data-name="Sergej Petrov" cx="1759.04" cy="142.003" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Sergej Petrov — Emeriti-Stammtisch</title></circle>
<circle class="person" data-gid="34" data-gruppe="Emeriti-Stammtisch" data-name="Kathrin Polat" cx="1740.37" cy="160.67" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Kathrin Polat — Emeriti-Stammtisch</title></circle>
<circle class="person" data-gid="34" data-gruppe="Emeriti-Stammtisch" data-name="Marija Aksoy" cx="1721.7" cy="142.003" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Marija Aksoy — Emeriti-Stammtisch</title></circle>
<ellipse cx="1740.37" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1740.37" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">59</text>
<text x="1740.37" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1831.7" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="67" data-gruppe="Familie Sahin (Studierenden-Familie 47)" data-name="Nicole Sahin" cx="1831.7" cy="123.335" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Nicole Sahin — Familie Sahin (Studierenden-Familie 47)</title></circle>
<circle class="person" data-gid="67" data-gruppe="Familie Sahin (Studierenden-Familie 47)" data-name="Markus Sahin" cx="1850.37" cy="142.003" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Markus Sahin — Familie Sahin (Studierenden-Familie 47)</title></circle>
<circle class="person" data-gid="67" data-gruppe="Familie Sahin (Studierenden-Familie 47)" data-name="Kathrin Sahin" cx="1831.7" cy="160.67" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Kathrin Sahin — Familie Sahin (Studierenden-Familie 47)</title></circle>
<circle class="person" data-gid="67" data-gruppe="Familie Sahin (Studierenden-Familie 47)" data-name="Patrick Sahin" cx="1813.04" cy="142.003" r="12" fill="#9a6324" stroke="black" stroke-width="1"><title>Patrick Sahin — Familie Sahin (Studierenden-Familie 47)</title></circle>
<ellipse cx="1831.7" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1831.7" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">60</text>
<text x="1831.7" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1923.04" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="66" data-gruppe="Familie Maier (Studierenden-Familie 46)" data-name="Sarah Maier" cx="1923.04" cy="123.335" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Sarah Maier — Familie Maier (Studierenden-Familie 46)</title></circle>
<circle class="person" data-gid="66" data-gruppe="Familie Maier (Studierenden-Familie 46)" data-name="Christian Maier" cx="1941.71" cy="142.003" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Christian Maier — Familie Maier (Studierenden-Familie 46)</title></circle>
<circle class="person" data-gid="66" data-gruppe="Familie Maier (Studierenden-Familie 46)" data-name="Olga Maier" cx="1923.04" cy="160.67" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Olga Maier — Familie Maier (Studierenden-Familie 46)</title></circle>
<circle class="person" data-gid="66" data-gruppe="Familie Maier (Studierenden-Familie 46)" data-name="Arda Maier" cx="1904.37" cy="142.003" r="12" fill="#800000" stroke="black" stroke-width="1"><title>Arda Maier — Familie Maier (Studierenden-Familie 46)</title></circle>
<ellipse cx="1923.04" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1923.04" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">61</text>
<text x="1923.04" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2105.71" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="46" data-gruppe="Familie Krause (Studierenden-Familie 26)" data-name="Andreas Krause" cx="2105.71" cy="123.335" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Andreas Krause — Familie Krause (Studierenden-Familie 26)</title></circle>
<circle class="person" data-gid="46" data-gruppe="Familie Krause (Studierenden-Familie 26)" data-name="Emma Krause" cx="2124.38" cy="142.003" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Emma Krause — Familie Krause (Studierenden-Familie 26)</title></circle>
<circle class="person" data-gid="46" data-gruppe="Familie Krause (Studierenden-Familie 26)" data-name="Arda Krause" cx="2105.71" cy="160.67" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Arda Krause — Familie Krause (Studierenden-Familie 26)</title></circle>
<circle class="person" data-gid="46" data-gruppe="Familie Krause (Studierenden-Familie 26)" data-name="Julia Krause" cx="2087.04" cy="142.003" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Julia Krause — Familie Krause (Studierenden-Familie 26)</title></circle>
<ellipse cx="2105.71" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2105.71" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">63</text>
<text x="2105.71" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2197.05" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="31" data-gruppe="Doktorandenrunde Energietechnik" data-name="Katrin Werner" cx="2197.05" cy="123.335" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Katrin Werner — Doktorandenrunde Energietechnik</title></circle>
<circle class="person" data-gid="31" data-gruppe="Doktorandenrunde Energietechnik" data-name="Patrick Busch" cx="2215.71" cy="142.003" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Patrick Busch — Doktorandenrunde Energietechnik</title></circle>
<circle class="person" data-gid="31" data-gruppe="Doktorandenrunde Energietechnik" data-name="Emre Hoffmann" cx="2197.05" cy="160.67" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Emre Hoffmann — Doktorandenrunde Energietechnik</title></circle>
<circle class="person" data-gid="31" data-gruppe="Doktorandenrunde Energietechnik" data-name="Sergej Lange" cx="2178.38" cy="142.003" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Sergej Lange — Doktorandenrunde Energietechnik</title></circle>
<ellipse cx="2197.05" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2197.05" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">64</text>
<text x="2197.05" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2288.38" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="30" data-gruppe="Lehrstuhl Messtechnik" data-name="Nadine Arnold" cx="2288.38" cy="123.335" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Nadine Arnold — Lehrstuhl Messtechnik</title></circle>
<circle class="person" data-gid="30" data-gruppe="Lehrstuhl Messtechnik" data-name="Marco Richter" cx="2307.05" cy="142.003" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Marco Richter — Lehrstuhl Messtechnik</title></circle>
<circle class="person" data-gid="30" data-gruppe="Lehrstuhl Messtechnik" data-name="Prof. Dr. Patrick Hoffmann" cx="2288.38" cy="160.67" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Prof. Dr. Patrick Hoffmann — Lehrstuhl Messtechnik</title></circle>
<circle class="person" data-gid="30" data-gruppe="Lehrstuhl Messtechnik" data-name="Marija Polat" cx="2269.71" cy="142.003" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Marija Polat — Lehrstuhl Messtechnik</title></circle>
<ellipse cx="2288.38" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2288.38" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">65</text>
<text x="2288.38" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2379.72" cy="142.003" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="63" data-gruppe="Familie Simon (Studierenden-Familie 43)" data-name="Lena Simon" cx="2379.72" cy="123.335" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Lena Simon — Familie Simon (Studierenden-Familie 43)</title></circle>
<circle class="person" data-gid="63" data-gruppe="Familie Simon (Studierenden-Familie 43)" data-name="Markus Simon" cx="2398.38" cy="142.003" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Markus Simon — Familie Simon (Studierenden-Familie 43)</title></circle>
<circle class="person" data-gid="63" data-gruppe="Familie Simon (Studierenden-Familie 43)" data-name="Emma Simon" cx="2379.72" cy="160.67" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Emma Simon — Familie Simon (Studierenden-Familie 43)</title></circle>
<circle class="person" data-gid="63" data-gruppe="Familie Simon (Studierenden-Familie 43)" data-name="Andreas Simon" cx="2361.05" cy="142.003" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Andreas Simon — Familie Simon (Studierenden-Familie 43)</title></circle>
<ellipse cx="2379.72" cy="142.003" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2379.72" y="137.203" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">66</text>
<text x="2379.72" y="150.403" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1694.7" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="38" data-gruppe="Familie Wagner (Studierenden-Familie 18)" data-name="Nicole Wagner" cx="1694.7" cy="214.67" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Nicole Wagner — Familie Wagner (Studierenden-Familie 18)</title></circle>
<circle class="person" data-gid="38" data-gruppe="Familie Wagner (Studierenden-Familie 18)" data-name="Marco Wagner" cx="1713.37" cy="233.338" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Marco Wagner — Familie Wagner (Studierenden-Familie 18)</title></circle>
<circle class="person" data-gid="38" data-gruppe="Familie Wagner (Studierenden-Familie 18)" data-name="Sarah Wagner" cx="1694.7" cy="252.006" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Sarah Wagner — Familie Wagner (Studierenden-Familie 18)</title></circle>
<circle class="person" data-gid="38" data-gruppe="Familie Wagner (Studierenden-Familie 18)" data-name="Henry Wagner" cx="1676.03" cy="233.338" r="12" fill="#3cb44b" stroke="black" stroke-width="1"><title>Henry Wagner — Familie Wagner (Studierenden-Familie 18)</title></circle>
<ellipse cx="1694.7" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1694.7" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">68</text>
<text x="1694.7" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1877.37" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="45" data-gruppe="Familie Zimmermann (Studierenden-Familie 25)" data-name="Svenja Zimmermann" cx="1877.37" cy="214.67" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Svenja Zimmermann — Familie Zimmermann (Studierenden-Familie 25)</title></circle>
<circle class="person" data-gid="45" data-gruppe="Familie Zimmermann (Studierenden-Familie 25)" data-name="Jan Zimmermann" cx="1896.04" cy="233.338" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Jan Zimmermann — Familie Zimmermann (Studierenden-Familie 25)</title></circle>
<circle class="person" data-gid="45" data-gruppe="Familie Zimmermann (Studierenden-Familie 25)" data-name="Mia Zimmermann" cx="1877.37" cy="252.006" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Mia Zimmermann — Familie Zimmermann (Studierenden-Familie 25)</title></circle>
<circle class="person" data-gid="45" data-gruppe="Familie Zimmermann (Studierenden-Familie 25)" data-name="Markus Zimmermann" cx="1858.7" cy="233.338" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Markus Zimmermann — Familie Zimmermann (Studierenden-Familie 25)</title></circle>
<ellipse cx="1877.37" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1877.37" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">70</text>
<text x="1877.37" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2151.38" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="50" data-gruppe="Familie Neumann (Studierenden-Familie 30)" data-name="Jennifer Neumann" cx="2151.38" cy="214.67" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Jennifer Neumann — Familie Neumann (Studierenden-Familie 30)</title></circle>
<circle class="person" data-gid="50" data-gruppe="Familie Neumann (Studierenden-Familie 30)" data-name="Thomas Neumann" cx="2170.05" cy="233.338" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Thomas Neumann — Familie Neumann (Studierenden-Familie 30)</title></circle>
<circle class="person" data-gid="50" data-gruppe="Familie Neumann (Studierenden-Familie 30)" data-name="Lina Neumann" cx="2151.38" cy="252.006" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Lina Neumann — Familie Neumann (Studierenden-Familie 30)</title></circle>
<circle class="person" data-gid="50" data-gruppe="Familie Neumann (Studierenden-Familie 30)" data-name="Matteo Neumann" cx="2132.71" cy="233.338" r="12" fill="#f58231" stroke="black" stroke-width="1"><title>Matteo Neumann — Familie Neumann (Studierenden-Familie 30)</title></circle>
<ellipse cx="2151.38" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2151.38" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">73</text>
<text x="2151.38" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2242.71" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="62" data-gruppe="Familie Barth (Studierenden-Familie 42)" data-name="Patrick Barth" cx="2242.71" cy="214.67" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Patrick Barth — Familie Barth (Studierenden-Familie 42)</title></circle>
<circle class="person" data-gid="62" data-gruppe="Familie Barth (Studierenden-Familie 42)" data-name="Nadine Barth" cx="2261.38" cy="233.338" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Nadine Barth — Familie Barth (Studierenden-Familie 42)</title></circle>
<circle class="person" data-gid="62" data-gruppe="Familie Barth (Studierenden-Familie 42)" data-name="Timo Barth" cx="2242.71" cy="252.006" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Timo Barth — Familie Barth (Studierenden-Familie 42)</title></circle>
<circle class="person" data-gid="62" data-gruppe="Familie Barth (Studierenden-Familie 42)" data-name="Lina Barth" cx="2224.05" cy="233.338" r="12" fill="#911eb4" stroke="black" stroke-width="1"><title>Lina Barth — Familie Barth (Studierenden-Familie 42)</title></circle>
<ellipse cx="2242.71" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2242.71" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">74</text>
<text x="2242.71" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2334.05" cy="233.338" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="60" data-gruppe="Familie Pohl (Studierenden-Familie 40)" data-name="Dragana Pohl" cx="2334.05" cy="214.67" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Dragana Pohl — Familie Pohl (Studierenden-Familie 40)</title></circle>
<circle class="person" data-gid="60" data-gruppe="Familie Pohl (Studierenden-Familie 40)" data-name="Emre Pohl" cx="2352.72" cy="233.338" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Emre Pohl — Familie Pohl (Studierenden-Familie 40)</title></circle>
<circle class="person" data-gid="60" data-gruppe="Familie Pohl (Studierenden-Familie 40)" data-name="Mia Pohl" cx="2334.05" cy="252.006" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Mia Pohl — Familie Pohl (Studierenden-Familie 40)</title></circle>
<circle class="person" data-gid="60" data-gruppe="Familie Pohl (Studierenden-Familie 40)" data-name="Theo Pohl" cx="2315.38" cy="233.338" r="12" fill="#42d4f4" stroke="black" stroke-width="1"><title>Theo Pohl — Familie Pohl (Studierenden-Familie 40)</title></circle>
<ellipse cx="2334.05" cy="233.338" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2334.05" y="228.538" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">75</text>
<text x="2334.05" y="241.738" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1831.7" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="42" data-gruppe="Familie Hartmann (Studierenden-Familie 22)" data-name="Deniz Hartmann" cx="1831.7" cy="306.006" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Deniz Hartmann — Familie Hartmann (Studierenden-Familie 22)</title></circle>
<circle class="person" data-gid="42" data-gruppe="Familie Hartmann (Studierenden-Familie 22)" data-name="Nadine Hartmann" cx="1850.37" cy="324.673" r="12" fill="#e6194b" stroke="black" stroke-width="1"><title>Nadine Hartmann — Familie Hartmann (Studierenden-Familie 22)</title></circle>
<circle class="person" data-gid="55" data-gruppe="Familie Franke (Studierenden-Familie 35)" data-name="Michael Franke" cx="1831.7" cy="343.341" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Michael Franke — Familie Franke (Studierenden-Familie 35)</title></circle>
<circle class="person" data-gid="55" data-gruppe="Familie Franke (Studierenden-Familie 35)" data-name="Julia Franke" cx="1813.04" cy="324.673" r="12" fill="#469990" stroke="black" stroke-width="1"><title>Julia Franke — Familie Franke (Studierenden-Familie 35)</title></circle>
<ellipse cx="1831.7" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1831.7" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">78</text>
<text x="1831.7" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1923.04" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="48" data-gruppe="Familie Horn (Studierenden-Familie 28)" data-name="Kathrin Horn" cx="1923.04" cy="306.006" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Kathrin Horn — Familie Horn (Studierenden-Familie 28)</title></circle>
<circle class="person" data-gid="48" data-gruppe="Familie Horn (Studierenden-Familie 28)" data-name="Michael Horn" cx="1941.71" cy="324.673" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Michael Horn — Familie Horn (Studierenden-Familie 28)</title></circle>
<circle class="person" data-gid="48" data-gruppe="Familie Horn (Studierenden-Familie 28)" data-name="Layla Horn" cx="1923.04" cy="343.341" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Layla Horn — Familie Horn (Studierenden-Familie 28)</title></circle>
<circle class="person" data-gid="48" data-gruppe="Familie Horn (Studierenden-Familie 28)" data-name="Leon Horn" cx="1904.37" cy="324.673" r="12" fill="#f032e6" stroke="black" stroke-width="1"><title>Leon Horn — Familie Horn (Studierenden-Familie 28)</title></circle>
<ellipse cx="1923.04" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1923.04" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">79</text>
<text x="1923.04" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2014.38" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="54" data-gruppe="Familie Polat (Studierenden-Familie 34)" data-name="Stefanie Polat" cx="2014.38" cy="306.006" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Stefanie Polat — Familie Polat (Studierenden-Familie 34)</title></circle>
<circle class="person" data-gid="54" data-gruppe="Familie Polat (Studierenden-Familie 34)" data-name="Stefan Polat" cx="2033.04" cy="324.673" r="12" fill="#aaffc3" stroke="black" stroke-width="1"><title>Stefan Polat — Familie Polat (Studierenden-Familie 34)</title></circle>
<circle class="person" data-gid="49" data-gruppe="Familie Ott (Studierenden-Familie 29)" data-name="Melanie Ott" cx="2014.38" cy="343.341" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Melanie Ott — Familie Ott (Studierenden-Familie 29)</title></circle>
<circle class="person" data-gid="49" data-gruppe="Familie Ott (Studierenden-Familie 29)" data-name="Daniel Ott" cx="1995.71" cy="324.673" r="12" fill="#dcbeff" stroke="black" stroke-width="1"><title>Daniel Ott — Familie Ott (Studierenden-Familie 29)</title></circle>
<ellipse cx="2014.38" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2014.38" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">80</text>
<text x="2014.38" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2288.38" cy="324.673" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="51" data-gruppe="Familie Wolf (Studierenden-Familie 31)" data-name="Emma Wolf" cx="2288.38" cy="306.006" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Emma Wolf — Familie Wolf (Studierenden-Familie 31)</title></circle>
<circle class="person" data-gid="51" data-gruppe="Familie Wolf (Studierenden-Familie 31)" data-name="Ben Wolf" cx="2307.05" cy="324.673" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Ben Wolf — Familie Wolf (Studierenden-Familie 31)</title></circle>
<circle class="person" data-gid="51" data-gruppe="Familie Wolf (Studierenden-Familie 31)" data-name="Julia Wolf" cx="2288.38" cy="343.341" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Julia Wolf — Familie Wolf (Studierenden-Familie 31)</title></circle>
<circle class="person" data-gid="51" data-gruppe="Familie Wolf (Studierenden-Familie 31)" data-name="Thomas Wolf" cx="2269.71" cy="324.673" r="12" fill="#bfef45" stroke="black" stroke-width="1"><title>Thomas Wolf — Familie Wolf (Studierenden-Familie 31)</title></circle>
<ellipse cx="2288.38" cy="324.673" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2288.38" y="319.873" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">83</text>
<text x="2288.38" y="333.073" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="1968.71" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="59" data-gruppe="Familie Stein (Studierenden-Familie 39)" data-name="Thomas Stein" cx="1968.71" cy="397.341" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Thomas Stein — Familie Stein (Studierenden-Familie 39)</title></circle>
<circle class="person" data-gid="59" data-gruppe="Familie Stein (Studierenden-Familie 39)" data-name="Emilia Stein" cx="1987.38" cy="416.009" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Emilia Stein — Familie Stein (Studierenden-Familie 39)</title></circle>
<circle class="person" data-gid="59" data-gruppe="Familie Stein (Studierenden-Familie 39)" data-name="Ben Stein" cx="1968.71" cy="434.676" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Ben Stein — Familie Stein (Studierenden-Familie 39)</title></circle>
<circle class="person" data-gid="59" data-gruppe="Familie Stein (Studierenden-Familie 39)" data-name="Giovanna Stein" cx="1950.04" cy="416.009" r="12" fill="#fabed4" stroke="black" stroke-width="1"><title>Giovanna Stein — Familie Stein (Studierenden-Familie 39)</title></circle>
<ellipse cx="1968.71" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="1968.71" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">86</text>
<text x="1968.71" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
<circle cx="2151.38" cy="416.009" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle class="person" data-gid="10" data-gruppe="Institut fuer Informatik" data-name="Dr. Olga Klein" cx="2151.38" cy="397.341" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Dr. Olga Klein — Institut fuer Informatik</title></circle>
<circle class="person" data-gid="10" data-gruppe="Institut fuer Informatik" data-name="Dr. Jennifer Arnold" cx="2170.05" cy="416.009" r="12" fill="#000075" stroke="black" stroke-width="1"><title>Dr. Jennifer Arnold — Institut fuer Informatik</title></circle>
<circle class="person" data-gid="26" data-gruppe="Familie Frank (Studierenden-Familie 14)" data-name="Nadine Frank" cx="2151.38" cy="434.676" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Nadine Frank — Familie Frank (Studierenden-Familie 14)</title></circle>
<circle class="person" data-gid="26" data-gruppe="Familie Frank (Studierenden-Familie 14)" data-name="Dennis Frank" cx="2132.71" cy="416.009" r="12" fill="#4363d8" stroke="black" stroke-width="1"><title>Dennis Frank — Familie Frank (Studierenden-Familie 14)</title></circle>
<ellipse cx="2151.38" cy="416.009" rx="12" ry="15.6" fill="white" fill-opacity="0.75"/>
<text x="2151.38" y="411.209" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">88</text>
<text x="2151.38" y="424.409" text-anchor="middle" dominant-baseline="central" font-size="7.44" fill="#333">4 Pl.</text>
</svg>

After

Width:  |  Height:  |  Size: 122 KiB

+476
View File
@@ -0,0 +1,476 @@
[1]
[2]
Layla Lehmann = Hof 1, Tisch 2, Nummer 1
Thomas Lehmann = Hof 1, Tisch 2, Nummer 2
Nicole Lehmann = Hof 1, Tisch 2, Nummer 3
Markus Lehmann = Hof 1, Tisch 2, Nummer 4
[3]
Emre Klein = Hof 1, Tisch 3, Nummer 1
Dr. Patrick Kaya = Hof 1, Tisch 3, Nummer 2
Dr. Christina Krause = Hof 1, Tisch 3, Nummer 3
Julia Weber = Hof 1, Tisch 3, Nummer 4
[4]
Marco Winkler = Hof 1, Tisch 4, Nummer 1
Prof. Dr. Yusuf Seidel = Hof 1, Tisch 4, Nummer 2
Yusuf Bauer = Hof 1, Tisch 4, Nummer 3
Dr. Jan Bianchi = Hof 1, Tisch 4, Nummer 4
[5]
Dr. h.c. Alexander Grothe = Hof 1, Tisch 5, Nummer 1
Beate Grothe = Hof 1, Tisch 5, Nummer 2
Dr. Ferdinand Kessler = Hof 1, Tisch 5, Nummer 3
Viktoria Kessler = Hof 1, Tisch 5, Nummer 4
[6]
Elisabeth Steinbach = Hof 1, Tisch 6, Nummer 1
Dr. Konstantin Freiherr von Waldeck = Hof 1, Tisch 6, Nummer 2
Antonia Freifrau von Waldeck = Hof 1, Tisch 6, Nummer 3
Georg Steinbach = Hof 1, Tisch 6, Nummer 4
[7]
Heinrich Dallmann = Hof 1, Tisch 7, Nummer 1
Margarete Dallmann = Hof 1, Tisch 7, Nummer 2
Maximilian Dallmann = Hof 1, Tisch 7, Nummer 3
Charlotte Dallmann = Hof 1, Tisch 7, Nummer 4
[8]
Giovanna Hansen = Hof 1, Tisch 8, Nummer 1
Markus Hansen = Hof 1, Tisch 8, Nummer 2
Olga Hansen = Hof 1, Tisch 8, Nummer 3
[9]
Giovanna Ludwig = Hof 1, Tisch 9, Nummer 1
Emre Ludwig = Hof 1, Tisch 9, Nummer 2
Elif Ludwig = Hof 1, Tisch 9, Nummer 3
Elias Ludwig = Hof 1, Tisch 9, Nummer 4
[10]
Giovanna Petrov = Hof 1, Tisch 10, Nummer 1
Dr. Nadine Stein = Hof 1, Tisch 10, Nummer 2
Markus Schmitt = Hof 1, Tisch 10, Nummer 3
Christian Peters = Hof 1, Tisch 10, Nummer 4
[11]
Prof. Dr. Kathrin Petrov = Hof 1, Tisch 11, Nummer 1
Dr. Markus Seidel = Hof 1, Tisch 11, Nummer 2
Markus Kraus = Hof 1, Tisch 11, Nummer 3
[12]
Matthias Popescu = Hof 1, Tisch 12, Nummer 1
Sarah Albrecht = Hof 1, Tisch 12, Nummer 2
Andreas Albrecht = Hof 1, Tisch 12, Nummer 3
Prof. Dr. Markus Stein = Hof 1, Tisch 12, Nummer 4
[13]
Prof. Dr. Yusuf Albrecht = Hof 1, Tisch 13, Nummer 1
Giovanna Lehmann = Hof 1, Tisch 13, Nummer 2
Milan Lehmann = Hof 1, Tisch 13, Nummer 3
Svenja Simon = Hof 1, Tisch 13, Nummer 4
[14]
Nicole Becker = Hof 1, Tisch 14, Nummer 1
Jan Becker = Hof 1, Tisch 14, Nummer 2
Sandra Becker = Hof 1, Tisch 14, Nummer 3
[15]
Anja Nguyen = Hof 1, Tisch 15, Nummer 1
Daniel Nguyen = Hof 1, Tisch 15, Nummer 2
Sofia Nguyen = Hof 1, Tisch 15, Nummer 3
[16]
Thomas Hansen = Hof 1, Tisch 16, Nummer 1
Nicole Schmidt = Hof 1, Tisch 16, Nummer 2
Julia Nguyen = Hof 1, Tisch 16, Nummer 3
Dr. Stefanie Seifert = Hof 1, Tisch 16, Nummer 4
[17]
Thomas Winkler = Hof 1, Tisch 17, Nummer 1
Dr. Jan Esposito = Hof 1, Tisch 17, Nummer 2
Prof. Dr. Julia Roth = Hof 1, Tisch 17, Nummer 3
[18]
Stefanie Klein = Hof 1, Tisch 18, Nummer 1
Milan Klein = Hof 1, Tisch 18, Nummer 2
Lina Klein = Hof 1, Tisch 18, Nummer 3
[19]
Nicole Seifert = Hof 1, Tisch 19, Nummer 1
Yusuf Seifert = Hof 1, Tisch 19, Nummer 2
Leni Seifert = Hof 1, Tisch 19, Nummer 3
[20]
Timo Seifert = Hof 1, Tisch 20, Nummer 1
Elif Seifert = Hof 1, Tisch 20, Nummer 2
Julia Engel = Hof 1, Tisch 20, Nummer 3
Anton Engel = Hof 1, Tisch 20, Nummer 4
[21]
Nicole Engel = Hof 1, Tisch 21, Nummer 1
Anja Engel = Hof 1, Tisch 21, Nummer 2
Yusuf Engel = Hof 1, Tisch 21, Nummer 3
[22]
Prof. Dr. Anja Richter = Hof 1, Tisch 22, Nummer 1
Dr. Jan Thiel = Hof 1, Tisch 22, Nummer 2
Thomas Sahin = Hof 1, Tisch 22, Nummer 3
[23]
Sarah Roth = Hof 1, Tisch 23, Nummer 1
Christian Roth = Hof 1, Tisch 23, Nummer 2
Sofia Roth = Hof 1, Tisch 23, Nummer 3
[24]
Andreas Berger = Hof 1, Tisch 24, Nummer 1
Patrick Celik = Hof 1, Tisch 24, Nummer 2
Elif Celik = Hof 1, Tisch 24, Nummer 3
Svenja Berger = Hof 1, Tisch 24, Nummer 4
[25]
Nadine Aksoy = Hof 1, Tisch 25, Nummer 1
Thomas Aksoy = Hof 1, Tisch 25, Nummer 2
Marie Aksoy = Hof 1, Tisch 25, Nummer 3
[26]
Prof. Dr. Yusuf Ott = Hof 1, Tisch 26, Nummer 1
Dr. Nadine Berger = Hof 1, Tisch 26, Nummer 2
Patrick Lehmann = Hof 1, Tisch 26, Nummer 3
[27]
Jennifer Dietrich = Hof 1, Tisch 27, Nummer 1
Marco Dietrich = Hof 1, Tisch 27, Nummer 2
Sofia Dietrich = Hof 1, Tisch 27, Nummer 3
[28]
Prof. Dr. Timo Kaya = Hof 1, Tisch 28, Nummer 1
Dr. Sandra Demir = Hof 1, Tisch 28, Nummer 2
Lena Kovac = Hof 1, Tisch 28, Nummer 3
Tobias Kovac = Hof 1, Tisch 28, Nummer 4
[29]
Felix Nowak = Hof 1, Tisch 29, Nummer 1
Lena Winkler = Hof 1, Tisch 29, Nummer 2
Patrick Winkler = Hof 1, Tisch 29, Nummer 3
Kathrin Nowak = Hof 1, Tisch 29, Nummer 4
[30]
[31]
Prof. Dr. Julia Richter = Hof 1, Tisch 31, Nummer 1
Dr. Jennifer Haas = Hof 1, Tisch 31, Nummer 2
[32]
Jennifer Berger = Hof 1, Tisch 32, Nummer 1
Anton Berger = Hof 1, Tisch 32, Nummer 2
Layla Berger = Hof 1, Tisch 32, Nummer 3
Stefan Berger = Hof 1, Tisch 32, Nummer 4
[33]
Luca Aksoy = Hof 1, Tisch 33, Nummer 1
Sofia Aksoy = Hof 1, Tisch 33, Nummer 2
Sergej Aksoy = Hof 1, Tisch 33, Nummer 3
[34]
[35]
Leni Arnold = Hof 1, Tisch 35, Nummer 1
Christian Arnold = Hof 1, Tisch 35, Nummer 2
Mila Arnold = Hof 1, Tisch 35, Nummer 3
[36]
Marco Kovac = Hof 1, Tisch 36, Nummer 1
Anja Kovac = Hof 1, Tisch 36, Nummer 2
Henry Kovac = Hof 1, Tisch 36, Nummer 3
Marija Kovac = Hof 1, Tisch 36, Nummer 4
[37]
Aylin Nowak = Hof 1, Tisch 37, Nummer 1
Markus Nowak = Hof 1, Tisch 37, Nummer 2
Lina Nowak = Hof 1, Tisch 37, Nummer 3
Noah Nowak = Hof 1, Tisch 37, Nummer 4
[38]
Dr. Nicole Hansen = Hof 1, Tisch 38, Nummer 1
Thomas Krause = Hof 1, Tisch 38, Nummer 2
Kathrin Petrov = Hof 1, Tisch 38, Nummer 3
Milan Petrov = Hof 1, Tisch 38, Nummer 4
[39]
Markus Barth = Hof 1, Tisch 39, Nummer 1
Matthias Petrov = Hof 1, Tisch 39, Nummer 2
Andreas Weber = Hof 1, Tisch 39, Nummer 3
[40]
Melanie Rossi = Hof 1, Tisch 40, Nummer 1
Luca Rossi = Hof 1, Tisch 40, Nummer 2
Emilia Rossi = Hof 1, Tisch 40, Nummer 3
[41]
Julia Braun = Hof 1, Tisch 41, Nummer 1
Milan Braun = Hof 1, Tisch 41, Nummer 2
Nadine Braun = Hof 1, Tisch 41, Nummer 3
[42]
Jan Braun = Hof 1, Tisch 42, Nummer 1
Dragana Braun = Hof 1, Tisch 42, Nummer 2
Christian Braun = Hof 1, Tisch 42, Nummer 3
[43]
Jennifer Arnold = Hof 1, Tisch 43, Nummer 1
Patrick Arnold = Hof 1, Tisch 43, Nummer 2
Dragana Lange = Hof 1, Tisch 43, Nummer 3
Michael Lange = Hof 1, Tisch 43, Nummer 4
[44]
Jan Lange = Hof 1, Tisch 44, Nummer 1
Svenja Lange = Hof 1, Tisch 44, Nummer 2
Sofia Lange = Hof 1, Tisch 44, Nummer 3
[45]
Patrick Haas = Hof 1, Tisch 45, Nummer 1
Prof. Dr. Sergej Ott = Hof 1, Tisch 45, Nummer 2
Dragana Bauer = Hof 1, Tisch 45, Nummer 3
Nicole Peters = Hof 1, Tisch 45, Nummer 4
[46]
Yusuf Thiel = Hof 2, Tisch 46, Nummer 1
Christina Thiel = Hof 2, Tisch 46, Nummer 2
Julia Thiel = Hof 2, Tisch 46, Nummer 3
[47]
Sarah Schmitt = Hof 2, Tisch 47, Nummer 1
Markus Schmitt = Hof 2, Tisch 47, Nummer 2
Sofia Schmitt = Hof 2, Tisch 47, Nummer 3
[48]
Michael Koch = Hof 2, Tisch 48, Nummer 1
Emil Koch = Hof 2, Tisch 48, Nummer 2
Olga Koch = Hof 2, Tisch 48, Nummer 3
[49]
Sarah Koch = Hof 2, Tisch 49, Nummer 1
Jan Koch = Hof 2, Tisch 49, Nummer 2
Marie Koch = Hof 2, Tisch 49, Nummer 3
[50]
Anja Richter = Hof 2, Tisch 50, Nummer 1
Matthias Richter = Hof 2, Tisch 50, Nummer 2
Greta Richter = Hof 2, Tisch 50, Nummer 3
Anton Richter = Hof 2, Tisch 50, Nummer 4
[51]
Prof. Dr. Dennis Werner = Hof 2, Tisch 51, Nummer 1
Dr. Thomas Hoffmann = Hof 2, Tisch 51, Nummer 2
Olga Tran = Hof 2, Tisch 51, Nummer 3
Dr. Anja Seidel = Hof 2, Tisch 51, Nummer 4
[52]
Prof. Dr. Stefan Schmitt = Hof 2, Tisch 52, Nummer 1
Marija Tran = Hof 2, Tisch 52, Nummer 2
Dr. Kathrin Koch = Hof 2, Tisch 52, Nummer 3
Dr. Julia Kuhn = Hof 2, Tisch 52, Nummer 4
[53]
Prof. Dr. Dragana Dietrich = Hof 2, Tisch 53, Nummer 1
Dr. Michael Aksoy = Hof 2, Tisch 53, Nummer 2
Katrin Weber = Hof 2, Tisch 53, Nummer 3
Luca Werner = Hof 2, Tisch 53, Nummer 4
[54]
Sandra Bianchi = Hof 2, Tisch 54, Nummer 1
Thomas Bianchi = Hof 2, Tisch 54, Nummer 2
Mia Bianchi = Hof 2, Tisch 54, Nummer 3
[55]
Sandra Werner = Hof 2, Tisch 55, Nummer 1
Andreas Werner = Hof 2, Tisch 55, Nummer 2
Nadine Werner = Hof 2, Tisch 55, Nummer 3
Marco Werner = Hof 2, Tisch 55, Nummer 4
[56]
Olga Busch = Hof 2, Tisch 56, Nummer 1
Emre Busch = Hof 2, Tisch 56, Nummer 2
Marie Busch = Hof 2, Tisch 56, Nummer 3
Michael Busch = Hof 2, Tisch 56, Nummer 4
[57]
Prof. Dr. Emre Ludwig = Hof 2, Tisch 57, Nummer 1
Daniel Krause = Hof 2, Tisch 57, Nummer 2
Nicole Aksoy = Hof 2, Tisch 57, Nummer 3
Markus Klein = Hof 2, Tisch 57, Nummer 4
[58]
Prof. Dr. Marco Seifert = Hof 2, Tisch 58, Nummer 1
Matthias Krause = Hof 2, Tisch 58, Nummer 2
Giovanna Schwarz = Hof 2, Tisch 58, Nummer 3
[59]
Prof. Dr. Thomas Tran = Hof 2, Tisch 59, Nummer 1
Sergej Petrov = Hof 2, Tisch 59, Nummer 2
Kathrin Polat = Hof 2, Tisch 59, Nummer 3
Marija Aksoy = Hof 2, Tisch 59, Nummer 4
[60]
Nicole Sahin = Hof 2, Tisch 60, Nummer 1
Markus Sahin = Hof 2, Tisch 60, Nummer 2
Kathrin Sahin = Hof 2, Tisch 60, Nummer 3
Patrick Sahin = Hof 2, Tisch 60, Nummer 4
[61]
Sarah Maier = Hof 2, Tisch 61, Nummer 1
Christian Maier = Hof 2, Tisch 61, Nummer 2
Olga Maier = Hof 2, Tisch 61, Nummer 3
Arda Maier = Hof 2, Tisch 61, Nummer 4
[62]
Luca Kovac = Hof 2, Tisch 62, Nummer 1
Dr. Dragana Krause = Hof 2, Tisch 62, Nummer 2
Prof. Dr. Dennis Schmitt = Hof 2, Tisch 62, Nummer 3
[63]
Andreas Krause = Hof 2, Tisch 63, Nummer 1
Emma Krause = Hof 2, Tisch 63, Nummer 2
Arda Krause = Hof 2, Tisch 63, Nummer 3
Julia Krause = Hof 2, Tisch 63, Nummer 4
[64]
Katrin Werner = Hof 2, Tisch 64, Nummer 1
Patrick Busch = Hof 2, Tisch 64, Nummer 2
Emre Hoffmann = Hof 2, Tisch 64, Nummer 3
Sergej Lange = Hof 2, Tisch 64, Nummer 4
[65]
Nadine Arnold = Hof 2, Tisch 65, Nummer 1
Marco Richter = Hof 2, Tisch 65, Nummer 2
Prof. Dr. Patrick Hoffmann = Hof 2, Tisch 65, Nummer 3
Marija Polat = Hof 2, Tisch 65, Nummer 4
[66]
Lena Simon = Hof 2, Tisch 66, Nummer 1
Markus Simon = Hof 2, Tisch 66, Nummer 2
Emma Simon = Hof 2, Tisch 66, Nummer 3
Andreas Simon = Hof 2, Tisch 66, Nummer 4
[67]
Yusuf Weber = Hof 2, Tisch 67, Nummer 1
Dr. Patrick Kraus = Hof 2, Tisch 67, Nummer 2
Dr. Aylin Ludwig = Hof 2, Tisch 67, Nummer 3
[68]
Nicole Wagner = Hof 2, Tisch 68, Nummer 1
Marco Wagner = Hof 2, Tisch 68, Nummer 2
Sarah Wagner = Hof 2, Tisch 68, Nummer 3
Henry Wagner = Hof 2, Tisch 68, Nummer 4
[69]
Olga Franke = Hof 2, Tisch 69, Nummer 1
Amira Franke = Hof 2, Tisch 69, Nummer 2
Marco Franke = Hof 2, Tisch 69, Nummer 3
[70]
Svenja Zimmermann = Hof 2, Tisch 70, Nummer 1
Jan Zimmermann = Hof 2, Tisch 70, Nummer 2
Mia Zimmermann = Hof 2, Tisch 70, Nummer 3
Markus Zimmermann = Hof 2, Tisch 70, Nummer 4
[71]
Luca Ott = Hof 2, Tisch 71, Nummer 1
Patrick Zimmermann = Hof 2, Tisch 71, Nummer 2
Stefan Richter = Hof 2, Tisch 71, Nummer 3
[72]
Matthias Ott = Hof 2, Tisch 72, Nummer 1
Hannah Ott = Hof 2, Tisch 72, Nummer 2
Olga Ott = Hof 2, Tisch 72, Nummer 3
[73]
Jennifer Neumann = Hof 2, Tisch 73, Nummer 1
Thomas Neumann = Hof 2, Tisch 73, Nummer 2
Lina Neumann = Hof 2, Tisch 73, Nummer 3
Matteo Neumann = Hof 2, Tisch 73, Nummer 4
[74]
Patrick Barth = Hof 2, Tisch 74, Nummer 1
Nadine Barth = Hof 2, Tisch 74, Nummer 2
Timo Barth = Hof 2, Tisch 74, Nummer 3
Lina Barth = Hof 2, Tisch 74, Nummer 4
[75]
Dragana Pohl = Hof 2, Tisch 75, Nummer 1
Emre Pohl = Hof 2, Tisch 75, Nummer 2
Mia Pohl = Hof 2, Tisch 75, Nummer 3
Theo Pohl = Hof 2, Tisch 75, Nummer 4
[76]
Prof. Dr. Yusuf Esposito = Hof 2, Tisch 76, Nummer 1
Marija Becker = Hof 2, Tisch 76, Nummer 2
Matthias Kovac = Hof 2, Tisch 76, Nummer 3
[77]
Luca Kaya = Hof 2, Tisch 77, Nummer 1
Christina Kaya = Hof 2, Tisch 77, Nummer 2
Nicole Kaya = Hof 2, Tisch 77, Nummer 3
[78]
Deniz Hartmann = Hof 2, Tisch 78, Nummer 1
Nadine Hartmann = Hof 2, Tisch 78, Nummer 2
Michael Franke = Hof 2, Tisch 78, Nummer 3
Julia Franke = Hof 2, Tisch 78, Nummer 4
[79]
Kathrin Horn = Hof 2, Tisch 79, Nummer 1
Michael Horn = Hof 2, Tisch 79, Nummer 2
Layla Horn = Hof 2, Tisch 79, Nummer 3
Leon Horn = Hof 2, Tisch 79, Nummer 4
[80]
Stefanie Polat = Hof 2, Tisch 80, Nummer 1
Stefan Polat = Hof 2, Tisch 80, Nummer 2
Melanie Ott = Hof 2, Tisch 80, Nummer 3
Daniel Ott = Hof 2, Tisch 80, Nummer 4
[81]
Sarah Polat = Hof 2, Tisch 81, Nummer 1
Markus Polat = Hof 2, Tisch 81, Nummer 2
Katrin Polat = Hof 2, Tisch 81, Nummer 3
[82]
Olga Roth = Hof 2, Tisch 82, Nummer 1
Prof. Dr. Emre Albrecht = Hof 2, Tisch 82, Nummer 2
Thomas Bianchi = Hof 2, Tisch 82, Nummer 3
[83]
Emma Wolf = Hof 2, Tisch 83, Nummer 1
Ben Wolf = Hof 2, Tisch 83, Nummer 2
Julia Wolf = Hof 2, Tisch 83, Nummer 3
Thomas Wolf = Hof 2, Tisch 83, Nummer 4
[84]
Marija Hartmann = Hof 2, Tisch 84, Nummer 1
Thomas Hartmann = Hof 2, Tisch 84, Nummer 2
Olga Hartmann = Hof 2, Tisch 84, Nummer 3
[85]
Matthias Schmidt = Hof 2, Tisch 85, Nummer 1
Marie Schmidt = Hof 2, Tisch 85, Nummer 2
Giovanna Schmidt = Hof 2, Tisch 85, Nummer 3
[86]
Thomas Stein = Hof 2, Tisch 86, Nummer 1
Emilia Stein = Hof 2, Tisch 86, Nummer 2
Ben Stein = Hof 2, Tisch 86, Nummer 3
Giovanna Stein = Hof 2, Tisch 86, Nummer 4
[87]
Lena Frank = Hof 2, Tisch 87, Nummer 1
Marie Frank = Hof 2, Tisch 87, Nummer 2
Finn Frank = Hof 2, Tisch 87, Nummer 3
[88]
Dr. Olga Klein = Hof 2, Tisch 88, Nummer 1
Dr. Jennifer Arnold = Hof 2, Tisch 88, Nummer 2
Nadine Frank = Hof 2, Tisch 88, Nummer 3
Dennis Frank = Hof 2, Tisch 88, Nummer 4
+111
View File
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="1240" height="420" viewBox="0 0 1240 420" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="620" y="26" text-anchor="middle" font-size="18" fill="#333">Sommerfest - Umfeld/Grundriss: zwei trapezfoermige Innenhoefe (88 Vierertische, 300 Gaeste)</text>
<polygon points="48,96 512,96 432,320 128,320" fill="#f5f0e6" stroke="#7a6a50" stroke-width="2"/>
<text x="280" y="342" text-anchor="middle" font-size="14" fill="#7a6a50">Hof 1 (Tische 1-45)</text>
<polygon points="688,96 1152,96 1032,320 808,320" fill="#f5f0e6" stroke="#7a6a50" stroke-width="2"/>
<text x="920" y="342" text-anchor="middle" font-size="14" fill="#7a6a50">Hof 2 (Tische 46-88)</text>
<rect x="536" y="24" width="168" height="48" fill="#d9c9e8" stroke="#6b4d8a" stroke-width="2"/>
<text x="620" y="50" text-anchor="middle" font-size="13" fill="#4a3465">Buehne - Band</text>
<rect x="536" y="92" width="168" height="176" fill="#cfe3f0" stroke="#4a7ba0" stroke-width="2" stroke-dasharray="8 4"/>
<text x="620" y="180" text-anchor="middle" font-size="13" fill="#2d566f">Tanzflaeche</text>
<text x="16" y="208" text-anchor="start" font-size="12" fill="#a03030">Eingang West</text>
<text x="1184" y="208" text-anchor="end" font-size="12" fill="#a03030">Eingang Ost</text>
<text x="620" y="328" text-anchor="middle" font-size="12" fill="#a03030">Eingang Sued</text>
<polygon points="42,192 42,224 66,208" fill="#a03030"/>
<polygon points="1158,192 1158,224 1134,208" fill="#a03030"/>
<polygon points="604,318 636,318 620,294" fill="#a03030"/>
<circle cx="80" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="120" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="160" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="200" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="240" cy="128" r="12" fill="white" stroke="#c0392b" stroke-width="2.5"/>
<text x="240" y="131" text-anchor="middle" font-size="9" fill="#c0392b">VIP</text>
<circle cx="280" cy="128" r="12" fill="white" stroke="#c0392b" stroke-width="2.5"/>
<text x="280" y="131" text-anchor="middle" font-size="9" fill="#c0392b">VIP</text>
<circle cx="320" cy="128" r="12" fill="white" stroke="#c0392b" stroke-width="2.5"/>
<text x="320" y="131" text-anchor="middle" font-size="9" fill="#c0392b">VIP</text>
<circle cx="360" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="400" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="440" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="480" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="100" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="140" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="180" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="220" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="260" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="300" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="340" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="380" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="420" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="460" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="120" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="160" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="200" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="240" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="280" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="320" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="360" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="400" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="440" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="140" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="180" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="220" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="260" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="300" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="340" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="380" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="420" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="160" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="200" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="240" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="280" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="320" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="360" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="400" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="720" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="760" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="800" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="840" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="880" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="920" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="960" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1000" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1040" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1080" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1120" cy="128" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="740" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="780" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="820" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="860" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="900" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="940" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="980" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1020" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1060" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1100" cy="168" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="760" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="800" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="840" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="880" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="920" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="960" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1000" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1040" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1080" cy="208" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="780" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="820" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="860" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="900" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="940" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="980" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1020" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1060" cy="248" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="840" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="880" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="920" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="960" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<circle cx="1000" cy="288" r="12" fill="white" stroke="#999999" stroke-width="1"/>
<text x="620" y="408" text-anchor="middle" font-size="11" fill="#888">Umfeld.svg - Grundriss-Elemente (Buehne, Band, Tanzflaeche, Eingaenge) werden nicht mitoptimiert; VIP-Tische 5/6/7 vor der Buehne</text>
</svg>

After

Width:  |  Height:  |  Size: 9.1 KiB

+301
View File
@@ -0,0 +1,301 @@
Vorname;Nachname;Titel;Gruppe;Tisch;Anzahl
Alexander;Grothe;Dr. h.c.;VIP Industrie: Vorstand Automobilkonzern (fest an Tisch 5, vor der Buehne);5;
Beate;Grothe;;VIP Industrie: Vorstand Automobilkonzern (fest an Tisch 5, vor der Buehne);5;
Ferdinand;Kessler;Dr.;VIP Industrie: Vorstand Automobilkonzern (fest an Tisch 5, vor der Buehne);5;
Viktoria;Kessler;;VIP Industrie: Vorstand Automobilkonzern (fest an Tisch 5, vor der Buehne);5;
Konstantin;Freiherr von Waldeck;Dr.;VIP Wirtschaft: Bankvorstand (fest an Tisch 6);6;
Antonia;Freifrau von Waldeck;;VIP Wirtschaft: Bankvorstand (fest an Tisch 6);6;
Georg;Steinbach;;VIP Wirtschaft: Bankvorstand (fest an Tisch 6);6;
Elisabeth;Steinbach;;VIP Wirtschaft: Bankvorstand (fest an Tisch 6);6;
Heinrich;Dallmann;;VIP Industrie: Unternehmerfamilie (fest an Tisch 7);7;
Margarete;Dallmann;;VIP Industrie: Unternehmerfamilie (fest an Tisch 7);7;
Maximilian;Dallmann;;VIP Industrie: Unternehmerfamilie (fest an Tisch 7);7;
Charlotte;Dallmann;;VIP Industrie: Unternehmerfamilie (fest an Tisch 7);7;
Sandra;Bianchi;;Familie Bianchi (Studierenden-Familie 1);;
Thomas;Bianchi;;Familie Bianchi (Studierenden-Familie 1);;
Mia;Bianchi;;Familie Bianchi (Studierenden-Familie 1);;
Jennifer;Arnold;;Familie Arnold (Studierenden-Familie 2);;
Patrick;Arnold;;Familie Arnold (Studierenden-Familie 2);;
Leni;Arnold;;Familie Arnold (Studierenden-Familie 2);;
Christian;Arnold;;Familie Arnold (Studierenden-Familie 2);;
Mila;Arnold;;Familie Arnold (Studierenden-Familie 2);;
Nicole;Seifert;;Familie Seifert (Studierenden-Familie 3);;
Yusuf;Seifert;;Familie Seifert (Studierenden-Familie 3);;
Leni;Seifert;;Familie Seifert (Studierenden-Familie 3);;
Timo;Seifert;;Familie Seifert (Studierenden-Familie 3);;
Elif;Seifert;;Familie Seifert (Studierenden-Familie 3);;
Sarah;Albrecht;;Familie Albrecht (Studierenden-Familie 4);;
Andreas;Albrecht;;Familie Albrecht (Studierenden-Familie 4);;
Yusuf;Esposito;Prof. Dr.;Institut fuer Maschinenwesen;;
Marija;Becker;;Institut fuer Maschinenwesen;;
Matthias;Kovac;;Institut fuer Maschinenwesen;;
Nicole;Kaya;;Familie Kaya (Studierenden-Familie 5);;
Luca;Kaya;;Familie Kaya (Studierenden-Familie 5);;
Christina;Kaya;;Familie Kaya (Studierenden-Familie 5);;
Julia;Richter;Prof. Dr.;Lehrstuhl Thermodynamik;;
Jennifer;Haas;Dr.;Lehrstuhl Thermodynamik;;
Markus;Barth;;Lehrstuhl Thermodynamik;;
Matthias;Petrov;;Lehrstuhl Thermodynamik;;
Andreas;Weber;;Lehrstuhl Thermodynamik;;
Giovanna;Schmidt;;Familie Schmidt (Studierenden-Familie 6);;
Matthias;Schmidt;;Familie Schmidt (Studierenden-Familie 6);;
Marie;Schmidt;;Familie Schmidt (Studierenden-Familie 6);;
Anja;Richter;;Familie Richter (Studierenden-Familie 7);;
Matthias;Richter;;Familie Richter (Studierenden-Familie 7);;
Greta;Richter;;Familie Richter (Studierenden-Familie 7);;
Anton;Richter;;Familie Richter (Studierenden-Familie 7);;
Emre;Albrecht;Prof. Dr.;Institut fuer Informatik;;
Thomas;Bianchi;;Institut fuer Informatik;;
Olga;Roth;;Institut fuer Informatik;;
Olga;Klein;Dr.;Institut fuer Informatik;;
Jennifer;Arnold;Dr.;Institut fuer Informatik;;
Dennis;Werner;Prof. Dr.;Lehrstuhl Regelungstechnik;;
Thomas;Hoffmann;Dr.;Lehrstuhl Regelungstechnik;;
Olga;Tran;;Lehrstuhl Regelungstechnik;;
Anja;Seidel;Dr.;Lehrstuhl Regelungstechnik;;
Markus;Stein;Prof. Dr.;Institut fuer Werkstoffkunde;;
Matthias;Popescu;;Institut fuer Werkstoffkunde;;
Yusuf;Albrecht;Prof. Dr.;Lehrstuhl Stroemungsmechanik;;
Svenja;Simon;;Lehrstuhl Stroemungsmechanik;;
Julia;Roth;Prof. Dr.;Institut fuer Elektrotechnik;;
Thomas;Hansen;;Institut fuer Elektrotechnik;;
Nicole;Schmidt;;Institut fuer Elektrotechnik;;
Julia;Nguyen;;Institut fuer Elektrotechnik;;
Stefanie;Seifert;Dr.;Institut fuer Elektrotechnik;;
Thomas;Winkler;;Institut fuer Elektrotechnik;;
Jan;Esposito;Dr.;Institut fuer Elektrotechnik;;
Nicole;Becker;;Familie Becker (Studierenden-Familie 8);;
Jan;Becker;;Familie Becker (Studierenden-Familie 8);;
Sandra;Becker;;Familie Becker (Studierenden-Familie 8);;
Kathrin;Petrov;Prof. Dr.;Lehrstuhl Mathematik;;
Markus;Seidel;Dr.;Lehrstuhl Mathematik;;
Markus;Kraus;;Lehrstuhl Mathematik;;
Giovanna;Petrov;;Lehrstuhl Mathematik;;
Nadine;Stein;Dr.;Lehrstuhl Mathematik;;
Markus;Schmitt;;Lehrstuhl Mathematik;;
Christian;Peters;;Lehrstuhl Mathematik;;
Anja;Nguyen;;Familie Nguyen (Studierenden-Familie 9);;
Daniel;Nguyen;;Familie Nguyen (Studierenden-Familie 9);;
Sofia;Nguyen;;Familie Nguyen (Studierenden-Familie 9);;
Elif;Celik;;Familie Celik (Studierenden-Familie 10);;
Patrick;Celik;;Familie Celik (Studierenden-Familie 10);;
Stefanie;Klein;;Familie Klein (Studierenden-Familie 11);;
Milan;Klein;;Familie Klein (Studierenden-Familie 11);;
Lina;Klein;;Familie Klein (Studierenden-Familie 11);;
Olga;Busch;;Familie Busch (Studierenden-Familie 12);;
Emre;Busch;;Familie Busch (Studierenden-Familie 12);;
Marie;Busch;;Familie Busch (Studierenden-Familie 12);;
Michael;Busch;;Familie Busch (Studierenden-Familie 12);;
Stefan;Schmitt;Prof. Dr.;Institut fuer Physik;;
Marija;Tran;;Institut fuer Physik;;
Kathrin;Koch;Dr.;Institut fuer Physik;;
Julia;Kuhn;Dr.;Institut fuer Physik;;
Katrin;Weber;;Institut fuer Physik;;
Luca;Werner;;Institut fuer Physik;;
Anja;Engel;;Familie Engel (Studierenden-Familie 13);;
Yusuf;Engel;;Familie Engel (Studierenden-Familie 13);;
Julia;Engel;;Familie Engel (Studierenden-Familie 13);;
Anton;Engel;;Familie Engel (Studierenden-Familie 13);;
Nicole;Engel;;Familie Engel (Studierenden-Familie 13);;
Emre;Ludwig;Prof. Dr.;Lehrstuhl Produktionstechnik;;
Daniel;Krause;;Lehrstuhl Produktionstechnik;;
Nicole;Aksoy;;Lehrstuhl Produktionstechnik;;
Markus;Klein;;Lehrstuhl Produktionstechnik;;
Dennis;Schmitt;Prof. Dr.;Institut fuer Chemie;;
Luca;Kovac;;Institut fuer Chemie;;
Dragana;Krause;Dr.;Institut fuer Chemie;;
Luca;Ott;;Institut fuer Chemie;;
Patrick;Zimmermann;;Institut fuer Chemie;;
Stefan;Richter;;Institut fuer Chemie;;
Yusuf;Seidel;Prof. Dr.;Lehrstuhl Fahrzeugtechnik;;
Yusuf;Bauer;;Lehrstuhl Fahrzeugtechnik;;
Jan;Bianchi;Dr.;Lehrstuhl Fahrzeugtechnik;;
Marco;Winkler;;Lehrstuhl Fahrzeugtechnik;;
Emre;Klein;;Lehrstuhl Fahrzeugtechnik;;
Patrick;Kaya;Dr.;Lehrstuhl Fahrzeugtechnik;;
Christina;Krause;Dr.;Lehrstuhl Fahrzeugtechnik;;
Nadine;Frank;;Familie Frank (Studierenden-Familie 14);;
Dennis;Frank;;Familie Frank (Studierenden-Familie 14);;
Marie;Frank;;Familie Frank (Studierenden-Familie 14);;
Finn;Frank;;Familie Frank (Studierenden-Familie 14);;
Lena;Frank;;Familie Frank (Studierenden-Familie 14);;
Sandra;Werner;;Familie Werner (Studierenden-Familie 15);;
Andreas;Werner;;Familie Werner (Studierenden-Familie 15);;
Nadine;Werner;;Familie Werner (Studierenden-Familie 15);;
Marco;Werner;;Familie Werner (Studierenden-Familie 15);;
Sarah;Roth;;Familie Roth (Studierenden-Familie 16);;
Christian;Roth;;Familie Roth (Studierenden-Familie 16);;
Sofia;Roth;;Familie Roth (Studierenden-Familie 16);;
Marco;Seifert;Prof. Dr.;Institut fuer Bauingenieurwesen;;
Matthias;Krause;;Institut fuer Bauingenieurwesen;;
Giovanna;Schwarz;;Institut fuer Bauingenieurwesen;;
Yusuf;Weber;;Institut fuer Bauingenieurwesen;;
Patrick;Kraus;Dr.;Institut fuer Bauingenieurwesen;;
Aylin;Ludwig;Dr.;Institut fuer Bauingenieurwesen;;
Patrick;Hoffmann;Prof. Dr.;Lehrstuhl Messtechnik;;
Marija;Polat;;Lehrstuhl Messtechnik;;
Nadine;Arnold;;Lehrstuhl Messtechnik;;
Marco;Richter;;Lehrstuhl Messtechnik;;
Dragana;Dietrich;Prof. Dr.;Doktorandenrunde Energietechnik;;
Michael;Aksoy;Dr.;Doktorandenrunde Energietechnik;;
Katrin;Werner;;Doktorandenrunde Energietechnik;;
Patrick;Busch;;Doktorandenrunde Energietechnik;;
Emre;Hoffmann;;Doktorandenrunde Energietechnik;;
Sergej;Lange;;Doktorandenrunde Energietechnik;;
Anja;Richter;Prof. Dr.;Doktorandenrunde Robotik;;
Jan;Thiel;Dr.;Doktorandenrunde Robotik;;
Thomas;Sahin;;Doktorandenrunde Robotik;;
Sarah;Koch;;Familie Koch (Studierenden-Familie 17);;
Jan;Koch;;Familie Koch (Studierenden-Familie 17);;
Marie;Koch;;Familie Koch (Studierenden-Familie 17);;
Emil;Koch;;Familie Koch (Studierenden-Familie 17);;
Olga;Koch;;Familie Koch (Studierenden-Familie 17);;
Michael;Koch;;Familie Koch (Studierenden-Familie 17);;
Thomas;Tran;Prof. Dr.;Emeriti-Stammtisch;;
Sergej;Petrov;;Emeriti-Stammtisch;;
Kathrin;Polat;;Emeriti-Stammtisch;;
Marija;Aksoy;;Emeriti-Stammtisch;;
Sergej;Ott;Prof. Dr.;Institut fuer Verfahrenstechnik;;
Dragana;Bauer;;Institut fuer Verfahrenstechnik;;
Nicole;Peters;;Institut fuer Verfahrenstechnik;;
Nicole;Hansen;Dr.;Institut fuer Verfahrenstechnik;;
Thomas;Krause;;Institut fuer Verfahrenstechnik;;
Patrick;Haas;;Institut fuer Verfahrenstechnik;;
Timo;Kaya;Prof. Dr.;Lehrstuhl Mechatronik;;
Sandra;Demir;Dr.;Lehrstuhl Mechatronik;;
Yusuf;Ott;Prof. Dr.;Institut fuer Luftfahrttechnik;;
Nadine;Berger;Dr.;Institut fuer Luftfahrttechnik;;
Patrick;Lehmann;;Institut fuer Luftfahrttechnik;;
Nicole;Wagner;;Familie Wagner (Studierenden-Familie 18);;
Marco;Wagner;;Familie Wagner (Studierenden-Familie 18);;
Sarah;Wagner;;Familie Wagner (Studierenden-Familie 18);;
Henry;Wagner;;Familie Wagner (Studierenden-Familie 18);;
Jennifer;Dietrich;;Familie Dietrich (Studierenden-Familie 19);;
Marco;Dietrich;;Familie Dietrich (Studierenden-Familie 19);;
Sofia;Dietrich;;Familie Dietrich (Studierenden-Familie 19);;
Julia;Thiel;;Familie Thiel (Studierenden-Familie 20);;
Yusuf;Thiel;;Familie Thiel (Studierenden-Familie 20);;
Christina;Thiel;;Familie Thiel (Studierenden-Familie 20);;
Sarah;Schmitt;;Familie Schmitt (Studierenden-Familie 21);;
Markus;Schmitt;;Familie Schmitt (Studierenden-Familie 21);;
Sofia;Schmitt;;Familie Schmitt (Studierenden-Familie 21);;
Marija;Hartmann;;Familie Hartmann (Studierenden-Familie 22);;
Thomas;Hartmann;;Familie Hartmann (Studierenden-Familie 22);;
Olga;Hartmann;;Familie Hartmann (Studierenden-Familie 22);;
Deniz;Hartmann;;Familie Hartmann (Studierenden-Familie 22);;
Nadine;Hartmann;;Familie Hartmann (Studierenden-Familie 22);;
Melanie;Rossi;;Familie Rossi (Studierenden-Familie 23);;
Luca;Rossi;;Familie Rossi (Studierenden-Familie 23);;
Emilia;Rossi;;Familie Rossi (Studierenden-Familie 23);;
Julia;Braun;;Familie Braun (Studierenden-Familie 24);;
Milan;Braun;;Familie Braun (Studierenden-Familie 24);;
Nadine;Braun;;Familie Braun (Studierenden-Familie 24);;
Jan;Braun;;Familie Braun (Studierenden-Familie 24);;
Dragana;Braun;;Familie Braun (Studierenden-Familie 24);;
Christian;Braun;;Familie Braun (Studierenden-Familie 24);;
Svenja;Zimmermann;;Familie Zimmermann (Studierenden-Familie 25);;
Jan;Zimmermann;;Familie Zimmermann (Studierenden-Familie 25);;
Mia;Zimmermann;;Familie Zimmermann (Studierenden-Familie 25);;
Markus;Zimmermann;;Familie Zimmermann (Studierenden-Familie 25);;
Julia;Krause;;Familie Krause (Studierenden-Familie 26);;
Andreas;Krause;;Familie Krause (Studierenden-Familie 26);;
Emma;Krause;;Familie Krause (Studierenden-Familie 26);;
Arda;Krause;;Familie Krause (Studierenden-Familie 26);;
Aylin;Nowak;;Familie Nowak (Studierenden-Familie 27);;
Markus;Nowak;;Familie Nowak (Studierenden-Familie 27);;
Lina;Nowak;;Familie Nowak (Studierenden-Familie 27);;
Noah;Nowak;;Familie Nowak (Studierenden-Familie 27);;
Kathrin;Nowak;;Familie Nowak (Studierenden-Familie 27);;
Felix;Nowak;;Familie Nowak (Studierenden-Familie 27);;
Kathrin;Horn;;Familie Horn (Studierenden-Familie 28);;
Michael;Horn;;Familie Horn (Studierenden-Familie 28);;
Layla;Horn;;Familie Horn (Studierenden-Familie 28);;
Leon;Horn;;Familie Horn (Studierenden-Familie 28);;
Melanie;Ott;;Familie Ott (Studierenden-Familie 29);;
Daniel;Ott;;Familie Ott (Studierenden-Familie 29);;
Olga;Ott;;Familie Ott (Studierenden-Familie 29);;
Matthias;Ott;;Familie Ott (Studierenden-Familie 29);;
Hannah;Ott;;Familie Ott (Studierenden-Familie 29);;
Jennifer;Neumann;;Familie Neumann (Studierenden-Familie 30);;
Thomas;Neumann;;Familie Neumann (Studierenden-Familie 30);;
Lina;Neumann;;Familie Neumann (Studierenden-Familie 30);;
Matteo;Neumann;;Familie Neumann (Studierenden-Familie 30);;
Julia;Wolf;;Familie Wolf (Studierenden-Familie 31);;
Thomas;Wolf;;Familie Wolf (Studierenden-Familie 31);;
Emma;Wolf;;Familie Wolf (Studierenden-Familie 31);;
Ben;Wolf;;Familie Wolf (Studierenden-Familie 31);;
Nadine;Aksoy;;Familie Aksoy (Studierenden-Familie 32);;
Thomas;Aksoy;;Familie Aksoy (Studierenden-Familie 32);;
Marie;Aksoy;;Familie Aksoy (Studierenden-Familie 32);;
Luca;Aksoy;;Familie Aksoy (Studierenden-Familie 32);;
Sofia;Aksoy;;Familie Aksoy (Studierenden-Familie 32);;
Sergej;Aksoy;;Familie Aksoy (Studierenden-Familie 32);;
Giovanna;Hansen;;Familie Hansen (Studierenden-Familie 33);;
Markus;Hansen;;Familie Hansen (Studierenden-Familie 33);;
Olga;Hansen;;Familie Hansen (Studierenden-Familie 33);;
Stefanie;Polat;;Familie Polat (Studierenden-Familie 34);;
Stefan;Polat;;Familie Polat (Studierenden-Familie 34);;
Sarah;Polat;;Familie Polat (Studierenden-Familie 34);;
Markus;Polat;;Familie Polat (Studierenden-Familie 34);;
Katrin;Polat;;Familie Polat (Studierenden-Familie 34);;
Olga;Franke;;Familie Franke (Studierenden-Familie 35);;
Marco;Franke;;Familie Franke (Studierenden-Familie 35);;
Amira;Franke;;Familie Franke (Studierenden-Familie 35);;
Michael;Franke;;Familie Franke (Studierenden-Familie 35);;
Julia;Franke;;Familie Franke (Studierenden-Familie 35);;
Lena;Kovac;;Familie Kovac (Studierenden-Familie 36);;
Tobias;Kovac;;Familie Kovac (Studierenden-Familie 36);;
Marija;Kovac;;Familie Kovac (Studierenden-Familie 36);;
Marco;Kovac;;Familie Kovac (Studierenden-Familie 36);;
Anja;Kovac;;Familie Kovac (Studierenden-Familie 36);;
Henry;Kovac;;Familie Kovac (Studierenden-Familie 36);;
Lena;Winkler;;Familie Winkler (Studierenden-Familie 37);;
Patrick;Winkler;;Familie Winkler (Studierenden-Familie 37);;
Kathrin;Petrov;;Familie Petrov (Studierenden-Familie 38);;
Milan;Petrov;;Familie Petrov (Studierenden-Familie 38);;
Giovanna;Stein;;Familie Stein (Studierenden-Familie 39);;
Thomas;Stein;;Familie Stein (Studierenden-Familie 39);;
Emilia;Stein;;Familie Stein (Studierenden-Familie 39);;
Ben;Stein;;Familie Stein (Studierenden-Familie 39);;
Dragana;Pohl;;Familie Pohl (Studierenden-Familie 40);;
Emre;Pohl;;Familie Pohl (Studierenden-Familie 40);;
Mia;Pohl;;Familie Pohl (Studierenden-Familie 40);;
Theo;Pohl;;Familie Pohl (Studierenden-Familie 40);;
Svenja;Berger;;Familie Berger (Studierenden-Familie 41);;
Andreas;Berger;;Familie Berger (Studierenden-Familie 41);;
Jennifer;Berger;;Familie Berger (Studierenden-Familie 41);;
Anton;Berger;;Familie Berger (Studierenden-Familie 41);;
Layla;Berger;;Familie Berger (Studierenden-Familie 41);;
Stefan;Berger;;Familie Berger (Studierenden-Familie 41);;
Nadine;Barth;;Familie Barth (Studierenden-Familie 42);;
Timo;Barth;;Familie Barth (Studierenden-Familie 42);;
Lina;Barth;;Familie Barth (Studierenden-Familie 42);;
Patrick;Barth;;Familie Barth (Studierenden-Familie 42);;
Lena;Simon;;Familie Simon (Studierenden-Familie 43);;
Markus;Simon;;Familie Simon (Studierenden-Familie 43);;
Emma;Simon;;Familie Simon (Studierenden-Familie 43);;
Andreas;Simon;;Familie Simon (Studierenden-Familie 43);;
Dragana;Lange;;Familie Lange (Studierenden-Familie 44);;
Michael;Lange;;Familie Lange (Studierenden-Familie 44);;
Sofia;Lange;;Familie Lange (Studierenden-Familie 44);;
Jan;Lange;;Familie Lange (Studierenden-Familie 44);;
Svenja;Lange;;Familie Lange (Studierenden-Familie 44);;
Giovanna;Lehmann;;Familie Lehmann (Studierenden-Familie 45);;
Milan;Lehmann;;Familie Lehmann (Studierenden-Familie 45);;
Layla;Lehmann;;Familie Lehmann (Studierenden-Familie 45);;
Thomas;Lehmann;;Familie Lehmann (Studierenden-Familie 45);;
Nicole;Lehmann;;Familie Lehmann (Studierenden-Familie 45);;
Markus;Lehmann;;Familie Lehmann (Studierenden-Familie 45);;
Sarah;Maier;;Familie Maier (Studierenden-Familie 46);;
Christian;Maier;;Familie Maier (Studierenden-Familie 46);;
Olga;Maier;;Familie Maier (Studierenden-Familie 46);;
Arda;Maier;;Familie Maier (Studierenden-Familie 46);;
Nicole;Sahin;;Familie Sahin (Studierenden-Familie 47);;
Markus;Sahin;;Familie Sahin (Studierenden-Familie 47);;
Kathrin;Sahin;;Familie Sahin (Studierenden-Familie 47);;
Patrick;Sahin;;Familie Sahin (Studierenden-Familie 47);;
Giovanna;Ludwig;;Familie Ludwig (Studierenden-Familie 48);;
Emre;Ludwig;;Familie Ludwig (Studierenden-Familie 48);;
Elif;Ludwig;;Familie Ludwig (Studierenden-Familie 48);;
Elias;Ludwig;;Familie Ludwig (Studierenden-Familie 48);;
Julia;Weber;;Familie Weber (Studierenden-Familie 49);;
1 Vorname Nachname Titel Gruppe Tisch Anzahl
2 Alexander Grothe Dr. h.c. VIP Industrie: Vorstand Automobilkonzern (fest an Tisch 5, vor der Buehne) 5
3 Beate Grothe VIP Industrie: Vorstand Automobilkonzern (fest an Tisch 5, vor der Buehne) 5
4 Ferdinand Kessler Dr. VIP Industrie: Vorstand Automobilkonzern (fest an Tisch 5, vor der Buehne) 5
5 Viktoria Kessler VIP Industrie: Vorstand Automobilkonzern (fest an Tisch 5, vor der Buehne) 5
6 Konstantin Freiherr von Waldeck Dr. VIP Wirtschaft: Bankvorstand (fest an Tisch 6) 6
7 Antonia Freifrau von Waldeck VIP Wirtschaft: Bankvorstand (fest an Tisch 6) 6
8 Georg Steinbach VIP Wirtschaft: Bankvorstand (fest an Tisch 6) 6
9 Elisabeth Steinbach VIP Wirtschaft: Bankvorstand (fest an Tisch 6) 6
10 Heinrich Dallmann VIP Industrie: Unternehmerfamilie (fest an Tisch 7) 7
11 Margarete Dallmann VIP Industrie: Unternehmerfamilie (fest an Tisch 7) 7
12 Maximilian Dallmann VIP Industrie: Unternehmerfamilie (fest an Tisch 7) 7
13 Charlotte Dallmann VIP Industrie: Unternehmerfamilie (fest an Tisch 7) 7
14 Sandra Bianchi Familie Bianchi (Studierenden-Familie 1)
15 Thomas Bianchi Familie Bianchi (Studierenden-Familie 1)
16 Mia Bianchi Familie Bianchi (Studierenden-Familie 1)
17 Jennifer Arnold Familie Arnold (Studierenden-Familie 2)
18 Patrick Arnold Familie Arnold (Studierenden-Familie 2)
19 Leni Arnold Familie Arnold (Studierenden-Familie 2)
20 Christian Arnold Familie Arnold (Studierenden-Familie 2)
21 Mila Arnold Familie Arnold (Studierenden-Familie 2)
22 Nicole Seifert Familie Seifert (Studierenden-Familie 3)
23 Yusuf Seifert Familie Seifert (Studierenden-Familie 3)
24 Leni Seifert Familie Seifert (Studierenden-Familie 3)
25 Timo Seifert Familie Seifert (Studierenden-Familie 3)
26 Elif Seifert Familie Seifert (Studierenden-Familie 3)
27 Sarah Albrecht Familie Albrecht (Studierenden-Familie 4)
28 Andreas Albrecht Familie Albrecht (Studierenden-Familie 4)
29 Yusuf Esposito Prof. Dr. Institut fuer Maschinenwesen
30 Marija Becker Institut fuer Maschinenwesen
31 Matthias Kovac Institut fuer Maschinenwesen
32 Nicole Kaya Familie Kaya (Studierenden-Familie 5)
33 Luca Kaya Familie Kaya (Studierenden-Familie 5)
34 Christina Kaya Familie Kaya (Studierenden-Familie 5)
35 Julia Richter Prof. Dr. Lehrstuhl Thermodynamik
36 Jennifer Haas Dr. Lehrstuhl Thermodynamik
37 Markus Barth Lehrstuhl Thermodynamik
38 Matthias Petrov Lehrstuhl Thermodynamik
39 Andreas Weber Lehrstuhl Thermodynamik
40 Giovanna Schmidt Familie Schmidt (Studierenden-Familie 6)
41 Matthias Schmidt Familie Schmidt (Studierenden-Familie 6)
42 Marie Schmidt Familie Schmidt (Studierenden-Familie 6)
43 Anja Richter Familie Richter (Studierenden-Familie 7)
44 Matthias Richter Familie Richter (Studierenden-Familie 7)
45 Greta Richter Familie Richter (Studierenden-Familie 7)
46 Anton Richter Familie Richter (Studierenden-Familie 7)
47 Emre Albrecht Prof. Dr. Institut fuer Informatik
48 Thomas Bianchi Institut fuer Informatik
49 Olga Roth Institut fuer Informatik
50 Olga Klein Dr. Institut fuer Informatik
51 Jennifer Arnold Dr. Institut fuer Informatik
52 Dennis Werner Prof. Dr. Lehrstuhl Regelungstechnik
53 Thomas Hoffmann Dr. Lehrstuhl Regelungstechnik
54 Olga Tran Lehrstuhl Regelungstechnik
55 Anja Seidel Dr. Lehrstuhl Regelungstechnik
56 Markus Stein Prof. Dr. Institut fuer Werkstoffkunde
57 Matthias Popescu Institut fuer Werkstoffkunde
58 Yusuf Albrecht Prof. Dr. Lehrstuhl Stroemungsmechanik
59 Svenja Simon Lehrstuhl Stroemungsmechanik
60 Julia Roth Prof. Dr. Institut fuer Elektrotechnik
61 Thomas Hansen Institut fuer Elektrotechnik
62 Nicole Schmidt Institut fuer Elektrotechnik
63 Julia Nguyen Institut fuer Elektrotechnik
64 Stefanie Seifert Dr. Institut fuer Elektrotechnik
65 Thomas Winkler Institut fuer Elektrotechnik
66 Jan Esposito Dr. Institut fuer Elektrotechnik
67 Nicole Becker Familie Becker (Studierenden-Familie 8)
68 Jan Becker Familie Becker (Studierenden-Familie 8)
69 Sandra Becker Familie Becker (Studierenden-Familie 8)
70 Kathrin Petrov Prof. Dr. Lehrstuhl Mathematik
71 Markus Seidel Dr. Lehrstuhl Mathematik
72 Markus Kraus Lehrstuhl Mathematik
73 Giovanna Petrov Lehrstuhl Mathematik
74 Nadine Stein Dr. Lehrstuhl Mathematik
75 Markus Schmitt Lehrstuhl Mathematik
76 Christian Peters Lehrstuhl Mathematik
77 Anja Nguyen Familie Nguyen (Studierenden-Familie 9)
78 Daniel Nguyen Familie Nguyen (Studierenden-Familie 9)
79 Sofia Nguyen Familie Nguyen (Studierenden-Familie 9)
80 Elif Celik Familie Celik (Studierenden-Familie 10)
81 Patrick Celik Familie Celik (Studierenden-Familie 10)
82 Stefanie Klein Familie Klein (Studierenden-Familie 11)
83 Milan Klein Familie Klein (Studierenden-Familie 11)
84 Lina Klein Familie Klein (Studierenden-Familie 11)
85 Olga Busch Familie Busch (Studierenden-Familie 12)
86 Emre Busch Familie Busch (Studierenden-Familie 12)
87 Marie Busch Familie Busch (Studierenden-Familie 12)
88 Michael Busch Familie Busch (Studierenden-Familie 12)
89 Stefan Schmitt Prof. Dr. Institut fuer Physik
90 Marija Tran Institut fuer Physik
91 Kathrin Koch Dr. Institut fuer Physik
92 Julia Kuhn Dr. Institut fuer Physik
93 Katrin Weber Institut fuer Physik
94 Luca Werner Institut fuer Physik
95 Anja Engel Familie Engel (Studierenden-Familie 13)
96 Yusuf Engel Familie Engel (Studierenden-Familie 13)
97 Julia Engel Familie Engel (Studierenden-Familie 13)
98 Anton Engel Familie Engel (Studierenden-Familie 13)
99 Nicole Engel Familie Engel (Studierenden-Familie 13)
100 Emre Ludwig Prof. Dr. Lehrstuhl Produktionstechnik
101 Daniel Krause Lehrstuhl Produktionstechnik
102 Nicole Aksoy Lehrstuhl Produktionstechnik
103 Markus Klein Lehrstuhl Produktionstechnik
104 Dennis Schmitt Prof. Dr. Institut fuer Chemie
105 Luca Kovac Institut fuer Chemie
106 Dragana Krause Dr. Institut fuer Chemie
107 Luca Ott Institut fuer Chemie
108 Patrick Zimmermann Institut fuer Chemie
109 Stefan Richter Institut fuer Chemie
110 Yusuf Seidel Prof. Dr. Lehrstuhl Fahrzeugtechnik
111 Yusuf Bauer Lehrstuhl Fahrzeugtechnik
112 Jan Bianchi Dr. Lehrstuhl Fahrzeugtechnik
113 Marco Winkler Lehrstuhl Fahrzeugtechnik
114 Emre Klein Lehrstuhl Fahrzeugtechnik
115 Patrick Kaya Dr. Lehrstuhl Fahrzeugtechnik
116 Christina Krause Dr. Lehrstuhl Fahrzeugtechnik
117 Nadine Frank Familie Frank (Studierenden-Familie 14)
118 Dennis Frank Familie Frank (Studierenden-Familie 14)
119 Marie Frank Familie Frank (Studierenden-Familie 14)
120 Finn Frank Familie Frank (Studierenden-Familie 14)
121 Lena Frank Familie Frank (Studierenden-Familie 14)
122 Sandra Werner Familie Werner (Studierenden-Familie 15)
123 Andreas Werner Familie Werner (Studierenden-Familie 15)
124 Nadine Werner Familie Werner (Studierenden-Familie 15)
125 Marco Werner Familie Werner (Studierenden-Familie 15)
126 Sarah Roth Familie Roth (Studierenden-Familie 16)
127 Christian Roth Familie Roth (Studierenden-Familie 16)
128 Sofia Roth Familie Roth (Studierenden-Familie 16)
129 Marco Seifert Prof. Dr. Institut fuer Bauingenieurwesen
130 Matthias Krause Institut fuer Bauingenieurwesen
131 Giovanna Schwarz Institut fuer Bauingenieurwesen
132 Yusuf Weber Institut fuer Bauingenieurwesen
133 Patrick Kraus Dr. Institut fuer Bauingenieurwesen
134 Aylin Ludwig Dr. Institut fuer Bauingenieurwesen
135 Patrick Hoffmann Prof. Dr. Lehrstuhl Messtechnik
136 Marija Polat Lehrstuhl Messtechnik
137 Nadine Arnold Lehrstuhl Messtechnik
138 Marco Richter Lehrstuhl Messtechnik
139 Dragana Dietrich Prof. Dr. Doktorandenrunde Energietechnik
140 Michael Aksoy Dr. Doktorandenrunde Energietechnik
141 Katrin Werner Doktorandenrunde Energietechnik
142 Patrick Busch Doktorandenrunde Energietechnik
143 Emre Hoffmann Doktorandenrunde Energietechnik
144 Sergej Lange Doktorandenrunde Energietechnik
145 Anja Richter Prof. Dr. Doktorandenrunde Robotik
146 Jan Thiel Dr. Doktorandenrunde Robotik
147 Thomas Sahin Doktorandenrunde Robotik
148 Sarah Koch Familie Koch (Studierenden-Familie 17)
149 Jan Koch Familie Koch (Studierenden-Familie 17)
150 Marie Koch Familie Koch (Studierenden-Familie 17)
151 Emil Koch Familie Koch (Studierenden-Familie 17)
152 Olga Koch Familie Koch (Studierenden-Familie 17)
153 Michael Koch Familie Koch (Studierenden-Familie 17)
154 Thomas Tran Prof. Dr. Emeriti-Stammtisch
155 Sergej Petrov Emeriti-Stammtisch
156 Kathrin Polat Emeriti-Stammtisch
157 Marija Aksoy Emeriti-Stammtisch
158 Sergej Ott Prof. Dr. Institut fuer Verfahrenstechnik
159 Dragana Bauer Institut fuer Verfahrenstechnik
160 Nicole Peters Institut fuer Verfahrenstechnik
161 Nicole Hansen Dr. Institut fuer Verfahrenstechnik
162 Thomas Krause Institut fuer Verfahrenstechnik
163 Patrick Haas Institut fuer Verfahrenstechnik
164 Timo Kaya Prof. Dr. Lehrstuhl Mechatronik
165 Sandra Demir Dr. Lehrstuhl Mechatronik
166 Yusuf Ott Prof. Dr. Institut fuer Luftfahrttechnik
167 Nadine Berger Dr. Institut fuer Luftfahrttechnik
168 Patrick Lehmann Institut fuer Luftfahrttechnik
169 Nicole Wagner Familie Wagner (Studierenden-Familie 18)
170 Marco Wagner Familie Wagner (Studierenden-Familie 18)
171 Sarah Wagner Familie Wagner (Studierenden-Familie 18)
172 Henry Wagner Familie Wagner (Studierenden-Familie 18)
173 Jennifer Dietrich Familie Dietrich (Studierenden-Familie 19)
174 Marco Dietrich Familie Dietrich (Studierenden-Familie 19)
175 Sofia Dietrich Familie Dietrich (Studierenden-Familie 19)
176 Julia Thiel Familie Thiel (Studierenden-Familie 20)
177 Yusuf Thiel Familie Thiel (Studierenden-Familie 20)
178 Christina Thiel Familie Thiel (Studierenden-Familie 20)
179 Sarah Schmitt Familie Schmitt (Studierenden-Familie 21)
180 Markus Schmitt Familie Schmitt (Studierenden-Familie 21)
181 Sofia Schmitt Familie Schmitt (Studierenden-Familie 21)
182 Marija Hartmann Familie Hartmann (Studierenden-Familie 22)
183 Thomas Hartmann Familie Hartmann (Studierenden-Familie 22)
184 Olga Hartmann Familie Hartmann (Studierenden-Familie 22)
185 Deniz Hartmann Familie Hartmann (Studierenden-Familie 22)
186 Nadine Hartmann Familie Hartmann (Studierenden-Familie 22)
187 Melanie Rossi Familie Rossi (Studierenden-Familie 23)
188 Luca Rossi Familie Rossi (Studierenden-Familie 23)
189 Emilia Rossi Familie Rossi (Studierenden-Familie 23)
190 Julia Braun Familie Braun (Studierenden-Familie 24)
191 Milan Braun Familie Braun (Studierenden-Familie 24)
192 Nadine Braun Familie Braun (Studierenden-Familie 24)
193 Jan Braun Familie Braun (Studierenden-Familie 24)
194 Dragana Braun Familie Braun (Studierenden-Familie 24)
195 Christian Braun Familie Braun (Studierenden-Familie 24)
196 Svenja Zimmermann Familie Zimmermann (Studierenden-Familie 25)
197 Jan Zimmermann Familie Zimmermann (Studierenden-Familie 25)
198 Mia Zimmermann Familie Zimmermann (Studierenden-Familie 25)
199 Markus Zimmermann Familie Zimmermann (Studierenden-Familie 25)
200 Julia Krause Familie Krause (Studierenden-Familie 26)
201 Andreas Krause Familie Krause (Studierenden-Familie 26)
202 Emma Krause Familie Krause (Studierenden-Familie 26)
203 Arda Krause Familie Krause (Studierenden-Familie 26)
204 Aylin Nowak Familie Nowak (Studierenden-Familie 27)
205 Markus Nowak Familie Nowak (Studierenden-Familie 27)
206 Lina Nowak Familie Nowak (Studierenden-Familie 27)
207 Noah Nowak Familie Nowak (Studierenden-Familie 27)
208 Kathrin Nowak Familie Nowak (Studierenden-Familie 27)
209 Felix Nowak Familie Nowak (Studierenden-Familie 27)
210 Kathrin Horn Familie Horn (Studierenden-Familie 28)
211 Michael Horn Familie Horn (Studierenden-Familie 28)
212 Layla Horn Familie Horn (Studierenden-Familie 28)
213 Leon Horn Familie Horn (Studierenden-Familie 28)
214 Melanie Ott Familie Ott (Studierenden-Familie 29)
215 Daniel Ott Familie Ott (Studierenden-Familie 29)
216 Olga Ott Familie Ott (Studierenden-Familie 29)
217 Matthias Ott Familie Ott (Studierenden-Familie 29)
218 Hannah Ott Familie Ott (Studierenden-Familie 29)
219 Jennifer Neumann Familie Neumann (Studierenden-Familie 30)
220 Thomas Neumann Familie Neumann (Studierenden-Familie 30)
221 Lina Neumann Familie Neumann (Studierenden-Familie 30)
222 Matteo Neumann Familie Neumann (Studierenden-Familie 30)
223 Julia Wolf Familie Wolf (Studierenden-Familie 31)
224 Thomas Wolf Familie Wolf (Studierenden-Familie 31)
225 Emma Wolf Familie Wolf (Studierenden-Familie 31)
226 Ben Wolf Familie Wolf (Studierenden-Familie 31)
227 Nadine Aksoy Familie Aksoy (Studierenden-Familie 32)
228 Thomas Aksoy Familie Aksoy (Studierenden-Familie 32)
229 Marie Aksoy Familie Aksoy (Studierenden-Familie 32)
230 Luca Aksoy Familie Aksoy (Studierenden-Familie 32)
231 Sofia Aksoy Familie Aksoy (Studierenden-Familie 32)
232 Sergej Aksoy Familie Aksoy (Studierenden-Familie 32)
233 Giovanna Hansen Familie Hansen (Studierenden-Familie 33)
234 Markus Hansen Familie Hansen (Studierenden-Familie 33)
235 Olga Hansen Familie Hansen (Studierenden-Familie 33)
236 Stefanie Polat Familie Polat (Studierenden-Familie 34)
237 Stefan Polat Familie Polat (Studierenden-Familie 34)
238 Sarah Polat Familie Polat (Studierenden-Familie 34)
239 Markus Polat Familie Polat (Studierenden-Familie 34)
240 Katrin Polat Familie Polat (Studierenden-Familie 34)
241 Olga Franke Familie Franke (Studierenden-Familie 35)
242 Marco Franke Familie Franke (Studierenden-Familie 35)
243 Amira Franke Familie Franke (Studierenden-Familie 35)
244 Michael Franke Familie Franke (Studierenden-Familie 35)
245 Julia Franke Familie Franke (Studierenden-Familie 35)
246 Lena Kovac Familie Kovac (Studierenden-Familie 36)
247 Tobias Kovac Familie Kovac (Studierenden-Familie 36)
248 Marija Kovac Familie Kovac (Studierenden-Familie 36)
249 Marco Kovac Familie Kovac (Studierenden-Familie 36)
250 Anja Kovac Familie Kovac (Studierenden-Familie 36)
251 Henry Kovac Familie Kovac (Studierenden-Familie 36)
252 Lena Winkler Familie Winkler (Studierenden-Familie 37)
253 Patrick Winkler Familie Winkler (Studierenden-Familie 37)
254 Kathrin Petrov Familie Petrov (Studierenden-Familie 38)
255 Milan Petrov Familie Petrov (Studierenden-Familie 38)
256 Giovanna Stein Familie Stein (Studierenden-Familie 39)
257 Thomas Stein Familie Stein (Studierenden-Familie 39)
258 Emilia Stein Familie Stein (Studierenden-Familie 39)
259 Ben Stein Familie Stein (Studierenden-Familie 39)
260 Dragana Pohl Familie Pohl (Studierenden-Familie 40)
261 Emre Pohl Familie Pohl (Studierenden-Familie 40)
262 Mia Pohl Familie Pohl (Studierenden-Familie 40)
263 Theo Pohl Familie Pohl (Studierenden-Familie 40)
264 Svenja Berger Familie Berger (Studierenden-Familie 41)
265 Andreas Berger Familie Berger (Studierenden-Familie 41)
266 Jennifer Berger Familie Berger (Studierenden-Familie 41)
267 Anton Berger Familie Berger (Studierenden-Familie 41)
268 Layla Berger Familie Berger (Studierenden-Familie 41)
269 Stefan Berger Familie Berger (Studierenden-Familie 41)
270 Nadine Barth Familie Barth (Studierenden-Familie 42)
271 Timo Barth Familie Barth (Studierenden-Familie 42)
272 Lina Barth Familie Barth (Studierenden-Familie 42)
273 Patrick Barth Familie Barth (Studierenden-Familie 42)
274 Lena Simon Familie Simon (Studierenden-Familie 43)
275 Markus Simon Familie Simon (Studierenden-Familie 43)
276 Emma Simon Familie Simon (Studierenden-Familie 43)
277 Andreas Simon Familie Simon (Studierenden-Familie 43)
278 Dragana Lange Familie Lange (Studierenden-Familie 44)
279 Michael Lange Familie Lange (Studierenden-Familie 44)
280 Sofia Lange Familie Lange (Studierenden-Familie 44)
281 Jan Lange Familie Lange (Studierenden-Familie 44)
282 Svenja Lange Familie Lange (Studierenden-Familie 44)
283 Giovanna Lehmann Familie Lehmann (Studierenden-Familie 45)
284 Milan Lehmann Familie Lehmann (Studierenden-Familie 45)
285 Layla Lehmann Familie Lehmann (Studierenden-Familie 45)
286 Thomas Lehmann Familie Lehmann (Studierenden-Familie 45)
287 Nicole Lehmann Familie Lehmann (Studierenden-Familie 45)
288 Markus Lehmann Familie Lehmann (Studierenden-Familie 45)
289 Sarah Maier Familie Maier (Studierenden-Familie 46)
290 Christian Maier Familie Maier (Studierenden-Familie 46)
291 Olga Maier Familie Maier (Studierenden-Familie 46)
292 Arda Maier Familie Maier (Studierenden-Familie 46)
293 Nicole Sahin Familie Sahin (Studierenden-Familie 47)
294 Markus Sahin Familie Sahin (Studierenden-Familie 47)
295 Kathrin Sahin Familie Sahin (Studierenden-Familie 47)
296 Patrick Sahin Familie Sahin (Studierenden-Familie 47)
297 Giovanna Ludwig Familie Ludwig (Studierenden-Familie 48)
298 Emre Ludwig Familie Ludwig (Studierenden-Familie 48)
299 Elif Ludwig Familie Ludwig (Studierenden-Familie 48)
300 Elias Ludwig Familie Ludwig (Studierenden-Familie 48)
301 Julia Weber Familie Weber (Studierenden-Familie 49)
File diff suppressed because it is too large Load Diff
+615
View File
@@ -0,0 +1,615 @@
[1]
Nummer=1
Hof=1
Plaetze=4
Nachbarliste=[2, 12]
Koordinaten=(0,0)
[2]
Nummer=2
Hof=1
Plaetze=4
Nachbarliste=[1, 3, 12, 13]
Koordinaten=(1,0)
[3]
Nummer=3
Hof=1
Plaetze=4
Nachbarliste=[2, 4, 13, 14]
Koordinaten=(2,0)
[4]
Nummer=4
Hof=1
Plaetze=4
Nachbarliste=[3, 5, 14, 15]
Koordinaten=(3,0)
[5]
Nummer=5
Hof=1
Plaetze=4
Nachbarliste=[4, 6, 15, 16]
Koordinaten=(4,0)
[6]
Nummer=6
Hof=1
Plaetze=4
Nachbarliste=[5, 7, 16, 17]
Koordinaten=(5,0)
[7]
Nummer=7
Hof=1
Plaetze=4
Nachbarliste=[6, 8, 17, 18]
Koordinaten=(6,0)
[8]
Nummer=8
Hof=1
Plaetze=4
Nachbarliste=[7, 9, 18, 19]
Koordinaten=(7,0)
[9]
Nummer=9
Hof=1
Plaetze=4
Nachbarliste=[8, 10, 19, 20]
Koordinaten=(8,0)
[10]
Nummer=10
Hof=1
Plaetze=4
Nachbarliste=[9, 11, 20, 21]
Koordinaten=(9,0)
[11]
Nummer=11
Hof=1
Plaetze=4
Nachbarliste=[10, 21]
Koordinaten=(10,0)
[12]
Nummer=12
Hof=1
Plaetze=4
Nachbarliste=[1, 2, 13, 22]
Koordinaten=(0.5,1)
[13]
Nummer=13
Hof=1
Plaetze=4
Nachbarliste=[2, 3, 12, 14, 22, 23]
Koordinaten=(1.5,1)
[14]
Nummer=14
Hof=1
Plaetze=4
Nachbarliste=[3, 4, 13, 15, 23, 24]
Koordinaten=(2.5,1)
[15]
Nummer=15
Hof=1
Plaetze=4
Nachbarliste=[4, 5, 14, 16, 24, 25]
Koordinaten=(3.5,1)
[16]
Nummer=16
Hof=1
Plaetze=4
Nachbarliste=[5, 6, 15, 17, 25, 26]
Koordinaten=(4.5,1)
[17]
Nummer=17
Hof=1
Plaetze=4
Nachbarliste=[6, 7, 16, 18, 26, 27]
Koordinaten=(5.5,1)
[18]
Nummer=18
Hof=1
Plaetze=4
Nachbarliste=[7, 8, 17, 19, 27, 28]
Koordinaten=(6.5,1)
[19]
Nummer=19
Hof=1
Plaetze=4
Nachbarliste=[8, 9, 18, 20, 28, 29]
Koordinaten=(7.5,1)
[20]
Nummer=20
Hof=1
Plaetze=4
Nachbarliste=[9, 10, 19, 21, 29, 30]
Koordinaten=(8.5,1)
[21]
Nummer=21
Hof=1
Plaetze=4
Nachbarliste=[10, 11, 20, 30]
Koordinaten=(9.5,1)
[22]
Nummer=22
Hof=1
Plaetze=4
Nachbarliste=[12, 13, 23, 31]
Koordinaten=(1,2)
[23]
Nummer=23
Hof=1
Plaetze=4
Nachbarliste=[13, 14, 22, 24, 31, 32]
Koordinaten=(2,2)
[24]
Nummer=24
Hof=1
Plaetze=4
Nachbarliste=[14, 15, 23, 25, 32, 33]
Koordinaten=(3,2)
[25]
Nummer=25
Hof=1
Plaetze=4
Nachbarliste=[15, 16, 24, 26, 33, 34]
Koordinaten=(4,2)
[26]
Nummer=26
Hof=1
Plaetze=4
Nachbarliste=[16, 17, 25, 27, 34, 35]
Koordinaten=(5,2)
[27]
Nummer=27
Hof=1
Plaetze=4
Nachbarliste=[17, 18, 26, 28, 35, 36]
Koordinaten=(6,2)
[28]
Nummer=28
Hof=1
Plaetze=4
Nachbarliste=[18, 19, 27, 29, 36, 37]
Koordinaten=(7,2)
[29]
Nummer=29
Hof=1
Plaetze=4
Nachbarliste=[19, 20, 28, 30, 37, 38]
Koordinaten=(8,2)
[30]
Nummer=30
Hof=1
Plaetze=4
Nachbarliste=[20, 21, 29, 38]
Koordinaten=(9,2)
[31]
Nummer=31
Hof=1
Plaetze=4
Nachbarliste=[22, 23, 32, 39]
Koordinaten=(1.5,3)
[32]
Nummer=32
Hof=1
Plaetze=4
Nachbarliste=[23, 24, 31, 33, 39, 40]
Koordinaten=(2.5,3)
[33]
Nummer=33
Hof=1
Plaetze=4
Nachbarliste=[24, 25, 32, 34, 40, 41]
Koordinaten=(3.5,3)
[34]
Nummer=34
Hof=1
Plaetze=4
Nachbarliste=[25, 26, 33, 35, 41, 42]
Koordinaten=(4.5,3)
[35]
Nummer=35
Hof=1
Plaetze=4
Nachbarliste=[26, 27, 34, 36, 42, 43]
Koordinaten=(5.5,3)
[36]
Nummer=36
Hof=1
Plaetze=4
Nachbarliste=[27, 28, 35, 37, 43, 44]
Koordinaten=(6.5,3)
[37]
Nummer=37
Hof=1
Plaetze=4
Nachbarliste=[28, 29, 36, 38, 44, 45]
Koordinaten=(7.5,3)
[38]
Nummer=38
Hof=1
Plaetze=4
Nachbarliste=[29, 30, 37, 45]
Koordinaten=(8.5,3)
[39]
Nummer=39
Hof=1
Plaetze=4
Nachbarliste=[31, 32, 40]
Koordinaten=(2,4)
[40]
Nummer=40
Hof=1
Plaetze=4
Nachbarliste=[32, 33, 39, 41]
Koordinaten=(3,4)
[41]
Nummer=41
Hof=1
Plaetze=4
Nachbarliste=[33, 34, 40, 42]
Koordinaten=(4,4)
[42]
Nummer=42
Hof=1
Plaetze=4
Nachbarliste=[34, 35, 41, 43]
Koordinaten=(5,4)
[43]
Nummer=43
Hof=1
Plaetze=4
Nachbarliste=[35, 36, 42, 44]
Koordinaten=(6,4)
[44]
Nummer=44
Hof=1
Plaetze=4
Nachbarliste=[36, 37, 43, 45]
Koordinaten=(7,4)
[45]
Nummer=45
Hof=1
Plaetze=4
Nachbarliste=[37, 38, 44]
Koordinaten=(8,4)
[46]
Nummer=46
Hof=2
Plaetze=4
Nachbarliste=[47, 57]
Koordinaten=(16,0)
[47]
Nummer=47
Hof=2
Plaetze=4
Nachbarliste=[46, 48, 57, 58]
Koordinaten=(17,0)
[48]
Nummer=48
Hof=2
Plaetze=4
Nachbarliste=[47, 49, 58, 59]
Koordinaten=(18,0)
[49]
Nummer=49
Hof=2
Plaetze=4
Nachbarliste=[48, 50, 59, 60]
Koordinaten=(19,0)
[50]
Nummer=50
Hof=2
Plaetze=4
Nachbarliste=[49, 51, 60, 61]
Koordinaten=(20,0)
[51]
Nummer=51
Hof=2
Plaetze=4
Nachbarliste=[50, 52, 61, 62]
Koordinaten=(21,0)
[52]
Nummer=52
Hof=2
Plaetze=4
Nachbarliste=[51, 53, 62, 63]
Koordinaten=(22,0)
[53]
Nummer=53
Hof=2
Plaetze=4
Nachbarliste=[52, 54, 63, 64]
Koordinaten=(23,0)
[54]
Nummer=54
Hof=2
Plaetze=4
Nachbarliste=[53, 55, 64, 65]
Koordinaten=(24,0)
[55]
Nummer=55
Hof=2
Plaetze=4
Nachbarliste=[54, 56, 65, 66]
Koordinaten=(25,0)
[56]
Nummer=56
Hof=2
Plaetze=4
Nachbarliste=[55, 66]
Koordinaten=(26,0)
[57]
Nummer=57
Hof=2
Plaetze=4
Nachbarliste=[46, 47, 58, 67]
Koordinaten=(16.5,1)
[58]
Nummer=58
Hof=2
Plaetze=4
Nachbarliste=[47, 48, 57, 59, 67, 68]
Koordinaten=(17.5,1)
[59]
Nummer=59
Hof=2
Plaetze=4
Nachbarliste=[48, 49, 58, 60, 68, 69]
Koordinaten=(18.5,1)
[60]
Nummer=60
Hof=2
Plaetze=4
Nachbarliste=[49, 50, 59, 61, 69, 70]
Koordinaten=(19.5,1)
[61]
Nummer=61
Hof=2
Plaetze=4
Nachbarliste=[50, 51, 60, 62, 70, 71]
Koordinaten=(20.5,1)
[62]
Nummer=62
Hof=2
Plaetze=4
Nachbarliste=[51, 52, 61, 63, 71, 72]
Koordinaten=(21.5,1)
[63]
Nummer=63
Hof=2
Plaetze=4
Nachbarliste=[52, 53, 62, 64, 72, 73]
Koordinaten=(22.5,1)
[64]
Nummer=64
Hof=2
Plaetze=4
Nachbarliste=[53, 54, 63, 65, 73, 74]
Koordinaten=(23.5,1)
[65]
Nummer=65
Hof=2
Plaetze=4
Nachbarliste=[54, 55, 64, 66, 74, 75]
Koordinaten=(24.5,1)
[66]
Nummer=66
Hof=2
Plaetze=4
Nachbarliste=[55, 56, 65, 75]
Koordinaten=(25.5,1)
[67]
Nummer=67
Hof=2
Plaetze=4
Nachbarliste=[57, 58, 68, 76]
Koordinaten=(17,2)
[68]
Nummer=68
Hof=2
Plaetze=4
Nachbarliste=[58, 59, 67, 69, 76, 77]
Koordinaten=(18,2)
[69]
Nummer=69
Hof=2
Plaetze=4
Nachbarliste=[59, 60, 68, 70, 77, 78]
Koordinaten=(19,2)
[70]
Nummer=70
Hof=2
Plaetze=4
Nachbarliste=[60, 61, 69, 71, 78, 79]
Koordinaten=(20,2)
[71]
Nummer=71
Hof=2
Plaetze=4
Nachbarliste=[61, 62, 70, 72, 79, 80]
Koordinaten=(21,2)
[72]
Nummer=72
Hof=2
Plaetze=4
Nachbarliste=[62, 63, 71, 73, 80, 81]
Koordinaten=(22,2)
[73]
Nummer=73
Hof=2
Plaetze=4
Nachbarliste=[63, 64, 72, 74, 81, 82]
Koordinaten=(23,2)
[74]
Nummer=74
Hof=2
Plaetze=4
Nachbarliste=[64, 65, 73, 75, 82, 83]
Koordinaten=(24,2)
[75]
Nummer=75
Hof=2
Plaetze=4
Nachbarliste=[65, 66, 74, 83]
Koordinaten=(25,2)
[76]
Nummer=76
Hof=2
Plaetze=4
Nachbarliste=[67, 68, 77]
Koordinaten=(17.5,3)
[77]
Nummer=77
Hof=2
Plaetze=4
Nachbarliste=[68, 69, 76, 78, 84]
Koordinaten=(18.5,3)
[78]
Nummer=78
Hof=2
Plaetze=4
Nachbarliste=[69, 70, 77, 79, 84, 85]
Koordinaten=(19.5,3)
[79]
Nummer=79
Hof=2
Plaetze=4
Nachbarliste=[70, 71, 78, 80, 85, 86]
Koordinaten=(20.5,3)
[80]
Nummer=80
Hof=2
Plaetze=4
Nachbarliste=[71, 72, 79, 81, 86, 87]
Koordinaten=(21.5,3)
[81]
Nummer=81
Hof=2
Plaetze=4
Nachbarliste=[72, 73, 80, 82, 87, 88]
Koordinaten=(22.5,3)
[82]
Nummer=82
Hof=2
Plaetze=4
Nachbarliste=[73, 74, 81, 83, 88]
Koordinaten=(23.5,3)
[83]
Nummer=83
Hof=2
Plaetze=4
Nachbarliste=[74, 75, 82]
Koordinaten=(24.5,3)
[84]
Nummer=84
Hof=2
Plaetze=4
Nachbarliste=[77, 78, 85]
Koordinaten=(19,4)
[85]
Nummer=85
Hof=2
Plaetze=4
Nachbarliste=[78, 79, 84, 86]
Koordinaten=(20,4)
[86]
Nummer=86
Hof=2
Plaetze=4
Nachbarliste=[79, 80, 85, 87]
Koordinaten=(21,4)
[87]
Nummer=87
Hof=2
Plaetze=4
Nachbarliste=[80, 81, 86, 88]
Koordinaten=(22,4)
[88]
Nummer=88
Hof=2
Plaetze=4
Nachbarliste=[81, 82, 87]
Koordinaten=(23,4)
+458
View File
@@ -0,0 +1,458 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="2200" height="430" viewBox="0 0 2200 430" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="1100" y="30" text-anchor="middle" font-size="16" fill="#333">Abstammung der Loesungen (Mutationsbaum)</text>
<line x1="60.0" y1="60.0" x2="60.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="86.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="166.7" y1="60.0" x2="112.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="139.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="165.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="191.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="380.0" y1="60.0" x2="218.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="433.3" y1="60.0" x2="244.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="270.6" y2="150.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="540.0" y1="60.0" x2="297.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="323.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="349.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="700.0" y1="60.0" x2="375.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="753.3" y1="60.0" x2="402.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="428.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="454.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="481.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="507.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="533.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1073.3" y1="60.0" x2="560.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="586.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1180.0" y1="60.0" x2="612.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1233.3" y1="60.0" x2="639.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="665.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1340.0" y1="60.0" x2="691.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="718.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="744.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="770.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="797.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="823.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1660.0" y1="60.0" x2="849.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="876.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="902.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1820.0" y1="60.0" x2="928.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1873.3" y1="60.0" x2="955.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1926.7" y1="60.0" x2="981.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1980.0" y1="60.0" x2="1007.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="1034.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="1060.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="60.0" x2="1086.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="60.0" x2="1113.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="1139.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="166.7" y1="60.0" x2="1165.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="1192.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="1218.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="1244.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="380.0" y1="60.0" x2="1271.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="433.3" y1="60.0" x2="1297.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="1323.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="540.0" y1="60.0" x2="1350.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="1376.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="1402.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="700.0" y1="60.0" x2="1429.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="753.3" y1="60.0" x2="1455.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="1481.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="1508.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="1534.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="1560.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="1587.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1073.3" y1="60.0" x2="1613.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="1639.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1180.0" y1="60.0" x2="1666.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1233.3" y1="60.0" x2="1692.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="1718.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1340.0" y1="60.0" x2="1745.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="1771.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="1797.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="1824.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="1850.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="1876.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1660.0" y1="60.0" x2="1903.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="1929.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="1955.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1820.0" y1="60.0" x2="1982.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1873.3" y1="60.0" x2="2008.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1926.7" y1="60.0" x2="2034.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1980.0" y1="60.0" x2="2061.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="2087.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="2113.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="60.0" x2="2140.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="60.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="91.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="191.6" y1="150.0" x2="122.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="244.3" y1="150.0" x2="153.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="270.6" y1="150.0" x2="184.2" y2="240.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="323.3" y1="150.0" x2="215.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="428.6" y1="150.0" x2="246.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="507.6" y1="150.0" x2="277.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="744.6" y1="150.0" x2="308.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="770.9" y1="150.0" x2="339.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="849.9" y1="150.0" x2="370.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1007.8" y1="150.0" x2="401.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1086.8" y1="150.0" x2="432.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1192.2" y1="150.0" x2="463.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1244.8" y1="150.0" x2="494.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1323.8" y1="150.0" x2="525.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1376.5" y1="150.0" x2="556.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1481.8" y1="150.0" x2="587.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1508.1" y1="150.0" x2="618.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1560.8" y1="150.0" x2="649.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1639.7" y1="150.0" x2="680.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1771.4" y1="150.0" x2="711.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1850.4" y1="150.0" x2="743.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1982.0" y1="150.0" x2="774.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2087.3" y1="150.0" x2="805.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="150.0" x2="836.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="867.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="898.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="929.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="960.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="991.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="1022.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="1053.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="1084.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="1115.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="1146.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="191.6" y1="150.0" x2="1177.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="244.3" y1="150.0" x2="1208.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="270.6" y1="150.0" x2="1239.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="323.3" y1="150.0" x2="1270.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="428.6" y1="150.0" x2="1301.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="507.6" y1="150.0" x2="1332.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="744.6" y1="150.0" x2="1363.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="770.9" y1="150.0" x2="1394.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="849.9" y1="150.0" x2="1426.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1007.8" y1="150.0" x2="1457.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1086.8" y1="150.0" x2="1488.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1192.2" y1="150.0" x2="1519.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1244.8" y1="150.0" x2="1550.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1323.8" y1="150.0" x2="1581.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1376.5" y1="150.0" x2="1612.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1481.8" y1="150.0" x2="1643.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1508.1" y1="150.0" x2="1674.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1560.8" y1="150.0" x2="1705.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1639.7" y1="150.0" x2="1736.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1771.4" y1="150.0" x2="1767.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1850.4" y1="150.0" x2="1798.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1982.0" y1="150.0" x2="1829.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2087.3" y1="150.0" x2="1860.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="150.0" x2="1891.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="1922.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="1953.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="1984.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="2015.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="2046.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="2077.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="2109.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="2140.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="153.1" y1="240.0" x2="60.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="184.2" y1="240.0" x2="97.8" y2="330.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="215.2" y1="240.0" x2="135.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="277.3" y1="240.0" x2="173.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="339.4" y1="240.0" x2="211.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="370.4" y1="240.0" x2="249.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="401.5" y1="240.0" x2="286.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="432.5" y1="240.0" x2="324.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="494.6" y1="240.0" x2="362.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="525.7" y1="240.0" x2="400.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="587.8" y1="240.0" x2="438.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="836.1" y1="240.0" x2="476.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="867.2" y1="240.0" x2="513.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="898.2" y1="240.0" x2="551.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1115.5" y1="240.0" x2="589.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1146.6" y1="240.0" x2="627.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1208.7" y1="240.0" x2="665.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1426.0" y1="240.0" x2="702.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1488.1" y1="240.0" x2="740.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1643.3" y1="240.0" x2="778.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1674.3" y1="240.0" x2="816.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1705.4" y1="240.0" x2="854.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1798.5" y1="240.0" x2="892.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1984.8" y1="240.0" x2="929.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="2046.9" y1="240.0" x2="967.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="2077.9" y1="240.0" x2="1005.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="1043.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="1081.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="153.1" y1="240.0" x2="1118.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="184.2" y1="240.0" x2="1156.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="215.2" y1="240.0" x2="1194.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="277.3" y1="240.0" x2="1232.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="339.4" y1="240.0" x2="1270.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="370.4" y1="240.0" x2="1308.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="401.5" y1="240.0" x2="1345.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="432.5" y1="240.0" x2="1383.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="494.6" y1="240.0" x2="1421.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="525.7" y1="240.0" x2="1459.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="587.8" y1="240.0" x2="1497.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="836.1" y1="240.0" x2="1534.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="867.2" y1="240.0" x2="1572.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="898.2" y1="240.0" x2="1610.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1115.5" y1="240.0" x2="1648.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1146.6" y1="240.0" x2="1686.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1208.7" y1="240.0" x2="1724.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1426.0" y1="240.0" x2="1761.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1488.1" y1="240.0" x2="1799.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1643.3" y1="240.0" x2="1837.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1674.3" y1="240.0" x2="1875.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1705.4" y1="240.0" x2="1913.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1798.5" y1="240.0" x2="1950.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1984.8" y1="240.0" x2="1988.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="2046.9" y1="240.0" x2="2026.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="2077.9" y1="240.0" x2="2064.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="2102.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="2140.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<circle cx="60.0" cy="60.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 1, Wert -133.7</title></circle>
<circle cx="113.3" cy="60.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 2, Wert -103.7</title></circle>
<circle cx="166.7" cy="60.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 3, Wert -67.0</title></circle>
<circle cx="220.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 4, Wert -19.7</title></circle>
<circle cx="273.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 5, Wert -19.7</title></circle>
<circle cx="326.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 6, Wert -19.7</title></circle>
<circle cx="380.0" cy="60.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 7, Wert -133.7</title></circle>
<circle cx="433.3" cy="60.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 8, Wert -67.0</title></circle>
<circle cx="486.7" cy="60.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 9, Wert -19.7</title></circle>
<circle cx="540.0" cy="60.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 10, Wert -67.0</title></circle>
<circle cx="593.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 11, Wert -19.7</title></circle>
<circle cx="646.7" cy="60.0" r="5" fill="#944e3b" stroke="#333" stroke-width="0.5"><title>Id 12, Wert -140.3</title></circle>
<circle cx="700.0" cy="60.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 13, Wert -133.7</title></circle>
<circle cx="753.3" cy="60.0" r="5" fill="#527347" stroke="#333" stroke-width="0.5"><title>Id 14, Wert -67.0</title></circle>
<circle cx="806.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 15, Wert -19.7</title></circle>
<circle cx="860.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 16, Wert -19.7</title></circle>
<circle cx="913.3" cy="60.0" r="5" fill="#686743" stroke="#333" stroke-width="0.5"><title>Id 17, Wert -91.7</title></circle>
<circle cx="966.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 18, Wert -19.7</title></circle>
<circle cx="1020.0" cy="60.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 19, Wert -103.7</title></circle>
<circle cx="1073.3" cy="60.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 20, Wert -133.7</title></circle>
<circle cx="1126.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 21, Wert -19.7</title></circle>
<circle cx="1180.0" cy="60.0" r="5" fill="#c13533" stroke="#333" stroke-width="0.5"><title>Id 22, Wert -190.3</title></circle>
<circle cx="1233.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 23, Wert -19.7</title></circle>
<circle cx="1286.7" cy="60.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 24, Wert -103.7</title></circle>
<circle cx="1340.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 25, Wert -19.7</title></circle>
<circle cx="1393.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 26, Wert -19.7</title></circle>
<circle cx="1446.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 27, Wert -19.7</title></circle>
<circle cx="1500.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 28, Wert -19.7</title></circle>
<circle cx="1553.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 29, Wert -19.7</title></circle>
<circle cx="1606.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 30, Wert -19.7</title></circle>
<circle cx="1660.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 31, Wert -19.7</title></circle>
<circle cx="1713.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 32, Wert -19.7</title></circle>
<circle cx="1766.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 33, Wert -19.7</title></circle>
<circle cx="1820.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 34, Wert -19.7</title></circle>
<circle cx="1873.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 35, Wert -19.7</title></circle>
<circle cx="1926.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 36, Wert -19.7</title></circle>
<circle cx="1980.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 37, Wert -19.7</title></circle>
<circle cx="2033.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 38, Wert -19.7</title></circle>
<circle cx="2086.7" cy="60.0" r="5" fill="#c13533" stroke="#333" stroke-width="0.5"><title>Id 39, Wert -190.3</title></circle>
<circle cx="2140.0" cy="60.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 40, Wert -60.3</title></circle>
<circle cx="60.0" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 41, Wert -133.7</title></circle>
<circle cx="86.3" cy="150.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 42, Wert -55.0</title></circle>
<circle cx="112.7" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 43, Wert -19.7</title></circle>
<circle cx="139.0" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 44, Wert -19.7</title></circle>
<circle cx="165.3" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 45, Wert -133.7</title></circle>
<circle cx="191.6" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 46, Wert -19.7</title></circle>
<circle cx="218.0" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 47, Wert -85.0</title></circle>
<circle cx="244.3" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 48, Wert -19.7</title></circle>
<circle cx="270.6" cy="150.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 49, Wert -19.7</title></circle>
<circle cx="297.0" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 50, Wert -60.3</title></circle>
<circle cx="323.3" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 51, Wert -19.7</title></circle>
<circle cx="349.6" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 52, Wert -85.0</title></circle>
<circle cx="375.9" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 53, Wert -85.0</title></circle>
<circle cx="402.3" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 54, Wert -133.7</title></circle>
<circle cx="428.6" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 55, Wert -19.7</title></circle>
<circle cx="454.9" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 56, Wert -60.3</title></circle>
<circle cx="481.3" cy="150.0" r="5" fill="#686743" stroke="#333" stroke-width="0.5"><title>Id 57, Wert -91.7</title></circle>
<circle cx="507.6" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 58, Wert -19.7</title></circle>
<circle cx="533.9" cy="150.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 59, Wert -55.0</title></circle>
<circle cx="560.3" cy="150.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 60, Wert -55.0</title></circle>
<circle cx="586.6" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 61, Wert -60.3</title></circle>
<circle cx="612.9" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 62, Wert -85.0</title></circle>
<circle cx="639.2" cy="150.0" r="5" fill="#944e3b" stroke="#333" stroke-width="0.5"><title>Id 63, Wert -140.3</title></circle>
<circle cx="665.6" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 64, Wert -133.7</title></circle>
<circle cx="691.9" cy="150.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 65, Wert -103.7</title></circle>
<circle cx="718.2" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 66, Wert -60.3</title></circle>
<circle cx="744.6" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 67, Wert -19.7</title></circle>
<circle cx="770.9" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 68, Wert -19.7</title></circle>
<circle cx="797.2" cy="150.0" r="5" fill="#b53c35" stroke="#333" stroke-width="0.5"><title>Id 69, Wert -176.3</title></circle>
<circle cx="823.5" cy="150.0" r="5" fill="#b53c35" stroke="#333" stroke-width="0.5"><title>Id 70, Wert -176.3</title></circle>
<circle cx="849.9" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 71, Wert -19.7</title></circle>
<circle cx="876.2" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 72, Wert -60.3</title></circle>
<circle cx="902.5" cy="150.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 73, Wert -103.7</title></circle>
<circle cx="928.9" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 74, Wert -60.3</title></circle>
<circle cx="955.2" cy="150.0" r="5" fill="#c13533" stroke="#333" stroke-width="0.5"><title>Id 75, Wert -190.3</title></circle>
<circle cx="981.5" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 76, Wert -60.3</title></circle>
<circle cx="1007.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 77, Wert -19.7</title></circle>
<circle cx="1034.2" cy="150.0" r="5" fill="#9a4b3a" stroke="#333" stroke-width="0.5"><title>Id 78, Wert -147.0</title></circle>
<circle cx="1060.5" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 79, Wert -133.7</title></circle>
<circle cx="1086.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 80, Wert -19.7</title></circle>
<circle cx="1113.2" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 81, Wert -133.7</title></circle>
<circle cx="1139.5" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 82, Wert -133.7</title></circle>
<circle cx="1165.8" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 83, Wert -60.3</title></circle>
<circle cx="1192.2" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 84, Wert -19.7</title></circle>
<circle cx="1218.5" cy="150.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 85, Wert -103.7</title></circle>
<circle cx="1244.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 86, Wert -19.7</title></circle>
<circle cx="1271.1" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 87, Wert -85.0</title></circle>
<circle cx="1297.5" cy="150.0" r="5" fill="#c13533" stroke="#333" stroke-width="0.5"><title>Id 88, Wert -190.3</title></circle>
<circle cx="1323.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 89, Wert -19.7</title></circle>
<circle cx="1350.1" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 90, Wert -133.7</title></circle>
<circle cx="1376.5" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 91, Wert -19.7</title></circle>
<circle cx="1402.8" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 92, Wert -85.0</title></circle>
<circle cx="1429.1" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 93, Wert -85.0</title></circle>
<circle cx="1455.4" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 94, Wert -60.3</title></circle>
<circle cx="1481.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 95, Wert -19.7</title></circle>
<circle cx="1508.1" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 96, Wert -19.7</title></circle>
<circle cx="1534.4" cy="150.0" r="5" fill="#686743" stroke="#333" stroke-width="0.5"><title>Id 97, Wert -91.7</title></circle>
<circle cx="1560.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 98, Wert -19.7</title></circle>
<circle cx="1587.1" cy="150.0" r="5" fill="#477a4a" stroke="#333" stroke-width="0.5"><title>Id 99, Wert -55.0</title></circle>
<circle cx="1613.4" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 100, Wert -133.7</title></circle>
<circle cx="1639.7" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 101, Wert -19.7</title></circle>
<circle cx="1666.1" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 102, Wert -85.0</title></circle>
<circle cx="1692.4" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 103, Wert -133.7</title></circle>
<circle cx="1718.7" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 104, Wert -133.7</title></circle>
<circle cx="1745.1" cy="150.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 105, Wert -103.7</title></circle>
<circle cx="1771.4" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 106, Wert -19.7</title></circle>
<circle cx="1797.7" cy="150.0" r="5" fill="#bb3934" stroke="#333" stroke-width="0.5"><title>Id 107, Wert -183.0</title></circle>
<circle cx="1824.1" cy="150.0" r="5" fill="#795d40" stroke="#333" stroke-width="0.5"><title>Id 108, Wert -110.3</title></circle>
<circle cx="1850.4" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 109, Wert -19.7</title></circle>
<circle cx="1876.7" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 110, Wert -60.3</title></circle>
<circle cx="1903.0" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 111, Wert -60.3</title></circle>
<circle cx="1929.4" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 112, Wert -60.3</title></circle>
<circle cx="1955.7" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 113, Wert -60.3</title></circle>
<circle cx="1982.0" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 114, Wert -19.7</title></circle>
<circle cx="2008.4" cy="150.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 115, Wert -60.3</title></circle>
<circle cx="2034.7" cy="150.0" r="5" fill="#7e5b3f" stroke="#333" stroke-width="0.5"><title>Id 116, Wert -115.0</title></circle>
<circle cx="2061.0" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 117, Wert -133.7</title></circle>
<circle cx="2087.3" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 118, Wert -19.7</title></circle>
<circle cx="2113.7" cy="150.0" r="5" fill="#626a44" stroke="#333" stroke-width="0.5"><title>Id 119, Wert -85.0</title></circle>
<circle cx="2140.0" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 120, Wert -19.7</title></circle>
<circle cx="60.0" cy="240.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 121, Wert -133.7</title></circle>
<circle cx="91.0" cy="240.0" r="5" fill="#7f5a3f" stroke="#333" stroke-width="0.5"><title>Id 122, Wert -117.0</title></circle>
<circle cx="122.1" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 123, Wert -60.3</title></circle>
<circle cx="153.1" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 124, Wert -19.7</title></circle>
<circle cx="184.2" cy="240.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 125, Wert -19.7</title></circle>
<circle cx="215.2" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 126, Wert -19.7</title></circle>
<circle cx="246.3" cy="240.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 127, Wert -103.7</title></circle>
<circle cx="277.3" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 128, Wert -19.7</title></circle>
<circle cx="308.4" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 129, Wert -60.3</title></circle>
<circle cx="339.4" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 130, Wert -19.7</title></circle>
<circle cx="370.4" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 131, Wert -19.7</title></circle>
<circle cx="401.5" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 132, Wert -19.7</title></circle>
<circle cx="432.5" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 133, Wert -19.7</title></circle>
<circle cx="463.6" cy="240.0" r="5" fill="#9a4b3a" stroke="#333" stroke-width="0.5"><title>Id 134, Wert -147.0</title></circle>
<circle cx="494.6" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 135, Wert -19.7</title></circle>
<circle cx="525.7" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 136, Wert -19.7</title></circle>
<circle cx="556.7" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 137, Wert -60.3</title></circle>
<circle cx="587.8" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 138, Wert -19.7</title></circle>
<circle cx="618.8" cy="240.0" r="5" fill="#795d40" stroke="#333" stroke-width="0.5"><title>Id 139, Wert -110.3</title></circle>
<circle cx="649.9" cy="240.0" r="5" fill="#bf3633" stroke="#333" stroke-width="0.5"><title>Id 140, Wert -187.7</title></circle>
<circle cx="680.9" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 141, Wert -60.3</title></circle>
<circle cx="711.9" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 142, Wert -60.3</title></circle>
<circle cx="743.0" cy="240.0" r="5" fill="#795d40" stroke="#333" stroke-width="0.5"><title>Id 143, Wert -110.3</title></circle>
<circle cx="774.0" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 144, Wert -60.3</title></circle>
<circle cx="805.1" cy="240.0" r="5" fill="#944e3b" stroke="#333" stroke-width="0.5"><title>Id 145, Wert -140.3</title></circle>
<circle cx="836.1" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 146, Wert -19.7</title></circle>
<circle cx="867.2" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 147, Wert -19.7</title></circle>
<circle cx="898.2" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 148, Wert -19.7</title></circle>
<circle cx="929.3" cy="240.0" r="5" fill="#7f5a3f" stroke="#333" stroke-width="0.5"><title>Id 149, Wert -117.0</title></circle>
<circle cx="960.3" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 150, Wert -60.3</title></circle>
<circle cx="991.3" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 151, Wert -60.3</title></circle>
<circle cx="1022.4" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 152, Wert -60.3</title></circle>
<circle cx="1053.4" cy="240.0" r="5" fill="#a94237" stroke="#333" stroke-width="0.5"><title>Id 153, Wert -163.7</title></circle>
<circle cx="1084.5" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 154, Wert -60.3</title></circle>
<circle cx="1115.5" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 155, Wert -19.7</title></circle>
<circle cx="1146.6" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 156, Wert -19.7</title></circle>
<circle cx="1177.6" cy="240.0" r="5" fill="#bb3934" stroke="#333" stroke-width="0.5"><title>Id 157, Wert -183.0</title></circle>
<circle cx="1208.7" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 158, Wert -19.7</title></circle>
<circle cx="1239.7" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 159, Wert -60.3</title></circle>
<circle cx="1270.7" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 160, Wert -60.3</title></circle>
<circle cx="1301.8" cy="240.0" r="5" fill="#a44538" stroke="#333" stroke-width="0.5"><title>Id 161, Wert -157.7</title></circle>
<circle cx="1332.8" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 162, Wert -60.3</title></circle>
<circle cx="1363.9" cy="240.0" r="5" fill="#9a4b3a" stroke="#333" stroke-width="0.5"><title>Id 163, Wert -147.0</title></circle>
<circle cx="1394.9" cy="240.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 164, Wert -103.7</title></circle>
<circle cx="1426.0" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 165, Wert -19.7</title></circle>
<circle cx="1457.0" cy="240.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 166, Wert -133.7</title></circle>
<circle cx="1488.1" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 167, Wert -19.7</title></circle>
<circle cx="1519.1" cy="240.0" r="5" fill="#bb3934" stroke="#333" stroke-width="0.5"><title>Id 168, Wert -183.0</title></circle>
<circle cx="1550.1" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 169, Wert -60.3</title></circle>
<circle cx="1581.2" cy="240.0" r="5" fill="#bf3633" stroke="#333" stroke-width="0.5"><title>Id 170, Wert -187.7</title></circle>
<circle cx="1612.2" cy="240.0" r="5" fill="#c13533" stroke="#333" stroke-width="0.5"><title>Id 171, Wert -190.3</title></circle>
<circle cx="1643.3" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 172, Wert -19.7</title></circle>
<circle cx="1674.3" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 173, Wert -19.7</title></circle>
<circle cx="1705.4" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 174, Wert -19.7</title></circle>
<circle cx="1736.4" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 175, Wert -60.3</title></circle>
<circle cx="1767.5" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 176, Wert -60.3</title></circle>
<circle cx="1798.5" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 177, Wert -19.7</title></circle>
<circle cx="1829.6" cy="240.0" r="5" fill="#b53c35" stroke="#333" stroke-width="0.5"><title>Id 178, Wert -176.3</title></circle>
<circle cx="1860.6" cy="240.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 179, Wert -197.0</title></circle>
<circle cx="1891.6" cy="240.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 180, Wert -103.7</title></circle>
<circle cx="1922.7" cy="240.0" r="5" fill="#9a4b3a" stroke="#333" stroke-width="0.5"><title>Id 181, Wert -147.0</title></circle>
<circle cx="1953.7" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 182, Wert -60.3</title></circle>
<circle cx="1984.8" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 183, Wert -19.7</title></circle>
<circle cx="2015.8" cy="240.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 184, Wert -103.7</title></circle>
<circle cx="2046.9" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 185, Wert -19.7</title></circle>
<circle cx="2077.9" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 186, Wert -19.7</title></circle>
<circle cx="2109.0" cy="240.0" r="5" fill="#795d40" stroke="#333" stroke-width="0.5"><title>Id 187, Wert -110.3</title></circle>
<circle cx="2140.0" cy="240.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 188, Wert -60.3</title></circle>
<circle cx="60.0" cy="330.0" r="5" fill="#944e3b" stroke="#333" stroke-width="0.5"><title>Id 189, Wert -140.3</title></circle>
<circle cx="97.8" cy="330.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 190, Wert -19.7</title></circle>
<circle cx="135.6" cy="330.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 191, Wert -103.7</title></circle>
<circle cx="173.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 192, Wert -19.7</title></circle>
<circle cx="211.3" cy="330.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 193, Wert -133.7</title></circle>
<circle cx="249.1" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 194, Wert -19.7</title></circle>
<circle cx="286.9" cy="330.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 195, Wert -103.7</title></circle>
<circle cx="324.7" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 196, Wert -19.7</title></circle>
<circle cx="362.5" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 197, Wert -60.3</title></circle>
<circle cx="400.4" cy="330.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 198, Wert -103.7</title></circle>
<circle cx="438.2" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 199, Wert -19.7</title></circle>
<circle cx="476.0" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 200, Wert -19.7</title></circle>
<circle cx="513.8" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 201, Wert -19.7</title></circle>
<circle cx="551.6" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 202, Wert -60.3</title></circle>
<circle cx="589.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 203, Wert -19.7</title></circle>
<circle cx="627.3" cy="330.0" r="5" fill="#9a4b3a" stroke="#333" stroke-width="0.5"><title>Id 204, Wert -147.0</title></circle>
<circle cx="665.1" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 205, Wert -60.3</title></circle>
<circle cx="702.9" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 206, Wert -19.7</title></circle>
<circle cx="740.7" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 207, Wert -19.7</title></circle>
<circle cx="778.5" cy="330.0" r="5" fill="#944e3b" stroke="#333" stroke-width="0.5"><title>Id 208, Wert -140.3</title></circle>
<circle cx="816.4" cy="330.0" r="5" fill="#795d40" stroke="#333" stroke-width="0.5"><title>Id 209, Wert -110.3</title></circle>
<circle cx="854.2" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 210, Wert -60.3</title></circle>
<circle cx="892.0" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 211, Wert -19.7</title></circle>
<circle cx="929.8" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 212, Wert -19.7</title></circle>
<circle cx="967.6" cy="330.0" r="5" fill="#944e3b" stroke="#333" stroke-width="0.5"><title>Id 213, Wert -140.3</title></circle>
<circle cx="1005.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 214, Wert -19.7</title></circle>
<circle cx="1043.3" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 215, Wert -19.7</title></circle>
<circle cx="1081.1" cy="330.0" r="5" fill="#7f5a3f" stroke="#333" stroke-width="0.5"><title>Id 216, Wert -117.0</title></circle>
<circle cx="1118.9" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 217, Wert -60.3</title></circle>
<circle cx="1156.7" cy="330.0" r="5" fill="#c13533" stroke="#333" stroke-width="0.5"><title>Id 218, Wert -190.3</title></circle>
<circle cx="1194.5" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 219, Wert -60.3</title></circle>
<circle cx="1232.4" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 220, Wert -60.3</title></circle>
<circle cx="1270.2" cy="330.0" r="5" fill="#c13533" stroke="#333" stroke-width="0.5"><title>Id 221, Wert -190.3</title></circle>
<circle cx="1308.0" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 222, Wert -19.7</title></circle>
<circle cx="1345.8" cy="330.0" r="5" fill="#c13533" stroke="#333" stroke-width="0.5"><title>Id 223, Wert -190.3</title></circle>
<circle cx="1383.6" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 224, Wert -19.7</title></circle>
<circle cx="1421.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 225, Wert -19.7</title></circle>
<circle cx="1459.3" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 226, Wert -19.7</title></circle>
<circle cx="1497.1" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 227, Wert -19.7</title></circle>
<circle cx="1534.9" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 228, Wert -60.3</title></circle>
<circle cx="1572.7" cy="330.0" r="5" fill="#bb3934" stroke="#333" stroke-width="0.5"><title>Id 229, Wert -183.0</title></circle>
<circle cx="1610.5" cy="330.0" r="5" fill="#b53c35" stroke="#333" stroke-width="0.5"><title>Id 230, Wert -176.3</title></circle>
<circle cx="1648.4" cy="330.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 231, Wert -103.7</title></circle>
<circle cx="1686.2" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 232, Wert -60.3</title></circle>
<circle cx="1724.0" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 233, Wert -60.3</title></circle>
<circle cx="1761.8" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 234, Wert -19.7</title></circle>
<circle cx="1799.6" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 235, Wert -60.3</title></circle>
<circle cx="1837.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 236, Wert -19.7</title></circle>
<circle cx="1875.3" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 237, Wert -60.3</title></circle>
<circle cx="1913.1" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 238, Wert -19.7</title></circle>
<circle cx="1950.9" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 239, Wert -19.7</title></circle>
<circle cx="1988.7" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 240, Wert -60.3</title></circle>
<circle cx="2026.5" cy="330.0" r="5" fill="#4c7749" stroke="#333" stroke-width="0.5"><title>Id 241, Wert -60.3</title></circle>
<circle cx="2064.4" cy="330.0" r="5" fill="#736141" stroke="#333" stroke-width="0.5"><title>Id 242, Wert -103.7</title></circle>
<circle cx="2102.2" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 243, Wert -19.7</title></circle>
<circle cx="2140.0" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 244, Wert -19.7</title></circle>
<text x="97.8" y="352.0" text-anchor="middle" font-size="12" font-weight="bold" fill="#c04040">190</text>
<text x="48" y="64.0" text-anchor="end" font-size="11" fill="#666">Gen 0</text>
<text x="48" y="154.0" text-anchor="end" font-size="11" fill="#666">Gen 1</text>
<text x="48" y="244.0" text-anchor="end" font-size="11" fill="#666">Gen 2</text>
<text x="48" y="334.0" text-anchor="end" font-size="11" fill="#666">Gen 3</text>
</svg>

After

Width:  |  Height:  |  Size: 48 KiB

+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="650" viewBox="0 0 900 650" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="450" y="30" text-anchor="middle" font-size="16" fill="#333">Entwicklung der Loesungsfindung</text>
<line x1="60" y1="60" x2="60" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="394.0" text-anchor="end" font-size="11" fill="#666">-197</text>
<line x1="60" y1="324.0" x2="840" y2="324.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="328.0" text-anchor="end" font-size="11" fill="#666">-162</text>
<line x1="60" y1="258.0" x2="840" y2="258.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="262.0" text-anchor="end" font-size="11" fill="#666">-126</text>
<line x1="60" y1="192.0" x2="840" y2="192.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="196.0" text-anchor="end" font-size="11" fill="#666">-91</text>
<line x1="60" y1="126.0" x2="840" y2="126.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="130.0" text-anchor="end" font-size="11" fill="#666">-55</text>
<line x1="60" y1="60.0" x2="840" y2="60.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="64.0" text-anchor="end" font-size="11" fill="#666">-20</text>
<text x="18" y="225.0" text-anchor="middle" font-size="12" fill="#333" transform="rotate(-90 18 225.0)">Wertigkeit (hoeher = besser)</text>
<polyline points="60.0,60.0 146.7,60.0 233.3,60.0 320.0,60.0 406.7,60.0 493.3,60.0 580.0,60.0 666.7,60.0 753.3,60.0 840.0,60.0" fill="none" stroke="#2f6f4f" stroke-width="2"/>
<polyline points="60.0,128.5 146.7,162.3 233.3,151.0 320.0,60.0 406.7,161.7 493.3,127.8 580.0,60.0 666.7,146.8 753.3,117.9 840.0,60.0" fill="none" stroke="#c08a2d" stroke-width="2"/>
<polyline points="60.0,377.6 146.7,377.6 233.3,377.6 320.0,60.0 406.7,390.0 493.3,390.0 580.0,60.0 666.7,377.6 753.3,377.6 840.0,60.0" fill="none" stroke="#a03030" stroke-width="2"/>
<line x1="680" y1="70" x2="704" y2="70" stroke="#2f6f4f" stroke-width="2"/>
<text x="710" y="74" font-size="11" fill="#333">beste Loesung</text>
<line x1="680" y1="88" x2="704" y2="88" stroke="#c08a2d" stroke-width="2"/>
<text x="710" y="92" font-size="11" fill="#333">Durchschnitt</text>
<line x1="680" y1="106" x2="704" y2="106" stroke="#a03030" stroke-width="2"/>
<text x="710" y="110" font-size="11" fill="#333">schlechteste Loesung</text>
<text x="450" y="428.0" text-anchor="middle" font-size="13" fill="#333">Anzahl erzeugter Verteilungen im Pool</text>
<line x1="60" y1="440.0" x2="60" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="594.0" text-anchor="end" font-size="11" fill="#666">0</text>
<line x1="60" y1="515.0" x2="840" y2="515.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="519.0" text-anchor="end" font-size="11" fill="#666">60</text>
<line x1="60" y1="440.0" x2="840" y2="440.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="444.0" text-anchor="end" font-size="11" fill="#666">120</text>
<polyline points="60.0,540.0 146.7,490.0 233.3,440.0 320.0,547.5 406.7,505.0 493.3,462.5 580.0,555.0 666.7,520.0 753.3,485.0 840.0,561.2" fill="none" stroke="#4060a0" stroke-width="2"/>
<text x="60.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">e</text>
<text x="146.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="233.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="320.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="406.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="493.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="580.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="666.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="753.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="840.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="450" y="638" text-anchor="middle" font-size="12" fill="#333">Zyklus-Aktion (Zeit)</text>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="405.657" height="108.914" viewBox="0 0 405.657 108.914">
<rect width="100%" height="100%" fill="white"/>
<polyline points="54.4572,54.4572 153.372,54.4572" fill="none" stroke="#3cb44b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<circle cx="252.286" cy="54.4572" r="44.4572" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="252.286" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
<circle cx="274.743" cy="54.4572" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
<circle cx="252.286" cy="76.9144" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
<circle cx="229.829" cy="54.4572" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
<circle cx="252.286" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="252.286" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">3</text>
<circle cx="54.4572" cy="54.4572" r="44.4572" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="54.4572" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="75.8152" cy="47.5175" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="67.6572" cy="72.6254" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="41.2572" cy="72.6254" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="33.0991" cy="47.5175" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="54.4572" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="54.4572" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">1</text>
<circle cx="153.372" cy="54.4572" r="44.4572" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="153.372" cy="32" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="174.73" cy="47.5175" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="166.572" cy="72.6254" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="140.172" cy="72.6254" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="132.013" cy="47.5175" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="153.372" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="153.372" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">2</text>
<circle cx="351.2" cy="54.4572" r="44.4572" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="351.2" cy="32" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
<circle cx="372.558" cy="47.5175" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
<circle cx="364.4" cy="72.6254" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
<circle cx="338" cy="72.6254" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
<circle cx="329.842" cy="47.5175" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
<circle cx="351.2" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="351.2" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">4</text>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

+34
View File
@@ -0,0 +1,34 @@
{
"gruppen": [
{
"anzahl": 10,
"personen": [
{
"vorname": "A",
"nachname": "AA",
"titel": "Dipl. Ing."
}
]
},
{
"anzahl": 4,
"personen": [
{
"vorname": "B",
"nachname": "BB",
"titel": "Prof."
}
]
},
{
"anzahl": 5,
"personen": [
{
"vorname": "C",
"nachname": "CC",
"titel": "Dr."
}
]
}
]
}
-32
View File
@@ -1,32 +0,0 @@
<Bestellung>
<Gruppe>
<Person>
<Vorname>A</Vorname>
<Nachname>AA</Nachname>
<Titel>Dipl. Ing.</Titel>
</Person>
<Anzahl>10</Anzahl>
</Gruppe>
<Gruppe>
<Person>
<Vorname>B</Vorname>
<Nachname>BB</Nachname>
<Titel>Prof.</Titel>
</Person>
<Anzahl>4</Anzahl>
</Gruppe>
<Gruppe>
<Person>
<Vorname>C</Vorname>
<Nachname>CC</Nachname>
<Titel>Dr.</Titel>
</Person>
<Anzahl>5</Anzahl>
</Gruppe>
</Bestellung>
+458
View File
@@ -0,0 +1,458 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="2200" height="430" viewBox="0 0 2200 430" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="1100" y="30" text-anchor="middle" font-size="16" fill="#333">Abstammung der Loesungen (Mutationsbaum)</text>
<line x1="60.0" y1="60.0" x2="60.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="86.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="166.7" y1="60.0" x2="112.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="139.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="165.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="191.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="380.0" y1="60.0" x2="218.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="433.3" y1="60.0" x2="244.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="270.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="540.0" y1="60.0" x2="297.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="323.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="349.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="700.0" y1="60.0" x2="375.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="753.3" y1="60.0" x2="402.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="428.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="454.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="481.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="507.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="533.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1073.3" y1="60.0" x2="560.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="586.6" y2="150.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="1180.0" y1="60.0" x2="612.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1233.3" y1="60.0" x2="639.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="665.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1340.0" y1="60.0" x2="691.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="718.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="744.6" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="770.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="797.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="823.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1660.0" y1="60.0" x2="849.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="876.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="902.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1820.0" y1="60.0" x2="928.9" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1873.3" y1="60.0" x2="955.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1926.7" y1="60.0" x2="981.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1980.0" y1="60.0" x2="1007.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="1034.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="1060.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="60.0" x2="1086.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="60.0" y1="60.0" x2="1113.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="113.3" y1="60.0" x2="1139.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="166.7" y1="60.0" x2="1165.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="1192.2" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="273.3" y1="60.0" x2="1218.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="326.7" y1="60.0" x2="1244.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="380.0" y1="60.0" x2="1271.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="433.3" y1="60.0" x2="1297.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="1323.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="540.0" y1="60.0" x2="1350.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="593.3" y1="60.0" x2="1376.5" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="1402.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="700.0" y1="60.0" x2="1429.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="753.3" y1="60.0" x2="1455.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="806.7" y1="60.0" x2="1481.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="860.0" y1="60.0" x2="1508.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="1534.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="966.7" y1="60.0" x2="1560.8" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1020.0" y1="60.0" x2="1587.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1073.3" y1="60.0" x2="1613.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="1639.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1180.0" y1="60.0" x2="1666.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1233.3" y1="60.0" x2="1692.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="1718.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1340.0" y1="60.0" x2="1745.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1393.3" y1="60.0" x2="1771.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="1797.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="1824.1" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1553.3" y1="60.0" x2="1850.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1606.7" y1="60.0" x2="1876.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1660.0" y1="60.0" x2="1903.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1713.3" y1="60.0" x2="1929.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1766.7" y1="60.0" x2="1955.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1820.0" y1="60.0" x2="1982.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1873.3" y1="60.0" x2="2008.4" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1926.7" y1="60.0" x2="2034.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="1980.0" y1="60.0" x2="2061.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="2087.3" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2086.7" y1="60.0" x2="2113.7" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="2140.0" y1="60.0" x2="2140.0" y2="150.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="60.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="270.6" y1="150.0" x2="91.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="349.6" y1="150.0" x2="122.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="428.6" y1="150.0" x2="153.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="586.6" y1="150.0" x2="184.2" y2="240.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="770.9" y1="150.0" x2="215.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="902.5" y1="150.0" x2="246.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1007.8" y1="150.0" x2="277.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1192.2" y1="150.0" x2="308.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1402.8" y1="150.0" x2="339.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1481.8" y1="150.0" x2="370.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1534.4" y1="150.0" x2="401.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1639.7" y1="150.0" x2="432.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1824.1" y1="150.0" x2="463.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1955.7" y1="150.0" x2="494.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2087.3" y1="150.0" x2="525.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="556.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="587.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="618.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="649.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="680.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="711.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="743.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="774.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="805.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="836.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="191.6" y1="150.0" x2="867.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="297.0" y1="150.0" x2="898.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="612.9" y1="150.0" x2="929.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="691.9" y1="150.0" x2="960.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="718.2" y1="150.0" x2="991.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="823.5" y1="150.0" x2="1022.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="849.9" y1="150.0" x2="1053.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="876.2" y1="150.0" x2="1084.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="1115.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="270.6" y1="150.0" x2="1146.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="349.6" y1="150.0" x2="1177.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="428.6" y1="150.0" x2="1208.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="586.6" y1="150.0" x2="1239.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="770.9" y1="150.0" x2="1270.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="902.5" y1="150.0" x2="1301.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1007.8" y1="150.0" x2="1332.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1192.2" y1="150.0" x2="1363.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1402.8" y1="150.0" x2="1394.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1481.8" y1="150.0" x2="1426.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1534.4" y1="150.0" x2="1457.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1639.7" y1="150.0" x2="1488.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1824.1" y1="150.0" x2="1519.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1955.7" y1="150.0" x2="1550.1" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2087.3" y1="150.0" x2="1581.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="220.0" y1="60.0" x2="1612.2" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="486.7" y1="60.0" x2="1643.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="646.7" y1="60.0" x2="1674.3" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="913.3" y1="60.0" x2="1705.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1126.7" y1="60.0" x2="1736.4" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1286.7" y1="60.0" x2="1767.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1446.7" y1="60.0" x2="1798.5" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="1500.0" y1="60.0" x2="1829.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="2033.3" y1="60.0" x2="1860.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="112.7" y1="150.0" x2="1891.6" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="191.6" y1="150.0" x2="1922.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="297.0" y1="150.0" x2="1953.7" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="612.9" y1="150.0" x2="1984.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="691.9" y1="150.0" x2="2015.8" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="718.2" y1="150.0" x2="2046.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="823.5" y1="150.0" x2="2077.9" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="849.9" y1="150.0" x2="2109.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="876.2" y1="150.0" x2="2140.0" y2="240.0" stroke="#bbb" stroke-width="1"/>
<line x1="91.0" y1="240.0" x2="60.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="184.2" y1="240.0" x2="97.8" y2="330.0" stroke="#c04040" stroke-width="2.5"/>
<line x1="215.2" y1="240.0" x2="135.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="277.3" y1="240.0" x2="173.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="370.4" y1="240.0" x2="211.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="401.5" y1="240.0" x2="249.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="432.5" y1="240.0" x2="286.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="463.6" y1="240.0" x2="324.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="494.6" y1="240.0" x2="362.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="525.7" y1="240.0" x2="400.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="556.7" y1="240.0" x2="438.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="774.0" y1="240.0" x2="476.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1115.5" y1="240.0" x2="513.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1146.6" y1="240.0" x2="551.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1177.6" y1="240.0" x2="589.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1363.9" y1="240.0" x2="627.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1426.0" y1="240.0" x2="665.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1457.0" y1="240.0" x2="702.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1519.1" y1="240.0" x2="740.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1550.1" y1="240.0" x2="778.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1612.2" y1="240.0" x2="816.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1798.5" y1="240.0" x2="854.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1829.6" y1="240.0" x2="892.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="929.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="270.6" y1="150.0" x2="967.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="349.6" y1="150.0" x2="1005.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="428.6" y1="150.0" x2="1043.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="586.6" y1="150.0" x2="1081.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="91.0" y1="240.0" x2="1118.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="184.2" y1="240.0" x2="1156.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="215.2" y1="240.0" x2="1194.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="277.3" y1="240.0" x2="1232.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="370.4" y1="240.0" x2="1270.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="401.5" y1="240.0" x2="1308.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="432.5" y1="240.0" x2="1345.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="463.6" y1="240.0" x2="1383.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="494.6" y1="240.0" x2="1421.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="525.7" y1="240.0" x2="1459.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="556.7" y1="240.0" x2="1497.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="774.0" y1="240.0" x2="1534.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1115.5" y1="240.0" x2="1572.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1146.6" y1="240.0" x2="1610.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1177.6" y1="240.0" x2="1648.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1363.9" y1="240.0" x2="1686.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1426.0" y1="240.0" x2="1724.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1457.0" y1="240.0" x2="1761.8" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1519.1" y1="240.0" x2="1799.6" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1550.1" y1="240.0" x2="1837.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1612.2" y1="240.0" x2="1875.3" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1798.5" y1="240.0" x2="1913.1" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="1829.6" y1="240.0" x2="1950.9" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="139.0" y1="150.0" x2="1988.7" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="270.6" y1="150.0" x2="2026.5" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="349.6" y1="150.0" x2="2064.4" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="428.6" y1="150.0" x2="2102.2" y2="330.0" stroke="#bbb" stroke-width="1"/>
<line x1="586.6" y1="150.0" x2="2140.0" y2="330.0" stroke="#bbb" stroke-width="1"/>
<circle cx="60.0" cy="60.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 1, Wert -30.0</title></circle>
<circle cx="113.3" cy="60.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 2, Wert -127.0</title></circle>
<circle cx="166.7" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 3, Wert -25.0</title></circle>
<circle cx="220.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 4, Wert -22.0</title></circle>
<circle cx="273.3" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 5, Wert -25.0</title></circle>
<circle cx="326.7" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 6, Wert -25.0</title></circle>
<circle cx="380.0" cy="60.0" r="5" fill="#9b4a3a" stroke="#333" stroke-width="0.5"><title>Id 7, Wert -98.0</title></circle>
<circle cx="433.3" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 8, Wert -25.0</title></circle>
<circle cx="486.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 9, Wert -22.0</title></circle>
<circle cx="540.0" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 10, Wert -25.0</title></circle>
<circle cx="593.3" cy="60.0" r="5" fill="#696743" stroke="#333" stroke-width="0.5"><title>Id 11, Wert -65.0</title></circle>
<circle cx="646.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 12, Wert -22.0</title></circle>
<circle cx="700.0" cy="60.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 13, Wert -30.0</title></circle>
<circle cx="753.3" cy="60.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 14, Wert -35.0</title></circle>
<circle cx="806.7" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 15, Wert -25.0</title></circle>
<circle cx="860.0" cy="60.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 16, Wert -68.0</title></circle>
<circle cx="913.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 17, Wert -22.0</title></circle>
<circle cx="966.7" cy="60.0" r="5" fill="#9b4a3a" stroke="#333" stroke-width="0.5"><title>Id 18, Wert -98.0</title></circle>
<circle cx="1020.0" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 19, Wert -25.0</title></circle>
<circle cx="1073.3" cy="60.0" r="5" fill="#9e4939" stroke="#333" stroke-width="0.5"><title>Id 20, Wert -100.0</title></circle>
<circle cx="1126.7" cy="60.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 21, Wert -22.0</title></circle>
<circle cx="1180.0" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 22, Wert -25.0</title></circle>
<circle cx="1233.3" cy="60.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 23, Wert -30.0</title></circle>
<circle cx="1286.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 24, Wert -22.0</title></circle>
<circle cx="1340.0" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 25, Wert -25.0</title></circle>
<circle cx="1393.3" cy="60.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 26, Wert -68.0</title></circle>
<circle cx="1446.7" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 27, Wert -22.0</title></circle>
<circle cx="1500.0" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 28, Wert -22.0</title></circle>
<circle cx="1553.3" cy="60.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 29, Wert -35.0</title></circle>
<circle cx="1606.7" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 30, Wert -25.0</title></circle>
<circle cx="1660.0" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 31, Wert -25.0</title></circle>
<circle cx="1713.3" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 32, Wert -25.0</title></circle>
<circle cx="1766.7" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 33, Wert -25.0</title></circle>
<circle cx="1820.0" cy="60.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 34, Wert -68.0</title></circle>
<circle cx="1873.3" cy="60.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 35, Wert -127.0</title></circle>
<circle cx="1926.7" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 36, Wert -25.0</title></circle>
<circle cx="1980.0" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 37, Wert -25.0</title></circle>
<circle cx="2033.3" cy="60.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 38, Wert -22.0</title></circle>
<circle cx="2086.7" cy="60.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 39, Wert -25.0</title></circle>
<circle cx="2140.0" cy="60.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 40, Wert -68.0</title></circle>
<circle cx="60.0" cy="150.0" r="5" fill="#92503c" stroke="#333" stroke-width="0.5"><title>Id 41, Wert -92.0</title></circle>
<circle cx="86.3" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 42, Wert -30.0</title></circle>
<circle cx="112.7" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 43, Wert -25.0</title></circle>
<circle cx="139.0" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 44, Wert -22.0</title></circle>
<circle cx="165.3" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 45, Wert -68.0</title></circle>
<circle cx="191.6" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 46, Wert -25.0</title></circle>
<circle cx="218.0" cy="150.0" r="5" fill="#c83232" stroke="#333" stroke-width="0.5"><title>Id 47, Wert -127.0</title></circle>
<circle cx="244.3" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 48, Wert -68.0</title></circle>
<circle cx="270.6" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 49, Wert -22.0</title></circle>
<circle cx="297.0" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 50, Wert -25.0</title></circle>
<circle cx="323.3" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 51, Wert -30.0</title></circle>
<circle cx="349.6" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 52, Wert -22.0</title></circle>
<circle cx="375.9" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 53, Wert -89.0</title></circle>
<circle cx="402.3" cy="150.0" r="5" fill="#86563e" stroke="#333" stroke-width="0.5"><title>Id 54, Wert -84.0</title></circle>
<circle cx="428.6" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 55, Wert -22.0</title></circle>
<circle cx="454.9" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 56, Wert -89.0</title></circle>
<circle cx="481.3" cy="150.0" r="5" fill="#487a4a" stroke="#333" stroke-width="0.5"><title>Id 57, Wert -43.0</title></circle>
<circle cx="507.6" cy="150.0" r="5" fill="#9b4a3a" stroke="#333" stroke-width="0.5"><title>Id 58, Wert -98.0</title></circle>
<circle cx="533.9" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 59, Wert -30.0</title></circle>
<circle cx="560.3" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 60, Wert -89.0</title></circle>
<circle cx="586.6" cy="150.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 61, Wert -22.0</title></circle>
<circle cx="612.9" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 62, Wert -25.0</title></circle>
<circle cx="639.2" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 63, Wert -30.0</title></circle>
<circle cx="665.6" cy="150.0" r="5" fill="#696743" stroke="#333" stroke-width="0.5"><title>Id 64, Wert -65.0</title></circle>
<circle cx="691.9" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 65, Wert -25.0</title></circle>
<circle cx="718.2" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 66, Wert -25.0</title></circle>
<circle cx="744.6" cy="150.0" r="5" fill="#487a4a" stroke="#333" stroke-width="0.5"><title>Id 67, Wert -43.0</title></circle>
<circle cx="770.9" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 68, Wert -22.0</title></circle>
<circle cx="797.2" cy="150.0" r="5" fill="#c03633" stroke="#333" stroke-width="0.5"><title>Id 69, Wert -122.0</title></circle>
<circle cx="823.5" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 70, Wert -25.0</title></circle>
<circle cx="849.9" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 71, Wert -25.0</title></circle>
<circle cx="876.2" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 72, Wert -25.0</title></circle>
<circle cx="902.5" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 73, Wert -22.0</title></circle>
<circle cx="928.9" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 74, Wert -89.0</title></circle>
<circle cx="955.2" cy="150.0" r="5" fill="#92503c" stroke="#333" stroke-width="0.5"><title>Id 75, Wert -92.0</title></circle>
<circle cx="981.5" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 76, Wert -25.0</title></circle>
<circle cx="1007.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 77, Wert -22.0</title></circle>
<circle cx="1034.2" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 78, Wert -25.0</title></circle>
<circle cx="1060.5" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 79, Wert -68.0</title></circle>
<circle cx="1086.8" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 80, Wert -30.0</title></circle>
<circle cx="1113.2" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 81, Wert -89.0</title></circle>
<circle cx="1139.5" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 82, Wert -89.0</title></circle>
<circle cx="1165.8" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 83, Wert -25.0</title></circle>
<circle cx="1192.2" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 84, Wert -22.0</title></circle>
<circle cx="1218.5" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 85, Wert -25.0</title></circle>
<circle cx="1244.8" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 86, Wert -25.0</title></circle>
<circle cx="1271.1" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 87, Wert -89.0</title></circle>
<circle cx="1297.5" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 88, Wert -68.0</title></circle>
<circle cx="1323.8" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 89, Wert -25.0</title></circle>
<circle cx="1350.1" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 90, Wert -25.0</title></circle>
<circle cx="1376.5" cy="150.0" r="5" fill="#92503c" stroke="#333" stroke-width="0.5"><title>Id 91, Wert -92.0</title></circle>
<circle cx="1402.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 92, Wert -22.0</title></circle>
<circle cx="1429.1" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 93, Wert -89.0</title></circle>
<circle cx="1455.4" cy="150.0" r="5" fill="#3b804c" stroke="#333" stroke-width="0.5"><title>Id 94, Wert -35.0</title></circle>
<circle cx="1481.8" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 95, Wert -22.0</title></circle>
<circle cx="1508.1" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 96, Wert -30.0</title></circle>
<circle cx="1534.4" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 97, Wert -22.0</title></circle>
<circle cx="1560.8" cy="150.0" r="5" fill="#92503c" stroke="#333" stroke-width="0.5"><title>Id 98, Wert -92.0</title></circle>
<circle cx="1587.1" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 99, Wert -25.0</title></circle>
<circle cx="1613.4" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 100, Wert -89.0</title></circle>
<circle cx="1639.7" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 101, Wert -22.0</title></circle>
<circle cx="1666.1" cy="150.0" r="5" fill="#974d3b" stroke="#333" stroke-width="0.5"><title>Id 102, Wert -95.0</title></circle>
<circle cx="1692.4" cy="150.0" r="5" fill="#8e523c" stroke="#333" stroke-width="0.5"><title>Id 103, Wert -89.0</title></circle>
<circle cx="1718.7" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 104, Wert -68.0</title></circle>
<circle cx="1745.1" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 105, Wert -25.0</title></circle>
<circle cx="1771.4" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 106, Wert -30.0</title></circle>
<circle cx="1797.7" cy="150.0" r="5" fill="#407e4b" stroke="#333" stroke-width="0.5"><title>Id 107, Wert -38.0</title></circle>
<circle cx="1824.1" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 108, Wert -22.0</title></circle>
<circle cx="1850.4" cy="150.0" r="5" fill="#a34638" stroke="#333" stroke-width="0.5"><title>Id 109, Wert -103.0</title></circle>
<circle cx="1876.7" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 110, Wert -25.0</title></circle>
<circle cx="1903.0" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 111, Wert -25.0</title></circle>
<circle cx="1929.4" cy="150.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 112, Wert -68.0</title></circle>
<circle cx="1955.7" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 113, Wert -22.0</title></circle>
<circle cx="1982.0" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 114, Wert -30.0</title></circle>
<circle cx="2008.4" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 115, Wert -30.0</title></circle>
<circle cx="2034.7" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 116, Wert -25.0</title></circle>
<circle cx="2061.0" cy="150.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 117, Wert -25.0</title></circle>
<circle cx="2087.3" cy="150.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 118, Wert -22.0</title></circle>
<circle cx="2113.7" cy="150.0" r="5" fill="#974d3b" stroke="#333" stroke-width="0.5"><title>Id 119, Wert -95.0</title></circle>
<circle cx="2140.0" cy="150.0" r="5" fill="#34854d" stroke="#333" stroke-width="0.5"><title>Id 120, Wert -30.0</title></circle>
<circle cx="60.0" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 121, Wert -25.0</title></circle>
<circle cx="91.0" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 122, Wert -22.0</title></circle>
<circle cx="122.1" cy="240.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 123, Wert -68.0</title></circle>
<circle cx="153.1" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 124, Wert -25.0</title></circle>
<circle cx="184.2" cy="240.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 125, Wert -22.0</title></circle>
<circle cx="215.2" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 126, Wert -22.0</title></circle>
<circle cx="246.3" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 127, Wert -25.0</title></circle>
<circle cx="277.3" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 128, Wert -22.0</title></circle>
<circle cx="308.4" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 129, Wert -25.0</title></circle>
<circle cx="339.4" cy="240.0" r="5" fill="#696743" stroke="#333" stroke-width="0.5"><title>Id 130, Wert -65.0</title></circle>
<circle cx="370.4" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 131, Wert -22.0</title></circle>
<circle cx="401.5" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 132, Wert -22.0</title></circle>
<circle cx="432.5" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 133, Wert -22.0</title></circle>
<circle cx="463.6" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 134, Wert -22.0</title></circle>
<circle cx="494.6" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 135, Wert -22.0</title></circle>
<circle cx="525.7" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 136, Wert -22.0</title></circle>
<circle cx="556.7" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 137, Wert -22.0</title></circle>
<circle cx="587.8" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 138, Wert -25.0</title></circle>
<circle cx="618.8" cy="240.0" r="5" fill="#756041" stroke="#333" stroke-width="0.5"><title>Id 139, Wert -73.0</title></circle>
<circle cx="649.9" cy="240.0" r="5" fill="#756041" stroke="#333" stroke-width="0.5"><title>Id 140, Wert -73.0</title></circle>
<circle cx="680.9" cy="240.0" r="5" fill="#c03633" stroke="#333" stroke-width="0.5"><title>Id 141, Wert -122.0</title></circle>
<circle cx="711.9" cy="240.0" r="5" fill="#756041" stroke="#333" stroke-width="0.5"><title>Id 142, Wert -73.0</title></circle>
<circle cx="743.0" cy="240.0" r="5" fill="#756041" stroke="#333" stroke-width="0.5"><title>Id 143, Wert -73.0</title></circle>
<circle cx="774.0" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 144, Wert -22.0</title></circle>
<circle cx="805.1" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 145, Wert -25.0</title></circle>
<circle cx="836.1" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 146, Wert -25.0</title></circle>
<circle cx="867.2" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 147, Wert -25.0</title></circle>
<circle cx="898.2" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 148, Wert -25.0</title></circle>
<circle cx="929.3" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 149, Wert -25.0</title></circle>
<circle cx="960.3" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 150, Wert -25.0</title></circle>
<circle cx="991.3" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 151, Wert -25.0</title></circle>
<circle cx="1022.4" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 152, Wert -25.0</title></circle>
<circle cx="1053.4" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 153, Wert -25.0</title></circle>
<circle cx="1084.5" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 154, Wert -25.0</title></circle>
<circle cx="1115.5" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 155, Wert -22.0</title></circle>
<circle cx="1146.6" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 156, Wert -22.0</title></circle>
<circle cx="1177.6" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 157, Wert -22.0</title></circle>
<circle cx="1208.7" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 158, Wert -25.0</title></circle>
<circle cx="1239.7" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 159, Wert -25.0</title></circle>
<circle cx="1270.7" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 160, Wert -25.0</title></circle>
<circle cx="1301.8" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 161, Wert -25.0</title></circle>
<circle cx="1332.8" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 162, Wert -25.0</title></circle>
<circle cx="1363.9" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 163, Wert -22.0</title></circle>
<circle cx="1394.9" cy="240.0" r="5" fill="#716242" stroke="#333" stroke-width="0.5"><title>Id 164, Wert -70.0</title></circle>
<circle cx="1426.0" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 165, Wert -22.0</title></circle>
<circle cx="1457.0" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 166, Wert -22.0</title></circle>
<circle cx="1488.1" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 167, Wert -25.0</title></circle>
<circle cx="1519.1" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 168, Wert -22.0</title></circle>
<circle cx="1550.1" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 169, Wert -22.0</title></circle>
<circle cx="1581.2" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 170, Wert -25.0</title></circle>
<circle cx="1612.2" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 171, Wert -22.0</title></circle>
<circle cx="1643.3" cy="240.0" r="5" fill="#c03633" stroke="#333" stroke-width="0.5"><title>Id 172, Wert -122.0</title></circle>
<circle cx="1674.3" cy="240.0" r="5" fill="#487a4a" stroke="#333" stroke-width="0.5"><title>Id 173, Wert -43.0</title></circle>
<circle cx="1705.4" cy="240.0" r="5" fill="#756041" stroke="#333" stroke-width="0.5"><title>Id 174, Wert -73.0</title></circle>
<circle cx="1736.4" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 175, Wert -25.0</title></circle>
<circle cx="1767.5" cy="240.0" r="5" fill="#487a4a" stroke="#333" stroke-width="0.5"><title>Id 176, Wert -43.0</title></circle>
<circle cx="1798.5" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 177, Wert -22.0</title></circle>
<circle cx="1829.6" cy="240.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 178, Wert -22.0</title></circle>
<circle cx="1860.6" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 179, Wert -25.0</title></circle>
<circle cx="1891.6" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 180, Wert -25.0</title></circle>
<circle cx="1922.7" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 181, Wert -25.0</title></circle>
<circle cx="1953.7" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 182, Wert -25.0</title></circle>
<circle cx="1984.8" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 183, Wert -25.0</title></circle>
<circle cx="2015.8" cy="240.0" r="5" fill="#6e6442" stroke="#333" stroke-width="0.5"><title>Id 184, Wert -68.0</title></circle>
<circle cx="2046.9" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 185, Wert -25.0</title></circle>
<circle cx="2077.9" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 186, Wert -25.0</title></circle>
<circle cx="2109.0" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 187, Wert -25.0</title></circle>
<circle cx="2140.0" cy="240.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 188, Wert -25.0</title></circle>
<circle cx="60.0" cy="330.0" r="5" fill="#c03633" stroke="#333" stroke-width="0.5"><title>Id 189, Wert -122.0</title></circle>
<circle cx="97.8" cy="330.0" r="7" fill="#288c50" stroke="#c04040" stroke-width="2"><title>Id 190, Wert -22.0</title></circle>
<circle cx="135.6" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 191, Wert -22.0</title></circle>
<circle cx="173.5" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 192, Wert -25.0</title></circle>
<circle cx="211.3" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 193, Wert -22.0</title></circle>
<circle cx="249.1" cy="330.0" r="5" fill="#716242" stroke="#333" stroke-width="0.5"><title>Id 194, Wert -70.0</title></circle>
<circle cx="286.9" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 195, Wert -25.0</title></circle>
<circle cx="324.7" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 196, Wert -25.0</title></circle>
<circle cx="362.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 197, Wert -22.0</title></circle>
<circle cx="400.4" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 198, Wert -25.0</title></circle>
<circle cx="438.2" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 199, Wert -22.0</title></circle>
<circle cx="476.0" cy="330.0" r="5" fill="#c03633" stroke="#333" stroke-width="0.5"><title>Id 200, Wert -122.0</title></circle>
<circle cx="513.8" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 201, Wert -22.0</title></circle>
<circle cx="551.6" cy="330.0" r="5" fill="#c03633" stroke="#333" stroke-width="0.5"><title>Id 202, Wert -122.0</title></circle>
<circle cx="589.5" cy="330.0" r="5" fill="#696743" stroke="#333" stroke-width="0.5"><title>Id 203, Wert -65.0</title></circle>
<circle cx="627.3" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 204, Wert -22.0</title></circle>
<circle cx="665.1" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 205, Wert -25.0</title></circle>
<circle cx="702.9" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 206, Wert -22.0</title></circle>
<circle cx="740.7" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 207, Wert -25.0</title></circle>
<circle cx="778.5" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 208, Wert -25.0</title></circle>
<circle cx="816.4" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 209, Wert -22.0</title></circle>
<circle cx="854.2" cy="330.0" r="5" fill="#696743" stroke="#333" stroke-width="0.5"><title>Id 210, Wert -65.0</title></circle>
<circle cx="892.0" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 211, Wert -22.0</title></circle>
<circle cx="929.8" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 212, Wert -22.0</title></circle>
<circle cx="967.6" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 213, Wert -22.0</title></circle>
<circle cx="1005.5" cy="330.0" r="5" fill="#487a4a" stroke="#333" stroke-width="0.5"><title>Id 214, Wert -43.0</title></circle>
<circle cx="1043.3" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 215, Wert -22.0</title></circle>
<circle cx="1081.1" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 216, Wert -22.0</title></circle>
<circle cx="1118.9" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 217, Wert -25.0</title></circle>
<circle cx="1156.7" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 218, Wert -25.0</title></circle>
<circle cx="1194.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 219, Wert -22.0</title></circle>
<circle cx="1232.4" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 220, Wert -22.0</title></circle>
<circle cx="1270.2" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 221, Wert -22.0</title></circle>
<circle cx="1308.0" cy="330.0" r="5" fill="#407e4b" stroke="#333" stroke-width="0.5"><title>Id 222, Wert -38.0</title></circle>
<circle cx="1345.8" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 223, Wert -22.0</title></circle>
<circle cx="1383.6" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 224, Wert -22.0</title></circle>
<circle cx="1421.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 225, Wert -22.0</title></circle>
<circle cx="1459.3" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 226, Wert -22.0</title></circle>
<circle cx="1497.1" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 227, Wert -22.0</title></circle>
<circle cx="1534.9" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 228, Wert -25.0</title></circle>
<circle cx="1572.7" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 229, Wert -22.0</title></circle>
<circle cx="1610.5" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 230, Wert -25.0</title></circle>
<circle cx="1648.4" cy="330.0" r="5" fill="#716242" stroke="#333" stroke-width="0.5"><title>Id 231, Wert -70.0</title></circle>
<circle cx="1686.2" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 232, Wert -22.0</title></circle>
<circle cx="1724.0" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 233, Wert -25.0</title></circle>
<circle cx="1761.8" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 234, Wert -22.0</title></circle>
<circle cx="1799.6" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 235, Wert -22.0</title></circle>
<circle cx="1837.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 236, Wert -22.0</title></circle>
<circle cx="1875.3" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 237, Wert -22.0</title></circle>
<circle cx="1913.1" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 238, Wert -22.0</title></circle>
<circle cx="1950.9" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 239, Wert -25.0</title></circle>
<circle cx="1988.7" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 240, Wert -25.0</title></circle>
<circle cx="2026.5" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 241, Wert -22.0</title></circle>
<circle cx="2064.4" cy="330.0" r="5" fill="#487a4a" stroke="#333" stroke-width="0.5"><title>Id 242, Wert -43.0</title></circle>
<circle cx="2102.2" cy="330.0" r="5" fill="#2c894f" stroke="#333" stroke-width="0.5"><title>Id 243, Wert -25.0</title></circle>
<circle cx="2140.0" cy="330.0" r="5" fill="#288c50" stroke="#333" stroke-width="0.5"><title>Id 244, Wert -22.0</title></circle>
<text x="97.8" y="352.0" text-anchor="middle" font-size="12" font-weight="bold" fill="#c04040">190</text>
<text x="48" y="64.0" text-anchor="end" font-size="11" fill="#666">Gen 0</text>
<text x="48" y="154.0" text-anchor="end" font-size="11" fill="#666">Gen 1</text>
<text x="48" y="244.0" text-anchor="end" font-size="11" fill="#666">Gen 2</text>
<text x="48" y="334.0" text-anchor="end" font-size="11" fill="#666">Gen 3</text>
</svg>

After

Width:  |  Height:  |  Size: 48 KiB

+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="650" viewBox="0 0 900 650" font-family="sans-serif">
<rect width="100%" height="100%" fill="white"/>
<text x="450" y="30" text-anchor="middle" font-size="16" fill="#333">Entwicklung der Loesungsfindung</text>
<line x1="60" y1="60" x2="60" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="390.0" x2="840" y2="390.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="394.0" text-anchor="end" font-size="11" fill="#666">-127</text>
<line x1="60" y1="324.0" x2="840" y2="324.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="328.0" text-anchor="end" font-size="11" fill="#666">-106</text>
<line x1="60" y1="258.0" x2="840" y2="258.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="262.0" text-anchor="end" font-size="11" fill="#666">-85</text>
<line x1="60" y1="192.0" x2="840" y2="192.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="196.0" text-anchor="end" font-size="11" fill="#666">-64</text>
<line x1="60" y1="126.0" x2="840" y2="126.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="130.0" text-anchor="end" font-size="11" fill="#666">-43</text>
<line x1="60" y1="60.0" x2="840" y2="60.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="64.0" text-anchor="end" font-size="11" fill="#666">-22</text>
<text x="18" y="225.0" text-anchor="middle" font-size="12" fill="#333" transform="rotate(-90 18 225.0)">Wertigkeit (hoeher = besser)</text>
<polyline points="60.0,60.0 146.7,60.0 233.3,60.0 320.0,60.0 406.7,60.0 493.3,60.0 580.0,60.0 666.7,60.0 753.3,60.0 840.0,60.0" fill="none" stroke="#2f6f4f" stroke-width="2"/>
<polyline points="60.0,120.1 146.7,140.8 233.3,133.9 320.0,62.5 406.7,95.9 493.3,84.7 580.0,60.0 666.7,92.8 753.3,81.9 840.0,60.0" fill="none" stroke="#c08a2d" stroke-width="2"/>
<polyline points="60.0,390.0 146.7,390.0 233.3,390.0 320.0,69.4 406.7,374.3 493.3,374.3 580.0,60.0 666.7,374.3 753.3,374.3 840.0,60.0" fill="none" stroke="#a03030" stroke-width="2"/>
<line x1="680" y1="70" x2="704" y2="70" stroke="#2f6f4f" stroke-width="2"/>
<text x="710" y="74" font-size="11" fill="#333">beste Loesung</text>
<line x1="680" y1="88" x2="704" y2="88" stroke="#c08a2d" stroke-width="2"/>
<text x="710" y="92" font-size="11" fill="#333">Durchschnitt</text>
<line x1="680" y1="106" x2="704" y2="106" stroke="#a03030" stroke-width="2"/>
<text x="710" y="110" font-size="11" fill="#333">schlechteste Loesung</text>
<text x="450" y="428.0" text-anchor="middle" font-size="13" fill="#333">Anzahl erzeugter Verteilungen im Pool</text>
<line x1="60" y1="440.0" x2="60" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#333" stroke-width="1.5"/>
<line x1="60" y1="590.0" x2="840" y2="590.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="594.0" text-anchor="end" font-size="11" fill="#666">0</text>
<line x1="60" y1="515.0" x2="840" y2="515.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="519.0" text-anchor="end" font-size="11" fill="#666">60</text>
<line x1="60" y1="440.0" x2="840" y2="440.0" stroke="#eee" stroke-width="1"/>
<text x="52" y="444.0" text-anchor="end" font-size="11" fill="#666">120</text>
<polyline points="60.0,540.0 146.7,490.0 233.3,440.0 320.0,547.5 406.7,505.0 493.3,462.5 580.0,555.0 666.7,520.0 753.3,485.0 840.0,561.2" fill="none" stroke="#4060a0" stroke-width="2"/>
<text x="60.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">e</text>
<text x="146.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="233.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="320.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="406.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="493.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="580.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="666.7" y="606.0" text-anchor="middle" font-size="10" fill="#999">m</text>
<text x="753.3" y="606.0" text-anchor="middle" font-size="10" fill="#999">j</text>
<text x="840.0" y="606.0" text-anchor="middle" font-size="10" fill="#999">s</text>
<text x="450" y="638" text-anchor="middle" font-size="12" fill="#333">Zyklus-Aktion (Zeit)</text>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

+17
View File
@@ -0,0 +1,17 @@
Bloedkopf, Bestelli, = Hof 1, Tisch 2, Nummer 2
Bloedkopf, Bestelli, = Hof 1, Tisch 2, Nummer 3
Bloedkopf, Bestelli, = Hof 1, Tisch 2, Nummer 4
Brandt, Willi, Dr. = Hof 1, Tisch 4, Nummer 5
Bruegge, Heinz, = Hof 1, Tisch 5, Nummer 2
Dietrich, Marlene, = Hof 1, Tisch 5, Nummer 5
Emmerlich, Walter, = Hof 1, Tisch 4, Nummer 3
Frenzen, Heinz Harald, = Hof 1, Tisch 3, Nummer 4
Hoehn, Bernd Robert, Professor = Hof 1, Tisch 1, Nummer 4
Junke, Harald, = Hof 1, Tisch 4, Nummer 4
K, Hubert, = Hof 1, Tisch 5, Nummer 3
Leone, Sergio, = Hof 1, Tisch 4, Nummer 2
Mueller, Magnus, Professor = Hof 1, Tisch 1, Nummer 3
Ruehmann, Heinz, = Hof 1, Tisch 5, Nummer 4
Schumacher, Michael, = Hof 1, Tisch 3, Nummer 3
Schumacher, Ralf, = Hof 1, Tisch 3, Nummer 2
Stangl, Michael, Dipl. Ing. = Hof 1, Tisch 1, Nummer 2
1 Bloedkopf Bestelli = Hof 1 Tisch 2 Nummer 2
2 Bloedkopf Bestelli = Hof 1 Tisch 2 Nummer 3
3 Bloedkopf Bestelli = Hof 1 Tisch 2 Nummer 4
4 Brandt Willi Dr. = Hof 1 Tisch 4 Nummer 5
5 Bruegge Heinz = Hof 1 Tisch 5 Nummer 2
6 Dietrich Marlene = Hof 1 Tisch 5 Nummer 5
7 Emmerlich Walter = Hof 1 Tisch 4 Nummer 3
8 Frenzen Heinz Harald = Hof 1 Tisch 3 Nummer 4
9 Hoehn Bernd Robert Professor = Hof 1 Tisch 1 Nummer 4
10 Junke Harald = Hof 1 Tisch 4 Nummer 4
11 K Hubert = Hof 1 Tisch 5 Nummer 3
12 Leone Sergio = Hof 1 Tisch 4 Nummer 2
13 Mueller Magnus Professor = Hof 1 Tisch 1 Nummer 3
14 Ruehmann Heinz = Hof 1 Tisch 5 Nummer 4
15 Schumacher Michael = Hof 1 Tisch 3 Nummer 3
16 Schumacher Ralf = Hof 1 Tisch 3 Nummer 2
17 Stangl Michael Dipl. Ing. = Hof 1 Tisch 1 Nummer 2
+37
View File
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="504.572" height="108.914" viewBox="0 0 504.572 108.914">
<rect width="100%" height="100%" fill="white"/>
<polyline points="252.286,54.4572 351.2,54.4572" fill="none" stroke="#3cb44b" stroke-width="12" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="0.5"/>
<circle cx="54.4572" cy="54.4572" r="37.242" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="54.4572" cy="39.2151" r="12" fill="#888888" stroke="black" stroke-width="1"/>
<circle cx="67.6572" cy="62.0782" r="12" fill="#888888" stroke="black" stroke-width="1"/>
<circle cx="41.2572" cy="62.0782" r="12" fill="#888888" stroke="black" stroke-width="1"/>
<circle cx="54.4572" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="54.4572" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">1</text>
<circle cx="153.372" cy="54.4572" r="44.4572" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="153.372" cy="32" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
<circle cx="172.82" cy="65.6858" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
<circle cx="133.923" cy="65.6858" r="12" fill="#e6194b" stroke="black" stroke-width="1"/>
<circle cx="153.372" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="153.372" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">2</text>
<circle cx="252.286" cy="54.4572" r="37.242" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="252.286" cy="39.2151" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="265.486" cy="62.0782" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="239.086" cy="62.0782" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="252.286" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="252.286" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">3</text>
<circle cx="351.2" cy="54.4572" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="351.2" cy="35.7896" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="369.868" cy="54.4572" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="351.2" cy="73.1248" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="332.533" cy="54.4572" r="12" fill="#3cb44b" stroke="black" stroke-width="1"/>
<circle cx="351.2" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="351.2" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">4</text>
<circle cx="450.115" cy="54.4572" r="40.6676" fill="white" stroke="black" stroke-width="1.5"/>
<circle cx="450.115" cy="35.7896" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
<circle cx="468.782" cy="54.4572" r="12" fill="#4363d8" stroke="black" stroke-width="1"/>
<circle cx="450.115" cy="73.1248" r="12" fill="#f58231" stroke="black" stroke-width="1"/>
<circle cx="431.447" cy="54.4572" r="12" fill="#f58231" stroke="black" stroke-width="1"/>
<circle cx="450.115" cy="54.4572" r="12" fill="white" fill-opacity="0.75"/>
<text x="450.115" y="54.4572" text-anchor="middle" dominant-baseline="central" font-size="13.2" font-weight="bold" fill="black">5</text>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

+27
View File
@@ -0,0 +1,27 @@
[1]
Dipl. Ing. Michael Stangl = Hof 1, Tisch 1, Nummer 1
Professor Magnus Mueller = Hof 1, Tisch 1, Nummer 2
Professor Bernd Robert Hoehn = Hof 1, Tisch 1, Nummer 3
[2]
Bestelli Bloedkopf = Hof 1, Tisch 2, Nummer 1
Bestelli Bloedkopf = Hof 1, Tisch 2, Nummer 2
Bestelli Bloedkopf = Hof 1, Tisch 2, Nummer 3
[3]
Ralf Schumacher = Hof 1, Tisch 3, Nummer 1
Michael Schumacher = Hof 1, Tisch 3, Nummer 2
Heinz Harald Frenzen = Hof 1, Tisch 3, Nummer 3
[4]
Sergio Leone = Hof 1, Tisch 4, Nummer 1
Walter Emmerlich = Hof 1, Tisch 4, Nummer 2
Harald Junke = Hof 1, Tisch 4, Nummer 3
Dr. Willi Brandt = Hof 1, Tisch 4, Nummer 4
[5]
Heinz Bruegge = Hof 1, Tisch 5, Nummer 1
Hubert K = Hof 1, Tisch 5, Nummer 2
Heinz Ruehmann = Hof 1, Tisch 5, Nummer 3
Marlene Dietrich = Hof 1, Tisch 5, Nummer 4
+93
View File
@@ -0,0 +1,93 @@
{
"gruppen": [
{
"name": "einfache Gruppe aus drei Personen\n\t mit festem Wunsch fuer einen Tisch",
"tisch": 1,
"personen": [
{
"vorname": "Michael",
"nachname": "Stangl",
"titel": "Dipl. Ing."
},
{
"vorname": "Magnus",
"nachname": "Mueller",
"titel": "Professor"
},
{
"vorname": "Bernd Robert",
"nachname": "Hoehn",
"titel": "Professor"
}
]
},
{
"name": "einfache Gruppe aus zwei Personen",
"personen": [
{
"vorname": "Heinz",
"nachname": "Bruegge"
},
{
"vorname": "Hubert",
"nachname": "K"
}
]
},
{
"personen": [
{
"vorname": "Heinz",
"nachname": "Ruehmann"
},
{
"vorname": "Marlene",
"nachname": "Dietrich"
}
]
},
{
"personen": [
{
"vorname": "Sergio",
"nachname": "Leone"
},
{
"vorname": "Walter",
"nachname": "Emmerlich"
},
{
"vorname": "Harald",
"nachname": "Junke"
},
{
"vorname": "Willi",
"nachname": "Brandt",
"titel": "Dr."
},
{
"vorname": "Michael",
"nachname": "Schumacher"
},
{
"vorname": "Ralf",
"nachname": "Schumacher"
},
{
"vorname": "Heinz Harald",
"nachname": "Frenzen"
}
]
},
{
"name": "Gruppe aus drei anonymen Personen",
"anzahl": 3,
"personen": [
{
"vorname": "Bestelli",
"nachname": "Bloedkopf"
}
]
}
]
}
-90
View File
@@ -1,90 +0,0 @@
<Bestellung>
<!-- einfache Gruppe aus drei Personen
mit festem Wunsch fuer einen Tisch-->
<Gruppe>
<Person>
<Vorname>Michael</Vorname>
<Nachname>Stangl</Nachname>
<Titel>Dipl. Ing.</Titel>
</Person>
<Person>
<Vorname>Magnus</Vorname>
<Nachname>Mueller</Nachname>
<Titel>Professor</Titel>
</Person>
<Person>
<Vorname>Bernd Robert</Vorname>
<Nachname>Hoehn</Nachname>
<Titel>Professor</Titel>
</Person>
<Tisch>1</Tisch>
</Gruppe>
<!-- einfache Gruppe aus zwei Personen -->
<Gruppe>
<Person>
<Vorname>Heinz</Vorname>
<Nachname>Bruegge</Nachname>
</Person>
<Person>
<Vorname>Hubert</Vorname>
<Nachname>K</Nachname>
</Person>
</Gruppe>
<Gruppe>
<Person>
<Vorname>Heinz</Vorname>
<Nachname>Ruehmann</Nachname>
</Person>
<Person>
<Vorname>Marlene</Vorname>
<Nachname>Dietrich</Nachname>
</Person>
</Gruppe>
<Gruppe>
<Person>
<Vorname>Sergio</Vorname>
<Nachname>Leone</Nachname>
</Person>
<Person>
<Vorname>Walter</Vorname>
<Nachname>Emmerlich</Nachname>
</Person>
<Person>
<Vorname>Harald</Vorname>
<Nachname>Junke</Nachname>
</Person>
<Person>
<Vorname>Willi</Vorname>
<Nachname>Brandt</Nachname>
<Titel>Dr.</Titel>
</Person>
<Person>
<Vorname>Michael</Vorname>
<Nachname>Schumacher</Nachname>
</Person>
<Person>
<Vorname>Ralf</Vorname>
<Nachname>Schumacher</Nachname>
</Person>
<Person>
<Vorname>Heinz Harald</Vorname>
<Nachname>Frenzen</Nachname>
</Person>
</Gruppe>
<!--Gruppe aus drei anonymen Personen-->
<Gruppe>
<Person>
<Vorname>Bestelli</Vorname>
<Nachname>Bloedkopf</Nachname>
</Person>
<Anzahl>3</Anzahl>
</Gruppe>
</Bestellung>