PageSourceSearch

https://www.meteobelgique.be/observations/animation/radar-precipitations

html meteobelgique.be collected 2026-10-01 12:03:59 UTC 129,832 bytes, 2,005 lines download raw bytes

1<!DOCTYPE html>
2<html lang="fr">
3<head>
4    <meta charset="utf-8">
5	<meta property="og:title" content="Radar des précipitations pour la Belgique - Météo en Belgique">
6	<meta property="og:url" content="https://www.meteobelgique.be/observations/animation/radar-precipitations">
7	<meta property="og:description" content="Radar des précipitations en Belgique : suivez en direct l’évolution de la pluie et consultez les prévisions pour la prochaine heure.">
8	<meta property="og:image" content="https://www.meteobelgium.be/belgium/radar/radar_be_202610011145_be36940656ae7c0c1b81ec07c4a7dbcc.jpg">
9	<meta property="og:type" content="website">
10	<meta name="description" content="Radar des précipitations en Belgique : suivez en direct l’évolution de la pluie et consultez les prévisions pour la prochaine heure.">
11	<meta name="generator" content="Joomla! - Open Source Content Management">
12	<title>Radar des précipitations pour la Belgique - Météo en Belgique</title>
13	<link href="/favicon.ico" rel="icon" type="image/vnd.microsoft.icon">
14<link href="/media/vendor/joomla-custom-elements/css/joomla-alert.min.css?0.4.1" rel="stylesheet">
15	<link href="/modules/mod_jux_megamenu/assets/css/jux_megamenu_merged.css" rel="stylesheet">
16	<link href="/media/sourcecoast/css/common.css" rel="stylesheet">
17	<link href="/media/sourcecoast/themes/sclogin/default.css" rel="stylesheet">
18	<style>
19         #jux_memamenu172 ul.megamenu li.haschild.megacss:hover>div.childcontent.adddropdown,
20         #jux_memamenu172 .childcontent.open>.dropdown-menu{
21            opacity:1;
22            -moz-animation:fadeInDown 100ms ease-in ;
23            -webkit-animation:fadeInDown 100ms ease-in ;
24            animation:fadeInDown 100ms ease-in ;
25    }</style>
26<script type="application/json" class="joomla-script-options new">{"joomla.jtext":{"ERROR":"Erreur","MESSAGE":"Message","NOTICE":"Annonce","WARNING":"Alerte","SUCCESS":"Succès","JCLOSE":"Fermer","JOK":"OK","JOPEN":"Ouvrir"},"bootstrap.modal":{"#login-modal-208":{"keyboard":true,"focus":true}},"system.paths":{"root":"","rootFull":"https:\/\/www.meteobelgique.be\/","base":"","baseFull":"https:\/\/www.meteobelgique.be\/"},"csrf.token":"54ec6a26a1c73b00855e669bed2ab093"}</script>
26
27	
27<script src="/media/system/js/core.min.js?a3d8f8"></script>
27
28	
28<script src="/media/system/js/messages.min.js?9a4811" type="module"></script>
28
29	
29<script src="/media/vendor/jquery/js/jquery.min.js?3.7.1"></script>
29
30	
30<script src="/media/legacy/js/jquery-noconflict.min.js?504da4"></script>
30
31	
31<script src="/media/system/js/fields/passwordview.min.js?61f142" defer></script>
31
32	
32<script src="/media/vendor/bootstrap/js/modal.min.js?5.3.8" type="module"></script>
32
33	
33<script src="/media/mod_menu/js/menu.min.js?707b5d" type="module"></script>
33
34	
34<script src="https://cdn.fuseplatform.net/publift/tags/2/3476/fuse.js" id="mb-fuse-script" async></script>
34
35	
35<script src="/modules/mod_jux_megamenu/assets/js/jux_megamenu_merged.js"></script>
35
36	
36<script>if (typeof jfbcJQuery == "undefined") jfbcJQuery = jQuery;</script>
36
37	<link rel="canonical" href="https://www.meteobelgique.be/observations/animation/radar-precipitations"/>
38	<link rel="alternate" href="https://www.meteobelgique.be/observations/animation/radar-precipitations" hreflang="fr-be" />
39	<link rel="alternate" href="https://www.meteobelgie.be/waarnemingen/animaties/neerslagradar" hreflang="nl-be" />
40	<link rel="alternate" href="https://www.meteobelgique.be/observations/animation/radar-precipitations" hreflang="x-default" />
41
42    <meta http-equiv="X-UA-Compatible" content="IE=edge">
43    <meta name="viewport" content="width=device-width, initial-scale=1">
44	<meta name="verify-v1" content="hwudPBEDpG4n6C1XThctjS0ybOt8ErL/Bh6aKjwOMV4=" /> 
45  
46    <meta name="apple-itunes-app" content="app-id=689793990">
47    <meta name="google-play-app" content="app-id=com.wazabe.meteobelgique"> 
48
49<!-- MANDATORY: BEGIN IAB STUB -->
50<script type="text/javascript">
51  !function(){var e=function(){var e,t="__tcfapiLocator",a=[],n=window;for(;n;){try{if(n.frames[t]){e=n;break}}catch(e){}if(n===window.top)break;n=n.parent}e||(!function e(){var a=n.document,r=!!n.frames[t];if(!r)if(a.body){var s=a.createElement("iframe");s.style.cssText="display:none",s.name=t,a.body.appendChild(s)}else setTimeout(e,5);return!r}(),n.__tcfapi=function(){for(var e,t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];if(!n.length)return a;if("setGdprApplies"===n[0])n.length>3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0));else if("ping"===n[0]){var s={gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"};"function"==typeof n[2]&&n[2](s)}else a.push(n)},n.addEventListener("message",(function(e){var t="string"==typeof e.data,a={};try{a=t?JSON.parse(e.data):e.data}catch(e){}var n=a.__tcfapiCall;n&&window.__tcfapi(n.command,n.version,(function(a,r){var s={__tcfapiReturn:{returnValue:a,success:r,callId:n.callId}};t&&(s=JSON.stringify(s)),e&&e.source&&e.source.postMessage&&e.source.postMessage(s,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=e:e()}();
52</script>
52
53<!-- MANDATORY: END IAB STUB -->
54<script type="text/javascript">
55  const configSFBXAppConsent = {
56    appKey: '7a6b6d0e-fc7c-4ffb-94b7-0ff32fa4473f'
57  }
58</script>
vendor: 1 bytes, line 58
58
59<script src="https://cdn.appconsent.io/tcf2-clear/current/core.bundle.js" defer async></script>
vendor: 1 bytes, line 59
59
60<script type="text/javascript">
61  window.dataLayer = window.dataLayer || [];
62  if (typeof gtag === 'function') {
63    window.isGtagInitBeforeAppConsent = true
64  } else {
65    function gtag() {
66      dataLayer.push(arguments);
67    }
68  }
69  (window.adsbygoogle = window.adsbygoogle || []).pauseAdRequests = 1;
70  gtag('consent', 'default', {
71    'analytics_storage': 'denied',
72    'ad_user_data': 'denied',
73    'ad_personalization': 'denied',
74    'functionality_storage': 'denied',
75    'security_storage': 'granted',
76    'personalization_storage': 'denied',
77    'ad_storage': 'denied',
78    'wait_for_update': 500
79  });
80</script>
80  
81  
82	<!-- 
82<script async src="https://cdn.fuseplatform.net/publift/tags/2/3476/fuse.js"></script>
82 -->
83    	
84    <!-- Google tag (gtag.js) -->
vendor: 68 bytes, lines 84-85
84
85    <script async src="https://www.googletagmanager.com/gtag/js?id=
85G-GP2R00L70J
vendor: 16 bytes, lines 85-86
85"></script>
86    
86<script>
87      
vendor: 145 bytes, lines 87-90
87window.dataLayer = window.dataLayer || [];
88      function gtag(){dataLayer.push(arguments);}
89      gtag('js', new Date());
90      gtag('config', '
90G-GP2R00L70J
vendor: 8 bytes, lines 90-91
90');
91    
91</script>
91
92           
93  <link href="/media/vendor/fontawesome-free/css/fontawesome.css" rel="stylesheet" data-asset-name="fontawesome">
94  <link rel="stylesheet" href="/templates/Content-new/css/bootstrap.css?v=3" type="text/css" />
95  <link rel="stylesheet" href="/templates/Content-new/css/template.css" type="text/css" />
96  <link rel="stylesheet" href="/templates/Merged/css/main.css?v=8" type="text/css" />
97  <link rel="stylesheet" href="/templates/Merged/css/layout.css?v=5" type="text/css" />
98 
99  <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700&display=swap" rel="stylesheet">
100
101  <link rel="shortcut icon" href="/templates/Content-new/favicon.ico">
102  
103   
104
105</head>
106
107<body id="default">
108	<section class="nav_top">
109        <div id="topmenu">
110    		<ul class="mod-menu mod-list nav ">
111<li class="nav-item item-371"><a href="https://www.meteobelgique.be" >Accueil</a></li><li class="nav-item item-373"><a href="/observations/animation/radar-precipitations" >Radar</a></li><li class="nav-item item-372"><a href="/observations/animation/image-satellite" >Image satellite</a></li><li class="nav-item item-375"><a href="/observations/temps-reel/stations-meteo" >Stations</a></li><li class="nav-item item-374"><a href="/observations/temps-reel/webcam" >Webcams</a></li><li class="nav-item item-376"><a href="/services/information/actualite" >Actualité</a></li><li class="nav-item item-377"><a href="/info-trafic?/option=com_static&amp;staticfile=services-trafic.php" >Info Trafic</a></li></ul>
112
113		</div>
114        <div id="lang">
115    		
116<div id="mod-custom155" class="mod-custom custom">
117    <ul>
118<li class="lang-active"><a href="http://www.meteobelgique.be/">FR</a></li>
119<li><a href="http://www.meteobelgie.be/">NL</a></li>
120</ul></div>
121
122		</div>
123        <div id="user">
124    		
125    <div class="sourcecoast ns-bs5 sclogin-modal-links sclogin">
126        <a href="/"  data-bs-toggle="modal" data-bs-target="#login-modal-208">
127			Connexion        </a>
128        <div id="login-modal-208" role="dialog" tabindex="-1" class="joomla-modal modal"  >
129    <div class="modal-dialog modal-lg">
130        <div class="modal-content">
131            <div class="modal-header">
132            <h3 class="modal-title">MeteoBelgique Premium</h3>
133                <button type="button" class="btn-close novalidate" data-bs-dismiss="modal" aria-label="Fermer">
134        </button>
135    </div>
136<div class="modal-body">
137    <div class="sclogin sourcecoast ns-bs5" id="sclogin-208">
138    
139    <div class="row">
140        
141    <div class="sclogin-joomla-login vertical col-md-12">
142                <form action="/observations/animation/radar-precipitations?staticfile=realtime-radarbelgium.php&amp;extserv=1" method="post" id="sclogin-form208">
143            <div class="mod-sclogin__userdata userdata">
144                <div class="mod-sclogin__username mb-3">
145                    <div class="input-group">
146                        <label for="sclogin-username-208" class="visually-hidden">Nom d'utilisateur</label>
147                        <input id="sclogin-username-208"
148                               type="text"
149                               name="username"
150                               class="form-control sclogin-username"
151                               autocomplete="username"
152                               placeholder="Nom d'utilisateur"
153                               aria-label="Nom d'utilisateur"
154                               tabindex="0"                         >
155                                                <span class="input-group-text btn " title="Nom d'utilisateur">
156                            <span class="fa-regular fa-user aria-hidden="true"></span>
157                        </span>
158                                                <!-- only add spans if they have buttons present -->
159                                            </div>
160                </div>
161                <div class="mod-sclogin__password mb-3">
162                    <div class="input-group">
163                        <input id="sclogin-passwd-208"
164                               type="password"
165                               name="password"
166                               autocomplete="current-password"
167                               class="form-control sclogin-passwd"
168                               placeholder="Mot de passe"
169                               aria-label="Mot de passe"
170                        >
171                        <!-- only add spans if they have buttons present -->
172                                            </div>
173                </div>
174                <div class="mb-3 form-sclogin-submitcreate gap-2" id="form-sclogin-submitcreate-208">
175                    <button type="submit" name="Submit" class="btn btn-primary col-md-12" aria-label="Connexion">Connexion</button>
176                    					                                    </div>
177                                        <div class="form-check">
178                            <div class="mb-3 form-sclogin-remember" id="form-sclogin-remember-208">
179                                <label for="sclogin-remember-208">
180                                    <input id="sclogin-remember-208" type="checkbox" name="remember" class="form-check-input sclogin-remember" checked value="yes" title="Remember Me" aria-label="Remember Me"/>
181                                    Se rappeler de moi                                </label>
182                            </div>
183                        </div>
184                    
185                <input type="hidden" name="option" value="com_users"/><input type="hidden" name="task" value="user.login"/><input type="hidden" name="return" value="aHR0cHM6Ly93d3cubWV0ZW9iZWxnaXF1ZS5iZS9vYnNlcnZhdGlvbnMvYW5pbWF0aW9uL3JhZGFyLXByZWNpcGl0YXRpb25z"/><input type="hidden" name="mod_id" value="208"/><input type="hidden" name="54ec6a26a1c73b00855e669bed2ab093" value="1">            </div>
186        </form>
187    </div>
188        </div>
189
190        <div class="clearfix"></div>
191</div>
192</div>
193        </div>
194    </div>
195</div>
196            </div>
197
198    
198<script>
199        jfbcJQuery(document).ready(function () {
200            jfbcJQuery("#login-modal-208").appendTo("body");
201        });
202        
203        jfbcJQuery('#login-modal-208').addClass('sourcecoast sclogin-modal');
204    </script>
204
205
206    
207
208		</div>
209		<div class="clr"></div>
210    </section>
211    <header>
212        <div id="logo">
213        	<a href="https://www.meteobelgique.be"></a>
214        </div>
215		<div id="search">
216			
217<div id="mod-custom174" class="mod-custom custom">
218    <form action="https://www.meteobelgique.be/observations/animation/radar-precipitations"
219      method="post" id="qform" autocomplete="off">
220    <input type="hidden" name="54ec6a26a1c73b00855e669bed2ab093" value="1" />
221    <input name="query" id="query"
222           maxlength="80"
223           placeholder="La météo pour ..." />
224    <button type="submit"></button>
225    <input type="hidden" name="zip" id="zip" pattern="[0-9]{4,6}" />
226</form>
227<div id="suggestions"></div>
228
229<script>
230(function () {
231    const input = document.getElementById("query");
232    const suggestionsBox = document.getElementById("suggestions");
233    const zipField = document.getElementById("zip");
234    const form = document.getElementById("qform");
235    let timeout = null;
236    let controller = null; // pour annuler les requêtes obsolètes
237
238    // N'autorise que les chemins relatifs internes (évite open redirect / javascript: URI)
239    function isSafeInternalUrl(url) {
240        if (typeof url !== "string") return false;
241        // doit commencer par un seul "/" (pas "//" qui est protocol-relative)
242        if (!/^\/(?!\/)/.test(url)) return false;
243        // interdit tout caractère de contrôle ou schéma déguisé
244        if (/^[a-z][a-z0-9+.\-]*:/i.test(url)) return false;
245        return true;
246    }
247
248    // N'autorise que des codes postaux numériques
249    function isSafeZip(zip) {
250        return typeof zip === "string" && /^[0-9]{4,6}$/.test(zip);
251    }
252
253    input.addEventListener("input", function () {
254        clearTimeout(timeout);
255        const kw = input.value.trim();
256
257        // Limite stricte des caractères autorisés (lettres, espaces, tirets, apostrophes, chiffres pour CP)
258        if (kw.length < 2 || kw.length > 80 || !/^[\p{L}0-9 \-'’]+$/u.test(kw)) {
259            suggestionsBox.style.display = "none";
260            suggestionsBox.innerHTML = "";
261            return;
262        }
263
264        timeout = setTimeout(() => {
265            if (controller) controller.abort();
266            controller = new AbortController();
267
268            fetch("/jsonservice/search_city.php?kw=" + encodeURIComponent(kw), {
269                signal: controller.signal,
270                headers: { "Accept": "application/json" }
271            })
272                .then(res => {
273                    if (!res.ok) throw new Error("Réponse invalide");
274                    return res.json();
275                })
276                .then(data => {
277                    const datasource = [
278                        ...(Array.isArray(data.cities) ? data.cities : []),
279                        ...(Array.isArray(data.nearby) ? data.nearby : [])
280                    ];
281
282                    suggestionsBox.innerHTML = "";
283                    suggestionsBox.style.display = datasource.length ? "block" : "none";
284
285                    datasource.forEach(o => {
286                        // Validation stricte de chaque champ avant utilisation
287                        if (!isSafeInternalUrl(o.url) || !isSafeZip(String(o.cpost)) || typeof o.label !== "string") {
288                            return; // on ignore silencieusement toute entrée suspecte
289                        }
290
291                        const div = document.createElement("div");
292                        div.textContent = o.label; // textContent => pas d'injection HTML
293                        div.dataset.zip = o.cpost;
294                        div.dataset.url = o.url;
295                        div.tabIndex = 0;
296                        div.setAttribute("role", "option");
297
298                        div.addEventListener("click", function () {
299                            input.value = o.label;
300                            zipField.value = o.cpost;
301                            form.action = o.url; // déjà validé par isSafeInternalUrl
302                            form.submit();
303                        });
304
305                        suggestionsBox.appendChild(div);
306                    });
307                })
308                .catch(err => {
309                    if (err.name !== "AbortError") {
310                        suggestionsBox.style.display = "none";
311                    }
312                });
313        }, 250);
314    });
315
316    document.addEventListener("click", function (e) {
317        if (!suggestionsBox.contains(e.target) && e.target !== input) {
318            suggestionsBox.style.display = "none";
319        }
320    });
321})();
322</script>
322</div>
323
324		</div>
325		<div id="vigilance">
326			<div class="componentheading">Vigilance météo</div>
327
328<div id="warn-map-no-slide"><a class="warn-slide"><img src="https://www.meteobelgium.org/staticfiles/images/maps_templates/warn_homepage_no_warning.png" 
329       width="100" height="100" 
330       alt="Vigilance météo"/></a></div>
331
332		</div>
333		<div class="clr"></div>
334	</header>
335    <nav>
336        <div id="weatherhere">
337   			
338<div id="mod-custom173" class="mod-custom custom">
339    <i class="fa-solid fa-location-dot"></i>
340<div class="favorite_location btn-group"><a id="location-cpost-position" class="btn btn-primary" title="Prévisions météo pour Bruxelles" href="/previsions-meteo-belgique/1000/bruxelles"><div class="city">Bruxelles</div><div class="symbol_picture"><img id="location-picto-position" alt="Ciel très nuageux" title="Ciel très nuageux" src="/staticfiles/images/picto/v2/wc/day/mostcloudy.png" /></div><div class="temp"><span id="location-temp-position">21</span> &deg;C</div></a><button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="sr-only">Toggle Dropdown</span></button><div class="dropdown-menu"><div class="dropdown-item">Aucun favori</div></div></div>
341<script>
342
343function applyData(data) {
344    var zone = data['zone'];
345    var today = zone['today'];
346    
347            jQuery("#location-cpost-position .city").html(zone['city_short_desktop']);
348    
349    jQuery("#location-cpost-position").attr("href", zone['link']);
350    jQuery("#location-cpost-position").attr("title", zone['city']);
351    jQuery("#location-picto-position").attr("src", "/staticfiles/images/picto/v2/wc/" + today['pictoprefix'] + '/' + today['symbol_file_now']);
352    jQuery("#location-picto-position").attr("alt", today['symbol_label_now']);
353    jQuery("#location-picto-position").attr("title", today['symbol_label_now']);
354    jQuery("#location-temp-position").html(today['temp']);
355}
356
357function fetchWeather(lat, lng) {
358    jQuery.get({
359        url: 'https://www.meteobelgium.be/jsonservice/forecast_v11.json.php?key=d1dd77179469ca17b0e045be5ed357f8&lang=fr&light=1&lat=' + lat + '&lng=' + lng,
360        dataType: 'json',
361        success: function(data) {
362            sessionStorage.setItem('weather_data', JSON.stringify(data));
363            sessionStorage.setItem('weather_timestamp', Date.now());
364            sessionStorage.setItem('weather_key', lat + '_' + lng);
365            applyData(data);
366        }
367    });
368}
369
370function redirectPosition(position) {
371    const lat = position.coords.latitude;
372    const lng = position.coords.longitude;
373
374    window.dispatchEvent(new CustomEvent("geolocation_ready", {
375        detail: { lat, lng }
376    }));
377
378    sessionStorage.setItem('geo_lat', lat);
379    sessionStorage.setItem('geo_lng', lng);
380
381    const maxAgeWeather = 5 * 60 * 1000; // 5 min
382    const cachedData = sessionStorage.getItem('weather_data');
383    const weather_timestamp = sessionStorage.getItem('weather_timestamp');
384    const cacheKey = sessionStorage.getItem('weather_key');
385
386    if (
387        cachedData &&
388        weather_timestamp &&
389        cacheKey === (lat + '_' + lng) &&
390        (Date.now() - weather_timestamp < maxAgeWeather)
391    ) {
392        applyData(JSON.parse(cachedData));
393    } else {
394        fetchWeather(lat, lng);
395    }
396}
397
398const geo_maxAge = 10 * 60 * 1000;
399
400const geo_lat = sessionStorage.getItem('geo_lat');
401const geo_lng = sessionStorage.getItem('geo_lng');
402const geo_timestamp = sessionStorage.getItem('geo_timestamp');
403
404if (geo_lat && geo_lng && geo_timestamp && (Date.now() - geo_timestamp < geo_maxAge)) {
405    redirectPosition({
406        coords: {
407            latitude: geo_lat,
408            longitude: geo_lng
409        }
410    });
411} else if (navigator.geolocation) {
412	sessionStorage.setItem('geo_timestamp', Date.now());
413    navigator.geolocation.getCurrentPosition(redirectPosition);
414}
415
416</script>
416
417</div>
418
419		</div>
420        <div id="menu">
421    		<div id="jux_memamenu172">
422    <div id="megamenucss" class="megamenucss172">
423        <div id="js-mainnav" class="clearfix megamenu horizontal left blackwhite left down noJS  megamenu">
424                        <div id="CSS3-megaMenuToggle" class="megaMenuToggle">
425                <i class="jux-fa jux-fa-bars fa-solid fa-bars font-item-menu"></i>
426            </div>
427                        <div class=" mainNav js-megamenu container   clearfix" id="js-meganav">
428<ul class="megamenu level0"><li  id="Accueil" class="megacss first submenu-align-auto"><a href="javascript:void(0);"  class="megacss first  hasTip" id="menu167" ><span class="menu-title"><i class="jux-fa  jux-"></i>Accueil</span></a></li><li  id="Prévisions" class="megacss haschild submenu-align-fullwidth"><a href="javascript:void(0);"  class="megacss haschild  hasTip" id="menu143" ><span class="menu-title"><i class="jux-fa  jux-"></i>Prévisions</span></a><div style='0' class="childcontent adddropdown clearfix cols4    ">
429<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
430<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 170px;"><ul class="megamenu level1"><li  id="Belgique" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu311" ><span class="menu-title"><i class="jux-fa  jux-"></i>Belgique</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Aujourd'hui" class="megacss first submenu-align-auto"><a href="https://www.meteobelgique.be"  class="megacss first  hasTip" id="menu58" ><span class="menu-title"><i class="jux-fa  jux-"></i>Aujourd'hui</span></a></li><li  id="Demain" class="megacss submenu-align-auto"><a href="/previsions-meteo/belgique/demain"  class="megacss  hasTip" id="menu53" ><span class="menu-title"><i class="jux-fa  jux-"></i>Demain</span></a></li><li  id="Alertesetvigilances" class="megacss submenu-align-auto"><a href="/previsions/belgique/alertes-et-vigilances"  class="megacss  hasTip" id="menu117" ><span class="menu-title"><i class="jux-fa  jux-"></i>Alertes et vigilances</span></a></li><li  id="Tendancessaisonnières" class="megacss submenu-align-auto"><a href="/previsions/belgique/tendances-saisonnieres"  class="megacss  hasTip" id="menu83" ><span class="menu-title"><i class="jux-fa  jux-"></i>Tendances saisonnières</span></a></li><li  id="BulletinVidéo" class="megacss submenu-align-auto"><a href="/previsions/belgique/bulletin-video"  class="megacss  hasTip" id="menu135" ><span class="menu-title"><i class="jux-fa  jux-"></i>Bulletin Vidéo</span></a></li><li  id="Barbecue?" class="megacss submenu-align-auto"><a href="/previsions/belgique/barbecue"  class="megacss  hasTip" id="menu136" ><span class="menu-title"><i class="jux-fa  jux-"></i>Barbecue ?</span></a></li><li  id="Marées" class="megacss last submenu-align-auto"><a href="https://www.meteobelgique.be/previsions-meteo-belgique/marees/8400/ostende"  class="megacss last  hasTip" id="menu477" ><span class="menu-title"><i class="jux-fa  jux-"></i>Marées</span></a></li></ul></div></div></li></ul></div><div class="megacol column2" style="width: 170px;"><ul class="megamenu level1"><li  id="Europe" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu468" ><span class="menu-title"><i class="jux-fa  jux-"></i>Europe</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Prochainsjours" class="megacss first submenu-align-auto"><a href="/previsions/europe/prochains-jours"  class="megacss first  hasTip" id="menu66" ><span class="menu-title"><i class="jux-fa  jux-"></i>Prochains jours</span></a></li><li  id="CartesSynoptiques" class="megacss last submenu-align-auto"><a href="/previsions/europe/cartes-synoptiques"  class="megacss last  hasTip" id="menu94" ><span class="menu-title"><i class="jux-fa  jux-"></i>Cartes Synoptiques</span></a></li></ul></div></div></li></ul></div><div class="megacol column3" style="width: 170px;"><ul class="megamenu level1"><li  id="Pro" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu317" ><span class="menu-title"><i class="jux-fa  jux-"></i>Pro</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="MétéoPro" class="megacss first submenu-align-auto"><a href="/previsions/pro/meteo-pro"  class="megacss first  hasTip" id="menu107" ><span class="menu-title"><i class="jux-fa  jux-"></i>Météo Pro</span></a></li><li  id="Météoagricole" class="megacss submenu-align-auto"><a href="/previsions/pro/meteo-agricole"  class="megacss  hasTip" id="menu491" ><span class="menu-title"><i class="jux-fa  jux-"></i>Météo agricole</span></a></li><li  id="Sécheresse" class="megacss submenu-align-auto"><a href="/previsions/pro/secheresse"  class="megacss  hasTip" id="menu139" ><span class="menu-title"><i class="jux-fa  jux-"></i>Sécheresse</span></a></li><li  id="Risqued'incendie" class="megacss submenu-align-auto"><a href="/previsions/pro/risque-incendie"  class="megacss  hasTip" id="menu120" ><span class="menu-title"><i class="jux-fa  jux-"></i>Risque d'incendie</span></a></li><li  id="Météogramme" class="megacss last haschild submenu-align-auto"><a href="/previsions/pro/meteogramme"  class="megacss last haschild  hasTip" id="menu427" ><span class="menu-title"><i class="jux-fa  jux-"></i>Météogramme</span></a><div style='0' class="childcontent adddropdown clearfix cols1    ">
431<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
432<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 200px;"><ul class="megamenu level2"><li  id="WRF" class="megacss first submenu-align-auto"><a href="/previsions/pro/meteogramme/wrf"  class="megacss first  hasTip" id="menu429" ><span class="menu-title"><i class="jux-fa  jux-"></i>WRF</span></a></li><li  id="GFS" class="megacss last submenu-align-auto"><a href="/previsions/pro/meteogramme/gfs"  class="megacss last  hasTip" id="menu430" ><span class="menu-title"><i class="jux-fa  jux-"></i>GFS</span></a></li></ul></div></div>
433</div></div></li></ul></div></div></li></ul></div><div class="megacol column4 last" style="width: 170px;"><ul class="megamenu level1"><li  id="Modèles" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu421" ><span class="menu-title"><i class="jux-fa  jux-"></i>Modèles</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="ICON-D2Belgique" class="megacss first submenu-align-auto"><a href="/previsions/modeles-meteo/icon-d2"  class="megacss first  hasTip" id="menu485" ><span class="menu-title"><i class="jux-fa  jux-"></i>ICON-D2 Belgique</span></a></li><li  id="AromeBelgique" class="megacss submenu-align-auto"><a href="/previsions/modeles-meteo/arome"  class="megacss  hasTip" id="menu423" ><span class="menu-title"><i class="jux-fa  jux-"></i>Arome Belgique</span></a></li><li  id="AlaroBelgique" class="megacss submenu-align-auto"><a href="/previsions/modeles-meteo/alaro"  class="megacss  hasTip" id="menu440" ><span class="menu-title"><i class="jux-fa  jux-"></i>Alaro Belgique</span></a></li><li  id="GFSBelgique-1h" class="megacss submenu-align-auto"><a href="/previsions/modeles-meteo/gfs-be-1h"  class="megacss  hasTip" id="menu418" ><span class="menu-title"><i class="jux-fa  jux-"></i>GFS Belgique - 1h</span></a></li><li  id="GFSBelgique-3h" class="megacss submenu-align-auto"><a href="/previsions/modeles-meteo/gfs-be"  class="megacss  hasTip" id="menu461" ><span class="menu-title"><i class="jux-fa  jux-"></i>GFS Belgique - 3h</span></a></li><li  id="GFSEurope" class="megacss submenu-align-auto"><a href="/previsions/modeles-meteo/gfs-eu"  class="megacss  hasTip" id="menu419" ><span class="menu-title"><i class="jux-fa  jux-"></i>
433GFS Europe</span></a></li><li  id="ECMWFBelgique" class="megacss submenu-align-auto"><a href="/previsions/modeles-meteo/ecmwf-be"  class="megacss  hasTip" id="menu490" ><span class="menu-title"><i class="jux-fa  jux-"></i>ECMWF Belgique</span></a></li><li  id="ECMWFEurope" class="megacss last submenu-align-auto"><a href="/previsions/modeles-meteo/ecmwf-eu"  class="megacss last  hasTip" id="menu422" ><span class="menu-title"><i class="jux-fa  jux-"></i>ECMWF Europe</span></a></li></ul></div></div></li></ul></div></div>
434</div></div></li><li  id="Observations" class="megacss haschild active submenu-align-fullwidth"><a href="javascript:void(0);"  class="megacss haschild active  hasTip" id="menu327" ><span class="menu-title"><i class="jux-fa  jux-"></i>Observations</span></a><div style='0' class="childcontent adddropdown clearfix cols4    ">
435<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
436<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 170px;"><ul class="megamenu level1"><li  id="Tempsréel" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu320" ><span class="menu-title"><i class="jux-fa  jux-"></i>Temps réel</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Stationsmétéo" class="megacss first submenu-align-auto"><a href="/observations/temps-reel/stations-meteo"  class="megacss first  hasTip" id="menu69" ><span class="menu-title"><i class="jux-fa  jux-"></i>Stations météo</span></a></li><li  id="Webcams" class="megacss submenu-align-auto"><a href="/observations/temps-reel/webcam"  class="megacss  hasTip" id="menu70" ><span class="menu-title"><i class="jux-fa  jux-"></i>Webcams</span></a></li><li  id="Températures" class="megacss submenu-align-auto"><a href="/observations/temps-reel/temperature"  class="megacss  hasTip" id="menu123" ><span class="menu-title"><i class="jux-fa  jux-"></i>Températures</span></a></li><li  id="Vitesseduvent" class="megacss submenu-align-auto"><a href="/observations/temps-reel/vent"  class="megacss  hasTip" id="menu425" ><span class="menu-title"><i class="jux-fa  jux-"></i>Vitesse du vent</span></a></li><li  id="Pluie24h" class="megacss submenu-align-auto"><a href="/observations/temps-reel/pluie-24h"  class="megacss  hasTip" id="menu428" ><span class="menu-title"><i class="jux-fa  jux-"></i>Pluie 24h</span></a></li><li  id="Observationsdétaillées" class="megacss last haschild submenu-align-auto"><a href="/observations/temps-reel/observation-detaillee"  class="megacss last haschild  hasTip" id="menu75" ><span class="menu-title"><i class="jux-fa  jux-"></i>Observations détaillées</span></a><div style='0' class="childcontent adddropdown clearfix cols1    ">
437<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
438<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 200px;"><ul class="megamenu level2"><li  id="Carte" class="megacss first submenu-align-auto"><a href="/observations/temps-reel/observation-detaillee/carte"  class="megacss first  hasTip" id="menu77" ><span class="menu-title"><i class="jux-fa  jux-"></i>Carte</span></a></li><li  id="Tableau" class="megacss last submenu-align-auto"><a href="/observations/temps-reel/observation-detaillee/tableau"  class="megacss last  hasTip" id="menu78" ><span class="menu-title"><i class="jux-fa  jux-"></i>Tableau</span></a></li></ul></div></div>
439</div></div></li></ul></div></div></li></ul></div><div class="megacol column2" style="width: 170px;"><ul class="megamenu level1"><li  id="Animations" class="megacss first group active submenu-align-auto"><div class="group clearfix"><div class="group-title active"><span  class="megacss first group active  hasTip" id="menu319" ><span class="menu-title"><i class="jux-fa  jux-"></i>Animations</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Radarprécipitations" class="megacss first active submenu-align-auto"><a href="/observations/animation/radar-precipitations"  class="megacss first active  hasTip" id="menu61" ><span class="menu-title"><i class="jux-fa  jux-"></i>Radar précipitations</span></a></li><li  id="Radardeneige" class="megacss submenu-align-auto"><a href="/observations/animation/radar-de-neige"  class="megacss  hasTip" id="menu475" ><span class="menu-title"><i class="jux-fa  jux-"></i>Radar de neige</span></a></li><li  id="Imagesatellite" class="megacss submenu-align-auto"><a href="/observations/animation/image-satellite"  class="megacss  hasTip" id="menu67" ><span class="menu-title"><i class="jux-fa  jux-"></i>Image satellite</span></a></li><li  id="Impactsdefoudre" class="megacss submenu-align-auto"><a href="/observations/animation/impacts-de-foudre-suivi-orages"  class="megacss  hasTip" id="menu411" ><span class="menu-title"><i class="jux-fa  jux-"></i>Impacts de foudre</span></a></li><li  id="Cumuldesprécipitations" class="megacss last submenu-align-auto"><a href="/observations/animation/cumul"  class="megacss last  hasTip" id="menu505" ><span class="menu-title"><i class="jux-fa  jux-"></i>Cumul des précipitations</span></a></li></ul></div></div></li></ul></div><div class="megacol column3" style="width: 170px;"><ul class="megamenu level1"><li  id="Divers" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu321" ><span class="menu-title"><i class="jux-fa  jux-"></i>Divers</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Qualitédel'air" class="megacss first submenu-align-auto"><a href="/observations/divers/qualite-de-lair"  class="megacss first  hasTip" id="menu101" ><span class="menu-title"><i class="jux-fa  jux-"></i>Qualité de l'air</span></a></li><li  id="Météodesneiges" class="megacss submenu-align-auto"><a href="/observations/divers/meteo-des-neiges"  class="megacss  hasTip" id="menu112" ><span class="menu-title"><i class="jux-fa  jux-"></i>
439Météo des neiges</span></a></li><li  id="Niveaudescoursd'eau" class="megacss submenu-align-auto"><a href="/observations/divers/niveau-cours-deau"  class="megacss  hasTip" id="menu140" ><span class="menu-title"><i class="jux-fa  jux-"></i>Niveau des cours d'eau</span></a></li><li  id="Observationdutemps" class="megacss submenu-align-auto"><a href="/observations/divers/observations-du-temps"  class="megacss  hasTip" id="menu98" ><span class="menu-title"><i class="jux-fa  jux-"></i>Observation du temps</span></a></li><li  id="Statistiquesdefoudre" class="megacss last submenu-align-auto"><a href="/observations/divers/statistiques-foudre"  class="megacss last  hasTip" id="menu443" ><span class="menu-title"><i class="jux-fa  jux-"></i>Statistiques de foudre</span></a></li></ul></div></div></li></ul></div><div class="megacol column4 last" style="width: 170px;"><ul class="megamenu level1"><li  id="Europe" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu322" ><span class="menu-title"><i class="jux-fa  jux-"></i>Europe</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="RadarPrécipitations" class="megacss first submenu-align-auto"><a href="/observations/europe/radar-precipitations"  class="megacss first  hasTip" id="menu68" ><span class="menu-title"><i class="jux-fa  jux-"></i>Radar Précipitations</span></a></li><li  id="Imagesatellite" class="megacss submenu-align-auto"><a href="/observations/europe/image-satellite"  class="megacss  hasTip" id="menu413" ><span class="menu-title"><i class="jux-fa  jux-"></i>Image satellite</span></a></li><li  id="Webcams" class="megacss submenu-align-auto"><a href="/observations/europe/webcams"  class="megacss  hasTip" id="menu121" ><span class="menu-title"><i class="jux-fa  jux-"></i>Webcams</span></a></li><li  id="Impactdefoudre" class="megacss submenu-align-auto"><a href="/observations/europe/impact-de-foudre"  class="megacss  hasTip" id="menu407" ><span class="menu-title"><i class="jux-fa  jux-"></i>Impact de foudre</span></a></li><li  id="Températures" class="megacss last submenu-align-auto"><a href="/observations/europe/temperature"  class="megacss last  hasTip" id="menu474" ><span class="menu-title"><i class="jux-fa  jux-"></i>Températures</span></a></li></ul></div></div></li></ul></div></div>
440</div></div></li><li  id="Services" class="megacss haschild submenu-align-fullwidth"><a href="javascript:void(0);"  class="megacss haschild  hasTip" id="menu2" ><span class="menu-title"><i class="jux-fa  jux-"></i>Services</span></a><div style='0' class="childcontent adddropdown clearfix cols4    ">
441<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
442<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 170px;"><ul class="megamenu level1"><li  id="Premium" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu324" ><span class="menu-title"><i class="jux-fa  jux-"></i>Premium</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Ensavoirplus" class="megacss first submenu-align-auto"><a href="/premium/info"  class="megacss first  hasTip" id="menu74" ><span class="menu-title"><i class="jux-fa  jux-"></i>En savoir plus</span></a></li><li  id="S'inscrire" class="megacss submenu-align-auto"><a href="/services/premium/inscription"  class="megacss  hasTip" id="menu330" ><span class="menu-title"><i class="jux-fa  jux-"></i>S'inscrire</span></a></li><li  id="Nouvelabonnement" class="megacss submenu-align-auto"><a href="/services/premium/nouvel-abonnement"  class="megacss  hasTip" id="menu331" ><span class="menu-title"><i class="jux-fa  jux-"></i>Nouvel abonnement</span></a></li><li  id="Seconnecter" class="megacss last submenu-align-auto"><a href="/services/premium/se-connecter"  class="megacss last  hasTip" id="menu408" ><span class="menu-title"><i class="jux-fa  jux-"></i>Se connecter</span></a></li></ul></div></div></li></ul></div><div class="megacol column2" style="width: 170px;"><ul class="megamenu level1"><li  id="Mobile" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu325" ><span class="menu-title"><i class="jux-fa  jux-"></i>Mobile</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="AlertesSMS" class="megacss first submenu-align-auto"><a href="/services/mobile/alerte-sms"  class="megacss first  hasTip" id="menu79" ><span class="menu-title"><i class="jux-fa  jux-"></i>Alertes SMS</span></a></li><li  id="ApplicationAndroid" class="megacss submenu-align-auto"><a href="https://play.google.com/store/apps/details" target="_blank"  class="megacss  hasTip" id="menu332" ><span class="menu-title"><i class="jux-fa  jux-"></i>Application Android</span></a></li><li  id="ApplicationiPhone" class="megacss last submenu-align-auto"><a href="https://itunes.apple.com/be/app/meteo-belgique/id689793990" target="_blank"  class="megacss last  hasTip" id="menu333" ><span class="menu-title"><i class="jux-fa  jux-"></i>Application iPhone</span></a></li></ul></div></div></li></ul></div><div class="megacol column3" style="width: 170px;"><ul class="megamenu level1"><li  id="Divers" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu326" ><span class="menu-title"><i class="jux-fa  jux-"></i>Divers</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Météosurmesure" class="megacss first submenu-align-auto"><a href="/services/divers/meteo-sur-mesure"  class="megacss first  hasTip" id="menu95" ><span class="menu-title"><i class="jux-fa  jux-"></i>Météo sur mesure</span></a></li><li  id="Météosurvotresite" class="megacss submenu-align-auto"><a href="/services/divers/meteo-sur-votre-site"  class="megacss  hasTip" id="menu111" ><span class="menu-title"><i class="jux-fa  jux-"></i>Météo sur votre site</span></a></li><li  id="Archivedesstations" class="megacss last submenu-align-auto"><a href="/services/divers/archive-des-stations"  class="megacss last  hasTip" id="menu392" ><span class="menu-title"><i class="jux-fa  jux-"></i>Archive des stations</span></a></li></ul></div></div></li></ul></div><div class="megacol column4 last" style="width: 170px;"><ul class="megamenu level1"><li  id="Information" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu328" ><span class="menu-title"><i class="jux-fa  jux-"></i>Information</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Actualité" class="megacss first submenu-align-auto"><a href="/services/information/actualite"  class="megacss first  hasTip" id="menu56" ><span class="menu-title"><i class="jux-fa  jux-"></i>Actualité</span></a></li><li  id="InfoTrafic" class="megacss submenu-align-auto"><a href="/services/information/info-trafic"  class="megacss  hasTip" id="menu109" ><span class="menu-title"><i class="jux-fa  jux-"></i>Info Trafic</span></a></li><li  id="Sortiecinéma" class="megacss last submenu-align-auto"><a href="/services/information/sortie-cinema"  class="megacss last  hasTip" id="menu106" ><span class="menu-title"><i class="jux-fa  jux-"></i>Sortie cinéma</span></a></li></ul></div></div></li></ul></div></div>
443</div></div></li><li  id="Climatologie" class="megacss haschild submenu-align-fullwidth"><a href="javascript:void(0);"  class="megacss haschild  hasTip" id="menu37" ><span class="menu-title"><i class="jux-fa  jux-"></i>Climatologie</span></a><div style='0' class="childcontent adddropdown clearfix cols4    ">
444<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
445<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 170px;"><ul class="megamenu level1"><li  id="Donnéesgraphiques" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu71" ><span class="menu-title"><i class="jux-fa  jux-"></i>Données graphiques</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Uccledepuis1833" class="megacss first submenu-align-auto"><a href="/article/donnees-statistiques/uccle-depuis-1833"  class="megacss first  hasTip" id="menu72" ><span class="menu-title"><i class="jux-fa  jux-"></i>Uccle depuis 1833</span></a></li><li  id="Enneigementdécadaire" class="megacss submenu-align-auto"><a href="/article/donnees-statistiques/enneigement-decadaire"  class="megacss  hasTip" id="menu73" ><span class="menu-title"><i class="jux-fa  jux-"></i>Enneigement décadaire</span></a></li><li  id="Degrés-jours" class="megacss submenu-align-auto"><a href="/article/donnees-statistiques/degres-jours"  class="megacss  hasTip" id="menu116" ><span class="menu-title"><i class="jux-fa  jux-"></i>Degrés-jours</span></a></li><li  id="Climatogrammes" class="megacss last submenu-align-auto"><a href="/article/donnees-statistiques/climatogramme"  class="megacss last  hasTip" id="menu132" ><span class="menu-title"><i class="jux-fa  jux-"></i>Climatogrammes</span></a></li></ul></div></div></li></ul></div><div class="megacol column2" style="width: 170px;"><ul class="megamenu level1"><li  id="RelevésetAnalyses" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu86" ><span class="menu-title"><i class="jux-fa  jux-"></i>Relevés et Analyses</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Année2026" class="megacss first submenu-align-auto"><a href="/article/releves-et-analyses/annee-2026"  class="megacss first  hasTip" id="menu524" ><span class="menu-title"><i class="jux-fa  jux-"></i>Année 2026</span></a></li><li  id="Année2025" class="megacss submenu-align-auto"><a href="/article/releves-et-analyses/annee-2025"  class="megacss  hasTip" id="menu504" ><span class="menu-title"><i class="jux-fa  jux-"></i>Année 2025</span></a></li><li  id="Année2024" class="megacss submenu-align-auto"><a href="/article/releves-et-analyses/annee-2024"  class="megacss  hasTip" id="menu493" ><span class="menu-title"><i class="jux-fa  jux-"></i>Année  2024</span></a></li><li  id="Année2023" class="megacss submenu-align-auto"><a href="/article/releves-et-analyses/annee-2023"  class="megacss  hasTip" id="menu492" ><span class="menu-title"><i class="jux-fa  jux-"></i>Année 2023</span></a></li><li  id="Année2022" class="megacss submenu-align-auto"><a href="/article/releves-et-analyses/annee-2022"  class="megacss  hasTip" id="menu486" ><span class="menu-title"><i class="jux-fa  jux-"></i>Année 2022</span></a></li><li  id="Lasuite..." class="megacss last submenu-align-auto"><a href="/article/releves-et-analyses/la-suite"  class="megacss last  hasTip" id="menu402" ><span class="menu-title"><i class="jux-fa  jux-"></i>La suite...</span></a></li></ul></div></div></li></ul></div><div class="megacol column3" style="width: 170px;"><ul class="megamenu level1"><li  id="Nouvelles" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu334" ><span class="menu-title"><i class="jux-fa  jux-"></i>Nouvelles</span></span></div><div class="group-content"><ul class="mod-articlescategory category-module mod-list">
446                    <li>
447                                    <a href="/article/nouvelles/la-suite/2667-les-vagues-de-chaleur-daout-2026-deux-vagues-de-chaleur-pour-le-prix-dune" class="mod-articles-category-title ">Les vagues de chaleur d'août 2026 : deux vagues de chaleur pour le prix d'une</a>    
448    
449    
450    
451    
452    
453    
454    </li>
455    </ul></div><div class="group-content"><ul class="megamenu level1"><li  id="Lasuite..." class="megacss first submenu-align-auto"><a href="/article/nouvelles/la-suite"  class="megacss first  hasTip" id="menu347" ><span class="menu-title"><i class="jux-fa  jux-"></i>La suite...</span></a></li></ul></div></div></li></ul></div><div class="megacol column4 last" style="width: 170px;"><ul class="megamenu level1"><li  id="Articlesetdossiers" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu335" ><span class="menu-title"><i class="jux-fa  jux-"></i>Articles et dossiers</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Leclimat" class="megacss first submenu-align-auto"><a href="/article/articles-et-dossier/le-climat"  class="megacss first  hasTip" id="menu85" ><span class="menu-title"><i class="jux-fa  jux-"></i>Le climat</span></a></li><li  id="Phénomènesmétéorologiques" class="megacss submenu-align-auto"><a href="/article/articles-et-dossier/phenomenes-meteorologiques"  class="megacss  hasTip" id="menu404" ><span class="menu-title"><i class="jux-fa  jux-"></i>Phénomènes météorologiques</span></a></li><li  id="Lesdossiers" class="megacss submenu-align-auto"><a href="/article/articles-et-dossier/les-dossiers"  class="megacss  hasTip" id="menu406" ><span class="menu-title"><i class="jux-fa  jux-"></i>Les dossiers</span></a></li><li  id="Divers" class="megacss submenu-align-auto"><a href="/article/articles-et-dossier/divers"  class="megacss  hasTip" id="menu405" ><span class="menu-title"><i class="jux-fa  jux-"></i>Divers</span></a></li><li  id="Rechercher" class="megacss last submenu-align-auto"><a href="/article/articles-et-dossier/rechercher"  class="megacss last  hasTip" id="menu469" ><span class="menu-title"><i class="jux-fa  jux-"></i>Rechercher</span></a></li></ul></div></div></li></ul></div></div>
456</div></div></li><li  id="Communauté" class="megacss haschild submenu-align-fullwidth"><a href="javascript:void(0);"  class="megacss haschild  hasTip" id="menu50" ><span class="menu-title"><i class="jux-fa  jux-"></i>
456Communauté</span></a><div style='0' class="childcontent adddropdown clearfix cols4    ">
457<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
458<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 170px;"><ul class="megamenu level1"><li  id="Nouslire" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu339" ><span class="menu-title"><i class="jux-fa  jux-"></i>Nous lire</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Nouvelles" class="megacss first submenu-align-auto"><a href="/communaute/a-lire/nouvelle"  class="megacss first  hasTip" id="menu340" ><span class="menu-title"><i class="jux-fa  jux-"></i>Nouvelles</span></a></li><li  id="FAQ" class="megacss last submenu-align-auto"><a href="/communaute/a-lire/faq"  class="megacss last  hasTip" id="menu91" ><span class="menu-title"><i class="jux-fa  jux-"></i>FAQ</span></a></li></ul></div></div></li></ul></div><div class="megacol column2" style="width: 170px;"><ul class="megamenu level1"><li  id="Noussuivre" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu341" ><span class="menu-title"><i class="jux-fa  jux-"></i>Nous suivre</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Facebook" class="megacss first submenu-align-auto"><a href="http://www.facebook.com/pages/MeteoBelgique/162524033785121" target="_blank"  class="megacss first  hasTip" id="menu138" ><span class="menu-title"><i class="jux-fa  jux-"></i>Facebook</span></a></li><li  id="Twitter" class="megacss last submenu-align-auto"><a href="https://twitter.com/meteobelgiquebe" target="_blank"  class="megacss last  hasTip" id="menu345" ><span class="menu-title"><i class="jux-fa  jux-"></i>Twitter</span></a></li></ul></div></div></li></ul></div><div class="megacol column3" style="width: 170px;"><ul class="megamenu level1"><li  id="Nousrejoindre" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu343" ><span class="menu-title"><i class="jux-fa  jux-"></i>Nous rejoindre</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Forumsdediscussion" class="megacss first submenu-align-auto"><a href="//www.forums.meteobelgium.be/" target="_blank"  class="megacss first  hasTip" id="menu80" ><span class="menu-title"><i class="jux-fa  jux-"></i>Forums de discussion</span></a></li></ul></div></div></li></ul></div><div class="megacol column4 last" style="width: 170px;"><ul class="megamenu level1"><li  id="MeteoBelgique" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu342" ><span class="menu-title"><i class="jux-fa  jux-"></i>MeteoBelgique</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Quisommes-nous?" class="megacss first submenu-align-auto"><a href="/communaute/divers/qui-sommes-nous"  class="megacss first  hasTip" id="menu344" ><span class="menu-title"><i class="jux-fa  jux-"></i>Qui sommes-nous ?</span></a></li><li  id="Contactez-nous" class="megacss submenu-align-auto"><a href="/communaute/divers/contact"  class="megacss  hasTip" id="menu87" ><span class="menu-title"><i class="jux-fa  jux-"></i>Contactez-nous</span></a></li><li  id="Fondd'écran" class="megacss last submenu-align-auto"><a href="/communaute/divers/fond-decran"  class="megacss last  hasTip" id="menu99" ><span class="menu-title"><i class="jux-fa  jux-"></i>Fond d'écran</span></a></li></ul></div></div></li></ul></div></div>
459</div></div></li><li  id="Premium" class="megacss last haschild submenu-align-fullwidth"><a href="javascript:void(0);"  class="megacss last haschild  hasTip" id="menu41" ><span class="menu-title"><i class="jux-fa  jux-"></i>Premium</span></a><div style='0' class="childcontent adddropdown clearfix cols3    ">
460<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
461<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 170px;"><ul class="megamenu level1"><li  id="Prévisions" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu351" ><span class="menu-title"><i class="jux-fa  jux-"></i>Prévisions</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="MétéoPro" class="megacss first submenu-align-auto"><a href="/premium/previsions/meteo-pro"  class="megacss first  hasTip" id="menu352" ><span class="menu-title"><i class="jux-fa  jux-"></i>Météo Pro</span></a></li><li  id="Tendancessaisonnières" class="megacss last submenu-align-auto"><a href="/premium/previsions/tendances-saisonnieres"  class="megacss last  hasTip" id="menu355" ><span class="menu-title"><i class="jux-fa  jux-"></i>Tendances saisonnières</span></a></li></ul></div></div></li></ul></div><div class="megacol column2" style="width: 170px;"><ul class="megamenu level1"><li  id="Observations" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu357" ><span class="menu-title"><i class="jux-fa  jux-"></i>Observations</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Observationsdétaillées" class="megacss first haschild submenu-align-auto"><a href="/premium/observation/observation-detaillee"  class="megacss first haschild  hasTip" id="menu358" ><span class="menu-title"><i class="jux-fa  jux-"></i>Observations détaillées</span></a><div style='0' class="childcontent adddropdown clearfix cols1    ">
462<div class="childcontent-inner-wrap dropdown-menu tabs_vertical">
463<div class="childcontent-inner clearfix"><div class="megacol column1 first" style="width: 200px;"><ul class="megamenu level2"><li  id="Carte" class="megacss first submenu-align-auto"><a href="/premium/observation/observation-detaillee/carte"  class="megacss first  hasTip" id="menu359" ><span class="menu-title"><i class="jux-fa  jux-"></i>
463Carte</span></a></li><li  id="Tableau" class="megacss last submenu-align-auto"><a href="/premium/observation/observation-detaillee/tableau"  class="megacss last  hasTip" id="menu360" ><span class="menu-title"><i class="jux-fa  jux-"></i>Tableau</span></a></li></ul></div></div>
464</div></div></li><li  id="Archivedesstations" class="megacss last submenu-align-auto"><a href="/premium/observation/archive-des-stations"  class="megacss last  hasTip" id="menu393" ><span class="menu-title"><i class="jux-fa  jux-"></i>Archive des stations</span></a></li></ul></div></div></li></ul></div><div class="megacol column3 last" style="width: 170px;"><ul class="megamenu level1"><li  id="Service" class="megacss first group submenu-align-auto"><div class="group clearfix"><div class="group-title"><span  class="megacss first group  hasTip" id="menu366" ><span class="menu-title"><i class="jux-fa  jux-"></i>Service</span></span></div><div class="group-content"><ul class="megamenu level1"><li  id="Ensavoirplus" class="megacss first submenu-align-auto"><a href="/premium/info"  class="megacss first  hasTip" id="menu367" ><span class="menu-title"><i class="jux-fa  jux-"></i>En savoir plus</span></a></li><li  id="S'inscrire" class="megacss submenu-align-auto"><a href="/premium/service/inscription"  class="megacss  hasTip" id="menu368" ><span class="menu-title"><i class="jux-fa  jux-"></i>S'inscrire</span></a></li><li  id="Nouvelabonnement" class="megacss submenu-align-auto"><a href="/premium/service/nouvel-abonnement"  class="megacss  hasTip" id="menu369" ><span class="menu-title"><i class="jux-fa  jux-"></i>Nouvel abonnement</span></a></li><li  id="Seconnecter" class="megacss last submenu-align-auto"><a href="/premium/service/se-connecter"  class="megacss last  hasTip" id="menu409" ><span class="menu-title"><i class="jux-fa  jux-"></i>Se connecter</span></a></li></ul></div></div></li></ul></div></div>
465</div></div></li></ul>
466</div>        </div>
467    </div>
468</div>
469
470<script type="text/javascript">
471    jQuery(document).ready(function ($) {
472
473        $(".megamenucss172 #CSS3-megaMenuToggle").click(function () {
474             // Menu on mobile
475                if(document.body.offsetWidth < 769){ 0
476                                
477                    if ((!$('.jux-custom-css').hasClass('jux-custom-css'))) {
478                        jQuery('.mainNav').navAccordion({
479                            expandButtonText: '<i class="fa-solid fa-angle-down jux-fa jux-fa-angle-down" style="text-align: right !important;" ></i>',  //Text inside of buttons can be HTML
480                            collapseButtonText: '<i class="fa-solid fa-angle-up jux-fa jux-fa-angle-up" style="text-align: right !important;" ></i>'
481                        });
482
483                    }
484                }
485                // end menu on mobile
486            $(".megamenucss172 .js-megamenu").toggleClass("dropdown-menucssjs-meganav");
487            $('.jux-custom-css').addClass('accordion-btn-wrap');
488        });
489        if(document.body.offsetWidth < 769){
490            $(".megamenucss172 .jux_tabs_db").removeClass("jux_tabs_item");  
491        }
492        $(window).resize(function () {
493
494            if (document.body.offsetWidth > 768) {
495                $(".megamenucss172 .jux_tabs_db").addClass("jux_tabs_item"); 
496                $(".megamenucss172 .js-megamenu").removeClass("dropdown-menucssjs-meganav"); 
497                $('.jux-custom-css').removeClass('accordion-btn-wrap');
498            }else{
499                $(".megamenucss172 .jux_tabs_db").removeClass("jux_tabs_item");
500            }
501
502        });
503    });
504</script>
vendor: 2 bytes, line 504
504
505<script>
506  // jQuery(document).ready(function ($) {
507  //   // jQuery( ".jux-tabs" ).tabs();
508  // });
509  jQuery(document).ready(function ($){
510    // Hàm active tab nào đó
511        // kiểm tra content của các tab, nếu không phải content của tab đầu tiên ( có class là first)  thì ẩn hết các content đó
512        $('.jux-tabs  .childcontent-inner  > .megacol  > .megamenu.level1  > .submenu-align-auto').each(function(index, el) {
513            if( !$(this).hasClass('first') ){
514                $(this).hide();
515            }
516        });
517        // activeTab($('.childcontent-inner   .jux_tabs_db.jux_tabs_item ul  li:first-child'));
518        function activeTab(obj)
519        {
520            // Xóa class active tất cả các tab
521            $('.childcontent-inner  .jux_tabs_db.jux_tabs_item ul li').removeClass('active');
522            // Thêm class active vòa tab đang click
523            $(obj).addClass('active');
524            // Lấy href của tab để show content tương ứng
525            var id = $(obj).find('a').attr('href');
526            // Hiển thị nội dung của tab hiện tại
527            $(obj).parents('.jux_tabs_item ').next().find(' > ul > li.submenu-align-auto').hide();
528            $(id).show();
529        }
530        // Sự kiện click đổi tab
531        $('.childcontent-inner .jux_tabs_db.jux_tabs_item ul li').click(function(){
532            activeTab(this);
533            return false;
534        });
535    });
536   jQuery(document).ready(function ($) {
537      $('[data-toggle="tooltip"]').tooltip()
538    });
539</script>
539
540
541<script type="text/javascript">
542    // fix problem sub menu align bi che khuat khi man hinh nho
543    jQuery(document).ready(function ($) {
544        function subMenuPosition(){
545            
546            $("ul.megamenu.level0 li li.megacss.haschild.submenu-align-left").mouseenter(function() {   
547                if ($(this).children('div.adddropdown').length == 1) {
548                    var parent  = $(this);                                   
549                    var child_menu = $(this).children('div.adddropdown');   
550
551                    var parent_offset_left = $(parent).offset().left;
552                    var parent_width = $(parent).width();
553                    var child_menu_width = $(child_menu).width();
554                    var window_width = $(window).width();
555
556                    if ( window_width -  (parent_offset_left + parent_width) < child_menu_width) {
557                        $(child_menu).attr('style', 'left:-'+parent_width+'px!important');
558                    }else{
559                        $(child_menu).attr('style', 'right:-'+parent_width+'px!important');
560                    }
561
562                }
563            });
564            $("ul.megamenu.level0 li li.megacss.haschild.submenu-align-right").mouseenter(function() {   
565                if ($(this).children('div.adddropdown').length == 1) {
566                    var parent  = $(this);                  
567                    var child_menu = $(this).children('div.adddropdown');
568
569                    var parent_offset_left = $(parent).offset().left;
570                    var parent_width = $(parent).width();
571                    var child_menu_width = $(child_menu).width();
572                    var window_width = $(window).width(); 
573
574                    if (parent_offset_left < child_menu_width) {
575                        $(child_menu).attr('style', 'right:-'+parent_width+'px!important');
576                    }else{
577                        $(child_menu).attr('style', 'left:-'+parent_width+'px!important');
578                    }
579                   
580                }
581            });
582            $("ul.megamenu.level0 li li.megacss.haschild.submenu-align-auto").mouseenter(function() {   
583                if ($(this).children('div.adddropdown').length == 1) {
584                    var parent  = $(this);                  
585                    var child_menu = $(this).children('div.adddropdown');  
586
587                    var parent_offset_left = $(parent).offset().left;
588                    var parent_width = $(parent).width();
589                    var child_menu_width = $(child_menu).width();
590                    var window_width = $(window).width();
591
592                    if ( window_width -  (parent_offset_left + parent_width) < child_menu_width) {
593                        $(child_menu).attr('style', 'right:-'+parent_width+'px!important');
594                    }else{
595                        $(child_menu).attr('style', 'right:-'+parent_width+'px!important');
596                    }
597                   
598                }
599            });
600            $("ul.megamenu.level0  li.megacss.haschild.submenu-align-center").mouseenter(function() {   
601                if ($(this).children('div.adddropdown').length == 1) {
602                    var parent  = $(this);                  
603                    var child_menu = $(this).children('div.adddropdown');  
604
605                    var parent_offset_left = $(parent).offset().left;
606                    var parent_width = $(parent).width();
607                    var child_menu_width = $(child_menu).width();
608                    var window_width = $(window).width();
609
610
611                    if( parent_offset_left+parent_width / 2 > child_menu_width / 2  &&  window_width - (parent_offset_left+parent_width / 2) > child_menu_width / 2  ){
612
613                             $(child_menu).attr('style', 'right:-'+ ( child_menu_width / 2  - parent_width / 2 ) +'px!important');
614                    }                    
615
616                    if( parent_offset_left+parent_width / 2 > child_menu_width / 2  &&  window_width - (parent_offset_left+parent_width / 2) < child_menu_width / 2 && parent_offset_left > child_menu_width - parent_width ){
617
618                             $(child_menu).attr('style', 'left:-'+ (child_menu_width - parent_width ) +'px!important');
619                    }
620
621                    if( parent_offset_left+parent_width / 2 > child_menu_width / 2  &&  window_width - (parent_offset_left+parent_width / 2) < child_menu_width / 2  ){
622 
623                             $(child_menu).attr('style', 'left:-'+ (child_menu_width - parent_width - (window_width -  (parent_offset_left + parent_width)) ) +'px!important');
624                    }
625
626                    if( parent_offset_left+parent_width / 2 < child_menu_width / 2  &&  window_width - (parent_offset_left+parent_width / 2) > child_menu_width / 2 && parent_offset_left < child_menu_width - parent_width ){
627
628                             $(child_menu).attr('style', 'right:-'+ (child_menu_width - parent_width ) +'px!important');
629                    }
630
631                    if( parent_offset_left+parent_width / 2 < child_menu_width / 2  &&  window_width - (parent_offset_left+parent_width / 2) > child_menu_width / 2  ){
632
633                             $(child_menu).attr('style', 'left:-'+ (child_menu_width - parent_width - parent_offset_left ) +'px!important');
634                            
635                    }
636                   
637                   
638                }
639            });
640        }
641        subMenuPosition();  
642         // check window resize 
643        $(window).resize(function(){
644            subMenuPosition();
645        });
646      
647            
648
649    });
650</script>
650
651
652    
653		</div>
654		<div class="clr"></div>
655    </nav>
656	<section class="warning">
657				
658<div id="mod-custom180" class="mod-custom custom">
659    <div id="home_weather_warning"></div></div>
660
661	</section>
662	    <section class="banner">
663					
663<script id="mb-adsense-script" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-0401245638566630" crossorigin="anonymous"></script>
663
664
665	
665<script>
666		window.mbAdStatus = { fuse: null, adsense: null };
667
668		document.getElementById('mb-fuse-script').addEventListener('error', function () {
669			window.mbAdStatus.fuse = 'blocked';
670		});
671		document.getElementById('mb-fuse-script').addEventListener('load', function () {
672			window.mbAdStatus.fuse = 'loaded';
673		});
674
675		document.getElementById('mb-adsense-script').addEventListener('error', function () {
676			window.mbAdStatus.adsense = 'blocked';
677		});
678		document.getElementById('mb-adsense-script').addEventListener('load', function () {
679			window.mbAdStatus.adsense = 'loaded';
680		});
681	</script>
681	
682		
683	
684		<style>
685		.leaderboard_responsive { width: 340px; height: 100px; align-items: center; }
686		@media(min-width: 500px) { .leaderboard_responsive { width: 468px; height: 60px; } }
687		@media(min-width: 800px) { .leaderboard_responsive { width: 728px; height: 90px; } }
688		@media(min-width: 1000px) { .leaderboard_responsive { width: 970px; height: 90px; } }
689		</style>
690			
691		<div id="banner_leaderboard" style="width:100%">
692		<center>
693			<div class="leaderboard_responsive" data-fuse="header"></div>
694		</center>
695		</div>
696		<style>
697	#bZrhpmUyqCJz {
698	display: none;
699	max-width : 727px;
700	margin-left: auto;
701	margin-right: auto;
702	height: 89px;
703	}
704	</style>
705
706	<div id="bZrhpmUyqCJz"><a href="/premium/info"><img src="/staticfiles/images/mb_top_fr_gray.gif" width="727" height="89"></a></div>
707	
708	
708<script defer type="text/javascript">
709		function mbSendStat(isBlocked) {
710			if (document.cookie.indexOf('mbx=1') !== -1) return;
711
712			var status = window.mbAdStatus || {};
713			var lang = "fr";
714			var fs = status.fuse === 'blocked' ? 'b' : (status.fuse === 'loaded' ? 'l' : '');
715			var as = status.adsense === 'blocked' ? 'b' : (status.adsense === 'loaded' ? 'l' : '');
716
717			var url = 'https://www.meteobelgium.be//sync.php?l=' + lang + '&s=' + (isBlocked ? 'b' : 'a') + '&fs=' + fs + '&as=' + as;
718
719			if (navigator.sendBeacon) {
720				navigator.sendBeacon(url);
721			} else {
722				new Image().src = url;
723			}
724
725			var expires = new Date(Date.now() + 24 * 3600 * 1000).toUTCString();
726			document.cookie = 'mbx=1; expires=' + expires + '; path=/';
727		}
728	
729		jQuery(function ($) {
730			var maxWait = 5000;
731			var checkInterval = 200;
732			var elapsed = 0;
733			var usedNetwork = "fuse";
734
735			var checker = setInterval(function () {
736				elapsed += checkInterval;
737				var status = window.mbAdStatus || {};
738				var networkKnown = status[usedNetwork] === 'blocked' || status[usedNetwork] === 'loaded';
739
740				if (networkKnown || elapsed >= maxWait) {
741					clearInterval(checker);
742					var isBlocked = (status[usedNetwork] === 'blocked');
743					if (isBlocked) {
744						$('#banner_leaderboard').hide();
745						$('#bZrhpmUyqCJz').show();
746					}
747					mbSendStat(isBlocked);
748				}
749			}, checkInterval);
750		});
751		</script>
751
752
753
754	</section>
755	    <main>
756    	<div class="container">
757			
758			<div class="white_content">
759				<div class="row">
760					<div class="col-xs-12 col-sm-8 ">
761																		<div id="system-message-container" aria-live="polite"></div>
762
763						<h1>Radar des précipitations pour la Belgique</h1>
764
765
766<div class="radars-container mf-first">
767
768<section id="radar_mf">
769    <center>
770        <div style="max-width:768px; position:relative;">
771			<div style="width:100%; text-align:right;">
772				<i class="fa-solid fa-circle-arrow-right mb-link-arrow-icon"></i>
773				<a href="/observations/animation/cumul">Cumul des précipitations</a>
774			</div>		
775            <div id="rdrWidget">
776                <div id="rdrMapAspect">
777                    <div id="rdrMap"></div>
778
779                    <div id="rdrHud">
780                        <label class="rdr-toggle">
781							<input type="checkbox" id="rdrToggleLightning" checked>
782							<span class="full">Foudre</span>
783							<span class="short">⚡</span>
784                        </label>
785						<div id="rdrClockWrap">
786							<div id="rdrClock">--:--</div>
787							<div id="rdrCityName"></div>
788						</div>
789                    </div>
790
791                    <div id="rdrStatus">Chargement des images…</div>
792                </div>
793
794                <div id="rdrControls" style="display:none;">
795                    <div id="rdrSliderRow">
796                        <button id="rdrPrevBtn" class="rdr-nav-btn" title="Précédent">‹</button>
797                        <button id="rdrPlayBtn" title="Lecture / Pause">▶</button>
798                        <button id="rdrNextBtn" class="rdr-nav-btn" title="Suivant">›</button>
799                        <input type="range" id="rdrSlider" min="0" max="0" step="1" value="0" disabled>
800                    </div>
801                    <div id="rdrMetaRow">
802                        <span class="rdr-frame-count" id="rdrFrameCount">0 / 0</span>
803                        <div class="rdr-speed-wrap">
804                            <button type="button" id="rdrSpeedBtn" class="rdr-speed-btn" aria-haspopup="listbox" aria-expanded="false">
805                                <span id="rdrSpeedLabel">Normal</span>
806                                <span class="rdr-speed-chevron">▾</span>
807                            </button>
808                            <ul id="rdrSpeedList" class="rdr-speed-list" role="listbox" hidden>
809                                <li role="option" data-value="900">Lent</li>
810                                <li role="option" data-value="500" aria-selected="true">Normal</li>
811                                <li role="option" data-value="250">Rapide</li>
812                            </ul>
813                        </div>
814                    </div>
815                </div>
816            </div>
817        </div>
818    </center>
819
820<center>
821	<p><img style="padding-top : 0px;" src="/staticfiles/images/legend_radarmf_mb.png" width="100%"></p>
822    <p style="padding-top : 10px;">Source : <a href="https://www.meteofrance.com/" target="_blank">Météo France</a> - <a href="https://www.blitzortung.org/" target="_blank">Blitzortung</a>
823    </p>
824</center>
825</section>
826
827<div class="radar-separator">
828	<hr>
829	<br>
830</div>
831
832<section id="radar_vmm">
833
834
835<center><div style="max-width:500px;"><div id="mb-slide1-wrapper" style="max-width:100%; margin:auto; font-family:sans-serif;">
836
837    <style>
838        #mb-slide1-controls {
839            display:flex;
840            align-items:center;
841            gap:4px;
842            background:#bfbfbf;
843            padding:4px;
844            justify-content:space-between;
845        }
846        #mb-slide1-controls-right {
847            display:flex;
848            gap:4px;
849            flex:1;
850            justify-content:center;
851        }
852        #mb-slide1-dropdown {
853            flex:0 0 auto;
854            width:33%;
855        }
856        #mb-slide1-controls button {
857            padding:2px 8px;
858            cursor:pointer;
859        }
860        #mb-slide1-viewport {
861            position:relative;
862            width:100%;
863            overflow:hidden;
864            cursor:zoom-in;
865        }
866        #mb-slide1-viewport img {
867            display:none;
868            width:100%;
869            height:auto;
870        }
871        #mb-slide1-viewport img.active {
872            display:block;
873        }
874
875        /* Lightbox */
876        #mb-slide1-lightbox {
877            display:none;
878            position:fixed;
879            top:0; right:0; bottom:0; left:0;
880            background:rgba(0,0,0,0.33);
881            z-index:9999;
882            align-items:center;
883            justify-content:center;
884        }
885        #mb-slide1-lightbox.open {
886            display:flex;
887        }
888        #mb-slide1-lightbox img {
889            max-width:95vw;
890            max-height:95vh;
891            object-fit:contain;
892        }
893        #mb-slide1-lightbox-close {
894            position:absolute;
895            top:16px;
896            right:24px;
897            color:#fff;
898            font-size:2em;
899            cursor:pointer;
900            line-height:1;
901        }
902        
903        #mb-slide1-progress {
904            display:none;
905            height:3px;
906            background:#ddd;
907            overflow:hidden;
908        }
909		
910		#mb-slide1-progress-bar {
911            height:100%;
912            width:100%;
913            background:#555;
914            transform:scaleX(0);
915            transform-origin:left;
916            transition:transform 0.15s ease;
917        }
918        
919        #mb-slide1-counter {
920            display:none;
921            text-align:center;
922            font-size:0.85em;
923            color:#666;
924            padding-top:2px;
925			padding-bottom:0px;
926        }
927        
928		@keyframes mb-slide1-hint {
929            0%, 100% { transform: translateX(0); }
930            30%      { transform: translateX(-12px); }
931            55%      { transform: translateX(4px); }
932            75%      { transform: translateX(0); }
933        }
934        #mb-slide1-viewport img.mb-slide1-swipe-hint {
935            animation: mb-slide1-hint 1s ease-in-out;
936        }
937
938        @media (max-width: 768px) {
939            #mb-slide1-viewport {
940                cursor:default;
941            }
942            
943            .mb-slide1-hidden-phone {
944                display:none !important;
945            }
946            
947            #mb-slide1-dropdown {
948                width:45%;
949            }
950            
951            #mb-slide1-progress,
952            #mb-slide1-counter {
953                display:block;
954            }
955        }
956        
957
958    </style>
959
960    <div id="mb-slide1-controls">
961        <select id="mb-slide1-dropdown"></select>
962        <div id="mb-slide1-controls-right">
963            <button id="mb-slide1-first" class="mb-slide1-hidden-phone">&lt;&lt;</button>
964            <button id="mb-slide1-prev">&lt;</button>
965            <button id="mb-slide1-toggle">Play</button>
966            <button id="mb-slide1-next">&gt;</button>
967            <button id="mb-slide1-last" class="mb-slide1-hidden-phone">&gt;&gt;</button>
968        </div>
969    </div>
970
971    <div id="mb-slide1-viewport">
972    
973        <img src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011025_4a2e860b06d9f57f6e18413a2ae8e37c.jpg" alt="01/10/2026 12:25" class=" active"><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011030_e585c8278f09fa7c0e5f6cf663f13418.jpg" alt="01/10/2026 12:30" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011035_7ad9b3197d9c0388dcc33ae8189a2f3c.jpg" alt="01/10/2026 12:35" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011040_f6e05b9dbd8ab6bef9a7032fffcf13ea.jpg" alt="01/10/2026 12:40" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011045_8c0a17fe0237d5e4a6b4d300a61159e9.jpg" alt="01/10/2026 12:45" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011050_da58dbca7d8fe5b656a7f292afbf6ea1.jpg" alt="01/10/2026 12:50" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011055_1ca05d12a0a9c607b967c97a0cc8d8fa.jpg" alt="01/10/2026 12:55" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011100_19197aba51afd8ed716cd1488170eeeb.jpg" alt="01/10/2026 13:00" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011105_5fa62c8f1196ca10a125e7cec4e6f26f.jpg" alt="01/10/2026 13:05" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011110_5392ede232b305506541c7e80083b9e6.jpg" alt="01/10/2026 13:10" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011115_81ffaa654fed250cbc964e93fa3fca39.jpg" alt="01/10/2026 13:15" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011120_065c8496576754dab83b052b09ceb9f0.jpg" alt="01/10/2026 13:20" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011125_fb63ab632a759a4585b3366853d88a12.jpg" alt="01/10/2026 13:25" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011130_916de27de093da5a540e24ce51c311a1.jpg" alt="01/10/2026 13:30" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011135_6f900beecfcb37a6a33c8a6a7a36716f.jpg" alt="01/10/2026 13:35" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011140_496a7fc02ed3d78d478434fcb6e1381a.jpg" alt="01/10/2026 13:40" class=""><img data-src="https://www.meteobelgium.be/belgium/radar/radar_be_202610011145_be36940656ae7c0c1b81ec07c4a7dbcc.jpg" alt="01/10/2026 13:45" class="">    </div>
974
975	<div id="mb-slide1-progress" style="display:none;">
976		<div id="mb-slide1-progress-bar"></div>
977	</div>
978	<div id="mb-slide1-counter" style="display:none;"></div>
979
980    <!-- Lightbox -->
981    <div id="mb-slide1-lightbox">
982        <span id="mb-slide1-lightbox-close">&times;</span>
983        <img id="mb-slide1-lightbox-img" src="/" alt="">
984    </div>
985
986</div>
987
988<script>
989(function() {
990    var id       = "slide1";
991    var images   = ["https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011025_4a2e860b06d9f57f6e18413a2ae8e37c.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011030_e585c8278f09fa7c0e5f6cf663f13418.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011035_7ad9b3197d9c0388dcc33ae8189a2f3c.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011040_f6e05b9dbd8ab6bef9a7032fffcf13ea.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011045_8c0a17fe0237d5e4a6b4d300a61159e9.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011050_da58dbca7d8fe5b656a7f292afbf6ea1.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011055_1ca05d12a0a9c607b967c97a0cc8d8fa.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011100_19197aba51afd8ed716cd1488170eeeb.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011105_5fa62c8f1196ca10a125e7cec4e6f26f.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011110_5392ede232b305506541c7e80083b9e6.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011115_81ffaa654fed250cbc964e93fa3fca39.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011120_065c8496576754dab83b052b09ceb9f0.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011125_fb63ab632a759a4585b3366853d88a12.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011130_916de27de093da5a540e24ce51c311a1.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011135_6f900beecfcb37a6a33c8a6a7a36716f.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011140_496a7fc02ed3d78d478434fcb6e1381a.jpg","https:\/\/www.meteobelgium.be\/belgium\/radar\/radar_be_202610011145_be36940656ae7c0c1b81ec07c4a7dbcc.jpg"];
992    var titles   = ["01\/10\/2026 12:25","01\/10\/2026 12:30","01\/10\/2026 12:35","01\/10\/2026 12:40","01\/10\/2026 12:45","01\/10\/2026 12:50","01\/10\/2026 12:55","01\/10\/2026 13:00","01\/10\/2026 13:05","01\/10\/2026 13:10","01\/10\/2026 13:15","01\/10\/2026 13:20","01\/10\/2026 13:25","01\/10\/2026 13:30","01\/10\/2026 13:35","01\/10\/2026 13:40","01\/10\/2026 13:45"];
993    var speed    = 500;
994    var delayEnd = 4000;
995    var autoplay = true;
996
997    var current  = 0;
998    var timer    = null;
999    var running  = false;
1000	var firstLoop = (0 === images.length - 1); 
1001
1002    var prefix    = '#mb-' + id + '-';
1003    var imgs      = document.querySelectorAll(prefix + 'viewport img');
1004    var dropdown  = document.querySelector(prefix + 'dropdown');
1005    var btnToggle = document.querySelector(prefix + 'toggle');
1006    var btnFirst  = document.querySelector(prefix + 'first');
1007    var btnPrev   = document.querySelector(prefix + 'prev');
1008    var btnNext   = document.querySelector(prefix + 'next');
1009    var btnLast   = document.querySelector(prefix + 'last');
1010    var viewport  = document.querySelector(prefix + 'viewport');
1011    var lightbox  = document.querySelector(prefix + 'lightbox');
1012    var lbImg     = document.querySelector(prefix + 'lightbox-img');
1013    var lbClose   = document.querySelector(prefix + 'lightbox-close');
1014    
1015    var progressBar = document.querySelector(prefix + 'progress-bar');
1016    var counter     = document.querySelector(prefix + 'counter');
1017    
1018    // API publique
1019	var api = window['mbSlideshow_' + id] = {
1020        getCurrentUrl: function() { return images[current]; },
1021        show: function(index) { pause(); goTo(index); },
1022        onChange: null
1023    };
1024
1025    // Populate dropdown
1026    titles.forEach(function(t, i) {
1027        var opt = document.createElement('option');
1028        opt.value = i;
1029        opt.textContent = t;
1030        dropdown.appendChild(opt);
1031    });
1032	
1033	function preloadAdjacent(index) {
1034		[-2,-1,1,2,3,4,5,6].forEach(function(offset) {
1035			var i = (index + offset + imgs.length) % imgs.length;  // modulo circulaire
1036			if (!imgs[i].src && imgs[i].dataset.src) {
1037				imgs[i].src = imgs[i].dataset.src;
1038			}
1039		});
1040	}
1041	
1042	function updateIndicators() {
1043        var ratio = (current + 1) / imgs.length;
1044        progressBar.style.transform = 'scaleX(' + ratio + ')';
1045        counter.textContent = (current + 1) + ' / ' + imgs.length;
1046    }
1047    
1048	var displayedIndex = current;
1049	var navigationToken = 0;
1050
1051	function loadImage(img) {
1052		if (!img.src && img.dataset.src) img.src = img.dataset.src;
1053		if (img.complete && img.naturalWidth > 0) {
1054			return img.decode ? img.decode().catch(function() {}) : Promise.resolve();
1055		}
1056		return new Promise(function(resolve) {
1057			img.addEventListener('load', resolve, { once: true });
1058			img.addEventListener('error', resolve, { once: true }); // resolve même en erreur, évite un blocage
1059		}).then(function() {
1060			return img.decode ? img.decode().catch(function() {}) : undefined;
1061		});
1062	}
1063
1064    // Fonction interne renommée goTo pour éviter conflit avec l'API publique
1065	/*function goTo(index) {
1066		if (index < 0) index = imgs.length - 1;
1067		if (index >= imgs.length) index = 0;
1068		imgs[current].classList.remove('active');
1069		current = index;
1070		if (!imgs[current].src && imgs[current].dataset.src) {
1071			imgs[current].src = imgs[current].dataset.src;
1072		}
1073		imgs[current].classList.add('active');
1074		dropdown.value = current;
1075		preloadAdjacent(current);
1076		updateIndicators();
1077		if (typeof api.onChange === 'function') api.onChange(current);
1078	}*/
1079	
1080	function goTo(index) {
1081		if (!imgs.length) return Promise.resolve();
1082		if (index < 0) index = imgs.length - 1;
1083		if (index >= imgs.length) index = 0;
1084
1085		current = index; // synchrone : API publique et indicateurs toujours à jour
1086		dropdown.value = current;
1087		updateIndicators();
1088		preloadAdjacent(current);
1089		if (typeof api.onChange === 'function') api.onChange(current);
1090
1091		var img = imgs[index];
1092		var token = ++navigationToken;
1093
1094		return loadImage(img).then(function() {
1095			if (token !== navigationToken) return; // une navigation plus récente a pris le dessus
1096			imgs[displayedIndex].classList.remove('active');
1097			img.classList.add('active');
1098			displayedIndex = index;
1099		});
1100	}
1101
1102	function tick() {
1103		if (current === imgs.length - 1) {
1104			var delay = (delayEnd !== null && !firstLoop) ? delayEnd : speed;
1105			firstLoop = false;  // désactive le flag après la première boucle
1106			timer = setTimeout(function() {
1107				if (!running) return;
1108				goTo(0);
1109				timer = setTimeout(tick, speed);
1110			}, delay);
1111		} else {
1112			goTo(current + 1);
1113			timer = setTimeout(tick, speed);
1114		}
1115	}
1116
1117    function play() {
1118        running = true;
1119        btnToggle.textContent = 'Pause';
1120        timer = setTimeout(tick, speed);
1121    }
1122
1123    function pause() {
1124        running = false;
1125        btnToggle.textContent = 'Play';
1126        clearTimeout(timer);
1127    }
1128	
1129    btnToggle.addEventListener('click', function() { running ? pause() : play(); });
1130    btnFirst.addEventListener('click',  function() { pause(); goTo(0); });
1131    btnLast.addEventListener('click',   function() { pause(); goTo(imgs.length - 1); });
1132    btnPrev.addEventListener('click',   function() { pause(); goTo(current - 1); });
1133    btnNext.addEventListener('click',   function() { pause(); goTo(current + 1); });
1134
1135    dropdown.addEventListener('change', function() { pause(); goTo(parseInt(this.value)); });
1136
1137    // Lightbox
1138    viewport.addEventListener('click', function() {
1139		if (touchMoved) { touchMoved = false; return; }
1140		if (window.matchMedia('(max-width: 768px)').matches) return; // pas de lightbox mobile
1141        lbImg.src = images[current];
1142        lbImg.alt = titles[current];
1143        lightbox.classList.add('open');
1144    });
1145    lbClose.addEventListener('click',  function() { lightbox.classList.remove('open'); });
1146    lightbox.addEventListener('click', function(e) {
1147        if (e.target === lightbox) lightbox.classList.remove('open');
1148    });
1149    document.addEventListener('keydown', function(e) {
1150        if (e.key === 'Escape') lightbox.classList.remove('open');
1151    });
1152    
1153	// Swipe mobile
1154    var touchStartX = 0;
1155    var touchStartY = 0;
1156    var touchMoved  = false;
1157    var SWIPE_THRESHOLD = 40; // px minimum pour considérer un swipe
1158
1159    viewport.addEventListener('touchstart', function(e) {
1160        touchStartX = e.changedTouches[0].screenX;
1161        touchStartY = e.changedTouches[0].screenY;
1162        touchMoved  = false;
1163    }, { passive: true });
1164
1165    viewport.addEventListener('touchmove', function() {
1166        touchMoved = true;
1167    }, { passive: true });
1168
1169    viewport.addEventListener('touchend', function(e) {
1170        var dx = e.changedTouches[0].screenX - touchStartX;
1171        var dy = e.changedTouches[0].screenY - touchStartY;
1172
1173        if (Math.abs(dx) > SWIPE_THRESHOLD && Math.abs(dx) > Math.abs(dy)) {
1174            pause();
1175            if (dx < 0) {
1176                goTo(current + 1); // swipe gauche -> image suivante
1177            } else {
1178                goTo(current - 1); // swipe droite -> image précédente
1179            }
1180            touchMoved = true; // empêche le lightbox de s'ouvrir après un swipe
1181        }
1182    });
1183
1184    // Init
1185    progressBar.style.transition = 'none';
1186    goTo(0);
1187    
1188    requestAnimationFrame(function() {
1189        progressBar.style.transition = 'transform 0.15s ease';
1190    });    
1191
1192	// Hint de swipe au premier chargement (mobile uniquement, une seule fois, jamais si autoplay)
1193    if (!autoplay && window.matchMedia('(max-width: 768px)').matches) {
1194        setTimeout(function() {
1195            var hintTarget = imgs[current]; // capture la référence exacte, pas l'index live
1196            hintTarget.classList.add('mb-' + id + '-swipe-hint');
1197            setTimeout(function() {
1198                hintTarget.classList.remove('mb-' + id + '-swipe-hint');
1199            }, 1000);
1200        }, 600);
1201    }
1202	
1203	if (autoplay) {
1204		play();
1205	}
1206
1207
1208
1209})();
1210</script>
1210
1211</div></center>
1212<center><p><img style="padding-top : 15px;" src="/staticfiles/images/legend_radar_mb.png"></p></center>
1213<center><p style="padding-top:5px;">Source : <a href="https://www.vmm.be/" target="_blank">https://www.vmm.be/</a></p></center>
1214</section>
1215</div>
1216
1217
1218<script>
1219(function(){
1220// ============================================================
1221// DONNÉES INJECTÉES DEPUIS PHP (DB generated_map) — la page se
1222// recharge entièrement pour voir de nouvelles images, pas de fetch().
1223// ============================================================
1224const RADAR_FRAMES    = [{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_381a9b8325366061a7cbf81687c81546_20261001103500.png","timestamp":"2026-10-01T10:35:00+00:00","date":"2026-10-01 12:35:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_aebedd8a2546396023b057216d823fb7_20261001104000.png","timestamp":"2026-10-01T10:40:00+00:00","date":"2026-10-01 12:40:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_4a2e869390f6f8d28c95ed711d0660ea_20261001104500.png","timestamp":"2026-10-01T10:45:00+00:00","date":"2026-10-01 12:45:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_20cee3ead000ccf5bad5d426abec3a55_20261001105000.png","timestamp":"2026-10-01T10:50:00+00:00","date":"2026-10-01 12:50:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_77171c654cd9854705c18c5df43a5afb_20261001105500.png","timestamp":"2026-10-01T10:55:00+00:00","date":"2026-10-01 12:55:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_c514a406b9e12af8b362ff929786d433_20261001110000.png","timestamp":"2026-10-01T11:00:00+00:00","date":"2026-10-01 13:00:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_71f63de6f71c986aa430ace3dd72ec1f_20261001110500.png","timestamp":"2026-10-01T11:05:00+00:00","date":"2026-10-01 13:05:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_b78724bc212090b0232e2b322a699a55_20261001111000.png","timestamp":"2026-10-01T11:10:00+00:00","date":"2026-10-01 13:10:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_9c8dd29f71bb5f04df1c0187b09b1bca_20261001111500.png","timestamp":"2026-10-01T11:15:00+00:00","date":"2026-10-01 13:15:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_e15eac5b4cabc99f059593f215e6cc2e_20261001112000.png","timestamp":"2026-10-01T11:20:00+00:00","date":"2026-10-01 13:20:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_cccf1472b3db473d46561cc0239b1222_20261001112500.png","timestamp":"2026-10-01T11:25:00+00:00","date":"2026-10-01 13:25:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_f10612c798eff8a7b7200e5be8333ba8_20261001113000.png","timestamp":"2026-10-01T11:30:00+00:00","date":"2026-10-01 13:30:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_f45f893cfa3c12dacfefd285ed66937c_20261001113500.png","timestamp":"2026-10-01T11:35:00+00:00","date":"2026-10-01 13:35:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_bb3e7f1b14434966afa94590a15fc019_20261001114000.png","timestamp":"2026-10-01T11:40:00+00:00","date":"2026-10-01 13:40:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_980539dadd7ddfdd307eaa207d1575fc_20261001114500.png","timestamp":"2026-10-01T11:45:00+00:00","date":"2026-10-01 13:45:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_53c408085736ef610bdf56437682d76d_20261001115000.png","timestamp":"2026-10-01T11:50:00+00:00","date":"2026-10-01 13:50:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_b31704482a421bb862adc8b5d232be0f_20261001115500.png","timestamp":"2026-10-01T11:55:00+00:00","date":"2026-10-01 13:55:00"},{"file":"https://www.meteobelgium.net/belgium/radar_mf/transparent/radar_be_mf_tr_bf3513ae553ff59a3fcfb0233a805298_20261001120000.png","timestamp":"2026-10-01T12:00:00+00:00","date":"2026-10-01 14:00:00"}];
1225const STRIKES_FRAMES  = [{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_04f6cc1dde1500eab8ddd191d60d628d_20261001103556.png","t
1225imestamp":"2026-10-01T10:35:56+00:00","date":"2026-10-01 12:35:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_3db50a4718a023a8432625f977c9e065_20261001104056.png","timestamp":"2026-10-01T10:40:56+00:00","date":"2026-10-01 12:40:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_e4036b2ab75056d0f828b57e43c63adb_20261001104556.png","timestamp":"2026-10-01T10:45:56+00:00","date":"2026-10-01 12:45:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_3f07600d780e12170acb94444cf8497d_20261001105057.png","timestamp":"2026-10-01T10:50:57+00:00","date":"2026-10-01 12:50:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_3186c0d74db12685b9a41cbece4cb926_20261001105557.png","timestamp":"2026-10-01T10:55:57+00:00","date":"2026-10-01 12:55:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_65739eac9bc9267aec30cc6fc71b9a92_20261001110057.png","timestamp":"2026-10-01T11:00:57+00:00","date":"2026-10-01 13:00:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_f2b7054d32ac3a4520a092ec9a30c8ab_20261001110556.png","timestamp":"2026-10-01T11:05:56+00:00","date":"2026-10-01 13:05:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_1bb9c41b509f6bb262bf94925dc8f427_20261001111056.png","timestamp":"2026-10-01T11:10:56+00:00","date":"2026-10-01 13:10:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_8da9ce8d05db451a1e4e89514fe50345_20261001111557.png","t
1225imestamp":"2026-10-01T11:15:57+00:00","date":"2026-10-01 13:15:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_060df2301a606aed23fceaffd698705c_20261001112056.png","timestamp":"2026-10-01T11:20:56+00:00","date":"2026-10-01 13:20:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_9856d7da08cb6930eeda2ac8cef4414a_20261001112556.png","timestamp":"2026-10-01T11:25:56+00:00","date":"2026-10-01 13:25:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_d0629f869344422818080728c68714ad_20261001113056.png","timestamp":"2026-10-01T11:30:56+00:00","date":"2026-10-01 13:30:56"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_aa42b165eac4322eaf8de179a3d7be4a_20261001113557.png","timestamp":"2026-10-01T11:35:57+00:00","date":"2026-10-01 13:35:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_045a8d75b6520bc01d650fe5a1b85389_20261001114056.png","timestamp":"2026-10-01T11:40:56+00:00","date":"2026-10-01 13:40:56"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_351f3e0e2face4530936f001ef628750_20261001114556.png","timestamp":"2026-10-01T11:45:56+00:00","date":"2026-10-01 13:45:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_a6cfadff33fea38a8393d877935afa28_20261001115057.png","timestamp":"2026-10-01T11:50:57+00:00","date":"2026-10-01 13:50:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_663a81acb8fdb7e0ec02d00ee3a8291a_20261001115556.png","timestamp":"2026-10-01T11:55:56+00:00","date":"2026-10-01 13:55:57"},{"file":"https://www.meteobelgium.net/belgium/blitzortung/dyn_map/blitzbe_dyn_17c4469da38abd8c440833ee1b3517d7_20261001120056.png","timestamp":"2026-10-01T12:00:56+00:00","date":"2026-10-01 14:00:56"}];
1226const FORECAST_FRAMES = [{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_9ab3558b344beb81deea6bf3a2e0c3e0_20261001120500.png","timestamp":"2026-10-01T12:05:00+00:00","horizon_min":5},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_7c0d8a508da8cc0fa4fe175bed199e8f_20261001121000.png","timestamp":"2026-10-01T12:10:00+00:00","horizon_min":10},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_50ab83b934f36d534c4645065a145cc4_20261001121500.png","timestamp":"2026-10-01T12:15:00+00:00","horizon_min":15},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_cd8258f654cad51d2e465cb8aeaeb95e_20261001122000.png","timestamp":"2026-10-01T12:20:00+00:00","horizon_min":20},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_29cd0e28e3e0d83faf3fcddda7551000_20261001122500.png","timestamp":"2026-10-01T12:25:00+00:00","horizon_min":25},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_ab0c99fcc65d12839a57f07677058d0b_20261001123000.png","timestamp":"2026-10-01T12:30:00+00:00","horizon_min":30},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_18a65ad218b5f3bacc9bc51408a9d42a_20261001123500.png","timestamp":"2026-10-01T12:35:00+00:00","horizon_min":35},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_12947b68f2a9e1d5349885760c1223ac_20261001124000.png","timestamp":"2026-10-01T12:40:00+00:00","horizon_min":40},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_7bfa0c80b468371536c2a61f61f62369_20261001124500.png","timestamp":"2026-10-01T12:45:00+00:00","horizon_min":45},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_27be13fbecbb656b51e37e446396c44c_20261001125000.png","timestamp":"2026-10-01T12:50:00+00:00","horizon_min":50},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_9e6b94b9d29aabbdbda401e9ba10d828_20261001125500.png","timestamp":"2026-10-01T12:55:00+00:00","horizon_min":55},{"file":"https://www.meteobelgium.net/belgium/radar_mf/forecasts_tr/radar_be_mf_tr_fc_62c7c726d66b2b77feed47be92acada1_20261001130000.png","t
1226imestamp":"2026-10-01T13:00:00+00:00","horizon_min":60}];
1227const TILE_HASH        = "d1dd77179469ca17b0e045be5ed357f8";
1228const I18N              = {"lightning":"Foudre","statusLoadingImages":"Chargement des images…","statusLoadingFirst":"Chargement de la première échéance…","errNoData":"Radar ou foudre indisponible — aucune image à afficher.","errNoSync":"Aucune échéance synchronisée entre radar et foudre (tolérance {s}s). Vérifiez les deux pipelines.","gestureTouch":"Utilisez deux doigts pour déplacer la carte","gestureScroll":"Utilisez Ctrl + molette pour zoomer","gestureScrollMac":"Utilisez ⌘ + molette pour zoomer","forecastPrefix":"Prévision ","forecastPrefixPlus":"+","forecastSuffix":"min","speedSlow":"Lent","speedNormal":"Normal","speedFast":"Rapide","centerPosition":"Centrer sur ma position"};
1229
1230// Position "ville" choisie explicitement, si disponible côté session PHP
1231// (page == "city"). Sinon null -> on retombe sur sessionStorage côté JS.
1232const SERVER_USER_LNG = null;
1233const SERVER_USER_LAT = null;
1234const CITY_NAME = null;
1235
1236// Les URLs venant de la DB sont déjà absolues -> pas de préfixe à ajouter.
1237const RADAR_BASE_URL    = "";
1238const STRIKES_BASE_URL  = "";
1239const FORECAST_BASE_URL = "";
1240
1241// Tolérance de synchronisation entre les deux séries (secondes).
1242const SYNC_TOLERANCE_SECONDS = 150;
1243
1244// Horizon minimum affiché pour une prévision (garde-fou : la première
1245// échéance doit être +5min, jamais +0min ni une valeur négative/aberrante
1246// issue d'un chevauchement live/prévision).
1247const MIN_FORECAST_HORIZON_MIN = 5;
1248const MAX_FORECAST_HORIZON_MIN = 60;
1249
1250// Bounds exacts de la zone Belgique + marge ~250km, EPSG:3857.
1251const IMAGE_BOUNDS = [
1252	[47.500693, -1.000817],
1253	[53.500587, 8.498009]
1254];
1255
1256const LOOP_PAUSE_MS = 1200;
1257
1258const USER_RADIUS_RINGS = [
1259	{ radius: 5000,  weight: 2, opacity: 0.8,  fillOpacity: 0.06, dashArray: '6,6' },
1260	{ radius: 15000, weight: 2, opacity: 0.8, fillOpacity: 0.06, dashArray: '8,6' }
1261];
1262
1263// Emprise Belgique (légèrement élargie pour ne pas coller aux bords) —
1264// fitBounds() calcule automatiquement le zoom adapté à la taille réelle
1265// du conteneur au moment de l'appel, donc s'adapte de lui-même à un
1266// conteneur plus étroit sur mobile sans qu'il faille deviner un niveau
1267// de zoom fixe par point de rupture.
1268const BELGIUM_BOUNDS_SW = [49.45, 2.40];
1269const BELGIUM_BOUNDS_NE = [51.55, 6.55];
1270
1271// ============================================================
1272// CHARGEMENT DIFFÉRÉ (lazy) — Leaflet + le plugin gesture-handling ne
1273// sont chargés, et la carte n'est initialisée, que lorsque le widget
1274// entre réellement dans le viewport. Sur une page où le widget n'est
1275// pas immédiatement visible (plus bas dans un article), ça évite de
1276// télécharger ~150-200 Ko de JS/CSS et de démarrer les requêtes de
1277// tuiles pour rien si l'utilisateur ne fait jamais défiler jusque-là.
1278// ============================================================
1279function loadScript(src){
1280	return new Promise((resolve, reject) => {
1281		const s = document.createElement('script');
1282		s.src = src;
1283		s.onload = resolve;
1284		s.onerror = reject;
1285		document.head.appendChild(s);
1286	});
1287}
1288
1289function loadStyle(href){
1290	return new Promise((resolve) => {
1291		const l = document.createElement('link');
1292		l.rel = 'stylesheet';
1293		l.href = href;
1294		// Une feuille de style qui échoue ne doit pas bloquer tout le widget.
1295		l.onload = resolve;
1296		l.onerror = resolve;
1297		document.head.appendChild(l);
1298	});
1299}
1300
1301let widgetStarted = false;
1302let pendingGeoPosition = null;
1303let geoReadyHandler = null;
1304
1305window.addEventListener('geolocation_ready', (e) => {
1306	if (e.detail.lat > 49 && e.detail.lat < 52 && e.detail.lng > 2 && e.detail.lng < 7) {
1307		if (geoReadyHandler) {
1308			geoReadyHandler(e.detail.lat, e.detail.lng);
1309		} else {
1310			pendingGeoPosition = { lat: e.detail.lat, lng: e.detail.lng };
1311		}
1312	}
1313});
1314
1315const cityNameEl = document.getElementById('rdrCityName');
1316if (CITY_NAME){
1317  cityNameEl.textContent = '🎯 ' + CITY_NAME;
1318  cityNameEl.style.display = 'block';
1319}
1320
1321async function startWidget(){
1322	if (widgetStarted) return;
1323	widgetStarted = true;
1324
1325	loadStyle('https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css');
1326	loadStyle('https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet-gesture-handling.min.css');
1327	await loadScript('https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.js');
1328	await loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/leaflet-gesture-handling.min.js');
1329
1330	// ============================================================
1331	// CARTE
1332	// ============================================================
1333	const map = L.map('rdrMap', {
1334		zoomControl: false,
1335		attributionControl: true,
1336		gestureHandling: true,
1337		minZoom: 6.5,
1338		zoomSnap: 0.5,
1339		zoomDelta: 0.5,
1340		maxBounds: [BELGIUM_BOUNDS_SW, BELGIUM_BOUNDS_NE],
1341		maxBoundsViscosity: 1.0,
1342		gestureHandlingOptions: {
1343			text: {
1344				touch: I18N.gestureTouch,
1345				scroll: I18N.gestureScroll,
1346				scrollMac: I18N.gestureScrollMac
1347			}
1348		}
1349	});
1350
1351	// Toute la Belgique visible dès l'ouverture — le zoom est recalculé
1352	// automatiquement selon la taille réelle du conteneur (mobile inclus).
1353	map.fitBounds([BELGIUM_BOUNDS_SW, BELGIUM_BOUNDS_NE], { padding: [8, 8], maxZoom: 9.5 });
1354	
1355	const INITIAL_MIN_ZOOM = 7;
1356	if (map.getZoom() < INITIAL_MIN_ZOOM) {
1357	  map.setZoom(INITIAL_MIN_ZOOM);
1358	}
1359
1360	// Boutons de zoom en bas à gauche de la carte (plus de barre de
1361	// contrôles flottante au-dessus qui les rendait redondants en haut).
1362	L.control.zoom({ position: 'bottomleft' }).addTo(map);
1363
1364//https://tiles.meteobelgium.be/cartolight/{z}/{x}/{y}{r}//${TILE_HASH}.png
1365//https://tiles.meteobelgium.be/mblight/{z}/{x}/{y}{r}//${TILE_HASH}.png
1366	L.tileLayer(`https://tiles.meteobelgium.be/mblightv2/{z}/{x}/{y}{r}//${TILE_HASH}.png`, {
1367		maxZoom: 10,
1368		minZoom: 6.5,
1369		attribution: '&copy; OpenStreetMap &copy; CARTO',
1370		className: 'rdr-mb-tiles',
1371	}).addTo(map);
1372
1373	map.createPane('labelsPane');
1374	map.getPane('labelsPane').style.zIndex = 450;
1375	map.getPane('labelsPane').style.pointerEvents = 'none';
1376
1377	L.tileLayer(`https://tiles.meteobelgium.be/cartolabels/{z}/{x}/{y}{r}//${TILE_HASH}.png`, {
1378		attribution: '',
1379		maxZoom: 10,
1380		minZoom: 6.5,
1381		pane: 'labelsPane'
1382	}).addTo(map);
1383
1384	// ============================================================
1385	// POSITION UTILISATEUR — session PHP (ville choisie) ou sessionStorage
1386	// (géolocalisation navigateur déjà gérée ailleurs sur le site). Pas de
1387	// bouton, pas de nouvelle demande de permission ici : affichage passif
1388	// si une position est déjà connue.
1389	// ============================================================
1390	let userMarker = null;
1391	let userRadiusLayers = [];
1392
1393	function resolveUserPosition(){
1394		if (SERVER_USER_LNG !== null && SERVER_USER_LAT !== null
1395		&& !isNaN(SERVER_USER_LNG) && !isNaN(SERVER_USER_LAT)){
1396			return { lat: SERVER_USER_LAT, lng: SERVER_USER_LNG };
1397		}
1398
1399		const lngStr = sessionStorage.getItem('geo_lng');
1400		const latStr = sessionStorage.getItem('geo_lat');
1401		if (lngStr !== null && latStr !== null){
1402			const lng = parseFloat(lngStr);
1403			const lat = parseFloat(latStr);
1404			if (!isNaN(lng) && !isNaN(lat)) return { lat, lng };
1405		}
1406
1407		return null;
1408	}
1409
1410	function clearUserRadiusLayers(){
1411		userRadiusLayers.forEach(layer => map.removeLayer(layer));
1412		userRadiusLayers = [];
1413	}
1414
1415	function drawUserRadiusRings(latlng){
1416		clearUserRadiusLayers();
1417		USER_RADIUS_RINGS.forEach(ring => {
1418			const circle = L.circle(latlng, {
1419				radius: ring.radius,
1420				color: '#1a56b0',
1421				weight: ring.weight,
1422				opacity: ring.opacity,
1423				fillColor: '#1a56b0',
1424				fillOpacity: ring.fillOpacity,
1425				dashArray: ring.dashArray,
1426				interactive: false,
1427			}).addTo(map);
1428			userRadiusLayers.push(circle);
1429		});
1430	}
1431
1432	function markerScaleForZoom(zoom){
1433		const minZoom = 7, maxZoom = 10;
1434		const minScale = 0.75, maxScale = 1.4;
1435		const t = Math.max(0, Math.min(1, (zoom - minZoom) / (maxZoom - minZoom)));
1436		return minScale + t * (maxScale - minScale);
1437	}
1438
1439	function applyUserMarkerScale(){
1440		if (!userMarker) return;
1441		const el = userMarker.getElement();
1442		if (!el) return;
1443		const wrap = el.querySelector('.rdr-user-dot-wrap');
1444		if (!wrap) return;
1445		wrap.style.transform = `scale(${markerScaleForZoom(map.getZoom())})`;
1446	}
1447
1448	map.on('zoomend', applyUserMarkerScale);
1449
1450	function showUserPosition(lat, lng){
1451		const latlng = L.latLng(lat, lng);	
1452
1453		const icon = L.divIcon({
1454			className: '',
1455			html: '<div class="rdr-user-dot-wrap">'
1456			+   '<div class="rdr-user-pulse"></div>'
1457			+   '<div class="rdr-user-pulse delay"></div>'
1458			+   '<div class="rdr-user-dot"></div>'
1459			+ '</div>',
1460			iconSize: [32, 32],
1461			iconAnchor: [16, 16]
1462		});
1463
1464		userMarker = L.marker(latlng, { icon, zIndexOffset: 1000, interactive: false }).addTo(map);
1465		applyUserMarkerScale();
1466		
1467		drawUserRadiusRings(latlng);
1468	}
1469	geoReadyHandler = (lat, lng) => showUserPosition(lat, lng);
1470
1471	const userPos = resolveUserPosition();
1472	if (userPos){
1473		showUserPosition(userPos.lat, userPos.lng);
1474	} else if (SERVER_USER_LNG === null && pendingGeoPosition){
1475		// L'event geolocation_ready est arrivé avant que le widget ne démarre
1476		// (lazy load) — on applique la position mise en cache.
1477		showUserPosition(pendingGeoPosition.lat, pendingGeoPosition.lng);
1478	}
1479
1480	const locateControl = L.control({ position: 'bottomleft' });
1481	locateControl.onAdd = function(){
1482		const div = L.DomUtil.create('div', 'leaflet-bar rdr-locate-control');
1483		div.innerHTML = `<a href="#" title="${I18N.centerPosition}" role="button" aria-label="${I18N.centerPosition}">`
1484		+ `<i class="fa-solid fa-location-crosshairs"></i>`
1485		+ `</a>`;
1486		L.DomEvent.disableClickPropagation(div);
1487		L.DomEvent.on(div, 'click', (e) => {
1488			e.preventDefault();
1489			if (userMarker) {
1490				map.setView(userMarker.getLatLng(), Math.max(map.getZoom(), 10));
1491			}
1492		});
1493		return div;
1494	};
1495	locateControl.addTo(map);
1496
1497	// ============================================================
1498	// ÉTAT TIMELAPSE
1499	// ============================================================
1500	let frames = [];
1501	let overlays = [];
1502	let currentIndex = -1;
1503	let playing = false;
1504	let timer = null;
1505	let lightningEnabled = document.getElementById('rdrToggleLightning').checked;
1506	let lastLiveTimestamp = null;
1507
1508	const statusEl        = document.getElementById('rdrStatus');
1509	const controlsEl      = document.getElementById('rdrControls');
1510	const playBtn         = document.getElementById('rdrPlayBtn');
1511	const prevBtn         = document.getElementById('rdrPrevBtn');
1512	const nextBtn         = document.getElementById('rdrNextBtn');
1513	const slider          = document.getElementById('rdrSlider');
1514	const speedBtn         = document.getElementById('rdrSpeedBtn');
1515	const speedLabel       = document.getElementById('rdrSpeedLabel');
1516	const speedList        = document.getElementById('rdrSpeedList');
1517	let currentSpeedMs      = 500;
1518	const clockEl         = document.getElementById('rdrClock');
1519	const frameCountEl    = document.getElementById('rdrFrameCount');
1520	const toggleLightning = document.getElementById('rdrToggleLightning');
1521
1522	function formatTs(iso){
1523		const d = new Date(iso);
1524		const opts = window.innerWidth <= 480
1525		? { hour:'2-digit', minute:'2-digit' }
1526		: { day:'2-digit', month:'2-digit', year:'numeric', hour:'2-digit', minute:'2-digit' };
1527		return d.toLocaleString('fr-BE', opts);
1528	}
1529
1530	// ============================================================
1531	// APPARIEMENT RADAR <-> FOUDRE
1532	// ============================================================
1533	function matchFrames(radarFrames, strikesFrames, toleranceSeconds){
1534		const strikesParsed = strikesFrames
1535		.map(f => ({ ...f, t: new Date(f.timestamp).getTime() }))
1536		.filter(f => !isNaN(f.t));
1537
1538		const pairs = [];
1539		for (const rf of radarFrames){
1540			const rt = new Date(rf.timestamp).getTime();
1541			if (isNaN(rt)) continue;
1542
1543			let best = null, bestDiff = Infinity;
1544			for (const sf of strikesParsed){
1545				const diff = Math.abs(sf.t - rt);
1546				if (diff < bestDiff){ bestDiff = diff; best = sf; }
1547			}
1548
1549			if (best && bestDiff <= toleranceSeconds * 1000){
1550				pairs.push({ timestamp: rf.timestamp, radarFile: rf.file, strikesFile: best.file });
1551			}
1552		}
1553		return pairs;
1554	}
1555
1556	// ============================================================
1557	// FRAMES DE PRÉVISION
1558	// ============================================================
1559	// Garde-fou : la première échéance affichée doit être +5min (jamais
1560	// +0min ni une valeur négative), au cas où le lot de prévision contienne
1561	// une frame en chevauchement avec la dernière observation live.
1562	function buildForecastFrames(forecastManifest){
1563		return [...forecastManifest]
1564		.filter(f => (f.horizon_min ?? 0) >= MIN_FORECAST_HORIZON_MIN && (f.horizon_min ?? 0) <= MAX_FORECAST_HORIZON_MIN)
1565		.sort((a, b) => (a.horizon_min ?? 0) - (b.horizon_min ?? 0))
1566		.map(f => ({
1567			timestamp: f.timestamp,
1568			radarFile: f.file,
1569			strikesFile: null,
1570			isForecast: true,
1571			horizonMin: f.horizon_min
1572		}));
1573	}
1574
1575	// ============================================================
1576	// CHARGEMENT "LOOK-AHEAD" (anti-flash sans préchargement bloquant)
1577	// ============================================================
1578	const loadedUrls = new Set();
1579	const pendingLoads = new Map();
1580	const PREFETCH_LOOKAHEAD = 2;
1581
1582	function ensureLoaded(url){
1583		if (loadedUrls.has(url)) return Promise.resolve(true);
1584		if (pendingLoads.has(url)) return pendingLoads.get(url);
1585
1586		const img = new Image();
1587		img.src = url;
1588
1589		const p = (img.decode ? img.decode() : new Promise((resolve, reject) => {
1590			img.onload = resolve;
1591			img.onerror = reject;
1592		}))
1593		.then(() => { loadedUrls.add(url); pendingLoads.delete(url); return true; })
1594		.catch(() => { pendingLoads.delete(url); return false; });
1595
1596		pendingLoads.set(url, p);
1597		return p;
1598	}
1599
1600	function frameUrls(f){
1601		const urls = [(f.isForecast ? FORECAST_BASE_URL : RADAR_BASE_URL) + f.radarFile];
1602		if (f.strikesFile) urls.push(STRIKES_BASE_URL + f.strikesFile);
1603		return urls;
1604	}
1605
1606	function ensureFrameLoaded(idx){
1607		return Promise.all(frameUrls(frames[idx]).map(ensureLoaded));
1608	}
1609
1610	function prefetchNeighbors(idx){
1611		for (let step = 1; step <= PREFETCH_LOOKAHEAD; step++){
1612			const nextIdx = (idx + step) % overlays.length;
1613			ensureFrameLoaded(nextIdx);
1614		}
1615	}
1616
1617	// ============================================================
1618	// LECTURE / AFFICHAGE
1619	// ============================================================
1620	function showFrame(idx){
1621		if (idx < 0 || idx >= overlays.length) return;
1622
1623		const next = overlays[idx];
1624		const f = frames[idx];
1625
1626		if (!map.hasLayer(next.radar)) next.radar.addTo(map);
1627		if (next.strikes && lightningEnabled){
1628			if (!map.hasLayer(next.strikes)) next.strikes.addTo(map);
1629		} else if (next.strikes && map.hasLayer(next.strikes)){
1630			map.removeLayer(next.strikes);
1631		}
1632
1633		overlays.forEach((ov, i) => {
1634			if (i === idx) return;
1635			if (map.hasLayer(ov.radar)) map.removeLayer(ov.radar);
1636			if (ov.strikes && map.hasLayer(ov.strikes)) map.removeLayer(ov.strikes);
1637		});
1638
1639		currentIndex = idx;
1640		slider.value = idx;
1641		frameCountEl.textContent = `${idx + 1} / ${overlays.length}`;
1642
1643		if (f.isForecast){
1644			clockEl.textContent = window.innerWidth <= 480
1645			? `${formatTs(f.timestamp)} ${I18N.forecastPrefixPlus}${String(f.horizonMin).padStart(2, '0')}${I18N.forecastSuffix}`
1646			: `${formatTs(f.timestamp)} ${I18N.forecastPrefixPlus}${String(f.horizonMin).padStart(2, '0')}${I18N.forecastSuffix}`;
1647			clockEl.classList.add('forecast');
1648		} else {
1649			clockEl.textContent = formatTs(f.timestamp);
1650			clockEl.classList.remove('forecast');
1651		}  
1652	}
1653
1654	let loadToken = 0;
1655
1656	async function goToFrame(idx){
1657		const token = ++loadToken;
1658		await ensureFrameLoaded(idx);
1659		if (token !== loadToken) return;
1660		showFrame(idx);
1661		prefetchNeighbors(idx);
1662	}
1663
1664	function stepForward(){
1665		if (currentIndex >= overlays.length - 1){
1666			clearTimeout(timer);
1667			timer = setTimeout(async () => {
1668				await goToFrame(0);
1669				scheduleNext();
1670			}, LOOP_PAUSE_MS);
1671			return;
1672		}
1673		goToFrame(currentIndex + 1).then(scheduleNext);
1674	}
1675
1676	function scheduleNext(){
1677		if (!playing) return;
1678		clearTimeout(timer);
1679		timer = setTimeout(stepForward, currentSpeedMs);
1680	}
1681
1682	function play(){
1683		if (overlays.length < 2) return;
1684		playing = true;
1685		playBtn.textContent = '⏸';
1686		scheduleNext();
1687	}
1688
1689	function pause(){
1690		playing = false;
1691		playBtn.textContent = '▶';
1692		clearTimeout(timer);
1693	}
1694
1695	playBtn.addEventListener('click', () => playing ? pause() : play());
1696
1697	prevBtn.addEventListener('click', () => {
1698		pause();
1699		goToFrame(Math.max(0, currentIndex - 1));
1700	});
1701
1702	nextBtn.addEventListener('click', () => {
1703		pause();
1704		goToFrame(Math.min(overlays.length - 1, currentIndex + 1));
1705	});
1706
1707	slider.addEventListener('input', () => {
1708		pause();
1709		goToFrame(parseInt(slider.value, 10));
1710	});
1711
1712	function closeSpeedList(){
1713		speedList.hidden = true;
1714		speedBtn.setAttribute('aria-expanded', 'false');
1715	}
1716
1717	function openSpeedList(){
1718		speedList.hidden = false;
1719		speedBtn.setAttribute('aria-expanded', 'true');
1720	}
1721
1722	speedBtn.addEventListener('click', (e) => {
1723		e.stopPropagation();
1724		if (speedList.hidden) openSpeedList(); else closeSpeedList();
1725	});
1726
1727	speedList.querySelectorAll('li').forEach(li => {
1728		li.addEventListener('click', () => {
1729			currentSpeedMs = parseInt(li.dataset.value, 10);
1730			speedLabel.textContent = li.textContent;
1731			speedList.querySelectorAll('li').forEach(x => x.setAttribute('aria-selected', 'false'));
1732			li.setAttribute('aria-selected', 'true');
1733			closeSpeedList();
1734			if (playing) scheduleNext();
1735		});
1736	});
1737
1738	document.addEventListener('click', (e) => {
1739		if (!speedBtn.contains(e.target) && !speedList.contains(e.target)) closeSpeedList();
1740	});
1741
1742	toggleLightning.addEventListener('change', () => {
1743		lightningEnabled = toggleLightning.checked;
1744		document.cookie = `rdr_lightning=${toggleLightning.checked ? '1' : '0'}; path=/; max-age=${60 * 60 * 24 * 365}; SameSite=Lax`;
1745		if (currentIndex >= 0) showFrame(currentIndex);
1746	});
1747
1748	// ============================================================
1749	// INITIALISATION — données déjà en mémoire (injectées par PHP),
1750	// plus de fetch() de manifest.
1751	// ============================================================
1752	async function init(){
1753		if (RADAR_FRAMES.length === 0 || STRIKES_FRAMES.length === 0){
1754			statusEl.textContent = I18N.errNoData;
1755			return;
1756		}
1757
1758		const pastFrames = matchFrames(RADAR_FRAMES, STRIKES_FRAMES, SYNC_TOLERANCE_SECONDS)
1759		.map(f => ({ ...f, isForecast: false }));
1760
1761		lastLiveTimestamp = pastFrames.length > 0 ? pastFrames[pastFrames.length - 1].timestamp : null;
1762
1763		if (pastFrames.length === 0){
1764			statusEl.textContent = I18N.errNoSync.replace('{s}', SYNC_TOLERANCE_SECONDS);
1765			return;
1766		}
1767
1768		const forecastFrames = buildForecastFrames(FORECAST_FRAMES);
1769		frames = [...pastFrames, ...forecastFrames];
1770
1771		const boundaryIndex = pastFrames.length - 1;
1772
1773		overlays = frames.map(f => ({
1774			radar: L.imageOverlay((f.isForecast ? FORECAST_BASE_URL : RADAR_BASE_URL) + f.radarFile, IMAGE_BOUNDS, {
1775				opacity: 1, interactive: false, zIndex: 350
1776			}),
1777			strikes: f.strikesFile ? L.imageOverlay(STRIKES_BASE_URL + f.strikesFile, IMAGE_BOUNDS, {
1778				opacity: 1, interactive: false, zIndex: 360
1779			}) : null
1780		}));
1781
1782		slider.max = overlays.length - 1;
1783		slider.disabled = false;
1784
1785		if (forecastFrames.length > 0 && overlays.length > 1){
1786			const boundaryPct = (boundaryIndex / (overlays.length - 1)) * 100;
1787			slider.style.background =
1788			`linear-gradient(to right, var(--panel-border) 0%, var(--panel-border) ${boundaryPct}%, `
1789			+ `rgba(166,84,10,0.25) ${boundaryPct}%, rgba(166,84,10,0.25) 100%)`;
1790		}
1791
1792		statusEl.textContent = I18N.statusLoadingFirst;
1793		await goToFrame(0);
1794
1795		statusEl.style.display = 'none';
1796		controlsEl.style.display = 'flex';
1797
1798		play();
1799	} // fin de init()
1800
1801	init();
1802} // fin de startWidget()
1803
1804const mapAspectEl = document.getElementById('rdrMapAspect');
1805if ('IntersectionObserver' in window){
1806	const observer = new IntersectionObserver((entries) => {
1807		entries.forEach(entry => {
1808			if (entry.isIntersecting){
1809				observer.disconnect();
1810				startWidget();
1811			}
1812		});
1813	}, { rootMargin: '200px 0px' });
1814	observer.observe(mapAspectEl);
1815} else {
1816	// Navigateur trop ancien pour IntersectionObserver : on charge direct.
1817	startWidget();
1818}
1819})();
1820</script>
1820
1821						
1822					</div>
1823				   					<div id="parent-right" class="col-xs-12 col-sm-4 right">
1824							
1825	
1826	
1827	
1827<script type="text/javascript">
1828
1829		window.mbCheckAdFallback = function (adId, fallbackId, usedNetwork) {
1830			var maxWait = 5000;
1831			var checkInterval = 200;
1832			var elapsed = 0;
1833
1834			var checker = setInterval(function () {
1835				elapsed += checkInterval;
1836				var status = window.mbAdStatus || {};
1837				var networkKnown = status[usedNetwork] === 'blocked' || status[usedNetwork] === 'loaded';
1838
1839				if (networkKnown || elapsed >= maxWait) {
1840					clearInterval(checker);
1841					var isBlocked = (status[usedNetwork] === 'blocked');
1842					if (isBlocked) {
1843						jQuery('#' + adId).hide();
1844						jQuery('#' + fallbackId).show();
1845					}
1846				}
1847			}, checkInterval);
1848		};
1849
1850	</script>
1850
1851			<div id="inner">
1852			<div id="imu-ad-scroll">
1853									<div id="fuse-container"></div>
1854					
1854<script>
1855					let fuse = window.innerWidth >= 992
1856						? "23053234809"
1857						: "23040641851";
1858					document.getElementById('fuse-container').innerHTML =
1859						'<div data-fuse="' + fuse + '"></div>';
1860					</script>
1860
1861							</div>
1862
1863			<div id="imu-fallback-scroll" style="display:none;">
1864				<a href="/premium/info"><img src="/staticfiles/images/mb_notice_a7f3_fr.gif" width="300" height="600" alt=""></a>
1865			</div>
1866		</div>
1867
1868		
1868<script type="text/javascript">
1869		jQuery(document).ready(function() {
1870			jQuery(window).scroll(function() {
1871				var p = jQuery("#parent-right");
1872				var inner = jQuery("#inner");
1873				var parentoff = p.offset();
1874				var parenthei = p.height();
1875				var inneroff = inner.offset();
1876				var innerhei = inner.height();
1877				var wintop = jQuery(window).scrollTop();
1878				if(parentoff.top < wintop && wintop < parentoff.top + parenthei - innerhei)
1879					jQuery("#inner").offset({top: wintop+10, left: inneroff.left});
1880			});
1881			window.mbCheckAdFallback('imu-ad-scroll', 'imu-fallback-scroll', 'fuse');
1882		});
1883		</script>
1883
1884
1885	
1886					</div>
1887				   				</div>
1888			</div>
1889        </div>
1890    </main>
1891
1892	<section class="villes">
1893	    <div class="container">
1894				
1895<div id="mod-custom177" class="mod-custom custom">
1896    <h2>Villes populaires</h2><p class="subheading"><i class="fa-solid fa-trophy"></i> Prévisions météo les plus consultées</p><div class="row"><div class="col-12 col-sm-3"><a title="Prévisions météo pour Bruxelles" href="/previsions-meteo-belgique/1000/bruxelles"style="background-image: url(/custom_modules/images/city/1000.jpg)" class="pinned_location 1000"><div class="layer"><h3>Bruxelles</h3><div class="wrap_weather"><div class="symbol_picture"><img width="50" height="50" alt="Ciel très nuageux" src="/staticfiles/images/picto/v2/wc/day/mostcloudy.png"></div><div class="temp">21 &deg;C</div><div class="clr"></div></div></div></a></div><div class="col-12 col-sm-3"><a title="Prévisions météo pour Liège" href="/previsions-meteo-belgique/4000/liege"style="background-image: url(/custom_modules/images/city/4000.jpg)" class="pinned_location 4000"><div class="layer"><h3>Liège</h3><div class="wrap_weather"><div class="symbol_picture"><img width="50" height="50" alt="Ciel très nuageux" src="/staticfiles/images/picto/v2/wc/day/mostcloudy.png"></div><div class="temp">20 &deg;C</div><div class="clr"></div></div></div></a></div><div class="col-12 col-sm-3"><a title="Prévisions météo pour Namur" href="/previsions-meteo-belgique/5000/namur"style="background-image: url(/custom_modules/images/city/5000.jpg)" class="pinned_location 5000"><div class="layer"><h3>Namur</h3><div class="wrap_weather"><div class="symbol_picture"><img width="50" height="50" alt="Ciel très nuageux" src="/staticfiles/images/picto/v2/wc/day/mostcloudy.png"></div><div class="temp">20 &deg;C</div><div class="clr"></div></div></div></a></div><div class="col-12 col-sm-3"><a title="Prévisions météo pour Mons" href="/previsions-meteo-belgique/7000/mons"style="background-image: url(/custom_modules/images/city/7000.jpg)" class="pinned_location 7000"><div class="layer"><h3>Mons</h3><div class="wrap_weather"><div class="symbol_picture"><img width="50" height="50" alt="Ciel très nuageux" src="/staticfiles/images/picto/v2/wc/day/mostcloudy.png"></div><div class="temp">21 &deg;C</div><div class="clr"></div></div></div></a></div></div><style>
1897.subheading {
1898
1899  align-items: center;
1900  gap: 8px;
1901  padding: 4px 10px;
1902  border-radius: 12px;     /* arrondi doux */
1903  color: #FFFFFF;
1904  font-size: 16px;
1905  font-weight: 500;
1906  text-align:center
1907}
1908</style></div>
1909
1910		</div>
1911	</section>
1912
1913    <section class="newsflash">
1914	    <div class="container">
1915				
1916<div id="mod-custom210" class="mod-custom custom">
1917    <h2>Actualité Météo</h2>
1918<div class="row newsflash-horiz">
1919
1920
1921<div class="col-md-4">
1922<a class="newsflash" href="/article/releves-et-analyses/annee-2026/2672-bilan-climatologique-de-septembre-2026">
1923<img src="/images/stories/headers/202609.jpg#joomlaImage://local-images/stories/headers/202609.jpg?width=520&height=254" loading="lazy" alt="Bilan climatologique de septembre 2026 : encore chaud et sec.">
1924<h3>Bilan climatologique de septembre 2026 : encore chaud et sec.</h3>
1925</a>
1926<span class="article-separator">&nbsp;</span>
1927</div>
1928
1929<div class="col-md-4">
1930<a class="newsflash" href="/article/articles-et-dossier/le-climat/81-climats-dhier-et-daujourdhui/2671-un-temps-que-les-moins-de-20-ans-ne-peuvent-pas-connaitre-septembre-1976">
1931<img src="/images/stories/headers/197609.jpg#joomlaImage://local-images/stories/headers/197609.jpg?width=520&height=369" loading="lazy" alt="Un temps que les moins de 20 ans ne peuvent pas connaître : septembre 1976">
1932<h3>Un temps que les moins de 20 ans ne peuvent pas connaître : septembre 1976</h3>
1933</a>
1934<span class="article-separator">&nbsp;</span>
1935</div>
1936
1937<div class="col-md-4">
1938<a class="newsflash" href="/previsions/belgique/tendances-saisonnieres/2670-tendances-pour-lautomne-2026">
1939<img src="/images/stories/headers/saisosautomne.jpg#joomlaImage://local-images/stories/headers/saisosautomne.jpg?width=453&height=300" loading="lazy" alt="Automne 2026 : encore doux mais retour progressif des précipitations ?">
1940<h3>Automne 2026 : encore doux mais retour progressif des précipitations ?</h3>
1941</a>
1942<span class="article-separator">&nbsp;</span>
1943</div>
1944</div>
1945
1946</div>
1947
1948		</div>
1949	</section>
1950    <section class="bottom">
1951	    <div class="container">
1952            <div class="row">
1953                <div class="col-xs-12 col-lg-4">
1954                	
1955<div id="mod-custom114" class="mod-custom custom">
1956    <div class="moduletable">
1957<h2><span class="backh3">A propos</span></h2>
1958<p>Créé en 2001 par plusieurs passionnés de météorologie, MeteoBelgique n'a cessé de grandir et est rapidement devenu le site de référence en Belgique francophone fort de 25 années d'expérience dans les domaines des prévisions météorologiques, du réseau en temps réel et des analyses climatologiques.</p>
1959</div></div>
1960
1961                </div>
1962                <div class="col-xs-12 col-lg-4">
1963                	
1964<div id="mod-custom115" class="mod-custom custom">
1965    <div class="moduletable">
1966<h2><span class="backh3">Nos services</span></h2>
1967<ul>
1968<li><a href="/communaute/divers/contact/7-equipe-meteobelgique">Nous contacter</a></li>
1969<li><a href="/premium/info">MeteoBelgique Premium</a></li>
1970<li><a href="/services/mobile/alerte-sms">Alertes par SMS</a></li>
1971<li><a href="/services/divers/meteo-sur-mesure">Prévisions météo sur mesure</a></li>
1972<li><a href="/services/divers/archive-des-stations">Archives Climatologiques</a></li>
1973</ul>
1974<p><a href="https://play.google.com/store/apps/details?id=com.wazabe.meteobelgique" target="_blank" rel="noopener"><img src="/images/services/app_google_fr.png" alt="app google nl" width="130" height="45" style="margin: 0px 0px 10px 10px; float: right;" /></a><a href="https://itunes.apple.com/be/app/meteo-belgique/id689793990" target="_blank" rel="noopener"><img src="/images/services/app_store_fr.png" alt="app store nl" width="130" height="44" style="margin: 0px 0px 10px 10px; float: right;" /></a></p>
1975</div></div>
1976
1977                </div>
1978                <div class="col-xs-12 col-lg-4">
1979                	
1980<div id="mod-custom187" class="mod-custom custom">
1981    <div class="moduletable">
1982<h2><span class="backh3">Nous suivre</span></h2>
1983<p><a href="https://www.facebook.com/MeteoBelgiqueBe/" target="_blank" rel="noopener"><img src="/images/contact/facebook-logo.png" alt="Facebook" width="50" height="50" style="margin-left: 20px; float: left;" /></a><a href="https://twitter.com/meteobelgiquebe?lang=fr" target="_blank" rel="noopener"><img src="/images/contact/twitter-logo.png" alt="Twitter" width="50" height="50" style="margin-left: 15px; margin-right: 15px; float: left;" /></a></p>
1984</div></div>
1985
1986                </div>
1987          </div>
1988    	</div>
1989    </section>
1990    <footer>	
1991	    <div class="container">
1992            <div class="row">
1993                <div class="col-xs-12 col-sm-4"><div class="moduletable">Copyright 2026 MétéoBelgique | Tous droits réservé.</div></div>
1994                <div class="col-xs-12 col-sm-5"></div>
1995                <div class="col-xs-12 col-sm-3"><a href="/privacy.php" target="_blank" class="gdocreative">&nbsp;Privacy</a><a class="gdocreative" onclick="javascript:__tcfapi('show', 2, function() {} )">&nbsp;Préférences des cookies - </a><a href="/disclaimer.php" target="_blank" class="gdocreative">Disclaimer - </a>
1996                </div>
1997            </div>
1998    	</div>
1999    </footer>
2000
2001	
2001<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
2001                
2002    
2002<script async="async" src="/templates/Content-new/js/bootstrap.js"></script>
2002
2003  </body>
2004</html>
2005

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.