MediaWiki:Carte personnalisée.js

De Guild Wars 2 Wiki
Aller à la navigation Aller à la recherche

Note : après avoir publié vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.

  • Firefox / Safari : maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou appuyez sur Ctrl + F5 ou Ctrl + R (⌘ + R sur un Mac).
  • Google Chrome : appuyez sur Ctrl + Maj + R (⌘ + Shift + R sur un Mac).
  • Internet Explorer / Edge : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl + F5.
  • Opera : appuyez sur Ctrl + F5.
class CartePersonnalisee {
	constructor (requestTerms, iconeURL, hauteur, largeur, zoom, cible, indice, continent, course, succes, lien) {
		this.iconeURL = 'https://wiki-fr.guildwars2.com/wiki/Special:Filepath/'+iconeURL;
		this.customIcon = true;
		if(iconeURL === null){
			this.iconeURL = "https://wiki-fr.guildwars2.com/images/3/37/Icône_succès.png";
			this.customIcon = false;
		}
		this.defaultIcone = L.icon({
			iconUrl: this.iconeURL,
			iconSize: [25, 25], iconAnchor: [10, 10], popupAnchor: [2.5, -10]
		});
		

		this.map = L.map('MapDisplay'+indice, {
						noWrap: true,
						crs : L.CRS.Simple,
						continuousWorld: true,
						infinite: false,
						maxBoundsViscosity: 1.0
					});
					
		this.whitelist = ["Précipice perdu","Caverne dorée","Vallée des esprits","Passage de la rédemption","Forteresse des Fidèles","Bastion du pénitent"];
		this.mapslist = {};
		this.callback = null;
		this.isMapsDataReady = false;
		this.isFractalsReady = false;
		this.isMarkersDataReady = false;
		this.isAchievementsDataReady = !succes;
		this.markersdata = {};
		this.debug = false;
		this.waypointsDone = [];
		this.textureDim = [];
		this.zonesArray = [];
		this.imagesArr = new Array();
		this.requestTerms = requestTerms;
		this.hauteur = hauteur;
		this.largeur = largeur;
		this.zoom = zoom;
		this.cible = cible;
		this.indice = indice;	
		this.lien = lien;	
		this.continent = continent != null ? parseInt(continent) : null;	
		this.course = course !== null ? course.toLowerCase() : null;
		this.raceIcons = {	"montures":{start:"https://wiki-fr.guildwars2.com/wiki/Special:Filepath/"+"Événement dynamique - dialogue.png",
										checkpoint:"https://wiki-fr.guildwars2.com/wiki/Special:Filepath/"+"Icône course - point de passage.png",
										end:"https://wiki-fr.guildwars2.com/wiki/Special:Filepath/"+"Icône course - ligne d'arrivée.png"
									},
					"guilde":{start:"https://wiki-fr.guildwars2.com/wiki/Special:Filepath/"+"Icône course de guilde.png",
										checkpoint:"https://wiki-fr.guildwars2.com/wiki/Special:Filepath/"+"Icône course de guilde - point de passage.png",
										end:"https://wiki-fr.guildwars2.com/wiki/Special:Filepath/"+"Icône course de guilde - ligne d'arrivée.png"
									}
				}
		this.fractals = {};
		this.succes = succes;
	}	

	getFractalsNames() {
		let obj = this;
		$.getJSON("https://api.guildwars2.com/v2/continents/2/floors?ids=all&lang=fr").done(function (data) {
			for(let i in data){
				for(let region in data[i].regions){
					if(data[i].regions[region].name === "Fractales des Brumes"){
						for(let map in data[i].regions[region].maps){
							let sector = Object.keys(data[i].regions[region].maps[map].sectors)[0];
							obj.fractals[map] = data[i].regions[region].maps[map].sectors[sector].name;
						}
					}
				}
			}
			if(obj.debug){console.log('Données des fractales chargées');}
			obj.getMapsDataFromAPI()
		}).fail(function() {console.log("Les données de cartes n'ont pas pu être chargées depuis l'API.");});
	}

	getMapsDataFromAPI() {
		let obj = this;
		$.getJSON("https://api.guildwars2.com/v2/maps?ids=all&lang=fr").done(function (data) {
			for(let map in data) {
				if(obj.continent === 2 && data[map].name === "Fractales des Brumes"){
					obj.mapslist[obj.fractals[data[map].id]] = {	id : data[map].id, rect : data[map].continent_rect, continent_id : data[map].continent_id, default_floor : data[map].default_floor }
				} else {
					if((((data[map].type === "Public" || data[map].continent_id === 2) && data[map].name !== "Super Adventure Box") || obj.whitelist.indexOf(data[map].name) > 0) && (!(data[map].name in obj.mapslist) || (data[map].default_floor == 1 && obj.mapslist[data[map].name].default_floor != 1))){
						let tmpName = data[map].name;
						if(data[map].continent_id === 2 && (data[map].type === "GreenHome" ||data[map].type === "BlueHome" || data[map].type === "RedHome")) {
							tmpName = data[map].name.substr(3);
							if(tmpName === "Territoires alpins" && data[map].type === "GreenHome") {
								tmpName += " (vert)"
							} else if(tmpName === "Territoires alpins" && data[map].type === "BlueHome") {
								tmpName += " (bleu)"
							}
						}
						obj.mapslist[tmpName] = {id : data[map].id, rect : data[map].continent_rect, continent_id : data[map].continent_id, default_floor : data[map].default_floor}
						
					}	
				}
			}
			obj.isMapsDataReady = true;
			if(obj.debug){console.log('Données des cartes chargées');}
			if (obj.callback !== null && obj.isMarkersDataReady && obj.isAchievementsDataReady) {
				obj.callback();
			}
		}).fail(function() {console.log("Les données de cartes n'ont pas pu être chargées depuis l'API.");});
	};

	preLoadImages(img) {
		let image = new Image()
		image.src = img;
		this.imagesArr.push(image);
	};

	getMarkersDataFromWiki() {
		let obj = this;
		mw.loader.using( 'mediawiki.api', function () {
			(new mw.Api()).get({action: 'ask',query: obj.requestTerms+'|?Zone|?Coordonnée-X|?Coordonnée-Y|?Nom|?Nom de la page|?Icône|?Permanent|limit=500',format: 'json'}).done(function(data){
				for (let i in data.query.results) {
					let results = {};
					let k = 0;
					for (let j in data.query.results[i].printouts) {
						results[k] = data.query.results[i].printouts[j];					
						k++;
					}
					if(typeof results[3] !== "undefined"){
						if(typeof obj.markersdata[results[3]] === "undefined")
							obj.markersdata[results[3]] = {};
						obj.markersdata[results[3]].nom = results[3];
						if(typeof results[4][0] !== "undefined"){
							obj.markersdata[results[3]].nomPage = results[4][0].fulltext;
						}
						if(typeof results[5][0] !== "undefined"){
							let iconeurl = 'https://wiki-fr.guildwars2.com/wiki/Special:Filepath/'+results[5][0].fullurl.substring(results[5][0].fullurl.lastIndexOf(":")+1,results[5][0].fullurl.length);
							obj.markersdata[results[3]].icone = iconeurl;
							obj.preLoadImages(iconeurl);
						}
						
						if(typeof obj.markersdata[results[3]].location === "undefined")
							obj.markersdata[results[3]].location = [];
						
						if(typeof results[0][0] !== "undefined" && typeof results[1][0] !== "undefined" && typeof results[2][0] !== "undefined"){
							if(typeof results[6][0] !== "undefined" && results[6][0] === "f") {
								obj.markersdata[results[3]].location.push({	zone: results[0][0].fulltext,
																		x: parseInt(results[1][0]),
																		y: parseInt(results[2][0]),
																		permanent: false
								});
							} else {
								obj.markersdata[results[3]].location.push({	zone: results[0][0].fulltext,
																		x: parseInt(results[1][0]),
																		y: parseInt(results[2][0])
								});
							}
						}
					}
				}
				
				let countobj = 0;
				for(let marker in obj.markersdata){
					let length = Object.keys(obj.markersdata).length;
					if(obj.markersdata[marker].location.length === 0 || (obj.course != null && typeof obj.markersdata[marker].location.position === "undefined")){
						obj.markersdata[marker].location = [];
						mw.loader.using( 'mediawiki.api', function () {
							(new mw.Api()).get({action: 'ask',query: '[[-Possède un sous-objet::+]][[Nom de la page::'+obj.markersdata[marker].nomPage+']][[Type::Élément explorable]]|?Zone|?Coordonnée-X|?Coordonnée-Y|?Nom|?Position|limit=500',format: 'json'}).done(function(data){
								for (let i in data.query.results) {
									let results = {};
									let k = 0;
									for (let j in data.query.results[i].printouts) {
										results[k] = data.query.results[i].printouts[j];					
										k++;
									}
									if(typeof results[0][0] !== "undefined" && typeof results[1][0] !== "undefined" && typeof results[2][0] !== "undefined"){
										if(results[3] in obj.markersdata)
											obj.markersdata[results[3]].location.push({	zone: results[0][0].fulltext,
																						x: parseInt(results[1][0]),
																						y: parseInt(results[2][0]),
																						position: results[4][0]
											});								
									}
								}
								countobj++;
								if(countobj === length){
									obj.isMarkersDataReady = true;
								}
								if (obj.callback !== null && obj.isMapsDataReady && obj.isMarkersDataReady) {
									obj.callback();
								}
							});
						});				
					}else{
						countobj++;
						if(countobj === length){
							obj.isMarkersDataReady = true;
						}
						if (obj.callback !== null && obj.isMapsDataReady && obj.isMarkersDataReady && obj.isAchievementsDataReady) {
							obj.callback();
						}
					}
				}	
				if(obj.succes) 
					obj.getAchievementsDataFromWiki();
			});
		});
	};

	getAchievementsDataFromWiki() {	
		let obj = this;
		let re = /\[{2}([^\].]+)::([^\[.]+)\]{2}/gi;
		let reqItems = {};
		let reResults;
		while ((reResults = re.exec(this.requestTerms)) !== null) {
			reqItems[reResults[1]] = reResults[2];
		}
		let requete = "";
		if(typeof reqItems["Page de succès"] !== "undefined") requete += "[[A pour collection::"+reqItems["Page de succès"]+"]]";
		if(typeof reqItems["Nom"] !== "undefined") requete += "[[Nom::"+reqItems["Nom"]+"]]";
		mw.loader.using( 'mediawiki.api', function () {
			(new mw.Api()).get({action: 'ask',query: requete+'|?Nom|?Icône|?Nom de la page|limit=500',format: 'json'}).done(function(data){
				for (let i in data.query.results) {
					let results = {};
					results["Nom"] = data.query.results[i].printouts["Nom"];
					results["Icône"] = data.query.results[i].printouts["Icône"][0].fullurl;
					results["Nom de la page"] = data.query.results[i].printouts["Nom de la page"][0].fulltext;
				
					if(typeof obj.markersdata[results["Nom"]] !== "undefined"){
						if(typeof results["Nom"] !== "undefined"){
							obj.markersdata[results["Nom"]].nomPage = results["Nom de la page"];
						}
						if(typeof results["Icône"] !== "undefined"){
							let iconeurl = 'https://wiki-fr.guildwars2.com/wiki/Special:Filepath/'+results["Icône"].substring(results["Icône"].lastIndexOf(":")+1,results["Icône"].length);
							obj.preLoadImages(iconeurl);
							obj.markersdata[results["Nom"]].icone = iconeurl;
						}
					}
				}
				
				obj.isAchievementsDataReady = true;
				if(obj.debug){console.log('Données des cartes chargées');}
				if (obj.callback !== null && obj.isMarkersDataReady && obj.isMapsDataReady) {
					obj.callback();
				}
			});	
		});
	};

	loadMapSettings(ratio, rect, maxsize, minZoom, maxZoom, layerURL) {
		let factor = 2;
		
		let width = (rect[1][0] - rect[0][0]) / factor;
		let height = (rect[1][1] - rect[0][1]) / factor;
		if(this.largeur === null && this.hauteur === null){		
			while (width > maxsize) {
				factor *= ratio;

				if((rect[1][0] - rect[0][0]) / factor < 200){break;}
				
				width = (rect[1][0] - rect[0][0]) / factor;
				height = (rect[1][1] - rect[0][1]) / factor;
			}
		} else {	
			while (width > this.largeur && height > this.hauteur) {
				factor *= ratio;

				if((rect[1][0] - rect[0][0]) / factor < 200){break;}
				
				width = (rect[1][0] - rect[0][0]) / factor;
				height = (rect[1][1] - rect[0][1]) / factor;
			}
		}
			
		let mapdisplay = document.getElementById('MapDisplay'+this.indice);
		mapdisplay.style.width = width + 'px';
		mapdisplay.style.height = height + 'px';
		
		let mapCenter = [(rect[0][0]+rect[1][0])/2,(rect[0][1]+rect[1][1])/2];
		if(rect[1][0]-rect[0][0] > 40000){
			mapCenter = [16384,16384];
		}
		
		let southWest = this.map.unproject([rect[0][0], rect[1][1]], maxZoom);
		let northEast = this.map.unproject([rect[1][0], rect[0][1]], maxZoom);
		let bounds = new L.LatLngBounds(southWest, northEast);
					
		this.map.fitBounds(bounds);
		if(!this.succes){
			this.map.setMaxBounds(bounds);
		}
		this.map.setMinZoom(minZoom);
		this.map.setMaxZoom(maxZoom);
		this.map.invalidateSize(false);
		let displayZoom = minZoom;
		if(this.zoom !== null){displayZoom = this.zoom;}
		
		this.map.setView(this.map.unproject(mapCenter, maxZoom), displayZoom);
		if(layerURL !== null){
			this.map.tileLayer = L.tileLayer(layerURL, {
				minZoom : minZoom,
				maxZoom: maxZoom,
				noWrap: true,
				crs : L.CRS.Simple,
				continuousWorld: true,
				infinite: false,
				errorTileUrl: "https://wiki-fr.guildwars2.com/images/1/1e/No-tile.jpg"
			});
			let obj = this;
			L.TileLayer.include({
				getTileUrl: function(coords) {						
					if(this._url.substr(29,1) != 2)
						return 'https://wiki.guildwars2.com/wiki/Special:Filepath/World_map_tile_C1_F1_Z'+(coords.z+1)+'_X'+coords.x+'_Y'+coords.y+'.jpg'
					else {
						let tmp = this._url;
						
						let data = {
							s: this._getSubdomain(coords),
							x: coords.x,
							y: coords.y,
							z: this._getZoomForUrl()
						};					
						let templateRe = /\{ *([\w_-]+) *\}/g;
						return tmp.replace(templateRe, function (str, key) {
							let value = data[key];

							if (value === undefined) {
								throw new Error('No value provided for letiable ' + str);

							} else if (typeof value === 'function') {
								value = value(data);
							}
							return value;
						});
					}
				}
			});
			this.map.tileLayer.addTo(this.map);
		}
	};

	addDataOnMap(continent, zones) {	
		if(this.zonesArray.length > 0){		
			let minZoom = Math.max(1, this.zoom);
			let maxZoom = continent != 2 ? 7 : 6;			
			
			let layerURL = null;
			if(this.zonesArray.length === 1){
				layerURL = 'https://tiles.guildwars2.com/'+continent+'/'+this.mapslist[this.zonesArray[0]].default_floor+'/{z}/{x}/{y}.jpg';
				if (this.mapslist[this.zonesArray[0]].continent_id === 2) {
					this.loadMapSettings(2, this.mapslist[this.zonesArray[0]].rect, 800, minZoom, maxZoom, layerURL);
				} else {
					this.loadMapSettings(2, this.mapslist[this.zonesArray[0]].rect, 800, minZoom, maxZoom, layerURL);
				}							
			} else if(this.zonesArray.length > 1){
				layerURL = 'https://tiles.guildwars2.com/'+continent+'/1/{z}/{x}/{y}.jpg';	
			} else {
				return;
			}
		

			let waypoints = L.layerGroup();
			let obj = this;
			$.getJSON("https://api.guildwars2.com/v2/continents/"+continent+"/floors?ids=all&lang=fr").done(function (data) {
				let wpicon = L.icon({
					iconUrl: 'https://wiki-fr.guildwars2.com/images/b/b1/Ic%C3%B4ne_point_de_passage.png',
					iconSize: [25, 25], iconAnchor: [10, 10], popupAnchor: [2.5, -10]
				});
				obj.textureDim = [[0,0],data[0].texture_dims];
				for(let floor in data) {
					for(let region in data[floor].regions) {
						for(let carte in data[floor].regions[region].maps) {
							if(data[floor].regions[region].maps[carte].name !== "Super Adventure Box" && zones.includes(data[floor].regions[region].maps[carte].name)){
								for(let i in data[floor].regions[region].maps[carte].points_of_interest){
									if(data[floor].regions[region].maps[carte].points_of_interest[i].type === "waypoint" && !(obj.waypointsDone.includes(data[floor].regions[region].maps[carte].points_of_interest[i].id))){
										let marker = L.marker(obj.unproject(obj.map, L.point(data[floor].regions[region].maps[carte].points_of_interest[i].coord[0], data[floor].regions[region].maps[carte].points_of_interest[i].coord[1])), {
											title : data[floor].regions[region].maps[carte].points_of_interest[i].name,
											icon : wpicon,
											zIndexOffset : 200,
											riseOnHover : true,
											riseOffset : 1050
										});
										let html = '<p><b><a href="https://wiki-fr.guildwars2.com/wiki/'+data[floor].regions[region].maps[carte].points_of_interest[i].name+'">'+data[floor].regions[region].maps[carte].points_of_interest[i].name+'</a></b><br>(Point de passage&nbsp;:&nbsp;<input readonly class="carteChatLink" style="width:74px;display:hidden-block;font-size:8pt;background-color:transparent;border: 0px solid;" value="'+data[floor].regions[region].maps[carte].points_of_interest[i].chat_link+'" onClick="this.setSelectionRange(0, this.value.length)">)</p>';
										
										marker.bindPopup(html, {closeButton: false, offset: marker.options.icon.options.popupAnchor});
										waypoints.addLayer(marker)
										obj.waypointsDone.push(data[floor].regions[region].maps[carte].points_of_interest[i].id);
									}
								}
							}
						}
					}	
				}
				
				if(obj.zonesArray.length > 1){
					let rect = obj.textureDim;
					obj.loadMapSettings(2, rect, 1200, minZoom, maxZoom, layerURL);
				}
				
				if(obj.map.getZoom() >= 5)
					waypoints.addTo(obj.map);
				obj.addMarkersOnMap(continent);	
			}).fail(function() {console.log("Les données des points de passages n'ont pas pu être chargées depuis l'API.");});
			
			obj.map.on('zoomend', function(event) {
				if(obj.map.getZoom() >= 5){
					waypoints.addTo(obj.map);
				}else{
					obj.map.removeLayer(waypoints);
				}
			});
		} else {
			return;
		}
	};

	addMarkersOnMap(continent) {				
		let markerId = 0;
		if(this.course !== null){
			var polylineCoords = [];
		}
		
		for(let i in this.markersdata) {
			for(let j in this.markersdata[i].location) {
				if(this.mapslist[this.markersdata[i].location[j].zone].continent_id === continent){
					if(!isNaN(this.markersdata[i].location[j].x)&&!isNaN(this.markersdata[i].location[j].y)){
						let marker = null;
						let tmpIcon = null;
						let html = '<div style="text-align: center;"><span style="display:inline-block; max-width:200px; vertical-align:middle;"><b>'+ this.markersdata[i].nom +'</b></span><div>';
						if(this.course === null){
							if(typeof this.markersdata[i].icone !== "undefined" && !this.customIcon){
								tmpIcon = L.icon({
									iconUrl: this.markersdata[i].icone,
									iconSize: [25, 25], iconAnchor: [10, 10], popupAnchor: [2.5, -10],
									className: "custom-marker-icon"
								});
							} else {
								tmpIcon = this.defaultIcone;
							}						
							let iconHtml = "";
							if(typeof this.markersdata[i].icone !== 'undefined')
								iconHtml += '<span style="display:inline-block; margin-right:5px; width:32px; height:32px; vertical-align:middle;"><img class="'+this.indice+'_desc_'+ this.markersdata[i].nom[0].replace(/\s+/g, '_').replace(/[',]/g, '').toLowerCase() +'" src="'+ tmpIcon.options.iconUrl +'"></span>';
							let descHtml = "";
							if(typeof this.markersdata[i].location[j].permanent !== 'undefined') {
								descHtml = '</br><span>(Emplacement non permanent)</span>';
							}
							if(typeof this.markersdata[i].nomPage !== 'undefined' && this.markersdata[i].nomPage.match(/\//gi) === null && this.lien == 'oui') {
								html = '<div><a href="https://wiki-fr.guildwars2.com/wiki/'+ this.markersdata[i].nomPage +'">'+iconHtml+'<span style="display:inline-block; max-width:200px; vertical-align:middle;"><b>'+ this.markersdata[i].nom +'</b></span></a>'+descHtml+'<div>';
							} else {
								html = '<div>'+iconHtml+'<span style="display:inline-block; max-width:200px; vertical-align:middle;"><b>'+ this.markersdata[i].nom +'</b></span>'+descHtml+'<div>';
							}
						} else {
							polylineCoords[this.markersdata[i].location[j].position - 1] = (this.unproject(this.map, L.point(this.mapslist[this.markersdata[i].location[j].zone].rect[0][0]+this.markersdata[i].location[j].x, this.mapslist[this.markersdata[i].location[j].zone].rect[0][1]+this.markersdata[i].location[j].y)));
							if(this.course in this.raceIcons){
								let tmpUrl = this.raceIcons[this.course]["checkpoint"];
								html = '<div style="text-align: center;"><span style="display:inline-block; max-width:200px; vertical-align:middle;"><b>Étape</b></span><div>';
								if(this.markersdata[i].location[j].position === 1){//ligne de départ
									tmpUrl = this.raceIcons[this.course]["start"];
									html = '<div><span style="display:inline-block; max-width:200px; vertical-align:middle;"><b>Ligne de départ</b></span><div>';
								} else if(this.markersdata[i].location[j].position === this.markersdata[i].location.length){//ligne d'arrivée
									tmpUrl = this.raceIcons[this.course]["end"];
									html = "<div><span style='display:inline-block; max-width:200px; vertical-align:middle;'><b>Ligne d'arrivée</b></span><div>";
								}
								tmpIcon = L.icon({
									iconUrl: tmpUrl,
									iconSize: [25, 25], iconAnchor: [10, 10], popupAnchor: [2.5, -10]
								});
							} else {
								html = '<div><span style="display:inline-block; max-width:200px; vertical-align:middle;"><b>Étape</b></span><div>';
								if(this.markersdata[i].location[j].position === 1){//ligne de départ
									html = '<div style="text-align: center;"><span style="display:inline-block; max-width:200px; vertical-align:middle;"><b>Ligne de départ</b></span><div>';
								} else if(this.markersdata[i].location[j].position === this.markersdata[i].location.length){//ligne d'arrivée
									html = "<div style='text-align: center;'><span style='display:inline-block; max-width:200px; vertical-align:middle;'><b>Ligne d'arrivée</b></span><div>";
								}
								tmpIcon = L.icon({
									iconUrl: this.raceIcons["montures"]["checkpoint"],
									iconSize: [25, 25], iconAnchor: [10, 10], popupAnchor: [2.5, -10]
								});
							}
						}
													
						marker = L.marker(this.unproject(this.map, L.point(this.mapslist[this.markersdata[i].location[j].zone].rect[0][0]+this.markersdata[i].location[j].x, this.mapslist[this.markersdata[i].location[j].zone].rect[0][1]+this.markersdata[i].location[j].y)), {
							title : this.markersdata[i].nom,
							icon : tmpIcon,
							zIndexOffset : 200,
							riseOnHover : true,
							riseOffset : 1050
						});
						
						marker.bindPopup(html, {closeButton: false});
						marker.addTo(this.map);
												
						let test = this.markersdata[i].nom[0].replace(/\s+/g, '_').replace(/[',]/g, '').toLowerCase();
						marker._icon.id = this.indice+"_marker_"+markerId;
						markerId++;
											
						if($("img#"+marker._icon.id).length > 0){	
						this.getImageSize($("img#"+marker._icon.id), function(width, height, el) {
								if(width === 256 && height === 256){
									el[0].style.width = "50px";
									el[0].style.height = "50px";
									el[0].style.position = "absolute";
									el[0].style.top = "-10px";
									el[0].style.left = "-10px";
									el[0].style.clipPath = "polygon(25% 25%, 75% 25%, 75% 75%, 25% 75%)";
									el[0].style.backgroundColor = "";
								}
							});
						}
								
						function initIconDesc(id, indice){
							let obj = $("img."+indice+"_desc_"+id);
							if(obj.length > 0) {
								for(let o in obj){
									if(typeof obj[o] != "undefined"){
										let width = obj[o].width;
										let height = obj[o].height;
										if(width === 256 && height === 256){								
											obj[o].width = 64;
											obj[o].height = 64;
											obj[o].style.position = "absolute";
											obj[o].style.top = "-10px";
											obj[o].style.left = "-10px";
										} else {
											obj[o].width = 32;
											obj[o].height = 32;
										}
									}
								}
							}
						}
						
						marker.on("popupopen", L.bind(initIconDesc, null, test, this.indice));
					}
				}
			}
		}
		
		if(this.course !== null){
			let line = L.polyline(polylineCoords,
						{color: 'orange', weight: 4, opacity: 1, dashArray: '0,8',}
			).addTo(this.map);	
		}
	};

	getImageSize(img, callback) {
		let $img = $(img);

		let wait = setInterval(function() {
			let w = $img[0].naturalWidth,
				h = $img[0].naturalHeight;
			if (w && h) {
				clearInterval(wait);
				callback.apply(this, [w, h, $img]);
			}
		}, 30);
	};

	unproject(map, coord) {
		return this.map.unproject(coord, map.getMaxZoom());
	};

	run() {
		if(!this.isMapsDataReady || !this.isMarkersDataReady || !this.isAchievementsDataReady){
			this.callback = function () {this.run();}
			return;
		}
		
		for (let i in this.markersdata){
			for (let j in this.markersdata[i].location){
				if(this.zonesArray.indexOf(this.markersdata[i].location[j].zone) < 0 && typeof this.mapslist[this.markersdata[i].location[j].zone] !== "undefined" && (this.mapslist[this.markersdata[i].location[j].zone].continent_id === this.continent || this.continent === null)){
					this.zonesArray.push(this.markersdata[i].location[j].zone);
				}
			}
		}	
		if(this.zonesArray.length > 0){
			let continentId = this.continent === null ? this.mapslist[this.zonesArray[0]].continent_id : this.continent;
			this.addDataOnMap(continentId, this.zonesArray);
		}
	};
}