1( function( $, elementor ) { 2 3 "use strict"; 4 5 var JetElements = { 6 7 init: function() { 8 9 var widgets = { 10 'jet-carousel.default' : JetElements.widgetCarousel, 11 'jet-circle-progress.default' : JetElements.widgetProgress, 12 'jet-map.default' : JetElements.widgetMap, 13 'jet-countdown-timer.default' : JetElements.widgetCountdown, 14 'jet-posts.default' : JetElements.widgetPosts, 15 'jet-animated-text.default' : JetElements.widgetAnimatedText, 16 'jet-animated-box.default' : JetElements.widgetAnimatedBox, 17 'jet-images-layout.default' : JetElements.widgetImagesLayout, 18 'jet-slider.default' : JetElements.widgetSlider, 19 'jet-testimonials.default' : JetElements.widgetTestimonials, 20 'jet-image-comparison.default' : JetElements.widgetImageComparison, 21 'jet-instagram-gallery.default' : JetElements.widgetInstagramGallery, 22 'jet-scroll-navigation.default' : JetElements.widgetScrollNavigation, 23 'jet-subscribe-form.default' : JetElements.widgetSubscribeForm, 24 'jet-progress-bar.default' : JetElements.widgetProgressBar, 25 'jet-portfolio.default' : JetElements.widgetPortfolio, 26 'jet-timeline.default': JetElements.widgetTimeLine, 27 'jet-table.default': JetElements.widgetTable, 28 'jet-dropbar.default': JetElements.widgetDropbar, 29 'jet-video.default': JetElements.widgetVideo, 30 'jet-audio.default': JetElements.widgetAudio, 31 'jet-horizontal-timeline.default': JetElements.widgetHorizontalTimeline, 32 'mp-timetable.default': JetElements.widgetTimeTable, 33 'jet-pie-chart.default': JetElements.widgetPieChart, 34 'jet-bar-chart.default': JetElements.widgetBarChart, 35 'jet-line-chart.default': JetElements.widgetLineChart, 36 'jet-lottie.default': JetElements.widgetLottie, 37 'jet-pricing-table.default': JetElements.widgetPricingTable 38 }; 39 40 $.each( widgets, function( widget, callback ) { 41 elementor.hooks.addAction( 'frontend/element_ready/' + widget, callback ); 42 }); 43 44 elementor.hooks.addAction( 'frontend/element_ready/section', JetElements.elementorSection ); 45 }, 46 47 initElementsHandlers: function( $selector ) { 48 $selector.find( '[data-element_type]' ).each( function() { 49 var $this = $( this ), 50 elementType = $this.data( 'element_type' ); 51 52 if ( !elementType ) { 53 return; 54 } 55 56 if ( 'widget' === elementType ) { 57 elementType = $this.data( 'widget_type' ); 58 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ ); 59 } 60 61 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ ); 62 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ ); 63 64 } ); 65 }, 66 67 widgetCountdown: function( $scope ) { 68 69 var timeInterval, 70 $countdown = $scope.find( '.jet-countdown-timer' ), 71 type = $countdown.data( 'type' ), 72 endTime = null, 73 dueDate = $countdown.data( 'due-date' ), 74 startDate = $countdown.data( 'start-date' ), 75 actions = $countdown.data( 'expire-actions' ), 76 evergreenInterval = $countdown.data( 'evergreen-interval' ), 77 restartInterval = $countdown.data( 'restart-interval' ), 78 elements = { 79 days: $countdown.find( '[data-value="days"]' ), 80 hours: $countdown.find( '[data-value="hours"]' ), 81 minutes: $countdown.find( '[data-value="minutes"]' ), 82 seconds: $countdown.find( '[data-value="seconds"]' ) 83 }; 84 85 var initClock = function() { 86 87 switch( type ) { 88 case 'due_date': 89 endTime = new Date( dueDate * 1000 ); 90 break; 91 92 case 'evergreen': 93 if ( evergreenInterval > 0 ) { 94 endTime = getEvergreenDate(); 95 } 96 break; 97 98 case 'endless': 99 var currentTime = new Date(), 100 startTime = new Date( startDate * 1000 ); 101 102 if ( currentTime > startTime ) { 103 endTime = new Date( (startDate + restartInterval) * 1000 ); 104 } 105 106 if ( endTime && ( currentTime > endTime ) ) { 107 endTime = endTime.setSeconds( endTime.getSeconds() + (Math.floor( (currentTime - endTime) / (restartInterval * 1000) ) + 1) * restartInterval ); 108 } 109 110 break; 111 } 112 113 updateClock(); 114 timeInterval = setInterval( updateClock, 1000 ); 115 }; 116 117 var updateClock = function() { 118 119 if ( ! endTime ) { 120 return; 121 } 122 123 var timeRemaining = getTimeRemaining( 124 endTime, 125 { 126 days: elements.days.length, 127 hours: elements.hours.length, 128 minutes: elements.minutes.length 129 } 130 ); 131 132 $.each( timeRemaining.parts, function( timePart ) { 133 134 var $element = elements[ timePart ]; 135 136 if ( $element.length ) { 137 $element.html( this ); 138 } 139 140 } ); 141 142 if ( timeRemaining.total <= 0 ) { 143 clearInterval( timeInterval ); 144 runActions(); 145 } 146 }; 147 148 var splitNum = function( num ) { 149 150 var num = num.toString(), 151 arr = [], 152 result = ''; 153 154 if ( 1 === num.length ) { 155 num = 0 + num; 156 } 157 158 arr = num.match(/\d{1}/g); 159 160 $.each( arr, function( index, val ) { 161 result += '<span class="jet-countdown-timer__digit">' + val + '</span>'; 162 }); 163 164 return result; 165 }; 166 167 var getTimeRemaining = function( endTime, visible ) { 168 169 var timeRemaining = endTime - new Date(), 170 seconds = Math.floor( ( timeRemaining / 1000 ) % 60 ), 171 minutes = Math.floor( ( timeRemaining / 1000 / 60 ) % 60 ), 172 hours = Math.floor( ( timeRemaining / ( 1000 * 60 * 60 ) ) % 24 ), 173 days = Math.floor( timeRemaining / ( 1000 * 60 * 60 * 24 ) ); 174 175 if ( days < 0 || hours < 0 || minutes < 0 ) { 176 seconds = minutes = hours = days = 0; 177 } 178 179 if ( ! visible.days ) { 180 hours += days * 24; 181 days = 0; 182 } 183 184 if ( ! visible.hours ) { 185 minutes += hours * 60; 186 hours = 0; 187 } 188 189 if ( ! visible.minutes ) { 190 seconds += minutes * 60; 191 minutes = 0; 192 } 193 194 return { 195 total: timeRemaining, 196 parts: { 197 days: splitNum( days ), 198 hours: splitNum( hours ), 199 minutes: splitNum( minutes ), 200 seconds: splitNum( seconds ) 201 } 202 }; 203 }; 204 205 var runActions = function() { 206 207 $scope.trigger( 'jetCountdownTimerExpire', $scope ); 208 209 if ( ! actions ) { 210 return; 211 } 212 213 $.each( actions, function( index, action ) { 214 switch ( action ) { 215 case 'redirect': 216 var redirect_url = $countdown.data( 'expire-redirect-url' ); 217 218 if ( redirect_url ) { 219 window.location.href = redirect_url; 220 } 221 222 break; 223 224 case 'message': 225 $scope.find( '.jet-countdown-timer-message' ).show(); 226 break; 227 228 case 'hide': 229 $countdown.hide(); 230 break; 231 232 case 'restart': 233 234 endTime = new Date(); 235 endTime = endTime.setSeconds( endTime.getSeconds() + restartInterval ); 236 237 updateClock(); 238 timeInterval = setInterval( updateClock, 1000 ); 239 break; 240 } 241 } ); 242 }; 243 244 var getEvergreenDate = function() { 245 var id = $scope.data( 'id' ),
246 dueDateKey = 'jet_evergreen_countdown_due_date_' + id, 247 intervalKey = 'jet_evergreen_countdown_interval_' + id, 248 localDueDate = localStorage.getItem( dueDateKey ), 249 localInterval = localStorage.getItem( intervalKey ), 250 251 initEvergreenTimer = function(){ 252 var dueDate = new Date(), 253 _endTime = dueDate.setSeconds( dueDate.getSeconds() + evergreenInterval ); 254 255 localStorage.setItem( dueDateKey, _endTime ); 256 localStorage.setItem( intervalKey, evergreenInterval ); 257 258 return _endTime; 259 }; 260 261 if ( null === localDueDate && null === localInterval ) { 262 return initEvergreenTimer(); 263 } 264 265 if ( null !== localDueDate && evergreenInterval !== parseInt( localInterval, 10 ) ) { 266 return initEvergreenTimer(); 267 } 268 269 if ( localDueDate > 0 && parseInt( localInterval, 10 ) === evergreenInterval ) { 270 return localDueDate; 271 } 272 }; 273 274 initClock(); 275 276 }, 277 278 widgetMap: function( $scope ) { 279 280 var $container = $scope.find( '.jet-map' ), 281 map, 282 init, 283 pins; 284 285 if ( ! window.google || ! $container.length ) { 286 return; 287 } 288 289 init = $container.data( 'init' ); 290 pins = $container.data( 'pins' ); 291 map = new google.maps.Map( $container[0], init ); 292 293 if ( pins ) { 294 $.each( pins, function( index, pin ) { 295 296 var marker, 297 infowindow, 298 pinData = { 299 position: pin.position, 300 map: map 301 }; 302 303 if ( '' !== pin.image ) { 304 305 if ( undefined !== pin.image_width && undefined !== pin.image_height ) { 306 var icon = { 307 url: pin.image, 308 scaledSize: new google.maps.Size( pin.image_width, pin.image_height ), 309 origin: new google.maps.Point( 0, 0 ), 310 anchor: new google.maps.Point( pin.image_width/2, pin.image_height/2 ) 311 } 312 313 pinData.icon = icon; 314 } else { 315 pinData.icon = pin.image; 316 } 317 } 318 319 marker = new google.maps.Marker( pinData ); 320 321 if ( '' !== pin.desc || undefined !== pin.link_title ) { 322 323 if ( undefined !== pin.link_title ) { 324 var link_url = pin.link.url, 325 link_is_external = 'on' === pin.link.is_external ? 'target="_blank"': '', 326 link_nofollow = 'on' === pin.link.nofollow ? 'rel="nofollow"': '', 327 link_custom_attributes = undefined !== parse_custom_attributes( pin.link.custom_attributes ) ? parse_custom_attributes( pin.link.custom_attributes ) : '', 328 link_layout; 329 330 link_layout = '<div class="jet-map-pin__wrapper">
330<a class="jet-map-pin__link" href="' + link_url + '" ' + link_is_external + link_nofollow + link_custom_attributes + '>' + pin.link_title + '</a></div>'; 331 pin.desc += link_layout; 332 } 333 334 infowindow = new google.maps.InfoWindow({ 335 content: pin.desc, 336 disableAutoPan: true 337 }); 338 } 339 340 marker.addListener( 'click', function() { 341 infowindow.setOptions({ disableAutoPan: false }); 342 infowindow.open( map, marker ); 343 }); 344 345 if ( 'visible' === pin.state && '' !== pin.desc ) { 346 infowindow.open( map, marker ); 347 } 348 349 }); 350 } 351 352 function parse_custom_attributes( attributes_string, delimiter = ',' ) { 353 var attributes = attributes_string.split( delimiter ), 354 result; 355 356 result = attributes.reduce(function( res, attribute ) { 357 var attr_key_value = attribute.split( '|' ), 358 attr_key = attr_key_value[0].toLowerCase(), 359 attr_value = '', 360 regex = new RegExp(/[-_a-z0-9]+/); 361 362 if( !regex.test( attr_key ) ) { 363 return; 364 } 365 366 // Avoid Javascript events and unescaped href. 367 if ( 'href' === attr_key || 'on' === attr_key.substring( 0, 2 ) ) { 368 return; 369 } 370 371 if ( undefined !== attr_key_value[1] ) { 372 attr_value = attr_key_value[1].trim(); 373 } else { 374 attr_value = ''; 375 } 376 return res + attr_key + '="' + attr_value + '" '; 377 }, ''); 378 379 return result; 380 } 381 }, 382 383 prepareWaypointOptions: function( $scope, waypointOptions ) { 384 var options = waypointOptions || {}, 385 $parentPopup = $scope.closest( '.jet-popup__container-inner, .elementor-popup-modal .dialog-message' ); 386 387 if ( $parentPopup[0] ) { 388 options.context = $parentPopup[0]; 389 } 390 391 return options; 392 }, 393 394 widgetProgress: function( $scope ) { 395 396 var $progress = $scope.find( '.circle-progress' ); 397 398 if ( ! $progress.length ) { 399 return; 400 } 401 402 var $value = $progress.find( '.circle-progress__value' ), 403 $meter = $progress.find( '.circle-progress__meter' ), 404 percent = parseInt( $value.data( 'value' ) ), 405 progress = percent / 100, 406 duration = $scope.find( '.circle-progress-wrap' ).data( 'duration' ), 407 currentDeviceMode = elementorFrontend.getCurrentDeviceMode(), 408 isAnimatedCircle = false, 409 breakpoints = JetElementsTools.getElementorElementSettings( $scope ), 410 breakpointsSettings = [], 411 activeBreakpoints = elementor.config.responsive.activeBreakpoints; 412 413 breakpointsSettings['desktop'] = []; 414 415 var breakpointSize = breakpoints['circle_size']['size'] ? breakpoints['circle_size']['size'] : $progress[0].getAttribute( 'width' ), 416 417 breakpointStrokeValue = breakpoints['value_stroke']['size'] ? breakpoints['value_stroke']['size'] : $progress[0].getElementsByClassName( 'circle-progress__value' )[0].getAttribute( 'stroke-width' ), 418 419 breakpointStrokeBg = breakpoints['bg_stroke']['size'] ? breakpoints['bg_stroke']['size'] : $progress[0].getElementsByClassName( 'circle-progress__meter' )[0].getAttribute( 'stroke-width' ); 420 421 breakpointSizes( 'desktop', breakpointSize, breakpointStrokeValue, breakpointStrokeBg ); 422 423 Object.keys( activeBreakpoints ).reverse().forEach( function( breakpointName, index ) { 424 425 if ( 'widescreen' === breakpointName ){ 426 var breakpointSize = breakpoints['circle_size_' + breakpointName]['size'] ? breakpoints['circle_size_' + breakpointName]['size'] : breakpoints['circle_size']['size'], 427 428 breakpointStrokeValue = breakpoints['value_stroke_' + breakpointName]['size'] ? breakpoints['value_stroke_' + breakpointName]['size'] : breakpoints['value_stroke']['size'], 429 430 breakpointStrokeBg = breakpoints['bg_stroke_' + breakpointName]['size'] ? breakpoints['bg_stroke_' + breakpointName]['size'] : breakpoints['bg_stroke']['size']; 431 432 breakpointsSettings[breakpointName] = []; 433 434 breakpointSizes( breakpointName, breakpointSize, breakpointStrokeValue, breakpointStrokeBg ); 435 } else { 436 var breakpointSize = breakpoints['circle_size_' + breakpointName]['size'] ? breakpoints['circle_size_' + breakpointName]['size'] : $progress[0].getAttribute( 'width' ), 437 438 breakpointStrokeValue = breakpoints['value_stroke_' + breakpointName]['size'] ? breakpoints['value_stroke_' + breakpointName]['size'] : $progress[0].getElementsByClassName( 'circle-progress__value' )[0].getAttribute( 'stroke-width' ), 439 440 breakpointStrokeBg = breakpoints['bg_stroke_' + breakpointName]['size'] ? breakpoints['bg_stroke_' + breakpointName]['size'] : $progress[0].getElementsByClassName( 'circle-progress__meter' )[0].getAttribute( 'stroke-width' ); 441 442 breakpointsSettings[breakpointName] = []; 443 444 breakpointSizes( breakpointName, breakpointSize, breakpointStrokeValue, breakpointStrokeBg ); 445 } 446 } ); 447 448 updateSvgSizes( breakpointsSettings[currentDeviceMode]['size'], 449 breakpointsSettings[currentDeviceMode]['viewBox'], 450 breakpointsSettings[currentDeviceMode]['center'],
451 breakpointsSettings[currentDeviceMode]['radius'], 452 breakpointsSettings[currentDeviceMode]['valStroke'], 453 breakpointsSettings[currentDeviceMode]['bgStroke'], 454 breakpointsSettings[currentDeviceMode]['circumference'] 455 ); 456 457 elementorFrontend.waypoint( $scope, function() { 458 459 // animate counter 460 var $number = $scope.find( '.circle-counter__number' ), 461 data = $number.data(); 462 463 var decimalDigits = data.toValue.toString().match( /\.(.*)/ ); 464 465 if ( decimalDigits ) { 466 data.rounding = decimalDigits[1].length; 467 } 468 469 data.duration = duration; 470 471 $number.numerator( data ); 472 473 // animate progress 474 var circumference = parseInt( $progress.data( 'circumference' ) ), 475 dashoffset = circumference * (1 - progress); 476 477 $value.css({ 478 'transitionDuration': duration + 'ms', 479 'strokeDashoffset': dashoffset 480 }); 481 482 isAnimatedCircle = true; 483 484 }, JetElements.prepareWaypointOptions( $scope, { 485 offset: 'bottom-in-view' 486 } ) ); 487 488 $( window ).on( 'resize.jetCircleProgress orientationchange.jetCircleProgress', JetElementsTools.debounce( 50, function() { 489 currentDeviceMode = elementorFrontend.getCurrentDeviceMode(); 490 491 if ( breakpointsSettings[currentDeviceMode] ) { 492 updateSvgSizes( breakpointsSettings[currentDeviceMode]['size'], 493 breakpointsSettings[currentDeviceMode]['viewBox'], 494 breakpointsSettings[currentDeviceMode]['center'], 495 breakpointsSettings[currentDeviceMode]['radius'], 496 breakpointsSettings[currentDeviceMode]['valStroke'], 497 breakpointsSettings[currentDeviceMode]['bgStroke'], 498 breakpointsSettings[currentDeviceMode]['circumference'] 499 ); 500 } 501 } ) ); 502 503 function breakpointSizes( breakpointName, breakpointSize, breakpointStrokeValue, breakpointStrokeBg) { 504 var max, 505 radius; 506 507 breakpointsSettings[breakpointName]['size'] = breakpointSize; 508 breakpointsSettings[breakpointName]['viewBox'] = `0 0 ${breakpointSize} ${breakpointSize}`; 509 breakpointsSettings[breakpointName]['center'] = breakpointSize / 2; 510 radius = breakpointSize / 2; 511 max = ( breakpointStrokeValue >= breakpointStrokeBg ) ? breakpointStrokeValue : breakpointStrokeBg; 512 breakpointsSettings[breakpointName]['radius'] = radius - ( max / 2 ); 513 breakpointsSettings[breakpointName]['circumference'] = 2 * Math.PI * breakpointsSettings[breakpointName]['radius']; 514 breakpointsSettings[breakpointName]['valStroke'] = breakpointStrokeValue; 515 breakpointsSettings[breakpointName]['bgStroke'] = breakpointStrokeBg; 516 } 517 518 function updateSvgSizes( size, viewBox, center, radius, valStroke, bgStroke, circumference ) { 519 var dashoffset = circumference * (1 - progress); 520 521 $progress.attr( { 522 'width': size, 523 'height': size, 524 'data-radius': radius, 525 'data-circumference': circumference 526 } ); 527 528 $progress[0].setAttribute( 'viewBox', viewBox ); 529 530 $meter.attr( { 531 'cx': center, 532 'cy': center, 533 'r': radius, 534 'stroke-width': bgStroke 535 } ); 536 537 if ( isAnimatedCircle ) { 538 $value.css( { 539 'transitionDuration': '' 540 } ); 541 } 542 543 $value.attr( { 544 'cx': center, 545 'cy': center, 546 'r': radius, 547 'stroke-width': valStroke 548 } ); 549 550 $value.css( { 551 'strokeDasharray': circumference, 552 'strokeDashoffset': isAnimatedCircle ? dashoffset : circumference 553 } ); 554 } 555 }, 556 557 widgetCarousel: function( $scope ) { 558 559 var $carousel = $scope.find( '.jet-carousel' ), 560 fraction_nav = $carousel.find('.jet-carousel__fraction-navigation'); 561 562 if ( ! $carousel.length ) { 563 return; 564 } 565 566 if ( true === $carousel.data( 'slider_options' ).fractionNav ) { 567 $carousel.find( '.elementor-slick-slider' ).on( 'init reInit afterChange', function ( event, slick, currentSlide, nextSlide ) { 568 //currentSlide is undefined on init -- set it to 0 in this case (currentSlide is 0 based) 569 var i = ( currentSlide ? currentSlide : 0 ) + 1; 570 fraction_nav.html( '<span class="current">' + i + '</span>' + '<span class="separator">/</span>' + '<span class="total">
570' + slick.slideCount + '</span>'); 571 } ); 572 } 573 574 JetElements.initCarousel( $carousel.find( '.elementor-slick-slider' ), $carousel.data( 'slider_options' ) ); 575 576 }, 577 578 widgetPosts: function ( $scope ) { 579 580 var $target = $scope.find( '.jet-carousel' ), 581 settings = $target.data( 'slider_options' ); 582 583 if ( ! $target.length ) { 584 return; 585 } 586 587 settings['slide'] = '.jet-posts__item'; 588 589 JetElements.initCarousel( $target.find( '.jet-posts' ), settings ); 590 591 }, 592 593 widgetAnimatedText: function( $scope ) { 594 var $target = $scope.find( '.jet-animated-text' ), 595 instance = null, 596 settings = {}; 597 598 if ( ! $target.length ) { 599 return; 600 } 601 602 settings = $target.data( 'settings' ); 603 instance = new jetAnimatedText( $target, settings ); 604 instance.init(); 605 }, 606 607 widgetAnimatedBox: function( $scope ) { 608 609 JetElements.onAnimatedBoxSectionActivated( $scope ); 610 611 var $target = $scope.find( '.jet-animated-box' ), 612 defaultSettings = { 613 widgetId: null, 614 switchEventType: 'hover', 615 paperFoldDirection: 'left', 616 slideOutDirection: 'left' 617 }, 618 settings = $target.data( 'settings' ), 619 settings = $.extend( {}, defaultSettings, settings ), 620 scrollOffset = $( window ).scrollTop(), 621 firstMouseEvent = true, 622 editMode = Boolean( elementor.isEditMode() ); 623 624 if ( ! $target.length ) { 625 return; 626 } 627 628 switch( settings['switchEventType'] ) { 629 case 'hover': 630 if ( ! editMode ) { 631 hoverSwitchType(); 632 } else { 633 clickSwitchType(); 634 } 635 636 break; 637 638 case 'click': 639 clickSwitchType(); 640 break; 641 642 case 'toggle': 643 toggleSwitchType(); 644 break; 645 646 case 'scratch': 647 scratchSwitchType(); 648 break; 649 650 case 'fold': 651 foldSwitchType(); 652 break; 653 654 case 'peel': 655 peelSwitchType(); 656 break; 657 658 case 'slide-out': 659 slideOutSwitchType(); 660 break; 661 } 662 663 function hoverSwitchType() { 664 665 if ( 'ontouchend' in window || 'ontouchstart' in window ) { 666 $target.on( 'touchstart', function( event ) { 667 scrollOffset = $( window ).scrollTop(); 668 } ); 669 670 $target.on( 'touchend', function( event ) { 671 672 if ( scrollOffset !== $( window ).scrollTop() ) { 673 return false; 674 } 675 676 var $this = $( this ); 677 678 if ( $this.hasClass( 'flipped-stop' ) ) { 679 return; 680 } 681 682 setTimeout( function() { 683 $this.toggleClass( 'flipped' ); 684 }, 10 ); 685 } ); 686 687 $( document ).on( 'touchend', function( event ) { 688 689 if ( $( event.target ).closest( $target ).length ) { 690 return; 691 } 692 693 if ( $target.hasClass( 'flipped-stop' ) ) { 694 return; 695 } 696 697 if ( ! $target.hasClass( 'flipped' ) ) { 698 return; 699 } 700 701 $target.removeClass( 'flipped' ); 702 } ); 703 } else { 704 705 $target.on( 'mouseenter mouseleave', function( event ) { 706 707 if ( firstMouseEvent && 'mouseleave' === event.type ) { 708 return; 709 } 710 711 if ( firstMouseEvent && 'mouseenter' === event.type ) { 712 firstMouseEvent = false; 713 } 714 715 if ( ! $( this ).hasClass( 'flipped-stop' ) ) { 716 $( this ).toggleClass( 'flipped' ); 717 } 718 } ); 719 } 720 } 721 722 function clickSwitchType() { 723 if ( 'ontouchend' in window || 'ontouchstart' in window ) { 724 $target.on( 'touchstart', function( event ) { 725 scrollOffset = $( window ).scrollTop(); 726 } ); 727 728 $target.on( 'touchend', function( event ) { 729 730 if ( scrollOffset !== $( window ).scrollTop() ) { 731 return false; 732 } 733 734 var $this = $( this ); 735 736 if ( $this.hasClass( 'flipped-stop' ) ) { 737 return; 738 } 739 740 setTimeout( function() { 741 $this.toggleClass( 'flipped' ); 742 }, 10 ); 743 } ); 744 745 $( document ).on( 'touchend', function( event ) { 746 747 if ( $( event.target ).closest( $target ).length ) { 748 return; 749 } 750 751 if ( $target.hasClass( 'flipped-stop' ) ) { 752 return; 753 } 754 755 if ( ! $target.hasClass( 'flipped' ) ) { 756 return; 757 } 758 759 $target.removeClass( 'flipped' ); 760 } ); 761 } else { 762 $target.on( 'click', function( event ) { 763 764 if ( ! $target.hasClass( 'flipped-stop' ) ) { 765 $target.toggleClass( 'flipped' ); 766 } 767 } ); 768 } 769 } 770 771 function toggleSwitchType() {
772 if ( 'ontouchend' in window || 'ontouchstart' in window ) { 773 $target.on( 'touchstart', '.jet-animated-box__toggle', function( event ) { 774 775 if ( ! $target.hasClass( 'flipped-stop' ) ) { 776 $target.toggleClass( 'flipped' ); 777 } 778 } ); 779 } else { 780 $target.on( 'click', '.jet-animated-box__toggle', function( event ) { 781 782 if ( ! $target.hasClass( 'flipped-stop' ) ) { 783 $target.toggleClass( 'flipped' ); 784 } 785 } ); 786 } 787 } 788 789 function scratchSwitchType() { 790 791 if ( editMode ) { 792 return false; 793 } 794 795 var windowWidth = $( window ).width(); 796 797 $( 'html, body' ).scrollTop(0); 798 799 html2canvas( document.querySelector( '#jet-animated-box__front-' + settings['widgetId'] ), { 800 allowTaint: true, 801 backgroundColor: null, 802 windowWidth: $( window ).width(), 803 windowHeight: $( window ).height(), 804 scrollX: 0, 805 scrollY: -window.scrollY, 806 } ).then( function( canvas ) { 807 canvas.setAttribute( 'id', 'jet-animated-box-canvas-' + settings['widgetId'] ); 808 $target.prepend( canvas ); 809 810 $( '.jet-animated-box__front', $target ).fadeOut( 300, function() { 811 $( this ).remove(); 812 }); 813 814 $( window ).one( 'resize.jetScratch', function( e ) { 815 816 if ( $( window ).width() !== windowWidth ) { 817 windowWidth = $( window ).width(); 818 819 $( canvas ).fadeOut( 250, function() { 820 $( this ).remove(); 821 }); 822 } 823 824 } ); 825 826 var jetScratch = new jetScratchEffect( 827 '#jet-animated-box-' + settings['widgetId'], 828 '#jet-animated-box-canvas-' + settings['widgetId'], 829 function() { 830 $( canvas ).fadeOut( 300, function() { 831 $( this ).remove(); 832 $target.removeClass( 'back-events-inactive' ); 833 } ); 834 }, 835 settings['scratchFillPercent'] 836 ); 837 } ); 838 } 839 840 function foldSwitchType() { 841 842 if ( editMode ) { 843 $target.addClass( 'fold-init' ); 844 845 return false; 846 } 847 848 var folded = null, 849 frontSelector = '#jet-animated-box__front-' + settings['widgetId']; 850 851 folded = new OriDomi( document.querySelector( frontSelector ), { 852 vPanels: 5, 853 hPanels: 5, 854 speed: 500, 855 ripple: true, 856 shadingIntensity: .9, 857 perspective: 1000, 858 //maxAngle: 90, 859 shading: false, 860 gapNudge: 0, 861 touchSensitivity: .25, 862 touchMoveCallback: function( moveCoordinate, event ) { 863 864 if ( 89.5 < moveCoordinate ) { 865 $( frontSelector ).remove(); 866 } 867 } 868 }).accordion( 0, settings['paperFoldDirection'] ); 869 870 $target.addClass( 'fold-init' ); 871 } 872 873 function peelSwitchType() { 874 875 if ( editMode ) { 876 $target.addClass( 'peel-ready' ); 877 878 return false; 879 } 880 881 var $front = $( '.jet-animated-box__front', $target ), 882 $frontClone = $front.clone(); 883 884 $( '.jet-animated-box__front', $target ).addClass( 'peel-top' ); 885 886 $frontClone.removeAttr('id'); 887 $frontClone.addClass('peel-back'); 888 $frontClone.insertAfter( '#jet-animated-box__front-' + settings['widgetId'] ); 889 890 $( '.jet-animated-box__back', $target ).addClass( 'peel-bottom' ); 891 892 var peel = new Peel( '#jet-animated-box-' + settings['widgetId'], { 893 corner: Peel.Corners.TOP_RIGHT 894 } ); 895 896 var targetWidth = $target.width(), 897 targetHeight = $target.height(); 898 899 peel.setPeelPosition( targetWidth - 30, 40 ); 900 901 peel.setFadeThreshold(.8); 902 903 peel.handleDrag( function( evt, x, y ) { 904 var targetOffset = $target.offset(), 905 offsetX = targetOffset.left, 906 offsetY = targetOffset.top, 907 deltaX = x - offsetX, 908 deltaY = y - offsetY; 909 910 deltaX = deltaX < 0 ? deltaX*=3 : deltaX; 911 deltaY = deltaY < 0 ? deltaY*=3 : deltaY; 912 913 if ( 0.98 < this.getAmountClipped() ) { 914 this.removeEvents(); 915 916 $( '.peel-top, .peel-back, .peel-bottom-shadow', $target ).remove(); 917 } 918 919 peel.setPeelPosition( Math.round( deltaX ), Math.round( deltaY ) ); 920 921 }); 922 } 923 924 function slideOutSwitchType() { 925 926 var $frontSide = $( '.jet-animated-box__front', $target ), 927 $backSide = $( '.jet-animated-box__back', $target ), 928 $targetWidth = $target.width(), 929 $targetHeight = $target.height(), 930 axis = ( 'left' === settings.slideOutDirection || 'right' === settings.slideOutDirection ) ? 'x' : 'y'; 931 932 $frontSide.draggable( { 933 axis: axis, 934 drag: function( event, ui ) { 935 var dragData = ui.position; 936 switch( settings.slideOutDirection ) { 937 case 'left': 938 if ( dragData.left >= 0 ) { 939 ui.position.left = 0; 940 } 941 break; 942 case 'right': 943 if ( dragData.left <= 0 ) { 944 ui.position.left = 0; 945 } 946 break; 947 case 'top': 948 if ( dragData.top >= 0 ) { 949 ui.position.top = 0; 950 } 951 break; 952 case 'bottom': 953 if ( dragData.top <= 0 ) { 954 ui.position.top = 0; 955 } 956 break; 957 } 958 959 }, 960 } ); 961 962 } 963 }, 964 965 onAnimatedBoxSectionActivated: function( $scope ) { 966 if ( ! window.elementor ) { 967 return; 968 } 969 970 if ( ! window.JetElementsEditor ) { 971 return; 972 } 973 974 if ( ! window.JetElementsEditor.activeSection ) { 975 return; 976 } 977 978 var section = window.JetElementsEditor.activeSection; 979 var isBackSide = -1 !== [ 'section_back_content', 'section_action_button_style' ].indexOf( section ); 980 981 if ( isBackSide ) { 982 $scope.find( '.jet-animated-box' ).addClass( 'flipped' ); 983 $scope.find( '.jet-animated-box' ).addClass( 'flipped-stop' ); 984 } else { 985 $scope.find( '.jet-animated-box' ).removeClass( 'flipped' ); 986 $scope.find( '.jet-animated-box' ).removeClass( 'flipped-stop' ); 987 } 988 }, 989 990 widgetImagesLayout: function( $scope ) { 991 var $target = $scope.find( '.jet-images-layout' ), 992 instance = null, 993 settings = {}; 994 995 if ( ! $target.length ) { 996 return; 997 } 998 999 settings = $target.data( 'settings' ); 1000 instance = new jetImagesLayout( $target, settings ); 1001 instance.init(); 1002 }, 1003 1004 widgetPortfolio: function( $scope ) { 1005 var $target = $scope.find( '.jet-portfolio' ), 1006 instance = null, 1007 eSettings = JetElementsTools.getElementorElementSettings( $scope ), 1008 settings = { 1009 id: $scope.data( 'id' ) 1010 }; 1011 1012 if ( ! $target.length ) { 1013 return; 1014 } 1015 1016 settings = $.extend( {}, settings, $target.data( 'settings' ), eSettings ); 1017 instance = new jetPortfolio( $target, settings ); 1018 instance.init(); 1019 }, 1020 1021 widgetInstagramGallery: function( $scope ) { 1022 var $target = $scope.find( '.jet-instagram-gallery__instance' ), 1023 instance = null, 1024 defaultSettings = {}, 1025 settings = {}; 1026 1027 if ( ! $target.length ) { 1028 return; 1029 } 1030 1031 settings = $target.data( 'settings' ), 1032 1033 /* 1034 * Default Settings 1035 */ 1036 defaultSettings = { 1037 layoutType: 'masonry', 1038 } 1039 /** 1040 * Checking options, settings and options merging 1041 */ 1042 $.extend( defaultSettings, settings ); 1043 1044 if ( 'masonry' === settings.layoutType ) {
1045 salvattore.init(); 1046 1047 $( window ).on( 'resize orientationchange', function() { 1048 salvattore.rescanMediaQueries(); 1049 } ) 1050 } 1051 }, 1052 1053 widgetScrollNavigation: function( $scope ) { 1054 var $target = $scope.find( '.jet-scroll-navigation' ), 1055 instance = null, 1056 settings = $target.data( 'settings' ); 1057 1058 instance = new jetScrollNavigation( $scope, $target, settings ); 1059 instance.init(); 1060 }, 1061 1062 widgetSubscribeForm: function( $scope ) { 1063 var $target = $scope.find( '.jet-subscribe-form' ), 1064 scoreId = $scope.data( 'id' ), 1065 settings = $target.data( 'settings' ), 1066 jetSubscribeFormAjax = null, 1067 subscribeFormAjax = 'jet_subscribe_form_ajax', 1068 ajaxRequestSuccess = false, 1069 $subscribeForm = $( '.jet-subscribe-form__form', $target ), 1070 $fields = $( '.jet-subscribe-form__fields', $target ), 1071 $mailField = $( '.jet-subscribe-form__mail-field', $target ), 1072 $inputData = $mailField.data( 'instance-data' ), 1073 $submitButton = $( '.jet-subscribe-form__submit', $target ), 1074 $subscribeFormMessage = $( '.jet-subscribe-form__message', $target ), 1075 timeout = null, 1076 invalidMailMessage = window.jetElements.messages.invalidMail || 'Please specify a valid email'; 1077 1078 $mailField.on( 'focus', function() { 1079 $mailField.removeClass( 'mail-invalid' ); 1080 } ); 1081 1082 $( document ).keydown( function( event ) { 1083 1084 if ( 13 === event.keyCode && $mailField.is( ':focus' ) ) { 1085 subscribeHandle(); 1086 1087 return false; 1088 } 1089 } ); 1090 1091 $submitButton.on( 'click', function() { 1092 subscribeHandle(); 1093 1094 return false; 1095 } ); 1096 1097 function subscribeHandle() { 1098 var inputValue = $mailField.val(), 1099 sendData = { 1100 'email': inputValue, 1101 'use_target_list_id': settings['use_target_list_id'] || false, 1102 'target_list_id': settings['target_list_id'] || '', 1103 'data': $inputData 1104 }, 1105 serializeArray = $subscribeForm.serializeArray(), 1106 additionalFields = {}; 1107 1108 if ( JetElementsTools.validateEmail( inputValue ) ) { 1109 1110 $.each( serializeArray, function( key, fieldData ) { 1111 1112 if ( 'email' === fieldData.name ) { 1113 sendData[ fieldData.name ] = fieldData.value; 1114 } else { 1115 additionalFields[ fieldData.name ] = fieldData.value; 1116 } 1117 } ); 1118 1119 sendData['additional'] = additionalFields; 1120 1121 if ( ! ajaxRequestSuccess && jetSubscribeFormAjax ) { 1122 jetSubscribeFormAjax.abort(); 1123 } 1124 1125 jetSubscribeFormAjax = $.ajax( { 1126 type: 'POST', 1127 url: window.jetElements.ajaxUrl, 1128 data: { 1129 action: subscribeFormAjax, 1130 data: sendData 1131 }, 1132 cache: false, 1133 beforeSend: function() { 1134 $submitButton.addClass( 'loading' ); 1135 ajaxRequestSuccess = false; 1136 }, 1137 success: function( data ){ 1138 var successType = data.type, 1139 message = data.message || '', 1140 responceClass = 'jet-subscribe-form--response-' + successType; 1141 1142 $submitButton.removeClass( 'loading' ); 1143 ajaxRequestSuccess = true; 1144 1145 $target.removeClass( 'jet-subscribe-form--response-error' ); 1146 $target.addClass( responceClass ); 1147 1148 $( 'span', $subscribeFormMessage ).html( message ); 1149 $subscribeFormMessage.css( { 'visibility': 'visible' } ); 1150 1151 timeout = setTimeout( function() { 1152 $subscribeFormMessage.css( { 'visibility': 'hidden' } ); 1153 $target.removeClass( responceClass ); 1154 }, 20000 ); 1155 1156 if ( settings['redirect'] ) { 1157 window.location.href = settings['redirect_url']; 1158 } 1159 1160 $( window ).trigger( { 1161 type: 'jet-elements/subscribe', 1162 elementId: scoreId, 1163 successType: successType, 1164 inputData: $inputData 1165 } ); 1166 } 1167 }); 1168 1169 } else { 1170 $mailField.addClass( 'mail-invalid' ); 1171 1172 $target.addClass( 'jet-subscribe-form--response-error' ); 1173 $( 'span', $subscribeFormMessage ).html( invalidMailMessage ); 1174 $subscribeFormMessage.css( { 'visibility': 'visible' } ); 1175 1176 timeout = setTimeout( function() { 1177 $target.removeClass( 'jet-subscribe-form--response-error' ); 1178 $subscribeFormMessage.css( { 'visibility': 'hidden' } ); 1179 $mailField.removeClass( 'mail-invalid' ); 1180 }, 20000 ); 1181 } 1182 } 1183 }, 1184 1185 widgetProgressBar: function( $scope ) { 1186 var $target = $scope.find( '.jet-progress-bar' ), 1187 percent = $target.data( 'percent' ), 1188 type = $target.data( 'type' ), 1189 deltaPercent = percent * 0.01; 1190 1191 elementorFrontend.waypoint( $target, function( direction ) { 1192 var $this = $( this ), 1193 animeObject = { charged: 0 }, 1194 $statusBar = $( '.jet-progress-bar__status-bar', $this ), 1195 $percent = $( '.jet-progress-bar__percent-value', $this ), 1196 animeProgress, 1197 animePercent; 1198 1199 if ( 'type-7' == type ) { 1200 $statusBar.css( { 1201 'height': percent + '%' 1202 } ); 1203 } else { 1204 $statusBar.css( { 1205 'width': percent + '%' 1206 } ); 1207 } 1208 1209 animePercent = anime({ 1210 targets: animeObject, 1211 charged: percent, 1212 round: 1, 1213 duration: 1000, 1214 easing: 'easeInOutQuad', 1215 update: function() { 1216 $percent.html( animeObject.charged ); 1217 } 1218 } ); 1219 1220 }, JetElements.prepareWaypointOptions( $scope ) ); 1221 }, 1222 1223 widgetSlider: function( $scope ) { 1224 var $target = $scope.find( '.jet-slider' ), 1225 $imagesTagList = $( '.sp-image', $target ), 1226 item = $( '.jet-slider__item', $target ), 1227 instance = null, 1228 item_url = '', 1229 item_url_target = '', 1230 defaultSettings = { 1231 imageScaleMode: 'cover', 1232 slideDistance: { size: 10, unit: 'px' }, 1233 slideDuration: 500, 1234 sliderAutoplay: true, 1235 sliderAutoplayDelay: 2000,
1236 sliderAutoplayOnHover: 'pause', 1237 sliderFadeMode: false, 1238 sliderFullScreen: true, 1239 sliderFullscreenIcon: '', 1240 sliderHeight: { size: 600, unit: 'px' }, 1241 sliderLoop: true, 1242 sliderNaviOnHover: false, 1243 sliderNavigation: true, 1244 sliderNavigationIcon: '', 1245 sliderPagination: false, 1246 sliderShuffle: false, 1247 sliderWidth: { size: 100, unit: '%' }, 1248 thumbnailWidth: 120, 1249 thumbnailHeight: 80, 1250 thumbnails: true, 1251 rightToLeft: false, 1252 }, 1253 instanceSettings = $target.data( 'settings' ) || {}, 1254 breakpoints = JetElementsTools.getElementorElementSettings( $scope ), 1255 breakpointsSettings = {}, 1256 defaultHeight, 1257 defaultThumbHeight, 1258 defaultThumbWidth, 1259 activeBreakpoints = elementor.config.responsive.activeBreakpoints, 1260 settings = $.extend( {}, defaultSettings, instanceSettings ), 1261 fraction_nav = $target.find( '.jet-slider__fraction-pagination' ); 1262 1263 if ( ! $target.length ) { 1264 return; 1265 } 1266 1267 item.each( function() { 1268 var _this = $( this ).find( '.jet-slider__content' ); 1269 1270 if ( _this.data( 'slide-url' ) && !elementor.isEditMode() ) { 1271 let clickXPos, 1272 clickYPos; 1273 1274 _this.on( 'mousedown touchstart', function( e ) { 1275 window.XPos = e.pageX || e.originalEvent.changedTouches[0].pageX; 1276 window.YPos = e.pageY || e.originalEvent.changedTouches[0].pageY; 1277 } ) 1278 1279 _this.on( 'mouseup touchend', function( e ) { 1280 item_url = _this.data( 'slide-url' ); 1281 item_url_target = _this.data( 'slide-url-target' ); 1282 clickXPos = e.pageX || e.originalEvent.changedTouches[0].pageX; 1283 clickYPos = e.pageY || e.originalEvent.changedTouches[0].pageY; 1284 1285 if ( window.XPos === clickXPos && window.YPos === clickYPos ) { 1286 if ( '_blank' === item_url_target ) { 1287 window.open( item_url ); 1288 return; 1289 } else { 1290 window.location = item_url; 1291 } 1292 } 1293 } ); 1294 } 1295 } ); 1296 1297 defaultHeight = ( breakpoints['slider_height'] && '' != breakpoints['slider_height']['size'] ) ? breakpoints['slider_height']['size'] + breakpoints['slider_height']['unit'] : '600px'; 1298 1299 defaultThumbHeight = ( breakpoints['thumbnail_height'] && '' != breakpoints['thumbnail_height']['size'] ) ? breakpoints['thumbnail_height']['size'] : 80; 1300 1301 defaultThumbWidth = ( breakpoints['thumbnail_width'] && '' != breakpoints['thumbnail_width']['size'] ) ? breakpoints['thumbnail_width']['size'] : 120; 1302 1303 Object.keys( activeBreakpoints ).forEach( function( breakpointName ) { 1304 1305 if ( 'widescreen' === breakpointName ) { 1306 var breakpoint = activeBreakpoints[breakpointName].value - 1, 1307 1308 breakpointHeight = '' != breakpoints['slider_height_' + breakpointName]['size'] ? breakpoints['slider_height_' + breakpointName]['size'] + breakpoints['slider_height_' + breakpointName]['unit'] : defaultHeight, 1309 1310 breakpointThumbHeight = '' != breakpoints['thumbnail_height_' + breakpointName] ? breakpoints['thumbnail_height_' + breakpointName] : defaultThumbHeight, 1311 1312 breakpointThumbWidth = '' != breakpoints['thumbnail_width_' + breakpointName] ? breakpoints['thumbnail_width_' + breakpointName] : defaultThumbWidth, 1313 1314 desktopHeight = '' != breakpoints['slider_height']['size'] ? breakpoints['slider_height']['size'] + breakpoints['slider_height']['unit'] : settings['sliderHeight']['size'] + settings['sliderHeight']['unit'], 1315 1316 desktopThumbHeight = '' != breakpoints['thumbnail_height'] ? breakpoints['thumbnail_height'] : settings['thumbnailHeight'], 1317 1318 desktopThumbWidth = '' != breakpoints['thumbnail_width'] ? breakpoints['thumbnail_width'] : settings['thumbnailWidth']; 1319 1320 if ( breakpointHeight || breakpointThumbHeight || breakpointThumbWidth ) { 1321 breakpointsSettings[breakpoint] = {}; 1322 } else { 1323 return; 1324 } 1325 1326 if ( breakpointHeight ) { 1327 defaultHeight = breakpointHeight; 1328 1329 breakpointsSettings[breakpoint]['height'] = desktopHeight; 1330 } 1331 1332 if ( breakpointThumbHeight ) { 1333 defaultThumbHeight = breakpointThumbHeight; 1334 1335 breakpointsSettings[breakpoint]['thumbnailHeight'] = desktopThumbHe
1335ight; 1336 } 1337 1338 if ( breakpointThumbWidth ) { 1339 defaultThumbWidth = breakpointThumbWidth; 1340 1341 breakpointsSettings[breakpoint]['thumbnailWidth'] = desktopThumbWidth; 1342 } 1343 1344 } else { 1345 var breakpoint = activeBreakpoints[breakpointName].value - 1, 1346 1347 breakpointThumbHeight = breakpoints['thumbnail_height_' + breakpointName] ? breakpoints['thumbnail_height_' + breakpointName] : false, 1348 breakpointThumbWidth = breakpoints['thumbnail_width_' + breakpointName] ? breakpoints['thumbnail_width_' + breakpointName] : false; 1349 1350 breakpointHeight = breakpoints['slider_height_' + breakpointName]['size'] ? breakpoints['slider_height_' + breakpointName]['size'] + breakpoints['slider_height_' + breakpointName]['unit'] : false; 1351 1352 if ( breakpointHeight || breakpointThumbHeight || breakpointThumbWidth ) { 1353 breakpointsSettings[breakpoint] = {}; 1354 } else { 1355 return; 1356 } 1357 1358 if ( breakpointHeight ) { 1359 breakpointsSettings[breakpoint]['height'] = breakpointHeight; 1360 } 1361 1362 if ( breakpointThumbHeight ) { 1363 breakpointsSettings[breakpoint]['thumbnailHeight'] = breakpointThumbHeight; 1364 } 1365 1366 if ( breakpointThumbWidth ) { 1367 breakpointsSettings[breakpoint]['thumbnailWidth'] = breakpointThumbWidth; 1368 } 1369 } 1370 } ); 1371 1372 $( '.slider-pro', $target ).sliderPro( { 1373 width: settings['sliderWidth']['size'] + settings['sliderWidth']['unit'], 1374 height: defaultHeight, 1375 arrows: settings['sliderNavigation'], 1376 fadeArrows: settings['sliderNaviOnHover'], 1377 buttons: settings['sliderPagination'], 1378 autoplay: settings['sliderAutoplay'], 1379 autoplayDelay: settings['sliderAutoplayDelay'], 1380 autoplayOnHover: settings['sliderAutoplayOnHover'], 1381 fullScreen: settings['sliderFullScreen'], 1382 shuffle: settings['sliderShuffle'], 1383 loop: settings['sliderLoop'], 1384 fade: settings['sliderFadeMode'], 1385 slideDistance: ( 'string' !== typeof settings['slideDistance']['size'] ) ? settings['slideDistance']['size'] : 0, 1386 slideAnimationDuration: +settings['slideDuration'], 1387 imageScaleMode: 'exact', 1388 waitForLayers: false, 1389 grabCursor: false, 1390 thumbnailWidth: defaultThumbWidth, 1391 thumbnailHeight: defaultThumbHeight, 1392 rightToLeft: settings['rightToLeft'], 1393 touchSwipe: settings['touchswipe'], 1394 init: function() { 1395 var fullscreenIconHtml = $( '.' + settings['sliderFullscreenIcon'] ).html(), 1396 arrowIconHtml = $( '.' + settings['sliderNavigationIcon'] ).html(); 1397 1398 $( '.sp-full-screen-button', $target ).html( fullscreenIconHtml ); 1399 $( '.sp-previous-arrow', $target ).html( arrowIconHtml ); 1400 $( '.sp-next-arrow', $target ).html( arrowIconHtml ); 1401 $( '.slider-pro', $target ).addClass( 'slider-loaded' ); 1402 1403 this.resize(); 1404 }, 1405 gotoSlideComplete: function() { 1406 if ( true === settings['fractionPag'] ) { 1407 var i = ( this.getSelectedSlide() ? this.getSelectedSlide() : 0 ) + 1; 1408 1409 fraction_nav.html( '<span class="current">' + i + '</span>' + '<span class="separator">/</span>' + '<span class="total">' + this.getTotalSlides() + '</span>'); 1410 } 1411 }, 1412 update: function() { 1413 if ( true === settings['fractionPag'] ) { 1414 var i = ( this.getSelectedSlide() ? this.getSelectedSlide() : 0 ) + 1; 1415 1416 fraction_nav.html( '<span class="current">' + i + '</span>' + '<span class="separator">/</span>' + '<span class="total">' + this.getTotalSlides() + '</span>'); 1417 } 1418 }, 1419 breakpoints: breakpointsSettings 1420 } ); 1421
1422 $( '.slider-pro', $target ).on( 'gotoSlide', function() { 1423 $target.find( '[data-element_type]' ).each( function() { 1424 window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $( this ), $ ); 1425 } ); 1426 } ); 1427 1428 }, 1429 1430 widgetTestimonials: function( $scope ) { 1431 var $target = $scope.find( '.jet-testimonials__instance' ), 1432 $imagesTagList = $( '.jet-testimonials__figure', $target ), 1433 targetContent = $( '.jet-testimonials__content', $target ), 1434 instance = null, 1435 settings = $target.data( 'settings' ), 1436 ratingSettings = $target.data( 'rating-settings' ); 1437 1438 if ( ! $target.length ) { 1439 return; 1440 } 1441 1442 targetContent.each( function() { 1443 var ratingList = $( '.jet-testimonials__rating', this ); 1444 1445 if ( ratingList ) { 1446 var rating = ratingList.data('rating'); 1447 1448 ratingList.each( function() { 1449 1450 $( 'i', this ).each( function( index ) { 1451 if ( index <= rating - 1 ) { 1452 var itemClass = $( this ).data( 'active-star' ); 1453 $( this ).addClass( itemClass ); 1454 } else { 1455 var itemClass = $( this ).data( 'star' ); 1456 $( this ).addClass( itemClass ); 1457 } 1458 } ) 1459 } ) 1460 } 1461 } ) 1462 1463 settings.adaptiveHeight = settings['adaptiveHeight']; 1464 1465 settings['slide'] = '.jet-testimonials__item'; 1466 1467 JetElements.initCarousel( $target, settings ); 1468 }, 1469 1470 widgetImageComparison: function( $scope ) { 1471 var $target = $scope.find( '.jet-image-comparison__instance' ), 1472 instance = null, 1473 imageComparisonItems = $( '.jet-image-comparison__container', $target ), 1474 settings = $target.data( 'settings' ), 1475 elementId = $scope.data( 'id' ); 1476 1477 if ( ! $target.length ) { 1478 return; 1479 } 1480 1481 window.juxtapose.scanPage( '.jet-juxtapose' ); 1482 1483 settings.draggable = false; 1484 settings.infinite = false; 1485 //settings.adaptiveHeight = true; 1486 JetElements.initCarousel( $target, settings ); 1487 }, 1488 1489 widgetTimeTable: function( $scope ) { 1490 1491 var $mptt_shortcode_wrapper = $scope.find( '.mptt-shortcode-wrapper' ); 1492 1493 if ( ( typeof typenow ) !== 'undefined' ) { 1494 if ( pagenow === typenow ) { 1495 switch ( typenow ) { 1496 1497 case 'mp-event': 1498 Registry._get( 'Event' ).init(); 1499 break; 1500 1501 case 'mp-column': 1502 Registry._get( 'Event' ).initDatePicker(); 1503 Registry._get( 'Event' ).columnRadioBox(); 1504 break; 1505 1506 default: 1507 break; 1508 } 1509 } 1510 } 1511 1512 if ( $mptt_shortcode_wrapper.length ) { 1513 1514 Registry._get( 'Event' ).initTableData(); 1515 Registry._get( 'Event' ).filterShortcodeEvents(); 1516 Registry._get( 'Event' ).getFilterByHash(); 1517 1518 $mptt_shortcode_wrapper.show(); 1519 } 1520 1521 if ( $( '.upcoming-events-widget' ).length || $mptt_shortcode_wrapper.length ) { 1522 Registry._get( 'Event' ).setColorSettings(); 1523 } 1524 }, 1525 1526 elementorSection: function( $scope ) { 1527 var $target = $scope, 1528 instance = null, 1529 editMode = Boolean( elementor.isEditMode() ); 1530 1531 instance = new jetSectionParallax( $target ); 1532 instance.init(); 1533 }, 1534 1535 initCarousel: function( $target, options ) { 1536 1537 var defaultOptions, 1538 slickOptions, 1539 responsive = [], 1540 eTarget = $target.closest( '.elementor-widget' ), 1541 breakpoints = JetElementsTools.getElementorElementSettings( eTarget ), 1542 activeBreakpoints = elementor.config.responsive.activeBreakpoints, 1543 prevDeviceToShowValue, 1544 prevDeviceToScrollValue, 1545 slidesCount, 1546 dotsEnable = options.dots; 1547 1548 if ( $target.hasClass( 'jet-posts' ) && $target.parent().hasClass( 'jet-carousel' ) ) { 1549 function renameKeys( obj, newKeys ) { 1550 const keyValues = Object.keys( obj ).map( key => { 1551 const newKey = newKeys[key] || key; 1552 return { [newKey]: obj[key] }; 1553 } ); 1554 return Object.assign( {}, ...keyValues ); 1555 } 1556 1557 var newBreakpointsKeys = { 1558 columns: "slides_to_show", 1559 columns_widescreen: "slides_to_show_widescreen", 1560 columns_laptop: "slides_to_show_laptop", 1561 columns_tablet_extra: "slides_to_show_tablet_extra", 1562 columns_tablet: "slides_to_show_tablet", 1563 columns_mobile_extra: "slides_to_show_mobile_extra", 1564 columns_mobile: "slides_to_show_mobile" 1565 }; 1566 1567 breakpoints = renameKeys( breakpoints, newBreakpointsKeys ); 1568 slidesCount = $( '> div.jet-posts__item', $target ).length; 1569 } else { 1570 slidesCount = $( '> div', $target ).length; 1571 } 1572 1573 options.slidesToShow = +breakpoints.slides_to_show; 1574 1575 Object.keys( activeBreakpoints ).forEach( function( breakpointName ) { 1576 if ( 'widescreen' === breakpointName ) { 1577 options.slidesToShow = breakpoints.slides_to_show_widescreen ? +breakpoints.slides_to_show_widescreen : +breakpoints.slides_to_show; 1578 1579 if ( breakpoints.slides_to_scroll_widescreen ) { 1580 options.slidesToScroll = '' != breakpoints.slides_to_scroll_widescreen ? +breakpoints.slides_to_scroll_widescreen : +breakpoints.slides_to_scroll; 1581 } else { 1582 options.slidesToScroll = 1; 1583 } 1584 } 1585 } ); 1586 1587 if ( options.slidesToShow >= slidesCount ) { 1588 options.dots = false;
1589 } 1590 1591 prevDeviceToShowValue = options.slidesToShow; 1592 prevDeviceToScrollValue = options.slidesToScroll; 1593 1594 $target.on( 'init reInit', function() { 1595 if ( options.infinite ) { 1596 var $items = $( this ), 1597 $clonedSlides = $( '> .slick-list > .slick-track > .slick-cloned.jet-carousel__item', $items ); 1598 1599 if ( !$clonedSlides.length ) { 1600 return; 1601 } 1602 1603 JetElements.initElementsHandlers( $clonedSlides ); 1604 1605 } 1606 } ); 1607 1608 if ( $target.hasClass( 'slick-initialized' ) ) { 1609 $target.slick( 'refresh', true ); 1610 return; 1611 } 1612 1613 Object.keys( activeBreakpoints ).reverse().forEach( function( breakpointName ) { 1614 1615 if ( breakpoints['slides_to_show_' + breakpointName] || breakpoints['slides_to_scroll_' + breakpointName] ) { 1616 1617 var breakpointSetting = { 1618 breakpoint: null, 1619 settings: {} 1620 } 1621 1622 breakpointSetting.breakpoint = 'widescreen' != breakpointName ? activeBreakpoints[breakpointName].value : activeBreakpoints[breakpointName].value - 1; 1623 1624 if ( 'widescreen' === breakpointName ) { 1625 breakpointSetting.settings.slidesToShow = +breakpoints['slides_to_show']; 1626 breakpointSetting.settings.slidesToScroll = +breakpoints['slides_to_scroll']; 1627 } else { 1628 breakpointSetting.settings.slidesToShow = breakpoints['slides_to_show_' + breakpointName] ? +breakpoints['slides_to_show_' + breakpointName] : prevDeviceToShowValue; 1629 1630 breakpointSetting.settings.slidesToScroll = breakpoints['slides_to_scroll_' + breakpointName] ? +breakpoints['slides_to_scroll_' + breakpointName] : prevDeviceToScrollValue; 1631 } 1632 1633 $target.on( 'init reInit', function( event, slick, currentSlide, nextSlide ) { 1634 if ( breakpointSetting.settings.slidesToShow >= slick.slideCount ) { 1635 breakpointSetting.settings.dots = false; 1636 } else { 1637 if ( dotsEnable ) { 1638 breakpointSetting.settings.dots = true; 1639 } 1640 } 1641 } ); 1642 1643 prevDeviceToShowValue = breakpointSetting.settings.slidesToShow; 1644 prevDeviceToScrollValue = breakpointSetting.settings.slidesToScroll 1645 1646 responsive.push( breakpointSetting ); 1647 } 1648 } ); 1649 1650 options.responsive = responsive; 1651 1652 if ( options.slidesToShow >= slidesCount ) { 1653 options.dots = false; 1654 } 1655 1656 defaultOptions = { 1657 customPaging: function(slider, i) { 1658 return $( '<span />' ).text( i + 1 ); 1659 }, 1660 dotsClass: 'jet-slick-dots' 1661 }; 1662 1663 slickOptions = $.extend( {}, defaultOptions, options ); 1664 1665 $target.slick( slickOptions ); 1666 }, 1667 1668 widgetTimeLine : function ( $scope ){ 1669 var $target = $scope.find( '.jet-timeline' ), 1670 instance = null; 1671 1672 if ( ! $target.length ) { 1673 return; 1674 } 1675 1676 instance = new jetTimeLine( $target ); 1677 instance.init(); 1678 }, 1679 1680 widgetTable: function( $scope ) { 1681 var $target = $scope.find( '.jet-table' ), 1682 options = { 1683 cssHeader: 'jet-table-header-sort', 1684 cssAsc: 'jet-table-header-sort--up', 1685 cssDesc: 'jet-table-header-sort--down', 1686 initWidgets: false 1687 }; 1688 1689 if ( ! $target.length ) { 1690 return; 1691 } 1692 1693 if ( $target.hasClass( 'jet-table--sorting' ) ) { 1694 $target.tablesorter( options ); 1695 } 1696 1697 $( '.jet-table__body-row', $target ).each( function() { 1698 var _this = $( this ), 1699 itemsCounter = 0, 1700 emptyContents = 0; 1701 1702 $( '.jet-table__cell', _this ).each( function() { 1703 var image = $( 'img', $( this ) ), 1704 svg = $( 'svg', $( this ) ), 1705 icon = $( 'i', $( this ) ), 1706 itemImages = 0; 1707 1708 if ( 0 === svg.length && 0 === icon.length ) { 1709 image.each( function() { 1710 if ( '' != $( this ).attr( 'src' ) ) { 1711 itemImages++; 1712 } 1713 } ) 1714 1715 if ( 0 === $( this ).text().length && 0 === itemImages ) { 1716 emptyContents++; 1717 } 1718 } 1719 1720 itemsCounter++; 1721 } ) 1722 1723 if( emptyContents === itemsCounter ) { 1724 _this.remove(); 1725 } 1726 } ) 1727 }, 1728 1729 widgetDropbar: function( $scope ) { 1730 var $dropbar = $scope.find( '.jet-dropbar' ), 1731 $dropbar_inner = $dropbar.find( '.jet-dropbar__inner' ), 1732 $btn = $dropbar.find( '.jet-dropbar__button' ), 1733 $content = $dropbar.find( '.jet-dropbar__content' ), 1734 settings = $dropbar.data( 'settings' ) || {}, 1735 mode = settings['mode'] || 'hover', 1736 hide_delay = +settings['hide_delay'] || 0, 1737 activeClass = 'jet-dropbar-open', 1738 scrollOffset, 1739 timer; 1740 1741 if ( 'click' === mode ) { 1742 $btn.on( 'click.jetDropbar', function( event ) { 1743 $dropbar.toggleClass( activeClass ); 1744 } ); 1745 } else {
1746 if ( 'ontouchstart' in window || 'ontouchend' in window ) { 1747 $btn.on( 'touchend.jetDropbar', function( event ) { 1748 if ( $( window ).scrollTop() !== scrollOffset ) { 1749 return; 1750 } 1751 1752 $dropbar.toggleClass( activeClass ); 1753 } ); 1754 } else { 1755 $dropbar_inner.on( 'mouseenter.jetDropbar', function( event ) { 1756 clearTimeout( timer ); 1757 $dropbar.addClass( activeClass ); 1758 } ); 1759 1760 $dropbar_inner.on( 'mouseleave.jetDropbar', function( event ) { 1761 timer = setTimeout( function() { 1762 $dropbar.removeClass( activeClass ); 1763 }, hide_delay ); 1764 } ); 1765 } 1766 } 1767 1768 $( document ).on( 'touchstart.jetDropbar', function( event ) { 1769 scrollOffset = $( window ).scrollTop(); 1770 } ); 1771 1772 $( document ).on( 'click.jetDropbar touchend.jetDropbar', function( event ) { 1773 1774 if ( 'touchend' === event.type && $( window ).scrollTop() !== scrollOffset ) { 1775 return; 1776 } 1777 1778 if ( $( event.target ).closest( $btn ).length || $( event.target ).closest( $content ).length ) { 1779 return; 1780 } 1781 1782 if ( ! $dropbar.hasClass( activeClass ) ) { 1783 return; 1784 } 1785 1786 $dropbar.removeClass( activeClass ); 1787 } ); 1788 }, 1789 1790 widgetVideo: function( $scope ) { 1791 var $video = $scope.find( '.jet-video' ), 1792 $iframe = $scope.find( '.jet-video-iframe' ), 1793 $videoPlaer = $scope.find( '.jet-video-player' ), 1794 $mejsPlaer = $scope.find( '.jet-video-mejs-player' ), 1795 mejsPlaerControls = $mejsPlaer.data( 'controls' ) || ['playpause', 'current', 'progress', 'duration', 'volume', 'fullscreen'], 1796 $overlay = $scope.find( '.jet-video__overlay' ), 1797 hasOverlay = $overlay.length > 0, 1798 settings = $video.data( 'settings' ) || {}, 1799 lightbox = settings.lightbox || false, 1800 autoplay = settings.autoplay || false; 1801 1802 if ( $overlay[0] ) { 1803 $overlay.on( 'click.jetVideo', function( event ) { 1804 1805 if ( $videoPlaer[0] ) { 1806 $videoPlaer[0].play(); 1807 1808 $overlay.remove(); 1809 hasOverlay = false; 1810 1811 return; 1812 } 1813 1814 if ( $iframe[0] ) { 1815 iframeStartPlay(); 1816 } 1817 } ); 1818 } 1819 1820 if ( autoplay && $iframe[0] && $overlay[0] ) { 1821 iframeStartPlay(); 1822 } 1823 1824 function iframeStartPlay() { 1825 var lazyLoad = $iframe.data( 'lazy-load' ); 1826 1827 if ( lazyLoad ) { 1828 $iframe.attr( 'src', lazyLoad ); 1829 } 1830 1831 if ( ! autoplay ) { 1832 $iframe[0].src = $iframe[0].src.replace( '&autoplay=0', '&autoplay=1' ); 1833 } 1834 1835 $overlay.remove(); 1836 hasOverlay = false; 1837 } 1838 1839 if ( $videoPlaer[0] ) { 1840 $videoPlaer.on( 'play.jetVideo', function( event ) { 1841 if ( hasOverlay ) { 1842 $overlay.remove(); 1843 hasOverlay = false; 1844 } 1845 } ); 1846 1847 if ( autoplay ) { 1848 $overlay.remove(); 1849 } 1850 } 1851 1852 if ( $mejsPlaer[0] ) { 1853 $mejsPlaer.mediaelementplayer( { 1854 videoVolume: 'horizontal', 1855 hideVolumeOnTouchDevices: false, 1856 enableProgressTooltip: false, 1857 features: mejsPlaerControls, 1858 success: function( media ) { 1859 media.addEventListener( 'timeupdate', function( event ) { 1860 var $currentTime = $scope.find( '.mejs-time-current' ), 1861 inlineStyle = $currentTime.attr( 'style' ); 1862 1863 if ( inlineStyle ) { 1864 var scaleX = inlineStyle.match(/scaleX\([0-9.]*\)/gi)[0].replace( 'scaleX(', '' ).replace( ')', '' ); 1865 1866 if ( scaleX ) { 1867 $currentTime.css( 'width', scaleX * 100 + '%' ); 1868 } 1869 } 1870 }, false ); 1871 } 1872 } ); 1873 } 1874 }, 1875 1876 widgetAudio: function( $scope ) { 1877 var $wrapper = $scope.find( '.jet-audio' ), 1878 $player = $scope.find( '.jet-audio-player' ), 1879 settings = $wrapper.data( 'audio-settings' ), 1880 unmuted = 0, 1881 hasVolume = false, 1882 startVolume; 1883 1884 if ( ! $player[0] ) { 1885 return; 1886 } 1887 1888 startVolume = settings['startVolume'] || 0.8; 1889 1890 settings['controls'].map( function( control ) { 1891 if ( 'volume' === control ) { 1892 hasVolume = true; 1893 } 1894 } ); 1895 1896 $player.mediaelementplayer( { 1897 features: settings['controls'] || ['playpause', 'current', 'progress', 'duration', 'volume'], 1898 audioVolume: settings['audioVolume'] || 'horizontal', 1899 startVolume: startVolume, 1900 hideVolumeOnTouchDevices: settings['hideVolumeOnTouchDevices'], 1901 enableProgressTooltip: false, 1902 success: function( media ) { 1903 var muteBtn = $scope.find( '.mejs-button button' ); 1904 1905 media.addEventListener( 'timeupdate', function( event ) { 1906 var $currentTime = $scope.find( '.mejs-time-current' ), 1907 inlineStyle = $currentTime.attr( 'style' ); 1908 1909 if ( inlineStyle ) {
1910 var scaleX = inlineStyle.match(/scaleX\([0-9.]*\)/gi)[0].replace( 'scaleX(', '' ).replace( ')', '' ); 1911 1912 if ( scaleX ) { 1913 $currentTime.css( 'width', scaleX * 100 + '%' ); 1914 } 1915 } 1916 }, false ); 1917 1918 if ( hasVolume && 'yes' === settings['hasVolumeBar'] && !settings['hideVolumeOnTouchDevices']) { 1919 media.setVolume( startVolume ); 1920 media.addEventListener( 'volumechange', function() { 1921 var volumeBar = 'horizontal' === settings['audioVolume'] ? $scope.find( '.mejs-horizontal-volume-current' ) : $scope.find( '.mejs-volume-current' ), 1922 volumeValue = 'horizontal' === settings['audioVolume'] ? parseInt( volumeBar[0].style.width, 10 ) / 100 : parseInt( volumeBar[0].style.height, 10 ) / 100, 1923 volumeBarTotal = 'horizontal' === settings['audioVolume'] ? $scope.find( '.mejs-horizontal-volume-total' ) : $scope.find( '.mejs-volume-slider .mejs-volume-total' ), 1924 playBrn = $scope.find( '.mejs-playpause-button' ), 1925 volumeCurrentValue = ''; 1926 1927 volumeBarTotal.on( 'click', function() { 1928 if ( 'horizontal' === settings['audioVolume'] ) { 1929 volumeCurrentValue = parseInt( $scope.find( '.mejs-horizontal-volume-total .mejs-horizontal-volume-current' )[0].style.width, 10 ) / 100; 1930 } else { 1931 volumeCurrentValue = parseInt( $scope.find( '.mejs-volume-slider .mejs-volume-total .mejs-volume-current' )[0].style.height, 10 ) / 100; 1932 } 1933 } ) 1934 1935 playBrn.on( 'click', function() { 1936 if ( '' !== volumeCurrentValue ) { 1937 media.setVolume( volumeCurrentValue ); 1938 } 1939 } ) 1940 1941 muteBtn.on( 'click', function() { 1942 if ( ! media.muted ) { 1943 if ( 'yes' === settings['muted'] && 0 === unmuted && 0 === volumeValue ) { 1944 media.setVolume( startVolume ); 1945 unmuted = 1; 1946 } 1947 } 1948 } ) 1949 }, false ); 1950 } else if ( hasVolume && !settings['hideVolumeOnTouchDevices'] ) { 1951 muteBtn.on( 'click', function() { 1952 media.setVolume( startVolume ); 1953 } ) 1954 } 1955 } 1956 } ); 1957 }, 1958 1959 widgetHorizontalTimeline: function( $scope ) { 1960 var $timeline = $scope.find( '.jet-hor-timeline' ), 1961 $timelineTrack = $scope.find( '.jet-hor-timeline-track' ), 1962 $items = $scope.find( '.jet-hor-timeline-item' ), 1963 $arrows = $scope.find( '.jet-arrow' ), 1964 $nextArrow = $scope.find( '.jet-next-arrow' ), 1965 $prevArrow = $scope.find( '.jet-prev-arrow' ), 1966 settings = $timeline.data( 'timeline-settings' ) || {}, 1967 columns = settings.column || {}, 1968 slidesToScroll = settings.slidesToScroll || {}, 1969 firstMouseEvent = true, 1970 currentDeviceMode = elementorFrontend.getCurrentDeviceMode(), 1971 prevDeviceMode = currentDeviceMode, 1972 itemsCount = $scope.find( '.jet-hor-timeline-list--middle .jet-hor-timeline-item' ).length, 1973 isRTL = JetElementsTools.isRTL(), 1974 currentTransform = 0, 1975 currentPosition = 0, 1976 transform = { 1977 desktop: 100 / columns.desktop, 1978 tablet: 100 / columns.tablet, 1979 mobile: 100 / columns.mobile 1980 }, 1981 maxPosition = { 1982 desktop: Math.max( 0, (itemsCount - columns.desktop) ), 1983 tablet: Math.max( 0, (itemsCount - columns.tablet) ), 1984 mobile: Math.max( 0, (itemsCount - columns.mobile) ) 1985 }; 1986 1987 if ( 'ontouchstart' in window || 'ontouchend' in window ) { 1988 $items.on( 'touchend.jetHorTimeline', function( event ) { 1989 var itemId = $( this ).data( 'item-id' ); 1990 1991 $scope.find( '.elementor-repeater-item-' + itemId ).toggleClass( 'is-hover' ); 1992 } ); 1993 } else { 1994 $items.on( 'mouseenter.jetHorTimeline mouseleave.jetHorTimeline', function( event ) { 1995 1996 if ( firstMouseEvent && 'mouseleave' === event.type ) { 1997 return; 1998 } 1999 2000 if ( firstMouseEvent && 'mouseenter' === event.type ) { 2001 firstMouseEvent = false; 2002 } 2003 2004 var itemId = $( this ).data( 'item-id' ); 2005 2006 $scope.find( '.elementor-repeater-item-' + itemId ).toggleClass( 'is-hover' ); 2007 } ); 2008 } 2009 2010 // Set Line Position 2011 setLinePosition(); 2012 $( window ).on( 'resize.jetHorTimeline orientationchange.jetHorTimeline', JetElementsTools.debounce( 50, setLinePosition ) ); 2013 2014 function setLinePosition() { 2015 var $line = $scope.find( '.jet-hor-timeline__line' ), 2016 $firstPoint = $scope.find( '.jet-hor-timeline-item__point-content:first' ), 2017 $lastPoint = $scope.find( '.jet-hor-timeline-item__point-content:last' ), 2018 firstPointLeftPos = $firstPoint.position().left + parseInt( $firstPoint.css( 'marginLeft' ) ), 2019 lastPointLeftPos = $lastPoint.position().left + parseInt( $lastPoint.css( 'marginLeft' ) ), 2020 pointWidth = $firstPoint.outerWidth(); 2021 2022 $line.css( { 2023 'left': !isRTL ? ( firstPointLeftPos + pointWidth/2 ) : ( lastPointLeftPos + pointWidth/2 ), 2024 'width': Math.abs( lastPointLeftPos - firstPointLeftPos ) 2025 } ); 2026 } 2027 2028 // Arrows Navigation Type 2029 if ( $nextArrow[0] && maxPosition[ currentDeviceMode ] === 0 ) { 2030 $nextArrow.addClass( 'jet-arrow-disabled' ); 2031 } 2032 2033 if ( $arrows[0] ) { 2034 var slidesScroll = slidesToScroll[ currentDeviceMode ], 2035 xPos = 0, 2036 yPos = 0, 2037 diffpos; 2038 2039 $arrows.on( 'click.jetHorTimeline', function( event ){ 2040 var $this = $( this ), 2041 currentDeviceMode = elementorFrontend.getCurrentDeviceMode(), 2042 direction = $this.hasClass( 'jet-next-arrow' ) ? 'next' : 'prev', 2043 dirMultiplier = !isRTL ? -1 : 1; 2044 2045 if ( slidesScroll > columns[ currentDeviceMode ] ) { 2046 slidesScroll = columns[ currentDeviceMode ]; 2047 } 2048 2049 if ( 'next' === direction && currentPosition < maxPosition[ currentDeviceMode ] ) { 2050 currentPosition += slidesScroll; 2051 2052 if ( currentPosition > maxPosition[ currentDeviceMode ] ) { 2053 currentPosition = maxPosition[ currentDeviceMode ]; 2054 } 2055 } 2056 2057 if ( 'prev' === direction && currentPosition > 0 ) { 2058 currentPosition -= slidesScroll; 2059 2060 if ( currentPosition < 0 ) { 2061 currentPosition = 0; 2062 } 2063 } 2064 2065 if ( currentPosition > 0 ) { 2066 $prevArrow.removeClass( 'jet-arrow-disabled' ); 2067 } else { 2068 $prevArrow.addClass( 'jet-arrow-disabled' ); 2069 } 2070 2071 if ( currentPosition === maxPosition[ currentDeviceMode ] ) { 2072 $nextArrow.addClass( 'jet-arrow-disabled' ); 2073 } else { 2074 $nextArrow.removeClass( 'jet-arrow-disabled' ); 2075 } 2076 2077 if ( currentPosition === 0 ) { 2078 currentTransform = 0; 2079 } else { 2080 currentTransform = currentPosition * transform[ currentDeviceMode ]; 2081 } 2082 2083 $timelineTrack.css({ 2084 'transform': 'translateX(' + dirMultiplier * currentTransform + '%)' 2085 }); 2086 2087 } ); 2088 2089 $( $items ).on( 'touchstart', function( e ) { 2090 var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 2091 2092 xPos = touch.pageX; 2093 } ); 2094 2095 $( $items ).on( 'touchend', function( e ) { 2096 var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 2097 2098 yPos = touch.pageX; 2099 diffpos = yPos - xPos; 2100 2101 if ( diffpos < -50 ) { 2102 var dirMultiplier = !isRTL ? -1 : 1; 2103 2104 if ( slidesScroll > columns[ currentDeviceMode ] ) { 2105 slidesScroll = columns[ currentDeviceMode ]; 2106 } 2107 2108 if ( currentPosition < maxPosition[ currentDeviceMode ] ) { 2109 currentPosition += slidesScroll; 2110 2111 if ( currentPosition > maxPosition[ currentDeviceMode ] ) { 2112 currentPosition = maxPosition[ currentDeviceMode ]; 2113 } 2114 } 2115 2116 if ( currentPosition > 0 ) { 2117 $prevArrow.removeClass( 'jet-arrow-disabled' ); 2118 } else { 2119 $prevArrow.addClass( 'jet-arrow-disabled' ); 2120 } 2121 2122 if ( currentPosition === maxPosition[ currentDeviceMode ] ) { 2123 $nextArrow.addClass( 'jet-arrow-disabled' ); 2124 } else { 2125 $nextArrow.removeClass( 'jet-arrow-disabled' ); 2126 } 2127 2128 if ( currentPosition === 0 ) { 2129 currentTransform = 0; 2130 } else { 2131 currentTransform = currentPosition * transform[ currentDeviceMode ]; 2132 } 2133 2134 $timelineTrack.css( { 2135 'transform': 'translateX(' + dirMultiplier * currentTransform + '%)' 2136 } ); 2137 2138 } else if ( diffpos > 50 ) { 2139 var dirMultiplier = !isRTL ? -1 : 1; 2140 2141 if ( slidesScroll > columns[ currentDeviceMode ] ) { 2142 slidesScroll = columns[ currentDeviceMode ]; 2143 } 2144 2145 if ( currentPosition > 0 ) { 2146 currentPosition -= slidesScroll; 2147 2148 if ( currentPosition < 0 ) { 2149 currentPosition = 0; 2150 } 2151 } 2152 2153 if ( currentPosition > 0 ) { 2154 $prevArrow.removeClass( 'jet-arrow-disabled' ); 2155 } else { 2156 $prevArrow.addClass( 'jet-arrow-disabled' ); 2157 } 2158 2159 if ( currentPosition === maxPosition[ currentDeviceMode ] ) { 2160 $nextArrow.addClass( 'jet-arrow-disabled' ); 2161 } else { 2162 $nextArrow.removeClass( 'jet-arrow-disabled' ); 2163 } 2164 2165 if ( currentPosition === 0 ) { 2166 currentTransform = 0; 2167 } else { 2168 currentTransform = currentPosition * transform[ currentDeviceMode ]; 2169 } 2170 2171 $timelineTrack.css( { 2172 'transform': 'translateX(' + dirMultiplier * currentTransform + '%)' 2173 } ); 2174 } 2175 } ); 2176 } 2177 2178 setArrowPosition(); 2179 $( window ).on( 'resize.jetHorTimeline orientationchange.jetHorTimeline', setArrowPosition ); 2180 $( window ).on( 'resize.jetHorTimeline orientationchange.jetHorTimeline', timelineSliderResizeHandler ); 2181 2182 function setArrowPosition() { 2183 if ( ! $arrows[0] ) { 2184 return; 2185 } 2186
2187 var $middleList = $scope.find( '.jet-hor-timeline-list--middle' ), 2188 middleListTopPosition = $middleList.position().top, 2189 middleListHeight = $middleList.outerHeight(); 2190 2191 $arrows.css({ 2192 'top': middleListTopPosition + middleListHeight/2 2193 }); 2194 } 2195 2196 function timelineSliderResizeHandler( event ) { 2197 if ( ! $timeline.hasClass( 'jet-hor-timeline--arrows-nav' ) ) { 2198 return; 2199 } 2200 2201 var currentDeviceMode = elementorFrontend.getCurrentDeviceMode(), 2202 resetSlider = function() { 2203 $prevArrow.addClass( 'jet-arrow-disabled' ); 2204 2205 if ( $nextArrow.hasClass( 'jet-arrow-disabled' ) ) { 2206 $nextArrow.removeClass( 'jet-arrow-disabled' ); 2207 } 2208 2209 if ( maxPosition[ currentDeviceMode ] === 0 ) { 2210 $nextArrow.addClass( 'jet-arrow-disabled' ); 2211 } 2212 2213 currentTransform = 0; 2214 currentPosition = 0; 2215 2216 $timelineTrack.css({ 2217 'transform': 'translateX(0%)' 2218 }); 2219 }; 2220 2221 switch ( currentDeviceMode ) { 2222 case 'desktop': 2223 if ( 'desktop' !== prevDeviceMode ) { 2224 resetSlider(); 2225 prevDeviceMode = 'desktop'; 2226 } 2227 break; 2228 2229 case 'tablet': 2230 if ( 'tablet' !== prevDeviceMode ) { 2231 resetSlider(); 2232 prevDeviceMode = 'tablet'; 2233 } 2234 break; 2235 2236 case 'mobile': 2237 if ( 'mobile' !== prevDeviceMode ) { 2238 resetSlider(); 2239 prevDeviceMode = 'mobile'; 2240 } 2241 break; 2242 } 2243 } 2244 }, 2245 2246 widgetPieChart: function( $scope ) { 2247 var $container = $scope.find( '.jet-pie-chart-container' ), 2248 $canvas = $scope.find( '.jet-pie-chart' )[0], 2249 data = $container.data( 'chart' ) || {}, 2250 options = $container.data( 'options' ) || {}, 2251 tooltip = $container.data( 'tooltip' ) || '', 2252 defaultOptions = { 2253 maintainAspectRatio: false 2254 }; 2255 2256 options = $.extend( {}, defaultOptions, options ); 2257 2258 if ( true === options.tooltips.enabled ) { 2259 options.tooltips.callbacks = { 2260 label: function( tooltipItem, data ) { 2261 return ' ' + data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index] + tooltip; 2262 } 2263 }; 2264 } 2265 2266 elementorFrontend.waypoint( $scope, function() { 2267 var chartInstance = new Chart( $canvas, { 2268 type: 'pie', 2269 data: data, 2270 options: options 2271 } ); 2272 }, JetElements.prepareWaypointOptions( $scope, { 2273 offset: 'bottom-in-view' 2274 } ) ); 2275 }, 2276 2277 widgetBarChart: function( $scope ) { 2278 2279 var $chart = $scope.find( '.jet-bar-chart-container' ), 2280 $chart_canvas = $chart.find( '.jet-bar-chart' ), 2281 settings = $chart.data( 'settings' ), 2282 tooltip_prefix = $chart.data( 'tooltip-prefix' ) || '', 2283 tooltip_suffix = $chart.data( 'tooltip-suffix' ) || '', 2284 tooltip_separator = $chart.data( 'tooltip-separator' ) || ''; 2285 2286 if ( true === settings.options.tooltips.enabled ) { 2287 settings.options.tooltips.callbacks = { 2288 label: function(tooltipItem, data) { 2289 return ' ' + data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; 2290 } 2291 } 2292 } 2293 2294 if ( ! $chart.length ) { 2295 return; 2296 } 2297 2298 if ( true === settings.options.tooltips.enabled ) { 2299 settings.options.tooltips.callbacks = { 2300 label: function( tooltipItem, data ) { 2301 var value = '' != tooltip_separator ? JetElementsTools.addThousandCommaSeparator( data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], tooltip_separator) : data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; 2302 return ' ' + data.labels[tooltipItem.index] + ': ' + tooltip_prefix + value + tooltip_suffix; 2303 } 2304 }; 2305 } 2306 2307 elementorFrontend.waypoint( $chart_canvas, function() { 2308 var $this = $( this ), 2309 ctx = $this[0].getContext( '2d' ), 2310 myChart = new Chart( ctx, settings ); 2311 }, JetElements.prepareWaypointOptions( $scope, { 2312 offset: 'bottom-in-view' 2313 2314 } ) ); 2315 }, 2316 widgetLineChart: function( $scope ) { 2317 var id = $scope.data( 'id' ), 2318 $line_chart = $scope.find( '.jet-line-chart-container' ), 2319 $line_chart_canvas = $line_chart.find( '.jet-line-chart' ), 2320 $compare = $line_chart.data( 'compare' ), 2321 previous_label = $line_chart.data( 'previous-label' ), 2322 current_label = $line_chart.data( 'current-label' ), 2323 settings = $line_chart.data( 'settings' ), 2324 compare_labels_type = $line_chart.data( 'compare-labels-type' ), 2325 tooltip_prefix = $line_chart.data( 'tooltip-prefix' ) || '', 2326 tooltip_suffix = $line_chart.data( 'tooltip-suffix' ) || '', 2327 tooltip_separator = $line_chart.data( 'tooltip-separator' ) || ''; 2328 2329 if ( ! $line_chart.length ) { 2330 return; 2331 } 2332 2333 elementorFrontend.waypoint( $line_chart_canvas, function() { 2334 2335 var $this = $( this ), 2336 ctx = $this[0].getContext( '2d' ), 2337 myLineChart = new Chart( ctx, settings ); 2338 2339 myLineChart.options.tooltips = { 2340 enabled: false, 2341 mode: 'x-axis', 2342 intersect: false, 2343 callbacks: { 2344 label: function( tooltipItem, data ) { 2345 var colorBox = data.datasets[tooltipItem.datasetIndex].borderColor; 2346 colorBox = colorBox.replace( /"/g, '"' ); 2347 2348 if ( true === $compare ) { 2349 var currentLabel = 'custom' === compare_labels_type ? current_label : data.labels[tooltipItem.index], 2350 title = data.datasets[tooltipItem.datasetIndex].label, 2351 currentVal = '' != tooltip_separator ? JetElementsTools.addThousandCommaSeparator( data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], tooltip_separator ) : data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], 2352 current = '<div class="jet-line-chart-tooltip-compare-current">' + currentLabel + ' : ' + tooltip_prefix + currentVal + tooltip_suffix + '</div>', 2353 previous = '', 2354 compareColorBox = data.datasets[tooltipItem.datasetIndex].borderColor, 2355 compareColorBox = compareColorBox.replace( /"/g, '"' ); 2356 2357 if ( typeof (data.labels[tooltipItem.index - 1]) != "undefined" && data.labels[tooltipItem.index - 1] !== null ) { 2358 var previousLabel = 'custom' === compare_labels_type ? previous_label : data.labels[tooltipItem.index - 1], 2359 previousVal = '' != tooltip_separator ? JetElementsTools.addThousandCommaSeparator( data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index - 1], tooltip_separator ) : data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index - 1], 2360 previous = '<div class="jet-line-chart-tooltip-compare-previous">' + previousLabel + ' : ' + tooltip_prefix + previousVal + tooltip_suffix + '</div>'; 2361 } 2362 2363 return '<div class="jet-line-chart-tooltip-title"><span class="jet-line-chart-tooltip-color-box" style="background:' + compareColorBox + '"></span>' + title + '</div><div class="jet-line-chart-tooltip-body">' + current + previous + '</div>'; 2364 } else { 2365 var label = data.datasets[tooltipItem.datasetIndex].label, 2366 val = '' != tooltip_separator ? JetElementsTools.addThousandCommaSeparator( data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index], tooltip_separator ) : data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; 2367 return '<div class="jet-line-chart-tooltip-body"><span class="jet-line-chart-tooltip-color-box" style="background:' + colorBox + '"></span>' + label + ' : ' + tooltip_prefix + val + tooltip_suffix + '</div>'; 2368 } 2369 }, 2370 }, 2371 custom: function( tooltipModel ) { 2372 // Tooltip Element 2373 var tooltipEl = document.getElementById( 'chartjs-tooltip_' + id ); 2374 2375 // Create element on first render 2376 if ( !tooltipEl ) { 2377 tooltipEl = document.createElement( 'div' ); 2378 tooltipEl.id = 'chartjs-tooltip_' + id; 2379 tooltipEl.innerHTML = '<div class="jet-line-chart-tooltip"></div>'; 2380 document.body.appendChild( tooltipEl ); 2381 } 2382 2383 // Hide if no tooltip 2384 if ( tooltipModel.opacity === 0 ) { 2385 tooltipEl.style.opacity = 0; 2386 return; 2387 } 2388 // Set caret Position 2389 tooltipEl.classList.remove( 'above', 'below', 'no-transform' ); 2390 if ( tooltipModel.yAlign ) { 2391 tooltipEl.classList.add( tooltipModel.yAlign ); 2392 } else { 2393 tooltipEl.classList.add( 'no-transform' ); 2394 } 2395 2396 function getBody( bodyItem ) { 2397 return bodyItem.lines; 2398 } 2399 2400 // Set Text 2401 if ( tooltipModel.body ) { 2402 var titleLines = tooltipModel.title || []; 2403 var bodyLines = tooltipModel.body.map( getBody ); 2404 var innerHtml = ''; 2405 2406 innerHtml += '<div class="jet-line-chart-tooltip-wrapper">';
2407 bodyLines.forEach( function( body, i ) { 2408 innerHtml += body; 2409 } ); 2410 innerHtml += '</div>'; 2411 2412 var tableRoot = tooltipEl.querySelector( 'div' ); 2413 tableRoot.innerHTML = innerHtml; 2414 } 2415 2416 // `this` will be the overall tooltip 2417 2418 var _this = this, 2419 position = this._chart.canvas.getBoundingClientRect(), 2420 tooltipWidth = tooltipEl.offsetWidth, 2421 tooltipHeight = tooltipEl.offsetHeight, 2422 offsetX = 0, 2423 offsetY = 0; 2424 2425 setTimeout( function(){ 2426 tooltipWidth = tooltipEl.offsetWidth; 2427 tooltipHeight = tooltipEl.offsetHeight; 2428 2429 if ( _this._chart.width / 2 > _this._chart.tooltip._eventPosition.x ) { 2430 offsetX = 0; 2431 } else { 2432 offsetX = -tooltipWidth; 2433 } 2434 2435 if ( _this._chart.height / 2 > _this._chart.tooltip._eventPosition.y ) { 2436 offsetY = 0; 2437 } else { 2438 offsetY = -tooltipHeight; 2439 } 2440 tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + offsetX + 'px'; 2441 tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + offsetY + 'px'; 2442 tooltipEl.style.opacity = 1; 2443 }, 10 ); 2444 2445 // Display, position, and set styles for font 2446 tooltipEl.style.position = 'absolute'; 2447 tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily; 2448 tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px'; 2449 tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle; 2450 tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px'; 2451 tooltipEl.style.pointerEvents = 'none'; 2452 }, 2453 }; 2454 myLineChart.update(); 2455 }, JetElements.prepareWaypointOptions( $scope, { 2456 offset: 'bottom-in-view' 2457 } ) ); 2458 }, 2459 2460 widgetLottie: function ( $scope ) { 2461 var $lottie = $scope.find( '.jet-lottie' ), 2462 $lottieElem = $lottie.find( '.jet-lottie__elem' ), 2463 settings = $lottie.data( 'settings' ), 2464 options, 2465 instance; 2466 2467 if ( ! $lottie[0] ) { 2468 return; 2469 } 2470 2471 options = { 2472 container: $lottieElem[0], 2473 renderer: settings.renderer, 2474 loop: '' === settings.loop_times ? settings.loop : settings.loop_times, 2475 autoplay: false, 2476 path: settings.path, 2477 name: 'jet-lottie' 2478 }; 2479 2480 instance = lottie.loadAnimation( options ); 2481 2482 if ( settings.play_speed ) { 2483 instance.setSpeed( settings.play_speed ); 2484 } 2485 2486 if ( settings.reversed ) { 2487 instance.setDirection( -1 ); 2488 } 2489 2490 var start = 0, 2491 end = 0; 2492 2493 if ( settings.viewport ) { 2494 start = -settings.viewport.start || 0; 2495 end = -(100 - settings.viewport.end) || 0; 2496 } 2497 2498 switch( settings.action_start ) { 2499 case 'on_hover': 2500 2501 var startFlag = false, 2502 2503 onHoverHandler = function() { 2504 if ( startFlag && 'reverse' === settings.on_hover_out ) { 2505 var reverseValue = settings.reversed ? -1 : 1; 2506 instance.setDirection( reverseValue ); 2507 } 2508 2509 instance.play(); 2510 startFlag = true; 2511 }, 2512 2513 onHoverOutHandler = function() { 2514 switch ( settings.on_hover_out ) { 2515 case 'pause': 2516 instance.pause(); 2517 break; 2518 2519 case 'stop': 2520 instance.stop(); 2521 break; 2522 2523 case 'reverse': 2524 var reverseValue = settings.reversed ? 1 : -1; 2525 instance.setDirection( reverseValue ); 2526 instance.play(); 2527 } 2528 }; 2529 2530 $lottie 2531 .off( 'mouseenter.JetLottie', onHoverHandler ) 2532 .on( 'mouseenter.JetLottie', onHoverHandler ); 2533 2534 $lottie 2535 .off( 'mouseleave.JetLottie', onHoverOutHandler ) 2536 .on( 'mouseleave.JetLottie', onHoverOutHandler ); 2537 2538 break; 2539 2540 case 'on_click': 2541 2542 var $link = $lottie.find( '.jet-lottie__link' ), 2543 redirectTimeout = +settings.redirect_timeout, 2544 2545 onClickHandler = function() { 2546 instance.play(); 2547 }, 2548 2549 onLinkClickHandler = function( event ) { 2550 2551 event.preventDefault(); 2552 2553 instance.play(); 2554 2555 var url = $( this ).attr( 'href' ), 2556 target = '_blank' === $( this ).attr( 'target' ) ? '_blank' : '_self'; 2557 2558 setTimeout( function() { 2559 window.open( url, target ); 2560 }, redirectTimeout ); 2561 }; 2562 2563 if ( $link[0] && redirectTimeout > 0 ) { 2564 2565 $link 2566 .off( 'click.JetLottie', onLinkClickHandler ) 2567 .on( 'click.JetLottie', onLinkClickHandler ); 2568 2569 } else { 2570 $lottie 2571 .off( 'click.JetLottie', onClickHandler ) 2572 .on( 'click.JetLottie', onClickHandler ); 2573 } 2574 2575 break; 2576
2577 case 'on_viewport': 2578 2579 if ( undefined !== window.IntersectionObserver ) { 2580 var observer = new IntersectionObserver( 2581 function( entries, observer ) { 2582 if ( entries[0].isIntersecting ) { 2583 instance.play(); 2584 } else { 2585 instance.pause(); 2586 } 2587 }, 2588 { 2589 rootMargin: end +'% 0% ' + start + '%' 2590 } 2591 ); 2592 2593 observer.observe( $lottie[0] ); 2594 } else { 2595 instance.play(); 2596 } 2597 2598 break; 2599 2600 case 'on_scroll': 2601 2602 if ( undefined !== window.IntersectionObserver ) { 2603 var scrollY = 0, 2604 requestId, 2605 scrollObserver = new IntersectionObserver( 2606 function( entries, observer ) { 2607 if ( entries[0].isIntersecting ) { 2608 2609 requestId = requestAnimationFrame( function scrollAnimation() { 2610 if ( window.scrollY !== scrollY ) { 2611 var viewportPercentage = JetElementsTools.getElementPercentageSeen( $lottieElem, { start: start, end: end } ), 2612 nextFrame = (instance.totalFrames - instance.firstFrame) * viewportPercentage / 100; 2613 2614 instance.goToAndStop( nextFrame, true ); 2615 scrollY = window.scrollY; 2616 } 2617 2618 requestId = requestAnimationFrame( scrollAnimation ); 2619 } ); 2620 } else { 2621 cancelAnimationFrame(requestId); 2622 } 2623 }, 2624 { 2625 rootMargin: end +'% 0% ' + start + '%' 2626 } 2627 ); 2628 2629 scrollObserver.observe( $lottie[0] ); 2630 } 2631 2632 break; 2633 2634 default: 2635 var delay = +settings.delay; 2636 2637 if ( delay > 0 ) { 2638 2639 setTimeout( function() { 2640 instance.play(); 2641 }, delay ); 2642 2643 } else { 2644 instance.play(); 2645 } 2646 } 2647 2648 }, 2649 2650 widgetPricingTable: function( $scope ) { 2651 var $target = $scope.find( '.pricing-table' ), 2652 $tooltips = $( '.pricing-feature .pricing-feature__inner[data-tippy-content]', $target ), 2653 settings = $target.data( 'tooltips-settings' ), 2654 $fold_target = $scope.find( '.pricing-table__fold-mask' ), 2655 $fold_button = $scope.find( '.pricing-table__fold-button' ), 2656 $fold_mask = $fold_target, 2657 $fold_content = $( '.pricing-table__features', $fold_target ), 2658 fold_settings = $fold_target.data( 'fold-settings' ) || {}, 2659 fold_enabled = fold_settings['fold_enabled'] || false, 2660 fold_maskHeight = 0, 2661 contentHeight = 0, 2662 unfoldDuration = fold_settings['unfoldDuration'], 2663 foldDuration = fold_settings['unfoldDuration'], 2664 unfoldEasing = fold_settings['unfoldEasing'], 2665 foldEasing = fold_settings['foldEasing']; 2666 2667 if ( $tooltips[0] ) { 2668 $tooltips.each( function() { 2669 var $this = $( this ), 2670 itemSelector = $this[0]; 2671 2672 if ( itemSelector._tippy ) { 2673 itemSelector._tippy.destroy(); 2674 } 2675 2676 tippy( [ itemSelector ], { 2677 arrow: settings['tooltipArrow'] ? true : false, 2678 duration: [ settings['tooltipShowDuration']['size'], settings['tooltipHideDuration']['size'] ], 2679 delay: settings['tooltipDelay']['size'], 2680 placement: settings['tooltipPlacement'], 2681 trigger: settings['tooltipTrigger'], 2682 animation: settings['tooltipAnimation'], 2683 appendTo: itemSelector, 2684 offset: [ 0, settings['tooltipDistance']['size'] ], 2685 allowHTML: true, 2686 popperOptions: { 2687 strategy: 'fixed', 2688 }, 2689 } ); 2690 2691 } ); 2692 } 2693 2694 function maskHeight(){ 2695 $scope.find( '.pricing-table__fold-mask .fold_visible' ).each( function() { 2696 fold_maskHeight = fold_maskHeight + $( this ).outerHeight( true ); 2697 } ); 2698 } 2699 2700 function fold_content_height(){ 2701 contentHeight = 0; 2702 $scope.find( '.pricing-table__fold-mask .pricing-feature' ).each( function() { 2703 contentHeight = contentHeight + $( this ).outerHeight( true ); 2704 } ) 2705 } 2706 2707 if ( fold_enabled ) { 2708 2709 maskHeight(); 2710 fold_content_height(); 2711 2712 if ( !$fold_target.hasClass( 'pricing-table-unfold-state' ) ) { 2713 $fold_mask.css( { 2714 'height': fold_maskHeight 2715 } ); 2716 } 2717 2718 $scope.find( '.pricing-table__fold-mask' ).css('max-height', 'none'); 2719 2720 $fold_button.on( 'click.jetPricingTable', function() { 2721 var $this = $( this ), 2722 $buttonText = $( '.pricing-table__fold-button-text', $this ), 2723 $buttonIcon = $( '.pricing-table__fold-button-icon', $this ), 2724 unfoldText = $this.data( 'unfold-text' ), 2725 foldText = $this.data( 'fold-text' ), 2726 unfoldIcon = $this.data( 'unfold-icon' ), 2727 foldIcon = $this.data( 'fold-icon' ); 2728 2729 if ( ! $fold_target.hasClass( 'pricing-table-unfold-state' ) ) { 2730 $fold_target.addClass( 'pricing-table-unfold-state' ); 2731 2732 fold_content_height(); 2733 2734 $buttonIcon.html( foldIcon ); 2735 $buttonText.html( foldText ); 2736 2737 anime( { 2738 targets: $fold_mask[0], 2739 height: contentHeight, 2740 duration: unfoldDuration['size'] || unfoldDuration, 2741 easing: unfoldEasing 2742 } ); 2743 } else { 2744 $fold_target.removeClass( 'pricing-table-unfold-state' ); 2745 2746 $buttonIcon.html( unfoldIcon ); 2747 $buttonText.html( unfoldText ); 2748 2749 anime( { 2750 targets: $fold_mask[0], 2751 height: fold_maskHeight, 2752 duration: foldDuration['size'] || foldDuration, 2753 easing: foldEasing 2754 } ); 2755 } 2756 } ); 2757 } 2758 } 2759 }; 2760 2761 $( window ).on( 'elementor/frontend/init', JetElements.init ); 2762 2763 var JetElementsTools = { 2764 2765 getElementPercentageSeen: function( $element, offset ) { 2766 var offsetSettings = offset || {}, 2767 startOffset = offsetSettings.start || 0, 2768 endOffset = offsetSettings.end || 0,
2769 viewportHeight = $( window ).height(), 2770 viewportStartOffset = viewportHeight * startOffset / 100, 2771 viewportEndOffset = viewportHeight * endOffset / 100, 2772 scrollTop = $( window ).scrollTop(), 2773 elementOffsetTop = $element.offset().top, 2774 elementHeight = $element.height(), 2775 percentage; 2776 2777 percentage = (scrollTop + viewportHeight + viewportStartOffset - elementOffsetTop) / (viewportHeight + viewportStartOffset + viewportEndOffset + elementHeight); 2778 percentage = Math.min( 100, Math.max( 0, percentage * 100 ) ); 2779 2780 return parseFloat( percentage.toFixed( 2 ) ); 2781 }, 2782 2783 isRTL: function() { 2784 return $( 'body' ).hasClass( 'rtl' ); 2785 }, 2786 2787 inArray: function( needle, haystack ) { 2788 return -1 < haystack.indexOf( needle ); 2789 }, 2790 2791 debounce: function( threshold, callback ) { 2792 var timeout; 2793 2794 return function debounced( $event ) { 2795 function delayed() { 2796 callback.call( this, $event ); 2797 timeout = null; 2798 } 2799 2800 if ( timeout ) { 2801 clearTimeout( timeout ); 2802 } 2803 2804 timeout = setTimeout( delayed, threshold ); 2805 }; 2806 }, 2807 2808 getObjectNextKey: function( object, key ) { 2809 var keys = Object.keys( object ), 2810 idIndex = keys.indexOf( key ), 2811 nextIndex = idIndex += 1; 2812 2813 if( nextIndex >= keys.length ) { 2814 //we're at the end, there is no next 2815 return false; 2816 } 2817 2818 var nextKey = keys[ nextIndex ]; 2819 2820 return nextKey; 2821 }, 2822 2823 getObjectPrevKey: function( object, key ) { 2824 var keys = Object.keys( object ), 2825 idIndex = keys.indexOf( key ), 2826 prevIndex = idIndex -= 1; 2827 2828 if ( 0 > idIndex ) { 2829 //we're at the end, there is no next 2830 return false; 2831 } 2832 2833 var prevKey = keys[ prevIndex ]; 2834 2835 return prevKey; 2836 }, 2837 2838 getObjectFirstKey: function( object ) { 2839 return Object.keys( object )[0]; 2840 }, 2841 2842 getObjectLastKey: function( object ) { 2843 return Object.keys( object )[ Object.keys( object ).length - 1 ]; 2844 }, 2845 2846 getObjectValues: function( object ) { 2847 var values; 2848 2849 if ( !Object.values ) { 2850 values = Object.keys( object ).map( function( e ) { 2851 return object[e] 2852 } ); 2853 2854 return values; 2855 } 2856 2857 return Object.values( object ); 2858 }, 2859 2860 validateEmail: function( email ) { 2861 var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 2862 2863 return re.test( email ); 2864 }, 2865 2866 mobileAndTabletcheck: function() { 2867 var check = false; 2868 2869 (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
2869sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); 2870 2871 return check; 2872 }, 2873 2874 addThousandCommaSeparator: function ( nStr, separator ) { 2875 var nStr = nStr + '', 2876 x = nStr.split('.'), 2877 x1 = x[0], 2878 x2 = x.length > 1 ? '.' + x[1] : '', 2879 rgx = /(\d+)(\d{3})/; 2880 2881 while ( rgx.test(x1) ) { 2882 x1 = x1.replace(rgx, '$1' + separator + '$2'); 2883 } 2884 2885 return x1 + x2; 2886 }, 2887 2888 getElementorElementSettings: function( $scope ) { 2889 2890 if ( window.elementorFrontend && window.elementorFrontend.isEditMode() && $scope.hasClass( 'elementor-element-edit-mode' ) ) { 2891 return JetElementsTools.getEditorElementSettings( $scope ); 2892 } 2893 2894 return $scope.data( 'settings' ) || {}; 2895 }, 2896 2897 getEditorElementSettings: function( $scope ) { 2898 var modelCID = $scope.data( 'model-cid' ), 2899 elementData; 2900 2901 if ( ! modelCID ) { 2902 return {}; 2903 } 2904 2905 if ( ! elementor.hasOwnProperty( 'config' ) ) { 2906 return {}; 2907 } 2908 2909 if ( ! elementor.config.hasOwnProperty( 'elements' ) ) { 2910 return {}; 2911 } 2912 2913 if ( ! elementor.config.elements.hasOwnProperty( 'data' ) ) { 2914 return {}; 2915 } 2916 2917 elementData = elementor.config.elements.data[ modelCID ]; 2918 2919 if ( ! elementData ) { 2920 return {}; 2921 } 2922 2923 return elementData.toJSON(); 2924 } 2925 } 2926 2927 /** 2928 * Jet animated text Class 2929 * 2930 * @return {void} 2931 */ 2932 window.jetAnimatedText = function( $selector, settings ) { 2933 var self = this, 2934 $instance = $selector, 2935 $animatedTextContainer = $( '.jet-animated-text__animated-text', $instance ), 2936 $animatedTextList = $( '.jet-animated-text__animated-text-item', $animatedTextContainer ), 2937 timeOut = null, 2938 defaultSettings = { 2939 effect: 'fx1', 2940 delay: 3000 2941 }, 2942 settings = $.extend( defaultSettings, settings || {} ), 2943 currentIndex = 0, 2944 animationDelay = settings.delay; 2945 2946 /** 2947 * Avaliable Effects 2948 */ 2949 self.avaliableEffects = { 2950 'fx1' : { 2951 in: { 2952 duration: 1000, 2953 delay: function( el, index ) { return 75 + index * 100; }, 2954 easing: 'easeOutElastic', 2955 elasticity: 650, 2956 opacity: { 2957 value: [ 0, 1 ], 2958 easing: 'easeOutExpo', 2959 }, 2960 translateY: ['100%','0%'] 2961 }, 2962 out: { 2963 duration: 300, 2964 delay: function(el, index) { return index*40; }, 2965 easing: 'easeInOutExpo', 2966 opacity: 0, 2967 translateY: '-100%' 2968 } 2969 }, 2970 'fx2' : { 2971 in: { 2972 duration: 800, 2973 delay: function( el, index) { return index * 50; }, 2974 easing: 'easeOutElastic', 2975 opacity: { 2976 value: [ 0, 1 ], 2977 easing: 'easeOutExpo', 2978 }, 2979 translateY: function(el, index) { 2980 return index%2 === 0 ? ['-80%', '0%'] : ['80%', '0%']; 2981 } 2982 }, 2983 out: { 2984 duration: 300, 2985 delay: function( el, index ) { return index * 20; }, 2986 easing: 'easeOutExpo', 2987 opacity: 0, 2988 translateY: function( el, index ) { 2989 return index%2 === 0 ? '80%' : '-80%'; 2990 } 2991 } 2992 }, 2993 'fx3' : { 2994 in: { 2995 duration: 700, 2996 delay: function(el, index) { 2997 return ( el.parentNode.children.length - index - 1 ) * 80; 2998 }, 2999 easing: 'easeOutElastic', 3000 opacity: { 3001 value: [ 0, 1 ], 3002 easing: 'easeOutExpo', 3003 }, 3004 translateY: function(el, index) { 3005 return index%2 === 0 ? [ '-80%', '0%' ] : [ '80%', '0%' ]; 3006 }, 3007 rotateZ: [90,0] 3008 }, 3009 out: { 3010 duration: 300, 3011 delay: function(el, index) { return (el.parentNode.children.length-index-1) * 50; }, 3012 easing: 'easeOutExpo', 3013 opacity: 0, 3014 translateY: function(el, index) { 3015 return index%2 === 0 ? '80%' : '-80%'; 3016 }, 3017 rotateZ: function(el, index) { 3018 return index%2 === 0 ? -25 : 25; 3019 } 3020 } 3021 }, 3022 'fx4' : { 3023 in: { 3024 duration: 700, 3025 delay: function( el, index ) { return 550 + index * 50; }, 3026 easing: 'easeOutQuint', 3027 opacity: { 3028 value: [ 0, 1 ], 3029 easing: 'easeOutExpo', 3030 }, 3031 translateY: [ '-150%','0%' ], 3032 rotateY: [ 180, 0 ] 3033 }, 3034 out: { 3035 duration: 200, 3036 delay: function( el, index ) { return index * 30; }, 3037 easing: 'easeInQuint', 3038 opacity: { 3039 value: 0, 3040 easing: 'linear', 3041 }, 3042 translateY: '100%', 3043 rotateY: -180 3044 } 3045 }, 3046 'fx5' : { 3047 in: { 3048 duration: 250, 3049 delay: function( el, index ) { return 200 + index * 25; }, 3050 easing: 'easeOutCubic', 3051 opacity: { 3052 value: [ 0, 1 ], 3053 easing: 'easeOutExpo', 3054 }, 3055 translateY: ['-50%','0%'] 3056 }, 3057 out: { 3058 duration: 250, 3059 delay: function( el, index ) { return index * 25; }, 3060 easing: 'easeOutCubic', 3061 opacity: 0, 3062 translateY: '50%' 3063 } 3064 }, 3065 'fx6' : { 3066 in: { 3067 duration: 400, 3068 delay: function( el, index ) { return index * 50; }, 3069 easing: 'easeOutSine', 3070 opacity: { 3071 value: [ 0, 1 ], 3072 easing: 'easeOutExpo', 3073 }, 3074 rotateY: [ -90, 0 ] 3075 }, 3076 out: { 3077 duration: 200, 3078 delay: function( el, index ) { return index * 50; }, 3079 easing: 'easeOutSine', 3080 opacity: 0, 3081 rotateY: 45 3082 } 3083 }, 3084 'fx7' : { 3085 in: { 3086 duration: 1000, 3087 delay: function( el, index ) { return 100 + index * 30; }, 3088 easing: 'easeOutElastic', 3089 opacity: { 3090 value: [ 0, 1 ], 3091 easing: 'easeOutExpo', 3092 }, 3093 rotateZ: function( el, index ) { 3094 return [ anime.random( 20, 40 ), 0 ]; 3095 } 3096 }, 3097 out: { 3098 duration: 300, 3099 opacity: { 3100 value: [ 1, 0 ], 3101 easing: 'easeOutExpo', 3102 } 3103 } 3104 }, 3105 'fx8' : { 3106 in: { 3107 duration: 400, 3108 delay: function( el, index ) { return 200 + index * 20; }, 3109 easing: 'easeOutExpo', 3110 opacity: 1, 3111 rotateY: [ -90, 0 ], 3112 translateY: [ '50%','0%' ] 3113 }, 3114 out: { 3115 duration: 250, 3116 delay: function( el, index ) { return index * 20; }, 3117 easing: 'easeOutExpo', 3118 opacity: 0, 3119 rotateY: 90 3120 } 3121 }, 3122 'fx9' : { 3123 in: { 3124 duration: 400, 3125 delay: function(el, index) { return 200+index*30; }, 3126 easing: 'easeOutExpo', 3127 opacity: 1, 3128 rotateX: [90,0] 3129 }, 3130 out: { 3131 duration: 250, 3132 delay: function(el, index) { return index*30; }, 3133 easing: 'easeOutExpo', 3134 opacity: 0, 3135 rotateX: -90 3136 } 3137 }, 3138 'fx10' : { 3139 in: { 3140 duration: 400, 3141 delay: function( el, index ) { return 100 + index * 50; }, 3142 easing: 'easeOutExpo', 3143 opacity: { 3144 value: [ 0, 1 ], 3145 easing: 'easeOutExpo', 3146 }, 3147 rotateX: [ 110, 0 ] 3148 }, 3149 out: { 3150 duration: 250, 3151 delay: function( el, index ) { return index * 50; }, 3152 easing: 'easeOutExpo', 3153 opacity: 0, 3154 rotateX: -110 3155 } 3156 }, 3157 'fx11' : { 3158 in: { 3159 duration: function( el, index ) { return anime.random( 800, 1000 ); }, 3160 delay: function( el, index ) { return anime.random( 100, 300 ); }, 3161 easing: 'easeOutExpo', 3162 opacity: { 3163 value: [ 0, 1 ], 3164 easing: 'easeOutExpo', 3165 }, 3166 translateY: [ '-150%','0%' ], 3167 rotateZ: function( el, index ) { return [ anime.random( -50, 50 ), 0 ]; } 3168 }, 3169 out: { 3170 duration: function( el, index ) { return anime.random( 200, 300 ); }, 3171 delay: function( el, index ) { return anime.random( 0, 80 ); }, 3172 easing: 'easeInQuart', 3173 opacity: 0, 3174 translateY: '50%', 3175 rotateZ: function( el, index ) { return anime.random( -50, 50 ); } 3176 } 3177 }, 3178 'fx12' : { 3179 in: { 3180 elasticity: false, 3181 duration: 1, 3182 delay: function( el, index ) {
3183 var delay = index * 100 + anime.random( 50, 100 ); 3184 3185 return delay; 3186 }, 3187 width: [ 0, function( el, i ) { return $( el ).width(); } ] 3188 }, 3189 out: { 3190 duration: 1, 3191 delay: function( el, index ) { return ( el.parentNode.children.length - index - 1 ) * 20; }, 3192 easing: 'linear', 3193 width: { 3194 value: 0 3195 } 3196 } 3197 } 3198 }; 3199 3200 self.textChange = function() { 3201 var currentDelay = animationDelay, 3202 $prevText = $animatedTextList.eq( currentIndex ), 3203 $nextText; 3204 3205 if ( currentIndex < $animatedTextList.length - 1 ) { 3206 currentIndex++; 3207 } else { 3208 currentIndex = 0; 3209 } 3210 3211 $nextText = $animatedTextList.eq( currentIndex ); 3212 3213 self.hideText( $prevText, settings.effect, null, function( anime ) { 3214 $prevText.toggleClass( 'visible' ); 3215 3216 var currentDelay = animationDelay; 3217 3218 if ( timeOut ) { 3219 clearTimeout( timeOut ); 3220 } 3221 3222 self.showText( 3223 $nextText, 3224 settings.effect, 3225 function() { 3226 $nextText.toggleClass( 'active' ); 3227 $prevText.toggleClass( 'active' ); 3228 3229 $nextText.toggleClass( 'visible' ); 3230 }, 3231 function() { 3232 timeOut = setTimeout( function() { 3233 self.textChange(); 3234 }, currentDelay ); 3235 } 3236 ); 3237 3238 } ); 3239 }; 3240 3241 self.showText = function( $selector, effect, beginCallback, completeCallback ) { 3242 var targets = []; 3243 3244 $( 'span', $selector ).each( function() { 3245 $( this ).css( { 3246 'width': 'auto', 3247 'opacity': 1, 3248 'WebkitTransform': '', 3249 'transform': '' 3250 }); 3251 targets.push( this ); 3252 }); 3253 3254 self.animateText( targets, 'in', effect, beginCallback, completeCallback ); 3255 }; 3256 3257 self.hideText = function( $selector, effect, beginCallback, completeCallback ) { 3258 var targets = []; 3259 3260 $( 'span', $selector ).each( function() { 3261 targets.push(this); 3262 }); 3263 3264 self.animateText( targets, 'out', effect, beginCallback, completeCallback ); 3265 }; 3266 3267 self.animateText = function( targets, direction, effect, beginCallback, completeCallback ) { 3268 var effectSettings = self.avaliableEffects[ effect ] || {}, 3269 animationOptions = effectSettings[ direction ], 3270 animeInstance = null; 3271 3272 animationOptions.targets = targets; 3273 3274 animationOptions.begin = beginCallback; 3275 animationOptions.complete = completeCallback; 3276 3277 animeInstance = anime( animationOptions ); 3278 }; 3279 3280 self.init = function() { 3281 var $text = $animatedTextList.eq( currentIndex ); 3282 3283 self.showText( 3284 $text, 3285 settings.effect, 3286 null, 3287 function() { 3288 var currentDelay = animationDelay; 3289 3290 if ( timeOut ) { 3291 clearTimeout( timeOut ); 3292 } 3293 3294 timeOut = setTimeout( function() { 3295 self.textChange(); 3296 }, currentDelay ); 3297 3298 } 3299 ); 3300 }; 3301 } 3302 3303 /** 3304 * Jet Images Layout Class 3305 * 3306 * @return {void} 3307 */ 3308 window.jetImagesLayout = function( $selector, settings ) { 3309 var self = this, 3310 $instance = $selector, 3311 $instanceList = $( '.jet-images-layout__list', $instance ), 3312 $itemsList = $( '.jet-images-layout__item', $instance ), 3313 defaultSettings = {}, 3314 editMode = Boolean( elementor.isEditMode() ), 3315 settings = settings || {}; 3316 3317 /* 3318 * Default Settings 3319 */ 3320 defaultSettings = { 3321 layoutType: 'masonry', 3322 justifyHeight: 300 3323 } 3324 3325 /** 3326 * Checking options, settings and options merging 3327 */ 3328 $.extend( defaultSettings, settings ); 3329 3330 /** 3331 * Layout build 3332 */ 3333 self.layoutBuild = function() { 3334 switch ( settings['layoutType'] ) { 3335 case 'masonry': 3336 salvattore.init(); 3337 break; 3338 case 'justify': 3339 $itemsList.each( function() { 3340 var $this = $( this ), 3341 $imageInstance = $( '.jet-images-layout__image-instance', $this), 3342 imageWidth = $imageInstance.data( 'width' ), 3343 imageHeight = $imageInstance.data( 'height' ), 3344 imageRatio = +imageWidth / +imageHeight, 3345 flexValue = imageRatio * 100, 3346 newWidth = +settings['justifyHeight'] * imageRatio, 3347 newHeight = 'auto'; 3348 3349 $this.css( { 3350 'flex-grow': flexValue, 3351 'flex-basis': newWidth 3352 } ); 3353 } ); 3354 break; 3355 } 3356 3357 if ( $.isFunction( $.fn.imagesLoaded ) ) { 3358 3359 $( '.jet-images-layout__image', $itemsList ).imagesLoaded().progress( function( instance, image ) { 3360 var $image = $( image.img ), 3361 $parentItem = $image.closest( '.jet-images-layout__item' ), 3362 $loader = $( '.jet-images-layout__image-loader', $parentItem ); 3363 3364 $parentItem.addClass( 'image-loaded' ); 3365 3366 $loader.fadeTo( 500, 0, function() { 3367 $( this ).remove(); 3368 } ); 3369 3370 }); 3371 3372 } else { 3373 var $loader = $( '.jet-images-layout__image-loader', $itemsList ); 3374 3375 $itemsList.addClass( 'image-loaded' ); 3376 3377 $loader.fadeTo( 500, 0, function() { 3378 $( this ).remove(); 3379 } ); 3380 } 3381 } 3382 3383 /** 3384 * Init 3385 */ 3386 self.init = function() { 3387 self.layoutBuild(); 3388 } 3389 } 3390
3391 /** 3392 * Jet Scroll Navigation Class 3393 * 3394 * @return {void} 3395 */ 3396 window.jetScrollNavigation = function( $scope, $selector, settings ) { 3397 var self = this, 3398 $window = $( window ), 3399 $document = $( document ), 3400 $body = $( 'body' ), 3401 $instance = $selector, 3402 $htmlBody = $( 'html, body' ), 3403 $itemsList = $( '.jet-scroll-navigation__item', $instance ), 3404 sectionList = [], 3405 defaultSettings = { 3406 speed: 500, 3407 blockSpeed: 500, 3408 offset: 0, 3409 sectionSwitch: false, 3410 sectionSwitchOnMobile: true, 3411 }, 3412 settings = $.extend( {}, defaultSettings, settings ), 3413 sections = {}, 3414 currentSection = null, 3415 isScrolling = false, 3416 isSwipe = false, 3417 hash = window.location.hash.slice(1), 3418 timeout = null, 3419 timeStamp = 0, 3420 platform = navigator.platform; 3421 3422 jQuery.extend( jQuery.easing, { 3423 easeInOutCirc: function (x, t, b, c, d) { 3424 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; 3425 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; 3426 } 3427 }); 3428 3429 /** 3430 * [init description] 3431 * @return {[type]} [description] 3432 */ 3433 self.init = function() { 3434 self.setSectionsData(); 3435 3436 if ( hash && sections.hasOwnProperty( hash ) ) { 3437 $itemsList.addClass( 'invert' ); 3438 } 3439 3440 // Add Events 3441 $itemsList.on( 'click.jetScrollNavigation', function( event ) { 3442 var $this = $( this ), 3443 sectionId = $this.data( 'anchor' ); 3444 3445 self.onAnchorChange( sectionId ); 3446 } ); 3447 3448 $window.on( 'resize.jetScrollNavigation orientationchange.jetScrollNavigation', JetElementsTools.debounce( 50, self.onResize ) ); 3449 $window.on( 'load', function() { self.setSectionsData(); } ); 3450 3451 $document.keydown( function( event ) { 3452 if ( !self.isEnabled() ) { 3453 return; 3454 } 3455 3456 if ( 38 == event.keyCode ) { 3457 self.directionSwitch( event, 'up' ); 3458 } 3459 3460 if ( 40 == event.keyCode ) { 3461 self.directionSwitch( event, 'down' ); 3462 } 3463 } ); 3464 3465 // waypoint section detection 3466 self.waypointHandler(); 3467 3468 // hijaking handler 3469 self.hijakingHandler(); 3470 3471 // init resizeSensor.js 3472 if ( 'undefined' !== typeof ResizeSensor ) { 3473 new ResizeSensor( $( '.jet-scroll-navigation-section' ), JetElementsTools.debounce( 50, function() { 3474 self.setSectionsData(); 3475 self.waypointHandler(); 3476 } ) ); 3477 } 3478 }; 3479 3480 /** 3481 * [setSectionsData description] 3482 */ 3483 self.setSectionsData = function() { 3484 $itemsList.each( function() { 3485 var $this = $( this ), 3486 sectionId = $this.data('anchor'), 3487 sectionInvert = 'yes' === $this.data('invert') ? true : false, 3488 $section = $( '#' + sectionId ); 3489 3490 if ( $section[0] ) { 3491 $section.addClass( 'jet-scroll-navigation-section' ); 3492 //$section.attr( 'touch-action', 'none' ); 3493 $section[0].dataset.sectionName = sectionId; 3494 sections[ sectionId ] = { 3495 selector: $section, 3496 offset: Math.round( $section.offset().top ), 3497 height: $section.outerHeight(), 3498 invert: sectionInvert 3499 }; 3500 } 3501 } ); 3502 }; 3503 3504 /** 3505 * [waypointHandler description] 3506 * @return {[type]} [description] 3507 */ 3508 self.waypointHandler = function() { 3509 3510 for ( var section in sections ) { 3511 var $section = sections[section].selector; 3512 3513 elementorFrontend.waypoint( $section, function( direction ) { 3514 var $this = $( this ), 3515 sectionId = $this.attr( 'id' ); 3516 3517 if ( 'down' === direction && ! isScrolling ) { 3518 window.history.pushState( null, null, '#' + sectionId ); 3519 currentSection = sectionId; 3520 $itemsList.removeClass( 'active' ); 3521 $( '[data-anchor=' + sectionId + ']', $instance ).addClass( 'active' ); 3522 3523 $itemsList.removeClass( 'invert' ); 3524 3525 if ( sections[sectionId].invert ) { 3526 $itemsList.addClass( 'invert' ); 3527 } 3528 } 3529 }, { 3530 offset: '70%', 3531 triggerOnce: false 3532 } ); 3533 3534 elementorFrontend.waypoint( $section, function( direction ) { 3535 var $this = $( this ), 3536 sectionId = $this.attr( 'id' ); 3537 3538 if ( 'up' === direction && ! isScrolling ) { 3539 window.history.pushState( null, null, '#' + sectionId ); 3540 currentSection = sectionId; 3541 $itemsList.removeClass( 'active' ); 3542 $( '[data-anchor=' + sectionId + ']', $instance ).addClass( 'active' ); 3543 3544 $itemsList.removeClass( 'invert' ); 3545 3546 if ( sections[sectionId].invert ) { 3547 $itemsList.addClass( 'invert' ); 3548 } 3549 } 3550 }, { 3551 offset: '0%', 3552 triggerOnce: false 3553 } ); 3554 } 3555 }; 3556 3557 /** 3558 * [onAnchorChange description] 3559 * @param {[type]} event [description] 3560 * @return {[type]} [description] 3561 */ 3562 self.onAnchorChange = function( sectionId ) { 3563 var $this = $( '[data-anchor=' + sectionId + ']', $instance ), 3564 offset = null; 3565 3566 if ( ! sections.hasOwnProperty( sectionId ) ) { 3567 return false;
3568 } 3569 3570 offset = sections[sectionId].offset - settings.offset; 3571 3572 if ( ! isScrolling ) { 3573 isScrolling = true; 3574 3575 window.history.pushState( null, null, '#' + sectionId ); 3576 currentSection = sectionId; 3577 3578 $itemsList.removeClass( 'active' ); 3579 $this.addClass( 'active' ); 3580 3581 $itemsList.removeClass( 'invert' ); 3582 3583 if ( sections[sectionId].invert ) { 3584 $itemsList.addClass( 'invert' ); 3585 } 3586 3587 $htmlBody.animate( { 'scrollTop': offset }, settings.speed, 'easeInOutCirc', function() { 3588 isScrolling = false; 3589 } ); 3590 } 3591 }; 3592 3593 /** 3594 * [directionSwitch description] 3595 * @param {[type]} event [description] 3596 * @param {[type]} direction [description] 3597 * @return {[type]} [description] 3598 */ 3599 self.directionSwitch = function( event, direction ) { 3600 var direction = direction || 'up', 3601 nextItem = $( '[data-anchor=' + currentSection + ']', $instance ).next(), 3602 prevItem = $( '[data-anchor=' + currentSection + ']', $instance ).prev(); 3603 3604 if ( isScrolling ) { 3605 return false; 3606 } 3607 3608 if ( 'up' === direction ) { 3609 if ( prevItem[0] ) { 3610 prevItem.trigger( 'click.jetScrollNavigation' ); 3611 } 3612 } 3613 3614 if ( 'down' === direction ) { 3615 if ( nextItem[0] ) { 3616 nextItem.trigger( 'click.jetScrollNavigation' ); 3617 } 3618 } 3619 }; 3620 3621 /** 3622 * [scrollifyHandler description] 3623 * @return {[type]} [description] 3624 */ 3625 self.hijakingHandler = function() { 3626 var isMobile = JetElementsTools.mobileAndTabletcheck(), 3627 touchStartY = 0, 3628 touchEndY = 0; 3629 3630 if ( settings.sectionSwitch ) { 3631 3632 if ( ! isMobile ) { 3633 document.addEventListener( 'wheel', self.onWheel, { passive: false } ); 3634 } 3635 3636 if ( isMobile && settings['sectionSwitchOnMobile'] ) { 3637 3638 document.addEventListener( 'touchstart', function( event ) { 3639 if ( !self.isEnabled() ) { 3640 return; 3641 } 3642 3643 var $target = $( event.target ), 3644 $section = $target.closest( '.elementor-top-section' ), 3645 sectionId = $section.attr( 'id' ) || false; 3646 3647 touchStartY = event.changedTouches[0].clientY; // clientY instead of screenY, screenY is implemented differently in iOS, making it useless for thresholding 3648 3649 if ( sectionId && isScrolling ) { 3650 event.preventDefault(); 3651 } 3652 3653 }, { passive: false } ); 3654 3655 document.addEventListener( 'touchend', function( event ) { 3656 if ( !self.isEnabled() ) { 3657 return; 3658 } 3659 3660 var $target = $( event.target ), 3661 $navigation = $target.closest( '.jet-scroll-navigation' ) || false, 3662 $section = $target.closest( '.elementor-top-section' ) || false, 3663 sectionId = $section.attr( 'id' ) || false, 3664 endScrollTop = $window.scrollTop(), 3665 touchEndY = event.changedTouches[0].clientY, 3666 direction = touchEndY > touchStartY ? 'up' : 'down', 3667 sectionOffset = false, 3668 newSectionId = false, 3669 prevSectionId = false, 3670 nextSectionId = false, 3671 swipeYthreshold = (window.screen.availHeight / 8); // defining pageswitch threshold at 1/8 of screenheight 3672 3673 if ( Math.abs( touchEndY - touchStartY ) < 20 ) { 3674 return false; 3675 } 3676 3677 if ( $navigation[0] ) { 3678 return false; 3679 } 3680 3681 if ( sectionId && sections.hasOwnProperty( sectionId ) ) { 3682 3683 prevSectionId = JetElementsTools.getObjectPrevKey( sections, sectionId ); 3684 nextSectionId = JetElementsTools.getObjectNextKey( sections, sectionId ); 3685 3686 sectionOffset = sections[ sectionId ].offset; 3687 3688 if ( 'up' === direction ) { 3689 3690 if ( sectionOffset - swipeYthreshold < endScrollTop ) { //threshold used here 3691 prevSectionId = sectionId; 3692 } 3693 3694 if ( prevSectionId ) { 3695 newSectionId = prevSectionId; 3696 } 3697 } 3698 3699 if ( 'down' === direction ) { 3700 3701 if ( sectionOffset + swipeYthreshold > endScrollTop ) { //threshold used here 3702 nextSectionId = sectionId; 3703 } 3704 3705 if ( nextSectionId ) { 3706 newSectionId = nextSectionId; 3707 } 3708 } 3709 3710 if ( newSectionId ) { 3711 3712 self.onAnchorChange( newSectionId ); 3713 } 3714 } 3715 3716 }, { passive: false } ); 3717 } 3718 } 3719 } 3720 3721 /** 3722 * [onScroll description] 3723 * @param {[type]} event [description] 3724 * @return {[type]} [description] 3725 */ 3726 self.onScroll = function( event ) { 3727 event.preventDefault(); 3728 }; 3729 3730 self.onWheel = function( event ) { 3731 3732 if ( !self.isEnabled() ) { 3733 return; 3734 } 3735 3736 if ( isScrolling ) { 3737 event.preventDefault(); 3738 } 3739 3740 var $target = $( event.target ), 3741 $section = $target.closest( '.elementor-top-section[id]' ), 3742 sectionId = $section.attr( 'id' ) || false, 3743 delta = event.deltaY, 3744 direction = ( 0 > delta ) ? 'up' : 'down', 3745 sectionOffset = false, 3746 newSectionId = false, 3747 prevSectionId = false, 3748 nextSectionId = false, 3749 windowScrollTop = $window.scrollTop(); 3750 3751 if ( sectionId && sections.hasOwnProperty( sectionId ) ) { 3752 3753 prevSectionId = JetElementsTools.getObjectPrevKey( sections, sectionId ); 3754 nextSectionId = JetElementsTools.getObjectNextKey( sections, sectionId ); 3755 3756 sectionOffset = sections[ sectionId ].offset; 3757 3758 if ( 'up' === direction ) { 3759 3760 if ( sectionOffset < windowScrollTop + settings.offset - 10 ) { 3761 prevSectionId = sectionId; 3762 } 3763 3764 if ( prevSectionId ) { 3765 newSectionId = prevSectionId; 3766 } 3767 } 3768 3769 if ( 'down' === direction ) { 3770 3771 if ( sectionOffset > windowScrollTop + settings.offset + 10 ) { 3772 nextSectionId = sectionId; 3773 } 3774 3775 if ( nextSectionId ) { 3776 newSectionId = nextSectionId; 3777 } 3778 } 3779 3780 if ( newSectionId ) { 3781 event.preventDefault(); 3782 3783 if ( event.timeStamp - timeStamp > 15 && 'MacIntel' == platform ) { 3784 timeStamp = event.timeStamp; 3785 3786 return false;
3787 } 3788 3789 self.onAnchorChange( newSectionId ); 3790 } 3791 } 3792 3793 return false; 3794 }; 3795 3796 /** 3797 * [onResize description] 3798 * @param {[type]} event [description] 3799 * @return {[type]} [description] 3800 */ 3801 self.onResize = function( event ) { 3802 self.setSectionsData(); 3803 }; 3804 3805 /** 3806 * [scrollStop description] 3807 * @return {[type]} [description] 3808 */ 3809 self.scrollStop = function() { 3810 $htmlBody.stop( true ); 3811 }; 3812 3813 /** 3814 * Is the responsive breakpoint enabled 3815 * 3816 * @return {boolean} Enabled 3817 */ 3818 self.isEnabled = function() { 3819 return $scope.is(":visible"); 3820 }; 3821 3822 /** 3823 * Mobile and tablet check funcion. 3824 * 3825 * @return {boolean} Mobile Status 3826 */ 3827 self.mobileAndTabletcheck = function() { 3828 var check = false; 3829 3830 (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); 3831 3832 return check; 3833 }; 3834 3835 } 3836 3837 /** 3838 * jetSectionParallax Class 3839 * 3840 * @return {void} 3841 */ 3842 window.jetSectionParallax = function( $target ) { 3843 var self = this, 3844 sectionId = $target.data('id'), 3845 settings = false, 3846 editMode = Boolean( elementor.isEditMode() ), 3847 $window = $( window ), 3848 $body = $( 'body' ), 3849 scrollLayoutList = [], 3850 mouseLayoutList = [], 3851 winScrollTop = $window.scrollTop(), 3852 winHeight = $window.height(), 3853 requesScroll = null, 3854 requestMouse = null, 3855 tiltx = 0, 3856 tilty = 0, 3857 isSafari = !!navigator.userAgent.match(/Version\/[\d\.]+.*Safari/), 3858 platform = navigator.platform; 3859 3860 /** 3861 * Init 3862 */ 3863 self.init = function() { 3864 3865 if ( ! editMode ) { 3866 settings = $target.data('settings') || false; 3867 settings = false != settings ? settings['jet_parallax_layout_list'] : false; 3868 } else { 3869 settings = self.generateEditorSettings( sectionId ); 3870 } 3871 3872 if ( ! settings ) { 3873 return false; 3874 } 3875 3876 self.generateLayouts(); 3877 3878 $window.on( 'resize.jetSectionParallax orientationchange.jetSectionParallax', JetElementsTools.debounce( 30, self.generateLayouts ) ); 3879 3880 if ( 0 !== scrollLayoutList.length ) { 3881 $window.on( 'scroll.jetSectionParallax resize.jetSectionParallax', self.scrollHandler ); 3882 } 3883 3884 if ( 0 !== mouseLayoutList.length ) { 3885 $target.on( 'mousemove.jetSectionParallax resize.jetSectionParallax', self.mouseMoveHandler ); 3886 $target.on( 'mouseleave.jetSectionParallax', self.mouseLeaveHandler ); 3887 } 3888 3889 self.scrollUpdate(); 3890 }; 3891 3892 self.generateEditorSettings = function( sectionId ) { 3893 var editorElements = null, 3894 sectionsData = {}, 3895 sectionData = {}, 3896 sectionParallaxData = {}, 3897 settings = []; 3898 3899 if ( ! window.elementor.hasOwnProperty( 'elements' ) ) { 3900 return false;
3901 } 3902 3903 editorElements = window.elementor.elements; 3904 3905 if ( ! editorElements.models ) { 3906 return false; 3907 } 3908 3909 $.each( editorElements.models, function( index, obj ) { 3910 if ( sectionId == obj.id ) { 3911 sectionData = obj.attributes.settings.attributes; 3912 } 3913 } ); 3914 3915 if ( ! sectionData.hasOwnProperty( 'jet_parallax_layout_list' ) || 0 === Object.keys( sectionData ).length ) { 3916 return false; 3917 } 3918 3919 sectionParallaxData = sectionData[ 'jet_parallax_layout_list' ].models; 3920 3921 $.each( sectionParallaxData, function( index, obj ) { 3922 settings.push( obj.attributes ); 3923 } ); 3924 3925 if ( 0 !== settings.length ) { 3926 return settings; 3927 } 3928 3929 return false; 3930 }; 3931 3932 self.generateLayouts = function() { 3933 3934 $( '.jet-parallax-section__layout', $target ).remove(); 3935 3936 $.each( settings, function( index, layout ) { 3937 var imageData = layout['jet_parallax_layout_image'], 3938 speed = layout['jet_parallax_layout_speed']['size'] || 50, 3939 zIndex = layout['jet_parallax_layout_z_index'], 3940 animProp = layout['jet_parallax_layout_animation_prop'] || 'bgposition', 3941 deviceMode = elementorFrontend.getCurrentDeviceMode(), 3942 activeBreakpoints = elementor.config.responsive.activeBreakpoints, 3943 activeBreakpointsArray = [], 3944 bgX = layout['jet_parallax_layout_bg_x'], 3945 bgY = layout['jet_parallax_layout_bg_y'], 3946 type = layout['jet_parallax_layout_type'] || 'none', 3947 direction = layout['jet_parallax_layout_direction'] || '1', 3948 fxDirection = layout['jet_parallax_layout_fx_direction'] || 'fade-in', 3949 device = layout['jet_parallax_layout_on'] || ['desktop', 'tablet'], 3950 _id = layout['_id'], 3951 $layout = null, 3952 layoutData = {}, 3953 safariClass = isSafari ? ' is-safari' : '', 3954 macClass = 'MacIntel' == platform ? ' is-mac' : ''; 3955 3956 if ( -1 === device.indexOf( deviceMode ) ) { 3957 return false; 3958 } 3959 3960 3961 for ( var [key, value] of Object.entries( activeBreakpoints ) ) { 3962 if ( 'widescreen' === key ) { 3963 activeBreakpointsArray.push( 'desktop' ); 3964 activeBreakpointsArray.push( key ); 3965 } else { 3966 activeBreakpointsArray.push( key ); 3967 } 3968 3969 } 3970 3971 if ( -1 === activeBreakpointsArray.indexOf( 'widescreen' ) ) { 3972 activeBreakpointsArray.push( 'desktop' ); 3973 } 3974 3975 activeBreakpointsArray = activeBreakpointsArray.reverse(); 3976 3977 var breakpoints = [ 'widescreen', 'desktop', 'laptop', 'tablet_extra', 'tablet', 'mobile_extra', 'mobile'], 3978 i = 0, 3979 prevDevice, 3980 layoutBreakpoinntsSettings = []; 3981 3982 breakpoints.forEach( function( item ) { 3983 3984 if ( -1 != activeBreakpointsArray.indexOf( item ) ) { 3985 3986 layoutBreakpoinntsSettings[i] = []; 3987 3988 if ( 'widescreen' === item ) { 3989 layoutBreakpoinntsSettings[i][item] = { 3990 'bgX' : '' != layout['jet_parallax_layout_bg_x_' + item] ? layout['jet_parallax_layout_bg_x'] : 0, 3991 3992 'bgY' : '' != layout['jet_parallax_layout_bg_y_' + item] ? layout['jet_parallax_layout_bg_y'] : 0, 3993 3994 'layoutImageData' : '' != layout['jet_parallax_layout_image_' + item] ? layout['jet_parallax_layout_image_' + item] : '' 3995 }; 3996 } else if ( 'desktop' === item ) { 3997 layoutBreakpoinntsSettings[i][item] = { 3998 'bgX' : '' != layout['jet_parallax_layout_bg_x'] ? layout['jet_parallax_layout_bg_x'] : 0, 3999 4000 'bgY' : '' != layout['jet_parallax_layout_bg_y'] ? layout['jet_parallax_layout_bg_y'] : 0, 4001 4002 'layoutImageData' : imageData['url'] || layout['jet_parallax_layout_image']['url'] 4003 }; 4004 } else { 4005 layoutBreakpoinntsSettings[i][item] = { 4006 'bgX': ( layout['jet_parallax_layout_bg_x_' + item] && '' != layout['jet_parallax_layout_bg_x_' + item] ) ? layout['jet_parallax_layout_bg_x_' + item] : layoutBreakpoinntsSettings[i-1][prevDevice].bgX, 4007 4008 'bgY' : ( layout['jet_parallax_layout_bg_y_' + item] && '' != layout['jet_parallax_layout_bg_y_' + item] ) ? layout['jet_parallax_layout_bg_y_' + item] : layoutBreakpoinntsSettings[i-1][prevDevice].bgY, 4009 4010 'layoutImageData' : ( layout['jet_parallax_layout_image_' + item] && '' != layout['jet_parallax_layout_image_' + item]['url'] ) ? layout['jet_parallax_layout_image_' + item]['url'] : layoutBreakpoinntsSettings[i-1][prevDevice].layoutImageData 4011 }; 4012 } 4013 4014 if ( deviceMode === item ) { 4015 bgX = layoutBreakpoinntsSettings[i][item].bgX; 4016 bgY = layoutBreakpoinntsSettings[i][item].bgY; 4017 imageData = layoutBreakpoinntsSettings[i][item].layoutImageData; 4018 } 4019 4020 prevDevice = item; 4021 4022 i++; 4023 } 4024 4025 } ); 4026 4027 if ( ! $target.hasClass( 'jet-parallax-section' ) ) { 4028 $target.addClass( 'jet-parallax-section' ); 4029 } 4030 4031 $layout = $( '<div class="jet-parallax-section__layout elementor-repeater-item-' + _id + ' jet-parallax-section__' + type +'-layout' + macClass + '"><div class="jet-parallax-section__image"></div></div>' ) 4032 .prependTo( $target ) 4033 .css( { 4034 'z-index': zIndex 4035 } ); 4036 4037 var imageCSS = { 4038 'background-position-x': bgX + '%', 4039 'background-position-y': bgY + '%', 4040 'background-image': 'url(' + imageData + ')' 4041 }; 4042 4043 $( '> .jet-parallax-section__image', $layout ).css( imageCSS ); 4044 4045 layoutData = { 4046 selector: $layout, 4047 prop: animProp, 4048 type: type, 4049 device: device, 4050 xPos: bgX, 4051 yPos: bgY, 4052 direction: +direction, 4053 fxDirection: fxDirection, 4054 speed: 2 * ( speed / 100 ) 4055 }; 4056 4057 if ( 'none' !== type ) { 4058 if ( JetElementsTools.inArray( type, ['scroll', 'h-scroll', 'zoom', 'rotate', 'blur', 'opacity'] ) ) { 4059 scrollLayoutList.push( layoutData ); 4060 } 4061 4062 if ( 'mouse' === type ) { 4063 mouseLayoutList.push( layoutData ); 4064 } 4065 } 4066 4067 } ); 4068 4069 }; 4070 4071 self.scrollHandler = function( event ) { 4072 winScrollTop = $window.scrollTop(); 4073 winHeight = $window.height(); 4074 4075 self.scrollUpdate(); 4076 }; 4077 4078 self.scrollUpdate = function() { 4079 $.each( scrollLayoutList, function( index, layout ) { 4080 4081 var $this = layout.selector, 4082 $image = $( '.jet-parallax-section__image', $this ), 4083 speed = layout.speed, 4084 offsetTop = $this.offset().top, 4085 thisHeight = $this.outerHeight(), 4086 prop = layout.prop, 4087 type = layout.type, 4088 dir = layout.direction, 4089 fxDir = layout.fxDirection, 4090 posY = ( winScrollTop - offsetTop + winHeight ) / thisHeight * 100,
4091 device = elementorFrontend.getCurrentDeviceMode(); 4092 4093 if ( -1 === layout.device.indexOf( device ) ) { 4094 $image.css( { 4095 'transform': 'translateX(0) translateY(0)', 4096 'background-position-y': layout.yPos, 4097 'background-position-x': layout.xPos, 4098 'filter': 'none', 4099 'opacity': '1' 4100 } ); 4101 4102 return false; 4103 } 4104 4105 if ( winScrollTop < offsetTop - winHeight ) posY = 0; 4106 if ( winScrollTop > offsetTop + thisHeight) posY = 200; 4107 4108 posY = parseFloat( speed * posY ).toFixed(1); 4109 4110 switch( type ) { 4111 case 'scroll': 4112 if ( 'bgposition' === prop ) { 4113 $image.css( { 4114 'background-position-y': 'calc(' + layout.yPos + '% + ' + posY + 'px)' 4115 } ); 4116 } else { 4117 $image.css( { 4118 'transform': 'translateY(' + posY + 'px)' 4119 } ); 4120 } 4121 break; 4122 case 'h-scroll': 4123 if ( 'bgposition' === prop ) { 4124 $image.css( { 4125 'background-position-x': 'calc(' + layout.xPos + '% + ' + (posY * dir) + 'px)' 4126 } ); 4127 } else { 4128 $image.css( { 4129 'transform': 'translateX(' + (posY * dir) + 'px)' 4130 } ); 4131 } 4132 break; 4133 case 'zoom': 4134 var deltaScale = ( winScrollTop - offsetTop + winHeight ) / winHeight, 4135 scale = deltaScale * speed; 4136 4137 scale = scale + 1; 4138 4139 $image.css( { 4140 'transform': 'scale(' + scale + ')' 4141 } ); 4142 break; 4143 case 'rotate': 4144 var rotate = posY; 4145 4146 $image.css( { 4147 'transform': 'rotateZ(' + (rotate * dir) + 'deg)' 4148 } ); 4149 break; 4150 case 'blur': 4151 var blur = 0; 4152 4153 switch ( fxDir ) { 4154 case 'fade-in': 4155 blur = posY / 40; 4156 break; 4157 4158 case 'fade-out': 4159 blur = (5 * speed) - (posY / 40); 4160 break 4161 } 4162 4163 $image.css( { 4164 'filter': 'blur(' + blur + 'px)' 4165 } ); 4166 break; 4167 case 'opacity': 4168 var opacity = 1; 4169 4170 switch ( fxDir ) { 4171 case 'fade-in': 4172 opacity = 1 - (posY / 400); 4173 break; 4174 4175 case 'fade-out': 4176 opacity = (1 - (0.5 * speed)) + (posY / 400); 4177 break 4178 } 4179 4180 $image.css( { 4181 'opacity': opacity 4182 } ); 4183 break; 4184 } 4185 4186 } ); 4187 }; 4188 4189 self.mouseMoveHandler = function( event ) { 4190 var windowWidth = $window.width(), 4191 windowHeight = $window.height(), 4192 cx = Math.ceil( windowWidth / 2 ), 4193 cy = Math.ceil( windowHeight / 2 ), 4194 dx = event.clientX - cx, 4195 dy = event.clientY - cy; 4196 4197 tiltx = -1 * ( dx / cx ); 4198 tilty = -1 * ( dy / cy ); 4199 4200 self.mouseMoveUpdate(); 4201 }; 4202 4203 self.mouseLeaveHandler = function( event ) { 4204 4205 $.each( mouseLayoutList, function( index, layout ) { 4206 var $this = layout.selector, 4207 $image = $( '.jet-parallax-section__image', $this ); 4208 4209 switch( layout.prop ) { 4210 case 'transform3d': 4211 TweenMax.to( 4212 $image[0], 4213 1.2, { 4214 x: 0, 4215 y: 0, 4216 z: 0, 4217 rotationX: 0, 4218 rotationY: 0, 4219 ease:Power2.easeOut 4220 } 4221 ); 4222 break; 4223 } 4224 4225 } ); 4226 }; 4227 4228 self.mouseMoveUpdate = function() { 4229 $.each( mouseLayoutList, function( index, layout ) { 4230 var $this = layout.selector, 4231 $image = $( '.jet-parallax-section__image', $this ), 4232 speed = layout.speed, 4233 prop = layout.prop, 4234 posX = parseFloat( tiltx * 125 * speed ).toFixed(1), 4235 posY = parseFloat( tilty * 125 * speed ).toFixed(1), 4236 posZ = layout.zIndex * 50, 4237 rotateX = parseFloat( tiltx * 25 * speed ).toFixed(1), 4238 rotateY = parseFloat( tilty * 25 * speed ).toFixed(1), 4239 device = elementorFrontend.getCurrentDeviceMode(); 4240 4241 if ( -1 == layout.device.indexOf( device ) ) { 4242 $image.css( { 4243 'transform': 'translateX(0) translateY(0)', 4244 'background-position-x': layout.xPos, 4245 'background-position-y': layout.yPos 4246 } ); 4247 4248 return false; 4249 } 4250 4251 switch( prop ) { 4252 case 'bgposition': 4253 4254 var bgPosX = layout.xPos + ( posX / $image[0].offsetWidth ) * 100, 4255 bgPosY = layout.yPos + ( posY / $image[0].offsetHeight ) * 100; 4256 4257 TweenMax.to( 4258 $image[0], 4259 1, { 4260 backgroundPositionX: bgPosX, 4261 backgroundPositionY: bgPosY, 4262 ease:Power2.easeOut 4263 } 4264 ); 4265 break; 4266 4267 case 'transform': 4268 TweenMax.to( 4269 $image[0], 4270 1, { 4271 x: posX, 4272 y: posY, 4273 ease:Power2.easeOut 4274 } 4275 ); 4276 break; 4277 4278 case 'transform3d': 4279 TweenMax.to( 4280 $image[0], 4281 2, { 4282 x: posX, 4283 y: posY, 4284 z: posZ, 4285 rotationX: rotateY, 4286 rotationY: -rotateX, 4287 ease:Power2.easeOut 4288 } 4289 ); 4290 break; 4291 } 4292 4293 } ); 4294 }; 4295 4296 } 4297
4298 /** 4299 * Jet Portfolio Class 4300 * 4301 * @return {void} 4302 */ 4303 window.jetPortfolio = function( $selector, settings ) { 4304 var self = this, 4305 $instance = $selector, 4306 $instanceList = $( '.jet-portfolio__list', $instance ), 4307 $itemsList = $( '.jet-portfolio__item', $instance ), 4308 $filterList = $( '.jet-portfolio__filter-item', $instance ), 4309 $moreWrapper = $( '.jet-portfolio__view-more', $instance ), 4310 $moreButton = $( '.jet-portfolio__view-more-button', $instance ), 4311 isViewMore = $moreButton[0], 4312 itemsData = {}, 4313 filterData = {}, 4314 currentFilter = 'all', 4315 activeSlug = [], 4316 isRTL = JetElementsTools.isRTL(), 4317 editMode = Boolean( elementor.isEditMode() ), 4318 defaultSettings = { 4319 layoutType: 'masonry', 4320 columns: 3, 4321 perPage: 6 4322 }, 4323 masonryOptions = { 4324 itemSelector: '.jet-portfolio__item', 4325 percentPosition: true, 4326 isOriginLeft : true === isRTL ? false : true 4327 }, 4328 settings = $.extend( defaultSettings, settings ), 4329 $masonryInstance, 4330 page = 1; 4331 4332 /** 4333 * Init 4334 */ 4335 self.init = function() { 4336 self.layoutBuild(); 4337 4338 if ( editMode && $masonryInstance.get(0) ) { 4339 4340 $(window).on( 'resize', JetElementsTools.debounce( 50, function() { 4341 $masonryInstance.masonry('layout'); 4342 })); 4343 } 4344 } 4345 4346 /** 4347 * Layout build 4348 */ 4349 self.layoutBuild = function() { 4350 4351 self.generateData(); 4352 4353 $filterList.data( 'showItems', isViewMore ? settings.perPage : 'all' ); 4354 4355 if ( 'justify' == settings['layoutType'] ) { 4356 masonryOptions['columnWidth'] = '.grid-sizer'; 4357 } 4358 4359 if ( 'masonry' == settings['layoutType'] || 'justify' == settings['layoutType'] ) { 4360 $masonryInstance = $instanceList.masonry( masonryOptions ); 4361 } 4362 4363 if ( $.isFunction( $.fn.imagesLoaded ) ) { 4364 4365 $( '.jet-portfolio__image', $itemsList ).imagesLoaded().progress( function( instance, image ) { 4366 var $image = $( image.img ), 4367 $parentItem = $image.closest( '.jet-portfolio__item' ), 4368 $loader = $( '.jet-portfolio__image-loader', $parentItem ); 4369 4370 $loader.remove(); 4371 4372 $parentItem.addClass( 'item-loaded' ); 4373 4374 if ( $masonryInstance ) { 4375 $masonryInstance.masonry( 'layout' ); 4376 } 4377 } ); 4378 4379 } else { 4380 var $loader = $( '.jet-portfolio__image-loader', $itemsList ); 4381 4382 $itemsList.addClass( 'item-loaded' ); 4383 4384 $loader.remove(); 4385 } 4386 4387 $filterList.on( 'click.jetPortfolio', self.filterHandler ); 4388 $moreButton.on( 'click.jetPortfolio', self.moreButtonHandler ); 4389 4390 self.render(); 4391 self.checkMoreButton(); 4392 }; 4393 4394 self.generateData = function() { 4395 if ( $filterList[0] ) { 4396 $filterList.each( function( index ) { 4397 var $this = $( this ), 4398 slug = $this.data('slug'); 4399 4400 filterData[ slug ] = false; 4401 4402 if ( 'all' == slug ) { 4403 filterData[ slug ] = true; 4404 } 4405 } ); 4406 } else { 4407 filterData['all'] = true; 4408 } 4409 4410 $itemsList.each( function( index ) { 4411 var $this = $( this ), 4412 slug = $this.data('slug'); 4413 4414 itemsData[ index ] = { 4415 selector: $this, 4416 slug: slug, 4417 visible: $this.hasClass( 'visible-status' ) ? true : false, 4418 more: $this.hasClass( 'hidden-status' ) ? true : false, 4419 lightboxEnabled: 'yes' === $this.find('.jet-portfolio__link').data( 'elementor-open-lightbox' ) ? true : false 4420 }; 4421 } ); 4422 }; 4423 4424 self.filterHandler = function( event ) { 4425 var $this = $( this ), 4426 counter = 1, 4427 slug = $this.data( 'slug' ), 4428 showItems = $this.data( 'showItems' ); 4429 4430 $filterList.removeClass( 'active' ); 4431 $this.addClass( 'active' ); 4432 4433 for ( var slugName in filterData ) { 4434 filterData[ slugName ] = false; 4435 4436 if ( slugName == slug ) { 4437 filterData[ slugName ] = true; 4438 currentFilter = slugName; 4439 } 4440 } 4441 4442 $.each( itemsData, function( index, obj ) { 4443 var visible = false; 4444 4445 if ( 'all' === showItems ) { 4446 4447 if ( self.isItemVisible( obj.slug ) && ! obj['more'] ) { 4448 visible = true; 4449 } 4450 4451 } else if ( self.isItemVisible( obj.slug ) ) { 4452 4453 if ( counter <= showItems ) { 4454 visible = true; 4455 obj.more = false; 4456 } else { 4457 obj.more = true; 4458 } 4459 4460 counter++ 4461 } 4462 4463 obj.visible = visible; 4464 4465 } ); 4466 4467 self.render(); 4468 self.checkMoreButton(); 4469 } 4470 4471 /** 4472 * [moreButtonHandler description] 4473 * @param {[type]} event [description] 4474 * @return {[type]} [description] 4475 */ 4476 self.moreButtonHandler = function( event ) { 4477 var $this = $( this ), 4478 counter = 1, 4479 activeFilter = $( '.jet-portfolio__filter-item.active', $instance ), 4480 showItems; 4481 4482 $.each( itemsData, function( index, obj ) { 4483 4484 if ( self.isItemVisible( obj.slug ) && obj.more && counter <= settings.perPage ) { 4485 obj.more = false;
4486 obj.visible = true; 4487 4488 counter++; 4489 } 4490 } ); 4491 4492 if ( activeFilter[0] ) { 4493 showItems = activeFilter.data( 'showItems' ); 4494 activeFilter.data( 'showItems', showItems + counter - 1 ); 4495 } 4496 4497 self.render(); 4498 self.checkMoreButton(); 4499 } 4500 4501 /** 4502 * [checkmoreButton description] 4503 * @return {[type]} [description] 4504 */ 4505 self.checkMoreButton = function() { 4506 var check = false; 4507 4508 $.each( itemsData, function( index, obj ) { 4509 4510 if ( self.isItemVisible( obj.slug ) && obj.more ) { 4511 check = true; 4512 } 4513 } ); 4514 4515 if ( check ) { 4516 $moreWrapper.removeClass( 'hidden-status' ); 4517 } else { 4518 $moreWrapper.addClass( 'hidden-status' ); 4519 } 4520 } 4521 4522 /** 4523 * [anyFilterEnabled description] 4524 * @return {Boolean} [description] 4525 */ 4526 self.isItemVisible = function( slugs ) { 4527 var slugList = JetElementsTools.getObjectValues( slugs ); 4528 4529 for ( var slug in filterData ) { 4530 var checked = filterData[ slug ]; 4531 4532 if ( checked && -1 !== slugList.indexOf( slug ) ) { 4533 return true; 4534 } 4535 } 4536 4537 return false; 4538 } 4539 4540 /** 4541 * [anyFilterEnabled description] 4542 * @return {Boolean} [description] 4543 */ 4544 self.anyFilterEnabled = function() { 4545 4546 for ( var slug in filterData ) { 4547 if ( filterData[ slug ] ) { 4548 return true; 4549 } 4550 } 4551 4552 return false; 4553 } 4554 4555 /** 4556 * Render 4557 * 4558 * @return void 4559 */ 4560 self.render = function() { 4561 var hideAnimation, 4562 showAnimation; 4563 4564 $itemsList.removeClass( 'visible-status' ).removeClass( 'hidden-status' ); 4565 4566 $.each( itemsData, function( index, itemData ) { 4567 var selector = $( '.jet-portfolio__inner', itemData.selector ), 4568 $itemLink = $( '.jet-portfolio__link', itemData.selector ), 4569 slideshowID = settings.id + '-' + currentFilter; 4570 4571 if ( itemData.visible ) { 4572 itemData.selector.addClass( 'visible-status' ); 4573 4574 if ( itemData.lightboxEnabled ) { 4575 $itemLink[0].setAttribute( 'data-elementor-lightbox-slideshow', slideshowID ); 4576 } 4577 4578 showAnimation = anime( { 4579 targets: selector[0], 4580 opacity: { 4581 value: 1, 4582 duration: 400, 4583 }, 4584 scale: { 4585 value: 1, 4586 duration: 500, 4587 easing: 'easeOutExpo' 4588 }, 4589 delay: 50, 4590 elasticity: false 4591 } ); 4592 } else { 4593 itemData.selector.addClass( 'hidden-status' ); 4594 $itemLink[0].removeAttribute( 'data-elementor-lightbox-slideshow' ); 4595 4596 hideAnimation = anime( { 4597 targets: selector[0], 4598 opacity: 0, 4599 scale: 0, 4600 duration: 500, 4601 elasticity: false 4602 } ); 4603 } 4604 } ); 4605 4606 if ( $masonryInstance ) { 4607 $masonryInstance.masonry( 'layout' ); 4608 } 4609 } 4610 } 4611 4612 /** 4613 * Jet Timeline Class 4614 * 4615 * @return {void} 4616 */ 4617 window.jetTimeLine = function ( $element ) { 4618 var $parentPopup = $element.closest( '.jet-popup__container-inner, .elementor-popup-modal .dialog-message' ), 4619 inPopup = !!$parentPopup[0], 4620 $viewport = inPopup ? $parentPopup : $(window), 4621 viewportOffset = inPopup ? $viewport.offset().top - $(window).scrollTop() : 0, 4622 self = this, 4623 $line = $element.find( '.jet-timeline__line' ), 4624 $progress = $line.find( '.jet-timeline__line-progress' ), 4625 $cards = $element.find( '.jet-timeline-item' ), 4626 $points = $element.find('.timeline-item__point'), 4627 4628 currentScrollTop = $viewport.scrollTop(), 4629 lastScrollTop = -1, 4630 currentWindowHeight = $viewport.height(),
4631 currentViewportHeight = inPopup ? $viewport.outerHeight() : window.innerHeight, 4632 lastWindowHeight = -1, 4633 requestAnimationId = null, 4634 flag = false; 4635 4636 self.onScroll = function (){ 4637 currentScrollTop = $viewport.scrollTop(); 4638 viewportOffset = inPopup ? $viewport.offset().top - $(window).scrollTop() : 0; 4639 4640 self.updateFrame(); 4641 self.animateCards(); 4642 }; 4643 4644 self.onResize = function() { 4645 currentScrollTop = $viewport.scrollTop(); 4646 currentWindowHeight = $viewport.height(); 4647 viewportOffset = inPopup ? $viewport.offset().top - $(window).scrollTop() : 0; 4648 4649 self.updateFrame(); 4650 }; 4651 4652 self.updateWindow = function() { 4653 flag = false; 4654 4655 $line.css({ 4656 'top' : $cards.first().find( $points ).offset().top - $cards.first().offset().top, 4657 'bottom' : ( $element.offset().top + $element.outerHeight() ) - $cards.last().find( $points ).offset().top 4658 }); 4659 4660 if ( ( lastScrollTop !== currentScrollTop ) ) { 4661 lastScrollTop = currentScrollTop; 4662 lastWindowHeight = currentWindowHeight; 4663 4664 self.updateProgress(); 4665 } 4666 }; 4667 4668 self.updateProgress = function() { 4669 var lastCartOffset = $cards.last().find( $points ).offset().top, 4670 progressFinishPosition = ! inPopup ? lastCartOffset : lastCartOffset + currentScrollTop - viewportOffset - $(window).scrollTop(), 4671 progressOffsetTop = ! inPopup ? $progress.offset().top : $progress.offset().top + currentScrollTop - viewportOffset - $(window).scrollTop(), 4672 progressHeight = ( currentScrollTop - progressOffsetTop ) + ( currentViewportHe
4672ight / 2 ); 4673 4674 if ( progressFinishPosition <= ( currentScrollTop + currentViewportHeight / 2 ) ) { 4675 progressHeight = progressFinishPosition - progressOffsetTop; 4676 } 4677 4678 $progress.css({ 4679 'height' : progressHeight + 'px' 4680 }); 4681 4682 $cards.each( function() { 4683 var itemOffset = $(this).find( $points ).offset().top; 4684 itemOffset = ! inPopup ? itemOffset : itemOffset + currentScrollTop - viewportOffset - $(window).scrollTop(); 4685 4686 if ( itemOffset < ( currentScrollTop + currentViewportHeight * 0.5 ) ) { 4687 $(this).addClass('is--active'); 4688 } else { 4689 $(this).removeClass('is--active'); 4690 } 4691 }); 4692 }; 4693 4694 self.updateFrame = function() { 4695 if ( ! flag ) { 4696 requestAnimationId = requestAnimationFrame( self.updateWindow ); 4697 } 4698 flag = true; 4699 }; 4700 4701 self.animateCards = function() { 4702 $cards.each( function() { 4703 var itemOffset = $(this).offset().top; 4704 itemOffset = ! inPopup ? itemOffset : itemOffset + currentScrollTop - viewportOffset - $(window).scrollTop(); 4705 4706 if( itemOffset <= currentScrollTop + currentViewportHe
4706ight * 0.9 && $(this).hasClass('jet-timeline-item--animated') ) { 4707 $(this).addClass('is--show'); 4708 } 4709 }); 4710 }; 4711 4712 self.init = function(){ 4713 $(document).ready(self.onScroll); 4714 $viewport.on('scroll.jetTimeline', self.onScroll); 4715 $(window).on('resize.jetTimeline orientationchange.jetTimeline', JetElementsTools.debounce( 50, self.onResize )); 4716 }; 4717 } 4718 4719 /** 4720 * [jetScratchEffect description] 4721 * @param {[type]} elementId [description] 4722 * @param {[type]} canvasId [description] 4723 * @param {[type]} completeCallback [description] 4724 * @return {[type]} [description] 4725 */ 4726 window.jetScratchEffect = function ( elementId, canvasId, completeCallback, fillpercent = 75 ) { 4727 var container = document.querySelector( elementId ), 4728 canvas = document.querySelector( canvasId ), 4729 canvasWidth = canvas.width, 4730 canvasHeight = canvas.height, 4731 ctx = canvas.getContext('2d'), 4732 brush = new Image(), 4733 isDrawing = false, 4734 lastPoint; 4735 4736 brush.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAxCAYAAABNuS5SAAAKFklEQVR42u2aCXCcdRnG997NJtlkk83VJE3apEma9CQlNAR60UqrGSqW4PQSO9iiTkE8BxWtlGMqYCtYrLRQtfVGMoJaGRFliijaViwiWgQpyCEdraI1QLXG52V+n/5nzd3ENnX/M8/sJvvt933/533e81ufL7MyK7NOzuXPUDD0FQCZlVn/+xUUQhkXHny8M2TxGsq48MBjXdAhL9/7YN26dd5nI5aVRrvEc0GFEBNKhbDjwsHh3qP/FJK1EdYIedOFlFAOgREhPlICifZDYoBjTna3LYe4xcI4oSpNcf6RvHjuAJRoVszD0qFBGmgMChipZGFxbqzQkJWVZUSOF7JRX3S4LtLTeyMtkkqljMBkPzHRs2aYY5PcZH/qLY1EIo18byQ6hBytIr3WCAXcV4tQHYvFxg3w3N6+Bh3OQolEoqCoqCinlw16JzTFJSE6PYuZKqvztbC2ex7bzGxhKu+rerjJrEEq+r9ieElJSXFDQ0Mh9zYzOzu7FBUWcO4Q9xbD6HYvhXhGLccVD5ZAPyfMqaioyOrBUgEv8FZXV8caGxtz8vLykhCWTnZIKmsKhUJnEYeKcKk2YYERH41G7UYnck1/WvAPOxsdLJm2+bEY0Ay0RNeqkytXQkoBZM4U5oOaoYSUkBGRtvnesrBZK4e4F6ypqSkuLy+v4KI99ZQxkfc6vZ4jNAl1wkbhG8LrhfNBCdkxmhYacvj/GOce+3K9MHHbDHUmicOufREELRIWch/DljzMsglutr+VIJO5KjGrVfZAnpF8mnCd8G5hrnC60Cl8T/iw8C1hKd9P9eDCMcgo5HwBx8BB/g7xeRPkrBbeJ3xTeAxjvRGVV3NcshfPG1JX4tVDQae47GuVOknCi23xHr5nyrxe2C1sFlYJ7xe+Jlwm7BRulItP0ms957RzTMK1ws41jMS8eDxehopaOCYfxc3AIHcIX+K6nxW+ImyVF1i8PQ8DTuwtdC1atCja3NwcHkq5EuXmo85G+jq+yMm28V4q/zcIPxV+K9zPxnbgTi0ocybu6wX66fx/vfAB4T1gHt8xI1wlXMF5zEXnQKC56ruEjwhvEa4WrrXvK/Yt5Pt5I1UveeVKyKmT+lpG2gQ2npMmez8ZzFT3e+HXwj
47367hKXNf6rFZbDpJUjESLdFsFX4mfFv4Fd/7qPBm4UPCJ4RNwncwym4UfYVUtiAcDk/T+3NRmylwWzAY7BCBCwYYogZPnrJoRNm2IDc3tw4FVKXFm95UmGLzkTTFpog524WnhQPCQeGvwiPCCuFCYmk5GbEJt3tOeF54HPVeLLyXxHOv8BPhYaFLeFU4gsI7OWeZk3g+hpJNvVMGIIqhdRvy+biVISouq2TBqWxoIL1wgBhU5AR1SzJvFR4UnhX+Bl4RfsFGP0npUkTymIQ7fh8Cf4l6F0LgXkj6o3O+buGfwj+ElzGQETaNeJqPhxiahckYq8KJ9V6mP+4pTIATjsGCA8lCQVy9VbhB2CM8itu9IBxlkx6O4nbmmpcSi0KUExa3Psfn23DZC4lhlhRuIWs/R1Y9BrpR4WHcfiOq34bLl5DJm1B7BANPGO4+2OJfDcVwX+RZkL5d+DRqeRJ360IJx1CFp4w/8/lhVGXxay1xKp8asQ31rSbgz2az1aBBWCZsgKTfEFe7uM4xYus9KHWXcBv3eolwJe67hJLIN6yubMVpW1tbbllZWVxtzjRquvQe9981IG3RZHUQttH7hB8IP0cdLwp/YnNHcdsjEP1xsEruO56i2Fy3UWXMskAgYAH/EjOiCD6NDc/XZ4v12RqSy3WQ9rJD3jPClwkZz2Aoy8JnUEjPcwYWfgfHvcIW84h308mABQP4Xp02OY44M4tSZSfx7UXIewU3NpXuxw0vJzauYDP1XM8y8Ttx67fhylYrdlAMW1x7h/BF3NWI+4PwFwjbSha26/xQuBmib6HDqeI+m4m5wzrj9A/xO+O5qbm4yizcbDOKfAjVWeC/WzAFLSeI+4hN9WzQ65EvED7D8Tt4vwE33O64rIfD1JW3k6xeQoX3UN6chyG8In4tcbHuRAyKw2ktVIIM2U5XcA7t2FKy5vWQeBexbbrTpvmZiJwN6e3EwKspW/ajqBuAKfKQk8m7KIce5bgnMNQDkLWPUmkj511DSVV5HJOd417FzrDAK7RjZLMZiURigmLVFCYs5tI2PFhpcUj/n6z6sp72LwJKiU2rUdp62rA7IX4XytpJ3Weh4XfE1/0kk/uoFX8kbCHudZLld5E8vJIs2+mbT8iznaR60DHMBt0EE1DySVlSsOBvyrL6zkZG5qI2T/QSBYTHMYAlq2tw1+0MFO4kVj5GSbSbgvkA8fQQr1uIdfdD5mZ1GhZbP0XfuwlPmOp0SNkYbkQV2JdlEsq69VJS+rTER+NtZVC+TX+NRFq1XGeiHXbG
4736UHMg6lk2/DiZ+mHU8wTueoTXLtS3F5e9l2PNZW9lyrOB5LGSmJokzMQ6OjqCA3wsMXLLhqrWoZgKe3lyZ5YtLiwsLLfMLhJL0ibW3rKa7oMQ+Ajq6gKHcMeHeP8qZcpRMvyt1J97SRabcNP1ZGsbKhSb6lF+5GR6shUnlqTSyPM7LZxV/PUqjOfTH6cvqx+XyN3aCfBPUWh3UZIcxC2/jgu/BJ7Eve/G1R/EXS9gaLCc0dgySqIm7jV4MhEYdAaN4R4eRHkBusJp3GNp56iSOscyYN0DaUch8Ai13X6yrg0PvotCO8nme0geKymBaulc1qO+NbxOOpHZtrcHR+nT6+wePvcnk8k8qv6iNBdyH4/OoGR5gXbv75D4NIX3NoruLSjtKmLlbTwCKER1NmV+QIqfS13aai0izUHsRKksAQE5g0w4fuehj9f+xb25Ym1tbcIhuw2COmkBn2cAcQAFbsclV1BTns49JZio3EQWPkgCySJpFIu8aor0UfeLigDTlUTa/8eimhRGuUiKOZPYtYNabh9EGik3Mkk+A9I8JTWoAiik/LEpzY8tY4uwWc4AJMjxQd8oXRHU8JqbW32orNyAiubZo0WR5wX9KyHrLpLD52nrxhFHa1CVV5w3081cRu/7BYichpEqfafA7/sCzhT7tVkhLZvhTeB8Gv1r6U+ty/gqtWHQCSNTcPOl9NmXM1S4hgRjBjjL1MdUJ8cx3uhe3d3dfh5Meb8qyKWsuJRidwtN/h20XEtxvTwya7tKncU8ACqmXVwLict5fy6TnFhra2uW7xT8dWk2BHptVBOx8GLKjo3g7bhrBQq1sdVsCvEkhLZIac1y/zmUSO0oO8fX/0P2Ub3cwaWpZSITnLnOpDlBWTIfMleJqFb10jXCBJUlMyORSIP14LhqNef6v/05bpZTdHulUyXKsufDNdRxZ4vIhSKwhQFG5vfLfcwZsx2X92Jhje8/P8OI+TK/oO+zeA84WTzkvI/6RuB3y6f68qf11xnyMiuzMms4178AwArmZmkkdGcAAAAASUVORK5CYII='; 4737 4738 canvas.addEventListener( 'mousedown', handleMouseDown, false ); 4739 canvas.addEventListener( 'mousemove', JetElementsTools.debounce( 5, handleMouseMove ), false ); 4740 canvas.addEventListener( 'mouseup', handleMouseUp, false ); 4741 4742 canvas.addEventListener( 'touchstart', handleMouseDown, false ); 4743 canvas.addEventListener( 'touchmove', handleMouseMove, false ); 4744 canvas.addEventListener( 'touchend', handleMouseUp, false ); 4745 4746 function distanceBetween( point1, point2 ) { 4747 return Math.sqrt( Math.pow( point2.x - point1.x, 2 ) + Math.pow( point2.y - point1.y, 2 ) ); 4748 } 4749 4750 function angleBetween( point1, point2 ) { 4751 return Math.atan2( point2.x - point1.x, point2.y - point1.y ); 4752 } 4753 4754 function getFilledInPixels( stride ) { 4755 4756 if ( ! stride || stride < 1 ) { 4757 stride = 1; 4758 } 4759 4760 var pixels = ctx.getImageData(0, 0, canvasWidth, canvasHeight), 4761 pdata = pixels.data, 4762 l = pdata.length, 4763 total = ( l / stride ), 4764 count = 0; 4765 4766 for( var i = count = 0; i < l; i += stride ) { 4767 if ( parseInt( pdata[i] ) === 0 ) { 4768 count++; 4769 } 4770 } 4771 4772 return Math.round( ( count / total ) * 100 ); 4773 } 4774 4775 function getMouse( e, canvas ) { 4776 var offsetX = 0, 4777 offsetY = 0, 4778 mx, 4779 my; 4780 4781 mx = ( e.pageX || e.touches[0].clientX ) - offsetX; 4782 my = ( e.pageY || e.touches[0].clientY ) - offsetY; 4783 4784 return { x: mx, y: my }; 4785 } 4786 4787 function handlePercentage( filledInPixels ) { 4788 filledInPixels = filledInPixels || 0; 4789 4790 if ( filledInPixels > fillpercent && completeCallback ) { 4791 completeCallback.call( canvas ); 4792 } 4793 } 4794 4795 function handleMouseDown( e ) { 4796 isDrawing = true; 4797 lastPoint = getMouse( e, canvas ); 4798 } 4799 4800 function handleMouseMove( e ) { 4801 4802 if ( ! isDrawing ) { 4803 return; 4804 } 4805 4806 e.preventDefault(); 4807 4808 var currentPoint = getMouse( e, canvas ), 4809 dist = distanceBetween( lastPoint, currentPoint ), 4810 angle = angleBetween( lastPoint, currentPoint ), 4811 x = 0, 4812 y = 0, 4813 userAgent = navigator.userAgent || navigator.vendor || window.opera, 4814 isIos = /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream, 4815 isMobileDevice = JetElementsTools.mobileAndTabletcheck(), 4816 yScroll = ( isMobileDevice && !isIos ) ? window.scrollY : 0; 4817 4818 for ( var i = 0; i < dist; i++ ) { 4819 x = lastPoint.x + ( Math.sin( angle ) * i ) - 40; 4820 y = lastPoint.y + ( Math.cos( angle ) * i ) - 40 + yScroll; 4821 ctx.globalCompositeOperation = 'destination-out'; 4822 ctx.drawImage( brush, x, y, 80, 80 ); 4823 } 4824 4825 lastPoint = currentPoint; 4826 4827 handlePercentage( getFilledInPixels( 32 ) ); 4828 } 4829 4830 function handleMouseUp( e ) { 4831 isDrawing = false; 4832 } 4833 } 4834 4835}( jQuery, window.elementorFrontend ) ); 4836
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.