PageSourceSearch

https://seeds.ca/app/ev/dist/jquery.vmap.js

js seeds.ca collected 2026-09-24 19:49:15 UTC 34,341 bytes, 1,289 lines download raw bytes

1/*!
2 * JQVMap: jQuery Vector Map Library
3 * @author JQVMap <[email protected]>
4 * @version 1.5.1
5 * @link http://jqvmap.com
6 * @license https://github.com/manifestinteractive/jqvmap/blob/master/LICENSE
7 * @builddate 2016/06/02
8 */
9
10var VectorCanvas = function (width, height, params) {
11  this.mode = window.SVGAngle ? 'svg' : 'vml';
12  this.params = params;
13
14  if (this.mode === 'svg') {
15    this.createSvgNode = function (nodeName) {
16      return document.createElementNS(this.svgns, nodeName);
17    };
18  } else {
19    try {
20      if (!document.namespaces.rvml) {
21        document.namespaces.add('rvml', 'urn:schemas-microsoft-com:vml');
22      }
23      this.createVmlNode = function (tagName) {
24        return document.createElement('<rvml:' + tagName + ' class="rvml">');
25      };
26    } catch (e) {
27      this.createVmlNode = function (tagName) {
28        return document.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
29      };
30    }
31
32    document.createStyleSheet().addRule('.rvml', 'behavior:url(#default#VML)');
33  }
34
35  if (this.mode === 'svg') {
36    this.canvas = this.createSvgNode('svg');
37  } else {
38    this.canvas = this.createVmlNode('group');
39    this.canvas.style.position = 'absolute';
40  }
41
42  this.setSize(width, height);
43};
44
45VectorCanvas.prototype = {
46  svgns: 'http://www.w3.org/2000/svg',
47  mode: 'svg',
48  width: 0,
49  height: 0,
50  canvas: null
51};
52
53var ColorScale = function (colors, normalizeFunction, minValue, maxValue) {
54  if (colors) {
55    this.setColors(colors);
56  }
57  if (normalizeFunction) {
58    this.setNormalizeFunction(normalizeFunction);
59  }
60  if (minValue) {
61    this.setMin(minValue);
62  }
63  if (minValue) {
64    this.setMax(maxValue);
65  }
66};
67
68ColorScale.prototype = {
69  colors: []
70};
71
72var JQVMap = function (params) {
73  params = params || {};
74  var map = this;
75  var mapData = JQVMap.maps[params.map];
76  var mapPins;
77
78  if( !mapData){
79    throw new Error('Invalid "' + params.map + '" map parameter. Please make sure you have loaded this map file in your HTML.');
80  }
81
82  this.selectedRegions = [];
83  this.multiSelectRegion = params.multiSelectRegion;
84
85  this.container = params.container;
86
87  this.defaultWidth = mapData.width;
88  this.defaultHeight = mapData.height;
89
90  this.color = params.color;
91  this.selectedColor = params.selectedColor;
92  this.hoverColor = params.hoverColor;
93  this.hoverColors = params.hoverColors;
94  this.hoverOpacity = params.hoverOpacity;
95  this.setBackgroundColor(params.backgroundColor);
96
97  this.width = params.container.width();
98  this.height = params.container.height();
99
100  this.resize();
101
102  jQuery(window).resize(function () {
103    var newWidth = params.container.width();
104    var newHeight = params.container.height();
105
106    if(newWidth && newHeight){
107      map.width = newWidth;
108      map.height = newHeight;
109      map.resize();
110      map.canvas.setSize(map.width, map.height);
111      map.applyTransform();
112
113      var resizeEvent = jQuery.Event('resize.jqvmap');
114      jQuery(params.container).trigger(resizeEvent, [newWidth, newHeight]);
115
116      if(mapPins){
117        jQuery('.jqvmap-pin').remove();
118        map.pinHandlers = false;
119        map.placePins(mapPins.pins, mapPins.mode);
120      }
121    }
122  });
123
124  this.canvas = new VectorCanvas(this.width, this.height, params);
125  params.container.append(this.canvas.canvas);
126
127  this.makeDraggable();
128
129  this.rootGroup = this.canvas.createGroup(true);
130
131  this.index = JQVMap.mapIndex;
132  this.label = jQuery('<div/>').addClass('jqvmap-label').appendTo(jQuery('body')).hide();
133
134  if (params.enableZoom) {
135    jQuery('<div/>').addClass('jqvmap-zoomin').text('+').appendTo(params.container);
136    jQuery('<div/>').addClass('jqvmap-zoomout').html('&#x2212;').appendTo(params.container);
137  }
138
139  map.countries = [];
140
141  for (var key in mapData.paths) {
142    var path = this.canvas.createPath({
143      path: mapData.paths[key].path
144    });
145
146    path.setFill(this.color);
147    path.id = map.getCountryId(key);
148    map.countries[key] = path;
149
150    if (this.canvas.mode === 'svg') {
151      path.setAttribute('class', 'jqvmap-region');
152    } else {
153      jQuery(path).addClass('jqvmap-region');
154    }
155
156    jQuery(this.rootGroup).append(path);
157  }
158
159  jQuery(params.container).delegate(this.canvas.mode === 'svg' ? 'path' : 'shape', 'mouseover mouseout', function (e) {
160    var containerPath = e.target,
161      code = e.target.id.split('_').pop(),
162      labelShowEvent = jQuery.Event('labelShow.jqvmap'),
163      regionMouseOverEvent = jQuery.Event('regionMouseOver.jqvmap');
164
165    code = code.toLowerCase();
166
167    if (e.type === 'mouseover') {
168      jQuery(params.container).trigger(regionMouseOverEvent, [code, mapData.paths[code].name]);
169      if (!regionMouseOverEvent.isDefaultPrevented()) {
170        map.highlight(code, containerPath);
171      }
172      if (params.showTooltip) {
173        map.label.text(mapData.paths[code].name);
174        jQuery(params.container).trigger(labelShowEvent, [map.label, code]);
175
176        if (!labelShowEvent.isDefaultPrevented()) {
177          map.label.show();
178          map.labelWidth = map.label.width();
179          map.labelHeight = map.label.height();
180        }
181      }
182    } else {
183      map.unhighlight(code, containerPath);
184
185      map.label.hide();
186      jQuery(params.container).trigger('regionMouseOut.jqvmap', [code, mapData.paths[code].name]);
187    }
188  });
189
190  jQuery(params.container).delegate(this.canvas.mode === 'svg' ? 'path' : 'shape', 'click', function (regionClickEvent) {
191
192    var targetPath = regionClickEvent.target;
193    var code = regionClickEvent.target.id.split('_').pop();
194    var mapClickEvent = jQuery.Event('regionClick.jqvmap');
195
196    code = code.toLowerCase();
197
198    jQuery(params.container).trigger(mapClickEvent, [code, mapData.paths[code].name]);
199
200    if ( !params.multiSelectRegion && !mapClickEvent.isDefaultPrevented()) {
201      for (var keyPath in mapData.paths) {
202        map.countries[keyPath].currentFillColor = map.countries[keyPath].getOriginalFill
202();
203        map.countries[keyPath].setFill(map.countries[keyPath].getOriginalFill());
204      }
205    }
206
207    if ( !mapClickEvent.isDefaultPrevented()) {
208      if (map.isSelected(code)) {
209        map.deselect(code, targetPath);
210      } else {
211        map.select(code, targetPath);
212      }
213    }
214  });
215
216  if (params.showTooltip) {
217    params.container.mousemove(function (e) {
218      if (map.label.is(':visible')) {
219        var left = e.pageX - 15 - map.labelWidth;
220        var top = e.pageY - 15 - map.labelHeight;
221
222        if(left < 0) {
223          left = e.pageX + 15;
224        }
225        if(top < 0) {
226          top = e.pageY + 15;
227        }
228
229        map.label.css({
230          left: left,
231          top: top
232        });
233      }
234    });
235  }
236
237  this.setColors(params.colors);
238
239  this.canvas.canvas.appendChild(this.rootGroup);
240
241  this.applyTransform();
242
243  this.colorScale = new ColorScale(params.scaleColors, params.normalizeFunction, params.valueMin, params.valueMax);
244
245  if (params.values) {
246    this.values = params.values;
247    this.setValues(params.values);
248  }
249
250  if (params.selectedRegions) {
251    if (params.selectedRegions instanceof Array) {
252      for(var k in params.selectedRegions) {
253        this.select(params.selectedRegions[k].toLowerCase());
254      }
255    } else {
256      this.select(params.selectedRegions.toLowerCase());
257    }
258  }
259
260  this.bindZoomButtons();
261
262  if(params.pins) {
263    mapPins = {
264      pins: params.pins,
265      mode: params.pinMode
266    };
267
268    this.pinHandlers = false;
269    this.placePins(params.pins, params.pinMode);
270  }
271
272  if(params.showLabels){
273    this.pinHandlers = false;
274
275    var pins = {};
276    for (key in map.countries){
277      if (typeof map.countries[key] !== 'function') {
278        if( !params.pins || !params.pins[key] ){
279          pins[key] = key.toUpperCase();
280        }
281      }
282    }
283
284    mapPins = {
285      pins: pins,
286      mode: 'content'
287    };
288
289    this.placePins(pins, 'content');
290  }
291
292  JQVMap.mapIndex++;
293};
294
295JQVMap.prototype = {
296  transX: 0,
297  transY: 0,
298  scale: 1,
299  baseTransX: 0,
300  baseTransY: 0,
301  baseScale: 1,
302  width: 0,
303  height: 0,
304  countries: {},
305  countriesColors: {},
306  countriesData: {},
307  zoomStep: 1.4,
308  zoomMaxStep: 4,
309  zoomCurStep: 1
310};
311
312JQVMap.xlink = 'http://www.w3.org/1999/xlink';
313JQVMap.mapIndex = 1;
314JQVMap.maps = {};
315
316(function(){
317
318  var apiParams = {
319    colors: 1,
320    values: 1,
321    backgroundColor: 1,
322    scaleColors: 1,
323    normalizeFunction: 1,
324    enableZoom: 1,
325    showTooltip: 1,
326    borderColor: 1,
327    borderWidth: 1,
328    borderOpacity: 1,
329    selectedRegions: 1,
330    multiSelectRegion: 1
331  };
332
333  var apiEvents = {
334    onLabelShow: 'labelShow',
335    onLoad: 'load',
336    onRegionOver: 'regionMouseOver',
337    onRegionOut: 'regionMouseOut',
338    onRegionClick: 'regionClick',
339    onRegionSelect: 'regionSelect',
340    onRegionDeselect: 'regionDeselect',
341    onResize: 'resize'
342  };
343
344  jQuery.fn.vectorMap = function (options) {
345
346    var defaultParams = {
347      map: 'world_en',
348      backgroundColor: '#a5bfdd',
349      color: '#f4f3f0',
350      hoverColor: '#c9dfaf',
351      hoverColors: {},
352      selectedColor: '#c9dfaf',
353      scaleColors: ['#b6d6ff', '#005ace'],
354      normalizeFunction: 'linear',
355      enableZoom: true,
356      showTooltip: true,
357      borderColor: '#818181',
358      borderWidth: 1,
359      borderOpacity: 0.25,
360      selectedRegions: null,
361      multiSelectRegion: false
362    }, map = this.data('mapObject');
363
364    if (options === 'addMap') {
365      JQVMap.maps[arguments[1]] = arguments[2];
366    } else if (options === 'set' && apiParams[arguments[1]]) {
367      map['set' + arguments[1].charAt(0).toUpperCase() + arguments[1].substr(1)].apply(map, Array.prototype.slice.call(arguments, 2));
368    } else if (typeof options === 'string' &&
369      typeof map[options] === 'function') {
370      return map[options].apply(map, Array.prototype.slice.call(arguments, 1));
371    } else {
372      jQuery.extend(defaultParams, options);
373      defaultParams.container = this;
374      this.css({ position: 'relative', overflow: 'hidden' });
375
376      map = new JQVMap(defaultParams);
377
378      this.data('mapObject', map);
379
380      this.unbind('.jqvmap');
381
382      for (var e in apiEvents) {
383        if (defaultParams[e]) {
384          this.bind(apiEvents[e] + '.jqvmap', defaultParams[e]);
385        }
386      }
387
388      var loadEvent = jQuery.Event('load.jqvmap');
389      jQuery(defaultParams.container).trigger(loadEvent, map);
390
391      return map;
392    }
393  };
394
395})(jQuery);
396
397ColorScale.arrayToRgb = function (ar) {
398  var rgb = '#';
399  var d;
400  for (var i = 0; i < ar.length; i++) {
401    d = ar[i].toString(16);
402    rgb += d.length === 1 ? '0' + d : d;
403  }
404  return rgb;
405};
406
407ColorScale.prototype.getColor = function (value) {
408  if (typeof this.normalize === 'function') {
409    value = this.normalize(value);
410  }
411
412  var lengthes = [];
413  var fullLength = 0;
414  var l;
415
416  for (var i = 0; i < this.colors.length - 1; i++) {
417    l = this.vectorLength(this.vectorSubtract(this.colors[i + 1], this.colors[i]));
418    lengthes.push(l);
419    fullLength += l;
420  }
421
422  var c = (this.maxValue - this.minValue) / fullLength;
423
424  for (i = 0; i < lengthes.length; i++) {
425    lengthes[i] *= c;
426  }
427
428  i = 0;
429  value -= this.minValue;
430
431  while (value - lengthes[i] >= 0) {
432    value -= lengthes[i];
433    i++;
434  }
435
436  var color;
437  if (i === this.colors.length - 1) {
438    color = this.vectorToNum(this.colors[i]).toString(16);
439  } else {
440    color = (this.vectorToNum(this.vectorAdd(this.colors[i], this.vectorMult(this.vectorSubtract(this.colors[i + 1], this.colors[i]), (value) / (lengthes[i]))))).toString(16);
441  }
442
443  while (color.length < 6) {
444    color = '0' + color;
445  }
446  return '#' + color;
447};
448
449ColorScale.rgbToArray = function (rgb) {
450  rgb = rgb.substr(1);
451  return [parseInt(rgb.substr(0, 2), 16), parseInt(rgb.substr(2, 2), 16), parseInt(rgb.substr(4, 2), 16)];
452};
453
454ColorScale.prototype.setColors = function (colors) {
455  for (var i = 0; i < colors.length; i++) {
456    colors[i] = ColorScale.rgbToArray(colors[i]);
457  }
458  this.colors = colors;
459};
460
461ColorScale.prototype.setMax = function (max) {
462  this.clearMaxValue = max;
463  if (typeof this.normalize === 'function') {
464    this.maxValue = this.normalize(max);
465  } else {
466    this.maxValue = max;
467  }
468};
469
470ColorScale.prototype.setMin = function (min) {
471  this.clearMinValue = min;
472
473  if (typeof this.normalize === 'function') {
474    this.minValue = this.normalize(min);
475  } else {
476    this.minValue = min;
477  }
478};
479
480ColorScale.prototype.setNormalizeFunction = function (f) {
481  if (f === 'polynomial') {
482    this.normalize = function (value) {
483      return Math.pow(value, 0.2);
484    };
485  } else if (f === 'linear') {
486    delete this.normalize;
487  } else {
488    this.normalize = f;
489  }
490  this.setMin(this.clearMinValue);
491  this.setMax(this.clearMaxValue);
492};
493
494ColorScale.prototype.vectorAdd = function (vector1, vector2) {
495  var vector = [];
496  for (var i = 0; i < vector1.length; i++) {
497    vector[i] = vector1[i] + vector2[i];
498  }
499  return vector;
500};
501
502ColorScale.prototype.vectorLength = function (vector) {
503  var result = 0;
504  for (var i = 0; i < vector.length; i++) {
505    result += vector[i] * vector[i];
506  }
507  return Math.sqrt(result);
508};
509
510ColorScale.prototype.vectorMult = function (vector, num) {
511  var result = [];
512  for (var i = 0; i < vector.length; i++) {
513    result[i] = vector[i] * num;
514  }
515  return result;
516};
517
518ColorScale.prototype.vectorSubtract = function (vector1, vector2) {
519  var vector = [];
520  for (var i = 0; i < vector1.length; i++) {
521    vector[i] = vector1[i] - vector2[i];
522  }
523  return vector;
524};
525
526ColorScale.prototype.vectorToNum = function (vector) {
527  var num = 0;
528  for (var i = 0; i < vector.length; i++) {
529    num += Math.round(vector[i]) * Math.pow(256, vector.length - i - 1);
530  }
531  return num;
532};
533
534JQVMap.prototype.applyTransform = function () {
535  var maxTransX, maxTransY, minTransX, minTransY;
536  if (this.defaultWidth * this.scale <= this.width) {
537    maxTransX = (this.width - this.defaultWidth * this.scale) / (2 * this.scale);
538    minTransX = (this.width - this.defaultWidth * this.scale) / (2 * this.scale);
539  } else {
540    maxTransX = 0;
541    minTransX = (this.width - this.defaultWidth * this.scale) / this.scale;
542  }
543
544  if (this.defaultHeight * this.scale <= this.height) {
545    maxTransY = (this.height - this.defaultHeight * this.scale) / (2 * this.scale);
546    minTransY = (this.height - this.defaultHeight * this.scale) / (2 * this.scale);
547  } else {
548    maxTransY = 0;
549    minTransY = (this.height - this.defaultHeight * this.scale) / this.scale;
550  }
551
552  if (this.transY > maxTransY) {
553    this.transY = maxTransY;
554  } else if (this.transY < minTransY) {
555    this.transY = minTransY;
556  }
557  if (this.transX > maxTransX) {
558    this.transX = maxTransX;
559  } else if (this.transX < minTransX) {
560    this.transX = minTransX;
561  }
562
563  this.canvas.applyTransformParams(this.scale, this.transX, this.transY);
564};
565
566JQVMap.prototype.bindZoomButtons = function () {
567  var map = this;
568  this.container.find('.jqvmap-zoomin').click(function(){
569    map.zoomIn();
570  });
571  this.container.find('.jqvmap-zoomout').click(function(){
572    map.zoomOut();
573  });
574};
575
576JQVMap.prototype.deselect = function (cc, path) {
577  cc = cc.toLowerCase();
578  path = path || jQuery('#' + this.getCountryId(cc))[0];
579
580  if (this.isSelected(cc)) {
581    this.selectedRegions.splice(this.selectIndex(cc), 1);
582
583    jQuery(this.container).trigger('regionDeselect.jqvmap', [cc]);
584    path.currentFillColor = path.getOriginalFill();
585    path.setFill(path.getOriginalFill());
586  } else {
587    for (var key in this.countries) {
588      this.selectedRegions.splice(this.selectedRegions.indexOf(key), 1);
589      this.countries[key].currentFillColor = this.color;
590      this.countries[key].setFill(this.color);
591    }
592  }
593};
594
595JQVMap.prototype.getCountryId = function (cc) {
596  return 'jqvmap' + this.index + '_' + cc;
597};
598
599JQVMap.prototype.getPin = function(cc){
600  var pinObj = jQuery('#' + this.getPinId(cc));
601  return pinObj.html();
602};
603
604JQVMap.prototype.getPinId = function (cc) {
605  return this.getCountryId(cc) + '_pin';
606};
607
608JQVMap.prototype.getPins = function(){
609  var pins = this.container.find('.jqvmap-pin');
610  var ret = {};
611  jQuery.each(pins, function(index, pinObj){
612    pinObj = jQuery(pinObj);
613    var cc = pinObj.attr('for').toLowerCase();
614    var pinContent = pinObj.html();
615    ret[cc] = pinContent;
616  });
617  return JSON.stringify(ret);
618};
619
620JQVMap.prototype.highlight = function (cc, path) {
621  path = path || jQuery('#' + this.getCountryId(cc))[0];
622  if (this.hoverOpacity) {
623    path.setOpacity(this.hoverOpacity);
624  } else if (this.hoverColors && (cc in this.hoverColors)) {
625    path.currentFillColor = path.getFill() + '';
626    path.setFill(this.hoverColors[cc]);
627  } else if (this.hoverColor) {
628    path.currentFillColor = path.getFill() + '';
629    path.setFill(this.hoverColor);
630  }
631};
632
633JQVMap.prototype.isSelected = function(cc) {
634  return this.selectIndex(cc) >= 0;
635};
636
637JQVMap.prototype.makeDraggable = function () {
638  var mouseDown = false;
639  var oldPageX, oldPageY;
640  var self = this;
641
642  self.isMoving = false;
643  self.isMovingTimeout = false;
644
645  var lastTouchCount;
646  var touchCenterX;
647  var touchCenterY;
648  var touchStartDistance;
649  var touchStartScale;
650  var touchX;
651  var touchY;
652
653  this.container.mousemove(function (e) {
654
655    if (mouseDown) {
656      self.transX -= (oldPageX - e.pageX) / self.scale;
657      self.transY -= (oldPageY - e.pageY) / self.scale;
658
659      self.applyTransform();
660
661      oldPageX = e.pageX;
662      oldPageY = e.pageY;
663
664      self.isMoving = true;
665      if (self.isMovingTimeout) {
666        clearTimeout(self.isMovingTimeout);
667      }
668
669      self.container.trigger('drag');
670    }
671
672    return false;
673
674  }).mousedown(function (e) {
675
676    mouseDown = true;
677    oldPageX = e.pageX;
678    oldPageY = e.pageY;
679
680    return false;
681
682  }).mouseup(function () {
683
684    mouseDown = false;
685
686    clearTimeout(self.isMovingTimeout);
687    self.isMovingTimeout = setTimeout(function () {
688      self.isMoving = false;
689    }, 100);
690
691    return false;
692
693  }).mouseout(function () {
694
695    if(mouseDown && self.isMoving){
696
697      clearTimeout(self.isMovingTimeout);
698      self.isMovingTimeout = setTimeout(function () {
699        mouseDown = false;
700        self.isMoving = false;
701      }, 100);
702
703      return false;
704    }
705  });
706
707  jQuery(this.container).bind('touchmove', function (e) {
708
709    var offset;
710    var scale;
711    var touches = e.originalEvent.touches;
712    var transformXOld;
713    var transformYOld;
714
715    if (touches.length === 1) {
716      if (lastTouchCount === 1) {
717
718        if(touchX === touches[0].pageX && touchY === touches[0].pageY){
719          return;
720        }
721
722        transformXOld = self.transX;
723        transformYOld = self.transY;
724
725        self.transX -= (touchX - touches[0].pageX) / self.scale;
726        self.transY -= (touchY - touches[0].pageY) / self.scale;
727
728        self.applyTransform();
729
730        if (transformXOld !== self.transX || transformYOld !== self.transY) {
731          e.preventDefault();
732        }
733
734        self.isMoving = true;
735        if (self.isMovingTimeout) {
736          clearTimeout(self.isMovingTimeout);
737        }
738      }
739
740      touchX = touches[0].pageX;
741      touchY = touches[0].pageY;
742
743    } else if (touches.length === 2) {
744
745      if (lastTouchCount === 2) {
746        scale = Math.sqrt(
747            Math.pow(touches[0].pageX - touches[1].pageX, 2) +
748            Math.pow(touches[0].pageY - touches[1].pageY, 2)
749          ) / touchStartDistance;
750
751        self.setScale(
752          touchStartScale * scale,
753          touchCenterX,
754          touchCenterY
755        );
756
757        e.preventDefault();
758
759      } else {
760
761        offset = jQuery(self.container).offset();
762        if (touches[0].pageX > touches[1].pageX) {
763          touchCenterX = touches[1].pageX + (touches[0].pageX - touches[1].pageX) / 2;
764        } else {
765          touchCenterX = touches[0].pageX + (touches[1].pageX - touches[0].pageX) / 2;
766        }
767
768        if (touches[0].pageY > touches[1].pageY) {
769          touchCenterY = touches[1].pageY + (touches[0].pageY - touches[1].pageY) / 2;
770        } else {
771          touchCenterY = touches[0].pageY + (touches[1].pageY - touches[0].pageY) / 2;
772        }
773
774        touchCenterX -= offset.left;
775        touchCenterY -= offset.top;
776        touchStartScale = self.scale;
777
778        touchStartDistance = Math.sqrt(
779          Math.pow(touches[0].pageX - touches[1].pageX, 2) +
780          Math.pow(touches[0].pageY - touches[1].pageY, 2)
781        );
782      }
783    }
784
785    lastTouchCount = touches.length;
786  });
787
788  jQuery(this.container).bind('touchstart', function () {
789    lastTouchCount = 0;
790  });
791
792  jQuery(this.container).bind('touchend', function () {
793    lastTouchCount = 0;
794  });
795};
796
797JQVMap.prototype.placePins = function(pins, pinMode){
798  var map = this;
799
800  if(!pinMode || (pinMode !== 'content' && pinMode !== 'id')) {
801    pinMode = 'content';
802  }
803
804  if(pinMode === 'content') {//treat pin as content
805    jQuery.each(pins, function(index, pin){
806      if(jQuery('#' + map.getCountryId(index)).length === 0){
807        return;
808      }
809
810      var pinIndex = map.getPinId(index);
811      var $pin = jQuery('#' + pinIndex);
812      if($pin.length > 0){
813        $pin.remove();
814      }
815      map.container.append('<div id="' + pinIndex + '" for="' + index + '" class="jqvmap-pin" style="position:absolute">' + pin + '</div>');
816    });
817  } else { //treat pin as id of an html content
818    jQuery.each(pins, function(index, pin){
819      if(jQuery('#' + map.getCountryId(index)).length === 0){
820        return;
821      }
822      var pinIndex = map.getPinId(index);
823      var $pin = jQuery('#' + pinIndex);
824      if($pin.length > 0){
825        $pin.remove();
826      }
827      map.container.append('<div id="' + pinIndex + '" for="' + index + '" class="jqvmap-pin" style="position:absolute"></div>');
828      $pin.append(jQuery('#' + pin));
829    });
830  }
831
832  this.positionPins();
833  if(!this.pinHandlers){
834    this.pinHandlers = true;
835    var positionFix = function(){
836      map.positionPins();
837    };
838    this.container.bind('zoomIn', positionFix)
839      .bind('zoomOut', positionFix)
840      .bind('drag', positionFix);
841  }
842};
843
844JQVMap.prototype.positionPins = function(){
845  var map = this;
846  var pins = this.container.find('.jqvmap-pin');
847  jQuery.each(pins, function(index, pinObj){
848    pinObj = jQuery(pinObj);
849    var countryId = map.getCountryId(pinObj.attr('for').toLowerCase());
850    var countryObj = jQuery('#' + countryId);
851    var bbox = countryObj[0].getBBox();
852
853    var scale = map.scale;
854    var rootCoords = map.canvas.rootGroup.getBoundingClientRect();
855    var mapCoords = map.container[0].getBoundingClientRect();
856    var coords = {
857      left: rootCoords.left - mapCoords.left,
858      top: rootCoords.top - mapCoords.top
859    };
860
861    var middleX = (bbox.x * scale) + ((bbox.width * scale) / 2);
862    var middleY = (bbox.y * scale) + ((bbox.height * scale) / 2);
863
864    pinObj.css({
865      left: coords.left + middleX - (pinObj.width() / 2),
866      top: coords.top + middleY - (pinObj.height() / 2)
867    });
868  });
869};
870
871JQVMap.prototype.removePin = function(cc) {
872  cc = cc.toLowerCase();
873  jQuery('#' + this.getPinId(cc)).remove();
874};
875
876JQVMap.prototype.removePins = function(){
877  this.container.find('.jqvmap-pin').remove();
878};
879
880JQVMap.prototype.reset = function () {
881  for (var key in this.countries) {
882    this.countries[key].setFill(this.color);
883  }
884  this.scale = this.baseScale;
885  this.transX = this.baseTransX;
886  this.transY = this.baseTransY;
887  this.applyTransform();
888  this.zoomCurStep = 1;
889};
890
891JQVMap.prototype.resize = function () {
892  var curBaseScale = this.baseScale;
893  if (this.width / this.height > this.defaultWidth / this.defaultHeight) {
894    this.baseScale = this.height / this.defaultHeight;
895    this.baseTransX = Math.abs(this.width - this.defaultWidth * this.baseScale) / (2 * this.baseScale);
896  } else {
897    this.baseScale = this.width / this.defaultWidth;
898    this.baseTransY = Math.abs(this.height - this.defaultHeight * this.baseScale) / (2 * this.baseScale);
899  }
900  this.scale *= this.baseScale / curBaseScale;
901  this.transX *= this.baseScale / curBaseScale;
902  this.transY *= this.baseScale / curBaseScale;
903};
904
905JQVMap.prototype.select = function (cc, path) {
906  cc = cc.toLowerCase();
907  path = path || jQuery('#' + this.getCountryId(cc))[0];
908
909  if (!this.isSelected(cc)) {
910    if (this.multiSelectRegion) {
911      this.selectedRegions.push(cc);
912    } else {
913      this.selectedRegions = [cc];
914    }
915
916    jQuery(this.container).trigger('regionSelect.jqvmap', [cc]);
917    if (this.selectedColor && path) {
918      path.currentFillColor = this.selectedColor;
919      path.setFill(this.selectedColor);
920    }
921  }
922};
923
924JQVMap.prototype.selectIndex = function (cc) {
925  cc = cc.toLowerCase();
926  for (var i = 0; i < this.selectedRegions.length; i++) {
927    if (cc === this.selectedRegions[i]) {
928      return i;
929    }
930  }
931  return -1;
932};
933
934JQVMap.prototype.setBackgroundColor = function (backgroundColor) {
935  this.container.css('background-color', backgroundColor);
936};
937
938JQVMap.prototype.setColors = function (key, color) {
939  if (typeof key === 'string') {
940    this.countries[key].setFill(color);
941    this.countries[key].setAttribute('original', color);
942  } else {
943    var colors = key;
944
945    for (var code in colors) {
946      if (this.countries[code]) {
947        this.countries[code].setFill(colors[code]);
948        this.countries[code].setAttribute('original', colors[code]);
949      }
950    }
951  }
952};
953
954JQVMap.prototype.setNormalizeFunction = function (f) {
955  this.colorScale.setNormalizeFunction(f);
956
957  if (this.values) {
958    this.setValues(this.values);
959  }
960};
961
962JQVMap.prototype.setScale = function (scale) {
963  this.scale = scale;
964  this.applyTransform();
965};
966
967JQVMap.prototype.setScaleColors = function (colors) {
968  this.colorScale.setColors(colors);
969
970  if (this.values) {
971    this.setValues(this.values);
972  }
973};
974
975JQVMap.prototype.setValues = function (values) {
976  var max = 0,
977    min = Number.MAX_VALUE,
978    val;
979
980  for (var cc in values) {
981    cc = cc.toLowerCase();
982    val = parseFloat(values[cc]);
983
984    if (isNaN(val)) {
985      continue;
986    }
987    if (val > max) {
988      max = values[cc];
989    }
990    if (val < min) {
991      min = val;
992    }
993  }
994
995  if (min === max) {
996    max++;
997  }
998
999  this.colorScale.setMin(min);
1000  this.colorScale.setMax(max);
1001
1002  var colors = {};
1003  for (cc in values) {
1004    cc = cc.toLowerCase();
1005    val = parseFloat(values[cc]);
1006    colors[cc] = isNaN(val) ? this.color : this.colorScale.getColor(val);
1007  }
1008  this.setColors(colors);
1009  this.values = values;
1010};
1011
1012JQVMap.prototype.unhighlight = function (cc, path) {
1013  cc = cc.toLowerCase();
1014  path = path || jQuery('#' + this.getCountryId(cc))[0];
1015  path.setOpacity(1);
1016  if (path.currentFillColor) {
1017    path.setFill(path.currentFillColor);
1018  }
1019};
1020
1021JQVMap.prototype.zoomIn = function () {
1022  var map = this;
1023  var sliderDelta = (jQuery('#zoom').innerHeight() - 6 * 2 - 15 * 2 - 3 * 2 - 7 - 6) / (this.zoomMaxStep - this.zoomCurStep);
1024
1025  if (map.zoomCurStep < map.zoomMaxStep) {
1026    map.transX -= (map.width / map.scale - map.width / (map.scale * map.zoomStep)) / 2;
1027    map.transY -= (map.height / map.scale - map.height / (map.scale * map.zoomStep)) / 2;
1028    map.setScale(map.scale * map.zoomStep);
1029    map.zoomCurStep++;
1030
1031    var $slider = jQuery('#zoomSlider');
1032
1033    $slider.css('top', parseInt($slider.css('top'), 10) - sliderDelta);
1034
1035    map.container.trigger('zoomIn');
1036  }
1037};
1038
1039JQVMap.prototype.zoomOut = function () {
1040  var map = this;
1041  var sliderDelta = (jQuery('#zoom').innerHeight() - 6 * 2 - 15 * 2 - 3 * 2 - 7 - 6) / (this.zoomMaxStep - this.zoomCurStep);
1042
1043  if (map.zoomCurStep > 1) {
1044    map.transX += (map.width / (map.scale / map.zoomStep) - map.width / map.scale) / 2;
1045    map.transY += (map.height / (map.scale / map.zoomStep) - map.height / map.scale) / 2;
1046    map.setScale(map.scale / map.zoomStep);
1047    map.zoomCurStep--;
1048
1049    var $slider = jQuery('#zoomSlider');
1050
1051    $slider.css('top', parseInt($slider.css('top'), 10) + sliderDelta);
1052
1053    map.container.trigger('zoomOut');
1054  }
1055};
1056
1057VectorCanvas.prototype.applyTransformParams = function (scale, transX, transY) {
1058  if (this.mode === 'svg') {
1059    this.rootGroup.setAttribute('transform', 'scale(' + scale + ') translate(' + transX + ', ' + transY + ')');
1060  } else {
1061    this.rootGroup.coordorigin = (this.width - transX) + ',' + (this.height - transY);
1062    this.rootGroup.coordsize = this.width / scale + ',' + this.height / scale;
1063  }
1064};
1065
1066VectorCanvas.prototype.createGroup = function (isRoot) {
1067  var node;
1068  if (this.mode === 'svg') {
1069    node = this.createSvgNode('g');
1070  } else {
1071    node = this.createVmlNode('group');
1072    node.style.width = this.width + 'px';
1073    node.style.height = this.height + 'px';
1074    node.style.left = '0px';
1075    node.style.top = '0px';
1076    node.coordorigin = '0 0';
1077    node.coordsize = this.width + ' ' + this.height;
1078  }
1079
1080  if (isRoot) {
1081    this.rootGroup = node;
1082  }
1083  return node;
1084};
1085
1086VectorCanvas.prototype.createPath = function (config) {
1087  var node;
1088  if (this.mode === 'svg') {
1089    node = this.createSvgNode('path');
1090    node.setAttribute('d', config.path);
1091
1092    if (this.params.borderColor !== null) {
1093      node.setAttribute('stroke', this.params.borderColor);
1094    }
1095    if (this.params.borderWidth > 0) {
1096      node.setAttribute('stroke-width', this.params.borderWidth);
1097      node.setAttribute('stroke-linecap', 'round');
1098      node.setAttribute('stroke-linejoin', 'round');
1099    }
1100    if (this.params.borderOpacity > 0) {
1101      node.setAttribute('stroke-opacity', this.params.borderOpacity);
1102    }
1103
1104    node.setFill = function (color) {
1105      this.setAttribute('fill', color);
1106      if (this.getAttribute('original') === null) {
1107        this.setAttribute('original', color);
1108      }
1109    };
1110
1111    node.getFill = function () {
1112      return this.getAttribute('fill');
1113    };
1114
1115    node.getOriginalFill = function () {
1116      return this.getAttribute('original');
1117    };
1118
1119    node.setOpacity = function (opacity) {
1120      this.setAttribute('fill-opacity', opacity);
1121    };
1122  } else {
1123    node = this.createVmlNode('shape');
1124    node.coordorigin = '0 0';
1125    node.coordsize = this.width + ' ' + this.height;
1126    node.style.width = this.width + 'px';
1127    node.style.height = this.height + 'px';
1128    node.fillcolor = JQVMap.defaultFillColor;
1129    node.stroked = false;
1130    node.path = VectorCanvas.pathSvgToVml(config.path);
1131
1132    var scale = this.createVmlNode('skew');
1133    scale.on = true;
1134    scale.matrix = '0.01,0,0,0.01,0,0';
1135    scale.offset = '0,0';
1136
1137    node.appendChild(scale);
1138
1139    var fill = this.createVmlNode('fill');
1140    node.appendChild(fill);
1141
1142    node.setFill = function (color) {
1143      this.getElementsByTagName('fill')[0].color = color;
1144      if (this.getAttribute('original') === null) {
1145        this.setAttribute('original', color);
1146      }
1147    };
1148
1149    node.getFill = function () {
1150      return this.getElementsByTagName('fill')[0].color;
1151    };
1152    node.getOriginalFill = function () {
1153      return this.getAttribute('original');
1154    };
1155    node.setOpacity = function (opacity) {
1156      this.getElementsByTagName('fill')[0].opacity = parseInt(opacity * 100, 10) + '%';
1157    };
1158  }
1159  return node;
1160};
1161
1162VectorCanvas.prototype.pathSvgToVml = function (path) {
1163  var result = '';
1164  var cx = 0, cy = 0, ctrlx, ctrly;
1165
1166  return path.replace(/([MmLlHhVvCcSs])((?:-?(?:\d+)?(?:\.\d+)?,?\s?)+)/g, function (segment, letter, coords) {
1167    coords = coords.replace(/(\d)-/g, '$1,-').replace(/\s+/g, ',').split(',');
1168    if (!coords[0]) {
1169      coords.shift();
1170    }
1171
1172    for (var i = 0, l = coords.length; i < l; i++) {
1173      coords[i] = Math.round(100 * coords[i]);
1174    }
1175
1176    switch (letter) {
1177      case 'm':
1178        cx += coords[0];
1179        cy += coords[1];
1180        result = 't' + coords.join(',');
1181        break;
1182
1183      case 'M':
1184        cx = coords[0];
1185        cy = coords[1];
1186        result = 'm' + coords.join(',');
1187        break;
1188
1189      case 'l':
1190        cx += coords[0];
1191        cy += coords[1];
1192        result = 'r' + coords.join(',');
1193        break;
1194
1195      case 'L':
1196        cx = coords[0];
1197        cy = coords[1];
1198        result = 'l' + coords.join(',');
1199        break;
1200
1201      case 'h':
1202        cx += coords[0];
1203        result = 'r' + coords[0] + ',0';
1204        break;
1205
1206      case 'H':
1207        cx = coords[0];
1208        result = 'l' + cx + ',' + cy;
1209        break;
1210
1211      case 'v':
1212        cy += coords[0];
1213        result = 'r0,' + coords[0];
1214        break;
1215
1216      case 'V':
1217        cy = coords[0];
1218        result = 'l' + cx + ',' + cy;
1219        break;
1220
1221      case 'c':
1222        ctrlx = cx + coords[coords.length - 4];
1223        ctrly = cy + coords[coords.length - 3];
1224        cx += coords[coords.length - 2];
1225        cy += coords[coords.length - 1];
1226        result = 'v' + coords.join(',');
1227        break;
1228
1229      case 'C':
1230        ctrlx = coords[coords.length - 4];
1231        ctrly = coords[coords.length - 3];
1232        cx = coords[coords.length - 2];
1233        cy = coords[coords.length - 1];
1234        result = 'c' + coords.join(',');
1235        break;
1236
1237      case 's':
1238        coords.unshift(cy - ctrly);
1239        coords.unshift(cx - ctrlx);
1240        ctrlx = cx + coords[coords.length - 4];
1241        ctrly = cy + coords[coords.length - 3];
1242        cx += coords[coords.length - 2];
1243        cy += coords[coords.length - 1];
1244        result = 'v' + coords.join(',');
1245        break;
1246
1247      case 'S':
1248        coords.unshift(cy + cy - ctrly);
1249        coords.unshift(cx + cx - ctrlx);
1250        ctrlx = coords[coords.length - 4];
1251        ctrly = coords[coords.length - 3];
1252        cx = coords[coords.length - 2];
1253        cy = coords[coords.length - 1];
1254        result = 'c' + coords.join(',');
1255        break;
1256
1257      default:
1258        break;
1259    }
1260
1261    return result;
1262
1263  }).replace(/z/g, '');
1264};
1265
1266VectorCanvas.prototype.setSize = function (width, height) {
1267  if (this.mode === 'svg') {
1268    this.canvas.setAttribute('width', width);
1269    this.canvas.setAttribute('height', height);
1270  } else {
1271    this.canvas.style.width = width + 'px';
1272    this.canvas.style.height = height + 'px';
1273    this.canvas.coordsize = width + ' ' + height;
1274    this.canvas.coordorigin = '0 0';
1275    if (this.rootGroup) {
1276      var paths = this.rootGroup.getElementsByTagName('shape');
1277      for (var i = 0, l = paths.length; i < l; i++) {
1278        paths[i].coordsize = width + ' ' + height;
1279        paths[i].style.width = width + 'px';
1280        paths[i].style.height = height + 'px';
1281      }
1282      this.rootGroup.coordsize = width + ' ' + height;
1283      this.rootGroup.style.width = width + 'px';
1284      this.rootGroup.style.height = height + 'px';
1285    }
1286  }
1287  this.width = width;
1288  this.height = height;
1289};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.