PageSourceSearch

https://elbe-roeder.de/js/script.js

js elbe-roeder.de collected 2026-10-06 14:11:15 UTC 60,931 bytes, 1,889 lines download raw bytes

1/**
2 * Global variables
3 */
4"use strict";
5
6var userAgent = navigator.userAgent.toLowerCase(),
7  initialDate = new Date(),
8
9  $document = $(document),
10  $window = $(window),
11  $html = $("html"),
12
13  isDesktop = $html.hasClass("desktop"),
14  isIE = userAgent.indexOf("msie") != -1 ? parseInt(userAgent.split("msie")[1]) : userAgent.indexOf("trident") != -1 ? 11 : userAgent.indexOf("edge") != -1 ? 12 : false,
15  isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
16  isTouch = "ontouchstart" in window,
17
18  plugins = {
19    pointerEvents: isIE < 11 ? "js/pointer-events.min.js" : false,
20    bootstrapTooltip: $("[data-toggle='tooltip']"),
21    bootstrapTabs: $(".tabs"),
22    bootstrapAccordions: $(".accordion"),
23    rdParallax: $(".rd-parallax"),
24    rdGoogleMaps: $(".rd-google-map"),
25    rdNavbar: $(".rd-navbar"),
26    mfp: $('[data-lightbox]').not('[data-lightbox="gallery"] [data-lightbox]'),
27    mfpGallery: $('[data-lightbox^="gallery"]'),
28    owl: $(".owl-carousel"),
29    swiper: $(".swiper-slider"),
30    counter: $(".counter"),
31    twitterfeed: $(".twitter"),
32    progressBar: $(".progress-bar-js"),
33    isotope: $(".isotope"),
34    countDown: $(".countdown"),
35    popover: $('[data-toggle="popover"]'),
36    dateCountdown: $('.DateCountdown'),
37    statefulButton: $('.btn-stateful'),
38    slick: $('.slick-slider'),
39    viewAnimate: $('.view-animate'),
40    selectFilter: $("select"),
41    rdInputLabel: $(".form-label"),
42    bootstrapDateTimePicker: $("[data-time-picker]"),
43    customWaypoints: $('[data-custom-scroll-to]'),
44    photoSwipeGallery: $("[data-photo-swipe-item]"),
45    stepper: $("input[type='number']"),
46    radio: $("input[type='radio']"),
47    checkbox: $("input[type='checkbox']"),
48    customToggle: $("[data-custom-toggle]"),
49    rdMailForm: $(".rd-mailform"),
50    regula: $("[data-constraints]"),
51    pageLoader: $(".page-loader"),
52    search: $(".rd-search"),
53    searchResults: $('.rd-search-results'),
54    imgZoom: $('[mag-thumb]'),
55    pageTitles: $('.page-title')
56  };
57
58/**
59 * Initialize All Scripts
60 */
61$document.ready(function () {
62  var isNoviBuilder = window.xMode;
63
64  /**
65   * Adjustments for Safari on Mac
66   */
67  (function($){
68    if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Mac') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
69      $('html').addClass('mac'); // provide a class for the safari-mac specific css to filter with
70    }
71  })(jQuery);
72
73  /**
74   * getSwiperHeight
75   * @description  calculate the height of swiper slider basing on data attr
76   */
77  function getSwiperHeight(object, attr) {
78    var val = object.attr("data-" + attr),
79      dim;
80
81    if (!val) {
82      return undefined;
83    }
84
85    dim = val.match(/(px)|(%)|(vh)$/i);
86
87    if (dim.length) {
88      switch (dim[0]) {
89        case "px":
90          return parseFloat(val);
91        case "vh":
92          return $(window).height() * (parseFloat(val) / 100);
93        case "%":
94          return object.width() * (parseFloat(val) / 100);
95      }
96    } else {
97      return undefined;
98    }
99  }
100
101  /**
102   * toggleSwiperInnerVideos
103   * @description  toggle swiper videos on active slides
104   */
105  function toggleSwiperInnerVideos(swiper) {
106    var prevSlide = $(swiper.slides[swiper.previousIndex]),
107      nextSlide = $(swiper.slides[swiper.activeIndex]),
108      videos;
109
110    prevSlide.find("video").each(function () {
111      this.pause();
112    });
113
114    videos = nextSlide.find("video");
115    if (videos.length) {
116      videos.get(0).play();
117    }
118  }
119
120  /**
121   * toggleSwiperCaptionAnimation
122   * @description  toggle swiper animations on active slides
123   */
124  function toggleSwiperCaptionAnimation(swiper) {
125    var prevSlide = $(swiper.container),
126      nextSlide = $(swiper.slides[swiper.activeIndex]);
127
128    prevSlide
129      .find("[data-caption-animate]")
130      .each(function () {
131        var $this = $(this);
132        $this
133          .removeClass("animated")
134          .removeClass($this.attr("data-caption-animate"))
135          .addClass("not-animated");
136      });
137
138
139    nextSlide
140      .find("[data-caption-animate]")
141      .each(function () {
142        var $this = $(this),
143          delay = $this.attr("data-caption-delay");
144
145        if (!isNoviBuilder) {
146          setTimeout(function () {
147            $this
148              .removeClass("not-animated")
149              .addClass($this.attr("data-caption-animate"))
150              .addClass("animated");
151          }, delay ? parseInt(delay) : 0);
152        }else{
153          $this
154            .removeClass("not-animated")
155        }
156      });
157  }
158
159  /**
160   * makeParallax
161   * @description  create swiper parallax scrolling effect
162   */
163  function makeParallax(el, speed, wrapper, prevScroll) {
164    var scrollY = window.scrollY || window.pageYOffset;
165
166    if (prevScroll != scrollY) {
167      prevScroll = scrollY;
168      el.addClass('no-transition');
169      el[0].style['transform'] = 'translate3d(0,' + -scrollY * (1 - speed) + 'px,0)';
170      el.height();
171      el.removeClass('no-transition');
172
173      if (el.attr('data-fade') === 'true') {
174        var bound = el[0].getBoundingClientRect(),
175          offsetTop = bound.top * 2 + scrollY,
176          sceneHeight = wrapper.outerHeight(),
177          sceneDevider = wrapper.offset().top + sceneHeight / 2.0,
178          layerDevider = offsetTop + el.outerHeight() / 2.0,
179          pos = sceneHeight / 6.0,
180          opacity;
181        if (sceneDevider + pos > layerDevider && sceneDevider - pos < layerDevider) {
182          el[0].style["opacity"] = 1;
183        } else {
184          if (sceneDevider - pos < layerDevider) {
185            opacity = 1 + ((sceneDevider + pos - layerDevider) / sceneHeight / 3.0 * 5);
186          } else {
187            opacity = 1 - ((sceneDevider - pos - layerDevider) / sceneHeight / 3.0 * 5);
188          }
189          el[0].style["opacity"] = opacity < 0 ? 0 : opacity > 1 ? 1 : opacity.toFixed(2);
190        }
191      }
192    }
193
194    requestAnimationFrame(function () {
195      makeParallax(el, speed, wrapper, prevScroll);
196    });
197  }
198
199  /**
200   * isScrolledIntoView
201   * @description  check the element whas been scrolled into the view
202   */
203  function isScrolledIntoView(elem) {
204    var $window = $(window);
205    return elem.offset().top + elem.outerHeight() >= $window.scrollTop() && elem.offset().top <= $window.scrollTop() + $window.height();
206  }
207
208  /**
209   * initOnView
210   * @description  calls a function when element has been scrolled into the view
211   */
212  function lazyInit(element, func) {
213    var $win = jQuery(window);
214    $win.on('load scroll', function () {
215      if ((!element.hasClass('lazy-loaded') && (isScrolledIntoView(element)))) {
216        func.call();
217        element.addClass('lazy-loaded');
218      }
219    });
220  }
221
222  /**
223   * Live Search
224   * @description  create live search results
225   */
226  function liveSearch(options){
227    $('#' + options.live).removeClass('cleared').html();
228    options.current++;
229    options.spin.addClass('loading');
230    $.get(handler, {
231      s: decodeURI(options.term),
232      liveSearch: options.live,
233      dataType: "html",
234      liveCount: options.liveCount,
235      filter: options.filter,
236      template: options.template
237    }, function (data) {
238      options.processed++;
239      var live = $('#' + options.live);
240      if (options.processed == options.current && !live.hasClass('cleared')){
241        live.find('> #search-results').removeClass('active');
242        live.html(data);
243        setTimeout(function () {
244          live.find('> #search-results').addClass('active');
245        }, 50);
246      }
247      options.spin.parents('.rd-search').find('.input-group-addon').removeClass('loading');
248    })
249  }
250
251  /**
252   * attachFormValidator
253   * @description  attach form validation to elements
254   */
255  function attachFormValidator(elements) {
256    for (var i = 0; i < elements.length; i++) {
257      var o = $(elements[i]), v;
258      o.addClass("form-control-has-validation").after("<span class='form-validation'></span>");
259      v = o.parent().find(".form-validation");
260      if (v.is(":last-child")) {
261        o.addClass("form-control-last-child");
262      }
263    }
264
265    elements
266      .on('input change propertychange blur', function (e) {
267        var $this = $(this), results;
268
269        if (e.type != "blur") {
270          if (!$this.parent().hasClass("has-error")) {
271            return;
272          }
273        }
274
275        if ($this.parents('.rd-mailform').hasClass('success')) {
276          return;
277        }
278
279        if ((results = $this.regula('validate')).length) {
280          for (i = 0; i < results.length; i++) {
281            $this.siblings(".form-validation").text(results[i].message).parent().addClass("has-error")
282          }
283        } else {
284          $this.siblings(".form-validation").text("").parent().removeClass("has-error")
285        }
286      })
287      .regula('bind');
288  }
289
290  /**
291   * isValidated
292   * @description  check if all elemnts pass validation
293   */
294  function isValidated(elements) {
295    var results, errors = 0;
296    if (elements.length) {
297      for (j = 0; j < elements.length; j++) {
298
299        var $input = $(elements[j]);
300
301        if ((results = $input.regula('validate')).length) {
302          for (k = 0; k < results.length; k++) {
303            errors++;
304            $input.siblings(".form-validation").text(results[k].message).parent().addClass("has-error");
305          }
306        } else {
307          $input.siblings(".form-validation").text("").parent().removeClass("has-error")
308        }
309      }
310
311      return errors == 0;
312    }
313    return true;
314  }
315
316  /**
317   * Init Bootstrap tooltip
318   * @description  calls a function when need to init bootstrap tooltips
319   */
320  function initBootstrapTooltip(tooltipPlacement) {
321    if (window.innerWidth < 599) {
322      plugins.bootstrapTooltip.tooltip('destroy');
323      plugins.bootstrapTooltip.tooltip({
324        placement: 'bottom'
325      });
326    } else {
327      plugins.bootstrapTooltip.tooltip('destroy');
328      plugins.bootstrapTooltip.tooltipPlacement;
329      plugins.bootstrapTooltip.tooltip();
330    }
331  }
332
333  /**
334   * ChangeExternalButtons
335   * @description Change active tab in responsive active tab by external buttons (next tab, prev tab)
336   */
337  function changeExternalButtons(respTabItem, direction) {
338    var prev,
339      next,
340      activeItem;
341
342    respTabItem.find('.resp-tabs-extertal-list li').removeClass('active');
343
344    activeItem = respTabItem.find('.resp-tab-item.resp-tab-active');
345
346    next = activeItem.next();
347    if (!next.length) {
348      next = respTabItem.find('.resp-tab-item:first-child()');
349    }
350
351    prev = activeItem.prev();
352    if (!prev.length) {
353      prev = respTabItem.find('.resp-tab-item:last-child()');
354    }
355
356    if (direction) {
357      if (direction === 'next') {
358        next.trigger('click');
359      } else {
360        prev.trigger('click');
361      }
362
363      setTimeout(function () {
364        changeExternalButtons(respTabItem);
365      }, 10);
366    }
367
368    respTabItem.find('.resp-tab-external-prev li:nth-child(' + (prev.index() + 1) + ')').addClass('active');
369    respTabItem.find('.resp-tab-external-next li:nth-child(' + (next.index() + 1) + ')').addClass('active');
370  }
371
372  /**
373   * Copyright Year
374   * @description  Evaluates correct copyright year
375   */
376  var o = $("#copyright-year");
377  if (o.length) {
378    o.text(initialDate.getFullYear());
379  }
380
381  /**
382   * IE Polyfills
383   * @description  Adds some loosing functionality to IE browsers
384   */
385  if (isIE) {
386    if (isIE < 10) {
387      $html.addClass("lt-ie-10");
388    }
389
390    if (isIE < 11) {
391      if (plugins.pointerEvents) {
392        $.getScript(plugins.pointerEvents)
393          .done(function () {
394            $html.addClass("ie-10");
395            PointerEventsPolyfill.initialize({});
396          });
397      }
398    }
399
400    if (isIE === 11) {
401      $("html").addClass("ie-11");
402    }
403
404    if (isIE === 12) {
405      $("html").addClass("ie-edge");
406    }
407  }
408
409  /**
410   * Bootstrap Tooltips
411   * @description Activate Bootstrap Tooltips
412   */
413  if (plugins.bootstrapTooltip.length) {
414    var tooltipPlacement = plugins.bootstrapTooltip.attr('data-placement');
415    initBootstrapTooltip(tooltipPlacement);
416    $(window).on('resize orientationchange', function () {
417      initBootstrapTooltip(tooltipPlacement);
418    })
419  }
420
421  /**
422   * @module       Magnific Popup
423   * @author       Dmitry Semenov
424   * @see          http://dimsemenov.com/plugins/magnific-popup/
425   * @version      v1.0.0
426   */
427  if (plugins.mfp.length > 0 || plugins.mfpGallery.length > 0 && isNoviBuilder != "designMode") {
428    if (plugins.mfp.length) {
429      for (i = 0; i < plugins.mfp.length; i++) {
430        var mfpItem = plugins.mfp[i];
431
432        $(mfpItem).magnificPopup({
433          type: mfpItem.getAttribute("data-lightbox")
434        });
435      }
436    }
437    if (plugins.mfpGallery.length) {
438      for (i = 0; i < plugins.mfpGallery.length; i++) {
439        var mfpGalleryItem = $(plugins.mfpGallery[i]).find('[data-lightbox]');
440
441        for (var c = 0; c < mfpGalleryItem.length; c++) {
442          $(mfpGalleryItem).addClass("mfp-" + $(mfpGalleryItem).attr("data-lightbox"));
443        }
444
445        mfpGalleryItem.end()
446          .magnificPopup({
447            delegate: '[data-lightbox]',
448            type: "image",
449            gallery: {
450              enabled: true
451            }
452          });
453      }
454    }
455  }
456
457  /**
458   * RD Google Maps
459   * @description Enables RD Google Maps plugin
460   */
461  if (plugins.rdGoogleMaps.length) {
462    var i;
463
464    $.getScript("//maps.google.com/maps/api/js?key=AIzaSyAFeB0kVA6ou
464yJ_gEvFbMaefLy3cBCyRwo&sensor=false&libraries=geometry,places&v=3.7", function() {
465      var head = document.getElementsByTagName('head')[0],
466        insertBefore = head.insertBefore;
467
468      head.insertBefore = function(newElement, referenceElement) {
469        if (newElement.href && newElement.href.indexOf('//fonts.googleapis.com/css?family=Roboto') != -1 || newElement.innerHTML.indexOf('gm-style') != -1) {
470          return;
471        }
472        insertBefore.call(head, newElement, referenceElement);
473      };
474
475      function initGoogleMap(){
476        var $this = $(this),
477          styles = $this.attr("data-styles");
478
479        $this.googleMap({
480          styles: styles ? JSON.parse(styles) : [],
481          onInit: function(map) {
482            var inputAddress = $('#rd-google-map-address');
483
484            if (inputAddress.length) {
485              var input = inputAddress;
486              var geocoder = new google.maps.Geocoder();
487              var marker = new google.maps.Marker({
488                map: map,
489                icon: "images/gmap_marker.png",
490              });
491              var autocomplete = new google.maps.places.Autocomplete(inputAddress[0]);
492              autocomplete.bindTo('bounds', map);
493              inputAddress.attr('placeholder', '');
494              inputAddress.on('change', function() {
495                $("#rd-google-map-address-submit").trigger('click');
496              });
497              inputAddress.on('keydown', function(e) {
498                if (e.keyCode == 13) {
499                  $("#rd-google-map-address-submit").trigger('click');
500                }
501              });
502
503
504              $("#rd-google-map-address-submit").on('click', function(e) {
505                e.preventDefault();
506                var address = input.val();
507                geocoder.geocode({
508                  'address': address
509                }, function(results, status) {
510                  if (status == google.maps.GeocoderStatus.OK) {
511                    var latitude = results[0].geometry.location.lat();
512                    var longitude = results[0].geometry.location.lng();
513
514                    map.setCenter(new google.maps.LatLng(
515                      parseFloat(latitude),
516                      parseFloat(longitude)
517                    ));
518                    marker.setPosition(new google.maps.LatLng(
519                      parseFloat(latitude),
520                      parseFloat(longitude)
521                    ))
522                  }
523                });
524              });
525            }
526          }
527        });
528      }
529
530      for (i = 0; i < plugins.rdGoogleMaps.length; i++) {
531        if (isNoviBuilder !== "designMode") {
532          lazyInit($(plugins.rdGoogleMaps[i]), initGoogleMap.bind(plugins.rdGoogleMaps[i]));
533        } else {
534          initGoogleMap.bind(plugins.rdGoogleMaps[i])();
535        }
536      }
537    });
538  }
539
540  /**
541   * Bootstrap Date time picker
542   */
543  if (plugins.bootstrapDateTimePicker.length) {
544    var i;
545    for (i = 0; i < plugins.bootstrapDateTimePicker.length; i++) {
546      var $dateTimePicker = $(plugins.bootstrapDateTimePicker[i]);
547      var options = {};
548
549      options['format'] = 'dddd DD MMMM YYYY - HH:mm';
550      if ($dateTimePicker.attr("data-time-picker") == "date") {
551        options['format'] = 'dddd DD MMMM YYYY';
552        options['minDate'] = new Date();
553      } else if ($dateTimePicker.attr("data-time-picker") == "time") {
554        options['format'] = 'HH:mm';
555      }
556
557      options["time"] = ($dateTimePicker.attr("data-time-picker") != "date");
558      options["date"] = ($dateTimePicker.attr("data-time-picker") != "time");
559      options["shortTime"] = true;
560
561      $dateTimePicker.bootstrapMaterialDatePicker(options);
562    }
563  }
564
565  /**
566   * RD Twitter Feed
567   * @description Enables RD Twitter Feed plugin
568   */
569  if (plugins.twitterfeed.length > 0) {
570    var i;
571    for (i = 0; i < plugins.twitterfeed.length; i++) {
572      var twitterfeedItem = plugins.twitterfeed[i];
573      $(twitterfeedItem).RDTwitter({});
574    }
575  }
576
577  /**
578   * Select2
579   * @description Enables select2 plugin
580   */
581  if (plugins.selectFilter.length) {
582    var i;
583    for (i = 0; i < plugins.selectFilter.length; i++) {
584      var select = $(plugins.selectFilter[i]);
585
586      select.select2({
587        theme: select.attr('data-custom-theme') ? select.attr('data-custom-theme') : "bootstrap"
588      }).next().addClass(select.attr("class").match(/(input-sm)|(input-lg)|($)/i).toString().replace(new RegExp(",", 'g'), " "));
589    }
590  }
591
592  /**
593   * Stepper
594   * @description Enables Stepper Plugin
595   */
596  if (plugins.stepper.length) {
597    plugins.stepper.stepper({
598      labels: {
599        up: "",
600        down: ""
601      }
602    });
603  }
604
605  /**
606   * Radio
607   * @description Add custom styling options for input[type="radio"]
608   */
609  if (plugins.radio.length) {
610    var i;
611    for (i = 0; i < plugins.radio.length; i++) {
612      var $this = $(plugins.radio[i]);
613      $this.addClass("radio-custom").after("<span class='radio-custom-dummy'></span>")
614    }
615  }
616
617  /**
618   * Checkbox
619   * @description Add custom styling options for input[type="checkbox"]
620   */
621  if (plugins.checkbox.length) {
622    var i;
623    for (i = 0; i < plugins.checkbox.length; i++) {
624      var $this = $(plugins.checkbox[i]);
625      $this.addClass("checkbox-custom").after("<span class='checkbox-custom-dummy'></span>")
626    }
627  }
628
629  /**
630   * Popovers
631   * @description Enables Popovers plugin
632   */
633  if (plugins.popover.length) {
634    if (window.innerWidth < 767) {
635      plugins.popover.attr('data-placement', 'bottom');
636      plugins.popover.popover();
637    }
638    else {
639      plugins.popover.popover();
640    }
641  }
642
643  /**
644   * jQuery Countdown
645   * @description  Enable countdown plugin
646   */
647  if (plugins.countDown.length) {
648    var i;
649    for (i = 0; i < plugins.countDown.length; i++) {
650      var countDownItem = plugins.countDown[i],
651        d = new Date(),
652        type = countDownItem.getAttribute('data-type'),
653        time = countDownItem.getAttribute('data-time'),
654        format = countDownItem.getAttribute('data-format'),
655        settings = [];
656
657      d.setTime(Date.parse(time)).toLocaleString();
658      settings[type] = d;
659      settings['format'] = format;
660      $(countDownItem).countdown(settings);
661    }
662  }
663
664  /**
665   * TimeCircles
666   * @description  Enable TimeCircles plugin
667   */
668  if (plugins.dateCountdown.length) {
669    var i;
670    for (i = 0; i < plugins.dateCountdown.length; i++) {
671      var dateCountdownItem = $(plugins.dateCountdown[i]),
672        time = {
673          "Days": {
674            "text": "Days",
675            "show": true,
676            color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
677          },
678          "Hours": {
679            "text": "Hours",
680            "show": true,
681            color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
682          },
683          "Minutes": {
684            "text": "Minutes",
685            "show": true,
686            color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
687          },
688          "Seconds": {
689            "text": "Seconds",
690            "show": true,
691            color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
692          }
693        };
694
695      dateCountdownItem.TimeCircles({
696        color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "rgba(247, 247, 247, 1)",
697        animation: "smooth",
698        bg_width: dateCountdownItem.attr("data-bg-width") ? dateCountdownItem.attr("data-bg-width") : 0.9,
699        circle_bg_color: dateCountdownItem.attr("data-bg") ? dateCountdownItem.attr("data-bg") : "rgba(0, 0, 0, 1)",
700        fg_width: dateCountdownItem.attr("data-width") ? dateCountdownItem.attr("data-width") : 0.03
701      });
702
703      $(window).on('load resize orientationchange', function () {
704        if (window.innerWidth < 479) {
705          dateCountdownItem.TimeCircles({
706            time: {
707              "Days": {
708                "text": "Days",
709                "show": true,
710                color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
711              },
712              "Hours": {
713                "text": "Hours",
714                "show": true,
715                color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
716              },
717              "Minutes": {
718                "text": "Minutes",
719                "show": true,
720                color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
721              },
722              Seconds: {
723                "text": "Seconds",
724                show: false,
725                color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
726              }
727            }
728          }).rebuild();
729        } else if (window.innerWidth < 767) {
730          dateCountdownItem.TimeCircles({
731            time: {
732              "Days": {
733                "text": "Days",
734                "show": true,
735                color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
736              },
737              "Hours": {
738                "text": "Hours",
739                "show": true,
740                color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
741              },
742              "Minutes": {
743                "text": "Minutes",
744                "show": true,
745                color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
746              },
747              Seconds: {
748                text: '',
749                show: false,
750                color: dateCountdownItem.attr("data-color") ? dateCountdownItem.attr("data-color") : "#f9f9f9"
751              }
752            }
753          }).rebuild();
754        } else {
755          dateCountdownItem.TimeCircles({time: time}).rebuild();
756        }
757      });
758    }
759  }
760
761  /**
762   * Bootstrap Buttons
763   * @description  Enable Bootstrap Buttons plugin
764   */
765  if (plugins.statefulButton.length) {
766    $(plugins.statefulButton).on('click', function () {
767      var statefulButtonLoading = $(this).button('loading');
768
769      setTimeout(function () {
770        statefulButtonLoading.button('reset')
771      }, 2000);
772    })
773  }
774
775  /**
776   * Progress bar
777   * @description  Enable progress bar
778   */
779  if (plugins.progressBar.length) {
780    var i,
781      bar,
782      type;
783
784    for (i = 0; i < plugins.progressBar.length; i++) {
785      var progressItem = plugins.progressBar[i];
786      bar = null;
787
788      if (progressItem.className.indexOf("progress-bar-horizontal") > -1) {
789        type = 'Line';
790      }
791
792      if (progressItem.className.indexOf("progress-bar-radial") > -1) {
793        type = 'Circle';
794      }
795
796      if (progressItem.getAttribute("data-stroke") && progressItem.getAttribute("data-value") && type) {
797        bar = new ProgressBar[type](progressItem, {
798          strokeWidth: Math.round(parseFloat(progressItem.getAttribute("data-stroke")) / progressItem.offsetWidth * 100),
799          trailWidth: progressItem.getAttribute("data-trail") ? Math.round(parseFloat(progressItem.getAttribute("data-trail")) / progressItem.offsetWidth * 100) : 0,
800          text: {
801            value: progressItem.getAttribute("data-counter") === "true" ? '0' : null,
802            className: 'progress-bar__body',
803            style: null
804          }
805        });
806        bar.svg.setAttribute('preserveAspectRatio', "none meet");
807        if (type === 'Line') {
808          bar.svg.setAttributeNS(null, "height", progressItem.getAttribute("data-stroke"));
809        }
810
811        bar.path.removeAttribute("stroke");
812        bar.path.className.baseVal = "progress-bar__stroke";
813        if (bar.trail) {
814          bar.trail.removeAttribute("stroke");
815          bar.trail.className.baseVal = "progress-bar__trail";
816        }
817
818        if (progressItem.getAttribute("data-easing") && !isIE) {
819          $(document)
820            .on("scroll", {"barItem": bar}, $.proxy(function (event) {
821              var bar = event.data.barItem;
822              var $this = $(this);
823
824              if (isScrolledIntoView($this) && this.className.indexOf("progress-bar--animated") === -1) {
825                this.className += " progress-bar--animated";
826                bar.animate(parseInt($this.attr("data-value")) / 100.0, {
827                  easing: $this.attr("data-easing"),
828                  duration: $this.attr("data-duration") ? parseInt($this.attr("data-duration")) : 800,
829                  step: function (state, b) {
830                    if (b._container.className.indexOf("progress-bar-horizontal") > -1 ||
831                      b._container.className.indexOf("progress-bar-vertical") > -1) {
832                      b.text.style.width = Math.abs(b.value() * 100).toFixed(0) + "%"
833                    }
834                    b.setText(Math.abs(b.value() * 100).toFixed(0));
835                  }
836                });
837              }
838            }, progressItem))
839            .trigger("scroll");
840        } else {
841          bar.set(parseInt($(progressItem).attr("data-value")) / 100.0);
842          bar.setText($(progressItem).attr("data-value"));
843          if (type === 'Line') {
844            bar.text.style.width = parseInt($(progressItem).attr("data-value")) + "%";
845          }
846        }
847      } else {
848        console.error(progressItem.className + ": progress bar type is not defined");
849      }
850    }
851  }
852
853  /**
854   * UI To Top
855   * @description Enables ToTop Button
856   */
857  if (isDesktop && !isNoviBuilder) {
858    $().UItoTop({
859      easingType: 'easeOutQuart',
860      containerClass: 'ui-to-top fa fa-angle-up'
861    });
862  }
863
864  /**
865   * RD Navbar
866   * @description Enables RD Navbar plugin
867   */
868  if (plugins.rdNavbar.length) {
869    plugins.rdNavbar.RDNavbar({
870      stickUpClone: (plugins.rdNavbar.attr("data-stick-up-clone")  && !isNoviBuilder) ? plugins.rdNavbar.attr("data-stick-up-clone") === 'true' : false,
871      responsive: {
872        0: {
873          stickUp: (!isNoviBuilder) ? plugins.rdNavbar.attr("data-stick-up") === 'true' : false
874        },
875        768: {
876          stickUp: (!isNoviBuilder) ? plugins.rdNavbar.attr("data-sm-stick-up") === 'true' : false
877        },
878        992: {
879          stickUp: (!isNoviBuilder) ? plugins.rdNavbar.attr("data-md-stick-up") === 'true' : false
880        },
881        1200: {
882          stickUp: (!isNoviBuilder) ? plugins.rdNavbar.attr("data-lg-stick-up") === 'true' : false
883        }
884      }
885    });
886    if (plugins.rdNavbar.attr("data-body-class")) {
887      document.body.className += ' ' + plugins.rdNavbar.attr("data-body-class");
888    }
889  }
890
891  /**
892   * ViewPort Universal
893   * @description Add class in viewport
894   */
895  if (plugins.viewAnimate.length) {
896    var i;
897    for (i = 0; i < plugins.viewAnimate.length; i++) {
898      var $view = $(plugins.viewAnimate[i]).not('.active');
899      $document.on("scroll", $.proxy(function () {
900        if (isScrolledIntoView(this)) {
901          this.addClass("active");
902        }
903      }, $view))
904        .trigger("scroll");
905    }
906  }
907
908
909  /**
910   * Swiper 3.1.7
911   * @description  Enable Swiper Slider
912   */
913  if (plugins.swiper.length) {
914    var i;
915    for (i = 0; i < plugins.swiper.length; i++) {
916      var s = $(plugins.swiper[i]);
917      var pag = s.find(".swiper-pagination"),
918        next = s.find(".swiper-button-next"),
919        prev = s.find(".swiper-button-prev"),
920        bar = s.find(".swiper-scrollbar"),
921        parallax = s.parents('.rd-parallax').length,
922        swiperSlide = s.find(".swiper-slide");
923
924      for (j = 0; j < swiperSlide.length; j++) {
925        var $this = $(swiperSlide[j]),
926          url;
927
928        if (url = $this.attr("data-slide-bg")) {
929          $this.css({
930            "background-image": "url(" + url + ")",
931            "background-size": "cover"
932          })
933        }
934      }
935
936      swiperSlide.end()
937        .find("[data-caption-animate]")
938        .addClass("not-animated")
939        .end()
940        .swiper({
941          autoplay: s.attr('data-autoplay') !== "false" && !isNoviBuilder ? s.attr('data-autoplay')  : null,
942          direction: s.attr('data-direction') ? s.attr('data-direction') : "horizontal",
943          effect: s.attr('data-slide-effect') ? s.attr('data-slide-effect') : "slide",
944          speed: s.attr('data-slide-speed') ? s.attr('data-slide-speed') : 1000,
945          keyboardControl: s.attr('data-keyboard') === "true",
946          mousewheelControl: s.attr('data-mousewheel') === "true",
947          mousewheelReleaseOnEdges: s.attr('data-mousewheel-release') === "true",
948          nextButton: next.length ? next.get(0) : null,
949          prevButton: prev.length ? prev.get(0) : null,
950          pagination: pag.length ? pag.get(0) : null,
951          paginationClickable: pag.length ? pag.attr("data-clickable") !== "false" : false,
952          paginationBulletRender: pag.length ? pag.attr("data-index-bullet") === "true" ? function (index, className) {
953            return '<span class="' + className + '">' + (index + 1) + '</span>';
954          } : null : null,
955          scrollbar: bar.length ? bar.get(0) : null,
956          scrollbarDraggable: bar.length ? bar.attr("data-draggable") !== "false" : true,
957          scrollbarHide: bar.length ? bar.attr("data-draggable") === "false" : false,
958          loop: s.attr("data-loop") && !isNoviBuilder ? s.attr('data-loop') !== "false" : false,
959          simulateTouch: s.attr('data-simulate-touch') && !isNoviBuilder ? s.attr('data-simulate-touch') === "true" : false,
960          onTransitionStart: function (swiper) {
961            toggleSwiperInnerVideos(swiper);
962          },
963          onTransitionEnd: function (swiper) {
964            toggleSwiperCaptionAnimation(swiper);
965          },
966          onInit: function (swiper) {
967            toggleSwiperInnerVideos(swiper);
968            toggleSwiperCaptionAnimation(swiper);
969
970            var swiperParalax = s.find(".swiper-parallax");
971
972            for (var k = 0; k < swiperParalax.length; k++) {
973              var $this = $(swiperParalax[k]),
974                speed;
975
976              if (parallax && !isIEBrows && !isMobile) {
977                if (speed = $this.attr("data-speed")) {
978                  makeParallax($this, speed, s, false);
979                }
980              }
981            }
982            $(window).on('resize', function () {
983              swiper.update(true);
984            })
985          }
986        });
987
988      $(window)
989        .on("resize", function () {
990          var mh = getSwiperHeight(s, "min-height"),
991            h = getSwiperHeight(s, "height");
992          if (h) {
993            s.css("height", mh ? mh > h ? mh : h : h);
994          }
995        })
996        .trigger("resize");
997    }
998  }
999
1000  /**
1001   * Page loader
1002   * @description Enables Page loader
1003   */
1004  if (plugins.pageLoader.length > 0) {
1005
1006    $window.on("load", function () {
1007      var loader = setTimeout(function () {
1008        plugins.pageLoader.addClass("loaded");
1009        $window.trigger("resize");
1010      }, 200);
1011    });
1012
1013  }
1014
1015  /**
1016   * RD Search
1017   * @description Enables search
1018   */
1019  if (plugins.search.length || plugins.searchResults) {
1020    var handler = "bat/rd-search.php";
1021    var defaultTemplate = '<h6 class="search_title"><a target="_top" href="#{href}" class="search_link">#{title}</a></h6>' +
1022      '<p>...#{token}...</p>' +
1023      '<p class="match"><em>Terms matched: #{count} - URL: #{href}</em></p>';
1024    var defaultFilter = '*.html';
1025
1026    if (plugins.search.length) {
1027
1028      for (i = 0; i < plugins.search.length; i++) {
1029        var searchItem = $(plugins.search[i]),
1030          options = {
1031            element: searchItem,
1032            filter: (searchItem.attr('data-search-filter')) ? searchItem.attr('data-search-filter') : defaultFilter,
1033            template: (searchItem.attr('data-search-template')) ? searchItem.attr('data-search-template') : defaultTemplate,
1034            live: (searchItem.attr('data-search-live')) ? searchItem.attr('data-search-live') : false,
1035            liveCount: (searchItem.attr('data-search-live-count')) ? parseInt(searchItem.attr('data-search-live-count')) : 4,
1036            current: 0, processed: 0, timer: {}
1037          };
1038
1039        if ($('.rd-navbar-search-toggle').length) {
1040          var toggle = $('.rd-navbar-search-toggle');
1041          toggle.on('click', function () {
1042            if (!($(this).hasClass('active'))) {
1043              searchItem.find('input').val('').trigger('propertychange');
1044            }
1045          });
1046        }
1047
1048        if (options.live) {
1049          var clearHandler = false;
1050
1051          searchItem.find('input').on("keyup input propertychange", $.proxy(function () {
1052            this.term = this.element.find('input').val().trim();
1053            this.spin = this.element.find('.input-group-addon');
1054
1055            clearTimeout(this.timer);
1056
1057            if (this.term.length > 2) {
1058              this.timer = setTimeout(liveSearch(this), 200);
1059
1060              if (clearHandler == false) {
1061                clearHandler = true;
1062
1063                $("body").on("click", function (e) {
1064                  if ($(e.toElement).parents('.rd-search').length == 0) {
1065                    $('#rd-search-results-live').addClass('cleared').html('');
1066                  }
1067                })
1068              }
1069
1070            } else if (this.term.length == 0) {
1071              $('#' + this.live).addClass('cleared').html('');
1072            }
1073          }, options, this));
1074        }
1075
1076        searchItem.submit($.proxy(function () {
1077          $('<input />').attr('type', 'hidden')
1078            .attr('name', "filter")
1079            .attr('value', this.filter)
1080            .appendTo(this.element);
1081          return true;
1082        }, options, this))
1083      }
1084    }
1085
1086    if (plugins.searchResults.length) {
1087      var regExp = /\?.*s=([^&]+)\&filter=([^&]+)/g;
1088      var match = regExp.exec(location.search);
1089
1090      if (match != null) {
1091        $.get(handler, {
1092          s: decodeURI(match[1]),
1093          dataType: "html",
1094          filter: match[2],
1095          template: defaultTemplate,
1096          live: ''
1097        }, function (data) {
1098          plugins.searchResults.html(data);
1099        })
1100      }
1101    }
1102  }
1103
1104  /**
1105   * Slick carousel
1106   * @description  Enable Slick carousel plugin
1107   */
1108  if (plugins.slick.length) {
1109    var i;
1110    for (i = 0; i < plugins.slick.length; i++) {
1111      var $slickItem = $(plugins.slick[i]);
1112
1113      $slickItem.slick({
1114        slidesToScroll: parseInt($slickItem.attr('data-slide-to-scroll')) || 1,
1115        asNavFor: $slickItem.attr('data-for') || false,
1116        dots: $slickItem.attr("data-dots") == "true",
1117        infinite: isNoviBuilder ? false : $slickItem.attr("data-loop") == "true",
1118        focusOnSelect: true,
1119        arrows: $slickItem.attr("data-arrows") == "true",
1120        swipe: $slickItem.attr("data-swipe") == "true",
1121        autoplay: $slickItem.attr("data-autoplay") == "true",
1122        vertical: $slickItem.attr("data-vertical") == "true",
1123        centerMode: $slickItem.attr("data-center-mode") == "true",
1124        centerPadding: $slickItem.attr("data-center-padding") ? $slickItem.attr("data-center-padding") : '0.50',
1125        mobileFirst: true,
1126        responsive: [
1127          {
1128            breakpoint: 0,
1129            settings: {
1130              slidesToShow: parseInt($slickItem.attr('data-items')) || 1,
1131            }
1132          },
1133          {
1134            breakpoint: 479,
1135            settings: {
1136              slidesToShow: parseInt($slickItem.attr('data-xs-items')) || 1,
1137            }
1138          },
1139          {
1140            breakpoint: 767,
1141            settings: {
1142              slidesToShow: parseInt($slickItem.attr('data-sm-items')) || 1,
1143            }
1144          },
1145          {
1146            breakpoint: 991,
1147            settings: {
1148              slidesToShow: parseInt($slickItem.attr('data-md-items')) || 1,
1149            }
1150          },
1151          {
1152            breakpoint: 1199,
1153            settings: {
1154              slidesToShow: parseInt($slickItem.attr('data-lg-items')) || 1,
1155            }
1156          }
1157        ]
1158      })
1159        .on('afterChange', function (event, slick, currentSlide, nextSlide) {
1160          var $this = $(this),
1161            childCarousel = $this.attr('data-child');
1162
1163          if (childCarousel) {
1164            $(childCarousel + ' .slick-slide').removeClass('slick-current');
1165            $(childCarousel + ' .slick-slide').eq(currentSlide).addClass('slick-current');
1166          }
1167        });
1168    }
1169  }
1170
1171  /**
1172   * Owl carousel
1173   * @description Enables Owl carousel plugin
1174   */
1175  if (plugins.owl.length) {
1176    var i;
1177    for (i = 0; i < plugins.owl.length; i++) {
1178      var c = $(plugins.owl[i]),
1179        responsive = {};
1180
1181      var aliaces = ["-", "-xs-", "-sm-", "-md-", "-lg-"],
1182        values = [0, 480, 768, 992, 1200],
1183        j, k;
1184
1185      for (j = 0; j < values.length; j++) {
1186        responsive[values[j]] = {};
1187        for (k = j; k >= -1; k--) {
1188          if (!responsive[values[j]]["items"] && c.attr("data" + aliaces[k] + "items")) {
1189            responsive[values[j]]["items"] = k < 0 ? 1 : parseInt(c.attr("data" + aliaces[k] + "items"));
1190          }
1191          if (!responsive[values[j]]["stagePadding"] && responsive[values[j]]["stagePadding"] !== 0 && c.attr("data" + aliaces[k] + "stage-padding")) {
1192            responsive[values[j]]["stagePadding"] = k < 0 ? 0 : parseInt(c.attr("data" + aliaces[k] + "stage-padding"));
1193          }
1194          if (!responsive[values[j]]["margin"] && responsive[values[j]]["margin"] !== 0 && c.attr("data" + aliaces[k] + "margin")) {
1195            responsive[values[j]]["margin"] = k < 0 ? 30 : parseInt(c.attr("data" + aliaces[k] + "margin"));
1196          }
1197        }
1198      }
1199
1200      // Create custom Pagination
1201      if (c.attr('data-dots-custom')) {
1202        c.on("initialized.owl.carousel", function (event) {
1203          var carousel = $(event.currentTarget),
1204            customPag = $(carousel.attr("data-dots-custom")),
1205            active = 0;
1206
1207          if (carousel.attr('data-active')) {
1208            active = parseInt(carousel.attr('data-active'));
1209          }
1210
1211          carousel.trigger('to.owl.carousel', [active, 300, true]);
1212          customPag.find("[data-owl-item='" + active + "']").addClass("active");
1213
1214          customPag.find("[data-owl-item]").on('click', function (e) {
1215            e.preventDefault();
1216            carousel.trigger('to.owl.carousel', [parseInt(this.getAttribute("data-owl-item")), 300, true]);
1217          });
1218
1219          carousel.on("translate.owl.carousel", function (event) {
1220            customPag.find(".active").removeClass("active");
1221            customPag.find("[data-owl-item='" + event.item.index + "']").addClass("active")
1222          });
1223        });
1224      }
1225
1226      // Create custom Numbering
1227      if (typeof(c.attr("data-numbering")) !== 'undefined') {
1228        var numberingObject = $(c.attr("data-numbering"));
1229
1230        c.on('initialized.owl.carousel changed.owl.carousel', function (numberingObject) {
1231          return function (e) {
1232            if (!e.namespace) return;
1233            numberingObject.find('.numbering-current').text(e.item.index + 1);
1234            numberingObject.find('.numbering-count').text(e.item.count);
1235          };
1236        }(numberingObject));
1237      }
1238
1239      c.owlCarousel({
1240        autoplay: c.attr("data-autoplay") === "true",
1241        loop: isNoviBuilder === "designMode" ? false : c.attr("data-loop") == 'true',
1242        items: 1,
1243        dotsContainer: c.attr("data-pagination-class") || false,
1244        navContainer: c.attr("data-navigation-class") || false, 
1245        mouseDrag: isNoviBuilder === "designMode" ? false : c.attr("data-mouse-drag") !== "false",
1246        nav: c.attr("data-nav") === "true",
1247        dots: c.attr("data-dots") === "true",
1248        dotsEach: c.attr("data-dots-each") ? parseInt(c.attr("data-dots-each")) : false,
1249        animateIn: c.attr('data-animation-in') ? c.attr('data-animation-in') : 'slide',
1250        animateOut: c.attr('data-animation-out') ? c.attr('data-animation-out') : false,
1251        responsive: responsive,
1252        navText: []
1253      });
1254    }
1255  }
1256
1257  /**
1258   * jQuery Count To
1259   * @description Enables Count To plugin
1260   */
1261  if (plugins.counter.length) {
1262    var i;
1263
1264    for (i = 0; i < plugins.counter.length; i++) {
1265      var $counterNotAnimated = $(plugins.counter[i]).not('.animated');
1266      $document
1267        .on("scroll", $.proxy(function() {
1268          var $this = this;
1269
1270          if ((!$this.hasClass("animated")) && (isScrolledIntoView($this))) {
1271            $this.countTo({
1272              refreshInterval: 40,
1273              from: 0,
1274              to: parseInt($this.text(),10),
1275              speed: $this.attr("data-speed") || 1000,
1276              formatter: function(value, options) {
1277                value = value.toFixed(options.decimals);
1278                if (value < 10) {
1279                  return '0' + value;
1280                }
1281                return value;
1282              }
1283            });
1284            $this.addClass('animated');
1285          }
1286        }, $counterNotAnimated))
1287        .trigger("scroll");
1288    }
1289  }
1290
1291  /**
1292   * Isotope
1293   * @description Enables Isotope plugin
1294   */
1295  if (plugins.isotope.length) {
1296    var i, j, isogroup = [];
1297    for (i = 0; i < plugins.isotope.length; i++) {
1298      var isotopeItem = plugins.isotope[i],
1299        filterItems = $(isotopeItem).closest('.isotope-wrap').find('[data-isotope-filter]'),
1300        iso;
1301
1302      iso = new Isotope(isotopeItem, {
1303        itemSelector: '.isotope-item',
1304        layoutMode: isotopeItem.getAttribute('data-isotope-layout') ? isotopeItem.getAttribute('data-isotope-layout') : 'masonry',
1305        filter: '*',
1306        masonry: {
1307          columnWidth: 0.42
1308        }
1309      });
1310
1311      isogroup.push(iso);
1312
1313      filterItems.on("click", function (e) {
1314        e.preventDefault();
1315        var filter = $(this),
1316          iso = $('.isotope[data-isotope-group="' + this.getAttribute("data-isotope-group") + '"]'),
1317          filtersContainer = filter.closest(".isotope-filters");
1318
1319        filtersContainer
1320          .find('.active')
1321          .removeClass("active");
1322        filter.addClass("active");
1323
1324        iso.isotope({
1325          itemSelector: '.isotope-item',
1326          layoutMode: iso.attr('data-isotope-layout') ? iso.attr('data-isotope-layout') : 'masonry',
1327          filter: this.getAttribute("data-isotope-filter") == '*' ? '*' : '[data-filter*="' + this.getAttribute("data-isotope-filter") + '"]',
1328          masonry: {
1329            columnWidth: 0.42
1330          }
1331        });
1332
1333        $window.trigger('resize');
1334
1335      }).eq(0).trigger("click");
1336    }
1337
1338    $(window).on('load', function () {
1339      setTimeout(function () {
1340        var i;
1341        for (i = 0; i < isogroup.length; i++) {
1342          isogroup[i].element.className += " isotope--loaded";
1343          isogroup[i].layout();
1344        }
1345      }, 600);
1346    });
1347  }
1348
1349  /**
1350   * WOW
1351   * @description Enables Wow animation plugin
1352   */
1353  if (!isNoviBuilder) {
1354    if (isDesktop && $html.hasClass("wow-animation") && $(".wow").length) {
1355      new WOW().init();
1356    }
1357  }
1358
1359  /**
1360   * Bootstrap tabs
1361   * @description Activate Bootstrap Tabs
1362   */
1363  if (plugins.bootstrapTabs.length) {
1364    var i;
1365    for (i = 0; i < plugins.bootstrapTabs.length; i++) {
1366      var bootstrapTabsItem = $(plugins.bootstrapTabs[i]);
1367
1368      bootstrapTabsItem.on("click", "a", function (event) {
1369        event.preventDefault();
1370        $(this).tab('show');
1371      });
1372    }
1373  }
1374
1375  /**
1376   * RD Input Label
1377   * @description Enables RD Input Label Plugin
1378   */
1379  if (plugins.rdInputLabel.length) {
1380    plugins.rdInputLabel.RDInputLabel();
1381  }
1382
1383  /**
1384   * Regula
1385   * @description Enables Regula plugin
1386   */
1387  if (plugins.regula.length) {
1388    attachFormValidator(plugins.regula);
1389  }
1390
1391  /**
1392   * RD Mailform
1393   */
1394
1395  if (plugins.rdMailForm.length) {
1396    var i, j, k,
1397      msg = {
1398        'MF000': 'Successfully sent!',
1399        'MF001': 'Recipients are not set!',
1400        'MF002': 'Form will not work locally!',
1401        'MF003': 'Please, define email field in your form!',
1402        'MF004': 'Please, define type of your form!',
1403        'MF254': 'Something went wrong with PHPMailer!',
1404        'MF255': 'Aw, snap! Something went wrong.'
1405      };
1406    for (i = 0; i < plugins.rdMailForm.length; i++) {
1407      var $form = $(plugins.rdMailForm[i]);
1408
1409      $form.attr('novalidate', 'novalidate').ajaxForm({
1410        data: {
1411          "form-type": $form.attr("data-form-type") || "contact",
1412          "counter": i
1413        },
1414        beforeSubmit: function () {
1415          if (!isNoviBuilder){
1416            var form = $(plugins.rdMailForm[this.extraData.counter]);
1417            var inputs = form.find("[data-constraints]");
1418            if (isValidated(inputs)){
1419              var output = $("#" + form.attr("data-form-output"));
1420
1421              if (output.hasClass("snackbars")) {
1422                output.html('<p><span class="icon text-middle fa fa-circle-o-notch fa-spin icon-xs"></span><span>Sending</span></p>');
1423                output.addClass("active");
1424              }
1425            } else{
1426              return false;
1427            }
1428          }
1429
1430        },
1431        error: function (result) {
1432          if (!isNoviBuilder){
1433            var output = $("#" + $(plugins.rdMailForm[this.extraData.counter]).attr("data-form-output"));
1434            output.text(msg[result]);
1435          }
1436
1437        },
1438        success: function (result) {
1439          if (!isNoviBuilder){
1440            var form = $(plugins.rdMailForm[this.extraData.counter]);
1441            var output = $("#" + form.attr("data-form-output"));
1442            form.addClass('success');
1443            result = result.length == 5 ? result : 'MF255';
1444            output.text(msg[result]);
1445            if (result === "MF000") {
1446              if (output.hasClass("snackbars")) {
1447                output.html('<p><span class="icon text-middle fa-check icon-xs"></span><span>' + msg[result] + '</span></p>');
1448              } else {
1449                output.addClass("success");
1450                output.addClass("active");
1451              }
1452            } else {
1453              if (output.hasClass("snackbars")) {
1454                output.html(' <p class="snackbars-left"><span class="icon icon-xs fa-warning text-middle"></span><span>' + msg[result] + '</span></p>');
1455              } else {
1456                output.addClass("error");
1457                output.addClass("active");
1458              }
1459            }
1460            form.clearForm();
1461            form.find('input, textarea').blur();
1462
1463            setTimeout(function () {
1464              output.removeClass("active");
1465              form.removeClass('success');
1466            }, 5000);
1467          }
1468        }
1469      });
1470    }
1471  }
1472
1473  /**
1474   * PhotoSwipe Gallery
1475   * @description Enables PhotoSwipe Gallery plugin
1476   */
1477  if (plugins.photoSwipeGallery.length && !isNoviBuilder) {
1478
1479    // init image click event
1480    $document.delegate("[data-photo-swipe-item]", "click", function (event) {
1481      event.preventDefault();
1482
1483      var $el = $(this),
1484        $galleryItems = $el.parents("[data-photo-swipe-gallery]").find("a[data-photo-swipe-item]"),
1485        pswpElement = document.querySelectorAll('.pswp')[0],
1486        encounteredItems = {},
1487        pswpItems = [],
1488        options,
1489        pswpIndex = 0,
1490        pswp;
1491
1492      if ($galleryItems.length == 0) {
1493        $galleryItems = $el;
1494      }
1495
1496      // loop over the gallery to build up the photoswipe items
1497      $galleryItems.each(function () {
1498        var $item = $(this),
1499          src = $item.attr('href'),
1500          size = $item.attr('data-size').split('x'),
1501          pswdItem;
1502
1503        if ($item.is(':visible')) {
1504
1505          // if we have this image the first time
1506          if (!encounteredItems[src]) {
1507            // build the photoswipe item
1508            pswdItem = {
1509              src: src,
1510              w: parseInt(size[0], 10),
1511              h: parseInt(size[1], 10),
1512              el: $item // save link to element for getThumbBoundsFn
1513            };
1514
1515            // store that we already had this item
1516            encounteredItems[src] = {
1517              item: pswdItem,
1518              index: pswpIndex
1519            };
1520
1521            // push the item to the photoswipe list
1522            pswpItems.push(pswdItem);
1523            pswpIndex++;
1524          }
1525        }
1526      });
1527
1528      options = {
1529        index: encounteredItems[$el.attr('href')].index,
1530
1531        getThumbBoundsFn: function (index) {
1532          var $el = pswpItems[index].el,
1533            offset = $el.offset();
1534
1535          return {
1536            x: offset.left,
1537            y: offset.top,
1538            w: $el.width()
1539          };
1540        }
1541      };
1542
1543      // open the photoswipe gallery
1544      pswp = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, pswpItems, options);
1545      pswp.init();
1546    });
1547  }
1548
1549  /**
1550   * Custom Toggles
1551   */
1552  if (plugins.customToggle.length) {
1553    var i;
1554
1555    for (i = 0; i < plugins.customToggle.length; i++) {
1556      var $this = $(plugins.customToggle[i]);
1557
1558      $this.on('click', $.proxy(function (event) {
1559        event.preventDefault();
1560        var $ctx = $(this);
1561        $($ctx.attr('data-custom-toggle')).add(this).toggleClass('active');
1562      }, $this));
1563
1564      if ($this.attr("data-custom-toggle-hide-on-blur") === "true") {
1565        $("body").on("click", $this, function (e) {
1566          if (e.target !== e.data[0]
1567            && $(e.data.attr('data-custom-toggle')).find($(e.target)).length
1568            && e.data.find($(e.target)).length == 0) {
1569            $(e.data.attr('data-custom-toggle')).add(e.data[0]).removeClass('active');
1570          }
1571        })
1572      }
1573
1574      if ($this.attr("data-custom-toggle-disable-on-blur") === "true") {
1575        $("body").on("click", $this, function (e) {
1576          if (e.target !== e.data[0] && $(e.data.attr('data-custom-toggle')).find($(e.target)).length == 0 && e.data.find($(e.target)).length == 0) {
1577            $(e.data.attr('data-custom-toggle')).add(e.data[0]).removeClass('active');
1578          }
1579        })
1580      }
1581    }
1582  }
1583
1584  /**
1585   * Magnificent image zoom
1586   */
1587  if (plugins.imgZoom.length) {
1588    var i;
1589    for (i = 0; i < plugins.imgZoom.length; i++) {
1590      var $imgZoomItem = $(plugins.imgZoom[i]);
1591      $imgZoomItem.mag();
1592    }
1593  }
1594
1595  /**
1596   * Custom Waypoints
1597   */
1598  if (isNoviBuilder !== "designMode") {
1599    if (plugins.customWaypoints.length) {
1600      var i;
1601      for (i = 0; i < plugins.customWaypoints.length; i++) {
1602        var $this = $(plugins.customWaypoints[i]);
1603
1604        $this.on('click', function(e) {
1605          e.preventDefault();
1606          $("body, html").stop().animate({
1607            scrollTop: $("#" + $(this).attr('data-custom-scroll-to')).offset().top
1608          }, 1000, function() {
1609            $(window).trigger("resize");
1610          });
1611        });
1612      }
1613    }
1614  }
1615
1616
1617  /**
1618   * RD Parallax
1619   * @description Enables RD Parallax plugin
1620   */
1621  if (isNoviBuilder !== "designMode") {
1622    if (plugins.rdParallax.length && !isMobile) {
1623      var i;
1624      $.RDParallax();
1625
1626      if (!isIE && !isMobile) {
1627        $(window).on("scroll", function() {
1628          for (i = 0; i < plugins.rdParallax.length; i++) {
1629            var parallax = $(plugins.rdParallax[i]);
1630            if (isScrolledIntoView(parallax)) {
1631              parallax.find(".rd-parallax-inner").css("position", "fixed");
1632            } else {
1633              parallax.find(".rd-parallax-inner").css("position", "absolute");
1634            }
1635          }
1636        });
1637      }
1638
1639      $("a[href='#']").on("click", function(event) {
1640        setTimeout(function() {
1641          $(window).trigger("resize");
1642        }, 300);
1643      });
1644    }
1645  }
1646
1647  /**
1648   * Page title
1649   * @description Enables page-title plugin
1650   */
1651  if (isNoviBuilder !== "designMode"){
1652    if (plugins.pageTitles) {
1653      var varCount = 10;
1654
1655      for (var i = 0; i < plugins.pageTitles.length; i++) {
1656        var pageTitle = $(plugins.pageTitles[i]);
1657
1658        var header = pageTitle.children()[0];
1659        var wrapper = $(document.createElement('div'));
1660        wrapper.addClass('page-title-inner');
1661
1662        var pageTitleLeft = $(document.createElement('div')),
1663          pageTitleCenter = $(document.createElement('div')),
1664          pageTitleRight = $(document.createElement('div'));
1665
1666        pageTitleLeft.addClass('page-title-left');
1667        pageTitleCenter.addClass('page-title-center');
1668        pageTitleRight.addClass('page-title-right');
1669
1670        for (var j = 0; j < varCount; j++) {
1671          pageTitleLeft.append(header.cloneNode(true));
1672          pageTitleRight.append(header.cloneNode(true));
1673        }
1674
1675        pageTitleCenter.append(header.cloneNode(true));
1676        pageTitle.children(0).remove();
1677
1678        wrapper.append(pageTitleLeft);
1679        wrapper.append(pageTitleCenter);
1680        wrapper.append(pageTitleRight);
1681
1682        pageTitle.append(wrapper);
1683      }
1684    }
1685  }
1686});
1687
1688
1689
1690
1691// TYPO3 13: WS Flexslider – sofortige manuelle Navigation
1692(function () {
1693  'use strict';
1694
1695  var lastTouchTarget = null;
1696  var lastTouchTime = 0;
1697
1698  function navigateImmediately(event) {
1699    var link = event.target && event.target.closest
1700      ? event.target.closest('.tx-ws-flexslider .flex-direction-nav a.flex-prev, .tx-ws-flexslider .flex-direction-nav a.flex-next')
1701      : null;
1702
1703    if (!link) {
1704      return;
1705    }
1706
1707    if (event.type === 'click' && lastTouchTarget === link && performance.now() - lastTouchTime < 700) {
1708      event.preventDefault();
1709      event.stopImmediatePropagation();
1710      event.stopPropagation();
1711      return;
1712    }
1713
1714    event.preventDefault();
1715    event.stopImmediatePropagation();
1716    event.stopPropagation();
1717
1718    if (event.type === 'touchend') {
1719      lastTouchTarget = link;
1720      lastTouchTime = performance.now();
1721    }
1722
1723    var element = link.closest('.tx-ws-flexslider .flexslider');
1724    var slider = window.jQuery && element ? window.jQuery(element).data('flexslider') : null;
1725
1726    if (!slider) {
1727      return;
1728    }
1729
1730    if (slider.animating) {
1731      slider.slides.stop(true, false);
1732      slider.currentSlide = slider.animatingTo;
1733      slider.animating = false;
1734      slider.slides.css({ opacity: 0, zIndex: 1 })
1735        .eq(slider.currentSlide).css({ opacity: 1, zIndex: 2 });
1736    }
1737
1738    var animationSpeed = slider.vars.animationSpeed;
1739    slider.vars.animationSpeed = 0;
1740
1741    try {
1742      var direction = link.classList.contains('flex-next') ? 'next' : 'prev';
1743      slider.flexAnimate(slider.getTarget(direction), slider.vars.pauseOnAction, true);
1744      slider.slides.stop(true, true);
1745    } finally {
1746      slider.vars.animationSpeed = animationSpeed;
1747    }
1748  }
1749
1750  document.addEventListener('click', navigateImmediately, true);
1751  document.addEventListener('touchend', navigateImmediately, true);
1752}());
1753/* Burger-Drawer: vorhandenen .active-Zustand für Backdrop und Scroll-Sperre nutzen */
1754(function () {
1755  if (window.rdDrawerBackdropInitialized) { return; }
1756  window.rdDrawerBackdropInitialized = true;
1757  function initializeDrawerBackdrop() {
1758    var drawer = document.querySelector('.rd-navbar-nav-wrap');
1759    var toggle = document.querySelector('.rd-navbar-toggle[data-custom-toggle=".rd-navbar-nav-wrap"]');
1760    if (!drawer || !toggle) { return; }
1761    var backdrop = document.createElement('div');
1762    backdrop.className = 'rd-drawer-backdrop';
1763    backdrop.setAttribute('aria-hidden', 'true');
1764    backdrop.addEventListener('click', function () { if (drawer.classList.contains('active')) { toggle.click(); } });
1765    function synchronizeDrawerState() {
1766      var isOpen = drawer.classList.contains('active');
1767      if (isOpen && window.rdDrawerOpenCurrentTrail) {
1768        window.rdDrawerOpenCurrentTrail();
1769      }
1770      document.body.classList.toggle('rd-drawer-is-open', isOpen);
1771      if (isOpen) { if (!backdrop.parentNode) { document.body.appendChild(backdrop); } }
1772      else if (backdrop.parentNode) { backdrop.parentNode.removeChild(backdrop); }
1773    }
1774    new MutationObserver(synchronizeDrawerState).observe(drawer, { attributes: true, attributeFilter: ['class'] });
1775    synchronizeDrawerState();
1776  }
1777  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeDrawerBackdrop); }
1778  else { initializeDrawerBackdrop(); }
1779}());
1780
1781/* Burger-Drawer: Scrollposition vor dem vorhandenen Toggle erfassen */
1782(function () {
1783  function initializeDrawerScrollLock() {
1784    if (window.rdDrawerScrollLockInitialized || !document.body) {
1785      return;
1786    }
1787    window.rdDrawerScrollLockInitialized = true;
1788
1789    var savedScrollY = 0;
1790    var isLocked = false;
1791
1792    document.addEventListener('click', function (event) {
1793      var target = event.target && event.target.closest ? event.target : null;
1794      var toggle = target
1795        ? target.closest('.rd-navbar-toggle[data-custom-toggle=".rd-navbar-nav-wrap"]')
1796        : null;
1797      var drawer = document.querySelector('.rd-navbar-nav-wrap');
1798
1799      if (toggle && drawer && !drawer.classList.contains('active')) {
1800        savedScrollY = window.scrollY;
1801      }
1802    }, true);
1803
1804    new MutationObserver(function () {
1805      var open = document.body.classList.contains('rd-drawer-is-open');
1806
1807      if (open && !isLocked) {
1808        document.body.style.top = (-savedScrollY) + 'px';
1809        isLocked = true;
1810      } else if (!open && isLocked) {
1811        document.body.style.top = '';
1812        var restoreScrollY = savedScrollY;
1813        isLocked = false;
1814        window.setTimeout(function () {
1815          window.scrollTo(0, restoreScrollY);
1816        }, 0);
1817      }
1818    }).observe(document.body, { attributes: true, attributeFilter: ['class'] });
1819  }
1820
1821  if (document.readyState === 'loading') {
1822    document.addEventListener('DOMContentLoaded', initializeDrawerScrollLock);
1823  } else {
1824    initializeDrawerScrollLock();
1825  }
1826}());
1827
1828/* Burger-Drawer: aktuellen sichtbaren Navigationspfad markieren und beim Oeffnen zeigen. */
1829(function () {
1830  function markCurrentDrawerLink() {
1831    var path = window.location.pathname.replace(/\/$/, '') || '/';
1832    var links = document.querySelectorAll('.rd-navbar-nav a[href]');
1833    var currentItem = null;
1834
1835    for (var i = 0; i < links.length; i++) {
1836      var href = links[i].getAttribute('href').replace(/\/$/, '') || '/';
1837      if (href === path) {
1838        currentItem = links[i].parentNode;
1839        currentItem.classList.add('rd-drawer-current');
1840        break;
1841      }
1842    }
1843
1844    if (!currentItem) {
1845      currentItem = document.querySelector('.rd-navbar-nav li.active');
1846
1847      if (!currentItem) {
1848        var activeLink = document.querySelector('.rd-navbar-nav a.active');
1849        if (activeLink) {
1850          currentItem = activeLink.closest('li');
1851          currentItem.classList.add('rd-drawer-current');
1852        }
1853      }
1854    }
1855    if (!currentItem) { return; }
1856
1857    var mainItem = currentItem;
1858    while (mainItem.parentNode && !mainItem.parentNode.classList.contains('rd-navbar-nav')) {
1859      mainItem = mainItem.parentNode.closest('li');
1860      if (!mainItem) { return; }
1861    }
1862
1863    if (currentItem !== mainItem) {
1864      var secondLevelItem = currentItem;
1865      while (secondLevelItem.parentNode && secondLevelItem.parentNode.parentNode !== mainItem) {
1866        secondLevelItem = secondLevelItem.parentNode.closest('li');
1867        if (!secondLevelItem) { return; }
1868      }
1869      secondLevelItem.classList.add('rd-drawer-current');
1870    }
1871
1872    window.rdDrawerOpenCurrentTrail = function () {
1873      if (mainItem.classList.contains('rd-navbar-submenu')) {
1874        mainItem.classList.add('opened');
1875      }
1876    };
1877
1878    var drawer = document.querySelector('.rd-navbar-nav-wrap');
1879    if (drawer && drawer.classList.contains('active')) {
1880      window.rdDrawerOpenCurrentTrail();
1881    }
1882  }
1883
1884  if (document.readyState === 'loading') {
1885    document.addEventListener('DOMContentLoaded', markCurrentDrawerLink);
1886  } else {
1887    markCurrentDrawerLink();
1888  }
1889}());

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.