Android Radio Konfigurator: Unterschied zwischen den Versionen

Aus Wiki rund um Android-Navis für BMW E38/E39/E46/E53
Wechseln zu: Navigation, Suche
 
(15 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
<html><script>document.write("JS läuft");</script></html>
<big><big> '''Mit diesem Tool kann auf Basis von Fahrzeug und vorhandenen Komponenten eine Liste nötiger Komponenten erstellt werden.</big></big><br>
<big>Zu den gewählten Komponenten werden Links in den I-BUS Shop gezeigt und abschließend kann mit der Auswahl eine Anfrage-Mail an das I-BUS App Team gesendet werden.<br>'''</big>


<html><div id="nvk">
<html>
<div id="nvk">
<style>
<style>
#nvk{max-width:900px;line-height:1.45}
#nvk{max-width:900px;line-height:1.45}
#nvk *{box-sizing:border-box}
#nvk *{box-sizing:border-box}
#nvk .nvk-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:14px;margin:12px 0}
#nvk .nvk-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:14px;margin:12px 0}
#nvk .nvk-f label,#nvk .nvk-h{display:block;font-weight:700;margin-bottom:4px}
#nvk .nvk-f label{display:block;font-weight:700;margin-bottom:4px}
#nvk select{width:100%;padding:9px 8px;font:inherit;color:#202122;background:#fff;border:1px solid #a2a9b1;border-radius:4px}
#nvk select{width:100%;padding:9px 8px;font:inherit;color:#202122;background:#fff;border:1px solid #a2a9b1;border-radius:4px}
#nvk .nvk-help{font-size:.85em;opacity:.75;margin-top:3px}
#nvk fieldset{border:1px solid rgba(128,128,128,.45);border-radius:6px;padding:10px 14px;margin:14px 0}
#nvk fieldset{border:1px solid rgba(128,128,128,.45);border-radius:6px;padding:10px 14px;margin:14px 0}
#nvk legend{font-weight:700;padding:0 6px}
#nvk legend{font-weight:700;padding:0 6px}
Zeile 18: Zeile 21:
#nvk .nvk-card{border:1px solid rgba(128,128,128,.45);border-left:5px solid #36c;border-radius:4px;padding:9px 12px;margin:8px 0}
#nvk .nvk-card{border:1px solid rgba(128,128,128,.45);border-left:5px solid #36c;border-radius:4px;padding:9px 12px;margin:8px 0}
#nvk .nvk-card.opt{border-left-color:#14866d}
#nvk .nvk-card.opt{border-left-color:#14866d}
#nvk .nvk-card.rad{border-left-color:#fff;background:rgba(255,255,255,.08)}
#nvk .nvk-card b{display:block}
#nvk .nvk-card b{display:block}
#nvk .nvk-card a.nvk-shop{display:inline-block;margin-top:4px;font-weight:600}
#nvk .nvk-links{margin-top:4px;font-weight:600}
#nvk .nvk-links a{margin-right:14px}
#nvk .nvk-note{border:1px solid rgba(128,128,128,.45);border-left:5px solid #fc3;border-radius:4px;padding:9px 12px;margin:8px 0}
#nvk .nvk-note{border:1px solid rgba(128,128,128,.45);border-left:5px solid #fc3;border-radius:4px;padding:9px 12px;margin:8px 0}
#nvk .nvk-miss{opacity:.8;font-style:italic}
#nvk .nvk-miss{opacity:.8;font-style:italic}
#nvk .nvk-img{max-width:150px;max-height:110px;height:auto;margin:4px 8px 0 0;border:1px solid rgba(128,128,128,.4);border-radius:3px;background:#fff}
#nvk .nvk-card .nvk-img{max-width:230px;max-height:150px}
#nvk input[type=text],#nvk input[type=email],#nvk textarea{width:100%;padding:9px 8px;font:inherit;color:#202122;background:#fff;border:1px solid #a2a9b1;border-radius:4px}
#nvk .nvk-card.hl{border:2px solid #36c;border-left-width:8px;background:rgba(51,102,204,.12);padding:12px 14px}
#nvk .nvk-card.hl b{font-size:1.1em}
#nvk .nvk-row{display:flex;flex-wrap:wrap;gap:4px 12px;align-items:baseline;padding:2px 0;border-bottom:1px solid rgba(128,128,128,.3)}
#nvk .nvk-row label{flex:1;margin:0;min-width:240px}
#nvk .nvk-row a{white-space:nowrap;font-weight:600}
#nvk .nvk-img.wide{max-width:min(100%,460px);max-height:none}
#nvk #nvk-form{margin-top:22px}
</style>
</style>
<div class="nvk-grid" id="nvk-fields"></div>
<div class="nvk-grid" id="nvk-fields"></div>
<fieldset id="nvk-optset"><legend>Zusatzoptionen</legend><div id="nvk-opts"></div></fieldset>
<fieldset id="nvk-optset"><legend>Zusatzoptionen</legend><div id="nvk-opts"></div></fieldset>
<button type="button" class="nvk-btn" id="nvk-reset">Auswahl zurücksetzen</button>
<button type="button" class="nvk-btn" id="nvk-reset">Auswahl zurücksetzen</button>
<div id="nvk-out" aria-live="polite"></div>
<div id="nvk-out" aria-live="polite"></div>
<fieldset id="nvk-form" style="display:none"><legend>Anfrage senden</legend>
<p class="nvk-help">Deine Auswahl und die Liste oben werden automatisch mitgesendet. Alle Felder mit * sind Pflicht.</p>
<div class="nvk-grid">
<div class="nvk-f"><label for="nvk-name">Name *</label><input id="nvk-name" type="text" autocomplete="name"></div>
<div class="nvk-f"><label for="nvk-mail">E-Mail *</label><input id="nvk-mail" type="email" autocomplete="email"></div>
<div class="nvk-f"><label for="nvk-size">Gewünschte Displaygröße (optional)</label><select id="nvk-size"><option value="">Keine Angabe / Beratung gewünscht</option><option>7"</option><option>8.8"</option><option>9"</option><option>10.25"</option><option>12.3"</option><option>14.9"</option><option>Andere Größe (bitte im Kommentar nennen)</option></select><div class="nvk-help">Diagonale in Zoll. Nicht jede Größe gibt es für jede Baureihe, das prüfen wir für Dich.</div></div>
<div class="nvk-f"><label for="nvk-vin">VIN oder FGN (optional)</label><input id="nvk-vin" type="text" maxlength="17" placeholder="AB12345 oder 17-stellige FGN"></div>
</div>
<div class="nvk-f"><label for="nvk-msg">Kommentar *</label><textarea id="nvk-msg" rows="4"></textarea></div>
<div class="nvk-f" style="max-width:300px"><label for="nvk-cap" id="nvk-capq">Sicherheitsfrage *</label><input id="nvk-cap" type="text" inputmode="numeric"></div>
<input id="nvk-hp" type="text" tabindex="-1" autocomplete="off" aria-hidden="true" style="position:absolute;left:-9999px;width:1px">
<label class="nvk-o"><input type="checkbox" id="nvk-dsgvo"> Ich stimme zu, dass meine Angaben zur Bearbeitung der Anfrage per E-Mail verarbeitet werden.<span id="nvk-dslink"></span> *</label>
<button type="button" class="nvk-btn" id="nvk-send">Anfrage senden</button>
<div id="nvk-status" class="nvk-note" style="display:none"></div>
</fieldset>
<div id="nvk-legal" class="nvk-help" style="margin-top:20px"><b>Hinweis:</b> Der Konfigurator gibt eine unverbindliche Orientierung zu passenden Artikeln. Ausstattung und Anschlüsse können je nach Baujahr, Modell und Umbauten abweichen. Bitte gleiche Deine Auswahl vor der Bestellung mit Deinem Fahrzeug ab. Im Zweifel nutze die Anfrage-Funktion, wir prüfen die Zusammenstellung gern für Dich.<div id="nvk-legal-links" style="margin-top:4px"></div></div>
<noscript>Für den Konfigurator wird JavaScript benötigt.</noscript>
<noscript>Für den Konfigurator wird JavaScript benötigt.</noscript>
<script>
<script>
(function () {
(function () {
"use strict";
"use strict";
/* =====================================================================
/* =====================================================================
   KONFIGURATION – hier wird gepflegt. Kein weiterer Code nötig.
   KONFIGURATION - hier wird gepflegt.
  Textformat in Hinweisen: [b]fett[/b]  [br] Zeilenumbruch  [a=URL]Linktext[/a]
  Bitte im Skript KEIN kaufmännisches Und, kein Kleiner-/Größer-Zeichen
  und keine Leerzeilen verwenden (das Wiki wandelt sie um).
   ===================================================================== */
   ===================================================================== */
 
var SHOP = "https://shop.ibus-app.de/";
/* ---- 1) Auswahlfelder -------------------------------------------------
var WIKI = "https://wiki.ibus-app.de/index.php?title=";
   v = interner Wert, t = Anzeigetext,
/* Bilder aus dem Wiki (Thumbnail-Adressen; Klick öffnet automatisch das Originalbild) */
   only = Wert nur anbieten, wenn Bedingung passt (z. B. nur bestimmte Fahrzeuge)
var IM = "https://xtrons.ibus-app.de/images/thumb/";
   show = ganzes Feld nur zeigen, wenn Bedingung passt                      */
var P = {
  schema:  IM + "e/ea/BMW_E39_Verl%C3%A4ngerungen_EXL005%2BFAKRA_.png/135px-BMW_E39_Verl%C3%A4ngerungen_EXL005%2BFAKRA_.png",
  exl005:  IM + "7/70/Exl005-1.webp/257px-Exl005-1.webp.png",
  fakra6m: IM + "d/d8/FM-extension_01_1.png/270px-FM-extension_01_1.png",
  isofakra: IM + "4/4e/ISO-FAKRA_1.png/270px-ISO-FAKRA_1.png",
  bm24:    IM + "8/82/BM24.png/130px-BM24.png",
  iso:    IM + "d/dd/Iso.jpg/69px-Iso.jpg",
  bm54:    IM + "3/34/BM54.png/135px-BM54.png",
  fakra:  IM + "b/b3/Fakra.jpg/100px-Fakra.jpg",
  pfeil:  IM + "e/ee/Navi_E46.jpg/239px-Navi_E46.jpg",
  noquad:  IM + "6/68/No_elongation.jpg/180px-No_elongation.jpg",
  noexl6:  IM + "7/7b/No_EXL006.jpg/180px-No_EXL006.jpg",
  halter:  IM + "3/3b/Halter_Alu.webp/92px-Halter_Alu.webp.png",
  deepobd: "https://xtrons.ibus-app.de/images/d/d4/DeepOBD_Interface_1.png",
  n43:    IM + "e/e4/Navi4_3.jpg/240px-Navi4_3.jpg",
  n169:    IM + "8/8a/Navi16_9.jpg/240px-Navi16_9.jpg",
  radio:  IM + "9/96/E39_Radio.jpg/240px-E39_Radio.jpg",
  idrive:  "https://xtrons.ibus-app.de/images/0/02/MASK-CCC-CIC-NBT-EVO-iDrive.jpg",
  iris:    "https://xtrons.ibus-app.de/images/b/be/BusinessKas_IRISG.jpg",
  resler:  "https://xtrons.ibus-app.de/images/d/d1/Resler_Modul_01.png",
  can:    "https://xtrons.ibus-app.de/images/6/69/CAN_Interface.png",
  funktr:  IM + "7/7e/E46_Funktionstraeger.png/240px-E46_Funktionstraeger.png"
};
/* Anfrage-Formular: MAIL_TO = Empfänger. SEND_URL leer = E-Mail-Programm des Kunden öffnen (mailto).
  SEND_URL = Adresse des Server-Skripts send-anfrage.php = Versand direkt vom Server (mit CC an den Kunden). */
var MAIL_TO = "info@ibus-app.de";
var MAIL_SUBJECT = "Anfrage aus Android Radio Konfigurator";
var SEND_URL = "https://xtrons.ibus-app.de/send-anfrage.php";
/* Shop-Anbindung: API = radios.php (liefert Radio-Liste und Artikelnummern). Warenkorb = Shopware-Link pro Artikelnummer. */
var API = "https://xtrons.ibus-app.de/radios.php";
/* CART_TRANSFER = true: Warenkorb-Button öffnet den Shop mit ?nvk=ARTIKELNUMMERN. Das funktioniert nur, wenn im Shop das Skript shop-warenkorb-uebergabe.js eingebunden ist. */
var CART_TRANSFER = true;
var CART = "https://shop.ibus-app.de/checkout/cart";
/* Rechtliche Seiten (Links unter dem Konfigurator und beim Datenschutz-Haken). Leer = Link wird nicht angezeigt. */
var LEGAL = { agb: "https://shop.ibus-app.de/allgemeine-geschaeftsbedingungen", widerruf: "https://shop.ibus-app.de/widerrufsrecht", datenschutz: "https://shop.ibus-app.de/datenschutz" };
/* ---- 1) Baureihen --------------------------------------------------------
   v = Shop-Kategorie (Link: SHOP + bmw-radios/ + v + /)
  gen: alt = I-BUS-Fahrzeuge (E38/E39/E46/E53/E83)
        b  = M-ASK / CCC / CIC    c = CIC / NBT / NBT EVO
  body = Karosserieformen (siehe BODY)                                      */
var BODY = { limo: "Limousine", touring: "Touring", coupe: "Coupé", cabrio: "Cabrio", schraeg: "Schrägheck",
  compact: "Compact", gt: "Gran Turismo", gc: "Gran Coupé", suv: "SUV / SAV", roadster: "Roadster" };
var VEHICLES = [
  { v: "1er-e8x", t: "1er E8x", gen: "b", body: "schraeg,coupe,cabrio" },
  { v: "1er-f2x", t: "1er F2x", gen: "c", body: "schraeg" },
  { v: "2er-f2x", t: "2er F2x", gen: "c", body: "coupe,cabrio" },
  { v: "3er-e46", t: "3er E46", gen: "alt", body: "limo,touring,coupe,cabrio,compact" },
  { v: "3er-e9x", t: "3er E9x", gen: "b", body: "limo,touring,coupe,cabrio" },
  { v: "3er-f3x", t: "3er F3x", gen: "c", body: "limo,touring,gt" },
  { v: "4er-f3x", t: "4er F3x", gen: "c", body: "coupe,cabrio,gc" },
  { v: "5er-e39", t: "5er E39", gen: "alt", body: "limo,touring" },
  { v: "5er-e6x", t: "5er E6x", gen: "b", body: "limo,touring" },
  { v: "5er-f1x", t: "5er F1x", gen: "c", body: "limo,touring,gt" },
  { v: "6er-e6x", t: "6er E6x", gen: "b", body: "coupe,cabrio" },
  { v: "7er-e38", t: "7er E38", gen: "alt", body: "limo" },
  { v: "7er-e65", t: "7er E65", gen: "b", body: "limo" },
  { v: "7er-f01", t: "7er F01", gen: "c", body: "limo" },
  { v: "x1-e84", t: "X1 E84", gen: "c", body: "suv" },
  { v: "x1-f48", t: "X1 F48", gen: "c", body: "suv" },
  { v: "x3-e83", t: "X3 E83", gen: "alt", body: "suv" },
  { v: "x3-f25", t: "X3 F25", gen: "c", body: "suv" },
  { v: "x5-e53", t: "X5 E53", gen: "alt", body: "suv" },
  { v: "x5-e70", t: "X5 E70", gen: "b", body: "suv" },
  { v: "x5-f15", t: "X5 F15", gen: "c", body: "suv" },
  { v: "x6-e71", t: "X6 E71", gen: "b", body: "suv" },
  { v: "z4-e85e86", t: "Z4 E85/E86", gen: "b", body: "roadster,coupe" },
  { v: "z4-e89", t: "Z4 E89", gen: "c", body: "roadster", noCat: true }
];
/* Fahrzeuge mit K-CAN App (Beta) */
var KCAN = ["1er-e8x", "3er-e9x", "5er-e6x", "6er-e6x", "7er-e65", "x1-e84", "x5-e70", "x6-e71", "z4-e89"];
var bodyValues = Object.keys(BODY).map(function (k) {
  return { v: k, t: BODY[k], only: { vehicle: VEHICLES.filter(function (x) { return x.body.split(",").indexOf(k) !== -1; }).map(function (x) { return x.v; }) } };
});
/* ---- 2) Auswahlfelder ------------------------------------------------------
   only = Wert nur anbieten, wenn Bedingung passt   show = Feld nur dann zeigen
   optional = muss nicht gewählt werden            auto = bei nur einem Wert vorwählen */
var FIELDS = [
var FIELDS = [
   { id: "vehicle", label: "Fahrzeug", values: [
   { id: "vehicle", label: "Fahrzeug", values: VEHICLES.map(function (x) { return { v: x.v, t: "BMW " + x.t }; }) },
     { v: "E38", t: "BMW E38" }, { v: "E39", t: "BMW E39" }, { v: "E46", t: "BMW E46" },
  { id: "factory", label: "Verbaut ab Werk", pre: { when: { gen: ["b", "c"] }, html: "[b]So erkennst Du Dein System:[/b][br][imgw=" + P.idrive + "]" }, values: [
     { v: "E53", t: "BMW E53" }, { v: "E83", t: "BMW E83" } ] },
     { v: "iris", t: "Radio mit IRIS", only: { vehicle: ["3er-e46", "5er-e39", "7er-e38", "x5-e53"] }, info: "[img=" + P.iris + "]" },
 
    { v: "mid",   t: "Radio mit MID", only: { gen: ["alt"] }, info: "[img=" + P.radio + "]" },
  { id: "factory", label: "Verbaut ab Werk", values: [
     { v: "n43",   t: "4:3 Navi",      only: { vehicle: ["5er-e39", "7er-e38"] }, info: "[img=" + P.n43 + "]" },
     { v: "iris",  t: "Radio mit IRIS" },
    { v: "n169", t: "16:9 Navi",      only: { gen: ["alt"] }, info: "[img=" + P.n169 + "]" },
     { v: "mid",  t: "Radio mit MID" },
    { v: "pfeil", t: "Pfeilnavi",     only: { vehicle: ["3er-e46"] }, info: "[img=" + P.pfeil + "]" },
     { v: "n43",  t: "4:3 Navi", only: { vehicle: ["E38", "E39"] } },
     { v: "mask",  t: "M-ASK",          only: { gen: ["b"] } },
     { v: "n169", t: "16:9 Navi" },
     { v: "ccc",  t: "CCC",            only: { gen: ["b"] } },
     { v: "pfeil", t: "Pfeilnavi", only: { vehicle: ["E46"] } } ] },
     { v: "cic",  t: "CIC",           only: { gen: ["b", "c"] } },
 
     { v: "nbt",   t: "NBT",            only: { gen: ["c"] } },
   { id: "trunk", label: "Befindet sich im Kofferraum ein Radiomodul?",
     { v: "nbtevo", t: "NBT EVO",       only: { gen: ["c"] } } ] },
    show: { factory: ["pfeil"] }, values: [
   { id: "trunk", label: "Wo sitzt das Radiomodul des Pfeilnavis?", optional: true, show: { factory: ["pfeil"] },
     { v: "ja", t: "Ja, Radio-/Navimodul im Kofferraum" },
    help: "Bitte prüfen: Sitzt das Modul im Kofferraum, oder im Pfeilnavi selbst (Quadlock hinten neben dem Antennenstecker)?[br][img=" + P.pfeil + "]",
     { v: "nein", t: "Nein, Anschlüsse nur hinter dem Radio" },
    values: [
     { v: "ja", t: "Im Kofferraum (Verlängerungen nötig)" },
     { v: "nein", t: "Im Pfeilnavi, Quadlock hinten (keine Verlängerung)" },
     { v: "unk", t: "Weiß ich nicht" } ] },
     { v: "unk", t: "Weiß ich nicht" } ] },
 
  { id: "aux", label: "AUX-IN verfügbar?", show: { gen: ["b", "c"] }, values: [
    { v: "ja", t: "Ja" }, { v: "nein", t: "Nein" } ] },
   { id: "sound", label: "Soundsystem", values: [
   { id: "sound", label: "Soundsystem", values: [
     { v: "stereo", t: "Stereo" },
     { v: "stereo", t: "Stereo" },
     { v: "hifi",  t: "Hifi" },
     { v: "hifi",  t: "Hifi" },
     { v: "dsp",    t: "DSP",         only: { vehicle: ["E38", "E39", "E53"] } },
     { v: "dsp",    t: "DSP", only: { vehicle: ["7er-e38", "5er-e39", "x5-e53", "x3-e83"] }, info: "[a=" + WIKI + "Habe_ich_DSP%3F]Habe ich DSP?[/a]" },
     { v: "hk",    t: "Harman Kardon", only: { vehicle: ["E46", "E83"] } } ] },
     { v: "hk",    t: "Harman Kardon", only: { vehicle: ["3er-e46", "z4-e85e86"] } },
 
    { v: "logic7", t: "Logic7", only: { vehicle: ["3er-e9x", "5er-e6x", "6er-e6x", "7er-e65", "1er-e8x"] } },
    { v: "hksur",  t: "Harman Kardon Surround", only: { vehicle: ["1er-f2x", "2er-f2x", "3er-f3x", "4er-f3x", "5er-f1x"] } } ] },
   { id: "current", label: "Aktuell verbaut", values: [
   { id: "current", label: "Aktuell verbaut", values: [
     { v: "werk", t: "Werksradio / Werksnavi" },
     { v: "werk", t: "Werksradio / Werksnavi" },
     { v: "nach", t: "Nachrüst-Radio / -Navi" } ] },
     { v: "nach", t: "Nachrüst-Radio / -Navi" } ] },
 
   { id: "body", label: "Karosserie", auto: true, values: bodyValues },
   { id: "body", label: "Karosserie", values: [
  { id: "ant", label: "Antennenstecker am Radio (optional)", optional: true, def: "unk",
    { v: "limo",   t: "Limousine", only: { vehicle: ["E38", "E39", "E46"] } },
     show: { vehicle: ["7er-e38", "5er-e39", "3er-e46", "x5-e53"] },
     { v: "touring", t: "Touring",   only: { vehicle: ["E39", "E46"] } },
    values: [
     { v: "coupe",  t: "Coupé",     only: { vehicle: ["E46"] } },
     { v: "unk",  t: "Weiß ich nicht", info: "[b]BM24[/b] (Rundpin) = ISO-Antennenstecker:[br][img=" + P.bm24 + "][img=" + P.iso + "][br][b]BM54[/b] = FAKRA:[br][img=" + P.bm54 + "][img=" + P.fakra + "]" },
    { v: "cabrio",  t: "Cabrio",    only: { vehicle: ["E46"] } },
     { v: "iso",   t: "ISO (BM24, Rundpin)", info: "[img=" + P.bm24 + "][img=" + P.iso + "]" },
     { v: "suv",     t: "SUV",       only: { vehicle: ["E53", "E83"] } } ] },
     { v: "fakra", t: "FAKRA (BM54)", info: "[img=" + P.bm54 + "][img=" + P.fakra + "]" } ] }
 
  { id: "ant", label: "Antennenstecker am Radio (optional)", optional: true, def: "unk", values: [
    { v: "unk",  t: "Weiß ich nicht" },
     { v: "iso",   t: "ISO (rund, „BM24“)" },
    { v: "fakra", t: "FAKRA (eckig, „BM54“)" } ] }
];
];
 
/* ---- 3) Zusatzoptionen (Mehrfachauswahl) ---------------------------------
/* ---- 2) Zusatzoptionen (Mehrfachauswahl) -----------------------------
   show = nur sichtbar wenn Bedingung passt   requires = nur sichtbar wenn diese Optionen gewählt sind
   show     = Option nur sichtbar, wenn Bedingung passt
   excl = Optionen derselben Gruppe schließen sich aus   items = Artikel aus ITEMS */
  requires = Option nur sichtbar, wenn diese anderen Optionen gewählt sind
   excl     = Optionen mit gleicher excl-Gruppe schließen sich gegenseitig aus
  item    = Eintrag in ITEMS, der in der Liste erscheint                  */
var OPTS = [
var OPTS = [
   { id: "halter",  t: "Radio-Halter", sub: "nur BMW E39", show: { vehicle: ["E39"] }, item: "halter" },
   { id: "halter",  t: "Radio-Halter", sub: "nur BMW E39", show: { vehicle: ["5er-e39"] }, items: ["halter"] },
   { id: "ibus",    t: "I-BUS App", item: "ibus" },
   { id: "ibus",    t: "I-BUS App", show: { gen: ["alt"] }, items: ["ibus", "resler", "bclic"] },
   { id: "deepobd", t: "DeepOBD (Diagnose)", item: "deepobd" },
   { id: "deepobd", t: "DeepOBD (Diagnose)", items: ["deepobd"] },
   { id: "can",    t: "CAN Interface", sub: "Addon – nur mit I-BUS App", requires: ["ibus"], item: "can" },
   { id: "can",    t: "CAN Interface", sub: "Addon - nur mit I-BUS App", show: { gen: ["alt"] }, requires: ["ibus"], items: ["can"] },
   { id: "tpms",    t: "TPMS (Reifendruck)", item: "tpms" },
  { id: "kcan",    t: "K-CAN App (Beta)", sub: "Pendant zur I-BUS App", show: { vehicle: KCAN }, items: ["kcan", "kcanlic", "can"] },
   { id: "dab1",    t: "DAB+ (Single Receiver)", excl: "dab", item: "dab1" },
   { id: "tpms",    t: "TPMS (Reifendruck)", items: ["tpms"] },
   { id: "dab2",    t: "DAB+ (Dual Receiver)",  excl: "dab", item: "dab2" },
   { id: "dab1",    t: "DAB+ (Single Receiver)", excl: "dab", items: ["dab1"] },
   { id: "rcam",    t: "Rückfahrkamera", item: "rcam" },
   { id: "dab2",    t: "DAB+ (Dual Receiver)",  excl: "dab", items: ["dab2"] },
   { id: "fcam",    t: "Front-Kamera", item: "fcam" },
   { id: "rcam",    t: "Rückfahrkamera", items: ["rcam"] },
   { id: "tool",    t: "Einbau-Werkzeug (Kunststoffheber)", item: "tool" }
   { id: "fcam",    t: "Front-Kamera", items: ["fcam"] },
   { id: "tool",    t: "Einbau-Werkzeug (Kunststoffheber)", items: ["tool"] }
];
];
 
/* Erzwungene Optionen (werden automatisch gesetzt und gesperrt) */
/* Wird eine Option durch eine Auswahl erzwungen, wird sie automatisch gesetzt. */
var FORCED = [
var FORCED = [
   { when: { sound: ["dsp"] }, opts: ["ibus"], why: "wegen DSP erforderlich" }
   { when: { sound: ["dsp"] }, opts: ["ibus"], why: "wegen DSP erforderlich" }
];
];
 
/* ---- 4) Artikel ------------------------------------------------------------
/* ---- 3) Artikel/Produkte ---------------------------------------------
   u = Shop-Link (ut = Linktext)  w = Wiki-Link (wt = Linktext)  leer = kein Link
   u = Link in den Shop (leer lassen = Eintrag ohne Link)                  */
  skipIf = Artikel entfällt, wenn der genannte Artikel schon in der Liste steht */
var ITEMS = {
var ITEMS = {
   exl005:  { t: "Verlängerung EXL005", d: "Ersetzt das Radiomodul im Kofferraum (Bus-/Stromanschluss nach vorn).",
   exl005:  { t: "Verlängerung EXL005", d: "Ersetzt das Radiomodul im Kofferraum.", u: SHOP + "detail/index/sArticle/212/", img: [P.exl005, P.schema] },
            u: "https://shop.ibus-app.de/detail/index/sArticle/212/" },
   fakra6m: { t: "Verlängerung 6 m FAKRA(m) auf FAKRA(f), gewinkelt", d: "Antennenverlängerung vom Kofferraum nach vorn.", img: [P.fakra6m],
   fakra6m: { t: "Verlängerung 6 m FAKRA(m) auf FAKRA(f), gewinkelt", d: "Antennenverlängerung vom Kofferraum nach vorn.",
             u: SHOP + "shop/zubehoer/adapterkabel/192/verlaengerung-6m-fakra-m-auf-fakra-f-kurz-gewinkelt" },
             u: "https://shop.ibus-app.de/shop/zubehoer/adapterkabel/192/verlaengerung-6m-fakra-m-auf-fakra-f-kurz-gewinkelt" },
   isoada:  { t: "Adapter ISO-Stecker auf FAKRA, gewinkelt (15 cm)", d: "Nötig bei ISO-Antennenstecker (BM24, Rundpin).", img: [P.isofakra],
   isoada:  { t: "Adapter ISO-Stecker auf FAKRA, gewinkelt (15 cm)", d: "Nötig, wenn das Fahrzeug einen ISO-Antennenstecker hat.",
             u: SHOP + "shop/zubehoer/adapterkabel/193/adapter-kabel-iso-f-auf-fakra-f-kurz-gewinkelt-15cm" },
             u: "https://shop.ibus-app.de/shop/zubehoer/adapterkabel/193/adapter-kabel-iso-f-auf-fakra-f-kurz-gewinkelt-15cm" },
   bcdsp:   { t: "I-BUS App - BC+DSP Lizenz", d: "Ohne DSP-Lizenz arbeitet das Werks-DSP nicht.",
   dsplic: { t: "DSP-Lizenz für die I-BUS App", d: "Ohne diese Lizenz arbeitet das Werks-DSP nicht.", u: "" },
            u: SHOP + "i-bus-app/lizenzen/171/i-bus-app-bc-dsp-lizenz",
   halter:  { t: "Halter zur Radio-Montage im BMW E39", d: "Empfohlen bei Radios, die nicht von AVIN stammen.",
            w: WIKI + "Habe_ich_DSP%3F", wt: "Wiki: Habe ich DSP?" },
             u: "https://shop.ibus-app.de/shop/zubehoer/182/halter-zur-radio-montage-im-bmw-e39" },
   halter:  { t: "Alu-Halter zur Radio-Montage im BMW E39", d: "Empfohlen bei Radios, die nicht von AVIN stammen.", img: [P.halter],
   ibus:    { t: "I-BUS App", d: "Erhält Bordcomputer-Funktionen und steuert z. B. den Original-CD-Wechsler.",
             u: SHOP + "i-bus-app/zubehoer/radiohalter/185/alu-halter-zur-radio-montage-im-bmw-e39" },
             u: "http://www.ibus-app.de" },
   ibus:    { t: "I-BUS App", hl: true,
   deepobd: { t: "DeepOBD (Diagnose)", d: "Live-Werte auslesen, Fehler lesen und löschen.", u: "" },
            d: "Die I-BUS App ist eine Android Applikation, die dazu dient Ihren Bordcomputer auf einem Android Gerät darzustellen und in Ihrem Fahrzeug viele Comfort-/Codierfunktionen integriert. Der Download der App ist kostenlos und es kann eine Verbindung zum Interface/Modul hergestellt werden. Um alle Funktionen der App nutzen zu können, wird eine I-BUS App Lizenz benötigt.",
   can:    { t: "CAN Interface (Addon zur I-BUS App)", d: "Funktioniert nur zusammen mit der I-BUS App.", u: "" },
            u: SHOP + "cat/index/sCategory/42",
   tpms:    { t: "TPMS – Reifendruckanzeige", d: "", u: "https://xtrons.co.uk/tyre-pressure-monitoring-system-tpms01" },
            links: [
   dab1:    { t: "DAB+ Single Receiver", d: "", u: "https://xtrons.co.uk/dab-tuner-usbdab01" },
              { u: WIKI + "Was_brauche_ich_um_die_I-BUS_App_nutzen_zu_k%C3%B6nnen%3F", t: "Wiki: Was brauche ich für die I-BUS App?" },
   dab2:    { t: "DAB+ Dual Receiver", d: "", u: "" },
              { u: WIKI + "Funktionen", t: "Liste aller I-BUS App Funktionen (BMW E38|E39|E46|E53|E83)" },
   rcam:    { t: "Rückfahrkamera", d: "", u: "" },
              { u: WIKI + "Was_geht_beim_BMW_E46_nicht", t: "Was geht beim BMW E46, E83, E85,.. nicht? (da werkseitig nicht verbaut)" },
   fcam:    { t: "Front-Kamera", d: "", u: "" },
              { u: WIKI + "Funktionseinschr%C3%A4nkungen_nach_Baujahr/Ausstattung/Modell", t: "Funktionseinschränkungen nach Baujahr/Ausstattung/Modell" } ] },
   tool:    { t: "Einbau-Werkzeug (Kunststoffheber)", d: "Zum schonenden Lösen der Verkleidungen.", u: "" }
  resler:  { t: "Resler USB I-BUS Modul inkl. Anschlusskabel", d: "Verbindet I-BUS App und Fahrzeug.", img: [P.resler],
            u: SHOP + "i-bus-app/zubehoer/interfaces-module/191/resler-usb-i-bus-modul-inkl.-anschlusskabel",
             w: "https://wiki.ibus-app.de/index.php?title=Hauptseite#Einbauanleitung_f.C3.BCr_Resler_Modul_und_Resler_Interface", wt: "Einbauanleitung Resler Modul" },
  bclic:  { t: "I-BUS App - BC Lizenz", d: "Schaltet u. a. die BC-Daten der App frei.", skipIf: "bcdsp",
            u: SHOP + "i-bus-app/lizenzen/167/i-bus-app-bc-lizenz" },
   deepobd: { t: "Deep OBD OBD-II Bluetooth-Adapter", d: "Live-Werte auslesen, Fehler lesen und löschen.", img: [P.deepobd],
            u: SHOP + "i-bus-app/zubehoer/interfaces-module/258/deep-obd-obd-ii-bluetooth-adapter?c=54",
            w: "https://xtrons.ibus-app.de/index.php?title=DeepOBD_-_Adapter_und_App_einrichten", wt: "Wiki: DeepOBD einrichten" },
   can:    { t: "CAN-Bus Interface inkl. Anschlusskabel", d: "Addon, funktioniert nur zusammen mit der I-BUS App bzw. der K-CAN App.", img: [P.can],
            u: SHOP + "i-bus-app/zubehoer/interfaces-module/346/can-bus-interface-inkl.-anschlusskabel",
            w: WIKI + "Einbauanleitung_CAN-Bus_Interface", wt: "Einbauanleitung CAN-Bus Interface" },
   kcan:    { t: "K-CAN App (Beta)", d: "Pendant zur I-BUS App für Fahrzeuge mit K-CAN, aktuell als Betaversion.",
            w: "https://wiki.kcan-app.de/", wt: "Wiki zur K-CAN App" },
  kcanlic: { t: "K-CAN App - Lizenz Betaversion", d: "Beta-Lizenz für die K-CAN App.",
            u: SHOP + "i-bus-app/lizenzen/358/k-can-app-lizenz-betaversion" },
  tpms:    { t: "TPMS - Reifendruckkontrolle", d: "", u: SHOP + "radiozubehoer/tpms/" },
   dab1:    { t: "DAB+ Empfänger inkl. Antenne (Single)", d: "", w: "https://xtrons.ibus-app.de/index.php?title=Installation_der_DAB%2B_Antenne", wt: "Installation der DAB+ Antenne", u: SHOP + "radiozubehoer/dab/291/dab-empfaenger-inkl.-antenne-usbdab04" },
   dab2:    { t: "Dual DAB+ Empfänger-Stick inkl. 2 Antennen", d: "", w: "https://xtrons.ibus-app.de/index.php?title=Installation_der_DAB%2B_Antenne", wt: "Installation der DAB+ Antenne", u: SHOP + "radiozubehoer/dab/391/dual-dab-empfaenger-stick-inkl.-2-antennen-acusbdab05t?c=75" },
   rcam:    { t: "Rückfahrkamera", d: "", u: SHOP + "radiozubehoer/kameras/", ut: "Kameras im Shop ansehen →" },
   fcam:    { t: "Front-Kamera", d: "", u: SHOP + "radiozubehoer/kameras/", ut: "Kameras im Shop ansehen →" },
   tool:    { t: "Einbau-Werkzeug (Kunststoffheber)", d: "Zum schonenden Lösen der Verkleidungen.", u: SHOP + "radiozubehoer/einbauwerkzeug/" }
};
};
 
/* ---- 5) Regeln --------------------------------------------------------------
/* ---- 4) Regeln --------------------------------------------------------
   type: need (Das brauchst Du) oder hint (Hinweise)   when = Bedingung auf die Felder
   type = "need" (Das brauchst Du) | "hint" (Hinweise)
   opts = diese Zusatzoptionen müssen gewählt sein     items = Artikel   html = Text
  when = Bedingung auf die Auswahlfelder (alle Schlüssel müssen passen)
  Abgeleitete Werte: gen (alt/b/c) und module (ja/nein/unk = Radiomodul im Kofferraum, nur gen alt) */
   opts = (optional) diese Zusatzoptionen müssen gewählt sein
  items = Artikel aus ITEMS      html = Hinweistext (HTML erlaubt)
  Abgeleiteter Wert "module": ja = Radiomodul im Kofferraum, nein = nicht, unk = unklar */
var RULES = [
var RULES = [
   { type: "need", when: { current: ["werk"], module: ["ja"] }, items: ["exl005", "fakra6m"] },
   { type: "need", when: { current: ["werk"], module: ["ja"] }, items: ["exl005", "fakra6m"] },
   { type: "hint", when: { current: ["nach"], module: ["ja"] },
   { type: "hint", when: { current: ["nach"], module: ["ja"] },
     html: "<b>Verlängerungen prüfen:</b> Bei einem bereits verbauten Nachrüst-Radio sollten EXL005 und FAKRA-Verlängerung schon vorhanden sein. <b>Ungeeignet</b> sind die Standard-„Quad-Lock-Verlängerung kombiniert mit Antennenverlängerung“ und die „EXL006“ (kein BUS-Signal)." },
     html: "[b]Verlängerungen prüfen:[/b] Bei einem bereits verbauten Nachrüst-Radio sollten EXL005 und FAKRA-Verlängerung schon vorhanden sein. [b]Ungeeignet[/b] sind die Standard-Quad-Lock-Verlängerung kombiniert mit Antennenverlängerung und die EXL006 (kein BUS-Signal).[br][img=" + P.noquad + "][img=" + P.noexl6 + "]" },
   { type: "hint", when: { module: ["ja"] },
   { type: "hint", when: { module: ["ja"] },
     html: "<b>Kabelwege:</b> Die Technik sitzt im Kofferraum. Es müssen mindestens Kabel für Radioanschluss und FM-Antenne nach vorn verlegt werden. Optional zusätzlich: GPS (OEM-Antenne), Verlängerung für DAB+, Anschluss OEM-CD-Wechsler, Cinch für Subwoofer." },
     html: "[b]Kabelwege:[/b] Die Technik sitzt im Kofferraum. Mindestens Radioanschluss und FM-Antenne müssen nach vorn verlegt werden. Optional zusätzlich: GPS (OEM-Antenne), Verlängerung für DAB+, Anschluss OEM-CD-Wechsler, Cinch für Subwoofer." },
   { type: "hint", when: { module: ["nein"] },
   { type: "hint", when: { module: ["nein"] },
     html: "<b>Kabelwege:</b> Alle Anschlüsse befinden sich direkt hinter dem Radio, es müssen <b>keine</b> Kabel verlegt werden. Optional ggf. für: GPS (OEM-Antenne), DAB+, OEM-CD-Wechsler, Cinch für Subwoofer." },
     html: "[b]Kabelwege:[/b] Alle Anschlüsse befinden sich direkt hinter dem Radio, es müssen [b]keine[/b] Kabel verlegt werden. Optional ggf. für: GPS (OEM-Antenne), DAB+, OEM-CD-Wechsler, Cinch für Subwoofer." },
   { type: "hint", when: { module: ["unk"] },
   { type: "hint", when: { module: ["unk"] },
     html: "<b>Bitte prüfen:</b> Schau nach, ob im Kofferraum ein Radiomodul sitzt. Manche E46 mit Pfeilnavi (vermutlich Vorfacelift) haben das Radio hinten und benötigen dann EXL005 + FAKRA-Verlängerung." },
     html: "[b]Bitte prüfen:[/b] Schau nach, ob im Kofferraum ein Radiomodul sitzt. Bei E46 mit Pfeilnavi gibt es zwei Varianten: Radiomodul im Kofferraum = EXL005 und FAKRA-Verlängerung nötig. Radiomodul im Pfeilnavi (Quadlock hinten neben dem Antennenstecker) = keine Verlängerung nötig." },
 
   { type: "need", when: { ant: ["iso"] }, items: ["isoada"] },
   { type: "need", when: { ant: ["iso"] }, items: ["isoada"] },
   { type: "hint", when: { ant: ["unk"] },
   { type: "hint", when: { ant: ["unk"] },
     html: "<b>Antennenstecker:</b> Hat Dein Fahrzeug einen ISO-Antennenstecker, brauchst Du zusätzlich den <a href='https://shop.ibus-app.de/shop/zubehoer/adapterkabel/193/adapter-kabel-iso-f-auf-fakra-f-kurz-gewinkelt-15cm'>Adapter ISO auf FAKRA</a>. Bei FAKRA ist kein Adapter nötig." },
     html: "[b]Antennenstecker:[/b] [b]BM24[/b] (Rundpin) = ISO-Antennenstecker, ggf. wird der [a=" + SHOP + "shop/zubehoer/adapterkabel/193/adapter-kabel-iso-f-auf-fakra-f-kurz-gewinkelt-15cm]Adapter ISO auf FAKRA[/a] nötig. [b]BM54[/b] = FAKRA, kein Adapter nötig." },
 
   { type: "need", when: { sound: ["dsp"] }, items: ["bcdsp"] },
   { type: "need", when: { sound: ["dsp"] }, items: ["dsplic"] },
   { type: "hint", when: { sound: ["dsp"] },
   { type: "hint", when: { sound: ["dsp"] },
     html: "<b>DSP:</b> Damit das Werks-DSP überhaupt arbeitet, wird die I-BUS App mit DSP-Lizenz benötigt." },
     html: "[b]DSP:[/b] Damit das Werks-DSP überhaupt arbeitet, wird die I-BUS App mit BC+DSP Lizenz benötigt. Ob Dein Fahrzeug ein DSP hat: [a=" + WIKI + "Habe_ich_DSP%3F]Habe ich DSP?[/a]" },
   { type: "hint", when: { sound: ["hk"] },
   { type: "hint", when: { sound: ["hk"], gen: ["alt"] },
     html: "<b>Harman Kardon:</b> Benötigt <b>keine</b> DSP-Lizenz. Das Remote-Signal (+12 V, wenn Radio an) genügt zum Starten." },
     html: "[b]Harman Kardon:[/b] Benötigt [b]keine[/b] DSP-Lizenz. Das Remote-Signal (+12 V, wenn Radio an) genügt zum Starten." },
 
  { type: "hint", when: { aux: ["nein"] },
   { type: "hint", when: { vehicle: ["E38", "E53"] },
    html: "[b]AUX-IN:[/b] Der AUX-IN muss codiert werden. Optional kann ein FM-Transmitter genutzt werden - das ist nicht empfohlen." },
     html: "<b>Montage:</b> Radios für BMW E38/E53 benötigen keine extra Halterungen." },
   { type: "hint", when: { vehicle: ["7er-e38", "x5-e53"] },
   { type: "hint", when: { vehicle: ["E39"] },
     html: "[b]Montage:[/b] Radios für BMW E38/E53 benötigen keine extra Halterungen." },
     html: "<b>Montage:</b> Bei Radios, die nicht von AVIN stammen, empfehlen wir einen Halter (siehe Zusatzoptionen) oder das Bearbeiten der beiliegenden Montagewinkel. Anleitungen: <a href='https://xtrons.ibus-app.de/index.php?title=Montageanleitungen'>Montageanleitungen</a>." },
   { type: "hint", when: { vehicle: ["5er-e39"] },
   { type: "hint", when: { vehicle: ["E46"], factory: ["iris", "mid", "pfeil"], current: ["werk"] },
     html: "[b]Montage:[/b] Bei Radios, die nicht von AVIN stammen, empfehlen wir einen Halter (siehe Zusatzoptionen) oder das Bearbeiten der beiliegenden Montagewinkel. Anleitungen: [a=https://xtrons.ibus-app.de/index.php?title=Montageanleitungen]Montageanleitungen[/a]." },
     html: "<b>Montage E46 ohne großes Navi:</b> Das Klimabedienteil muss nach unten versetzt werden. Dafür brauchst Du den passenden <b>Funktionsträger</b> (neu ca. 100 €, ggf. beim Teileverwerter günstiger):<br>" +
   { type: "hint", when: { vehicle: ["3er-e46"], factory: ["iris", "mid", "pfeil"], current: ["werk"] },
           "Einzelschalter (eher VFL): <a href='https://www.leebmann24.de/trager-3er-51168202186.html'>ohne Raucher 51168202186</a> / <a href='https://www.leebmann24.de/trager-3er-51168230902.html'>mit Raucher 51168230902</a><br>" +
     html: "[b]Montage E46 ohne großes Navi:[/b] Das Klimabedienteil muss nach unten versetzt werden. Dafür brauchst Du den passenden [b]Funktionsträger[/b] (neu ca. 100 €, ggf. beim Teileverwerter günstiger):[br]" +
           "Schaltzentrum (eher FL): <a href='https://www.leebmann24.de/funktionstrager-schaltzentrum-3er-51167001408.html'>ohne Raucher 51167001408</a> / <a href='https://www.leebmann24.de/funktionstrager-schaltzentrum-3er-51167001410.html'>mit Raucher 51167001410</a>" },
           "Einzelschalter (eher VFL): [a=https://www.leebmann24.de/trager-3er-51168202186.html]ohne Raucher 51168202186[/a] / [a=https://www.leebmann24.de/trager-3er-51168230902.html]mit Raucher 51168230902[/a][br]" +
 
           "Schaltzentrum (eher FL): [a=https://www.leebmann24.de/funktionstrager-schaltzentrum-3er-51167001408.html]ohne Raucher 51167001408[/a] / [a=https://www.leebmann24.de/funktionstrager-schaltzentrum-3er-51167001410.html]mit Raucher 51167001410[/a][br][img=" + P.funktr + "]" },
  { type: "hint", when: { factory: ["cic", "nbt", "nbtevo"] },
    html: "[b]Lichtleiter:[/b] Ggf. vorhandene Lichtleiter (MOST) müssen aus dem BMW-Stecker in den Xtrons-Adapter umgesteckt werden." },
  { type: "hint", when: { factory: ["mask", "ccc", "cic", "nbt", "nbtevo"] },
    html: "[b]Originales Radiomodul bleibt erhalten:[/b] Bei M-ASK, CCC, CIC, NBT und NBT EVO bleibt das originale Radiomodul im Fahrzeug und muss funktionieren! Ersetzt wird nur der Bildschirm." },
  { type: "hint", opts: ["kcan"], when: {},
    html: "[b]K-CAN App (Beta):[/b] Zur App benötigst Du das CAN-Bus Interface und die Beta-Lizenz. Einbauerklärung: [a=https://wiki.kcan-app.de/index.php?title=Hauptseite#Wo_wird_das_CAN_BUS_Interface_angeschlossen?]Wo wird das CAN-Bus Interface angeschlossen?[/a] Weitere Infos im [a=https://wiki.kcan-app.de/]Wiki zur K-CAN App[/a]." },
   { type: "hint", opts: ["ibus"], when: {},
   { type: "hint", opts: ["ibus"], when: {},
     html: "<b>I-BUS App:</b> Siehe <a href='https://wiki.ibus-app.de/index.php?title=Was_brauche_ich_um_die_I-BUS_App_nutzen_zu_k%C3%B6nnen%3F'>Was brauche ich, um die I-BUS App nutzen zu können?</a> und die <a href='https://wiki.ibus-app.de/index.php?title=Einbauanleitung_f%C3%BCr_Resler_Modul_und_Resler_Interface'>Einbauanleitung für Resler Modul und Interface</a>." },
     html: "[b]I-BUS App:[/b] Siehe [a=https://wiki.ibus-app.de/index.php?title=Was_brauche_ich_um_die_I-BUS_App_nutzen_zu_k%C3%B6nnen%3F]Was brauche ich, um die I-BUS App nutzen zu können?[/a] und die [a=https://wiki.ibus-app.de/index.php?title=Hauptseite#Einbauanleitung_f.C3.BCr_Resler_Modul_und_Resler_Interface]Einbauanleitung für Resler Modul und Interface[/a]." },
   { type: "hint", when: {}, opts: [],
   { type: "hint", when: {},
     html: "<b>Wichtig:</b> Bitte immer die Anschlüsse am eigenen Radio abgleichen. Welches Radio passt? → <a href='https://xtrons.ibus-app.de/index.php?title=Entscheidungshilfe%3A_AVIN_oder_XTRONS%3F'>Entscheidungshilfe AVIN oder XTRONS</a>, Kosten → <a href='https://xtrons.ibus-app.de/index.php?title=Grobe_Kosten%C3%BCbersicht'>Grobe Kostenübersicht</a>." }
     html: "[b]Wichtig:[/b] Bitte immer die Anschlüsse am eigenen Radio abgleichen. Welches Radio passt? [a=https://xtrons.ibus-app.de/index.php?title=Entscheidungshilfe%3A_AVIN_oder_XTRONS%3F]Entscheidungshilfe AVIN oder XTRONS[/a] - Kosten: [a=https://xtrons.ibus-app.de/index.php?title=Grobe_Kosten%C3%BCbersicht]Grobe Kostenübersicht[/a]." }
];
];
/* =====================================================================
/* =====================================================================
   PROGRAMMLOGIK
   PROGRAMMLOGIK
   ===================================================================== */
   ===================================================================== */
var $ = function (id) { return document.getElementById(id); };
var $ = function (id) { return document.getElementById(id); };
var sel = {}, picked = {};
var sel = {}, picked = {}, summary = "", capA = 0, capB = 0, radioCache = {}, chosenRadio = null, cartFill = null;
var fieldsEl = $("nvk-fields"), optsEl = $("nvk-opts"), outEl = $("nvk-out");
var fieldsEl = $("nvk-fields"), optsEl = $("nvk-opts"), outEl = $("nvk-out");
 
function full(u) { return u.indexOf("/thumb/") === -1 ? u : u.replace("/thumb/", "/").replace(/\/[^\/]+$/, ""); }
function fmt(t) {
  return t.replace(/\[imgw=([^\x5D]+)\]/g, function (m, u) {
    return "\u003Ca href=\"" + full(u) + "\" target=\"_blank\" rel=\"noopener\"\u003E\u003Cimg class=\"nvk-img wide\" src=\"" + u + "\" alt=\"\"\u003E\u003C/a\u003E";
  }).replace(/\[img=([^\x5D]+)\]/g, function (m, u) {
    return "\u003Ca href=\"" + full(u) + "\" target=\"_blank\" rel=\"noopener\"\u003E\u003Cimg class=\"nvk-img\" src=\"" + u + "\" alt=\"\"\u003E\u003C/a\u003E";
  }).replace(/\[b\]/g, "\u003Cb\u003E").replace(/\[\/b\]/g, "\u003C/b\u003E").replace(/\[br\]/g, "\u003Cbr\u003E")
    .replace(/\[a=([^\x5D]+)\]/g, "\u003Ca href=\"$1\" target=\"_blank\" rel=\"noopener\"\u003E").replace(/\[\/a\]/g, "\u003C/a\u003E");
}
function match(cond, s, lenient) {
function match(cond, s, lenient) {
   if (!cond) return true;
   if (!cond) return true;
   for (var k in cond) {
   for (var k in cond) {
     if (!s[k]) { if (lenient) continue; return false; }
     if (!s[k]) { if (lenient) continue; return false; }
     if (cond[k].indexOf(s[k]) < 0) return false;
     if (cond[k].indexOf(s[k]) === -1) return false;
   }
   }
   return true;
   return true;
}
}
function vehicleOf(id) { return VEHICLES.filter(function (x) { return x.v === id; })[0]; }
function derive() {
function derive() {
   var s = {}, k;
   var s = {}, k;
   for (k in sel) s[k] = sel[k];
   for (k in sel) s[k] = sel[k];
   if (s.factory === "n43" || s.factory === "n169") s.module = "ja";
   var veh = vehicleOf(sel.vehicle);
  else if (s.factory === "iris" || s.factory === "mid") s.module = "nein";
  if (veh) s.gen = veh.gen;
  else if (s.factory === "pfeil") s.module = s.trunk || "unk";
  if (s.gen === "alt") {
    if (s.factory === "n43" || s.factory === "n169") s.module = "ja";
    else if (s.factory === "iris" || s.factory === "mid") s.module = "nein";
    else if (s.factory === "pfeil") s.module = s.trunk || "unk";
  }
   return s;
   return s;
}
}
Zeile 211: Zeile 345:
   return (o.requires || []).every(function (r) { return on[r]; });
   return (o.requires || []).every(function (r) { return on[r]; });
}
}
/* Felder aufbauen */
FIELDS.forEach(function (f) {
FIELDS.forEach(function (f) {
   var wrap = document.createElement("div"); wrap.className = "nvk-f"; wrap.id = "nvk-w-" + f.id;
   var wrap = document.createElement("div"); wrap.className = "nvk-f"; wrap.id = "nvk-w-" + f.id;
Zeile 218: Zeile 350:
   var s = document.createElement("select"); s.id = "nvk-" + f.id;
   var s = document.createElement("select"); s.id = "nvk-" + f.id;
   s.addEventListener("change", function () { sel[f.id] = s.value; update(); });
   s.addEventListener("change", function () { sel[f.id] = s.value; update(); });
   wrap.appendChild(lab); wrap.appendChild(s); fieldsEl.appendChild(wrap);
   wrap.appendChild(lab); wrap.appendChild(s);
  if (f.help) { var h = document.createElement("div"); h.className = "nvk-help"; h.innerHTML = fmt(f.help); wrap.appendChild(h); }
  var inf = document.createElement("div"); inf.id = "nvk-i-" + f.id; wrap.appendChild(inf);
  fieldsEl.appendChild(wrap);
});
});
function renderFields() {
function renderFields() {
  var s = derive();
   FIELDS.forEach(function (f) {
   FIELDS.forEach(function (f) {
    var s = derive();
     var wrap = $("nvk-w-" + f.id), el = $("nvk-" + f.id);
     var wrap = $("nvk-w-" + f.id), el = $("nvk-" + f.id);
     var vis = match(f.show, s, false) || !f.show;
     var vis = f.show ? match(f.show, s, false) : true;
     wrap.style.display = vis ? "" : "none";
     wrap.style.display = vis ? "" : "none";
     if (!vis) { sel[f.id] = ""; return; }
     if (!vis) { sel[f.id] = ""; return; }
     var allowed = f.values.filter(function (v) { return match(v.only, s, true); });
     var allowed = f.values.filter(function (v) { return match(v.only, s, true); });
     if (sel[f.id] && !allowed.some(function (v) { return v.v === sel[f.id]; })) sel[f.id] = "";
     if (sel[f.id]) { if (!allowed.some(function (v) { return v.v === sel[f.id]; })) sel[f.id] = ""; }
     if (!sel[f.id] && f.def) sel[f.id] = f.def;
     if (!sel[f.id]) { if (f.def) sel[f.id] = f.def; }
    if (!sel[f.id]) { if (f.auto) { if (sel.vehicle) { if (allowed.length === 1) sel[f.id] = allowed[0].v; } } }
     el.innerHTML = "";
     el.innerHTML = "";
     if (!f.def) { var p = document.createElement("option"); p.value = ""; p.textContent = "– bitte wählen –"; el.appendChild(p); }
     if (!f.def) { var p = document.createElement("option"); p.value = ""; p.textContent = "– bitte wählen –"; el.appendChild(p); }
Zeile 237: Zeile 372:
     });
     });
     el.value = sel[f.id] || "";
     el.value = sel[f.id] || "";
    var cur = allowed.filter(function (v) { return v.v === sel[f.id]; })[0];
    var pre = f.pre ? (match(f.pre.when, s, false) ? fmt(f.pre.html) : "") : "";
    $("nvk-i-" + f.id).innerHTML = pre + (cur ? (cur.info ? fmt(cur.info) : "") : "");
   });
   });
}
}
function renderOpts() {
function renderOpts() {
   var s = derive(), st = onSet(s);
   var s = derive(), st = onSet(s);
  /* Gruppen-Ausschluss & nicht mehr sichtbare Optionen bereinigen */
   OPTS.forEach(function (o) { if (!optVisible(o, s, st.on)) picked[o.id] = false; });
   OPTS.forEach(function (o) { if (!optVisible(o, s, st.on)) picked[o.id] = false; });
   st = onSet(s);
   st = onSet(s);
Zeile 255: Zeile 391:
     cb.addEventListener("change", function () {
     cb.addEventListener("change", function () {
       picked[o.id] = cb.checked;
       picked[o.id] = cb.checked;
       if (cb.checked && o.excl) OPTS.forEach(function (x) { if (x.excl === o.excl && x.id !== o.id) picked[x.id] = false; });
       if (cb.checked) { if (o.excl) OPTS.forEach(function (x) { if (x.excl === o.excl) { if (x.id !== o.id) picked[x.id] = false; } }); }
       update();
       update();
     });
     });
     lab.appendChild(cb);
     lab.appendChild(cb);
    var txt = " " + o.t;
     lab.appendChild(document.createTextNode(" " + o.t));
     lab.appendChild(document.createTextNode(txt));
     var sub = [o.sub, isForced ? st.forced[o.id] : ""].filter(Boolean).join(" - ");
     var sub = [o.sub, isForced ? st.forced[o.id] : ""].filter(Boolean).join(" – ");
     if (sub) { var sm = document.createElement("small"); sm.textContent = " (" + sub + ")"; lab.appendChild(sm); }
     if (sub) { var sm = document.createElement("small"); sm.textContent = " (" + sub + ")"; lab.appendChild(sm); }
     optsEl.appendChild(lab);
     optsEl.appendChild(lab);
   });
   });
}
}
 
function link(url, text) {
  var a = document.createElement("a"); a.href = url; a.target = "_blank"; a.rel = "noopener"; a.textContent = text; return a;
}
function card(item, cls) {
function card(item, cls) {
   var d = document.createElement("div"); d.className = "nvk-card " + (cls || "");
   var d = document.createElement("div"); d.className = "nvk-card " + (cls || "") + (item.hl ? " hl" : "");
   var b = document.createElement("b"); b.textContent = item.t; d.appendChild(b);
   var b = document.createElement("b"); b.textContent = item.t; d.appendChild(b);
   if (item.d) { var p = document.createElement("span"); p.textContent = item.d; d.appendChild(p); }
   if (item.d) { var p = document.createElement("span"); p.textContent = item.d; d.appendChild(p); }
   if (item.u) {
   if (item.img) {
     var a = document.createElement("a"); a.className = "nvk-shop"; a.href = item.u; a.target = "_blank"; a.rel = "noopener";
     var im = document.createElement("div");
     a.textContent = "Im Shop ansehen →"; d.appendChild(a);
    item.img.forEach(function (u) {
      var a = document.createElement("a"); a.href = full(u); a.target = "_blank"; a.rel = "noopener";
      var g = document.createElement("img"); g.className = "nvk-img"; g.src = u; g.alt = item.t; a.appendChild(g); im.appendChild(a);
     });
    d.appendChild(im);
  }
  if (item.u || item.w) {
    var l = document.createElement("div"); l.className = "nvk-links";
    if (item.u) l.appendChild(link(item.u, item.ut || "Im Shop ansehen →"));
    if (item.w) l.appendChild(link(item.w, (item.wt || "Zum Wiki") + " →"));
    d.appendChild(l);
   }
   }
  if (item.links) item.links.forEach(function (x) {
    var r = document.createElement("div"); r.className = "nvk-links"; r.appendChild(link(x.u, x.t + " →")); d.appendChild(r);
  });
   return d;
   return d;
}
}
 
function heading(txt) { var h = document.createElement("h3"); h.textContent = txt; outEl.appendChild(h); }
function aidOf(u) {
  if (u.indexOf(SHOP) !== 0) return "";
  var m = u.match(/sArticle\/(\d+)/);
  if (!m) m = u.split("?")[0].match(/\/(\d+)\/[^\/]+$/);
  return m ? m[1] : "";
}
function renderRadioList(veh) {
  if (veh.noCat) return;
  if (chosenRadio) { if (chosenRadio.cat !== veh.v) chosenRadio = null; }
  var data = radioCache[veh.v];
  if (data === undefined) {
    radioCache[veh.v] = "loading";
    fetch(API + "?cat=" + encodeURIComponent(veh.v)).then(function (r) { return r.json(); }).then(function (j) {
      radioCache[veh.v] = (j.items || []).map(function (it) { it.cat = veh.v; return it; });
      renderResult();
    }).catch(function () { radioCache[veh.v] = []; renderResult(); });
  }
  if (data === undefined || data === "loading") {
    var m = document.createElement("p"); m.className = "nvk-miss"; m.textContent = "Verfügbare Radios werden geladen …"; outEl.appendChild(m); return;
  }
  if (!data.length) return;
  var want = { mask: /M-?ASK/i, ccc: /\bCCC\b/i, cic: /\bCIC\b/i, nbt: /\bNBT\b/i, nbtevo: /EVO/i }[sel.factory];
  function fits(it) { return want ? want.test(it.name) : false; }
  var list = data.slice().sort(function (a, b) { return (fits(b) ? 1 : 0) - (fits(a) ? 1 : 0); });
  var det = document.createElement("details"); det.open = Math.max(list.length, 8) === 8;
  var sm = document.createElement("summary"); sm.style.cursor = "pointer"; sm.style.fontWeight = "700";
  sm.textContent = "Verfügbare Radios für Deinen BMW " + veh.t + " (" + list.length + ")"; det.appendChild(sm);
  list.forEach(function (it) {
    var row = document.createElement("div"); row.className = "nvk-row";
    var lab = document.createElement("label"); lab.className = "nvk-o";
    var rb = document.createElement("input"); rb.type = "radio"; rb.name = "nvk-radio";
    rb.checked = chosenRadio ? chosenRadio.sku === it.sku : false;
    rb.addEventListener("change", function () { chosenRadio = it; if (cartFill) cartFill(); });
    lab.appendChild(rb);
    lab.appendChild(document.createTextNode(" " + it.name + (it.price ? "  -  " + it.price : "") + (fits(it) ? "  (passt zu Deiner Auswahl)" : "")));
    row.appendChild(lab); row.appendChild(link(it.url, "Shop →"));
    det.appendChild(row);
  });
  outEl.appendChild(det);
}
function cartBlock(needs, opt) {
  var items = [];
  needs.concat(opt).forEach(function (i) { var id = aidOf(i.u || ""); if (id) items.push({ t: i.t, aid: id }); });
  heading("In den Warenkorb");
  var box = document.createElement("div"); box.className = "nvk-card opt";
  var p = document.createElement("div");
  p.textContent = "Das oben gewählte Radio (falls ausgewählt) und diese Artikel werden direkt im Shop in den Warenkorb gelegt:";
  box.appendChild(p);
  var listEl = document.createElement("div"); box.appendChild(listEl);
  cartFill = function () {
    listEl.innerHTML = "";
    var lines = (chosenRadio ? ["Radio: " + chosenRadio.type] : []).concat(items.map(function (x) { return x.t; }));
    lines.forEach(function (t) { var r = document.createElement("div"); r.textContent = "- " + t; listEl.appendChild(r); });
  };
  cartFill();
  var n = document.createElement("div"); n.className = "nvk-help";
  n.textContent = "Kameras, TPMS, Werkzeug und Artikel ohne Direktlink wählst Du bitte über die Links oben im Shop aus.";
  box.appendChild(n);
  var all = needs.concat(opt);
  var has = function (k) { return all.indexOf(ITEMS[k]) !== -1; };
  var l17 = has("kcanlic"), l7 = has("bclic") || has("bcdsp");
  if (l17 || l7) {
    var vb = document.createElement("div"); vb.className = "nvk-f"; vb.style.marginTop = "12px";
    var vlab = document.createElement("label"); vlab.htmlFor = "nvk-licvin";
    vlab.textContent = l17 ? "Fahrgestellnummer (17 Zeichen) für die Lizenz" : "VIN für die Lizenz (7 Zeichen, z. B. AB12345)";
    var vin = document.createElement("input"); vin.type = "text"; vin.id = "nvk-licvin"; vin.maxLength = 17;
    vin.value = $("nvk-vin").value.toUpperCase();
    var ta = document.createElement("textarea"); ta.rows = 3; ta.readOnly = true; ta.style.display = "none"; ta.style.marginTop = "6px";
    var cb = document.createElement("button"); cb.type = "button"; cb.className = "nvk-btn"; cb.style.marginTop = "6px";
    cb.textContent = "Kommentartext für die Kasse kopieren";
    var ls = document.createElement("div"); ls.className = "nvk-help";
    cb.addEventListener("click", function () {
      var v = vin.value.trim().toUpperCase(), v7 = "", v17 = "";
      if (/^[A-HJ-NPR-Z0-9]{17}$/.test(v)) { v17 = v; v7 = v.slice(10); }
      else if (/^[A-Z]{2}[0-9]{5}$/.test(v)) v7 = v;
      if (l17 ? !v17 : !v7) { ls.textContent = l17 ? "Bitte die vollständige 17-stellige Fahrgestellnummer eingeben." : "Bitte die VIN im Format AB12345 (oder die 17-stellige FGN) eingeben."; return; }
      var L = [];
      if (has("bclic")) L.push("I-BUS App BC Lizenz: VIN " + v7);
      if (has("bcdsp")) L.push("I-BUS App BC+DSP Lizenz: VIN " + v7);
      if (l17) L.push("K-CAN App Beta Lizenz: FGN " + v17);
      ta.value = L.join("\n"); ta.style.display = ""; ta.select();
      var hint = "Bitte an der Shop-Kasse in das Feld Kommentar einfügen.";
      if (navigator.clipboard) navigator.clipboard.writeText(ta.value).then(function () { ls.textContent = "Text kopiert. " + hint; }).catch(function () { ls.textContent = "Bitte den Text markieren und kopieren. " + hint; });
      else ls.textContent = "Bitte den Text markieren und kopieren. " + hint;
    });
    vb.appendChild(vlab); vb.appendChild(vin); vb.appendChild(cb); vb.appendChild(ta); vb.appendChild(ls); box.appendChild(vb);
  }
  if (!CART_TRANSFER) { outEl.appendChild(box); return; }
  var btn = document.createElement("button"); btn.type = "button"; btn.className = "nvk-btn"; btn.style.marginTop = "8px";
  btn.textContent = "Auswahl in den Warenkorb legen";
  var st = document.createElement("div"); st.className = "nvk-help";
  btn.addEventListener("click", function () { addToCart(items, st); });
  box.appendChild(btn); box.appendChild(st); outEl.appendChild(box);
}
function addToCart(items, st) {
  var list = items.slice();
  if (chosenRadio) list.unshift({ t: chosenRadio.type, sku: chosenRadio.sku });
  if (!list.length) { st.textContent = "Es ist noch nichts zum Bestellen ausgewählt."; return; }
  var w = window.open("", "_blank");
  st.textContent = "Artikelnummern werden ermittelt …";
  var ids = list.filter(function (x) { return x.aid; }).map(function (x) { return x.aid; });
  var get = ids.length ? fetch(API + "?aid=" + ids.join(",")).then(function (r) { return r.json(); }).then(function (j) { return j.skus || {}; }) : Promise.resolve({});
  get.then(function (map) {
    var skus = [];
    list.forEach(function (x) { var k = x.sku || map[x.aid]; if (k) skus.push(k); });
    if (!skus.length) throw new Error("none");
    var url = CART + "?nvk=" + encodeURIComponent(skus.join(","));
    if (w) {
      w.location.href = url;
      st.textContent = "Der Shop wurde in einem neuen Tab geöffnet (" + skus.length + " von " + list.length + " Artikeln übergeben). Bitte dort den Warenkorb kontrollieren.";
    } else {
      st.textContent = "Der neue Tab wurde blockiert. Bitte Pop-ups erlauben oder diesen Link nutzen: ";
      st.appendChild(link(url, "Warenkorb im Shop öffnen →"));
    }
  }).catch(function () { if (w) w.close(); st.textContent = "Das hat leider nicht geklappt. Bitte nutze die Shop-Links oben."; });
}
function renderResult() {
function renderResult() {
   var s = derive(), st = onSet(s);
   var s = derive(), st = onSet(s);
   var required = ["vehicle", "factory", "sound", "current", "body"];
   var missing = FIELDS.filter(function (f) {
  var names = { vehicle: "Fahrzeug", factory: "Verbaut ab Werk", sound: "Soundsystem", current: "Aktuell verbaut", body: "Karosserie" };
    var w = $("nvk-w-" + f.id);
  var missing = required.filter(function (k) { return !sel[k]; });
    return w.style.display !== "none" ? (!f.optional ? !sel[f.id] : false) : false;
  });
   outEl.innerHTML = "";
   outEl.innerHTML = "";
   if (missing.length) {
   if (missing.length) {
     var m = document.createElement("p"); m.className = "nvk-miss";
     var m = document.createElement("p"); m.className = "nvk-miss";
     m.textContent = "Bitte noch auswählen: " + missing.map(function (k) { return names[k]; }).join(", ");
     m.textContent = "Bitte noch auswählen: " + missing.map(function (f) { return f.label; }).join(", ");
     outEl.appendChild(m); return;
     outEl.appendChild(m); $("nvk-form").style.display = "none"; return;
   }
   }
  $("nvk-form").style.display = "";
  var veh = vehicleOf(sel.vehicle);
  var ru = veh.noCat ? SHOP + "bmw-radios/" : SHOP + "bmw-radios/" + veh.v + "/";
  heading("Passende Radios");
  outEl.appendChild(card({ t: "BMW Radios für " + veh.t, d: "Alle Radios, die für Deinen BMW " + veh.t + " im Shop erhältlich sind.",
    u: ru, ut: "Zu den passenden Radios →", w: SHOP + "bmw-radios/", wt: "Alle BMW Radios" }, "rad"));
  renderRadioList(veh);
   var needs = [], hints = [], seen = {};
   var needs = [], hints = [], seen = {};
   RULES.forEach(function (r) {
   RULES.forEach(function (r) {
     if (!match(r.when, s)) return;
     if (!match(r.when, s)) return;
     if (r.opts && !r.opts.every(function (o) { return st.on[o]; })) return;
     if (r.opts) { if (!r.opts.every(function (o) { return st.on[o]; })) return; }
     if (r.type === "need") (r.items || []).forEach(function (id) { if (!seen[id]) { seen[id] = 1; needs.push(ITEMS[id]); } });
     if (r.type === "need") (r.items || []).forEach(function (id) { if (!seen[id]) { seen[id] = 1; needs.push(ITEMS[id]); } });
     else hints.push(r.html);
     else hints.push(r.html);
   });
   });
   var h = document.createElement("h3"); h.textContent = "Das brauchst Du"; outEl.appendChild(h);
   heading("Das brauchst Du");
   if (needs.length) needs.forEach(function (i) { outEl.appendChild(card(i)); });
   if (needs.length) needs.forEach(function (i) { outEl.appendChild(card(i)); });
   else { var n = document.createElement("p"); n.textContent = "Für die Grundinstallation sind keine zusätzlichen Verlängerungen oder Adapter nötig."; outEl.appendChild(n); }
   else { var n = document.createElement("p"); n.textContent = "Für die Grundinstallation sind keine zusätzlichen Verlängerungen oder Adapter nötig."; outEl.appendChild(n); }
   var opt = [];
   var opt = [];
   OPTS.forEach(function (o) { if (st.on[o.id] && optVisible(o, s, st.on) && !seen[o.item]) opt.push(ITEMS[o.item]); });
   OPTS.forEach(function (o) {
   if (opt.length) {
    if (!st.on[o.id]) return;
    var h2 = document.createElement("h3"); h2.textContent = "Deine Zusatzoptionen"; outEl.appendChild(h2);
    if (!optVisible(o, s, st.on)) return;
    opt.forEach(function (i) { outEl.appendChild(card(i, "opt")); });
    o.items.forEach(function (id) {
  }
      if (seen[id]) return;
      var sk = ITEMS[id].skipIf;
      if (sk) { if (seen[sk]) return; }
      seen[id] = 1; opt.push(ITEMS[id]);
    });
  });
   if (opt.length) { heading("Deine Zusatzoptionen"); opt.forEach(function (i) { outEl.appendChild(card(i, "opt")); }); }
   if (hints.length) {
   if (hints.length) {
     var h3 = document.createElement("h3"); h3.textContent = "Hinweise"; outEl.appendChild(h3);
     heading("Hinweise");
     hints.forEach(function (t) { var d = document.createElement("div"); d.className = "nvk-note"; d.innerHTML = t; outEl.appendChild(d); });
     hints.forEach(function (t) { var d = document.createElement("div"); d.className = "nvk-note"; d.innerHTML = fmt(t); outEl.appendChild(d); });
   }
   }
  var L = ["KONFIGURATION"];
  FIELDS.forEach(function (f) {
    if (!sel[f.id]) return;
    var v = f.values.filter(function (x) { return x.v === sel[f.id]; })[0];
    if (v) L.push("- " + f.label + ": " + v.t);
  });
  L.push("", "BENÖTIGT");
  needs.forEach(function (i) { L.push("- " + i.t + (i.u ? "  " + i.u : "")); });
  if (opt.length) { L.push("", "ZUSATZOPTIONEN"); opt.forEach(function (i) { L.push("- " + i.t + (i.u ? "  " + i.u : "")); }); }
  L.push("", "Radios: " + ru);
  summary = L.join("\n");
  cartBlock(needs, opt);
}
}
function update() { renderFields(); renderOpts(); renderResult(); }
function update() { renderFields(); renderOpts(); renderResult(); }
$("nvk-reset").addEventListener("click", function () { sel = {}; picked = {}; update(); });
function newCaptcha() {
  capA = 1 + Math.floor(Math.random() * 9); capB = 1 + Math.floor(Math.random() * 9);
  $("nvk-capq").textContent = "Sicherheitsfrage: Was ist " + capA + " + " + capB + "? *"; $("nvk-cap").value = "";
}
function status(msg, ok) { var e = $("nvk-status"); e.style.display = ""; e.textContent = msg; e.style.borderLeftColor = ok ? "#14866d" : "#d33"; }
$("nvk-send").addEventListener("click", function () {
  var name = $("nvk-name").value.trim(), mail = $("nvk-mail").value.trim(), vin = $("nvk-vin").value.trim().toUpperCase(), msg = $("nvk-msg").value.trim();
  if (!name || !mail || !msg) return status("Bitte Name, E-Mail und Kommentar ausfüllen.", false);
  if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(mail)) return status("Bitte eine gültige E-Mail-Adresse eingeben.", false);
  if (vin) { if (!/^[A-Z]{2}[0-9]{5}$/.test(vin)) { if (!/^[A-HJ-NPR-Z0-9]{17}$/.test(vin)) return status("Bitte die VIN im Format AB12345 oder die 17-stellige FGN eingeben - oder das Feld leer lassen.", false); } }
  if (parseInt($("nvk-cap").value, 10) !== capA + capB) return status("Die Sicherheitsfrage wurde nicht richtig beantwortet.", false);
  if (!$("nvk-dsgvo").checked) return status("Bitte der Verarbeitung Deiner Daten zustimmen.", false);
  if ($("nvk-hp").value) return;
  var sz = $("nvk-size").value;
  var rad = chosenRadio ? "\n\nGEWÄHLTES RADIO\n- " + chosenRadio.type + "  " + chosenRadio.url : "";
  var sum2 = summary + rad + (sz ? "\n\nGewünschte Displaygröße: " + sz : "");
  var text = "Name: " + name + "\nE-Mail: " + mail + "\nVIN: " + (vin || "-") + "\n\nKommentar:\n" + msg + "\n\n" + sum2;
  if (SEND_URL) {
    var p = new URLSearchParams();
    p.append("name", name); p.append("mail", mail); p.append("vin", vin); p.append("msg", msg); p.append("summary", sum2);
    p.append("hp", $("nvk-hp").value); p.append("ca", capA); p.append("cb", capB); p.append("cv", $("nvk-cap").value);
    fetch(SEND_URL, { method: "POST", body: p }).then(function (r) {
      if (!r.ok) throw new Error("send");
      status("Danke! Deine Anfrage wurde gesendet, eine Kopie geht an " + mail + ".", true); newCaptcha();
    }).catch(function () { status("Das Senden hat nicht geklappt. Bitte versuche es später noch einmal oder schreibe direkt an " + MAIL_TO + ".", false); });
  } else {
    var AMP = "\u0026";
    window.location.href = "mailto:" + MAIL_TO + "?cc=" + encodeURIComponent(mail) + AMP + "subject=" + encodeURIComponent(MAIL_SUBJECT) + AMP + "body=" + encodeURIComponent(text);
    status("Dein E-Mail-Programm wurde mit der fertigen Anfrage geöffnet. Bitte dort noch auf Senden klicken.", true);
  }
});
$("nvk-reset").addEventListener("click", function () { sel = {}; picked = {}; chosenRadio = null; update(); });
var legalEl = $("nvk-legal-links"), firstLink = true;
[ ["agb", "AGB"], ["widerruf", "Widerrufsbelehrung"], ["datenschutz", "Datenschutzerklärung"] ].forEach(function (x) {
  var key = x[0];
  if (!LEGAL[key]) return;
  if (!firstLink) legalEl.appendChild(document.createTextNode(" | "));
  firstLink = false; legalEl.appendChild(link(LEGAL[key], x[1]));
});
if (LEGAL.datenschutz) {
  var dl = $("nvk-dslink");
  dl.appendChild(document.createTextNode(" (")); dl.appendChild(link(LEGAL.datenschutz, "Datenschutzerklärung")); dl.appendChild(document.createTextNode(")"));
}
newCaptcha();
update();
update();
})();
})();
Zeile 319: Zeile 652:
</div>
</div>
</html>
</html>
<small>Stand: 21.10.2026</small><br>

Aktuelle Version vom 22. Oktober 2026, 06:37 Uhr

Mit diesem Tool kann auf Basis von Fahrzeug und vorhandenen Komponenten eine Liste nötiger Komponenten erstellt werden.
Zu den gewählten Komponenten werden Links in den I-BUS Shop gezeigt und abschließend kann mit der Auswahl eine Anfrage-Mail an das I-BUS App Team gesendet werden.

Zusatzoptionen

Stand: 21.10.2026