PageSourceSearch

https://turystykawgminie.pl/wyszukiwanie/build/turysta_v2.min.js

js turystykawgminie.pl collected 2026-10-02 17:34:47 UTC 133,885 bytes, 4,122 lines download raw bytes

1// modifying polyline leaflet object for proper displaying label on hover
2L.Polyline.include({
3    bindLabelEx: function (content, options) {
4      if (!this.label || this.label.options !== options) {
5        this.label = new L.Label(options, this);
6      }
7
8      var latlngs = this.getLatLngs();
9      var nPoint = latlngs.length;
10
11      var lats = [];
12      var lngs = [];
13      for(var i = 0; i < nPoint; i++) {
14        lats.push(latlngs[i].lat);
15        lngs.push(latlngs[i].lng);
16      }
17
18      var minLat = Math.min.apply(null, lats);
19      var maxLat = Math.max.apply(null, lats);
20      var minLng = Math.min.apply(null, lngs);
21      var maxLng = Math.max.apply(null, lngs);
22
23      var pointM = {
24        lat: (minLat + maxLat) / 2,
25        lng: (minLng + maxLng) / 2
26      };
27
28      this.label.setContent(content);
29      this._showLabelAdded = true;
30      this._showLabel({
31        latlng: pointM
32      });
33    }
34  });;// display photo galery after click on image
35		$(document).ready(function() {
36			$(".fancybox-thumb").fancybox({
37				prevEffect	: 'none',
38				nextEffect	: 'none',
39				helpers	: {
40					title	: {
41						type: 'outside'
42					},
43					thumbs	: {
44						width	: 50,
45						height	: 50
46					}
47				}
48			});
49		});;$(document).ready(function () {
50
51  // if ($(window).width() <= 768) {
52
53    var app = $('.app-body');
54    app.append('<div class="mobile-closepanel"><i class="fa fa-times fa-2x mobile-closebtn"></i></div><div class="mobile-showmore"><i class="fa fa-angle-up fa-2x"></i><p>Więcej informacji</p></div>').append('<div class="mobile-icons"><div class="mobile-icon-search"><img src="../img/map/szukaj_white.png" class="img-responsive mobile-search"></div><div class="icon-counter mobile-icon-list"><img src="../img/map/obiekt.png" class="img-responsive mobile-list"><span class="number mobile-listnum"> </span></div></div>');
55
56
57  $('.mobile-closebtn').on('click', function () {
58    var elementsToHide = ['.mobile-closepanel', '.sidebar-switch', '.sidebar-search', '.sidebar-filters', '.sidebar-list', '.mobile-showmore'],
59      elementsToShow = ['.mobile-icon-search', '.mobile-icon-list', '.sidebar-integrate'];
60    $('div.activated-remove > img').click();
61    hideElements(elementsToHide);
62    showElements(elementsToShow);
63    $('.mobile-icons').css('top', '60px');
64    $('div.activated-remove > img').css('display', 'inline');
65  })
66
67  $('.mobile-search').on('click', function () {
68    $('.mobile-closebtn').click();
69    var elementsToShow = ['.sidebar-switch', '.sidebar-search', '.sidebar-filters'];
70    showClosepanel();
71    showElements(elementsToShow);
72    hideElements(['.mobile-showmore', '.sidebar-integrate']);
73    setTimeout(function () {
74      if ($('.filters-container').hasClass('hidden')) {
75        $('.filters-header .glyphicon.glyphicon-triangle-bottom').click();
76      }
77    }, 100)
78    $('.sidebar').css('top', '100px');
79    $('.mobile-icons').css('top', '150px');
80  })
81
82  $('.mobile-list').on('click', function () {
83    var elementsToHide = ['.mobile-icon-list', '.mobile-showmore', '.sidebar-integrate'];
84    $('.mobile-closebtn').click();
85    showClosepanel();
86    showElement('.sidebar-list');
87    hideElements(elementsToHide);
88    setTimeout(function () {
89      if ($('.list-container').hasClass('hidden')) {
90        $('.section-header .glyphicon.glyphicon-triangle-bottom').click();
91      }
92    }, 100)
93    $('.sidebar').css('top', '100px');
94    $('.mobile-icons').css('top', '150px');
95    $('.mobile-icon-search').css('z-index', 0);
96  })
97
98  $('.mobile-showmore').on('click', function () {
99    hideElements(['.mobile-showmore', '.sidebar-integrate']);
100    $('.sidebar').css('top', '100px');
101    $('.mobile-closepanel').css('top', '60px');
102    $('.mobile-icons').css('top', '150px');
103    $('.mobile-icon-search').css('z-index', 0);
104  })
105  // }
106});
107
108bpPassedCallback(768, function() {
109  if ($(window).width() > 768) {
110    showElements(['.sidebar-switch', '.sidebar-search', '.sidebar-filters', '.sidebar-list', '.sidebar-integrate']);
111    hideElements(['.mobile-showmore', '.mobile-list', '.mobile-search', '.mobile-closepanel']);
112    $('.sidebar').removeAttr('style');
113    $('.mobile-icons').removeAttr('style');
114  }
115  else {
116    hideElements(['.sidebar-switch', '.sidebar-search', '.sidebar-filters', '.sidebar-list']);
117    showElements(['.mobile-list', '.mobile-icon-list', '.mobile-icon-search', '.mobile-search']);
118    $('.sidebar').css('top', '100px');
119    // $('.mobile-icons').css('top', '150px');
120  }
121});
122
123
124function hideElement(element) {
125  $(element).css('display', 'none');
126}
127
128function hideElements(elements) {
129  $.each(elements, function (index, element) {
130    hideElement(element);
131  })
132}
133
134function showElement(element) {
135  $(element).css('display', 'block');
136}
137
138function showElements(elements) {
139  $.each(elements, function (index, element) {
140    showElement(element);
141  })
142}
143
144function showClosepanel() {
145  $('.mobile-closepanel').removeClass('hidden').css({
146    'display': 'flex',
147    'top': '60px'
148  });
149}
150
151function showObjectNameOnTheBottom() {
152  showClosepanel();
153  showElement('.sidebar-list');
154
155  setTimeout(function () {
156    if ($('.list-container').hasClass('hidden')) {
157      $('.section-header .glyphicon.glyphicon-triangle-bottom').click();
158    }
159    $('div.activated-remove > img').css('display', 'none')
160  }, 200);
161
162  $('.sidebar').css('top', 'calc(100vh - 88px)');
163  var top = $('.sidebar').css('top');
164
165  $('.mobile-closepanel').css({
166    'top': 'calc(100vh - 88px)',
167    'z-index': 2000
168  });
169  $('.mobile-showmore').css({
170    'display': 'flex',
171    'top': 'calc(100vh - 88px)',
172    'z-index': 2000
173  })
174}
175
176function bpPassedCallback(breakPoint, callback) {
177  var windowWidth = $(window).width();
178  var windowSize = windowWidth > breakPoint ? 'lg' : 'sm';
179
180  $(window).resize(function() {
181    windowWidth = $(window).width();
182    var bpPassed = false;
183
184    if (windowSize == 'lg') {
185      if (windowWidth <= breakPoint) {
186        bpPassed = true;
187        windowSize = 'sm';
188      }
189      else {
190        bpPassed = false;
191      }
192    }
193    else {
194      if (windowWidth > breakPoint) {
195        bpPassed = true;
196        windowSize = 'lg';
197      }
198      else {
199        bpPassed = false;
200      }
201
202    }
203
204    if (bpPassed) {
205      callback();
206    }
207
208  });
209
210}
211;var app = angular.module('mapApp', ['ngAnimate', 'angularLazyImg', 'ngSanitize']);
212
213app.config(['$httpProvider', 'lazyImgConfigProvider', function ($httpProvider, lazyImgConfigProvider) {
214
215    // Use x-www-form-urlencoded Content-Type
216    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
217
218    /**
219    * The workhorse; converts an object to x-www-form-urlencoded serialization.
220        * @param {Object} obj
221        * @return {String}
222    */
223
224    var param = function(obj) {
225        var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
226
227        for(name in obj) {
228            value = obj[name];
229
230            if(value instanceof Array) {
231                for(i=0; i<value.length; ++i) {
232                    subValue = value[i];
233                    fullSubName = name + '[' + i + ']';
234                    innerObj = {};
235                    innerObj[fullSubName] = subValue;
236                    query += param(innerObj) + '&';
237                };
238            }
239            else if(value instanceof Object) {
240                for(subName in value) {
241                    subValue = value[subName];
242                    fullSubName = name + '[' + subName + ']';
243                    innerObj = {};
244                    innerObj[fullSubName] = subValue;
245                    query += param(innerObj) + '&';
246                };
247            }
248            else if(value !== undefined && value !== null){
249                query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
250            };
251        };
252
253        return query.length ? query.substr(0, query.length - 1) : query;
254    };
255
256    // Override $http service's default transformRequest
257    $httpProvider.defaults.transformRequest = [function(data) {
258        return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
259    }];
260
261
262    // lazy loading
263    var scrollable = document.querySelector('.list-container');
264    lazyImgConfigProvider.setOptions({
265        offset: 400, // how early you want to load image (default = 100)
266        errorClass: 'error', // in case of loading image failure what class should be added (default = null)
267        successClass: 'success', // in case of loading image success what class should be added (default = null)
268        onError: function(image){}, // function fired on loading error
269        onSuccess: function(image){}, // function fired on loading success
270        container: angular.element(scrollable) // if scrollable container is not $window then provide it here
271    });
272}]);
273
274app.value('proxyHost', '/cgi-bin/proxy.cgi?url=');
275// app.value('proxyHost', '');
276app.value('serverRoot', 'https://administracja.gison.pl/turysta/');
277// app.value('serverRoot', 'http://192.168.2.115/turysta_prod/');
278app.value('path', window.location.pathname);
279app.value('strona_translate', window.strona_translate);
280;app.controller('mainController', ['$scope', '$http', '$q', 'Profile', 'Filters', 'permalinkValidator', 'permalinkGenerator', 'permalinkUpdater', function ($scope, $http, $q, Profile, Filters, permalinkValidator, permalinkGenerator, permalinkUpdater) {
281
282    // config object storing informations about initial app view
283    $scope.viewConfig = {};
284
285    // setting app config depends on permalinkValidator provider
286    $scope.setAppConfig = function (permalinkValidator) {
287
288        if (permalinkValidator.isPermalinkValid === true) {
289            $scope.viewConfig.isValid = true;
290            $scope.viewConfig.initialFilters = permalinkValidator.permalinkObject.filters;
291            $scope.viewConfig.mapView = permalinkValidator.permalinkObject.map;
292            $scope.viewConfig.searchMode = permalinkValidator.permalinkObject.sidebarMode;
293            $scope.viewConfig.selectedFeature = permalinkValidator.permalinkObject.featureObj;
294        }
295        else {
296            $scope.viewConfig.isValid = false;
297            permalinkValidator.removeInvalidPermalink();
298
299            // set default filters
300            var initialFilters = ['6', '11', '2']; //filters id -> service 'Filters'
301            $scope.viewConfig.searchMode = 'atrakcje';
302
303            $scope.viewConfig.initialFilters = initialFilters.filter(function(filterId) {
304              var showplaces = Filters.showplaces;
305              for (var i = 0; i < Filters.showplaces.length; i++) {
306                if (showplaces[i].id == filterId) {
307                  return true;
308                }
309              }
310              return false;
311            });
312
313            // listen for render map
314            $scope.$on('profile-map-rendered', function (event, mapSettings) {
315
316                var permalinkObject = {
317                    map: mapSettings,
318                    sidebarMode: $scope.viewConfig.searchMode,
319                    filters: $scope.viewConfig.initialFilters,
320                    featureObj: {
321                        id: '',
322                        type: ''
323                    }
324                };
325
326                permalinkUpdater.updateInitial(permalinkObject);
327
328                // fire after permalink initialized
329                $scope.map.initListener();
330            });
331        };
332    };
333
334
335
336    // load commune profile
337    $scope.profileLoading = function () {
338
339        $scope.profileDefer = new $q.defer();
340        Profile.getParametersFromPermalink(); //get parameters from permalink
341        Profile.getProfileFromServer().then(function () { //get commune profile from server
342
343            $scope.profileParameters = Profile.parameters;
344
345            //set title of map
346            document.title = 'Mapa turystyczna gminy ' + $scope.profileParameters.name;
347
348            var categoriesDefer = Filters.getAllCategories(); //get commune's unique categories for building advanced filter
349
350            $q.when(categoriesDefer.promise).then(function sucessCallback () {
351                //run setting app config
352                $scope.setAppConfig(permalinkValidator);
353
354                $scope.profileDefer.resolve(); //resolve when filters data is ready
355            });
356        });
357
358        return $scope.profileDefer.promise;
359    };
360
361    //get const variables for map and assign them to local scope
362    $scope.map = {};
363    $scope.map.mapid = 'map';
364    $scope.map.mapVariable = L.map($scope.map.mapid, {
365        center: [50,20],
366        minZoom: 10,
367        maxZoom: 18,
368        zoom: 12,
369        layers: [],
370        zoomControl: false,
371        fadeAnimation: false
372    });
373
374    //success callback when loading profile is ready
375    $q.when($scope.profileLoading(), function () {
376        var southWest = L.latLng($scope.profileParameters.geojson.properties.miny - 0.08, $scope.profileParameters.geojson.properties.minx - 0.08);
377        var northEast = L.latLng($scope.profileParameters.geojson.properties.maxy + 0.001, $scope.profileParameters.geojson.properties.maxx + 0.001);
378        $scope.map.maxBounds = L.latLngBounds(southWest, northEast);
379
380        if ($scope.profileParameters.profileID === 2041) {
381          translate.init({
382            google: {
383              // languages: ['en'],
384              languages: [],
385            },
386            manually: {
387              languages: ['en', 'cs', 'pl'],
388              dictionary: strona_translate,
389            }
390          });
391        }
392        else {
393          currentLang = 'pl';
394        }
395    });
396}]);
397;app.controller('sidebarController', ['$scope', '$q', 'Filters', 'TuristicObjects', 'turisticObjectByClick', 'serverRoot', 'permalinkUpdater', 'proxyHost', 'debounce', function ($scope, $q, Filters, TuristicObjects, turisticObjectByClick, serverRoot, permalinkUpdater, proxyHost, debounce) {
398
399  /************************** CONTROLLER INITIAL VALUES ***************************/
400  //initial value for seachbar text input
401  $scope.requestFlag = true;
402  $scope.timer = 0;
403
404  //***
405  $scope.markersArray = [];
406
407  //initial values of display
408  $scope.filters = {
409    hidden: true,
410    showplaces: Filters.showplaces,
411    tracks: Filters.tracks,
412    events: Filters.events,
413    sleep: Filters.sleep,
414    sleepDetails: Filters.sleepDetails,
415    selectedFiltersNumber: 0,
416    selectedShowplacesFiltersIDs: [],
417    selectedTracksFiltersIDs: [],
418    selectedEventsFiltersIDs: [],
419    selectedSleepFiltersIDs: [],
420    selectedSleepDetailFiltersIDs: [],
421    tracksType: {
422      temat: true,
423      turyst: true,
424    },
425    tracksDifficulty: null,
426    tracksLength: {
427      from: null,
428      to: null,
429    },
430    tracksDifficultyLevels: ['', 'bardzo łatwy', 'łatwy', 'trudny', 'bardzo trudny'],
431    translates: {
432      wyczyscWszystko: strona_translate.pl.wyczyscWszystko,
433      filtry: strona_translate.pl.filtry,
434      szlakiTematyczne: strona_translate.pl.szlakiTematyczne,
435      szlakiTurystyczne: strona_translate.pl.szlakiTurystyczne,
436    },
437    searchDelay: 500,
438  };
439
440  //list of finded objects
441  $scope.list = {
442    hidden: true,
443    loadingAnim: false,
444    noFound: false,
445    //finded objects
446    allCount: 0,
447    activePage: 1,
448    turisticObjects: [],
449    //activated object
450    activatedState: false,
451    activatedId: false,
452    //track label temp point
453    trackLabel: L.layerGroup()
454  };
455
456  //searching filter
457  $scope.searchFilter = {
458    kl: [],
459    szukaj: '',
460    from: 0,
461    to: 10
462  };
463
464  $scope.locationURL = window.location;
465  $scope.activetedObject = false;
466
467  $scope.integrate = {
468    getBounds: false,
469    bounds: null
470  }
471
472
473  /************************* FUNCTIONS FOR PERMALINK ***************************/
474
475  $scope.updateFiltersPermalink = function () {
476    if ($scope.viewConfig.searchMode === 'atrakcje') {
477      permalinkUpdater.updateFiltersLink($scope.filters.selectedShowplacesFiltersIDs);
478    } else if ($scope.viewConfig.searchMode === 'szlaki') {
479      permalinkUpdater.updateFiltersLink($scope.filters.selectedTracksFiltersIDs);
480    } else if ($scope.viewConfig.searchMode === 'wydarzenia') {
481      permalinkUpdater.updateFiltersLink($scope.filters.selectedEventsFiltersIDs);
482    } else {
483      // sleeps
484      permalinkUpdater.updateFiltersLink($scope.filters.selectedSleepFiltersIDs);
485    };
486
487  };
488
489
490  /************************** SEARCH MODES HANDLERS ***************************/
491  $scope.changeSearchMode = function (modeString) {
492
493    // clear list and text
494    $scope.list.turisticObjects = [];
495    if ($scope.searchFilter.szukaj.length != 0) {
496      $scope.searchFilter.szukaj = '';
497    };
498
499    if (modeString !== $scope.viewConfig.searchMode) {
500
501      // change to new mode string
502      $scope.viewConfig.searchMode = modeString;
503
504      // update permalink
505      permalinkUpdater.updateModeLink(modeString);
506
507      if (modeString === 'atrakcje') {
508        permalinkUpdater.updateFiltersLink($scope.filters.selectedShowplacesFiltersIDs);
509        $scope.filters.selectedFiltersNumber = $scope.filters.selectedShowplacesFiltersIDs.length;
510      } else if (modeString === 'szlaki') {
511        permalinkUpdater.updateFiltersLink($scope.filters.selectedTracksFiltersIDs);
512        $scope.filters.selectedFiltersNumber = $scope.filters.selectedTracksFiltersIDs.length;
513      } else if (modeString === 'wydarzenia') {
514        // events
515        permalinkUpdater.updateFiltersLink($scope.filters.selectedEventsFiltersIDs);
516        $scope.filters.selectedFiltersNumber = $scope.filters.selectedEventsFiltersIDs.length;
517      } else {
518        // sleeps
519        permalinkUpdater.updateFiltersLink($scope.filters.selectedSleepFiltersIDs);
520        $scope.filters.selectedFiltersNumber = $scope.filters.selectedSleepFiltersIDs.length + $scope.filters.selectedSleepDetailFiltersIDs.length;
521      };
522
523      // send new request
524      $scope.refreshPagination();
525      //      console.log('sendRequest()');
526      $scope.sendRequest();
527    };
528
529    $scope.translatePage();
530
531  };
532
533  /************************** MAIN CONTAINER STATES ***************************/
534  //user interaction events
535  $scope.changeContainerStatus = function ($event) {
536    //if filters header was clicked
537    if ($($event.currentTarget).hasClass('filters-header')) {
538      if ($scope.filters.hidden === true) {
539        $scope.filters.hidden = false;
540        $scope.list.hidden = true;
541      } else {
542        $scope.filters.hidden = true;
543      };
544    }
545    //if list header was clicked
546    else {
547      if ($scope.list.hidden === true) {
548        $scope.list.hidden = false;
549        $scope.filters.hidden = true;
550      } else {
551        $scope.list.hidden = true;
552      };
553    };
554  };
555
556  /************************** FILTERS INTERACTION ***************************/
557  //filters events
558  $scope.removeAllFilters = function () {
559    $scope.$broadcast('remove-all-filters'); //broadcast to all filters
560    $scope.filters.selectedFiltersNumber = 0; //change number of selected filters
561    if ($scope.list.noFound === true) {
562      $scope.list.noFound = false;
563    };
564
565    $scope.list.turisticObjects = [];
566
567    switch ($scope.viewConfig.searchMode) {
568      case 'atrakcje':
569        $scope.filters.selectedShowplacesFiltersIDs = [];
570        break;
571      case 'szlaki':
572        $scope.filters.selectedTracksFiltersIDs = [];
573        break;
574      case 'wydarzenia':
575        $scope.filters.selectedEventsFiltersIDs = [];
576        break;
577      default:
578        $scope.filters.selectedSleepFiltersIDs = [];
579        $scope.filters.selectedSleepDetailFiltersIDs = [];
580
581        // broadcast to deail filters groups and filters to change their state
582        $scope.$broadcast('cancel-filters', {});
583        break;
584    };
585
586    //    console.log('sendRequest()');
587    $scope.sendRequest();
588    $scope.refreshPagination();
589
590    $scope.updateFiltersPermalink();
591  };
592
593  $scope.addFilter = function (id) {
594
595    var id = id.toString();
596
597    if ($scope.viewConfig.searchMode === 'atrakcje') {
598      var index = $scope.filters.selectedShowplacesFiltersIDs.indexOf(id);
599      if (index === -1) {
600        $scope.filters.selectedShowplacesFiltersIDs.push(id);
601        $scope.filters.selectedFiltersNumber = $scope.filters.selectedShowplacesFiltersIDs.length;
602      };
603    } else if ($scope.viewConfig.searchMode === 'szlaki') {
604      var index = $scope.filters.selectedTracksFiltersIDs.indexOf(id);
605      if (index === -1) {
606        $scope.filters.selectedTracksFiltersIDs.push(id);
607        $scope.filters.selectedFiltersNumber = $scope.filters.selectedTracksFiltersIDs.length;
608      };
609    } else if ($scope.viewConfig.searchMode === 'wydarzenia') {
610      var index = $scope.filters.selectedEventsFiltersIDs.indexOf(id);
611      if (index === -1) {
612        $scope.filters.selectedEventsFiltersIDs.push(id);
613        $scope.filters.selectedFiltersNumber = $scope.filters.selectedEventsFiltersIDs.length;
614      };
615    } else {
616      var index = $scope.filters.selectedSleepFiltersIDs.indexOf(id);
617      if (index === -1) {
618        $scope.filters.selectedSleepFiltersIDs.push(id);
619        $scope.filters.selectedFiltersNumber = $scope.filters.selectedSleepFiltersIDs.length + $scope.filters.selectedSleepDetailFiltersIDs.length;
620      };
621    };
622
623    $scope.clearActivatedObjectFromList();
624
625    $scope.refreshPagination();
626    //    console.log('sendRequest');
627    $scope.sendRequest();
628
629    $scope.updateFiltersPermalink();
630  };
631
632  $scope.removeFilter = function (id) {
633
634    var id = id.toString();
635
636    if ($scope.viewConfig.searchMode == 'atrakcje') {
637
638      var index = $scope.filters.selectedShowplacesFiltersIDs.indexOf(id);
639      if (index != -1) {
640        $scope.filters.selectedShowplacesFiltersIDs.splice(index, 1);
641        $scope.filters.selectedFiltersNumber = $scope.filters.selectedShowplacesFiltersIDs.length;
642      };
643
644    } else if ($scope.viewConfig.searchMode == 'szlaki') {
645      var index = $scope.filters.selectedTracksFiltersIDs.indexOf(id);
646      if (index != -1) {
647        $scope.filters.selectedTracksFiltersIDs.splice(index, 1);
648        $scope.filters.selectedFiltersNumber = $scope.filters.selectedTracksFiltersIDs.length;
649      };
650    } else if ($scope.viewConfig.searchMode == 'wydarzenia') {
651
652      var index = $scope.filters.selectedEventsFiltersIDs.indexOf(id);
653      if (index != -1) {
654        $scope.filters.selectedEventsFiltersIDs.splice(index, 1);
655        $scope.filters.selectedFiltersNumber = $scope.filters.selectedEventsFiltersIDs.length;
656      };
657    } else {
658      var index = $scope.filters.selectedSleepFiltersIDs.indexOf(id);
659      if (index != -1) {
660        $scope.filters.selectedSleepFiltersIDs.splice(index, 1);
661        $scope.filters.selectedFiltersNumber = $scope.filters.selectedSleepFiltersIDs.length + $scope.filters.selectedSleepDetailFiltersIDs.length;
662      };
663    };
664
665    $scope.clearActivatedObjectFromList();
666
667    $scope.refreshPagination();
668    //    console.log('sendRequest()');
669    $scope.sendRequest();
670
671    $scope.updateFiltersPermalink();
672  };
673
674
675  /************************** INTEGRATION ***************************/
676  $scope.onIntegrateChange = function() {
677    $scope.list.turisticObjects = [];
678
679    if (!$scope.integrate.getBounds) {
680      $scope.integrate.bounds = null;
681      delete $scope.searchFilter.latmin;
682      delete $scope.searchFilter.lngmin;
683      delete $scope.searchFilter.latmax;
684      delete $scope.searchFilter.lngmax;
685    }
686    else {
687      var bounds = $scope.mapObj.mapVariable.getBounds();
688      $scope.integrate.bounds = bounds;
689    }
690
691    $scope.refreshPagination();
692    $scope.sendRequest();
693  };
694
695  /************************** LIST INTERACTION ***************************/
696  $scope.clearActivatedObjectFromList = function () {
697    if ($scope.list.activatedState === true) {
698      $scope.$broadcast('list-remove-activated', {
699        activeIndex: $scope.list.activatedId,
700        changeListState: true
701      });
702    };
703  };
704
705  //search bar interaction
706  $scope.userKeyPress = function () {
707
708    if ($scope.requestFlag === true) {
709
710      //clear list
711      if ($scope.list.turisticObjects.length > 0) {
712        $scope.list.turisticObjects = [];
713      }
714
715      //clear no found text
716      if ($scope.list.noFound === true) {
717        $scope.list.noFound = false;
718      };
719
720      //broadcast removing active list object if exist
721      if ($scope.list.activatedState === true) {
722        $scope.$broadcast('list-remove-activated', {
723          activeId: $scope.list.activatedId,
724          changeListState: true
725        });
726      };
727
728      clearTimeout($scope.timer);
729      $scope.loadingAnimationOn();
730
731      $scope.timer = setTimeout(function () {
732        $scope.refreshPagination();
733        //        console.log('sendRequest()');
734        $scope.sendRequest();
735      }, 600);
736
737    };
738  };
739
740  $scope.removeSearchText = function () {
741    //    console.log('removeSearchText');
742    if ($scope.requestFlag === true) {
743      //clear list
744      $scope.list.turisticObjects = []
745      //remove text filter
746      $scope.searchFilter.szukaj = '';
747      //turn on loading animation
748      $scope.loadingAnimationOn();
749      //send new request without text
750      $scope.refreshPagination();
751      $scope.sendRequest();
752    };
753  };
754
755  $scope.sendRequest = function () {
756    //    console.log('sendRequest');
757    $scope.requestFlag = false;
758
759    if ($scope.list.loadingAnim === false) {
760      if ($scope.list.activatedState === false) {
761        $scope.list.loadingAnim = true;
762      };
763    };
764
765    //remove 'no found' text if exist
766    if ($scope.list.noFound === true) {
767      $scope.list.noFound = false;
768    };
769
770    if ($scope.integrate.bounds) {
771      $scope.searchFilter.latmin = $scope.integrate.bounds.getSouth();
772      $scope.searchFilter.lngmin = $scope.integrate.bounds.getWest();
773      $scope.searchFilter.latmax = $scope.integrate.bounds.getNorth();
774      $scope.searchFilter.lngmax = $scope.integrate.bounds.getEast();
775    }
776
777    // check which request need to be send
778    var requestName = 'getTuristicObjects'; // default value
779
780    switch ($scope.viewConfig.searchMode) {
781
782      case 'szlaki':
783
784        requestName = 'getTracks';
785        $scope.searchFilter.kl = $scope.filters.selectedTracksFiltersIDs;
786        $scope.searchFilter.temat = $scope.filters.tracksType.temat;
787        $scope.searchFilter.turyst = $scope.filters.tracksType.turyst;
788        $scope.searchFilter.trudnosc = $scope.filters.tracksDifficulty;
789        $scope.searchFilter.dlugoscod = $scope.filters.tracksLength.from;
790        $scope.searchFilter.dlugoscdo = $scope.filters.tracksLength.to;
791
792        break;
793
794      case 'atrakcje':
795
796        requestName = 'getTuristicObjects';
797        $scope.searchFilter.kl = $scope.filters.selectedShowplacesFiltersIDs;
798
799        break;
800
801      case 'wydarzenia':
802
803        requestName = 'getEvents';
804        $scope.searchFilter.kl = $scope.filters.selectedEventsFiltersIDs;
805        break;
806
807      default:
808
809        requestName = 'getSleeps';
810
811        // update number of filters
812        $scope.filters.selectedFiltersNumber = $scope.filters.selectedSleepFiltersIDs.length + $scope.filters.selectedSleepDetailFiltersIDs.length;
813
814        // handling building proper filter for request
815        $scope.searchFilter.kl = $scope.filters.selectedSleepFiltersIDs;
816
817        if ($scope.filters.selectedSleepDetailFiltersIDs.length > 0) {
818
819          $scope.searchFilter.sl = $scope.filters.selectedSleepDetailFiltersIDs;
820
821        } else {
822
823          // if 'sl' parameter exist in global filter -> remove it
824          if ($scope.searchFilter.sl) {
825            delete $scope.searchFilter.sl;
826          };
827
828        };
829
830        break;
831
832    };
833
834    return TuristicObjects[requestName]($scope.searchFilter).then(function () { //success downloaded turistic objects
835      $scope.requestFlag = true;
836      $scope.list.turisticObjects = TuristicObjects.objects;
837      $scope.list.allCount = TuristicObjects.allCount;
838      $scope.list.loadingAnim = false; //turn off animation
839
840      $.each($scope.list.turisticObjects, function (i, v) {
841        $scope.markersArray.push(v);
842      });
843
844
845      // map
846      $scope.mapObj.removeTuristicObjectsFromMap(); // remove if some exist
847
848      // add leaflet vector objects to map
849      if ($scope.viewConfig.searchMode === 'szlaki') {
850
851        $scope.mapObj.addTracksToMap();
852
853      } else {
854        $scope.mapObj.addTuristicObjectsToMap();
855
856        // if 'sl' parameter exist in global filter -> remove it
857        if ($scope.searchFilter.sl) {
858          delete $scope.searchFilter.sl;
859        };
860
861      };
862
863      if ($scope.list.allCount === 0) {
864        if ($scope.list.activatedState === false) {
865          $scope.list.noFound = true;
866        };
867      };
868
869      //broadcast creating pagination for finded objects
870      $scope.$broadcast('create-pagination');
871
872      $scope.translatePage();
873
874    });
875  };
876
877  //loading animations handlers
878  $scope.loadingAnimationOn = function () {
879    //    console.log('loadingAnimationOn');
880    if ($scope.filters.hidden === false) {
881      $scope.filters.hidden = true;
882    };
883    if ($scope.list.hidden === true) {
884      $scope.list.hidden = false;
885    };
886    if ($scope.list.loadingAnim === false) {
887      $scope.list.loadingAnim = true;
888    };
889
890  };
891
892  $scope.loadingAnimationOff = function () {
893    if ($scope.list.hidden === false) {
894      $scope.list.hidden = true;
895    };
896    if ($scope.list.loadingAnim === true) {
897      $scope.list.loadingAnim = false;
898    };
899  };
900
901  //refresh pagination after user keypress
902  $scope.refreshPagination = function () {
903    //    console.log('refreshPagination');
904    if ($scope.searchFilter.activePage != 1) {
905      $scope.list.activePage = 1;
906      $scope.searchFilter.from = 0;
907      $scope.searchFilter.to = 10;
908
909    };
910  };
911
912  //translate page
913  $scope.translatePage = function (settings) {
914    settings = settings || {};
915    var timeout = settings.timeout || 0;
916
917    setTimeout(function () {
918      translate.translatePageManually(currentLang, currentLang);
919    }, timeout);
920  };
921
922  $scope.getTuristicObjectById = function (id) {
923
924    var list = $scope.list.turisticObjects;
925    var selectedIndex = '';
926
927    angular.forEach(list, function (showplace, index) {
928      if (showplace.hasOwnProperty('id')) {
929        if (showplace.id == id) {
930          selectedIndex = index;
931        };
932      };
933    });
934
935    return list[selectedIndex];
936  };
937
938  //activate turistic object mode
939  $scope.activateTuristicObject = function (settings) {
940    $scope.activetedObject = true;
941
942    var id = settings.id;
943    var turisticObj = $scope.getTuristicObjectById(id);
944
945    //if there is no activate state on list container
946    if ($scope.list.activatedState != true) {
947      $scope.list.activatedState = true;
948
949      turisticObj.naTrasie = strona_translate[currentLang].naTrasie;
950      turisticObj.podstawowe = strona_translate[currentLang].podstawowe;
951      turisticObj.opis = strona_translate[currentLang].opis;
952      turisticObj.cena = strona_translate[currentLang].cena;
953      turisticObj.sczegolyOferty = strona_translate[currentLang].sczegolyOferty;
954      turisticObj.jezyki = strona_translate[currentLang].jezyki;
955
956      //broadcast activated to turistic object activated container
957      $scope.$broadcast('object-activated', {
958        id: id,
959        activatedObject: turisticObj,
960        fromList: settings.fromList
961      });
962
963      //zoom to marker
964      $scope.mapObj.zoomToCoords(turisticObj.geometry.coords);
965
966      // $scope.setPointedFeature(id);
967    }
968    //if list container is on activated state already
969    else {
970      //check if clicked id is the same which already added activated object
971      if (id != $scope.list.activatedId) {
972        $scope.$broadcast('list-remove-activated', {
973          activeId: $scope.list.activatedId, //remove existing one
974          changeListState: false
975        });
976
977        turisticObj.naTrasie = strona_translate[currentLang].naTrasie;
978        turisticObj.podstawowe = strona_translate[currentLang].podstawowe;
979        turisticObj.opis = strona_translate[currentLang].opis;
980        turisticObj.cena = strona_translate[currentLang].cena;
981        turisticObj.sczegolyOferty = strona_translate[currentLang].sczegolyOferty;
982        turisticObj.jezyki = strona_translate[currentLang].jezyki;
983
984        //activate new one
985        $scope.$broadcast('object-activated', {
986          id: id,
987          activatedObject: turisticObj,
988          fromList: settings.fromList
989        });
990
991        //zoom to marker
992        $scope.mapObj.zoomToCoords(turisticObj.geometry.coords);
993
994        // $scope.setPointedFeature(id);
995
996      };
997    };
998
999    $scope.translatePage();
1000
1001  };
1002
1003  //remove activated
1004  $scope.$on('remove-activated', function (event, args) {
1005    if (args.changeListState) {
1006      $scope.list.activatedState = false;
1007    };
1008
1009    if (!$scope.list.noFound) {
1010      if ($scope.list.turisticObjects.length === 0) {
1011        $scope.list.noFound = true;
1012      };
1013    };
1014
1015    if (args.showMarkers) {
1016      $scope.mapObj.hideMarkers();
1017      $scope.mapObj.showMarkers();
1018    }
1019
1020    // check if window width is like mobile one
1021    // check if object has been activated from map or list
1022    if (window.outerWidth < 768 && args.fromList == false) {
1023      $scope.list.hidden = true;
1024    };
1025  });
1026
1027  //activate turistic object mode
1028  $scope.downloadGPX = function (settings) {
1029    var id = settings.id;
1030    var turisticObj = $scope.getTuristicObjectById(id);
1031
1032    var fileName = 'szlak-' + id + '.gpx';
1033    var url = proxyHost + serverRoot + 'Szlak/GPXGeometry/' + id;
1034
1035    $scope.downloadDataUrlFromJavascript(fileName, url);
1036  };
1037
1038  $scope.downloadDataUrlFromJavascript = function(filename, dataUrl) {
1039
1040    // Construct the 'a' element
1041    var link = document.createElement("a");
1042    link.download = filename;
1043    link.target = "_blank";
1044
1045    // Construct the URI
1046    link.href = dataUrl;
1047    document.body.appendChild(link);
1048    link.click();
1049
1050    // Cleanup the DOM
1051    document.body.removeChild(link);
1052    delete link;
1053  }
1054
1055  /************************** MAP INTEGRATION ***************************/
1056  $scope.mapObj.turisticLeafletObjects = new L.layerGroup();
1057
1058  $scope.mapObj.zoomToCoords = function (coords) {
1059    // zoom to point/track event
1060    // check for coords type to detect point or line
1061    var singleCoord = coords[0];
1062
1063    if (!angular.isObject(singleCoord)) {
1064      // point
1065      var zoom = $scope.mapObj.mapVariable.getZoom();
1066      if (zoom != 18) {
1067        $scope.mapObj.mapVariable.setView(coords, 18, {
1068          animate: true,
1069          reset: true
1070        });
1071      } else {
1072        $scope.mapObj.mapVariable.panTo(coords, {
1073          animate: true
1074        });
1075      };
1076    } else {
1077      //line
1078      var lineBounds = L.latLngBounds(coords);
1079      $scope.mapObj.mapVariable.fitBounds(lineBounds, {
1080        animate: true
1081      });
1082    };
1083  };
1084
1085  //turistic object activate integration with map
1086  $scope.mapObj.clickOnMarker = function (e) {
1087    //if panel is hidden -> show it
1088    if ($scope.list.hidden === true) {
1089      $scope.list.hidden = false;
1090    };
1091
1092    //if filters panel are opened -> close them
1093    if ($scope.filters.hidden === false) {
1094      $scope.filters.hidden = true;
1095    };
1096
1097    var id = e.target._leaflet_id;
1098    angular.forEach($scope.list.turisticObjects, function (showplace, index) {
1099      if (showplace._leaflet_id === id) {
1100        $scope.activateTuristicObject({
1101          id: showplace.id,
1102          fromList: false
1103        });
1104      };
1105    });
1106
1107  };
1108
1109  $scope.mapObj.clickOnLine = function (e) {
1110    //if panel is hidden -> show it
1111    if ($scope.list.hidden === true) {
1112      $scope.list.hidden = false;
1113    };
1114
1115    //if filters panel are opened -> close them
1116    if ($scope.filters.hidden === false) {
1117      $scope.filters.hidden = true;
1118    };
1119
1120    var id = e.target._leaflet_id;
1121    angular.forEach($scope.list.turisticObjects, function (track, index) {
1122      if (track._leaflet_id === id) {
1123        $scope.activateTuristicObject({
1124          id: track.id,
1125          fromList: false
1126        });
1127      };
1128    });
1129  };
1130
1131  $scope.mapObj.addTuristicObjectsToMap = function () {
1132    if ($scope.list.turisticObjects.length > 0) {
1133      //check if list has any objects
1134      angular.forEach($scope.list.turisticObjects, function (obj, index) {
1135
1136        if (obj._leaflet_id == undefined) {
1137          $scope.mapObj.addMarker(obj);
1138        }
1139      });
1140    };
1141    if ($scope.viewConfig.selectedFeature && $scope.viewConfig.selectedFeature != '') {
1142      //add only one marker
1143      TuristicObjects.getObjectById($scope.viewConfig.selectedFeature).then(function (response) {
1144        try {
1145          var object = angular.fromJson(response.data.flist[0]);
1146          if ($scope.viewConfig.selectedFeature.type === 's') {
1147            // showplace
1148            var obj = TuristicObjects.objectToTuristicObject(object, false);
1149            if ($scope.list.turisticObjects.find(function (o) {
1150                return o.id == obj.id
1151              }) == undefined) {
1152              $scope.mapObj.addMarker(obj);
1153
1154              if ($scope.markersArray.find(function (o) {
1155                  return o.id == obj.id
1156                }) == undefined) {
1157                $scope.markersArray.push(obj);
1158              } else {
1159                var find = $scope.markersArray.find(function (o) {
1160                  return o.id == obj.id
1161                });
1162                var index = $.inArray(find, $scope.markersArray);
1163                $scope.markersArray[index] = obj;
1164              }
1165              $scope.mapObj.turisticLeafletObjects._layers[obj._leaflet_id].addTo($scope.mapObj.mapVariable);
1166            } else {
1167              var objId = $scope.list.turisticObjects.find(function (o) {
1168                return o.id == obj.id
1169              });
1170              $scope.mapObj.turisticLeafletObjects._layers[objId._leaflet_id].addTo($scope.mapObj.mapVariable);
1171            }
1172          }
1173
1174        } catch (e) {
1175          console.log('Błąd pobierania punktu');
1176        };
1177      });
1178    } else {
1179      //add 10 markers
1180      $scope.mapObj.turisticLeafletObjects.addTo($scope.mapObj.mapVariable);
1181    }
1182  };
1183
1184  $scope.mapObj.addMarker = function (obj) {
1185    var icon = L.icon({
1186      iconSize: [28, 28],
1187      iconAnchor: [16, 37],
1188      popupAnchor: [0, -5],
1189      iconUrl: obj.graphic.icon
1190    });
1191
1192    var marker = L.marker(obj.geometry.coords, {
1193      icon: icon,
1194      riseOnHover: true
1195    }).bindLabel(obj.desc.name, {
1196      noHide: false
1197    });
1198
1199    marker.on('mouseover', function () {
1200      $scope.translatePage();
1201    });
1202    if (marker != undefined && marker._latlng != null) {
1203      $scope.mapObj.turisticLeafletObjects.addLayer(marker);
1204    }
1205
1206    //register click handler
1207    marker.on('click', $scope.mapObj.clickOnMarker);
1208
1209    //add leaflet id to list
1210    if (marker._leaflet_id != undefined) {
1211      obj._leaflet_id = marker._leaflet_id;
1212    }
1213  }
1214
1215  $scope.mapObj.checkMarkersArray = function (obj) {
1216    if ($scope.markersArray.find(function (o) {
1217        return o.id == obj.id
1218      }) == undefined) {
1219      $scope.markersArray.push(obj);
1220    } else {
1221      var find = $scope.markersArray.find(function (o) {
1222        return o.id == obj.id
1223      });
1224      var index = $.inArray(find, $scope.markersArray);
1225      $scope.markersArray[index] = obj;
1226    }
1227  }
1228
1229  $scope.mapObj.showMarker = function (obj) {
1230    if (obj.geometryType == 'point') {
1231      if (($scope.mapObj.mapVariable).hasLayer($scope.mapObj.turisticLeafletObjects._layers[obj._leaflet_id])) {
1232        var leafletObj = $scope.mapObj.turisticLeafletObjects.getLayer(obj._leaflet_id);
1233      } else {
1234        $scope.mapObj.addMarker(obj);
1235        $scope.mapObj.checkMarkersArray(obj);
1236
1237        $scope.mapObj.turisticLeafletObjects._layers[obj._leaflet_id].addTo($scope.mapObj.mapVariable);
1238        var leafletObj = $scope.mapObj.turisticLeafletObjects.getLayer(obj._leaflet_id);
1239      }
1240//      if (obj.geometryType === 'point') {
1241        var icon = L.icon({
1242          iconSize: [28, 28],
1243          iconAnchor: [16, 37],
1244          popupAnchor: [0, -5],
1245          iconUrl: obj.graphic.icon
1246        });
1247        leafletObj.setIcon(icon);
1248//      }
1249    }
1250  }
1251
1252  $scope.mapObj.showMarkers = function () {
1253    $.each($scope.list.turisticObjects, function (i, v) {
1254      $scope.mapObj.showMarker(v);
1255    });
1256  }
1257
1258  $scope.mapObj.hideMarker = function (obj) {
1259    if (obj.geometryType == 'point') {
1260    if (($scope.mapObj.mapVariable).hasLayer($scope.mapObj.turisticLeafletObjects._layers[obj._leaflet_id])) {
1261      var leafletObj = $scope.mapObj.turisticLeafletObjects.getLayer(obj._leaflet_id);
1262    } else {
1263      $scope.mapObj.addMarker(obj);
1264      $scope.mapObj.checkMarkersArray(obj);
1265      $scope.mapObj.turisticLeafletObjects._layers[obj._leaflet_id].addTo($scope.mapObj.mapVariable);
1266      var leafletObj = $scope.mapObj.turisticLeafletObjects.getLayer(obj._leaflet_id);
1267    }
1268//    if (obj.geometryType === 'point') {
1269      var invisibleIcon = L.icon({
1270        iconSize: [0, 0],
1271        iconAnchor: [0, 0],
1272        popupAnchor: [0, 0],
1273        iconUrl: obj.graphic.icon
1274      });
1275
1276      leafletObj.setIcon(invisibleIcon);
1277//    }
1278  }}
1279
1280  $scope.mapObj.hideMarkers = function () {
1281
1282    $.each($scope.markersArray, function (i, v) {
1283      $scope.mapObj.hideMarker(v);
1284    });
1285  }
1286
1287  $scope.mapObj.checkMarkers = function () {
1288    return ($scope.markersArray.length > 0 ? true : false);
1289  }
1290
1291  $scope.mapObj.addTracksToMap = function () {
1292
1293    if ($scope.list.turisticObjects.length > 0) {
1294      angular.forEach($scope.list.turisticObjects, function (track, index) {
1295        var polylineFunction = (TuristicObjects.coordsDeepLevel(track.geometry.coords) == 0) ? 'polyline' : 'multiPolyline';
1296
1297        var polyline = L[polylineFunction](track.geometry.coords, {
1298          color: track.desc.color,
1299          weight: 6
1300        }).bindLabel(track.desc.name, {
1301          noHide: false
1302        });
1303
1304        $scope.mapObj.turisticLeafletObjects.addLayer(polyline);
1305
1306        // register click handler
1307        polyline.on('click', $scope.mapObj.clickOnLine);
1308
1309        // add leaflet id to list
1310        track._leaflet_id = polyline._leaflet_id;
1311      });
1312      $scope.mapObj.turisticLeafletObjects.addTo($scope.mapObj.mapVariable);
1313    };
1314  };
1315
1316  $scope.mapObj.removeTuristicObjectsFromMap = function () {
1317    if ($scope.mapObj.turisticLeafletObjects.getLayers().length > 0) {
1318      try {
1319        $scope.mapObj.turisticLeafletObjects.clearLayers();
1320      } catch (e) {
1321
1322      }
1323
1324    };
1325  };
1326
1327  //mouse interaction with list obj -> map reaction
1328  $scope.mouseEnter = function (id) {
1329    var listObj = $scope.getTuristicObjectById(id);
1330    var leafletObj = $scope.mapObj.turisticLeafletObjects.getLayer(listObj._leaflet_id);
1331    if (listObj.geometryType === 'point') {
1332
1333      var bigIcon = L.icon({
1334        iconSize: [32, 32],
1335        iconAnchor: [20, 42],
1336        popupAnchor: [0, -5],
1337        iconUrl: listObj.graphic.icon
1338      });
1339
1340      leafletObj.setIcon(bigIcon);
1341      leafletObj.showLabel();
1342    } else {
1343      // geometry type === 'line'
1344      leafletObj.setStyle({
1345        weight: 10
1346      });
1347
1348      if ($scope.list.trackLabel.getLayers().length === 0) {
1349        // add temp point and display label
1350        var latLngs = leafletObj.getLatLngs();
1351        var coordsDeepLevel = TuristicObjects.coordsDeepLevel(latLngs);
1352
1353        if (coordsDeepLevel == 1) {
1354          var latLngs = [].concat.apply([], latLngs);
1355        }
1356
1357        var length = latLngs.length;
1358        var middleIndex = Math.round(length / 2);
1359
1360        var middlePoint = latLngs[middleIndex];
1361
1362        var point = L.circleMarker(middlePoint, {}).bindLabel(listObj.desc.name, {
1363          noHide: true
1364        });
1365
1366        point.setRadius(0);
1367
1368        $scope.list.trackLabel.addLayer(point);
1369        $scope.mapObj.mapVariable.addLayer($scope.list.trackLabel);
1370      };
1371    };
1372
1373    $scope.translatePage();
1374
1375  };
1376
1377  $scope.mouseLeave = function (id) {
1378
1379    if (!$scope.activetedObject) {
1380      var listObj = $scope.getTuristicObjectById(id);
1381      var leafletObj = $scope.mapObj.turisticLeafletObjects.getLayer(listObj._leaflet_id);
1382
1383      if (listObj.geometryType === 'point') {
1384
1385        var normalIcon = L.icon({
1386          iconSize: [28, 28],
1387          iconAnchor: [16, 37],
1388          popupAnchor: [0, -5],
1389          iconUrl: listObj.graphic.icon
1390        });
1391
1392        leafletObj.setIcon(normalIcon);
1393        leafletObj.hideLabel();
1394      } else {
1395        // geometry type === 'line'
1396        leafletObj.setStyle({
1397          weight: 6
1398        });
1399
1400        // remove displayed track label if exist
1401        if ($scope.list.trackLabel.getLayers().length != 0) {
1402          $scope.list.trackLabel.clearLayers();
1403          $scope.mapObj.mapVariable.removeLayer($scope.list.trackLabel);
1404        };
1405      };
1406    } else {
1407      $scope.activetedObject = false;
1408    }
1409
1410
1411  };
1412
1413  //mouse interaction with list obj -> map reaction
1414  $scope.setPointedFeature = function (id) {
1415    var listObj = $scope.getTuristicObjectById(id);
1416    var leafletObj = $scope.mapObj.turisticLeafletObjects.getLayer(listObj._leaflet_id);
1417    var pointedClassName = 'pointedFeature';
1418
1419    var prevImgs = document.getElementsByClassName(pointedClassName);
1420    //    console.log(prevImgs);
1421    if (prevImgs.length > 0) {
1422      prevImgs[0].classList.remove(pointedClassName);
1423    }
1424
1425
1426    if (listObj.geometryType === 'point') {
1427
1428      var bigIcon = L.icon({
1429        iconSize: [32, 32],
1430        iconAnchor: [20, 42],
1431        popupAnchor: [0, -5],
1432        iconUrl: listObj.graphic.icon,
1433        className: pointedClassName,
1434      });
1435
1436      leafletObj.setIcon(bigIcon);
1437    }
1438  };
1439
1440  $scope.removePointedFeatures = function (id) {
1441    var pointedClassName = 'pointedFeature';
1442
1443    var prevImgs = document.getElementsByClassName(pointedClassName);
1444    //    console.log(prevImgs);
1445    if (prevImgs.length > 0) {
1446      prevImgs[0].classList.remove(pointedClassName);
1447    }
1448  };
1449
1450  $scope.removePointedFeature = function (id) {
1451    var listObj = $scope.getTuristicObjectById(id);
1452    var leafletObj = $scope.mapObj.turisticLeafletObjects.getLayer(listObj._leaflet_id);
1453    if (listObj.geometryType === 'point') {
1454
1455      var bigIcon = L.icon({
1456        iconSize: [28, 28],
1457        iconAnchor: [16, 37],
1458        popupAnchor: [0, -5],
1459        iconUrl: listObj.graphic.icon,
1460      });
1461
1462      leafletObj.setIcon(bigIcon);
1463    }
1464  };
1465
1466  $scope.selectTracksDifficultyType = function (event) {
1467    if ($scope.filters.tracksDifficulty == '') {
1468      $scope.filters.tracksDifficulty = null;
1469    }
1470    $scope.sendRequest();
1471  }
1472
1473  //click on map listener
1474  $scope.mapObj.mapVariable.on('click', function (e) {
1475    var latlng = e.latlng;
1476    var zoom = $scope.mapObj.mapVariable.getZoom();
1477
1478    if (zoom > 13) {
1479      turisticObjectByClick.getObject(latlng.lat, latlng.lng).then(function successCallback(response) {
1480
1481        if ($scope.list.noFound === true) {
1482          $scope.list.noFound = false;
1483        };
1484
1485        //create turistic object
1486        var object = angular.fromJson(response.data.geom);
1487
1488        try {
1489          if (object.geometry.type === 'Point') {
1490            var obj = TuristicObjects.objectToTuristicObject(object, false);
1491          } else {
1492            var obj = TuristicObjects.trackToTuristicObject(object, false);
1493          }
1494
1495
1496          //check container state
1497          if ($scope.list.activatedState === true) {
1498
1499            if (obj.id != $scope.list.activatedId) {
1500              $scope.$broadcast('list-remove-activated', {
1501                activeId: $scope.list.activatedId, //remove existing one
1502                changeListState: false
1503              });
1504
1505              obj.naTrasie = strona_translate[currentLang].naTrasie;
1506              obj.podstawowe = strona_translate[currentLang].podstawowe;
1507              obj.opis = strona_translate[currentLang].opis;
1508              obj.cena = strona_translate[currentLang].cena;
1509              obj.sczegolyOferty = strona_translate[currentLang].sczegolyOferty;
1510              obj.jezyki = strona_translate[currentLang].jezyki;
1511
1512              $scope.$broadcast('object-activated', {
1513                id: obj.id, //remove existing one
1514                activatedObject: obj,
1515                fromList: false
1516              });
1517            };
1518          } else {
1519            //set container state
1520            $scope.list.activatedState = true;
1521            //emit event for list container to activate
1522
1523            obj.naTrasie = strona_translate[currentLang].naTrasie;
1524            obj.podstawowe = strona_translate[currentLang].podstawowe;
1525            obj.opis = strona_translate[currentLang].opis;
1526            obj.cena = strona_translate[currentLang].cena;
1527            obj.sczegolyOferty = strona_translate[currentLang].sczegolyOferty;
1528            obj.jezyki = strona_translate[currentLang].jezyki;
1529
1530            $scope.$broadcast('object-activated', {
1531              id: obj.id, //remove existing one
1532              activatedObject: obj,
1533              fromList: false
1534            });
1535          };
1536
1537          if ($scope.list.hidden === true) {
1538            $scope.list.hidden = false;
1539          };
1540
1541          if ($scope.filters.hidden === false) {
1542            $scope.filters.hidden = true;
1543          };
1544
1545          $scope.responsiveOptions();
1546
1547          $scope.translatePage();
1548
1549        } catch (e) {};
1550
1551      }, function errorCallback(response) {
1552        console.log('Błąd pobierania punktu');
1553      })
1554    };
1555  });
1556
1557  $scope.moveMapGetBounds = function(e) {
1558    if ($scope.integrate.getBounds) {
1559      $scope.list.turisticObjects = [];
1560
1561      var bounds = e.target.getBounds();
1562      $scope.integrate.bounds = bounds;
1563
1564      $scope.refreshPagination();
1565      $scope.sendRequest();
1566    }
1567  }
1568
1569  $scope.moveMapGetBoundsDebounced = debounce($scope.moveMapGetBounds, 1000, false);
1570
1571  $scope.mapObj.mapVariable.on('moveend', function (e) {
1572    $scope.moveMapGetBoundsDebounced(e);
1573  });
1574
1575
1576  //callback when loading profile is ready
1577  $q.when($scope.profileDefer.promise, function () {
1578    //modify filters depends on config variable
1579
1580    angular.forEach($scope.viewConfig.initialFilters, function (obj, index) {
1581
1582      if ($scope.viewConfig.searchMode === 'atrakcje') {
1583
1584        $scope.filters.selectedShowplacesFiltersIDs.push(obj);
1585
1586      } else if ($scope.viewConfig.searchMode === 'szlaki') {
1587
1588        $scope.filters.selectedTracksFiltersIDs.push(obj);
1589
1590      } else if ($scope.viewConfig.searchMode === 'wydarzenia') {
1591
1592        $scope.filters.selectedEventsFiltersIDs.push(obj);
1593
1594      } else {
1595        // sleeps
1596        $scope.filters.selectedSleepFiltersIDs.push(obj);
1597
1598      };
1599
1600    });
1601
1602    $scope.filters.selectedFiltersNumber = $scope.viewConfig.initialFilters.length;
1603
1604    $scope.list.hidden = false;
1605
1606    //send initial request
1607    //    console.log('sendRequest()');
1608
1609    $scope.sendRequest();
1610
1611    // display selected object from permalink
1612    if ($scope.viewConfig.isValid === true && typeof $scope.viewConfig.selectedFeature.type != undefined && typeof $scope.viewConfig.selectedFeature.id != 'undefined') {
1613
1614      TuristicObjects.getObjectById($scope.viewConfig.selectedFeature).then(function (response) {
1615        if ($scope.list.loadingAnim === true) {
1616          $scope.list.loadingAnim = false;
1617        };
1618
1619        if ($scope.list.activatedState === false) {
1620          $scope.list.activatedState = true;
1621        };
1622
1623        try {
1624          var object = angular.fromJson(response.data.flist[0]);
1625
1626          if ($scope.viewConfig.selectedFeature.type === 's') {
1627            // showplace
1628            var obj = TuristicObjects.objectToTuristicObject(object, false);
1629          } else if ($scope.viewConfig.selectedFeature.type === 't') {
1630            // track
1631            var obj = TuristicObjects.trackToTuristicObject(object, false);
1632          } else if ($scope.viewConfig.selectedFeature.type === 'e') {
1633            // event
1634            var obj = TuristicObjects.eventToTuristicObject(object, false);
1635          } else {
1636            // sleeps
1637            var obj = TuristicObjects.sleepToTuristicObject(object, false);
1638          };
1639
1640          if (!angular.equals({}, obj)) { // if object is not empty
1641
1642            obj.naTrasie = strona_translate[currentLang].naTrasie;
1643            obj.podstawowe = strona_translate[currentLang].podstawowe;
1644            obj.opis = strona_translate[currentLang].opis;
1645            obj.cena = strona_translate[currentLang].cena;
1646            obj.sczegolyOferty = strona_translate[currentLang].sczegolyOferty;
1647            obj.jezyki = strona_translate[currentLang].jezyki;
1648
1649            $scope.$broadcast('object-activated', {
1650              id: obj.id,
1651              activatedObject: obj,
1652              fromList: false
1653            });
1654          };
1655        } catch (e) {
1656          console.log('Błąd pobierania punktu');
1657        };
1658      });
1659
1660    };
1661  });
1662
1663  $scope.responsiveOptions = function () {
1664    if ($(window).width() <= 768) {
1665      showObjectNameOnTheBottom();
1666    }
1667  }
1668
1669  $scope.updateListnum = function () {
1670    if ($scope.list.allCount > 0) {
1671      $('.mobile-listnum').text($scope.list.allCount);
1672    } else {
1673      $('.mobile-listnum').text('');
1674    }
1675  }
1676
1677  $scope.updatingListnum = function () {
1678    if ($(window).width() <= 768) {
1679      setInterval(function () {
1680        $scope.updateListnum();
1681      }, 1000);
1682    }
1683  }();
1684
1685
1686}]);
1687;app.directive('map', ['Profile', '$q', 'permalinkUpdater', '$compile', 'proxyHost', 'serverRoot', function (Profile ,$q, permalinkUpdater, $compile, proxyHost, serverRoot) {
1688    return {
1689        restrict: 'A',
1690        replace: false,
1691        scope: {
1692            mapObj: '=',
1693            profileDefer: '=',
1694            borders: '=',
1695            viewConfig: '='
1696        },
1697        link: function ($scope, $element, $attrs) {
1698
1699            $scope.mapObj.getCommuneBorders = function () {
1700
1701                return L.geoJson($scope.borders, {
1702                    clickable: false,
1703                    style: function (feature) {
1704                        return {
1705                            opacity: 0.5,
1706                            fillOpacity: 0,
1707                            weight: 20,
1708                            color: "#7fafff"
1709                            };
1710                    }
1711                });
1712            };
1713
1714            $scope.mapObj.mapInit = function () {
1715
1716                $scope.urls = {
1717                    commune: 'https://administracja.gison.pl/cgi-bin/mapserv?map=/home/vboxuser/mpzp/turysta_gmina_profil.map&profil=' + Profile.parameters.profileID,
1718                    localGroup: 'https://administracja.gison.pl/cgi-bin/mapserv?map=/home/vboxuser/mpzp/turysta_lgd_profil.map&profil=' + Profile.parameters.profileID
1719                };
1720
1721                $scope.sourceUrl = (Profile.parameters.type == 'lgd') ? $scope.urls.localGroup : $scope.urls.commune;
1722
1723    			$scope.source = L.WMS.source($scope.sourceUrl, {
1724                    attribution: 'Data &copy; by <a href="http://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>.',
1725                    minZoom: 5,
1726                    maxZoom: 18,
1727                    zIndex: 2,
1728    				transparent: true,
1729    				format: 'image/png',
1730    				identify: false
1731                });
1732
1733                $scope.mapObj.turisticLayer = $scope.source.getLayer('turysta');
1734
1735                //add initial layers
1736                $scope.mapObj.mapVariable.addLayer($scope.mapObj.turisticLayer);
1737                $scope.mapObj.communeBorders = $scope.mapObj.getCommuneBorders();
1738                $scope.mapObj.mapVariable.addLayer($scope.mapObj.communeBorders);
1739
1740                if ($scope.viewConfig.isValid === true) {
1741
1742                    var center = L.latLng($scope.viewConfig.mapView[
17420], $scope.viewConfig.mapView[1]);
1743                    var zoom = $scope.viewConfig.mapView[2];
1744
1745                    $scope.mapObj.mapVariable.setView(center, zoom);
1746                }
1747                else {
1748                    $scope.mapObj.mapVariable.fitBounds($scope.mapObj.communeBorders);
1749                };
1750
1751                //set max bounds of map view
1752                $scope.mapObj.mapVariable.setMaxBounds($scope.mapObj.maxBounds);
1753
1754                var control = new L.Control.Zoom({ position: 'topright' }).addTo($scope.mapObj.mapVariable);
1755
1756                // wolow, uscie gorlickie
1757                if ([2489, 428].indexOf(profilid) != -1) {
1758                  L.control.route({
1759                    icon: {
1760                      control: '../lib/leaflet_route/leaflet-route-control.png',
1761                      controlAlt: '../lib/leaflet_route/leaflet-route-control-alt.png',
1762                      start: '../lib/leaflet_route/leaflet-route-start.png',
1763                      end: '../lib/leaflet_route/leaflet-route-end.png'
1764                    },
1765                    ajax: {
1766                      type: 'POST',
1767                      // type: 'GET',
1768                      url: proxyHost + serverRoot + 'Szlak/GetPublicPath',
1769                      // url: 'http://192.168.2.115/turysta-v7/' + 'Szlak/GetPublicPath',
1770                      data: {
1771                        profilid: profilid,
1772                        startY: '%startY%',
1773                        startX: '%startX%',
1774                        endY: '%endY%',
1775                        endX: '%endX%',
1776                      }
1777                    }
1778                  }).addTo($scope.mapObj.mapVariable);
1779
1780                  // var routeCalcHtml = '<div class="route-alert--calc">' +
1781                  //   '<i class="fa fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>' +
1782                  //   '<span>Obliczanie najkrótszej trasy...</span>' +
1783                  // '</div>';
1784
1785                  var routeErrHtml = '<div class="route-alert--calc">' +
1786                    '<i class="fa fa-exclamation-circle fa-2x" aria-hidden="true"></i>' +
1787                    '<span>Błąd wyznaczania trasy. Punkty leżą zbyt daleko od dostępnych szlaków lub błąd przesyłania danych.</span>' +
1788                  '</div>';
1789
1790                  // $scope.mapObj.mapVariable.on('route:calcStart', function() {
1791                  //   bootbox.alert(routeCalcHtml);
1792                  //   $('.modal-footer, .bootbox-close-button').remove();
1793                  // });
1794
1795                  // $scope.mapObj.mapVariable.on('route:calcFinish', function() {
1796                  //   bootbox.hideAll();
1797                  // });
1798
1799                  $scope.mapObj.mapVariable.on('route:calcError', function() {
1800                    // bootbox.hideAll();
1801                    bootbox.alert(routeErrHtml);
1802                  });
1803                }
1804
1805            };
1806
1807            // event for keeping permalink up to date
1808            $scope.mapObj.initListener = function () {
1809
1810                $scope.mapObj.mapVariable.on('moveend', function (e) {
1811
1812                    var mapSettings = $scope.getMapSettings();
1813
1814                    permalinkUpdater.updateMapLink(mapSettings);
1815                });
1816            };
1817
1818            $scope.getMapSettings = function () {
1819
1820                var center = $scope.mapObj.mapVariable.getCenter();
1821                var zoom = $scope.mapObj.mapVariable.getZoom();
1822
1823                var mapSettings = [Number((center.lat).toFixed(6)), Number((center.lng).toFixed(6)), zoom, $scope.mapObj.activeBgIndex];
1824
1825                return mapSettings;
1826            };
1827
1828            //init leaflet map
1829            $q.when($scope.profileDefer.promise).then(function () {
1830
1831                // watch for passed commune borders
1832                var watcher = $scope.$watch('borders', function () {
1833
1834                    if ($scope.borders === undefined) {
1835                        return;
1836                    }
1837                    else {
1838                        $scope.mapObj.mapInit();
1839                        watcher();
1840                    };
1841                });
1842
1843                // permalink-map integration
1844                if ($scope.viewConfig.isValid === false) {
1845
1846                    var mapSettings = $scope.getMapSettings();
1847
1848                    // broadcast profile rendered map event for permalink init
1849                    $scope.$emit('profile-map-rendered', mapSettings);
1850
1851                }
1852                else {
1853                    // fire when permalink already exist
1854                    $scope.mapObj.initListener();
1855                };
1856
1857                // compile map tap
1858                $element.append($compile('<div map-tap map-obj="mapObj"></div>')($scope));
1859            });
1860
1861        }
1862    };
1863}]);
1864
1865app.directive('mapBackgroundControls', ['$q', 'permalinkUpdater', function ($q, permalinkUpdater) {
1866    return {
1867        restrict: 'A',
1868        replace: true,
1869        templateUrl: '../../wyszukiwanie/templates/map_background_controls.html',
1870        scope: {
1871            mapObj: '=',
1872            profileDefer: '=',
1873            viewConfig: '='
1874        },
1875        link: function ($scope, $element, $attrs) {
1876
1877            $scope.mapObj.bg = {}
1878
1879            //define background tiles
1880            $scope.mapObj.bg.grayosm = L.tileLayer('https://server7.gison.pl/gis/wmts/osm_pastele/webmercator/{z}/{x}/{y}.png', {
1881                attribution: 'Data &copy; by <a href="http://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>.',
1882                minZoom: 5,
1883                maxZoom: 18,
1884                zIndex: 0
1885            });
1886
1887            $scope.mapObj.bg.worldosm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
1888            	maxZoom: 19,
1889            	attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'
1890            });
1891
1892            $scope.mapObj.bg.baseosm = L.tileLayer('https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', {
1893            	maxZoom: 19,
1894            	attribution: ''
1895            });
1896
1897
1898            $scope.mapObj.bg.ump = L.tileLayer('http://{s}.tiles.ump.waw.pl/ump_tiles/{z}/{x}/{y}.png', {
1899                subdomains: ['1','2','3','4'],
1900                attribution: 'Data by <a href="http://ump.waw.pl/" target="_blank">UMP-pcPL</a> + <a href="http://www2.jpl.nasa.gov/srtm/" target="_blank">SRTM</a>',
1901                minZoom: 5,
1902                maxZoom: 18,
1903                zIndex: 0
1904            });
1905
1906            // $scope.mapObj.bg.opencyclemap = L.tileLayer('http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', {
1907            //     subdomains: ['a','b','c'],
1908            //     attribution: '<b>OpenCycleMap.org - the <a href="http://www.openstreetmap.org">OpenStreetMap</a> Cycle Map</b>',
1909            //     minZoom: 5,
1910            //     maxZoom: 18,
1911            //     zIndex: 0
1912            // });
1913
1914            $scope.mapObj.bg.czechorto = L.tileLayer.wms('http://geop
1914ortal.cuzk.cz/WMS_ORTOFOTO_PUB/WMService.aspx?', {
1915                layers: 'GR_ORTFOTORGB',
1916                format: 'image/png',
1917                transparent: true,
1918            });
1919
1920            $scope.mapObj.bg.polorto = L.tileLayer('https://server8.gison.pl/gis/wmts/geop/webmercator/{z}/{x}/{y}.jpeg', {
1921              minZoom: 5,
1922              maxZoom: 18,
1923              zIndex: 0,
1924              format: 'image/png',
1925              transparent: true,
1926            });
1927
1928
1929
1930            // init leaflet map
1931            $q.when($scope.profileDefer.promise, function () {
1932
1933              if ([2041, 2489].indexOf(profilid) != -1) {
1934
1935                var searchPlaceholderName = (profilid == 2489) ? 'wyszukajMiejscowosc' : 'wyszukajAdres';
1936
1937                var data = {
1938                  format: 'json',
1939                  q: '{s}',
1940                  viewbox: [profileProperties.minx, profileProperties.miny, profileProperties.maxx, profileProperties.maxy].join(','),
1941                  bounded: 1,
1942                  country: 'pl'
1943                };
1944
1945                var dataArr = [];
1946                $.each(data, function(key, value) { dataArr.push(key + '=' + value); });
1947                var dataStr = dataArr.join('&');
1948
1949                $scope.mapObj.mapVariable.addControl( new L.Control.Search({
1950                  // url: 'http://nominatim.openstreetmap.org/search?format=json&q={s}&viewbox='+ profileProperties.miny+','+profileProperties.minx+','+profileProperties.maxy+','+profileProperties.maxx+'&bounded=1',
1951                  url: 'http://nominatim.openstreetmap.org/search?' + dataStr,
1952                  // jsonpParam: 'json_callback',
1953                  propertyName: 'display_name',
1954                  propertyLoc: ['lat','lon'],
1955                  autoType: false,
1956                  collapsed: false,
1957                  textPlaceholder: strona_translate[currentLang][searchPlaceholderName],
1958                  minLength: 2,
1959                  zoom: 16, //13
1960                  position: 'topright',
1961                }) );
1962
1963                $('.search-input').attr('data-translate', searchPlaceholderName);
1964              }
1965
1966              var osmName = (profilid != 2041) ? 'grayosm' : 'worldosm';
1967              var ortoName = (profilid != 2041) ? 'polorto' : ['polorto', 'czechorto'];
1968
1969              //list of background layers
1970              $scope.bgLayers = [
1971                  {
1972                      name: osmName, label: strona_translate[currentLang]['Mapa poglądowa'],
1973                  },
1974                  // {
1975                  //     name: 'opencyclemap', label: 'Mapa warstwicowa'
1976                  // },
1977                  {
1978                      name: ortoName, label: strona_translate[currentLang]['Ortofoto'],
1979                  },
1980                  {
1981                      name: 'ump', label: strona_translate[currentLang]['Model cieniowany'],
1982                  },
1983                  {
1984                    name: 'baseosm', label: strona_translate[currentLang]['Podkład OSM'],
1985                }
1986              ];
1987
1988                // set active bg index depends on given permalink
1989                if ($scope.viewConfig.isValid === true) {
1990                    $scope.mapObj.activeBgIndex = $scope.viewConfig.mapView[3];
1991                }
1992                else {
1993                    $scope.mapObj.activeBgIndex = 0;
1994                };
1995
1996                // set initial bg layer
1997                var initialLayerName = strToArr($scope.bgLayers[$scope.mapObj.activeBgIndex].name);
1998
1999                for (var i = 0; i < initialLayerName.length; i++) {
2000                  $scope.mapObj.mapVariable.addLayer($scope.mapObj.bg[initialLayerName[i]]);
2001                }
2002
2003            });
2004
2005            // change map background fn
2006            $scope.changeBackground = function (index) {
2007                if (index != $scope.mapObj.activeBgIndex) {
2008
2009                    var oldActiveIndex = angular.copy($scope.mapObj.activeBgIndex); //get old bg index
2010
2011                    $scope.mapObj.activeBgIndex = index; //set new one
2012
2013                    //remove old bg layer
2014                    var oldLayer = strToArr($scope.bgLayers[oldActiveIndex].name);
2015                    for (var i = 0; i < oldLayer.length; i++) {
2016                      $scope.mapObj.mapVariable.removeLayer($scope.mapObj.bg[oldLayer[i]]);
2017                    }
2018
2019                    //add new layer
2020                    var newLayerName = strToArr($scope.bgLayers[$scope.mapObj.activeBgIndex].name);
2021                    for (var i = 0; i < newLayerName.length; i++) {
2022                      $scope.mapObj.mapVariable.addLayer($scope.mapObj.bg[newLayerName[i]]);
2023                    }
2024
2025                    // change map part of permalink
2026                    $scope.updatePermalink($scope.mapObj.activeBgIndex)
2027                };
2028            };
2029
2030            $scope.updatePermalink = function (bgIndex) {
2031
2032                var center = $scope.mapObj.mapVariable.getCenter();
2033                var zoom = $scope.mapObj.mapVariable.getZoom();
2034
2035                var mapSettings = [Number((center.lat).toFixed(6)), Number((center.lng).toFixed(6)), zoom, bgIndex];
2036
2037                permalinkUpdater.updateMapLink(mapSettings);
2038            };
2039
2040            function strToArr(str) {
2041              return (!$.isArray(str)) ? [str]: str;
2042            }
2043        }
2044    };
2045}]);
2046
2047app.directive('backgroundControl', [function () {
2048    return {
2049        restrict: 'A',
2050        replace: true,
2051        template: '<li ng-class="{active: ($parent.$index == activeBgIndex)}
2051" ng-click="changeBackground($index)" data-translate="{{:: backgroundControl.label }}">{{:: backgroundControl.label }}</li>',
2052        scope: {
2053            activeBgIndex: '=',
2054            backgroundControl: '=',
2055            changeBackground: '&'
2056        }
2057    };
2058}]);
2059
2060
2061// tap animation
2062app.directive('mapTap', ['$timeout', '$q', function ($timeout, $q) {
2063    return {
2064        restrict: 'A',
2065        replace: true,
2066        template: '<div class="map-tap not-initialized" ng-show="animationFlag" ng-style="{left: cursorPosition.x, top: cursorPosition.y}"></div>',
2067        scope: {
2068            mapObj: '='
2069        },
2070        link: function ($scope, $element, $attrs) {
2071
2072            $scope.animationFlag = false;
2073
2074            $scope.cursorPosition = {
2075                x: 0,
2076                y: 0
2077            };
2078
2079            //click on map listener
2080            $scope.mapObj.mapVariable.on('click', function (e) {
2081
2082                var zoom = $scope.mapObj.mapVariable.getZoom();
2083
2084                if (zoom > 13) {
2085                    if ($scope.animationFlag === false) {
2086
2087                        $scope.animationFlag = true;
2088
2089                        if ( window.outerWidth < 768 ) {
2090                            $scope.cursorPosition.x = e.originalEvent.pageX - 15;
2091                            $scope.cursorPosition.y = e.originalEvent.pageY - 175;
2092                        }
2093                        else {
2094                            $scope.cursorPosition.x = e.originalEvent.pageX - 15;
2095                            $scope.cursorPosition.y = e.originalEvent.pageY - 65;
2096                        };
2097
2098                        $timeout(function () {
2099                            $scope.animationFlag = false;
2100                        }, 200);
2101
2102                    };
2103                };
2104
2105            });
2106        }
2107    }
2108}]);
2109;app.directive('navbar', [function () {
2110    return {
2111        restrict: 'A',
2112        templateUrl: '/wyszukiwanie/templates/navbar.html', 
2113        replace: true
2114    };
2115}]);;app.directive('sidebar', ['Filters', function (Filters) {
2116  return {
2117    restrict: 'A',
2118    template: '<div class="sidebar">' +
2119      '<div search-mode-switcher search-mode="viewConfig.searchMode"></div>' +
2120      '<div sidebar-search></div>' +
2121      '<div sidebar-filters></div>' +
2122      '<div sidebar-list></div>' +
2123      '<div sidebar-integrate></div>' +
2124    '</div>',
2125    replace: true,
2126    scope: {
2127      mapObj: '=',
2128      viewConfig: '=',
2129      profileDefer: '='
2130    },
2131    controller: 'sidebarController'
2132  };
2133}]);
2134
2135//search mode switcher
2136app.directive('searchModeSwitcher', ['permalinkUpdater', function (permalinkUpdater) {
2137  return {
2138    restrict: 'A',
2139    templateUrl: '/wyszukiwanie/templates/search_mode_switcher.html',
2140    replace: true,
2141    scope: {
2142      searchMode: '='
2143    }
2144  };
2145}]);
2146
2147//search mode switcher
2148app.directive('switchPointer', [function () {
2149  return {
2150    restrict: 'A',
2151    templateUrl: '/wyszukiwanie/templates/switch_pointer.html',
2152    replace: true,
2153    scope: {
2154      searchMode: '='
2155    },
2156    link: function ($scope, $element, $attrs) {
2157
2158      $scope.fadeIn = false;
2159
2160      var watcher = $scope.$watch('searchMode', function (newValue, oldValue) {
2161        if (newValue !== oldValue) {
2162          // recall watcher -> remove it
2163          $scope.stopWatching();
2164
2165          // run init animation
2166          $scope.initAnimation();
2167        };
2168      });
2169
2170      $scope.stopWatching = function () {
2171        watcher();
2172      };
2173
2174      $scope.initAnimation = function () {
2175
2176        $scope.fadeIn = true;
2177
2178      };
2179    }
2180  };
2181}]);
2182
2183//search field bar
2184app.directive('sidebarSearch', [function () {
2185  return {
2186    restrict: 'A',
2187    templateUrl: '/wyszukiwanie/templates/sidebar_search.html',
2188    replace: true,
2189    scope: true,
2190    require: 'sidebar'
2191  };
2192}]);
2193
2194
2195app.directive('sidebarIntegrate', [function () {
2196  return {
2197    restrict: 'A',
2198    templateUrl: '/wyszukiwanie/templates/sidebar_integrate.html',
2199    replace: true,
2200    scope: true,
2201  };
2202}]);
2203
2204//filters bars
2205app.directive('sidebarFilters', ['$q', '$compile', function ($q, $compile) {
2206  return {
2207    restrict: 'A',
2208    templateUrl: '/wyszukiwanie/templates/sidebar_filters.html',
2209    replace: true,
2210    scope: true,
2211    link: function ($scope, $element, $attrs) {
2212      var filtersContainer = angular.element($element[0].querySelector('.filters-tiles'));
2213
2214      // when profile is loaded (filters data is ready), compile filters
2215      $q.when($scope.profileDefer.promise).then(function profileLoadedCallback() {
2216        // compile filters
2217        filtersContainer.append($compile('<div single-filter ng-repeat="filter in filters.showplaces"></div>')($scope));
2218        filtersContainer.append($compile('<div single-filter ng-repeat="filter in filters.tracks"></div>')($scope));
2219        filtersContainer.append($compile('<div single-filter ng-repeat="filter in filters.events"></div>')($scope));
2220        filtersContainer.append($compile('<div single-filter ng-repeat="filter in filters.sleep"></div>')($scope));
2221        filtersContainer.append($compile('<div sleep-detail-filters search-mode="viewConfig.searchMode" detail-filters="filters.sleepDetails" send-request="sendRequest()" refresh-pagination="refreshPagination()" selected-filters-ids="filters.selectedSleepDetailFiltersIDs"></div>')($scope));
2222
2223      });
2224
2225    }
2226  };
2227}]);
2228
2229app.directive('sleepDetailFilters', ['$compile', function ($compile) {
2230  return {
2231    restrict: 'A',
2232    templateUrl: '/wyszukiwanie/templates/sleep_detail_filters.html',
2233    replace: true,
2234    scope: {
2235      detailFilters: '=',
2236      selectedFiltersIds: '=',
2237      searchMode: '=',
2238      sendRequest: '&',
2239      refreshPagination: '&',
2240      filters: '=',
2241    },
2242    compile: function ($scope, $elem, $attrs) {
2243      $scope.filters = {};
2244      $scope.filters.translates = {
2245        filtryZaawansowane: strona_translate.pl.filtryZaawansowane,
2246        anuluj: strona_translate.pl.anuluj,
2247        zapisz: strona_translate.pl.zapisz,
2248      }
2249
2250      return {
2251
2252        pre: function beforeLink($scope) {
2253
2254          $scope.groups = {
2255            basics: {
2256              label: 'Podstawowe',
2257              filters: []
2258            },
2259            recreation: {
2260              label: 'Rekreacja',
2261              filters: []
2262            },
2263            additionals: {
2264              label: 'Dodatkowe zalety',
2265              filters: []
2266            },
2267            neighborhood: {
2268              label: 'Otoczenie',
2269              filters: []
2270            }
2271          };
2272
2273          $scope.assignToGroup = function (filter) {
2274
2275            switch (filter.subGroup) {
2276
2277              case 'informacje podstawowe':
2278                $scope.groups.basics.filters.push(filter);
2279                break;
2280
2281              case 'rekreacja':
2282                $scope.groups.recreation.filters.push(filter);
2283                break;
2284
2285              case 'dodatkowe zalety':
2286                $scope.groups.additionals.filters.push(filter);
2287                break;
2288
2289              default: // 'otoczenie'
2290                $scope.groups.neighborhood.filters.push(filter);
2291                break;
2292
2293            };
2294
2295          };
2296
2297
2298          // group elements
2299          angular.forEach($scope.detailFilters, function (filter, index) {
2300            $scope.assignToGroup(filter);
2301          });
2302
2303        }
2304      };
2305
2306    },
2307    controller: function ($scope) {
2308
2309      // save filters event handler
2310      $scope.save = function () {
2311
2312        // send event for groups and filters
2313        $scope.$broadcast('save-filters', {});
2314
2315        $scope.refreshPagination();
2316        $scope.sendRequest();
2317      };
2318
2319      // cancel filters event handler
2320      $scope.cancel = function () {
2321
2322        $scope.selectedFiltersIds.length = 0;
2323
2324        // send event for groups and filters
2325        $scope.$broadcast('cancel-filters', {});
2326
2327        $scope.refreshPagination();
2328        $scope.sendRequest();
2329
2330      };
2331
2332    }
2333  };
2334}]);
2335
2336app.directive('detailFiltersGroup', [function () {
2337  return {
2338    restrict: 'A',
2339    templateUrl: '/wyszukiwanie/templates/detail_filters_group.html',
2340    replace: true,
2341    scope: {
2342      detailFiltersGroup: '=',
2343      selectedFiltersIds: '='
2344    },
2345    link: function ($scope, $elem, $attrs) {
2346
2347      $scope.collapsed = true;
2348
2349      // representing number of selected filters in group
2350      $scope.addedFilters = [];
2351
2352      $scope.changeFilterState = function (filterId) {
2353
2354        var id = filterId.toString();
2355
2356        if ($scope.selectedFiltersIds.indexOf(id) != -1) {
2357          $scope.removeFilter(id);
2358        } else {
2359          $scope.addFilter(id);
2360        };
2361
2362      };
2363
2364      $scope.addFilter = function (id) {
2365        // add to sidebar scope
2366        $scope.selectedFiltersIds.push(id);
2367
2368        // add to group scope
2369        $scope.addedFilters.push(id);
2370      };
2371
2372      $scope.removeFilter = function (id) {
2373
2374        // remove from sidebar scope
2375        var index = $scope.selectedFiltersIds.indexOf(id);
2376        $scope.selectedFiltersIds.splice(index, 1);
2377
2378        // remove from group scope
2379        var index = $scope.addedFilters.indexOf(id);
2380        $scope.addedFilters.splice(index, 1);
2381      };
2382
2383      $scope.changeVisibility = function () {
2384
2385        if ($scope.collapsed === false) {
2386          $scope.collapsed = true;
2387        } else {
2388          $scope.collapsed = false;
2389        }
2390
2391      };
2392
2393      $scope.hide = function () {
2394        $scope.collapsed = true;
2395      };
2396
2397      $scope.show = function () {
2398        $scope.collapsed = false;
2399      };
2400
2401      // EVENTS
2402      // cancel filters event listener
2403      $scope.$on('cancel-filters', function (event, data) {
2404
2405        $scope.addedFilters = [];
2406
2407        $scope.hide();
2408
2409      });
2410
2411      // cancel filters event listener
2412      $scope.$on('save-filters', function (event, data) {
2413
2414        $scope.hide();
2415
2416      });
2417    }
2418  }
2419}]);
2420
2421app.directive('detailFilter', [function () {
2422  return {
2423    restrict: 'A',
2424    templateUrl: '/wyszukiwanie/templates/detail_filter.html',
2425    replace: true,
2426    scope: {
2427      detailFilter: '=',
2428      changeFilterState: '&'
2429    },
2430    link: function ($scope, $elem, $attrs) {
2431
2432      $scope.checked = false;
2433
2434      // cancel filters event handler
2435      $scope.$on('cancel-filters', function (event, data) {
2436
2437        if ($scope.checked === true) {
2438
2439          $scope.checked = false;
2440        };
2441
2442      });
2443
2444    }
2445  }
2446}]);
2447
2448app.directive('singleFilter', [function () {
2449  return {
2450    restrict: 'A',
2451    templateUrl: '/wyszukiwanie/templates/single_filter.html',
2452    replace: true,
2453    scope: true,
2454    link: function ($scope, $element, $attrs) {
2455      $scope.id = $attrs.id;
2456      $scope.group = $attrs.group;
2457
2458      //set filter initial true/false selected value
2459
2460      if ($scope.viewConfig.initialFilters.indexOf($scope.id) === -1) {
2461        $scope.selected = false;
2462      } else {
2463        if ($attrs.group === $scope.viewConfig.searchMode) {
2464          $scope.selected = true;
2465        } else {
2466          $scope.selected = false;
2467        };
2468      };
2469
2470      //select filter event
2471      $scope.selectFilter = function (id) {
2472
2473        if ($scope.requestFlag === true) {
2474          if ($scope.selected === false) {
2475            $scope.selected = true;
2476            $scope.addFilter(id);
2477          } else {
2478            $scope.selected = false;
2479            $scope.removeFilter(id);
2480          };
2481        };
2482
2483      };
2484
2485      //trigger when remove all filters
2486      $scope.$on('remove-all-filters', function (e) {
2487
2488        if ($attrs.group === $scope.viewConfig.searchMode) {
2489
2490          if ($scope.selected === true) {
2491            $scope.selected = false;
2492          };
2493
2494        };
2495
2496      });
2497    }
2498  };
2499}]);
2500
2501//list bars
2502app.directive('sidebarList', [function () {
2503  return {
2504    restrict: 'A',
2505    templateUrl: '/wyszukiwanie/templates/sidebar_list.html',
2506    replace: true,
2507    scope: true
2508  };
2509}]);
2510
2511//turistic object
2512app.directive('turisticObject', [function () {
2513  return {
2514    restrict: 'A',
2515    templateUrl: '/wyszukiwanie/templates/turistic_object.html',
2516    replace: true,
2517    scope: true
2518  };
2519}]);
2520
2521app.directive('listPagination', ['$timeout', function ($timeout) {
2522  return {
2523    restrict: 'A',
2524    templateUrl: '/wyszukiwanie/templates/list_pagination.html',
2525    replace: true,
2526    scope: true,
2527    link: function ($scope, $element, $attr) {
2528
2529      $scope.pages = [];
2530
2531      //return number of pages for pagination
2532      $scope.countPages = function (number) {
2533        if (number > 10) {
2534
2535          var entirePages = parseInt(number / 10);
2536          var additionalPage = number % 10;
2537
2538          if (additionalPage > 0) {
2539            return entirePages += 1;
2540          } else {
2541            return entirePages;
2542          }
2543        };
2544      };
2545
2546      //listener for creating pagination
2547      $scope.$on('create-pagination', function () {
2548
2549        $scope.pages = new Array($scope.countPages($scope.list.allCount));
2550
2551        $scope.$broadcast('update-pagination-visiblity', {
2552          active: $scope.list.activePage,
2553          pages: $scope.pages.length
2554        });
2555
2556      });
2557
2558      //change 'from' and 'to' parameters in filter which depends on pagination selection
2559      $scope.changePage = function (pageNumber) {
2560        $scope.mapObj.hideMarkers();
2561        if (pageNumber != $scope.list.activePage) {
2562          //change filter page
2563          $scope.searchFilter.from = (pageNumber - 1) * 10;
2564          $scope.searchFilter.to = 10;
2565          //clear list
2566          $scope.list.turisticObjects = [];
2567          //turn on animation
2568          $scope.list.loadingAnim = true;
2569          $scope.sendRequest();
2570          //set new active page
2571          $scope.setActivePage(pageNumber);
2572        };
2573      };
2574
2575      //set active page
2576      $scope.setActivePage = function (pageNumber) {
2577        $scope.list.activePage = pageNumber;
2578      };
2579    }
2580  }
2581}]);
2582
2583app.directive('listElement', ['$compile', function ($compile) {
2584  return {
2585    restrict: 'A',
2586    scope: false,
2587    link: function ($scope, $element, $attrs) {
2588
2589      $scope.number = parseInt($attrs.listElementIndex) + 1;
2590      $scope.activeNumber = parseInt($attrs.listActivePage) // from active page to active index
2591      $scope.pagesNumber = parseInt($attrs.pagesNumber);
2592
2593      $scope.visible = false;
2594      $scope.dots = false;
2595
2596      $scope.checkVisibility = function () {
2597
2598        $scope.visible = false;
2599        $scope.dots = false;
2600
2601        if ($scope.$first || $scope.number == $scope.pagesNumber) {
2602          $scope.visible = true;
2603        } else {
2604
2605          if ($scope.activeNumber <= 3) {
2606
2607            if ($scope.number <= 6) {
2608              $scope.visible = true;
2609
2610              if ($scope.number == 6) {
2611                $scope.dots = true;
2612              };
2613
2614            } else {
2615
2616              $scope.visible = false;
2617
2618            };
2619          } else if ($scope.activeNumber >= 4 && $scope.activeNumber <= $scope.pagesNumber - 5) {
2620
2621            var minVisible = $scope.activeNumber - 3;
2622            var maxVisible = $scope.activeNumber + 3;
2623
2624            if ($scope.number >= minVisible && $scope.number <= maxVisible) {
2625
2626              $scope.visible = true;
2627
2628              if ($scope.number == minVisible || $scope.number == maxVisible) {
2629                $scope.dots = true;
2630              };
2631
2632            };
2633
2634
2635          } else {
2636
2637            if ($scope.number > $scope.pagesNumber - 7) {
2638
2639              $scope.visible = true;
2640
2641              if ($scope.number == $scope.pagesNumber - 6) {
2642                $scope.dots = true;
2643              };
2644            } else {
2645              $scope.visible = false;
2646            };
2647          };
2648
2649        };
2650
2651      };
2652
2653      $scope.setInnerHtmlToElement = function () {
2654
2655        $element.children().remove();
2656
2657        if ($scope.visible == false) {
2658          $element.css('display', 'none');
2659        } else {
2660          $element.css('display', 'inherit');
2661        };
2662
2663        if ($scope.dots == true) {
2664          $element.html('<span>...</span>');
2665        } else {
2666          var el = $compile('<a ng-href="" ng-click="changePage(number)"> {{ number }} </a>')($scope);
2667          $element.append(el);
2668        };
2669      };
2670
2671      $scope.setVisiblity = function () {
2672
2673        // if more than 9 pages -> prevent displaying all pages
2674        if ($scope.pagesNumber >= 9) {
2675
2676          $scope.checkVisibility();
2677
2678          $scope.setInnerHtmlToElement();
2679
2680        } else {
2681          $scope.visible = true;
2682          $scope.dots = false;
2683
2684          $scope.setInnerHtmlToElement();
2685        };
2686      };
2687
2688      $scope.setVisiblity();
2689
2690      // change active page
2691      $scope.$on('update-pagination-visiblity', function (event, obj) {
2692
2693        // set active page number
2694        $scope.activeNumber = parseInt(obj.active);
2695        $scope.pagesNumber = parseInt(obj.pages);
2696
2697        $scope.setVisiblity();
2698
2699      });
2700    }
2701  }
2702}]);
2703
2704app.directive('activatedTuristicObject', ['$compile', 'permalinkUpdater', function ($compile, permalinkUpdater) {
2705  return {
2706    restrict: 'A',
2707    template: '<div class="activated-turistic-object"></div>',
2708    replace: true,
2709    scope: true,
2710    link: function ($scope, $element, $attrs) {
2711
2712      $scope.activatedDetails = {};
2713
2714      //listener for activate object
2715      $scope.$on('object-activated', function (event, args) {
2716        $scope.list.activatedId = args.id;
2717        $scope.activatedDetails = args.activatedObject;
2718        $scope.fromList = args.fromList;
2719        $element.append($compile('<div id="list.activatedId" activated-object="activatedDetails" from-list="fromList"></div>')($scope));
2720
2721        // update permalink
2722        permalinkUpdater.updateFeatureLink({
2723          id: args.id,
2724          type: args.activatedObject.turisticType
2725        });
2726
2727        //display only one marker on the map
2728        $scope.mapObj.hideMarkers();
2729
2730        if ($scope.markersArray.find(function (o) {
2731          return o.id == args.activatedObject.id
2732        }) == undefined) {
2733          $scope.markersArray.push(args.activatedObject);
2734        } else {
2735          var find = $scope.markersArray.find(function (o) {
2736            return o.id == args.activatedObject.id
2737          });
2738          var index = $.inArray(find, $scope.markersArray);
2739          $scope.markersArray[index] = args.activatedObject;
2740        }
2741        $scope.mapObj.showMarker(args.activatedObject);
2742      });
2743    }
2744  };
2745}]);
2746
2747app.directive('activatedObject', ['$timeout', 'permalinkUpdater', function ($timeout, permalinkUpdater) {
2748  return {
2749    restrict: 'A',
2750    templateUrl: '/wyszukiwanie/templates/activated_object.html',
2751    replace: true,
2752    scope: {
2753      id: '=',
2754      activatedObject: '=',
2755      fromList: '='
2756    },
2757    link: function ($scope, $element, $attrs, scope) {
2758
2759      // function show less attractions
2760      var showMoreAttractions = function () {
2761        var attractionsContainer = $(".poilist");
2762        var attractionsList = attractionsContainer.find(".poilists");
2763        var attractions = attractionsContainer.find("p").not(".section-desc");
2764        var poilistsShortClass = "poilists-short";
2765        var minAttractionsNum = 8;
2766        var showMoreText = "<span data-translate='rozwinWiecej'>Rozwiń więcej </span><i class='fa fa-caret-down' aria-hidden='true'></i>";
2767        var showLessText = "<span data-translate='zwin'>Zwiń </span><i class='fa fa-caret-up' aria-hidden='true'></i>";
2768
2769        if (attractions.length > minAttractionsNum) {
2770          attractionsList.addClass(poilistsShortClass);
2771          attractionsContainer.append("<div class='showMore'><div></div><span class='showMore__label'>" + showMoreText + "</span></div>");
2772
2773          var showMore = $(".showMore__label");
2774
2775          showMore.click(function () {
2776            if (attractionsList.hasClass(poilistsShortClass)) {
2777              showMore.html(showLessText);
2778              attractionsList.removeClass(poilistsShortClass);
2779            } else {
2780              showMore.html(showMoreText);
2781              attractionsList.addClass(poilistsShortClass);
2782            }
2783            // $scope.mapObj.addTuristicObjectsToMap();
2784          });
2785        }
2786
2787      };
2788
2789      // call function after DOM rendered
2790      $timeout(function () {
2791        showMoreAttractions();
2792      });
2793
2794      //click on remove button callback
2795      $scope.remove = function (changeListState) {
2796        $element.remove();
2797        $scope.$emit('remove-activated', {
2798          changeListState: changeListState,
2799          fromList: $scope.fromList,
2800          showMarkers: true
2801        });
2802
2803        //update permalink
2804        permalinkUpdater.updateFeatureLink({
2805          id: '',
2806          type: ''
2807        });
2808        $scope.$destroy();
2809      };
2810
2811      //click on remove button callback
2812      $scope.removeCallback = function (changeListState) {
2813
2814        $element.remove();
2815        $scope.$emit('remove-activated', {
2816          changeListState: changeListState,
2817          fromList: $scope.fromList
2818        });
2819
2820        $scope.$destroy();
2821      };
2822
2823      //reaction on 'remove-activeted' event broadcasted by sidebar controller
2824      $scope.$on('list-remove-activated', function (event, args) {
2825        if ($scope.id === args.activeId) {
2826
2827          //update permalink
2828          permalinkUpdater.updateFeatureLink({
2829            id: '',
2830            type: ''
2831          });
2832
2833          $timeout(function () { //timeout for handling digest cycle
2834            $scope.removeCallback(args.changeListState);
2835          });
2836        };
2837
2838      });
2839
2840      $scope.activateObjectpoilist = function (settings) {
2841        var poilink = permalinkUpdater.poilistFeatureLink({
2842          id: settings.id,
2843          type: settings.obiekt,
2844          lng: settings.lng,
2845          lat: settings.lat
2846        });
2847        window.open(poilink);
2848
2849      };
2850
2851      $scope.downloadGPX = function (settings) {
2852        $scope.$parent.$parent.$parent.downloadGPX(settings);
2853      };
2854
2855    }
2856  };
2857}]);
2858
2859app.directive('singleDetail', [function () {
2860  return {
2861    restrict: 'A',
2862    templateUrl: '/wyszukiwanie/templates/single_detail.html',
2863    replace: true,
2864    scope: {
2865      singleDetail: '='
2866    }
2867  };
2868}]);
2869
2870app.directive('toHtml', [function () {
2871  return {
2872    restrict: 'A',
2873    link: function ($scope, $element, $attrs) {
2874      $element.html($attrs.toHtml);
2875    }
2876  }
2877}]);
2878;// Create an AngularJS service called debounce
2879app.factory('debounce', ['$timeout','$q', function($timeout, $q) {
2880  // The service is actually this function, which we call with the func
2881  // that should be debounced and how long to wait in between calls
2882  return function debounce(func, wait, immediate) {
2883    var timeout;
2884    // Create a deferred object that will be resolved when we need to
2885    // actually call the func
2886    var deferred = $q.defer();
2887    return function() {
2888      var context = this, args = arguments;
2889      var later = function() {
2890        timeout = null;
2891        if(!immediate) {
2892          deferred.resolve(func.apply(context, args));
2893          deferred = $q.defer();
2894        }
2895      };
2896      var callNow = immediate && !timeout;
2897      if ( timeout ) {
2898        $timeout.cancel(timeout);
2899      }
2900      timeout = $timeout(later, wait);
2901      if (callNow) {
2902        deferred.resolve(func.apply(context,args));
2903        deferred = $q.defer();
2904      }
2905      return deferred.promise;
2906    };
2907  };
2908}]);
2909;app.factory('permalinkGenerator', [function () {
2910
2911    var generator = {
2912        initPermalink: initPermalink,
2913        createMapLink: createMapLink,
2914        createModeLink: createModeLink,
2915        createFiltersLink: createFiltersLink,
2916        createFeatureLink: createFeatureLink
2917    };
2918
2919    return generator;
2920
2921
2922    ///////////////
2923
2924    function initPermalink (permalinkObject) {
2925        var path = window.location.pathname;
2926
2927        if (path.indexOf('/@') === -1) {
2928
2929            var splitted = path.split('/');
2930            var permalink = '';
2931
2932            if (splitted.length === 3) {
2933                permalink = '/@';
2934            }
2935            else {
2936                //has already additional slash
2937                permalink = '@';
2938            };
2939
2940            permalink += createMapLink(permalinkObject.map) +
2941                        '/' + createModeLink(permalinkObject.sidebarMode) +
2942                        '/' + createFiltersLink(permalinkObject.filters) +
2943                        '/' + createFeatureLink(permalinkObject.featureObj);
2944
2945            return permalink;
2946        };
2947    };
2948
2949    function createMapLink (mapSettings) {
2950        return mapSettings.join(',');
2951    };
2952
2953    function createModeLink (modeString) {
2954        return modeString;
2955    };
2956
2957    function createFiltersLink (filters) {
2958        try {
2959            return 'fs=' + filters.join(',');
2960        }
2961        catch (e) {
2962            return 'fs=';
2963        };
2964    };
2965
2966    function createFeatureLink (featureObj) {
2967
2968        return 'f=' + featureObj.type + featureObj.id;
2969    }
2970}]);
2971;app.factory('permalinkUpdater', ['permalinkGenerator', function (permalinkGenerator) {
2972    
2973    var updater = {
2974        updateInitial: updateInitial,
2975        updateMapLink: updateMapLink,
2976        updateModeLink: updateModeLink,
2977        updateFiltersLink: updateFiltersLink,
2978        updateFeatureLink: updateFeatureLink,
2979		poilistFeatureLink: poilistFeatureLink
2980    };
2981    
2982    return updater;
2983    
2984    ////////////////
2985    
2986    function updateInitial (permalinkObject) {
2987        var initialPerma = permalinkGenerator.initPermalink(permalinkObject);
2988        var existingUrl = window.location.href;
2989        window.history.replaceState('', '', existingUrl + initialPerma);
2990    };
2991    
2992    function updateMapLink (mapSettings) {
2993        var parts = window.location.href.split('/@');
2994        
2995        var path = parts[0];
2996        var splitted = parts[1].split('/');
2997        
2998        var toReplace = permalinkGenerator.createMapLink(mapSettings);
2999        splitted[0] = toReplace;
3000        
3001        var newPermalink = path + '/@' + splitted.join('/');
3002        
3003        window.history.replaceState('', '', newPermalink);
3004    };
3005    
3006    function updateModeLink (modeString) {
3007        var parts = window.location.href.split('/@');
3008        
3009        var path = parts[0];
3010        var splitted = parts[1].split('/');
3011        
3012        var toReplace = permalinkGenerator.createModeLink(modeString);
3013        splitted[1] = toReplace;
3014        
3015        var newPermalink = path + '/@' + splitted.join('/');
3016        
3017        window.history.replaceState('', '', newPermalink);
3018    };
3019    
3020    function updateFiltersLink (filters) {
3021        var parts = window.location.href.split('/@');
3022        
3023        var path = parts[0];
3024        var splitted = parts[1].split('/');
3025        
3026        var toReplace = permalinkGenerator.createFiltersLink(filters);
3027        splitted[2] = toReplace;
3028        
3029        var newPermalink = path + '/@' + splitted.join('/');
3030        
3031        window.history.replaceState('', '', newPermalink);
3032    };
3033    
3034    function updateFeatureLink (featureObj) {
3035        var parts = window.location.href.split('/@');
3036        
3037        var path = parts[0];
3038        var splitted = parts[1].split('/');
3039        
3040        var toReplace = permalinkGenerator.createFeatureLink(featureObj);
3041        splitted[3] = toReplace;
3042        
3043        var newPermalink = path + '/@' + splitted.join('/');
3044        
3045        window.history.replaceState('', '', newPermalink);
3046    };
3047	
3048	    function poilistFeatureLink (featureObj) {
3049        var parts = window.location.href.split('/@');
3050        
3051        var path = parts[0];
3052        var splitted = parts[1].split('/');
3053        
3054		if (featureObj.type == 'a')
3055		{
3056			var featureType = 'noclegi';
3057		}
3058		else { var featureType = 'atrakcje';}
3059		
3060        var toReplace = permalinkGenerator.createFeatureLink(featureObj);
3061
3062		splitted[0] = featureObj.lat + "," + featureObj.lng + ",18,0";
3063		splitted[1] = featureType;
3064        splitted[3] = toReplace;
3065        
3066        var newPermalink = path + '/@' + splitted.join('/');
3067        
3068        return newPermalink;
3069    };
3070}]);;app.factory('permalinkValidator', ['path', function (path) {
3071
3072    'use strict';
3073
3074    var validator = {
3075
3076        // initial settings
3077        path: path,
3078        isPermalinkValid: true,
3079        permalinkObject: {
3080            map: [],
3081            filters: [],
3082            featureObj: {}
3083        },
3084
3085        // functions
3086        preValidation: preValidation,
3087        validateMapSettings: validateMapSettings,
3088        validateModeSettings: validateModeSettings,
3089        validateFiltersSettings: validateFiltersSettings,
3090        validateFeature: validateFeature,
3091        getSettings: getSettings,
3092        removeInvalidPermalink: removeInvalidPermalink,
3093        validateUrl: validateUrl
3094
3095    };
3096
3097    validateUrl(path);
3098
3099    return validator;
3100
3101    /////////////
3102
3103    function validateMapSettings (mapSettings) {
3104
3105        try {
3106
3107            var settings = mapSettings.split(',');
3108            var length = settings.length
3109
3110            // exacly 4 splitted parts in map settings
3111            if (length === 4) {
3112                for (var i = 0; i < length; i++) {
3113                    if ( !isFinite(parseInt(settings[i])) ) {
3114                        return false;
3115                    };
3116                };
3117
3118                return [
3119                    parseFloat(settings[0]),
3120                    parseFloat(settings[1]),
3121                    parseInt(settings[2]),
3122                    parseInt(settings[3]),
3123                ];
3124            }
3125            else {
3126                return false;
3127            };
3128        }
3129        catch (e) {
3130            return false;
3131        };
3132
3133    };
3134
3135    function validateFiltersSettings (filtersSettings) {
3136
3137        var filtersIDs = [];
3138
3139        try {
3140            var preSplitted = filtersSettings.split('=')[1];
3141
3142            if (preSplitted.length != 0) {
3143                var filters = preSplitted.split(',');
3144                var length = filters.length;
3145
3146                for (var i = 0; i < length; i++) {
3147
3148                    var id = filters[i].toString();
3149
3150                    filtersIDs.push(id);
3151
3152                };
3153
3154                return filtersIDs;
3155            }
3156            else {
3157                return filtersIDs; // permalink with empty filters part is valid
3158            };
3159        }
3160        catch (e) {
3161            return false;
3162        };
3163    };
3164
3165    function validateFeature (featureString) {
3166        try {
3167            var featureId = featureString.split('=')[1];
3168
3169            if (featureId.length != 0) {
3170                var type = featureId.slice(0, 1);
3171                var id = parseInt(featureId.slice(1, featureId.length));
3172
3173                if ( !isFinite(id) ) {
3174                    return false;
3175                }
3176                else {
3177                    return {
3178                        type: type,
3179                        id: id
3180                    };
3181                };
3182
3183            }
3184            else {
3185                return ''; // permalink with empty feature id is valid
3186            };
3187        }
3188        catch (e) {
3189            return false;
3190        };
3191    };
3192
3193    function validateModeSettings (modeString) {
3194        try {
3195            var length = modeString.length;
3196
3197            if (length != 0) {
3198                if (modeString === 'atrakcje' || modeString === 'szlaki' || modeString === 'wydarzenia' || modeString === 'noclegi') {
3199                    return modeString;
3200                }
3201                else {
3202                    return false;
3203                };
3204            }
3205            else {
3206                return false;
3207            };
3208        }
3209        catch (e) {
3210            return false
3211        };
3212    };
3213
3214    function preValidation (path) {
3215        try {
3216
3217            var splittedParts = path.split('@')[1].split('/');
3218
3219            if (splittedParts.length === 4) {
3220                return true;
3221            }
3222            else {
3223                return false;
3224            };
3225        }
3226        catch (e) {
3227            return false;
3228        };
3229    };
3230
3231    function getSettings (path) {
3232
3233        var splittedParts = path.split('@')[1].split('/');
3234
3235        var mapSettings = validateMapSettings(splittedParts[0]);
3236        var sidebarMode = validateModeSettings(splittedParts[1]);
3237        var filters = validateFiltersSettings(splittedParts[2]);
3238        var featureObj = validateFeature(splittedParts[3]);
3239
3240        return {
3241            map: mapSettings,
3242            sidebarMode: sidebarMode,
3243            filters: filters,
3244            featureObj: featureObj
3245        };
3246    };
3247
3248    function removeInvalidPermalink () {
3249        var url = window.location.href;
3250        window.history.replaceState('', '', url.split('/@')[0]);
3251    };
3252
3253    function validateUrl (path) {
3254
3255        var preValid = validator.preValidation(path);
3256
3257        if (preValid === true) {
3258            var settings = validator.getSettings(path);
3259
3260            angular.forEach(settings, function (value, key) {
3261
3262                if (settings.hasOwnProperty(key)) {
3263
3264                    if (typeof value === 'boolean') {
3265
3266                        validator.isPermalinkValid = false;
3267
3268                        return;
3269                    };
3270                };
3271            });
3272
3273            validator.permalinkObject = settings;
3274        }
3275        else {
3276            validator.isPermalinkValid = false;
3277        };
3278    };
3279}]);
3280;app.service('Profile', ['$http', 'proxyHost', 'serverRoot', function ($http, proxyHost, serverRoot) {
3281
3282    this.parameters = {
3283        params: {},
3284        profileKey: '',
3285        profileID: ''
3286    };
3287
3288    this.getParametersFromPermalink = function () {
3289        var path = window.location.pathname;
3290        this.parameters.profileKey = path.split('/')[2];
3291    };
3292
3293    this.getProfileFromServer = function () {
3294        var that = this;
3295        return $http({
3296            method: 'POST',
3297            url: proxyHost + serverRoot + 'profil/LoadProfil2/',
3298            data: {
3299                _nazwa: that.parameters.profileKey,
3300                root: serverRoot,
3301                visit: true,
3302                map: true,
3303            }
3304        }).then(function successCallback(response) {
3305            //when success
3306            var data = JSON.parse(response.data);
3307            L.geoJson(data, { onEachFeature: function (profile) { //sent by geojson
3308
3309                profilid = profile.properties.profilid;
3310                that.parameters.geojson = profile;
3311                that.parameters.profileID = profile.properties.profilid;
3312                that.parameters.name = profile.properties.opis;
3313				that.parameters.type = profile.properties.typprofilu;
3314                profileProperties = profile.properties;
3315                }
3316            });
3317
3318        }, function errorCallback(response) {
3319            alert('Błąd wczytywania profilu.');
3320        });
3321
3322    };
3323}]);
3324
3325app.service('Filters', ['$http', 'Profile', 'proxyHost', 'serverRoot', '$q', function ($http, Profile, proxyHost, serverRoot, $q) {
3326
3327    this.showplaces = [];
3328    this.tracks = [];
3329	this.events = [];
3330	this.sleep = [];
3331	this.sleepDetails = []
3332
3333    this.getShowplacesCategories = function () {
3334        var that = this;
3335        //getting showplaces categories from server
3336        return $http({
3337            method: 'GET',
3338            url: proxyHost + serverRoot + 'KategoriaObiektu/GetPublicList/?_profilid=' + Profile.parameters.profileID
3339        }).then(function successCallback(response) {
3340            var data = response.data;
3341            var length = data.length;
3342            for (var i = 0; i < length; i++) {
3343                if (data[i].search === true) {
3344                    that.showplaces.push({label: data[i].nazwa, group: 'atrakcje', id: data[i].id, icon_color: serverRoot + data[i].icon_color, icon_gray: serverRoot + data[i].icon_gray});
3345                };
3346            };
3347
3348        }, function errorCallback(response) {
3349            alert('Błąd połączenia z serwerem.');
3350        });
3351
3352    };
3353
3354    this.getTracksCategories = function () {
3355        var that = this;
3356
3357        // getting tracks categories from file
3358
3359        return $http({
3360            method: 'GET',
3361            url: '/wyszukiwanie/data/tracks_filters.json'
3362        }).then(function successCallback (response) {
3363
3364            var data = response.data.list;
3365            var length = data.length;
3366
3367            for (var i = 0; i < length; i++) {
3368                that.tracks.push({label: data[i].nazwa, group: 'szlaki', id: data[i].id, icon_color: data[i].icon_color, icon_gray: data[i].icon_gray})
3369            };
3370        }, function errorCallback (response) {
3371            console.log(response);
3372        });
3373    };
3374
3375	this.getEventsCategories = function () {
3376        var that = this;
3377
3378        // getting events categories from file
3379
3380        return $http({
3381            method: 'GET',
3382            url: '/wyszukiwanie/data/events_filters.json'
3383        }).then(function successCallback (response) {
3384
3385            var data = response.data.list;
3386            var length = data.length;
3387
3388            for (var i = 0; i < length; i++) {
3389                that.events.push({label: data[i].nazwa, group: 'wydarzenia', id: data[i].id, icon_color: data[i].icon_color, icon_gray: data[i].icon_gray})
3390            };
3391        }, function errorCallback (response) {
3392            console.log(response);
3393        });
3394    };
3395
3396	this.getSleepCategories = function () {
3397
3398		var that = this;
3399
3400		// getting sleep categories from server
3401
3402        return $http({
3403            method: 'GET',
3404            url: proxyHost + serverRoot + 'kategoriaobiektu/GetPublicListNoclegi?_profilid=' + Profile.parameters.profileID
3405        }).then(function successCallback (response) {
3406
3407            var data = response.data;
3408            var length = data.length;
3409
3410            for (var i = 0; i < length; i++) {
3411                that.sleep.push({label: data[i].nazwa, group: 'noclegi', id: data[i].id, icon_color: serverRoot + data[i].icon_color, icon_gray: serverRoot + data[i].icon_gray})
3412            };
3413
3414        }, function errorCallback (response) {
3415            console.log(response);
3416        });
3417	};
3418
3419	this.getSleepDetailCategories = function () {
3420		var that = this;
3421
3422        return $http({
3423            method: 'GET',
3424            url: proxyHost + serverRoot + 'common/GetPublicListNoclegSzczegoly?_profilid=' + Profile.parameters.profileID
3425        }).then(function successCallback (response) {
3426
3427            var data = response.data;
3428            var length = data.length;
3429
3430            for (var i = 0; i < length; i++) {
3431                that.sleepDetails.push({label: data[i].nazwa, group: 'noclegi', subGroup: data[i].grupa, id: data[i].id, icon_color: serverRoot + data[i].icon})
3432            };
3433        }, function errorCallback (response) {
3434            console.log(response);
3435        });
3436	};
3437
3438    this.getAllCategories = function () {
3439
3440        var defer = $q.defer();
3441
3442        var showplacesPromise = this.getShowplacesCategories();
3443        var tracksPromise = this.getTracksCategories();
3444		var eventsPromise = this.getEventsCategories();
3445        var sleepPromise = this.getSleepCategories();
3446		var sleepDetailsPromise = this.getSleepDetailCategories();
3447
3448        $q.all([showplacesPromise, tracksPromise, eventsPromise, sleepPromise, sleepDetailsPromise]).then(function successCallback () {
3449
3450            defer.resolve();
3451        });
3452
3453        return defer;
3454    };
3455}]);
3456
3457app.factory('turisticObjectByClick', ['$http', 'Profile', 'proxyHost', 'serverRoot', function ($http, Profile, proxyHost, serverRoot) {
3458    return {
3459        getObject: function (lat,lng) {
3460            return $http({
3461                method: 'POST',
3462                url: proxyHost + serverRoot + 'Feature/GetPublicObjectXY/',
3463                data: {
3464                    lat: lat,
3465                    lng: lng,
3466                    profil: Profile.parameters.profileID
3467                }
3468            });
3469        }
3470    };
3471}]);
3472
3473app.service('TuristicObjects', ['$http', 'Profile', 'proxyHost', 'serverRoot', '$httpParamSerializerJQLike', function ($http, Profile, proxyHost, serverRoot, $httpParamSerializerJQLike) {
3474
3475    this.objects = [];
3476    this.allCount = 0;
3477  var that = this;
3478
3479	this.numberToPolishMonth = function (number) {
3480		var polishMonths = ['Stycznia', 'Lutego', 'Marca', 'Kwietnia', 'Maja', 'Czerwca', 'Lipca', 'Sierpnia', 'Września', 'Października', 'Listopada', 'Grudnia'];
3481		var month = polishMonths[number];
3482		return month;
3483	};
3484
3485	// parse date to dd [mm] yyyy format
3486	this.parseDate = function (rawDate) {
3487		if (rawDate) {
3488			var miliseconds = Date.parse(rawDate);
3489
3490			var date = new Date(miliseconds);
3491
3492			var dateObj = {
3493				day: date.getDate(),
3494				month: this.numberToPolishMonth(date.getMonth()),
3495				year: date.getFullYear()
3496			};
3497
3498			return dateObj.day + ' ' + dateObj.month + ' ' + dateObj.year;
3499		}
3500		else {
3501			return null;
3502		};
3503	};
3504
3505    this.objectToTuristicObject = function (object, fromListBool) {
3506
3507        var obj = {
3508            id: object.properties.id,
3509            geometryType: 'point',
3510            turisticType: 's',
3511            geometry: {
3512                coords: [object.geometry.coordinates[1], object.geometry.coordinates[0]]
3513            },
3514            graphic: {
3515                icon: (function () {
3516                    if (object.properties.icon.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3517                        return serverRoot + object.properties.icon;
3518                    }
3519                    else {
3520                        return  object.properties.icon;
3521                    };
3522                })(),
3523                img: (function () {
3524                    if (object.properties.photolist.length > 0){
3525                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3526                            return serverRoot + object.properties.photolist[0].imgs;
3527                        }
3528                        else {
3529                            return object.properties.photolist[0].imgs;
3530                        };
3531                    };
3532                })(),
3533                bigImg: (function () {
3534                    if (object.properties.photolist.length > 0){
3535                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3536                            return serverRoot + object.properties.photolist[0].img;
3537                        }
3538                        else {
3539                            return object.properties.photolist[0].img;
3540                        };
3541                    };
3542                })(),
3543
3544                hasImg: false
3545            },
3546            desc: {
3547                // name: object.properties.label,
3548                name: this.twoLanguageText(object.properties.label, object.properties.Name_Cz),
3549                address: object.properties.address,
3550                category: object.properties.category,
3551                mail: object.properties.mail,
3552                phone: object.properties.phone,
3553                website: object.properties.www,
3554                photolist: (function () {
3555                    if (object.properties.photolist.length > 0){
3556                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3557                            for (var a = 0; a < object.properties.photolist.length; a++)
3558							{
3559								object.properties.photolist[a].img = serverRoot + object.properties.photolist[a].img;
3560								object.properties.photolist[a].imgs = serverRoot + object.properties.photolist[a].imgs;
3561							}
3562							return object.properties.photolist;
3563                        }
3564                        else {
3565                            return object.properties.photolist;
3566                        };
3567                    };
3568                })(),
3569                // fullDescription: object.properties.description,
3570                fullDescription: this.twoLanguageText(object.properties.description, object.properties.Opis_Cz),
3571                lat: object.properties.lat,
3572                lng: object.properties.lng,
3573
3574            },
3575            fromList: fromListBool
3576        };
3577
3578        //if graphic exist -> add flag
3579        if (obj.graphic.img) {
3580            obj.graphic.hasImg = true;
3581        };
3582
3583        return obj;
3584    };
3585
3586    this.twoLanguageText = function(text1, text2) {
3587      var text = '';
3588      var plTextAdded = (text1 && text1.length > 0);
3589      var csTextAdded = (text2 && text2.length > 0);
3590
3591      if (plTextAdded) {
3592        text += createTextWrapper(text1, 'pl');
3593        text += createTextWrapper(text1, 'en');
3594      }
3595
3596      if (csTextAdded) {
3597        text += createTextWrapper(text2, 'cs');
3598      }
3599
3600      if (plTextAdded && !csTextAdded) {
3601        text += createTextWrapper(text1, 'cs');
3602      }
3603
3604      if (text.length > 0) {
3605        return text;
3606      }
3607      else {
3608        return null;
3609      }
3610
3611      function createTextWrapper(text, lang) {
3612        var additionalClasses = (lang === 'pl') ? "" :'hidden';
3613
3614        var $textWrapper = $('<span>', {
3615          'data-translate-show': lang,
3616          class: additionalClasses,
3617        });
3618
3619        return $textWrapper.html(text)[0].outerHTML;
3620      }
3621
3622    }
3623
3624    this.coordsDeepLevel = function(coords) {
3625      var firstCoord = coords[0] ? coords[0] : (coords.lat ? coords.lat : []);
3626      // console.log(firstCoord);
3627
3628      if (typeof firstCoord == 'number') {
3629        return -1;
3630      }
3631      else {
3632        return 1 + that.coordsDeepLevel(coords[0]);
3633      }
3634    }
3635
3636    this.trackToTuristicObject = function (object, fromListBool) {
3637         var coordsDeepLevel = that.coordsDeepLevel(object.geometry.coordinates);
3638         // console.log(coordsDeepLevel);
3639         var obj = {
3640            id: object.properties.id,
3641            geometryType: 'line',
3642            turisticType: 't',
3643            geometry: {
3644                coords: L.GeoJSON.coordsToLatLngs(object.geometry.coordinates, coordsDeepLevel)
3645            },
3646            graphic: {
3647                icon: (function () {
3648                    if (object.properties.icon.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3649                        return serverRoot + object.properties.icon;
3650                    }
3651                    else {
3652                        return  object.properties.icon;
3653                    };
3654                })(),
3655                img: (function () {
3656                    if (object.properties.photolist.length > 0){
3657                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3658                            return serverRoot + object.properties.photolist[0].imgs;
3659                        }
3660                        else {
3661                            return object.properties.photolist[0].imgs;
3662                        };
3663                    };
3664                })(),
3665                bigImg: (function () {
3666                    if (object.properties.photolist.length > 0){
3667                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3668                            return serverRoot + object.properties.photolist[0].img;
3669                        }
3670                        else {
3671                            return object.properties.photolist[0].img;
3672                        };
3673                    };
3674                })(),
3675
3676                hasImg: false
3677            },
3678            desc: {
3679                // name: object.properties.nazwa,
3680                name: this.twoLanguageText(object.properties.nazwa, object.properties.Name_Cz),
3681                photolist: (function () {
3682                    if (object.properties.photolist.length > 0){
3683                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3684                            for (var a = 0; a < object.properties.photolist.length; a++)
3685							{
3686								object.properties.photolist[a].img = serverRoot + object.properties.photolist[a].img;
3687								object.properties.photolist[a].imgs = serverRoot + object.properties.photolist[a].imgs;
3688							}
3689							return object.properties.photolist;
3690                        }
3691                        else {
3692                            return object.properties.photolist;
3693                        };
3694                    };
3695                })(),
3696				poilist: (function () {
3697					if (typeof object.properties.poilist !== 'undefined')
3698					{
3699						if (object.properties.poilist.length > 0){
3700							if (object.properties.poilist[0].icon.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3701								for (var a = 0; a < object.properties.poilist.length; a++)
3702								{
3703									object.properties.poilist[a].icon = serverRoot + object.properties.poilist[a].icon;
3704								}
3705								return object.properties.poilist;
3706							}
3707							else {
3708								return object.properties.poilist;
3709							};
3710						};
3711					} else
3712					{
3713						return null;
3714					}
3715                })(),
3716                // fullDescription: object.properties.description,
3717                fullDescription: this.twoLanguageText(object.properties.description, object.properties.Opis_Cz),
3718                length: object.properties.dlugosc,
3719                color: object.properties.kolor,
3720                difficulty: object.properties.trudnosc || 'nie określono',
3721            },
3722            fromList: fromListBool,
3723            gpxfile: object.properties.gpxfile,
3724        };
3725
3726        //if graphic exist -> add flag
3727        if (obj.graphic.img) {
3728            obj.graphic.hasImg = true;
3729        };
3730        return obj;
3731    };
3732
3733	this.eventToTuristicObject = function (object, fromListBool) {
3734
3735		var that = this;
3736
3737		var obj = {
3738            id: object.properties.id,
3739            geometryType: 'point',
3740            turisticType: 'e',
3741            geometry: {
3742                coords: [object.geometry.coordinates[1], object.geometry.coordinates[0]]
3743            },
3744            graphic: {
3745                icon: (function () {
3746                    if (object.properties.type === 'kultura') {
3747                        return '/img/map/events_categories/wydarzenia_kulturalne.png';
3748                    }
3749					else if (object.properties.type === 'inne') {
3750                        return '/img/map/events_categories/wydarzenia_inne.png';
3751                    }
3752                    else {
3753                        return  '/img/map/events_categories/wydarzenia_sportowe.png';
3754                    };
3755                })(),
3756                img: (function () {
3757                    if (object.properties.photolist.length > 0){
3758                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3759                            return serverRoot + object.properties.photolist[0].imgs;
3760                        }
3761                        else {
3762                            return object.properties.photolist[0].imgs;
3763                        };
3764                    };
3765                })(),
3766                bigImg: (function () {
3767                    if (object.properties.photolist.length > 0){
3768                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3769                            return serverRoot + object.properties.photolist[0].img;
3770                        }
3771                        else {
3772                            return object.properties.photolist[0].img;
3773                        };
3774                    };
3775                })(),
3776
3777                hasImg: false
3778            },
3779            desc: {
3780                // name: object.properties.nazwa,
3781                name: this.twoLanguageText(object.properties.nazwa, object.properties.Name_Cz),
3782                address: null,
3783                category: null,
3784                mail: null,
3785                phone: null,
3786				contact: object.properties.kontakt,
3787                website: null,
3788                photolist: (function () {
3789                    if (object.properties.photolist.length > 0){
3790                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3791                            for (var a = 0; a < object.properties.photolist.length; a++)
3792							{
3793								object.properties.photolist[a].img = serverRoot + object.properties.photolist[a].img;
3794								object.properties.photolist[a].imgs = serverRoot + object.properties.photolist[a].imgs;
3795							}
3796							return object.properties.photolist;
3797                        }
3798                        else {
3799                            return object.properties.photolist;
3800                        };
3801                    };
3802                })(),
3803                // fullDescription: object.properties.opis,
3804                fullDescription: this.twoLanguageText(object.properties.opis, object.properties.Opis_Cz),
3805
3806				fromDate: (function () {
3807					try {
3808
3809						return that.parseDate(object.properties.dataod);
3810
3811					}
3812					catch (e) {return null};
3813				})(),
3814				toDate: (function (){
3815					try {
3816
3817						return that.parseDate(object.properties.datado);
3818
3819					}
3820					catch (e) {return null};
3821				})()
3822            },
3823            fromList: fromListBool
3824        };
3825
3826        //if graphic exist -> add flag
3827        if (obj.graphic.img) {
3828            obj.graphic.hasImg = true;
3829        };
3830
3831        return obj;
3832	};
3833
3834	this.sleepToTuristicObject = function (object, fromListBool) {
3835
3836		var obj = {
3837            id: object.properties.id,
3838            geometryType: 'point',
3839            turisticType: 'a',
3840            geometry: {
3841                coords: [object.geometry.coordinates[1], object.geometry.coordinates[0]]
3842            },
3843            graphic: {
3844                icon: (function () {
3845                    if (object.properties.icon.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3846                        return serverRoot + object.properties.icon;
3847                    }
3848                    else {
3849                        return  object.properties.icon;
3850                    };
3851                })(),
3852                img: (function () {
3853                    if (object.properties.photolist.length > 0){
3854                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3855                            return serverRoot + object.properties.photolist[0].imgs;
3856                        }
3857                        else {
3858                            return object.properties.photolist[0].imgs;
3859                        };
3860                    };
3861                })(),
3862                bigImg: (function () {
3863                    if (object.properties.photolist.length > 0){
3864                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3865                            return serverRoot + object.properties.photolist[0].img;
3866                        }
3867                        else {
3868                            return object.properties.photolist[0].img;
3869                        };
3870                    };
3871                })(),
3872
3873                hasImg: false
3874            },
3875            desc: {
3876                // name: object.properties.label,
3877                name: this.twoLanguageText(object.properties.label, object.properties.Name_Cz),
3878                address: object.properties.address,
3879                category: object.properties.category,
3880                mail: object.properties.mail,
3881                phone: object.properties.phone,
3882                website: object.properties.www,
3883                photolist: (function () {
3884                    if (object.properties.photolist.length > 0){
3885                        if (object.properties.photolist[0].img.indexOf('https://administracja.gison.pl/turysta-v8-1/') === -1) {
3886                            for (var a = 0; a < object.properties.photolist.length; a++)
3887							{
3888								object.properties.photolist[a].img = serverRoot + object.properties.photolist[a].img;
3889								object.properties.photolist[a].imgs = serverRoot + object.properties.photolist[a].imgs;
3890							}
3891							return object.properties.photolist;
3892                        }
3893                        else {
3894                            return object.properties.photolist;
3895                        };
3896                    };
3897                })(),
3898                // fullDescription: object.properties.description,
3899                fullDescription: this.twoLanguageText(object.properties.description, object.properties.Opis_Cz),
3900                lat: object.properties.lat,
3901                lng: object.properties.lng,
3902            },
3903			sleepPlace: {
3904				prices: object.properties.cena,
3905				langs: object.properties.jezyki,
3906				details: object.properties.nocleg_szczegoly
3907			},
3908            fromList: fromListBool
3909        };
3910
3911        //if graphic exist -> add flag
3912        if (obj.graphic.img) {
3913            obj.graphic.hasImg = true;
3914        };
3915
3916        return obj;
3917
3918	};
3919
3920    this.getTuristicObjects = function (filter) {
3921        var that = this;
3922
3923        filter._profilid = Profile.parameters.profileID; //assign profile id
3924
3925        return $http({
3926
3927            method: 'POST',
3928            data: filter,
3929            url: proxyHost + serverRoot + 'common/GetPublicFeatures2Poi/'
3930
3931        }).then(function successCallback (response) {
3932
3933            that.objects = [];
3934
3935            var data = response.data.flist;
3936            var length = data.length;
3937
3938            for (var i = 0; i < length; i++) {
3939                var object = angular.fromJson(data[i]);
3940
3941                var obj = that.objectToTuristicObject(object, true);
3942
3943                that.objects.push(obj);
3944            };
3945
3946            that.allCount = response.data.allCount;
3947
3948        }, function errorCallback (response) {
3949            alert('Błąd wyszukiwania.');
3950        });
3951    };
3952
3953    this.getTracks = function (filter) {
3954        var that = this;
3955
3956        filter._profilid = Profile.parameters.profileID; //assign profile id
3957
3958        return $http({
3959
3960            method: 'POST',
3961            data: filter,
3962            url: proxyHost + serverRoot + 'common/GetPublicFeatures2Szlak'
3963
3964        }).then(function successCallback (response) {
3965
3966            that.objects = [];
3967
3968            var data = response.data.flist;
3969            var length = data.length;
3970
3971            for (var i = 0; i < length; i++) {
3972                var object = angular.fromJson(data[i]);
3973
3974                var obj = that.trackToTuristicObject(object, true);
3975
3976                that.objects.push(obj);
3977            };
3978
3979            that.allCount = response.data.allCount;
3980
3981        }, function errorCallback (response) {
3982            alert('Błąd wyszukiwania.');
3983        });
3984    };
3985
3986	this.getEvents = function (filter) {
3987		var that = this;
3988
3989		filter._profilid = Profile.parameters.profileID; // assign profile id
3990
3991		// temporary solution !
3992
3993		// today date
3994		var actualDate = new Date();
3995
3996		var myDate = {
3997			year: actualDate.getFullYear(),
3998			month: (actualDate.getMonth() > 9) ? actualDate.getMonth() : '0'+actualDate.getMonth(),
3999			day: (actualDate.getDate() > 9) ? actualDate.getDate() : '0'+actualDate.getDate()
4000		};
4001
4002		filter.data_od = myDate.year + '-' + myDate.month + '-' + myDate.day;
4003
4004		return $http({
4005
4006			method: 'POST',
4007			data: filter,
4008			url: proxyHost + serverRoot + 'common/GetPublicFeatures2Wydarzenie'
4009
4010		}).then(function successCallback (response) {
4011
4012			that.objects = [];
4013			var data = response.data.flist;
4014			var length = data.length;
4015
4016			for (var i = 0; i < length; i++) {
4017				var object = angular.fromJson(data[i]);
4018
4019				// null ?
4020				if (object != null) {
4021
4022					var obj = that.eventToTuristicObject(object, true);
4023					that.objects.push(obj);
4024
4025				};
4026
4027			};
4028
4029			// termporary solution !
4030			that.allCount = response.data.allCount;
4031
4032		}, function errorCallback (response) {
4033			alert('Błąd wyszukiwania');
4034		});
4035	};
4036
4037	this.getSleeps = function (filter) {
4038		var that = this;
4039
4040        filter._profilid = Profile.parameters.profileID; //assign profile id
4041
4042        return $http({
4043
4044            method: 'POST',
4045            data: filter,
4046            url: proxyHost + serverRoot + 'common/GetPublicFeatures2Nocleg'
4047
4048        }).then(function successCallback (response) {
4049
4050            that.objects = [];
4051
4052            var data = response.data.flist;
4053            var length = data.length;
4054
4055            for (var i = 0; i < length; i++) {
4056                var object = angular.fromJson(data[i]);
4057
4058                var obj = that.sleepToTuristicObject(object, true);
4059
4060                that.objects.push(obj);
4061            };
4062
4063            that.allCount = response.data.allCount;
4064
4065        }, function errorCallback (response) {
4066            alert('Błąd wyszukiwania.');
4067        });
4068	};
4069
4070    this.getObjectById = function (selectedFeature) {
4071        var that = this;
4072
4073        if (selectedFeature.type === 's') { // case of showplace obj
4074
4075            return $http({
4076                method: 'POST',
4077                data: {
4078                    root: serverRoot,
4079                    featureid: selectedFeature.id,
4080                    _profilid: Profile.parameters.profileID
4081                },
4082                url: proxyHost + serverRoot + 'PunktPoi/GetPublicFeatures2'
4083            });
4084
4085        }
4086		else if (selectedFeature.type === 'e') { //case of event obj
4087
4088			return $http({
4089                method: 'POST',
4090                data: {
4091                    root: serverRoot,
4092                    featureid: selectedFeature.id,
4093                    _profilid: Profile.parameters.profileID
4094                },
4095                url: proxyHost + serverRoot + 'Wydarzenie/GetPublicFeatures2'
4096            });
4097		}
4098        else if (selectedFeature.type === 't') {
4099            return $http({
4100                method: 'POST',
4101                data: {
4102                    root: serverRoot,
4103                    featureid: selectedFeature.id,
4104                    _profilid: Profile.parameters.profileID
4105                },
4106                url: proxyHost + serverRoot + 'Szlak/GetPublicFeatures2'
4107            });
4108        }
4109		else {
4110            return $http({
4111                method: 'POST',
4112                data: {
4113                    root: serverRoot,
4114                    featureid: selectedFeature.id,
4115                    _profilid: Profile.parameters.profileID
4116                },
4117                url: proxyHost + serverRoot + 'PunktPoi/GetPublicFeatures2'
4118            });
4119        };;
4120    };
4121
4122}]);

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.