<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wikicolombes.fr/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3ACarte-osm.js</id>
	<title>MediaWiki:Carte-osm.js - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://wikicolombes.fr/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3ACarte-osm.js"/>
	<link rel="alternate" type="text/html" href="https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;action=history"/>
	<updated>2026-10-08T07:23:23Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.43.3</generator>
	<entry>
		<id>https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;diff=1087&amp;oldid=prev</id>
		<title>Joebrable : Cartes : cartes d ensemble (parametre sources), pictogramme par theme, points dans les tableaux, Deplacer corrige l article source</title>
		<link rel="alternate" type="text/html" href="https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;diff=1087&amp;oldid=prev"/>
		<updated>2026-09-29T20:22:48Z</updated>

		<summary type="html">&lt;p&gt;Cartes : cartes d ensemble (parametre sources), pictogramme par theme, points dans les tableaux, Deplacer corrige l article source&lt;/p&gt;
&lt;a href=&quot;https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;amp;diff=1087&amp;amp;oldid=1079&quot;&gt;Voir les modifications&lt;/a&gt;</summary>
		<author><name>Joebrable</name></author>
	</entry>
	<entry>
		<id>https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;diff=1079&amp;oldid=prev</id>
		<title>Joebrable : Cartes : outil Deplacer pour les utilisateurs connectes (fiche du lieu, clic sur la carte, enregistrement dans le wikicode)</title>
		<link rel="alternate" type="text/html" href="https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;diff=1079&amp;oldid=prev"/>
		<updated>2026-09-29T08:29:56Z</updated>

		<summary type="html">&lt;p&gt;Cartes : outil Deplacer pour les utilisateurs connectes (fiche du lieu, clic sur la carte, enregistrement dans le wikicode)&lt;/p&gt;
&lt;a href=&quot;https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;amp;diff=1079&amp;amp;oldid=1070&quot;&gt;Voir les modifications&lt;/a&gt;</summary>
		<author><name>Joebrable</name></author>
	</entry>
	<entry>
		<id>https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;diff=1070&amp;oldid=prev</id>
		<title>Joebrable : Cartes OpenStreetMap : script des modeles Carte OSM et Point carte (Leaflet 1.9.4 heberge sur le serveur du wiki)</title>
		<link rel="alternate" type="text/html" href="https://wikicolombes.fr/index.php?title=MediaWiki:Carte-osm.js&amp;diff=1070&amp;oldid=prev"/>
		<updated>2026-09-29T07:55:16Z</updated>

		<summary type="html">&lt;p&gt;Cartes OpenStreetMap : script des modeles Carte OSM et Point carte (Leaflet 1.9.4 heberge sur le serveur du wiki)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/* Cartes OpenStreetMap de WikiColombes.&lt;br /&gt;
 *&lt;br /&gt;
 * Mode d&amp;#039;emploi, côté wikicode :&lt;br /&gt;
 *   - {{Carte OSM}} place la carte dans la page ;&lt;br /&gt;
 *   - {{Point carte|latitude|longitude|niveau=…|statut=…|adresse=…}}, posé à côté&lt;br /&gt;
 *     d&amp;#039;un nom dans une liste, y ajoute ce lieu.&lt;br /&gt;
 * Le script lit tous les points de la page, les range sous le titre de section&lt;br /&gt;
 * (niveau 3, à défaut 2) qui les précède, et fabrique la légende à partir de ces&lt;br /&gt;
 * titres. Ajouter une ligne à la liste suffit donc à l&amp;#039;ajouter à la carte.&lt;br /&gt;
 *&lt;br /&gt;
 * Niveaux : M maternelle, É élémentaire, P primaire (couleur des écoles),&lt;br /&gt;
 * C collège, L lycée ; plusieurs niveaux se séparent par des espaces (« P C L »).&lt;br /&gt;
 * Sans niveau, le lieu reçoit une pastille neutre : la carte sert aussi hors écoles.&lt;br /&gt;
 * statut=privé dessine une pastille carrée au lieu d&amp;#039;une ronde.&lt;br /&gt;
 *&lt;br /&gt;
 * Bibliothèque : Leaflet 1.9.4, hébergée sur le serveur du wiki&lt;br /&gt;
 * (/ressources/leaflet/1.9.4/) pour ne dépendre d&amp;#039;aucun CDN tiers.&lt;br /&gt;
 * Fond de carte : tuiles OpenStreetMap standard, attribution obligatoire.&lt;br /&gt;
 * Styles : bloc « Cartes OpenStreetMap » de MediaWiki:Common.css.&lt;br /&gt;
 */&lt;br /&gt;
( function () {&lt;br /&gt;
	&amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	if ( mw.carteOsm ) {&lt;br /&gt;
		return;                 // déjà chargé (aperçu de modification, etc.)&lt;br /&gt;
	}&lt;br /&gt;
	mw.carteOsm = {};&lt;br /&gt;
&lt;br /&gt;
	var LEAFLET = &amp;#039;/ressources/leaflet/1.9.4/&amp;#039;;&lt;br /&gt;
	var TUILES = &amp;#039;https://tile.openstreetmap.org/{z}/{x}/{y}.png&amp;#039;;&lt;br /&gt;
	var ATTRIBUTION = &amp;#039;&amp;amp;copy; &amp;lt;a href=&amp;quot;https://www.openstreetmap.org/copyright&amp;quot;&amp;gt;les contributeurs d’OpenStreetMap&amp;lt;/a&amp;gt;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
	var NIVEAUX = {&lt;br /&gt;
		M: { nom: &amp;#039;École maternelle&amp;#039;, famille: &amp;#039;ecole&amp;#039; },&lt;br /&gt;
		&amp;#039;É&amp;#039;: { nom: &amp;#039;École élémentaire&amp;#039;, famille: &amp;#039;ecole&amp;#039; },&lt;br /&gt;
		P: { nom: &amp;#039;École primaire&amp;#039;, famille: &amp;#039;ecole&amp;#039; },&lt;br /&gt;
		C: { nom: &amp;#039;Collège&amp;#039;, famille: &amp;#039;college&amp;#039; },&lt;br /&gt;
		L: { nom: &amp;#039;Lycée&amp;#039;, famille: &amp;#039;lycee&amp;#039; },&lt;br /&gt;
		&amp;#039;•&amp;#039;: { nom: &amp;#039;Lieu&amp;#039;, famille: &amp;#039;lieu&amp;#039; }       // point sans niveau : pastille neutre&lt;br /&gt;
	};&lt;br /&gt;
	var ORDRE = [ &amp;#039;M&amp;#039;, &amp;#039;É&amp;#039;, &amp;#039;P&amp;#039;, &amp;#039;C&amp;#039;, &amp;#039;L&amp;#039;, &amp;#039;•&amp;#039; ];&lt;br /&gt;
	var HAUTEUR_PX = 26;        // hauteur d&amp;#039;un marqueur (pastille de 22 px + liseré)&lt;br /&gt;
	var MARGE_PX = 3;           // écart minimal entre deux marqueurs voisins&lt;br /&gt;
	var reduit = window.matchMedia &amp;amp;&amp;amp; window.matchMedia( &amp;#039;(prefers-reduced-motion: reduce)&amp;#039; ).matches;&lt;br /&gt;
&lt;br /&gt;
	/* ---------- utilitaires ---------- */&lt;br /&gt;
&lt;br /&gt;
	function echapper( s ) {&lt;br /&gt;
		return String( s ).replace( /[&amp;amp;&amp;lt;&amp;gt;&amp;quot;&amp;#039;]/g, function ( c ) {&lt;br /&gt;
			return { &amp;#039;&amp;amp;&amp;#039;: &amp;#039;&amp;amp;amp;&amp;#039;, &amp;#039;&amp;lt;&amp;#039;: &amp;#039;&amp;amp;lt;&amp;#039;, &amp;#039;&amp;gt;&amp;#039;: &amp;#039;&amp;amp;gt;&amp;#039;, &amp;#039;&amp;quot;&amp;#039;: &amp;#039;&amp;amp;quot;&amp;#039;, &amp;quot;&amp;#039;&amp;quot;: &amp;#039;&amp;amp;#39;&amp;#039; }[ c ];&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function lireNiveaux( texte ) {&lt;br /&gt;
		var vus = [];&lt;br /&gt;
		String( texte || &amp;#039;&amp;#039; ).toUpperCase().split( /[\s,;\/]+/ ).forEach( function ( n ) {&lt;br /&gt;
			if ( n === &amp;#039;E&amp;#039; ) {&lt;br /&gt;
				n = &amp;#039;É&amp;#039;;&lt;br /&gt;
			}&lt;br /&gt;
			if ( NIVEAUX[ n ] &amp;amp;&amp;amp; vus.indexOf( n ) === -1 ) {&lt;br /&gt;
				vus.push( n );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
		vus.sort( function ( a, b ) {&lt;br /&gt;
			return ORDRE.indexOf( a ) - ORDRE.indexOf( b );&lt;br /&gt;
		} );&lt;br /&gt;
		return vus.length ? vus : [ &amp;#039;•&amp;#039; ];&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function pastille( niveau, statut ) {&lt;br /&gt;
		return &amp;#039;&amp;lt;span class=&amp;quot;carte-osm-pastille carte-osm-&amp;#039; + NIVEAUX[ niveau ].famille +&lt;br /&gt;
			( statut === &amp;#039;privé&amp;#039; ? &amp;#039; carte-osm-prive&amp;#039; : &amp;#039;&amp;#039; ) + &amp;#039;&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&amp;#039; + niveau + &amp;#039;&amp;lt;/span&amp;gt;&amp;#039;;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function pastillesDe( p ) {&lt;br /&gt;
		return p.niveaux.map( function ( n ) {&lt;br /&gt;
			return pastille( n, p.statut );&lt;br /&gt;
		} ).join( &amp;#039;&amp;#039; );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function texteTitre( h ) {&lt;br /&gt;
		var cible = h.querySelector( &amp;#039;.mw-headline&amp;#039; ) || h;&lt;br /&gt;
		return cible.textContent.replace( /\s*\([^)]*\)\s*$/, &amp;#039;&amp;#039; ).trim();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Le nom d&amp;#039;un lieu : la page liée (titre complet), sinon le texte de la ligne. */&lt;br /&gt;
	function lireNom( li, el ) {&lt;br /&gt;
		var liens = li ? li.querySelectorAll( &amp;#039;a&amp;#039; ) : [],&lt;br /&gt;
			lien = null, i;&lt;br /&gt;
		for ( i = 0; i &amp;lt; liens.length; i++ ) {&lt;br /&gt;
			if ( !liens[ i ].closest( &amp;#039;.reference, .point-carte-voir, .mw-cite-backlink&amp;#039; ) ) {&lt;br /&gt;
				lien = liens[ i ];&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		if ( lien ) {&lt;br /&gt;
			return {&lt;br /&gt;
				court: lien.textContent.trim(),&lt;br /&gt;
				complet: ( lien.getAttribute( &amp;#039;title&amp;#039; ) || lien.textContent )&lt;br /&gt;
					.replace( /\s*\(page inexistante\)$/, &amp;#039;&amp;#039; ).trim(),&lt;br /&gt;
				lien: lien.getAttribute( &amp;#039;href&amp;#039; ),&lt;br /&gt;
				rouge: lien.classList.contains( &amp;#039;new&amp;#039; )&lt;br /&gt;
			};&lt;br /&gt;
		}&lt;br /&gt;
		var copie = ( li || el.parentNode ).cloneNode( true );&lt;br /&gt;
		copie.querySelectorAll( &amp;#039;sup, ul, ol, .point-carte-voir&amp;#039; ).forEach( function ( x ) {&lt;br /&gt;
			x.remove();&lt;br /&gt;
		} );&lt;br /&gt;
		var texte = copie.textContent.replace( /\s*\(.*$/, &amp;#039;&amp;#039; ).trim();&lt;br /&gt;
		return { court: texte, complet: texte, lien: null, rouge: false };&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Sans lien, « Guy de Maupassant » devient « Lycée Guy de Maupassant ». */&lt;br /&gt;
	function nomComplet( p ) {&lt;br /&gt;
		if ( p.nom.lien || p.niveaux[ 0 ] === &amp;#039;•&amp;#039; ||&lt;br /&gt;
			/^(École|Ecole|Collège|Lycée|Groupe|Institut|Cité)\b/i.test( p.nom.complet ) ) {&lt;br /&gt;
			return p.nom.complet;&lt;br /&gt;
		}&lt;br /&gt;
		return NIVEAUX[ p.niveaux[ p.niveaux.length - 1 ] ].nom + &amp;#039; &amp;#039; + p.nom.complet;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ---------- lecture de la page ---------- */&lt;br /&gt;
&lt;br /&gt;
	function lirePoints( racine ) {&lt;br /&gt;
		var points = [], sections = [], index = {}, courante = null;&lt;br /&gt;
		racine.querySelectorAll( &amp;#039;h2, h3, .point-carte&amp;#039; ).forEach( function ( el ) {&lt;br /&gt;
			if ( !el.classList.contains( &amp;#039;point-carte&amp;#039; ) ) {&lt;br /&gt;
				courante = texteTitre( el );&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			var lat = parseFloat( el.getAttribute( &amp;#039;data-lat&amp;#039; ) ),&lt;br /&gt;
				lon = parseFloat( el.getAttribute( &amp;#039;data-lon&amp;#039; ) );&lt;br /&gt;
			if ( isNaN( lat ) || isNaN( lon ) ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			var cle = courante || &amp;#039;Autres lieux&amp;#039;,&lt;br /&gt;
				li = el.closest( &amp;#039;li&amp;#039; );&lt;br /&gt;
			if ( !index[ cle ] ) {&lt;br /&gt;
				index[ cle ] = { nom: cle, points: [], actif: true };&lt;br /&gt;
				sections.push( index[ cle ] );&lt;br /&gt;
			}&lt;br /&gt;
			var p = {&lt;br /&gt;
				lat: lat,&lt;br /&gt;
				lon: lon,&lt;br /&gt;
				niveaux: lireNiveaux( el.getAttribute( &amp;#039;data-niveau&amp;#039; ) ),&lt;br /&gt;
				statut: /priv/i.test( el.getAttribute( &amp;#039;data-statut&amp;#039; ) || &amp;#039;&amp;#039; ) ? &amp;#039;privé&amp;#039; : &amp;#039;public&amp;#039;,&lt;br /&gt;
				adresse: el.getAttribute( &amp;#039;data-adresse&amp;#039; ) || &amp;#039;&amp;#039;,&lt;br /&gt;
				section: index[ cle ],&lt;br /&gt;
				el: el&lt;br /&gt;
			};&lt;br /&gt;
			p.nom = lireNom( li, el );&lt;br /&gt;
			index[ cle ].points.push( p );&lt;br /&gt;
			points.push( p );&lt;br /&gt;
		} );&lt;br /&gt;
		return { points: points, sections: sections };&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ---------- construction d&amp;#039;une carte ---------- */&lt;br /&gt;
&lt;br /&gt;
	function construire( conteneur, racine ) {&lt;br /&gt;
		var donnees = lirePoints( racine );&lt;br /&gt;
		if ( !donnees.points.length ) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		conteneur.classList.add( &amp;#039;carte-osm-prete&amp;#039; );&lt;br /&gt;
		conteneur.innerHTML = &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
		/* légende et filtres, au-dessus de la carte */&lt;br /&gt;
		var legende = document.createElement( &amp;#039;div&amp;#039; );&lt;br /&gt;
		legende.className = &amp;#039;carte-osm-legende&amp;#039;;&lt;br /&gt;
		legende.setAttribute( &amp;#039;role&amp;#039;, &amp;#039;group&amp;#039; );&lt;br /&gt;
		legende.setAttribute( &amp;#039;aria-label&amp;#039;, &amp;#039;Lieux affichés sur la carte&amp;#039; );&lt;br /&gt;
		donnees.sections.forEach( function ( s ) {&lt;br /&gt;
			var etiquette = document.createElement( &amp;#039;label&amp;#039; ),&lt;br /&gt;
				caseACocher = document.createElement( &amp;#039;input&amp;#039; );&lt;br /&gt;
			caseACocher.type = &amp;#039;checkbox&amp;#039;;&lt;br /&gt;
			caseACocher.checked = true;&lt;br /&gt;
			caseACocher.setAttribute( &amp;#039;aria-label&amp;#039;, s.nom + &amp;#039; (&amp;#039; + s.points.length + &amp;#039;)&amp;#039; );&lt;br /&gt;
			caseACocher.addEventListener( &amp;#039;change&amp;#039;, function () {&lt;br /&gt;
				s.actif = caseACocher.checked;&lt;br /&gt;
				dessiner();&lt;br /&gt;
			} );&lt;br /&gt;
			s.caseACocher = caseACocher;&lt;br /&gt;
			etiquette.appendChild( caseACocher );&lt;br /&gt;
			etiquette.insertAdjacentHTML( &amp;#039;beforeend&amp;#039;,&lt;br /&gt;
				&amp;#039;&amp;lt;span class=&amp;quot;carte-osm-puces&amp;quot;&amp;gt;&amp;#039; + pastillesDe( s.points[ 0 ] ) + &amp;#039;&amp;lt;/span&amp;gt;&amp;#039; +&lt;br /&gt;
				&amp;#039;&amp;lt;span&amp;gt;&amp;#039; + echapper( s.nom ) + &amp;#039;&amp;lt;/span&amp;gt;&amp;#039; +&lt;br /&gt;
				&amp;#039;&amp;lt;span class=&amp;quot;carte-osm-compte&amp;quot;&amp;gt;&amp;#039; + s.points.length + &amp;#039;&amp;lt;/span&amp;gt;&amp;#039; );&lt;br /&gt;
			legende.appendChild( etiquette );&lt;br /&gt;
		} );&lt;br /&gt;
&lt;br /&gt;
		var fond = document.createElement( &amp;#039;div&amp;#039; );&lt;br /&gt;
		fond.className = &amp;#039;carte-osm-fond&amp;#039;;&lt;br /&gt;
		fond.setAttribute( &amp;#039;aria-label&amp;#039;, conteneur.getAttribute( &amp;#039;data-titre&amp;#039; ) || &amp;#039;Carte&amp;#039; );&lt;br /&gt;
		conteneur.appendChild( legende );&lt;br /&gt;
		conteneur.appendChild( fond );&lt;br /&gt;
&lt;br /&gt;
		var carte = L.map( fond, {&lt;br /&gt;
			zoomControl: false,&lt;br /&gt;
			scrollWheelZoom: false,       // la molette fait défiler la page tant qu&amp;#039;on n&amp;#039;a pas cliqué la carte&lt;br /&gt;
			minZoom: 12,&lt;br /&gt;
			maxZoom: 19,&lt;br /&gt;
			zoomAnimation: !reduit,&lt;br /&gt;
			fadeAnimation: !reduit,&lt;br /&gt;
			markerZoomAnimation: !reduit&lt;br /&gt;
		} );&lt;br /&gt;
		L.tileLayer( TUILES, { maxZoom: 19, attribution: ATTRIBUTION } ).addTo( carte );&lt;br /&gt;
		carte.attributionControl.setPrefix( &amp;#039;&amp;lt;a href=&amp;quot;https://leafletjs.com/&amp;quot;&amp;gt;Leaflet&amp;lt;/a&amp;gt;&amp;#039; );&lt;br /&gt;
		L.control.zoom( { zoomInTitle: &amp;#039;Zoom avant&amp;#039;, zoomOutTitle: &amp;#039;Zoom arrière&amp;#039; } ).addTo( carte );&lt;br /&gt;
&lt;br /&gt;
		var limites = L.latLngBounds( donnees.points.map( function ( p ) {&lt;br /&gt;
			return [ p.lat, p.lon ];&lt;br /&gt;
		} ) );&lt;br /&gt;
		function cadrer() {&lt;br /&gt;
			carte.fitBounds( limites, { padding: [ 24, 24 ] } );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		var ToutVoir = L.Control.extend( {&lt;br /&gt;
			options: { position: &amp;#039;topleft&amp;#039; },&lt;br /&gt;
			onAdd: function () {&lt;br /&gt;
				var bouton = L.DomUtil.create( &amp;#039;button&amp;#039;, &amp;#039;carte-osm-toutvoir&amp;#039; );&lt;br /&gt;
				bouton.type = &amp;#039;button&amp;#039;;&lt;br /&gt;
				bouton.textContent = &amp;#039;Tout voir&amp;#039;;&lt;br /&gt;
				bouton.title = &amp;#039;Revenir à la vue d’ensemble&amp;#039;;&lt;br /&gt;
				L.DomEvent.disableClickPropagation( bouton );&lt;br /&gt;
				L.DomEvent.on( bouton, &amp;#039;click&amp;#039;, cadrer );&lt;br /&gt;
				return bouton;&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
		new ToutVoir().addTo( carte );&lt;br /&gt;
&lt;br /&gt;
		carte.on( &amp;#039;focus click&amp;#039;, function () {&lt;br /&gt;
			carte.scrollWheelZoom.enable();&lt;br /&gt;
		} );&lt;br /&gt;
		carte.on( &amp;#039;blur mouseout&amp;#039;, function () {&lt;br /&gt;
			carte.scrollWheelZoom.disable();&lt;br /&gt;
		} );&lt;br /&gt;
&lt;br /&gt;
		/* ---------- regroupement des lieux trop proches à l&amp;#039;échelle affichée ---------- */&lt;br /&gt;
&lt;br /&gt;
		var calque = L.layerGroup().addTo( carte ),&lt;br /&gt;
			groupes = [];&lt;br /&gt;
&lt;br /&gt;
		function rang( p ) {&lt;br /&gt;
			return ORDRE.indexOf( p.niveaux[ 0 ] ) * 2 + ( p.statut === &amp;#039;privé&amp;#039; ? 1 : 0 );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		function bulle( g ) {&lt;br /&gt;
			var html = &amp;#039;&amp;lt;div class=&amp;quot;carte-osm-bulle&amp;quot;&amp;gt;&amp;lt;ul&amp;gt;&amp;#039;;&lt;br /&gt;
			g.membres.slice().sort( function ( a, b ) {&lt;br /&gt;
				return rang( a ) - rang( b ) || nomComplet( a ).localeCompare( nomComplet( b ), &amp;#039;fr&amp;#039; );&lt;br /&gt;
			} ).forEach( function ( p ) {&lt;br /&gt;
				var nom = echapper( nomComplet( p ) );&lt;br /&gt;
				if ( p.nom.lien ) {&lt;br /&gt;
					nom = &amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + echapper( p.nom.lien ) + &amp;#039;&amp;quot;&amp;#039; + ( p.nom.rouge ? &amp;#039; class=&amp;quot;new&amp;quot;&amp;#039; : &amp;#039;&amp;#039; ) + &amp;#039;&amp;gt;&amp;#039; + nom + &amp;#039;&amp;lt;/a&amp;gt;&amp;#039;;&lt;br /&gt;
				}&lt;br /&gt;
				html += &amp;#039;&amp;lt;li&amp;gt;&amp;lt;span class=&amp;quot;carte-osm-puces&amp;quot;&amp;gt;&amp;#039; + pastillesDe( p ) + &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;span&amp;gt;&amp;#039; +&lt;br /&gt;
					&amp;#039;&amp;lt;span class=&amp;quot;carte-osm-nom&amp;quot;&amp;gt;&amp;#039; + nom + &amp;#039;&amp;lt;/span&amp;gt;&amp;#039; +&lt;br /&gt;
					&amp;#039;&amp;lt;span class=&amp;quot;carte-osm-detail&amp;quot;&amp;gt;Enseignement &amp;#039; + p.statut +&lt;br /&gt;
					( p.adresse ? &amp;#039; · &amp;#039; + echapper( p.adresse ) : &amp;#039;&amp;#039; ) + &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;&amp;#039;;&lt;br /&gt;
			} );&lt;br /&gt;
			html += &amp;#039;&amp;lt;/ul&amp;gt;&amp;#039;;&lt;br /&gt;
			if ( g.etendu ) {&lt;br /&gt;
				html += &amp;#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;carte-osm-zoom&amp;quot;&amp;gt;Zoomer sur ces &amp;#039; + g.membres.length + &amp;#039; lieux&amp;lt;/button&amp;gt;&amp;#039;;&lt;br /&gt;
			}&lt;br /&gt;
			return html + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		/* Un groupe = les lieux qui se chevaucheraient à l&amp;#039;écran. Son marqueur aligne&lt;br /&gt;
		   une pastille par niveau présent, d&amp;#039;où une largeur variable : on compare&lt;br /&gt;
		   donc les boîtes réelles des marqueurs, pas seulement leurs centres, et on&lt;br /&gt;
		   fusionne tant qu&amp;#039;il reste un chevauchement. */&lt;br /&gt;
		function majGroupe( g ) {&lt;br /&gt;
			var x = 0, y = 0, vues = {};&lt;br /&gt;
			g.membres.forEach( function ( p ) {&lt;br /&gt;
				x += p.px.x / g.membres.length;&lt;br /&gt;
				y += p.px.y / g.membres.length;&lt;br /&gt;
			} );&lt;br /&gt;
			g.px = L.point( x, y );&lt;br /&gt;
			g.puces = [];&lt;br /&gt;
			ORDRE.forEach( function ( n ) {&lt;br /&gt;
				[ &amp;#039;public&amp;#039;, &amp;#039;privé&amp;#039; ].forEach( function ( st ) {&lt;br /&gt;
					g.membres.forEach( function ( p ) {&lt;br /&gt;
						if ( p.statut === st &amp;amp;&amp;amp; p.niveaux.indexOf( n ) !== -1 &amp;amp;&amp;amp; !vues[ n + st ] ) {&lt;br /&gt;
							vues[ n + st ] = true;&lt;br /&gt;
							g.puces.push( pastille( n, st ) );&lt;br /&gt;
						}&lt;br /&gt;
					} );&lt;br /&gt;
				} );&lt;br /&gt;
			} );&lt;br /&gt;
			g.largeur = g.puces.length * 24 + 2;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		function chevauchent( a, b ) {&lt;br /&gt;
			return Math.abs( a.px.x - b.px.x ) &amp;lt; ( a.largeur + b.largeur ) / 2 + MARGE_PX &amp;amp;&amp;amp;&lt;br /&gt;
				Math.abs( a.px.y - b.px.y ) &amp;lt; HAUTEUR_PX + MARGE_PX;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		function dessiner() {&lt;br /&gt;
			calque.clearLayers();&lt;br /&gt;
			groupes = donnees.points.filter( function ( p ) {&lt;br /&gt;
				return p.section.actif;&lt;br /&gt;
			} ).map( function ( p ) {&lt;br /&gt;
				p.px = carte.latLngToLayerPoint( [ p.lat, p.lon ] );&lt;br /&gt;
				var g = { membres: [ p ] };&lt;br /&gt;
				majGroupe( g );&lt;br /&gt;
				return g;&lt;br /&gt;
			} );&lt;br /&gt;
			var i, j, fusion = true;&lt;br /&gt;
			while ( fusion ) {&lt;br /&gt;
				fusion = false;&lt;br /&gt;
				for ( i = 0; i &amp;lt; groupes.length &amp;amp;&amp;amp; !fusion; i++ ) {&lt;br /&gt;
					for ( j = i + 1; j &amp;lt; groupes.length; j++ ) {&lt;br /&gt;
						if ( chevauchent( groupes[ i ], groupes[ j ] ) ) {&lt;br /&gt;
							groupes[ i ].membres = groupes[ i ].membres.concat( groupes[ j ].membres );&lt;br /&gt;
							majGroupe( groupes[ i ] );&lt;br /&gt;
							groupes.splice( j, 1 );&lt;br /&gt;
							fusion = true;&lt;br /&gt;
							break;&lt;br /&gt;
						}&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			groupes.forEach( function ( g ) {&lt;br /&gt;
				g.limites = L.latLngBounds( g.membres.map( function ( p ) {&lt;br /&gt;
					return [ p.lat, p.lon ];&lt;br /&gt;
				} ) );&lt;br /&gt;
				g.etendu = g.membres.length &amp;gt; 1 &amp;amp;&amp;amp;&lt;br /&gt;
					carte.distance( g.limites.getSouthWest(), g.limites.getNorthEast() ) &amp;gt; 5;&lt;br /&gt;
				var puces = g.puces,&lt;br /&gt;
					noms = g.membres.map( nomComplet ).join( &amp;#039;, &amp;#039; ),&lt;br /&gt;
					html = &amp;#039;&amp;lt;span class=&amp;quot;carte-osm-marque&amp;quot;&amp;gt;&amp;#039; + puces.join( &amp;#039;&amp;#039; ) +&lt;br /&gt;
						( g.membres.length &amp;gt; puces.length ? &amp;#039;&amp;lt;span class=&amp;quot;carte-osm-nombre&amp;quot;&amp;gt;&amp;#039; + g.membres.length + &amp;#039;&amp;lt;/span&amp;gt;&amp;#039; : &amp;#039;&amp;#039; ) +&lt;br /&gt;
						&amp;#039;&amp;lt;/span&amp;gt;&amp;#039;;&lt;br /&gt;
				g.marque = L.marker( carte.layerPointToLatLng( g.px ), {&lt;br /&gt;
					icon: L.divIcon( { className: &amp;#039;carte-osm-icone&amp;#039;, html: html, iconSize: null } ),&lt;br /&gt;
					title: noms,&lt;br /&gt;
					keyboard: true,&lt;br /&gt;
					riseOnHover: true&lt;br /&gt;
				} ).bindPopup( bulle( g ), { maxWidth: 300, minWidth: 200, maxHeight: 280 } ).addTo( calque );&lt;br /&gt;
				var icone = g.marque.getElement();&lt;br /&gt;
				if ( icone ) {&lt;br /&gt;
					icone.setAttribute( &amp;#039;aria-label&amp;#039;, noms );&lt;br /&gt;
				}&lt;br /&gt;
				g.marque.on( &amp;#039;popupopen&amp;#039;, function ( e ) {&lt;br /&gt;
					var fermer = e.popup.getElement().querySelector( &amp;#039;.leaflet-popup-close-button&amp;#039; ),&lt;br /&gt;
						bouton = e.popup.getElement().querySelector( &amp;#039;.carte-osm-zoom&amp;#039; );&lt;br /&gt;
					if ( fermer ) {&lt;br /&gt;
						fermer.setAttribute( &amp;#039;aria-label&amp;#039;, &amp;#039;Fermer&amp;#039; );&lt;br /&gt;
						fermer.title = &amp;#039;Fermer&amp;#039;;&lt;br /&gt;
					}&lt;br /&gt;
					if ( bouton ) {&lt;br /&gt;
						bouton.addEventListener( &amp;#039;click&amp;#039;, function () {&lt;br /&gt;
							carte.closePopup();&lt;br /&gt;
							carte.fitBounds( g.limites, { padding: [ 48, 48 ], maxZoom: 18 } );&lt;br /&gt;
						} );&lt;br /&gt;
					}&lt;br /&gt;
				} );&lt;br /&gt;
			} );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		carte.on( &amp;#039;zoomend&amp;#039;, dessiner );&lt;br /&gt;
&lt;br /&gt;
		/* ---------- « situer sur la carte » depuis la liste ---------- */&lt;br /&gt;
&lt;br /&gt;
		donnees.points.forEach( function ( p ) {&lt;br /&gt;
			if ( p.el.nextElementSibling &amp;amp;&amp;amp; p.el.nextElementSibling.classList.contains( &amp;#039;point-carte-voir&amp;#039; ) ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			var bouton = document.createElement( &amp;#039;button&amp;#039; );&lt;br /&gt;
			bouton.type = &amp;#039;button&amp;#039;;&lt;br /&gt;
			bouton.className = &amp;#039;point-carte-voir&amp;#039;;&lt;br /&gt;
			bouton.textContent = &amp;#039;📍&amp;#039;;&lt;br /&gt;
			bouton.title = &amp;#039;Situer sur la carte&amp;#039;;&lt;br /&gt;
			bouton.setAttribute( &amp;#039;aria-label&amp;#039;, &amp;#039;Situer &amp;#039; + nomComplet( p ) + &amp;#039; sur la carte&amp;#039; );&lt;br /&gt;
			bouton.addEventListener( &amp;#039;click&amp;#039;, function () {&lt;br /&gt;
				if ( !p.section.actif ) {&lt;br /&gt;
					p.section.actif = true;&lt;br /&gt;
					p.section.caseACocher.checked = true;&lt;br /&gt;
				}&lt;br /&gt;
				conteneur.scrollIntoView( { behavior: reduit ? &amp;#039;auto&amp;#039; : &amp;#039;smooth&amp;#039;, block: &amp;#039;center&amp;#039; } );&lt;br /&gt;
				var cible = L.latLng( p.lat, p.lon ), zoom = Math.max( carte.getZoom(), 17 );&lt;br /&gt;
				function ouvrir() {&lt;br /&gt;
					dessiner();&lt;br /&gt;
					groupes.forEach( function ( g ) {&lt;br /&gt;
						if ( g.membres.indexOf( p ) !== -1 ) {&lt;br /&gt;
							g.marque.openPopup();&lt;br /&gt;
						}&lt;br /&gt;
					} );&lt;br /&gt;
				}&lt;br /&gt;
				if ( carte.getZoom() === zoom &amp;amp;&amp;amp; carte.getCenter().distanceTo( cible ) &amp;lt; 1 ) {&lt;br /&gt;
					ouvrir();&lt;br /&gt;
				} else {&lt;br /&gt;
					carte.once( &amp;#039;moveend&amp;#039;, ouvrir );&lt;br /&gt;
					carte.setView( cible, zoom, { animate: !reduit } );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
			p.el.insertAdjacentElement( &amp;#039;afterend&amp;#039;, bouton );&lt;br /&gt;
		} );&lt;br /&gt;
&lt;br /&gt;
		/* une carte dans une section repliée (vue mobile) naît sans dimensions */&lt;br /&gt;
		function montrer() {&lt;br /&gt;
			carte.invalidateSize();&lt;br /&gt;
			cadrer();&lt;br /&gt;
			dessiner();&lt;br /&gt;
		}&lt;br /&gt;
		if ( fond.offsetWidth &amp;amp;&amp;amp; fond.offsetHeight ) {&lt;br /&gt;
			montrer();&lt;br /&gt;
		}&lt;br /&gt;
		if ( window.ResizeObserver ) {&lt;br /&gt;
			var avant = fond.offsetWidth;&lt;br /&gt;
			new ResizeObserver( function () {&lt;br /&gt;
				if ( fond.offsetWidth &amp;amp;&amp;amp; !avant ) {&lt;br /&gt;
					montrer();&lt;br /&gt;
				} else if ( fond.offsetWidth ) {&lt;br /&gt;
					carte.invalidateSize();&lt;br /&gt;
				}&lt;br /&gt;
				avant = fond.offsetWidth;&lt;br /&gt;
			} ).observe( fond );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* ---------- chargement de Leaflet, puis des cartes de la page ---------- */&lt;br /&gt;
&lt;br /&gt;
	var leaflet = null;&lt;br /&gt;
	function chargerLeaflet() {&lt;br /&gt;
		if ( !leaflet ) {&lt;br /&gt;
			mw.loader.load( LEAFLET + &amp;#039;leaflet.css&amp;#039;, &amp;#039;text/css&amp;#039; );&lt;br /&gt;
			leaflet = window.L ? Promise.resolve() : mw.loader.getScript( LEAFLET + &amp;#039;leaflet.js&amp;#039; );&lt;br /&gt;
		}&lt;br /&gt;
		return leaflet;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	mw.hook( &amp;#039;wikipage.content&amp;#039; ).add( function ( $contenu ) {&lt;br /&gt;
		var racine = $contenu &amp;amp;&amp;amp; $contenu[ 0 ],&lt;br /&gt;
			cartes = racine ? racine.querySelectorAll( &amp;#039;.carte-osm:not(.carte-osm-prete)&amp;#039; ) : [];&lt;br /&gt;
		if ( !cartes.length ) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
		chargerLeaflet().then( function () {&lt;br /&gt;
			cartes.forEach( function ( conteneur ) {&lt;br /&gt;
				construire( conteneur, racine );&lt;br /&gt;
			} );&lt;br /&gt;
		}, function () {&lt;br /&gt;
			cartes.forEach( function ( conteneur ) {&lt;br /&gt;
				var repli = conteneur.querySelector( &amp;#039;.carte-osm-repli&amp;#039; );&lt;br /&gt;
				if ( repli ) {&lt;br /&gt;
					repli.textContent = &amp;#039;La carte n’a pas pu être chargée.&amp;#039;;&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
}() );&lt;/div&gt;</summary>
		<author><name>Joebrable</name></author>
	</entry>
</feed>