1"use strict"; 2(function () { 3 // Global variables 4 var userAgent = navigator.userAgent.toLowerCase(), 5 initialDate = new Date(), 6 7 $document = $(document), 8 $window = $(window), 9 $html = $("html"), 10 $body = $("body"), 11 12 isDesktop = $html.hasClass("desktop"), 13 isRtl = $html.attr("dir") === "rtl", 14 isIE = userAgent.indexOf("msie") != -1 ? parseInt(userAgent.split("msie")[1], 10) : 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 onloadCaptchaCallback, 18 windowReady = false, 19 isNoviBuilder = false, 20 livedemo = true, 21 22 plugins = { 23 pointerEvents: isIE < 11 ? "js/pointer-events.min.js" : false, 24 bootstrapTooltip: $("[data-toggle='tooltip']"), 25 bootstrapModalDialog: $('.modal'), 26 bootstrapTabs: $(".tabs-custom"), 27 rdNavbar: $(".rd-navbar"), 28 rdMailForm: $(".rd-mailform"), 29 rdInputLabel: $(".form-label"), 30 regula: $("[data-constraints]"), 31 owl: $(".owl-carousel"), 32 swiper: $(".swiper-slider"), 33 search: $(".rd-search"), 34 searchResults: $('.rd-search-results'), 35 statefulButton: $('.btn-stateful'), 36 isotope: $(".isotope"), 37 popover: $('[data-toggle="popover"]'), 38 viewAnimate: $('.view-animate'), 39 radio: $("input[type='radio']"), 40 checkbox: $("input[type='checkbox']"), 41 customToggle: $("[data-custom-toggle]"), 42 facebookWidget: $('#fb-root'), 43 flickrfeed: $(".flickr"), 44 twitterfeed: $(".twitter"), 45 counter: $(".counter"), 46 progressLinear: $(".progress-linear"), 47 progressCircle: $(".progress-circle"), 48 dateCountdown: $('.DateCountdown'), 49 preloader: $(".page-loader"), 50 captcha: $('.recaptcha'), 51 scroller: $(".scroll-wrap"), 52 lightGallery: $( '[data-lightgallery="group"]' ), 53 lightGalleryItem: $( '[data-lightgallery="item"]' ), 54 lightDynamicGalleryItem: $( '[data-lightgallery="dynamic"]' ), 55 mailchimp: $('.mailchimp-mailform'), 56 campaignMonitor: $('.campaign-mailform'), 57 copyrightYear: $(".copyright-year"), 58 maps: $( '.google-map-container' ), 59 }; 60 61 /** 62 * @desc Check the element was been scrolled into the view 63 * @param {object} elem - jQuery object 64 * @return {boolean} 65 */ 66 function isScrolledIntoView ( elem ) { 67 if ( isNoviBuilder ) return true; 68 return elem.offset().top + elem.outerHeight() >= $window.scrollTop() && elem.offset().top <= $window.scrollTop() + $window.height(); 69 } 70 71 /** 72 * @desc Calls a function when element has been scrolled into the view 73 * @param {object} element - jQuery object 74 * @param {function} func - init function 75 */ 76 function lazyInit( element, func ) { 77 var scrollHandler = function () { 78 if ( ( !element.hasClass( 'lazy-loaded' ) && ( isScrolledIntoView( element ) ) ) ) { 79 func.call(); 80 element.addClass( 'lazy-loaded' ); 81 } 82 }; 83 84 scrollHandler(); 85 $window.on( 'scroll', scrollHandler ); 86 } 87 88 // Initialize scripts that require a loaded window 89 $window.on('load', function () { 90 // Page loader & Page transition 91 if (plugins.preloader.length && !isNoviBuilder) { 92 setTimeout(function () { 93 plugins.preloader.addClass("loaded"); 94 $window.trigger("resize"); 95 }, 1000); 96 } 97 }); 98 99// Initialize scripts that require a finished document 100 $(function () { 101 isNoviBuilder = window.xMode; 102 103 /** 104 * @desc Google map function for getting latitude and longitude 105 */ 106 function getLatLngObject(str, marker, map, callback) { 107 var coordinates = {}; 108 try { 109 coordinates = JSON.parse(str); 110 callback(new google.maps.LatLng( 111 coordinates.lat, 112 coordinates.lng 113 ), marker, map) 114 } catch (e) { 115 map.geocoder.geocode({'address': str}, function (results, status) { 116 if (status === google.maps.GeocoderStatus.OK) { 117 var latitude = results[0].geometry.location.lat(); 118 var longitude = results[0].geometry.location.lng(); 119 120 callback(new google.maps.LatLng( 121 parseFloat(latitude), 122 parseFloat(longitude) 123 ), marker, map) 124 } 125 }) 126 } 127 } 128 129 /** 130 * @desc Initialize Google maps 131 */ 132 function initMaps() { 133 var key; 134 135 for ( var i = 0; i < plugins.maps.length; i++ ) { 136 if ( plugins.maps[i].hasAttribute( "data-key" ) ) { 137 key = plugins.maps[i].getAttribute( "data-key" ); 138 break; 139 } 140 } 141 142 $.getScript('//maps.google.com/maps/api/js?'+ ( key ? 'key='+ key + '&' : '' ) +'sensor=false&libraries=geometry,places&v=quarterly', function () { 143 var head = document.getElementsByTagName('head')[0], 144 insertBefore = head.insertBefore; 145 146 head.insertBefore = function (newElement, referenceElement) { 147 if (newElement.href && newElement.href.indexOf('//fonts.googleapis.com/css?family=Roboto') !== -1 || newElement.innerHTML.indexOf('gm-style') !== -1) { 148 return; 149 } 150 insertBefore.call(head, newElement, referenceElement); 151 }; 152 var geocoder = new google.maps.Geocoder; 153 for (var i = 0; i < plugins.maps.length; i++) { 154 var zoom = parseInt(plugins.maps[i].getAttribute("data-zoom"), 10) || 11; 155 var styles = plugins.maps[i].hasAttribute('data-styles') ? JSON.parse(plugins.maps[i].getAttribute("data-styles")) : []; 156 var center = plugins.maps[i].getAttribute("data-center") || "New York"; 157 158 // Initialize map 159 var map = new google.maps.Map(plugins.maps[i].querySelectorAll(".google-map")[0], { 160 zoom: zoom, 161 styles: styles, 162 scrollwheel: false, 163 center: {lat: 0, lng: 0} 164 }); 165 166 // Add map object to map node 167 plugins.maps[i].map = map; 168 plugins.maps[i].geocoder = geocoder; 169 plugins.maps[i].keySupported = true; 170 plugins.maps[i].google = google; 171 172 // Get Center coordinates from attribute
173 getLatLngObject(center, null, plugins.maps[i], function (location, markerElement, mapElement) { 174 mapElement.map.setCenter(location); 175 }); 176 177 // Add markers from google-map-markers array 178 var markerItems = plugins.maps[i].querySelectorAll(".google-map-markers li"); 179 180 if (markerItems.length){ 181 var markers = []; 182 for (var j = 0; j < markerItems.length; j++){ 183 var markerElement = markerItems[j]; 184 getLatLngObject(markerElement.getAttribute("data-location"), markerElement, plugins.maps[i], function(location, markerElement, mapElement){ 185 var icon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon"); 186 var activeIcon = markerElement.getAttribute("data-icon-active") || mapElement.getAttribute("data-icon-active"); 187 var info = markerElement.getAttribute("data-description") || ""; 188 var infoWindow = new google.maps.InfoWindow({ 189 content: info 190 }); 191 markerElement.infoWindow = infoWindow; 192 var markerData = { 193 position: location, 194 map: mapElement.map 195 } 196 if (icon){ 197 markerData.icon = icon; 198 } 199 var marker = new google.maps.Marker(markerData); 200 markerElement.gmarker = marker; 201 markers.push({markerElement: markerElement, infoWindow: infoWindow}); 202 marker.isActive = false; 203 // Handle infoWindow close click 204 google.maps.event.addListener(infoWindow,'closeclick',(function(markerElement, mapElement){ 205 var markerIcon = null; 206 markerElement.gmarker.isActive = false; 207 markerIcon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon"); 208 markerElement.gmarker.setIcon(markerIcon); 209 }).bind(this, markerElement, mapElement)); 210 211 212 // Set marker active on Click and open infoWindow 213 google.maps.event.addListener(marker, 'click', (function(markerElement, mapElement) { 214 if (markerElement.infoWindow.getContent().length === 0) return; 215 var gMarker, currentMarker = markerElement.gmarker, currentInfoWindow; 216 for (var k =0; k < markers.length; k++){ 217 var markerIcon; 218 if (markers[k].markerElement === markerElement){ 219 currentInfoWindow = markers[k].infoWindow; 220 } 221 gMarker = markers[k].markerElement.gmarker; 222 if (gMarker.isActive && markers[k].markerElement !== markerElement){ 223 gMarker.isActive = false; 224 markerIcon = markers[k].markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon") 225 gMarker.setIcon(markerIcon); 226 markers[k].infoWindow.close(); 227 } 228 } 229 230 currentMarker.isActive = !currentMarker.isActive; 231 if (currentMarker.isActive) { 232 if (markerIcon = markerElement.getAttribute("data-icon-active") || mapElement.getAttribute("data-icon-active")){ 233 currentMarker.setIcon(markerIcon); 234 } 235 236 currentInfoWindow.open(map, marker); 237 }else{ 238 if (markerIcon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon")){ 239 currentMarker.setIcon(markerIcon); 240 } 241 currentInfoWindow.close(); 242 } 243 }).bind(this, markerElement, mapElement)) 244 }) 245 } 246 } 247 } 248 }); 249 } 250 251 /** 252 * getSwiperHeight 253 * @description calculate the height of swiper slider basing on data attr 254 */ 255 function getSwiperHeight(object, attr) { 256 var val = object.attr("data-" + attr), 257 dim; 258 259 if (!val) { 260 return undefined; 261 } 262 263 dim = val.match(/(px)|(%)|(vh)$/i); 264 265 if (dim.length) { 266 switch (dim[0]) { 267 case "px": 268 return parseFloat(val); 269 case "vh": 270 return $window.height() * (parseFloat(val) / 100); 271 case "%": 272 return object.width() * (parseFloat(val) / 100); 273 } 274 } else { 275 return undefined; 276 } 277 } 278 279 /** 280 * toggleSwiperInnerVideos 281 * @description toggle swiper videos on active slides 282 */ 283 function toggleSwiperInnerVideos(swiper) { 284 var prevSlide = $(swiper.slides[swiper.previousIndex]), 285 nextSlide = $(swiper.slides[swiper.activeIndex]), 286 videos, 287 videoItems = prevSlide.find("video"); 288 289 for (i = 0; i < videoItems.length; i++) { 290 videoItems[i].pause(); 291 } 292 293 videos = nextSlide.find("video"); 294 if (videos.length) { 295 videos.get(0).play(); 296 } 297 } 298 299 /** 300 * toggleSwiperCaptionAnimation 301 * @description toggle swiper animations on active slides 302 */ 303 function toggleSwiperCaptionAnimation(swiper) { 304 var prevSlide = $(swiper.container).find("[data-caption-animate]"), 305 nextSlide = $(swiper.slides[swiper.activeIndex]).find("[data-caption-animate]"), 306 delay, 307 duration, 308 nextSlideItem, 309 prevSlideItem; 310 311 for (i = 0; i < prevSlide.length; i++) { 312 prevSlideItem = $(prevSlide[i]); 313 314 prevSlideItem.removeClass("animated") 315 .removeClass(prevSlideItem.attr("data-caption-animate")) 316 .addClass("not-animated"); 317 } 318 319 for (i = 0; i < nextSlide.length; i++) { 320 nextSlideItem = $(nextSlide[i]);
321 delay = nextSlideItem.attr("data-caption-delay"); 322 duration = nextSlideItem.attr('data-caption-duration'); 323 324 var tempFunction = function (nextSlideItem, duration) { 325 return function () { 326 nextSlideItem 327 .removeClass("not-animated") 328 .addClass(nextSlideItem.attr("data-caption-animate")) 329 .addClass("animated"); 330 331 if (duration) { 332 nextSlideItem.css('animation-duration', duration + 'ms'); 333 } 334 }; 335 }; 336 337 setTimeout(tempFunction(nextSlideItem, duration), delay ? parseInt(delay, 10) : 0); 338 } 339 } 340 341 /** 342 * @desc Initialize owl carousel plugin 343 * @param {object} carousel - carousel jQuery object 344 */ 345 function initOwlCarousel ( carousel ) { 346 var 347 aliaces = [ '-', '-sm-', '-md-', '-lg-', '-xl-', '-xxl-' ], 348 values = [ 0, 576, 768, 992, 1200, 1600 ], 349 responsive = {}; 350 351 for ( var j = 0; j < values.length; j++ ) { 352 responsive[ values[ j ] ] = {}; 353 for ( var k = j; k >= -1; k-- ) { 354 if ( !responsive[ values[ j ] ][ 'items' ] && carousel.attr( 'data' + aliaces[ k ] + 'items' ) ) { 355 responsive[ values[ j ] ][ 'items' ] = k < 0 ? 1 : parseInt( carousel.attr( 'data' + aliaces[ k ] + 'items' ), 10 ); 356 } 357 if ( !responsive[ values[ j ] ][ 'stagePadding' ] && responsive[ values[ j ] ][ 'stagePadding' ] !== 0 && carousel.attr( 'data' + aliaces[ k ] + 'stage-padding' ) ) { 358 responsive[ values[ j ] ][ 'stagePadding' ] = k < 0 ? 0 : parseInt( carousel.attr( 'data' + aliaces[ k ] + 'stage-padding' ), 10 ); 359 } 360 if ( !responsive[ values[ j ] ][ 'margin' ] && responsive[ values[ j ] ][ 'margin' ] !== 0 && carousel.attr( 'data' + aliaces[ k ] + 'margin' ) ) { 361 responsive[ values[ j ] ][ 'margin' ] = k < 0 ? 30 : parseInt( carousel.attr( 'data' + aliaces[ k ] + 'margin' ), 10 ); 362 } 363 } 364 } 365 366 // Enable custom pagination 367 if ( carousel.attr( 'data-dots-custom' ) ) { 368 carousel.on( 'initialized.owl.carousel', function ( event ) { 369 var 370 carousel = $( event.currentTarget ), 371 customPag = $( carousel.attr( 'data-dots-custom' ) ), 372 active = 0; 373 374 if ( carousel.attr( 'data-active' ) ) { 375 active = parseInt( carousel.attr( 'data-active' ), 10 ); 376 } 377 378 carousel.trigger( 'to.owl.carousel', [ active, 300, true ] ); 379 customPag.find( '[data-owl-item="' + active + '"]' ).addClass( 'active' ); 380 381 customPag.find( '[data-owl-item]' ).on( 'click', function ( event ) { 382 event.preventDefault(); 383 carousel.trigger( 'to.owl.carousel', [ parseInt( this.getAttribute( 'data-owl-item' ), 10 ), 300, true ] ); 384 } ); 385 386 carousel.on( 'translate.owl.carousel', function ( event ) { 387 customPag.find( '.active' ).removeClass( 'active' ); 388 customPag.find( '[data-owl-item="' + event.item.index + '"]' ).addClass( 'active' ) 389 } ); 390 } ); 391 } 392 393 // Initialize lightgallery items in cloned owl items 394 carousel.on( 'initialized.owl.carousel', function () { 395 initLightGalleryItem( carousel.find( '[data-lightgallery="item"]' ), 'lightGallery-in-carousel' ); 396 } ); 397 398 carousel.owlCarousel( { 399 autoplay: isNoviBuilder ? false : carousel.attr( 'data-autoplay' ) !== 'false', 400 autoplayTimeout: carousel.attr( "data-autoplay" ) ? Number( carousel.attr( "data-autoplay" ) ) : 3000, 401 autoplayHoverPause: true, 402 loop: isNoviBuilder ? false : carousel.attr( 'data-loop' ) !== 'false', 403 items: 1, 404 center: carousel.attr( 'data-center' ) === 'true', 405 dotsContainer: carousel.attr( 'data-pagination-class' ) || false, 406 navContainer: carousel.attr( 'data-navigation-class' ) || false, 407 mouseDrag: isNoviBuilder ? false : carousel.attr( 'data-mouse-drag' ) !== 'false', 408 nav: carousel.attr( 'data-nav' ) === 'true', 409 dots: carousel.attr( 'data-dots' ) === 'true', 410 dotsEach: carousel.attr( 'data-dots-each' ) ? parseInt( carousel.attr( 'data-dots-each' ), 10 ) : false, 411 animateIn: carousel.attr( 'data-animation-in' ) ? carousel.attr( 'data-animation-in' ) : false, 412 animateOut: carousel.attr( 'data-animation-out' ) ? carousel.attr( 'data-animation-out' ) : false, 413 responsive: responsive, 414 navText: carousel.attr( 'data-nav-text' ) ? $.parseJSON( carousel.attr( 'data-nav-text' ) ) : [], 415 navClass: carousel.attr( 'data-nav-class' ) ? $.parseJSON( carousel.attr( 'data-nav-class' ) ) : [ 'owl-prev', 'owl-next' ] 416 } ); 417 } 418 419 /** 420 * isScrolledIntoView 421 * @description check the element whas been scrolled into the view 422 */ 423 function isScrolledIntoView(elem) { 424 if (!isNoviBuilder) { 425 return elem.offset().top + elem.outerHeight() >= $window.scrollTop() && elem.offset().top <= $window.scrollTop() + $window.height(); 426 } else { 427 return true; 428 } 429 } 430 431 /** 432 * initOnView 433 * @description calls a function when element has been scrolled into the view 434 */ 435 function lazyInit(element, func) { 436 var $win = jQuery(window); 437 $win.on('load scroll', function () { 438 if ((!element.hasClass('lazy-loaded') && (isScrolledIntoView(element)))) { 439 func.call(); 440 element.addClass('lazy-loaded'); 441 } 442 }); 443 } 444 445 /** 446 * @desc Create live search results 447 * @param {object} options 448 */ 449 function liveSearch(options) { 450 $('#' + options.live).removeClass('cleared').html(); 451 options.current++; 452 options.spin.addClass('loading'); 453 $.get(handler, {
454 s: decodeURI(options.term), 455 liveSearch: options.live, 456 dataType: "html", 457 liveCount: options.liveCount, 458 filter: options.filter, 459 template: options.template 460 }, function (data) { 461 options.processed++; 462 var live = $('#' + options.live); 463 if ((options.processed === options.current) && !live.hasClass('cleared')) { 464 live.find('> #search-results').removeClass('active'); 465 live.html(data); 466 setTimeout(function () { 467 live.find('> #search-results').addClass('active'); 468 }, 50); 469 } 470 options.spin.parents('.rd-search').find('.input-group-addon').removeClass('loading'); 471 }) 472 } 473 474 /** 475 * @desc Initialize Bootstrap tooltip with required placement 476 * @param {string} tooltipPlacement 477 */ 478 function initBootstrapTooltip(tooltipPlacement) { 479 plugins.bootstrapTooltip.tooltip('dispose'); 480 481 if (window.innerWidth < 576) { 482 plugins.bootstrapTooltip.tooltip({placement: 'bottom'}); 483 } else { 484 plugins.bootstrapTooltip.tooltip({placement: tooltipPlacement}); 485 } 486 } 487 488 /** 489 * @desc Initialize the gallery with set of images 490 * @param {object} itemsToInit - jQuery object 491 * @param {string} [addClass] - additional gallery class 492 */ 493 function initLightGallery ( itemsToInit, addClass ) { 494 if ( !isNoviBuilder ) { 495 $( itemsToInit ).lightGallery( { 496 thumbnail: $( itemsToInit ).attr( "data-lg-thumbnail" ) !== "false", 497 selector: "[data-lightgallery='item']", 498 autoplay: $( itemsToInit ).attr( "data-lg-autoplay" ) === "true", 499 pause: parseInt( $( itemsToInit ).attr( "data-lg-autoplay-delay" ) ) || 5000, 500 addClass: addClass, 501 mode: $( itemsToInit ).attr( "data-lg-animation" ) || "lg-slide", 502 loop: $( itemsToInit ).attr( "data-lg-loop" ) !== "false" 503 } ); 504 } 505 } 506 507 /** 508 * @desc Initialize the gallery with dynamic addition of images 509 * @param {object} itemsToInit - jQuery object 510 * @param {string} [addClass] - additional gallery class 511 */ 512 function initDynamicLightGallery ( itemsToInit, addClass ) { 513 if ( !isNoviBuilder ) { 514 $( itemsToInit ).on( "click", function () { 515 $( itemsToInit ).lightGallery( { 516 thumbnail: $( itemsToInit ).attr( "data-lg-thumbnail" ) !== "false", 517 selector: "[data-lightgallery='item']", 518 autoplay: $( itemsToInit ).attr( "data-lg-autoplay" ) === "true", 519 pause: parseInt( $( itemsToInit ).attr( "data-lg-autoplay-delay" ) ) || 5000, 520 addClass: addClass, 521 mode: $( itemsToInit ).attr( "data-lg-animation" ) || "lg-slide", 522 loop: $( itemsToInit ).attr( "data-lg-loop" ) !== "false", 523 dynamic: true, 524 dynamicEl: JSON.parse( $( itemsToInit ).attr( "data-lg-dynamic-elements" ) ) || [] 525 } ); 526 } ); 527 } 528 } 529 530 /** 531 * @desc Initialize the gallery with one image 532 * @param {object} itemToInit - jQuery object 533 * @param {string} [addClass] - additional gallery class 534 */ 535 function initLightGalleryItem ( itemToInit, addClass ) { 536 if ( !isNoviBuilder ) { 537 $( itemToInit ).lightGallery( { 538 selector: "this", 539 addClass: addClass, 540 counter: false, 541 youtubePlayerParams: { 542 modestbranding: 1, 543 showinfo: 0, 544 rel: 0, 545 controls: 0 546 }, 547 vimeoPlayerParams: { 548 byline: 0, 549 portrait: 0 550 } 551 } ); 552 } 553 } 554 555 /** 556 * @desc Attach form validation to elements 557 * @param {object} elements - jQuery object 558 */ 559 function attachFormValidator(elements) { 560 // Custom validator - phone number 561 regula.custom({ 562 name: 'PhoneNumber', 563 defaultMessage: 'Invalid phone number format', 564 validator: function() { 565 if ( this.value === '' ) return true; 566 else return /^(\+\d)?[0-9\-\(\) ]{5,}$/i.test( this.value ); 567 } 568 }); 569 570 for (var i = 0; i < elements.length; i++) { 571 var o = $(elements[i]), v; 572 o.addClass("form-control-has-validation").after("<span class='form-validation'></span>"); 573 v = o.parent().find(".form-validation"); 574 if (v.is(":last-child")) o.addClass("form-control-last-child"); 575 } 576 577 elements.on('input change propertychange blur', function (e) { 578 var $this = $(this), results; 579 580 if (e.type !== "blur") if (!$this.parent().hasClass("has-error")) return; 581 if ($this.parents('.rd-mailform').hasClass('success')) return; 582 583 if (( results = $this.regula('validate') ).length) { 584 for (i = 0; i < results.length; i++) { 585 $this.siblings(".form-validation").text(results[i].message).parent().addClass("has-error"); 586 } 587 } else { 588 $this.siblings(".form-validation").text("").parent().removeClass("has-error") 589 } 590 }).regula('bind'); 591 592 var regularConstraintsMessages = [ 593 { 594 type: regula.Constraint.Required, 595 newMessage: "The text field is required." 596 }, 597 { 598 type: regula.Constraint.Email, 599 newMessage: "The email is not a valid email." 600 }, 601 { 602 type: regula.Constraint.Numeric, 603 newMessage: "Only numbers are required" 604 }, 605 { 606 type: regula.Constraint.Selected, 607 newMessage: "Please choose an option." 608 } 609 ]; 610 611 612 for (var i = 0; i < regularConstraintsMessages.length; i++) { 613 var regularConstraint = regularConstraintsMessages[i]; 614 615 regula.override({ 616 constraintType: regularConstraint.type, 617 defaultMessage: regularConstraint.newMessage 618 }); 619 } 620 } 621 622 /** 623 * @desc Check if all elements pass validation 624 * @param {object} elements - object of items for validation 625 * @param {object} captcha - captcha object for validation 626 * @return {boolean} 627 */ 628 function isValidated(elements, captcha) { 629 var results, errors = 0; 630 631 if (elements.length) { 632 for (var j = 0; j < elements.length; j++) { 633 634 var $input = $(elements[j]); 635 if ((results = $input.regula('validate')).length) { 636 for (k = 0; k < results.length; k++) { 637 errors++; 638 $input.siblings(".form-validation").text(results[k].message).parent().addClass("has-error"); 639 } 640 } else { 641 $input.siblings(".form-validation").text("").parent().removeClass("has-error") 642 } 643 } 644 645 if (captcha) { 646 if (captcha.length) { 647 return validateReCaptcha(captcha) && errors === 0 648 } 649 } 650 651 return errors === 0; 652 } 653 return true; 654 } 655 656 /** 657 * @desc Validate google reCaptcha 658 * @param {object} captcha - captcha object for validation 659 * @return {boolean} 660 */ 661 function validateReCaptcha(captcha) { 662 var captchaToken = captcha.find('.g-recaptcha-response').val(); 663 664 if (captchaToken.length === 0) { 665 captcha 666 .siblings('.form-validation') 667 .html('Please, prove that you are not robot.') 668 .addClass('active'); 669 captcha 670 .closest('.form-wrap') 671 .addClass('has-error'); 672
673 captcha.on('propertychange', function () { 674 var $this = $(this), 675 captchaToken = $this.find('.g-recaptcha-response').val(); 676 677 if (captchaToken.length > 0) { 678 $this 679 .closest('.form-wrap') 680 .removeClass('has-error'); 681 $this 682 .siblings('.form-validation') 683 .removeClass('active') 684 .html(''); 685 $this.off('propertychange'); 686 } 687 }); 688 689 return false; 690 } 691 692 return true; 693 } 694 695 /** 696 * @desc Initialize Google reCaptcha 697 */ 698 window.onloadCaptchaCallback = function () { 699 for (var i = 0; i < plugins.captcha.length; i++) { 700 var 701 $captcha = $(plugins.captcha[i]), 702 resizeHandler = (function() { 703 var 704 frame = this.querySelector( 'iframe' ), 705 inner = this.firstElementChild, 706 inner2 = inner.firstElementChild, 707 containerRect = null, 708 frameRect = null, 709 scale = null; 710 711 inner2.style.transform = ''; 712 inner.style.height = 'auto'; 713 inner.style.width = 'auto'; 714 715 containerRect = this.getBoundingClientRect(); 716 frameRect = frame.getBoundingClientRect(); 717 scale = containerRect.width/frameRect.width; 718 719 if ( scale < 1 ) { 720 inner2.style.transform = 'scale('+ scale +')'; 721 inner.style.height = ( frameRect.height * scale ) + 'px'; 722 inner.style.width = ( frameRect.width * scale ) + 'px'; 723 } 724 }).bind( plugins.captcha[i] ); 725 726 grecaptcha.render( 727 $captcha.attr('id'), 728 { 729 sitekey: $captcha.attr('data-sitekey'), 730 size: $captcha.attr('data-size') ? $captcha.attr('data-size') : 'normal', 731 theme: $captcha.attr('data-theme') ? $captcha.attr('data-theme') : 'light', 732 callback: function () { 733 $('.recaptcha').trigger('propertychange'); 734 } 735 } 736 ); 737 738 $captcha.after("<span class='form-validation'></span>"); 739 740 if ( plugins.captcha[i].hasAttribute( 'data-auto-size' ) ) { 741 resizeHandler(); 742 window.addEventListener( 'resize', resizeHandler ); 743 } 744 } 745 }; 746 747 /** 748 * Copyright Year 749 * @description Evaluates correct copyright year 750 */ 751 if (plugins.copyrightYear.length) { 752 plugins.copyrightYear.text(initialDate.getFullYear()); 753 } 754 755 /** 756 * Google ReCaptcha 757 * @description Enables Google ReCaptcha 758 */ 759 if (plugins.captcha.length) { 760 $.getScript("//www.google.com/recaptcha/api.js?onload=onloadCaptchaCallback&render=explicit&hl=en"); 761 } 762 763 /** 764 * Is Mac os 765 * @description add additional class on html if mac os. 766 */ 767 if (navigator.platform.match(/(Mac)/i)) $html.addClass("mac-os"); 768 769 /** 770 * IE Polyfills 771 * @description Adds some loosing functionality to IE browsers 772 */ 773 if (isIE) { 774 if (isIE < 10) { 775 $html.addClass("lt-ie-10"); 776 } 777 778 if (isIE < 11) { 779 if (plugins.pointerEvents) { 780 $.getScript(plugins.pointerEvents) 781 .done(function () { 782 $html.addClass("ie-10"); 783 PointerEventsPolyfill.initialize({}); 784 }); 785 } 786 } 787 788 if (isIE === 11) { 789 $html.addClass("ie-11"); 790 } 791 792 if (isIE === 12) { 793 $html.addClass("ie-edge"); 794 } 795 } 796 797 // Bootstrap Tooltips 798 if (plugins.bootstrapTooltip.length) { 799 var tooltipPlacement = plugins.bootstrapTooltip.attr('data-placement'); 800 initBootstrapTooltip(tooltipPlacement); 801 802 $window.on('resize orientationchange', function () { 803 initBootstrapTooltip(tooltipPlacement); 804 }) 805 } 806 807 /** 808 * bootstrapModalDialog 809 * @description Stap vioeo in bootstrapModalDialog 810 */ 811 if (plugins.bootstrapModalDialog.length > 0) { 812 var i = 0; 813 814 for (i = 0; i < plugins.bootstrapModalDialog.length; i++) { 815 var modalItem = $(plugins.bootstrapModalDialog[i]); 816 817 modalItem.on('hidden.bs.modal', $.proxy(function () { 818 var activeModal = $(this), 819 rdVideoInside = activeModal.find('video'), 820 youTubeVideoInside = activeModal.find('iframe'); 821 822 if (rdVideoInside.length) { 823 rdVideoInside[0].pause(); 824 } 825 826 if (youTubeVideoInside.length) { 827 var videoUrl = youTubeVideoInside.attr('src'); 828 829 youTubeVideoInside 830 .attr('src', '') 831 .attr('src', videoUrl); 832 } 833 }, modalItem)) 834 } 835 } 836 837 /** 838 * JQuery mousewheel plugin 839 * @description Enables jquery mousewheel plugin 840 */ 841 if (plugins.scroller.length) { 842 var i; 843 for (i = 0; i < plugins.scroller.length; i++) { 844 var scrollerItem = $(plugins.scroller[i]); 845 846 scrollerItem.mCustomScrollbar({ 847 theme: scrollerItem.attr('data-theme') ? scrollerItem.attr('data-theme') : 'minimal', 848 scrollInertia: 100,
849 scrollButtons: {enable: false} 850 }); 851 } 852 } 853 854 /** 855 * Facebook widget 856 * @description Enables official Facebook widget 857 */ 858 if (plugins.facebookWidget.length) { 859 lazyInit(plugins.facebookWidget, function () { 860 (function (d, s, id) { 861 var js, fjs = d.getElementsByTagName(s)[0]; 862 if (d.getElementById(id)) return; 863 js = d.createElement(s); 864 js.id = id; 865 js.src = "//connect.facebook.net/en_EN/sdk.js#xfbml=1&version=v2.5"; 866 fjs.parentNode.insertBefore(js, fjs); 867 }(document, 'script', 'facebook-jssdk')); 868 }); 869 } 870 871 /** 872 * Radio 873 * @description Add custom styling options for input[type="radio"] 874 */ 875 if (plugins.radio.length) { 876 var i; 877 for (i = 0; i < plugins.radio.length; i++) { 878 var $this = $(plugins.radio[i]); 879 $this.addClass("radio-custom").after("<span class='radio-custom-dummy'></span>") 880 } 881 } 882 883 /** 884 * Checkbox 885 * @description Add custom styling options for input[type="checkbox"] 886 */ 887 if (plugins.checkbox.length) { 888 var i; 889 for (i = 0; i < plugins.checkbox.length; i++) { 890 var $this = $(plugins.checkbox[i]); 891 $this.addClass("checkbox-custom").after("<span class='checkbox-custom-dummy'></span>") 892 } 893 } 894 895 /** 896 * Popovers 897 * @description Enables Popovers plugin 898 */ 899 if (plugins.popover.length) { 900 if (window.innerWidth < 767) { 901 plugins.popover.attr('data-placement', 'bottom'); 902 plugins.popover.popover(); 903 } else { 904 plugins.popover.popover(); 905 } 906 } 907 908 /** 909 * Bootstrap Buttons 910 * @description Enable Bootstrap Buttons plugin 911 */ 912 if (plugins.statefulButton.length) { 913 $(plugins.statefulButton).on('click', function () { 914 var statefulButtonLoading = $(this).button('loading'); 915 916 setTimeout(function () { 917 statefulButtonLoading.button('reset') 918 }, 2000); 919 }) 920 } 921 922 /** 923 * UI To Top 924 * @description Enables ToTop Button 925 */ 926 if (isDesktop && !isNoviBuilder) { 927 $().UItoTop({ 928 easingType: 'easeOutQuart', 929 containerClass: 'ui-to-top fa fa-arrow-up' 930 }); 931 } 932 933 // RD Navbar 934 if ( plugins.rdNavbar.length ) { 935 var 936 navbar = plugins.rdNavbar, 937 aliases = { '-': 0, '-sm-': 576, '-md-': 768, '-lg-': 992, '-xl-': 1200, '-xxl-': 1600 }, 938 responsive = {}; 939 940 for ( var alias in aliases ) { 941 var link = responsive[ aliases[ alias ] ] = {}; 942 if ( navbar.attr( 'data'+ alias +'layout' ) ) link.layout = navbar.attr( 'data'+ alias +'layout' ); 943 if ( navbar.attr( 'data'+ alias +'device-layout' ) ) link.deviceLayout = navbar.attr( 'data'+ alias +'device-layout' ); 944 if ( navbar.attr( 'data'+ alias +'hover-on' ) ) link.focusOnHover = navbar.attr( 'data'+ alias +'hover-on' ) === 'true'; 945 if ( navbar.attr( 'data'+ alias +'auto-height' ) ) link.autoHeight = navbar.attr( 'data'+ alias +'auto-height' ) === 'true'; 946 if ( navbar.attr( 'data'+ alias +'stick-up-offset' ) ) link.stickUpOffset = navbar.attr( 'data'+ alias +'stick-up-offset' ); 947 if ( navbar.attr( 'data'+ alias +'stick-up' ) ) link.stickUp = navbar.attr( 'data'+ alias +'stick-up' ) === 'true'; 948 if ( isNoviBuilder ) link.stickUp = false; 949 else if ( navbar.attr( 'data'+ alias +'stick-up' ) ) link.stickUp = navbar.attr( 'data'+ alias +'stick-up' ) === 'true'; 950 } 951 952 plugins.rdNavbar.RDNavbar({ 953 anchorNav: !isNoviBuilder, 954 stickUpClone: (plugins.rdNavbar.attr("data-stick-up-clone") && !isNoviBuilder) ? plugins.rdNavbar.attr("data-stick-up-clone") === 'true' : false, 955 responsive: responsive, 956 callbacks: { 957 onStuck: function () { 958 var navbarSearch = this.$element.find('.rd-search input'); 959 960 if (navbarSearch) { 961 navbarSearch.val('').trigger('propertychange'); 962 } 963 }, 964 onDropdownOver: function () { 965 return !isNoviBuilder; 966 }, 967 onUnstuck: function () { 968 if (this.$clone === null) 969 return; 970 971 var navbarSearch = this.$clone.find('.rd-search input'); 972 973 if (navbarSearch) { 974 navbarSearch.val('').trigger('propertychange'); 975 navbarSearch.trigger('blur'); 976 } 977 978 } 979 } 980 }); 981 } 982 983 // RD Search 984 if (plugins.search.length || plugins.searchResults) { 985 var handler = "bat/rd-search.php"; 986 var defaultTemplate = '<h5 class="search-title"><a target="_top" href="#{href}" class="search-link">#{title}</a></h5>' + 987 '<p>...#{token}...</p>' + 988 '<p class="match"><em>Terms matched: #{count} - URL: #{href}</em></p>'; 989 var defaultFilter = '*.html'; 990 991 if (plugins.search.length) { 992 for (var i = 0; i < plugins.search.length; i++) { 993 var searchItem = $(plugins.search[i]), 994 options = { 995 element: searchItem, 996 filter: (searchItem.attr('data-search-filter')) ? searchItem.attr('data-search-filter') : defaultFilter, 997 template: (searchItem.attr('data-search-template')) ? searchItem.attr('data-search-template') : defaultTemplate, 998 live: (searchItem.attr('data-search-live')) ? searchItem.attr('data-search-live') : false, 999 liveCount: (searchItem.attr('data-search-live-count')) ? parseInt(searchItem.attr('data-search-live'), 10) : 4, 1000 current: 0, processed: 0, timer: {} 1001 }; 1002 1003 var $toggle = $('.rd-navbar-search-toggle'); 1004 if ($toggle.length) { 1005 $toggle.on('click', (function (searchItem) { 1006 return function () { 1007 if (!($(this).hasClass('active'))) { 1008 searchItem.find('input').val('').trigger('propertychange'); 1009 } 1010 } 1011 })(searchItem)); 1012 } 1013 1014 if (options.live) { 1015 var clearHandler = false;
1016 1017 searchItem.find('input').on("input propertychange", $.proxy(function () { 1018 this.term = this.element.find('input').val().trim(); 1019 this.spin = this.element.find('.input-group-addon'); 1020 1021 clearTimeout(this.timer); 1022 1023 if (this.term.length > 2) { 1024 this.timer = setTimeout(liveSearch(this), 200); 1025 1026 if (clearHandler === false) { 1027 clearHandler = true; 1028 1029 $body.on("click", function (e) { 1030 if ($(e.toElement).parents('.rd-search').length === 0) { 1031 $('#rd-search-results-live').addClass('cleared').html(''); 1032 } 1033 }) 1034 } 1035 1036 } else if (this.term.length === 0) { 1037 $('#' + this.live).addClass('cleared').html(''); 1038 } 1039 }, options, this)); 1040 } 1041 1042 searchItem.submit($.proxy(function () { 1043 $('<input />').attr('type', 'hidden') 1044 .attr('name', "filter") 1045 .attr('value', this.filter) 1046 .appendTo(this.element); 1047 return true; 1048 }, options, this)) 1049 } 1050 } 1051 1052 if (plugins.searchResults.length) { 1053 var regExp = /\?.*s=([^&]+)\&filter=([^&]+)/g; 1054 var match = regExp.exec(location.search); 1055 1056 if (match !== null) { 1057 $.get(handler, { 1058 s: decodeURI(match[1]), 1059 dataType: "html", 1060 filter: match[2], 1061 template: defaultTemplate, 1062 live: '' 1063 }, function (data) { 1064 plugins.searchResults.html(data); 1065 }) 1066 } 1067 } 1068 } 1069 1070 /** 1071 * ViewPort Universal 1072 * @description Add class in viewport 1073 */ 1074 if (plugins.viewAnimate.length) { 1075 var i; 1076 for (i = 0; i < plugins.viewAnimate.length; i++) { 1077 var $view = $(plugins.viewAnimate[i]).not('.active'); 1078 $document.on("scroll", $.proxy(function () { 1079 if (isScrolledIntoView(this)) { 1080 this.addClass("active"); 1081 } 1082 }, $view)) 1083 .trigger("scroll"); 1084 } 1085 } 1086 1087 /** 1088 * Swiper 3.1.7 1089 * @description Enable Swiper Slider 1090 */ 1091 if (plugins.swiper.length) { 1092 var i; 1093 for (i = 0; i < plugins.swiper.length; i++) { 1094 var s = $(plugins.swiper[i]); 1095 var pag = s.find(".swiper-pagination"), 1096 next = s.find(".swiper-button-next"), 1097 prev = s.find(".swiper-button-prev"), 1098 bar = s.find(".swiper-scrollbar"), 1099 swiperSlide = s.find(".swiper-slide"), 1100 autoplay = false; 1101 1102 for (j = 0; j < swiperSlide.length; j++) { 1103 var $this = $(swiperSlide[j]), 1104 url; 1105 1106 if (url = $this.attr("data-slide-bg")) { 1107 $this.css({ 1108 "background-image": "url(" + url + ")", 1109 "background-size": "cover" 1110 }) 1111 } 1112 } 1113 1114 1115 swiperSlide.end() 1116 .find("[data-caption-animate]") 1117 .addClass("not-animated") 1118 .end() 1119 .swiper({ 1120 autoplay: isNoviBuilder ? null : s.attr('data-autoplay') ? s.attr('data-autoplay') === "false" ? undefined : s.attr('data-autoplay') : 5000, 1121 direction: s.attr('data-direction') ? s.attr('data-direction') : "horizontal", 1122 effect: s.attr('data-slide-effect') ? s.attr('data-slide-effect') : "slide", 1123 speed: s.attr('data-slide-speed') ? s.attr('data-slide-speed') : 600, 1124 keyboardControl: s.attr('data-keyboard') === "true", 1125 mousewheelControl: s.attr('data-mousewheel') === "true", 1126 mousewheelReleaseOnEdges: s.attr('data-mousewheel-release') === "true", 1127 nextButton: next.length ? next.get(0) : null, 1128 prevButton: prev.length ? prev.get(0) : null, 1129 pagination: pag.length ? pag.get(0) : null, 1130 paginationClickable: pag.length ? pag.attr("data-clickable") !== "false" : false, 1131 paginationBulletRender: pag.length ? pag.attr("data-index-bullet") === "true" ? function (index, className) { 1132 return '<span class="' + className + '">' + (index + 1) + '</span>'; 1133 } : null : null, 1134 scrollbar: bar.length ? bar.get(0) : null, 1135 scrollbarDraggable: bar.length ? bar.attr("data-draggable") !== "false" : true, 1136 scrollbarHide: bar.length ? bar.attr("data-draggable") === "false" : false, 1137 loop: isNoviBuilder ? false : s.attr('data-loop') !== "false", 1138 simulateTouch: s.attr('data-simulate-touch') && !isNoviBuilder ? s.attr('data-simulate-touch') === "true" : false, 1139 onTransitionStart: function (swiper) { 1140 toggleSwiperInnerVideos(swiper); 1141 }, 1142 onTransitionEnd: function (swiper) { 1143 toggleSwiperCaptionAnimation(swiper); 1144 }, 1145 onInit: function (swiper) { 1146 toggleSwiperInnerVideos(swiper); 1147 toggleSwiperCaptionAnimation(swiper); 1148 1149 $window.on('resize', function () { 1150 swiper.update(true); 1151 }) 1152 }, 1153 onSlideChangeStart: function (swiper) { 1154 var activeSlideIndex, slidesCount; 1155 1156 activeSlideIndex = swiper.activeIndex; 1157 slidesCount = swiper.slides.not(".swiper-slide-duplicate").length; 1158 1159 if (activeSlideIndex === slidesCount + 1) { 1160 activeSlideIndex = 1; 1161 } else if (activeSlideIndex === 0) { 1162 activeSlideIndex = slidesCount; 1163 } 1164 if (swiper.slides[activeSlideIndex - 1].getAttribute("data-sli
1164de-title")) { 1165 $(swiper.container).find('.swiper-button-next .title')[0].innerHTML = swiper.slides[activeSlideIndex + 1166 1].getAttribute("data-slide-title"); 1167 $(swiper.container).find('.swiper-button-prev .title')[0].innerHTML = swiper.slides[activeSlideIndex - 1168 1].getAttribute("data-slide-title"); 1169 } 1170 1171 if (swiper.slides[activeSlideIndex - 1].getAttribute("data-slide-subtitle")) { 1172 $(swiper.container).find('.swiper-button-prev .subtitle')[0].innerHTML = swiper.slides[activeSlideIndex - 1173 1].getAttribute("data-slide-subtitle"); 1174 $(swiper.container).find('.swiper-button-next .subtitle')[0].innerHTML = swiper.slides[activeSlideIndex + 1175 1].getAttribute("data-slide-subtitle"); 1176 } 1177 //Replace btn img 1178 if ($(swiper.container).find('.preview__img')[0] !== undefined) { 1179 $(swiper.container).find('.swiper-button-prev .preview__img').css("background-image", "url(" + 1180 swiper.slides[activeSlideIndex - 1].getAttribute("data-slide-bg") + ")"); 1181 $(swiper.container).find('.swiper-button-next .preview__img').css("background-image", "url(" + 1182 swiper.slides[activeSlideIndex + 1].getAttribute("data-slide-bg") + ")"); 1183 } 1184 } 1185 }); 1186 1187 $window 1188 .on("resize", function () { 1189 var mh = getSwiperHeight(s, "min-height"), 1190 h = getSwiperHeight(s, "height"); 1191 if (h) { 1192 s.css("height", mh ? mh > h ? mh : h : h); 1193 } 1194 }) 1195 .trigger("resize"); 1196 } 1197 } 1198 1199 // Owl carousel
1200 if ( plugins.owl.length ) { 1201 for ( var i = 0; i < plugins.owl.length; i++ ) { 1202 var carousel = $( plugins.owl[ i ] ); 1203 plugins.owl[ i ].owl = carousel; 1204 initOwlCarousel( carousel ); 1205 } 1206 } 1207 1208 /** 1209 * Isotope 1210 * @description Enables Isotope plugin 1211 */ 1212 if (plugins.isotope.length) { 1213 var i, isogroup = []; 1214 for (i = 0; i < plugins.isotope.length; i++) { 1215 var isotopeItem = plugins.isotope[i], 1216 iso = new Isotope(isotopeItem, { 1217 itemSelector: '.isotope-item', 1218 layoutMode: isotopeItem.getAttribute('data-isotope-layout') ? isotopeItem.getAttribute('data-isotope-layout') : 'masonry', 1219 filter: '*' 1220 }); 1221 1222 isogroup.push(iso); 1223 } 1224 1225 $window.on('load', function () { 1226 setTimeout(function () { 1227 var i; 1228 for (i = 0; i < isogroup.length; i++) { 1229 isogroup[i].element.className += " isotope--loaded"; 1230 isogroup[i].layout(); 1231 } 1232 }, 600); 1233 }); 1234 1235 var resizeTimout, 1236 isotopeFilter = $("[data-isotope-filter]"); 1237 1238 isotopeFilter.on("click", function (e) { 1239 e.preventDefault(); 1240 var filter = $(this); 1241 clearTimeout(resizeTimout); 1242 filter.parents(".isotope-filters").find('.active').removeClass("active"); 1243 filter.addClass("active"); 1244 var iso = $('.isotope[data-isotope-group="' + this.getAttribute("data-isotope-group") + '"]'); 1245 iso.isotope({ 1246 itemSelector: '.isotope-item', 1247 layoutMode: iso.attr('data-isotope-layout') ? iso.attr('data-isotope-layout') : 'masonry', 1248 filter: this.getAttribute("data-isotope-filter") == '*' ? '*' : '[data-filter*="' + this.getAttribute("data-isotope-filter") + '"]' 1249 }); 1250 }).eq(0).trigger("click") 1251 } 1252 1253 /** 1254 * WOW 1255 * @description Enables Wow animation plugin 1256 */ 1257 if (isDesktop && $html.hasClass("wow-animation") && $(".wow").length) { 1258 new WOW().init(); 1259 } 1260 1261 // Bootstrap tabs 1262 if (plugins.bootstrapTabs.length) { 1263 for (var i = 0; i < plugins.bootstrapTabs.length; i++) { 1264 var bootstrapTabsItem = $(plugins.bootstrapTabs[i]); 1265 1266 //If have slick carousel inside tab - resize slick carousel on click 1267 if (bootstrapTabsItem.find('.slick-slider').length) { 1268 bootstrapTabsItem.find('.tabs-custom-list > li > a').on('click', $.proxy(function () { 1269 var $this = $(this); 1270 var setTimeOutTime = isNoviBuilder ? 1500 : 300; 1271 1272 setTimeout(function () { 1273 $this.find('.tab-content .tab-pane.active .slick-slider').slick('setPosition'); 1274 }, setTimeOutTime); 1275 }, bootstrapTabsItem)); 1276 } 1277 } 1278 } 1279 1280 /** 1281 * RD Input Label 1282 * @description Enables RD Input Label Plugin 1283 */ 1284 if (plugins.rdInputLabel.length) { 1285 plugins.rdInputLabel.RDInputLabel(); 1286 } 1287 1288 /** 1289 * Regula 1290 * @description Enables Regula plugin 1291 */ 1292 if (plugins.regula.length) { 1293 attachFormValidator(plugins.regula); 1294 } 1295 1296 /** 1297 * MailChimp Ajax subscription 1298 */ 1299 if (plugins.mailchimp.length) { 1300 for (i = 0; i < plugins.mailchimp.length; i++) { 1301 var $mailchimpItem = $(plugins.mailchimp[i]), 1302 $email = $mailchimpItem.find('input[type="email"]'); 1303 1304 // Required by MailChimp 1305 $mailchimpItem.attr('novalidate', 'true'); 1306 $email.attr('name', 'EMAIL'); 1307 1308 $mailchimpItem.on('submit', $.proxy(function (e) { 1309 e.preventDefault(); 1310 1311 var $this = this; 1312 1313 var data = {}, 1314 url = $this.attr('action').replace('/post?', '/post-json?').concat('&c=?'), 1315 dataArray = $this.serializeArray(), 1316 $output = $("#" + $this.attr("data-form-output")); 1317 1318 for (i = 0; i < dataArray.length; i++) { 1319 data[dataArray[i].name] = dataArray[i].value; 1320 } 1321 1322 $.ajax({ 1323 data: data, 1324 url: url, 1325 dataType: 'jsonp', 1326 error: function (resp, text) { 1327 $output.html('Server error: ' + text); 1328 1329 setTimeout(function () { 1330 $output.removeClass("active"); 1331 }, 4000); 1332 }, 1333 success: function (resp) { 1334 $output.html(resp.msg).addClass('active'); 1335 1336 setTimeout(function () { 1337 $output.removeClass("active"); 1338 }, 6000); 1339 }, 1340 beforeSend: function (data) { 1341 // Stop request if builder or inputs are invalide 1342 if (isNoviBuilder || !isValidated($this.find('[data-constraints]'))) 1343 return false;
1344 1345 $output.html('Submitting...').addClass('active'); 1346 } 1347 }); 1348 1349 return false; 1350 }, $mailchimpItem)); 1351 } 1352 } 1353 1354 /** 1355 * Campaign Monitor ajax subscription 1356 */ 1357 if (plugins.campaignMonitor.length) { 1358 for (i = 0; i < plugins.campaignMonitor.length; i++) { 1359 var $campaignItem = $(plugins.campaignMonitor[i]); 1360 1361 $campaignItem.on('submit', $.proxy(function (e) { 1362 var data = {}, 1363 url = this.attr('action'), 1364 dataArray = this.serializeArray(), 1365 $output = $("#" + plugins.campaignMonitor.attr("data-form-output")), 1366 $this = $(this); 1367 1368 for (i = 0; i < dataArray.length; i++) { 1369 data[dataArray[i].name] = dataArray[i].value; 1370 } 1371 1372 $.ajax({ 1373 data: data, 1374 url: url, 1375 dataType: 'jsonp', 1376 error: function (resp, text) { 1377 $output.html('Server error: ' + text); 1378 1379 setTimeout(function () { 1380 $output.removeClass("active"); 1381 }, 4000); 1382 }, 1383 success: function (resp) { 1384 $output.html(resp.Message).addClass('active'); 1385 1386 setTimeout(function () { 1387 $output.removeClass("active"); 1388 }, 6000); 1389 }, 1390 beforeSend: function (data) { 1391 // Stop request if builder or inputs are invalide 1392 if (isNoviBuilder || !isValidated($this.find('[data-constraints]'))) 1393 return false; 1394 1395 $output.html('Submitting...').addClass('active'); 1396 } 1397 }); 1398 1399 return false; 1400 }, $campaignItem)); 1401 } 1402 } 1403 1404 /** 1405 * RD Mailform 1406 * @version 3.0.0 1407 */ 1408 if (plugins.rdMailForm.length) { 1409 var i, j, k, 1410 msg = { 1411 'MF000': 'Successfully sent!', 1412 'MF001': 'Recipients are not set!', 1413 'MF002': 'Form will not work locally!', 1414 'MF003': 'Please, define email field in your form!', 1415 'MF004': 'Please, define type of your form!', 1416 'MF254': 'Something went wrong with PHPMailer!', 1417 'MF255': 'Aw, snap! Something went wrong.' 1418 }, 1419 recipients = '[email protected]'; 1420 1421 for (i = 0; i < plugins.rdMailForm.length; i++) { 1422 var $form = $(plugins.rdMailForm[i]), 1423 formHasCaptcha = false; 1424 1425 $form.attr('novalidate', 'novalidate').ajaxForm({ 1426 data: { 1427 "form-type": $form.attr("data-form-type") || "contact", 1428 "recipients": recipients, 1429 "counter": i 1430 }, 1431 beforeSubmit: function (arr, $form, options) { 1432 if (isNoviBuilder) 1433 return; 1434 1435 var form = $(plugins.rdMailForm[this.extraData.counter]), 1436 inputs = form.find("[data-constraints]"), 1437 output = $("#" + form.attr("data-form-output")), 1438 captcha = form.find('.recaptcha'), 1439 captchaFlag = true; 1440 1441 output.removeClass("active error success"); 1442 1443 if (isValidated(inputs, captcha)) { 1444 1445 // veify reCaptcha 1446 if (captcha.length) { 1447 var captchaToken = captcha.find('.g-recaptcha-response').val(), 1448 captchaMsg = { 1449 'CPT001': 'Please, setup you "site key" and "secret key" of reCaptcha', 1450 'CPT002': 'Something wrong with google reCaptcha' 1451 } 1452 1453 formHasCaptcha = true; 1454 1455 $.ajax({ 1456 method: "POST", 1457 url: "bat/reCaptcha.php", 1458 data: {'g-recaptcha-response': captchaToken}, 1459 async: false 1460 }) 1461 .done(function (responceCode) { 1462 if (responceCode != 'CPT000') { 1463 if (output.hasClass("snackbars")) { 1464 output.html('<p><span class="icon text-middle mdi mdi-check icon-xxs"></span><span>' + captchaMsg[responceCode] + '</span></p>') 1465 1466 setTimeout(function () { 1467 output.removeClass("active"); 1468 }, 3500); 1469 1470 captchaFlag = false; 1471 } else { 1472 output.html(captchaMsg[responceCode]); 1473 } 1474 1475 output.addClass("active"); 1476 } 1477 }); 1478 } 1479 1480 if (!captchaFlag) { 1481 return false; 1482 } 1483 1484 form.addClass('form-in-process'); 1485 1486 if (output.hasClass("snackbars")) { 1487 output.html('<p><span class="icon text-middle fa fa-circle-o-notch fa-spin icon-xxs"></span><span>Sending</span></p>'); 1488 output.addClass("active"); 1489 } 1490 } else { 1491 return false;
1492 } 1493 }, 1494 error: function (result) { 1495 if (isNoviBuilder) 1496 return; 1497 1498 var output = $("#" + $(plugins.rdMailForm[this.extraData.counter]).attr("data-form-output")), 1499 form = $(plugins.rdMailForm[this.extraData.counter]); 1500 1501 output.text(msg[result]); 1502 form.removeClass('form-in-process'); 1503 1504 if (formHasCaptcha) { 1505 grecaptcha.reset(); 1506 } 1507 }, 1508 success: function (result) { 1509 if (isNoviBuilder) 1510 return; 1511 1512 var form = $(plugins.rdMailForm[this.extraData.counter]), 1513 output = $("#" + form.attr("data-form-output")); 1514 1515 form 1516 .addClass('success') 1517 .removeClass('form-in-process'); 1518 1519 if (formHasCaptcha) { 1520 grecaptcha.reset(); 1521 } 1522 1523 result = result.length === 5 ? result : 'MF255'; 1524 output.text(msg[result]); 1525 1526 if (result === "MF000") { 1527 if (output.hasClass("snackbars")) { 1528 output.html('<p><span class="icon text-middle mdi mdi-check icon-xxs"></span><span>' + msg[result] + '</span></p>'); 1529 } else { 1530 output.addClass("active success"); 1531 } 1532 } else { 1533 if (output.hasClass("snackbars")) { 1534 output.html(' <p class="snackbars-left"><span class="icon icon-xxs mdi mdi-alert-outline text-middle"></span><span>' + msg[result] + '</span></p>'); 1535 } else { 1536 output.addClass("active error"); 1537 } 1538 } 1539 1540 form.clearForm(); 1541 form.find('input, textarea').trigger('blur'); 1542 1543 setTimeout(function () { 1544 output.removeClass("active error success"); 1545 form.removeClass('success'); 1546 }, 3500); 1547 } 1548 }); 1549 } 1550 } 1551 1552 /** 1553 * Custom Toggles 1554 */ 1555 if (plugins.customToggle.length) { 1556 var i; 1557 1558 for (i = 0; i < plugins.customToggle.length; i++) { 1559 var $this = $(plugins.customToggle[i]); 1560 1561 $this.on('click', $.proxy(function (event) { 1562 event.preventDefault(); 1563 var $ctx = $(this); 1564 $($ctx.attr('data-custom-toggle')).add(this).toggleClass('active'); 1565 }, $this)); 1566 1567 if ($this.attr("data-custom-toggle-hide-on-blur") === "true") { 1568 $body.on("click", $this, function (e) { 1569 if (e.target !== e.data[0] 1570 && $(e.data.attr('data-custom-toggle')).find($(e.target)).length 1571 && e.data.find($(e.target)).length == 0) { 1572 $(e.data.attr('data-custom-toggle')).add(e.data[0]).removeClass('active'); 1573 } 1574 }) 1575 } 1576 1577 if ($this.attr("data-custom-toggle-disable-on-blur") === "true") { 1578 $body.on("click", $this, function (e) { 1579 if (e.target !== e.data[0] && $(e.data.attr('data-custom-toggle')).find($(e.target)).length == 0 && e.data.find($(e.target)).length == 0) { 1580 $(e.data.attr('data-custom-toggle')).add(e.data[0]).removeClass('active'); 1581 } 1582 }) 1583 } 1584 } 1585 } 1586 1587 /** 1588 * jQuery Count To 1589 * @description Enables Count To plugin 1590 */ 1591 if (plugins.counter.length) { 1592 var i; 1593 1594 for (i = 0; i < plugins.counter.length; i++) { 1595 var $counterNotAnimated = $(plugins.counter[i]).not('.animated'); 1596 $document 1597 .on("scroll", $.proxy(function () { 1598 var $this = this; 1599 1600 if ((!$this.hasClass("animated")) && (isScrolledIntoView($this))) { 1601 $this.countTo({ 1602 refreshInterval: 40, 1603 from: 0, 1604 to: parseInt($this.text(), 10), 1605 speed: $this.attr("data-speed") || 1000 1606 }); 1607 $this.addClass('animated'); 1608 } 1609 }, $counterNotAnimated)) 1610 .trigger("scroll"); 1611 } 1612 } 1613 1614 /** 1615 * TimeCircles 1616 * @description Enable TimeCircles plugin 1617 */ 1618 if (plugins.dateCountdown.length) { 1619 var i; 1620 for (i = 0; i < plugins.dateCountdown.length; i++) { 1621 var dateCountdownItem = $(plugins.dateCountdown[i]); 1622 1623 $window.on('load resize orientationchange', $.proxy(function () { 1624 var $this = $(this), 1625 circleColor = $this.data('circle-inner-color'), 1626 dateCountdownItemBgColor = $this.data('circle-bg'), 1627 time = { 1628 "Days": { 1629 "text": "Days", 1630 "color": circleColor, 1631 "show": true 1632 }, 1633 "Hours": { 1634 "text": "Hours", 1635 "color": circleColor, 1636 "show": true 1637 }, 1638 "Minutes": { 1639 "text": "Minutes", 1640 "color": circleColor, 1641 "show": true 1642 }, 1643 "Seconds": { 1644 "text": "Seconds", 1645 "color": circleColor, 1646 "show": true 1647 } 1648 }; 1649 1650 $this.TimeCircles({ 1651 fg_width: $this.data('circle-fg-width') || 0.045, 1652 circle_bg_color: dateCountdownItemBgColor, 1653 bg_width: $this.data('circle-bg-width') || 0.9, 1654 time: time 1655 }); 1656 1657 if (window.innerWidth < 479) { 1658 $this.TimeCircles({ 1659 time: { 1660 Days: { 1661 "color": circleColor, 1662 "show": true 1663 }, 1664 Hours: { 1665 "color": circleColor, 1666 "show": true 1667 }, 1668 Minutes: { 1669 color: circleColor, 1670 show: true 1671 }, 1672 Seconds: { 1673 show: false 1674 } 1675 } 1676 }).rebuild(); 1677 } else if (window.innerWidth < 767) { 1678 $this.TimeCircles({ 1679 time: { 1680 Days: { 1681 "color": circleColor, 1682 "show": true 1683 }, 1684 Hours: { 1685 "color": circleColor, 1686 "show": true 1687 }, 1688 Seconds: {show: false} 1689 } 1690 }).rebuild(); 1691 } else { 1692 $this.TimeCircles({time: time}).rebuild(); 1693 } 1694 }, dateCountdownItem)); 1695 } 1696 } 1697 1698 // Progress Circle 1699 if ( plugins.progressCircle ) { 1700 for ( var i = 0; i < plugins.progressCircle.length; i++ ) { 1701 var 1702 container = plugins.progressCircle[i], 1703 counter = aCounter({ 1704 node: container.querySelector( '.progress-circle-counter' ), 1705 duration: 500, 1706 onUpdate: function( value ) { 1707 this.custom.bar.render( value * 3.6 ); 1708 } 1709 }); 1710 1711 counter.params.onComplete = counter.params.onUpdate; 1712 1713 counter.custom = { 1714 container: container, 1715 bar: aProgressCircle({ node: container.querySelector( '.progress-circle-bar' ) }), 1716 onScroll: (function() { 1717 if ( Util.inViewport( this.custom.container ) && !this.custom.container.classList.contains( 'animated' ) ) { 1718 this.run(); 1719 this.custom.container.classList.add( 'animated' ); 1720 } 1721 }).bind( counter ), 1722 onBlur: (function() { 1723 this.params.to = parseInt( this.params.node.textContent, 10 ); 1724 this.run(); 1725 }).bind( counter ) 1726 }; 1727 1728 counter.custom.onScroll(); 1729 window.addEventListener( 'scroll', counter.custom.onScroll ); 1730 counter.params.node.addEventListener( 'blur', counter.custom.onBlur ); 1731 } 1732 } 1733 1734 /** 1735 * Linear Progress bar 1736 * @description Enable progress bar 1737 */ 1738 if (plugins.progressLinear.length) { 1739 for (i = 0; i < plugins.progressLinear.length; i++) { 1740 var progressBar = $(plugins.progressLinear[i]); 1741 $window 1742 .on("scroll load", $.proxy(function () { 1743 var bar = $(this); 1744 if (!bar.hasClass('animated-first') && isScrolledIntoView(bar)) { 1745 var end = parseInt($(this).find('.progress-value').text(), 10); 1746 bar.find('.progress-bar-linear').css({width: end + '%'}); 1747 bar.find('.progress-value').countTo({ 1748 refreshInterval: 40, 1749 from: 0, 1750 to: end, 1751 speed: 500 1752 }); 1753 bar.addClass('animated-first'); 1754 } 1755 }, progressBar)); 1756 } 1757 } 1758 1759 /** 1760 * RD Flickr Feed
1761 * @description Enables RD Flickr Feed plugin 1762 */ 1763 if (plugins.flickrfeed.length > 0) { 1764 var i; 1765 for (i = 0; i < plugins.flickrfeed.length; i++) { 1766 var flickrfeedItem = $(plugins.flickrfeed[i]); 1767 flickrfeedItem.RDFlickr({ 1768 callback: function () { 1769 var items = flickrfeedItem.find("[data-photo-swipe-item]"); 1770 1771 if (items.length) { 1772 for (var j = 0; j < items.length; j++) { 1773 var image = new Image(); 1774 image.setAttribute('data-index', j); 1775 image.onload = function () { 1776 items[this.getAttribute('data-index')].setAttribute('data-size', this.naturalWidth + 'x' + this.naturalHeight); 1777 }; 1778 image.src = items[j].getAttribute('href'); 1779 } 1780 } 1781 } 1782 }); 1783 } 1784 } 1785 1786 /** 1787 * RD Twitter Feed 1788 * @description Enables RD Twitter Feed plugin 1789 */ 1790 if (plugins.twitterfeed.length > 0) { 1791 var i; 1792 for (i = 0; i < plugins.twitterfeed.length; i++) { 1793 var twitterfeedItem = plugins.twitterfeed[i]; 1794 $(twitterfeedItem).RDTwitter({}); 1795 } 1796 } 1797 1798 // Google maps 1799 if( plugins.maps.length ) { 1800 lazyInit( plugins.maps, initMaps ); 1801 } 1802 1803 // lightGallery 1804 if (plugins.lightGallery.length) { 1805 for (var i = 0; i < plugins.lightGallery.length; i++) { 1806 initLightGallery(plugins.lightGallery[i]); 1807 } 1808 } 1809 1810 // lightGallery item 1811 if (plugins.lightGalleryItem.length) { 1812 // Filter carousel items 1813 var notCarouselItems = []; 1814 1815 for (var z = 0; z < plugins.lightGalleryItem.length; z++) { 1816 if (!$(plugins.lightGalleryItem[z]).parents('.owl-carousel').length && 1817 !$(plugins.lightGalleryItem[z]).parents('.swiper-slider').length && 1818 !$(plugins.lightGalleryItem[z]).parents('.slick-slider').length) { 1819 notCarouselItems.push(plugins.lightGalleryItem[z]); 1820 } 1821 } 1822 1823 plugins.lightGalleryItem = notCarouselItems; 1824 1825 for (var i = 0; i < plugins.lightGalleryItem.length; i++) { 1826 initLightGalleryItem(plugins.lightGalleryItem[i]); 1827 } 1828 } 1829 1830 // Dynamic lightGallery 1831 if (plugins.lightDynamicGalleryItem.length) { 1832 for (var i = 0; i < plugins.lightDynamicGalleryItem.length; i++) { 1833 initDynamicLightGallery(plugins.lightDynamicGalleryItem[i]); 1834 } 1835 } 1836 1837 }); 1838 1839}()); 1840
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.