Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
//<nowiki> /***************************************************************************  * MarkerTooltip.js v1.6, 2025-01-02  * Displays an extended marker tooltip on mouse over on desktops  * or on click on smartphones  * Displays tooltip for abbreviations on smartphones  * Original author: Roland Unger  * Support of both desktop and mobile views  * Documentation: https://de.wikivoyage.org/wiki/Wikivoyage:Gadget-MarkerTooltip.js  * License: GPL-2.0+, CC-by-sa 3.0  ***************************************************************************/ /* eslint-disable mediawiki/class-doc */  ( function ( $ ) { 	'use strict';  	var mkTooltip = function() { 		const strings = { 			de: { 				hint:          'Click auf den Marker öffnet die Karte direkt.', 				hint2:         'Bitte nutzen Sie zur Anzeige die Kartendienste.',  				ch1903:        'CH1903', 				ch1903Title:   'Es folgt die Koordinate in der Form der Schweizer Landeskoordinaten.', 				dec:           'Dezimal', 				decTitle:      'Es folgt die Koordinate in Dezimalform. Über den nebenstehenden Geo-URI-Link kann eine Karten-Anwendung gestartet werden.', 				geoUriTitle:   'Über diesen Link startet der Browser eine Karten-Anwendung, z.&#x202F;B. Google Maps. Auf vielen Smartphones bereits eingerichtet.', 				hex:           'GMS', 				hexTitle:      'Es folgt die Koordinate in der Form Grad-Minuten-Sekunden.', 				plus:          'Plus Code', 				plusTitle:     'Es folgt die Koordinate als Plus Code.',  				anchor:        'Anker', 				anchorTitle:   'Zeigt den Namen des Vorlagen-Ankers an.', 				anchorText:    'Der Name des Vorlagen-Ankers lautet:\n\n', 				clipboard:     'Ablage', 				clipboardTitle:'Kopiert die nebenstehende Angabe in die Zwischenablage. Insbesondere ältere Browser unterstützten diese Funktion leider nicht.', 				mapSources:    'Kartendienste', 				mapSourcesTitle: 'Es folgen verschiedene Listen mit Kartenquellen und -diensten', 				tools:         'Werkzeuge', 				toolsTitle:    'Es folgen verschiedene Vorlagen-Werkzeuge', 				voy:           'Wikivoyage', 				voyTitle:      'Öffnet eine Wikivoyage-eigene Internetseite, die zahlreiche Kartenquellen und -dienste auflistet.', 				voyURL:        '/w/index.php?title=Special%3AMapsources', 				wmflabs:       'WMF-Labs', 				wmflabsTitle:  'Öffnet eine Internetseite von WMF Labs, die zahlreiche Kartenquellen und -dienste auflistet.', 				wmflabsURL:    'https://tools.wmflabs.org/geohack/geohack.php',  				EW:            'OW', // international: 'EW' 				NS:            'NS' 			}, 			en: { 				hint:          'Clicking on the marker directly opens the map.', 				hint2:         'Please use the map tools for display.',  				ch1903:        'CH1903', 				ch1903Title:   'Coordinates are shown in the form of the Swiss national coordinates.', 				dec:           'Decimal', 				decTitle:      'Coordinates are shown as decimal values. A map application can be started via the adjacent Geo-URI link.', 				geoUriTitle:   'The browser starts a map application using this link, e.&#x202F;g. Google Maps. Already set up on many smartphones.', 				hex:           'DMS', 				hexTitle:      'Coordinates are shown as degree-minutes-seconds.', 				plus:          'Plus Code', 				plusTitle:     'Coordinates are shown as Plus Code.',  				anchor:        'Anchor', 				anchorTitle:   'Shows the name of the template anchor.', 				anchorText:    'The name of the template anchor is:\n\n', 				clipboard:     'Clipboard', 				clipboardTitle:'Copies the adjacent information to the clipboard. Unfortunately, older browsers do not support this feature.', 				mapSources:    'Map tools', 				mapSourcesTitle: 'The following lists with map sources and services are available', 				tools:         'Tools', 				toolsTitle:    'The following tools are available', 				voy:           'Wikivoyage', 				voyTitle:      'Opens Wikivoyage’s own webpage which lists numerous map sources and services.', 				voyURL:        '/w/index.php?title=Special%3AMapsources', 				wmflabs:       'WMF Labs', 				wmflabsTitle:  'Opens a WMF Labs webpage which lists numerous map sources and services.', 				wmflabsURL:    'https://tools.wmflabs.org/geohack/geohack.php',  				EW:            'EW', 				NS:            'NS' 			}, 			es: { 				hint:          'Haga clic aquí para abrir el mapa.', 				hint2:         'Utilice los servicios de mapas para visualizar.',  				ch1903:        'CH1903', 				ch1903Title:   'A esto le sigue la coordenada en forma de coordenadas nacionales suizas.', 				dec:           'Decimal', 				decTitle:      'La coordenada sigue en forma decimal. Se puede iniciar una aplicación de mapas a través del enlace Geo-URI adyacente.', 				geoUriTitle:   'El navegador inicia una aplicación de mapas a través de este enlace, p. ej. mapas de Google. Ya está configurado en muchos teléfonos inteligentes Android.', 				hex:           'GMS', 				hexTitle:      'La coordenada sigue en forma de grados-minutos-segundos.', 				plus:          'Plus Code', 				plusTitle:     'La coordenada sigue como un código de ubicación abierto.',  				anchor:        'Ancla', 				anchorTitle:   'Muestra el nombre del ancla de la plantilla.', 				anchorText:    'El nombre del ancla de la plantilla es:\n\n', 				clipboard:     'Portapapeles', 				clipboardTitle:'Copia la información adyacente al portapapeles. Lamentablemente, los navegadores más antiguos no admiten esta función.', 				mapSources:    'Instrumentos de mapas', 				mapSourcesTitle: 'Las siguientes listas con fuentes y instrumentos de mapas están disponibles.', 				tools:         'Instrumentos', 				toolsTitle:    'Los siguientes instrumentos están disponibles.', 				voy:           'Wikiviajes', 				voyTitle:      'Abre un sitio web de Wikiviajes que enumera numerosas fuentes y instrumentos de mapas.', 				voyURL:        '/w/index.php?title=Special%3AMapsources', 				wmflabs:       'WMF Labs', 				wmflabsTitle:  'Abre un sitio web de WMF Labs que enumera numerosas fuentes y instrumentos de mapas.', 				wmflabsURL:    'https://tools.wmflabs.org/geohack/geohack.php',  				EW:            'EO',  // international: 'EW' 				NS:            'NS' 			} 		};  		const fallbackLang = 'en', 			maxZoomLevel = 19; // see also getScaleFromZoom  		const options = { 			plusCode: false, 			ch1903:   true 		};  		const version = "2024-12-31";  		const classes = { 			copyMarker:       'voy-copy-marker', 			idRegex:          /vCard_.+/, // see [[Module:Marker_utilities/i18n]], texts.anchor 			listingTooltip:   'listing-tooltip', 			listingTooltipMobile: 'listing-tooltip-mobile', 			withoutMarker:    'voy-without-marker' 		};  		const selectors = { 			kartographerLink: '.mw-kartographer-maplink', 			latitude:         '.p-latitude', 			longitude:        '.p-longitude', 			lCoordinates:     '.listing-coordinates', 			lEditButton:      '.listing-edit-button button', 			lInfoButton:      '.listing-info-button button', 			lMap:             '.listing-map, .listing-without-marker', 			lName:            '.listing-name', 			vcard:            '.vcard' 		};  		const data = { 			color:      'data-color', 			id:         'data-tooltip-id', 			lat:        'data-lat', 			lon:        'data-lon', 			mAttribute: 'data-copy-marker-attribute', 			mContent:   'data-copy-marker-content', 			name:       'data-name', 			region:     'data-region', 			wikilang:   'data-wikilang', 			zoom:       'data-zoom', 			version:    'data-version' 		};  		// internal use 		const pageLang = mw.config.get( 'wgPageContentLanguage' ), 			userLang = mw.config.get( 'wgUserLanguage' ), 		//	isMobile = window.matchMedia( '(any-pointer: coarse)' ).matches &&  // has touch screen or similar 		//		!window.matchMedia( '(any-pointer: fine)' ).matches,  // has mouse 			isMobile = ( /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test( navigator.userAgent.toLowerCase() ) ), 			timeouts = []; 		var messages = {};  		function addMessages( str, chain ) { 			for ( var i = chain.length - 1; i >= 0; i-- ) { 				if ( str.hasOwnProperty( chain[ i ] ) ) { 					$.extend( messages, strings[ chain[ i ] ] ); 				} 			} 		}  		function setupMessages() { 			const chain = ( userLang == pageLang ) ? [ pageLang, fallbackLang ] : 				[ userLang, pageLang, fallbackLang ]; 			addMessages( strings, chain ); 		}  		// Only n digits 		function round( coord, n ) { 			const m = Math.pow( 10, n ); 			return Math.round( coord * m ) / m; 		}  		// Converting decimal to DMS coordinates 		function toDMS( dec, letters ) { 			const letter = letters.charAt( ( dec >= 0 ) ? 0 : 1 ); 			const angle = Math.abs( dec );  			var deg = Math.floor( angle ); 			var min = ( angle - deg ) * 60; 			var sec = Math.round( ( min - Math.floor( min ) ) * 60 ); 			min = Math.floor( min ); 			if ( sec >= 60 ) { 				sec -= 60; 				min += 1; 			} 			if ( min >= 60 ) { 				min -= 60; 				deg += 1; 			} 			return `${deg}° ${min}${sec}${letter}`; 		}  		// Converting decimal to CH1903 coordinates 		// see: https://de.wikipedia.org/wiki/Schweizer_Landeskoordinaten 		function toCH1903( lat, lon ) { 			const ch1903 = { 				easting: 0, 				northing: 0, 				error: true 			}; 			if ( lat < 45.5 || lat > 48 || lon < 5.0 || lon > 11 ) { 				return ch1903; 			}  			const phi = ( lat * 3600 - 169028.66 ) / 10000; 			const phi2 = phi * phi; 			const lambda = ( lon * 3600 - 26782.5 ) / 10000; 			const lambda2 = lambda * lambda;  			ch1903.northing = Math.round( 200147.07 + 308807.95 * phi + 3745.25 * lambda2 + 				76.63 * phi2 - 194.56 * lambda2 * phi + 119.79 * phi2 * phi );  			ch1903.easting = Math.round( 600072.37 + 211455.93 * lambda - 10938.51 * lambda * phi - 				0.36 * lambda * phi2 - 44.54 * lambda2 * lambda );  			ch1903.error = false; 			return ch1903; 		}  		// Converting decimal to Open Location Code (Plus Code) 		// see: https://en.wikipedia.org/wiki/Open_Location_Code 		function toPlusCode( lat, lon ) { 			const codeChars = '23456789CFGHJMPQRVWX'; 			const resolutions = [ 20.0, 1.0, 0.05, 0.0025, 0.000125 ]; 			var code = '';  			var modLat = lat; 			modLat = Math.max( -90, modLat ); 			modLat = Math.min( modLat, 90 - 0.000025 ); 			// 0.000025 = resolutions[ 4 ] / 5 [rows] 			modLat += 90; // starting from 0 			 			var modLon = lon; 			while ( modLon < -180 ) { 				modLon += 360; 			} 			while ( modLon >= 180 ) { 				modLon -= 360; 			} 			modLon += 180; // starting from 0  			// first 10 + 1 digits 			for ( var i = 0; i < 5; i++ ) { 				const res = resolutions[ i ];  				var digit = Math.floor( modLat / res ); 				modLat -= digit * res; 				code += codeChars.charAt( digit );  				digit = Math.floor( modLon / res ); 				modLon -= digit * res; 				code += codeChars.charAt( digit );  				if ( i === 3 ) { 					code += '+'; 				} 			}  			// last digit 			const row = Math.floor( 5 * modLat / resolutions[ 4 ] ); 			const col = Math.floor( 4 * modLon / resolutions[ 4 ] ); 			code += codeChars.charAt( 4 * row + col );  			return code; 		}  		function shortenCoordinate( coord ) { 			return Math.round( coord * 1E5 ) / 1E5; // only 5 decimals 		}  		// zoom level 19 -> 1:1000, 0 -> 500000000 		function getScaleFromZoom( zoom ) { 			const scales = [ 1000, 2000, 4000, 8000, 15000, 35000, 70000, 150000, 250000, 				500000, 1000000, 2000000, 4000000, 10000000, 15000000, 35000000, 70000000, 				150000000, 250000000, 500000000 ]; 			if ( zoom >= maxZoomLevel ) { 				return scales[ 0 ]; 			} else if ( zoom <= 0 ) { 				return scales[ scales.length - 1 ]; 			} 			return scales[ maxZoomLevel - Math.round( zoom ) ]; 		}  		function copyToClipboard( selector, container ) { 			const clipboard = $( '<textarea id="mkClipboard"></textarea>' ) 				.css( { 'width': 1, 'border': 'none', 'opacity': 0 } ); 			$( 'body' ).append( clipboard ); 			const text = ( selector !== '.mkClip5' ) ? $( selector, container ).text() 				: $( '#anchorId', container ).text(); 			clipboard.val( text ).select(); 			document.execCommand( 'copy' ); 			clipboard.remove(); 		}  		function clipboardLink( aClass ) { 			return aClass ?  				`[ <a href="javascript:" class="${aClass}" title="${messages.clipboardTitle}">${messages.clipboard}</a> ]` : ''; 		}  		function makeTableRow( label, title, clipClass, buttonClass, text ) { 			return `<tr><td><span title="${title}">${label}:</span> <span class="${clipClass}">${text}</span></td><td>${clipboardLink( buttonClass )}</td></tr>`; 		}  		function makeContent( $origin ) { 			var link = $( selectors.kartographerLink, $origin ).first(); 			var lat, lon, withMarker, zoom; 			if ( link.length ) { 				lat = round( link.attr( data.lat ), 6 ); 				lon = round( link.attr( data.lon ), 6 ); 				zoom = link.attr( data.zoom ); 				withMarker = true; 			} else { 				link = $origin.closest( selectors.vcard ).find( selectors.lCoordinates ); 				lat = round( $( selectors.latitude, link ).text(), 6 ); 				lon = round( $( selectors.longitude, link ).text(), 6 ); 				zoom = 16; 				withMarker = false; 			} 			const latStr = toDMS( lat, messages.NS ); 			const lonStr = toDMS( lon, messages.EW );  			const wrapper = $origin.closest( selectors.vcard ); 			const color = wrapper.attr( data.color ); 			const lang = wrapper.attr( data.wikilang ); 			var region = wrapper.attr( data.region ); 			if ( !region ) { 				region = ''; 			}  			var name = wrapper.attr( data.name ); 			if ( !name ) { 				name = $( selectors.lName, wrapper ).first(); 				var wikiLink = $( 'a', name ).first(); 				name = ( wikiLink.length ) ? wikiLink.text() : name = name.text(); 			} 			name = encodeURI( name.replace( /\s/g, '+' ) ).replace( /&/g, '%26' );  			var params = '&params=' + 				Math.abs( lat ) + ( lat < 0 ? '_S_' : '_N_' ) + 				Math.abs( lon ) + ( lon < 0 ? '_W' : '_E' ) + 				`_scale%3A${getScaleFromZoom( zoom )}_type%3Alandmark_globe%3Aearth`; 			if ( region !== '' ) { 				params += '_region%3A' + region; 			}  			const ch1903 = toCH1903( lat, lon ), 				plusCode = toPlusCode( lat, lon ), 				latDec = shortenCoordinate( lat ), 				lonDec = shortenCoordinate( lon );  			var table = '<table>' + 				makeTableRow( messages.hex, messages.hexTitle, 'mkClip1', 'mkButton1', 					latStr + ' ' + lonStr ) + 				makeTableRow( messages.dec, messages.decTitle, 'mkClip2', 'mkButton2', 					`<a href="geo:${latDec},${lonDec}" title="${messages.geoUriTitle}">${latDec}, ${lonDec}</a>` ); 			if ( options.plusCode ) { 				table += makeTableRow( messages.plus, messages.plusTitle, 'mkClip3', 'mkButton3', 					`<span class="voy-mkTooltipPlusCode">${plusCode.substr( 0, 4 ) }</span>` + 					plusCode.substr( 4 ) ); 			} 			if ( options.ch1903 && !ch1903.error ) { 				table += makeTableRow( messages.ch1903, messages.ch1903Title, 					'mkClip4', 'mkButton4', 					`<span title="CH1903 easting">${ch1903.easting}</span> / <span title="CH1903 northing">${ch1903.northing}</span>` ); 			}  			const html = [], 				infobutton = $( selectors.lInfoButton, wrapper ).prop( 'outerHTML' ) || ''; 			if ( infobutton !== '' ) { 				html.push( `<span id="infobutton">${infobutton}</span>` ); 			} 			const editbutton = $( selectors.lEditButton, wrapper ).prop( 'outerHTML' ) || ''; 			if ( editbutton !== '' ) { 				html.push( `<span id="editbutton">${editbutton}</span>` ); 			} 			let id = wrapper.attr( 'id' ); 			id = id && id.match( classes.idRegex ); 			if ( id ) { 				var anchor = `<a href="#" id="anchorIdLink" title="${messages.anchorTitle}">${messages.anchor}</a>` + 					`<span id="anchorId" style="display: none">${id}</span>`; 				html.push( anchor ); 			} 			if ( html.length ) { 				table += makeTableRow( messages.tools, messages.toolsTitle, 'mkClip5', 					id ? 'mkButton5' : null, html.join( ' | ' ) ); 			} 			table += '</table>';  			var mapSources = `<div title="${messages.mapSourcesTitle}">${messages.mapSources}: ` + 				`<a href="${messages.voyURL + params}&locname=${name}" title="${messages.voyTitle}" target="_blank" rel="noopener">${messages.voy}</a> | ` + 				`<a href="${messages.wmflabsURL}?pagename=${name}&language=${lang + params}" title="${messages.wmflabsTitle}" target="_blank" rel="noopener">${messages.wmflabs}</a>` + 				'</div>';  			return $( '<div class="voy-mkTooltipInner"></div>' ) 				.css( 'border-left-color', color ) 				.append( $( '<div class="voy-mkTooltipHint">' + (withMarker ? messages.hint : messages.hint2 ) + '</div>' ) 					.css( { 'margin-bottom': '0.5em' } ) ) 				.append( $( table ) ) 				.append( $( mapSources ) ) 				.append( $( '<div class="voy-mkTooltipTail"></div>' ) ); 		}  		// setting tooltip position 		function setTooltipPosition( e, tooltip, $this ) { 			const tail = $( '.voy-mkTooltipTail', tooltip ); 			const winWidth = $( window ).width(); 			var left, offset, right, width; 			 			if ( e.clientY < $( window ).height() / 2 ) { 				tooltip.css( 'top', $this.innerHeight() - 4 ) 					.addClass('voy-mkBelow'); 			} else { 				tooltip.css( 'bottom', $this.innerHeight() - 4 ) 					.addClass('voy-mkAbove'); 			} 			if ( e.clientX < winWidth / 2 ) { 				tooltip.css( 'left', $this.innerWidth() / 2 - 16 ) 					.addClass('voy-mkLeft'); 				if ( isMobile ) { 					offset = tooltip.offset(); 					right = offset.left + tooltip.outerWidth(); 					if ( right > winWidth - 1 ) { 						left = offset.left - ( right - winWidth ) - 2; 						if ( left < 2 ) { 							left = 2; 						} 						width = tooltip.innerWidth(); 						tooltip.offset( { top: offset.top, left: left } ); 						tooltip.innerWidth( width ); 						width = offset.left - left; 						offset = tail.offset(); 						offset.left += width; 						tail.offset( offset ); 					} 				} 			} 			else { 				tooltip.css( 'right', $this.innerWidth() / 2 - 13 ) 					.addClass('voy-mkRight'); 				if ( isMobile ) { 					offset = tooltip.offset(); 					left = offset.left; 					if ( left < 2 ) { 						width = tooltip.innerWidth(); 						tooltip.offset( { top: offset.top, left: 2 } ); 						tooltip.innerWidth( width ); 						offset = tail.offset(); 						offset.left += left; 						tail.offset( offset ); 					} 				} 			} 		}  		function showMarkerTooltip( e ) { 			const $this = $( e.target ).closest( '.' + classes.listingTooltip ), 				id = $this.attr( data.id ), 				isCopyMarker = $this.hasClass( classes.copyMarker ), 				wrapper = $this.closest( selectors.vcard ), 				withoutMarker = wrapper.hasClass( classes.withoutMarker ), 				triggerWrapper = withoutMarker || !isCopyMarker; 			var $origin = $this; 			e.stopPropagation(); 			if ( isCopyMarker ) { 				// getting from original marker 				const attr = $this.attr( data.mAttribute ); 				const content = $this.attr( data.mContent ); 				$origin = $( `*[${attr}="${content}"]` ).first(); 			}  			const tooltip = $( `<div class="voy-mkTooltip" role="tooltip" ${data.version}="${version}"/>` ) 				.append( makeContent( $origin ) ); 			if ( isMobile ) { 				tooltip.addClass( 'voy-mkTooltipMobile' ); 			} else { 				tooltip.hide(); // later fade-in; 			} 			$this.append( tooltip ); 			setTooltipPosition( e, tooltip, $this );  			$( '.mkButton1', tooltip ) 				.click( function() { copyToClipboard( '.mkClip1', tooltip ); } ); 			$( '.mkButton2', tooltip ) 				.click( function() { copyToClipboard( '.mkClip2', tooltip ); } ); 			$( '.mkButton3', tooltip ) 				.click( function() { copyToClipboard( '.mkClip3', tooltip ); } ); 			$( '.mkButton4', tooltip ) 				.click( function() { copyToClipboard( '.mkClip4', tooltip ); } ); 			$( '.mkButton5', tooltip ) 				.click( function() { copyToClipboard( '.mkClip5', tooltip ); } ); 			$( '#anchorIdLink', tooltip ) 				.click( function() { 					var alertText = messages.anchorText + $( '#anchorId', tooltip ).text(); 					removeAllTooltips(); 					alert( alertText ); 				} ); 			$( '#infobutton', tooltip ) 				.click( function( e ) { 					e.stopImmediatePropagation(); 					$( selectors.lInfoButton, triggerWrapper ? wrapper : $origin ).trigger( 'click' ); 					removeAllTooltips(); 				} ); 			$( '#editbutton', tooltip ) 				.click( function( e ) { 					e.stopImmediatePropagation(); 					$( selectors.lEditButton, triggerWrapper ? wrapper : $origin ).trigger( 'click' ); 					removeAllTooltips(); 				} );  			if ( isMobile ) { 				// removing tooltip after 10 sec in mobile mode 				timeouts[ id ] = 					setTimeout( function() { removeTooltip( $this ); }, 10000 ); 				$( 'body' ).click( handleOutsideClick ); 			} else { 				// fading-in hidden tooltip in desktop mode 				setTimeout( function() { tooltip.fadeIn( 500 ); }, 300 ); 			}  			return; 		}  		// Click event handler if clicked outside any tooltip 		function handleOutsideClick( event ) { 			if ( !$( event.target ).closest( '.voy-mkTooltip' ).length && 				$( '.voy-mkTooltip' ).is( ':visible' ) ) { 				removeAllTooltips(); 			} 		}  		function removeTooltip( marker ) { 			const id = marker.attr( data.id ); 			if ( id ) { 				clearTimeout( timeouts[ id ] ); 			} 			$( '.voy-mkTooltip', marker ).remove(); 			$( '.voy-mkTooltipButton', marker ).text( '▼' ); 		}  		function removeAllTooltips() { 			if ( isMobile ) { 				$( 'body' ).off( 'click', handleOutsideClick ); 			} 			var markers = $( '.' + classes.listingTooltip ).add( $( 'abbr' ) ); 			markers.each( function() { 				removeTooltip( $( this ) ); 			}); 		}  		function showMobileMarker( e ) { 			const $this = $( e.target ).closest( '.voy-mkTooltipButton' ); 			const text = $this.text(); 			removeAllTooltips(); 			if ( text === '▼' ) { 				$this.text( '▲' ); 				showMarkerTooltip( e ); 			} 		}  		function initMarkerTooltip() { 			$( selectors.lMap ).addClass( classes.listingTooltip ) 				.css( { position: 'relative' } ); 			if ( isMobile ) { 				$( selectors.lMap ).addClass( classes.listingTooltipMobile ); 			}  			const markers = $( '.' + classes.listingTooltip ) 				.attr( 'title', '' ); 			var id = 0; 			// setting id for timeout handler 			markers.each( function() { 				$( this ).attr( data.id, 'tt' + id ); 				id += 1; 			} ); 				 			if ( isMobile ) { 				const mobileMarker = $( '<span class="voy-mkTooltipButton">▼</span>' ) 					.click( function( e ) {  						showMobileMarker( e ); 					}); 				markers.append( mobileMarker ); 			} else { 				markers.mouseenter( function( e ) { 					showMarkerTooltip( e ); 				}) 				.mouseleave( function( e ) { 					$( '.voy-mkTooltip' ).remove(); 				}); 			} 		}  		function initAbbrTooltip() { 			const abbr = $( 'abbr' ) 				.css( { 'position': 'relative', 'cursor': 'pointer' } );  			var id = 0; 			// setting id for timeout handler 			abbr.each( function() { 				$( this ).attr( data.id, 'at' + id ); 				id += 1; 			} );  			abbr.click( function( e ) { 				e.stopPropagation(); 				const $this = $( e.target ).closest( 'abbr' ); 				const id = $this.attr( data.id ); 				var tooltip = $( '.voy-mkTooltip', $this ); 				removeAllTooltips(); 				if ( tooltip.length === 0 ) { 					const title = $this.attr( 'title' ); 					if ( title ) { 						const div = $( `<div class="voy-mkTooltipInner voy-mkTooltipMaxWidth">${title}</div>` ) 							.append( $( '<div class="voy-mkTooltipTail"></div>' ) ); 						tooltip = $( '<div class="voy-mkTooltip voy-mkTooltipMobile" role="tooltip"></div>' ) 							.append( div ); 						$this.append( tooltip ); 						setTooltipPosition( e, tooltip, $this ); 						timeouts[ id ] = 							setTimeout( function() { removeTooltip( $this ); }, 10000 ); 						$( 'body' ).click( handleOutsideClick ); 					} 				} 			} ); 		}  		function init() { 			setupMessages(); 			initMarkerTooltip(); 			if ( isMobile ) { 				initAbbrTooltip(); 			} 		}  		return { init: init }; 	} (); 	 	$( mkTooltip.init );  } ( jQuery ) );  //</nowiki>