travlrmap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/public/gmaps.js ADDED
@@ -0,0 +1,2149 @@
1
+ (function(root, factory) {
2
+ if(typeof exports === 'object') {
3
+ module.exports = factory();
4
+ }
5
+ else if(typeof define === 'function' && define.amd) {
6
+ define('GMaps', [], factory);
7
+ }
8
+
9
+ root.GMaps = factory();
10
+
11
+ }(this, function() {
12
+
13
+ /*!
14
+ * GMaps.js v0.4.16
15
+ * http://hpneo.github.com/gmaps/
16
+ *
17
+ * Copyright 2014, Gustavo Leon
18
+ * Released under the MIT License.
19
+ */
20
+
21
+ if (!(typeof window.google === 'object' && window.google.maps)) {
22
+ throw 'Google Maps API is required. Please register the following JavaScript library http://maps.google.com/maps/api/js?sensor=true.'
23
+ }
24
+
25
+ var extend_object = function(obj, new_obj) {
26
+ var name;
27
+
28
+ if (obj === new_obj) {
29
+ return obj;
30
+ }
31
+
32
+ for (name in new_obj) {
33
+ obj[name] = new_obj[name];
34
+ }
35
+
36
+ return obj;
37
+ };
38
+
39
+ var replace_object = function(obj, replace) {
40
+ var name;
41
+
42
+ if (obj === replace) {
43
+ return obj;
44
+ }
45
+
46
+ for (name in replace) {
47
+ if (obj[name] != undefined) {
48
+ obj[name] = replace[name];
49
+ }
50
+ }
51
+
52
+ return obj;
53
+ };
54
+
55
+ var array_map = function(array, callback) {
56
+ var original_callback_params = Array.prototype.slice.call(arguments, 2),
57
+ array_return = [],
58
+ array_length = array.length,
59
+ i;
60
+
61
+ if (Array.prototype.map && array.map === Array.prototype.map) {
62
+ array_return = Array.prototype.map.call(array, function(item) {
63
+ callback_params = original_callback_params;
64
+ callback_params.splice(0, 0, item);
65
+
66
+ return callback.apply(this, callback_params);
67
+ });
68
+ }
69
+ else {
70
+ for (i = 0; i < array_length; i++) {
71
+ callback_params = original_callback_params;
72
+ callback_params.splice(0, 0, array[i]);
73
+ array_return.push(callback.apply(this, callback_params));
74
+ }
75
+ }
76
+
77
+ return array_return;
78
+ };
79
+
80
+ var array_flat = function(array) {
81
+ var new_array = [],
82
+ i;
83
+
84
+ for (i = 0; i < array.length; i++) {
85
+ new_array = new_array.concat(array[i]);
86
+ }
87
+
88
+ return new_array;
89
+ };
90
+
91
+ var coordsToLatLngs = function(coords, useGeoJSON) {
92
+ var first_coord = coords[0],
93
+ second_coord = coords[1];
94
+
95
+ if (useGeoJSON) {
96
+ first_coord = coords[1];
97
+ second_coord = coords[0];
98
+ }
99
+
100
+ return new google.maps.LatLng(first_coord, second_coord);
101
+ };
102
+
103
+ var arrayToLatLng = function(coords, useGeoJSON) {
104
+ var i;
105
+
106
+ for (i = 0; i < coords.length; i++) {
107
+ if (!(coords[i] instanceof google.maps.LatLng)) {
108
+ if (coords[i].length > 0 && typeof(coords[i][0]) == "object") {
109
+ coords[i] = arrayToLatLng(coords[i], useGeoJSON);
110
+ }
111
+ else {
112
+ coords[i] = coordsToLatLngs(coords[i], useGeoJSON);
113
+ }
114
+ }
115
+ }
116
+
117
+ return coords;
118
+ };
119
+
120
+ var getElementById = function(id, context) {
121
+ var element,
122
+ id = id.replace('#', '');
123
+
124
+ if ('jQuery' in this && context) {
125
+ element = $("#" + id, context)[0];
126
+ } else {
127
+ element = document.getElementById(id);
128
+ };
129
+
130
+ return element;
131
+ };
132
+
133
+ var findAbsolutePosition = function(obj) {
134
+ var curleft = 0,
135
+ curtop = 0;
136
+
137
+ if (obj.offsetParent) {
138
+ do {
139
+ curleft += obj.offsetLeft;
140
+ curtop += obj.offsetTop;
141
+ } while (obj = obj.offsetParent);
142
+ }
143
+
144
+ return [curleft, curtop];
145
+ };
146
+
147
+ var GMaps = (function(global) {
148
+ "use strict";
149
+
150
+ var doc = document;
151
+
152
+ var GMaps = function(options) {
153
+ if (!this) return new GMaps(options);
154
+
155
+ options.zoom = options.zoom || 15;
156
+ options.mapType = options.mapType || 'roadmap';
157
+
158
+ var self = this,
159
+ i,
160
+ events_that_hide_context_menu = ['bounds_changed', 'center_changed', 'click', 'dblclick', 'drag', 'dragend', 'dragstart', 'idle', 'maptypeid_changed', 'projection_changed', 'resize', 'tilesloaded', 'zoom_changed'],
161
+ events_that_doesnt_hide_context_menu = ['mousemove', 'mouseout', 'mouseover'],
162
+ options_to_be_deleted = ['el', 'lat', 'lng', 'mapType', 'width', 'height', 'markerClusterer', 'enableNewStyle'],
163
+ container_id = options.el || options.div,
164
+ markerClustererFunction = options.markerClusterer,
165
+ mapType = google.maps.MapTypeId[options.mapType.toUpperCase()],
166
+ map_center = new google.maps.LatLng(options.lat, options.lng),
167
+ zoomControl = options.zoomControl || true,
168
+ zoomControlOpt = options.zoomControlOpt || {
169
+ style: 'DEFAULT',
170
+ position: 'TOP_LEFT'
171
+ },
172
+ zoomControlStyle = zoomControlOpt.style || 'DEFAULT',
173
+ zoomControlPosition = zoomControlOpt.position || 'TOP_LEFT',
174
+ panControl = options.panControl || true,
175
+ mapTypeControl = options.mapTypeControl || true,
176
+ scaleControl = options.scaleControl || true,
177
+ streetViewControl = options.streetViewControl || true,
178
+ overviewMapControl = overviewMapControl || true,
179
+ map_options = {},
180
+ map_base_options = {
181
+ zoom: this.zoom,
182
+ center: map_center,
183
+ mapTypeId: mapType
184
+ },
185
+ map_controls_options = {
186
+ panControl: panControl,
187
+ zoomControl: zoomControl,
188
+ zoomControlOptions: {
189
+ style: google.maps.ZoomControlStyle[zoomControlStyle],
190
+ position: google.maps.ControlPosition[zoomControlPosition]
191
+ },
192
+ mapTypeControl: mapTypeControl,
193
+ scaleControl: scaleControl,
194
+ streetViewControl: streetViewControl,
195
+ overviewMapControl: overviewMapControl
196
+ };
197
+
198
+ if (typeof(options.el) === 'string' || typeof(options.div) === 'string') {
199
+ this.el = getElementById(container_id, options.context);
200
+ } else {
201
+ this.el = container_id;
202
+ }
203
+
204
+ if (typeof(this.el) === 'undefined' || this.el === null) {
205
+ throw 'No element defined.';
206
+ }
207
+
208
+ window.context_menu = window.context_menu || {};
209
+ window.context_menu[self.el.id] = {};
210
+
211
+ this.controls = [];
212
+ this.overlays = [];
213
+ this.layers = []; // array with kml/georss and fusiontables layers, can be as many
214
+ this.singleLayers = {}; // object with the other layers, only one per layer
215
+ this.markers = [];
216
+ this.polylines = [];
217
+ this.routes = [];
218
+ this.polygons = [];
219
+ this.infoWindow = null;
220
+ this.overlay_el = null;
221
+ this.zoom = options.zoom;
222
+ this.registered_events = {};
223
+
224
+ this.el.style.width = options.width || this.el.scrollWidth || this.el.offsetWidth;
225
+ this.el.style.height = options.height || this.el.scrollHeight || this.el.offsetHeight;
226
+
227
+ google.maps.visualRefresh = options.enableNewStyle;
228
+
229
+ for (i = 0; i < options_to_be_deleted.length; i++) {
230
+ delete options[options_to_be_deleted[i]];
231
+ }
232
+
233
+ if(options.disableDefaultUI != true) {
234
+ map_base_options = extend_object(map_base_options, map_controls_options);
235
+ }
236
+
237
+ map_options = extend_object(map_base_options, options);
238
+
239
+ for (i = 0; i < events_that_hide_context_menu.length; i++) {
240
+ delete map_options[events_that_hide_context_menu[i]];
241
+ }
242
+
243
+ for (i = 0; i < events_that_doesnt_hide_context_menu.length; i++) {
244
+ delete map_options[events_that_doesnt_hide_context_menu[i]];
245
+ }
246
+
247
+ this.map = new google.maps.Map(this.el, map_options);
248
+
249
+ if (markerClustererFunction) {
250
+ this.markerClusterer = markerClustererFunction.apply(this, [this.map]);
251
+ }
252
+
253
+ var buildContextMenuHTML = function(control, e) {
254
+ var html = '',
255
+ options = window.context_menu[self.el.id][control];
256
+
257
+ for (var i in options){
258
+ if (options.hasOwnProperty(i)) {
259
+ var option = options[i];
260
+
261
+ html += '<li><a id="' + control + '_' + i + '" href="#">' + option.title + '</a></li>';
262
+ }
263
+ }
264
+
265
+ if (!getElementById('gmaps_context_menu')) return;
266
+
267
+ var context_menu_element = getElementById('gmaps_context_menu');
268
+
269
+ context_menu_element.innerHTML = html;
270
+
271
+ var context_menu_items = context_menu_element.getElementsByTagName('a'),
272
+ context_menu_items_count = context_menu_items.length,
273
+ i;
274
+
275
+ for (i = 0; i < context_menu_items_count; i++) {
276
+ var context_menu_item = context_menu_items[i];
277
+
278
+ var assign_menu_item_action = function(ev){
279
+ ev.preventDefault();
280
+
281
+ options[this.id.replace(control + '_', '')].action.apply(self, [e]);
282
+ self.hideContextMenu();
283
+ };
284
+
285
+ google.maps.event.clearListeners(context_menu_item, 'click');
286
+ google.maps.event.addDomListenerOnce(context_menu_item, 'click', assign_menu_item_action, false);
287
+ }
288
+
289
+ var position = findAbsolutePosition.apply(this, [self.el]),
290
+ left = position[0] + e.pixel.x - 15,
291
+ top = position[1] + e.pixel.y- 15;
292
+
293
+ context_menu_element.style.left = left + "px";
294
+ context_menu_element.style.top = top + "px";
295
+
296
+ context_menu_element.style.display = 'block';
297
+ };
298
+
299
+ this.buildContextMenu = function(control, e) {
300
+ if (control === 'marker') {
301
+ e.pixel = {};
302
+
303
+ var overlay = new google.maps.OverlayView();
304
+ overlay.setMap(self.map);
305
+
306
+ overlay.draw = function() {
307
+ var projection = overlay.getProjection(),
308
+ position = e.marker.getPosition();
309
+
310
+ e.pixel = projection.fromLatLngToContainerPixel(position);
311
+
312
+ buildContextMenuHTML(control, e);
313
+ };
314
+ }
315
+ else {
316
+ buildContextMenuHTML(control, e);
317
+ }
318
+ };
319
+
320
+ this.setContextMenu = function(options) {
321
+ window.context_menu[self.el.id][options.control] = {};
322
+
323
+ var i,
324
+ ul = doc.createElement('ul');
325
+
326
+ for (i in options.options) {
327
+ if (options.options.hasOwnProperty(i)) {
328
+ var option = options.options[i];
329
+
330
+ window.context_menu[self.el.id][options.control][option.name] = {
331
+ title: option.title,
332
+ action: option.action
333
+ };
334
+ }
335
+ }
336
+
337
+ ul.id = 'gmaps_context_menu';
338
+ ul.style.display = 'none';
339
+ ul.style.position = 'absolute';
340
+ ul.style.minWidth = '100px';
341
+ ul.style.background = 'white';
342
+ ul.style.listStyle = 'none';
343
+ ul.style.padding = '8px';
344
+ ul.style.boxShadow = '2px 2px 6px #ccc';
345
+
346
+ doc.body.appendChild(ul);
347
+
348
+ var context_menu_element = getElementById('gmaps_context_menu')
349
+
350
+ google.maps.event.addDomListener(context_menu_element, 'mouseout', function(ev) {
351
+ if (!ev.relatedTarget || !this.contains(ev.relatedTarget)) {
352
+ window.setTimeout(function(){
353
+ context_menu_element.style.display = 'none';
354
+ }, 400);
355
+ }
356
+ }, false);
357
+ };
358
+
359
+ this.hideContextMenu = function() {
360
+ var context_menu_element = getElementById('gmaps_context_menu');
361
+
362
+ if (context_menu_element) {
363
+ context_menu_element.style.display = 'none';
364
+ }
365
+ };
366
+
367
+ var setupListener = function(object, name) {
368
+ google.maps.event.addListener(object, name, function(e){
369
+ if (e == undefined) {
370
+ e = this;
371
+ }
372
+
373
+ options[name].apply(this, [e]);
374
+
375
+ self.hideContextMenu();
376
+ });
377
+ };
378
+
379
+ //google.maps.event.addListener(this.map, 'idle', this.hideContextMenu);
380
+ google.maps.event.addListener(this.map, 'zoom_changed', this.hideContextMenu);
381
+
382
+ for (var ev = 0; ev < events_that_hide_context_menu.length; ev++) {
383
+ var name = events_that_hide_context_menu[ev];
384
+
385
+ if (name in options) {
386
+ setupListener(this.map, name);
387
+ }
388
+ }
389
+
390
+ for (var ev = 0; ev < events_that_doesnt_hide_context_menu.length; ev++) {
391
+ var name = events_that_doesnt_hide_context_menu[ev];
392
+
393
+ if (name in options) {
394
+ setupListener(this.map, name);
395
+ }
396
+ }
397
+
398
+ google.maps.event.addListener(this.map, 'rightclick', function(e) {
399
+ if (options.rightclick) {
400
+ options.rightclick.apply(this, [e]);
401
+ }
402
+
403
+ if(window.context_menu[self.el.id]['map'] != undefined) {
404
+ self.buildContextMenu('map', e);
405
+ }
406
+ });
407
+
408
+ this.refresh = function() {
409
+ google.maps.event.trigger(this.map, 'resize');
410
+ };
411
+
412
+ this.fitZoom = function() {
413
+ var latLngs = [],
414
+ markers_length = this.markers.length,
415
+ i;
416
+
417
+ for (i = 0; i < markers_length; i++) {
418
+ if(typeof(this.markers[i].visible) === 'boolean' && this.markers[i].visible) {
419
+ latLngs.push(this.markers[i].getPosition());
420
+ }
421
+ }
422
+
423
+ this.fitLatLngBounds(latLngs);
424
+ };
425
+
426
+ this.fitLatLngBounds = function(latLngs) {
427
+ var total = latLngs.length;
428
+ var bounds = new google.maps.LatLngBounds();
429
+
430
+ for(var i=0; i < total; i++) {
431
+ bounds.extend(latLngs[i]);
432
+ }
433
+
434
+ this.map.fitBounds(bounds);
435
+ };
436
+
437
+ this.setCenter = function(lat, lng, callback) {
438
+ this.map.panTo(new google.maps.LatLng(lat, lng));
439
+
440
+ if (callback) {
441
+ callback();
442
+ }
443
+ };
444
+
445
+ this.getElement = function() {
446
+ return this.el;
447
+ };
448
+
449
+ this.zoomIn = function(value) {
450
+ value = value || 1;
451
+
452
+ this.zoom = this.map.getZoom() + value;
453
+ this.map.setZoom(this.zoom);
454
+ };
455
+
456
+ this.zoomOut = function(value) {
457
+ value = value || 1;
458
+
459
+ this.zoom = this.map.getZoom() - value;
460
+ this.map.setZoom(this.zoom);
461
+ };
462
+
463
+ var native_methods = [],
464
+ method;
465
+
466
+ for (method in this.map) {
467
+ if (typeof(this.map[method]) == 'function' && !this[method]) {
468
+ native_methods.push(method);
469
+ }
470
+ }
471
+
472
+ for (i=0; i < native_methods.length; i++) {
473
+ (function(gmaps, scope, method_name) {
474
+ gmaps[method_name] = function(){
475
+ return scope[method_name].apply(scope, arguments);
476
+ };
477
+ })(this, this.map, native_methods[i]);
478
+ }
479
+ };
480
+
481
+ return GMaps;
482
+ })(this);
483
+
484
+ GMaps.prototype.createControl = function(options) {
485
+ var control = document.createElement('div');
486
+
487
+ control.style.cursor = 'pointer';
488
+
489
+ if (options.disableDefaultStyles !== true) {
490
+ control.style.fontFamily = 'Roboto, Arial, sans-serif';
491
+ control.style.fontSize = '11px';
492
+ control.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px';
493
+ }
494
+
495
+ for (var option in options.style) {
496
+ control.style[option] = options.style[option];
497
+ }
498
+
499
+ if (options.id) {
500
+ control.id = options.id;
501
+ }
502
+
503
+ if (options.classes) {
504
+ control.className = options.classes;
505
+ }
506
+
507
+ if (options.content) {
508
+ if (typeof options.content === 'string') {
509
+ control.innerHTML = options.content;
510
+ }
511
+ else if (options.content instanceof HTMLElement) {
512
+ control.appendChild(options.content);
513
+ }
514
+ }
515
+
516
+ if (options.position) {
517
+ control.position = google.maps.ControlPosition[options.position.toUpperCase()];
518
+ }
519
+
520
+ for (var ev in options.events) {
521
+ (function(object, name) {
522
+ google.maps.event.addDomListener(object, name, function(){
523
+ options.events[name].apply(this, [this]);
524
+ });
525
+ })(control, ev);
526
+ }
527
+
528
+ control.index = 1;
529
+
530
+ return control;
531
+ };
532
+
533
+ GMaps.prototype.addControl = function(options) {
534
+ var control = this.createControl(options);
535
+ this.controls.push(control);
536
+ this.map.controls[control.position].push(control);
537
+
538
+ return control;
539
+ };
540
+
541
+ GMaps.prototype.removeControl = function(control) {
542
+ var position = null;
543
+
544
+ for (var i = 0; i < this.controls.length; i++) {
545
+ if (this.controls[i] == control) {
546
+ position = this.controls[i].position;
547
+ this.controls.splice(i, 1);
548
+ }
549
+ }
550
+
551
+ if (position) {
552
+ for (i = 0; i < this.map.controls.length; i++) {
553
+ var controlsForPosition = this.map.controls[control.position]
554
+ if (controlsForPosition.getAt(i) == control) {
555
+ controlsForPosition.removeAt(i);
556
+ break;
557
+ }
558
+ }
559
+ }
560
+
561
+ return control;
562
+ };
563
+
564
+ GMaps.prototype.createMarker = function(options) {
565
+ if (options.lat == undefined && options.lng == undefined && options.position == undefined) {
566
+ throw 'No latitude or longitude defined.';
567
+ }
568
+
569
+ var self = this,
570
+ details = options.details,
571
+ fences = options.fences,
572
+ outside = options.outside,
573
+ base_options = {
574
+ position: new google.maps.LatLng(options.lat, options.lng),
575
+ map: null
576
+ },
577
+ marker_options = extend_object(base_options, options);
578
+
579
+ delete marker_options.lat;
580
+ delete marker_options.lng;
581
+ delete marker_options.fences;
582
+ delete marker_options.outside;
583
+
584
+ var marker = new google.maps.Marker(marker_options);
585
+
586
+ marker.fences = fences;
587
+
588
+ if (options.infoWindow) {
589
+ marker.infoWindow = new google.maps.InfoWindow(options.infoWindow);
590
+
591
+ var info_window_events = ['closeclick', 'content_changed', 'domready', 'position_changed', 'zindex_changed'];
592
+
593
+ for (var ev = 0; ev < info_window_events.length; ev++) {
594
+ (function(object, name) {
595
+ if (options.infoWindow[name]) {
596
+ google.maps.event.addListener(object, name, function(e){
597
+ options.infoWindow[name].apply(this, [e]);
598
+ });
599
+ }
600
+ })(marker.infoWindow, info_window_events[ev]);
601
+ }
602
+ }
603
+
604
+ var marker_events = ['animation_changed', 'clickable_changed', 'cursor_changed', 'draggable_changed', 'flat_changed', 'icon_changed', 'position_changed', 'shadow_changed', 'shape_changed', 'title_changed', 'visible_changed', 'zindex_changed'];
605
+
606
+ var marker_events_with_mouse = ['dblclick', 'drag', 'dragend', 'dragstart', 'mousedown', 'mouseout', 'mouseover', 'mouseup'];
607
+
608
+ for (var ev = 0; ev < marker_events.length; ev++) {
609
+ (function(object, name) {
610
+ if (options[name]) {
611
+ google.maps.event.addListener(object, name, function(){
612
+ options[name].apply(this, [this]);
613
+ });
614
+ }
615
+ })(marker, marker_events[ev]);
616
+ }
617
+
618
+ for (var ev = 0; ev < marker_events_with_mouse.length; ev++) {
619
+ (function(map, object, name) {
620
+ if (options[name]) {
621
+ google.maps.event.addListener(object, name, function(me){
622
+ if(!me.pixel){
623
+ me.pixel = map.getProjection().fromLatLngToPoint(me.latLng)
624
+ }
625
+
626
+ options[name].apply(this, [me]);
627
+ });
628
+ }
629
+ })(this.map, marker, marker_events_with_mouse[ev]);
630
+ }
631
+
632
+ google.maps.event.addListener(marker, 'click', function() {
633
+ this.details = details;
634
+
635
+ if (options.click) {
636
+ options.click.apply(this, [this]);
637
+ }
638
+
639
+ if (marker.infoWindow) {
640
+ self.hideInfoWindows();
641
+ marker.infoWindow.open(self.map, marker);
642
+ }
643
+ });
644
+
645
+ google.maps.event.addListener(marker, 'rightclick', function(e) {
646
+ e.marker = this;
647
+
648
+ if (options.rightclick) {
649
+ options.rightclick.apply(this, [e]);
650
+ }
651
+
652
+ if (window.context_menu[self.el.id]['marker'] != undefined) {
653
+ self.buildContextMenu('marker', e);
654
+ }
655
+ });
656
+
657
+ if (marker.fences) {
658
+ google.maps.event.addListener(marker, 'dragend', function() {
659
+ self.checkMarkerGeofence(marker, function(m, f) {
660
+ outside(m, f);
661
+ });
662
+ });
663
+ }
664
+
665
+ return marker;
666
+ };
667
+
668
+ GMaps.prototype.addMarker = function(options) {
669
+ var marker;
670
+ if(options.hasOwnProperty('gm_accessors_')) {
671
+ // Native google.maps.Marker object
672
+ marker = options;
673
+ }
674
+ else {
675
+ if ((options.hasOwnProperty('lat') && options.hasOwnProperty('lng')) || options.position) {
676
+ marker = this.createMarker(options);
677
+ }
678
+ else {
679
+ throw 'No latitude or longitude defined.';
680
+ }
681
+ }
682
+
683
+ marker.setMap(this.map);
684
+
685
+ if(this.markerClusterer) {
686
+ this.markerClusterer.addMarker(marker);
687
+ }
688
+
689
+ this.markers.push(marker);
690
+
691
+ GMaps.fire('marker_added', marker, this);
692
+
693
+ return marker;
694
+ };
695
+
696
+ GMaps.prototype.addMarkers = function(array) {
697
+ for (var i = 0, marker; marker=array[i]; i++) {
698
+ this.addMarker(marker);
699
+ }
700
+
701
+ return this.markers;
702
+ };
703
+
704
+ GMaps.prototype.hideInfoWindows = function() {
705
+ for (var i = 0, marker; marker = this.markers[i]; i++){
706
+ if (marker.infoWindow) {
707
+ marker.infoWindow.close();
708
+ }
709
+ }
710
+ };
711
+
712
+ GMaps.prototype.removeMarker = function(marker) {
713
+ for (var i = 0; i < this.markers.length; i++) {
714
+ if (this.markers[i] === marker) {
715
+ this.markers[i].setMap(null);
716
+ this.markers.splice(i, 1);
717
+
718
+ if(this.markerClusterer) {
719
+ this.markerClusterer.removeMarker(marker);
720
+ }
721
+
722
+ GMaps.fire('marker_removed', marker, this);
723
+
724
+ break;
725
+ }
726
+ }
727
+
728
+ return marker;
729
+ };
730
+
731
+ GMaps.prototype.removeMarkers = function (collection) {
732
+ var new_markers = [];
733
+
734
+ if (typeof collection == 'undefined') {
735
+ for (var i = 0; i < this.markers.length; i++) {
736
+ var marker = this.markers[i];
737
+ marker.setMap(null);
738
+
739
+ if(this.markerClusterer) {
740
+ this.markerClusterer.removeMarker(marker);
741
+ }
742
+
743
+ GMaps.fire('marker_removed', marker, this);
744
+ }
745
+
746
+ this.markers = new_markers;
747
+ }
748
+ else {
749
+ for (var i = 0; i < collection.length; i++) {
750
+ var index = this.markers.indexOf(collection[i]);
751
+
752
+ if (index > -1) {
753
+ var marker = this.markers[index];
754
+ marker.setMap(null);
755
+
756
+ if(this.markerClusterer) {
757
+ this.markerClusterer.removeMarker(marker);
758
+ }
759
+
760
+ GMaps.fire('marker_removed', marker, this);
761
+ }
762
+ }
763
+
764
+ for (var i = 0; i < this.markers.length; i++) {
765
+ var marker = this.markers[i];
766
+ if (marker.getMap() != null) {
767
+ new_markers.push(marker);
768
+ }
769
+ }
770
+
771
+ this.markers = new_markers;
772
+ }
773
+ };
774
+
775
+ GMaps.prototype.drawOverlay = function(options) {
776
+ var overlay = new google.maps.OverlayView(),
777
+ auto_show = true;
778
+
779
+ overlay.setMap(this.map);
780
+
781
+ if (options.auto_show != null) {
782
+ auto_show = options.auto_show;
783
+ }
784
+
785
+ overlay.onAdd = function() {
786
+ var el = document.createElement('div');
787
+
788
+ el.style.borderStyle = "none";
789
+ el.style.borderWidth = "0px";
790
+ el.style.position = "absolute";
791
+ el.style.zIndex = 100;
792
+ el.innerHTML = options.content;
793
+
794
+ overlay.el = el;
795
+
796
+ if (!options.layer) {
797
+ options.layer = 'overlayLayer';
798
+ }
799
+
800
+ var panes = this.getPanes(),
801
+ overlayLayer = panes[options.layer],
802
+ stop_overlay_events = ['contextmenu', 'DOMMouseScroll', 'dblclick', 'mousedown'];
803
+
804
+ overlayLayer.appendChild(el);
805
+
806
+ for (var ev = 0; ev < stop_overlay_events.length; ev++) {
807
+ (function(object, name) {
808
+ google.maps.event.addDomListener(object, name, function(e){
809
+ if (navigator.userAgent.toLowerCase().indexOf('msie') != -1 && document.all) {
810
+ e.cancelBubble = true;
811
+ e.returnValue = false;
812
+ }
813
+ else {
814
+ e.stopPropagation();
815
+ }
816
+ });
817
+ })(el, stop_overlay_events[ev]);
818
+ }
819
+
820
+ if (options.click) {
821
+ panes.overlayMouseTarget.appendChild(overlay.el);
822
+ google.maps.event.addDomListener(overlay.el, 'click', function() {
823
+ options.click.apply(overlay, [overlay]);
824
+ });
825
+ }
826
+
827
+ google.maps.event.trigger(this, 'ready');
828
+ };
829
+
830
+ overlay.draw = function() {
831
+ var projection = this.getProjection(),
832
+ pixel = projection.fromLatLngToDivPixel(new google.maps.LatLng(options.lat, options.lng));
833
+
834
+ options.horizontalOffset = options.horizontalOffset || 0;
835
+ options.verticalOffset = options.verticalOffset || 0;
836
+
837
+ var el = overlay.el,
838
+ content = el.children[0],
839
+ content_height = content.clientHeight,
840
+ content_width = content.clientWidth;
841
+
842
+ switch (options.verticalAlign) {
843
+ case 'top':
844
+ el.style.top = (pixel.y - content_height + options.verticalOffset) + 'px';
845
+ break;
846
+ default:
847
+ case 'middle':
848
+ el.style.top = (pixel.y - (content_height / 2) + options.verticalOffset) + 'px';
849
+ break;
850
+ case 'bottom':
851
+ el.style.top = (pixel.y + options.verticalOffset) + 'px';
852
+ break;
853
+ }
854
+
855
+ switch (options.horizontalAlign) {
856
+ case 'left':
857
+ el.style.left = (pixel.x - content_width + options.horizontalOffset) + 'px';
858
+ break;
859
+ default:
860
+ case 'center':
861
+ el.style.left = (pixel.x - (content_width / 2) + options.horizontalOffset) + 'px';
862
+ break;
863
+ case 'right':
864
+ el.style.left = (pixel.x + options.horizontalOffset) + 'px';
865
+ break;
866
+ }
867
+
868
+ el.style.display = auto_show ? 'block' : 'none';
869
+
870
+ if (!auto_show) {
871
+ options.show.apply(this, [el]);
872
+ }
873
+ };
874
+
875
+ overlay.onRemove = function() {
876
+ var el = overlay.el;
877
+
878
+ if (options.remove) {
879
+ options.remove.apply(this, [el]);
880
+ }
881
+ else {
882
+ overlay.el.parentNode.removeChild(overlay.el);
883
+ overlay.el = null;
884
+ }
885
+ };
886
+
887
+ this.overlays.push(overlay);
888
+ return overlay;
889
+ };
890
+
891
+ GMaps.prototype.removeOverlay = function(overlay) {
892
+ for (var i = 0; i < this.overlays.length; i++) {
893
+ if (this.overlays[i] === overlay) {
894
+ this.overlays[i].setMap(null);
895
+ this.overlays.splice(i, 1);
896
+
897
+ break;
898
+ }
899
+ }
900
+ };
901
+
902
+ GMaps.prototype.removeOverlays = function() {
903
+ for (var i = 0, item; item = this.overlays[i]; i++) {
904
+ item.setMap(null);
905
+ }
906
+
907
+ this.overlays = [];
908
+ };
909
+
910
+ GMaps.prototype.drawPolyline = function(options) {
911
+ var path = [],
912
+ points = options.path;
913
+
914
+ if (points.length) {
915
+ if (points[0][0] === undefined) {
916
+ path = points;
917
+ }
918
+ else {
919
+ for (var i=0, latlng; latlng=points[i]; i++) {
920
+ path.push(new google.maps.LatLng(latlng[0], latlng[1]));
921
+ }
922
+ }
923
+ }
924
+
925
+ var polyline_options = {
926
+ map: this.map,
927
+ path: path,
928
+ strokeColor: options.strokeColor,
929
+ strokeOpacity: options.strokeOpacity,
930
+ strokeWeight: options.strokeWeight,
931
+ geodesic: options.geodesic,
932
+ clickable: true,
933
+ editable: false,
934
+ visible: true
935
+ };
936
+
937
+ if (options.hasOwnProperty("clickable")) {
938
+ polyline_options.clickable = options.clickable;
939
+ }
940
+
941
+ if (options.hasOwnProperty("editable")) {
942
+ polyline_options.editable = options.editable;
943
+ }
944
+
945
+ if (options.hasOwnProperty("icons")) {
946
+ polyline_options.icons = options.icons;
947
+ }
948
+
949
+ if (options.hasOwnProperty("zIndex")) {
950
+ polyline_options.zIndex = options.zIndex;
951
+ }
952
+
953
+ var polyline = new google.maps.Polyline(polyline_options);
954
+
955
+ var polyline_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick'];
956
+
957
+ for (var ev = 0; ev < polyline_events.length; ev++) {
958
+ (function(object, name) {
959
+ if (options[name]) {
960
+ google.maps.event.addListener(object, name, function(e){
961
+ options[name].apply(this, [e]);
962
+ });
963
+ }
964
+ })(polyline, polyline_events[ev]);
965
+ }
966
+
967
+ this.polylines.push(polyline);
968
+
969
+ GMaps.fire('polyline_added', polyline, this);
970
+
971
+ return polyline;
972
+ };
973
+
974
+ GMaps.prototype.removePolyline = function(polyline) {
975
+ for (var i = 0; i < this.polylines.length; i++) {
976
+ if (this.polylines[i] === polyline) {
977
+ this.polylines[i].setMap(null);
978
+ this.polylines.splice(i, 1);
979
+
980
+ GMaps.fire('polyline_removed', polyline, this);
981
+
982
+ break;
983
+ }
984
+ }
985
+ };
986
+
987
+ GMaps.prototype.removePolylines = function() {
988
+ for (var i = 0, item; item = this.polylines[i]; i++) {
989
+ item.setMap(null);
990
+ }
991
+
992
+ this.polylines = [];
993
+ };
994
+
995
+ GMaps.prototype.drawCircle = function(options) {
996
+ options = extend_object({
997
+ map: this.map,
998
+ center: new google.maps.LatLng(options.lat, options.lng)
999
+ }, options);
1000
+
1001
+ delete options.lat;
1002
+ delete options.lng;
1003
+
1004
+ var polygon = new google.maps.Circle(options),
1005
+ polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick'];
1006
+
1007
+ for (var ev = 0; ev < polygon_events.length; ev++) {
1008
+ (function(object, name) {
1009
+ if (options[name]) {
1010
+ google.maps.event.addListener(object, name, function(e){
1011
+ options[name].apply(this, [e]);
1012
+ });
1013
+ }
1014
+ })(polygon, polygon_events[ev]);
1015
+ }
1016
+
1017
+ this.polygons.push(polygon);
1018
+
1019
+ return polygon;
1020
+ };
1021
+
1022
+ GMaps.prototype.drawRectangle = function(options) {
1023
+ options = extend_object({
1024
+ map: this.map
1025
+ }, options);
1026
+
1027
+ var latLngBounds = new google.maps.LatLngBounds(
1028
+ new google.maps.LatLng(options.bounds[0][0], options.bounds[0][1]),
1029
+ new google.maps.LatLng(options.bounds[1][0], options.bounds[1][1])
1030
+ );
1031
+
1032
+ options.bounds = latLngBounds;
1033
+
1034
+ var polygon = new google.maps.Rectangle(options),
1035
+ polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick'];
1036
+
1037
+ for (var ev = 0; ev < polygon_events.length; ev++) {
1038
+ (function(object, name) {
1039
+ if (options[name]) {
1040
+ google.maps.event.addListener(object, name, function(e){
1041
+ options[name].apply(this, [e]);
1042
+ });
1043
+ }
1044
+ })(polygon, polygon_events[ev]);
1045
+ }
1046
+
1047
+ this.polygons.push(polygon);
1048
+
1049
+ return polygon;
1050
+ };
1051
+
1052
+ GMaps.prototype.drawPolygon = function(options) {
1053
+ var useGeoJSON = false;
1054
+
1055
+ if(options.hasOwnProperty("useGeoJSON")) {
1056
+ useGeoJSON = options.useGeoJSON;
1057
+ }
1058
+
1059
+ delete options.useGeoJSON;
1060
+
1061
+ options = extend_object({
1062
+ map: this.map
1063
+ }, options);
1064
+
1065
+ if (useGeoJSON == false) {
1066
+ options.paths = [options.paths.slice(0)];
1067
+ }
1068
+
1069
+ if (options.paths.length > 0) {
1070
+ if (options.paths[0].length > 0) {
1071
+ options.paths = array_flat(array_map(options.paths, arrayToLatLng, useGeoJSON));
1072
+ }
1073
+ }
1074
+
1075
+ var polygon = new google.maps.Polygon(options),
1076
+ polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick'];
1077
+
1078
+ for (var ev = 0; ev < polygon_events.length; ev++) {
1079
+ (function(object, name) {
1080
+ if (options[name]) {
1081
+ google.maps.event.addListener(object, name, function(e){
1082
+ options[name].apply(this, [e]);
1083
+ });
1084
+ }
1085
+ })(polygon, polygon_events[ev]);
1086
+ }
1087
+
1088
+ this.polygons.push(polygon);
1089
+
1090
+ GMaps.fire('polygon_added', polygon, this);
1091
+
1092
+ return polygon;
1093
+ };
1094
+
1095
+ GMaps.prototype.removePolygon = function(polygon) {
1096
+ for (var i = 0; i < this.polygons.length; i++) {
1097
+ if (this.polygons[i] === polygon) {
1098
+ this.polygons[i].setMap(null);
1099
+ this.polygons.splice(i, 1);
1100
+
1101
+ GMaps.fire('polygon_removed', polygon, this);
1102
+
1103
+ break;
1104
+ }
1105
+ }
1106
+ };
1107
+
1108
+ GMaps.prototype.removePolygons = function() {
1109
+ for (var i = 0, item; item = this.polygons[i]; i++) {
1110
+ item.setMap(null);
1111
+ }
1112
+
1113
+ this.polygons = [];
1114
+ };
1115
+
1116
+ GMaps.prototype.getFromFusionTables = function(options) {
1117
+ var events = options.events;
1118
+
1119
+ delete options.events;
1120
+
1121
+ var fusion_tables_options = options,
1122
+ layer = new google.maps.FusionTablesLayer(fusion_tables_options);
1123
+
1124
+ for (var ev in events) {
1125
+ (function(object, name) {
1126
+ google.maps.event.addListener(object, name, function(e) {
1127
+ events[name].apply(this, [e]);
1128
+ });
1129
+ })(layer, ev);
1130
+ }
1131
+
1132
+ this.layers.push(layer);
1133
+
1134
+ return layer;
1135
+ };
1136
+
1137
+ GMaps.prototype.loadFromFusionTables = function(options) {
1138
+ var layer = this.getFromFusionTables(options);
1139
+ layer.setMap(this.map);
1140
+
1141
+ return layer;
1142
+ };
1143
+
1144
+ GMaps.prototype.getFromKML = function(options) {
1145
+ var url = options.url,
1146
+ events = options.events;
1147
+
1148
+ delete options.url;
1149
+ delete options.events;
1150
+
1151
+ var kml_options = options,
1152
+ layer = new google.maps.KmlLayer(url, kml_options);
1153
+
1154
+ for (var ev in events) {
1155
+ (function(object, name) {
1156
+ google.maps.event.addListener(object, name, function(e) {
1157
+ events[name].apply(this, [e]);
1158
+ });
1159
+ })(layer, ev);
1160
+ }
1161
+
1162
+ this.layers.push(layer);
1163
+
1164
+ return layer;
1165
+ };
1166
+
1167
+ GMaps.prototype.loadFromKML = function(options) {
1168
+ var layer = this.getFromKML(options);
1169
+ layer.setMap(this.map);
1170
+
1171
+ return layer;
1172
+ };
1173
+
1174
+ GMaps.prototype.addLayer = function(layerName, options) {
1175
+ //var default_layers = ['weather', 'clouds', 'traffic', 'transit', 'bicycling', 'panoramio', 'places'];
1176
+ options = options || {};
1177
+ var layer;
1178
+
1179
+ switch(layerName) {
1180
+ case 'weather': this.singleLayers.weather = layer = new google.maps.weather.WeatherLayer();
1181
+ break;
1182
+ case 'clouds': this.singleLayers.clouds = layer = new google.maps.weather.CloudLayer();
1183
+ break;
1184
+ case 'traffic': this.singleLayers.traffic = layer = new google.maps.TrafficLayer();
1185
+ break;
1186
+ case 'transit': this.singleLayers.transit = layer = new google.maps.TransitLayer();
1187
+ break;
1188
+ case 'bicycling': this.singleLayers.bicycling = layer = new google.maps.BicyclingLayer();
1189
+ break;
1190
+ case 'panoramio':
1191
+ this.singleLayers.panoramio = layer = new google.maps.panoramio.PanoramioLayer();
1192
+ layer.setTag(options.filter);
1193
+ delete options.filter;
1194
+
1195
+ //click event
1196
+ if (options.click) {
1197
+ google.maps.event.addListener(layer, 'click', function(event) {
1198
+ options.click(event);
1199
+ delete options.click;
1200
+ });
1201
+ }
1202
+ break;
1203
+ case 'places':
1204
+ this.singleLayers.places = layer = new google.maps.places.PlacesService(this.map);
1205
+
1206
+ //search, nearbySearch, radarSearch callback, Both are the same
1207
+ if (options.search || options.nearbySearch || options.radarSearch) {
1208
+ var placeSearchRequest = {
1209
+ bounds : options.bounds || null,
1210
+ keyword : options.keyword || null,
1211
+ location : options.location || null,
1212
+ name : options.name || null,
1213
+ radius : options.radius || null,
1214
+ rankBy : options.rankBy || null,
1215
+ types : options.types || null
1216
+ };
1217
+
1218
+ if (options.radarSearch) {
1219
+ layer.radarSearch(placeSearchRequest, options.radarSearch);
1220
+ }
1221
+
1222
+ if (options.search) {
1223
+ layer.search(placeSearchRequest, options.search);
1224
+ }
1225
+
1226
+ if (options.nearbySearch) {
1227
+ layer.nearbySearch(placeSearchRequest, options.nearbySearch);
1228
+ }
1229
+ }
1230
+
1231
+ //textSearch callback
1232
+ if (options.textSearch) {
1233
+ var textSearchRequest = {
1234
+ bounds : options.bounds || null,
1235
+ location : options.location || null,
1236
+ query : options.query || null,
1237
+ radius : options.radius || null
1238
+ };
1239
+
1240
+ layer.textSearch(textSearchRequest, options.textSearch);
1241
+ }
1242
+ break;
1243
+ }
1244
+
1245
+ if (layer !== undefined) {
1246
+ if (typeof layer.setOptions == 'function') {
1247
+ layer.setOptions(options);
1248
+ }
1249
+ if (typeof layer.setMap == 'function') {
1250
+ layer.setMap(this.map);
1251
+ }
1252
+
1253
+ return layer;
1254
+ }
1255
+ };
1256
+
1257
+ GMaps.prototype.removeLayer = function(layer) {
1258
+ if (typeof(layer) == "string" && this.singleLayers[layer] !== undefined) {
1259
+ this.singleLayers[layer].setMap(null);
1260
+
1261
+ delete this.singleLayers[layer];
1262
+ }
1263
+ else {
1264
+ for (var i = 0; i < this.layers.length; i++) {
1265
+ if (this.layers[i] === layer) {
1266
+ this.layers[i].setMap(null);
1267
+ this.layers.splice(i, 1);
1268
+
1269
+ break;
1270
+ }
1271
+ }
1272
+ }
1273
+ };
1274
+
1275
+ var travelMode, unitSystem;
1276
+
1277
+ GMaps.prototype.getRoutes = function(options) {
1278
+ switch (options.travelMode) {
1279
+ case 'bicycling':
1280
+ travelMode = google.maps.TravelMode.BICYCLING;
1281
+ break;
1282
+ case 'transit':
1283
+ travelMode = google.maps.TravelMode.TRANSIT;
1284
+ break;
1285
+ case 'driving':
1286
+ travelMode = google.maps.TravelMode.DRIVING;
1287
+ break;
1288
+ default:
1289
+ travelMode = google.maps.TravelMode.WALKING;
1290
+ break;
1291
+ }
1292
+
1293
+ if (options.unitSystem === 'imperial') {
1294
+ unitSystem = google.maps.UnitSystem.IMPERIAL;
1295
+ }
1296
+ else {
1297
+ unitSystem = google.maps.UnitSystem.METRIC;
1298
+ }
1299
+
1300
+ var base_options = {
1301
+ avoidHighways: false,
1302
+ avoidTolls: false,
1303
+ optimizeWaypoints: false,
1304
+ waypoints: []
1305
+ },
1306
+ request_options = extend_object(base_options, options);
1307
+
1308
+ request_options.origin = /string/.test(typeof options.origin) ? options.origin : new google.maps.LatLng(options.origin[0], options.origin[1]);
1309
+ request_options.destination = /string/.test(typeof options.destination) ? options.destination : new google.maps.LatLng(options.destination[0], options.destination[1]);
1310
+ request_options.travelMode = travelMode;
1311
+ request_options.unitSystem = unitSystem;
1312
+
1313
+ delete request_options.callback;
1314
+ delete request_options.error;
1315
+
1316
+ var self = this,
1317
+ service = new google.maps.DirectionsService();
1318
+
1319
+ service.route(request_options, function(result, status) {
1320
+ if (status === google.maps.DirectionsStatus.OK) {
1321
+ for (var r in result.routes) {
1322
+ if (result.routes.hasOwnProperty(r)) {
1323
+ self.routes.push(result.routes[r]);
1324
+ }
1325
+ }
1326
+
1327
+ if (options.callback) {
1328
+ options.callback(self.routes);
1329
+ }
1330
+ }
1331
+ else {
1332
+ if (options.error) {
1333
+ options.error(result, status);
1334
+ }
1335
+ }
1336
+ });
1337
+ };
1338
+
1339
+ GMaps.prototype.removeRoutes = function() {
1340
+ this.routes = [];
1341
+ };
1342
+
1343
+ GMaps.prototype.getElevations = function(options) {
1344
+ options = extend_object({
1345
+ locations: [],
1346
+ path : false,
1347
+ samples : 256
1348
+ }, options);
1349
+
1350
+ if (options.locations.length > 0) {
1351
+ if (options.locations[0].length > 0) {
1352
+ options.locations = array_flat(array_map([options.locations], arrayToLatLng, false));
1353
+ }
1354
+ }
1355
+
1356
+ var callback = options.callback;
1357
+ delete options.callback;
1358
+
1359
+ var service = new google.maps.ElevationService();
1360
+
1361
+ //location request
1362
+ if (!options.path) {
1363
+ delete options.path;
1364
+ delete options.samples;
1365
+
1366
+ service.getElevationForLocations(options, function(result, status) {
1367
+ if (callback && typeof(callback) === "function") {
1368
+ callback(result, status);
1369
+ }
1370
+ });
1371
+ //path request
1372
+ } else {
1373
+ var pathRequest = {
1374
+ path : options.locations,
1375
+ samples : options.samples
1376
+ };
1377
+
1378
+ service.getElevationAlongPath(pathRequest, function(result, status) {
1379
+ if (callback && typeof(callback) === "function") {
1380
+ callback(result, status);
1381
+ }
1382
+ });
1383
+ }
1384
+ };
1385
+
1386
+ GMaps.prototype.cleanRoute = GMaps.prototype.removePolylines;
1387
+
1388
+ GMaps.prototype.drawRoute = function(options) {
1389
+ var self = this;
1390
+
1391
+ this.getRoutes({
1392
+ origin: options.origin,
1393
+ destination: options.destination,
1394
+ travelMode: options.travelMode,
1395
+ waypoints: options.waypoints,
1396
+ unitSystem: options.unitSystem,
1397
+ error: options.error,
1398
+ callback: function(e) {
1399
+ if (e.length > 0) {
1400
+ self.drawPolyline({
1401
+ path: e[e.length - 1].overview_path,
1402
+ strokeColor: options.strokeColor,
1403
+ strokeOpacity: options.strokeOpacity,
1404
+ strokeWeight: options.strokeWeight
1405
+ });
1406
+
1407
+ if (options.callback) {
1408
+ options.callback(e[e.length - 1]);
1409
+ }
1410
+ }
1411
+ }
1412
+ });
1413
+ };
1414
+
1415
+ GMaps.prototype.travelRoute = function(options) {
1416
+ if (options.origin && options.destination) {
1417
+ this.getRoutes({
1418
+ origin: options.origin,
1419
+ destination: options.destination,
1420
+ travelMode: options.travelMode,
1421
+ waypoints : options.waypoints,
1422
+ unitSystem: options.unitSystem,
1423
+ error: options.error,
1424
+ callback: function(e) {
1425
+ //start callback
1426
+ if (e.length > 0 && options.start) {
1427
+ options.start(e[e.length - 1]);
1428
+ }
1429
+
1430
+ //step callback
1431
+ if (e.length > 0 && options.step) {
1432
+ var route = e[e.length - 1];
1433
+ if (route.legs.length > 0) {
1434
+ var steps = route.legs[0].steps;
1435
+ for (var i=0, step; step=steps[i]; i++) {
1436
+ step.step_number = i;
1437
+ options.step(step, (route.legs[0].steps.length - 1));
1438
+ }
1439
+ }
1440
+ }
1441
+
1442
+ //end callback
1443
+ if (e.length > 0 && options.end) {
1444
+ options.end(e[e.length - 1]);
1445
+ }
1446
+ }
1447
+ });
1448
+ }
1449
+ else if (options.route) {
1450
+ if (options.route.legs.length > 0) {
1451
+ var steps = options.route.legs[0].steps;
1452
+ for (var i=0, step; step=steps[i]; i++) {
1453
+ step.step_number = i;
1454
+ options.step(step);
1455
+ }
1456
+ }
1457
+ }
1458
+ };
1459
+
1460
+ GMaps.prototype.drawSteppedRoute = function(options) {
1461
+ var self = this;
1462
+
1463
+ if (options.origin && options.destination) {
1464
+ this.getRoutes({
1465
+ origin: options.origin,
1466
+ destination: options.destination,
1467
+ travelMode: options.travelMode,
1468
+ waypoints : options.waypoints,
1469
+ error: options.error,
1470
+ callback: function(e) {
1471
+ //start callback
1472
+ if (e.length > 0 && options.start) {
1473
+ options.start(e[e.length - 1]);
1474
+ }
1475
+
1476
+ //step callback
1477
+ if (e.length > 0 && options.step) {
1478
+ var route = e[e.length - 1];
1479
+ if (route.legs.length > 0) {
1480
+ var steps = route.legs[0].steps;
1481
+ for (var i=0, step; step=steps[i]; i++) {
1482
+ step.step_number = i;
1483
+ self.drawPolyline({
1484
+ path: step.path,
1485
+ strokeColor: options.strokeColor,
1486
+ strokeOpacity: options.strokeOpacity,
1487
+ strokeWeight: options.strokeWeight
1488
+ });
1489
+ options.step(step, (route.legs[0].steps.length - 1));
1490
+ }
1491
+ }
1492
+ }
1493
+
1494
+ //end callback
1495
+ if (e.length > 0 && options.end) {
1496
+ options.end(e[e.length - 1]);
1497
+ }
1498
+ }
1499
+ });
1500
+ }
1501
+ else if (options.route) {
1502
+ if (options.route.legs.length > 0) {
1503
+ var steps = options.route.legs[0].steps;
1504
+ for (var i=0, step; step=steps[i]; i++) {
1505
+ step.step_number = i;
1506
+ self.drawPolyline({
1507
+ path: step.path,
1508
+ strokeColor: options.strokeColor,
1509
+ strokeOpacity: options.strokeOpacity,
1510
+ strokeWeight: options.strokeWeight
1511
+ });
1512
+ options.step(step);
1513
+ }
1514
+ }
1515
+ }
1516
+ };
1517
+
1518
+ GMaps.Route = function(options) {
1519
+ this.origin = options.origin;
1520
+ this.destination = options.destination;
1521
+ this.waypoints = options.waypoints;
1522
+
1523
+ this.map = options.map;
1524
+ this.route = options.route;
1525
+ this.step_count = 0;
1526
+ this.steps = this.route.legs[0].steps;
1527
+ this.steps_length = this.steps.length;
1528
+
1529
+ this.polyline = this.map.drawPolyline({
1530
+ path: new google.maps.MVCArray(),
1531
+ strokeColor: options.strokeColor,
1532
+ strokeOpacity: options.strokeOpacity,
1533
+ strokeWeight: options.strokeWeight
1534
+ }).getPath();
1535
+ };
1536
+
1537
+ GMaps.Route.prototype.getRoute = function(options) {
1538
+ var self = this;
1539
+
1540
+ this.map.getRoutes({
1541
+ origin : this.origin,
1542
+ destination : this.destination,
1543
+ travelMode : options.travelMode,
1544
+ waypoints : this.waypoints || [],
1545
+ error: options.error,
1546
+ callback : function() {
1547
+ self.route = e[0];
1548
+
1549
+ if (options.callback) {
1550
+ options.callback.call(self);
1551
+ }
1552
+ }
1553
+ });
1554
+ };
1555
+
1556
+ GMaps.Route.prototype.back = function() {
1557
+ if (this.step_count > 0) {
1558
+ this.step_count--;
1559
+ var path = this.route.legs[0].steps[this.step_count].path;
1560
+
1561
+ for (var p in path){
1562
+ if (path.hasOwnProperty(p)){
1563
+ this.polyline.pop();
1564
+ }
1565
+ }
1566
+ }
1567
+ };
1568
+
1569
+ GMaps.Route.prototype.forward = function() {
1570
+ if (this.step_count < this.steps_length) {
1571
+ var path = this.route.legs[0].steps[this.step_count].path;
1572
+
1573
+ for (var p in path){
1574
+ if (path.hasOwnProperty(p)){
1575
+ this.polyline.push(path[p]);
1576
+ }
1577
+ }
1578
+ this.step_count++;
1579
+ }
1580
+ };
1581
+
1582
+ GMaps.prototype.checkGeofence = function(lat, lng, fence) {
1583
+ return fence.containsLatLng(new google.maps.LatLng(lat, lng));
1584
+ };
1585
+
1586
+ GMaps.prototype.checkMarkerGeofence = function(marker, outside_callback) {
1587
+ if (marker.fences) {
1588
+ for (var i = 0, fence; fence = marker.fences[i]; i++) {
1589
+ var pos = marker.getPosition();
1590
+ if (!this.checkGeofence(pos.lat(), pos.lng(), fence)) {
1591
+ outside_callback(marker, fence);
1592
+ }
1593
+ }
1594
+ }
1595
+ };
1596
+
1597
+ GMaps.prototype.toImage = function(options) {
1598
+ var options = options || {},
1599
+ static_map_options = {};
1600
+
1601
+ static_map_options['size'] = options['size'] || [this.el.clientWidth, this.el.clientHeight];
1602
+ static_map_options['lat'] = this.getCenter().lat();
1603
+ static_map_options['lng'] = this.getCenter().lng();
1604
+
1605
+ if (this.markers.length > 0) {
1606
+ static_map_options['markers'] = [];
1607
+
1608
+ for (var i = 0; i < this.markers.length; i++) {
1609
+ static_map_options['markers'].push({
1610
+ lat: this.markers[i].getPosition().lat(),
1611
+ lng: this.markers[i].getPosition().lng()
1612
+ });
1613
+ }
1614
+ }
1615
+
1616
+ if (this.polylines.length > 0) {
1617
+ var polyline = this.polylines[0];
1618
+
1619
+ static_map_options['polyline'] = {};
1620
+ static_map_options['polyline']['path'] = google.maps.geometry.encoding.encodePath(polyline.getPath());
1621
+ static_map_options['polyline']['strokeColor'] = polyline.strokeColor
1622
+ static_map_options['polyline']['strokeOpacity'] = polyline.strokeOpacity
1623
+ static_map_options['polyline']['strokeWeight'] = polyline.strokeWeight
1624
+ }
1625
+
1626
+ return GMaps.staticMapURL(static_map_options);
1627
+ };
1628
+
1629
+ GMaps.staticMapURL = function(options){
1630
+ var parameters = [],
1631
+ data,
1632
+ static_root = 'http://maps.googleapis.com/maps/api/staticmap';
1633
+
1634
+ if (options.url) {
1635
+ static_root = options.url;
1636
+ delete options.url;
1637
+ }
1638
+
1639
+ static_root += '?';
1640
+
1641
+ var markers = options.markers;
1642
+
1643
+ delete options.markers;
1644
+
1645
+ if (!markers && options.marker) {
1646
+ markers = [options.marker];
1647
+ delete options.marker;
1648
+ }
1649
+
1650
+ var styles = options.styles;
1651
+
1652
+ delete options.styles;
1653
+
1654
+ var polyline = options.polyline;
1655
+ delete options.polyline;
1656
+
1657
+ /** Map options **/
1658
+ if (options.center) {
1659
+ parameters.push('center=' + options.center);
1660
+ delete options.center;
1661
+ }
1662
+ else if (options.address) {
1663
+ parameters.push('center=' + options.address);
1664
+ delete options.address;
1665
+ }
1666
+ else if (options.lat) {
1667
+ parameters.push(['center=', options.lat, ',', options.lng].join(''));
1668
+ delete options.lat;
1669
+ delete options.lng;
1670
+ }
1671
+ else if (options.visible) {
1672
+ var visible = encodeURI(options.visible.join('|'));
1673
+ parameters.push('visible=' + visible);
1674
+ }
1675
+
1676
+ var size = options.size;
1677
+ if (size) {
1678
+ if (size.join) {
1679
+ size = size.join('x');
1680
+ }
1681
+ delete options.size;
1682
+ }
1683
+ else {
1684
+ size = '630x300';
1685
+ }
1686
+ parameters.push('size=' + size);
1687
+
1688
+ if (!options.zoom && options.zoom !== false) {
1689
+ options.zoom = 15;
1690
+ }
1691
+
1692
+ var sensor = options.hasOwnProperty('sensor') ? !!options.sensor : true;
1693
+ delete options.sensor;
1694
+ parameters.push('sensor=' + sensor);
1695
+
1696
+ for (var param in options) {
1697
+ if (options.hasOwnProperty(param)) {
1698
+ parameters.push(param + '=' + options[param]);
1699
+ }
1700
+ }
1701
+
1702
+ /** Markers **/
1703
+ if (markers) {
1704
+ var marker, loc;
1705
+
1706
+ for (var i=0; data=markers[i]; i++) {
1707
+ marker = [];
1708
+
1709
+ if (data.size && data.size !== 'normal') {
1710
+ marker.push('size:' + data.size);
1711
+ delete data.size;
1712
+ }
1713
+ else if (data.icon) {
1714
+ marker.push('icon:' + encodeURI(data.icon));
1715
+ delete data.icon;
1716
+ }
1717
+
1718
+ if (data.color) {
1719
+ marker.push('color:' + data.color.replace('#', '0x'));
1720
+ delete data.color;
1721
+ }
1722
+
1723
+ if (data.label) {
1724
+ marker.push('label:' + data.label[0].toUpperCase());
1725
+ delete data.label;
1726
+ }
1727
+
1728
+ loc = (data.address ? data.address : data.lat + ',' + data.lng);
1729
+ delete data.address;
1730
+ delete data.lat;
1731
+ delete data.lng;
1732
+
1733
+ for(var param in data){
1734
+ if (data.hasOwnProperty(param)) {
1735
+ marker.push(param + ':' + data[param]);
1736
+ }
1737
+ }
1738
+
1739
+ if (marker.length || i === 0) {
1740
+ marker.push(loc);
1741
+ marker = marker.join('|');
1742
+ parameters.push('markers=' + encodeURI(marker));
1743
+ }
1744
+ // New marker without styles
1745
+ else {
1746
+ marker = parameters.pop() + encodeURI('|' + loc);
1747
+ parameters.push(marker);
1748
+ }
1749
+ }
1750
+ }
1751
+
1752
+ /** Map Styles **/
1753
+ if (styles) {
1754
+ for (var i = 0; i < styles.length; i++) {
1755
+ var styleRule = [];
1756
+ if (styles[i].featureType){
1757
+ styleRule.push('feature:' + styles[i].featureType.toLowerCase());
1758
+ }
1759
+
1760
+ if (styles[i].elementType) {
1761
+ styleRule.push('element:' + styles[i].elementType.toLowerCase());
1762
+ }
1763
+
1764
+ for (var j = 0; j < styles[i].stylers.length; j++) {
1765
+ for (var p in styles[i].stylers[j]) {
1766
+ var ruleArg = styles[i].stylers[j][p];
1767
+ if (p == 'hue' || p == 'color') {
1768
+ ruleArg = '0x' + ruleArg.substring(1);
1769
+ }
1770
+ styleRule.push(p + ':' + ruleArg);
1771
+ }
1772
+ }
1773
+
1774
+ var rule = styleRule.join('|');
1775
+ if (rule != '') {
1776
+ parameters.push('style=' + rule);
1777
+ }
1778
+ }
1779
+ }
1780
+
1781
+ /** Polylines **/
1782
+ function parseColor(color, opacity) {
1783
+ if (color[0] === '#'){
1784
+ color = color.replace('#', '0x');
1785
+
1786
+ if (opacity) {
1787
+ opacity = parseFloat(opacity);
1788
+ opacity = Math.min(1, Math.max(opacity, 0));
1789
+ if (opacity === 0) {
1790
+ return '0x00000000';
1791
+ }
1792
+ opacity = (opacity * 255).toString(16);
1793
+ if (opacity.length === 1) {
1794
+ opacity += opacity;
1795
+ }
1796
+
1797
+ color = color.slice(0,8) + opacity;
1798
+ }
1799
+ }
1800
+ return color;
1801
+ }
1802
+
1803
+ if (polyline) {
1804
+ data = polyline;
1805
+ polyline = [];
1806
+
1807
+ if (data.strokeWeight) {
1808
+ polyline.push('weight:' + parseInt(data.strokeWeight, 10));
1809
+ }
1810
+
1811
+ if (data.strokeColor) {
1812
+ var color = parseColor(data.strokeColor, data.strokeOpacity);
1813
+ polyline.push('color:' + color);
1814
+ }
1815
+
1816
+ if (data.fillColor) {
1817
+ var fillcolor = parseColor(data.fillColor, data.fillOpacity);
1818
+ polyline.push('fillcolor:' + fillcolor);
1819
+ }
1820
+
1821
+ var path = data.path;
1822
+ if (path.join) {
1823
+ for (var j=0, pos; pos=path[j]; j++) {
1824
+ polyline.push(pos.join(','));
1825
+ }
1826
+ }
1827
+ else {
1828
+ polyline.push('enc:' + path);
1829
+ }
1830
+
1831
+ polyline = polyline.join('|');
1832
+ parameters.push('path=' + encodeURI(polyline));
1833
+ }
1834
+
1835
+ /** Retina support **/
1836
+ var dpi = window.devicePixelRatio || 1;
1837
+ parameters.push('scale=' + dpi);
1838
+
1839
+ parameters = parameters.join('&');
1840
+ return static_root + parameters;
1841
+ };
1842
+
1843
+ GMaps.prototype.addMapType = function(mapTypeId, options) {
1844
+ if (options.hasOwnProperty("getTileUrl") && typeof(options["getTileUrl"]) == "function") {
1845
+ options.tileSize = options.tileSize || new google.maps.Size(256, 256);
1846
+
1847
+ var mapType = new google.maps.ImageMapType(options);
1848
+
1849
+ this.map.mapTypes.set(mapTypeId, mapType);
1850
+ }
1851
+ else {
1852
+ throw "'getTileUrl' function required.";
1853
+ }
1854
+ };
1855
+
1856
+ GMaps.prototype.addOverlayMapType = function(options) {
1857
+ if (options.hasOwnProperty("getTile") && typeof(options["getTile"]) == "function") {
1858
+ var overlayMapTypeIndex = options.index;
1859
+
1860
+ delete options.index;
1861
+
1862
+ this.map.overlayMapTypes.insertAt(overlayMapTypeIndex, options);
1863
+ }
1864
+ else {
1865
+ throw "'getTile' function required.";
1866
+ }
1867
+ };
1868
+
1869
+ GMaps.prototype.removeOverlayMapType = function(overlayMapTypeIndex) {
1870
+ this.map.overlayMapTypes.removeAt(overlayMapTypeIndex);
1871
+ };
1872
+
1873
+ GMaps.prototype.addStyle = function(options) {
1874
+ var styledMapType = new google.maps.StyledMapType(options.styles, { name: options.styledMapName });
1875
+
1876
+ this.map.mapTypes.set(options.mapTypeId, styledMapType);
1877
+ };
1878
+
1879
+ GMaps.prototype.setStyle = function(mapTypeId) {
1880
+ this.map.setMapTypeId(mapTypeId);
1881
+ };
1882
+
1883
+ GMaps.prototype.createPanorama = function(streetview_options) {
1884
+ if (!streetview_options.hasOwnProperty('lat') || !streetview_options.hasOwnProperty('lng')) {
1885
+ streetview_options.lat = this.getCenter().lat();
1886
+ streetview_options.lng = this.getCenter().lng();
1887
+ }
1888
+
1889
+ this.panorama = GMaps.createPanorama(streetview_options);
1890
+
1891
+ this.map.setStreetView(this.panorama);
1892
+
1893
+ return this.panorama;
1894
+ };
1895
+
1896
+ GMaps.createPanorama = function(options) {
1897
+ var el = getElementById(options.el, options.context);
1898
+
1899
+ options.position = new google.maps.LatLng(options.lat, options.lng);
1900
+
1901
+ delete options.el;
1902
+ delete options.context;
1903
+ delete options.lat;
1904
+ delete options.lng;
1905
+
1906
+ var streetview_events = ['closeclick', 'links_changed', 'pano_changed', 'position_changed', 'pov_changed', 'resize', 'visible_changed'],
1907
+ streetview_options = extend_object({visible : true}, options);
1908
+
1909
+ for (var i = 0; i < streetview_events.length; i++) {
1910
+ delete streetview_options[streetview_events[i]];
1911
+ }
1912
+
1913
+ var panorama = new google.maps.StreetViewPanorama(el, streetview_options);
1914
+
1915
+ for (var i = 0; i < streetview_events.length; i++) {
1916
+ (function(object, name) {
1917
+ if (options[name]) {
1918
+ google.maps.event.addListener(object, name, function(){
1919
+ options[name].apply(this);
1920
+ });
1921
+ }
1922
+ })(panorama, streetview_events[i]);
1923
+ }
1924
+
1925
+ return panorama;
1926
+ };
1927
+
1928
+ GMaps.prototype.on = function(event_name, handler) {
1929
+ return GMaps.on(event_name, this, handler);
1930
+ };
1931
+
1932
+ GMaps.prototype.off = function(event_name) {
1933
+ GMaps.off(event_name, this);
1934
+ };
1935
+
1936
+ GMaps.custom_events = ['marker_added', 'marker_removed', 'polyline_added', 'polyline_removed', 'polygon_added', 'polygon_removed', 'geolocated', 'geolocation_failed'];
1937
+
1938
+ GMaps.on = function(event_name, object, handler) {
1939
+ if (GMaps.custom_events.indexOf(event_name) == -1) {
1940
+ if(object instanceof GMaps) object = object.map;
1941
+ return google.maps.event.addListener(object, event_name, handler);
1942
+ }
1943
+ else {
1944
+ var registered_event = {
1945
+ handler : handler,
1946
+ eventName : event_name
1947
+ };
1948
+
1949
+ object.registered_events[event_name] = object.registered_events[event_name] || [];
1950
+ object.registered_events[event_name].push(registered_event);
1951
+
1952
+ return registered_event;
1953
+ }
1954
+ };
1955
+
1956
+ GMaps.off = function(event_name, object) {
1957
+ if (GMaps.custom_events.indexOf(event_name) == -1) {
1958
+ if(object instanceof GMaps) object = object.map;
1959
+ google.maps.event.clearListeners(object, event_name);
1960
+ }
1961
+ else {
1962
+ object.registered_events[event_name] = [];
1963
+ }
1964
+ };
1965
+
1966
+ GMaps.fire = function(event_name, object, scope) {
1967
+ if (GMaps.custom_events.indexOf(event_name) == -1) {
1968
+ google.maps.event.trigger(object, event_name, Array.prototype.slice.apply(arguments).slice(2));
1969
+ }
1970
+ else {
1971
+ if(event_name in scope.registered_events) {
1972
+ var firing_events = scope.registered_events[event_name];
1973
+
1974
+ for(var i = 0; i < firing_events.length; i++) {
1975
+ (function(handler, scope, object) {
1976
+ handler.apply(scope, [object]);
1977
+ })(firing_events[i]['handler'], scope, object);
1978
+ }
1979
+ }
1980
+ }
1981
+ };
1982
+
1983
+ GMaps.geolocate = function(options) {
1984
+ var complete_callback = options.always || options.complete;
1985
+
1986
+ if (navigator.geolocation) {
1987
+ navigator.geolocation.getCurrentPosition(function(position) {
1988
+ options.success(position);
1989
+
1990
+ if (complete_callback) {
1991
+ complete_callback();
1992
+ }
1993
+ }, function(error) {
1994
+ options.error(error);
1995
+
1996
+ if (complete_callback) {
1997
+ complete_callback();
1998
+ }
1999
+ }, options.options);
2000
+ }
2001
+ else {
2002
+ options.not_supported();
2003
+
2004
+ if (complete_callback) {
2005
+ complete_callback();
2006
+ }
2007
+ }
2008
+ };
2009
+
2010
+ GMaps.geocode = function(options) {
2011
+ this.geocoder = new google.maps.Geocoder();
2012
+ var callback = options.callback;
2013
+ if (options.hasOwnProperty('lat') && options.hasOwnProperty('lng')) {
2014
+ options.latLng = new google.maps.LatLng(options.lat, options.lng);
2015
+ }
2016
+
2017
+ delete options.lat;
2018
+ delete options.lng;
2019
+ delete options.callback;
2020
+
2021
+ this.geocoder.geocode(options, function(results, status) {
2022
+ callback(results, status);
2023
+ });
2024
+ };
2025
+
2026
+ //==========================
2027
+ // Polygon containsLatLng
2028
+ // https://github.com/tparkin/Google-Maps-Point-in-Polygon
2029
+ // Poygon getBounds extension - google-maps-extensions
2030
+ // http://code.google.com/p/google-maps-extensions/source/browse/google.maps.Polygon.getBounds.js
2031
+ if (!google.maps.Polygon.prototype.getBounds) {
2032
+ google.maps.Polygon.prototype.getBounds = function(latLng) {
2033
+ var bounds = new google.maps.LatLngBounds();
2034
+ var paths = this.getPaths();
2035
+ var path;
2036
+
2037
+ for (var p = 0; p < paths.getLength(); p++) {
2038
+ path = paths.getAt(p);
2039
+ for (var i = 0; i < path.getLength(); i++) {
2040
+ bounds.extend(path.getAt(i));
2041
+ }
2042
+ }
2043
+
2044
+ return bounds;
2045
+ };
2046
+ }
2047
+
2048
+ if (!google.maps.Polygon.prototype.containsLatLng) {
2049
+ // Polygon containsLatLng - method to determine if a latLng is within a polygon
2050
+ google.maps.Polygon.prototype.containsLatLng = function(latLng) {
2051
+ // Exclude points outside of bounds as there is no way they are in the poly
2052
+ var bounds = this.getBounds();
2053
+
2054
+ if (bounds !== null && !bounds.contains(latLng)) {
2055
+ return false;
2056
+ }
2057
+
2058
+ // Raycast point in polygon method
2059
+ var inPoly = false;
2060
+
2061
+ var numPaths = this.getPaths().getLength();
2062
+ for (var p = 0; p < numPaths; p++) {
2063
+ var path = this.getPaths().getAt(p);
2064
+ var numPoints = path.getLength();
2065
+ var j = numPoints - 1;
2066
+
2067
+ for (var i = 0; i < numPoints; i++) {
2068
+ var vertex1 = path.getAt(i);
2069
+ var vertex2 = path.getAt(j);
2070
+
2071
+ if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) {
2072
+ if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) {
2073
+ inPoly = !inPoly;
2074
+ }
2075
+ }
2076
+
2077
+ j = i;
2078
+ }
2079
+ }
2080
+
2081
+ return inPoly;
2082
+ };
2083
+ }
2084
+
2085
+ if (!google.maps.Circle.prototype.containsLatLng) {
2086
+ google.maps.Circle.prototype.containsLatLng = function(latLng) {
2087
+ if (google.maps.geometry) {
2088
+ return google.maps.geometry.spherical.computeDistanceBetween(this.getCenter(), latLng) <= this.getRadius();
2089
+ }
2090
+ else {
2091
+ return true;
2092
+ }
2093
+ };
2094
+ }
2095
+
2096
+ google.maps.LatLngBounds.prototype.containsLatLng = function(latLng) {
2097
+ return this.contains(latLng);
2098
+ };
2099
+
2100
+ google.maps.Marker.prototype.setFences = function(fences) {
2101
+ this.fences = fences;
2102
+ };
2103
+
2104
+ google.maps.Marker.prototype.addFence = function(fence) {
2105
+ this.fences.push(fence);
2106
+ };
2107
+
2108
+ google.maps.Marker.prototype.getId = function() {
2109
+ return this['__gm_id'];
2110
+ };
2111
+
2112
+ //==========================
2113
+ // Array indexOf
2114
+ // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf
2115
+ if (!Array.prototype.indexOf) {
2116
+ Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
2117
+ "use strict";
2118
+ if (this == null) {
2119
+ throw new TypeError();
2120
+ }
2121
+ var t = Object(this);
2122
+ var len = t.length >>> 0;
2123
+ if (len === 0) {
2124
+ return -1;
2125
+ }
2126
+ var n = 0;
2127
+ if (arguments.length > 1) {
2128
+ n = Number(arguments[1]);
2129
+ if (n != n) { // shortcut for verifying if it's NaN
2130
+ n = 0;
2131
+ } else if (n != 0 && n != Infinity && n != -Infinity) {
2132
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
2133
+ }
2134
+ }
2135
+ if (n >= len) {
2136
+ return -1;
2137
+ }
2138
+ var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
2139
+ for (; k < len; k++) {
2140
+ if (k in t && t[k] === searchElement) {
2141
+ return k;
2142
+ }
2143
+ }
2144
+ return -1;
2145
+ }
2146
+ }
2147
+
2148
+ return GMaps;
2149
+ }));