{"id":67,"date":"2026-01-03T11:06:22","date_gmt":"2026-01-03T11:06:22","guid":{"rendered":"https:\/\/boat.wesolution.fr\/?page_id=67"},"modified":"2026-01-03T11:38:36","modified_gmt":"2026-01-03T11:38:36","slug":"service-boat","status":"publish","type":"page","link":"https:\/\/boat.wesolution.fr\/index.php\/service-boat\/","title":{"rendered":"Service Boat"},"content":{"rendered":"\n<!doctype html>\n<html lang=\"fr\">\n<head>\n  <meta charset=\"utf-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \/>\n  <title>S\u00e9lecteur maintenance \u2014 Donn\u00e9es d&rsquo;entr\u00e9e<\/title>\n\n  <style>\n    :root{\n      --bg: #0b1220;\n      --card: rgba(255,255,255,0.06);\n      --stroke: rgba(255,255,255,0.12);\n      --text: rgba(255,255,255,0.92);\n      --muted: rgba(255,255,255,0.62);\n      --accent: #7dd3fc;\n      --accent2:#a78bfa;\n      --ok:#34d399;\n      --radius: 18px;\n      --shadow: 0 18px 60px rgba(0,0,0,0.45);\n    }\n\n    *{ box-sizing: border-box; }\n    body{\n      margin:0;\n      font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, \"Apple Color Emoji\",\"Segoe UI Emoji\";\n      background: radial-gradient(1200px 600px at 15% 10%, rgba(125,211,252,0.18), transparent 55%),\n                  radial-gradient(900px 500px at 85% 25%, rgba(167,139,250,0.16), transparent 55%),\n                  radial-gradient(800px 600px at 50% 90%, rgba(52,211,153,0.10), transparent 60%),\n                  var(--bg);\n      color: var(--text);\n      min-height: 100vh;\n      padding: 28px;\n    }\n\n    .wrap{ max-width: 1180px; margin: 0 auto; }\n\n    .header{\n      display:flex;\n      align-items:flex-end;\n      justify-content:space-between;\n      gap: 16px;\n      margin-bottom: 18px;\n    }\n\n    .title{ display:flex; flex-direction:column; gap:6px; }\n    .title h1{\n      margin:0;\n      font-size: clamp(22px, 2.5vw, 32px);\n      letter-spacing: -0.02em;\n      line-height: 1.1;\n    }\n    .title p{ margin:0; color: var(--muted); font-size: 14px; }\n\n    .pill{\n      display:inline-flex;\n      align-items:center;\n      gap:10px;\n      padding:10px 12px;\n      background: linear-gradient(90deg, rgba(125,211,252,0.14), rgba(167,139,250,0.12));\n      border: 1px solid var(--stroke);\n      border-radius: 999px;\n      color: var(--text);\n      font-size: 13px;\n      backdrop-filter: blur(10px);\n      box-shadow: 0 10px 28px rgba(0,0,0,0.25);\n      white-space: nowrap;\n    }\n    .dot{\n      width:10px;height:10px;border-radius:50%;\n      background: var(--ok);\n      box-shadow: 0 0 0 6px rgba(52,211,153,0.14);\n      flex:0 0 auto;\n    }\n\n    \/* \u2705 haut en 50\/50 *\/\n    .gridTop{\n      display:grid;\n      grid-template-columns: 1fr 1fr;\n      gap: 18px;\n      align-items: stretch;\n    }\n\n    .card{\n      background: linear-gradient(180deg, var(--card), rgba(255,255,255,0.04));\n      border: 1px solid var(--stroke);\n      border-radius: var(--radius);\n      box-shadow: var(--shadow);\n      overflow: hidden;\n      position: relative;\n      min-width: 0;\n    }\n\n    .card .inner{ padding: 18px; }\n\n    .card h2{\n      margin:0 0 12px 0;\n      font-size: 16px;\n      letter-spacing: -0.01em;\n      color: rgba(255,255,255,0.92);\n    }\n\n    .form{ display:grid; gap: 14px; }\n\n    .field{\n      display:grid;\n      gap: 8px;\n      padding: 14px;\n      border-radius: 14px;\n      background: rgba(255,255,255,0.04);\n      border: 1px solid rgba(255,255,255,0.10);\n    }\n\n    .labelRow{\n      display:flex;\n      align-items:center;\n      justify-content:space-between;\n      gap:10px;\n    }\n\n    label{ font-size: 13px; color: rgba(255,255,255,0.86); }\n\n    select{ width: 100%; }\n\n    select{\n      appearance: none;\n      background: rgba(0,0,0,0.18);\n      color: var(--text);\n      border: 1px solid rgba(255,255,255,0.14);\n      border-radius: 12px;\n      padding: 12px 12px;\n      outline: none;\n      font-size: 14px;\n    }\n    select:focus{\n      border-color: rgba(125,211,252,0.55);\n      box-shadow: 0 0 0 4px rgba(125,211,252,0.14);\n    }\n\n    .selectWrap{ position: relative; }\n    .selectWrap:after{\n      content:\"\u25be\";\n      position:absolute;\n      right:12px;\n      top:50%;\n      transform: translateY(-50%);\n      color: rgba(255,255,255,0.65);\n      pointer-events:none;\n      font-size: 14px;\n    }\n\n    .badge{\n      font-size: 12px;\n      padding: 6px 10px;\n      border-radius: 999px;\n      border: 1px solid rgba(255,255,255,0.14);\n      background: rgba(0,0,0,0.20);\n      color: rgba(255,255,255,0.88);\n      white-space: nowrap;\n      max-width: 55%;\n      overflow:hidden;\n      text-overflow: ellipsis;\n    }\n\n    .actions{\n      display:flex;\n      gap: 10px;\n      margin-top: 6px;\n      flex-wrap:wrap;\n    }\n    .btn{\n      border: 1px solid rgba(255,255,255,0.14);\n      background: rgba(0,0,0,0.20);\n      color: rgba(255,255,255,0.92);\n      padding: 10px 12px;\n      border-radius: 12px;\n      cursor:pointer;\n      font-size: 13px;\n      transition: transform .05s ease, border-color .2s ease, background .2s ease;\n      user-select:none;\n    }\n    .btn:hover{\n      border-color: rgba(125,211,252,0.55);\n      background: rgba(125,211,252,0.10);\n    }\n    .btn:active{ transform: translateY(1px); }\n\n    \/* \u2705 Image \u00e0 droite, m\u00eame hauteur que la carte gauche *\/\n    .imageCard{\n      display:flex;\n      flex-direction:column;\n      min-height: 100%;\n    }\n\n    .hero{\n      flex: 1;\n      background:\n        radial-gradient(700px 240px at 20% 10%, rgba(125,211,252,0.20), transparent 60%),\n        radial-gradient(700px 240px at 80% 25%, rgba(167,139,250,0.18), transparent 60%),\n        rgba(255,255,255,0.03);\n      border-top: 1px solid rgba(255,255,255,0.10);\n      overflow:hidden;\n      display:flex;\n      align-items:center;\n      justify-content:center;\n      padding: 14px;\n    }\n\n    .hero img{\n      width: 100%;\n      height: 100%;\n      object-fit: contain;\n      object-position: center;\n      border-radius: 14px;\n      border: 1px solid rgba(255,255,255,0.12);\n      display:none;\n      transform: scale(1.04);\n    }\n\n    .placeholder{\n      border: 1px dashed rgba(255,255,255,0.22);\n      border-radius: 14px;\n      width: 100%;\n      height: 100%;\n      display:flex;\n      align-items:center;\n      justify-content:center;\n      color: rgba(255,255,255,0.70);\n      background: rgba(0,0,0,0.16);\n      text-align:center;\n      padding: 16px;\n      min-height: 180px;\n    }\n    .placeholder strong{\n      display:block;\n      color: rgba(255,255,255,0.92);\n      font-size: 14px;\n      margin-bottom: 6px;\n    }\n    .placeholder span{\n      display:block;\n      font-size: 12px;\n      color: var(--muted);\n      line-height: 1.45;\n    }\n\n    @media (max-width: 980px){\n      body{ padding: 18px; }\n      .gridTop{ grid-template-columns: 1fr; }\n      .hero{ min-height: 260px; }\n    }\n  <\/style>\n<\/head>\n\n<body>\n  <div class=\"wrap\">\n    <div class=\"header\">\n      <div class=\"title\">\n        <h1>S\u00e9lecteur maintenance \u2014 Donn\u00e9es d\u2019entr\u00e9e<\/h1>\n        <p>Choisis le bateau, puis la maintenance thermique et\/ou l\u2019hivernage.<\/p>\n      <\/div>\n\n      <div class=\"pill\">\n        <span class=\"dot\"><\/span>\n        <span>Mode d\u00e9mo \u2014 aucune donn\u00e9e envoy\u00e9e<\/span>\n      <\/div>\n    <\/div>\n\n    <!-- \u2705 LIGNE DU HAUT : \u00e0 gauche (bateau + maintenance), \u00e0 droite (image) -->\n    <div class=\"gridTop\">\n      <section class=\"card\">\n        <div class=\"inner\">\n          <h2>1) Param\u00e8tres bateau<\/h2>\n\n          <div class=\"form\">\n            <div class=\"field\">\n              <div class=\"labelRow\">\n                <label for=\"boatBrand\">Marque<\/label>\n              <\/div>\n              <div class=\"selectWrap\">\n                <select id=\"boatBrand\" disabled>\n                  <option>Chargement\u2026<\/option>\n                <\/select>\n              <\/div>\n            <\/div>\n\n            <div class=\"field\">\n              <div class=\"labelRow\">\n                <label for=\"boatModel\">Mod\u00e8le du bateau<\/label>\n              <\/div>\n              <div class=\"selectWrap\">\n                <select id=\"boatModel\" disabled>\n                  <option>Choisis une marque\u2026<\/option>\n                <\/select>\n              <\/div>\n            <\/div>\n\n            <!-- \u2705 MAINTENANCE D\u00c9CAL\u00c9E ICI (sous le mod\u00e8le) -->\n            <div class=\"field\">\n              <div class=\"labelRow\">\n                <label for=\"maintenanceThermique\">Maintenance thermique<\/label>\n                <span class=\"badge\" id=\"maintenanceThermiqueBadge\">\u2014<\/span>\n              <\/div>\n              <div class=\"selectWrap\">\n                <select id=\"maintenanceThermique\">\n                  <option value=\"\" selected>Choisir\u2026<\/option>\n                  <option value=\"revision_annuelle\">R\u00e9vision annuelle (check complet)<\/option>\n                  <option value=\"vidange_moteur_filtre\">Vidange moteur + filtre \u00e0 huile<\/option>\n                  <option value=\"filtre_gasoil_decanteur\">Filtre gasoil + d\u00e9canteur<\/option>\n                  <option value=\"turbine_pompe_eau\">Turbine\/pompe \u00e0 eau de mer<\/option>\n                  <option value=\"courroies_galets\">Courroies + galets \/ tension<\/option>\n                  <option value=\"circuit_refroidissement\">Circuit de refroidissement (contr\u00f4le + purge)<\/option>\n                  <option value=\"anodes\">Remplacement anodes (moteur \/ embase)<\/option>\n                  <option value=\"bougies_allumage\">Bougies \/ allumage (essence)<\/option>\n                  <option value=\"injecteurs\">Contr\u00f4le injecteurs \/ alimentation (diesel)<\/option>\n                  <option value=\"turbo_echappement\">Contr\u00f4le turbo \/ \u00e9chappement<\/option>\n                  <option value=\"inverseur_embase\">Inverseur \/ embase (niveau, \u00e9tat, bruit)<\/option>\n                  <option value=\"diagnostic_panne\">Diagnostic panne (fum\u00e9e, perte puissance, surchauffe)<\/option>\n                <\/select>\n              <\/div>\n            <\/div>\n\n            <!-- \u2705 2e s\u00e9lecteur : HIVERNAGE -->\n            <div class=\"field\">\n              <div class=\"labelRow\">\n                <label for=\"hivernageType\">Hivernage<\/label>\n                <span class=\"badge\" id=\"hivernageBadge\">\u2014<\/span>\n              <\/div>\n              <div class=\"selectWrap\">\n                <select id=\"hivernageType\">\n                  <option value=\"\" selected>Choisir\u2026<\/option>\n                  <option value=\"hivernage_simple\">Hivernage simple (mise en s\u00e9curit\u00e9)<\/option>\n                  <option value=\"hivernage_complet_moteur\">Hivernage complet moteur (traitement + conservation)<\/option>\n                  <option value=\"purge_eau_douce\">Purge eau douce \/ circuits<\/option>\n                  <option value=\"antigel_circuit\">Antigel circuit refroidissement<\/option>\n                  <option value=\"carburant_stabilisant\">Stabilisant carburant + plein s\u00e9curit\u00e9<\/option>\n                  <option value=\"batteries_entretien\">Batteries (d\u00e9pose \/ maintien charge \/ contr\u00f4le)<\/option>\n                  <option value=\"vidange_embase_inverseur\">Vidange embase \/ inverseur (avant stockage)<\/option>\n                  <option value=\"nettoyage_protection\">Nettoyage + protection (cockpit, inox, sellerie)<\/option>\n                  <option value=\"deshumidification\">D\u00e9shumidification \/ ventilation<\/option>\n                  <option value=\"bache_stockage\">B\u00e2chage \/ stockage \u00e0 sec<\/option>\n                <\/select>\n              <\/div>\n\n              <div class=\"actions\">\n                <button class=\"btn\" id=\"btnReset\" type=\"button\">R\u00e9initialiser<\/button>\n              <\/div>\n            <\/div>\n\n          <\/div>\n        <\/div>\n      <\/section>\n\n      <aside class=\"card imageCard\">\n        <div class=\"inner\">\n          <h2>2) Visuel \/ Sch\u00e9ma du bateau<\/h2>\n        <\/div>\n\n        <div class=\"hero\">\n          <img id=\"boatImage\" alt=\"Bateau\">\n          <div class=\"placeholder\" id=\"imgPlaceholder\">\n            <div>\n              <strong>Image du bateau (\u00e0 ajouter)<\/strong>\n              <span>Tu mettras l\u2019URL plus tard.<\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/aside>\n    <\/div>\n  <\/div>\n\n  <script>\n    const AJAX_URL = \"\/wp-admin\/admin-ajax.php\";\n\n    async function ajaxGet(action, params = {}) {\n      const url = new URL(AJAX_URL, window.location.origin);\n      url.searchParams.set(\"action\", action);\n      Object.entries(params).forEach(([k,v]) => url.searchParams.set(k, v));\n      const res = await fetch(url.toString(), { cache: \"no-store\" });\n      return res.json();\n    }\n\n    const els = {\n      boatBrand: document.getElementById(\"boatBrand\"),\n      boatModel: document.getElementById(\"boatModel\"),\n\n      maintenanceThermique: document.getElementById(\"maintenanceThermique\"),\n      maintenanceThermiqueBadge: document.getElementById(\"maintenanceThermiqueBadge\"),\n\n      hivernageType: document.getElementById(\"hivernageType\"),\n      hivernageBadge: document.getElementById(\"hivernageBadge\"),\n\n      boatImage: document.getElementById(\"boatImage\"),\n      imgPlaceholder: document.getElementById(\"imgPlaceholder\"),\n      btnReset: document.getElementById(\"btnReset\"),\n    };\n\n    function updateBoatImageByModel(model) {\n      const m = (model || \"\").toLowerCase().trim();\n      if (m === \"ariston\") {\n        setBoatImage(\"http:\/\/boat.wesolution.fr\/wp-content\/uploads\/2025\/12\/ariston.png\");\n      } else if (m === \"solo ruff 24\") {\n        setBoatImage(\"http:\/\/boat.wesolution.fr\/wp-content\/uploads\/2025\/12\/solo_ruff_24.png\");\n      }\n    }\n\n    function labelFromSelect(selectEl, value){\n      if (!value) return \"\u2014\";\n      const opt = selectEl.querySelector(`option[value=\"${CSS.escape(value)}\"]`);\n      return opt ? opt.textContent : \"\u2014\";\n    }\n\n    function updateUI(){\n      const brand = els.boatBrand.value || \"\";\n      const model = els.boatModel.value || \"\";\n      const maintenance_thermique = els.maintenanceThermique.value || \"\";\n      const hivernage = els.hivernageType.value || \"\";\n\n      updateBoatImageByModel(model);\n\n      els.maintenanceThermiqueBadge.textContent = labelFromSelect(els.maintenanceThermique, maintenance_thermique);\n      els.hivernageBadge.textContent = labelFromSelect(els.hivernageType, hivernage);\n\n      \/\/ \u2705 Donn\u00e9es pr\u00eates pour l\u2019\u00e9tape suivante (devis \/ mise en relation)\n      window.BOAT_SERVICE_INPUTS = {\n        brand,\n        model,\n        maintenance_thermique,\n        hivernage\n      };\n    }\n\n    window.setBoatImage = function(url){\n      if (!url) return;\n      els.boatImage.src = url;\n      els.boatImage.style.display = \"block\";\n      els.imgPlaceholder.style.display = \"none\";\n    };\n\n    async function loadBrandsAndFirstModels(){\n      els.boatBrand.disabled = true;\n      els.boatModel.disabled = true;\n\n      const brandsResp = await ajaxGet(\"boats_get_brands\");\n      if (!brandsResp || !brandsResp.ok) {\n        els.boatBrand.innerHTML = \"<option>Erreur chargement marques<\/option>\";\n        return;\n      }\n\n      els.boatBrand.innerHTML = \"\";\n      brandsResp.brands.forEach(b => {\n        const o = document.createElement(\"option\");\n        o.value = b;\n        o.textContent = b;\n        els.boatBrand.appendChild(o);\n      });\n\n      els.boatBrand.disabled = false;\n\n      const firstBrand = els.boatBrand.value;\n      await loadModelsForBrand(firstBrand);\n    }\n\n    async function loadModelsForBrand(brand){\n      els.boatModel.disabled = true;\n      els.boatModel.innerHTML = \"<option>Chargement\u2026<\/option>\";\n\n      const modelsResp = await ajaxGet(\"boats_get_models\", { brand });\n      if (!modelsResp || !modelsResp.ok) {\n        els.boatModel.innerHTML = \"<option>Erreur chargement mod\u00e8les<\/option>\";\n        return;\n      }\n\n      els.boatModel.innerHTML = \"\";\n      modelsResp.models.forEach(m => {\n        const o = document.createElement(\"option\");\n        o.value = m;\n        o.textContent = m;\n        els.boatModel.appendChild(o);\n      });\n\n      els.boatModel.disabled = false;\n      updateUI();\n    }\n\n    [\"change\",\"input\"].forEach(evt => {\n      els.boatModel.addEventListener(evt, updateUI);\n      els.maintenanceThermique.addEventListener(evt, updateUI);\n      els.hivernageType.addEventListener(evt, updateUI);\n    });\n\n    els.boatBrand.addEventListener(\"change\", async () => {\n      await loadModelsForBrand(els.boatBrand.value);\n    });\n\n    els.btnReset.addEventListener(\"click\", async () => {\n      els.maintenanceThermique.value = \"\";\n      els.hivernageType.value = \"\";\n      await loadBrandsAndFirstModels();\n      updateUI();\n    });\n\n    (async function init(){\n      await loadBrandsAndFirstModels();\n      updateUI();\n    })();\n  <\/script>\n<\/body>\n<\/html>\n\n\n\n\n<!-- \u2705 MODULE \"CHANTIER NAVAL\" (recherche + s\u00e9lection sur carte)\n     \u2705 + Liste \"WESOLUTION\" int\u00e9gr\u00e9e (points en dur, g\u00e9ocod\u00e9s \u00e0 la demande)\n     Colle tout dans UN seul bloc WordPress \"HTML personnalis\u00e9\"\n-->\n\n<link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css\">\n<script src=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\"><\/script>\n\n<style>\n  :root{\n    --bg: #0b1220;\n    --card: rgba(255,255,255,0.06);\n    --stroke: rgba(255,255,255,0.12);\n    --text: rgba(255,255,255,0.92);\n    --muted: rgba(255,255,255,0.62);\n    --radius: 18px;\n    --shadow: 0 18px 60px rgba(0,0,0,0.45);\n  }\n\n  .wrap1180{ max-width: 1180px; margin: 18px auto 0; }\n\n  .card{\n    background: linear-gradient(180deg, var(--card), rgba(255,255,255,0.04));\n    border: 1px solid var(--stroke);\n    border-radius: var(--radius);\n    box-shadow: var(--shadow);\n    overflow: hidden;\n    position: relative;\n    min-width: 0;\n    color: var(--text);\n  }\n  .card .inner{ padding: 18px; }\n  .card h2{\n    margin:0 0 12px 0;\n    font-size: 16px;\n    letter-spacing: -0.01em;\n    color: rgba(255,255,255,0.92);\n  }\n\n  .grid{\n    display:grid;\n    grid-template-columns: 1fr 1fr;\n    gap: 18px;\n    align-items: stretch;\n  }\n\n  .field{\n    display:grid;\n    gap: 10px;\n    padding: 14px;\n    border-radius: 14px;\n    background: rgba(255,255,255,0.04);\n    border: 1px solid rgba(255,255,255,0.10);\n    margin-bottom: 12px;\n  }\n  label{ font-size: 13px; color: rgba(255,255,255,0.86); }\n\n  .row{ display:flex; gap:10px; align-items:center; }\n  input[type=\"text\"]{\n    width:100%;\n    min-width:0;\n    appearance:none;\n    background: rgba(0,0,0,0.18);\n    color: var(--text);\n    border: 1px solid rgba(255,255,255,0.14);\n    border-radius: 12px;\n    padding: 12px 12px;\n    outline: none;\n    font-size: 14px;\n  }\n  input[type=\"text\"]:focus{\n    border-color: rgba(125,211,252,0.55);\n    box-shadow: 0 0 0 4px rgba(125,211,252,0.14);\n  }\n\n  .btn{\n    border: 1px solid rgba(255,255,255,0.14);\n    background: rgba(0,0,0,0.20);\n    color: rgba(255,255,255,0.92);\n    padding: 10px 12px;\n    border-radius: 12px;\n    cursor:pointer;\n    font-size: 13px;\n    transition: transform .05s ease, border-color .2s ease, background .2s ease;\n    user-select:none;\n    white-space:nowrap;\n  }\n  .btn:hover{\n    border-color: rgba(125,211,252,0.55);\n    background: rgba(125,211,252,0.10);\n  }\n  .btn:active{ transform: translateY(1px); }\n\n  .hint{ font-size: 12px; color: var(--muted); line-height: 1.45; margin: 0; }\n\n  .resultBox{ display:grid; gap: 10px; }\n  .kpi{\n    padding: 12px;\n    border-radius: 14px;\n    background: rgba(255,255,255,0.04);\n    border: 1px solid rgba(255,255,255,0.10);\n    display:flex;\n    justify-content:space-between;\n    align-items:baseline;\n    gap: 12px;\n  }\n  .kpi .k{ font-size: 12px; color: var(--muted); }\n  .kpi .v{\n    font-size: 14px;\n    color: rgba(255,255,255,0.92);\n    font-weight: 600;\n    text-align:right;\n  }\n\n  .list{\n    display:grid;\n    gap: 10px;\n    max-height: 340px;\n    overflow:auto;\n    padding-right: 4px;\n  }\n  .yardItem{\n    padding: 12px;\n    border-radius: 14px;\n    background: rgba(255,255,255,0.04);\n    border: 1px solid rgba(255,255,255,0.10);\n    cursor:pointer;\n    transition: border-color .2s ease, background .2s ease, transform .05s ease;\n  }\n  .yardItem:hover{\n    border-color: rgba(125,211,252,0.45);\n    background: rgba(125,211,252,0.08);\n  }\n  .yardItem:active{ transform: translateY(1px); }\n\n  .yardName{\n    font-weight: 650;\n    font-size: 13px;\n    margin-bottom: 6px;\n    color: rgba(255,255,255,0.92);\n  }\n  .yardAddr{ font-size: 12px; color: var(--muted); line-height: 1.35; }\n  .yardMeta{\n    margin-top: 8px;\n    font-size: 12px;\n    color: rgba(255,255,255,0.78);\n    display:flex;\n    gap: 10px;\n    flex-wrap:wrap;\n  }\n  .pillMini{\n    padding: 5px 9px;\n    border-radius: 999px;\n    border: 1px solid rgba(255,255,255,0.14);\n    background: rgba(0,0,0,0.18);\n  }\n\n  .mapShell{ display:flex; flex-direction:column; height: 100%; min-width: 0; }\n  .mapHeader{\n    padding: 14px 18px;\n    border-bottom: 1px solid rgba(255,255,255,0.10);\n    display:flex;\n    justify-content:space-between;\n    align-items:center;\n    gap: 10px;\n  }\n  .mapHeader .mini{ font-size: 12px; color: var(--muted); }\n\n  #yardMap{ height: 520px; border-top: 1px solid rgba(255,255,255,0.10); }\n\n  @media (max-width: 980px){\n    .grid{ grid-template-columns: 1fr; }\n    #yardMap{ height: 420px; }\n  }\n<\/style>\n\n<div class=\"wrap1180\">\n  <section class=\"card\" id=\"yardModule\">\n    <div class=\"inner\">\n      <h2>6) Chantier naval<\/h2>\n\n      <div class=\"grid\">\n\n        <!-- LEFT -->\n        <div>\n          <div class=\"field\">\n            <label for=\"yardCity\">Ville \/ zone<\/label>\n            <div class=\"row\">\n              <input id=\"yardCity\" type=\"text\" placeholder=\"Ex : Saint-Tropez, La Rochelle, Nice...\" \/>\n              <button class=\"btn\" id=\"yardSearchBtn\" type=\"button\">Rechercher<\/button>\n            <\/div>\n            <p class=\"hint\">R\u00e9sultats = (liste WESOLUTION g\u00e9ocod\u00e9e) + (OpenStreetMap autour) \u2014 puis s\u00e9lection sur carte.<\/p>\n          <\/div>\n\n          <div class=\"field\">\n            <label>R\u00e9sultat s\u00e9lectionn\u00e9<\/label>\n\n            <div class=\"resultBox\">\n              <div class=\"kpi\">\n                <div class=\"k\">Nom<\/div>\n                <div class=\"v\" id=\"yardSelName\">\u2014<\/div>\n              <\/div>\n              <div class=\"kpi\">\n                <div class=\"k\">Adresse<\/div>\n                <div class=\"v\" id=\"yardSelAddr\">\u2014<\/div>\n              <\/div>\n              <div class=\"kpi\">\n                <div class=\"k\">Coordonn\u00e9es<\/div>\n                <div class=\"v\"><span id=\"yardSelLat\">\u2014<\/span>, <span id=\"yardSelLon\">\u2014<\/span><\/div>\n              <\/div>\n            <\/div>\n\n            <input type=\"hidden\" id=\"yardNameField\" value=\"\">\n            <input type=\"hidden\" id=\"yardAddrField\" value=\"\">\n            <input type=\"hidden\" id=\"yardLatField\" value=\"\">\n            <input type=\"hidden\" id=\"yardLonField\" value=\"\">\n          <\/div>\n\n          <div class=\"field\">\n            <label>Liste (clique pour s\u00e9lectionner)<\/label>\n            <div class=\"list\" id=\"yardList\">\n              <div class=\"hint\" id=\"yardListHint\">Fais une recherche pour afficher des chantiers.<\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n\n        <!-- RIGHT -->\n        <aside class=\"card mapShell\">\n          <div class=\"mapHeader\">\n            <div>\n              <div style=\"font-weight:600;\">Carte<\/div>\n              <div class=\"mini\">Clique un marqueur pour s\u00e9lectionner le chantier.<\/div>\n            <\/div>\n            <div class=\"mini\">Rayon : <span id=\"yardRadiusLabel\">10<\/span> km<\/div>\n          <\/div>\n          <div id=\"yardMap\"><\/div>\n        <\/aside>\n\n      <\/div>\n    <\/div>\n  <\/section>\n<\/div>\n\n<script>\n  (function(){\n    if (window.__YARD_MODULE_INITED) return;\n    window.__YARD_MODULE_INITED = true;\n\n    \/\/ ====== Config ======\n    const SEARCH_RADIUS_KM = 10;\n    const MAX_WESOLUTION_TO_GEOCODE = 20; \/\/ \u00e9vite trop d'appels \u00e0 Nominatim\n    document.getElementById(\"yardRadiusLabel\").textContent = String(SEARCH_RADIUS_KM);\n\n    \/\/ ====== Liste \"WESOLUTION\" (hard-coded) ======\n    \/\/ \u26a0\ufe0f Ici : nom + ville. Le code g\u00e9ocode au moment de la recherche.\n    const WESOLUTION_YARDS = [\n      \/\/ Manche \/ Atlantique Nord\n      { name:\"Chantier Naval de Cherbourg Plaisance\", city:\"Cherbourg-en-Cotentin\" },\n      { name:\"Atelier Nautique Cherbourg\", city:\"Cherbourg-en-Cotentin\" },\n      { name:\"Normandie Nautic Services\", city:\"Cherbourg-en-Cotentin\" },\n\n      { name:\"Chantier Naval de la C\u00f4te d\u2019\u00c9meraude\", city:\"Saint-Malo\" },\n      { name:\"Saint-Malo Nautic Services\", city:\"Saint-Malo\" },\n\n      { name:\"Chantier Naval du H\u00e9rel\", city:\"Granville\" },\n      { name:\"Granville Nautic\", city:\"Granville\" },\n\n      \/\/ Bretagne\n      { name:\"Chantier Naval du Blavet\", city:\"Lorient\" },\n      { name:\"Lorient Nautic Services\", city:\"Lorient\" },\n\n      { name:\"Chantier Naval de Cornouaille\", city:\"Concarneau\" },\n      { name:\"Armor Nautic\", city:\"Concarneau\" },\n\n      { name:\"Chantier Naval du Bono\", city:\"Le Bono\" },\n      { name:\"Chantier Nautique de Baden\", city:\"Baden\" },\n      { name:\"Nautic Services Arradon\", city:\"Arradon\" },\n\n      \/\/ Loire-Atlantique \/ Vend\u00e9e\n      { name:\"Chantier Naval de Pornichet\", city:\"Pornichet\" },\n      { name:\"Atlantique Nautic Services\", city:\"Pornichet\" },\n\n      { name:\"Chantier Naval de Pornic\", city:\"Pornic\" },\n      { name:\"Jade Nautisme\", city:\"Pornic\" },\n\n      { name:\"Chantier Naval des Sables\", city:\"Les Sables-d\u2019Olonne\" },\n      { name:\"Sablais Nautic Services\", city:\"Les Sables-d\u2019Olonne\" },\n\n      \/\/ Charente-Maritime\n      { name:\"Chantier des Minimes\", city:\"La Rochelle\" },\n      { name:\"LR Nautic Services\", city:\"La Rochelle\" },\n      { name:\"Chantier Nautique Rochelais\", city:\"La Rochelle\" },\n\n      { name:\"Chantier Naval Royannais\", city:\"Royan\" },\n      { name:\"Royan Nautic\", city:\"Royan\" },\n\n      { name:\"Chantier Naval de la Teste\", city:\"La Teste-de-Buch\" },\n      { name:\"Bassin Nautique Services\", city:\"Arcachon\" },\n      { name:\"Arcachon Nautic\", city:\"Arcachon\" },\n\n      \/\/ M\u00e9diterran\u00e9e\n      { name:\"Chantier Naval M\u00e9diterran\u00e9e Plaisance\", city:\"S\u00e8te\" },\n      { name:\"S\u00e8te Nautic Services\", city:\"S\u00e8te\" },\n\n      { name:\"Chantier Naval de Port Camargue\", city:\"Le Grau-du-Roi\" },\n      { name:\"Camargue Nautic\", city:\"Le Grau-du-Roi\" },\n\n      { name:\"Chantier Naval de l\u2019Estaque\", city:\"Marseille\" },\n      { name:\"Marseille Nautic Services\", city:\"Marseille\" },\n\n      { name:\"Chantier Naval Ciotaden\", city:\"La Ciotat\" },\n      { name:\"CN La Ciotat Plaisance\", city:\"La Ciotat\" },\n\n      { name:\"Chantier Naval du Mourillon\", city:\"Toulon\" },\n      { name:\"Toulon Nautic\", city:\"Toulon\" },\n\n      { name:\"Chantier Naval d\u2019Antibes\", city:\"Antibes\" },\n      { name:\"Antibes Nautic Services\", city:\"Antibes\" },\n\n      { name:\"Chantier Naval de Villefranche\", city:\"Villefranche-sur-Mer\" },\n      { name:\"Nice Nautic Plaisance\", city:\"Nice\" },\n\n      \/\/ Corse\n      { name:\"Chantier Naval Ajaccien\", city:\"Ajaccio\" },\n      { name:\"Corsica Nautic Services\", city:\"Ajaccio\" },\n\n      { name:\"Chantier Naval de Bastia\", city:\"Bastia\" },\n      { name:\"Bastia Nautic\", city:\"Bastia\" },\n    ];\n\n    \/\/ ====== Map init ======\n    const map = L.map(\"yardMap\").setView([46.2, 2.2], 6);\n    L.tileLayer(\"https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png\", {\n      maxZoom: 19,\n      attribution: \"&copy; OpenStreetMap\"\n    }).addTo(map);\n\n    const markersLayer = L.layerGroup().addTo(map);\n    let cityMarker = null;\n    let radiusCircle = null;\n\n    const els = {\n      city: document.getElementById(\"yardCity\"),\n      btn: document.getElementById(\"yardSearchBtn\"),\n      list: document.getElementById(\"yardList\"),\n\n      selName: document.getElementById(\"yardSelName\"),\n      selAddr: document.getElementById(\"yardSelAddr\"),\n      selLat: document.getElementById(\"yardSelLat\"),\n      selLon: document.getElementById(\"yardSelLon\"),\n\n      fName: document.getElementById(\"yardNameField\"),\n      fAddr: document.getElementById(\"yardAddrField\"),\n      fLat: document.getElementById(\"yardLatField\"),\n      fLon: document.getElementById(\"yardLonField\"),\n    };\n\n    \/\/ ====== Helpers ======\n    function escapeHtml(s){\n      return String(s || \"\")\n        .replaceAll(\"&\",\"&amp;\")\n        .replaceAll(\"<\",\"&lt;\")\n        .replaceAll(\">\",\"&gt;\")\n        .replaceAll('\"',\"&quot;\")\n        .replaceAll(\"'\",\"&#039;\");\n    }\n\n    function setSelected(y){\n      const name = y.name || \"\u2014\";\n      const addr = y.address || \"\u2014\";\n      const lat = (typeof y.lat === \"number\") ? y.lat : null;\n      const lon = (typeof y.lon === \"number\") ? y.lon : null;\n\n      els.selName.textContent = name;\n      els.selAddr.textContent = addr;\n      els.selLat.textContent = (lat !== null) ? lat.toFixed(6) : \"\u2014\";\n      els.selLon.textContent = (lon !== null) ? lon.toFixed(6) : \"\u2014\";\n\n      els.fName.value = name;\n      els.fAddr.value = addr;\n      els.fLat.value = (lat !== null) ? String(lat) : \"\";\n      els.fLon.value = (lon !== null) ? String(lon) : \"\";\n\n      window.YARD_SELECTED = { name, address: addr, lat, lon };\n    }\n\n    function clearList(){ els.list.innerHTML = \"\"; }\n\n    function makeItem(y){\n      const div = document.createElement(\"div\");\n      div.className = \"yardItem\";\n      div.innerHTML = `\n        <div class=\"yardName\">${escapeHtml(y.name || \"Chantier naval\")}<\/div>\n        <div class=\"yardAddr\">${escapeHtml(y.address || \"\")}<\/div>\n        <div class=\"yardMeta\">\n          <span class=\"pillMini\">${(y.dist_km ?? 0).toFixed(1)} km<\/span>\n          ${y.source ? `<span class=\"pillMini\">${escapeHtml(y.source)}<\/span>` : \"\"}\n        <\/div>\n      `;\n      div.addEventListener(\"click\", () => {\n        setSelected(y);\n        map.setView([y.lat, y.lon], 14);\n      });\n      return div;\n    }\n\n    function haversineKm(lat1, lon1, lat2, lon2){\n      const toRad = d => (d * Math.PI) \/ 180;\n      const R = 6371;\n      const dLat = toRad(lat2 - lat1);\n      const dLon = toRad(lon2 - lon1);\n      const a =\n        Math.sin(dLat\/2)*Math.sin(dLat\/2) +\n        Math.cos(toRad(lat1))*Math.cos(toRad(lat2)) *\n        Math.sin(dLon\/2)*Math.sin(dLon\/2);\n      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));\n      return R * c;\n    }\n\n    function drawCityStuff(lat, lon){\n      if (cityMarker) map.removeLayer(cityMarker);\n      if (radiusCircle) map.removeLayer(radiusCircle);\n\n      cityMarker = L.marker([lat, lon]).addTo(map);\n      radiusCircle = L.circle([lat, lon], { radius: SEARCH_RADIUS_KM * 1000 }).addTo(map);\n      map.setView([lat, lon], 12);\n    }\n\n    \/\/ ====== OSM calls ======\n    async function geocodeCity(q){\n      const url = \"https:\/\/nominatim.openstreetmap.org\/search?format=json&limit=1&q=\" + encodeURIComponent(q);\n      const res = await fetch(url, { headers: { \"Accept-Language\":\"fr\" } });\n      const data = await res.json();\n      if (!data || !data.length) return null;\n      return { lat: parseFloat(data[0].lat), lon: parseFloat(data[0].lon), label: data[0].display_name };\n    }\n\n    async function geocodePlace(q){\n      const url = \"https:\/\/nominatim.openstreetmap.org\/search?format=json&limit=1&q=\" + encodeURIComponent(q);\n      const res = await fetch(url, { headers: { \"Accept-Language\":\"fr\" } });\n      const data = await res.json();\n      if (!data || !data.length) return null;\n      return { lat: parseFloat(data[0].lat), lon: parseFloat(data[0].lon), label: data[0].display_name };\n    }\n\n    async function searchYardsAround(lat, lon, radiusKm){\n      const radiusM = Math.round(radiusKm * 1000);\n      const query = `\n        [out:json][timeout:25];\n        (\n          nwr(around:${radiusM},${lat},${lon})[\"industrial\"=\"shipyard\"];\n          nwr(around:${radiusM},${lat},${lon})[\"man_made\"=\"shipyard\"];\n          nwr(around:${radiusM},${lat},${lon})[\"craft\"=\"boatbuilder\"];\n          nwr(around:${radiusM},${lat},${lon})[\"leisure\"=\"marina\"][\"service:boat:repair\"=\"yes\"];\n          nwr(around:${radiusM},${lat},${lon})[\"name\"][\"boat:repair\"=\"yes\"];\n        );\n        out center tags;\n      `;\n      const url = \"https:\/\/overpass-api.de\/api\/interpreter\";\n      const res = await fetch(url, {\n        method: \"POST\",\n        headers: { \"Content-Type\":\"text\/plain;charset=UTF-8\" },\n        body: query\n      });\n      const json = await res.json();\n      const elements = json.elements || [];\n\n      const yards = elements.map(el => {\n        const t = el.tags || {};\n        const yLat = (el.type === \"node\") ? el.lat : (el.center ? el.center.lat : null);\n        const yLon = (el.type === \"node\") ? el.lon : (el.center ? el.center.lon : null);\n\n        const name = t.name || t.operator || \"Chantier naval\";\n        const addrParts = [\n          t[\"addr:housenumber\"], t[\"addr:street\"], t[\"addr:postcode\"], t[\"addr:city\"]\n        ].filter(Boolean).join(\" \").trim();\n        const address = addrParts || t[\"addr:full\"] || t[\"contact:address\"] || \"\";\n\n        const dist_km = (yLat && yLon) ? haversineKm(lat, lon, yLat, yLon) : 999;\n\n        return {\n          id: \"osm:\" + el.type + \":\" + el.id,\n          name,\n          address,\n          lat: yLat,\n          lon: yLon,\n          dist_km,\n          source: \"OSM\"\n        };\n      }).filter(y => y.lat && y.lon);\n\n      yards.sort((a,b) => a.dist_km - b.dist_km);\n      return yards.slice(0, 25);\n    }\n\n    \/\/ ====== Render ======\n    function renderYards(yards){\n      clearList();\n      markersLayer.clearLayers();\n\n      if (!yards.length){\n        els.list.innerHTML = `<div class=\"hint\">Aucun chantier trouv\u00e9. Essaie une autre ville.<\/div>`;\n        return;\n      }\n\n      yards.forEach(y => {\n        els.list.appendChild(makeItem(y));\n\n        const m = L.marker([y.lat, y.lon]).addTo(markersLayer);\n        const popup = `\n          <b>${escapeHtml(y.name)}<\/b><br>\n          ${escapeHtml(y.address || \"\")}<br>\n          <span style=\"opacity:.8\">${(y.dist_km ?? 0).toFixed(1)} km \u2014 ${escapeHtml(y.source || \"\")}<\/span><br><br>\n          <button id=\"pick_${escapeHtml(String(y.id)).replaceAll(\":\",\"_\")}\" style=\"\n            border:1px solid rgba(255,255,255,0.25);\n            background: rgba(0,0,0,0.35);\n            color: white;\n            padding: 6px 10px;\n            border-radius: 10px;\n            cursor:pointer;\n          \">Choisir ce chantier<\/button>\n        `;\n        m.bindPopup(popup);\n\n        m.on(\"popupopen\", () => {\n          const btn = document.getElementById(\"pick_\" + String(y.id).replaceAll(\":\",\"_\"));\n          if (btn) btn.onclick = () => { setSelected(y); m.closePopup(); };\n        });\n\n        m.on(\"click\", () => setSelected(y));\n      });\n\n      setSelected(yards[0]);\n    }\n\n    function uniqMergeByNameLatLon(list){\n      const seen = new Set();\n      const out = [];\n      for (const y of list){\n        const key = (y.name||\"\").toLowerCase() + \"|\" + (y.lat?.toFixed(5) ?? \"\") + \"|\" + (y.lon?.toFixed(5) ?? \"\");\n        if (seen.has(key)) continue;\n        seen.add(key);\n        out.push(y);\n      }\n      return out;\n    }\n\n    function normalizeQuery(q){\n      return (q || \"\")\n        .toLowerCase()\n        .normalize(\"NFD\").replace(\/[\\u0300-\\u036f]\/g, \"\")\n        .replace(\/\\s+\/g, \" \")\n        .trim();\n    }\n\n    async function geocodeWesolutionForCity(cityQuery, centerLat, centerLon){\n      const qn = normalizeQuery(cityQuery);\n      \/\/ filtre simple : match sur ville (ou contient)\n      const candidates = WESOLUTION_YARDS.filter(y => {\n        const cn = normalizeQuery(y.city);\n        return cn.includes(qn) || qn.includes(cn);\n      }).slice(0, MAX_WESOLUTION_TO_GEOCODE);\n\n      const out = [];\n      for (let i = 0; i < candidates.length; i++){\n        const c = candidates[i];\n        const placeQ = `${c.name}, ${c.city}, France`;\n        const g = await geocodePlace(placeQ);\n        if (!g) continue;\n\n        out.push({\n          id: \"ws:\" + i,\n          name: c.name,\n          address: g.label || c.city,\n          lat: g.lat,\n          lon: g.lon,\n          dist_km: haversineKm(centerLat, centerLon, g.lat, g.lon),\n          source: \"WESOLUTION\"\n        });\n\n        \/\/ petit \u201ccooldown\u201d pour \u00e9viter de taper trop vite Nominatim\n        await new Promise(r => setTimeout(r, 220));\n      }\n\n      out.sort((a,b) => a.dist_km - b.dist_km);\n      return out;\n    }\n\n    \/\/ ====== main search ======\n    async function runSearch(){\n      const q = els.city.value.trim();\n      if (!q) return;\n\n      els.btn.disabled = true;\n      els.btn.textContent = \"Recherche...\";\n      clearList();\n      els.list.innerHTML = `<div class=\"hint\">Recherche en cours\u2026<\/div>`;\n\n      try{\n        const city = await geocodeCity(q);\n        if (!city){\n          els.list.innerHTML = `<div class=\"hint\">Ville introuvable. Essaie \u201cPort de \u2026\u201d ou une commune voisine.<\/div>`;\n          return;\n        }\n\n        drawCityStuff(city.lat, city.lon);\n\n        \/\/ 1) base WESOLUTION (g\u00e9ocod\u00e9e pour cette ville)\n        const ws = await geocodeWesolutionForCity(q, city.lat, city.lon);\n\n        \/\/ 2) OSM autour\n        const osm = await searchYardsAround(city.lat, city.lon, SEARCH_RADIUS_KM);\n\n        \/\/ merge + tri + limite\n        let merged = uniqMergeByNameLatLon([...ws, ...osm]);\n        merged.sort((a,b) => (a.dist_km ?? 999) - (b.dist_km ?? 999));\n        merged = merged.slice(0, 25);\n\n        renderYards(merged);\n\n        setTimeout(() => map.invalidateSize(), 200);\n\n      }catch(e){\n        els.list.innerHTML = `<div class=\"hint\">Erreur de recherche. R\u00e9essaie dans quelques secondes.<\/div>`;\n      }finally{\n        els.btn.disabled = false;\n        els.btn.textContent = \"Rechercher\";\n      }\n    }\n\n    els.btn.addEventListener(\"click\", runSearch);\n    els.city.addEventListener(\"keydown\", (e) => { if (e.key === \"Enter\") runSearch(); });\n\n    window.YARD_SELECTED = { name:\"\", address:\"\", lat:null, lon:null };\n    setTimeout(() => map.invalidateSize(), 250);\n  })();\n<\/script>\n\n\n\n\n<!-- \u2705 AJOUT \"R\u00c9SULTAT FINAL\" (liste avec Nom \/ Adresse \/ Prix \/ bouton Choisir)\n     \u00c0 coller DANS TON MODULE, juste avant <\/section> (ou n\u2019importe o\u00f9 dans le bloc HTML)\n     + ajoute les fonctions JS plus bas (voir plus bas)\n-->\n\n<style>\n  \/* \u2705 bloc final (m\u00eame style) *\/\n  .finalBox{\n    margin-top: 12px;\n    padding: 14px;\n    border-radius: 14px;\n    background: rgba(255,255,255,0.04);\n    border: 1px solid rgba(255,255,255,0.10);\n  }\n  .finalHeader{\n    display:flex;\n    align-items:baseline;\n    justify-content:space-between;\n    gap: 12px;\n    margin-bottom: 10px;\n  }\n  .finalHeader .t{\n    font-weight: 650;\n    font-size: 13px;\n    color: rgba(255,255,255,0.92);\n  }\n  .finalHeader .s{\n    font-size: 12px;\n    color: rgba(255,255,255,0.62);\n  }\n\n  .finalList{\n    display:grid;\n    gap: 10px;\n    max-height: 360px;\n    overflow:auto;\n    padding-right: 4px;\n  }\n  .finalRow{\n    display:grid;\n    grid-template-columns: 1.4fr 1.8fr 0.8fr auto;\n    gap: 10px;\n    align-items:center;\n    padding: 12px;\n    border-radius: 14px;\n    background: rgba(255,255,255,0.04);\n    border: 1px solid rgba(255,255,255,0.10);\n  }\n  .finalRow .name{\n    font-weight:650;\n    font-size: 13px;\n    color: rgba(255,255,255,0.92);\n  }\n  .finalRow .addr{\n    font-size: 12px;\n    color: rgba(255,255,255,0.62);\n    line-height: 1.35;\n  }\n  .finalRow .price{\n    font-size: 13px;\n    font-weight:650;\n    text-align:right;\n    color: rgba(255,255,255,0.92);\n    white-space:nowrap;\n  }\n\n  .btnPick{\n    border: 1px solid rgba(255,255,255,0.14);\n    background: rgba(0,0,0,0.20);\n    color: rgba(255,255,255,0.92);\n    padding: 10px 12px;\n    border-radius: 12px;\n    cursor:pointer;\n    font-size: 13px;\n    transition: transform .05s ease, border-color .2s ease, background .2s ease;\n    user-select:none;\n    white-space:nowrap;\n  }\n  .btnPick:hover{\n    border-color: rgba(125,211,252,0.55);\n    background: rgba(125,211,252,0.10);\n  }\n  .btnPick:active{ transform: translateY(1px); }\n\n  .finalRow.isSelected{\n    border-color: rgba(125,211,252,0.55);\n    background: rgba(125,211,252,0.10);\n  }\n\n  @media (max-width: 980px){\n    .finalRow{\n      grid-template-columns: 1fr;\n      gap: 8px;\n      align-items:start;\n    }\n    .finalRow .price{ text-align:left; }\n  }\n<\/style>\n\n<div class=\"field\">\n  <label>R\u00e9sultat final (choix du chantier)<\/label>\n  <div class=\"finalBox\">\n    <div class=\"finalHeader\">\n      <div class=\"t\">Chantiers trouv\u00e9s<\/div>\n      <div class=\"s\" id=\"finalCount\">0<\/div>\n    <\/div>\n    <div class=\"finalList\" id=\"yardFinalResults\">\n      <div class=\"hint\">Fais une recherche pour afficher la liste finale.<\/div>\n    <\/div>\n\n    <!-- \u2705 export \u201cfinal\u201d (si tu veux l\u2019utiliser ailleurs) -->\n    <input type=\"hidden\" id=\"yardPriceField\" value=\"\">\n  <\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>S\u00e9lecteur maintenance \u2014 Donn\u00e9es d&rsquo;entr\u00e9e S\u00e9lecteur maintenance \u2014 Donn\u00e9es d\u2019entr\u00e9e Choisis le bateau, puis la maintenance thermique et\/ou l\u2019hivernage. Mode d\u00e9mo \u2014 aucune donn\u00e9e envoy\u00e9e 1) Param\u00e8tres bateau Marque Chargement\u2026 Mod\u00e8le du bateau Choisis une marque\u2026 Maintenance thermique \u2014 Choisir\u2026R\u00e9vision annuelle (check complet)Vidange moteur + filtre \u00e0 huileFiltre gasoil + d\u00e9canteurTurbine\/pompe \u00e0 eau de merCourroies [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-67","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/boat.wesolution.fr\/index.php\/wp-json\/wp\/v2\/pages\/67","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/boat.wesolution.fr\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/boat.wesolution.fr\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/boat.wesolution.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/boat.wesolution.fr\/index.php\/wp-json\/wp\/v2\/comments?post=67"}],"version-history":[{"count":5,"href":"https:\/\/boat.wesolution.fr\/index.php\/wp-json\/wp\/v2\/pages\/67\/revisions"}],"predecessor-version":[{"id":74,"href":"https:\/\/boat.wesolution.fr\/index.php\/wp-json\/wp\/v2\/pages\/67\/revisions\/74"}],"wp:attachment":[{"href":"https:\/\/boat.wesolution.fr\/index.php\/wp-json\/wp\/v2\/media?parent=67"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}