{
  "version": 3,
  "sources": ["/cdn/shop/t/25/assets/sen-raumplaner.js?x=9388"],
  "sourcesContent": ["/*\n  Raumplaner Pr\u00E4senzmelder (sections/sen-raumplaner.liquid).\n\n  Der Kunde zeichnet seinen Raum, stellt M\u00F6bel, T\u00FCren und Melder hinein und sieht, was jeder Melder\n  erfasst, welche M\u00F6bel in derselben Zone liegen und was durch T\u00FCren hinaus reicht.\n\n  Zwei Melderklassen (Fernando 21.10., nach Gespr\u00E4ch mit Christian): Basis, KL und KL LD sind Raum-Pr\u00E4senzmelder,\n  ihre Entfernungszonen spielen im Planer keine Rolle; es z\u00E4hlt, ob die Aufenthaltsm\u00F6bel im Bereich liegen, in dem\n  auch Stillsitzen erkannt wird (kr\u00E4ftig; hell = nur Bewegung; wei\u00DF = nicht erfasst). Der KL MZ ist der\n  Zonen-Pr\u00E4senzmelder: er unterscheidet bis zu vier selbst gezeichnete Bereiche (Stufe 2, noch nicht gebaut).\n  \u201EMelder hinzuf\u00FCgen\u201C fragt zuerst, was der Melder tun soll (neuKlasse), und zeigt dann die Modelle der Klasse.\n  \u201EMelder vorschlagen\u201C sucht die g\u00FCnstigste Abdeckung aller Pl\u00E4tze (plaetzeGruppen), \u201EBeste Stelle\u201C die Wandstelle\n  mit der besten Abdeckung f\u00FCr den gew\u00E4hlten Melder. Hinweise zu T\u00FCren, Fenstern und St\u00F6ren wie bisher.\n  Herkunft: Prototyp entwuerfe/raumplaner (Okt. 2026, nicht im Repo); ab hier wird diese Datei gepflegt.\n\n  Warum ein eigenes Element mit Shadow-DOM: Das Theme setzt global .btn, .nav, .notice, .dialog,\n  `input { display:block; width:100% }` und unter 768 px `h2, h3 { font-size: 24px !important }`. Im\n  Shadow-DOM greift davon nichts, nur Schrift und Farbe werden vererbt (Fallen: senvolon-theme-setup).\n\n  Texte: alle aus locales/*.json, Zweig raumplaner (Liste im Snippet sen-raumplaner-texte, erzeugt von\n  scripts/raumplaner-texte.py). Platzhalter in einfachen Klammern: {name}. Deutsch siezt wie der Shop.\n  Preise und Lieferbarkeit kommen aus Shopify (Section), die Messwerte der Melder stehen unten in MODELLE.\n\n  Beantwortet: Pr\u00E4senz (ruhende Personen) reicht bei Basis, KL und KL LD bis etwa 1 m vor dem Ende der\n  Reichweite, die 4 m gelten nur f\u00FCr den KL MZ (Fernando 17.10.). So rechnet kern().\n\n  Am Ger\u00E4t abgelesen (Oberfl\u00E4che KL LD 192.168.10.102, Basis .103, 17.10., nur gelesen):\n  - Zonen sind frei einstellbare Entfernungsbereiche in cm (\u201EVon/Bis\u201C, ab Werk KL LD 0\u2013180\u2013\u2026\u2013900, Basis\n    0\u2013150\u2013300\u2013450); gemeldet wird die Zone, in der die gemessene Entfernung liegt. Also: getrennt wird nur\n    nach Entfernung. Die Werkszonen des KL sind wie bei der Basis angenommen (Frage an Christian).\n  - KL LD: 13 Stufen, Abstand 0,75/0,5/0,2 m, Einstellung \u201ETop mounted / Side mounted\u201C (Decke vorgesehen).\n  - Basis (wie KL): ruhend sind Stufe 0 und 1 fest auf h\u00F6chste Empfindlichkeit, nicht blind; erkannt wird\n    dort immer, ausblenden l\u00E4sst es sich nicht. Beim KL LD sind alle Stufen einstellbar.\n\n  Beantwortet (Fernando 17.10.): An der Decke gilt derselbe \u00D6ffnungswinkel wie an der Wand, der Kreis auf dem\n  Boden h\u00E4ngt von der Raumh\u00F6he ab (so rechnet decke()); auch die Basis darf an die Decke. Gegen gegenseitiges\n  St\u00F6ren hat die Firmware derzeit nichts, der Hinweis 'stoeren' bleibt.\n\n  Offene Fragen, bevor der Planer ohne \u201EBeta\u201C l\u00E4uft:\n  3. Decke: Wird die Entfernung schr\u00E4g gemessen (Melder \u2192 Person, so rechnet der Planer) oder am Boden? \u2013 Christian\n  5. Decke: Metall-M\u00F6bel und Schr\u00E4nke schirmen hier nicht ab (Annahme). Stimmt das f\u00FCr eine\n     sitzende Person direkt dahinter? \u2013 Christian\n  6. Fensterglas und Glast\u00FCren gelten als dicht (Fernando 16.10.: Glas reflektiert sehr wahrscheinlich).\n     Bodentief oder mit Br\u00FCstung \u00E4ndert damit nichts an der Rechnung, nur an der Zeichnung. \u2013 Christian\n  7. Randbereich: 5\u00B0 je Seite und etwa 1 m am Ende der Reichweite bei 0,75-m-Stufen (Christian). Die 1 m sind\n     nicht fest (Fernando 17.10.), der Planer verk\u00FCrzt den Rand im Verh\u00E4ltnis zur Stufe (0,2 m \u2192 0,27 m).\n     Decke rechnet seit 21.10. mit 0,75-m-Stufen (Fernando; mit den 0,2 m der Anleitung blieben \u00D8 2 m Reichweite und\n     \u00D8 0,6 m Pr\u00E4senz, der Shop sagt 8 m). Ob die Anleitung oder der Shop-Satz stimmt: Frage an Christian.\n  8. T\u00FCren d\u00E4mpfen (Fernando 20.10.): hinter einer geschlossenen T\u00FCr und hinter dem offenen Blatt erkennt der\n     Planer Bewegung, aber kein Stillsitzen (daempfer). Stimmt das, auch f\u00FCr ein Blatt direkt vor dem Melder? \u2013 Christian\n*/\n(function () {\n  'use strict';\n\n  const ANSICHT_HTML = `\n<div id=\"app\">\n  <main id=\"plan\">\n    <svg id=\"svg\"></svg>\n    <div class=\"plan-kopf\">\n      <button class=\"plan-knopf\" id=\"menue-auf\">\n        <svg viewBox=\"0 0 20 20\" width=\"20\" height=\"20\"><path d=\"M3 5h14M3 10h14M3 15h14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>\n      </button>\n      <a class=\"plan-logo\" id=\"logo\" hidden><img alt=\"\"></a>\n      <button class=\"plan-pille\" id=\"link-knopf\" data-akt=\"link\">\n        <svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8.5 11.5a3.5 3.5 0 0 0 5 0l2.5-2.5a3.5 3.5 0 0 0-5-5L10 5M11.5 8.5a3.5 3.5 0 0 0-5 0L4 11a3.5 3.5 0 0 0 5 5l1-1\"/></svg>\n        <span class=\"link-text\"></span>\n      </button>\n    </div>\n    <button class=\"plan-summe\" id=\"summe\"><span class=\"summe-text\"><span class=\"summe-n\"></span><span class=\"summe-preis\"></span></span><span class=\"summe-weiter\"><span class=\"summe-weiter-text\"></span></span></button>\n    <div class=\"werkzeuge\" id=\"werkzeuge\">\n      <div class=\"plan-gruppe\" id=\"zoom\">\n        <button data-zoom=\"in\">+</button>\n        <button data-zoom=\"out\">\u2212</button>\n        <button data-zoom=\"fit\">\n          <svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\"><path d=\"M3 8V3h5M12 3h5v5M17 12v5h-5M8 17H3v-5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>\n        </button>\n      </div>\n      <button class=\"plan-knopf\" id=\"masse-knopf\" data-akt=\"masse\" aria-pressed=\"true\">\n        <svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linejoin=\"round\"><path d=\"M2.5 13.5l11-11 4 4-11 11zM6 10l1.5 1.5M8.5 7.5l1.5 1.5M11 5l1.5 1.5\"/></svg>\n      </button>\n    </div>\n    <div class=\"legende\" id=\"legende\" hidden></div>\n    <div class=\"warten\" id=\"warten\" role=\"status\" hidden><span class=\"warten-kreis\" aria-hidden=\"true\"></span><span id=\"warten-text\"></span></div>\n    <div class=\"nur-vorlesen\" id=\"status\" aria-live=\"polite\"></div>\n    <div class=\"plan-meldung\" id=\"plan-meldung\" aria-hidden=\"true\" hidden></div>\n    <div class=\"plan-gruppe\" id=\"verlauf\">\n      <button id=\"rueckgaengig\" disabled>\n        <svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\"><path d=\"M7 4L3 8l4 4M3 8h9a5 5 0 0 1 0 10H9\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>\n      </button>\n      <button id=\"wiederholen\" disabled>\n        <svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\"><path d=\"M13 4l4 4-4 4M17 8H8a5 5 0 0 0 0 10h3\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>\n      </button>\n    </div>\n  </main>\n  <section id=\"sheet\"></section>\n</div>\n<dialog class=\"dialog blatt\" id=\"blatt\" aria-labelledby=\"blatt-titel\">\n  <div class=\"blatt__kopf\">\n    <h2 id=\"blatt-titel\"></h2>\n    <button class=\"plan-knopf\" data-akt=\"blattzu\">\n      <svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\"><path d=\"M5 5l10 10M15 5L5 15\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/></svg>\n    </button>\n  </div>\n  <div id=\"blatt-inhalt\"></div>\n</dialog>`;\n\n  class SenRaumplaner extends HTMLElement {\n    connectedCallback() {\n      if (this.gestartet) { if (this.verbinden) this.verbinden(); return; }\n      this.gestartet = true;\n      starten(this);\n    }\n    // Rendert der Theme-Editor die Section neu, bleiben sonst Tastatur- und Resize-Listener der alten Instanz h\u00E4ngen\n    disconnectedCallback() { if (this.trennen) this.trennen(); }\n  }\n  if (!customElements.get('sen-raumplaner')) customElements.define('sen-raumplaner', SenRaumplaner);\n\n  function starten(host) {\n    const daten = n => { const el = host.querySelector(`script[data-${n}]`); try { return el ? JSON.parse(el.textContent) : {}; } catch (e) { return {}; } };\n    const TEXTE = daten('texte'), SHOPDATEN = daten('produkte'), LINKS = daten('links');\n    const SPRACHE = host.dataset.sprache || 'de', WAEHRUNG = host.dataset.waehrung || 'EUR';\n    const ROUTER = host.dataset.router || '';\n    // Rechenkern ohne Zustand, DOM und Texte: assets/sen-raumplaner-kern.js (in Node testbar, scripts/raumplaner-tests.mjs)\n    const KERN = window.SenRaumplanerKern;\n    const { MODELLE, wm, praesenzBis, grundStufe, ARTEN, BEZUG, MAX_RAUM, MAX_MOEBEL, MAX_HOEHE, RASTER_JE_M, raster, rad, normWinkel, neueId, kanten, innenWinkelKante, innenWinkelEcke, rechteckKanten, innen, ausrichten, MIN_WAND, gueltig, rund, grad360, wandPunkt, oeffnungProben, nachAussen, tuerBlatt, istDecke, MAX_ZONEN_ECKEN, inRechteck, rechteckPoly, istRechteck, zuordnen, ursprung, strahl, verdeckt, imRaum } = KERN;\n\n    const root = host.attachShadow({ mode: 'open' });\n    root.innerHTML = `<link rel=\"stylesheet\" href=\"${host.dataset.css}\">` + ANSICHT_HTML;\n\n    // Text aus locales/*.json; {platzhalter} werden ersetzt. Fehlt ein Schl\u00FCssel, steht er sichtbar da.\n    const t = (k, v) => {\n      let s = TEXTE[k] != null ? TEXTE[k] : k;\n      if (v) s = s.replace(/\\{(\\w+)\\}/g, (m, n) => (v[n] != null ? v[n] : m));\n      return s;\n    };\n\n    // Preis (Cent, W\u00E4hrung des Marktes), Lieferbarkeit und Adresse aus der Section\n    for (const M of Object.values(MODELLE)) {\n      const v = SHOPDATEN[M.variante];\n      M.preis = v ? v.preis : null;\n      M.lieferbar = !!(v && v.lieferbar);\n      M.url = v ? v.url : null;\n      M.bild = v ? v.bild : null;\n    }\n    // Wand und Decke rechnen mit der gr\u00F6\u00DFten Stufe (0,75 m): so stimmt der Deckenkreis mit dem Shop-Satz \u201E8 m Durchmesser\n    // bei 2,50 m\u201C \u00FCberein und ist bei Basis, KL und KL MZ gleich gro\u00DF (Fernando 21.10.). Die Anleitung empfiehlt f\u00FCr die\n    // Decke 0,2 m, damit blieben nur 1,8 m Reichweite (\u00D8 2 m); das steht als Satz am Deckenmelder (decke_stufe).\n    const ANLEITUNG_DECKE = 0.2;\n    // Melderfarben = Zonenfarben der Ger\u00E4teoberfl\u00E4che (Tokens), ab dem f\u00FCnften Melder wieder von vorn;\n    // der Buchstabe unterscheidet. Cyan (Signal), Rot (Fehler) und Navy (Akzent) bleiben frei.\n    // Eine Farbe f\u00FCr alle Melder (Fernando 21.10.: je Melder eine Farbe wurde mit mehreren Meldern wirr); der angetippte\n    // Melder wird kr\u00E4ftiger und mit Rand gezeichnet. EINFARBIG = false bringt die Farben je Melder zur\u00FCck.\n    const EINFARBIG = true;\n    const farbe = i => EINFARBIG ? 'var(--color-feld)' : `var(--color-zone-${i % 4 + 1})`;\n    // Einfarbig: ist ein anderer Melder angetippt, tritt dieser grau zur\u00FCck\n    const andererGewaehlt = s => EINFARBIG && auswahl && auswahl.typ === 'melder' && auswahl.id !== s.id;\n    // Deckkraft der Fl\u00E4chen: hell = nur Bewegung, kern kommt dar\u00FCber (zusammen rund 0,36). Legende rechnet mit.\n    const FLAECHE = { hell: 0.14, kern: 0.26, hellHervor: 0.24, kernHervor: 0.42 };   // \u2026Hervor: der angetippte Melder\n    // Vorlagen: name ist der Schl\u00FCssel des Textes (raumplaner.v_\u2026); im Plan steht der \u00FCbersetzte Name.\n    // Acht Vorlagen, das Material h\u00E4ngt an der Vorlage und ist nicht w\u00E4hlbar (Fernando 18.10.). Runder Tisch und\n    // eckige S\u00E4ule \u00FCber \u201ERund/Eckig\u201C, ein Wandst\u00FCck ist eine eckige S\u00E4ule mit anderen Ma\u00DFen.\n    // \u00C4ltere Links und die Beispielr\u00E4ume nennen auch tvwand, runder_tisch, moebel; die Texte dazu bleiben.\n    // ort: Platz, an dem sich Personen aufhalten. Kommt aus der Vorlage, gefragt wird nicht mehr (Fernando 20.10.: Sitzm\u00F6bel,\n    // Betten, Schreibtisch und K\u00FCchenzeile ja, Schrank und Fernseher nein).\n    const VORLAGEN = [\n      { name: 'sofa', w: 2.2, h: 0.9, ort: true },\n      { name: 'sessel', w: 0.9, h: 0.9, ort: true },\n      { name: 'stuhl', w: 0.45, h: 0.5, ort: true },\n      { name: 'esstisch', w: 1.8, h: 1.4, ort: true },\n      { name: 'bett', w: 1.8, h: 2.0, ort: true },\n      { name: 'schreibtisch', w: 1.4, h: 0.7, ort: true },\n      // man steht davor; gerechnet wie Polster (Annahme: Unterschr\u00E4nke schirmen nicht ab), z\u00E4hlt als Platz\n      { name: 'kueche', w: 2.4, h: 0.6, ort: true },\n      // Bad (Fernando 21.10.): man sitzt, liegt oder steht darin, gerechnet wie Polster\n      { name: 'dusche', w: 0.9, h: 0.9, ort: true },\n      { name: 'wc', w: 0.4, h: 0.65, ort: true },\n      { name: 'badewanne', w: 1.7, h: 0.75, ort: true },\n      { name: 'kommode', w: 1.2, h: 0.45 },                           // niedrig: der Melder sieht dar\u00FCber, kein Platz\n      { name: 'schrank', w: 1.2, h: 0.6, stoff: 'hoch' },\n      { name: 'fernseher', w: 1.4, h: 0.08, stoff: 'metall' },\n      { name: 'saeule', w: 0.4, h: 0.4, stoff: 'massiv', rund: true },   // Bauteil: unter \u201ERaum\u201C, nicht bei den M\u00F6beln\n    ];\n    const istBauteil = v => stoff(v) === 'massiv';\n    const vorlageName = k => t('v_' + k);\n    // T\u00FCren, Durchg\u00E4nge, Fenster (Fernando 16.10.). Sitzen auf einer Wand: x, y ist die Mitte, sie rastet an\n    // der n\u00E4chsten Wand ein. Durchgang und T\u00FCr lassen den Melder hinaussehen, Fensterglas reflektiert.\n    // Ein Vorhang vor dem Fenster l\u00F6st aus, wenn er sich bewegt.\n    // Fernando 18.10.: kein Material der T\u00FCr (gilt als Holz), keine Br\u00FCstung/bodentief, offen/zu nur \u00FCber den\n    // Knopf \u201Ealle \u00F6ffnen\u201C. \u00C4ltere Links mit stoff oder hoehe an der \u00D6ffnung: wird nicht mehr ausgewertet.\n    const OEFFNUNG_VORLAGEN = [\n      { art: 'tuer', b: 0.9 },\n      { art: 'durchgang', b: 1.0 },\n      { art: 'fenster', b: 1.2, vorhang: false },\n    ];\n    const artName = a => t('art_' + a);\n    // offen: T\u00FCr oder Fenster steht offen (Knopf \u201Ealle \u00F6ffnen\u201C); dann sieht der Melder hinaus wie durch einen Durchgang.\n    // T\u00FCren d\u00E4mpfen (Fernando 20.10., \u201Eso ein Mittelding\u201C): geschlossen kommt Bewegung hindurch, aber kein Stillsitzen;\n    // offen d\u00E4mpft stattdessen das Blatt im Raum (daempfer).\n    const offen = o => o.art === 'durchgang' || o.zustand === 'offen';\n    const durchlaessig = o => offen(o) || o.art === 'tuer';\n    function oeffnungName(o) {\n      const gleich = S.oeffnungen.filter(q => q.art === o.art);\n      return artName(o.art) + (gleich.length > 1 ? ' ' + (gleich.indexOf(o) + 1) : '');\n    }\n    // Material: Polster l\u00E4sst der Radar durch, Metall und Mauerwerk nicht. Kommt aus der Vorlage.\n    // 'hoch': Schrank und Co. verdecken wie eine Wand (Fernando 19.10.), vorsichtig gerechnet, ein voller Schrank\n    // d\u00E4mpft stark. Sofa, Bett, Tisch nicht: wer darauf sitzt, ist dar\u00FCber. Von der Decke aus verdeckt er nicht.\n    const stoff = o => o.stoff || 'weich';\n    // Schirmt das M\u00F6bel einen Wandmelder ab? Nicht, wenn es niedriger als der Melder ist (Fernando 21.10.: sein Melder\n    // h\u00E4ngt \u00FCber dem Fernseher und sieht dar\u00FCber hinweg)\n    const schirmt = o => stoff(o) !== 'weich' && !o.niedrig;\n    const ausblendbar = M => !M.stufe;              // KL MZ: Bereiche lassen sich in der App ausblenden\n    // Aufenthalt: weiche M\u00F6bel, auf denen jemand sitzt oder liegt. Gruppen gibt es vorerst keine (Fernando 20.10.: die\n    // Bereichszuweisung hat keiner verstanden); Schritt 2 zeigt je Zone, welche M\u00F6bel darin liegen, und sagt, dass\n    // M\u00F6bel in derselben Zone nicht getrennt erkannt werden.\n    const istOrt = o => stoff(o) === 'weich' && o.ort;\n    const moebelName = id => (S.moebel.find(o => o.id === id) || {}).name || '';\n    const stoffKurz = o => (stoff(o) === 'metall' ? ' \u00B7 ' + t('kurz_metall') : stoff(o) === 'massiv' ? ' \u00B7 ' + t('kurz_massiv')\n      : stoff(o) === 'hoch' ? ' \u00B7 ' + t('kurz_hoch') : '') + (o.niedrig ? ' \u00B7 ' + t('kurz_niedrig') : '');\n    const masse = o => o.rund ? `\u00D8 ${zahl(o.w, 2)} m` : `${zahl(o.w, 2)} \u00D7 ${zahl(o.h, 2)} m`;\n    const FANG = 0.5;           // Abstand in m, ab dem ein Melder an Wand oder Ecke einrastet; weiter drin wird er Deckenmelder\n    const fangM = () => Math.max(FANG, 24 / ansicht.k);   // auf dem Bildschirm mindestens 24 px, sonst \u201Everliert\u201C man die Wand beim Loslassen\n    const PROBE = 0.3;          // m, Probenabstand in Zonen, auf M\u00F6beln und an der Wand\n    const PROBE_GROB = 0.5;     // m, Probenabstand f\u00FCr Fl\u00E4che und Decke\n    const STRAHL_SCHRITT = 2;   // Grad zwischen zwei Strahlen bei N\u00E4he- und T\u00FCrblattpr\u00FCfung\n    const MIN_SEITE = 0.3;      // m, kleinste Seite von Zone und Grenze\n    const REICHWEITE_OPTION = false;   // Reiter \u201EReichweite\u201C am Melder zeigen (Fernando 22.10.: vorerst raus)\n    let mitDecke = false;       // H\u00E4kchen beim Vorschlag: auch Stellen an der Decke probieren (Fernando 22.10.; Deckenreichweite offen)\n\n    const $ = s => root.querySelector(s);\n    const svg = $('#svg');\n    const sheet = $('#sheet');\n\n    let S;                       // Zustand: raum, moebel, melder, oeffnungen\n    let auswahl = null;          // { typ: 'moebel' | 'melder' | 'oeffnung' | 'wand' | 'ecke', id }\n    let modus = 'start';         // start | raum | moebel-neu | melder-neu | moebel | melder | oeffnung | hinweise\n    const ansicht = { k: 40, tx: 0, ty: 0 };\n    // Kernfunktionen, die den Raum oder seine H\u00F6he brauchen\n    const huelle = (poly = raumPoly()) => KERN.huelle(poly);\n    const oeffnungLage = (o, poly = raumPoly()) => KERN.oeffnungLage(o, poly);\n    const decke = s => KERN.decke(s, S.raum.hoehe);\n    const kern = s => KERN.kern(s, S.raum.hoehe);\n    const pruefen = d => KERN.pruefen(d);\n\n    // ---------- Hilfen ----------\n    const zahlFormate = {};\n    const zahl = (n, st = 1) => (zahlFormate[st] || (zahlFormate[st] = new Intl.NumberFormat(SPRACHE,\n      { minimumFractionDigits: st, maximumFractionDigits: st, useGrouping: false }))).format(n);\n    const meter = v => zahl(v, Math.abs(v - Math.round(v)) < 0.05 ? 0 : 1);   // Beschriftung im Plan, ohne Nachkomma-Nullen\n    const geldFormat = new Intl.NumberFormat(SPRACHE, { style: 'currency', currency: WAEHRUNG });\n    const geld = cent => geldFormat.format(cent / 100);\n    // Drehung eines Wandmelders gegen\u00FCber der Wand (in der Ecke: gegen\u00FCber der Diagonale in den Raum); frei stehend die Richtung\n    function drehText(s) {\n      const i = s.wand ? +s.wand.slice(1) : NaN, poly = raumPoly();\n      if (Number.isNaN(i) || !poly[i]) return grad360(s.dir) + '\u00B0';\n      const g = Math.round(normWinkel(s.dir - (s.wand[0] === 'e' ? innenWinkelKante(poly, i) : innenWinkelEcke(poly, i))));\n      return !g ? t('dreh_gerade') : g < 0 ? t('dreh_links', { g: -g }) : t('dreh_rechts', { g });\n    }\n    const buchstabe = i => String.fromCharCode(65 + i);\n    const esc = s => String(s).replace(/[&<>\"]/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;' }[c]));\n\n    // Beispielr\u00E4ume im Men\u00FC \u201EBeispiel laden\u201C (der Planer startet leer, Fernando 22.10.); Fernando hat sie im\n    // Planer gebaut. \u201EWohnen und Essen, L-Form\u201C (Testfall aus dem Briefing) ist seit 22.10. raus.\n    // M\u00F6belnamen sind Vorlagen-Schl\u00FCssel und werden beim Laden \u00FCbersetzt.\n    const BEISPIELE = [\n      { name: 'b_raumteile', daten: {\n        raum: { form: 'frei', b: 4, l: 5, ab: 1.5, at: 1.5, ecke: 'ul', hoehe: 2.5,\n          punkte: [[-0.8, 1.1], [1.58, 0.55], [4.5, 0.55], [4.5, 5.45], [0, 5.45], [0, 2.5], [-0.7, 2.5], [-0.7, 5.45], [-3.35, 5.45], [-3.35, 1.1]], glas: [7] },\n        moebel: [\n          { id: 'm1', name: 'sessel', x: 1.55, y: 0.8, w: 0.9, h: 0.9, ort: true },\n          { id: 'm2', name: 'sessel', x: 2.65, y: 0.8, w: 0.9, h: 0.9, ort: true },\n          { id: 'm3', name: 'sofa', x: 3.45, y: 1.8, w: 0.9, h: 2.2, ort: true },\n          { id: 'm4', name: 'runder_tisch', x: 2.05, y: 2.2, w: 1, h: 1, ort: true, rund: true },\n          { id: 'm5', name: 'sessel', x: 0.35, y: 4.3, w: 0.9, h: 0.9, ort: true },\n          { id: 'm6', name: 'schrank', stoff: 'hoch', x: -3.1, y: 1.25, w: 2, h: 0.6 },\n        ],\n        melder: [],\n        oeffnungen: [\n          { id: 'o1', art: 'durchgang', b: 0.9, x: 4.5, y: 4.74 },\n          { id: 'o2', art: 'tuer', b: 0.9, x: 2.06, y: 5.45, zustand: 'offen' },\n          { id: 'o3', art: 'tuer', b: 0.9, x: -3.35, y: 2.7, zustand: 'offen' },\n          { id: 'o4', art: 'tuer', b: 0.9, x: -2.07, y: 5.45, zustand: 'offen' },\n        ],\n      } },\n      { name: 'b_frei', daten: {\n        raum: { form: 'frei', b: 6.5, l: 10.9, ab: 3.5, at: 1.5, ecke: 'ul', hoehe: 2.5,\n          punkte: [[0, 0], [3.85, 0], [3.85, 2.9], [5.85, 4.1], [6.5, 4.1], [6.5, 10.9], [3.5, 10.9], [3.5, 9.4], [0, 9.4]] },\n        moebel: [\n          { id: 'm1', name: 'sofa', x: 0.2, y: 0.3, w: 3.2, h: 0.9, ort: true },\n          { id: 'm2', name: 'sofa', x: 0.2, y: 1.2, w: 0.9, h: 1.8, ort: true },\n          { id: 'm3', name: 'tvwand', x: 0.6, y: 4, w: 2.8, h: 0.3, stoff: 'hoch' },\n          { id: 'm4', name: 'fernseher', x: 1.3, y: 3.9, w: 1.4, h: 0.08, stoff: 'metall' },\n          { id: 'm5', name: 'esstisch', x: 4.35, y: 7.65, w: 1.4, h: 2.5, ort: true },\n          { id: 'm6', name: 'schrank', stoff: 'hoch', x: 1.05, y: 4.35, w: 2, h: 0.4 },\n          { id: 'm7', name: 'schrank', stoff: 'hoch', x: 0.05, y: 5.55, w: 0.6, h: 2 },\n          { id: 'm8', name: 'schrank', stoff: 'hoch', x: 0.05, y: 7.95, w: 0.6, h: 1.2 },\n        ],\n        melder: [],\n        oeffnungen: [{ id: 'o1', art: 'tuer', b: 0.9, x: 4.85, y: 3.5 }],\n      } },\n      { name: 'b_wohnzimmer', daten: {\n        raum: { form: 'frei', b: 4, l: 5, ab: 1.5, at: 1.5, ecke: 'ul', hoehe: 2.5,\n          punkte: [[0.55, 0], [3.55, 0], [3.55, -0.95], [4.5, -0.95], [4.5, -1.5], [2.95, -1.5], [2.95, -2.7], [6, -2.7], [6, 1.05], [6.75, 2], [6.75, 4], [0, 4], [0, 2], [0.55, 2]] },\n        moebel: [\n          { id: 'm1', name: 'saeule', x: 3.75, y: 2.05, w: 0.8, h: 0.4, stoff: 'massiv' },\n          { id: 'm2', name: 'sofa', x: 0.8, y: 3.05, w: 2.2, h: 0.9, ort: true },\n          { id: 'm3', name: 'sessel', x: 0.8, y: 2.15, w: 0.9, h: 0.9, ort: true },\n          { id: 'm4', name: 'fernseher', x: 1.35, y: 0.1, w: 1.4, h: 0.08, stoff: 'metall', niedrig: true },\n          { id: 'm5', name: 'kommode', x: 0.9, y: 0.2, w: 2.4, h: 0.45 },\n          { id: 'm6', name: 'esstisch', x: 4.8, y: 2.55, w: 1.2, h: 1.2, rund: true, ort: true },\n          { id: 'm7', name: 'esstisch', x: 2, y: 2.1, w: 1, h: 0.5, ort: true },\n        ],\n        // Melder wie in Fernandos Planung vom 22.10.: zwei KL LD, am Fenster links und in der Nische oben rechts\n        melder: [\n          { id: 's1', modell: 'kl_ld', x: 0.6, y: 4, dir: 300, max: 9.75, stufe: 0.75, wand: 'e10', montage: 'wand' },\n          { id: 's2', modell: 'kl_ld', x: 6, y: -1.05, dir: 165, max: 9.75, stufe: 0.75, wand: 'e7', montage: 'wand' },\n        ],\n        oeffnungen: [\n          { id: 'o1', art: 'tuer', b: 0.9, x: 6.75, y: 3.03 },\n          { id: 'o2', art: 'tuer', b: 0.9, x: 6, y: -0.36 },\n          { id: 'o3', art: 'tuer', b: 0.9, x: 6, y: -1.96 },\n          { id: 'o4', art: 'tuer', b: 0.9, x: 5.25, y: -2.7 },\n          { id: 'o5', art: 'tuer', b: 0.9, x: 3.67, y: -2.7 },\n          { id: 'o6', art: 'tuer', b: 0.9, x: 2.95, y: -2.1 },\n          { id: 'o7', art: 'fenster', b: 2, x: 0, y: 3.05 },\n          { id: 'o8', art: 'tuer', b: 0.9, x: 0, y: 0.66, seite: 'b' },\n        ],\n      } },\n    ];\n    function beispiel(nr = 0) {\n      const d = JSON.parse(JSON.stringify(BEISPIELE[nr].daten));\n      d.moebel.forEach(o => { o.name = vorlageName(o.name); });\n      return d;\n    }\n    function leer() {\n      return { raum: { form: 'rechteck', b: 4, l: 5, ab: 1.5, at: 1.5, ecke: 'ul', hoehe: 2.5 }, moebel: [], melder: [], oeffnungen: [] };\n    }\n\n    // ---------- Geometrie ----------\n    function raumPoly() { return raumPolyVon(S.raum); }\n    function raumPolyVon(R) {\n      if (R.form === 'frei' && R.punkte && R.punkte.length >= 3) return R.punkte;\n      const { form, b, l, ecke } = R;\n      if (form !== 'L') return [[0, 0], [b, 0], [b, l], [0, l]];\n      const ab = Math.min(R.ab, b - 0.5), at = Math.min(R.at, l - 0.5);\n      // im Uhrzeigersinn (y nach unten), die Aussparung sitzt in der genannten Ecke\n      if (ecke === 'ul') return [[0, 0], [b, 0], [b, l], [ab, l], [ab, l - at], [0, l - at]];\n      if (ecke === 'ur') return [[0, 0], [b, 0], [b, l - at], [b - ab, l - at], [b - ab, l], [0, l]];\n      if (ecke === 'ol') return [[ab, 0], [b, 0], [b, l], [0, l], [0, at], [ab, at]];\n      return [[0, 0], [b - ab, 0], [b - ab, at], [b, at], [b, l], [0, l]];\n    }\n\n    // Melder an Wand oder Ecke wandern mit, wenn sich W\u00E4nde bewegen; ihre Drehung zur Wand bleibt.\n    // Vor der \u00C4nderung merken, danach setzen (Ecken- und Wandnummern d\u00FCrfen sich dazwischen nicht \u00E4ndern).\n    function wandMelderMerken() {\n      const poly = raumPoly(), k = kanten(poly);\n      return S.melder.filter(s => s.wand && !istDecke(s) && +s.wand.slice(1) < poly.length).map(s => {\n        const i = +s.wand.slice(1);\n        if (s.wand[0] === 'v') return { s, i, ecke: true, dir0: s.dir, ref: innenWinkelEcke(poly, i) };\n        const [x1, y1, x2, y2] = k[i];\n        const tt = ((s.x - x1) * (x2 - x1) + (s.y - y1) * (y2 - y1)) / ((x2 - x1) ** 2 + (y2 - y1) ** 2);\n        return { s, i, t: tt, dir0: s.dir, ref: innenWinkelKante(poly, i) };\n      });\n    }\n    function wandMelderSetzen(liste) {\n      const poly = raumPoly(), k = kanten(poly);\n      for (const m of liste) {\n        if (m.ecke) {\n          [m.s.x, m.s.y] = poly[m.i];\n          m.s.dir = grad360(m.dir0 + normWinkel(innenWinkelEcke(poly, m.i) - m.ref));\n        } else {\n          const [x1, y1, x2, y2] = k[m.i];\n          m.s.x = rund(x1 + m.t * (x2 - x1)); m.s.y = rund(y1 + m.t * (y2 - y1));\n          m.s.dir = grad360(m.dir0 + normWinkel(innenWinkelKante(poly, m.i) - m.ref));\n        }\n      }\n    }\n    // Nach Einf\u00FCgen oder Entfernen einer Ecke: Lage bleibt, Nummer der Wand neu suchen, Drehung behalten\n    function nachrasten() {\n      S.melder.filter(s => s.wand && !istDecke(s)).forEach(s => {\n        const dir = s.dir; s.wand = null; einrasten(s, { x: s.x, y: s.y }); s.dir = dir;\n      });\n    }\n    function eckeEinfuegen(i) {                     // in die Mitte von Wand i, gibt die neue Eckennummer zur\u00FCck\n      const p = S.raum.punkte, q = p[(i + 1) % p.length];\n      p.splice(i + 1, 0, [rund((p[i][0] + q[0]) / 2), rund((p[i][1] + q[1]) / 2)]);\n      if (S.raum.glas) S.raum.glas = S.raum.glas.flatMap(j => j < i ? [j] : j === i ? [i, i + 1] : [j + 1]);   // beide H\u00E4lften bleiben Glas\n      nachrasten();\n      return i + 1;\n    }\n    function eckeLoeschen(i) {\n      const neu = S.raum.punkte.filter((_, j) => j !== i);\n      if (neu.length < 3 || !gueltig(neu)) return false;\n      S.raum.punkte = neu;\n      // W\u00E4nde i\u22121 und i werden eine; sie beh\u00E4lt die Art von Wand i\u22121, die Nummern danach r\u00FCcken auf\n      if (S.raum.glas) S.raum.glas = S.raum.glas.filter(j => j !== i).map(j => (j > i ? j - 1 : j));\n      nachrasten();\n      return true;\n    }\n    // Ecke ziehen; rastet an der Flucht der Nachbarecken ein, damit rechte Winkel leicht gehen\n    function eckeZiehen(i, x, y, melder) {\n      const p = S.raum.punkte, n = p.length, tol = 12 / ansicht.k;\n      x = raster(x); y = raster(y);\n      for (const j of [(i - 1 + n) % n, (i + 1) % n]) {\n        if (Math.abs(x - p[j][0]) < tol) x = p[j][0];\n        if (Math.abs(y - p[j][1]) < tol) y = p[j][1];\n      }\n      const neu = p.map((q, j) => j === i ? [x, y] : q);\n      if (!gueltig(neu)) return;\n      S.raum.punkte = neu; wandMelderSetzen(melder);\n    }\n    // Wand parallel verschieben: beide Ecken wandern entlang der Innennormalen\n    function wandSchieben(g, w) {\n      const n = g.p0.length, a = g.p0[g.i], b = g.p0[(g.i + 1) % n];\n      const len = Math.hypot(b[0] - a[0], b[1] - a[1]), nx = -(b[1] - a[1]) / len, ny = (b[0] - a[0]) / len;\n      const d = raster((w.x - g.start.x) * nx + (w.y - g.start.y) * ny);\n      const neu = g.p0.map((q, j) => j === g.i || j === (g.i + 1) % n ? [rund(q[0] + nx * d), rund(q[1] + ny * d)] : q);\n      if (!gueltig(neu)) return;\n      S.raum.punkte = neu; wandMelderSetzen(g.melder);\n    }\n    // Rechteck und L (Fernando 22.10.): eine Wand ziehen \u00E4ndert b, l, ab oder at, die Gegenwand bleibt stehen. Zieht man die\n    // obere oder linke Wand, wandert der Ursprung; der Inhalt wird gegenverschoben, damit er an den anderen W\u00E4nden bleibt.\n    // \u00D6ffnungen auf der gezogenen Wand wandern mit ihr, Wandmelder \u00FCber merken/setzen.\n    function verschiebeInhalt(dx, dy) {\n      const v = o => { o.x = rund(o.x + dx); o.y = rund(o.y + dy); };\n      S.moebel.forEach(v); S.oeffnungen.forEach(v);\n      S.melder.forEach(m => { v(m); if (m.grenze) v(m.grenze); });\n      (S.zonen || []).forEach(z => { z.p = z.p.map(([x, y]) => [rund(x + dx), rund(y + dy)]); });\n    }\n    function wandMass(g, w) {\n      const R0 = g.R0, [x1, y1, x2] = kanten(raumPolyVon(R0))[g.i];\n      const senkrecht = Math.abs(x2 - x1) < 1e-9, c = senkrecht ? x1 : y1, L = R0.form === 'L';\n      const d = raster(senkrecht ? w.x - g.start.x : w.y - g.start.y);\n      const gl = (a, b) => Math.abs(a - b) < 1e-6, R = { ...R0 };\n      let rueckt = 0;                                  // so weit r\u00FCckt der Ursprung (obere oder linke Wand gezogen)\n      if (senkrecht) {\n        if (gl(c, 0)) { R.b = R0.b - d; rueckt = d; }\n        else if (gl(c, R0.b)) R.b = R0.b + d;\n        else if (L) R.ab = R0.ecke === 'ul' || R0.ecke === 'ol' ? R0.ab + d : R0.ab - d;\n        else return;\n      } else {\n        if (gl(c, 0)) { R.l = R0.l - d; rueckt = d; }\n        else if (gl(c, R0.l)) R.l = R0.l + d;\n        else if (L) R.at = R0.ecke === 'ol' || R0.ecke === 'or' ? R0.at + d : R0.at - d;\n        else return;\n      }\n      const ok = R.b >= 1 && R.l >= 1 && R.b <= MAX_RAUM && R.l <= MAX_RAUM &&\n        (!L || (R.ab >= 0.5 && R.at >= 0.5 && R.ab <= R.b - 0.5 && R.at <= R.l - 0.5));\n      if (!ok) return;\n      Object.assign(S.raum, { b: rund(R.b), l: rund(R.l), ab: rund(R.ab), at: rund(R.at) });\n      const s = rueckt - g.angewandt;\n      if (s) { verschiebeInhalt(senkrecht ? -s : 0, senkrecht ? 0 : -s); g.angewandt = rueckt; }\n      wandMelderSetzen(g.melder);\n      const [nx1, ny1] = kanten(raumPoly())[g.i];\n      g.tueren.forEach(o => { if (senkrecht) o.x = nx1; else o.y = ny1; });\n    }\n    // L\u00E4nge von Wand i eingeben: die Ecke am Ende r\u00FCckt, die Wand danach verschiebt sich parallel mit\n    function wandLaenge(i, L) {\n      const p = S.raum.punkte, n = p.length, a = p[i], b = p[(i + 1) % n];\n      const len = Math.hypot(b[0] - a[0], b[1] - a[1]);\n      const dx = (b[0] - a[0]) / len * (L - len), dy = (b[1] - a[1]) / len * (L - len);\n      const neu = p.map((q, j) => j === (i + 1) % n || (j === (i + 2) % n && j !== i) ? [rund(q[0] + dx), rund(q[1] + dy)] : q);\n      if (!gueltig(neu)) return false;\n      const m = wandMelderMerken(); S.raum.punkte = neu; wandMelderSetzen(m);\n      return true;\n    }\n    // W\u00E4nde antippen nur unter \u201ERaum\u201C, nicht im Reiter T\u00FCren/Fenster: dort geh\u00F6ren die W\u00E4nde den \u00D6ffnungen.\n    // Griffe zum Ziehen (Ecken, +) gibt es nur bei der freien Form.\n    const wandWahl = () => modus === 'raum' && reiter.raum !== 'oeffnungen';\n    const freiBearbeiten = () => S.raum.form === 'frei' && wandWahl();\n    // Glasfront (Fernando 16.10.): Wandnummern in S.raum.glas. Rechnet wie eine Mauer, weil Glas das Signal\n    // zur\u00FCckwirft (Frage 6); gezeichnet wie ein Fenster. T\u00FCren und Fenster darin bleiben eigene \u00D6ffnungen.\n    const istGlas = i => (S.raum.glas || []).includes(i);\n    function glasSetzen(i, an) {\n      const g = (S.raum.glas || []).filter(j => j !== i);\n      S.raum.glas = an ? [...g, i].sort((a, b) => a - b) : g;\n    }\n\n    // Drehwinkel f\u00FCr Text entlang der Richtung (dx, dy), nie auf dem Kopf\n    const lesbar = (dx, dy) => { let w = Math.atan2(dy, dx) * 180 / Math.PI; if (w > 90) w -= 180; if (w <= -90) w += 180; return w; };\n    function oeffnungSetzen(o, p) {\n      const L = oeffnungLage({ ...o, x: p.x, y: p.y });\n      if (L) { o.x = rund(L.mx); o.y = rund(L.my); }\n    }\n    // W\u00E4nde ohne die L\u00FCcken von Durchg\u00E4ngen, Holzt\u00FCren und offenen T\u00FCren und Fenstern\n    function wandSegmente(poly) {\n      const luecken = S.oeffnungen.filter(durchlaessig).map(o => oeffnungLage(o, poly)).filter(Boolean);\n      const segs = [];\n      kanten(poly).forEach(([x1, y1, x2, y2], i) => {\n        const stueck = (a, b) => segs.push([x1 + a * (x2 - x1), y1 + a * (y2 - y1), x1 + b * (x2 - x1), y1 + b * (y2 - y1)]);\n        let tt = 0;\n        for (const L of luecken.filter(x => x.i === i).sort((a, b) => a.t0 - b.t0)) {\n          if (L.t0 > tt) stueck(tt, L.t0);\n          tt = Math.max(tt, L.t1);\n        }\n        if (tt < 1) stueck(tt, 1);\n      });\n      return segs;\n    }\n    // Was abschattet: alle W\u00E4nde (massiv angenommen, au\u00DFer in den L\u00FCcken oben), Mauerwerk, Metall und hohe M\u00F6bel.\n    // Polster nicht.\n    function hindernisse() {\n      const segs = wandSegmente(raumPoly());\n      S.moebel.filter(schirmt).forEach(o => segs.push(...rechteckKanten(o)));\n      return segs;\n    }\n    // Was d\u00E4mpft: das offene T\u00FCrblatt (90\u00B0 in den Raum) oder die geschlossene T\u00FCr in der Wand. Dahinter erkennt der Melder\n    // Bewegung, aber kein Stillsitzen (Fernando 20.10.: \u201Eeher Bewegung, so ein Mittelding\u201C; Annahme, Frage 8 an Christian).\n    // Von der Decke aus nicht.\n    function daempfer() {\n      const poly = raumPoly(), l = [];\n      S.oeffnungen.filter(o => o.art === 'tuer').forEach(o => {\n        const L = oeffnungLage(o, poly); if (!L) return;\n        if (offen(o)) { if (!nachAussen(o)) { const B = tuerBlatt(L, o); l.push([B.an.x, B.an.y, B.spitze.x, B.spitze.y]); } }   // offen nach au\u00DFen: Blatt steht drau\u00DFen\n        else { const a = wandPunkt(L, L.t0), b = wandPunkt(L, L.t1); l.push([a.x, a.y, b.x, b.y]); }\n      });\n      return l;\n    }\n    // Von der Decke aus: W\u00E4nde und Mauerwerk; M\u00F6bel aus Metall und Schr\u00E4nke sind zu niedrig\n    function deckenHindernisse() {\n      const segs = wandSegmente(raumPoly());\n      S.moebel.filter(o => stoff(o) === 'massiv').forEach(o => segs.push(...rechteckKanten(o)));\n      return segs;\n    }\n    // ---------- Zonen des Raums und Grenze des KL MZ (Stufe 2, Fernando 21.10.) ----------\n    // S.zonen: Rechtecke {id, x, y, w, h}, die ein KL MZ getrennt melden soll. Erst zeichnet man die Zonen, dann findet der\n    // Vorschlag die Melder dazu (Fernando 21.10.: \u201Ezuerst die Zonen bestimmen\u201C). Welche Zone zu welchem Melder geh\u00F6rt,\n    // rechnet zonenZuordnung() jedes Mal neu: je Zone der KL MZ, der sie am besten erfasst, h\u00F6chstens MAX_ZONEN je Melder.\n    // s.grenze: Rechteck am KL MZ, au\u00DFerhalb erkennt er nichts (etwa den Flur hinter einer T\u00FCr).\n    const MAX_ZONEN = MODELLE.kl_mz.zonen;   // eine Zahl, eine Stelle: Karte und Suche zeigen dasselbe\n    const FLAECHE_ZIEL = 0.9, FLAECHE_SCHRITT = 0.1;   // Raum-Modus: bis 90 % der begehbaren Fl\u00E4che, je Melder mindestens 10 Punkte\n    const hatZonen = s => MODELLE[s.modell].klasse === 'zonen';\n    const zonen = () => S.zonen || [];\n    // Eine Zone ist ein Vieleck z.p = [[x, y], \u2026] (3 bis MAX_ZONEN_ECKEN Ecken, wie in der App des Melders)\n    const inZone = (p, z) => imRaum(p, z.p);\n    // Zonenecke in die H\u00FClle des Raums gedr\u00FCckt: \u00FCber die Wand hinaus hat eine Zone keinen Sinn\n    const imRaumHalten = ([x, y], H = huelle()) => [rund(Math.min(H.x1, Math.max(H.x0, x))), rund(Math.min(H.y1, Math.max(H.y0, y)))];\n    // M\u00F6bel mit Aufenthalt, deren Mitte in der Zone liegt\n    const moebelIm = z => S.moebel.filter(o => istOrt(o) && inZone({ x: o.x + o.w / 2, y: o.y + o.h / 2 }, z)).map(o => o.id);\n    const moebelNamen = z => [...new Set(moebelIm(z).map(moebelName))].map(esc);   // je Name einmal, f\u00FCrs HTML\n    // Proben alle 30 cm innerhalb des Vielecks; eine sehr kleine Zone bekommt ihren Mittelpunkt\n    function zoneProben(z) {\n      const H = huelle(z.p), poly = raumPoly(), l = [];\n      for (let x = H.x0 + PROBE / 2; x < H.x1; x += PROBE) for (let y = H.y0 + PROBE / 2; y < H.y1; y += PROBE) { const q = { x, y }; if (inZone(q, z) && imRaum(q, poly)) l.push(q); }\n      if (!l.length) l.push({ x: z.p.reduce((a, q) => a + q[0], 0) / z.p.length, y: z.p.reduce((a, q) => a + q[1], 0) / z.p.length });\n      return l;\n    }\n    // Anteil der Zone, in dem der Melder auch Stillsitzen erkennt\n    function rechteckAnteil(s, z, K = null) {\n      const l = zoneProben(z), V = vorbereiten(s, kontext(K)); let ja = 0;\n      for (const q of l) { const e = erfassungV(V, q, false); if (e.st === 'ja' && e.kern) ja++; }\n      return l.length ? ja / l.length : 0;\n    }\n    // Rechteck um die M\u00F6bel einer Liste, mit Rand, in den Raum gedr\u00FCckt, als Vieleck\n    function rechteckUm(ids, rand = 0.25) {\n      const o = S.moebel.filter(m => ids.includes(m.id)); if (!o.length) return null;\n      const H = huelle();\n      const x0 = Math.max(H.x0, Math.min(...o.map(m => m.x)) - rand), y0 = Math.max(H.y0, Math.min(...o.map(m => m.y)) - rand);\n      const x1 = Math.min(H.x1, Math.max(...o.map(m => m.x + m.w)) + rand), y1 = Math.min(H.y1, Math.max(...o.map(m => m.y + m.h)) + rand);\n      return { p: rechteckPoly(x0, y0, Math.max(MIN_SEITE, x1 - x0), Math.max(MIN_SEITE, y1 - y0)) };\n    }\n    // Zone \u2192 Melder: je KL MZ h\u00F6chstens MAX_ZONEN, je Raum-Melder eine (er unterscheidet nichts, erfasst aber eine\n    // einzelne Zone; Fernando 21.10.). Map zoneId \u2192 { s, anteil }\n    // Zonen geh\u00F6ren nur zum KL MZ (Fernando 22.10.): ein Raum-Melder unterscheidet nichts, auch wenn er die Zone sieht.\n    // Vorher z\u00E4hlte er mit einer Zone (Tauschregel vom 21.10.), dadurch sprang eine Zone auf einen KL LD, der den ganzen Raum sah.\n    const zonenJe = s => hatZonen(s) ? MAX_ZONEN : 0;\n    function zonenZuordnung() { return memoFuer('zonen', zonenZuordnungRechnen); }\n    function zonenZuordnungRechnen() {\n      const Z = zonen(), kap = new Map(S.melder.map(s => [s.id, zonenJe(s)])), K = kontext();\n      const anteile = Z.map(z => S.melder.filter(hatZonen).map(s => ({ key: s.id, s, wert: rechteckAnteil(s, z, K) })).filter(k => k.wert >= VOLL).sort((p, q) => q.wert - p.wert));\n      const von = zuordnen(Z.length, g => anteile[g], key => kap.get(key));\n      const zu = new Map();\n      von.forEach((k, g) => zu.set(Z[g].id, { s: k.s, anteil: k.wert }));\n      return zu;\n    }\n    const zonenVon = (s, zu = zonenZuordnung()) => zonen().filter(z => zu.get(z.id) && zu.get(z.id).s === s);\n    const zoneNr = z => zonen().indexOf(z) + 1;\n    // Zonen aus den M\u00F6beln: je Platz (M\u00F6bel mit h\u00F6chstens 0,5 m Abstand) eine Zone\n    const zonenAusMoebeln = () => plaetzeGruppen().map(ids => ({ id: neueId('z'), ...rechteckUm(ids) }));\n    // Zonen als \u201EPl\u00E4tze\u201C f\u00FCr Stellensuche und Vorschlag: Proben je Zone, Schl\u00FCssel = Zonen-Id\n    const zonenProben = () => new Map(zonen().map(z => [z.id, zoneProben(z)]));\n    const zonenP = () => zonen().map(z => [z.id]);\n    // Grenze: Rechteck um den Pr\u00E4senzbereich des Melders, in den Raum gedr\u00FCckt\n    function grenzeVorschlag(s) {\n      const H = huelle(), u = ursprung(s), r = praesenzBis(s, wm(s));\n      const x0 = Math.max(H.x0, u.x - r), y0 = Math.max(H.y0, u.y - r), x1 = Math.min(H.x1, u.x + r), y1 = Math.min(H.y1, u.y + r);\n      return { x: rund(x0), y: rund(y0), w: rund(x1 - x0), h: rund(y1 - y0) };\n    }\n    // Plaketten im Plan, Pfade um (0,0) in 20er-Einheiten (dieselben Formen wie KLIMA, SONNE, SIRENE im Feld)\n    const PLAKETTEN = [\n      ['klima', 'M-2 -6.5a2 2 0 0 1 4 0v7.2a3.5 3.5 0 1 1-4 0zM0 -2v6'],\n      ['helligkeit', 'M3.5 0a3.5 3.5 0 1 1-7 0a3.5 3.5 0 1 1 7 0M0 -7.5v2M0 5.5v2M-7.5 0h2M5.5 0h2M-5.3 -5.3l1.4 1.4M3.9 3.9l1.4 1.4M-5.3 5.3l1.4-1.4M3.9 -3.9l1.4-1.4'],\n      ['sirene', 'M-4.5 5v-5a4.5 4.5 0 0 1 9 0v5zM-6 5h12M0 -7v1.5M-5.8 -4.2l1.1 1.1M5.8 -4.2l-1.1 1.1'],\n    ];\n    // Beim Wechsel an die Decke r\u00FCckt ein Wandmelder in den Raum, \u00FCber die Fangweite hinaus: auf der Wandlinie liefen die\n    // Strahlen nach au\u00DFen und der Kreis stand zur H\u00E4lfte vor dem Haus (Fernando 21.10.). Die Decke kennt keine Wand (wand = null).\n    function vonWandAb(s) {\n      if (!s.wand) return;\n      const i = +s.wand.slice(1), poly = raumPoly(), ab = fangM() + 0.25;\n      if (poly[i]) {\n        const g = rad(s.wand[0] === 'e' ? innenWinkelKante(poly, i) : innenWinkelEcke(poly, i));\n        s.x = rund(s.x + ab * Math.cos(g)); s.y = rund(s.y + ab * Math.sin(g));\n      }\n      s.wand = null;\n    }\n    // Montage folgt der Lage (Fernando 22.10.): nah an Wand oder Ecke Wandmelder, weiter im Raum Deckenmelder. Beim Wechsel\n    // Entfernungsstufe und Reichweite auf den Grundwert, wie beim Schalter im Reiter \u201EMontage\u201C.\n    function montageSetzen(s, m) {\n      if (s.montage === m) return;\n      s.montage = m; s.stufe = grundStufe(MODELLE[s.modell]); s.max = wm(s).reichweite;\n    }\n    // 'ja' | 'weit' | 'winkel' | 'verdeckt'; bei 'ja' sagt kern, ob auch Pr\u00E4senz erkannt wird\n    // ---------- Suchkontext ----------\n    // Die Stellensuche ruft erfassung() hunderttausendfach (Kandidaten \u00D7 Proben \u00D7 Modelle \u00D7 Runden). Alles, was dabei\n    // gleich bleibt, rechnet der Kontext K nur einmal: Hindernisse, T\u00FCrd\u00E4mpfer, Deckenhindernisse; je Ursprung und Probe\n    // Abstand, Richtung und die Sichtpr\u00FCfungen, unabh\u00E4ngig vom Modell und von der Runde (22.10.: vorher 8,8 s f\u00FCr\n    // \u201EMelder vorschlagen\u201C am Beispielraum, davon zw\u00F6lf von dreizehn Abstandsrechnungen f\u00FCr den T\u00FCrd\u00E4mpfer je Probe).\n    // Jede Funktion, die K nimmt, nimmt auch nichts; kontext() macht daraus ein frisches K.\n    function kontext(K) {\n      return K || { segs: hindernisse(), _daempf: null, _decken: null, stellen: new Map(), nah: new Map(), probleme: new Map() };\n    }\n    const daempferVon = K => K._daempf || (K._daempf = daempfer());\n    const deckenVon = K => K._decken || (K._decken = deckenHindernisse());\n    // Melder f\u00FCr viele Proben vorbereiten: Modellwerte, Ursprung und Kern einmal statt je Probe\n    function vorbereiten(s, K) {\n      const o = ursprung(s), M = wm(s), D = istDecke(s);\n      return { s, o, M, D, K, kern: kern(s), dk: D ? decke(s) : null, halb: M.winkel / 2, key: (D ? 'd' : 'w') + o.x + '|' + o.y, sp: null };\n    }\n    // merken: die Probe ist ein fester Punkt der Suche (Pl\u00E4tze, Zonen, Fl\u00E4che); je Ursprung bleiben Abstand, Richtung und\n    // Sichtpr\u00FCfungen (v: Hindernisse, dm: D\u00E4mpfer, -1 = noch nicht gerechnet) f\u00FCr die n\u00E4chsten Modelle und Runden stehen\n    function erfassungV(V, p, behalten = true) {\n      const { s, o, K } = V;\n      let e;\n      if (behalten) {\n        if (!V.sp) { V.sp = K.stellen.get(V.key); if (!V.sp) K.stellen.set(V.key, V.sp = new Map()); }\n        e = V.sp.get(p);\n      }\n      if (!e) {\n        e = { d: Math.hypot(p.x - o.x, p.y - o.y), g: Math.atan2(p.y - o.y, p.x - o.x) * 180 / Math.PI, v: -1, dm: -1 };\n        if (behalten) V.sp.set(p, e);\n      }\n      if (V.D) {\n        const { dh, R } = V.dk, r = e.d, d = Math.hypot(r, dh);\n        if (r > R) return { st: 'weit', d };\n        if (e.v < 0) e.v = verdeckt(o, p, deckenVon(K)) ? 1 : 0;\n        if (e.v) return { st: 'verdeckt', d };\n        return { st: 'ja', d, kern: r <= V.kern.R };\n      }\n      const d = e.d;\n      if (d > s.max) return { st: 'weit', d };\n      if (s.grenze && !inRechteck(p, s.grenze)) return { st: 'grenze', d };   // KL MZ: au\u00DFerhalb der Grenze nichts\n      const ab = Math.abs(normWinkel(e.g - s.dir));\n      if (ab > V.halb) return { st: 'winkel', d };\n      if (e.v < 0) e.v = verdeckt(o, p, K.segs) ? 1 : 0;\n      if (e.v) return { st: 'verdeckt', d };\n      let praesenz = d <= V.kern.r && ab <= V.kern.w / 2;\n      if (praesenz) { if (e.dm < 0) e.dm = verdeckt(o, p, daempferVon(K)) ? 1 : 0; praesenz = !e.dm; }   // hinter T\u00FCrblatt oder geschlossener T\u00FCr nur Bewegung\n      return { st: 'ja', d, kern: praesenz };\n    }\n    // 'ja' | 'weit' | 'winkel' | 'verdeckt' | 'grenze'; bei 'ja' sagt kern, ob auch Pr\u00E4senz erkannt wird. Einzelabfrage\n    // ohne Speicher; wer viele Proben hat, nimmt vorbereiten() und erfassungV()\n    function erfassung(s, p, K) { return erfassungV(vorbereiten(s, kontext(K)), p, false); }\n\n    // Melder an p setzen: innerhalb der Fangweite rastet er an Wand oder Ecke ein (Wandmelder), sonst steht er im Raum\n    // (Deckenmelder). Au\u00DFerhalb des Raums: die n\u00E4chste Wand, egal wie weit (fang = Infinity, auch der Schalter nutzt das).\n    function einrasten(s, p, fang = fangM()) {\n      const poly = raumPoly();\n      let best = null;\n      poly.forEach((v, i) => {\n        const d = Math.hypot(p.x - v[0], p.y - v[1]);\n        if (d < fang && (!best || d < best.d)) best = { d, key: 'v' + i, x: v[0], y: v[1], dir: innenWinkelEcke(poly, i) };\n      });\n      if (!best) kanten(poly).forEach(([x1, y1, x2, y2], i) => {\n        const sx = x2 - x1, sy = y2 - y1, len2 = sx * sx + sy * sy;\n        const tt = Math.max(0, Math.min(1, ((p.x - x1) * sx + (p.y - y1) * sy) / len2));\n        const qx = x1 + tt * sx, qy = y1 + tt * sy, d = Math.hypot(p.x - qx, p.y - qy);\n        if (d < fang && (!best || d < best.d)) best = { d, key: 'e' + i, x: qx, y: qy, dir: innenWinkelKante(poly, i) };\n      });\n      if (best) {\n        s.x = best.x; s.y = best.y;\n        if (s.wand !== best.key) { s.wand = best.key; s.dir = Math.round(best.dir); }\n        montageSetzen(s, 'wand');\n      } else if (fang !== Infinity && !imRaum(p, poly)) {\n        einrasten(s, p, Infinity);\n      } else {\n        s.x = raster(p.x); s.y = raster(p.y); s.wand = null;\n        montageSetzen(s, 'decke');\n      }\n    }\n\n    // ---------- Auswertung ----------\n    // Ergebnis gilt, bis sich der Zustand \u00E4ndert (memo): Zeichnen, Aktionsleiste und Vorschlag fragen je \u00C4nderung mehrfach\n    function analyse() { return memoFuer('analyse', analyseRechnen); }\n    function analyseRechnen() {\n      const K = kontext();\n      // je weiches M\u00F6bel eine Zeile: Anteil erfasst, Anteil auch Stillsitzen, n\u00E4chste und weiteste Entfernung\n      const liste = S.moebel.filter(o => stoff(o) === 'weich');\n      const res = S.melder.map((s, si) => {\n        const M = wm(s), V = vorbereiten(s, K);\n        const zeilen = liste.map(o => {\n          const nx = Math.max(2, Math.ceil(o.w / 0.1)), ny = Math.max(2, Math.ceil(o.h / 0.1));\n          let n = 0, hit = 0, kernHit = 0, dmin = Infinity, dmax = 0;\n          for (let i = 0; i < nx; i++) for (let j = 0; j < ny; j++) {\n            const p = { x: o.x + (i + 0.5) * o.w / nx, y: o.y + (j + 0.5) * o.h / ny };\n            if (!innen(o, p)) continue;\n            n++;\n            const e = erfassungV(V, p, false);\n            if (e.st !== 'ja') continue;\n            hit++; if (e.kern) kernHit++;\n            dmin = Math.min(dmin, e.d); dmax = Math.max(dmax, e.d);\n          }\n          return { key: o.id, name: o.name, ort: !!o.ort, anteil: n ? hit / n : 0, kern: n ? kernHit / n : 0, dmin, dmax };\n        });\n        return { s, si, M, zeilen };\n      });\n      // \u00D6ffnungen z\u00E4hlen den Rand mit: dort l\u00F6st Bewegung aus.\n      // Ob ein M\u00F6bel ganz, im Rand oder gar nicht erfasst ist, zeigt der Plan selbst; dazu kein Hinweis\n      // (Fernando 20.10.: man sieht es, und wohin der Melder geh\u00F6rt, wei\u00DF der Kunde am besten).\n      const hinweise = [];\n      // Zwei Melder an der Wand im selben Band, die sich gegenseitig im Bereich haben\n      for (let i = 0; i < res.length; i++) for (let j = i + 1; j < res.length; j++) {\n        const a = res[i], b = res[j];\n        if (istDecke(a.s) || istDecke(b.s) || a.M.ghz !== b.M.ghz) continue;\n        if (erfassung(a.s, ursprung(b.s), K).st === 'ja' && erfassung(b.s, ursprung(a.s), K).st === 'ja') hinweise.push({ r: a, art: 'stoeren', mit: b.s });\n      }\n      // \u00D6ffnungen: wie weit ein Melder durch eine durchl\u00E4ssige \u00D6ffnung hinaussieht; ob er einen Vorhang sieht.\n      // Der KL MZ (ohne Stufen, Zonen frei gezeichnet) blendet den Bereich an der T\u00FCr in seiner App aus (Fernando 20.10.):\n      // der Hinweis kommt trotzdem, aber gr\u00FCn mit H\u00E4kchen und ohne Z\u00E4hlung (ok).\n      const poly = raumPoly();\n      const melden = x => hinweise.push(ausblendbar(x.r.M) ? { ...x, ok: true } : x);\n      for (const r of res) for (const o of S.oeffnungen) {\n        const L = oeffnungLage(o, poly); if (!L) continue;\n        if (durchlaessig(o)) { const { weit, dnah } = hinausWeit(r.s, L, K); if (weit > 0.1) melden({ r, o, art: 'hinaus', weit, dnah }); }\n        if (o.art === 'fenster' && o.vorhang) {\n          let dmin = Infinity, dmax = 0;\n          for (const p of oeffnungProben(L, 0.1)) {\n            const e = erfassung(r.s, p, K);\n            if (e.st === 'ja') { dmin = Math.min(dmin, e.d); dmax = Math.max(dmax, e.d); }\n          }\n          if (dmax > 0) melden({ r, o, art: 'vorhang', dmin, dmax });\n        }\n      }\n      // T\u00FCrblatt: Anteil des Blickfelds eines Wandmelders, in dem das offene Blatt steht, dahinter nur Bewegung\n      // (Fernando 18.10.: der Anschlag entscheidet, ob die offene T\u00FCr vor dem Melder steht). Gilt, ob die T\u00FCr gerade\n      // offen ist oder nicht, damit man den Anschlag pr\u00FCft. Als Abhilfe nie \u201EAnschlag wechseln\u201C (Fernando 18.10.).\n      for (const o of S.oeffnungen.filter(x => x.art === 'tuer')) {\n        for (const r of res) {\n          const anteil = blattAnteil(r.s, o, K);\n          if (anteil >= 0.1) hinweise.push({ r, o, art: 'tuerblatt', anteil });\n        }\n      }\n      // Je Melder ein gesammelter Hinweis zu seinen \u00D6ffnungen (Fernando 21.10.: einer je T\u00FCr wurden schnell viele,\n      // und der Plan zeigt es ohnehin). Die Einzelteile bleiben als teile erhalten.\n      const je = new Map(), rest = [];\n      for (const x of hinweise) {\n        if (!x.o) { rest.push(x); continue; }\n        if (!je.has(x.r)) je.set(x.r, { r: x.r, art: 'oeffnungen', teile: [], ok: true });\n        const g = je.get(x.r); g.teile.push(x); if (!x.ok) g.ok = false;\n      }\n      return { res, hinweise: [...rest, ...je.values()] };\n    }\n    // Wie weit Melder s durch die \u00D6ffnung (Lage L) hinaussieht, und die n\u00E4chste Entfernung dorthin; 12 Proben\n    function hinausWeit(s, L, K) {\n      let weit = 0, dnah = Infinity;\n      for (const p of oeffnungProben(L, -0.05)) {\n        const e = erfassung(s, p, K);\n        if (e.st !== 'ja') continue;\n        weit = Math.max(weit, istDecke(s) ? decke(s).R - Math.hypot(p.x - s.x, p.y - s.y) : s.max - e.d);\n        dnah = Math.min(dnah, e.d);\n      }\n      return { weit, dnah };\n    }\n    // Anteil des Blickfelds eines Wandmelders, in dem das offene T\u00FCrblatt vor der Wand steht (dort nur Bewegung)\n    function blattAnteil(c, o, K = null) {\n      const L = oeffnungLage(o); if (!L || istDecke(c) || nachAussen(o)) return 0;\n      const segs = kontext(K).segs;\n      const B = tuerBlatt(L, o), blatt = [[B.an.x, B.an.y, B.spitze.x, B.spitze.y]], u = ursprung(c), M = wm(c);\n      let n = 0, zu = 0;\n      for (let g = c.dir - M.winkel / 2; g <= c.dir + M.winkel / 2 + 1e-9; g += STRAHL_SCHRITT) {\n        n++;\n        if (strahl(u, g, c.max, blatt) < strahl(u, g, c.max, segs)) zu++;\n      }\n      return n ? zu / n : 0;\n    }\n    const betrifft = (h, s) => h.r.s === s || h.mit === s;\n    // Alle Hinweise als eine Liste, je mit dem, worauf sie sich im Plan beziehen (zum Markieren)\n    function hinweisListe(a = analyse()) {\n      const l = [];\n      a.hinweise.forEach(x => {\n        const vs0 = x.ok ? null : vorschlagHinweis(x), vs = vs0 && { ...vs0, s: x.r.s }, tx = hinweisText(x, vs), ohne = x.art === 'stoeren';\n        const tueren = teile(x, 'tuerblatt').map(p => p.o);   // \u201EAnschlag wechseln\u201C nur, wenn genau eine T\u00FCr gemeint ist\n        l.push({ text: ohne ? tx : t('mit_melder', { melder: melderName(x.r.s), text: tx }),\n          kurz: tx, melder: x.mit ? [x.r.s, x.mit] : [x.r.s], moebel: [], oeffnung: x.teile ? x.teile.map(p => p.o) : [], linie: !!x.mit,\n          ok: !!x.ok, vorschlag: vs, tuer: tueren.length === 1 ? tueren[0] : null });\n      });\n      // Hinweise zu T\u00FCren und Fenstern ans Ende (Fernando 17.10.); Reihenfolge fest, die Nummer markiert\n      return [...l.filter(x => !x.oeffnung.length), ...l.filter(x => x.oeffnung.length)];\n    }\n    // Nummer des angetippten Hinweises (unteres Feld \u201EHinweise\u201C oder Reiter \u201EHinweise\u201C eines Melders); gilt nur, solange\n    // man dort bleibt, wo man ihn angetippt hat\n    let markiert = null, markiertBei = '';\n    const markOrt = () => modus + ':' + (auswahl ? auswahl.id : '');\n    // Hinweise ohne farbigen Kasten: \u24D8 und grauer Text wie im IKEA-Planer (Fernando 16.10.). Das Symbol tr\u00E4gt\n    // das Wort \u201EHinweis\u201C f\u00FCr Screenreader. Gelb (meldung 'warn', \u201EBitte beachten\u201C) nur, wo etwas nicht geht.\n    const INFO = () => `<svg class=\"tipp-icon\" role=\"img\" aria-label=\"${esc(t('achtung'))}\" viewBox=\"0 0 20 20\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"><circle cx=\"10\" cy=\"10\" r=\"7.5\"/><path d=\"M10 9v5M10 6.3v.01\"/></svg>`;\n    const OK = () => `<svg class=\"tipp-icon tipp-icon--ok\" role=\"img\" aria-label=\"${esc(t('ok_label'))}\" viewBox=\"0 0 20 20\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"10\" cy=\"10\" r=\"7.5\"/><path d=\"M6.5 10.2l2.4 2.4 4.6-4.8\"/></svg>`;\n    const tipp = text => `<div class=\"tipp\">${INFO()}<p>${text}</p></div>`;\n    // Thermometer an Modellen, die auch das Raumklima messen (Fernando 21.10.): auf den Karten und in der Zusammenfassung\n    const KLIMA = () => `<svg class=\"klima-icon\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" aria-hidden=\"true\"><path d=\"M8 3.5a2 2 0 0 1 4 0v7.2a3.5 3.5 0 1 1-4 0z\"/><path d=\"M10 8v6\"/><circle cx=\"10\" cy=\"14\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/></svg>`;\n    const SONNE = () => `<svg class=\"klima-icon\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" aria-hidden=\"true\"><circle cx=\"10\" cy=\"10\" r=\"3.5\"/><path d=\"M10 2.5v2M10 15.5v2M2.5 10h2M15.5 10h2M4.7 4.7l1.4 1.4M13.9 13.9l1.4 1.4M4.7 15.3l1.4-1.4M13.9 6.1l1.4-1.4\"/></svg>`;\n    const SIRENE = () => `<svg class=\"klima-icon\" viewBox=\"0 0 20 20\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5.5 15v-5a4.5 4.5 0 0 1 9 0v5zM4 15h12M10 3v1.5M4.2 5.8l1.1 1.1M15.8 5.8l-1.1 1.1\"/></svg>`;\n    // Auf den Modellkarten nur, was die Modelle unterscheidet (Fernando 22.10.): \u201Eohne Raumklima\u201C beim Basis, sonst nichts;\n    // Helligkeit und Sirene haben alle vier. Die Zusammenfassung zeigt weiter die volle Ausstattung (merkmale).\n    const unterschied = M => M.klima ? '' : `<span class=\"klein\">${t('ohne_klima')}</span>`;\n    // Ausstattung eines Modells: Raumklima, Helligkeit, Sirene (Fernando 21.10.: alles mit auff\u00FChren, was verbaut ist)\n    const merkmale = M => [M.klima && [KLIMA(), t('klima')], M.helligkeit && [SONNE(), t('helligkeit')], M.sirene && [SIRENE(), t('sirene')]]\n      .filter(Boolean).map(([sym, tx]) => `<span class=\"klein klima\">${sym}${tx}</span>`).join('');\n    // Knopf zum \u00DCbernehmen eines Vorschlags auch direkt beim Text, nicht nur in der Aktionsleiste (Fernando 20.10.: am Desktop\n    // \u00FCbersieht man die Leiste unten, der Blick ist in der Seitenleiste). Beim Hinweis erst sichtbar, wenn er angetippt ist (CSS).\n    const vorschlagText = vs => vs.neu ? t('vorschlag_zweiter') : vs.anders && vs.anders.modell ? t('vorschlag_modell', { modell: MODELLE[vs.anders.modell].name }) : t('vorschlag_setzen');\n    const vorschlagKnopf = (vs, opt) => `<div class=\"vorschlag-knopf\"><button class=\"btn btn--primary\" data-akt=\"vorschlag\"${opt != null ? ` data-opt=\"${opt}\"` : ''}>${vorschlagText(vs)}</button></div>`;\n    // Unter dem angetippten Hinweis: \u201EAnschlag wechseln\u201C beim T\u00FCrblatt (der Hinweis fragt danach, Fernando 20.10.) und\n    // der Vorschlag zum \u00DCbernehmen\n    const aufText = o => nachAussen(o) ? 'auf_innen' : 'auf_aussen';   // Knopf nennt die Richtung, in die man wechselt\n    const hinweisKnoepfe = x => !x.tuer && !x.vorschlag ? '' : '<div class=\"vorschlag-knopf\">' +\n      (x.tuer ? `<button class=\"btn\" data-akt=\"seite_hinweis\">${t('anschlag')}</button><button class=\"btn\" data-akt=\"auf_hinweis\">${t(aufText(x.tuer))}</button>` : '') +\n      (x.vorschlag ? `<button class=\"btn btn--primary\" data-akt=\"vorschlag\">${vorschlagText(x.vorschlag)}</button>` : '') + '</div>';\n    const hinweisZeile = (x, k, text) => `<li><button class=\"tipp hinweis-knopf${x.ok ? ' hinweis-knopf--ok' : ''}\" data-hinweis=\"${k}\" aria-pressed=\"${k === markiert}\">${x.ok ? OK() : INFO()}<p>${text}</p></button>` +\n      hinweisKnoepfe(x) + '</li>';\n    // Jeder Hinweis nennt eine Abhilfe (Fernando 18.10.: nicht nur das Problem; nie \u201EM\u00F6bel verstellen\u201C). Was der\n    // Planer ausrechnen kann, steht mit Zahl da: Reichweite am Melder begrenzen, eine andere Stelle, ein Modell in\n    // einem anderen Band oder der KL MZ an \u00D6ffnungen. Modelle nur, wenn lieferbar.\n    const abhilfe = text => `<span class=\"abhilfe\">${text}</span>`;\n    const lieferbare = () => Object.entries(MODELLE).filter(([, m]) => m.lieferbar);\n    // Reichweite, bei der der Bereich vor der \u00D6ffnung (Entfernung d) endet und alle Pl\u00E4tze erfasst bleiben\n    function grenze(r, d) {\n      const st = r.M.stufe || 0.5, g = Math.floor((d - 0.05) / st + 1e-9) * st;\n      if (g < st || g >= r.s.max - 1e-9) return null;\n      return r.zeilen.every(z => !z.ort || z.anteil <= 0.05 || z.dmax <= g) ? g : null;\n    }\n    // Gedreht muss dabeistehen: zieht man den Melder an die Stelle, steht er gerade zur Wand\n    const stelleText = vs => t('abhilfe_stelle') + (vs.dreh ? ' ' + t('stelle_gedreht', { g: vs.dreh }) : '');\n    // Ohne gestrichelte Stelle: Reichweite begrenzen, sonst der KL MZ, sonst ehrlich keine (Fernando 20.10.: \u201Ewegdrehen oder\n    // an eine andere Wand\u201C schickte den Kunden auf eine Suche ohne Ergebnis)\n    function ohneStelle(h, d) {\n      const g = grenze(h.r, d), mz = mzModell(h);\n      if (g) return t('abhilfe_begrenzen', { m: zahl(g, 2) }) + (mz ? ' ' + t('abhilfe_mz_tuer', { modell: mz }) : '');\n      return mz ? t('abhilfe_mz_allein', { modell: mz }) : t('abhilfe_keine_stelle');\n    }\n\n    // Konkrete Stelle f\u00FCr den Melder eines Hinweises an einer \u00D6ffnung (vorschlagOeffnung). Durchprobiert werden Stellen\n    // an den W\u00E4nden alle 30 cm und die Ecken, je gerade und um 15\u00B0/30\u00B0 gedreht; an der Decke ein Raster von 50 cm.\n    // Rechnet nur, wenn ein Hinweis gezeigt wird, und merkt sich das Ergebnis je Zustand. Der Speicher h\u00E4lt nur die\n    // Stelle, nicht den Melder: nach \u201ER\u00FCckg\u00E4ngig\u201C ist der Melder ein neues Objekt.\n    const vorschlagSpeicher = new Map();\n    // Proben je M\u00F6bel alle 30 cm, gr\u00F6ber als in analyse()\n    function proben(o) {\n      const l = [], nx = Math.max(2, Math.ceil(o.w / PROBE)), ny = Math.max(2, Math.ceil(o.h / PROBE));\n      for (let i = 0; i < nx; i++) for (let j = 0; j < ny; j++) {\n        const q = { x: o.x + (i + 0.5) * o.w / nx, y: o.y + (j + 0.5) * o.h / ny };\n        if (innen(o, q)) l.push(q);\n      }\n      return l;\n    }\n    // Proben je M\u00F6bel mit Aufenthalt (Schl\u00FCssel wie die Zeilen in analyse())\n    function plaetzeProben() {\n      const plaetze = new Map();\n      S.moebel.filter(istOrt).forEach(o => plaetze.set(o.id, proben(o)));\n      return plaetze;\n    }\n    // Je Platz: Anteil erfasst, Anteil im Kern, n\u00E4chste und weiteste Entfernung, f\u00FCr Melder c\n    function messen(c, plaetze, K) {\n      const z = new Map(), V = vorbereiten(c, kontext(K));\n      for (const [name, l] of plaetze) {\n        let hit = 0, kernHit = 0, dmin = Infinity, dmax = 0;\n        for (const q of l) {\n          const e = erfassungV(V, q);\n          if (e.st !== 'ja') continue;\n          hit++; if (e.kern) kernHit++;\n          dmin = Math.min(dmin, e.d); dmax = Math.max(dmax, e.d);\n        }\n        z.set(name, { anteil: l.length ? hit / l.length : 0, kern: l.length ? kernHit / l.length : 0, dmin, dmax });\n      }\n      return z;\n    }\n    const zustandKey = () => JSON.stringify([S.raum, S.moebel, S.oeffnungen, S.melder, S.zonen || []]);   // Zonen z\u00E4hlen mit (Vorschlag und beste Stelle rechnen damit)\n    // Abgeleitetes je Zustand nur einmal (analyse, zonenZuordnung). Ergebnisse halten Objekte aus S: wird S ersetzt\n    // (R\u00FCckg\u00E4ngig, Laden, Vorschlag), muss memoLeeren() laufen, sonst zeigen sie auf alte Melder.\n    const memo = { key: null };\n    function memoFuer(name, fn) {\n      const k = zustandKey();\n      if (memo.key !== k) { memo.key = k; memo.analyse = null; memo.zonen = null; }\n      if (!memo[name]) memo[name] = fn();\n      return memo[name];\n    }\n    const memoLeeren = () => { memo.key = null; };\n    // Stellen zum Durchprobieren: W\u00E4nde alle 30 cm (nicht in T\u00FCren und Fenstern) und Ecken, gedreht; Decke 50-cm-Raster\n    function kandidaten(poly, anDecke, dir) {\n      const kand = [];\n      if (anDecke) {\n        const H = huelle(poly);\n        for (let x = H.x0 + PROBE_GROB / 2; x < H.x1; x += PROBE_GROB) for (let y = H.y0 + PROBE_GROB / 2; y < H.y1; y += PROBE_GROB)\n          if (imRaum({ x, y }, poly)) kand.push({ x, y, dir, wand: null, dreh: 0 });\n        return kand;\n      }\n      const lagen = S.oeffnungen.map(o => oeffnungLage(o, poly)).filter(Boolean);\n      kanten(poly).forEach(([x1, y1, x2, y2], i) => {\n        const len = Math.hypot(x2 - x1, y2 - y1), g = innenWinkelKante(poly, i);\n        for (let d = PROBE / 2; d <= len - PROBE / 2 + 1e-9; d += PROBE) {\n          const tt = d / len;\n          if (lagen.some(L => L.i === i && tt > L.t0 - 0.02 && tt < L.t1 + 0.02)) continue;\n          for (const dr of [-30, -15, 0, 15, 30]) kand.push({ x: x1 + tt * (x2 - x1), y: y1 + tt * (y2 - y1), dir: g + dr, wand: 'e' + i, dreh: Math.abs(dr) });\n        }\n      });\n      poly.forEach(([x, y], i) => { const g = innenWinkelEcke(poly, i); for (const dr of [-15, 0, 15]) kand.push({ x, y, dir: g + dr, wand: 'v' + i, dreh: Math.abs(dr) }); });\n      return kand;\n    }\n    // Keine Stelle direkt neben Schrank, Metall oder Mauer: verdecken sie im ersten Meter mehr als 10 % des Blickfelds,\n    // f\u00E4llt die Stelle weg (Fernando 20.10.: Vorschlag lag in der Ecke 25 cm neben einem Schrank). An der Decke nicht.\n    const NAH_FREI = 1, NAH_ANTEIL = 0.1;\n    function nahFrei(c, moebelSegs, K = null) {\n      if (istDecke(c) || !moebelSegs.length) return true;\n      const u = ursprung(c), M = wm(c), key = K ? u.x + '|' + u.y + '|' + c.dir + '|' + M.winkel : null;\n      if (key && K.nah.has(key)) return K.nah.get(key);\n      let n = 0, zu = 0;\n      for (let g = c.dir - M.winkel / 2; g <= c.dir + M.winkel / 2 + 1e-9; g += STRAHL_SCHRITT) { n++; if (strahl(u, g, NAH_FREI, moebelSegs) < NAH_FREI) zu++; }\n      const frei = zu / n <= NAH_ANTEIL;\n      if (key) K.nah.set(key, frei);\n      return frei;\n    }\n    const moebelKanten = () => S.moebel.filter(schirmt).flatMap(rechteckKanten);\n    // Beste Stelle f\u00FCr den Melder basis: pruefen(z, c, K, k) gibt einen Wert (kleiner = besser) oder null (ung\u00FCltig);\n    // k.dreh = Grad, um die der Melder aus der Wandrichtung gedreht ist\n    function stelleSuchen(key, basis, bewerten) {\n      if (vorschlagSpeicher.has(key)) return vorschlagSpeicher.get(key);\n      if (zeiger.size) return null;                   // w\u00E4hrend ein Finger zieht nicht rechnen; nach dem Loslassen schon\n      if (vorschlagSpeicher.size > 50) vorschlagSpeicher.clear();\n      const poly = raumPoly(), K = kontext(), plaetze = plaetzeProben(), mk = moebelKanten();\n      let best = null;\n      for (const k of kandidaten(poly, istDecke(basis), basis.dir)) {\n        const c = { ...basis, x: rund(k.x), y: rund(k.y), dir: grad360(k.dir), wand: k.wand };\n        if (!nahFrei(c, mk, K)) continue;\n        const z = messen(c, plaetze, K), wert = bewerten(z, c, K, k);\n        if (wert == null) continue;\n        if (!best || wert < best.wert) best = { wert, c, z, k };\n      }\n      const v = best ? { x: best.c.x, y: best.c.y, dir: best.c.dir, wand: best.c.wand, z: best.z, dreh: best.k.dreh } : null;\n      vorschlagSpeicher.set(key, v);\n      return v;\n    }\n    // Sieht Melder c durch die \u00D6ffnung hinaus bzw. den Vorhang (wie in analyse())\n    function siehtOeffnung(c, o, art, K = null) {\n      const L = oeffnungLage(o); if (!L) return false;\n      K = kontext(K);\n      for (const p of oeffnungProben(L, art === 'vorhang' ? 0.1 : -0.05)) if (erfassung(c, p, K).st === 'ja') return true;\n      return false;\n    }\n    // Hinaussehen oder Vorhang, wenn Begrenzen der Reichweite nicht reicht: Stelle, von der aus der Melder seine\n    // Pl\u00E4tze beh\u00E4lt und nicht mehr dorthin blickt. Mit Reserve: auch 10\u00B0 verdreht noch frei, sonst reicht ein schief\n    // montierter Melder, und er sieht doch hinaus. Gerade an der Wand geht vor gedreht (Fernando 20.10.: an die\n    // Stelle gezogen, steht er gerade und sah wieder durch die T\u00FCr, der Vorschlag war um 30\u00B0 gedreht).\n    // Die Stelle darf auch an keiner anderen \u00D6ffnung ein neues Problem schaffen (Fernando 20.10.: weg von der T\u00FCr, daf\u00FCr\n    // stand das T\u00FCrblatt im Blickfeld)\n    function problemeAn(c, K = null) {\n      // je Stelle, Richtung und Modell nur einmal (h\u00E4ngt nicht von den anderen Meldern ab)\n      const key = K && K.segs ? [c.x, c.y, c.dir, c.modell, c.max, c.stufe, c.montage, c.grenze ? JSON.stringify(c.grenze) : ''].join('|') : null;\n      if (key && K.probleme.has(key)) return K.probleme.get(key);\n      const l = [], frei = ausblendbar(wm(c));          // KL MZ: Hinaussehen blendet man aus, kein Problem\n      for (const o of S.oeffnungen) {\n        if (!frei && durchlaessig(o) && siehtOeffnung(c, o, 'hinaus', K)) l.push(o.id + '|hinaus');\n        if (!frei && o.art === 'fenster' && o.vorhang && siehtOeffnung(c, o, 'vorhang', K)) l.push(o.id + '|vorhang');\n        if (o.art === 'tuer' && blattAnteil(c, o, K) >= 0.1) l.push(o.id + '|tuerblatt');\n      }\n      if (key) K.probleme.set(key, l);\n      return l;\n    }\n    // Was am alten Platz beim Stillsitzen erkannt wird, muss es auch an der neuen Stelle (Fernando 20.10.: beim KL MZ\n    // lag sonst fast alles im Bereich, der nur Bewegung erkennt).\n    // Die Teile eines gesammelten Hinweises einer Art; die n\u00E4chste Entfernung zu einer \u00D6ffnung (f\u00FCr \u201EReichweite begrenzen\u201C)\n    const teile = (h, art) => (h.teile || []).filter(p => p.art === art);\n    const naechste = h => Math.min(...teile(h, 'hinaus').map(p => p.dnah), ...teile(h, 'vorhang').map(p => p.dmin));\n    function vorschlagOeffnung(h) {\n      const s = h.r.s, Z = h.r.zeilen.filter(z => z.ort), ziele = h.teile.map(p => p.o.id + '|' + p.art);\n      const P = Z.filter(z => z.anteil >= 0.5).map(z => z.key), KERNE = Z.filter(z => z.kern >= 0.5).map(z => [z.key, z.kern]);\n      let jetzt = null;\n      const geht = (c, K) => {\n        const p = problemeAn(c, K);\n        return !p.some(x => ziele.includes(x)) && p.every(x => jetzt.has(x));\n      };\n      return stelleSuchen(zustandKey() + s.id + '|o|' + ziele.join(','), s, (z, c, K, k) => {\n        if (P.some(n => !z.get(n) || z.get(n).anteil < 0.5) || KERNE.some(([n, k0]) => z.get(n).kern < k0 - 0.15)) return null;   // h\u00F6chstens 15 Punkte Pr\u00E4senz weniger\n        if (!jetzt) jetzt = new Set(problemeAn(s, K));\n        if (istDecke(c) ? !geht(c, K) : [0, -10, 10].some(d => !geht({ ...c, dir: grad360(c.dir + d) }, K))) return null;\n        return -P.reduce((a, n) => a + z.get(n).kern, 0) * 3 + Math.hypot(c.x - s.x, c.y - s.y) * 0.05 + k.dreh / 30;\n      });\n    }\n    // Stelle f\u00FCr die Hinweise an \u00D6ffnungen; \u201Ek\u00F6nnen sich st\u00F6ren\u201C hat keinen Vorschlag\n    function vorschlagHinweis(h) {\n      if (h.art !== 'oeffnungen') return null;\n      // Nur Hinaussehen und Vorhang: reicht Begrenzen, keine Stelle. Steht ein T\u00FCrblatt davor, hilft nur eine andere Stelle\n      if (!teile(h, 'tuerblatt').length && grenze(h.r, naechste(h))) return null;\n      return vorschlagOeffnung(h);\n    }\n    // ---------- Beste Stelle (Schritt 2, Knopf im Reiter \u201EZonen und Hinweise\u201C) ----------\n    // M\u00F6bel mit Aufenthalt, die h\u00F6chstens NAH auseinanderstehen, z\u00E4hlen als ein Platz: Sofa und Sessel einer Sitzecke,\n    // die beiden Teile eines Ecksofas, Tisch und St\u00FChle. Ohne Zutun des Kunden (Fernando 20.10.: Bereichsnummern hat keiner\n    // verstanden). Getestet an den Beispielr\u00E4umen: ohne Pl\u00E4tze trennte der Vorschlag den Tisch von seinen Sesseln.\n    const NAH = 0.5;\n    function plaetzeGruppen() {\n      const o = S.moebel.filter(istOrt), wurzel = new Map(o.map(m => [m.id, m.id]));\n      const f = id => wurzel.get(id) === id ? id : f(wurzel.get(id));\n      const luecke = (a, b) => Math.max(0, Math.max(a.x, b.x) - Math.min(a.x + a.w, b.x + b.w), Math.max(a.y, b.y) - Math.min(a.y + a.h, b.y + b.h));\n      for (const a of o) for (const b of o) if (a !== b && luecke(a, b) <= NAH) wurzel.set(f(a.id), f(b.id));\n      const g = new Map();\n      o.forEach(m => { const k = f(m.id); g.set(k, [...(g.get(k) || []), m.id]); });\n      return [...g.values()];                          // je Platz die M\u00F6bel-IDs\n    }\n    // je Platz: ganz erfasst, d. h. jedes M\u00F6bel zu mindestens VOLL im Bereich, der auch Stillsitzen erkennt (Fernando\n    // 21.10.: bei 50 % galt ein halb verdecktes Sofa als erfasst, \u201EMurks\u201C); dazu der mittlere Anteil als Grad\n    const VOLL = 0.9;\n    function platzWerte(c, P, plaetze, K) {\n      const z = messen(c, plaetze, K);\n      return {\n        p: P.map(ids => ids.every(id => { const w = z.get(id); return !!w && w.kern >= VOLL; })),\n        g: P.map(ids => ids.reduce((a, id) => a + ((z.get(id) || {}).kern || 0), 0) / ids.length),\n      };\n    }\n    // Wie viele Pl\u00E4tze mindestens ein Melder ganz erfasst, und die Summe der besten Grade (f\u00FCr Stellen, die nicht alles\n    // schaffen: m\u00F6glichst viel abdecken)\n    // deckel: h\u00F6chstens so viele Pl\u00E4tze je Melder (Zonen: MAX_ZONEN); Zuordnung wie bei den Zonen (zuordnen)\n    function platzBilanz(E, P, deckel = Infinity) {\n      const von = zuordnen(P.length, g => E.map((e, i) => ({ key: i, wert: e.g[g], p: e.p[g] })).filter(k => k.p).sort((a, b) => b.wert - a.wert), () => deckel);\n      let grad = 0;\n      P.forEach((_, g) => { grad += Math.max(0, ...E.map(e => e.g[g])); });\n      return { erfasst: von.size, grad };\n    }\n    // Probleme an \u00D6ffnungen (auch 10\u00B0 verdreht, wie bei vorschlagOeffnung) und gegenseitiges St\u00F6ren mit den anderen\n    function stelleProbleme(c, andere, K) {\n      const l = new Set();\n      for (const d of [0, -10, 10]) problemeAn({ ...c, dir: grad360(c.dir + d) }, K).forEach(x => l.add(x));\n      return l.size + andere.filter(s2 => !istDecke(s2) && wm(s2).ghz === wm(c).ghz &&\n        erfassung(c, ursprung(s2), K).st === 'ja' && erfassung(s2, ursprung(c), K).st === 'ja').length;\n    }\n    const vergleich = (a, b) => { for (let i = 0; i < a.length; i++) if (Math.abs(a[i] - b[i]) > 1e-9) return a[i] - b[i]; return 0; };\n    // Begehbare Fl\u00E4che des Raums als Proben alle 50 cm (ohne Schrank, Metall, Mauerwerk): im Raum-Modus soll die Fl\u00E4che\n    // mit Stillsitzen m\u00F6glichst ganz erfasst sein (Fernando 21.10.), nicht nur die Pl\u00E4tze\n    function raumProben() {\n      const poly = raumPoly(), H = huelle(poly), hoch = S.moebel.filter(schirmt), l = [];\n      for (let x = H.x0 + PROBE_GROB / 2; x < H.x1; x += PROBE_GROB) for (let y = H.y0 + PROBE_GROB / 2; y < H.y1; y += PROBE_GROB) {\n        const p = { x, y };\n        if (imRaum(p, poly) && !hoch.some(o => inRechteck(p, o) && innen(o, p))) l.push(p);\n      }\n      return l;\n    }\n    const flaecheWerte = (c, punkte, K) => { const V = vorbereiten(c, kontext(K)); return punkte.map(q => { const e = erfassungV(V, q); return e.st === 'ja' && !!e.kern; }); };\n    const flaecheAnteil = (listen, n) => { let z = 0; for (let i = 0; i < n; i++) if (listen.some(l => l[i])) z++; return n ? z / n : 0; };\n    // Wert einer Stelle, kleiner = besser: erfasste Pl\u00E4tze, (im Raum-Modus: erfasste Fl\u00E4che), Grad der Abdeckung, Probleme,\n    // gedreht, Weg. fl = { proben, andere: Fl\u00E4chenwerte der anderen Melder } schaltet die Fl\u00E4che ein.\n    function stelleFuer(basis, andere, P, plaetze, K, deckel = Infinity, fl = null) {\n      K = kontext(K);\n      const E0 = andere.map(s2 => platzWerte(s2, P, plaetze, K)), mk = moebelKanten();\n      let best = null;\n      // Wand und Ecke immer; die Decke (50-cm-Raster) nur mit H\u00E4kchen \u201EAuch Deckenmontage vorschlagen\u201C (Fernando 22.10.)\n      const kand = kandidaten(raumPoly(), false, basis.dir).map(k => ({ ...k, montage: 'wand' }));\n      if (mitDecke) kand.push(...kandidaten(raumPoly(), true, 90).map(k => ({ ...k, montage: 'decke' })));\n      for (const k of kand) {\n        const c = { ...basis, x: rund(k.x), y: rund(k.y), dir: grad360(k.dir), wand: k.wand, montage: k.montage };\n        if (!nahFrei(c, mk, K)) continue;\n        const w = platzBilanz([...E0, platzWerte(c, P, plaetze, K)], P, deckel);\n        if (best && -w.erfasst > best.wert[0]) continue;   // Fl\u00E4che und Probleme nur rechnen, wo es sich lohnt\n        const meine = fl ? flaecheWerte(c, fl.proben, K) : null;\n        const flaeche = fl ? Math.round(flaecheAnteil([...fl.andere, meine], fl.proben.length) * 100) / 100 : 0;\n        if (best && vergleich([-w.erfasst, -flaeche], best.wert.slice(0, 2)) > 0) continue;\n        const probleme = stelleProbleme(c, andere, K);\n        const wert = [-w.erfasst, -flaeche, -Math.round(w.grad * 20) / 20, probleme, k.dreh, Math.hypot(c.x - basis.x, c.y - basis.y)];\n        if (!best || vergleich(wert, best.wert) < 0) best = { wert, w, c, dreh: k.dreh, probleme, flaeche, fl: meine };\n      }\n      return best;\n    }\n    // Stufenweise (Fernando 20.10.): erst der Melder selbst an einer anderen Stelle, dann ein lieferbares Modell derselben\n    // Klasse mit mehr Reichweite (g\u00FCnstigstes zuerst), dann ein zweiter Melder. Gut hei\u00DFt: alle Pl\u00E4tze werden mit\n    // Stillsitzen erfasst, keine Probleme an \u00D6ffnungen, kein St\u00F6ren. Gesucht wird nur an der Wand.\n    // Ergebnis als Wahl (Fernando 20.10.: Stelle f\u00FCr den eigenen Melder und \u201Eanderes Produkt an anderer Stelle\u201C sahen\n    // gleich aus): zuerst immer der eigene Melder, darunter nur, wenn es damit besser geht, ein anderes Modell oder ein\n    // zweiter Melder, ausdr\u00FCcklich benannt und mit Aufpreis.\n    function besteStelle(s) {\n      // KL MZ mit Zonen: die Zonen sind die Pl\u00E4tze (h\u00F6chstens MAX_ZONEN je Melder), sonst die M\u00F6belpl\u00E4tze\n      const mitZonen = hatZonen(s) && zonen().length > 0, deckel = mitZonen ? MAX_ZONEN : Infinity;\n      const P = mitZonen ? zonenP() : plaetzeGruppen();\n      if (!P.length) return { P, optionen: [{ art: 'leer' }], wahl: 0 };\n      const plaetze = mitZonen ? zonenProben() : plaetzeProben(), K = kontext(), andere = S.melder.filter(x => x !== s);\n      const gut = b => b && b.wert[0] === -P.length && b.probleme === 0;\n      // Raum-Modus: die Fl\u00E4che z\u00E4hlt mit; die anderen Melder bringen ihre Fl\u00E4chen ein\n      const fp = mitZonen ? null : raumProben();\n      const flFuer = liste => fp ? { proben: fp, andere: liste.map(s2 => flaecheWerte(s2, fp, K)) } : null;\n      const vs = (b, extra) => ({ x: b.c.x, y: b.c.y, dir: b.c.dir, wand: b.c.wand, dreh: b.dreh, ...extra });\n      const M1 = MODELLE[s.modell];\n      // gesucht wird an der Wand; ein Deckenmelder bekommt daf\u00FCr Stufe und Reichweite der Wand\n      const anWand = istDecke(s) ? { montage: 'wand', stufe: grundStufe(M1), max: M1.reichweite } : { montage: 'wand' };\n      const eigen = stelleFuer({ ...s, ...anWand }, andere, P, plaetze, K, deckel, flFuer(andere)), optionen = [];\n      if (!eigen) return { P, optionen: [{ art: 'keine' }], wahl: 0 };   // keine Wandstelle frei (nahFrei), kein Absturz\n      const da = Math.hypot(eigen.c.x - s.x, eigen.c.y - s.y) < 0.01 && eigen.c.dir === grad360(s.dir) && !istDecke(s);\n      if (gut(eigen)) optionen.push(da ? { art: 'schon' } : { art: 'stelle', vorschlag: vs(eigen, { s, anders: anWand }) });\n      else optionen.push(da ? { art: 'teil_da', e: eigen.w.erfasst } : { art: 'teil', e: eigen.w.erfasst, vorschlag: vs(eigen, { s, anders: anWand }) });\n      if (!gut(eigen)) {\n        const mehr = lieferbare().filter(([k, M]) => k !== s.modell && M.klasse === M1.klasse && M.reichweite > wm(s).reichweite).sort((a, b) => (a[1].preis || 0) - (b[1].preis || 0));\n        let ok = false;\n        for (const [k, M] of mehr) {\n          const anders = { modell: k, max: M.reichweite, stufe: grundStufe(M), montage: 'wand' };\n          const b = stelleFuer({ ...s, ...anders }, andere, P, plaetze, K, deckel, flFuer(andere));\n          if (gut(b)) { optionen.push({ art: 'modell', modell: M.name, plus: (M.preis || 0) - (M1.preis || 0), vorschlag: vs(b, { s, anders }) }); ok = true; break; }\n        }\n        if (!ok) {\n          const neu = { id: 'neu', modell: s.modell, dir: 90, max: M1.reichweite, stufe: grundStufe(M1), wand: null };\n          const zweit = stelleFuer(neu, S.melder, P, plaetze, K, deckel, flFuer(S.melder));\n          if (gut(zweit)) optionen.push({ art: 'zweiter', modell: M1.name, plus: M1.preis || 0, vorschlag: vs(zweit, { neu }) });\n        }\n      }\n      return { P, optionen, wahl: optionen.findIndex(o => o.vorschlag) };\n    }\n    // ---------- Vorschlag (Knopf unter \u201EMelder hinzuf\u00FCgen\u201C) ----------\n    // Setzt von sich aus so viele Melder der gew\u00E4hlten Klasse, wie n\u00F6tig sind, damit jeder Platz mit Stillsitzen erfasst\n    // wird (Fernando 20.10.: wer den Raum mit M\u00F6beln gebaut hat, soll nicht noch die Modelle durchprobieren m\u00FCssen).\n    // Regeln: das g\u00FCnstigste lieferbare Modell, das es schafft, nur an der Wand, keine Obergrenze. Schritt f\u00FCr Schritt\n    // kommt der Melder hinzu, der die meisten Pl\u00E4tze neu erfasst (so kommt der KL LD nur, wenn 6 m nicht reichen,\n    // Fernando 21.10.); bei gleichem Gewinn der mit weniger Problemen, dann der g\u00FCnstigste. Bringt kein Modell mehr einen\n    // Platz hinzu, bleibt der Rest offen und das Ergebnis sagt es. Ersetzt die Melder im Plan; \u201ER\u00FCckg\u00E4ngig\u201C holt sie zur\u00FCck.\n    // Neuer Wandmelder eines Modells, noch ohne Stelle (die sucht stelleFuer)\n    const neuerMelder = (k, M, p = { x: 0, y: 0 }) => ({ id: neueId('s'), modell: k, x: p.x, y: p.y, dir: 90, max: M.reichweite, stufe: grundStufe(M), wand: null, montage: 'wand' });\n    function vorschlagAlle(klasse = 'raum') {\n      // Klasse Zonen: die gezeichneten Zonen sind die Pl\u00E4tze, je Melder h\u00F6chstens MAX_ZONEN (Fernando 21.10.)\n      // Klasse beides: wie Zonen, danach f\u00FCllen Raum-Melder die begehbare Fl\u00E4che auf (flaecheAuffuellen)\n      const zm = zonenModus(klasse);\n      const P = zm ? zonenP() : plaetzeGruppen(), deckel = zm ? MAX_ZONEN : Infinity;\n      if (!P.length) return { P, melder: [], erfasst: 0, klasse };\n      const plaetze = zm ? zonenProben() : plaetzeProben(), K = kontext(), H = huelle(raumPoly());\n      const mitte = { x: (H.x0 + H.x1) / 2, y: (H.y0 + H.y1) / 2 };\n      const modelle = lieferbare().filter(([, M]) => M.klasse === (zm ? 'zonen' : 'raum')).sort((a, b) => (a[1].preis || 0) - (b[1].preis || 0));\n      // Der erste Melder misst auch das Raumklima (Fernando 21.10.: KL statt Basis, wenn beide reichen; ein Klimasensor im\n      // Raum gen\u00FCgt), weitere so g\u00FCnstig wie m\u00F6glich. Gibt es kein lieferbares Modell mit Raumklima, z\u00E4hlt nur der Preis.\n      // H\u00E4kchen \u201EAuch das Raumklima erfassen\u201C aus (Fernando 22.10.): nur der Preis, der Basis darf der erste sein.\n      const mitKlima = mitRaumklima ? modelle.filter(([, M]) => M.klima) : [];\n      // Raum-Modus: nach den Pl\u00E4tzen z\u00E4hlt die begehbare Fl\u00E4che. Melder kommen hinzu, bis FLAECHE_ZIEL erreicht ist oder\n      // keiner mehr FLAECHE_SCHRITT bringt (Fernando 21.10.: \u201Em\u00F6glichst nah an 100 %\u201C, der KL geh\u00F6rte in die linke H\u00E4lfte).\n      const fp = klasse === 'raum' ? raumProben() : null, decken = [];\n      const liste = [];\n      let erfasst = 0, flaeche = 0;\n      while (true) {\n        let best = null;\n        for (const [k, M] of (liste.length || !mitKlima.length ? modelle : mitKlima)) {\n          const neu = neuerMelder(k, M, mitte);\n          const b = stelleFuer(neu, liste, P, plaetze, K, deckel, fp ? { proben: fp, andere: decken } : null);\n          if (!b) continue;\n          // Gewinn an Pl\u00E4tzen, Gewinn an Fl\u00E4che (beide negativ = besser), Probleme; Reihenfolge = Preis.\n          // Fl\u00E4che z\u00E4hlt nur bis zum Ziel (Fernando 22.10.): erreichen zwei Modelle die 90 %, gewinnt das g\u00FCnstigere,\n          // sonst schlug der KL LD den Basis in jedem Raum, weil er immer ein paar Punkte mehr erfasst.\n          const fl = v => Math.min(v || 0, FLAECHE_ZIEL);\n          const wert = [erfasst - b.w.erfasst, -(fl(b.flaeche) - fl(flaeche)), b.probleme];\n          if (!best || vergleich(wert, best.wert) < 0) best = { wert, b };\n        }\n        if (!best) break;\n        const plaetzeGewinn = best.wert[0] < 0, flaechenGewinn = fp && flaeche < FLAECHE_ZIEL && best.b.flaeche - flaeche >= FLAECHE_SCHRITT;\n        if (!plaetzeGewinn && !flaechenGewinn) break;\n        liste.push(best.b.c); erfasst = best.b.w.erfasst;\n        if (fp) { decken.push(best.b.fl); flaeche = best.b.flaeche; }\n      }\n      // Zonen und ganzer Raum: der KL MZ meldet Anwesenheit auch au\u00DFerhalb seiner Zonen (Fernando 21.10.), sein Feld\n      // z\u00E4hlt f\u00FCr die Fl\u00E4che; wo er nicht hinreicht, kommen g\u00FCnstige Raum-Melder dazu\n      if (klasse === 'beides') flaeche = flaecheAuffuellen(liste, K, mitte);\n      return { P, melder: liste, erfasst, klasse, flaeche: fp || klasse === 'beides' ? flaeche : null };\n    }\n    // Raum-Melder hinzuf\u00FCgen, bis FLAECHE_ZIEL der begehbaren Fl\u00E4che mit Stillsitzen erfasst ist oder keiner mehr\n    // FLAECHE_SCHRITT bringt; die Felder der vorhandenen Melder z\u00E4hlen mit. Gibt den erreichten Anteil zur\u00FCck.\n    function flaecheAuffuellen(liste, K, mitte) {\n      const fp = raumProben(), decken = liste.map(s => flaecheWerte(s, fp, K));\n      let flaeche = Math.round(flaecheAnteil(decken, fp.length) * 100) / 100;\n      const modelle = lieferbare().filter(([, M]) => M.klasse === 'raum').sort((a, b) => (a[1].preis || 0) - (b[1].preis || 0));\n      while (flaeche < FLAECHE_ZIEL) {\n        let best = null;\n        for (const [k, M] of modelle) {\n          const neu = neuerMelder(k, M, mitte);\n          const b = stelleFuer(neu, liste, [], new Map(), K, Infinity, { proben: fp, andere: decken });\n          if (!b) continue;\n          const wert = [-(b.flaeche - flaeche), b.probleme];   // Gewinn an Fl\u00E4che, Probleme; Reihenfolge = Preis\n          if (!best || vergleich(wert, best.wert) < 0) best = { wert, b };\n        }\n        if (!best || best.b.flaeche - flaeche < FLAECHE_SCHRITT) break;\n        liste.push(best.b.c); decken.push(best.b.fl); flaeche = best.b.flaeche;\n      }\n      return flaeche;\n    }\n    // Ergebnis des Vorschlags, gilt, solange sich nichts \u00E4ndert\n    let vorschlagErg = null;                           // { key, erg }\n    const vorschlagAktuell = () => vorschlagErg && vorschlagErg.key === zustandKey() ? vorschlagErg.erg : null;\n    function vorschlagAlleText(e) {\n      if (!e.melder.length) return tipp(t('beste_leer'));\n      const namen = e.melder.map(s => `${punkt(S.melder.indexOf(s))}${esc(melderName(s))}`).join(', ');\n      const preis = geld(e.melder.reduce((a, s) => a + (MODELLE[s.modell].preis || 0), 0));\n      const z = zonenModus(e.klasse), ganz = e.erfasst === e.P.length;\n      return (ganz ? meldung('ok', t('passt'), t(z ? 'vorschlag_zonen_ok' : 'vorschlag_alle_ok', { p: e.P.length, liste: namen, preis }))\n        : tipp(t(z ? 'vorschlag_zonen_teil' : 'vorschlag_alle_teil', { e: e.erfasst, p: e.P.length, liste: namen, preis }))) +\n        (e.flaeche != null ? `<p class=\"hinweis\">${t('vorschlag_flaeche', { p: Math.round(e.flaeche * 100) })}</p>` : '') +\n        `<p class=\"hinweis\">${t('vorschlag_alle_weiter')}</p>`;   // keine Platz- oder Zonenliste mehr (Fernando 22.10.)\n    }\n    // Ergebnis gilt, solange sich nichts \u00E4ndert und man im selben Reiter bleibt\n    let beste = null;                                  // { bei, key, erg }\n    const besteAktuell = () => beste && beste.bei === markOrt() && beste.key === zustandKey() ? beste.erg : null;\n    function besteMarkierung() {\n      const e = besteAktuell(), o = e && e.optionen[e.wahl];\n      if (!o || !o.vorschlag) return null;\n      return { melder: o.vorschlag.s ? [o.vorschlag.s] : [...S.melder], moebel: e.P.flat(), oeffnung: [], vorschlag: o.vorschlag };\n    }\n    function besteText(e) {\n      const sel = finde('melder', auswahl.id), name = MODELLE[sel.modell].name;\n      const h = e.optionen.map((o, i) => {\n        const dreh = o.vorschlag && o.vorschlag.dreh ? ' ' + t('stelle_gedreht', { g: o.vorschlag.dreh }) : '';\n        const titel = o.art === 'modell' ? t('beste_titel_modell') : o.art === 'zweiter' ? t('beste_titel_zweiter') : t('beste_titel_eigen', { modell: name });\n        const satz = o.art === 'leer' ? t('beste_leer') : o.art === 'keine' ? t('beste_keine') : o.art === 'schon' ? t('beste_schon') : o.art === 'stelle' ? t('beste_stelle')\n          : o.art === 'teil' ? t('beste_teil', { e: o.e, n: e.P.length }) : o.art === 'teil_da' ? t('beste_teil_da', { e: o.e, n: e.P.length })\n          : o.art === 'modell' ? t('beste_modell', { modell: o.modell, alt: name, preis: geld(o.plus) })\n          : t('beste_zweiter', { modell: o.modell, preis: geld(o.plus) });\n        if (o.art === 'leer' || o.art === 'keine') return tipp(satz);\n        // antippen zeigt die Stelle dieser M\u00F6glichkeit im Plan; der Knopf darin \u00FCbernimmt sie\n        return `<div class=\"beste-option\" data-beste=\"${i}\" aria-pressed=\"${e.wahl === i}\" role=\"button\" tabindex=\"0\"><p class=\"feld-titel\">${titel}</p>` +\n          `<p>${satz}${dreh}</p>${o.vorschlag ? vorschlagKnopf(o.vorschlag, i) : ''}</div>`;\n      }).join('');\n      return h;\n    }\n\n    // Vorschlag des markierten Hinweises (Hinweisliste oder Reiter \u201EHinweise\u201C), sonst null\n    function markierterHinweis() {\n      if (markiert === null || markiertBei !== markOrt()) return null;\n      return hinweisListe()[markiert] || null;\n    }\n    function markierterVorschlag() {\n      const x = markierterHinweis() || besteMarkierung();\n      return x && x.vorschlag ? x.vorschlag : null;\n    }\n    function abhilfeText(h, vs) {\n      if (h.ok) return t('ok_ausblenden');\n      if (h.art === 'stoeren') {\n        const band = lieferbare().find(([, m]) => m.ghz !== h.r.M.ghz);\n        return t('abhilfe_stoeren') + (band ? ' ' + t('abhilfe_band', { modell: band[1].name, ghz: band[1].ghz }) : '');\n      }\n      const blatt = teile(h, 'tuerblatt').length > 0;\n      if (vs) return stelleText(vs) + (blatt ? '' : mzTuer(h));   // T\u00FCrblatt, oder Begrenzen reicht nicht: andere Stelle\n      if (blatt) return t('abhilfe_tuerblatt');\n      return ohneStelle(h, naechste(h));   // hinaus, vorhang\n    }\n    // Zusatz bei \u00D6ffnungen: der KL MZ blendet den Bereich aus, wenn er lieferbar ist und nicht schon gew\u00E4hlt\n    function mzModell(h) {\n      const mz = lieferbare().find(([, m]) => ausblendbar(m));\n      return mz && !ausblendbar(h.r.M) ? mz[1].name : null;\n    }\n    const mzTuer = h => { const mz = mzModell(h); return mz ? ' ' + t('abhilfe_mz_tuer', { modell: mz }) : ''; };\n    const hinweisText = (h, vs) => hinweisGrund(h) + ' ' + abhilfe(abhilfeText(h, vs));\n    function hinweisGrund(h) {\n      if (h.art === 'stoeren') return t('stoeren', { a: melderName(h.r.s), b: melderName(h.mit), ghz: h.r.M.ghz });\n      // gesammelt je Melder: je Art ein Satz, bei mehreren \u00D6ffnungen die Namen als Liste\n      const saetze = [], namen = l => l.map(p => oeffnungName(p.o)).join(', ');\n      const hin = teile(h, 'hinaus'), vor = teile(h, 'vorhang'), bl = teile(h, 'tuerblatt');\n      if (hin.length === 1) saetze.push(t('hinaus_' + hin[0].o.art, { name: oeffnungName(hin[0].o), m: zahl(hin[0].weit) }));\n      else if (hin.length) saetze.push(t('hinaus_mehrere', { liste: namen(hin), m: zahl(Math.max(...hin.map(p => p.weit))) }));\n      if (vor.length === 1) saetze.push(t('vorhang_bereich', { name: oeffnungName(vor[0].o), von: zahl(vor[0].dmin), bis: zahl(vor[0].dmax) }));\n      else if (vor.length) saetze.push(t('vorhang_mehrere', { liste: namen(vor) }));\n      if (bl.length === 1) saetze.push(t('tuerblatt_vor', { name: oeffnungName(bl[0].o), p: Math.round(bl[0].anteil * 100) }) + ' ' + t('tuerblatt_pruefen'));\n      else if (bl.length) saetze.push(t('tuerblatt_mehrere', { liste: namen(bl), p: Math.round(Math.max(...bl.map(p => p.anteil)) * 100) }) + ' ' + t('tuerblatt_pruefen_mehrere'));\n      return saetze.join(' ');\n    }\n\n    // ---------- Zeichnen ----------\n    function faecherPfad(o, dir, w, r) {\n      const a1 = rad(dir - w / 2), a2 = rad(dir + w / 2);\n      return `M${o.x},${o.y} L${o.x + r * Math.cos(a1)},${o.y + r * Math.sin(a1)} ` +\n        `A${r},${r} 0 ${w > 180 ? 1 : 0} 1 ${o.x + r * Math.cos(a2)},${o.y + r * Math.sin(a2)} Z`;\n    }\n    function sichtPfad(s, segs) {\n      const o = ursprung(s), M = wm(s);\n      if (istDecke(s)) {\n        const { R } = decke(s), w = deckenHindernisse();\n        let d = '';\n        for (let g = 0; g < 360; g += 1) {\n          const tt = strahl(o, g, R, w);\n          d += (g ? ' L' : 'M') + `${o.x + tt * Math.cos(rad(g))},${o.y + tt * Math.sin(rad(g))}`;\n        }\n        return d + ' Z';\n      }\n      let d = `M${o.x},${o.y}`;\n      for (let g = s.dir - M.winkel / 2; g <= s.dir + M.winkel / 2 + 1e-9; g += 0.5) {\n        const tt = strahl(o, g, s.max, segs);\n        d += ` L${o.x + tt * Math.cos(rad(g))},${o.y + tt * Math.sin(rad(g))}`;\n      }\n      return d + ' Z';\n    }\n    const formSvg = (o, attr) => o.rund\n      ? `<circle cx=\"${o.x + o.w / 2}\" cy=\"${o.y + o.h / 2}\" r=\"${o.w / 2}\" ${attr}/>`\n      : `<rect x=\"${o.x}\" y=\"${o.y}\" width=\"${o.w}\" height=\"${o.h}\" ${attr}/>`;\n    const polyPfad = poly => 'M' + poly.map(p => p.join(',')).join(' L') + ' Z';\n    // Legende oben links am Plan: was kr\u00E4ftig, hell und wei\u00DF hei\u00DFt, in der Farbe des gew\u00E4hlten Melders (sonst A)\n    let legendeAlt = '';\n    function legendeNeu() {\n      const el = $('#legende'), sel = auswahl && auswahl.typ === 'melder' ? S.melder.findIndex(s => s.id === auswahl.id) : -1;\n      const f = farbe(Math.max(0, sel)), deckKern = 1 - (1 - FLAECHE.hell) * (1 - FLAECHE.kern);\n      const feld = (art, deck) => `<span class=\"legende-feld legende-feld--${art}\" style=\"--f:${f};--d:${Math.round(deck * 100)}%\"></span>`;\n      const h = S.melder.length ? `<span>${feld('kern', deckKern)}${t('legende_praesenz')}</span><span>${feld('hell', FLAECHE.hell)}${t('legende_bewegung')}</span>` +\n        `<span>${feld('nicht', 0)}${t('legende_nicht')}</span>` +\n        (zonen().length ? `<span><span class=\"legende-bereich\" style=\"--f:${f}\"></span>${t('legende_zone')}</span>` : '') +\n        [['klima', KLIMA], ['helligkeit', SONNE], ['sirene', SIRENE]].filter(([k]) => S.melder.some(s => MODELLE[s.modell][k]))\n          .map(([k, sym]) => `<span class=\"legende-klima\" style=\"--f:${f}\">${sym()}${t(k)}</span>`).join('') : '';\n      if (h === legendeAlt) return;\n      legendeAlt = h; el.innerHTML = h; el.hidden = !h;\n    }\n\n    function zeichne() {\n      const k = ansicht.k, px = v => v / k;\n      if (markiert !== null && markiertBei !== markOrt()) markiert = null;\n      const mk = (markiert !== null ? hinweisListe()[markiert] || null : null) || besteMarkierung();\n      const poly = raumPoly(), segs = hindernisse();\n      const H = huelle(poly);\n      const ns = 'vector-effect=\"non-scaling-stroke\"';\n      let h = `<g transform=\"translate(${ansicht.tx},${ansicht.ty}) scale(${k})\">`;\n      // Ist ein Hinweis markiert, tritt alles zur\u00FCck, was er nicht meint (Fernando 17.10.): grau bzw. blass\n      const blass = (start, aus) => { if (aus) h = h.slice(0, start) + '<g opacity=\".25\">' + h.slice(start) + '</g>'; };\n\n      // Raster 1 m\n      h += `<g class=\"p-raster\" stroke-width=\"1\">`;\n      for (let x = Math.ceil(H.x0 - 1e-9); x <= H.x1 + 1e-9; x++) h += `<line x1=\"${x}\" y1=\"${H.y0}\" x2=\"${x}\" y2=\"${H.y1}\" ${ns}/>`;\n      for (let y = Math.ceil(H.y0 - 1e-9); y <= H.y1 + 1e-9; y++) h += `<line x1=\"${H.x0}\" y1=\"${y}\" x2=\"${H.x1}\" y2=\"${y}\" ${ns}/>`;\n      h += '</g>';\n      h += `<path class=\"p-boden\" d=\"${polyPfad(poly)}\"/>`;\n      // Grenzlinien und Ringe enden an den W\u00E4nden; drau\u00DFen steht nur, was der Melder wirklich durch eine \u00D6ffnung\n      // sieht (die Fl\u00E4che), sonst sieht eine Linie jenseits der Wand aus wie Erfassung durch die T\u00FCr (Fernando 20.10.)\n      h += `<clipPath id=\"raumclip\"><path d=\"${polyPfad(poly)}\"/></clipPath>`;\n      // Beim Ziehen eines Melders: Band entlang der W\u00E4nde zeigt die Fangzone (dort Wandmelder, innen Deckenmelder)\n      if ((geste && geste.art === 'ziehen' && geste.typ === 'melder' && geste.bewegt) || (kartenZug && kartenZug.aktiv))\n        h += `<path class=\"p-fang\" d=\"${polyPfad(poly)}\" fill=\"none\" clip-path=\"url(#raumclip)\" stroke-width=\"${2 * fangM()}\" stroke-linejoin=\"round\"/>`;\n\n      // M\u00F6bel (Fl\u00E4chen)\n      for (const o of S.moebel) {\n        const st = h.length;\n        h += formSvg(o, `class=\"p-moebel p-moebel--${stoff(o)}${o.niedrig ? ' p-moebel--niedrig' : ''}\"`);\n        blass(st, mk && !mk.moebel.includes(o.id));\n      }\n\n      // Erfassungsbereiche. Reihenfolge bei einer Farbe: erst alle hellen Fl\u00E4chen (Bewegung), dar\u00FCber alle kr\u00E4ftigen\n      // (Pr\u00E4senz), zuletzt der angetippte Melder; R\u00E4nder und Beschriftung obenauf. Sonst mischt sich Pr\u00E4senz von A mit\n      // Bewegung von B zu einem dritten Ton.\n      // Die Deckkraft sitzt an der Gruppe, nicht am Pfad: dann addieren sich \u00FCberlappende Melder nicht zu einem dunkleren\n      // Ton, und die Legende stimmt \u00FCberall. Nicht gemeinte Melder (leise) bleiben als Pfad blasser.\n      const feld = { hell: '', kern: '', obenHell: '', obenKern: '', obenRand: '', rest: '' };\n      S.melder.forEach((s, i) => {\n        const M = wm(s), o = ursprung(s);\n        const hervor = EINFARBIG && !mk && auswahl && auswahl.typ === 'melder' && auswahl.id === s.id;\n        // nicht gemeint (Hinweis) oder nicht angetippt (einfarbig, ein anderer ist gew\u00E4hlt): grau (Fernando 21.10.)\n        const f = mk ? (mk.melder.includes(s) ? farbe(i) : 'var(--color-text-muted)') : andererGewaehlt(s) ? 'var(--color-text-muted)' : farbe(i);\n        const dk = istDecke(s) ? decke(s) : null;\n        const voll = dk ? `M${o.x - dk.R},${o.y} a${dk.R},${dk.R} 0 1 0 ${2 * dk.R},0 a${dk.R},${dk.R} 0 1 0 ${-2 * dk.R},0 Z`\n          : faecherPfad(o, s.dir, M.winkel, s.max);\n        // Beschriftung nur am ausgew\u00E4hlten Melder (oder wenn es nur einen gibt), andere F\u00E4cher treten zur\u00FCck\n        const fokus = mk ? mk.melder.includes(s) : auswahl && auswahl.typ === 'melder' ? auswahl.id === s.id : S.melder.length === 1;\n        const leise = mk ? !fokus : !EINFARBIG && auswahl && auswahl.typ === 'melder' && !fokus;\n        // Verdecktes bleibt wei\u00DF wie der Boden, nur die Grenze der Reichweite gestrichelt (Fernando 19.10.: glasklar,\n        // was dunkel und hell bedeutet). Die Deckkraft steht auch in der Legende (legendeNeu).\n        h += `<clipPath id=\"c${i}\"><path d=\"${voll}\"/></clipPath>`;\n        feld.rest += `<path d=\"${voll}\" clip-path=\"url(#raumclip)\" fill=\"none\" style=\"stroke:${f}\" stroke-opacity=\"${leise ? .2 : .5}\" stroke-dasharray=\"4 4\" stroke-width=\"1\" ${ns}/>`;\n        // sichtbar: Rand hell (nur Bewegung), Kern (auch Stillsitzen) kr\u00E4ftig dar\u00FCber\n        const K = kern(s), sp = sichtPfad(s, segs), spKern = dk ? sp : sichtPfad(s, [...segs, ...daempfer()]);   // hinter T\u00FCrblatt oder geschlossener T\u00FCr nur hell\n        const kp = dk ? `M${o.x - K.R},${o.y} a${K.R},${K.R} 0 1 0 ${2 * K.R},0 a${K.R},${K.R} 0 1 0 ${-2 * K.R},0 Z` : faecherPfad(o, s.dir, K.w, K.r);\n        h += `<clipPath id=\"k${i}\"><path d=\"${kp}\"/></clipPath>`;\n        // Grenze des KL MZ: die Fl\u00E4chen enden dort\n        const G = s.grenze, inG = teil => G ? `<g clip-path=\"url(#g${i})\">${teil}</g>` : teil;\n        if (G) h += `<clipPath id=\"g${i}\"><rect x=\"${G.x}\" y=\"${G.y}\" width=\"${G.w}\" height=\"${G.h}\"/></clipPath>`;\n        const hellF = inG(`<path d=\"${sp}\" style=\"fill:${f}\" fill-opacity=\"${leise ? .36 : 1}\"/>`);\n        const kernF = inG(`<path d=\"${spKern}\" clip-path=\"url(#k${i})\" style=\"fill:${f}\" fill-opacity=\"${leise ? .38 : 1}\"/>`);\n        if (hervor) { feld.obenHell += hellF; feld.obenKern += kernF; feld.obenRand += inG(`<path d=\"${sp}\" fill=\"none\" style=\"stroke:${f}\" stroke-width=\"1.5\" ${ns}/>`); }\n        else { feld.hell += hellF; feld.kern += kernF; }\n        if (fokus) feld.rest += `<g clip-path=\"url(#raumclip)\"><path d=\"${kp}\" clip-path=\"url(#c${i})\" fill=\"none\" style=\"stroke:${f}\" stroke-opacity=\".7\" stroke-width=\"1.5\" stroke-dasharray=\"2 3\" ${ns}/></g>`;\n        if (!fokus) return;\n        // an der Decke ist die Entfernung schr\u00E4g: Ring auf dem Plan bei sqrt(d\u00B2 \u2212 H\u00F6henunterschied\u00B2)\n        const c = Math.cos(rad(dk ? -45 : s.dir)), sn = Math.sin(rad(dk ? -45 : s.dir));\n        const beschriften = lab => { for (const l of lab) {\n          const x = l.x != null ? l.x : o.x + l.rp * c, y = l.y != null ? l.y : o.y + l.rp * sn;\n          feld.rest += `<text class=\"p-halo\" x=\"${x}\" y=\"${y}\" font-size=\"${px(11)}\" style=\"fill:${f}\" text-anchor=\"middle\" dominant-baseline=\"middle\" ` +\n            `stroke-width=\"${px(3)}\" font-weight=\"600\">${esc(l.t)}</text>`;\n        } };\n        // Beschriftung auf einem Kreis, von der Mittelachse aus an der ersten Stelle im Raum; liegt der Kreis ganz\n        // drau\u00DFen, entf\u00E4llt sie\n        const g0 = dk ? -45 : s.dir;\n        const stelle = (rp, halb) => {\n          for (let d = 0; d <= halb; d += 5) for (const v of d ? [1, -1] : [1]) {\n            const g = rad(g0 + v * d), p = { x: o.x + rp * Math.cos(g), y: o.y + rp * Math.sin(g) };\n            if (imRaum(p, poly)) return p;\n          }\n          return null;\n        };\n        // Nur die beiden Grenzen, Pr\u00E4senz und Bewegung, mit Meterzahl (auf dem Plan gemessen). Liegt die Grenze ganz\n        // drau\u00DFen, reicht der Melder bis zur Wand.\n        const kr = dk ? K.R : K.r, br = dk ? dk.R : s.max;\n        beschriften([{ rp: kr, halb: dk ? 180 : K.w / 2 - 3, t: t('praesenz_label', { m: meter(kr) }) },\n          { rp: br, halb: dk ? 180 : M.winkel / 2 - 3, t: t('bewegung_label', { m: meter(br) }) }]\n          .filter(l => l.rp > 0.3).map(l => ({ ...l, ...stelle(l.rp, l.halb) })).filter(l => l.x != null));\n      });\n      h += `<g opacity=\"${FLAECHE.hell}\">${feld.hell}</g><g opacity=\"${FLAECHE.kern}\">${feld.kern}</g>` +\n        `<g opacity=\"${FLAECHE.hellHervor}\">${feld.obenHell}</g><g opacity=\"${FLAECHE.kernHervor}\">${feld.obenKern}</g>` + feld.obenRand + feld.rest;\n      legendeNeu();\n\n      // W\u00E4nde\n      h += `<path class=\"p-wand\" d=\"${polyPfad(poly)}\" stroke-width=\"4\" stroke-linejoin=\"miter\" ${ns}/>`;\n      kanten(poly).forEach(([x1, y1, x2, y2], i) => {          // Glasfront: Wand aussparen, zwei d\u00FCnne Linien wie beim Fenster\n        if (!istGlas(i)) return;\n        const len = Math.hypot(x2 - x1, y2 - y1), nx = -(y2 - y1) / len * px(2), ny = (x2 - x1) / len * px(2);\n        h += `<line class=\"p-luecke\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke-width=\"6\" ${ns}/>`;\n        for (const f of [-1, 1]) h += `<line class=\"p-oeffnung\" x1=\"${x1 + f * nx}\" y1=\"${y1 + f * ny}\" x2=\"${x2 + f * nx}\" y2=\"${y2 + f * ny}\" stroke-width=\"1\" ${ns}/>`;\n      });\n      const abstand = px(freiBearbeiten() ? 30 : 14);         // beim Bearbeiten Platz f\u00FCr das + in der Wandmitte\n      // Ma\u00DFe parallel zur Wand, lesbar gedreht (Fernando 20.10.: senkrechte W\u00E4nde auch senkrecht beschriften)\n      if (masseAn) kanten(poly).forEach(([x1, y1, x2, y2], i) => {\n        const len = Math.hypot(x2 - x1, y2 - y1), g = rad(innenWinkelKante(poly, i));\n        const mx = (x1 + x2) / 2 - Math.cos(g) * abstand, my = (y1 + y2) / 2 - Math.sin(g) * abstand;\n        h += `<text class=\"p-mass p-halo\" x=\"${mx}\" y=\"${my}\" transform=\"rotate(${lesbar(x2 - x1, y2 - y1)} ${mx} ${my})\" font-size=\"${px(12)}\" stroke-width=\"${px(3)}\" ` +\n          `text-anchor=\"middle\" dominant-baseline=\"middle\">${zahl(len, 2)} m</text>`;\n      });\n\n      // M\u00F6bel (Umriss, Beschriftung, Trefferfl\u00E4che)\n      for (const o of S.moebel) {\n        const st = h.length;\n        const sel = (auswahl && auswahl.id === o.id) || (mk && mk.moebel.includes(o.id));\n        h += formSvg(o, `class=\"p-moebel-rand p-moebel-rand--${stoff(o)}${sel ? ' is-gewaehlt' : ''}\" stroke-width=\"${sel ? 2.5 : 1}\" ${ns}`);\n        // Name entlang der langen Seite: ein hochkant gedrehtes M\u00F6bel (K\u00FCchenzeile, Schrank) bekommt ihn senkrecht (Fernando 20.10.)\n        const lang = Math.max(o.w, o.h), kurz = Math.min(o.w, o.h), senk = o.h > o.w && !o.rund;\n        if (lang * k > 40 && kurz * k > 14) {\n          const cx = o.x + o.w / 2, cy = o.y + o.h / 2;\n          h += `<text class=\"p-name${stoff(o) === 'massiv' ? ' p-name--massiv' : ''}\" x=\"${cx}\" y=\"${cy}\"${senk ? ` transform=\"rotate(-90 ${cx} ${cy})\"` : ''} font-size=\"${px(12)}\" text-anchor=\"middle\" dominant-baseline=\"middle\">${esc(o.name)}</text>`;\n        }\n        const r = px(8);\n        h += `<rect data-id=\"${o.id}\" data-typ=\"moebel\" x=\"${o.x - r}\" y=\"${o.y - r}\" width=\"${o.w + 2 * r}\" height=\"${o.h + 2 * r}\" fill=\"transparent\"/>`;\n        blass(st, mk && !sel);\n      }\n\n      // T\u00FCren, Durchg\u00E4nge, Fenster: Wand an der Stelle aussparen, dann das \u00FCbliche Grundriss-Zeichen\n      let treffer = '';\n      for (const o of S.oeffnungen) {\n        const L = oeffnungLage(o, poly); if (!L) continue;\n        const st = h.length;\n        const a = wandPunkt(L, L.t0), b = wandPunkt(L, L.t1), sel = (auswahl && auswahl.id === o.id) || (mk && mk.oeffnung.includes(o));\n        // Bezieht sich ein angetippter Hinweis auf die \u00D6ffnung, wird sie fl\u00E4chig markiert: die T\u00FCr mit ihrem Schwenkbereich,\n        // Durchgang und Fenster als Band beiderseits der Wand (Fernando 20.10.: der blaue Strich ging im Plan unter)\n        const hinweisHier = mk && mk.oeffnung.includes(o);\n        if (hinweisHier) {\n          if (o.art === 'tuer') {\n            const { an, gegen, spitze, sweep: sw } = tuerBlatt(L, o);\n            h += `<path class=\"p-markiert\" d=\"M${an.x},${an.y} L${spitze.x},${spitze.y} A${L.b},${L.b} 0 0 ${sw} ${gegen.x},${gegen.y} Z\" stroke-width=\"2\" ${ns}/>`;\n          } else {\n            const q = [wandPunkt(L, L.t0, -0.2), wandPunkt(L, L.t1, -0.2), wandPunkt(L, L.t1, 0.35), wandPunkt(L, L.t0, 0.35)];\n            h += `<path class=\"p-markiert\" d=\"M${q.map(p => `${p.x},${p.y}`).join(' L')} Z\" stroke-width=\"2\" ${ns}/>`;\n          }\n        }\n        const linie = (p, q, attr) => `<line x1=\"${p.x}\" y1=\"${p.y}\" x2=\"${q.x}\" y2=\"${q.y}\" ${attr} ${ns}/>`;\n        h += linie(a, b, 'class=\"p-luecke\" stroke-width=\"6\"');\n        if (sel) h += linie(a, b, `class=\"p-wand-wahl\" stroke-width=\"${hinweisHier ? 8 : 6}\"`);\n        const quer = (p, n) => linie({ x: p.x - L.nx * n, y: p.y - L.ny * n }, { x: p.x + L.nx * n, y: p.y + L.ny * n }, 'class=\"p-oeffnung\" stroke-width=\"2\"');\n        h += quer(a, px(4)) + quer(b, px(4));                         // Leibungen\n        if (o.art === 'fenster') {\n          const d = px(2);\n          if (offen(o)) {                                            // offen: Fl\u00FCgel nach innen gedreht, kein Glas in der Wand\n            const m = wandPunkt(L, (L.t0 + L.t1) / 2), fl = L.b / 2 * 0.8;\n            for (const [p, q] of [[a, m], [b, m]]) {\n              const ux = (q.x - p.x) / (L.b / 2), uy = (q.y - p.y) / (L.b / 2);\n              h += linie(p, { x: p.x + (ux * 0.5 + L.nx * 0.87) * fl, y: p.y + (uy * 0.5 + L.ny * 0.87) * fl }, 'class=\"p-oeffnung\" stroke-width=\"2\"');\n            }\n          } else for (const n of [-d, d]) h += linie(wandPunkt(L, L.t0, n), wandPunkt(L, L.t1, n), 'class=\"p-oeffnung\" stroke-width=\"1\"');\n          if (o.vorhang) {                                            // Zickzack knapp vor dem Fenster\n            let d2 = '';\n            const n = Math.max(2, Math.round(L.b / 0.12));\n            for (let kk = 0; kk <= n; kk++) { const q = wandPunkt(L, L.t0 + (L.t1 - L.t0) * kk / n, 0.08 + (kk % 2 ? 0.05 : 0)); d2 += (kk ? ' L' : 'M') + `${q.x},${q.y}`; }\n            h += `<path class=\"p-vorhang\" d=\"${d2}\" stroke-width=\"1.5\" ${ns}/>`;\n          }\n        } else if (o.art === 'tuer') {                                // Bogen zeigt die Schlagrichtung; Blatt offen nach innen oder zu in der Wand\n          const { an, gegen, spitze, sweep } = tuerBlatt(L, o);\n          h += linie(an, offen(o) ? spitze : gegen, 'class=\"p-oeffnung\" stroke-width=\"2\"');\n          h += `<path class=\"p-tuer-bogen\" d=\"M${spitze.x},${spitze.y} A${L.b},${L.b} 0 0 ${sweep} ${gegen.x},${gegen.y}\" stroke-width=\"1\" stroke-dasharray=\"3 3\" ${offen(o) ? '' : 'stroke-opacity=\".5\"'} ${ns}/>`;\n        }\n        // Name parallel zur Wand, au\u00DFen wie die Ma\u00DFe (Fernando 20.10.: T\u00FCren und Fenster gingen im Plan unter); liegt die\n        // \u00D6ffnung dort, wo das Wandma\u00DF steht, eine Zeile weiter au\u00DFen. Erst, wenn sie auf dem Bildschirm breit genug ist.\n        if (L.b * k > 28) {\n          const mitte = (L.t0 + L.t1) / 2, amMass = masseAn && Math.abs(mitte - 0.5) * L.len < px(45);\n          const m = wandPunkt(L, mitte, -(abstand + (amMass ? px(15) : 0)));\n          h += `<text class=\"p-name p-halo\" x=\"${m.x}\" y=\"${m.y}\" transform=\"rotate(${lesbar(L.ux, L.uy)} ${m.x} ${m.y})\" font-size=\"${px(11)}\" stroke-width=\"${px(3)}\" ` +\n            `text-anchor=\"middle\" dominant-baseline=\"middle\">${esc(oeffnungName(o))}</text>`;\n        }\n        blass(st, mk && !sel);\n        treffer += linie(a, b, `data-typ=\"oeffnung\" data-id=\"${o.id}\" stroke=\"transparent\" stroke-width=\"26\"`);\n      }\n      // Unter \u201ERaum\u201C (Form, Ma\u00DFe) liegen die W\u00E4nde dar\u00FCber und gehen vor, auch wo T\u00FCren und Fenster sitzen: eine\n      // Glasfront ist oft ganz damit belegt. T\u00FCren packt man unter \u201ET\u00FCren, Fenster\u201C oder in der Startansicht.\n      h += treffer;\n\n      // markierter Hinweis mit Vorschlag: Melder an der neuen Stelle gestrichelt, mit seinem Bereich und einer Linie dorthin\n      if (mk && mk.vorschlag) {\n        const v = mk.vorschlag, g = { ...(v.neu || v.s), ...(v.anders || {}), x: v.x, y: v.y, dir: v.dir, wand: v.wand }, f = farbe(v.neu ? S.melder.length : S.melder.indexOf(v.s));\n        h += `<path d=\"${sichtPfad(g, segs)}\" style=\"fill:${f};stroke:${f}\" fill-opacity=\".12\" stroke-width=\"1.5\" stroke-dasharray=\"6 4\" ${ns}/>`;\n        if (!v.neu) h += `<line x1=\"${v.s.x}\" y1=\"${v.s.y}\" x2=\"${g.x}\" y2=\"${g.y}\" style=\"stroke:${f}\" stroke-width=\"1.5\" stroke-dasharray=\"3 4\" ${ns}/>`;\n        if (!istDecke(g)) h += `<line x1=\"${g.x}\" y1=\"${g.y}\" x2=\"${g.x + px(18) * Math.cos(rad(g.dir))}\" y2=\"${g.y + px(18) * Math.sin(rad(g.dir))}\" style=\"stroke:${f}\" stroke-width=\"3\" stroke-dasharray=\"3 2\" ${ns}/>`;\n        h += `<circle class=\"p-geraet\" cx=\"${g.x}\" cy=\"${g.y}\" r=\"${px(9)}\" style=\"stroke:${f}\" stroke-width=\"2\" stroke-dasharray=\"3 2\" ${ns}/>`;\n        if (v.anders && v.anders.modell) h += `<text class=\"p-halo\" x=\"${g.x}\" y=\"${g.y - px(16)}\" font-size=\"${px(12)}\" text-anchor=\"middle\" stroke-width=\"${px(3)}\" font-weight=\"600\" style=\"fill:${f}\">${esc(MODELLE[v.anders.modell].name)}</text>`;\n      }\n      // markierter Hinweis \u201Ek\u00F6nnen sich st\u00F6ren\u201C: Linie zwischen den beiden Meldern\n      if (mk && mk.linie) {\n        const [a, b] = mk.melder;\n        h += `<line class=\"p-auswahl\" x1=\"${a.x}\" y1=\"${a.y}\" x2=\"${b.x}\" y2=\"${b.y}\" stroke-width=\"2\" stroke-dasharray=\"6 4\" ${ns}/>`;\n      }\n\n      // Melder\n      S.melder.forEach((s, i) => {\n        const st = h.length;\n        const f = !mk && andererGewaehlt(s) ? 'var(--color-text-muted)' : farbe(i), sel = (auswahl && auswahl.id === s.id) || (mk && mk.melder.includes(s));\n        const c = Math.cos(rad(s.dir)), sn = Math.sin(rad(s.dir));\n        if (sel) h += `<circle cx=\"${s.x}\" cy=\"${s.y}\" r=\"${px(15)}\" fill=\"none\" style=\"stroke:${f}\" stroke-width=\"2\" ${ns}/>`;\n        if (istDecke(s)) h += `<circle class=\"p-geraet\" cx=\"${s.x}\" cy=\"${s.y}\" r=\"${px(13)}\" style=\"stroke:${f}\" stroke-width=\"1.5\" stroke-dasharray=\"3 2\" ${ns}/>`;\n        else h += `<line x1=\"${s.x}\" y1=\"${s.y}\" x2=\"${s.x + px(18) * c}\" y2=\"${s.y + px(18) * sn}\" style=\"stroke:${f}\" stroke-width=\"3\" ${ns}/>`;\n        h += `<circle class=\"p-geraet\" cx=\"${s.x}\" cy=\"${s.y}\" r=\"${px(9)}\" style=\"stroke:${f}\" stroke-width=\"3\" ${ns}/>`;\n        h += `<text x=\"${s.x}\" y=\"${s.y}\" font-size=\"${px(10)}\" font-weight=\"700\" style=\"fill:${f}\" text-anchor=\"middle\" dominant-baseline=\"central\">${buchstabe(i)}</text>`;\n        // Ausstattung als kleine Plaketten oben rechts am Melder: Thermometer, Sonne, Sirene (Fernando 21.10.); Gr\u00F6\u00DFe in\n        // Bildschirmpixeln, Reihenfolge wie auf den Karten\n        PLAKETTEN.filter(([pk]) => MODELLE[s.modell][pk]).forEach(([, d], n) => {\n          h += `<g class=\"p-plakette p-plakette--${k}\" transform=\"translate(${s.x + px(13 + 15 * n)},${s.y - px(13)}) scale(${px(0.55)})\">` +\n            `<circle r=\"12\" style=\"fill:var(--color-bg);stroke:${f}\" stroke-width=\"1.5\" ${ns}/>` +\n            `<path d=\"${d}\" fill=\"none\" style=\"stroke:${f}\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" ${ns}/></g>`;\n        });\n        h += `<circle data-id=\"${s.id}\" data-typ=\"melder\" cx=\"${s.x}\" cy=\"${s.y}\" r=\"${px(24)}\" fill=\"transparent\"/>`;\n        blass(st, mk && !sel);\n      });\n\n      // Zonen des Raums in der Farbe des Melders, der sie erfasst, ohne Melder grau; Grenze je KL MZ. Antippen w\u00E4hlt,\n      // die Ecke unten rechts \u00E4ndert die Gr\u00F6\u00DFe.\n      // Griffe an allen vier Ecken (Fernando 21.10.); data-ecke sagt, welche Ecke mitzieht\n      const griff = (r, typ, id, f) => [['nw', r.x, r.y], ['ne', r.x + r.w, r.y], ['sw', r.x, r.y + r.h], ['se', r.x + r.w, r.y + r.h]].map(([e, x, y]) =>\n        `<rect x=\"${x - px(7)}\" y=\"${y - px(7)}\" width=\"${px(14)}\" height=\"${px(14)}\" style=\"fill:${f}\" />` +\n        `<rect data-typ=\"${typ}-griff\" data-id=\"${id}\" data-ecke=\"${e}\" x=\"${x - px(14)}\" y=\"${y - px(14)}\" width=\"${px(28)}\" height=\"${px(28)}\" fill=\"transparent\"/>`).join('');\n      const beschriftung = (r, f, text) => `<text class=\"p-halo\" x=\"${r.x + px(6)}\" y=\"${r.y + px(6)}\" font-size=\"${px(11)}\" style=\"fill:${f}\" dominant-baseline=\"hanging\" stroke-width=\"${px(3)}\" font-weight=\"600\">${esc(text)}</text>`;\n      const zuZ = zonen().length ? zonenZuordnung() : new Map();\n      zonen().forEach((z, n) => {\n        const zu = zuZ.get(z.id), f = zu ? farbe(S.melder.indexOf(zu.s)) : 'var(--color-text-muted)';\n        const sel = auswahl && auswahl.typ === 'zone' && auswahl.id === z.id, HZ = huelle(z.p);\n        h += `<path d=\"${polyPfad(z.p)}\" style=\"fill:${f};stroke:${f}\" fill-opacity=\"${zu ? .18 : .1}\" stroke-width=\"${sel ? 2.5 : 1.5}\" ${zu ? '' : 'stroke-dasharray=\"4 3\"'} ${ns}/>`;\n        h += beschriftung({ x: HZ.x0, y: HZ.y0 }, f, t('zone_n', { n: n + 1 }) + (zu && EINFARBIG ? ' \u00B7 ' + buchstabe(S.melder.indexOf(zu.s)) : ''));\n        h += `<path data-typ=\"zone\" data-id=\"${z.id}\" d=\"${polyPfad(z.p)}\" fill=\"transparent\"/>`;\n        if (!sel) return;\n        // Ecken ziehen; \u201E+\u201C auf jeder Kante f\u00FCgt eine Ecke hinzu (bis MAX_ZONEN_ECKEN); die gew\u00E4hlte Ecke ist gef\u00FCllt\n        z.p.forEach(([x, y], i) => {\n          const aktiv = auswahl.ecke === i;\n          h += `<circle cx=\"${x}\" cy=\"${y}\" r=\"${px(7)}\" style=\"fill:${aktiv ? f : 'var(--color-bg)'};stroke:${f}\" stroke-width=\"2\" ${ns}/>`;\n          h += `<circle data-typ=\"zone-griff\" data-id=\"${z.id}\" data-ecke=\"${i}\" cx=\"${x}\" cy=\"${y}\" r=\"${px(16)}\" fill=\"transparent\"/>`;\n        });\n        if (z.p.length < MAX_ZONEN_ECKEN) z.p.forEach(([x, y], i) => {\n          const [x2, y2] = z.p[(i + 1) % z.p.length], mx = (x + x2) / 2, my = (y + y2) / 2;\n          h += `<circle cx=\"${mx}\" cy=\"${my}\" r=\"${px(6)}\" style=\"fill:var(--color-bg);stroke:${f}\" stroke-width=\"1.5\" ${ns}/>` +\n            `<path d=\"M${mx - px(3)},${my}h${px(6)}M${mx},${my - px(3)}v${px(6)}\" style=\"stroke:${f}\" stroke-width=\"1.5\" ${ns}/>` +\n            `<circle data-typ=\"zone-neu\" data-id=\"${z.id}\" data-ecke=\"${i}\" cx=\"${mx}\" cy=\"${my}\" r=\"${px(14)}\" fill=\"transparent\"/>`;\n        });\n      });\n      S.melder.forEach((s, i) => {\n        const G = s.grenze; if (!hatZonen(s) || !G) return;\n        const f = farbe(i), sel = auswahl && auswahl.typ === 'grenze' && auswahl.id === s.id;\n        h += `<rect x=\"${G.x}\" y=\"${G.y}\" width=\"${G.w}\" height=\"${G.h}\" fill=\"none\" style=\"stroke:${f}\" stroke-width=\"${sel ? 2.5 : 1.5}\" stroke-dasharray=\"8 5\" ${ns}/>`;\n        h += beschriftung(G, f, t('grenze'));\n        h += `<rect data-typ=\"grenze\" data-id=\"${s.id}\" x=\"${G.x}\" y=\"${G.y}\" width=\"${G.w}\" height=\"${G.h}\" fill=\"none\" stroke=\"transparent\" stroke-width=\"${px(16)}\" pointer-events=\"stroke\"/>`;\n        if (sel) h += griff(G, 'grenze', s.id, f);\n      });\n\n      // Rechteck und L unter \u201ERaum\u201C: Wand antippen (Glasfront)\n      if (wandWahl() && !freiBearbeiten()) {\n        kanten(poly).forEach(([x1, y1, x2, y2], i) => {\n          if (auswahl && auswahl.typ === 'wand' && auswahl.id === i) h += `<line class=\"p-wand-wahl\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke-width=\"6\" ${ns}/>`;\n          h += `<line data-typ=\"wand\" data-id=\"${i}\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"transparent\" stroke-width=\"24\" ${ns}/>`;\n        });\n      }\n      // Freie Form unter \u201ERaum\u201C: Wand ziehen = parallel verschieben, + = Ecke einf\u00FCgen, Ecke ziehen\n      if (freiBearbeiten()) {\n        const k2 = kanten(poly);\n        k2.forEach(([x1, y1, x2, y2], i) => {\n          if (auswahl && auswahl.typ === 'wand' && auswahl.id === i) h += `<line class=\"p-wand-wahl\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke-width=\"6\" ${ns}/>`;\n          h += `<line data-typ=\"wand\" data-id=\"${i}\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"transparent\" stroke-width=\"24\" ${ns}/>`;\n        });\n        k2.forEach(([x1, y1, x2, y2], i) => {\n          if (Math.hypot(x2 - x1, y2 - y1) * k < 90) return;       // zu kurz f\u00FCr einen eigenen Griff\n          const mx = (x1 + x2) / 2, my = (y1 + y2) / 2, a = px(5);\n          h += `<g class=\"p-neu\"><circle cx=\"${mx}\" cy=\"${my}\" r=\"${px(10)}\" stroke-width=\"1.5\" ${ns}/>` +\n            `<path d=\"M${mx - a},${my}h${2 * a}M${mx},${my - a}v${2 * a}\" stroke-width=\"2\" ${ns}/></g>`;\n          h += `<circle data-typ=\"neu\" data-id=\"${i}\" cx=\"${mx}\" cy=\"${my}\" r=\"${px(20)}\" fill=\"transparent\"/>`;\n        });\n        poly.forEach(([x, y], i) => {\n          const sel = auswahl && auswahl.typ === 'ecke' && auswahl.id === i;\n          h += `<circle class=\"p-griff${sel ? ' is-gewaehlt' : ''}\" cx=\"${x}\" cy=\"${y}\" r=\"${px(sel ? 9 : 7)}\" stroke-width=\"3\" ${ns}/>`;\n          h += `<circle data-typ=\"ecke\" data-id=\"${i}\" cx=\"${x}\" cy=\"${y}\" r=\"${px(22)}\" fill=\"transparent\"/>`;\n        });\n      }\n\n      h += '</g>';\n      svg.innerHTML = h;\n    }\n\n    // ---------- Ansicht ----------\n    // Seitlich Platz f\u00FCr die Wandma\u00DFe, oben und unten zus\u00E4tzlich f\u00FCr die Kn\u00F6pfe \u00FCber dem Plan.\n    // Eingepasst wird auf die Fl\u00E4che \u00FCber dem Feld unten: in der Startansicht gro\u00DF, beim Bearbeiten (Feld\n    // --feld-h hoch) kleiner. Wechselt das Feld, gleitet der Raum nach, aber erst wenn kein Finger mehr\n    // liegt, sonst rutscht das angetippte Teil unter dem Finger weg.\n    let angepasst = true;        // false, sobald man selbst schiebt oder zoomt; dann bleibt die Ansicht stehen\n    function zielAnsicht() {\n      const r = svg.getBoundingClientRect(), H = huelle();\n      const bx = H.x1 - H.x0, by = H.y1 - H.y0;\n      legendeNeu();\n      const lg = $('#legende'), seite = 44, unten = 64;\n      const oben = lg.hidden ? 84 : Math.max(84, lg.offsetTop + lg.offsetHeight + 12);   // unter der Legende\n      // 10 % Luft um den Raum (Fernando 20.10.: war immer einen Tick zu nah); Ma\u00DFe und Melder am Rand brauchen Platz\n      const k = Math.max(5, 0.9 * Math.min((r.width - 2 * seite) / bx, (r.height - oben - unten) / by));\n      return { k, tx: (r.width - bx * k) / 2 - H.x0 * k, ty: oben + (r.height - oben - unten - by * k) / 2 - H.y0 * k };\n    }\n    function einpassen() { Object.assign(ansicht, zielAnsicht()); angepasst = true; }\n    let gleitet = 0, feldBearbeiten = false, nachpassen = false;\n    function gleiten() {\n      nachpassen = false;\n      const von = { ...ansicht }, nach = zielAnsicht(), t0 = performance.now();\n      const dauer = matchMedia('(prefers-reduced-motion: reduce)').matches ? 0 : 250;\n      cancelAnimationFrame(gleitet);\n      const schritt = jetzt => {\n        const tt = dauer ? Math.min(1, (jetzt - t0) / dauer) : 1, e = 1 - (1 - tt) ** 3;\n        for (const z of ['k', 'tx', 'ty']) ansicht[z] = von[z] + (nach[z] - von[z]) * e;\n        zeichne();\n        gleitet = tt < 1 ? requestAnimationFrame(schritt) : 0;\n      };\n      gleitet = requestAnimationFrame(schritt);\n    }\n    function zoomUm(f, sx, sy) {\n      const k = Math.max(5, Math.min(400, ansicht.k * f));\n      const wx = (sx - ansicht.tx) / ansicht.k, wy = (sy - ansicht.ty) / ansicht.k;\n      ansicht.k = k; ansicht.tx = sx - wx * k; ansicht.ty = sy - wy * k;\n    }\n    function welt(e) {\n      const r = svg.getBoundingClientRect();\n      return { x: (e.clientX - r.left - ansicht.tx) / ansicht.k, y: (e.clientY - r.top - ansicht.ty) / ansicht.k };\n    }\n\n    // ---------- Bedienung im Plan ----------\n    const zeiger = new Map();\n    let geste = null;\n    let kartenZug = null;        // Ziehen von der Produktkachel: { modell, karte, pointerId, sx, sy, letzt, timer, aktiv, s }\n\n    function finde(typ, id) {\n      if (typ === 'moebel') return S.moebel.find(o => o.id === id);\n      if (typ === 'melder') return S.melder.find(s => s.id === id);\n      if (typ === 'oeffnung') return S.oeffnungen.find(o => o.id === id);\n      if (typ === 'zone') return zonen().find(z => z.id === id) || null;\n      if (typ === 'grenze') { const m = S.melder.find(x => x.id === id); return m && m.grenze ? m.grenze : null; }\n      if (typ === 'ecke') return S.raum.form === 'frei' ? S.raum.punkte[id] : null;\n      if (typ === 'wand') return kanten(raumPoly())[id] || null;\n    }\n    svg.addEventListener('pointerdown', e => {\n      cancelAnimationFrame(gleitet); gleitet = 0;\n      svg.setPointerCapture(e.pointerId);\n      zeiger.set(e.pointerId, { x: e.clientX, y: e.clientY });\n      if (zeiger.size === 1) {\n        const tg = e.target.closest('[data-id]');\n        const w = welt(e);\n        if (tg && ['ecke', 'wand', 'neu'].includes(tg.dataset.typ)) {\n          let i = +tg.dataset.id;\n          if (tg.dataset.typ === 'neu') i = eckeEinfuegen(i);\n          const wand = tg.dataset.typ === 'wand';\n          auswahl = { typ: wand ? 'wand' : 'ecke', id: i };\n          reiter.raum = 'masse';\n          if (S.raum.form !== 'frei') {\n            // Rechteck und L: Wand ziehen \u00E4ndert das Ma\u00DF (wandMass), Ecke antippen w\u00E4hlt nur\n            geste = wand ? { art: 'wandmass', i, start: w, sx: e.clientX, sy: e.clientY, bewegt: false, R0: { ...S.raum }, angewandt: 0,\n              melder: wandMelderMerken(), tueren: S.oeffnungen.filter(o => { const L = oeffnungLage(o); return L && L.i === i; }) }\n              : { art: 'tippen', sx: e.clientX, sy: e.clientY, bewegt: false };\n            zeichneSheet(); planNeu(); return;\n          }\n          geste = { art: wand ? 'wand' : 'ecke', i, start: w, sx: e.clientX, sy: e.clientY, bewegt: false,\n            melder: wandMelderMerken(), p0: S.raum.punkte.map(q => q.slice()), x0: S.raum.punkte[i][0], y0: S.raum.punkte[i][1] };\n          zeichneSheet(); geaendert(false);\n        } else if (tg && (tg.dataset.typ === 'zone-griff' || tg.dataset.typ === 'zone-neu')) {\n          // Ecke einer Zone ziehen; \u201E+\u201C auf einer Kante f\u00FCgt erst eine Ecke ein und zieht sie dann\n          const z = finde('zone', tg.dataset.id); let i = +tg.dataset.ecke;\n          if (!z) return;   // SVG \u00E4lter als der Zustand (nach Vorschlag, R\u00FCckg\u00E4ngig oder w\u00E4hrend rechnen()): kein Ziel\n          if (tg.dataset.typ === 'zone-neu') {\n            const [x1, y1] = z.p[i], [x2, y2] = z.p[(i + 1) % z.p.length];\n            z.p.splice(i + 1, 0, [rund((x1 + x2) / 2), rund((y1 + y2) / 2)]); i = i + 1;\n          }\n          auswahl = { typ: 'zone', id: z.id, ecke: i }; modus = 'melder-neu'; neuKlasse = zonenKlasse();\n          geste = { art: 'zonenecke', z, i, start: w, x0: z.p[i][0], y0: z.p[i][1], p0: z.p.map(q => q.slice()), rechteck: istRechteck(z.p), sx: e.clientX, sy: e.clientY, bewegt: false };\n          zeichneSheet(); geaendert(false);\n        } else if (tg && tg.dataset.typ.endsWith('-griff')) {\n          // Ecke der Grenze: Gr\u00F6\u00DFe ziehen\n          const typ = tg.dataset.typ.replace('-griff', ''), obj = finde(typ, tg.dataset.id);\n          if (!obj) return;\n          geste = { art: 'groesse', obj, ecke: tg.dataset.ecke || 'se', start: w, x0: obj.x, y0: obj.y, w0: obj.w, h0: obj.h, sx: e.clientX, sy: e.clientY, bewegt: false };\n        } else if (tg) {\n          const typ = tg.dataset.typ, id = tg.dataset.id, obj = finde(typ, id);\n          if (!obj) return;\n          const neu = !auswahl || auswahl.id !== id;\n          auswahl = { typ, id };\n          if (typ === 'zone') { modus = 'melder-neu'; neuKlasse = zonenKlasse(); } else modus = typ;   // Zone: kein eigener Schirm (Fernando 21.10.)\n          geste = { art: 'ziehen', obj, typ, start: w, x0: obj.x, y0: obj.y, p0: typ === 'zone' ? obj.p.map(q => q.slice()) : null, sx: e.clientX, sy: e.clientY, bewegt: false };\n          if (neu) { zeichneSheet(); planNeu(); }\n        } else {\n          geste = { art: 'schieben', sx: e.clientX, sy: e.clientY, tx0: ansicht.tx, ty0: ansicht.ty, bewegt: false, w };\n        }\n      } else if (zeiger.size === 2) {\n        const [a, b] = [...zeiger.values()];\n        geste = { art: 'zoom', d0: Math.hypot(a.x - b.x, a.y - b.y), m0: { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 },\n          k0: ansicht.k, tx0: ansicht.tx, ty0: ansicht.ty };\n      }\n    });\n    svg.addEventListener('pointermove', e => {\n      if (!zeiger.has(e.pointerId)) return;\n      zeiger.set(e.pointerId, { x: e.clientX, y: e.clientY });\n      if (!geste) return;\n      const r = svg.getBoundingClientRect();\n      if (geste.art === 'zoom' && zeiger.size >= 2) {\n        const [a, b] = [...zeiger.values()];\n        const d = Math.hypot(a.x - b.x, a.y - b.y), m = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n        const k = Math.max(5, Math.min(400, geste.k0 * d / geste.d0));\n        const wx = (geste.m0.x - r.left - geste.tx0) / geste.k0, wy = (geste.m0.y - r.top - geste.ty0) / geste.k0;\n        ansicht.k = k; ansicht.tx = m.x - r.left - wx * k; ansicht.ty = m.y - r.top - wy * k;\n        planNeu();\n        return;\n      }\n      const weit = Math.hypot(e.clientX - geste.sx, e.clientY - geste.sy) > 5;\n      if (!geste.bewegt && !weit) return;\n      geste.bewegt = true;\n      if (geste.art === 'schieben') {\n        ansicht.tx = geste.tx0 + e.clientX - geste.sx; ansicht.ty = geste.ty0 + e.clientY - geste.sy;\n        planNeu();\n      } else if (geste.art === 'ecke') {\n        const w = welt(e);\n        eckeZiehen(geste.i, geste.x0 + w.x - geste.start.x, geste.y0 + w.y - geste.start.y, geste.melder);\n        geaendert(false);\n      } else if (geste.art === 'wand') {\n        wandSchieben(geste, welt(e));\n        geaendert(false);\n      } else if (geste.art === 'wandmass') {\n        wandMass(geste, welt(e));\n        geaendert(false);\n      } else if (geste.art === 'groesse') {\n        // Ecke ziehen: die gegen\u00FCberliegende Ecke bleibt stehen, mindestens 0,3 m Seite, Raster 5 cm\n        const w = welt(e), o = geste.obj, dx = raster(w.x - geste.start.x), dy = raster(w.y - geste.start.y);\n        const links = geste.ecke[1] === 'w', oben = geste.ecke[0] === 'n';\n        if (links) { const nw = Math.max(MIN_SEITE, geste.w0 - dx); o.x = rund(geste.x0 + geste.w0 - nw); o.w = rund(nw); } else o.w = Math.max(MIN_SEITE, rund(geste.w0 + dx));\n        if (oben) { const nh = Math.max(MIN_SEITE, geste.h0 - dy); o.y = rund(geste.y0 + geste.h0 - nh); o.h = rund(nh); } else o.h = Math.max(MIN_SEITE, rund(geste.h0 + dy));\n        geaendert(false);\n      } else if (geste.art === 'zonenecke') {\n        const w = welt(e), P = geste.z.p, i = geste.i;\n        const q = imRaumHalten([geste.x0 + w.x - geste.start.x, geste.y0 + w.y - geste.start.y]);\n        if (geste.rechteck) {\n          // Rechteck: mindestens MIN_SEITE zur gegen\u00FCberliegenden Ecke; der Nachbar mit gleichem x bekommt das neue x, der mit gleichem y das neue y\n          const [ox, oy] = geste.p0[(i + 2) % 4];\n          const sx = Math.sign(geste.p0[i][0] - ox) || 1, sy = Math.sign(geste.p0[i][1] - oy) || 1;\n          if ((q[0] - ox) * sx < MIN_SEITE) q[0] = rund(ox + sx * MIN_SEITE);\n          if ((q[1] - oy) * sy < MIN_SEITE) q[1] = rund(oy + sy * MIN_SEITE);\n          for (const j of [(i + 1) % 4, (i + 3) % 4]) P[j] = geste.p0[j][0] === geste.p0[i][0] ? [q[0], P[j][1]] : [P[j][0], q[1]];\n        }\n        P[i] = q;\n        geaendert(false);\n      } else if (geste.art === 'ziehen') {\n        const w = welt(e), nx = geste.x0 + w.x - geste.start.x, ny = geste.y0 + w.y - geste.start.y;\n        if (geste.typ === 'melder') einrasten(geste.obj, { x: nx, y: ny });\n        else if (geste.typ === 'oeffnung') oeffnungSetzen(geste.obj, { x: nx, y: ny });\n        else if (geste.typ === 'zone') {\n          // alle Ecken mitnehmen, aber nur so weit, dass keine die H\u00FClle des Raums verl\u00E4sst\n          const H = huelle(), P = huelle(geste.p0);\n          const dx = Math.min(H.x1 - P.x1, Math.max(H.x0 - P.x0, rund(w.x - geste.start.x))), dy = Math.min(H.y1 - P.y1, Math.max(H.y0 - P.y0, rund(w.y - geste.start.y)));\n          geste.obj.p = geste.p0.map(([x, y]) => [rund(x + dx), rund(y + dy)]);\n        }\n        else { geste.obj.x = raster(nx); geste.obj.y = raster(ny); }\n        geaendert(false);\n      }\n    });\n    function zeigerEnde(e) {\n      if (!zeiger.has(e.pointerId)) return;\n      zeiger.delete(e.pointerId);\n      if (geste && geste.art === 'schieben' && !geste.bewegt && e.type === 'pointerup') {\n        // Tippen ins Leere: Auswahl aufheben, in den Hinweisen die Markierung\n        if (modus === 'hinweise') markiert = null;\n        else if (auswahl) abwaehlen(finde(auswahl.typ, auswahl.id));\n        zeichneSheet(); geaendert(false);\n      }\n      if (geste && ['ziehen', 'ecke', 'wand', 'wandmass', 'groesse', 'zonenecke'].includes(geste.art) && (geste.bewegt || geste.art === 'zonenecke')) { zeichneSheet(); if (!zeiger.size) merken(); }\n      // Antippen ohne Ziehen: der Reiter entstand beim Aufsetzen, ohne Vorschl\u00E4ge (die rechnen erst ohne Finger)\n      else if (!zeiger.size && infoOhneVorschlag) infoNeu();\n      if (geste && (geste.art === 'zoom' || (geste.art === 'schieben' && geste.bewegt))) angepasst = false;\n      geste = zeiger.size === 1 ? null : (zeiger.size === 0 ? null : geste);\n      if (!zeiger.size && nachpassen && angepasst) gleiten();\n    }\n    svg.addEventListener('pointerup', zeigerEnde);\n    svg.addEventListener('pointercancel', zeigerEnde);\n\n    // ---------- Ziehen von der Produktkachel in den Plan (Fernando 22.10.) ----------\n    // Maus: nach 5 px Bewegung h\u00E4ngt der Melder am Zeiger. Finger: erst kurz halten (300 ms), sonst scrollt die Liste;\n    // nach dem Halten unterbindet touchmove das Scrollen. Der Melder liegt ab dem Start in S und rastet wie beim Ziehen\n    // im Plan. Loslassen \u00FCber dem Plan setzt ihn, sonst verschwindet er wieder. Antippen setzt ihn weiter an die erste Wand.\n    let zugKlickSperre = false;  // der Klick nach dem Loslassen darf keinen zweiten Melder anlegen\n    function zugStart() {\n      const z = kartenZug; if (!z || z.aktiv) return;\n      z.aktiv = true; z.karte.classList.add('wahl--hebt');\n      const M = MODELLE[z.modell], s = neuerMelder(z.modell, M); delete s.montage;\n      z.s = s; S.melder.push(s); auswahl = { typ: 'melder', id: s.id };\n      einrasten(s, welt(z.letzt)); planNeu();\n    }\n    function zugEnde(e, setzen) {\n      const z = kartenZug; if (!z) return;\n      clearTimeout(z.timer); kartenZug = null; z.karte.classList.remove('wahl--hebt');\n      try { z.karte.releasePointerCapture(z.pointerId); } catch (x) { /* schon weg */ }\n      if (!z.aktiv) return;\n      zugKlickSperre = true; setTimeout(() => { zugKlickSperre = false; }, 400);\n      const r = svg.getBoundingClientRect();\n      const imPlan = e && e.clientX >= r.left && e.clientX <= r.right && e.clientY >= r.top && e.clientY <= r.bottom;\n      if (setzen && imPlan && S.melder.includes(z.s)) { neuGesetzt = z.s.id; modus = 'melder'; reiter.melder = 'montage'; geaendert(); merken(); }\n      else { S.melder = S.melder.filter(s => s !== z.s); if (auswahl && auswahl.id === z.s.id) auswahl = null; geaendert(false); }\n    }\n    sheet.addEventListener('pointerdown', e => {\n      const karte = e.target.closest('[data-modell]');\n      if (!karte || kartenZug || e.button) return;\n      kartenZug = { modell: karte.dataset.modell, karte, pointerId: e.pointerId, sx: e.clientX, sy: e.clientY, letzt: e, timer: 0, aktiv: false, s: null };\n      try { karte.setPointerCapture(e.pointerId); } catch (x) { /* egal */ }\n      if (e.pointerType !== 'mouse') kartenZug.timer = setTimeout(zugStart, 300);\n    });\n    sheet.addEventListener('pointermove', e => {\n      const z = kartenZug; if (!z || e.pointerId !== z.pointerId) return;\n      z.letzt = e;\n      if (!z.aktiv) {\n        if (Math.hypot(e.clientX - z.sx, e.clientY - z.sy) > 5) { if (e.pointerType === 'mouse') zugStart(); else zugEnde(e, false); }\n        return;\n      }\n      einrasten(z.s, welt(e)); planNeu();\n    });\n    sheet.addEventListener('pointerup', e => { if (kartenZug && e.pointerId === kartenZug.pointerId) zugEnde(e, true); });\n    sheet.addEventListener('pointercancel', e => { if (kartenZug && e.pointerId === kartenZug.pointerId) zugEnde(e, false); });\n    sheet.addEventListener('touchmove', e => { if (kartenZug && kartenZug.aktiv) e.preventDefault(); }, { passive: false });\n    sheet.addEventListener('contextmenu', e => { if (kartenZug) e.preventDefault(); });\n    svg.addEventListener('wheel', e => {\n      e.preventDefault();\n      const r = svg.getBoundingClientRect();\n      cancelAnimationFrame(gleitet); gleitet = 0;\n      zoomUm(Math.exp(-e.deltaY * 0.0015), e.clientX - r.left, e.clientY - r.top);\n      angepasst = false;\n      planNeu();\n    }, { passive: false });\n    $('#zoom').addEventListener('click', e => {\n      const b = e.target.closest('button'); if (!b) return;\n      const r = svg.getBoundingClientRect();\n      if (b.dataset.zoom === 'fit') einpassen();\n      else { zoomUm(b.dataset.zoom === 'in' ? 1.3 : 1 / 1.3, r.width / 2, r.height / 2); angepasst = false; }\n      planNeu();\n    });\n\n    // ---------- Aktualisieren ----------\n    let rafPlan = 0, rafInfo = 0, speichernT = 0;\n    function planNeu() { if (!rafPlan) rafPlan = requestAnimationFrame(() => { rafPlan = 0; zeichne(); }); }\n    function infoNeu() { if (!rafInfo) rafInfo = requestAnimationFrame(() => { rafInfo = 0; zeichneInfo(); }); }\n    function geaendert(sheetAuch = true) {\n      planNeu();\n      if (sheetAuch) zeichneSheet(); else infoNeu();\n      clearTimeout(speichernT);\n      speichernT = setTimeout(speichern, 300);\n    }\n    // Zustand steht base64 in der Adresse hinter #, damit ein Link den Raum mitnimmt. Pfad ausdr\u00FCcklich\n    // mitgeben: Das Theme setzt <base href>, ein blo\u00DFes '#\u2026' landete sonst auf der Startseite.\n    function speichern() {\n      if (!zeiger.size) merken();\n      try { history.replaceState(history.state, '', location.pathname + location.search + '#' + btoa(unescape(encodeURIComponent(JSON.stringify({ v: 1, ...S }))))); } catch (e) { /* egal */ }\n    }\n    function laden() {\n      try {\n        if (location.hash.length > 1) {\n          S = pruefen(JSON.parse(decodeURIComponent(escape(atob(location.hash.slice(1))))));\n          if (S.raum.punkte) ausrichten(S.raum.punkte);\n          return;\n        }\n      } catch (e) { ladeFehler = true; }   // kaputter Link: leerer Raum, und das Feld sagt es (sonst \u00FCberschreibt speichern() den Link still)\n      S = leer();   // Start mit dem leeren 4 \u00D7 5 m Raum (Fernando 22.10.), die Beispiele liegen im Men\u00FC\n    }\n    let ladeFehler = false;\n\n    // ---------- R\u00FCckg\u00E4ngig ----------\n    // Jeder gespeicherte Stand kommt in den Verlauf; w\u00E4hrend ein Finger zieht nicht, erst beim Loslassen.\n    let verlauf = [], pos = -1;\n    function merken() {\n      const j = JSON.stringify(S);\n      if (j === verlauf[pos]) return;\n      verlauf = verlauf.slice(0, pos + 1);\n      verlauf.push(j);\n      if (verlauf.length > 100) verlauf.shift();\n      pos = verlauf.length - 1;\n      verlaufKnoepfe();\n      messSchritt();\n    }\n    function verlaufKnoepfe() {\n      $('#rueckgaengig').disabled = pos <= 0;\n      $('#wiederholen').disabled = pos >= verlauf.length - 1;\n    }\n    function springen(d) {\n      const p = pos + d;\n      if (p < 0 || p >= verlauf.length) return;\n      if (d < 0) mess.rueckgaengig++;\n      pos = p; S = JSON.parse(verlauf[pos]);\n      beste = null; vorschlagErg = null; memoLeeren();   // hielten Melder-Objekte des alten Zustands (Pr\u00FCfung 21.10.: \u201E@ \u00B7 Basis\u201C)\n      verlaufKnoepfe();\n      clearTimeout(speichernT); speichern();\n      zeichneSheet(); planNeu();\n      if ($('#blatt').open) zeichneBlatt();\n    }\n    // Aktionsleiste unten auf dem Plan (IKEA-Planer, Fernando 16.10.): was man mit dem angetippten Teil tun\n    // kann. Ohne Auswahl: alle T\u00FCren und Fenster auf/zu und, wenn es welche gibt, die Hinweise.\n    // Die Kn\u00F6pfe l\u00F6sen dieselben data-akt aus wie fr\u00FCher die Kn\u00F6pfe in den Reitern (klick()).\n    const SYM = d => `<svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${d}</svg>`;\n    // Zeichen vor den W\u00F6rtern in Segmenten und auf Karten (Fernando 22.10.: schneller als der Satz)\n    const WORT_SYM = {\n      rechteck: SYM('<rect x=\"3\" y=\"4\" width=\"14\" height=\"12\"/>'),\n      L: SYM('<path d=\"M3 3h8v7h6v7H3z\"/>'),\n      frei: SYM('<path d=\"M3 5l6-2 8 4-2 9H4z\"/>'),\n      mauer: SYM('<path d=\"M2 10h16\" stroke-width=\"3.5\"/>'),\n      glas: SYM('<path d=\"M2 10h16\" stroke-dasharray=\"3 2.5\"/>'),\n      wand: SYM('<path d=\"M3 3v14\"/><circle cx=\"5\" cy=\"10\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M6 10l10-5M6 10l10 5\" stroke-dasharray=\"2 2\"/>'),\n      decke: SYM('<path d=\"M3 3h14\"/><circle cx=\"10\" cy=\"5\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M10 6l-6 11M10 6l6 11\" stroke-dasharray=\"2 2\"/>'),\n      tuer: SYM('<path d=\"M4 17V3h8\"/><path d=\"M12 3a8 8 0 0 1-8 8\" stroke-dasharray=\"2 2\"/>'),\n      durchgang: SYM('<path d=\"M3 17V3h4M17 17V3h-4\"/>'),\n      fenster: SYM('<rect x=\"3\" y=\"5\" width=\"14\" height=\"10\"/><path d=\"M10 5v10M3 10h14\"/>'),\n      saeule: SYM('<rect x=\"6\" y=\"6\" width=\"8\" height=\"8\"/>'),\n      plus: SYM('<path d=\"M10 4v12M4 10h12\"/>'),\n      // M\u00F6bel, Ansicht von vorn (Fernando 22.10.)\n      sofa: SYM('<path d=\"M3 11V9a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v2M3 11h14v4H3zM4 15v2M16 15v2\"/>'),\n      sessel: SYM('<path d=\"M5 11V9a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v2M5 11h10v4H5zM6 15v2M14 15v2\"/>'),\n      stuhl: SYM('<path d=\"M6 3v8h8V3M6 11v6M14 11v6M6 8h8\"/>'),\n      esstisch: SYM('<path d=\"M3 7h14M5 7v9M15 7v9\"/>'),\n      bett: SYM('<path d=\"M3 15V9h14v6M3 11h14M5 9V6h10v3M3 15v2M17 15v2\"/>'),\n      schreibtisch: SYM('<path d=\"M3 7h14M4 7v9M16 7v9M11 7v9M11 11h5\"/>'),\n      kueche: SYM('<path d=\"M3 8h14v8H3zM7 8v8M12 8v8M3 12h4\"/><circle cx=\"14.5\" cy=\"12\" r=\"1\"/>'),\n      dusche: SYM('<path d=\"M10 3v3M6 8a4 4 0 0 1 8 0M6 8h8M7 11v2M10 11v3M13 11v2\"/>'),\n      wc: SYM('<path d=\"M6 3h8v6H6zM5 9h10v3a5 5 0 0 1-10 0z\"/>'),\n      badewanne: SYM('<path d=\"M3 10h14v3a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4zM5 10V5a2 2 0 0 1 4 0\"/>'),\n      kommode: SYM('<path d=\"M3 6h14v9H3zM3 10.5h14M9 8h2M9 12.5h2\"/>'),\n      schrank: SYM('<path d=\"M4 3h12v14H4zM10 3v14M8 9v2M12 9v2\"/>'),\n      fernseher: SYM('<rect x=\"3\" y=\"4\" width=\"14\" height=\"9\"/><path d=\"M10 13v3M7 16h6\"/>'),\n    };\n    const mitSym = (k, tx) => (WORT_SYM[k] || '') + tx;\n    const AKT_SYM = {\n      kopie: SYM('<rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" rx=\"1.5\"/><path d=\"M13 4H4.5A1.5 1.5 0 0 0 3 5.5V13\"/>'),\n      drehen: SYM('<path d=\"M4 10a6 6 0 1 0 2-4.5M4 3v3h3\"/>'),\n      links: SYM('<path d=\"M4 10a6 6 0 1 0 2-4.5M4 3v3h3\"/>'),\n      rechts: SYM('<path d=\"M16 10a6 6 0 1 1-2-4.5M16 3v3h-3\"/>'),\n      loeschen: SYM('<path d=\"M4 6h12M8 6V4h4v2M6 6l1 11h6l1-11\"/>'),\n      info: SYM('<circle cx=\"10\" cy=\"10\" r=\"7\"/><path d=\"M10 9v5M10 6.5v.01\"/>'),\n      seite: SYM('<path d=\"M4 7h11l-3-3M16 13H5l3 3\"/>'),\n      auf: SYM('<path d=\"M3 17h14M6 17V9M6 9l5 2.5V17\"/><path d=\"M14 8V3M11.5 5.5L14 3l2.5 2.5\"/>'),\n      hinweise: SYM('<path d=\"M10 3l8 14H2zM10 8v4M10 14.5v.01\"/>'),\n      hierhin: SYM('<circle cx=\"10\" cy=\"8\" r=\"2.5\"/><path d=\"M10 18s-6-5.2-6-10a6 6 0 0 1 12 0c0 4.8-6 10-6 10z\"/>'),\n      alle_zu: '<svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\"><path d=\"M5 18V2h10v16M3 18h14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/><circle cx=\"12\" cy=\"10\" r=\"1.2\" fill=\"currentColor\"/></svg>',\n      alle_auf: '<svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\"><path d=\"M5 18V2h10v16M3 18h14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-dasharray=\"2 2\"/><path d=\"M5 18V2l6 2.5v15z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\"/></svg>',\n    };\n    // Alle T\u00FCren und Fenster auf einmal \u00F6ffnen oder schlie\u00DFen (Durchg\u00E4nge sind immer offen)\n    const schaltbar = () => S.oeffnungen.filter(o => o.art !== 'durchgang');\n    let nHinweiseZuletzt = 0;                      // Aufrufe ohne Zahl (Ma\u00DFe, Zone, Hinweis antippen) behalten den Stand\n    // Knopfzeile zum gew\u00E4hlten Teil, im Feld direkt unter dem Titel (Fernando 22.10.: unter dem Plan nur die Ansicht,\n    // rechts alles zum gew\u00E4hlten Teil; vorher lag das als Aktionsleiste unter dem Plan und die Drehung doppelt)\n    function teilAktionen() {\n      const sel = auswahl ? finde(auswahl.typ, auswahl.id) : null;\n      const knopf = (akt, text, sym, klasse = 'btn--quiet', extra = '') => `<button class=\"btn ${klasse}\" data-akt=\"${akt}\" ${extra}>${sym}<span>${text}</span></button>`;\n      let h = '';\n      if (sel && auswahl.typ === 'moebel') {\n        h = knopf('kopie', t('kopie'), AKT_SYM.kopie) + knopf('drehen', t('drehen'), AKT_SYM.drehen, 'btn--quiet', sel.rund ? 'disabled' : '') +\n          knopf('loeschen', t('loeschen'), AKT_SYM.loeschen, 'btn--danger');\n      } else if (sel && auswahl.typ === 'melder') {\n        const M = MODELLE[sel.modell], vs = markierterVorschlag();\n        h = (vs ? knopf('vorschlag', vorschlagText(vs), AKT_SYM.hierhin, 'btn--primary') : '') +\n          knopf('kopie', t('kopie'), AKT_SYM.kopie) + knopf('loeschen', t('loeschen'), AKT_SYM.loeschen, 'btn--danger') +   // Drehen: Reiter \u201EMontage\u201C\n          (M.url ? `<a class=\"btn btn--quiet\" href=\"${esc(M.url)}\" target=\"_blank\" rel=\"noopener\">${AKT_SYM.info}<span>${t('produktseite')}</span></a>` : '');\n      } else if (sel && auswahl.typ === 'oeffnung') {\n        if (sel.art === 'tuer') h += knopf('seite', t('anschlag'), AKT_SYM.seite) + knopf('auf', t(aufText(sel)), AKT_SYM.auf);\n        h += knopf('loeschen', t('loeschen'), AKT_SYM.loeschen, 'btn--danger');\n      } else if (sel && (auswahl.typ === 'zone' || auswahl.typ === 'grenze')) {\n        h = (auswahl.typ === 'zone' && auswahl.ecke != null && sel.p.length > 3 ? knopf('zone_ecke_weg', t('ecke_entfernen'), AKT_SYM.loeschen) : '') +\n          knopf('loeschen', t('loeschen'), AKT_SYM.loeschen, 'btn--danger');\n      } else if (auswahl && auswahl.typ === 'ecke' && S.raum.form === 'frei') {\n        h = knopf('eckeweg', t('ecke_entfernen'), AKT_SYM.loeschen, 'btn--danger', S.raum.punkte.length <= 3 ? 'disabled' : '');\n      }\n      return h ? `<div class=\"teil-aktionen\">${h}</div>` : '';\n    }\n    // Alle T\u00FCren und Fenster auf einmal: Knopf in der Raum-Ansicht, Reiter \u201ET\u00FCren, Fenster, S\u00E4ulen\u201C (Raumeigenschaft)\n    function alleTuerenKnopf() {\n      const l = schaltbar(), auf = l.length > 0 && l.every(o => o.zustand === 'offen');\n      return `<div class=\"teil-aktionen\"><button class=\"btn btn--quiet\" data-akt=\"alleoffen\" aria-pressed=\"${auf}\" ${l.length ? '' : 'disabled'}>${auf ? AKT_SYM.alle_auf : AKT_SYM.alle_zu}<span>${t(auf ? 'alle_schliessen' : 'alle_oeffnen')}</span></button></div>`;\n    }\n    // Werkzeugspalte im Plan: nur Ansicht (Zoom, Ma\u00DFe)\n    function aktionenNeu(nHinweise = nHinweiseZuletzt) {\n      nHinweiseZuletzt = nHinweise;\n      const mk = $('#masse-knopf');\n      mk.setAttribute('aria-pressed', masseAn);\n      mk.title = t(masseAn ? 'masse_aus' : 'masse_an'); mk.setAttribute('aria-label', mk.title);\n    }\n    // Wandma\u00DFe ein- oder ausblenden; nur Ansicht, kommt nicht in den Verlauf und nicht in den Link\n    let masseAn = true;\n    $('#verlauf').addEventListener('click', e => {\n      const b = e.target.closest('button'); if (!b) return;\n      springen(b.id === 'rueckgaengig' ? -1 : 1);\n    });\n    // Auswahl aufheben (Tippen ins Leere, Pfeil \u201E\u2039\u201C, L\u00F6schen). T\u00FCr, Fenster und S\u00E4ule geh\u00F6ren zu \u201ERaum\u201C: dorthin zur\u00FCck\n    // mit dem Reiter \u201ET\u00FCren, Fenster, S\u00E4ulen\u201C (Fernando 21.10.: sonst zwei Tipps bis zur n\u00E4chsten T\u00FCr). M\u00F6bel und Melder\n    // zur Startansicht, Ecke und Wand bleiben in \u201ERaum\u201C, au\u00DFer \u00FCber den Pfeil (zurueck).\n    function abwaehlen(sel, zurueck = false) {\n      // Zone: zur\u00FCck zur Zonenansicht (\u201EMelder hinzuf\u00FCgen\u201C, Aufgabe Zonen); Grenze: zur\u00FCck zum Melder, Reiter \u201EZonen\u201C\n      if (auswahl && auswahl.typ === 'zone') { auswahl = null; modus = 'melder-neu'; neuKlasse = zonenKlasse(); neuGesetzt = null; return; }\n      if (auswahl && auswahl.typ === 'grenze') {\n        const s = finde('melder', auswahl.id);\n        auswahl = s ? { typ: 'melder', id: s.id } : null; modus = auswahl ? 'melder' : 'start'; reiter.melder = 'zonen'; neuGesetzt = null;\n        return;\n      }\n      const bauteil = auswahl && (auswahl.typ === 'oeffnung' || (auswahl.typ === 'moebel' && sel && istBauteil(sel)));\n      if (bauteil) { modus = 'raum'; reiter.raum = 'oeffnungen'; }\n      else if (zurueck || !auswahl || (auswahl.typ !== 'ecke' && auswahl.typ !== 'wand')) modus = 'start';\n      auswahl = null; neuGesetzt = null;\n    }\n    function auswahlLoeschen(sel) {\n      if (auswahl.typ === 'moebel') { S.moebel = S.moebel.filter(o => o !== sel); mess.moebelWeg++; }\n      else if (auswahl.typ === 'oeffnung') S.oeffnungen = S.oeffnungen.filter(o => o !== sel);\n      else if (auswahl.typ === 'zone') S.zonen = zonen().filter(z => z !== sel);\n      else if (auswahl.typ === 'grenze') { const s = finde('melder', auswahl.id); if (s) delete s.grenze; }\n      else S.melder = S.melder.filter(s => s !== sel);\n      abwaehlen(sel);\n    }\n    // Strg+Z / Strg+Y; Entf/R\u00FCcktaste l\u00F6scht, was gew\u00E4hlt ist (Fernando 20.10., am Desktop gewohnt). Das Ereignis kommt\n    // am document an; was wirklich den Fokus hat, sagt composedPath.\n    let signal = null;   // AbortController der globalen Listener (host.verbinden / host.trennen)\n    function globaleListener() {\n      const ab = new AbortController(); signal = ab.signal;\n      host.trennen = () => ab.abort();\n      document.addEventListener('keydown', tastatur, { signal });\n      let breiteZuletzt = window.innerWidth;\n      // Nur bei Breiten\u00E4nderung neu einpassen: die Bildschirmtastatur am Handy \u00E4ndert nur die H\u00F6he, der Raum soll nicht springen\n      window.addEventListener('resize', () => { hoeheSetzen(); if (angepasst && window.innerWidth !== breiteZuletzt) einpassen(); breiteZuletzt = window.innerWidth; planNeu(); }, { signal });\n      BREIT.addEventListener('change', () => zeichneSheet(), { signal });\n    }\n    host.verbinden = globaleListener;\n    function tastatur(e) {\n      const ziel = e.composedPath()[0];\n      if (ziel && ziel.closest && ziel.closest('input, textarea, select, [contenteditable]')) return;\n      if ((e.key === 'Enter' || e.key === ' ') && ziel && ziel.matches && ziel.matches('[data-beste]')) { e.preventDefault(); ziel.click(); return; }\n      // Ohne Zeiger: Pfeiltasten verschieben das gew\u00E4hlte Teil um 5 cm (mit Umschalt 50 cm), Escape w\u00E4hlt ab\n      if (e.key.startsWith('Arrow') && auswahl && !$('#blatt').open && !e.ctrlKey && !e.metaKey && !e.altKey) {\n        const sel = finde(auswahl.typ, auswahl.id); if (!sel) return;\n        const d = e.shiftKey ? 0.5 : 1 / RASTER_JE_M;\n        const dx = e.key === 'ArrowLeft' ? -d : e.key === 'ArrowRight' ? d : 0, dy = e.key === 'ArrowUp' ? -d : e.key === 'ArrowDown' ? d : 0;\n        if (auswahl.typ === 'melder') einrasten(sel, { x: sel.x + dx, y: sel.y + dy });\n        else if (auswahl.typ === 'oeffnung') oeffnungSetzen(sel, { x: sel.x + dx, y: sel.y + dy });\n        else if (auswahl.typ === 'zone') sel.p = sel.p.map(([x, y]) => imRaumHalten([x + dx, y + dy]));\n        else if (auswahl.typ === 'moebel') { sel.x = raster(sel.x + dx); sel.y = raster(sel.y + dy); }\n        else return;\n        e.preventDefault(); geaendert(false); return;\n      }\n      if (e.key === 'Escape' && auswahl && !$('#blatt').open) { abwaehlen(finde(auswahl.typ, auswahl.id)); zeichneSheet(); planNeu(); return; }\n      if ((e.key === 'Delete' || e.key === 'Backspace') && !e.ctrlKey && !e.metaKey && !e.altKey && auswahl && !$('#blatt').open) {\n        const sel = finde(auswahl.typ, auswahl.id);\n        if (auswahl.typ === 'ecke') { if (S.raum.form === 'frei' && eckeLoeschen(auswahl.id)) auswahl = null; else return; }\n        else if (sel && ['moebel', 'melder', 'oeffnung', 'zone', 'grenze'].includes(auswahl.typ)) auswahlLoeschen(sel);\n        else return;\n        e.preventDefault(); geaendert(); return;\n      }\n      if (!(e.ctrlKey || e.metaKey)) return;\n      const k = e.key.toLowerCase();\n      if (k === 'z' && !e.shiftKey) { e.preventDefault(); springen(-1); }\n      else if (k === 'y' || (k === 'z' && e.shiftKey)) { e.preventDefault(); springen(1); }\n    }\n\n    // ---------- Unteres Feld ----------\n    // Aufbau wie im IKEA-Planer (Fernando 16.10.): Startansicht mit den Bereichen Raum, + M\u00F6bel, + Melder.\n    // Ein Bereich oder ein gew\u00E4hltes Teil zeigt Zur\u00FCck, Reiter und genau einen Reiterinhalt; so bleibt\n    // das Feld niedrig und der Plan gro\u00DF. Selteneres im Men\u00FC, Auswahl mit Summe oben rechts.\n    const BREIT = matchMedia('(min-width: 900px)');\n    let feldOrt = '';\n    const reiter = { raum: 'form', moebel: 'masse', melder: 'modell', oeffnung: 'art' };\n    const r_ = (...k) => k.map(x => [x, t('reiter_' + x)]);\n    function reiterListe() {\n      if (modus === 'raum') return r_('form', 'masse', 'oeffnungen', ...(S.raum.form === 'L' ? ['aussparung'] : []));\n      if (modus === 'oeffnung') {\n        const o = auswahl && finde('oeffnung', auswahl.id);\n        return r_('art', 'breite', ...(o && o.art === 'fenster' ? ['fenster'] : []));\n      }\n      if (modus === 'moebel') return [['masse', t('reiter_masse')], ['entfernung', t('reiter_erfasst')]];\n      if (modus === 'melder') {\n        const s = auswahl && finde('melder', auswahl.id);\n        // Reiter \u201EReichweite\u201C (Schieber f\u00FCr die maximale Entfernung) vorerst aus (Fernando 22.10.); Code bleibt, Schalter hier\n        return [...r_('modell', 'montage', ...(REICHWEITE_OPTION ? ['reichweite'] : []), ...(s && hatZonen(s) ? ['zonen'] : [])), ['sieht', t('hinweise_titel')]];\n      }\n      return [];\n    }\n    // Kopf einer Ansicht: \u201E\u2039 Zur\u00FCck\u201C zur vorigen Ansicht (Fernando 22.10.: statt Brotkrumen oder Zielwort), darunter die\n    // Zeile \u201EMelder bearbeiten\u201C und der Titel. akt ist die Aktion des Pfeils: 'zurueck' w\u00E4hlt ab (\u00DCbersicht, bei T\u00FCren und\n    // S\u00E4ulen der Raum, bei der Grenze der Melder), 'klasse_zurueck' geht von der Aufgabe zur\u00FCck zu \u201EMelder hinzuf\u00FCgen\u201C.\n    const kopf = (titel, zeile = '', akt = 'zurueck') =>\n      `<p class=\"rueck-zeile\"><button class=\"page-back\" data-akt=\"${akt}\" aria-label=\"${esc(t('zurueck'))}\"><span class=\"back-wort\">${esc(t('zurueck'))}</span></button></p>` +\n      (zeile ? `<p class=\"schritt-zeile\">${zeile}</p>` : '') + `<h2>${titel}</h2>`;\n    let neuGesetzt = null;                           // id des gerade gesetzten Teils: Kopf sagt \u201ENeu gesetzt\u201C bis zum Abw\u00E4hlen\n    const bearbeitenZeile = (sel, k) => neuGesetzt && sel && sel.id === neuGesetzt ? t('neu_gesetzt') : t(k);\n    let neuKlasse = null;                            // \u201EMelder hinzuf\u00FCgen\u201C: Antwort auf die Frage, was der Melder tun soll\n    let rueckInAufgabe = false;                          // \u201EZur\u00FCck\u201C in der Raum-Ansicht f\u00FChrt in die Aufgabe (nach \u201E\u00E4ndern\u201C an der Raumh\u00F6he)\n    let mitRaumklima = true;                         // H\u00E4kchen beim Vorschlag: der erste Melder misst auch das Raumklima (Fernando 22.10.)\n    // Reihenfolge der Frage \u201EWas m\u00F6chten Sie tun?\u201C: selbst ausw\u00E4hlen zuerst (Fernando 22.10.). 'beides' (Zonen und ganzer Raum)\n    // ist kein eigener Punkt mehr, sondern ein H\u00E4kchen in der Zonen-Ansicht; 'alle': ohne Assistent, selbst setzen (21.10.)\n    const KLASSEN = ['alle', 'raum', 'zonen'];\n    // Klassen, in denen Zonen gezeichnet werden; beim Antippen einer Zone bleibt 'beides' erhalten\n    const zonenModus = k => k === 'zonen' || k === 'beides';\n    const zonenKlasse = () => zonenModus(neuKlasse) ? neuKlasse : 'zonen';\n    const reiterLeiste = (liste, akt) => `<div class=\"nav\" role=\"tablist\">${liste.map(([k, tx]) =>\n      `<button role=\"tab\" id=\"reiter-${k}\" aria-controls=\"reiterinhalt\" data-reiter=\"${k}\" aria-selected=\"${k === akt}\">${tx}</button>`).join('')}</div>`;\n    function segment(feld, wert, optionen, aus = false) {\n      return `<div class=\"segment\">${optionen.map(([v, tx]) =>\n        `<button data-seg=\"${feld}\" data-wert=\"${v}\" class=\"${v === wert ? 'an' : ''}\" aria-pressed=\"${v === wert}\" ${aus ? 'disabled' : ''}>${tx}</button>`).join('')}</div>`;\n    }\n    function feldZahl(feld, label, wert, aus = false) {\n      // Einheit am Feld und eine Fehlerzeile je Feld: ein Wert au\u00DFerhalb wird nicht \u00FCbernommen, das soll man sehen\n      return `<label class=\"field\"><span class=\"field__label\">${label}</span><span class=\"input-mit-einheit\"><input class=\"input\" type=\"number\" inputmode=\"decimal\" step=\"0.05\" min=\"0.05\" ${DECKEL[feld] ? `max=\"${DECKEL[feld]}\"` : ''} data-feld=\"${feld}\" value=\"${wert}\" ${aus ? 'disabled' : ''}><span class=\"input-unit\">m</span></span><span class=\"field__error\" data-fehler=\"${feld}\"></span></label>`;\n    }\n    function melderName(s) { const i = S.melder.indexOf(s); return `${buchstabe(i)} \u00B7 ${MODELLE[s.modell].name}`; }\n    function punkt(i) { return EINFARBIG ? '' : `<span class=\"punkt\" style=\"background:${farbe(i)}\"></span>`; }\n    // Meldung mit Wort vorneweg (Bausteine der Ger\u00E4teoberfl\u00E4che), Zustand nie nur \u00FCber Farbe\n    const hinweisKnopf = n => `<button class=\"tipp hinweis-knopf\" data-akt=\"hinweise\">${INFO()}` +\n      `<p>${n === 1 ? t('hinweise_knopf_eins') : t('hinweise_knopf_mehr', { n })}</p></button>`;\n    const meldung = (art, wort, text) => `<div class=\"notice notice--${art}\"><span class=\"notice__label\">${wort}</span><p>${text}</p></div>`;\n    const preisText = M => M.preis != null ? geld(M.preis) : '';\n\n    // Bereiche der Startansicht: Schl\u00FCssel, Text auf dem Handy (Chip), Text auf dem Desktop (Liste), Symbol\n    const ICON = d => `<svg class=\"icon\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linejoin=\"round\">${d}</svg>`;\n    // T\u00FCren und Fenster nur unter \u201ERaum\u201C (Reiter \u201ET\u00FCren, Fenster\u201C), kein eigener Eintrag mehr (Fernando 20.10.)\n    // Schemazeichnungen zur Frage \u201EWas m\u00F6chten Sie tun?\u201C (Fernando 22.10.): Grundriss mit dem, was die Aufgabe ausmacht.\n    // Keine Produktfotos, das Modell kommt erst danach.\n    const SCHEMA_SVG = d => `<svg viewBox=\"0 0 48 48\" width=\"48\" height=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linejoin=\"round\" aria-hidden=\"true\">${d}</svg>`;\n    const SCHEMA = {\n      // selbst ausw\u00E4hlen: Melder an der Wand mit kleinem F\u00E4cher, Zeiger daran\n      alle: SCHEMA_SVG('<rect x=\"6\" y=\"8\" width=\"36\" height=\"32\" rx=\"1\"/><path d=\"M7 24L21 13a18 18 0 0 1 0 22z\" fill=\"currentColor\" fill-opacity=\".16\" stroke=\"none\"/>' +\n        '<circle cx=\"7\" cy=\"24\" r=\"2.4\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M26 20l11 6.5-4.5 1.2 3.2 5.3-2.2 1.3-3.2-5.3-3.3 3.3z\" fill=\"currentColor\" stroke=\"none\"/>'),\n      // Pr\u00E4senz im Raum: ein Melder in der Ecke, der F\u00E4cher f\u00FCllt den Raum\n      raum: SCHEMA_SVG('<rect x=\"6\" y=\"8\" width=\"36\" height=\"32\" rx=\"1\"/><path d=\"M8 38V12a26 26 0 0 1 26 26z\" fill=\"currentColor\" fill-opacity=\".16\" stroke=\"none\"/>' +\n        '<path d=\"M8 38V12a26 26 0 0 1 26 26\" stroke-dasharray=\"2 2\"/><circle cx=\"8\" cy=\"38\" r=\"2.4\" fill=\"currentColor\" stroke=\"none\"/>'),\n      // Zonen unterscheiden: zwei markierte Fl\u00E4chen, der Melder an der Wand blickt auf beide\n      zonen: SCHEMA_SVG('<rect x=\"6\" y=\"8\" width=\"36\" height=\"32\" rx=\"1\"/><rect x=\"10\" y=\"22\" width=\"12\" height=\"12\" rx=\"2\" fill=\"currentColor\" fill-opacity=\".28\" stroke-dasharray=\"2 2\"/>' +\n        '<rect x=\"27\" y=\"17\" width=\"11\" height=\"17\" rx=\"2\" fill=\"currentColor\" fill-opacity=\".28\" stroke-dasharray=\"2 2\"/><path d=\"M24 10l-8 12M24 10l8.5 7\" stroke-dasharray=\"2 2\"/>' +\n        '<circle cx=\"24\" cy=\"9\" r=\"2.4\" fill=\"currentColor\" stroke=\"none\"/>'),\n    };\n    // Zeichen an den H\u00E4kchen: Decke mit Melder darunter (Raumklima: Thermometer KLIMA, ganzer Raum: SCHEMA.raum)\n    const DECKE_ZEICHEN = SCHEMA_SVG('<path d=\"M6 8h36\"/><circle cx=\"24\" cy=\"11\" r=\"2.4\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M24 13l-13 22a27 27 0 0 1 26 0z\" fill=\"currentColor\" fill-opacity=\".16\" stroke=\"none\"/><path d=\"M11 35a27 27 0 0 1 26 0\" stroke-dasharray=\"2 2\"/>');\n    const BEREICHE = [\n      ['raum', 'bereich_raum', 'bereich_raum', ICON('<path d=\"M3 4h18v16H3zM12 4v7h9\"/>')],\n      ['moebel-neu', 'bereich_moebel', 'moebel_hinzu', ICON('<path d=\"M4 11V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3M3 11h18v6H3zM5 17v2M19 17v2\"/>')],\n      ['melder-neu', 'bereich_melder', 'melder_hinzu', ICON('<circle cx=\"12\" cy=\"18\" r=\"2\"/><path d=\"M8.5 14.5a5 5 0 0 1 7 0M5.5 11.5a9 9 0 0 1 13 0\"/>')],\n    ];\n    function zeichneSheet() {\n      let h = '';\n      if (modus !== 'raum') rueckInAufgabe = false;        // R\u00FCcksprung gilt nur, solange die Raum-Ansicht offen ist\n      const sel = auswahl ? finde(auswahl.typ, auswahl.id) : null;\n      if (auswahl && !sel) { auswahl = null; if (modus !== 'raum') modus = 'start'; }\n      const liste = reiterListe();\n      const r = liste.some(([k]) => k === reiter[modus]) ? reiter[modus] : liste.length ? liste[0][0] : null;\n      // Desktop (Seitenleiste, Fernando 18.10.): M\u00F6bel, Melder, T\u00FCr/Fenster ohne Reiter, alle Teile untereinander.\n      // \u201ERaum\u201C beh\u00E4lt die Reiter: dort entscheidet der Reiter, was man im Plan antippen kann.\n      const breit = BREIT.matches && ['moebel', 'melder', 'oeffnung'].includes(modus);\n      const abschnitte = breit ? liste : liste.filter(([k]) => k === r);\n      const leiste = breit ? '' : reiterLeiste(liste, r);\n      const teilTitel = tx => breit ? `<h3 class=\"teil-titel\">${tx}</h3>` : '';\n\n      if (modus === 'raum') {\n        const R = S.raum, F = R.form === 'frei';\n        h += kopf(t('bereich_raum'), t('bearbeiten_raum'), rueckInAufgabe ? 'aufgabe_zurueck' : 'zurueck') + reiterLeiste(liste, r) + '<div role=\"tabpanel\" id=\"reiterinhalt\" class=\"reiter-inhalt\">';\n        if (r === 'form') {\n          h += segment('raum.form', R.form, [['rechteck', mitSym('rechteck', t('form_rechteck'))], ['L', mitSym('L', t('form_l'))], ['frei', mitSym('frei', t('form_frei'))]]);\n          h += `<p class=\"hinweis\">${F ? t('form_hinweis_frei') : t('form_hinweis')}</p>`;\n        } else if (r === 'masse') {\n          const hoehe = feldZahl('raum.hoehe', t('raumhoehe'), R.hoehe || 2.5);\n          const wandArt = () => `<p class=\"feld-titel\">${t('diese_wand')}</p>` + segment('w.art', istGlas(auswahl.id) ? 'glas' : 'mauer', [['mauer', mitSym('mauer', t('wand_mauer'))], ['glas', mitSym('glas', t('wand_glas'))]]) +\n            `<p class=\"hinweis\">${t('wand_glas_hinweis')}</p>`;\n          if (F && auswahl && auswahl.typ === 'wand') {\n            const [x1, y1, x2, y2] = kanten(R.punkte)[auswahl.id];\n            h += `<div class=\"felder\">${feldZahl('w.laenge', t('wand_laenge'), rund(Math.hypot(x2 - x1, y2 - y1)))}${hoehe}</div>`;\n            h += `<p class=\"field__error\" id=\"raumfehler\"></p>`;\n            h += `<p class=\"hinweis\">${t('wand_laenge_hinweis')}</p>` + wandArt();\n          } else if (!F && auswahl && auswahl.typ === 'wand') {\n            h += wandArt();\n          } else if (F && auswahl && auswahl.typ === 'ecke') {\n            h += `<div class=\"felder\">${hoehe}</div><p class=\"hinweis\">${t('ecke_hinweis')}</p>` + teilAktionen();\n          } else if (F) {\n            h += `<div class=\"felder\">${hoehe}</div><p class=\"hinweis\">${t('masse_hinweis_frei')}</p>`;\n          } else {\n            h += `<div class=\"felder\">${feldZahl('raum.b', t('breite'), R.b)}${feldZahl('raum.l', t('laenge'), R.l)}${hoehe}</div>`;\n            h += `<p class=\"hinweis\">${t('masse_hinweis')}</p>`;\n          }\n        } else if (r === 'oeffnungen') {\n          h += '<ul class=\"wahl-reihe\">' + OEFFNUNG_VORLAGEN.map((v, i) =>\n            `<li><button class=\"wahl\" data-oeffnung=\"${i}\"><b>${mitSym(v.art, artName(v.art))}</b>` +\n            `<span class=\"klein\">${zahl(v.b, 2)} m</span></button></li>`).join('') +\n            // S\u00E4ulen geh\u00F6ren zum Raum, nicht zu den M\u00F6beln (Fernando 20.10.)\n            VORLAGEN.map((v, i) => istBauteil(v) ? `<li><button class=\"wahl\" data-vorlage=\"${i}\"><b>${mitSym('saeule', vorlageName(v.name))}</b>` +\n              `<span class=\"klein\">${masse(v)}</span></button></li>` : '').join('') + '</ul>';\n          h += `<p class=\"hinweis\">${t('oeffnungen_hinweis')}</p>` + alleTuerenKnopf();\n        } else {\n          h += `<div class=\"felder\">${feldZahl('raum.ab', t('breite'), R.ab)}${feldZahl('raum.at', t('tiefe'), R.at)}</div>`;\n          h += `<p class=\"feld-titel\">${t('ecke_welche')}</p>`;\n          h += segment('raum.ecke', R.ecke, ['ol', 'or', 'ul', 'ur'].map(e => [e, t('ecke_' + e)]));\n        }\n        h += '</div>';\n      } else if (modus === 'moebel-neu') {\n        h += kopf(t('moebel_hinzu')) + '<div role=\"tabpanel\" id=\"reiterinhalt\" class=\"reiter-inhalt\"><ul class=\"wahl-reihe\">';\n        h += VORLAGEN.map((v, i) => istBauteil(v) ? '' : `<li><button class=\"wahl\" data-vorlage=\"${i}\"><b>${mitSym(v.name, vorlageName(v.name))}</b>` +\n          `<span class=\"klein\">${masse(v)}${stoffKurz(v)}</span></button></li>`).join('') + '</ul>';\n        h += `<p class=\"hinweis\">${t('moebel_hinweis')}</p></div>`;\n      } else if (modus === 'melder-neu') {\n        // Frage zuerst (Fernando 21.10.): Anwesenheit im Raum (Basis, KL, KL LD) oder Bereiche unterscheiden (KL MZ).\n        // Die Klasse h\u00E4ngt am Modell, ein Raum darf beide mischen.\n        h += (neuKlasse ? kopf(t('klasse_' + (neuKlasse === 'beides' ? 'zonen' : neuKlasse)), '', 'klasse_zurueck') : kopf(t('melder_hinzu'))) + '<div role=\"tabpanel\" id=\"reiterinhalt\" class=\"reiter-inhalt reiter-inhalt--melder-neu\">';\n        if (!neuKlasse) {\n          h += `<p class=\"frage\">${t('klasse_frage')}</p><ul class=\"wahl-liste\">` + KLASSEN.map(k =>\n            `<li><button class=\"wahl wahl--schema\" data-klasse=\"${k}\"><span class=\"schema\">${SCHEMA[k] || ''}</span><span class=\"wahl-text\"><b>${t('klasse_' + k)}</b><span class=\"klein\">${t('klasse_' + k + '_hinweis', { p: MODELLE.kl_mz.personen })}</span></span></button></li>`).join('') +\n            '</ul></div>';\n        } else {\n        // Reihenfolge (Fernando 22.10.): erst die Zonen, dann die H\u00E4kchen, zuletzt \u201EMelder vorschlagen\u201C mit dem Ergebnis.\n        // Ohne Assistent (\u201Ealle\u201C): nur die Karten, keinen Vorschlag\n        const ve = vorschlagAktuell(), plaetze = zonenModus(neuKlasse) ? zonen().length > 0 : plaetzeGruppen().length > 0;\n        if (zonenModus(neuKlasse)) {\n          // Die Zonen (Fernando 21.10.: zuerst die Zonen bestimmen); der Vorschlag unten findet die Melder dazu\n          const Z = zonen(), zu = Z.length ? zonenZuordnung() : new Map();\n          h += `<p class=\"hinweis\">${t('zonen_zeichnen')}</p>`;\n          if (Z.length) h += '<ul class=\"liste liste--zonen\">' + Z.map((z, n) => {\n            const x = zu.get(z.id);   // keine M\u00F6belaufz\u00E4hlung (Fernando 22.10.: die Zone hat der Kunde selbst gezogen), leer bleibt als Hinweis\n            return `<li><button class=\"zone-knopf\" data-chip=\"zone\" data-id=\"${z.id}\" aria-pressed=\"${!!auswahl && auswahl.typ === 'zone' && auswahl.id === z.id}\"><span>${t('zone_n', { n: n + 1 })}` +\n              `<br><span class=\"klein${x ? '' : ' warn-text'}\">${x ? t('zone_melder', { melder: esc(melderName(x.s)) }) : t(S.melder.some(hatZonen) ? 'zone_ohne_melder' : 'zone_ohne_mz')}</span></span></button></li>`;\n          }).join('') + '</ul>';\n          else h += tipp(t('zonen_keine'));\n          // Beide Kn\u00F6pfe gestapelt und gleich breit (Fernando 22.10.: ungleich lange Kn\u00F6pfe nebeneinander st\u00F6rten)\n          if (auswahl && auswahl.typ === 'zone') h += teilAktionen();\n          h += `<div class=\"actions actions--tight actions--stapel\"><button class=\"btn\" data-akt=\"zone_neu\">${WORT_SYM.plus}${t('zone_hinzu')}</button>` +\n            `<button class=\"btn\" data-akt=\"zonen_aus_moebeln\" ${plaetzeGruppen().length ? '' : 'disabled'}>${t('zonen_aus_moebeln')}</button>` +\n            (Z.length ? `<button class=\"btn btn--danger\" data-akt=\"zonen_alle_weg\">${AKT_SYM.loeschen}${t('alle_zonen_loeschen')}</button>` : '') + '</div>';\n          if (Z.length) h += `<p class=\"hinweis\">${t('zone_hinweis')}</p>`;\n        }\n        if (neuKlasse !== 'alle') {\n          h += '<div class=\"optionen\">';\n          // H\u00E4kchen \u201EAuch Deckenmontage vorschlagen\u201C (Fernando 22.10.): sonst sucht der Vorschlag nur an Wand und Ecke\n          h += `<label class=\"check-row\"><input type=\"checkbox\" data-option=\"decke\" ${mitDecke ? 'checked' : ''}><span class=\"check-zeichen\">${DECKE_ZEICHEN}</span>${t('decke_option')}</label>` +\n            `<p class=\"hinweis\">${t('decke_option_hinweis', { h: zahl(S.raum.hoehe || 2.5, 2) })} <button class=\"textlink\" data-akt=\"raumhoehe\">${t('aendern')}</button></p>`;\n          // H\u00E4kchen Raumklima (Fernando 22.10.): entscheidet, ob der Basis schon der erste Melder sein darf\n          if (lieferbare().some(([, M]) => M.klima)) h += `<label class=\"check-row\"><input type=\"checkbox\" data-option=\"klima\" ${mitRaumklima ? 'checked' : ''}><span class=\"check-zeichen\">${KLIMA()}</span>${t('klima_option')}</label>`;\n          // H\u00E4kchen statt eigener Klasse (Fernando 22.10.): zus\u00E4tzlich den ganzen Raum erfassen = 'beides'\n          if (zonenModus(neuKlasse)) h += `<label class=\"check-row\"><input type=\"checkbox\" data-option=\"beides\" ${neuKlasse === 'beides' ? 'checked' : ''}><span class=\"check-zeichen\">${SCHEMA.raum}</span>${t('klasse_beides_option')}</label>` +\n            `<p class=\"hinweis\">${t('klasse_beides_hinweis')}</p>`;\n          h += '</div>';\n          h += `<div class=\"schritt\"><button class=\"btn btn--primary\" data-akt=\"vorschlag_alle\" ${plaetze ? '' : 'disabled'}>${t('vorschlag_alle_knopf')}</button>` +\n            `<p class=\"hinweis\">${neuKlasse === 'zonen' ? t('vorschlag_alle_hinweis_zonen', { m: zahl(MODELLE.kl_mz.praesenz, 0), n: MAX_ZONEN }) : neuKlasse === 'beides' ? t('vorschlag_alle_hinweis_beides', { n: MAX_ZONEN }) : t('vorschlag_alle_hinweis')}</p>${ve && ve.klasse === neuKlasse ? vorschlagAlleText(ve) + `<div class=\"actions actions--tight actions--stapel\"><button class=\"btn\" data-akt=\"selbst_setzen\">${t('weiterer_selbst')}</button></div>` : plaetze || zonenModus(neuKlasse) ? '' : tipp(t('beste_leer'))}</div>`;\n        }\n        // Mit Assistent keine Kacheln (Fernando 21.10.: Schirm \u00FCberladen; auch bei \u201EAnwesenheit im Raum\u201C erst einmal keine)\n        h += '<ul class=\"wahl-reihe wahl-reihe--breit\">';\n        for (const [key, M] of Object.entries(MODELLE)) {\n          if (!M.lieferbar || neuKlasse !== 'alle') continue;   // Kacheln nur ohne Assistent (Fernando 21.10.); sonst w\u00E4hlt der Vorschlag das Modell\n          const art = M.klasse === 'raum' ? t('melder_art_raum') : t('melder_art_zonen');\n          // Karte wie bei IKEA: Bild, Name, Werte, Preis; \u24D8 \u00F6ffnet die Produktseite (eigenes Tippziel, nicht im Knopf)\n          h += `<li class=\"karte\"><button class=\"wahl wahl--bild\" data-modell=\"${key}\">` +\n            (M.bild ? `<img src=\"${esc(M.bild)}\" alt=\"\" loading=\"lazy\" width=\"320\" height=\"240\">` : '') +\n            `<b>${M.name}</b><span class=\"klein\">${zahl(M.reichweite, M.reichweite % 1 ? 2 : 0)} m \u00B7 ${M.winkel}\u00B0</span>` +\n            `<span class=\"klein\">${art}</span><span class=\"merkmale\">${unterschied(M)}</span><span class=\"preis\">${preisText(M)}</span></button>` +\n            (M.url ? `<a class=\"karte-info\" href=\"${esc(M.url)}\" target=\"_blank\" rel=\"noopener\" aria-label=\"${esc(t('produktseite'))}\" title=\"${esc(t('produktseite'))}\">${INFO()}</a>` : '') + '</li>';\n        }\n        h += '</ul>';\n        if (neuKlasse === 'alle') h += `<p class=\"hinweis\">${t('klasse_alle_tipp')}</p>`;\n        h += '</div>';\n        }\n      } else if (modus === 'moebel' && sel) {\n        h += kopf(esc(sel.name), bearbeitenZeile(sel, istBauteil(sel) ? 'bearbeiten_oeffnung' : 'bearbeiten_moebel')) + teilAktionen();\n        h += leiste + '<div role=\"tabpanel\" id=\"reiterinhalt\" class=\"reiter-inhalt\">';\n        for (const [k, tx] of abschnitte) {\n        h += teilTitel(tx);\n        if (k === 'masse') {\n          h += segment('m.form', sel.rund ? 'rund' : 'eckig', [['eckig', t('form_eckig')], ['rund', t('form_rund')]]);\n          h += `<div class=\"felder\">${sel.rund ? feldZahl('m.w', t('durchmesser'), sel.w) : feldZahl('m.w', t('breite'), sel.w) + feldZahl('m.h', t('tiefe'), sel.h)}</div>`;\n          h += `<div class=\"felder\"><label class=\"field\"><span class=\"field__label\">${t('name')}</span><input class=\"input\" type=\"text\" data-feld=\"m.name\" maxlength=\"40\" value=\"${esc(sel.name)}\"></label></div>`;\n          // Fernseher, Sideboard: ein Wandmelder dar\u00FCber sieht dar\u00FCber hinweg (Fernando 21.10.)\n          if (stoff(sel) === 'metall' || stoff(sel) === 'hoch') h += `<label class=\"check-row\"><input type=\"checkbox\" data-feld=\"m.niedrig\" ${sel.niedrig ? 'checked' : ''}>${t('niedrig')}</label><p class=\"hinweis\">${t('niedrig_info')}</p>`;\n          h += `<p class=\"hinweis\">${t('verschieben')}</p>`;\n        } else {\n          h += '<div id=\"info\"></div>';\n        }\n        }\n        h += '</div>';\n      } else if (modus === 'melder' && sel) {\n        const M = wm(sel), i = S.melder.indexOf(sel), D = istDecke(sel);\n        h += kopf(`${punkt(i)}${melderName(sel)}`, bearbeitenZeile(sel, 'bearbeiten_melder')) + teilAktionen() + '<div id=\"warnzeile\"></div>' + leiste + '<div role=\"tabpanel\" id=\"reiterinhalt\" class=\"reiter-inhalt\">';\n        for (const [k, tx] of abschnitte) {\n        h += teilTitel(tx);\n        if (k === 'modell') {\n          h += segment('s.modell', sel.modell, Object.entries(MODELLE).filter(([mk, m]) => m.lieferbar || mk === sel.modell).map(([mk, m]) => [mk, m.name]));\n          if (!MODELLE[sel.modell].lieferbar) h += meldung('warn', t('beachten'), t('nicht_lieferbar', { name: MODELLE[sel.modell].name }));\n        } else if (k === 'montage') {\n          h += segment('s.montage', D ? 'decke' : 'wand', [['wand', mitSym('wand', t('montage_wand'))], ['decke', mitSym('decke', t('montage_decke'))]]);\n          h += `<p class=\"hinweis\">${t('montage_ziehen')}</p>`;\n          // Drehung gegen\u00FCber der Wand statt Richtung im Plan: \u201E135\u00B0\u201C hielt ein Tester f\u00FCr den \u00D6ffnungswinkel (Fernando 20.10.)\n          h += `<p class=\"feld-titel\">${t('dreh_titel')}</p><div class=\"drehen\"><button class=\"btn\" data-akt=\"links\" aria-label=\"${esc(t('nach_links'))}\" ${D ? 'disabled' : ''}>\u21BA 15\u00B0</button>` +\n            `<span class=\"wert\">${D ? t('rundum') : drehText(sel)}</span><button class=\"btn\" data-akt=\"rechts\" aria-label=\"${esc(t('nach_rechts'))}\" ${D ? 'disabled' : ''}>\u21BB 15\u00B0</button></div>`;\n          h += `<p class=\"hinweis\">${D ? t('montage_decke_hinweis', { h: zahl(S.raum.hoehe || 2.5, 2) }) : t('montage_wand_hinweis', { von: zahl(1.5, 2), bis: zahl(2, 2) })}</p>`;\n        } else if (k === 'reichweite') {\n          const st = M.stufe || 0.5;\n          h += `<label class=\"field\"><span class=\"feld-titel\">${t('max_entfernung')} <b id=\"maxwert\">${maxText(sel.max)}</b></span>` +\n            `<input type=\"range\" data-feld=\"s.max\" min=\"${st}\" max=\"${M.reichweite}\" step=\"${st}\" value=\"${sel.max}\"></label>`;\n        } else if (k === 'zonen') {\n          // Zonen, die dieser KL MZ erfasst (Zuordnung aus zonenZuordnung), dazu die Grenze; Zonen \u00E4ndert man unter \u201EMelder hinzuf\u00FCgen\u201C\n          const zu = zonenZuordnung(), meine = zonenVon(sel, zu);\n          if (meine.length) h += '<ul class=\"liste\">' + meine.map(z => {\n            return `<li><button class=\"zone-knopf\" data-chip=\"zone\" data-id=\"${z.id}\"><span>${t('zone_n', { n: zoneNr(z) })}` +\n              '</span></button></li>';\n          }).join('') + '</ul>';\n          else h += `<p class=\"hinweis\">${zonen().length ? t('zonen_keine_erfasst') : t('zonen_keine')}</p>`;\n          const ohneMelder = zonen().filter(z => !zu.get(z.id));\n          if (ohneMelder.length) h += `<p class=\"hinweis warn-text\">${t(S.melder.some(hatZonen) ? 'zonen_ohne_melder' : 'zonen_ohne_mz', { liste: ohneMelder.map(z => t('zone_n', { n: zoneNr(z) })).join(', ') })}</p>`;\n          h += `<div class=\"actions actions--tight actions--stapel\"><button class=\"btn\" data-akt=\"zonen_bearbeiten\">${t('zonen_bearbeiten')}</button>` +\n            `<button class=\"btn\" data-akt=\"${sel.grenze ? 'grenze_weg' : 'grenze_setzen'}\">${t(sel.grenze ? 'grenze_weg' : 'grenze_setzen')}</button></div>`;\n        } else {\n          h += '<div id=\"info\"></div>';\n        }\n        }\n        h += '</div>';\n      } else if (modus === 'grenze' && sel) {\n        h += kopf(t('grenze'), bearbeitenZeile(sel, 'bearbeiten_grenze')) + teilAktionen() + '<div role=\"tabpanel\" id=\"reiterinhalt\" class=\"reiter-inhalt\">';\n        h += `<p class=\"hinweis\">${t('grenze_hinweis')}</p></div>`;\n      } else if (modus === 'oeffnung' && sel) {\n        h += kopf(esc(oeffnungName(sel)), bearbeitenZeile(sel, 'bearbeiten_oeffnung')) + teilAktionen() + leiste + '<div role=\"tabpanel\" id=\"reiterinhalt\" class=\"reiter-inhalt\">';\n        for (const [k, tx] of abschnitte) {\n        h += teilTitel(tx);\n        if (k === 'art') {\n          h += segment('o.art', sel.art, ARTEN.map(a => [a, mitSym(a, artName(a))]));\n          if (sel.art === 'tuer') h += `<p class=\"hinweis\">${t('tuer_seite_hinweis')}</p>`;\n          // statt Reiter \u201EWirkung\u201C nur, was der Plan nicht zeigt (Fernando 20.10.: Liste der Melder war doppelt)\n          if (sel.art === 'tuer' && !offen(sel)) h += `<p class=\"hinweis\">${t('tuer_zu')}</p>`;\n          if (sel.art === 'fenster') h += `<p class=\"hinweis\">${t('fenster_glas')}</p>`;\n        } else if (k === 'breite') {\n          h += `<div class=\"felder\">${feldZahl('o.b', t('breite'), sel.b)}</div><p class=\"hinweis\">${t('oeffnung_verschieben')}</p>`;\n        } else if (k === 'fenster') {\n          h += `<label class=\"check-row\"><input type=\"checkbox\" data-feld=\"o.vorhang\" ${sel.vorhang ? 'checked' : ''}>${t('vorhang')}</label>`;\n        }\n        }\n        h += '</div>';\n      } else if (modus === 'hinweise') {\n        const l = hinweisListe();\n        if (markiert !== null && (markiert >= l.length || markiertBei !== markOrt())) markiert = null;\n        h += kopf(t('hinweise_titel'));\n        h += l.length ? `<p class=\"hinweis\">${t('hinweise_tipp')}</p><ul class=\"hinweis-liste\">` +\n          l.map((x, k) => hinweisZeile(x, k, x.text)).join('') + '</ul>'\n          : meldung('ok', t('passt'), t('keine_hinweise'));\n      } else {\n        modus = 'start';\n        h += `<h2>${t('titel')}${host.dataset.entwurf ? ` <span class=\"badge badge--warn\">${t('entwurf')}</span>` : ''}</h2><div id=\"warnzeile\"></div>`;\n        h += '<ul class=\"bereiche\">' + BEREICHE.map(([b, kurz, lang, icon]) =>\n          `<li><button data-bereich=\"${b}\">${icon}<span class=\"kurz\">${t(kurz)}</span><span class=\"lang\">${t(lang)}</span></button></li>`).join('') + '</ul>';\n        // Was im Raum steht, als Chips: antippen = bearbeiten, Plus oben = hinzuf\u00FCgen (Fernando 21.10.)\n        const chips = (titel, eintraege) => eintraege.length ? `<p class=\"feld-titel\">${titel}</p><ul class=\"chips\">${eintraege.join('')}</ul>` : '';\n        h += chips(t('im_raum_melder'), S.melder.map((s, i) => `<li><button class=\"chip\" data-chip=\"melder\" data-id=\"${s.id}\">${punkt(i)}${esc(melderName(s))}</button></li>`));\n        if (S.melder.length) h += `<p class=\"loesch-zeile\"><button class=\"textlink textlink--gefahr\" data-akt=\"melder_alle_weg\">${AKT_SYM.loeschen}${t('alle_melder_loeschen')}</button></p>`;\n        h += chips(t('im_raum_moebel'), S.moebel.filter(o => !istBauteil(o)).map(o => `<li><button class=\"chip\" data-chip=\"moebel\" data-id=\"${o.id}\">${esc(o.name)}</button></li>`));\n        h += chips(t('im_raum_zonen'), zonen().map((z, n) => `<li><button class=\"chip\" data-chip=\"zone\" data-id=\"${z.id}\">${t('zone_n', { n: n + 1 })}</button></li>`));\n        if (zonen().length) h += `<p class=\"loesch-zeile\"><button class=\"textlink textlink--gefahr\" data-akt=\"zonen_alle_weg\">${AKT_SYM.loeschen}${t('alle_zonen_loeschen')}</button></p>`;\n        h += `<p class=\"hinweis\">${S.melder.length ? t('start_hinweis_melder') : t('start_hinweis_leer')}</p>`;\n      }\n      const scroll = sheet.scrollTop;\n      sheet.innerHTML = h;\n      sheet.classList.toggle('is-bearbeiten', modus !== 'start');\n      if (feldBearbeiten !== (modus !== 'start')) {\n        feldBearbeiten = modus !== 'start';\n        if (angepasst) { if (zeiger.size) nachpassen = true; else gleiten(); }\n      }\n      zeichneInfo();\n      // nach oben nur bei einem anderen Teil oder Bereich; am Desktop steht alles untereinander, ein Klick weiter\n      // unten soll die Liste nicht zur\u00FCckspringen lassen. Erst nach zeichneInfo(): vorher ist #info leer, die Leiste\n      // k\u00FCrzer und die Position schon abgeschnitten.\n      const ort = modus + ':' + (auswahl ? auswahl.id : '') + ':' + (breit ? '' : r);\n      sheet.scrollTop = ort === feldOrt ? scroll : 0;\n      feldOrt = ort;\n    }\n    // Stufenabstand folgt der Montage (grundStufe), w\u00E4hlbar ist er nicht mehr (Fernando 19.10.: keine Zwischenebenen)\n    const maxText = v => zahl(v, 2) + ' m';\n    const spanne = z => `${zahl(z.dmin)}\u2013${zahl(z.dmax)} m`;   // n\u00E4chste bis weiteste Entfernung\n\n    let infoOhneVorschlag = false;                     // Infofeld entstand, w\u00E4hrend ein Finger lag: ohne gerechnete Stellen\n    function zeichneInfo() {\n      infoOhneVorschlag = zeiger.size > 0;\n      const { res, hinweise } = analyse();\n      const sel = auswahl ? finde(auswahl.typ, auswahl.id) : null;\n      const zaehlend = hinweise.filter(x => !x.ok);       // gr\u00FCne Hinweise z\u00E4hlen nicht\n      summeNeu(); aktionenNeu(zaehlend.length);\n      const wz = $('#warnzeile');\n      if (wz) {\n        if (modus === 'melder') {\n          const n = zaehlend.filter(x => betrifft(x, sel)).length;\n          wz.innerHTML = n ? tipp(n === 1 ? t('melder_warn_eins') : t('melder_warn_mehr', { n })) : '';\n        } else {\n          const n = zaehlend.length;\n          wz.innerHTML = (ladeFehler ? meldung('warn', t('beachten'), t('link_unlesbar')) : '') + (!n ? '' : hinweisKnopf(n));\n        }\n      }\n      if ($('#blatt').open && blattArt === 'auswahl') $('#blatt-inhalt').innerHTML = uebersichtHtml(res, hinweise);\n      const box = $('#info'); if (!box) return;\n      let h = '';\n\n      if (modus === 'melder' && sel) {\n        const r = res.find(x => x.s === sel);\n        const z = r.zeilen.filter(x => x.anteil > 0);\n        if (!z.length) h += `<p class=\"hinweis\">${t('kein_moebel')}</p>`;\n        // Keine M\u00F6belliste mit Prozent: was erfasst ist, zeigt der Plan (Fernando 20.10.). \u201EBeste Stelle\u201C sucht die Wandstelle,\n        // an der alle Pl\u00E4tze mit Stillsitzen erfasst werden.\n        if (z.length) { const e = besteAktuell(); h += e ? besteText(e) : `<div class=\"actions actions--tight\"><button class=\"btn\" data-akt=\"beste\">${t('beste_knopf')}</button></div>`; }\n        const eigene = hinweisListe({ hinweise }).map((x, k) => [x, k]).filter(([x]) => x.melder.includes(sel));\n        if (!eigene.length) h += `<p class=\"hinweis\">${t('keine_hinweise_melder')}</p>`;\n        if (markiert !== null && markiertBei === markOrt() && !eigene.some(([, k]) => k === markiert)) markiert = null;\n        if (eigene.length) h += `<ul class=\"hinweis-liste\">${eigene.map(([x, k]) => hinweisZeile(x, k, x.kurz)).join('')}</ul><p class=\"hinweis\">${t('tipp_markieren')}</p>`;\n        if (istDecke(sel)) {\n          const dk = decke(sel);\n          h += dk.R > 0\n            ? `<p class=\"hinweis\">${t('decke_kreis', { d: zahl(2 * dk.R), b: zahl(BEZUG), dh: zahl(dk.dh) })}</p>`\n            : meldung('warn', t('beachten'), t('decke_zukurz', { h: zahl(dk.H, 2), max: zahl(sel.max, 2), b: zahl(BEZUG), dh: zahl(dk.dh) }));\n          if (r.M.stufen) h += `<p class=\"hinweis\">${t('decke_stufe', { s: zahl(ANLEITUNG_DECKE, 2), ist: zahl(r.M.stufe, 2) })}</p>`;\n        }\n        if (!r.M.stufe) h += `<p class=\"hinweis\">${t('mz_info', { m: zahl(Math.min(r.M.praesenz, sel.max), 0) })}</p>`;\n        if (z.length) h += `<p class=\"hinweis\">${t('orientierung_kurz')}</p>`;\n      } else if (modus === 'moebel' && sel) {\n        if (sel.niedrig) h += `<p class=\"hinweis\">${t('niedrig_erfasst')}</p>`;\n        else if (stoff(sel) === 'metall') h += `<p class=\"hinweis\">${t('metall_info')}</p>`;\n        else if (stoff(sel) === 'hoch') h += `<p class=\"hinweis\">${t('hoch_info')}</p>`;\n        else if (stoff(sel) === 'massiv') h += `<p class=\"hinweis\">${t('massiv_info')}</p>`;\n        else if (!res.length) h += `<p class=\"hinweis\">${t('kein_melder')}</p>`;\n        else h += '<ul class=\"liste\">' + res.map(r => {\n          const z = r.zeilen.find(x => x.key === sel.id);\n          // Schritt 1 ohne Entfernung; dazu, wie viel davon nur Bewegung ist\n          const erf = z && z.anteil - z.kern >= 0.05 ? t('erfasst_rand', { p: Math.round(z.anteil * 100), r: Math.round((z.anteil - z.kern) * 100) })\n            : z && t('erfasst', { p: Math.round(z.anteil * 100) });\n          const txt = !z || !z.anteil ? `<span class=\"klein\">${t('nicht_erfasst')}</span>` : `<span class=\"klein\">${erf}</span>`;\n          return `<li>${punkt(r.si)}<span>${melderName(r.s)}</span><span class=\"rechts\">${txt}</span></li>`;\n        }).join('') + '</ul>';\n      }\n      box.innerHTML = h;\n    }\n\n    // ---------- Auswahl oben rechts und Men\u00FC oben links ----------\n    function auswahlZaehlen() {\n      const anz = {};\n      S.melder.forEach(s => anz[s.modell] = (anz[s.modell] || 0) + 1);\n      return { anz, summe: Object.entries(anz).reduce((a, [m, n]) => a + n * (MODELLE[m].preis || 0), 0) };\n    }\n    function summeNeu() {\n      const { summe } = auswahlZaehlen(), n = S.melder.length;\n      $('#summe .summe-n').textContent = t(n === 1 ? 'anzahl_eins' : 'anzahl_mehr', { n }) + ' \u00B7 ';\n      $('#summe .summe-preis').textContent = geld(summe);\n    }\n    function uebersichtHtml(res, hinweise) {\n      let h = '';\n      if (!S.melder.length) return `<p class=\"hinweis\">${t('kein_melder_plan')}</p>`;\n      const n = hinweise.filter(x => !x.ok).length;\n      if (n) h += hinweisKnopf(n);   // die Liste steht unten, der Plan bleibt frei\n      const zeilen = res.length ? res[0].zeilen.filter(z => z.ort) : [];\n      if (zeilen.length) {\n        h += `<h3>${t('entfernung_titel')}</h3><div class=\"tab-rahmen\"><table class=\"tab\"><tr><th>${t('moebel_spalte')}</th>${res.map(r => `<th>${punkt(r.si)} ${buchstabe(r.si)}</th>`).join('')}</tr>`;\n        for (const z0 of zeilen) {\n          h += `<tr><td>${esc(z0.name)}</td>${res.map(r => { const z = r.zeilen.find(x => x.key === z0.key);\n            return z.anteil > 0 ? `<td>${spanne(z)}</td>` : `<td class=\"leer\"><span aria-hidden=\"true\">\u2013</span><span class=\"nur-vorlesen\">${t('nicht_erfasst')}</span></td>`; }).join('')}</tr>`;\n        }\n        h += '</table></div>';\n      }\n      if (zonen().length) {\n        const zu = zonenZuordnung();\n        S.melder.forEach((s, i) => {\n          const meine = zonenVon(s, zu); if (!meine.length) return;\n          h += `<h3>${punkt(i)} ${esc(melderName(s))}: ${t('reiter_zonen')}</h3><ul class=\"liste\">` + meine.map(z => {\n            const drin = moebelNamen(z);\n            return `<li><span>${t('zone_n', { n: zoneNr(z) })}${drin.length ? `<br><span class=\"klein\">${drin.join(', ')}</span>` : ''}</span></li>`;\n          }).join('') + '</ul>';\n        });\n        const ohneMelder = zonen().filter(z => !zu.get(z.id));\n        if (ohneMelder.length) h += meldung('warn', t('beachten'), t(S.melder.some(hatZonen) ? 'zonen_ohne_melder' : 'zonen_ohne_mz', { liste: ohneMelder.map(z => t('zone_n', { n: zoneNr(z) })).join(', ') }));\n      }\n      const { anz, summe } = auswahlZaehlen();\n      h += `<h3>${t('melder_titel')}</h3><ul class=\"liste\">` + Object.entries(anz).map(([m, stueck]) =>\n        `<li><span>${stueck} \u00D7 ${MODELLE[m].url ? `<a href=\"${esc(MODELLE[m].url)}\">${MODELLE[m].name}</a>` : MODELLE[m].name}<br><span class=\"merkmale\">${merkmale(MODELLE[m])}</span></span><span class=\"rechts\">${geld(stueck * (MODELLE[m].preis || 0))}</span></li>`).join('') +\n        `<li><b>${t('summe')}</b><span class=\"rechts\"><b>${geld(summe)}</b></span></li></ul>`;\n      const fehlt = Object.keys(anz).filter(m => !MODELLE[m].lieferbar);\n      fehlt.forEach(m => h += meldung('warn', t('beachten'), t('nicht_lieferbar', { name: MODELLE[m].name })));\n      // Erwartung setzen, bevor gekauft wird: berechnet, nicht gemessen (Fernando 17.10.)\n      h += tipp(t('orientierung'));\n      h += `<p class=\"field__error\" id=\"korbfehler\"></p>`;\n      h += `<button class=\"btn btn--primary btn--block\" data-akt=\"warenkorb\" ${fehlt.length ? 'disabled' : ''}>${t('warenkorb')}</button>`;\n      return h + feedbackHtml();\n    }\n    // Zur\u00FCck dorthin, woher man kam, wenn es eine Seite des Shops war; sonst zur Startseite\n    function zurueckZiel() {\n      try {\n        const r = new URL(document.referrer);\n        if (r.origin === location.origin && r.pathname !== location.pathname) return r.href;\n      } catch (e) { /* kein Referrer */ }\n      return LINKS.shop || '/';\n    }\n    // Impressum zuerst, wie man es erwartet; was Shopify sonst liefert, in seiner Reihenfolge dahinter\n    const RECHT_ZUERST = ['legal-notice', 'privacy-policy', 'terms-of-service', 'refund-policy', 'widerruf-formular'];\n    const rechtSortiert = () => [...LINKS.recht].sort((a, b) => {\n      const r = l => { const i = RECHT_ZUERST.findIndex(k => l.url.includes(k)); return i < 0 ? 99 : i; };\n      return r(a) - r(b);\n    });\n    function menueHtml() {\n      let h = `<ul class=\"wahl-liste\"><li><a class=\"wahl\" href=\"${esc(zurueckZiel())}\">\u2190 ${t('zurueck_shop')}</a></li>` +\n        `<li><a class=\"wahl\" href=\"${esc(LINKS.warenkorb || ROUTER + '/cart')}\">${t('warenkorb_link')}</a></li>` +\n        `<li><button class=\"wahl\" data-akt=\"link\">${t(KANN_TEILEN ? 'link_teilen' : 'link_kopieren')}</button></li></ul>`;\n      h += `<p class=\"feld-titel\">${t('beispiel_laden')}</p><ul class=\"wahl-liste\">` + BEISPIELE.map((b, i) =>\n        `<li><button class=\"wahl\" data-akt=\"beispiel\" data-nr=\"${i}\">${t(b.name)}</button></li>`).join('') + '</ul>';\n      h += `<div class=\"actions actions--tight\"><button class=\"btn btn--danger\" data-akt=\"leeren\">${t('leeren')}</button></div>`;\n      h += `<p class=\"hinweis\">${t('leeren_hinweis')}</p>`;\n      // Nur der Hinweis zur vereinfachten Rechnung; Farben, Verdecken, T\u00FCren und Beta-Satz raus (Fernando 22.10.)\n      h += `<p class=\"hinweis\"><b>${t('orientierung')}</b></p>`;\n      h += feedbackHtml();\n      // Rechtliches als kleine Fu\u00DFzeile, Links nebeneinander statt einer langen Liste (Fernando 23.10.)\n      if (LINKS.recht && LINKS.recht.length) h += `<nav class=\"recht\" aria-label=\"${esc(t('rechtliches'))}\">` +\n        rechtSortiert().map(l => `<a href=\"${esc(l.url)}\">${esc(l.titel)}</a>`).join('') + '</nav>';\n      return h;\n    }\n    // ---------- R\u00FCckmeldung (Fernando 23.10.: schnell, ohne Chat) ----------\n    // Daumen und Grund gehen an Plausible, Freitext \u00FCber das versteckte Kontaktformular der Section ins Postfach.\n    const FB = { wert: null, grund: null, text: '', email: '', link: true, status: null };\n    const FB_GRUENDE = ['bedienung', 'ergebnis', 'fehlt'];\n    const datenschutzUrl = () => ((LINKS.recht || []).find(l => l.url.includes('privacy-policy')) || {}).url || '';\n    function feedbackHtml() {\n      if (FB.status === 'ok') return `<div class=\"fb\">${meldung('ok', t('fb_danke'), t('fb_gesendet'))}</div>`;\n      const druck = an => `aria-pressed=\"${an ? 'true' : 'false'}\"`;\n      let h = `<div class=\"fb\"><p class=\"feld-titel\">${t('fb_frage')}</p><ul class=\"chips\">` +\n        `<li><button class=\"chip\" data-akt=\"fb\" data-wert=\"ja\" ${druck(FB.wert === 'ja')}>${t('fb_ja')}</button></li>` +\n        `<li><button class=\"chip\" data-akt=\"fb\" data-wert=\"nein\" ${druck(FB.wert === 'nein')}>${t('fb_nein')}</button></li></ul>`;\n      if (FB.wert === 'nein') h += `<p class=\"feld-titel\">${t('fb_warum')}</p><ul class=\"chips\">` + FB_GRUENDE.map(g =>\n        `<li><button class=\"chip\" data-akt=\"fb_grund\" data-grund=\"${g}\" ${druck(FB.grund === g)}>${t('fb_grund_' + g)}</button></li>`).join('') + '</ul>';\n      if (FB.wert) {\n        const ds = datenschutzUrl();\n        h += `<div class=\"field\"><label for=\"fb-text\">${t(FB.wert === 'ja' ? 'fb_text_ja' : 'fb_text_nein')}</label>` +\n          `<textarea class=\"input fb-text\" id=\"fb-text\" data-fb=\"text\" maxlength=\"2000\" rows=\"3\">${esc(FB.text)}</textarea></div>` +\n          `<div class=\"field\"><label for=\"fb-email\">${t('fb_email')}</label><input class=\"input\" type=\"email\" id=\"fb-email\" data-fb=\"email\" maxlength=\"200\" autocomplete=\"email\" value=\"${esc(FB.email)}\"></div>` +\n          `<label class=\"check-row\"><input type=\"checkbox\" data-fb=\"link\" ${FB.link ? 'checked' : ''}>${t('fb_link')}</label>` +\n          `<p class=\"field__error\" id=\"fb-fehler\">${FB.status === 'fehler' ? t('fb_fehler') + (LINKS.kontakt ? ` <a href=\"${esc(LINKS.kontakt)}\">${t('fb_kontakt')}</a>` : '') : ''}</p>` +\n          `<div class=\"actions actions--tight\"><button class=\"btn\" data-akt=\"fb_senden\" ${FB.status === 'sendet' ? 'disabled' : ''}>${t(FB.status === 'sendet' ? 'fb_sendet' : 'fb_senden')}</button></div>` +\n          `<p class=\"field__hint\">${t('fb_hinweis')}${ds ? ` <a href=\"${esc(ds)}\">${t('fb_datenschutz')}</a>` : ''}</p>`;\n      }\n      return h + '</div>';\n    }\n    // Nur den Kasten neu zeichnen: Blatt und Liste bleiben, wo sie gescrollt sind\n    function feedbackNeu() {\n      const alt = $('#blatt-inhalt .fb');\n      if (!alt) return;\n      const neu = document.createElement('div'); neu.innerHTML = feedbackHtml();\n      alt.replaceWith(neu.firstElementChild);\n    }\n    // Gesendet wird das Formular der Section ganz normal (es nimmt Shopifys Captcha mit); die Seite l\u00E4dt neu und\n    // kommt mit ?contact_posted=true zur\u00FCck. Den Plan und die Antworten h\u00E4lt sessionStorage \u00FCber das Neuladen,\n    // fbZurueck() stellt sie beim Start wieder her. Das Blatt schlie\u00DFt vorher, ein Captcha-R\u00E4tsel l\u00E4ge sonst\n    // hinter dem modalen Dialog. Ein unsichtbarer Rahmen ging nicht: Shopify verbietet das Einbetten.\n    const FB_SPEICHER = 'sen-raumplaner-rueckmeldung';\n    function sendeFeedback() {\n      const form = document.getElementById('sen-fb-form');\n      if (!form) { FB.status = 'fehler'; feedbackNeu(); return; }\n      clearTimeout(speichernT); speichern();\n      const zeilen = [`R\u00FCckmeldung Raumplaner (${host.dataset.sprache || 'de'}, ${matchMedia('(pointer: coarse)').matches ? 'Finger' : 'Maus'}, ${window.innerWidth}\u00D7${window.innerHeight})`,\n        `Hilfreich: ${FB.wert === 'ja' ? 'ja' : 'nein'}${FB.grund ? `, Grund: ${FB.grund}` : ''}`,\n        `Melder im Plan: ${S.melder.length}, M\u00F6bel: ${S.moebel.length}`, '', FB.text.trim() || '(kein Text)'];\n      if (FB.link) zeilen.push('', `Plan: ${location.href}`);\n      form.elements['contact[body]'].value = zeilen.join('\\n');\n      form.elements['contact[email]'].value = FB.email.trim();\n      try {\n        window.sessionStorage.setItem(FB_SPEICHER, JSON.stringify({ hash: location.hash, wert: FB.wert, grund: FB.grund, link: FB.link, text: FB.text, email: FB.email, zeit: Date.now() }));\n      } catch (e) { /* ohne sessionStorage geht nach dem Neuladen nur der Plan verloren, gesendet wird trotzdem */ }\n      FB.status = 'sendet';\n      $('#blatt').close(); planMeldung(t('fb_sendet'), 0);\n      // Shopify bindet das Captcha beim ersten Fokus im Formular; erst danach absenden\n      form.dispatchEvent(new Event('focusin', { bubbles: true }));\n      let n = 0;\n      const warte = () => {\n        if (form.dataset.hcaptchaBound || form.dataset.recaptchaBound || ++n > 50) form.requestSubmit();\n        else setTimeout(warte, 100);\n      };\n      warte();\n    }\n    // Beim Start nach dem Senden: Plan zur\u00FCck in die Adresse, Ergebnis merken. Gibt true zur\u00FCck, wenn es ein\n    // R\u00FCckweg vom Senden war (dann z\u00E4hlt der Start nicht noch einmal).\n    function fbZurueck() {\n      let d = null;\n      try { d = JSON.parse(window.sessionStorage.getItem(FB_SPEICHER) || 'null'); window.sessionStorage.removeItem(FB_SPEICHER); } catch (e) { d = null; }\n      if (!d || Date.now() - d.zeit > 15 * 60 * 1000) return false;\n      const such = new window.URLSearchParams(location.search), ok = such.get('contact_posted') === 'true';\n      such.delete('contact_posted');\n      const rest = such.toString();\n      try { history.replaceState(history.state, '', location.pathname + (rest ? '?' + rest : '') + (d.hash || '')); } catch (e) { /* egal */ }\n      Object.assign(FB, { wert: d.wert, grund: d.grund, link: d.link, text: ok ? '' : d.text || '', email: ok ? '' : d.email || '', status: ok ? 'ok' : 'fehler' });\n      fbErgebnis = ok ? 'ok' : 'fehler';\n      if (ok) track('Raumplaner Feedback Text', { link: d.link ? 'ja' : 'nein', email: (d.email || '').trim() ? 'ja' : 'nein' });\n      return true;\n    }\n    let fbErgebnis = null;\n    let blattArt = null;\n    function zeichneBlatt() {\n      $('#blatt-titel').textContent = blattArt === 'menue' ? t('menue') : blattArt === 'ersetzen' ? t('ersetzen_titel') : t('auswahl_titel');\n      if (blattArt === 'menue') $('#blatt-inhalt').innerHTML = menueHtml();\n      // R\u00FCckfrage vor \u201EMelder vorschlagen\u201C, wenn schon Melder im Plan stehen (Fernando 22.10.: statt des Satzes im Hinweis)\n      else if (blattArt === 'ersetzen') $('#blatt-inhalt').innerHTML = `<p>${t(S.melder.length === 1 ? 'ersetzen_text_eins' : 'ersetzen_text', { n: S.melder.length })}</p>` +\n        `<div class=\"actions actions--stapel\"><button class=\"btn btn--primary\" data-akt=\"vorschlag_alle\" data-sicher=\"1\">${t('ersetzen_knopf')}</button><button class=\"btn\" data-akt=\"blattzu\">${t('abbrechen')}</button></div>`;\n      else { const { res, hinweise } = analyse(); $('#blatt-inhalt').innerHTML = uebersichtHtml(res, hinweise); }\n    }\n    function blattAuf(art) {\n      blattArt = art; zeichneBlatt();\n      const d = $('#blatt'); if (!d.open) d.showModal();\n    }\n    // Eingaben der R\u00FCckmeldung merken, damit ein Neuzeichnen des Blatts nichts verliert\n    $('#blatt').addEventListener('input', e => {\n      const f = e.target.closest('[data-fb]'); if (!f) return;\n      FB[f.dataset.fb] = f.type === 'checkbox' ? f.checked : f.value;\n    });\n    $('#menue-auf').addEventListener('click', () => blattAuf('menue'));\n    $('#summe').addEventListener('click', () => blattAuf('auswahl'));\n    // Tipp auf den abgedunkelten Rand schlie\u00DFt\n    $('#blatt').addEventListener('click', e => {\n      const r = e.currentTarget.getBoundingClientRect();\n      if (e.target === e.currentTarget && (e.clientX < r.left || e.clientX > r.right || e.clientY < r.top || e.clientY > r.bottom)) e.currentTarget.close();\n    });\n\n    // Warenkorb: \u00FCber die Warenkorb-Schnittstelle hinzuf\u00FCgen, was schon drin liegt, bleibt. Der Seitenrahmen\n    // des Planers hat keinen Mini-Warenkorb; das Blatt best\u00E4tigt und bietet den Weg zum Warenkorb an.\n    // \u201EAdd to Cart\u201C wie in sen-track.js, damit der Planer im Kauftrichter mitz\u00E4hlt.\n    async function inDenWarenkorb(knopf) {\n      const { anz } = auswahlZaehlen();\n      // _raumplaner: Planer-Spur in der Bestellung (Positionseigenschaft, f\u00FCr Kunden unsichtbar), siehe spurSetzen()\n      const items = Object.entries(anz).map(([m, n]) => ({ id: MODELLE[m].variante, quantity: n, properties: { _raumplaner: 'ja' } }));\n      if (!items.length) return;\n      knopf.disabled = true;\n      const fehler = $('#korbfehler');\n      try {\n        const antwort = await fetch(ROUTER + '/cart/add.js', {\n          method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n          body: JSON.stringify({ items }),\n        });\n        if (!antwort.ok) throw new Error(String(antwort.status));\n        track('Add to Cart', { produkt: 'raumplaner', variante: items.map(i => i.id).join(' '), quelle: 'raumplaner' });\n        track('Raumplaner Warenkorb', { melder: String(S.melder.length), modelle: modellListe(S.melder), summe: String(Math.round(auswahlZaehlen().summe / 100)), ...messProps() });\n        if (fehler) fehler.textContent = '';\n        knopf.outerHTML = meldung('ok', t('passt'), t('korb_ok')) +\n          `<a class=\"btn btn--primary btn--block\" href=\"${esc(LINKS.warenkorb || ROUTER + '/cart')}\">${t('zum_warenkorb')}</a>`;\n      } catch (e) {\n        knopf.disabled = false;\n        if (fehler) fehler.textContent = t('warenkorb_fehler');\n      }\n    }\n    const KANN_TEILEN = matchMedia('(pointer: coarse)').matches && !!navigator.share;\n    // Link zum Raum: der Zustand steht in der Adresse hinter #. Auf dem Handy das Teilen-Men\u00FC des Ger\u00E4ts,\n    // sonst in die Zwischenablage. R\u00FCckmeldung als Meldung im Plan, weil der schmale Knopf keinen Text zeigt\n    // (Fernando 23.10.: \u201Enull Feedback\u201C); scheitert das Kopieren, sagt sie das auch.\n    async function linkTeilen(knopf) {\n      clearTimeout(speichernT); speichern();\n      const url = location.href;\n      if (KANN_TEILEN) {\n        try { await navigator.share({ title: t('titel'), url }); track('Raumplaner Link', { weg: 'teilen' }); return; }\n        catch (e) { if (e && e.name === 'AbortError') return; }   // abgebrochen; sonst weiter mit Kopieren\n      }\n      if (!await kopiere(url)) { planMeldung(t('link_fehler')); return; }\n      track('Raumplaner Link', { weg: 'kopiert' });\n      const ziel = knopf.querySelector('.link-text') || knopf, alt = ziel.textContent;\n      ziel.textContent = t('link_kopiert'); planMeldung(t('link_kopiert'));\n      setTimeout(() => { ziel.textContent = alt; }, 2000);\n    }\n    // Zwischenablage; ohne Berechtigung der alte Weg \u00FCber ein markiertes Textfeld\n    async function kopiere(text) {\n      try { await navigator.clipboard.writeText(text); return true; } catch (e) { /* weiter mit dem alten Weg */ }\n      const f = document.createElement('textarea');\n      f.value = text; f.setAttribute('readonly', ''); f.style.cssText = 'position:fixed;top:0;left:0;opacity:0';\n      root.appendChild(f);\n      f.select();\n      let ok = false;\n      try { ok = document.execCommand('copy'); } catch (e) { ok = false; }\n      f.remove();\n      return ok;\n    }\n    let planMeldungT;\n    function planMeldung(text, dauer = 2500) {   // dauer 0: bleibt, bis die n\u00E4chste Meldung kommt\n      const m = $('#plan-meldung');\n      m.textContent = text; m.hidden = false; melde(text);\n      clearTimeout(planMeldungT); if (dauer) planMeldungT = setTimeout(() => { m.hidden = true; }, dauer);\n    }\n    // Plausible wie in sen-track.js: Z\u00E4hlen ist Beiwerk und darf nichts aufhalten\n    // Modelle als lesbare Eigenschaft f\u00FCr Plausible, z. B. \u201EKL MZ \u00D72, Basis \u00D71\u201C (meiste zuerst)\n    function modellListe(melder) {\n      const anz = {};\n      melder.forEach(s => anz[s.modell] = (anz[s.modell] || 0) + 1);\n      return Object.entries(anz).sort((a, b) => b[1] - a[1] || MODELLE[a[0]].name.localeCompare(MODELLE[b[0]].name))\n        .map(([m, n]) => MODELLE[m].name + ' \u00D7' + n).join(', ');\n    }\n    // Planer-Spur in der Bestellung (docs/raumplaner-messung.md \u00A7 6): Warenkorb-Attribut _raumplaner bei der ersten\n    // Aktion (ersteAktion), nicht beim Start, denn \u201ERaumplaner Start\u201C feuert schon beim Laden der Seite. Auch wer\n    // nur \u00FCber die Kacheln plant und sp\u00E4ter \u00FCber die Produktseite kauft, tr\u00E4gt so die Spur.\n    // Hei\u00DFt \u201Ebeeinflusst\u201C; die Positionseigenschaft in inDenWarenkorb() hei\u00DFt \u201Edirekt\u201C. Fehlschlag kostet nur die Spur.\n    let spurGesetzt = false;\n    function spurSetzen() {\n      if (spurGesetzt) return;\n      spurGesetzt = true;\n      fetch(ROUTER + '/cart/update.js', {\n        method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n        body: JSON.stringify({ attributes: { _raumplaner: 'ja' } }),\n      }).catch(() => { spurGesetzt = false; });\n    }\n    // Weg zwischen Start und Vorschlag (docs/raumplaner-messung.md \u00A7 1, 4): Meilensteine je Seitenaufruf einmal, erkannt\n    // in merken() am Vergleich mit dem Stand beim Laden; Beispiel und \u201EAlles leeren\u201C setzen eine neue Ausgangslage.\n    // Dauer, Fl\u00E4che, M\u00F6bel und Reibung reisen in Klassen mit \u201EVorschlag\u201C und \u201EWarenkorb\u201C, nie Ma\u00DFe oder Namen.\n    const mess = { t0: 0, herkunft: 'neu', basisRaum: '', basisMoebel: '', erste: false, raum: false, moebel: false, rueckgaengig: 0, geleert: 0, moebelWeg: 0 };\n    const raumKey = () => JSON.stringify([S.raum, S.oeffnungen]);\n    function messBasis() { mess.basisRaum = raumKey(); mess.basisMoebel = JSON.stringify(S.moebel); }\n    function ersteAktion() {\n      if (!mess.t0 || mess.erste) return;\n      mess.erste = true;\n      spurSetzen();\n      track('Raumplaner Erste Aktion', { herkunft: mess.herkunft });\n    }\n    function messSchritt() {\n      if (!mess.t0) return;   // Laden und R\u00FCckweg nach der R\u00FCckmeldung z\u00E4hlen nicht\n      ersteAktion();\n      if (!mess.raum && raumKey() !== mess.basisRaum) { mess.raum = true; track('Raumplaner Raum', { herkunft: mess.herkunft }); }\n      if (!mess.moebel && JSON.stringify(S.moebel) !== mess.basisMoebel) { mess.moebel = true; track('Raumplaner M\u00F6bel', { herkunft: mess.herkunft }); }\n    }\n    const messKlasse = (n, grenzen) => grenzen.find(([g]) => n <= g)[1];   // letzte Grenze ist immer Infinity\n    function messProps() {\n      const p = raumPoly();\n      let a = 0;\n      for (let i = 0; i < p.length; i++) { const q = p[(i + 1) % p.length]; a += p[i][0] * q[1] - q[0] * p[i][1]; }\n      const min = (Date.now() - mess.t0) / 60000;\n      return {\n        herkunft: mess.herkunft,\n        dauer: messKlasse(min, [[1, '<1 min'], [3, '1-3 min'], [10, '3-10 min'], [Infinity, '>10 min']]),\n        flaeche: messKlasse(Math.abs(a) / 2, [[15, '<15 m\u00B2'], [30, '15-30 m\u00B2'], [60, '30-60 m\u00B2'], [Infinity, '>60 m\u00B2']]),\n        moebel: messKlasse(S.moebel.length, [[0, '0'], [3, '1-3'], [8, '4-8'], [Infinity, '>8']]),\n        rueckgaengig: messKlasse(mess.rueckgaengig, [[0, '0'], [3, '1-3'], [10, '4-10'], [Infinity, '>10']]),\n        moebel_weg: messKlasse(mess.moebelWeg, [[0, '0'], [2, '1-2'], [Infinity, '>2']]),\n        geleert: messKlasse(mess.geleert, [[0, '0'], [1, '1'], [Infinity, '>1']]),\n      };\n    }\n    function track(name, props) {\n      if (typeof window.plausible !== 'function') return;\n      try { window.plausible(name, props ? { props } : undefined); } catch (e) { /* egal */ }\n    }\n\n    // Eingaben im unteren Feld; Zahlen \u00FCber dem Deckel werden nicht \u00FCbernommen\n    const DECKEL = { 'raum.b': MAX_RAUM, 'raum.l': MAX_RAUM, 'raum.ab': MAX_RAUM, 'raum.at': MAX_RAUM, 'raum.hoehe': MAX_HOEHE,\n      'm.w': MAX_MOEBEL, 'm.h': MAX_MOEBEL, 'o.b': MAX_MOEBEL };\n    sheet.addEventListener('input', e => {\n      const f = e.target.dataset.feld; if (!f) return;\n      if (f === 'w.laenge') {\n        const v = parseFloat(e.target.value);\n        const ok = isFinite(v) && v >= MIN_WAND && v <= MAX_RAUM && auswahl && auswahl.typ === 'wand' && wandLaenge(auswahl.id, v);\n        e.target.setAttribute('aria-invalid', ok ? 'false' : 'true');\n        $('#raumfehler').textContent = ok ? '' : t('raum_fehler');\n        if (ok) geaendert(false);\n        return;\n      }\n      const sel = auswahl ? finde(auswahl.typ, auswahl.id) : null;\n      const [obj, key] = f.split('.');\n      const ziel = obj === 'raum' ? S.raum : sel;\n      if (!ziel) return;\n      const v = e.target.type === 'checkbox' ? e.target.checked : e.target.type === 'text' ? e.target.value : parseFloat(e.target.value);\n      if (typeof v === 'number') {\n        const ok = isFinite(v) && v > 0 && v <= (DECKEL[f] || Infinity), fehler = sheet.querySelector(`[data-fehler=\"${f}\"]`);\n        e.target.setAttribute('aria-invalid', ok ? 'false' : 'true');\n        if (fehler) fehler.textContent = ok ? '' : DECKEL[f] ? t('feld_fehler_max', { max: zahl(DECKEL[f], 0) }) : t('feld_fehler');\n        if (!ok) return;\n      }\n      // Rechteck und L: Melder an einer Wand, die sich verschiebt, wandern mit (wie bei der freien Form)\n      const anWand = obj === 'raum' && S.raum.form !== 'frei' ? wandMelderMerken() : null;\n      ziel[key] = v;\n      if (anWand) wandMelderSetzen(anWand);\n      if (f === 'm.w' && sel.rund) sel.h = v;\n      if (f === 's.max') $('#maxwert').textContent = maxText(v);\n      geaendert(false);\n    });\n    // H\u00E4kchen \u201Ezus\u00E4tzlich den ganzen Raum erfassen\u201C in der Zonen-Ansicht schaltet die Klasse zwischen zonen und beides\n    sheet.addEventListener('change', e => {\n      const o = e.target.closest('[data-option=\"beides\"]');\n      if (o) { neuKlasse = o.checked ? 'beides' : 'zonen'; zeichneSheet(); planNeu(); }\n      const k = e.target.closest('[data-option=\"klima\"]');\n      if (k) { mitRaumklima = k.checked; vorschlagErg = null; zeichneSheet(); }\n      const d = e.target.closest('[data-option=\"decke\"]');\n      if (d) { mitDecke = d.checked; vorschlagErg = null; beste = null; zeichneSheet(); }\n    });\n    sheet.addEventListener('change', e => {\n      if (e.target.dataset.feld === 'm.name') zeichneSheet();\n    });\n    function klick(e) {\n      const sel = auswahl ? finde(auswahl.typ, auswahl.id) : null;\n      const bo = e.target.closest('[data-beste]');\n      if (bo && !e.target.closest('[data-akt]')) {\n        const eb = besteAktuell();\n        if (eb && eb.optionen[+bo.dataset.beste].vorschlag) { eb.wahl = +bo.dataset.beste; zeichneSheet(); planNeu(); }\n        return;\n      }\n      const hk = e.target.closest('[data-hinweis]');\n      if (hk) {                                        // nur umschalten, die Liste bleibt, wo sie gescrollt ist\n        markiert = markiert === +hk.dataset.hinweis ? null : +hk.dataset.hinweis; markiertBei = markOrt(); beste = null;\n        // wurde die Liste gezeichnet, w\u00E4hrend ein Finger zog, fehlt der Knopf noch (dann wird keine Stelle gerechnet)\n        const li = hk.closest('li'), mh = markierterHinweis();\n        if (li && mh && !li.querySelector('.vorschlag-knopf')) li.insertAdjacentHTML('beforeend', hinweisKnoepfe(mh));\n        sheet.querySelectorAll('[data-hinweis]').forEach(b => b.setAttribute('aria-pressed', +b.dataset.hinweis === markiert));\n        aktionenNeu(); planNeu(); return;\n      }\n      const rb = e.target.closest('[data-reiter]');\n      if (rb) { reiter[modus] = rb.dataset.reiter; zeichneSheet(); planNeu(); return; }\n      const ch = e.target.closest('[data-chip]');\n      if (ch) {                                        // Chip in der Startansicht oder Bereich in der Liste: das Teil bearbeiten\n        auswahl = { typ: ch.dataset.chip, id: ch.dataset.id }; neuGesetzt = null;\n        if (ch.dataset.chip === 'zone') { modus = 'melder-neu'; neuKlasse = zonenKlasse(); } else modus = ch.dataset.chip;\n        zeichneSheet(); planNeu(); return;\n      }\n      const kl = e.target.closest('[data-klasse]');\n      if (kl) { neuKlasse = kl.dataset.klasse; zeichneSheet(); return; }\n      const be = e.target.closest('[data-bereich]');\n      if (be) {\n        auswahl = null; modus = be.dataset.bereich; neuKlasse = null;\n        zeichneSheet(); planNeu(); return;\n      }\n      const seg = e.target.closest('[data-seg]');\n      if (seg) {\n        const [obj, key] = seg.dataset.seg.split('.'), v = seg.dataset.wert;\n        if (obj === 'w') { if (auswahl && auswahl.typ === 'wand') glasSetzen(auswahl.id, v === 'glas'); }\n        else if (obj === 'raum') {\n          if (key === 'form' && v === 'frei' && S.raum.form !== 'frei') S.raum.punkte = raumPoly().map(q => q.slice());\n          S.raum[key] = v; auswahl = null;\n          nachrasten();                              // W\u00E4nde sind neu nummeriert; Lage bleibt, Wand neu suchen\n        }\n        else if (obj === 'o' && sel) sel[key] = v;\n        else if (obj === 'm' && sel) {\n          if (key === 'form' && (v === 'rund') !== !!sel.rund) {\n            const cx = sel.x + sel.w / 2, cy = sel.y + sel.h / 2, d = Math.min(sel.w, sel.h);\n            sel.rund = v === 'rund';\n            if (sel.rund) { sel.w = sel.h = d; sel.x = rund(cx - d / 2); sel.y = rund(cy - d / 2); }\n          }\n        }\n        else if (sel) {\n          sel[key] = v;\n          if (key === 'modell' || key === 'montage') sel.stufe = grundStufe(MODELLE[sel.modell]);\n          sel.max = wm(sel).reichweite;\n          if (key === 'montage' && v === 'wand') { sel.wand = null; einrasten(sel, { x: sel.x, y: sel.y }, Infinity); }\n          if (key === 'montage' && v === 'decke') vonWandAb(sel);\n        }\n        geaendert(); return;\n      }\n      const vl = e.target.closest('[data-vorlage]');\n      if (vl) {\n        const v = VORLAGEN[+vl.dataset.vorlage], poly = raumPoly();\n        const H = huelle(poly), cx = (H.x0 + H.x1) / 2, cy = (H.y0 + H.y1) / 2;\n        const o = { id: neueId('m'), name: vorlageName(v.name), w: v.w, h: v.h, x: raster(cx - v.w / 2), y: raster(cy - v.h / 2), ort: !!v.ort, stoff: stoff(v), rund: !!v.rund };\n        S.moebel.push(o); neuGesetzt = o.id; auswahl = { typ: 'moebel', id: o.id }; modus = 'moebel'; reiter.moebel = 'masse'; geaendert(); return;\n      }\n      const ov = e.target.closest('[data-oeffnung]');\n      if (ov) {\n        const v = OEFFNUNG_VORLAGEN[+ov.dataset.oeffnung], poly = raumPoly();\n        // auf die l\u00E4ngste Wand, deren Mitte noch frei ist\n        const frei = kanten(poly).map(([x1, y1, x2, y2], i) => ({ i, len: Math.hypot(x2 - x1, y2 - y1), x: (x1 + x2) / 2, y: (y1 + y2) / 2 }))\n          .sort((a, b) => b.len - a.len)\n          .find(w => !S.oeffnungen.some(q => { const L = oeffnungLage(q, poly); return L && L.i === w.i && Math.abs((L.t0 + L.t1) / 2 - 0.5) * w.len < (L.b + v.b) / 2; }));\n        const w = frei || { x: poly[0][0], y: poly[0][1] };\n        const o = { ...v, id: neueId('o'), x: w.x, y: w.y };\n        oeffnungSetzen(o, w);\n        S.oeffnungen.push(o); neuGesetzt = o.id; auswahl = { typ: 'oeffnung', id: o.id }; modus = 'oeffnung'; reiter.oeffnung = 'art'; geaendert(); return;\n      }\n      const ml = e.target.closest('[data-modell]');\n      if (ml && zugKlickSperre) { zugKlickSperre = false; return; }\n      if (ml) {\n        const poly = raumPoly(), M = MODELLE[ml.dataset.modell];\n        const s = neuerMelder(ml.dataset.modell, M); delete s.montage;\n        const [x1, y1, x2, y2] = kanten(poly)[0];\n        einrasten(s, { x: (x1 + x2) / 2, y: (y1 + y2) / 2 });\n        S.melder.push(s); neuGesetzt = s.id; auswahl = { typ: 'melder', id: s.id }; modus = 'melder'; reiter.melder = 'montage'; geaendert(); return;\n      }\n      const b = e.target.closest('[data-akt]'); if (!b) return;\n      const akt = b.dataset.akt;\n      if (akt === 'blattzu') { $('#blatt').close(); return; }\n      if (akt === 'warenkorb') { inDenWarenkorb(b); return; }\n      if (akt === 'link') { linkTeilen(b); return; }\n      if (akt === 'fb') {\n        if (FB.wert !== b.dataset.wert) { FB.wert = b.dataset.wert; FB.grund = null; track('Raumplaner Feedback', { wert: FB.wert }); }\n        feedbackNeu(); return;\n      }\n      if (akt === 'fb_grund') { FB.grund = b.dataset.grund; track('Raumplaner Feedback Grund', { grund: FB.grund }); feedbackNeu(); return; }\n      if (akt === 'fb_senden') {\n        if (!FB.text.trim() && !FB.grund) { $('#fb-fehler').textContent = t('fb_leer'); return; }\n        sendeFeedback(); return;\n      }\n      if (akt === 'masse') { masseAn = !masseAn; aktionenNeu(); planNeu(); return; }\n      if (akt === 'zurueck') { abwaehlen(auswahl ? finde(auswahl.typ, auswahl.id) : null, true); zeichneSheet(); planNeu(); return; }\n      if (akt === 'klasse_zurueck') { auswahl = null; modus = 'melder-neu'; neuKlasse = null; neuGesetzt = null; zeichneSheet(); planNeu(); return; }\n      if (akt === 'start') { auswahl = null; modus = 'start'; neuGesetzt = null; zeichneSheet(); planNeu(); return; }\n      // \u201E\u00E4ndern\u201C an der Raumh\u00F6he im Decken-Hinweis: zur Raum-Ansicht, Reiter \u201EMa\u00DFe\u201C, Feld Raumh\u00F6he fokussiert; \u201EZur\u00FCck\u201C\n      // dort f\u00FChrt in die Aufgabe zur\u00FCck (rueckInAufgabe), solange man die Raum-Ansicht nicht anders verl\u00E4sst\n      // Unter dem Vorschlagsergebnis (Fernando 22.10.): weiteren Melder selbst setzen \u2192 Modellkarten, die Vorschl\u00E4ge bleiben\n      if (akt === 'selbst_setzen') { neuKlasse = 'alle'; auswahl = null; zeichneSheet(); planNeu(); return; }\n      if (akt === 'aufgabe_zurueck') { rueckInAufgabe = false; auswahl = null; modus = 'melder-neu'; zeichneSheet(); planNeu(); return; }\n      if (akt === 'raumhoehe') { auswahl = null; modus = 'raum'; reiter.raum = 'masse'; rueckInAufgabe = true; zeichneSheet(); planNeu(); const f = $('#sheet [data-feld=\"raum.hoehe\"]'); if (f) f.focus(); return; }\n      if (akt === 'hinweise') { $('#blatt').close(); auswahl = null; modus = 'hinweise'; markiert = 0; markiertBei = markOrt(); zeichneSheet(); planNeu(); return; }\n      if (akt === 'beispiel' || akt === 'leeren') ladeFehler = false;\n      if (akt === 'leeren' && !b.dataset.sicher) { b.dataset.sicher = '1'; b.textContent = t('leeren_sicher'); return; }   // R\u00FCckfrage im Knopf selbst\n      if (akt === 'beispiel' || akt === 'leeren') {\n        S = akt === 'beispiel' ? beispiel(+b.dataset.nr) : leer(); auswahl = null; modus = 'start'; memoLeeren();\n        if (akt === 'beispiel') mess.herkunft = 'beispiel'; else mess.geleert++;\n        messBasis();\n        $('#blatt').close(); einpassen();\n      }\n      else if (akt === 'drehen' && sel) { const cx = sel.x + sel.w / 2, cy = sel.y + sel.h / 2; [sel.w, sel.h] = [sel.h, sel.w]; sel.x = raster(cx - sel.w / 2); sel.y = raster(cy - sel.h / 2); }\n      else if (akt === 'kopie' && sel && auswahl.typ === 'melder') {\n        const s2 = { ...sel, id: neueId('s'), wand: null };\n        if (s2.grenze) s2.grenze = { ...s2.grenze };   // sonst ziehen beide Melder an derselben Grenze\n        einrasten(s2, { x: sel.x + 0.5, y: sel.y + 0.5 });\n        S.melder.push(s2); neuGesetzt = s2.id; auswahl = { typ: 'melder', id: s2.id };\n      }\n      else if (akt === 'kopie' && sel) { const o = { ...sel, id: neueId('m'), x: sel.x + 0.3, y: sel.y + 0.3 }; S.moebel.push(o); neuGesetzt = o.id; auswahl = { typ: 'moebel', id: o.id }; }\n      else if (akt === 'alleoffen') { const l = schaltbar(), auf = !l.every(o => o.zustand === 'offen'); l.forEach(o => o.zustand = auf ? 'offen' : 'zu'); }\n      else if (akt === 'loeschen' && sel) auswahlLoeschen(sel);\n      else if ((akt === 'links' || akt === 'rechts') && sel) { sel.dir = Math.round(sel.dir + (akt === 'links' ? -15 : 15)); }\n      else if (akt === 'eckeweg' && auswahl && auswahl.typ === 'ecke') { if (eckeLoeschen(auswahl.id)) auswahl = null; }\n      else if (akt === 'seite' && sel) { sel.seite = sel.seite === 'b' ? 'a' : 'b'; }\n      else if (akt === 'auf' && sel) { if (nachAussen(sel)) delete sel.auf; else sel.auf = 'aussen'; }\n      else if (akt === 'seite_hinweis' || akt === 'auf_hinweis') {\n        const mh = markierterHinweis();\n        if (mh && mh.tuer) {\n          if (akt === 'seite_hinweis') mh.tuer.seite = mh.tuer.seite === 'b' ? 'a' : 'b';\n          else if (nachAussen(mh.tuer)) delete mh.tuer.auf; else mh.tuer.auf = 'aussen';\n          markiert = null;\n        }\n      }\n      else if (akt === 'vorschlag') {\n        const eb = besteAktuell(), vs = b.dataset.opt != null ? eb && eb.optionen[+b.dataset.opt] && eb.optionen[+b.dataset.opt].vorschlag : markierterVorschlag();\n        if (vs && vs.neu) S.melder.push({ ...vs.neu, id: neueId('s'), x: vs.x, y: vs.y, dir: vs.dir, wand: vs.wand });\n        else if (vs) { Object.assign(vs.s, { ...(vs.anders || {}), x: vs.x, y: vs.y, dir: vs.dir, wand: vs.wand }); }\n        if (vs) { markiert = null; beste = null; }\n      }\n      else if (akt === 'vorschlag_alle') {\n        if (S.melder.length && !b.dataset.sicher) { blattAuf('ersetzen'); return; }\n        $('#blatt').close();\n        const klasse = neuKlasse || 'raum';\n        rechnen(() => {\n          const erg = vorschlagAlle(klasse);\n          if (erg.melder.length) { S.melder = erg.melder; auswahl = null; markiert = null; beste = null; memoLeeren(); }\n          vorschlagErg = { key: zustandKey(), erg };\n          ersteAktion();   // falls der Vorschlag nichts \u00E4ndert, kommt merken() nicht dazu\n          track('Raumplaner Vorschlag', { klasse: erg.klasse, melder: String(erg.melder.length), modelle: modellListe(erg.melder) || 'keine', plaetze: String(erg.P.length), erfasst: String(erg.erfasst), ...messProps() });\n          geaendert();\n        });\n        return;\n      }\n      // Alle Zonen oder alle Melder auf einmal weg (Fernando 22.10.); \u201ER\u00FCckg\u00E4ngig\u201C holt sie zur\u00FCck\n      else if (akt === 'zonen_alle_weg') { S.zonen = []; auswahl = null; }\n      else if (akt === 'melder_alle_weg') { S.melder = []; auswahl = null; beste = null; vorschlagErg = null; memoLeeren(); }\n      else if (akt === 'zone_neu') {\n        // neue Zone um das erste Aufenthaltsm\u00F6bel ohne Zone, sonst 1,5 \u00D7 1,5 m in der Raummitte\n        const Z = zonen(), frei = S.moebel.find(o => istOrt(o) && !Z.some(z => moebelIm(z).includes(o.id))), H = huelle();\n        const r = frei ? rechteckUm([frei.id]) : { p: rechteckPoly((H.x0 + H.x1) / 2 - 0.75, (H.y0 + H.y1) / 2 - 0.75, 1.5, 1.5) };\n        const z = { id: neueId('z'), ...r };\n        S.zonen = [...Z, z]; neuGesetzt = z.id; auswahl = { typ: 'zone', id: z.id };\n      }\n      else if (akt === 'zone_ecke_weg' && sel && auswahl.typ === 'zone' && auswahl.ecke != null && sel.p.length > 3) { sel.p.splice(auswahl.ecke, 1); auswahl = { typ: 'zone', id: sel.id }; }\n      else if (akt === 'zonen_aus_moebeln') { S.zonen = zonenAusMoebeln(); auswahl = null; }\n      else if (akt === 'zonen_bearbeiten') { auswahl = null; modus = 'melder-neu'; neuKlasse = zonenKlasse(); zeichneSheet(); planNeu(); return; }\n      else if (akt === 'grenze_setzen' && sel && hatZonen(sel)) { sel.grenze = grenzeVorschlag(sel); auswahl = { typ: 'grenze', id: sel.id }; modus = 'grenze'; neuGesetzt = null; }\n      else if (akt === 'grenze_weg' && sel && hatZonen(sel)) { delete sel.grenze; reiter.melder = 'zonen'; }\n      else if (akt === 'beste' && sel) {\n        rechnen(() => { beste = { bei: markOrt(), key: zustandKey(), erg: besteStelle(sel) }; markiert = null; zeichneSheet(); planNeu(); });\n        return;\n      }\n      geaendert();\n    }\n    sheet.addEventListener('click', klick);\n    $('#blatt').addEventListener('click', klick);\n    // L\u00E4ngere Rechnungen (Vorschlag, beste Stelle, mehrere Sekunden) mit Warteanzeige: erst zeichnen lassen, dann rechnen\n    // (Fernando 21.10.: man sah nicht, ob die Seite h\u00E4ngt). Der Kreis dreht per CSS-Transform auch, w\u00E4hrend das Skript rechnet.\n    let rechnet = false;\n    function rechnen(fn) {\n      if (rechnet) return;\n      rechnet = true;\n      const w = $('#warten'); w.hidden = false; melde(t('rechnet'));\n      requestAnimationFrame(() => requestAnimationFrame(() => setTimeout(() => {\n        try { fn(); } finally { w.hidden = true; rechnet = false; }\n        const n = sheet.querySelector('.notice'); if (n) melde([...n.children].map(e => e.textContent.trim()).join(' '));   // das Ergebnis vorlesen: \u201EPasst. Alle \u2026\u201C\n      }, 0)));\n    }\n    // F\u00FCr Screenreader: kurze Meldung in die Live-Region (erst leeren, sonst wird derselbe Text kein zweites Mal gelesen)\n    function melde(text) { const s = $('#status'); s.textContent = ''; setTimeout(() => { s.textContent = text; }, 50); }\n    $('#werkzeuge').addEventListener('click', e => { if (e.target.closest('[data-akt]')) klick(e); });\n    $('#link-knopf').addEventListener('click', klick);\n\n    // Beschriftungen der festen Kn\u00F6pfe\n    const knopfText = { '#svg': 'plan_label', '#menue-auf': 'menue', '#summe': 'auswahl_oeffnen', '[data-zoom=\"in\"]': 'zoom_in',\n      '[data-zoom=\"out\"]': 'zoom_out', '[data-zoom=\"fit\"]': 'zoom_fit', '#rueckgaengig': 'rueckgaengig', '#wiederholen': 'wiederholen',\n      '[data-akt=\"blattzu\"]': 'schliessen' };\n    for (const [s, k] of Object.entries(knopfText)) $(s).setAttribute('aria-label', t(k));\n    $('#summe .summe-weiter-text').textContent = t('zusammenfassung');\n    $('#warten-text').textContent = t('rechnet');\n    // Auf dem Handy das Teilen-Zeichen des Ger\u00E4ts (Kasten mit Pfeil nach oben), sonst die Kette (Fernando 23.10.)\n    $('#link-knopf .link-text').textContent = t(KANN_TEILEN ? 'link_teilen' : 'link_kopieren');\n    $('#link-knopf').setAttribute('aria-label', t(KANN_TEILEN ? 'link_teilen' : 'link_kopieren'));\n    if (KANN_TEILEN) $('#link-knopf svg').innerHTML = '<path d=\"M10 2.5v10M6.5 6 10 2.5 13.5 6M7 9H5v8.5h10V9h-2\"/>';\n    // Logo des Shops neben dem Men\u00FC, f\u00FChrt zur Startseite (Variante B hat keine Kopfzeile des Shops)\n    if (host.dataset.logo) {\n      const a = $('#logo');\n      a.href = LINKS.shop || '/'; a.hidden = false;\n      a.setAttribute('aria-label', t('zum_shop'));\n      a.querySelector('img').src = host.dataset.logo;\n    }\n\n    // H\u00F6he: im eigenen Seitenrahmen (Variante B, layout/raumplaner.liquid) der ganze Bildschirm. L\u00E4uft der\n    // Planer doch einmal im Theme-Rahmen, dann unter der Kopfzeile und \u00FCber der festen Leiste unten am Handy.\n    const LEISTE_UNTEN = '#stickymenu_bottom_mobile';\n    function hoeheSetzen() {\n      const oben = Math.max(0, host.getBoundingClientRect().top + window.scrollY);\n      const leiste = document.querySelector(LEISTE_UNTEN);\n      const unten = leiste && leiste.offsetHeight ? leiste.offsetHeight : 0;\n      host.style.setProperty('--sen-rp-hoehe', `calc(100dvh - ${Math.round(oben + unten)}px)`);\n    }\n    globaleListener();\n\n    // ---------- Start ----------\n    // Das Stylesheet im Shadow-DOM l\u00E4dt nachtr\u00E4glich; erst danach stimmen die Ma\u00DFe f\u00FCr einpassen().\n    const css = root.querySelector('link');\n    const los = () => {\n      hoeheSetzen();\n      const rueckweg = fbZurueck();   // vor laden(): stellt nach dem Senden der R\u00FCckmeldung den Plan in der Adresse wieder her\n      laden();\n      merken();\n      zeichneSheet();              // zuerst das Feld unten, damit einpassen() die echte Fl\u00E4che dar\u00FCber misst\n      einpassen();\n      zeichne();\n      if (!rueckweg) {\n        mess.t0 = Date.now(); mess.herkunft = location.hash.length > 1 && !ladeFehler ? 'link' : 'neu'; messBasis();\n        track('Raumplaner Start');\n      }\n      else if (fbErgebnis === 'ok') planMeldung(t('fb_gesendet'), 5000);\n      else blattAuf('menue');      // zeigt \u201ESenden ging nicht\u201C mit Link zur Kontaktseite\n    };\n    if (css.sheet) los(); else { css.addEventListener('load', los, { once: true }); css.addEventListener('error', los, { once: true }); }\n  }\n})();\n"],
  "mappings": "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",
  "names": ["d", "v", "b", "w", "z"]
}
