flashoff 0.0.1

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