PageSourceSearch

https://www.ayuntamiento-losmolinos.es/wp-content/plugins/wp-gpx-maps/js/WP-GPX-Maps.js?ver=1.6.02

js ayuntamiento-losmolinos.es collected 2026-10-02 12:11:24 UTC 45,201 bytes, 1,534 lines download raw bytes

1/*
2Plugin Name: WP-GPX-Maps
3Plugin URI: http://www.devfarm.it/
4Description: Draws a gpx track with altitude graph
5Version: 1.6.02
6Author: Bastianon Massimo
7Author URI: http://www.devfarm.it/
8*/
9
10
11let wpgpxmaps_FEET_MILES = "1";
12let wpgpxmaps_METERS_KILOMETERS = "2";
13let wpgpxmaps_METERS_NAUTICALMILES = "3";
14let wpgpxmaps_METER_MILES = "4";
15let wpgpxmaps_FEET_NAUTICALMILES = "5";
16let wpgpxmaps_MINUTES_PER_100METERS = "6";
17let wpgpxmaps_KNOTS = "5";
18let wpgpxmaps_MINUTES_PER_MILES = "4";
19let wpgpxmaps_MINUTES_PER_KM = "3";
20let wpgpxmaps_MILES_PER_HOURS = "2";
21let wpgpxmaps_KM_PER_HOURS = "1";
22
23var WPGPXMAPS = {
24
25	Utils: {
26
27		/* In case of multiple polylines this function divide the points of each polyline. */
28		DividePolylinesPoints: function( mapData ) {
29
30			var lastCut = 0;
31			var result = [];
32			var _len = mapData.length;
33
34			for ( i = 0; i < _len; i++ ) {
35				if ( null == mapData[i]) {
36					result.push( mapData.slice( lastCut == 0 ? 0 : lastCut + 1, i ) );
37					lastCut = i;
38				}
39			}
40			if ( ( _len - 1 ) != lastCut ) {
41				result.push( mapData.slice( lastCut ) );
42			}
43			return result;
44
45		},
46
47		GetItemFromArray: function( arr, index ) {
48			try {
49				return arr[index];
50			} catch ( e ) {
51				return [ 0, 0 ];
52			}
53		}
54
55	},
56
57	MapEngines: {
58
59		/* NOT WORKING AND TESTED! old code copy&paste */
60		GoogleMaps: function() {
61
62			var ngImageMarkers = [];
63
64			this.map = null,
65			this.EventSelectChart = null,
66			this.Polylines = [],
67			this.init = function( targetElement, mapType, scrollWheelZoom, ThunderforestApiKey ) {
68				var mapTypeIds = [];
69				for ( var type in google.maps.MapTypeId ) {
70					mapTypeIds.push( google.maps.MapTypeId[type]);
71				}
72
73				mapTypeIds.push( 'OSM1' );
74				mapTypeIds.push( 'OSM2' );
75				mapTypeIds.push( 'OSM3' );
76				mapTypeIds.push( 'OSM4' );
77				mapTypeIds.push( 'OSM5' );
78				//mapTypeIds.push( 'OSM6' );
79
80				switch ( mapType ) {
81					case 'TERRAIN': { mapType = google.maps.MapTypeId.TERRAIN; break;}
82					case 'SATELLITE': { mapType = google.maps.MapTypeId.SATELLITE; break;}
83					case 'ROADMAP': { mapType = google.maps.MapTypeId.ROADMAP; break;}
84					case 'OSM1': { mapType = 'OSM1'; break;}
85					case 'OSM2': { mapType = 'OSM2'; break;}
86					case 'OSM3': { mapType = 'OSM3'; break;}
87					case 'OSM4': { mapType = 'OSM4'; break;}
88					case 'OSM5': { mapType = 'OSM5'; break;}
89					//case 'OSM6': { mapType = 'OSM6'; break;}
90					default: { mapType = google.maps.MapTypeId.HYBRID; break;}
91				}
92
93				if ( 'TERRAIN' == mapType || 'SATELLITE' == mapType || 'ROADMAP' == mapType ) {
94
95					// Google maps.
96
97				} else {
98
99					// Show OpenStreetMaps credits.
100
101					$( el_osm_credits ).show();
102				}
103
104				this.map = new google.maps.Map( el_map, {
105					mapTypeId: mapType,
106					scrollwheel: ( 'true' == zoomOnScrollWheel ),
107					mapTypeControlOptions: {
108						style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
109						mapTypeIds: mapTypeIds
110					}
111				});
112
113				/* Map type: Open Street Mao */
114				this.map.mapTypes.set( 'OSM1', new google.maps.ImageMapType({
115					getTileUrl: function( coord, zoom ) {
116						return 'https://tile.openstreetmap.org/' + zoom + '/' + coord.x + '/' + coord.y + '.png';
117					},
118					tileSize: new google.maps.Size( 256, 256 ),
119					name: 'OSM',
120					alt: 'Open Street Map',
121					maxZoom: 18
122				}) );
123
124				/* Map type: Thunderforest - Open Cycle Map with API key or Open Cycle Map - Cycle */
125				this.map.mapTypes.set( 'OSM2', new google.maps.ImageMapType({
126					getTileUrl: function( coord, zoom ) {
127						if ( hasThunderforestApiKey ) {
128							return 'https://a.tile.thunderforest.com/cycle/' + zoom + '/' + coord.x + '/' + coord.y + '.png?apikey=' + ThunderforestApiKey;
129						} else {
130							return 'http://a.tile.opencyclemap.org/cycle/' + zoom + '/' + coord.x + '/' + coord.y + '.png';
131						}
132					},
133					tileSize: new google.maps.Size( 256, 256 ),
134					name: 'TF-OCM',
135					alt: 'Thunderforest - Open Cycle Map',
136					maxZoom: 18
137				}) );
138
139				/* Map type: Thunderforest - Transport with API key */
140				this.map.mapTypes.set( 'OSM3', new google.maps.ImageMapType({
141					getTileUrl: function( coord, zoom ) {
142						return 'https://a.tile.thunderforest.com/outdoors/' + zoom + '/' + coord.x + '/' + coord.y + '.png?apikey=' + ThunderforestApiKey;
143					},
144					tileSize: new google.maps.Size( 256, 256 ),
145					name: 'TF-Outd',
146					alt: 'Thunderforest - Outdoors',
147					maxZoom: 18
148				}) );
149
150				/* Map type: Thunderforest - Transport with API key */
151				this.map.mapTypes.set( 'OSM4', new google.maps.ImageMapType({
152					getTileUrl: function( coord, zoom ) {
153						return 'https://a.tile.thunderforest.com/transport/' + zoom + '/' + coord.x + '/' + coord.y + '.png?apikey=' + ThunderforestApiKey;
154					},
155					tileSize: new google.maps.Size( 256, 256 ),
156					name: 'TF-Tran',
157					alt: 'Thunderforest - Transport',
158					maxZoom: 18
159				}) );
160
161				/* Map type: Thunderforest - Landscape with API key */
162				this.map.mapTypes.set( 'OSM5', new google.maps.ImageMapType({
163					getTileUrl: function( coord, zoom ) {
164						return 'https://a.tile.thunderforest.com/landscape/' + zoom + '/' + coord.x + '/' + coord.y + '.png?apikey=' + ThunderforestApiKey;
165					},
166					tileSize: new google.maps.Size( 256, 256 ),
167					name: 'TF-Land',
168					alt: 'Thunderforest - Landscape',
169					maxZoom: 18
170				}) );
171
172				/* Map type: MapToolKit - Terrain */
173				//this.map.mapTypes.set( 'OSM6', new google.maps.ImageMapType({
174				//	getTileUrl: function( coord, zoom ) {
175				//		return 'https://tile2.maptoolkit.net/terrain/' + zoom + '/' + coord.x + '/' + coord.y + '.png';
176				//	},
177				//	tileSize: new google.maps.Size( 256, 256 ),
178				//	name: 'MTK-Terr',
179				//	alt: 'MapToolKit - Terrain',
180				//	maxZoom: 18
181				//}) );
182			},
183
184			this.AppPolylines = function( mapData, color1, currentIcon, startIcon, endIcon ) {
185
186				var points = [];
187				var lastCut = 0;
188				var polylinenes = [];
189				var polyline_number = 0;
190				var color = 0;
191				for ( i = 0; i < mapData.length; i++ ) {
192					if ( null == mapData[i]) {
193						var poly = new google.maps.Polyline({
194							path: points.slice( lastCut, i ),
195							strokeColor: color,
196							strokeOpacity: .7,
197							strokeWeight: 4,
198							map: this.map
199						});
200						polylinenes.push( poly );
201						lastCut = i;
202						polyline_number = polyline_number + 1;
203
204						// var p = new google.maps.LatLng(mapData[i-1][0], mapData[i-1][1]);
205						// points.push(p);
206						// bounds.extend(p);
207
208					} else {
209						var p = new google.maps.LatLng( mapData[i][0], mapData[i][1]);
210						points.push( p );
211						bounds.extend( p );
212					}
213				}
214
215				if ( points.length != lastCut ) {
216					if ( polyline_number < color1.length ) {
217						color = color1[polyline_number];
218					} else {
219						color = color1[color1.length - 1];
220					}
221					var poly = new google.maps.Polyline({
222						path: points.slice( lastCut ),
223						strokeColor: color,
224						strokeOpacity: .7,
225						strokeWeight: 4,
226						map: this.map
227					});
228					polylinenes.push( poly );
229					currentPoints = [];
230					polyline_number = polyline_number + 1;
231				}
232
233				if ( startIcon != '' ) {
234					var startIconImage = new google.maps.MarkerImage( startIcon );
235					var startMarker = new google.maps.Marker({
236						position: points[0],
237						map: this.map,
238						title: 'Start',
239						animation: google.maps.Animation.DROP,
240						icon: startIconImage,
241						zIndex: 10
242					});
243
244				}
245
246				if ( endIcon != '' ) {
247					var endIconImage = new google.maps.MarkerImage( endIcon );
248					var startMarker = new google.maps.Marker({
249						position: points[ points.length -1 ],
250						map: this.map,
251						title: 'End',
252						animation: google.maps.Animation.DROP,
253						icon: endIconImage,
254						zIndex: 10
255					});
256
257				}
258
259				var first = WPGPXMAPS.Utils.GetItemFromArray( mapData, 0 );
260
261				if ( currentIcon == '' ) {
262					currentIcon = 'https://maps.google.com/mapfiles/kml/pal4/icon25.png';
263				}
264
265				var current = new google.maps.MarkerImage( currentIcon,
266					new google.maps.Size( 32, 32 ),
267					new google.maps.Point( 0, 0 ),
268					new google.maps.Point( 16, 16 )
269				);
270
271				var marker = new google.maps.Marker({
272					position: new google.maps.LatLng( first[0], first[1]),
273					title: 'Current',
274					icon: current,
275					map: this.map,
276					zIndex: 10
277				});
278
279				for ( i = 0; i < polylinenes.length; i++ ) {
280					google.maps.event.addListener( polylinenes[i], 'mouseover', function( event ) {
281						if ( marker ) {
282							marker.setPosition( event.latLng );
283							marker.setTitle( lng.currentPosition );
284							if ( myChart ) {
285								var l1 = event.latLng.lat();
286								var l2 = event.latLng.lng();
287								var ci = getClosestIndex( mapData, l1, l2 );
288								var activeElements = [];
289								var seriesLen = myChart.data.datasets.length;
290								for ( var i = 0; i < seriesLen;i++ ) {
291									activeElements.push( myChart.chart.getDatasetMeta( i ).data[ci]);
292								}
293								if ( activeElements.length > 0 ) {
294									myChart.options.customLine.x = activeElements[0]._model.x;
295									if ( isNaN( myChart.tooltip._eventPosition ) ) {
296										myChart.tooltip._eventPosition = {
297												x: activeElements[0]._model.x,
298												y: activeElements[0]._model.y
299											};
300									}
301									myChart.tooltip._active = activeElements;
302									myChart.tooltip.update ( true );
303									myChart.draw();
304								}
305
306							}
307						}
308					});
309				}
310			},
311			this.AddWaypoints = function( waypoints, waypointIcon ) {
312			},
313			this.MoveMarkerToPosition = function( LatLon, updateChart ) {
314			};
315		},
316
317		Leaflet: function() {
318			this.Bounds = [],
319			this.lng = {},
320			this.map = null,
321			this.EventSelectChart = null,
322			this.Polylines = [],
323			this.CurrentPositionMarker = null,
324			this.CurrentGPSPositionMarker = null,
325			this.init = function( targetElement, mapType, scrollWheelZoom, ThunderforestApiKey ) {
326
327				this.map = L.map( targetElement,
328					{
329						scrollWheelZoom: scrollWheelZoom
330					}
331				);
332
333				/* create fullscreen control. */
334				var fsControl = new L.Control.FullScreen();
335
336				/* Add fullscreen control to the map. */
337				this.map.addControl( fsControl );
338
339				L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
340					attribution: 'Data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
341				}).addTo( this.map );
342
343				var hasThunderforestApiKey = ( ThunderforestApiKey + '' ).length > 0;
344
345				var baseMaps = {};
346
347				var overlayMaps = { };
348
349				var defaultMpaLayer = null;
350
351				if ( hasThunderforestApiKey ) {
352
353					/* Map type: Thunderforest - OpenCycleMap with API key */
354					baseMaps['Thunderforest - Cycle'] = L.tileLayer( 'https://a.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=' + ThunderforestApiKey, {
355						maxZoom: 18,
356						attribution: 'Maps &copy; <a href="https://www.thunderforest.com/">Thunderforest</a> contributors, ' +
357							'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
358							'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
359					});
360
361				} else {
362
363					/* Map type: Open Cycle Map - Cycle */
364					baseMaps['Open Cycle Map'] = L.tileLayer( 'http://a.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
365						maxZoom: 18,
366						attribution: 'Maps &copy; <a href="https://www.thunderforest.com/">Thunderforest</a> contributors, ' +
367							'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
368							'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
369					});
370
371				}
372
373				/* Map type: Thunderforest - Outdoors with API key */
374				baseMaps['Thunderforest - Outdoors'] = L.tileLayer( 'https://a.tile.thunderforest.com/outddors/{z}/{x}/{y}.png?apikey=' + ThunderforestApiKey, {
375					maxZoom: 18,
376					attribution: 'Maps &copy; <a href="https://www.thunderforest.com/">Thunderforest</a> contributors, ' +
377						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
378						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
379				});
380
381				/* Map type: Thunderforest - Transport with API key */
382				baseMaps['Thunderforest - Transport'] = L.tileLayer( 'https://a.tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=' + ThunderforestApiKey, {
383					maxZoom: 18,
384					attribution: 'Maps &copy; <a href="https://www.thunderforest.com/">Thunderforest</a> contributors, ' +
385						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
386						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
387				});
388
389				/* Map type: Thunderforest - Landscape with API key */
390				baseMaps['Thunderforest - Landscape'] = L.tileLayer( 'https://a.tile.thunderforest.com/landscape/{z}/{x}/{y}.png?apikey=' + ThunderforestApiKey, {
391					maxZoom: 18,
392					attribution: 'Maps &copy; <a href="https://www.thunderforest.com/">Thunderforest</a> contributors, ' +
393						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
394						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
395				});
396
397				/* Map type: Open Street Map */
398				baseMaps['Open Street Map'] = L.tileLayer( 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
399					maxZoom: 18,
400					attribution: 'Maps &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
401						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
402						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
403				});
404
405				///* Map type: MapToolKit - Terrain */
406				//baseMaps['MapToolKit - Terrain'] = L.tileLayer( 'https://tile2.maptoolkit.net/terrain/{z}/{x}/{y}.png', {
407				//	maxZoom: 18,
408				//	attribution: 'Maps &copy; <a href="https://www.maptoolkit.net/">Maptoolkit</a> contributors, ' +
409				//		'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
410				//		'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
411				//});
412
413				/* Map type: Open Street Map - Humanitarian Map Style */
414				baseMaps['Humanitarian Map Style'] = L.tileLayer( 'https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
415					maxZoom: 18,
416					attribution: 'Maps &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
417						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
418						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
419				});
420
421				/*
422				Map type: Open Ski Map
423				baseMaps['Open Ski Map'] = L.tileLayer( 'http://tiles.skimap.org/openskimap/{z}/{x}/{y}.png', {
424					maxZoom: 18,
425					attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
426						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
427						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
428				});
429				*/
430
431				/* Map type: Hike & Bike */
432				baseMaps['Hike & Bike'] = L.tileLayer( 'http://toolserver.org/tiles/hikebike/{z}/{x}/{y}.png', {
433					maxZoom: 18,
434					attribution: 'Maps &copy; <a href="https://hikebikemap.org/">Hike & Bike Map</a> contributors, ' +
435						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
436						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
437				});
438
439				/* Map type: Open Sea Map */
440				baseMaps['Open Sea Map'] = L.tileLayer( 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', {
441					maxZoom: 18,
442					attribution: 'Maps &copy; <a href="https://www.openseamap.org/">OpenSeaMap</a> contributors, ' +
443						'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
444						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
445				});
446				
447				baseMaps['GSI Map (Japan)'] = L.tileLayer( 'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
448					maxZoom: 18,
449					attribution: '&copy; <a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">国土地理院</a>, ' +
450						'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>'
451				});
452
453				switch ( mapType ) {
454
455					/* Map type: Open Street Map */
456					case 'OSM1': {
457						baseMaps['Open Street Map'].addTo( this.map );
458						break;
459					}
460
461					/* Map type: Thunderforest - Open Cycle Maps with API key */
462					case 'OSM2': {
463						baseMaps['Thunderforest - Cycle'].addTo( this.map );
464						break;
465					}
466
467					/* Map type: Thunderforest - Outdoors with API key */
468					case 'OSM3': {
469						baseMaps['Thunderforest - Outdoors'].addTo( this.map );
470						break;
471					}
472
473					/* Map type: Thunderforest - Landscape with API key */
474					case 'OSM4': {
475						baseMaps['Thunderforest - Transport'].addTo( this.map );
476						break;
477					}
478
479					/* Map type: Thunderforest - Landscape with API key */
480					case 'OSM5': {
481						baseMaps['Thunderforest - Landscape'].addTo( this.map );
482						break;
483					}
484
485					///* Map type: MapToolKit - Terrain */
486					//case 'OSM6': {
487					//	baseMaps['MapToolKit - Terrain'].addTo( this.map );
488					//	break;
489					//}
490
491					/* Map type: Open Street Map - Humanitarian Map Style*/
492					case 'OSM7': {
493						baseMaps['Humanitarian Map Style'].addTo( this.map );
494						break;
495					}
496
497					/*
498					Map type: Open Ski Map
499					case 'OSM8': {
500						baseMaps['Open Ski Map'].addTo( this.map );
501						break;
502					}
503					*/
504
505					/* Map type: Hike & Bike */
506					case 'OSM9': {
507						baseMaps['Hike & Bike'].addTo( this.map );
508						break;
509					}
510
511					/* Map type: Open Sea Map */
512					case 'OSM10': {
513						baseMaps['Open Sea Map'].addTo( this.map );
514						break;
515					}
516
517					case 'OSM11': {
518						baseMaps['GSI Map (Japan)'].addTo( this.map );
519						break;
520					}
521
522					/* Map type: Open Street Map */
523					default: {
524						baseMaps['Open Street Map'].addTo( this.map );
525					}
526
527				}
528
529				L.control.layers( baseMaps, overlayMaps ).addTo( this.map );
530
531			},
532
533			this.AppPolylines = function( mapData, color1, currentIcon, startIcon, endIcon ) {
534
535				var first = WPGPXMAPS.Utils.GetItemFromArray( mapData, 0 );
536
537				if ( '' == currentIcon ) {
538					currentIcon = 'https://maps.google.com/mapfiles/kml/pal4/icon25.png';
539				}
540
541				var CurrentPositionMarker = L.marker( first, { icon: L.icon ({
542					iconUrl: currentIcon,
543					iconSize: [ 32, 32 ], // Size of the icon.
544					iconAnchor: [ 16, 16 ] // Point of the icon which will correspond to marker's location.
545				})
546				});
547				CurrentPositionMarker.addTo( this.map );
548				CurrentPositionMarker.title = 'Current';
549
550				this.CurrentPositionMarker = CurrentPositionMarker;
551
552				var pointsArray = WPGPXMAPS.Utils.DividePolylinesPoints( mapData );
553
554				var lng = this.lng;
555				var EventSelectChart = this.EventSelectChart;
556
557				this.Bounds = mapData;
558
559				this.CenterMap();
560
561				for ( i = 0; i < pointsArray.length; i++ ) {
562					if ( i < color1.length ) {
563						color = color1[i];
564					} else {
565						color = color1[color1.length - 1];
566					}
567					try {
568						var polyline = L.polyline(  pointsArray[i], {color: color}).addTo( this.map );
569						this.Polylines.push( polyline );
570
571						var context = this;
572
573						this.Polylines[i].on( 'mousemove', function( e ) {
574							context.MoveMarkerToPosition([ e.latlng.lat, e.latlng.lng ], true );
575						});
576					} catch ( err ) {
577					}
578				}
579
580				if ( startIcon != '' ) {
581
582					var startMarker = L.marker( mapData[0], {icon: L.icon({
583						iconUrl: startIcon,
584						iconSize: [ 32, 32 ], // Size of the icon.
585						iconAnchor: [ 16, 16 ] // Point of the icon which will correspond to marker's location.
586					})
587					});
588
589					startMarker.addTo( this.map );
590					startMarker.title = 'Start';
591				}
592
593				if ( endIcon != '' ) {
594
595					var endMarker = L.marker( mapData[ mapData.length - 1 ], {icon: L.icon({
596						iconUrl: endIcon,
597						iconSize: [ 32, 32 ], // size of the icon
598						iconAnchor: [ 16, 16 ] // point of the icon which will correspond to marker's location
599					})
600					});
601
602					endMarker.addTo( this.map );
603					endMarker.title = 'End';
604				}
605
606				/*
607				var current = new google.maps.MarkerImage(currentIcon,
608					new google.maps.Size(32, 32),
609					new google.maps.Point(0,0),
610					new google.maps.Point(16, 16)
611				);
612
613				var marker = new google.maps.Marker({
614					position: new google.maps.LatLng(first[0], first[1]),
615					title:"Start",
616					icon: current,
617					map: map,
618					zIndex: 10
619				});
620
621				for (i=0; i < polylinenes.length; i++)
622				{
623
624					google.maps.event.addListener(polylinenes[i],'mouseover',function(event){
625						if (marker)
626						{
627							marker.setPosition(event.latLng);
628							marker.setTitle(lng.currentPosition);
629							if (myChart)
630							{
631								var l1 = event.latLng.lat();
632								var l2 = event.latLng.lng();
633								var ci = getClosestIndex(mapData,l1,l2);
634								var activeElements = [];
635								var seriesLen = myChart.data.datasets.length;
636								for(var i=0; i<seriesLen;i++)
637								{
638									activeElements.push(myChart.chart.getDatasetMeta(i).data[ci]);
639								}
640								if (activeElements.length > 0)
641								{
642									myChart.options.customLine.x = activeElements[0]._model.x;
643									if (isNaN(myChart.tooltip._eventPosition))
644									{
645										myChart.tooltip._eventPosition = {
646												x: activeElements[0]._model.x,
647												y: activeElements[0]._model.y
648											};
649									}
650									myChart.tooltip._active = activeElements;
651									myChart.tooltip.update(true);
652									myChart.draw();
653								}
654
655							}
656						}
657					});
658				}
659				*/
660
661			},
662
663			this.AddWaypoints = function( waypoints, waypointIcon ) {
664
665				var icon = L.icon({
666					iconUrl: 'https://maps.google.com/mapfiles/ms/micons/flag.png',
667					iconSize: [ 32, 32 ], // Size of the icon.
668					iconAnchor: [ 16, 16 ] // Point of the icon which will correspond to marker's location.
669				});
670
671				if ( waypointIcon != '' ) {
672					icon = L.icon({
673						iconUrl: 'waypointIcon',
674						iconSize: [ 32, 32 ], // Size of the icon.
675						iconAnchor: [ 16, 16 ] // Point of the icon which will correspond to marker's location.
676					});
677				}
678
679				for ( i = 0; i < waypoints.length; i++ ) {
680					var wpt = waypoints[i];
681
682					this.Bounds.push([ wpt.lat, wpt.lon ]);
683
684					var lat = wpt.lat;
685					var lon = wpt.lon;
686					var sym = wpt.sym;
687					var typ = wpt.type;
688
689					if ( icon.img ) {
690						icon.iconUrl = wpt.img;
691						wsh = '';
692					}
693					var marker = L.marker([ lat, lon ], {icon: icon });
694					var cnt = '';
695
696					if ( wpt.name == '' ) {
697						cnt = "<div>" + unescape( wpt.desc ) + "</div>";
698					} else {
699						cnt = "<div><b>" + wpt.name + "</b><br />" + unescape( wpt.desc ) + "</div>";
700					}
701					cnt += "<br /><p><a href='https://maps.google.com?daddr=" + lat + "," + lon + "' target='_blank'>Itin&eacute;raire</a></p>";
702					marker.addTo( this.map ).bindPopup( cnt );
703				}
704				this.CenterMap();
705			},
706
707			this.MoveMarkerToPosition = function( LatLon, updateChart ) {
708				if ( null == this.CurrentPositionMarker )
709					return;
710
711				this.CurrentPositionMarker.setLatLng( LatLon );
712
713				if ( this.lng )
714					this.CurrentPositionMarker.title = this.lng.currentPosition;
715
716				if ( true == updateChart && this.EventSelectChart )
717					this.EventSelectChart( LatLon );
718
719			},
720			this.CenterMap = function() {
721				this.map.fitBounds( this.Bounds );
722			};
723		}
724	}
725};
726
727( function( $ ) {
728
729    $.fn.wpgpxmaps = function( params ) {
730
731		var targetId = params.targetId;
732		var mapType = params.mapType;
733		var mapData = params.mapData;
734		var graphDist = params.graphDist;
735		var graphEle = params.graphEle;
736		var graphSpeed = params.graphSpeed;
737		var graphHr = params.graphHr;
738		var graphAtemp = params.graphAtemp;
739		var graphCad = params.graphCad;
740		var graphGrade = params.graphGrade;
741		var waypoints = params.waypoints;
742		var unit_of_measure = params.unit;
743		var unit_of_measure_speed = params.unitspeed;
744		var color1 = params.color1;
745		var color2 = params.color2;
746		var color3 = params.color3;
747		var color4 = params.color4;
748		var color5 = params.color5;
749		var color6 = params.color6;
750		var color7 = params.color7;
751		var chartFrom1 = params.chartFrom1;
752		var chartTo1 = params.chartTo1;
753		var chartFrom2 = params.chartFrom2;
754		var chartTo2 = params.chartTo2;
755		var startIcon = params.startIcon;
756		var waypointIcon = params.waypointIcon;
757		var endIcon = params.endIcon;
758		var currentIcon = params.currentIcon;
759		var zoomOnScrollWheel = params.zoomOnScrollWheel;
760		var lng = params.langs;
761		var pluginUrl = params.pluginUrl;
762		var usegpsposition = params.usegpsposition;
763		var currentpositioncon = params.currentpositioncon;
764		var ThunderforestApiKey = params.TFApiKey;
765
766		var hasThunderforestApiKey = ( ThunderforestApiKey + '' ).length > 0;
767
768		var _formats = [];
769
770		/* Unit of measure settings. */
771		var l_s;
772		var label_x;
773		var label_y;
774		var l_grade = { suf: '%', dec: 1 };
775		var l_hr = { suf: '', dec: 0 };
776		var l_cad = { suf: '', dec: 0 };
777
778		var el = document.getElementById( 'wpgpxmaps_' + targetId );
779		var el_map = document.getElementById( 'map_' + targetId );
780		var el_chart = document.getElementById( 'chart_' + targetId );
781		var el_report = document.getElementById( 'report_' + targetId );
782		var el_osm_credits = document.getElementById( 'wpgpxmaps_' + targetId + '_osm_footer' );
783
784		var mapWidth = el_map.style.width;
785
786		var map = new WPGPXMAPS.MapEngines.Leaflet();
787		map.lng = lng;
788		map.init(
789			'map_' + targetId,
790			mapType,
791			( 'true' == zoomOnScrollWheel ),
792			ThunderforestApiKey
793		);
794
795		map.EventSelectChart = function( LatLon ) {
796
797			if ( myChart ) {
798				var l1 = LatLon[0];
799				var l2 = LatLon[1];
800				var ci = getClosestIndex( mapData, l1, l2 );
801				var activeElements = [];
802				var seriesLen = myChart.data.datasets.length;
803				for ( var i = 0; i < seriesLen;i++ ) {
804					activeElements.push( myChart.chart.getDatasetMeta( i ).data[ci]);
805				}
806				if ( activeElements.length > 0 ) {
807					myChart.options.customLine.x = activeElements[0]._model.x;
808					if ( isNaN( myChart.tooltip._eventPosition ) ) {
809						myChart.tooltip._eventPosition = {
810								x: activeElements[0]._model.x,
811								y: activeElements[0]._model.y
812							};
813					}
814					myChart.tooltip._active = activeElements;
815					myChart.tooltip.update( true );
816					myChart.draw();
817				}
818			}
819		};
820
821		// var bounds = new google.maps.LatLngBounds();
822
823		if ( 'true' == usegpsposition ) {
824
825			/* Try HTML5 geolocation. */
826			if ( navigator.geolocation ) {
827				var context = map;
828				navigator.geolocation.watchPosition( function( position ) {
829					var radius = position.coords.accuracy / 2;
830
831					/* User position. */
832					var pos = [ position.coords.latitude, position.coords.longitude ];
833
834					if ( null == context.CurrentGPSPositionMarker ) {
835						if ( '' == currentpositioncon  ) {
836							currentpositioncon = 'https://maps.google.com/mapfiles/kml/pal4/icon25.png';
837						}
838
839						context.CurrentGPSPositionMarker = L.marker( pos, {icon: L.icon({
840							iconUrl: currentpositioncon,
841							iconSize: [ 32, 32 ], // Size of the icon.
842							iconAnchor: [ 16, 16 ] // Point of the icon which will correspond to marker's location.
843						})
844						})
845						.addTo( context.map )
846						.bindPopup( lng.currentPosition )
847						.openPopup();
848
849					} else {
850						context.CurrentGPSPositionMarker.setLatLng( pos );
851					}
852					context.Bounds.push( pos );
853					context.CenterMap();
854				},
855				function( e ) {
856
857					// Some errors.
858
859				},
860				{
861				enableHighAccuracy: false,
862				timeout: 5000,
863				maximumAge: 0
864				});
865			}
866		}
867
868		/* Print WayPoints. */
869		if ( ! jQuery.isEmptyObject( waypoints ) && waypoints.length > 0 ) {
870			map.AddWaypoints( waypoints, waypointIcon );
871		}
872
873		/* Print Images. */
874		jQuery( "#ngimages_" + targetId ).attr( "style", "display:block;position:absolute;left:-50000px" );
875
876		var nggImages = jQuery( "#ngimages_" + targetId + " span" ).toArray();
877
878		if ( nggImages !== undefined && nggImages.length > 0 ) {
879			var photos = [];
880
881			for ( var i = 0; i < nggImages.length; i++ ) {
882
883				var ngg_span = nggImages[i];
884				var ngg_span_a = ngg_span.children[0];
885
886				var pos = [
887					Number( ngg_span.getAttribute( 'lat' ) ),
888					Number( ngg_span.getAttribute( 'lon' ) )
889				];
890
891				map.Bounds.push( pos );
892
893				photos.push({
894					'lat': pos[0],
895					'lng': pos[1],
896					'name': ngg_span_a.children[0].getAttribute( 'alt' ),
897					'url': ngg_span_a.children[0].getAttribute( 'src' ),
898					'thumbnail': ngg_span_a.children[0].getAttribute( 'src' )
899				});
900
901			}
902
903			if ( photos.length > 0 ) {
904				var photoLayer = L.photo.cluster().on( 'click', function( evt ) {
905					var photo = evt.layer.photo;
906					var template = '<img src="{url}" /></a><p>{name}</p>';
907					evt.layer.bindPopup( L.Util.template( template, photo ), {
908					minWidth: 'auto'
909				}).openPopup();
910			});
911
912				photoLayer.add( photos ).addTo( map.map );
913
914				map.CenterMap();
915
916				/*
917				var showHideImagesCustomControl = L.Control.extend({
918
919					options: {
920						position: 'topleft'
921						//control position - allowed: 'topleft', 'topright', 'bottomleft', 'bottomright'
922					},
923
924				  onAdd: function (map) {
925
926					var container = document.createElement('img');
927					container.class= "leaflet-bar leaflet-control leaflet-control-custom"
928					container.style.backgroundColor = 'white';
929					container.style.width = '30px';
930					container.style.height = '30px';
931					container.src = pluginUrl + "/wp-gpx-maps/img/hideImages.png";
932					container.style.cursor = 'pointer';
933					container.title = lng.hideImages;
934
935					container.onclick = function(){
936
937						var isImagesHidden = (controlUIhi.isImagesHidden == true);
938						var mapDiv = map.getDiv();
939						var center = map.getCenter();
940
941						if (isImagesHidden)
942						{
943							for (var i=0; i<ngImageMarkers.length; i++) {
944								ngImageMarkers[i].setMap(map);
945							}
946							controlUIhi.src = pluginUrl + "/wp-gpx-maps/img/hideImages.png";
947							controlUIhi.title = lng.hideImages;
948						}
949						else
950						{
951							for (var i=0; i<ngImageMarkers.length; i++) {
952								ngImageMarkers[i].setMap(null);
953			}
954							controlUIhi.src = pluginUrl + "/wp-gpx-maps/img/showImages.png";
955							controlUIhi.title = lng.showImages;
956						}
957						controlUIhi.isImagesHidden = !isImagesHidden;
958						return false;
959
960					}
961
962					return container;
963				  },
964
965				});
966
967				map.map.addControl(new showHideImagesCustomControl());
968				*/
969
970			}
971
972		}
973
974		/*
975
976		// Nextgen Pro Lightbox FIX
977		var _xx = jQuery("#ngimages_" + targetId + " .nextgen_pro_lightbox");
978		if (_xx.length > 0)
979		{
980
981			var rnd1 = Math.random().toString(36).substring(7);
982			var rnd2 = Math.random().toString(36).substring(7);
983
984			//get first gallery without images
985			for (var _temp in galleries) {
986				var _gal = galleries[_temp];
987
988				if (_gal.source == "random_images" && _gal.wpgpxmaps != true )
989				{
990
991					_gal.source == "galleries";
992					_gal.wpgpxmaps = true;
993					_transient_id = _temp.replace("gallery_","")
994					_gal["entity_ids"] = [];
995					_gal["image_ids"] = [];
996					_gal["gallery_ids"] = [96];
997					for (var i=0;i<_xx.length;i++)
998					{
999						var __xx = jQuery(_xx[i]);
1000						__xx.attr("data-nplmodal-gallery-id", _transient_id);
1001						_gal["image_ids"].push(__xx.attr("data-image-id"));
1002					}
1003					break;
1004				}
1005			}
1006		}
1007		*/
1008
1009		/* Print Track. */
1010		if ( mapData != '' ) {
1011			map.AppPolylines( mapData, color1, currentIcon, startIcon, endIcon );
1012		}
1013
1014		/*
1015		map.setCenter(bounds.getCenter());
1016		map.fitBounds(bounds);
1017		*/
1018
1019		// Fix post tabs. */
1020		var $_tab = $( el ).closest( ".wordpress-post-tabs, .tab-pane" ).eq( 0 );
1021		if ( $_tab ) {
1022			var contextMap = map;
1023
1024			var FixMapSize = function( e ) {
1025				setTimeout( function( e ) {
1026
1027					// google.maps.event.trigger(map, 'resize');
1028					contextMap.map.invalidateSize();
1029					contextMap.CenterMap();
1030					tabResized = true;
1031				}, 300 );
1032			};
1033
1034			$( ".wpsm_nav-tabs a" ).click( FixMapSize );
1035
1036			$( "div > ul > li > a", $_tab ).click( FixMapSize );
1037		}
1038
1039
1040		var graphh = jQuery( '#myChart_' + params.targetId ).css( "height" );
1041
1042		if ( graphDist != '' && ( graphEle != '' || graphSpeed != '' || graphHr != '' || graphAtemp != '' || graphCad != '' ) && graphh != '0px' ) {
1043
1044			var valLen = graphDist.length;
1045
1046			if ( wpgpxmaps_FEET_MILES == unit_of_measure ) {
1047
1048				/* feet / miles */
1049				label_x = { suf: 'mi', dec: 1 };
1050				label_y = { suf: 'ft', dec: 0 };
1051
1052			} else if ( wpgpxmaps_METERS_KILOMETERS == unit_of_measure ) {
1053
1054				/* meters / kilometers */
1055				label_x = { suf: 'km', dec: 1 };
1056				label_y = { suf: 'm', dec: 2 };
1057
1058			} else if ( wpgpxmaps_METERS_NAUTICALMILES == unit_of_measure ) {
1059
1060				/* meters / nautical miles */
1061				label_x = { suf: 'NM', dec: 1 };
1062				label_y = { suf: 'm', dec: 0 };
1063
1064			} else if ( wpgpxmaps_METER_MILES == unit_of_measure ) {
1065
1066				/* meters / miles */
1067				label_x = { suf: 'mi', dec: 1 };
1068				label_y = { suf: 'm', dec: 0 };
1069
1070			} else if ( wpgpxmaps_FEET_NAUTICALMILES == unit_of_measure ) {
1071
1072				/* feet / nautical miles */
1073				label_x = { suf: 'NM', dec: 1 };
1074				label_y = { suf: 'ft', dec: 0 };
1075
1076			} else {
1077
1078				/* meters / meters */
1079				label_x = { suf: 'm', dec: 0 };
1080				label_y = { suf: 'm', dec: 0 };
1081
1082			}
1083
1084			var nn = 1111.1;
1085			var _nn = nn.toLocaleString();
1086			var _nnLen = _nn.length;
1087			var decPoint = _nn.substring( _nnLen - 2, _nnLen - 1 );
1088			var thousandsSep = _nn.substring( 1, 2 );
1089
1090			if ( '1' == decPoint )
1091				decPoint = '.';
1092
1093			if ( '1' == thousandsSep )
1094				thousandsSep = '';
1095
1096			/* Define the options. */
1097			var hoptions = {
1098				type: 'line',
1099				data: {
1100					datasets: []
1101				},
1102				borderWidth: 1,
1103				options: {
1104					animation: {
1105
1106						// duration: 0,
1107						// general animation time
1108					},
1109					hover: {
1110
1111						// animationDuration: 0,
1112						// duration of animations when hovering an item
1113					},
1114
1115					// responsiveAnimationDuration: 0,
1116					// animation duration after a resize
1117					customLine: {
1118						color: 'gray'
1119					},
1120					scales: {
1121						yAxes: [],
1122						xAxes: [ {
1123							type: 'linear',
1124							ticks: {
1125								suggestedMin: 0,
1126								max: graphDist[graphDist.length - 1],
1127
1128								/* Include a dollar sign in the ticks. */
1129								callback: function( value, index, values ) {
1130									return Math.round( value, label_x.dec ) + label_x.suf;
1131								}
1132							}
1133						} ]
1134					},
1135					tooltips: {
1136						position: 'average',
1137						mode: 'index',
1138						intersect: false,
1139						callbacks: {
1140							title: function( tooltipItems, data ) {
1141
1142								/* Return value for title: */
1143								var label_x = _formats[0].label_x;
1144								var x_pos = tooltipItems[0].xLabel;
1145								var x_dec = label_x.dec;
1146								var x_unit = label_x.suf;
1147								return Math.round( x_pos, x_dec ) + x_unit;
1148							},
1149							label: function( tooltipItem, data ) {
1150
1151								/* Format list values: */
1152								var label = data.datasets[tooltipItem.datasetIndex].label || '';
1153								var label_y = _formats[tooltipItem.datasetIndex].label_y;
1154								var y_dec = label_y.dec;
1155								var y_unit = label_y.suf;
1156								var y_pos = tooltipItem.yLabel;
1157								if ( label ) {
1158									label += ': ';
1159								}
1160								label += Math.round( y_pos, y_dec ) + y_unit;
1161								return label;
1162							},
1163							footer: function( tooltipItem ) {
1164
1165								/* Move the point in map. */
1166								var i = tooltipItem[0].index;
1167								var point = WPGPXMAPS.Utils.GetItemFromArray( mapData, i );
1168								map.MoveMarkerToPosition( point, false );
1169							}
1170						}
1171					}
1172				},
1173
1174				plugins: [ {
1175					beforeEvent: function( chart, e ) {
1176						if ( ( e.type === 'mousemove' )
1177						&& ( e.x >= e.chart.chartArea.left )
1178						&& ( e.x <= e.chart.chartArea.right )
1179						) {
1180							chart.options.customLine.x = e.x;
1181						}
1182					},
1183					afterDraw: function( chart, easing ) {
1184						var ctx = chart.chart.ctx;
1185						var chartArea = chart.chartArea;
1186						var x = chart.options.customLine.x;
1187						if ( ! isNaN( x ) ) {
1188							ctx.save();
1189							ctx.strokeStyle = chart.options.customLine.color;
1190							ctx.moveTo( chart.options.customLine.x, chartArea.bottom );
1191							ctx.lineTo( chart.options.customLine.x, chartArea.top );
1192							ctx.stroke();
1193							ctx.restore();
1194						}
1195					}
1196				} ],
1197				labels: graphDist
1198			};
1199
1200			if ( graphEle != '' ) {
1201				var myData = mergeArrayForChart( graphDist, graphEle );
1202				var yaxe = {
1203					type: 'linear',
1204					ticks: {
1205
1206						/* Include a dollar sign in the ticks. */
1207						// This draw the lateral axis alias
1208						callback: function( value, index, values ) {
1209							return Math.round( value, label_y.dec ) + label_y.suf;
1210						}
1211					},
1212					id: 'y-axis-' + ( hoptions.options.scales.yAxes.length + 1 )
1213				};
1214
1215				if ( chartFrom1 != '' )	{
1216
1217					yaxe.min = chartFrom1;
1218					yaxe.startOnTick = false;
1219
1220				} else {
1221
1222					yaxe.min = myData.Min;
1223
1224				}
1225
1226				if ( chartTo1 != '' ) {
1227
1228					yaxe.max = chartTo1;
1229					yaxe.endOnTick = false;
1230
1231				} else {
1232
1233					yaxe.max = myData.Max;
1234				}
1235
1236				_formats.push( {"label_x": label_x, "label_y":label_y} );
1237				hoptions.options.scales.yAxes.push( yaxe );
1238				hoptions.data.datasets.push( wpgpxmapsGetDataset( lng.altitude, myData.Items, color2, yaxe.id ) );
1239
1240			}
1241
1242			if ( graphSpeed != '' ) {
1243
1244
1245				if ( wpgpxmaps_MINUTES_PER_100METERS == unit_of_measure_speed ) {
1246
1247					/* min/100 meters */
1248					l_s = { suf: 'min/100m', dec: 2 };
1249
1250				} else if ( wpgpxmaps_KNOTS == unit_of_measure_speed ) {
1251
1252					/* knots */
1253					l_s = { suf: 'knots', dec: 2 };
1254
1255				} else if ( wpgpxmaps_MINUTES_PER_MILES == unit_of_measure_speed ) {
1256
1257					/* min/miles */
1258					l_s = { suf: 'min/mi', dec: 2 };
1259
1260				} else if ( wpgpxmaps_MINUTES_PER_KM == unit_of_measure_speed ) {
1261
1262					/* min/km */
1263					l_s = { suf: 'min/km', dec: 2 };
1264
1265				} else if ( wpgpxmaps_MILES_PER_HOURS == unit_of_measure_speed ) {
1266
1267					/* miles/h */
1268					l_s = { suf: 'mi/h', dec: 0 };
1269
1270				} else if ( wpgpxmaps_KM_PER_HOURS == unit_of_measure_speed ) {
1271
1272					/* km/h */
1273					l_s = { suf: 'km/h', dec: 0 };
1274
1275				} else {
1276
1277					/* dafault m/s */
1278					l_s = { suf: 'm/s', dec: 0 };
1279
1280				}
1281
1282				var myData = mergeArrayForChart( graphDist, graphSpeed );
1283				var yaxe = {
1284					type: 'linear',
1285					ticks: {
1286
1287						/* Include a dollar sign in the ticks. */
1288						callback: function( value, index, values ) {
1289							return Math.round( value, l_s.dec ) + l_s.suf;
1290						}
1291					},
1292					position: 'right',
1293					scalePositionLeft: false,
1294					id: 'y-axis-' + ( hoptions.options.scales.yAxes.length + 1 )
1295				};
1296
1297				if ( chartFrom2 != '' ) {
1298
1299					yaxe.min = chartFrom2;
1300					yaxe.startOnTick = false;
1301
1302				} else {
1303					yaxe.min = myData.Min;
1304				}
1305
1306				if ( chartTo2 != '' ) {
1307
1308					yaxe.max = chartTo2;
1309					yaxe.endOnTick = false;
1310
1311				} else {
1312					yaxe.max = myData.Max;
1313				}
1314
1315				_formats.push ( l_s );
1316				hoptions.options.scales.yAxes.push( yaxe );
1317				hoptions.data.datasets.push( wpgpxmapsGetDataset( lng.speed, myData.Items, color3, yaxe.id ) );
1318			}
1319
1320			if ( graphHr != '' ) {
1321				var myData = mergeArrayForChart( graphDist, graphHr );
1322				var yaxe = {
1323					type: 'linear',
1324					ticks: {
1325
1326						/* Include a dollar sign in the ticks. */
1327						callback: function( value, index, values ) {
1328							return Math.round( value, l_hr.dec ) + l_hr.suf;
1329						}
1330					},
1331					position: 'right',
1332					scalePositionLeft: false,
1333					id: 'y-axis-' + ( hoptions.options.scales.yAxes.length + 1 )
1334				};
1335				hoptions.options.scales.yAxes.push( yaxe );
1336				hoptions.data.datasets.push( wpgpxmapsGetDataset( lng.heartRate, myData.Items, color4, yaxe.id ) );
1337				_formats.push( l_hr );
1338			}
1339
1340			if ( graphAtemp != '' ) {
1341				var myData = mergeArrayForChart( graphDist, graphAtemp );
1342				var yaxe = {
1343					type: 'linear',
1344					ticks: {
1345
1346						/* Include a dollar sign in the ticks. */
1347						callback: function( value, index, values ) {
1348							return Math.round( value, 1 ) + "°C";
1349						}
1350					},
1351					position: 'right',
1352					scalePositionLeft: false,
1353					id: 'y-axis-' + ( hoptions.options.scales.yAxes.length + 1 )
1354				};
1355				hoptions.options.scales.yAxes.push( yaxe );
1356				hoptions.data.datasets.push( wpgpxmapsGetDataset( lng.atemp, myData.Items, color7, yaxe.id ) );
1357				_formats.push({ suf: '°C', dec: 1 });
1358			}
1359
1360
1361			if ( graphCad != '' ) {
1362
1363				var myData = mergeArrayForChart( graphDist, graphCad, true );
1364				var yaxe = {
1365					type: 'linear',
1366					ticks: {
1367
1368						// Include a dollar sign in the ticks.
1369						callback: function( value, index, values ) {
1370							return Math.round( value, l_cad.dec ) + l_cad.suf;
1371						}
1372					},
1373					position: 'right',
1374					scalePositionLeft: false,
1375					id: 'y-axis-' + ( hoptions.options.scales.yAxes.length + 1 )
1376				};
1377
1378				hoptions.options.scales.yAxes.push( yaxe );
1379				hoptions.data.datasets.push( wpgpxmapsGetDataset( lng.cadence, myData.Items, color5, yaxe.id ) );
1380				_formats.push( l_cad );
1381
1382			}
1383
1384			if ( graphGrade != '' ) {
1385
1386				var myData = mergeArrayForChart( graphDist, graphGrade );
1387				var yaxe = {
1388					type: 'linear',
1389					ticks: {
1390
1391						// Include a dollar sign in the ticks.
1392						callback: function( value, index, values ) {
1393							return Math.round( value, l_grade.dec ) + l_grade.suf;
1394						}
1395					},
1396					position: 'right',
1397					scalePositionLeft: false,
1398					id: "y-axis-" + ( hoptions.options.scales.yAxes.length + 1 )
1399				};
1400
1401				_formats.push( l_grade );
1402				hoptions.options.scales.yAxes.push( yaxe );
1403				hoptions.data.datasets.push( wpgpxmapsGetDataset( lng.grade, myData.Items, color6, yaxe.id ) );
1404			}
1405
1406			var ctx = document.getElementById( 'myChart_' + params.targetId ).getContext( '2d' );
1407			var myChart = new Chart( ctx, hoptions );
1408
1409		} else  {
1410			jQuery( '#myChart_' + params.targetId ).css( "display", "none" );
1411		}
1412
1413        return this;
1414    };
1415
1416	function mergeArrayForChart( distArr, dataArr, setZerosAsNull ) {
1417		var l = distArr.length;
1418
1419		var items = new Array( l );
1420		var min = 10000;
1421		var max = -10000;
1422
1423		for ( i = 0; i < l; i++ ) {
1424			if ( distArr[i] != null ) {
1425				var _item = dataArr[i];
1426
1427				if ( setZerosAsNull === true && _item === 0 ) {
1428					_item = null;
1429				}
1430
1431				items[i] = {
1432					x: distArr[i],
1433					y: _item
1434				};
1435				if ( _item > max )
1436					max = _item;
1437				if ( _item < min )
1438					min = _item;
1439			}
1440		}
1441		return {
1442			Items: items,
1443			Min: min,
1444			Max: max
1445		};
1446	}
1447
1448	function wpgpxmapsGetDataset( name, data, color, id ) {
1449		return {
1450			label: name, // jQuery("<div/>").html(name).text(), // convert html special chars to text, ugly but it works
1451			data: data,
1452			borderColor: color,
1453			backgroundColor: hexToRgbA( color, .3 ),
1454			pointRadius: 0,
1455			borderWidth: 1,
1456			pointHoverRadius: 1,
1457			yAxisID: id
1458		};
1459	}
1460
1461	function hexToRgbA( hex, a ) {
1462		var c;
1463		if ( /^#([A-Fa-f0-9]{3}){1,2}$/.test( hex ) ) {
1464			c = hex.substring( 1 ).split( '' );
1465			if ( c.length == 3 ) {
1466				c = [ c[0], c[0], c[1], c[1], c[2], c[2] ];
1467			}
1468			c = '0x' + c.join( '' );
1469			return 'rgba(' + [ ( c>>16 )&255, ( c>>8 )&255, c&255 ].join( ',' ) + ',' + a + ' )';
1470		}
1471		throw new Error( 'Bad Hex' );
1472	}
1473
1474
1475	function getItemFromArray( arr, index ) {
1476		try {
1477			return arr[index];
1478		} catch ( e ) {
1479			return [ 0, 0 ];
1480		}
1481	}
1482
1483
1484	function getClosestIndex( points, lat, lon ) {
1485		var dd = 10000;
1486		var ii = 0;
1487		for ( i = 0; i < points.length; i++ ) {
1488			if ( null == points[i])
1489				continue;
1490
1491			var d = wpgpxmapsDist( points[i][0], points[i][1], lat, lon );
1492			if ( d < dd ) {
1493				ii = i;
1494				dd = d;
1495			}
1496		}
1497		return ii;
1498	}
1499
1500	function getClosestImage( lat, lon, targetId ) {
1501		var dd = 10000;
1502		var img;
1503		var divImages = document.getElementById( "ngimages_" + targetId );
1504		var img_spans = divImages.getElementsByTagName( "span" );
1505		for ( var i = 0; i < img_spans.length; i++ ) {
1506			var imageLat = img_spans[i].getAttribute( 'lat' );
1507			var imageLon = img_spans[i].getAttribute( 'lon' );
1508
1509			imageLat = imageLat.replace( ",", "." );
1510			imageLon = imageLon.replace( ",", "." );
1511
1512			var d = wpgpxmapsDist( imageLat, imageLon, lat, lon );
1513			if ( d < dd ) {
1514				img = img_spans[i];
1515				dd = d;
1516			}
1517		}
1518		return img;
1519	}
1520
1521	function isNumeric( input ) {
1522		var RE = /^-{0,1}\d*\.{0,1}\d+$/;
1523		return ( RE.test( input ) );
1524	}
1525
1526	function wpgpxmapsDist( lat1, lon1, lat2, lon2 ) {
1527
1528		// Mathematically not correct but fast.
1529		var dLat = ( lat2 - lat1 );
1530		var dLon = ( lon2 - lon1 );
1531		return Math.sqrt( dLat * dLat + dLon * dLon );
1532	}
1533
1534}( jQuery ) );

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.