vendor: 14,874 bytes, lines 1-513
1/*! 2 * Bowser - a browser detector 3 * https://github.com/ded/bowser 4 * MIT License | (c) Dustin Diaz 2015 5 */ 6 7!function (name, definition) { 8 if (typeof module != 'undefined' && module.exports) module.exports = definition() 9 else if (typeof define == 'function' && define.amd) define(name, definition) 10 else this[name] = definition() 11}('bowser', function () { 12 /** 13 * See useragents.js for examples of navigator.userAgent 14 */ 15 16 var t = true 17 18 function detect(ua) { 19 20 function getFirstMatch(regex) { 21 var match = ua.match(regex); 22 return (match && match.length > 1 && match[1]) || ''; 23 } 24 25 function getSecondMatch(regex) { 26 var match = ua.match(regex); 27 return (match && match.length > 1 && match[2]) || ''; 28 } 29 30 var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase() 31 , likeAndroid = /like android/i.test(ua) 32 , android = !likeAndroid && /android/i.test(ua) 33 , nexusMobile = /nexus\s*[0-6]\s*/i.test(ua) 34 , nexusTablet = !nexusMobile && /nexus\s*[0-9]+/i.test(ua) 35 , chromeos = /CrOS/.test(ua) 36 , silk = /silk/i.test(ua) 37 , sailfish = /sailfish/i.test(ua) 38 , tizen = /tizen/i.test(ua) 39 , webos = /(web|hpw)os/i.test(ua) 40 , windowsphone = /windows phone/i.test(ua) 41 , windows = !windowsphone && /windows/i.test(ua) 42 , mac = !iosdevice && !silk && /macintosh/i.test(ua) 43 , linux = !android && !sailfish && !tizen && !webos && /linux/i.test(ua) 44 , edgeVersion = getFirstMatch(/edge\/(\d+(\.\d+)?)/i) 45 , versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i) 46 , tablet = /tablet/i.test(ua) 47 , mobile = !tablet && /[^-]mobi/i.test(ua) 48 , xbox = /xbox/i.test(ua) 49 , result 50 51 if (/opera|opr|opios/i.test(ua)) { 52 result = { 53 name: 'Opera' 54 , opera: t 55 , version: versionIdentifier || getFirstMatch(/(?:opera|opr|opios)[\s\/](\d+(\.\d+)?)/i) 56 } 57 } 58 else if (/coast/i.test(ua)) { 59 result = { 60 name: 'Opera Coast' 61 , coast: t 62 , version: versionIdentifier || getFirstMatch(/(?:coast)[\s\/](\d+(\.\d+)?)/i) 63 } 64 } 65 else if (/yabrowser/i.test(ua)) { 66 result = { 67 name: 'Yandex Browser' 68 , yandexbrowser: t 69 , version: versionIdentifier || getFirstMatch(/(?:yabrowser)[\s\/](\d+(\.\d+)?)/i) 70 } 71 } 72 else if (/ucbrowser/i.test(ua)) { 73 result = { 74 name: 'UC Browser' 75 , ucbrowser: t 76 , version: getFirstMatch(/(?:ucbrowser)[\s\/](\d+(?:\.\d+)+)/i) 77 } 78 } 79 else if (/mxios/i.test(ua)) { 80 result = { 81 name: 'Maxthon' 82 , maxthon: t 83 , version: getFirstMatch(/(?:mxios)[\s\/](\d+(?:\.\d+)+)/i) 84 } 85 } 86 else if (/epiphany/i.test(ua)) { 87 result = { 88 name: 'Epiphany' 89 , epiphany: t 90 , version: getFirstMatch(/(?:epiphany)[\s\/](\d+(?:\.\d+)+)/i) 91 } 92 } 93 else if (/puffin/i.test(ua)) { 94 result = { 95 name: 'Puffin' 96 , puffin: t 97 , version: getFirstMatch(/(?:puffin)[\s\/](\d+(?:\.\d+)?)/i) 98 } 99 } 100 else if (/sleipnir/i.test(ua)) { 101 result = { 102 name: 'Sleipnir' 103 , sleipnir: t 104 , version: getFirstMatch(/(?:sleipnir)[\s\/](\d+(?:\.\d+)+)/i) 105 } 106 } 107 else if (/k-meleon/i.test(ua)) { 108 result = { 109 name: 'K-Meleon' 110 , kMeleon: t 111 , version: getFirstMatch(/(?:k-meleon)[\s\/](\d+(?:\.\d+)+)/i) 112 } 113 } 114 else if (windowsphone) { 115 result = { 116 name: 'Windows Phone' 117 , windowsphone: t 118 } 119 if (edgeVersion) { 120 result.msedge = t 121 result.version = edgeVersion 122 } 123 else { 124 result.msie = t 125 result.version = getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i) 126 } 127 } 128 else if (/msie|trident/i.test(ua)) { 129 result = { 130 name: 'Internet Explorer' 131 , msie: t 132 , version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i) 133 } 134 } else if (chromeos) { 135 result = { 136 name: 'Chrome' 137 , chromeos: t 138 , chromeBook: t 139 , chrome: t 140 , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) 141 } 142 } else if (/chrome.+? edge/i.test(ua)) { 143 result = { 144 name: 'Microsoft Edge' 145 , msedge: t 146 , version: edgeVersion 147 } 148 } 149 else if (/vivaldi/i.test(ua)) { 150 result = { 151 name: 'Vivaldi' 152 , vivaldi: t 153 , version: getFirstMatch(/vivaldi\/(\d+(\.\d+)?)/i) || versionIdentifier 154 } 155 } 156 else if (sailfish) { 157 result = { 158 name: 'Sailfish' 159 , sailfish: t 160 , version: getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i) 161 } 162 } 163 else if (/seamonkey\//i.test(ua)) { 164 result = { 165 name: 'SeaMonkey' 166 , seamonkey: t 167 , version: getFirstMatch(/seamonkey\/(\d+(\.\d+)?)/i) 168 } 169 } 170 else if (/firefox|iceweasel|fxios/i.test(ua)) { 171 result = { 172 name: 'Firefox' 173 , firefox: t 174 , version: getFirstMatch(/(?:firefox|iceweasel|fxios)[ \/](\d+(\.\d+)?)/i) 175 } 176 if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) { 177 result.firefoxos = t 178 } 179 } 180 else if (silk) { 181 result = { 182 name: 'Amazon Silk' 183 , silk: t 184 , version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i) 185 } 186 } 187 else if (/phantom/i.test(ua)) { 188 result = { 189 name: 'PhantomJS' 190 , phantom: t 191 , version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i) 192 } 193 } 194 else if (/slimerjs/i.test(ua)) { 195 result = { 196 name: 'SlimerJS' 197 , slimer: t 198 , version: getFirstMatch(/slimerjs\/(\d+(\.\d+)?)/i) 199 } 200 } 201 else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) { 202 result = { 203 name: 'BlackBerry' 204 , blackberry: t 205 , version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i) 206 } 207 } 208 else if (webos) { 209 result = { 210 name: 'WebOS' 211 , webos: t 212 , version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i) 213 }; 214 if( /touchpad\//i.test(ua) ){ 215 result.touchpad = t; 216 } 217 } 218 else if (/bada/i.test(ua)) { 219 result = { 220 name: 'Bada' 221 , bada: t 222 , version: getFirstMatch(/dolfin\/(\d+(\.\d+)?)/i) 223 }; 224 } 225 else if (tizen) { 226 result = { 227 name: 'Tizen' 228 , tizen: t 229 , version: getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.\d+)?)/i) || versionIdentifier 230 }; 231 } 232 else if (/qupzilla/i.test(ua)) { 233 result = { 234 name: 'QupZilla' 235 , qupzilla: t 236 , version: getFirstMatch(/(?:qupzilla)[\s\/](\d+(?:\.\d+)+)/i) || versionIdentifier 237 } 238 } 239 else if (/chromium/i.test(ua)) { 240 result = { 241 name: 'Chromium' 242 , chromium: t 243 , version: getFirstMatch(/(?:chromium)[\s\/](\d+(?:\.\d+)?)/i) || versionIdentifier 244 } 245 } 246 else if (/chrome|crios|crmo/i.test(ua)) { 247 result = { 248 name: 'Chrome' 249 , chrome: t 250 , version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) 251 } 252 } 253 else if (android) { 254 result = { 255 name: 'Android' 256 , version: versionIdentifier 257 } 258 } 259 else if (/safari|applewebkit/i.test(ua)) { 260 result = { 261 name: 'Safari' 262 , safari: t 263 } 264 if (versionIdentifier) { 265 result.version = versionIdentifier 266 } 267 } 268 else if (iosdevice) { 269 result = { 270 name : iosdevice == 'iphone' ? 'iPhone' : iosdevice == 'ipad' ? 'iPad' : 'iPod' 271 } 272 // WTF: version is not part of user agent in web apps 273 if (versionIdentifier) { 274 result.version = versionIdentifier 275 } 276 } 277 else if(/googlebot/i.test(ua)) { 278 result = { 279 name: 'Googlebot' 280 , googlebot: t 281 , version: getFirstMatch(/googlebot\/(\d+(\.\d+))/i) || versionIdentifier 282 } 283 } 284 else { 285 result = { 286 name: getFirstMatch(/^(.*)\/(.*) /), 287 version: getSecondMatch(/^(.*)\/(.*) /) 288 }; 289 } 290 291 // set webkit or gecko flag for browsers based on these engines 292 if (!result.msedge && /(apple)?webkit/i.test(ua)) { 293 if (/(apple)?webkit\/537\.36/i.test(ua)) { 294 result.name = result.name || "Blink" 295 result.blink = t 296 } else { 297 result.name = result.name || "Webkit" 298 result.webkit = t 299 } 300 if (!result.version && versionIdentifier) { 301 result.version = versionIdentifier 302 } 303 } else if (!result.opera && /gecko\//i.test(ua)) { 304 result.name = result.name || "Gecko" 305 result.gecko = t 306 result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i) 307 } 308 309 // set OS flags for platforms that have multiple browsers 310 if (!result.msedge && (android || result.silk)) { 311 result.android = t 312 } else if (iosdevice) { 313 result[iosdevice] = t 314 result.ios = t 315 } else if (mac) { 316 result.mac = t 317 } else if (xbox) { 318 result.xbox = t 319 } else if (windows) { 320 result.windows = t 321 } else if (linux) { 322 result.linux = t 323 } 324 325 // OS version extraction 326 var osVersion = ''; 327 if (result.windowsphone) { 328 osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i); 329 } else if (iosdevice) { 330 osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i); 331 osVersion = osVersion.replace(/[_\s]/g, '.'); 332 } else if (android) { 333 osVersion = getFirstMatch(/android[ \/-](\d+(\.\d+)*)/i); 334 } else if (result.webos) { 335 osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i); 336 } else if (result.blackberry) { 337 osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i); 338 } else if (result.bada) { 339 osVersion = getFirstMatch(/bada\/(\d+(\.\d+)*)/i); 340 } else if (result.tizen) { 341 osVersion = getFirstMatch(/tizen[\/\s](\d+(\.\d+)*)/i); 342 } 343 if (osVersion) { 344 result.osversion = osVersion; 345 } 346 347 // device type extraction 348 var osMajorVersion = osVersion.split('.')[0]; 349 if ( 350 tablet 351 || nexusTablet 352 || iosdevice == 'ipad' 353 || (android && (osMajorVersion == 3 || (osMajorVersion >= 4 && !mobile))) 354 || result.silk 355 ) { 356 result.tablet = t 357 } else if ( 358 mobile 359 || iosdevice == 'iphone' 360 || iosdevice == 'ipod' 361 || android 362 || nexusMobile 363 || result.blackberry 364 || result.webos 365 || result.bada 366 ) { 367 result.mobile = t 368 } 369 370 // Graded Browser Support 371 // http://developer.yahoo.com/yui/articles/gbs 372 if (result.msedge || 373 (result.msie && result.version >= 10) || 374 (result.yandexbrowser && result.version >= 15) || 375 (result.vivaldi && result.version >= 1.0) || 376 (result.chrome && result.version >= 20) || 377 (result.firefox && result.version >= 20.0) || 378 (result.safari && result.version >= 6) || 379 (result.opera && result.version >= 10.0) || 380 (result.ios && result.osversion && result.osversion.split(".")[0] >= 6) || 381 (result.blackberry && result.version >= 10.1) 382 || (result.chromium && result.version >= 20) 383 ) { 384 result.a = t; 385 } 386 else if ((result.msie && result.version < 10) || 387 (result.chrome && result.version < 20) || 388 (result.firefox && result.version < 20.0) || 389 (result.safari && result.version < 6) || 390 (result.opera && result.version < 10.0) || 391 (result.ios && result.osversion && result.osversion.split(".")[0] < 6) 392 || (result.chromium && result.version < 20) 393 ) { 394 result.c = t 395 } else result.x = t 396 397 return result 398 } 399 400 var bowser = detect(typeof navigator !== 'undefined' ? navigator.userAgent : '') 401 402 bowser.test = function (browserList) { 403 for (var i = 0; i < browserList.length; ++i) { 404 var browserItem = browserList[i]; 405 if (typeof browserItem=== 'string') { 406 if (browserItem in bowser) { 407 return true; 408 } 409 } 410 } 411 return false; 412 } 413 414 /** 415 * Get version precisions count 416 * 417 * @example 418 * getVersionPrecision("1.10.3") // 3 419 * 420 * @param {string} version 421 * @return {number} 422 */ 423 function getVersionPrecision(version) { 424 return version.split(".").length; 425 } 426 427 /** 428 * Array::map polyfill 429 * 430 * @param {Array} arr 431 * @param {Function} iterator 432 * @return {Array} 433 */ 434 function map(arr, iterator) { 435 var result = [], i; 436 if (Array.prototype.map) { 437 return Array.prototype.map.call(arr, iterator); 438 } 439 for (i = 0; i < arr.length; i++) { 440 result.push(iterator(arr[i])); 441 } 442 return result; 443 } 444 445 /** 446 * Calculate browser version weight 447 * 448 * @example 449 * compareVersions(['1.10.2.1', '1.8.2.1.90']) // 1 450 * compareVersions(['1.010.2.1', '1.09.2.1.90']); // 1 451 * compareVersions(['1.10.2.1', '1.10.2.1']); // 0 452 * compareVersions(['1.10.2.1', '1.0800.2']); // -1 453 * 454 * @param {Array<String>} versions versions to compare 455 * @return {Number} comparison result 456 */ 457 function compareVersions(versions) { 458 // 1) get common precision for both versions, for example for "10.0" and "9" it should be 2 459 var precision = Math.max(getVersionPrecision(versions[0]), getVersionPrecision(versions[1])); 460 var chunks = map(versions, function (version) { 461 var delta = precision - getVersionPrecision(version); 462 463 // 2) "9" -> "9.0" (for precision = 2) 464 version = version + new Array(delta + 1).join(".0"); 465 466 // 3) "9.0" -> ["000000000"", "000000009"] 467 return map(version.split("."), function (chunk) { 468 return new Array(20 - chunk.length).join("0") + chunk; 469 }).reverse(); 470 }); 471 472 // iterate in reverse order by reversed chunks array 473 while (--precision >= 0) { 474 // 4) compare: "000000009" > "000000010" = false (but "9" > "10" = true) 475 if (chunks[0][precision] > chunks[1][precision]) { 476 return 1; 477 } 478 else if (chunks[0][precision] === chunks[1][precision]) { 479 if (precision === 0) { 480 // all version chunks are same 481 return 0; 482 } 483 } 484 else { 485 return -1; 486 } 487 } 488 } 489 490 /** 491 * Check if browser is unsupported 492 * 493 * @example 494 * bowser.isUnsupportedBrowser({ 495 * msie: "10", 496 * firefox: "23", 497 * chrome: "29", 498 * safari: "5.1", 499 * opera: "16", 500 * phantom: "534" 501 * }); 502 * 503 * @param {Object} minVersions map of minimal version to browser 504 * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map 505 * @param {String} [ua] user agent string 506 * @return {Boolean} 507 */ 508 function isUnsupportedBrowser(minVersions, strictMode, ua) { 509 var _bowser = bowser; 510 511 // make strictMode param optional with ua param usage 512 if (typeof strictMode === 'string') { 513 ua = strictMode;
514 strictMode = void(0); 515 } 516 517 if (strictMode === void(0)) { 518 strictMode = false; 519 } 520 if (ua) { 521 _bowser = detect(ua); 522 } 523 524 var version = "" + _bowser.version; 525 for (var browser in minVersions) { 526 if (minVersions.hasOwnProperty(browser)) { 527 if (_bowser[browser]) { 528 // browser version and min supported version. 529 return compareVersions([version, minVersions[browser]]) < 0; 530 } 531 } 532 } 533 534 return strictMode; // not found 535 } 536 537 /** 538 * Check if browser is supported 539 * 540 * @param {Object} minVersions map of minimal version to browser 541 * @param {Boolean} [strictMode = false] flag to return false if browser wasn't found in map 542 * @param {String} [ua] user agent string 543 * @return {Boolean} 544 */ 545 function check(minVersions, strictMode, ua) { 546 return !isUnsupportedBrowser(minVersions, strictMode, ua); 547 } 548 549 bowser.isUnsupportedBrowser = isUnsupportedBrowser; 550 bowser.compareVersions = compareVersions; 551 bowser.check = check; 552 553 /* 554 * Set our detect method to the main bowser object so we can 555 * reuse it to test other user agents. 556 * This is needed to implement future tests. 557 */ 558 bowser._detect = detect; 559 560 return bowser 561}); 562 563(function($){ 564 UABBTrigger = { 565 566 /** 567 * Trigger a hook. 568 * 569 * @since 1.1.0.3 570 * @method triggerHook 571 * @param {String} hook The hook to trigger. 572 * @param {Array} args An array of args to pass to the hook. 573 */ 574 triggerHook: function( hook, args ) 575 { 576 $( 'body' ).trigger( 'uabb-trigger.' + hook, args ); 577 }, 578 579 /** 580 * Add a hook. 581 * 582 * @since 1.1.0.3 583 * @method addHook 584 * @param {String} hook The hook to add. 585 * @param {Function} callback A function to call when the hook is triggered. 586 */ 587 addHook: function( hook, callback ) 588 { 589 $( 'body' ).on( 'uabb-trigger.' + hook, callback ); 590 }, 591 592 /** 593 * Remove a hook. 594 * 595 * @since 1.1.0.3 596 * @method removeHook 597 * @param {String} hook The hook to remove. 598 * @param {Function} callback The callback function to remove. 599 */ 600 removeHook: function( hook, callback ) 601 { 602 $( 'body' ).off( 'uabb-trigger.' + hook, callback ); 603 }, 604 }; 605})(jQuery); 606 607jQuery(document).ready(function( $ ) { 608 609 var uabb_browser = bowser.name, 610 uabb_browser_v = bowser.version, 611 uabb_browser_class = uabb_browser.replace(/\s+/g, '-').toLowerCase(), 612 uabb_browser_v_class = uabb_browser_class + parseInt( uabb_browser_v ); 613 614 $('html').addClass(uabb_browser_class).addClass(uabb_browser_v_class); 615}); 616var wpAjaxUrl = 'https://lynnco.com/wp-admin/admin-ajax.php';var flBuilderUrl = 'https://lynnco.com/wp-content/plugins/bb-plugin/';var FLBuilderLayoutConfig = { 617 anchorLinkAnimations : { 618 duration : 1000, 619 easing : 'swing', 620 offset : 100 621 }, 622 paths : { 623 pluginUrl : 'https://lynnco.com/wp-content/plugins/bb-plugin/', 624 wpAjaxUrl : 'https://lynnco.com/wp-admin/admin-ajax.php' 625 }, 626 breakpoints : { 627 small : 768, 628 medium : 992, 629 large : 1200 }, 630 waypoint: { 631 offset: 80 632 }, 633 emptyColWidth: '0%' 634}; 635(function($){ 636 637 if(typeof FLBuilderLayout != 'undefined') { 638 return; 639 } 640 641 /** 642 * Helper class with generic logic for a builder layout. 643 * 644 * @class FLBuilderLayout 645 * @since 1.0 646 */ 647 FLBuilderLayout = { 648 649 /** 650 * Initializes a builder layout. 651 * 652 * @since 1.0 653 * @method init 654 */ 655 init: function() 656 { 657 // Destroy existing layout events. 658 FLBuilderLayout._destroy(); 659 660 // Init CSS classes. 661 FLBuilderLayout._initClasses(); 662 663 // Init backgrounds.
664 FLBuilderLayout._initBackgrounds(); 665 666 // Init buttons. 667 FLBuilderLayout._initButtons(); 668 669 // Init row shape layer height. 670 FLBuilderLayout._initRowShapeLayerHeight(); 671 672 // Only init if the builder isn't active. 673 if ( 0 === $('.fl-builder-edit').length ) { 674 675 // Init anchor links. 676 FLBuilderLayout._initAnchorLinks(); 677 678 // Init the browser hash. 679 FLBuilderLayout._initHash(); 680 681 // Init forms. 682 FLBuilderLayout._initForms(); 683 684 FLBuilderLayout._reorderMenu(); 685 } 686 else { 687 FLBuilderLayout._initNestedColsWidth(); 688 } 689 $('body').removeClass( 'fl-no-js' ); 690 }, 691 692 /** 693 * Public method for refreshing Wookmark or MosaicFlow galleries 694 * within an element. 695 * 696 * @since 1.7.4 697 * @method refreshGalleries 698 */ 699 refreshGalleries: function( element ) 700 { 701 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 702 mfContent = $element.find( '.fl-mosaicflow-content' ), 703 wmContent = $element.find( '.fl-gallery' ), 704 mfObject = null; 705 706 if ( mfContent ) { 707 708 mfObject = mfContent.data( 'mosaicflow' ); 709 710 if ( mfObject ) { 711 mfObject.columns = $( [] ); 712 mfObject.columnsHeights = []; 713 mfContent.data( 'mosaicflow', mfObject ); 714 mfContent.mosaicflow( 'refill' ); 715 } 716 } 717 if ( wmContent ) { 718 wmContent.trigger( 'refreshWookmark' ); 719 } 720 }, 721 722 /** 723 * Public method for refreshing Masonry within an element 724 * 725 * @since 1.8.1 726 * @method refreshGridLayout 727 */ 728 refreshGridLayout: function( element ) 729 { 730 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 731 msnryContent = $element.find('.masonry'); 732 733 if ( msnryContent.length ) { 734 msnryContent.masonry('layout'); 735 } 736 }, 737 738 /** 739 * Public method for reloading BxSlider within an element 740 * 741 * @since 1.8.1 742 * @method reloadSlider 743 */ 744 reloadSlider: function( content ) 745 { 746 var $content = 'undefined' == typeof content ? $('body') : $(content); 747 748 // reload sliders. 749 if ($content.find('.bx-viewport > div').length > 0) { 750 $.each($content.find('.bx-viewport > div'), function (key, slider) { 751 setTimeout(function () { 752 $(slider).data('bxSlider').reloadSlider(); 753 }, 100); 754 }); 755 } 756 }, 757 758 /** 759 * Public method for resizing WP audio player 760 * 761 * @since 1.8.2 762 * @method resizeAudio 763 */ 764 resizeAudio: function( element ) 765 { 766 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 767 audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'), 768 player = null, 769 mejsPlayer = null, 770 rail = null, 771 railWidth = 400; 772 773 if ( audioPlayers.length && typeof mejs !== 'undefined' ) { 774 audioPlayers.each(function(){ 775 player = $(this); 776 mejsPlayer = mejs.players[player.attr('id')]; 777 rail = player.find('.mejs-controls .mejs-time-rail'); 778 var innerMejs = player.find('.mejs-inner'), 779 total = player.find('.mejs-controls .mejs-time-total'); 780 781 if ( typeof mejsPlayer !== 'undefined' ) { 782 railWidth = Math.ceil(player.width() * 0.8); 783 784 if ( innerMejs.length ) { 785 786 rail.css('width', railWidth +'px!important'); 787 //total.width(rail.width() - 10); 788 789 mejsPlayer.options.autosizeProgress = true; 790 791 // webkit has trouble doing this without a delay 792 setTimeout(function () { 793 mejsPlayer.setControlsSize(); 794 }, 50); 795 796 player.find('.mejs-inner').css({ 797 visibility: 'visible', 798 height: 'inherit' 799 }); 800 } 801 } 802 }); 803 } 804 }, 805 806 /** 807 * Public method for preloading WP audio player when it's inside the hidden element 808 * 809 * @since 1.8.2 810 * @method preloadAudio 811 */ 812 preloadAudio: function(element) 813 { 814 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ), 815 contentWrap = $element.closest('.fl-accordion-item'), 816 audioPlayers = $element.find('.wp-audio-shortcode.mejs-audio'); 817 818 if ( ! contentWrap.hasClass('fl-accordion-item-active') && audioPlayers.find('.mejs-inner').length ) { 819 audioPlayers.find('.mejs-inner').css({ 820 visibility : 'hidden', 821 height: 0 822 }); 823 } 824 }, 825 826 /** 827 * Public method for resizing slideshow momdule within the tab 828 * 829 * @since 1.10.5 830 * @method resizeSlideshow 831 */ 832 resizeSlideshow: function(){ 833 if(typeof YUI !== 'undefined') { 834 YUI().use('node-event-simulate', function(Y) { 835 Y.one(window).simulate("resize"); 836 }); 837 } 838 }, 839 840 /** 841 * Public method for reloading an embedded Google Map within the tabs or hidden element. 842 * 843 * @since 2.2 844 * @method reloadGoogleMap 845 */ 846 reloadGoogleMap: function(element){ 847 var $element = 'undefined' == typeof element ? $( 'body' ) : $( element ),
848 googleMap = $element.find( 'iframe[src*="google.com/maps"]' ); 849 850 if ( googleMap.length ) { 851 googleMap.attr( 'src', function(i, val) { 852 return val; 853 }); 854 } 855 }, 856 857 /** 858 * Unbinds builder layout events. 859 * 860 * @since 1.0 861 * @access private 862 * @method _destroy 863 */ 864 _destroy: function() 865 { 866 var win = $(window); 867 868 win.off('scroll.fl-bg-parallax'); 869 win.off('resize.fl-bg-video'); 870 }, 871 872 /** 873 * Checks to see if the current device has touch enabled. 874 * 875 * @since 1.0 876 * @access private 877 * @method _isTouch 878 * @return {Boolean} 879 */ 880 _isTouch: function() 881 { 882 if(('ontouchstart' in window) || (window.DocumentTouch && document instanceof DocumentTouch)) { 883 return true; 884 } 885 886 return false; 887 }, 888 889 /** 890 * Checks to see if the current device is mobile. 891 * 892 * @since 1.7 893 * @access private 894 * @method _isMobile 895 * @return {Boolean} 896 */ 897 _isMobile: function() 898 { 899 return /Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi|webOS/i.test( navigator.userAgent ); 900 }, 901 902 /** 903 * Initializes builder body classes. 904 * 905 * @since 1.0 906 * @access private 907 * @method _initClasses 908 */ 909 _initClasses: function() 910 { 911 var body = $( 'body' ), 912 ua = navigator.userAgent; 913 914 // Add the builder body class (skip on block-only frontend to avoid layout break). 915 if ( ! body.hasClass( 'fl-builder-blocks-only' ) && ! body.hasClass( 'archive' ) && $( '.fl-builder-content-primary' ).length > 0 ) { 916 body.addClass('fl-builder'); 917 } 918 919 // Add the builder touch body class. 920 if(FLBuilderLayout._isTouch()) { 921 body.addClass('fl-builder-touch'); 922 } 923 924 // Add the builder mobile body class. 925 if(FLBuilderLayout._isMobile()) { 926 body.addClass('fl-builder-mobile'); 927 } 928 929 if ( $(window).width() < FLBuilderLayoutConfig.breakpoints.small ) { 930 body.addClass( 'fl-builder-breakpoint-small' ); 931 } 932 933 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.small && $(window).width() < FLBuilderLayoutConfig.breakpoints.medium ) { 934 body.addClass( 'fl-builder-breakpoint-medium' ); 935 } 936 937 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.medium && $(window).width() < FLBuilderLayoutConfig.breakpoints.large ) { 938 body.addClass( 'fl-builder-breakpoint-large' ); 939 } 940 941 if ( $(window).width() > FLBuilderLayoutConfig.breakpoints.large ) { 942 body.addClass( 'fl-builder-breakpoint-default' ); 943 } 944 945 // IE11 body class. 946 if ( ua.indexOf( 'Trident/7.0' ) > -1 && ua.indexOf( 'rv:11.0' ) > -1 ) { 947 body.addClass( 'fl-builder-ie-11' ); 948 } 949 }, 950 951 /** 952 * Initializes builder node backgrounds that require 953 * additional JavaScript logic such as parallax. 954 * 955 * @since 1.1.4 956 * @access private
957 * @method _initBackgrounds 958 */ 959 _initBackgrounds: function() 960 { 961 var win = $(window); 962 963 // Init parallax backgrounds. 964 if($('.fl-row-bg-parallax').length > 0 && !FLBuilderLayout._isMobile()) { 965 FLBuilderLayout._scrollParallaxBackgrounds(); 966 FLBuilderLayout._initParallaxBackgrounds(); 967 win.on('resize.fl-bg-parallax', FLBuilderLayout._initParallaxBackgrounds); 968 win.on('scroll.fl-bg-parallax', FLBuilderLayout._scrollParallaxBackgrounds); 969 } 970 971 // Init video backgrounds. 972 if($('.fl-bg-video').length > 0) { 973 FLBuilderLayout._initBgVideos(); 974 FLBuilderLayout._resizeBgVideos(); 975 976 // Ensure FLBuilderLayout._resizeBgVideos() is only called once on window resize. 977 var resizeBGTimer = null; 978 win.on('resize.fl-bg-video', function(e){ 979 clearTimeout( resizeBGTimer ); 980 resizeBGTimer = setTimeout(function() { 981 FLBuilderLayout._resizeBgVideos(e); 982 }, 100 ); 983 }); 984 } 985 }, 986 987 /** 988 * Initializes all buttons in a layout. 989 * 990 * @since 2.10 991 * @access private 992 * @method _initButtons 993 */ 994 _initButtons: function() 995 { 996 // Trigger click event on Enter or Space key press for deprecated button markup. 997 $('a.fl-button[role="button"]').on('keydown', function(event) { 998 if (event.key === 'Enter' || event.key === ' ') { 999 // Necessary to prevent the default behavior of the space key from scrolling the page 1000 event.preventDefault(); 1001 $(this).trigger('click'); 1002 } 1003 }); 1004 }, 1005 1006 /** 1007 * Initializes all parallax backgrounds in a layout. 1008 * 1009 * @since 1.1.4 1010 * @access private 1011 * @method _initParallaxBackgrounds 1012 */ 1013 _initParallaxBackgrounds: function() 1014 { 1015 $('.fl-row-bg-parallax').each(FLBuilderLayout._initParallaxBackground); 1016 }, 1017 1018 /** 1019 * Initializes a single parallax background. 1020 * 1021 * @since 1.1.4 1022 * @access private 1023 * @method _initParallaxBackgrounds 1024 */ 1025 _initParallaxBackground: function() 1026 { 1027 var row = $(this), 1028 content = row.find('> .fl-row-content-wrap'), 1029 winWidth = $(window).width(), 1030 screenSize = '', 1031 imageSrc = { 1032 default: '', 1033 medium: '', 1034 responsive: '', 1035 }; 1036 1037 imageSrc.default = row.data('parallax-image') || ''; 1038 imageSrc.medium = row.data('parallax-image-medium') || imageSrc.default; 1039 imageSrc.responsive = row.data('parallax-image-responsive') || imageSrc.medium; 1040 1041 if (winWidth > FLBuilderLayoutConfig.breakpoints.medium) { 1042 screenSize = 'default'; 1043 } else if (winWidth > FLBuilderLayoutConfig.breakpoints.small && winWidth <= FLBuilderLayoutConfig.breakpoints.medium ) { 1044 screenSize = 'medium'; 1045 } else if (winWidth <= FLBuilderLayoutConfig.breakpoints.small) { 1046 screenSize = 'responsive'; 1047 } 1048 1049 content.css('background-image', 'url(' + imageSrc[screenSize] + ')'); 1050 row.data('current-image-loaded', screenSize ); 1051 1052 }, 1053 1054 /** 1055 * Fires when the window is scrolled to adjust 1056 * parallax backgrounds. 1057 * 1058 * @since 1.1.4 1059 * @access private 1060 * @method _scrollParallaxBackgrounds 1061 */ 1062 _scrollParallaxBackgrounds: function() 1063 { 1064 $('.fl-row-bg-parallax').each(FLBuilderLayout._scrollParallaxBackground); 1065 }, 1066 1067 /** 1068 * Fires when the window is scrolled to adjust 1069 * a single parallax background. 1070 * 1071 * @since 1.1.4 1072 * @access private 1073 * @method _scrollParallaxBackground 1074 */ 1075 _scrollParallaxBackground: function() 1076 { 1077 var win = $(window), 1078 row = $(this), 1079 content = row.find('> .fl-row-content-wrap'), 1080 speed = row.data('parallax-speed'), 1081 offset = content.offset(), 1082 yPos = -((win.scrollTop() - offset.top) / speed), 1083 initialOffset = ( row.data('parallax-offset') != null ) ? row.data('parallax-offset') : 0, 1084 totalOffset = yPos - initialOffset; 1085 1086 content.css('background-position', 'center ' + totalOffset + 'px'); 1087 }, 1088 1089 /** 1090 * Initializes all video backgrounds. 1091 * 1092 * @since 1.6.3.3 1093 * @access private 1094 * @method _initBgVideos 1095 */ 1096 _initBgVideos: function() 1097 { 1098 $('.fl-bg-video').each(FLBuilderLayout._initBgVideo); 1099 }, 1100 1101 /** 1102 * Initializes a video background. 1103 * 1104 * @since 1.6.3.3 1105 * @access private 1106 * @method _initBgVideo 1107 */ 1108 _initBgVideo: function() 1109 { 1110 var wrap = $( this ), 1111 width = wrap.data( 'width' ), 1112 height = wrap.data( 'height' ), 1113 mp4 = wrap.data( 'mp4' ), 1114 youtube = wrap.data( 'youtube'), 1115 vimeo = wrap.data( 'vimeo'), 1116 mp4Type = wrap.data( 'mp4-type' ), 1117 webm = wrap.data( 'webm' ), 1118 webmType = wrap.data( 'webm-type' ), 1119 fallback = wrap.data( 'fallback' ), 1120 loaded = wrap.data( 'loaded' ), 1121 videoMobile = wrap.data( 'video-mobile' ), 1122 playPauseButton = wrap.find('.fl-bg-video-play-pause-control'), 1123 fallbackTag = '', 1124 videoTag = null, 1125 mp4Tag = null, 1126 webmTag = null; 1127 1128 // Return if the video has been loaded for this row. 1129 if ( loaded ) { 1130 return; 1131 } 1132
1133 videoTag = $( '<video autoplay loop muted playsinline></video>' ); 1134 1135 /** 1136 * Add poster image (fallback image) 1137 */ 1138 if( 'undefined' != typeof fallback && '' != fallback ) { 1139 videoTag.attr( 'poster', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' ) 1140 videoTag.css({ 1141 backgroundImage: 'url("' + fallback + '")', 1142 backgroundColor: 'transparent', 1143 backgroundRepeat: 'no-repeat', 1144 backgroundSize: 'cover', 1145 backgroundPosition: 'center center', 1146 }) 1147 } 1148 1149 // MP4 Source Tag 1150 if ( 'undefined' != typeof mp4 && '' != mp4 ) { 1151 1152 mp4Tag = $( '<source />' ); 1153 mp4Tag.attr( 'src', mp4 ); 1154 mp4Tag.attr( 'type', mp4Type ); 1155 1156 videoTag.append( mp4Tag ); 1157 } 1158 // WebM Source Tag 1159 if ( 'undefined' != typeof webm && '' != webm ) { 1160 1161 webmTag = $( '<source />' ); 1162 webmTag.attr( 'src', webm ); 1163 webmTag.attr( 'type', webmType ); 1164 1165 videoTag.append( webmTag ); 1166 } 1167 1168 // This is either desktop, or mobile is enabled. 1169 if ( ! FLBuilderLayout._isMobile() || ( FLBuilderLayout._isMobile() && "yes" == videoMobile ) ) { 1170 if ( 'undefined' != typeof youtube ) { 1171 FLBuilderLayout._initYoutubeBgVideo.apply( this ); 1172 } 1173 else if ( 'undefined' != typeof vimeo ) { 1174 FLBuilderLayout._initVimeoBgVideo.apply( this ); 1175 } 1176 else { 1177 wrap.append( videoTag ); 1178 1179 if ( playPauseButton.length > 0 ) { 1180 var video = videoTag[0]; 1181 1182 playPauseButton.on( 'click', { video: video }, function(e) { 1183 var video = e.data.video; 1184 1185 if ( video.paused ) { 1186 video.play(); 1187 } else { 1188 video.pause(); 1189 } 1190 } ); 1191 1192 $( video ).on( 'play playing', function () { 1193 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1194 } ); 1195 1196 $( video ).on( 'pause ended waiting', function () { 1197 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1198 } ); 1199 } 1200 } 1201 } 1202 else { 1203 // if we are here, it means we are on mobile and NO is set so remove video src and use fallback 1204 videoTag.attr('src', '') 1205 wrap.append( videoTag ); 1206 } 1207 1208 // Mark this video as loaded. 1209 wrap.data('loaded', true); 1210 }, 1211 1212 /** 1213 * Initializes Youtube video background 1214 * 1215 * @since 1.9 1216 * @access private 1217 * @method _initYoutubeBgVideo 1218 */ 1219 _initYoutubeBgVideo: function() 1220 { 1221 var playerWrap = $(this), 1222 videoId = playerWrap.data('video-id'), 1223 videoPlayer = playerWrap.find('.fl-bg-video-player'), 1224 enableAudio = playerWrap.data('enable-audio'), 1225 audioButton = playerWrap.find('.fl-bg-video-audio'), 1226 playPauseButton = playerWrap.find('.fl-bg-video-play-pause-control'), 1227 startTime = 'undefined' !== typeof playerWrap.data('start') ? playerWrap.data('start') : 0, 1228 startTime = 'undefined' !== typeof playerWrap.data('t') && startTime === 0 ? playerWrap.data('t') : startTime, 1229 endTime = 'undefined' !== typeof playerWrap.data('end') ? playerWrap.data('end') : 0, 1230 loop = 'undefined' !== typeof playerWrap.data('loop') ? playerWrap.data('loop') : 1, 1231 stateCount = 0, 1232 player,fallback_showing; 1233 1234 if ( videoId ) { 1235 fallback = playerWrap.data('fallback') || false 1236 if( fallback ) { 1237 playerWrap.find('iframe').remove() 1238 fallbackTag = $( '<div></div>' ); 1239 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1240 fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' ); 1241 fallbackTag.css( 'background-size', 'cover' ); 1242 fallbackTag.css( 'transition', 'background-image 1s') 1243 playerWrap.append( fallbackTag ); 1244 fallback_showing = true; 1245 } 1246 FLBuilderLayout._onYoutubeApiReady( function( YT ) { 1247 setTimeout( function() { 1248 1249 player = new YT.Player( videoPlayer[0], { 1250 videoId: videoId, 1251 events: { 1252 onReady: function(event) { 1253 if ( "no" === enableAudio || FLBuilderLayout._isMobile() ) { 1254 event.target.mute(); 1255 } 1256 else if ( "yes" === enableAudio && event.target.isMuted ) { 1257 event.target.unMute(); 1258 } 1259 1260 // Store an instance to a parent 1261 playerWrap.data('YTPlayer', player); 1262 FLBuilderLayout._resizeYoutubeBgVideo.apply(playerWrap); 1263 1264 // Queue the video. 1265 event.target.playVideo(); 1266 1267 if ( audioButton.length > 0 && ! FLBuilderLayout._isMobile() ) {
1268 audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio ); 1269 } 1270 1271 if ( playPauseButton.length > 0 ) { 1272 playPauseButton.on( 'click', {player: player}, function(e) { 1273 var player = e.data.player; 1274 1275 if ( 1 === player.getPlayerState() ) { 1276 player.pauseVideo(); 1277 } else { 1278 player.playVideo(); 1279 } 1280 }); 1281 } 1282 }, 1283 onStateChange: function( event ) { 1284 1285 if ( event.data === 1 ) { 1286 if ( fallback_showing ) { 1287 $( '.fl-bg-video-fallback' ).css( 'background-image', 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)' ) 1288 } 1289 } 1290 // Manual check if video is not playable in some browsers. 1291 // StateChange order: [-1, 3, -1] 1292 if ( stateCount < 4 ) { 1293 stateCount++; 1294 } 1295 1296 // Comply with the audio policy in some browsers like Chrome and Safari. 1297 if ( stateCount > 1 && -1 === event.data && "yes" === enableAudio ) { 1298 player.mute(); 1299 player.playVideo(); 1300 audioButton.show(); 1301 } 1302 1303 if ( event.data === YT.PlayerState.ENDED && 1 === loop ) { 1304 if ( startTime > 0 ) { 1305 player.seekTo( startTime ); 1306 } 1307 else { 1308 player.playVideo(); 1309 } 1310 } 1311 1312 if ( event.data === YT.PlayerState.PLAYING ) { 1313 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1314 } else if ( event.data === YT.PlayerState.PAUSED ) { 1315 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1316 } else if ( event.data === YT.PlayerState.BUFFERING ) { 1317 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1318 } else if ( event.data === YT.PlayerState.CUED ) { 1319 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1320 } else if ( event.data === YT.PlayerState.ENDED ) { 1321 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1322 } 1323 }, 1324 onError: function(event) { 1325 console.info('YT Error: ' + event.data) 1326 FLBuilderLayout._onErrorYoutubeVimeo(playerWrap) 1327 } 1328 }, 1329 playerVars: { 1330 playsinline: FLBuilderLayout._isMobile() ? 1 : 0, 1331 controls: 0, 1332 showinfo: 0, 1333 rel : 0, 1334 start: startTime, 1335 end: endTime, 1336 } 1337 } ); 1338 }, 1 ); 1339 } ); 1340 } 1341 }, 1342 1343 /** 1344 * On youtube or vimeo error show the fallback image if available. 1345 * @since 2.0.7 1346 */ 1347 _onErrorYoutubeVimeo: function(playerWrap) { 1348 1349 fallback = playerWrap.data('fallback') || false 1350 if( ! fallback ) { 1351 return false; 1352 } 1353 playerWrap.find('iframe').remove() 1354 fallbackTag = $( '<div></div>' ); 1355 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1356 fallbackTag.css( 'background-image', 'url(' + playerWrap.data('fallback') + ')' ); 1357 playerWrap.append( fallbackTag ); 1358 }, 1359 1360 /** 1361 * Check if Youtube API has been downloaded 1362 * 1363 * @since 1.9 1364 * @access private 1365 * @method _onYoutubeApiReady 1366 * @param {Function} callback Method to call when YT API has been loaded 1367 */ 1368 _onYoutubeApiReady: function( callback ) { 1369 if ( window.YT && YT.loaded ) { 1370 callback( YT ); 1371 } else { 1372 // If not ready check again by timeout.. 1373 setTimeout( function() { 1374 FLBuilderLayout._onYoutubeApiReady( callback ); 1375 }, 350 ); 1376 } 1377 }, 1378 1379 /** 1380 * Initializes Vimeo video background 1381 * 1382 * @since 1.9 1383 * @access private 1384 * @method _initVimeoBgVideo 1385 */ 1386 _initVimeoBgVideo: function() 1387 { 1388 var playerWrap = $(this), 1389 videoId = playerWrap.data('video-id'), 1390 videoHash = playerWrap.data('video-hash'), 1391 videoPlayer = playerWrap.find('.fl-bg-video-player'), 1392 enableAudio = playerWrap.data('enable-audio'), 1393 audioButton = playerWrap.find('.fl-bg-video-audio'), 1394 playPauseButton = playerWrap.find('.fl-bg-video-play-pause-control'), 1395 playerState = '', 1396 player, 1397 width = playerWrap.outerWidth(), 1398 ua = navigator.userAgent; 1399 1400 if ( typeof Vimeo !== 'undefined' && videoId ) { 1401 1402 const vimOptions = { 1403 loop : true, 1404 title : false, 1405 portrait : false, 1406 background : true, 1407 autopause : false, 1408 muted : true, 1409 }; 1410 1411 if ( videoHash.length ) { 1412 vimOptions.url = `https://player.vimeo.com/video/${ videoId }?h=${ videoHash }`; 1413 } else { 1414 vimOptions.id = videoId; 1415 } 1416 1417 player = new Vimeo.Player(videoPlayer[0], vimOptions ); 1418 playerWrap.data('VMPlayer', player); 1419 if ( "no" === enableAudio ) { 1420 player.setVolume(0); 1421 } 1422 else if ("yes" === enableAudio ) { 1423 // Chrome, Safari, Firefox have audio policy restrictions for autoplay videos. 1424 if ( ua.indexOf("Safari") > -1 || ua.indexOf("Chrome") > -1 || ua.indexOf("Firefox") > -1 ) { 1425 player.setVolume(0); 1426 audioButton.show(); 1427 } 1428 else { 1429 player.setVolume(1); 1430 } 1431 } 1432 1433 player.play().catch(function(error) { 1434 FLBuilderLayout._onErrorYoutubeVimeo(playerWrap) 1435 }); 1436 1437 if ( audioButton.length > 0 ) {
1438 audioButton.on( 'click', {button: audioButton, player: player}, FLBuilderLayout._toggleBgVideoAudio ); 1439 } 1440 1441 player.on( 'play', function() { 1442 playerState = 'play'; 1443 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1444 } ); 1445 player.on( 'pause', function() { 1446 playerState = 'pause'; 1447 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1448 } ); 1449 player.on( 'ended', function() { 1450 playerState = 'ended'; 1451 playPauseButton.removeClass( 'fa-pause' ).addClass( 'fa-play' ); 1452 } ); 1453 player.on( 'bufferstart', function() { 1454 playerState = 'bufferstart'; 1455 playPauseButton.removeClass( 'fa-play' ).addClass( 'fa-pause' ); 1456 } ); 1457 1458 if ( playPauseButton.length > 0 ) { 1459 playPauseButton.on( 'click', { player: player }, function( e ) { 1460 var player = e.data.player; 1461 1462 if ( playerState === 'play' ) { 1463 player.pause(); 1464 } else { 1465 player.play(); 1466 } 1467 } ); 1468 } 1469 } 1470 }, 1471 1472 /** 1473 * Mute / unmute audio on row's video background. 1474 * It works for both Youtube and Vimeo. 1475 * 1476 * @since 2.1.3 1477 * @access private 1478 * @method _toggleBgVideoAudio 1479 * @param {Object} e Method arguments 1480 */ 1481 _toggleBgVideoAudio: function( e ) { 1482 var player = e.data.player, 1483 control = e.data.button.find('.fl-audio-control'); 1484 1485 if ( control.hasClass( 'fa-volume-off' ) ) { 1486 // Unmute 1487 control 1488 .removeClass( 'fa-volume-off' ) 1489 .addClass( 'fa-volume-up' ); 1490 e.data.button.find( '.fa-times' ).hide(); 1491 1492 if ( 'function' === typeof player.unMute ) { 1493 player.unMute(); 1494 } 1495 else { 1496 player.setVolume( 1 ); 1497 } 1498 } 1499 else { 1500 // Mute 1501 control 1502 .removeClass( 'fa-volume-up' ) 1503 .addClass( 'fa-volume-off' ); 1504 e.data.button.find( '.fa-times' ).show(); 1505 1506 if ( 'function' === typeof player.unMute ) { 1507 player.mute(); 1508 } 1509 else { 1510 player.setVolume( 0 ); 1511 } 1512 } 1513 }, 1514 1515 /** 1516 * Fires when there is an error loading a video 1517 * background source and shows the fallback. 1518 * 1519 * @since 1.6.3.3 1520 * @access private 1521 * @method _videoBgSourceError 1522 * @param {Object} e An event object 1523 * @deprecated 2.0.3 1524 */ 1525 _videoBgSourceError: function( e ) 1526 { 1527 var source = $( e.target ), 1528 wrap = source.closest( '.fl-bg-video' ), 1529 vid = wrap.find( 'video' ), 1530 fallback = wrap.data( 'fallback' ), 1531 fallbackTag = ''; 1532 source.remove(); 1533 1534 if ( vid.find( 'source' ).length ) { 1535 // Don't show the fallback if we still have other sources to check. 1536 return; 1537 } else if ( '' !== fallback ) { 1538 fallbackTag = $( '<div></div>' ); 1539 fallbackTag.addClass( 'fl-bg-video-fallback' ); 1540 fallbackTag.css( 'background-image', 'url(' + fallback + ')' ); 1541 wrap.append( fallbackTag ); 1542 vid.remove(); 1543 } 1544 }, 1545 1546 /** 1547 * Fires when the window is resized to resize 1548 * all video backgrounds. 1549 * 1550 * @since 1.1.4 1551 * @access private 1552 * @method _resizeBgVideos 1553 */ 1554 _resizeBgVideos: function() 1555 { 1556 $('.fl-bg-video').each( function() { 1557 1558 FLBuilderLayout._resizeBgVideo.apply( this ); 1559 1560 if ( $( this ).parent().find( 'img' ).length > 0 ) { 1561 $( this ).parent().imagesLoaded( $.proxy( FLBuilderLayout._resizeBgVideo, this ) ); 1562 } 1563 } ); 1564 }, 1565 1566 /** 1567 * Fires when the window is resized to resize 1568 * a single video background. 1569 * 1570 * @since 1.1.4 1571 * @access private 1572 * @method _resizeBgVideo 1573 */ 1574 _resizeBgVideo: function() 1575 { 1576 if ( 0 === $( this ).find( 'video' ).length && 0 === $( this ).find( 'iframe' ).length ) { 1577 return; 1578 } 1579 1580 var wrap = $(this), 1581 wrapHeight = wrap.outerHeight(), 1582 wrapWidth = wrap.outerWidth(), 1583 vid = wrap.find('video'), 1584 vidHeight = wrap.data('height'), 1585 vidWidth = wrap.data('width'), 1586 newWidth = wrapWidth, 1587 newHeight = Math.round(vidHeight * wrapWidth/vidWidth), 1588 newLeft = 0, 1589 newTop = 0, 1590 iframe = wrap.find('iframe'), 1591 isRowFullHeight = $(this).closest('.fl-row-bg-video').hasClass('fl-row-full-height'), 1592 vidCSS = { 1593 top: '50%', 1594 left: '50%', 1595 transform: 'translate(-50%,-50%)', 1596 }; 1597 1598 if ( vid.length ) { 1599 if(vidHeight === '' || typeof vidHeight === 'undefined' || vidWidth === '' || typeof vidWidth === 'undefined') { 1600 vid.css({ 1601 'left' : '0px', 1602 'top' : '0px', 1603 'width' : newWidth + 'px' 1604 }); 1605 1606 // Try to set the actual video dimension on 'loadedmetadata' when using URL as video source 1607 vid.on('loadedmetadata', FLBuilderLayout._resizeOnLoadedMeta); 1608 1609 return; 1610 } 1611 1612 if ( ! isRowFullHeight ) { 1613 if ( newHeight < wrapHeight ) { 1614 newHeight = wrapHeight; 1615 newLeft = -((newWidth - wrapWidth) / 2); 1616 newWidth = vidHeight ? Math.round(vidWidth * wrapHeight/vidHeight) : newWidth; 1617 } 1618 else { 1619 newTop = -((newHeight - wrapHeight)/2); 1620 } 1621 vidCSS = { 1622 left : newLeft + 'px', 1623 top : newTop + 'px', 1624 height : newHeight + 'px', 1625 width : newWidth + 'px', 1626 } 1627 } 1628 1629 vid.css( vidCSS ); 1630 1631 } 1632 else if ( iframe.length ) { 1633 1634 // Resize Youtube video player within iframe tag 1635 if ( typeof wrap.data('youtube') !== 'undefined' ) { 1636 FLBuilderLayout._resizeYoutubeBgVideo.apply(this); 1637 } 1638 } 1639 }, 1640 1641 /** 1642 * Fires when video meta has been loaded. 1643 * This will be Triggered when width/height attributes were not specified during video background resizing. 1644 * 1645 * @since 1.8.5 1646 * @access private 1647 * @method _resizeOnLoadedMeta 1648 */ 1649 _resizeOnLoadedMeta: function(){ 1650 var video = $(this), 1651 wrapHeight = video.parent().outerHeight(), 1652 wrapWidth = video.parent().outerWidth(), 1653 vidWidth = video[0].videoWidth, 1654 vidHeight = video[0].videoHeight, 1655 newHeight = Math.round(vidHeight * wrapWidth/vidWidth), 1656 newWidth = wrapWidth, 1657 newLeft = 0, 1658 newTop = 0; 1659 1660 if(newHeight < wrapHeight) { 1661 newHeight = wrapHeight; 1662 newWidth = Math.round(vidWidth * wrapHeight/vidHeight); 1663 newLeft = -((newWidth - wrapWidth)/2); 1664 } 1665 else { 1666 newTop = -((newHeight - wrapHeight)/2); 1667 } 1668 1669 video.parent().data('width', vidWidth); 1670 video.parent().data('height', vidHeight); 1671 1672 video.css({ 1673 'left' : newLeft + 'px', 1674 'top' : newTop + 'px', 1675 'width' : newWidth + 'px', 1676 'height' : newHeight + 'px' 1677 }); 1678 }, 1679 1680 /** 1681 * Fires when the window is resized to resize 1682 * a single Youtube video background. 1683 * 1684 * @since 1.9 1685 * @access private 1686 * @method _resizeYoutubeBgVideo 1687 */ 1688 _resizeYoutubeBgVideo: function() 1689 { 1690 var wrap = $(this), 1691 wrapWidth = wrap.outerWidth(), 1692 wrapHeight = wrap.outerHeight(), 1693 player = wrap.data('YTPlayer'), 1694 video = player ? player.getIframe() : null, 1695 aspectRatioSetting = '16:9', // Medium 1696 aspectRatioArray = aspectRatioSetting.split( ':' ),
1697 aspectRatio = aspectRatioArray[0] / aspectRatioArray[1], 1698 ratioWidth = wrapWidth / aspectRatio, 1699 ratioHeight = wrapHeight * aspectRatio, 1700 isWidthFixed = wrapWidth / wrapHeight > aspectRatio, 1701 width = isWidthFixed ? wrapWidth : ratioHeight, 1702 height = isWidthFixed ? ratioWidth : wrapHeight; 1703 1704 if ( video ) { 1705 $(video).width( width ).height( height ); 1706 } 1707 }, 1708 1709 /** 1710 * Opens a tab or accordion item if the browser hash is set 1711 * to the ID of one on the page. 1712 * 1713 * @since 1.6.0 1714 * @access private 1715 * @method _initHash 1716 */ 1717 _initHash: function() 1718 { 1719 var hash = window.location.hash.replace( '#', '' ).split( '/' ).shift(), 1720 element = null, 1721 tabs = null, 1722 responsiveLabel = null, 1723 tabIndex = null, 1724 label = null; 1725 1726 if ( '' !== hash ) { 1727 1728 try { 1729 1730 element = $( '#' + hash ); 1731 1732 if ( element.length > 0 ) { 1733 1734 if ( element.hasClass( 'fl-accordion-item' ) ) { 1735 setTimeout( function() { 1736 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1737 }, 100 ); 1738 } 1739 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1740 setTimeout( function() { 1741 tabs = element.closest( '.fl-tabs' ); 1742 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1743 tabIndex = responsiveLabel.data( 'index' ); 1744 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1745 1746 label[0].click(); 1747 FLBuilderLayout._scrollToElement(element); 1748 }, 100 ); 1749 } 1750 } 1751 } 1752 catch( e ) {} 1753 } 1754 }, 1755 1756 /** 1757 * Initializes all anchor links on the page for smooth scrolling. 1758 * 1759 * @since 1.4.9 1760 * @access private 1761 * @method _initAnchorLinks 1762 */ 1763 _initAnchorLinks: function() 1764 { 1765 $( 'a, [role="link"]' ).each( FLBuilderLayout._initAnchorLink ); 1766 }, 1767 1768 /** 1769 * Initializes a single anchor link for smooth scrolling. 1770 * 1771 * @since 1.4.9 1772 * @access private 1773 * @method _initAnchorLink 1774 */ 1775 _initAnchorLink: function() 1776 { 1777 var link = $( this ), 1778 href = link.data( 'url' ) ? link.data( 'url' ) : link.attr( 'href' ), 1779 target = link.data( 'url' ) ? new URL( href, window.location.href ) : this, 1780 loc = window.location, 1781 id = null, 1782 element = null, 1783 flNode = false; 1784 1785 if ( 'undefined' != typeof href && href.indexOf( '#' ) > -1 && link.closest('svg').length < 1 ) { 1786 1787 if ( loc.pathname.replace( /^\//, '' ) == target.pathname.replace( /^\//, '' ) && loc.hostname == target.hostname ) { 1788 1789 try { 1790 1791 id = href.split( '#' ).pop(); 1792 // If there is no ID then we have nowhere to look 1793 // Fixes a quirk in jQuery and FireFox 1794 if( ! id ) { 1795 return; 1796 } 1797 element = $( '#' + id ); 1798 1799 if ( element.length > 0 ) { 1800 flNode = element.hasClass( 'fl-row' ) || element.hasClass( 'fl-col' ) || element.hasClass( 'fl-module' ); 1801 if ( !element.hasClass( 'fl-no-scroll' ) && ( link.hasClass( 'fl-scroll-link' ) || flNode ) ) { 1802 $( link ).on( 'click', FLBuilderLayout._scrollToElementOnLinkClick ); 1803 } 1804 if ( element.hasClass( 'fl-accordion-item' ) ) { 1805 $( link ).on( 'click', FLBuilderLayout._scrollToAccordionOnLinkClick ); 1806 } 1807 if ( element.hasClass( 'fl-tabs-panel' ) ) { 1808 $( link ).on( 'click', FLBuilderLayout._scrollToTabOnLinkClick ); 1809 } 1810 } 1811 } 1812 catch( e ) {} 1813 } 1814 } 1815 }, 1816 1817 /** 1818 * Scrolls to an element when an anchor link is clicked. 1819 * 1820 * @since 1.4.9 1821 * @access private 1822 * @method _scrollToElementOnLinkClick 1823 * @param {Object} e An event object. 1824 * @param {Function} callback A function to call when the scroll is complete. 1825 */ 1826 _scrollToElementOnLinkClick: function( e, callback ) 1827 { 1828 var attribute = $( this ).data( 'url' ) ? $( this ).data( 'url' ) : $( this ).attr( 'href' ); 1829 var element = $( '#' + attribute.split( '#' ).pop() ); 1830 1831 FLBuilderLayout._scrollToElement( element, callback ); 1832 1833 e.preventDefault(); 1834 }, 1835 1836 /** 1837 * Scrolls to an element. 1838 * 1839 * @since 1.6.4.5 1840 * @access private 1841 * @method _scrollToElement 1842 * @param {Object} element The element to scroll to. 1843 * @param {Function} callback A function to call when the scroll is complete. 1844 */ 1845 _scrollToElement: function( element, callback ) 1846 { 1847 var config = FLBuilderLayoutConfig.anchorLinkAnimations, 1848 dest = 0, 1849 win = $( window ), 1850 doc = $( document ); 1851 1852 if ( element.length > 0 ) { 1853 1854 if ( 'fixed' === element.css('position') || 'fixed' === element.parent().css('position') ) { 1855 dest = element.position().top; 1856 } 1857 else if ( element.offset().top > doc.height() - win.height() ) { 1858 dest = doc.height() - win.height(); 1859 } 1860 else { 1861 dest = element.offset().top - config.offset; 1862 } 1863 1864 $( 'html, body' ).stop( true ).animate( { scrollTop: dest }, config.duration, config.easing, function() { 1865 1866 if ( 'undefined' != typeof callback ) { 1867 callback(); 1868 } 1869 1870 if ( undefined != element.attr( 'id' ) && window.location.hash !== '#' + element.attr( 'id' ) ) { 1871 1872 var firefox_version = window.navigator.userAgent.match( /Firefox\/(\d+)\./ ), 1873 firefox_version = firefox_version ? parseInt( firefox_version[1], 10 ) : null; 1874 1875 if ( firefox_version !== null && firefox_version < 135 ) { 1876 window.location.hash = element.attr( 'id' ); 1877 } else { 1878 if ( history.pushState ) { 1879 history.pushState( null, null, '#' + element.attr( 'id' ) ); 1880 } else { 1881 window.location.hash = element.attr( 'id' ); 1882 } 1883 } 1884 } 1885 } ); 1886 } 1887 }, 1888 1889 /** 1890 * Scrolls to an accordion item when a link is clicked. 1891 * 1892 * @since 1.5.9 1893 * @access private 1894 * @method _scrollToAccordionOnLinkClick 1895 * @param {Object} e An event object. 1896 */ 1897 _scrollToAccordionOnLinkClick: function( e ) 1898 { 1899 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ); 1900 1901 if ( element.length > 0 ) { 1902 1903 var callback = function() { 1904 if ( element ) { 1905 element.find( '.fl-accordion-button' ).trigger( 'click' ); 1906 element = false;
1907 } 1908 }; 1909 1910 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1911 } 1912 }, 1913 1914 /** 1915 * Scrolls to a tab panel when a link is clicked. 1916 * 1917 * @since 1.5.9 1918 * @access private 1919 * @method _scrollToTabOnLinkClick 1920 * @param {Object} e An event object. 1921 */ 1922 _scrollToTabOnLinkClick: function( e ) 1923 { 1924 var element = $( '#' + $( this ).attr( 'href' ).split( '#' ).pop() ), 1925 tabs = null, 1926 label = null, 1927 responsiveLabel = null; 1928 1929 if ( element.length > 0 ) { 1930 1931 tabs = element.closest( '.fl-tabs' ); 1932 responsiveLabel = element.find( '.fl-tabs-panel-label' ); 1933 tabIndex = responsiveLabel.data( 'index' ); 1934 label = tabs.find( '.fl-tabs-labels .fl-tabs-label[data-index=' + tabIndex + ']' ); 1935 1936 if ( responsiveLabel.is( ':visible' ) ) { 1937 1938 var callback = function() { 1939 if ( element ) { 1940 responsiveLabel.trigger( $.Event( 'click', { which: 1 } ) ); 1941 } 1942 }; 1943 1944 FLBuilderLayout._scrollToElementOnLinkClick.call( this, e, callback ); 1945 } 1946 else { 1947 label[0].click(); 1948 FLBuilderLayout._scrollToElement( element ); 1949 } 1950 1951 e.preventDefault(); 1952 } 1953 }, 1954 1955 /** 1956 * Initializes all builder forms on a page. 1957 * 1958 * @since 1.5.4 1959 * @access private 1960 * @method _initForms 1961 */ 1962 _initForms: function() 1963 { 1964 if ( ! FLBuilderLayout._hasPlaceholderSupport ) { 1965 $( '.fl-form-field input' ).each( FLBuilderLayout._initFormFieldPlaceholderFallback ); 1966 } 1967 1968 $( '.fl-form-field input' ).on( 'focus', FLBuilderLayout._clearFormFieldError ); 1969 }, 1970 1971 /** 1972 * Checks to see if the current device has HTML5 1973 * placeholder support. 1974 * 1975 * @since 1.5.4 1976 * @access private 1977 * @method _hasPlaceholderSupport 1978 * @return {Boolean} 1979 */ 1980 _hasPlaceholderSupport: function() 1981 { 1982 var input = document.createElement( 'input' ); 1983 1984 return 'undefined' != input.placeholder; 1985 }, 1986 1987 /** 1988 * Initializes the fallback for when placeholders aren't supported. 1989 * 1990 * @since 1.5.4 1991 * @access private 1992 * @method _initFormFieldPlaceholderFallback 1993 */ 1994 _initFormFieldPlaceholderFallback: function() 1995 { 1996 var field = $( this ), 1997 val = field.val(), 1998 placeholder = field.attr( 'placeholder' ); 1999 2000 if ( 'undefined' != placeholder && '' === val ) { 2001 field.val( placeholder ); 2002 field.on( 'focus', FLBuilderLayout._hideFormFieldPlaceholderFallback ); 2003 field.on( 'blur', FLBuilderLayout._showFormFieldPlaceholderFallback ); 2004 } 2005 }, 2006 2007 /** 2008 * Hides a fallback placeholder on focus. 2009 * 2010 * @since 1.5.4 2011 * @access private 2012 * @method _hideFormFieldPlaceholderFallback 2013 */ 2014 _hideFormFieldPlaceholderFallback: function() 2015 { 2016 var field = $( this ), 2017 val = field.val(), 2018 placeholder = field.attr( 'placeholder' ); 2019 2020 if ( val == placeholder ) { 2021 field.val( '' ); 2022 } 2023 }, 2024 2025 /** 2026 * Shows a fallback placeholder on blur. 2027 * 2028 * @since 1.5.4 2029 * @access private 2030 * @method _showFormFieldPlaceholderFallback 2031 */ 2032 _showFormFieldPlaceholderFallback: function() 2033 { 2034 var field = $( this ), 2035 val = field.val(), 2036 placeholder = field.attr( 'placeholder' ); 2037 2038 if ( '' === val ) { 2039 field.val( placeholder ); 2040 } 2041 }, 2042 2043 /** 2044 * Clears a form field error message. 2045 * 2046 * @since 1.5.4 2047 * @access private 2048 * @method _clearFormFieldError 2049 */ 2050 _clearFormFieldError: function() 2051 { 2052 var field = $( this ); 2053 2054 field.removeAttr( 'aria-invalid' ); 2055 field.removeClass( 'fl-form-error' ); 2056 const message = field.attr('aria-describedby'); 2057 message ? $( '#' + message ).hide() : field.siblings( '.fl-form-error-message' ).hide(); 2058 }, 2059 2060 /** 2061 * Init Row Shape Layer's height. 2062 * 2063 * @since 2.5.3 2064 * @access private 2065 * @method _initRowShapeLayerHeight 2066 */ 2067 _initRowShapeLayerHeight: function () { 2068 FLBuilderLayout._adjustRowShapeLayerHeight(); 2069 $( window ).on( 'resize', FLBuilderLayout._adjustRowShapeLayerHeight ); 2070 }, 2071 2072 /** 2073 * Set parent column width of nested columns when it's zero or blank. 2074 * 2075 * @since 2.7.4 2076 * @access private 2077 * @method _initNestedColsWidth 2078 */ 2079 _initNestedColsWidth: function() 2080 { 2081 var nestedCols = $( '.fl-col-has-cols' ); 2082 2083 if ( nestedCols.length <= 0 ) { 2084 return; 2085 } 2086 2087 $( nestedCols ).each( function(index, col ){ 2088 if ( $( col ).width() <= 0 ) { 2089 $( col ).css( 'width', FLBuilderLayoutConfig.emptyColWidth ); 2090 } 2091 }); 2092 }, 2093 2094 /** 2095 * Adjust Row Shape Layer's height to fix to remove the fine line that appears on certain screen sizes. 2096 * 2097 * @since 2.5.3 2098 * @access private 2099 * @method _adjustRowShapeLayerHeight 2100 */
2101 _adjustRowShapeLayerHeight: function() { 2102 var rowShapeLayers = $('.fl-builder-shape-layer'); 2103 2104 $( rowShapeLayers ).each(function (index) { 2105 var rowShapeLayer = $(this), 2106 shape = $(rowShapeLayer).find('svg'), 2107 height = shape.height(), 2108 excludeShapes = '.fl-builder-shape-circle, .fl-builder-shape-dot-cluster, .fl-builder-shape-topography, .fl-builder-shape-rect'; 2109 2110 if ( ! rowShapeLayer.is( excludeShapes ) ) { 2111 $(shape).css('height', Math.ceil( height ) ); 2112 } 2113 }); 2114 }, 2115 _string_to_slug: function( str ) { 2116 str = str.replace(/^\s+|\s+$/g, ''); // trim 2117 if ( 'undefined' == typeof window._fl_string_to_slug_regex ) { 2118 regex = new RegExp('[^a-zA-Z0-9\'":() !.,-_|]', 'g'); 2119 } else { 2120 regex = new RegExp('[^' + window._fl_string_to_slug_regex + '\'":\(\) !.,-_|\\\p{Letter}]', 'ug'); 2121 } 2122 str = str.replace(regex, '') // remove invalid chars 2123 .replace(/\s+/g, ' '); // collapse whitespace and replace by a space 2124 return str; 2125 }, 2126 _reorderMenu: function() { 2127 if ( $('#wp-admin-bar-fl-builder-frontend-edit-link-default li').length > 1 ) { 2128 $( '#wp-admin-bar-fl-builder-frontend-duplicate-link' ) 2129 .appendTo('#wp-admin-bar-fl-builder-frontend-edit-link-default') 2130 .css( 'padding-top', '5px' ) 2131 .css( 'border-top', '2px solid #1D2125' ) 2132 .css( 'margin-top', '5px' ) 2133 } 2134 } 2135 }; 2136 2137 /* Initializes the builder layout. */ 2138 $(function(){ 2139 FLBuilderLayout.init(); 2140 }); 2141 2142})(jQuery); 2143(function($){ 2144 2145 if(typeof FLBuilderLayoutModules !== 'undefined') { 2146 return; 2147 } 2148 2149 /** 2150 * Helper class with generic logic for builder modules. 2151 * If generic module code needs to work in both the block 2152 * editor and builder, it should go here. Otherwise, it 2153 * should go on FLBuilderLayout. 2154 * 2155 * @since 2.9 2156 */ 2157 FLBuilderLayoutModules = { 2158 2159 /** 2160 * Initializes builder module logic. 2161 * 2162 * @since 2.9 2163 * @method init 2164 */ 2165 init: function() 2166 { 2167 // Only init if the builder isn't active. 2168 if ( 0 === $('.fl-builder-edit').length ) { 2169 2170 // Init module animations. 2171 FLBuilderLayoutModules._initModuleAnimations(); 2172 } 2173 }, 2174 2175 /** 2176 * Initializes module animations. 2177 * 2178 * @since 1.1.9 2179 * @access private 2180 * @method _initModuleAnimations 2181 */ 2182 _initModuleAnimations: function() 2183 { 2184 if(typeof jQuery.fn.waypoint !== 'undefined') { 2185 $('.fl-animation').each( function() { 2186 var node = $( this ), 2187 nodeTop = node.offset().top, 2188 winHeight = $( window ).height(), 2189 bodyHeight = $( 'body' ).height(), 2190 waypoint = FLBuilderLayoutConfig.waypoint, 2191 offset = '80%'; 2192 2193 if ( typeof waypoint.offset !== undefined ) { 2194 offset = FLBuilderLayoutConfig.waypoint.offset + '%'; 2195 } 2196 2197 if ( bodyHeight - nodeTop < winHeight * 0.2 ) { 2198 offset = '100%'; 2199 } 2200 2201 node.waypoint({ 2202 offset: offset, 2203 handler: FLBuilderLayoutModules._doModuleAnimation 2204 }); 2205 } ); 2206 } 2207 }, 2208 2209 /** 2210 * Runs a module animation. 2211 * 2212 * @since 1.1.9 2213 * @access private 2214 * @method _doModuleAnimation 2215 */ 2216 _doModuleAnimation: function() 2217 { 2218 var module = 'undefined' == typeof this.element ? $(this) : $(this.element), 2219 delay = parseFloat(module.data('animation-delay')), 2220 duration = parseFloat(module.data('animation-duration')); 2221 2222 if ( ! isNaN( duration ) ) { 2223 module.css( 'animation-duration', duration + 's' ); 2224 } 2225 2226 if(!isNaN(delay) && delay > 0) { 2227 setTimeout(function(){ 2228 module.addClass('fl-animated'); 2229 }, delay * 1000); 2230 } else { 2231 setTimeout(function(){ 2232 module.addClass('fl-animated'); 2233 }, 1); 2234 } 2235 } 2236 }; 2237 2238 /* Initializes builder module logic. */ 2239 $(function(){ 2240 FLBuilderLayoutModules.init(); 2241 }); 2242 2243})(jQuery); 2244 2245/* Start Global JS */ 2246 2247/* End Global JS */ 2248 2249 2250;/** 2251 * This file should contain frontend logic for 2252 * all module instances. 2253 */(function($) { 2254 2255 $('.fl-node-myve0ihk715u .pp-infobox').on('mouseenter', function() { 2256 $('.fl-node-myve0ihk715u .pp-icon-wrapper').addClass(' none'); 2257 }); 2258 $('.fl-node-myve0ihk715u .pp-infobox').on('mouseleave', function() { 2259 $('.fl-node-myve0ihk715u .pp-icon-wrapper').removeClass(' none'); 2260 }); 2261 2262})(jQuery); 2263(function($) { 2264 2265 $('.fl-node-5dx1jhoaqmy4 .pp-infobox').on('mouseenter', function() { 2266 $('.fl-node-5dx1jhoaqmy4 .pp-icon-wrapper').addClass(' none'); 2267 }); 2268 $('.fl-node-5dx1jhoaqmy4 .pp-infobox').on('mouseleave', function() { 2269 $('.fl-node-5dx1jhoaqmy4 .pp-icon-wrapper').removeClass(' none'); 2270 }); 2271 2272})(jQuery); 2273(function($) { 2274 2275 $('.fl-node-g0jvsf91oxi5 .pp-infobox').on('mouseenter', function() { 2276 $('.fl-node-g0jvsf91oxi5 .pp-icon-wrapper').addClass(' none'); 2277 }); 2278 $('.fl-node-g0jvsf91oxi5 .pp-infobox').on('mouseleave', function() { 2279 $('.fl-node-g0jvsf91oxi5 .pp-icon-wrapper').removeClass(' none'); 2280 }); 2281 2282})(jQuery); 2283(function($) { 2284 2285 $('.fl-node-yhro2pcujawl .pp-infobox').on('mouseenter', function() { 2286 $('.fl-node-yhro2pcujawl .pp-icon-wrapper').addClass(' none'); 2287 }); 2288 $('.fl-node-yhro2pcujawl .pp-infobox').on('mouseleave', function() { 2289 $('.fl-node-yhro2pcujawl .pp-icon-wrapper').removeClass(' none'); 2290 }); 2291 2292})(jQuery); 2293(function($) { 2294 2295 $('.fl-node-hx9b7ai0ylms .pp-infobox').on('mouseenter', function() { 2296 $('.fl-node-hx9b7ai0ylms .pp-icon-wrapper').addClass(' none'); 2297 }); 2298 $('.fl-node-hx9b7ai0ylms .pp-infobox').on('mouseleave', function() { 2299 $('.fl-node-hx9b7ai0ylms .pp-icon-wrapper').removeClass(' none'); 2300 }); 2301 2302})(jQuery); 2303(function($) { 2304 2305 $('.fl-node-9c2kgy7febl0 .pp-infobox').on('mouseenter', function() { 2306 $('.fl-node-9c2kgy7febl0 .pp-icon-wrapper').addClass(' none'); 2307 }); 2308 $('.fl-node-9c2kgy7febl0 .pp-infobox').on('mouseleave', function() { 2309 $('.fl-node-9c2kgy7febl0 .pp-icon-wrapper').removeClass(' none'); 2310 }); 2311 2312})(jQuery); 2313 2314; 2315(function($) { 2316 var fixedHeight = true; 2317 function equalheight() { 2318 if ( ! fixedHeight ) { 2319 return; 2320 } 2321 var maxHeight = 0; 2322 $('.fl-node-d5sr826g3xzc .pp-testimonial .pp-content-wrapper').each(function(index) { 2323 if(($(this).outerHeight()) > maxHeight) { 2324 maxHeight = $(this).outerHeight(); 2325 } 2326 }); 2327 $('.fl-node-d5sr826g3xzc .pp-testimonial .pp-content-wrapper').css('height', maxHeight + 'px'); 2328 } 2329 2330 var left_arrow_svg = '<span aria-hidden="true"><svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512">
2330<path fill="currentColor" d="M25.1 247.5l117.8-116c4.7-4.7 12.3-4.7 17 0l7.1 7.1c4.7 4.7 4.7 12.3 0 17L64.7 256l102.2 100.4c4.7 4.7 4.7 12.3 0 17l-7.1 7.1c-4.7 4.7-12.3 4.7-17 0L25 264.5c-4.6-4.7-4.6-12.3.1-17z"></path></svg></span><span class="sr-only">Previous</span>'; 2331 var right_arrow_svg = '<span aria-hidden="true"><svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><path fill="currentColor" d="M166.9 264.5l-117.8 116c-4.7 4.7-12.3 4.7-17 0l-7.1-7.1c-4.7-4.7-4.7-12.3 0-17L127.3 256 25.1 155.6c-4.7-4.7-4.7-12.3 0-17l7.1-7.1c4.7-4.7 12.3-4.7 17 0l117.8 116c4.6 4.7 4.6 12.3-.1 17z"></path></svg></span><span class="sr-only">Next</span>'; 2332 2333 var setAriaHidden = function(e) { 2334 var currentIndex = e.item.index; // Get the index of the first visible slide 2335 var visibleItems = e.page.size; // Get the number of visible slides 2336 2337 // Loop through all slides 2338 $(e.target).find('.owl-item').each(function(index) { 2339 // Set aria-hidden="false" for visible slides, aria-hidden="true" for non-visible slides 2340 if (index >= currentIndex && index < currentIndex + visibleItems) { 2341 $(this).attr('aria-hidden', 'false'); 2342 } else { 2343 $(this).attr('aria-hidden', 'true'); 2344 } 2345 }); 2346 }; 2347 var onChange = function( e ) { 2348 setTimeout(function() { 2349 $( e.target ).find( '.owl-item' ).removeClass( 'pp-testimonial--center' ); 2350 var actives = $( e.target ).find( '.owl-item.active' ); 2351 if ( actives.length === 3 ) { 2352 $( actives[1] ).addClass( 'pp-testimonial--center' ); 2353 } 2354 }, 200); 2355 2356 $(e.target).find('.owl-dot').each(function() { 2357 if ( $(this).hasClass( 'active' ) ) { 2358 $(this).attr('aria-current', 'true'); 2359 } else { 2360 $(this).attr('aria-current', 'false'); 2361 } 2362 }); 2363 2364 //var currentIndex = e.item.index + 1; 2365 //$(e.target).find('.owl-item').eq(currentIndex).focus(); 2366 2367 var visibleSlides = 0; // Counter for real visible slides 2368 $(e.target).find('.owl-item').each(function(index) { 2369 // Check if the item is not a clone 2370 if (!$(this).hasClass('cloned')) { 2371 visibleSlides++; 2372 $(this).attr('aria-label', 'Testimonial ' + visibleSlides + ' of ' + e.item.count); 2373 } 2374 }); 2375 2376 setAriaHidden(e); 2377 }; 2378 2379 var options = { 2380 items: 1, 2381 responsive: { 2382 0: { 2383 items: 1, 2384 }, 2385 769: { 2386 items: 1, 2387 }, 2388 993: { 2389 items: 1, 2390 }, 2391 1201: { 2392 items: 1, 2393 } 2394 }, 2395 dots: true, 2396 2397 dotsEach: true, 2398 autoplay: true, 2399 autoplayHoverPause: true, 2400 autoplayTimeout: 7000, 2401 autoplaySpeed: 500, 2402 navSpeed: 500, 2403 dotsSpeed: 500, 2404 navText: [left_arrow_svg, right_arrow_svg], 2405 navContainer: '.fl-node-d5sr826g3xzc .pp-testimonials-nav', 2406 navElement:'button type="button"', 2407 loop: true, 2408 autoHeight: ! fixedHeight, 2409 slideBy: 1, 2410 mouseDrag: true, 2411 responsiveRefreshRate: 200, 2412 responsiveBaseWidth: window, 2413 margin: 20, 2414 rtl: $('body').hasClass( 'rtl' ), 2415 onInitialized: function(e) { 2416 onChange(e); 2417 setAriaHidden(e); 2418 equalheight(); 2419 2420 var count = 1; 2421 $(e.target).find('.owl-dot').each(function() { 2422 $(this).append( '<span class="sr-only">Testimonial Slide ' + count + '</span>' ); 2423 if ( $(this).hasClass( 'active' ) ) { 2424 $(this).attr('aria-current', 'true'); 2425 } else { 2426 $(this).attr('aria-current', 'false'); 2427 } 2428 count++; 2429 }); 2430 2431 $(e.target).find( '.owl-item' ).attr('role','group'); 2432 2433 var visibleSlides = 0; // Counter for real visible slides 2434 $(e.target).find('.owl-item').each(function(index) { 2435 // Check if the item is not a clone 2436 if (!$(this).hasClass('cloned')) { 2437 visibleSlides++; 2438 $(this).attr('aria-label', 'Testimonial ' + visibleSlides + ' of ' + e.item.count); 2439 } 2440 }); 2441 2442 $(e.target).parent().find('.owl-prev').attr('title','Previous testimonial'); 2443 $(e.target).parent().find('.owl-next').attr('title','Next testimonial'); 2444 2445 var carousel = this; 2446 carousel.$element.on( 'focus', function() { 2447 carousel.$element.on( 'keyup', function(e) { 2448 if ( 37 === e.keyCode || 37 === e.which ) { 2449 carousel.prev(); 2450 } 2451 if ( 39 === e.keyCode || 39 === e.which ) { 2452 carousel.next(); 2453 } 2454 } ); 2455 } ).on( 'blur', function() { 2456 carousel.$element.off( 'keyup' ); 2457 } ); 2458 }, 2459 onResized: equalheight, 2460 onRefreshed: equalheight, 2461 onLoadedLazy: equalheight, 2462 onChanged: onChange, 2463 onDragged: function(e) { 2464 var autoplay = true; 2465 2466 if ( ! autoplay ) { 2467 $(e.target).trigger( 'stop.owl.autoplay' ); 2468 } 2469 } 2470 }; 2471 2472 if ( $.fn.imagesLoaded ) { 2473 $('.fl-node-d5sr826g3xzc').imagesLoaded(function() { 2474 $('.fl-node-d5sr826g3xzc .owl-carousel').owlCarousel( options ); 2475 }); 2476 } else { 2477 $('.fl-node-d5sr826g3xzc .owl-carousel').owlCarousel( options ); 2478 } 2479 2480 if ( $('.fl-node-d5sr826g3xzc .owl-carousel').parents( '.pp-tabs-panel-content:not(:visible)' ).length > 0 ) { 2481 $('.fl-node-d5sr826g3xzc .owl-carousel').addClass( 'owl-hidden' ); 2482 } 2483 2484 2485})(jQuery); 2486 2487/* Start Global Node Custom JS */ 2488 2489/* End Global Node Custom JS */ 2490 2491 2492/* Start Layout Custom JS */ 2493 2494/* End Layout Custom JS */ 2495
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.