PageSourceSearch

https://luki.ru/js_src/3936/map.js

js luki.ru collected 2026-10-02 09:57:39 UTC 23,836 bytes, 699 lines download raw bytes

1MAP = {}
2
3/*
4 bl — base layers
5 bla — active base layer
6 ol — overlay layers
7 ola — active overlay layer
8*/
9
10MAP.init = function(node, stamp, geoJsonUrl)
11 {
12  MAP._node = node;
13  MAP._clickCount = 0;
14  CORE._silent_href_change = 1;
15  MAP._head = $$('head')[0];
16  MAP._body = $$('body')[0];
17
18  MAP._isMobile = document.viewport.getWidth() < 800;
19  MAP._isIframe = window!=window.top;
20
21  // MAP._isMobile = true;
22  // MAP._isIframe = true;
23
24  MAP.initParams();
25  MAP.setLayout();
26  MAP.initLeaflet();
27
28  MAP.layers();
29  MAP.initLocate();
30  MAP.finishLayout();
31  MAP.setPosition();
32  MAP.initEvents();
33
34  setTimeout(function(){ MAP._map.fire('load') }, 1000);
35  if (geoJsonUrl)
36    MAP.initGeoJsonUrl(geoJsonUrl);
37 }
38
39MAP.initParams = function() {
40  MAP._initParams = location.search.parseQuery();
41
42  MAP._initParams['bl'] = typeof (MAP._initParams['bl']) !== 'undefined' ? MAP._initParams['bl'].split(',') : (MAP._isIframe ? [1] : [1, 2, 3, 4]);
43  MAP._initParams['bla'] = typeof (MAP._initParams['bla']) !== 'undefined' ? MAP._initParams['bla'] : 1;
44  MAP._initParams['ol'] = typeof (MAP._initParams['ol']) !== 'undefined' ? MAP._initParams['ol'].split(',') : [1];
45  MAP._initParams['ola'] = typeof (MAP._initParams['ola']) !== 'undefined' ? MAP._initParams['ola'].split(',') : [1];
46  MAP._initParams['search'] = typeof (MAP._initParams['search']) !== 'undefined' ? MAP._initParams['search'] : 1;
47  MAP._initParams['locate'] = typeof (MAP._initParams['locate']) !== 'undefined' ? MAP._initParams['locate'] : 1;
48
49  MAP._initParams['bla'] = Number(MAP._initParams['bla']);
50  MAP._initParams['bl'] =  MAP._initParams['bl'].map(Number)
51  MAP._initParams['ol'] = MAP._initParams['ol'].map(Number)
52  MAP._initParams['ola'] = MAP._initParams['ola'].map(Number)
53}
54
55MAP.initLeaflet = function() {
56  MAP._map = new L.Map(MAP._node, {
57    closePopupOnClick: false,
58    zoomControl: false,
59    scrollWheelZoom: MAP._isIframe ? false : true,
60   });
61
62  MAP._layerControl = new L.Control.Layers();
63
64  MAP._search = new L.GeoJSON(null, {
65    onEachFeature: MAP.featureParse,
66    style: MAP.featureStyle
67   }); // search result layer
68
69  MAP._map.
70    addLayer(MAP._search).
71    addControl(MAP._layerControl).
72    addControl(new L.control.zoom({ zoomInTitle: 'Приблизить', zoomOutTitle: 'Отдалить'})).
73    addControl(new L.Control.Scale({imperial: false})) // zoom
74}
75
76MAP.initEvents = function() {
77  MAP._map.
78    on('load moveend zoomend', MAP.permalink).
79    on('click', MAP.clickWrap).
80    on('baselayerchange overlayadd overlayremove', function(e){
81      if (e.type == 'baselayerchange')
82        MAP._initParams['bla'] = e.layer.options.id;
83      else
84       {
85        var index = MAP._initParams['ola'].indexOf(e.layer.options.id);
86
87        if (e.type == 'overlayadd' && index === -1)
88          MAP._initParams['ola'].push(e.layer.options.id);
89
90        if (e.type == 'overlayremove' && index !== -1)
91          MAP._initParams['ola'].splice(index, 1);
92       }
93
94      MAP.permalink();
95     });
96
97  Element.observe(document, 'keydown', function(e)
98   {
99    if (e.keyCode == 27 && MAP._popup && MAP._popup.isClosed != 1)
100      MAP._map.closePopup(MAP._popup);
101    else if (e.keyCode == 27)
102      parent.GodsFinger.hide()
103    else if ((e.ctrlKey || e.metaKey) && e.keyCode === 70)
104     {
105      MAP._search_input.focus();
106      Event.stop(e);
107      return false;
108     }
109   });
110}
111
112MAP.layers = function()
113 {
114  /*
115    BaseLayers:
116    1 - luki
117    2 — google
118    3 — yandex.narod
119    4 — yandex.satellite
120
121    OverlapLayers:
122    1 — firms
123    2 - ballons
124  */
125
126  if (MAP._initParams['bl'].indexOf(1) !== -1)
127   {
128    var lukiLayer = new L.TileLayer('//s.luki.ru/t/' + stamp + '/{z}/{x}/{y}.png', {
129      // detectRetina: true,
130      minZoom: 13,
131      maxZoom: 18,
132      name: 'Карта }}} Луки.ру',
133      id: 1,
134     });
135
136    MAP._layerControl.addBaseLayer(lukiLayer, lukiLayer.options.name);
137
138    if (MAP._initParams['bla'] === 1)
139      MAP._map.addLayer(lukiLayer);
140   }
141
142  if (MAP._initParams['bl'].indexOf(2) !== -1)
143    MAP.initGoogle();
144
145  if (MAP._initParams['bl'].indexOf(3) !== -1 || MAP._initParams['bl'].indexOf(4) !== -1)
146    MAP.initYandex();
147
148  if (MAP._initParams['ol'].indexOf(1) !== -1)
149    MAP.initFirms();
150
151  if (MAP._initParams['ol'].indexOf(2) !== -1)
152    MAP.initBalloons();
153
154  if (MAP._initParams['ol'].indexOf(3) !== -1)
155    MAP.initChristmasTree();
156 }
157
158MAP.setSuggect = function(input, wrapper, options)
159 {
160  MAP._search_input = input;
161  if (typeof options !== 'undefined')
162    MAP._search_input._option = options
163  Element.observe(MAP._search_input, 'blur', MAP.hideSuggest);
164  Element.observe(MAP._search_input, 'keydown', function(e) {
165      if (e.keyCode == 38 || e.keyCode == 40)
166        Event.stop(e);
167    });
168
169  Element.observe(MAP._search_input, 'keyup', function(e)
170   {
171    if (e.keyCode == 38 || e.keyCode == 40)
172     {
173      var items = $$('a.map_suggest__item'),
174          n = 0;
175
176      if (items.length)
177       {
178        items.each(function(item, i){
179          if (item.hasClassName('map_suggest__current_result'))
180           {
181            item.removeClassName('map_suggest__current_result');
182            n = i + (e.keyCode == 38 ? -1 : 1);
183            if (n > items.length - 1)
184              n = 0;
185            else if (n < 0)
186              n = items.length - 1;
187           }
188        });
189
190        items[n].addClassName('map_suggest__current_result');
191        Event.stop(e);
192        return false;
193       }
194     }
195    else if (e.keyCode == 13)
196     {
197      var item = $$('.map_suggest__current_result')[0];
198
199      if (item)
200        item.onmousedown();
201      else
202        MAP.search(MAP._search_input.value)
203
204      Event.stop(e);
205      return false;
206     }
207    else if (e.keyCode == Event.KEY_ESC)
208     {
209      MAP.hideSuggest();
210      Event.stop(e);
211      return false;
212     }
213    else
214     {
215      MAP.showSuggest();
216     }
217    return true;
218   });
219
220  wrapper.
221    insert(MAP._search_input).
222    insert(new Element('div', {'id': 'leaflet-search-suggest'}));
223 }
224
225MAP.setLayout = function()
226 {
227  $('js-header_menu').setStyle({
228      marginLeft: '-' + ($('js-header_menu').getWidth()/2) + 'px',
229      opacity: .85
230    });
231
232  MAP._searchWrapper = new Element('div', {'class': 'leaflet-search'});
233  MAP._search_btn = new Element('a', {'class': 'leaflet-search-btn'});
234  Element.observe(MAP._search_btn, 'click', MAP.search);
235  MAP.setSuggect(new Element('input', {
236      'id': 'leaflet-search-input',
237      'class': 'leaflet-search-input',
238      'type': 'text',
239      'value': '',
240      'placeholder': 'поиск'
241    }), MAP._searchWrapper);
242
243  MAP._searchWrapper.
244    insert(MAP._search_btn);
245
246  $(MAP._node).insert({before: MAP._searchWrapper});
247 }
248
249MAP.finishLayout = function()
250 {
251  if (MAP._isMobile)
252   {
253    MAP._body.addClass('map__mobile');
254   }
255  else if (MAP._isIframe)
256   {
257    MAP._map.zoomOut();
258    MAP._body.addClass('map__iframe');
259   }
260  else if (MAP._search_input)
261   {
262    MAP._search_input.focus();
263   }
264
265  var controlZoom = $$('.leaflet-control-zoom')[0],
266      controlLayers = $$('.leaflet-control-layers')[0],
267      i = Math.max(5, $('js-header_menu').cumulativeOffset()['left']);
268
269  if (controlZoom)
270    controlZoom.setStyle({ 'left': i + 'px', 'opacity': .85 }).addClassName('map_shadow');
271
272  if (controlLayers)
273  controlLayers.setStyle({ 'right': i + 'px', 'opacity': .85}).addClassName('map_shadow');
274
275  if (MAP._searchWrapper)
276    MAP._searchWrapper.setStyle({
277      'top': (MAP._initParams['search'] ? controlZoom.cumulativeOffset()['top'] : -9999) + 'px',
278      'left': controlZoom.cumulativeOffset()['left'] + controlZoom.getWidth() + 10 + 'px',
279     }).addClassName('map_shadow');
280 }
281
282MAP.initGoogle = function()
283 {
284  MAP._head.insert(new Element('script', {
285      src: '//maps.google.com/maps/api/js?v=3.2&sensor=false&callback=MAP.initGoogleCallback'
286    }));
287 }
288
289MAP.initGoogleCallback = function()
290 {
291  var googleLayer = new L.Google('HYBRID', {
292      minZoom: 13,
293      maxZoom: 18,
294      name: 'Google карты: спутник',
295      id: 2
296    });
297
298  MAP._layerControl.addBaseLayer(googleLayer, googleLayer.options.name);
299
300  if (MAP._initParams['bla'] === 2)
301    MAP._map.addLayer(googleLayer);
302 }
303
304MAP.initYandex = function()
305 {
306  MAP._head.insert(new Element('script', {
307      src: '//api-maps.yandex.ru/2.0/?load=package.map&lang=ru-RU&onload=initYandexCallback'
308    }));
309 }
310
311initYandexCallback = function() // только хардкор, только глобальные функции!!!
312 {
313
314  if (MAP._initParams['bl'].indexOf(3) !== -1)
315   {
316    var yandexLayout = new L.Yandex('publicMap', {
317      minZoom: 13,
318      maxZoom: 18,
319      name: 'Яндекс.карты: народная',
320      id: 3
321     });
322
323    MAP._layerControl.addBaseLayer(yandexLayout, yandexLayout.options.name);
324    if (MAP._initParams['bla'] === 3)
325      MAP._map.addLayer(yandexLayout);
326   }
327
328  if (MAP._initParams['bl'].indexOf(4) !== -1)
329   {
330    var yandexLayout = new L.Yandex('hybrid', {
331      minZoom: 13,
332      maxZoom: 18,
333      name: 'Яндекс.карты: спутник',
334      id: 4
335     });
336
337    MAP._layerControl.addBaseLayer(yandexLayout, yandexLayout.options.name);
338
339    if (MAP._initParams['bla'] === 4)
340      MAP._map.addLayer(yandexLayout);
341   }
342 }
343
344MAP.loadJSON = function(url, value, fitBounds)
345 {
346  if (typeof(MAP._popup) != 'undefined')
347    MAP._map.closePopup(MAP._popup);
348
349  MAP.hideSuggest();
350  clearTimeout(MAP._search_input._suggestID);
351  MAP._search_input.writeAttribute('disabled', true);
352  MAP._search_input.addClassName('leaflet-search-input__busy');
353  if (typeof(value) != 'undefined')
354   {
355    MAP._search_input.value = value;
356    MAP._search_input._value  = value;
357   }
358
359  MAP._search_input._url = encodeURIComponent(url);
360
361  new Ajax.Request('/map/search.html?' + url, {
362      asynchronous: true,
363      method: 'GET',
364      onSuccess: function(r) { MAP.loadJSONComplete(r.responseText.evalJSON(true), fitBounds); }
365    });
366 }
367
368MAP.loadJSONComplete = function(geo_json, fitBounds)
369 {
370  if (typeof(fitBounds) == 'undefined') fitBounds = true;
371
372  MAP._search.clearLayers();
373  // MAP._markers.clearLayers();
374
375  if (geo_json.features && MAP._search.addData(geo_json) && fitBounds)
376    MAP._map.setView(MAP._search.getBounds().getCenter(), MAP._map.getBoundsZoom(MAP._search.getBounds()) - 1);
377
378  MAP._search_input.writeAttribute('disabled', false);
379  MAP._search_input.removeClassName('leaflet-search-input__busy');
380 }
381
382MAP.featureParse = function(feature, layer)
383 {
384  if (feature.properties && feature.properties.popupContent)
385   {
386    var markerCallback = function(e) { MAP.showPopup(e.latlng ? e.latlng : e.target._latlng, feature.properties.popupContent) };
387
388    if (feature.geometry.type == 'MultiPolygon')
389      MAP._search.addLayer(new L.Marker(layer.getBounds().getCenter()).on('click', markerCallback));
390
391    layer.on('click', markerCallback);
392   }
393 }
394
395MAP.featureStyle = function(feature)
396 {
397  if (feature.properties.style && feature.geometryType != 'Point')
398    return feature.properties.style;
399 }
400
401MAP.show = function(IDs, value)
402 {
403  if (IDs)
404   {
405    MAP.loadJSON('ids=' + encodeURIComponent(IDs), value);
406
407    if (MAP._isIframe && parent.document.getElementById('price_adress'))
408      setTimeout(function(){
409          parent.document.getElementById('price_adress').value = value;
410          parent.document.getElementById('price_adress__map_url').value = $('js-maplink').href;
411      }, 1000);
412   }
413 }
414
415MAP.search = function(q)
416 {
417  MAP.hideSuggest();
418  if ((q = q ? q : $('leaflet-search-input').value))
419    MAP.loadJSON('q=' + encodeURIComponent(q), q.replace('*', ''));
420 }
421
422MAP.showPopup = function(latlng, popupContent)
423 {
424  if (popupContent && typeof(latlng) !== 'undefined')
425   {
426    if (MAP._popup == null)
427      MAP._popup = new L.Popup();
428    MAP._popup.setContent(popupContent);
429    MAP._popup.setLatLng(latlng);
430    MAP._map.openPopup(MAP._popup);
431    MAP._map.on('popupopen', function(){MAP._popup.isClosed = 0;});
432    MAP._map.on('popupclose', function(){MAP._popup.isClosed = 1});
433   }
434 }
435
436MAP.setPosition = function()
437 {
438  var lat = typeof(MAP._initParams['lat']) !== 'undefined' ? Number(MAP._initParams['lat']) : 56.341,
439      lng = typeof(MAP._initParams['lng']) !== 'undefined' ? Number(MAP._initParams['lng']) : 30.544250646,
440      z = typeof(MAP._initParams['z']) !== 'undefined' ? Number(MAP._initParams['z']) : (document.viewport.getDimensions()['width'] > 1600 ? 14 : 13);
441
442  MAP._map.setView(new L.LatLng(lat,lng), z);
443
444  if (typeof(MAP._initParams['url']) !== 'undefined' && typeof(MAP._initParams['q']) !== 'undefined')
445    MAP.loadJSON(MAP._initParams['url'], MAP._initParams['q'], false);
446 }
447
448MAP.permalink = function()
449 {
450  if ($('js-maplink'))
451   {
452    var center = MAP._map.getCenter(),
453        url = __ABSBASEURL + 'map/?z=' + MAP._map._zoom + '&lat=' + center.lat.toPrecision(6) + '&lng=' + center.lng.toPrecision(6);
454
455    if (MAP._search_input._url) url += '&url=' + MAP._search_input._url;
456    if (MAP._search_input.value) url += '&q=' + encodeURIComponent(MAP._search_input.value);
457
458    url += '&bla=' + encodeURIComponent(MAP._initParams['bla']);
459    url += '&bl=' + encodeURIComponent(MAP._initParams['bl'].join(','));
460    url += '&ola=' + encodeURIComponent(MAP._initParams['ola']);
461    url += '&ol=' + encodeURIComponent(MAP._initParams['ol'].join(','));
462
463    if ($('js-maplink').href != url)
464     {
465      History.replaceState(null, document.title, url);
466      $('js-maplink').href = url;
467     }
468
469   }
470
471  MAP.hideLukiCopy();
472 }
473
474MAP.hideLukiCopy = function()
475 {
476  var i = MAP._initParams['bla'];
477
478  $('copy_map').setStyle({
479    opacity: .7,
480    marginBottom: i == 1 ? '0' : (i == 2 ? '10px' : '32px'),
481   });
482
483  MAP._body[i != 1 ? 'addClass' : 'removeClass']('map__hide_scale');
484 }
485
486MAP.hideSuggest = function()
487 {
488  MAP._search_input.removeClassName('leaflet-search-input__expand');
489  $('leaflet-search-suggest').update('');
490  $('leaflet-search-suggest').setStyle({ 'display': 'none' });
491 }
492
493MAP.showSuggest = function()
494 {
495  if (MAP._search_input._value == MAP._search_input.value)
496    return;
497
498  var q = MAP._search_input._value = MAP._search_input.value;
499  clearTimeout(MAP._search_input._suggestID);
500  MAP.hideSuggest();
501  MAP._search_input.removeClassName('leaflet-search-input__busy');
502
503  if (MAP._search_input.value.length)
504   {
505    MAP._search_input._suggestID = setTimeout(function()
506     {
507      MAP._search_input.addClassName('leaflet-search-input__busy');
508      new Ajax.Request('/map/search.html?s=' +  encodeURIComponent(q) + (MAP._search_input._option ? '&option=' + MAP._search_input._option : ''), {
509        asynchronous: true,
510        method: 'GET',
511        onSuccess: function(r)
512         {
513          if (q == MAP._search_input.value)
514           {
515            $('leaflet-search-suggest').update(r.responseText);
516            $$('.map_suggest__item').each(function(item){
517                $(item).on('mouseover', function(){
518                  var node = $$('.map_suggest__current_result')[0];
519                  if (node) node.removeClassName('map_suggest__current_result');
520                  item.addClassName('map_suggest__current_result');
521                });
522
523              });
524            MAP._search_input.addClassName('leaflet-search-input__expand');
525            MAP._search_input.removeClassName('leaflet-search-input__busy');
526            $('leaflet-search-suggest').setStyle({
527                'display': 'block'
528              });
529           }
530         }
531       });
532     }, 250);
533   }
534 }
535
536MAP.shortLink = function(url)
537 {
538  return GodsFinger.load('/ajax/shortlink.html?full=' + encodeURIComponent(url));
539 }
540
541MAP.initGeoJsonUrl = function(url)
542 {
543  MAP._head.insert(new Element('script', {
544      src: url + '&callback=MAP.loadJSONComplete&r=' + Math.random()
545    }));
546
547  MAP._searchWrapper.setStyle({
548    left: '-9999px!important',
549    display: 'none'
550  })
551 }
552
553MAP.clickWrap = function(e) //detect click && dblClick
554 {
555  MAP._clickCount += 1;
556
557  if (MAP._clickCount <= 1)
558    setTimeout(function() {
559      if (MAP._clickCount <= 1) MAP.click(e);
560      MAP._clickCount = 0;
561     }, 150);
562 }
563
564MAP.click = function(e)
565 {
566  if (typeof MAP._popup !== 'undefined' && !MAP._popup.isClosed)
567    MAP._map.closePopup(MAP._popup);
568  else if (MAP._initParams['bla'] === 1)
569    new Ajax.Request('/map/search.html?i=' + e.latlng.lng + ':' + e.latlng.lat, {
570      asynchronous: true,
571      method: 'GET',
572      onSuccess: function(r) {
573        if (r.responseText.length)
574         {
575          MAP.showPopup(e.latlng, r.responseText);
576
577          var last_addr = $$('.leaflet-popup-content .map__b_adress:last')[0];
578          if (last_addr)
579            last_addr.style.marginBottom = '6px';
580         }
581       }
582     });
583 }
584
585MAP.initLocate = function()
586 {
587  if (MAP._initParams['locate'] == 1 && typeof(navigator.geolocation) != undefined)
588   {
589    MAP._map.on('locationfound', function(e) {
590      var boundsCenter = e.bounds.getCenter(),
591          radius = boundsCenter.distanceTo(e.bounds._southWest);
592
593      if (typeof(MAP._meCircle) === 'undefined')
594       {
595        MAP._meCircle = new L.Circle(e.latlng, radius < 500 ? radius : 500, {weight: .25, fillOpacity: .1}).addTo(MAP._map);
596        MAP._meMarker = new L.Marker(e.latlng).addTo(MAP._map).bindPopup('Вы — здесь');
597       }
598      else
599       {
600        MAP._meCircle.
601          setLatLng(e.latlng).
602          setRadius(radius < 10500 ? radius : 500);
603
604        MAP._meMarker.setLatLng(e.latlng);
605       }
606     });
607
608    // MAP._map.on('locationerror', function(e) { alert(e.message); });
609    MAP._map.locate()
610   }
611 }
612
613MAP.initFirms = function() {
614  var firmsLayer = new L.LayerGroup(),
615      firms = [
616        {img:'/i/firmlogos/wmz.png', url:'//luki.ru/help/179302.html#domain_container', point: [56.331457, 30.579543], size:[26,26]},
617        {img:'/i/firmlogos/rti.png', url:'//luki.ru/help/214023.html#domain_container', point: [56.354400, 30.525580], size:[26,26], iconAnchor: [12, 26]},
618        // {img:'//s.luki.ru/s/00/00/00/01/90/0-29631/firm_logo_micro/logo_etazh_2.jpg', url:'//luki.ru/expetro', point: [56.34651425093962,30.561046600341797], size:[35,27]},
619        // {img:'//s.luki.ru/s/00/00/00/01/90/0-24266/firm_logo_micro/ren_vtrk.png', url:'//luki.ru/retro', point: [56.3469423307767,30.52649974822998], size:[22,28]},
620        // {img:'//s.luki.ru/s/00/00/00/01/90/0-28755/firm_logo_micro/image002.jpg', url:'//luki.ru/vostochnyi', point: [56.3401162632019, 30.5445671081543], size:[23,25]},
621        // {img:'//s.luki.ru/s/00/00/00/01/90/0-29027/firm_logo_micro/%D0%BC%D1%82%D1%81.jpg', url:'//luki.ru/mts', point: [56.33909343706542,30.538043975830078], size:[35,17]},
622        // {img:'//s.luki.ru/s/00/00/00/01/90/0-29027/firm_logo_micro/%D0%BC%D1%82%D1%81.jpg', url:'//luki.ru/mts', point: [56.34757255068286,30.509827136993405], size:[35,17]},
623        // {img:'//s.luki.ru/s/00/00/00/01/90/0-29028/firm_logo_micro/%D1%82%D0%B5%D0%BB%D0%B52.jpg', url:'//luki.ru/tele2', point: [56.346133731495705,30.52594184875488], size:[33,17]},
624        // {img:'//s.luki.ru/s/00/00/00/01/90/0-30984/firm_logo_micro/%D0%BB%D0%BE%D0%B3%D0%BE%D1%82%D0%B8%D0%BF.jpg', url:'//luki.ru/beeline', point: [56.34050873571912,30.53225040435791], size:[29,23]},
625        // {img:'//s.luki.ru/s/00/00/00/01/90/0-28798/firm_logo_micro/%D0%BB%D0%BE%D0%B3%D0%BE%D1%82%D0%B8%D0%BF.jpg', url:'//luki.ru/svyaznoy', point: [56.34147206023576,30.527336597442627], size:[51,16]},
626        // {img:'//s.luki.ru/s/00/00/00/01/90/0-28794/firm_logo_micro/Logo-MegaFon_Horizont-White_Gradient_web.jpg', url:'//luki.ru/megafon', point: [56.34344620484833,30.517734289169308], size:[47,16]},
627        // {img:'//s.luki.ru/s/00/00/00/01/90/0-32188/firm_logo_micro/%D0%9B%D0%9E%D0%93%D0%9E%D0%A2%D0%98%D0%9F.jpg', url:'//luki.ru/vel-luki_bank', point: [56.33786838828135,30.521135330200195], size:[34,20]},
628        // {img:'//s.luki.ru/s/00/00/00/01/90/0-29344/firm_logo_micro/columia.jpg', url:'//luki.ru/', point: [56.3430656547989,30.52167177200317], size:[47,16]},
629        // {img:'//s.luki.ru/s/00/00/00/01/90/0-30212/firm_logo_micro/%D0%BB%D0%BE%D0%B3%D0%BE.jpg', url:'//luki.ru/', point: [56.344076482517366,30.518839359283447], size:[43,17]},
630        // {img:'//s.luki.ru/s/00/00/00/01/90/0-28796/firm_logo_header/image001.png', url:'//luki.ru/', point: [56.346371556593006,30.527250766754147], size:[77,12]},
631        // {img:'//s.luki.ru/s/00/00/00/01/90/0-30228/firm_logo_micro/%D0%92%D1%8B%D0%B2%D0%B5%D1%81%D0%BA%D0%B0_%D0%A8%D0%B0%D0%B3%D0%B0%D0%BB.jpg', url:'//luki.ru/', point: [56.346567761181966,30.527787208557132], size:[44,17]},
632       ];
633
634  L.Util.setOptions(firmsLayer, {id: 1, name: 'Компании'});
635
636  firms.each(function(item){
637    var myIcon = L.icon({
638          iconUrl: item.img,
639          iconSize: item.size,
640          iconAnchor: item.size,
641         }),
642        marker = L.marker(item.point, {icon: myIcon}).on('click', function(){
643          window.open(item.url);
644         }).addTo(firmsLayer);
645   })
646
647  MAP._layerControl.addOverlay(firmsLayer, firmsLayer.options.name);
648
649  if (MAP._initParams['ola'].indexOf(1) !== -1)
650    MAP._map.addLayer(firmsLayer);
651 }
652
653MAP.initBalloons = function() {
654  var balloons = new L.LayerLive({url:'//89.28.166.187/', timeout: 1000, id: 2});
655  L.Util.setOptions(firmsLayer, {id: 2, name: 'Тепловые аэростаты'});
656  MAP._layerControl.addOverlay(balloons, firmsLayer.options.name);
657
658  if (MAP._initParams['ola'].indexOf(2) !== -1)
659    MAP._map.addLayer(balloons);
660 }
661
662MAP.initChristmasTree = function() {
663  var img = '/map/dist/images/_christmas_tree.png', url = '//luki.ru/news/330528.html#c', size = [37,37], firmsLayer = new L.LayerGroup(),
664      firms = [
665        {'img': img, 'url': url, 'point': [56.339236,30.530791], 'size': size, 'text': 'ул. Дьяконова, 1'},
666        {'img': img, 'url': url, 'point': [56.339144,30.525255], 'size': size, 'text': 'ул. Зверева, 28'},
667        {'img': img, 'url': url, 'point': [56.340922,30.541901], 'size': size, 'text': 'пр. Гагарина, 48'},
668        {'img': img, 'url': url, 'point': [56.321502,30.517096], 'size': size, 'text': 'пр. Октябрьский, 128'},
669        {'img': img, 'url': url, 'point': [56.343158,30.530046], 'size': size, 'text': 'ул. Зверева, 42'},
670        {'img': img, 'url': url, 'point': [56.353625,30.566121], 'size': size, 'text': 'ул. Дружбы, 19'},
671        {'img': img, 'url': url, 'point': [56.346544,30.562162], 'size': size, 'text': 'перекресток улиц Вокзальная — Гражданская'},
672        {'img': img, 'url': url, 'point': [56.33571,30.56662], 'size': size, 'text': 'ул. Малышева, 20'},
673        {'img': img, 'url': url, 'point': [56.350031,30.523104], 'size': size, 'text': 'ул. Ботвина, 9'},
674        {'img': img, 'url': url, 'point': [56.341362,30.500059], 'size': size, 'text': 'ул. Рабочая, 3'},
675        {'img': img, 'url': url, 'point': [56.350453,30.505407], 'size': size, 'text': 'ул. Ставского, 67'},
676        {'img': img, 'url': url, 'point': [56.347359,30.528511], 'size': size, 'text': 'перекресток ул. Полиграфистов – пр. Октябрьский'},
677       ];
678
679  L.Util.setOptions(firmsLayer, {id: 3, name: 'Ёлочные базары'});
680
681  firms.each(function(item){
682    var myIcon = L.icon({
683          iconUrl: item.img,
684          iconSize: item.size,
685          iconAnchor:   [18, 32],
686         }),
687        marker = L.marker(item.point, {icon: myIcon}).on('click', function(e){
688          if (!MAP._isIframe)
689            window.open(item.url);
690          else
691            MAP.showPopup(e.latlng, item.text);
692         }).addTo(firmsLayer);
693   })
694
695  MAP._layerControl.addOverlay(firmsLayer, firmsLayer.options.name);
696
697  if (MAP._initParams['ola'].indexOf(3) !== -1)
698    MAP._map.addLayer(firmsLayer);
699}

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.