PageSourceSearch

https://www.ernmt-officiel.com/plugins/jquery-maps/jquery.vmap.js?v=0.3

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

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.