सूचना: सम्पादनहरू प्रकाशित गरेपछि, परिवर्तनहरू हेर्नको लागि तपाईंले आफ्नो ब्राउजरको क्यासलाई बाइपास गर्नुपर्छ। गुगल क्रोम, फायरफक्स, माइक्रोसफ्ट एजसफारी: Shift कुञ्जी थिचिराखेर रिलोड उपकरणपट्टी बटनमा थिच्नुहोस्।
// See also: https://github.com/wikimedia/mediawiki-extensions-Kartographer/blob/master/modules/maplink/maplink.js
// Partly based on [[meta:MediaWiki:Wikiminiatlas.js]]
( function ( $, mw ) {
	var geohacklinks = [],
		routerInited = false,
		geohackUrl = '//tools.wmflabs.org/geohack/';

	if( !window.wma_settings ) {
		window.wma_settings = {};
	}
	// Try to disable wikiminiatlas
	window.wma_settings.enabled = false;

	function setupKartographer($content) {
		var geolinks = document.querySelectorAll('[href^="' + geohackUrl + '"]' );
		
		if( !geolinks.length) {
			return;
		}
		mw.loader.using( [
			'mediawiki.router',
			'ext.kartographer.linkbox',
			'ext.kartographer.style'
		] ).then( function( require ) {
			var router = require( 'mediawiki.router' );
			var kartolink = require( 'ext.kartographer.linkbox' );
			var uri, title, coord_params, coord_digits, lat, lon, globe, link,
				geohack, zoomlevel, marker, marker_symbol;
				
			var geohack_link_filter = /&params=([\d.+-]+)_([\d.+-]*)_?([\d.+-]*)_?([NSZ])_([\d.+-]+)_([\d.+-]*)_?([\d.+-]*)_?([EOW])([^&=<>|]{0,250})/;
			var globeRegExp = /_globe:([^_&]+)/;
			var typeRegExp = /_type:(country|satellite|state|adm1st|adm2nd|adm3rd|city|isle|river|waterbody|event|glacier|mountain|airport|edu|pass|landmark|railwaystation)/;
			var dimRegExp = /_dim:([\d.+-]+)(km|m|_|$)/;
			var scaleRegExp = /_scale:(\d+)(_|$)/;
 
			Array.prototype.forEach.call(geolinks, function (elem, index) {
				if ( !('href' in elem) || !geohack_link_filter.exec(elem.href)) {
					return;
				}
				coord_params = [];
				lat = lon = 0;
				globe = 'Earth';
				zoomlevel = 12;
				marker_symbol = 'marker';
				
				// Convert DMS to DD if needed
				lat = (1.0*RegExp.$1) + ((RegExp.$2||0)/60.0) + ((RegExp.$3||0)/3600.0);
				if (RegExp.$4!=='N') {
					lat *= -1;
				}
				lon = (1.0*RegExp.$5) + ((RegExp.$6||0)/60.0) + ((RegExp.$7||0)/3600.0);
				if (RegExp.$8==='W') {
					lon *= -1;
				}
				coord_params = RegExp.$9;
				
				// Zoom based on coordinate N/S precision
				coord_digits = RegExp.$3 ? 4 : RegExp.$2 ? 2 : RegExp.$1.length - (RegExp.$1+'.').indexOf('.') - 1;
				zoomlevel = coord_digits * Math.log(10)/Math.log(2);
				
				// Zoom level based on type, and retrieving markers symbols for those types
				if( typeRegExp.exec( coord_params ) ) {
					type = RegExp.$1;
					switch( type ) {
						case 'country':
						case 'satellite':
							zoomlevel = 5;
							break;
						case 'state':
							zoomlevel = 7;
							break;
						case 'adm1st':
							zoomlevel = 9;
							break;
						case 'adm2nd':
							zoomlevel = 11;
							break;
						case 'adm3rd':
						case 'city':
							zoomlevel = 12;
							marker_symbol = 'city';
							break;
						case 'isle':
						case 'river':
						case 'waterbody':
							zoomlevel = 12;
							break;
						case 'event':
						case 'glacier':
						case 'mountain':
							zoomlevel = 13;
							break;
						case 'airport':
							zoomlevel = 14;
							marker_symbol = 'airport';
							break;
						case 'railwaystation':
							marker_symbol = 'rail';
							break;
						case 'camera edu':
						case 'pass':
						case 'landmark':
							zoomlevel = 15;
							break;
						default:
					}
				}
				
				// wma shows dim approx 4e7m at zoom 0 or 1.5e8 is the scale of zoomlevel 0
				if (dimRegExp.exec(coord_params)) {
					zoomlevel = Math.log((RegExp.$2==='km' ? 4e4 : 4e7) / RegExp.$1)/Math.log(2);
				}
				if (scaleRegExp.exec(coord_params)) {
					zoomlevel = Math.log(1.5e8/RegExp.$1) / Math.log(2);
				}
				
				if (zoomlevel<0) { zoomlevel = 0; }
				
				// Check which globe
				if (globeRegExp.test(coord_params)) {
					globe = RegExp.$1;
					// All possible globes: ['Earth','Moon','Mars','Venus','Mercury','Io','Titan']
					// But we only handle Earth right now
					if( globe.toLowerCase() !== 'earth' ) {
						return;
					}
				}

				// Retrieve the pagename from the uri if possible
				uri = new mw.Uri( elem.href );
				title = uri.query.pagename;
				if(title) {
					title = title.replace(/_/g,' ');
				}
				marker = {
					"type": "Feature",
					"geometry": {
						"type": "Point",
						"coordinates": [lon, lat]
					},
					"properties": {
						"name": title,
						"marker-color": "#3366cc",
						"marker-symbol": marker_symbol,
						"marker-size": "medium"
					}
				};
				
				link = geohacklinks[ index ] = kartolink.link( {
					featureType: 'maplink',
					container: elem,
					center: [ lat, lon ],
					zoom: zoomlevel,
					data: [marker],
					captionText: title,
					fullScreenRoute: '/geohacklink/' + index
				} );
				$(elem).addClass('mw-kartographer-maplink').parent().removeClass('plainlinks');
			});
			
			if ( routerInited ) {
				return;
			}
			// execute this piece of code only once
			routerInited = true;
			
			// Opens a maplink in full screen. #/geohacklink(/:zoom)(/:latitude)(/:longitude)
			// Examples:
			//     #/geohacklink/0
			//     #/geohacklink/0/5
			//     #/geohacklink/0/16/-122.4006/37.7873
			router.route( /geohacklink\/([0-9]+)(?:\/([0-9]+))?(?:\/([+-]?\d+\.?\d{0,5})?\/([+-]?\d+\.?\d{0,5})?)?/, function ( maptagId, zoom, latitude, longitude ) {
				var link = geohacklinks[ maptagId ],
					position;
	
				if ( !link ) {
					router.navigate( '' );
					return;
				}
	
				if ( zoom !== undefined && latitude !== undefined && longitude !== undefined ) {
					position = {
						center: [ +latitude, +longitude ],
						zoom: +zoom
					};
				}
	
				// // We need this hack to differentiate these events from `open` events.
				// if ( !link.fullScreenMap && !link.clicked ) {
				// 	mw.track( 'mediawiki.kartographer', {
				// 		action: 'hashopen',
				// 		isFullScreen: true,
				// 		feature: link
				// 	} );
				// 	link.clicked = false;
				// }
				link.openFullScreen( position );
			} );
	
			// Check if we need to open a map in full screen.
			router.checkRoute();
		});
		
		if( $( '#coordinates' ).length && mw.config.get('skin') === 'minerva' ) {
			mw.loader.using( [
				'mediawiki.util',
				'oojs-ui.styles.icons-location'
			] ).then( function() {
				var mapLink = $( '<a>' ).text( 'Show on map' );
				mw.util.addCSS(
					'#page-actions .mw-show-on-map {' +
					'	opacity: 0.6;' +
					'	float: left;' +
					'	margin-left: -1em;' +
					'}'
				);
				var mapButton = $('.language-selector').clone()
					.removeClass( 'language-selector mw-ui-icon-language-switcher' )
					.addClass( 'mw-show-on-map mw-ui-icon-map' )
					.attr( {
						title: 'Show on map',
						role: 'button'
					} )
					.empty()
					.append( mapLink )
					.click( openTitleCoord );
				$( '.language-selector' ).parent().append( mapButton );
			} );
		}
	}
	
	var openTitleCoord = function() {
		$( '#coordinates .mw-kartographer-link' ).get( 0 ).click();
	};
	
	mw.hook( 'wikipage.content' ).add( setupKartographer );

	return geohacklinks;
}(
	jQuery,
	mediaWiki
));