1/* 2Name: Theme Base 3Written by: Okler Themes - (http://www.okler.net) 4Theme Version: 11.1.0 5*/ 6 7// Theme 8var $ = jQuery.noConflict(); 9window.theme = {}; 10 11// Theme Common Functions 12window.theme.fn = { 13 getOptions(opts) { 14 if (typeof opts == "object") { 15 return opts; 16 } else if (typeof opts == "string") { 17 try { 18 return JSON.parse(opts.replace(/'/g, '"').replace(";", "")); 19 } catch (e) { 20 return {}; 21 } 22 } else { 23 return {}; 24 } 25 }, 26 27 execPluginFunction(functionName, context) { 28 const args = Array.prototype.slice.call(arguments, 2); 29 const namespaces = functionName.split("."); 30 const func = namespaces.pop(); 31 32 for (let i = 0; i < namespaces.length; i++) { 33 context = context[namespaces[i]]; 34 } 35 36 return context[func](...args); 37 }, 38 39 intObs(selector, functionName, intObsOptions, alwaysObserve) { 40 const $el = document.querySelectorAll(selector); 41 let intersectionObserverOptions = { 42 rootMargin: "0px 0px 200px 0px", 43 }; 44 45 if (Object.keys(intObsOptions).length) { 46 intersectionObserverOptions = $.extend( 47 intersectionObserverOptions, 48 intObsOptions 49 ); 50 } 51 52 const observer = new IntersectionObserver((entries) => { 53 for (const entry of entries) { 54 if (entry.intersectionRatio > 0) { 55 if (typeof functionName === "string") { 56 const func = Function("return " + functionName)(); 57 } else { 58 const callback = functionName; 59 60 callback.call($(entry.target)); 61 } 62 63 // Unobserve 64 if (!alwaysObserve) { 65 observer.unobserve(entry.target); 66 } 67 } 68 } 69 }, intersectionObserverOptions); 70 71 $($el).each(function () { 72 observer.observe($(this)[0]); 73 }); 74 }, 75 76 intObsInit(selector, functionName) { 77 const $el = document.querySelectorAll(selector); 78 const intersectionObserverOptions = { 79 rootMargin: "200px", 80 }; 81 82 const observer = new IntersectionObserver((entries) => { 83 for (const entry of entries) { 84 if (entry.intersectionRatio > 0) { 85 const $this = $(entry.target); 86 let opts; 87 88 const pluginOptions = theme.fn.getOptions( 89 $this.data("plugin-options") 90 ); 91 if (pluginOptions) opts = pluginOptions; 92 93 theme.fn.execPluginFunction(functionName, $this, opts); 94 95 // Unobserve 96 observer.unobserve(entry.target); 97 } 98 } 99 }, intersectionObserverOptions); 100 101 $($el).each(function () { 102 observer.observe($(this)[0]); 103 }); 104 }, 105 106 dynIntObsInit(selector, functionName, pluginDefaults) { 107 const $el = document.querySelectorAll(selector); 108 109 $($el).each(function () { 110 const $this = $(this); 111 let opts; 112 113 const pluginOptions = theme.fn.getOptions($this.data("plugin-options")); 114 if (pluginOptions) opts = pluginOptions; 115 116 const mergedPluginDefaults = theme.fn.mergeOptions(pluginDefaults, opts); 117 118 const intersectionObserverOptions = { 119 rootMargin: theme.fn.getRootMargin(functionName, mergedPluginDefaults), 120 threshold: 0, 121 }; 122 123 if (!mergedPluginDefaults.forceInit) { 124 const observer = new IntersectionObserver((entries) => { 125 for (const entry of entries) { 126 if (entry.intersectionRatio > 0) { 127 theme.fn.execPluginFunction( 128 functionName, 129 $this, 130 mergedPluginDefaults 131 ); 132 133 // Unobserve 134 observer.unobserve(entry.target); 135 } 136 } 137 }, intersectionObserverOptions); 138 139 observer.observe($this[0]); 140 } else { 141 theme.fn.execPluginFunction(functionName, $this, mergedPluginDefaults); 142 } 143 }); 144 }, 145 146 getRootMargin(plugin, { accY }) { 147 switch (plugin) { 148 case "themePluginCounter": 149 return accY ? `0px 0px ${accY}px 0px` : "0px 0px 200px 0px"; 150 break; 151 152 case "themePluginAnimate": 153 return accY ? `0px 0px ${accY}px 0px` : "0px 0px 200px 0px"; 154 break; 155 156 case "themePluginIcon": 157 return accY ? `0px 0px ${accY}px 0px` : "0px 0px 200px 0px"; 158 break; 159 160 case "themePluginRandomImages": 161 return accY ? `0px 0px ${accY}px 0px` : "0px 0px 200px 0px"; 162 break; 163 164 default: 165 return "0px 0px 200px 0px"; 166 break; 167 } 168 }, 169 170 mergeOptions(obj1, obj2) { 171 const obj3 = {}; 172 173 for (var attrname in obj1) { 174 obj3[attrname] = obj1[attrname]; 175 } 176 for (var attrname in obj2) { 177 obj3[attrname] = obj2[attrname]; 178 } 179 180 return obj3; 181 }, 182 183 execOnceTroughEvent($el, event, callback) { 184 const self = this, 185 dataName = self.formatDataName(event); 186 187 $($el).on(event, function () { 188 if (!$(this).data(dataName)) { 189 // Exec Callback Function 190 callback.call($(this)); 191 192 // Add data name 193 $(this).data(dataName, true); 194 195 // Unbind event 196 $(this).off(event); 197 } 198 });
199 200 return this; 201 }, 202 203 execOnceTroughWindowEvent($el, event, callback) { 204 const self = this, 205 dataName = self.formatDataName(event); 206 207 $($el).on(event, function () { 208 if (!$(this).data(dataName)) { 209 // Exec Callback Function 210 callback(); 211 212 // Add data name 213 $(this).data(dataName, true); 214 215 // Unbind event 216 $(this).off(event); 217 } 218 }); 219 220 return this; 221 }, 222 223 formatDataName(name) { 224 name = name.replace(".", ""); 225 return name; 226 }, 227 228 isElementInView($el) { 229 const rect = $el[0].getBoundingClientRect(); 230 231 return rect.top <= window.innerHeight / 3; 232 }, 233 234 getScripts(arr, path) { 235 const _arr = $.map(arr, (scr) => $.getScript((path || "") + scr)); 236 237 _arr.push( 238 $.Deferred(({ resolve }) => { 239 $(resolve); 240 }) 241 ); 242 243 return $.when(..._arr); 244 }, 245 246 showErrorMessage(title, content) { 247 $(".modalThemeErrorMessage").remove(); 248 $("body").append( 249 '<div class="modal fade" id="modalThemeErrorMessage" aria-hidden="true" tabindex="-1"><div class="modal-dialog modal-dialog-centered"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">' + 250 title + 251 '</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><div class="modal-body">' + 252 content + 253 '</div><div class="modal-footer"><button type="button" class="btn btn-primary" data-bs-dismiss="modal">Close</button></div></div></div></div>' 254 ); 255 256 var modalThemeErrorMessage = document.getElementById( 257 "modalThemeErrorMessage" 258 ); 259 var modalThemeErrorMessage = bootstrap.Modal.getOrCreateInstance( 260 modalThemeErrorMessage 261 ); 262 modalThemeErrorMessage.show(); 263 }, 264}; 265 266((theme = {}, $) => { 267 /* 268 Local Environment Warning 269 */ 270 try { 271 if ("file://" === location.origin) { 272 if ($("[data-icon]").length || $("iframe").length) { 273 theme.fn.showErrorMessage( 274 "Local Environment Warning", 275 "SVG Objects, Icons, YouTube and Vimeo Videos might not show correctly on local environment. For better result, please preview on a server." 276 ); 277 } 278 } 279 } catch (e) {} 280 281 /* 282 Browser Selector 283 */ 284 $.extend({ 285 browserSelector() { 286 // jQuery.browser.mobile (http://detectmobilebrowser.com/) 287 ((a) => { 288 (jQuery.browser = jQuery.browser || {}).mobile = 289 /(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|phone)|xda|xiino/i.test( 290 a 291 ) || 292 /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 )|
292sy(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( 293 a.substr(0, 4) 294 ); 295 })(navigator.userAgent || navigator.vendor || window.opera); 296 297 // Touch 298 const hasTouch = "ontouchstart" in window || navigator.msMaxTouchPoints; 299 300 const u = navigator.userAgent, 301 ua = u.toLowerCase(), 302 is = (t) => ua.includes(t), 303 g = "gecko", 304 w = "webkit", 305 s = "safari", 306 o = "opera", 307 h = document.documentElement, 308 b = [ 309 !/opera|webtv/i.test(ua) && /msie\s(\d)/.test(ua) 310 ? `ie ie${parseFloat(navigator.appVersion.split("MSIE")[1])}` 311 : is("firefox/2") 312 ? `${g} ff2` 313 : is("firefox/3.5") 314 ? `${g} ff3 ff3_5` 315 : is("firefox/3") 316 ? `${g} ff3` 317 : is("gecko/") 318 ? g 319 : is("opera") 320 ? o + 321 (/version\/(\d+)/.test(ua) 322 ? ` ${o}${RegExp.jQuery1}` 323 : /opera(\s|\/)(\d+)/.test(ua) 324 ? ` ${o}${RegExp.jQuery2}` 325 : "") 326 : is("konqueror") 327 ? "konqueror" 328 : is("chrome") 329 ? `${w} chrome` 330 : is("iron") 331 ? `${w} iron` 332 : is("applewebkit/") 333 ? `${w} ${s}${ 334 /version\/(\d+)/.test(ua) ? ` ${s}${RegExp.jQuery1}` : "" 335 }` 336 : is("mozilla/") 337 ? g 338 : "", 339 is("j2me") 340 ? "mobile" 341 : is("iphone") 342 ? "iphone" 343 : is("ipod") 344 ? "ipod" 345 : is("mac") 346 ? "mac" 347 : is("darwin") 348 ? "mac" 349 : is("webtv") 350 ? "webtv" 351 : is("win") 352 ? "win" 353 : is("freebsd") 354 ? "freebsd" 355 : is("x11") || is("linux") 356 ? "linux" 357 : "", 358 "js", 359 ]; 360 361 c = b.join(" "); 362 363 if ($.browser.mobile) { 364 c += " mobile"; 365 } 366 367 if (hasTouch) { 368 c += " touch"; 369 } 370 371 h.className += ` ${c}`; 372 373 // Edge Detect 374 const isEdge = /Edge/.test(navigator.userAgent); 375 376 if (isEdge) { 377 $("html").removeClass("chrome").addClass("edge"); 378 } 379 380 // Dark and Boxed Compatibility 381 if ($("body").hasClass("dark")) { 382 $("html").addClass("dark"); 383 } 384 385 if ($("body").hasClass("boxed")) { 386 $("html").addClass("boxed"); 387 } 388 }, 389 }); 390 391 $.browserSelector(); 392 393 /* 394 Browser Workarounds 395 */ 396 if (/iPad|iPhone|iPod/.test(navigator.platform)) { 397 // iPad/Iphone/iPod Hover Workaround 398 $(document).ready(($) => { 399 $(".thumb-info").attr("onclick", "return true"); 400 }); 401 } 402 403 /* 404 Tabs 405 */ 406 if ($('a[data-bs-toggle="tab"]').length) { 407 $('a[data-bs-toggle="tab"]').on("shown.bs.tab", function ({ target }) { 408 const $tabPane = $($(target).attr("href")); 409 410 // Carousel Refresh 411 if ($tabPane.length) { 412 $tabPane.find(".owl-carousel").trigger("refresh.owl.carousel"); 413 } 414 415 // Change Active Class 416 $(this).parents(".nav-tabs").find(".active").removeClass("active"); 417 $(this).addClass("active").parent().addClass("active"); 418 }); 419 420 if (window.location.hash) { 421 $(window).on("load", () => { 422 if (window.location.hash !== "*" && $(window.location.hash).get(0)) { 423 new bootstrap.Tab( 424 $( 425 'a.nav-link[href="' + window.location.hash + '"]:not([data-hash])' 426 )[0] 427 ).show(); 428 } 429 }); 430 } 431 } 432 433 /* 434 On Load Scroll 435 */ 436 if ( 437 !$("html").hasClass("disable-onload-scroll") && 438 window.location.hash && 439 !["#*"].includes(window.location.hash) 440 ) { 441 window.scrollTo(0, 0); 442 443 $(window).on("load", () => { 444 setTimeout(() => { 445 const target = window.location.hash; 446 let offset = $(window).width() < 768 ? 180 : 90; 447 448 if (!$(target).length) { 449 return; 450 } 451 452 if ( 453 $("a[href$='" + window.location.hash + "']").is("[data-hash-offset]") 454 ) { 455 offset = parseInt( 456 $("a[href$='" + window.location.hash + "']") 457 .first() 458 .attr("data-hash-offset") 459 ); 460 } else if ($("html").is("[data-hash-offset]")) { 461 offset = parseInt($("html").attr("data-hash-offset")); 462 } 463 464 if (isNaN(offset)) { 465 offset = 0; 466 } 467 468 $("body").addClass("scrolling"); 469 470 $("html, body").animate( 471 { 472 scrollTop: $(target).offset().top - offset, 473 }, 474 600, 475 "easeOutQuad", 476 () => { 477 $("body").removeClass("scrolling"); 478 } 479 ); 480 }, 1); 481 });
482 } 483 484 /* 485 * Text Rotator 486 */ 487 $.fn.extend({ 488 textRotator(options) { 489 const defaults = { 490 fadeSpeed: 500, 491 pauseSpeed: 100, 492 child: null, 493 }; 494 495 var options = $.extend(defaults, options); 496 497 return this.each(function () { 498 const o = options; 499 const obj = $(this); 500 const items = $(obj.children(), obj); 501 items.each(function () { 502 $(this).hide(); 503 }); 504 if (!o.child) { 505 var next = $(obj).children(":first"); 506 } else { 507 var next = o.child; 508 } 509 $(next).fadeIn(o.fadeSpeed, () => { 510 $(next) 511 .delay(o.pauseSpeed) 512 .fadeOut(o.fadeSpeed, function () { 513 let next = $(this).next(); 514 if (next.length == 0) { 515 next = $(obj).children(":first"); 516 } 517 $(obj).textRotator({ 518 child: next, 519 fadeSpeed: o.fadeSpeed, 520 pauseSpeed: o.pauseSpeed, 521 }); 522 }); 523 }); 524 }); 525 }, 526 }); 527 528 /* 529 * Notice Top bar 530 */ 531 const $noticeTopBar = { 532 $wrapper: $(".notice-top-bar"), 533 $closeBtn: $(".notice-top-bar-close"), 534 $header: $("#header"), 535 $body: $(".body"), 536 init() { 537 const self = this; 538 539 if (!$.cookie("portoNoticeTopBarClose")) { 540 self.build().events(); 541 } else { 542 self.$wrapper 543 .parent() 544 .prepend("<!-- Notice Top Bar removed by cookie -->"); 545 self.$wrapper.remove(); 546 } 547 548 return this; 549 }, 550 build() { 551 const self = this; 552 553 $(window).on("load", () => { 554 setTimeout(() => { 555 self.$body.css({ 556 "margin-top": self.$wrapper.outerHeight(), 557 transition: "ease margin 300ms", 558 }); 559 560 $("#noticeTopBarContent").textRotator({ 561 fadeSpeed: 500, 562 pauseSpeed: 5000, 563 }); 564 565 if (["absolute", "fixed"].includes(self.$header.css("position"))) { 566 self.$header.css({ 567 top: self.$wrapper.outerHeight(), 568 transition: "ease top 300ms", 569 }); 570 } 571 572 $(window).trigger("notice.top.bar.opened"); 573 }, 1000); 574 }); 575 576 return this; 577 }, 578 events() { 579 const self = this; 580 581 self.$closeBtn.on("click", (e) => { 582 e.preventDefault(); 583 584 self.$body.animate( 585 { 586 "margin-top": 0, 587 }, 588 300, 589 () => { 590 self.$wrapper.remove(); 591 self.saveCookie(); 592 } 593 ); 594 595 if (["absolute", "fixed"].includes(self.$header.css("position"))) { 596 self.$header.animate( 597 { 598 top: 0, 599 }, 600 300 601 ); 602 } 603 604 // When header has shrink effect 605 if (self.$header.hasClass("header-effect-shrink")) { 606 self.$header.find(".header-body").animate( 607 { 608 top: 0, 609 }, 610 300 611 ); 612 } 613 614 $(window).trigger("notice.top.bar.closed"); 615 }); 616 617 return this; 618 }, 619 checkCookie() { 620 const self = this; 621 622 if ($.cookie("portoNoticeTopBarClose")) { 623 return true; 624 } else { 625 return false; 626 } 627 628 return this; 629 }, 630 saveCookie() { 631 const self = this; 632 633 $.cookie("portoNoticeTopBarClose", true); 634 635 return this; 636 }, 637 }; 638 639 if ($(".notice-top-bar").length) { 640 $noticeTopBar.init(); 641 } 642 643 /* 644 * Image Hotspots 645 */ 646 if ($(".image-hotspot").length) { 647 $(".image-hotspot") 648 .append('<span class="ring"></span>') 649 .append('<span class="circle"></span>'); 650 } 651 652 /* 653 * Reading Progress 654 */ 655 if ($(".progress-reading").length) { 656 function updateScrollProgress() { 657 const pixels = $(document).scrollTop(); 658 pageHeight = $(document).height() - $(window).height(); 659 progress = (100 * pixels) / pageHeight; 660 661 $(".progress-reading .progress-bar").width(parseInt(progress) + "%"); 662 } 663 664 $(document).on("scroll ready", () => { 665 updateScrollProgress(); 666 });
667 668 $(document).ready(() => { 669 $(window).afterResize(() => { 670 updateScrollProgress(); 671 }); 672 }); 673 } 674 675 /* 676 * Page Transition 677 */ 678 if ($("body[data-plugin-page-transition]").length) { 679 let link_click = false; 680 681 $(document).on("click", "a", function (e) { 682 link_click = $(this); 683 }); 684 685 $(window).on("beforeunload", (e) => { 686 if (typeof link_click === "object") { 687 const href = link_click.attr("href"); 688 689 if ( 690 href.indexOf("mailto:") != 0 && 691 href.indexOf("tel:") != 0 && 692 !link_click.data("rm-from-transition") 693 ) { 694 $("body").addClass("page-transition-active"); 695 } 696 } 697 }); 698 699 $(window).on("pageshow", ({ persisted, originalEvent }) => { 700 if (persisted || originalEvent.persisted) { 701 if ($("html").hasClass("safari")) { 702 window.location.reload(); 703 } 704 705 $("body").removeClass("page-transition-active"); 706 } 707 }); 708 } 709 710 /* 711 * Clone Element 712 */ 713 if ($("[data-clone-element]").length) { 714 $("[data-clone-element]").each(function () { 715 const $el = $(this), 716 content = $el.html(), 717 qty = $el.attr("data-clone-element"); 718 719 for (let i = 0; i < qty; i++) { 720 $el.html($el.html() + content); 721 } 722 }); 723 } 724 725 /* 726 * Thumb Info Floating Caption 727 */ 728 $(".thumb-info-floating-caption").each(function () { 729 $(this) 730 .addClass("thumb-info-floating-element-wrapper") 731 .append( 732 '<span class="thumb-info-floating-element thumb-info-floating-caption-title d-none">' + 733 $(this).data("title") + 734 "</span>" 735 ); 736 737 if ($(this).data("type")) { 738 $(".thumb-info-floating-caption-title", $(this)) 739 .append( 740 '<div class="thumb-info-floating-caption-type">' + 741 $(this).data("type") + 742 "</div>" 743 ) 744 .css({ 745 "padding-bottom": 22, 746 }); 747 } 748 749 if ($(this).hasClass("thumb-info-floating-caption-clean")) { 750 $(".thumb-info-floating-element", $(this)).addClass("bg-transparent"); 751 } 752 }); 753 754 /* 755 * Thumb Info Floating Element 756 */ 757 if ($(".thumb-info-floating-element-wrapper").length) { 758 if (typeof gsap !== "undefined") { 759 $(".thumb-info-floating-element-wrapper") 760 .on("mouseenter", function ({ clientX, clientY }) { 761 if (!$(this).data("offset")) { 762 $(this).data("offset", 0); 763 } 764 765 const offset = parseInt($(this).data("offset")); 766 767 $(".thumb-info-floating-element-clone").remove(); 768 769 $(".thumb-info-floating-element", $(this)) 770 .clone() 771 .addClass("thumb-info-floating-element-clone p-fixed p-events-none") 772 .attr("style", "transform: scale(0.1);") 773 .removeClass("d-none") 774 .appendTo("body"); 775 776 $(".thumb-info-floating-element-clone") 777 .css({ 778 left: clientX + offset, 779 top: clientY + offset, 780 }) 781 .fadeIn(300); 782 783 gsap.to(".thumb-info-floating-element-clone", 0.5, { 784 css: { 785 scaleX: 1, 786 scaleY: 1, 787 }, 788 }); 789 790 $(document) 791 .off("mousemove") 792 .on("mousemove", ({ clientX, clientY }) => { 793 gsap.to(".thumb-info-floating-element-clone", 0.5, { 794 css: { 795 left: clientX + offset, 796 top: clientY + offset, 797 }, 798 }); 799 }); 800 }) 801 .on("mouseout", () => { 802 gsap.to(".thumb-info-floating-element-clone", 0.5, { 803 css: { 804 scaleX: 0.5, 805 scaleY: 0.5, 806 opacity: 0, 807 }, 808 }); 809 }); 810 } else { 811 theme.fn.showErrorMessage( 812 "Failed to Load File", 813 "Failed to load: GSAP - Include the following file(s): (vendor/gsap/gsap.min.js)" 814 ); 815 } 816 } 817 818 /* 819 * Thumb Info Direction Aware 820 */ 821 $(window).on("load", () => { 822 $(".thumb-info-wrapper-direction-aware").each(function () { 823 $(this).hoverdir({ 824 speed: 300, 825 easing: "ease", 826 hoverDelay: 0, 827 inverse: false,
828 hoverElem: ".thumb-info-wrapper-overlay", 829 }); 830 }); 831 }); 832 833 /* 834 * Thumb Info Container Full 835 */ 836 $(".thumb-info-container-full-img").each(function () { 837 const $container = $(this); 838 839 $("[data-full-width-img-src]", $container).each(function () { 840 const uniqueId = "img" + Math.floor(Math.random() * 10000); 841 $(this).attr("data-rel", uniqueId); 842 843 $container.append( 844 '<div style="background-image: url(' + 845 $(this).attr("data-full-width-img-src") + 846 ');" id="' + 847 uniqueId + 848 '" class="thumb-info-container-full-img-large opacity-0"></div>' 849 ); 850 }); 851 852 $(".thumb-info", $container).on("mouseenter", function (e) { 853 $(".thumb-info-container-full-img-large").removeClass("active"); 854 $("#" + $(this).attr("data-rel")).addClass("active"); 855 }); 856 }); 857 858 /* 859 * Toggle Text Click 860 */ 861 $("[data-toggle-text-click]").on("click", function () { 862 $(this).text(function (i, text) { 863 return text === $(this).attr("data-toggle-text-click") 864 ? $(this).attr("data-toggle-text-click-alt") 865 : $(this).attr("data-toggle-text-click"); 866 }); 867 }); 868 869 /* 870 * Toggle Class 871 */ 872 $("[data-toggle-class]").on("click", function (e) { 873 e.preventDefault(); 874 875 $(this).toggleClass($(this).data("toggle-class")); 876 }); 877 878 /* 879 * Shape Divider Aspect Ratio 880 */ 881 if ($(".shape-divider").length) { 882 aspectRatioSVG(); 883 $(window).on("resize", () => { 884 aspectRatioSVG(); 885 }); 886 } 887 888 /* 889 * Shape Divider Animated 890 */ 891 if ($(".shape-divider-horizontal-animation").length) { 892 theme.fn.intObs( 893 ".shape-divider-horizontal-animation", 894 function () { 895 for (let i = 0; i <= 1; i++) { 896 const svgClone = $(this).find("svg:nth-child(1)").clone(); 897 898 $(this).append(svgClone); 899 } 900 901 $(this).addClass("start"); 902 }, 903 {} 904 ); 905 } 906 907 /* 908 * Shape Divider - SVG Aspect Ratio 909 */ 910 function aspectRatioSVG() { 911 if ($(window).width() < 1950) { 912 $(".shape-divider svg[preserveAspectRatio]").each(function () { 913 if (!$(this).parent().hasClass("shape-divider-horizontal-animation")) { 914 $(this).attr("preserveAspectRatio", "xMinYMin"); 915 } else { 916 $(this).attr("preserveAspectRatio", "none"); 917 } 918 }); 919 } else { 920 $(".shape-divider svg[preserveAspectRatio]").each(function () { 921 $(this).attr("preserveAspectRatio", "none"); 922 }); 923 } 924 } 925 926 /* 927 * Content Switcher 928 */ 929 $("[data-content-switcher]").on("change", function (e, v) { 930 const switcherRel = $(this).is(":checked") ? "1" : "2", 931 switcherId = $(this).attr("data-content-switcher-content-id"); 932 933 $("[data-content-switcher-id=" + switcherId + "]") 934 .addClass("initialized") 935 .removeClass("active"); 936 937 const $activeEl = $( 938 "[data-content-switcher-id=" + 939 switcherId + 940 "][data-content-switcher-rel=" + 941 switcherRel + 942 "]" 943 ); 944 945 $activeEl.addClass("active"); 946 947 $activeEl.parent().css("height", $activeEl.height()); 948 }); 949 950 $("[data-content-switcher]").trigger("change"); 951 952 /* 953 * Dynamic Height 954 */ 955 var $window = $(window); 956 $window.on("resize dynamic.height.resize", () => { 957 $("[data-dynamic-height]").each(function () { 958 const $this = $(this), 959 values = JSON.parse( 960 $this.data("dynamic-height").replace(/'/g, '"').replace(";", "") 961 ); 962 963 // XS 964 if ($window.width() < 576) { 965 $this.height(values[4]); 966 } 967 968 // SM 969 if ($window.width() > 575 && $window.width() < 768) { 970 $this.height(values[3]); 971 } 972 973 // MD 974 if ($window.width() > 767 && $window.width() < 992) { 975 $this.height(values[2]); 976 } 977 978 // LG 979 if ($window.width() > 991 && $window.width() < 1200) { 980 $this.height(values[1]); 981 } 982 983 // XS 984 if ($window.width() > 1199) { 985 $this.height(values[0]); 986 } 987 });
988 }); 989 990 // Mobile First Load 991 if ($window.width() < 992) { 992 $window.trigger("dynamic.height.resize"); 993 } 994 995 /* 996 * Video - Trigger Play 997 */ 998 if ($("[data-trigger-play-video]").length) { 999 theme.fn.execOnceTroughEvent( 1000 "[data-trigger-play-video]", 1001 "mouseover.trigger.play.video", 1002 function () { 1003 const $video = $($(this).data("trigger-play-video")); 1004 1005 $(this).on("click", function (e) { 1006 e.preventDefault(); 1007 1008 if ($(this).data("trigger-play-video-remove") == "yes") { 1009 $(this).animate( 1010 { 1011 opacity: 0, 1012 }, 1013 300, 1014 function () { 1015 $video[0].play(); 1016 1017 $(this).remove(); 1018 } 1019 ); 1020 } else { 1021 setTimeout(() => { 1022 $video[0].play(); 1023 }, 300); 1024 } 1025 }); 1026 } 1027 ); 1028 } 1029 1030 /* 1031 * Video - Auto Play 1032 */ 1033 if ($("video[data-auto-play]").length) { 1034 $(window).on("load", () => { 1035 $("video[data-auto-play]").each(function () { 1036 const $video = $(this); 1037 1038 setTimeout(() => { 1039 if ($("#" + $video.attr("id")).length) { 1040 if ( 1041 $('[data-trigger-play-video="#' + $video.attr("id") + '"]').data( 1042 "trigger-play-video-remove" 1043 ) == "yes" 1044 ) { 1045 $( 1046 '[data-trigger-play-video="#' + $video.attr("id") + '"]' 1047 ).animate( 1048 { 1049 opacity: 0, 1050 }, 1051 300, 1052 () => { 1053 $video[0].play(); 1054 1055 $( 1056 '[data-trigger-play-video="#' + $video.attr("id") + '"]' 1057 ).remove(); 1058 } 1059 ); 1060 } else { 1061 setTimeout(() => { 1062 $video[0].play(); 1063 }, 300); 1064 } 1065 } 1066 }, 100); 1067 }); 1068 }); 1069 } 1070 1071 /* 1072 * Remove min height after the load of page 1073 */ 1074 if ($("[data-remove-min-height]").length) { 1075 $(window).on("load", () => { 1076 $("[data-remove-min-height]").each(function () { 1077 $(this).css({ 1078 "min-height": 0, 1079 }); 1080 }); 1081 }); 1082 } 1083 1084 /* 1085 * Lazy Load Background Images (with lazySizes plugin) 1086 */ 1087 document.addEventListener("lazybeforeunveil", ({ target }) => { 1088 const bg = target.getAttribute("data-bg-src"); 1089 if (bg) { 1090 target.style.backgroundImage = "url(" + bg + ")"; 1091 } 1092 }); 1093 1094 /* 1095 * Title Border 1096 */ 1097 if ($("[data-title-border]").length) { 1098 const $pageHeaderTitleBorder = $( 1099 '<span class="page-header-title-border"></span>' 1100 ), 1101 $pageHeaderTitle = $("[data-title-border]"), 1102 $window = $(window); 1103 1104 $pageHeaderTitle.before($pageHeaderTitleBorder); 1105 1106 const setPageHeaderTitleBorderWidth = () => { 1107 $pageHeaderTitleBorder.width($pageHeaderTitle.width()); 1108 }; 1109 1110 $window.afterResize(() => { 1111 setPageHeaderTitleBorderWidth(); 1112 }); 1113 1114 setPageHeaderTitleBorderWidth(); 1115 1116 $pageHeaderTitleBorder.addClass("visible"); 1117 } 1118 1119 /* 1120 * Footer Reveal 1121 */ 1122 (($) => { 1123 const $footerReveal = { 1124 $wrapper: $(".footer-reveal"), 1125 init() { 1126 const self = this; 1127 1128 self.build(); 1129 self.events(); 1130 }, 1131 build() { 1132 const self = this, 1133 footer_height = self.$wrapper.outerHeight(true), 1134 window_height = $(window).height() - $(".header-body").height(); 1135 1136 if (footer_height > window_height) { 1137 $("#footer").removeClass("footer-reveal"); 1138 $("body").css("margin-bottom", 0); 1139 } else { 1140 $("#footer").addClass("footer-reveal"); 1141 $("body").css("margin-bottom", footer_height); 1142 } 1143 }, 1144 events() { 1145 const self = this, 1146 $window = $(window); 1147 1148 $window.on("load", () => { 1149 $window.afterResize(() => { 1150 self.build(); 1151 }); 1152 }); 1153 }, 1154 }; 1155 1156 if ($(".footer-reveal").length) { 1157 $footerReveal.init(); 1158 } 1159 })(jQuery); 1160 1161 /* 1162 * Re-Init Plugin 1163 */ 1164 if ($("[data-reinit-plugin]").length) { 1165 $("[data-reinit-plugin]").on("click", function (e) { 1166 e.preventDefault(); 1167 1168 const pluginInstance = $(this).data("reinit-plugin"), 1169 pluginFunction = $(this).data("reinit-plugin-function"), 1170 pluginElement = $(this).data("reinit-plugin-element"), 1171 pluginOptions = theme.fn.getOptions( 1172 $(this).data("reinit-plugin-options") 1173 ); 1174 1175 $(pluginElement).data(pluginInstance).destroy(); 1176 1177 setTimeout(() => { 1178 theme.fn.execPluginFunction( 1179 pluginFunction, 1180 $(pluginElement), 1181 pluginOptions 1182 ); 1183 }, 1000); 1184 });
1185 } 1186 1187 /* 1188 * Simple Copy To Clipboard 1189 */ 1190 if ($("[data-copy-to-clipboard]").length) { 1191 theme.fn.intObs( 1192 "[data-copy-to-clipboard]", 1193 function () { 1194 const $this = $(this); 1195 1196 $this.wrap( 1197 '<div class="copy-to-clipboard-wrapper position-relative"></div>' 1198 ); 1199 1200 const $copyButton = $( 1201 '<a href="#" class="btn btn-primary btn-px-2 py-1 text-0 position-absolute top-8 right-8">COPY</a>' 1202 ); 1203 $this.parent().prepend($copyButton); 1204 1205 $copyButton.on("click", function (e) { 1206 e.preventDefault(); 1207 1208 const $btn = $(this), 1209 $temp = $( 1210 '<textarea class="d-block opacity-0" style="height: 0;">' 1211 ); 1212 1213 $btn.parent().append($temp); 1214 1215 $temp.val($this.text()); 1216 1217 $temp[0].select(); 1218 $temp[0].setSelectionRange(0, 99999); 1219 1220 document.execCommand("copy"); 1221 1222 $btn.addClass("copied"); 1223 setTimeout(() => { 1224 $btn.removeClass("copied"); 1225 }, 1000); 1226 1227 $temp.remove(); 1228 }); 1229 }, 1230 { 1231 rootMargin: "0px 0px 0px 0px", 1232 } 1233 ); 1234 } 1235 1236 /* 1237 * Marquee 1238 */ 1239 if ($(".marquee").length && $.isFunction($.fn.marquee)) { 1240 $(".marquee").marquee({ 1241 duration: 5000, 1242 gap: 0, 1243 delayBeforeStart: 0, 1244 direction: "left", 1245 duplicated: true, 1246 }); 1247 } 1248 1249 /* 1250 * Style Switcher Open Loader Button 1251 */ 1252 if ($(".style-switcher-open-loader").length) { 1253 const urlParams = new URLSearchParams(window.location.search); 1254 1255 let hideStyleSwitcherAfterShow = false; 1256 1257 $(".style-switcher-open-loader").on("click", function (e) { 1258 e.preventDefault(); 1259 1260 const $this = $(this); 1261 1262 // Add Spinner to icon 1263 $this.addClass("style-switcher-open-loader-loading"); 1264 1265 const basePath = $(this).data("base-path"), 1266 skinSrc = $(this).data("skin-src"); 1267 1268 const script1 = document.createElement("script"); 1269 script1.src = 1270 basePath + "master/style-switcher/style.switcher.localstorage.js"; 1271 1272 const script2 = document.createElement("script"); 1273 script2.src = basePath + "master/style-switcher/style.switcher.js"; 1274 script2.id = "styleSwitcherScript"; 1275 script2.setAttribute("data-base-path", basePath); 1276 script2.setAttribute("data-skin-src", skinSrc); 1277 1278 script2.onload = () => { 1279 setTimeout(() => { 1280 // Trigger a click to open the style switcher sidebar 1281 function checkIfReady() { 1282 if (!$(".style-switcher-open").length) { 1283 window.setTimeout(checkIfReady, 100); 1284 } else { 1285 $(".style-switcher-open").trigger("click"); 1286 1287 if (hideStyleSwitcherAfterShow) { 1288 setTimeout(() => { 1289 $(".style-switcher-open").trigger("click"); 1290 }, 2000); 1291 } 1292 } 1293 } 1294 checkIfReady(); 1295 }, 500); 1296 }; 1297 1298 document.body.appendChild(script1); 1299 document.body.appendChild(script2); 1300 }); 1301 1302 let htmlDataOptions = $("html").data("style-switcher-options"); 1303 let showSwitcher = false; 1304 1305 if (htmlDataOptions) { 1306 htmlDataOptions = htmlDataOptions.replace(/'/g, '"'); 1307 1308 if (JSON.parse(htmlDataOptions).showSwitcher) { 1309 showSwitcher = true; 1310 } 1311 1312 if (JSON.parse(htmlDataOptions).hideStyleSwitcherAfterShow) { 1313 hideStyleSwitcherAfterShow = true; 1314 } 1315 } 1316 1317 if (urlParams.has("showStyleSwitcher")) { 1318 showSwitcher = true; 1319 } 1320 1321 if (urlParams.has("hideStyleSwitcherAfterShow")) { 1322 hideStyleSwitcherAfterShow = true; 1323 } 1324 1325 if (showSwitcher) { 1326 $(".style-switcher-open-loader").trigger("click"); 1327 } 1328 } 1329}).apply(this, [window.theme, jQuery]); 1330 1331// Animate 1332((theme = {}, $) => { 1333 const instanceName = "__animate"; 1334 1335 class PluginAnimate { 1336 constructor($el, opts) { 1337 return this.initialize($el, opts); 1338 } 1339 1340 initialize($el, opts) { 1341 if ($el.data(instanceName)) { 1342 return this; 1343 } 1344 1345 this.$el = $el; 1346 1347 this.setData().setOptions(opts).build(); 1348 1349 return this; 1350 } 1351 1352 setData() { 1353 this.$el.data(instanceName, this); 1354 1355 return this; 1356 } 1357 1358 setOptions(opts) { 1359 this.options = $.extend(true, {}, PluginAnimate.defaults, opts, { 1360 wrapper: this.$el, 1361 }); 1362 1363 return this; 1364 } 1365 1366 build() { 1367 const self = this; 1368 1369 // Flag Class Only 1370 // - Useful for simple animations like hightlight 1371 // - Less process and memory 1372 if (self.options.flagClassOnly) {
1373 const delay = self.options.wrapper.attr("data-appear-animation-delay") 1374 ? self.options.wrapper.attr("data-appear-animation-delay") 1375 : self.options.delay; 1376 1377 self.options.wrapper.css({ 1378 "animation-delay": delay + "ms", 1379 "transition-delay": delay + "ms", 1380 }); 1381 self.options.wrapper.addClass( 1382 self.options.wrapper.attr("data-appear-animation") 1383 ); 1384 1385 return this; 1386 } 1387 1388 if ($("body").hasClass("loading-overlay-showing")) { 1389 $(window).on("loading.overlay.ready", () => { 1390 self.animate(); 1391 }); 1392 } else { 1393 self.animate(); 1394 } 1395 1396 return this; 1397 } 1398 1399 animate() { 1400 const self = this; 1401 const $el = this.options.wrapper; 1402 let delay = 0; 1403 let duration = this.options.duration; 1404 const elTopDistance = $el.offset().top; 1405 const windowTopDistance = $(window).scrollTop(); 1406 1407 // If has appear animation elements inside a SVG. 1408 // Intersection Observer API do not check elements inside SVG's, so we need initialize trough top parent SVG 1409 if ($el.data("appear-animation-svg")) { 1410 $el.find("[data-appear-animation]").each(function () { 1411 const $this = $(this); 1412 let opts; 1413 1414 const pluginOptions = theme.fn.getOptions( 1415 $this.data("plugin-options") 1416 ); 1417 if (pluginOptions) opts = pluginOptions; 1418 1419 $this.themePluginAnimate(opts); 1420 }); 1421 1422 return this; 1423 } 1424 1425 // No animation at the first load of page. This is good for performance 1426 if (self.options.firstLoadNoAnim) { 1427 $el.removeClass("appear-animation"); 1428 1429 // Inside Carousel 1430 if ($el.closest(".owl-carousel").get(0)) { 1431 setTimeout(() => { 1432 $el.closest(".owl-carousel").on("change.owl.carousel", () => { 1433 self.options.firstLoadNoAnim = false; 1434 $el.removeData("__animate"); 1435 $el.themePluginAnimate(self.options); 1436 }); 1437 }, 500); 1438 } 1439 1440 return this; 1441 } 1442 1443 $el.addClass("appear-animation animated"); 1444 1445 if ( 1446 (!$("html").hasClass("no-csstransitions") && 1447 $(window).width() > self.options.minWindowWidth && 1448 elTopDistance >= windowTopDistance) || 1449 self.options.forceAnimation == true 1450 ) { 1451 delay = $el.attr("data-appear-animation-delay") 1452 ? $el.attr("data-appear-animation-delay") 1453 : self.options.delay; 1454 duration = $el.attr("data-appear-animation-duration") 1455 ? $el.attr("data-appear-animation-duration") 1456 : self.options.duration; 1457 1458 if (duration != "750ms") { 1459 $el.css("animation-duration", duration); 1460 } 1461 1462 $el.css("animation-delay", delay + "ms"); 1463 $el.addClass( 1464 $el.attr("data-appear-animation") + " appear-animation-visible" 1465 ); 1466 1467 $el.trigger("animation:show"); 1468 } else { 1469 $el.addClass("appear-animation-visible"); 1470 } 1471 1472 return this; 1473 } 1474 } 1475 1476 PluginAnimate.defaults = { 1477 accX: 0, 1478 accY: -80, 1479 delay: 100, 1480 duration: "750ms", 1481 minWindowWidth: 0, 1482 forceAnimation: false, 1483 flagClassOnly: false, 1484 }; 1485 1486 // expose to scope 1487 $.extend(theme, { 1488 PluginAnimate, 1489 }); 1490 1491 // jquery plugin 1492 $.fn.themePluginAnimate = function (opts) { 1493 return this.map(function () { 1494 const $this = $(this); 1495 1496 if ($this.data(instanceName)) { 1497 return $this.data(instanceName); 1498 } else { 1499 return new PluginAnimate($this, opts); 1500 } 1501 }); 1502 }; 1503}).apply(this, [window.theme, jQuery]); 1504 1505// Animated Content 1506((theme = {}, $) => { 1507 const instanceName = "__animatedContent"; 1508 1509 class PluginAnimatedContent { 1510 constructor($el, opts) { 1511 return this.initialize($el, opts); 1512 } 1513 1514 initialize($el, opts) { 1515 if ($el.data(instanceName)) { 1516 return this; 1517 } 1518 1519 const self = this; 1520 1521 this.$el = $el; 1522 this.initialText = $el.text(); 1523 1524 this.setData().setOptions(opts).build().events(); 1525 1526 return this; 1527 } 1528 1529 setData() { 1530 this.$el.data(instanceName, this); 1531 1532 return this; 1533 } 1534 1535 setOptions(opts) { 1536 this.options = $.extend(true, {}, PluginAnimatedContent.defaults, opts, { 1537 wrapper: this.$el, 1538 }); 1539 1540 return this; 1541 } 1542 1543 build() { 1544 const self = this; 1545 1546 if ($(window).width() < self.options.minWindowWidth) { 1547 return this; 1548 } 1549 1550 if (self.options.firstLoadNoAnim) { 1551 self.$el.css({ 1552 visibility: "visible", 1553 }); 1554 1555 // Inside Carousel 1556 if (self.$el.closest(".owl-carousel").get(0)) { 1557 setTimeout(() => { 1558 self.$el.closest(".owl-carousel").on("change.owl.carousel", () => { 1559 self.options.firstLoadNoAnim = false; 1560 self.build(); 1561 }); 1562 }, 500); 1563 } 1564 1565 return this; 1566 } 1567 1568 // Set Min Height to avoid flicking issues 1569 self.setMinHeight(); 1570 1571 // Letter 1572 if (self.options.contentType == "letter") { 1573 self.$el.addClass("initialized"); 1574 1575 const letters = self.$el.text().split(""); 1576 1577 self.$el.text(""); 1578 1579 // Type Writer 1580 if (self.options.animationName == "typeWriter") { 1581 self.$el.append( 1582 '<span class="letters-wrapper"></span><span class="typeWriter"></pre>' 1583 ); 1584 1585 let index = 0; 1586 1587 setTimeout(() => { 1588 const timeout = () => { 1589 const st = setTimeout(() => { 1590 const letter = letters[index]; 1591 1592 self.$el 1593 .find(".letters-wrapper") 1594 .append( 1595 '<span class="letter ' + 1596 (self.options.letterClass 1597 ? self.options.letterClass + " " 1598 : "") + 1599 '">' + 1600 letter + 1601 "</span>" 1602 ); 1603 1604 index++; 1605 timeout(); 1606 }, self.options.animationSpeed); 1607 1608 if (index >= letters.length) { 1609 clearTimeout(st); 1610 } 1611 }; 1612 timeout(); 1613 }, self.options.startDelay); 1614 1615 // Class Animation 1616 } else { 1617 setTimeout(() => { 1618 for (let i = 0; i < letters.length; i++) { 1619 const letter = letters[i]; 1620 1621 self.$el.append( 1622 '<span class="animated-letters-wrapper ' + 1623 self.options.wrapperClass + 1624 '"><span class="animated-letters-item letter ' + 1625 (self.options.letterClass 1626 ? self.options.letterClass + " " 1627 : "") + 1628 self.options.animationName + 1629 ' animated" style="animation-delay: ' + 1630 i * self.options.animationSpeed + 1631 'ms;">' + 1632 (letter == " " ? " " : letter) + 1633 "</span></span>" 1634 ); 1635 } 1636 }, self.options.startDelay); 1637 } 1638 1639 // Words 1640 } else if (self.options.contentType == "word") { 1641 const words = self.$el.text().split(" "); 1642 let delay = self.options.startDelay; 1643 1644 self.$el.empty(); 1645 1646 $.each(words, (i, v) => { 1647 self.$el.append( 1648 $( 1649 '<span class="animated-words-wrapper ' + 1650 self.options.wrapperClass + 1651 '">' 1652 ).html( 1653 '<span class="animated-words-item ' + 1654 self.options.wordClass + 1655 ' appear-animation" data-appear-animation="' + 1656 self.options.animationName + 1657 '" data-appear-animation-delay="' + 1658 delay + 1659 '">' + 1660 v + 1661 " </span>" 1662 ) 1663 );
1664 delay = delay + self.options.animationSpeed; 1665 }); 1666 1667 if ( 1668 $.isFunction($.fn["themePluginAnimate"]) && 1669 $(".animated-words-item[data-appear-animation]").length 1670 ) { 1671 theme.fn.dynIntObsInit( 1672 ".animated-words-item[data-appear-animation]", 1673 "themePluginAnimate", 1674 theme.PluginAnimate.defaults 1675 ); 1676 } 1677 1678 self.$el.addClass("initialized"); 1679 } 1680 1681 return this; 1682 } 1683 1684 setMinHeight() { 1685 const self = this; 1686 1687 // if it's inside carousel 1688 if (self.$el.closest(".owl-carousel").get(0)) { 1689 self.$el.closest(".owl-carousel").addClass("d-block"); 1690 self.$el.css("min-height", self.$el.height()); 1691 self.$el.closest(".owl-carousel").removeClass("d-block"); 1692 } else { 1693 self.$el.css("min-height", self.$el.height()); 1694 } 1695 1696 return this; 1697 } 1698 1699 destroy() { 1700 const self = this; 1701 1702 self.$el.html(self.initialText).css("min-height", ""); 1703 1704 return this; 1705 } 1706 1707 events() { 1708 const self = this; 1709 1710 // Destroy 1711 self.$el.on("animated.letters.destroy", () => { 1712 self.destroy(); 1713 }); 1714 1715 // Initialize 1716 self.$el.on("animated.letters.initialize", () => { 1717 self.build(); 1718 }); 1719 1720 return this; 1721 } 1722 } 1723 1724 PluginAnimatedContent.defaults = { 1725 contentType: "letter", 1726 animationName: "fadeIn", 1727 animationSpeed: 50, 1728 startDelay: 500, 1729 minWindowWidth: 768, 1730 letterClass: "", 1731 wordClass: "", 1732 wrapperClass: "", 1733 }; 1734 1735 // expose to scope 1736 $.extend(theme, { 1737 PluginAnimatedContent, 1738 }); 1739 1740 // jquery plugin 1741 $.fn.themePluginAnimatedContent = function (opts) { 1742 return this.map(function () { 1743 const $this = $(this); 1744 1745 if ($this.data(instanceName)) { 1746 return $this.data(instanceName); 1747 } else { 1748 return new PluginAnimatedContent($this, opts); 1749 } 1750 }); 1751 }; 1752}).apply(this, [window.theme, jQuery]); 1753 1754// Before / After 1755((theme = {}, $) => { 1756 const instanceName = "__beforeafter"; 1757 1758 class PluginBeforeAfter { 1759 constructor($el, opts) { 1760 return this.initialize($el, opts); 1761 } 1762 1763 initialize($el, opts) { 1764 this.$el = $el; 1765 1766 this.setData().setOptions(opts).build(); 1767 1768 return this; 1769 } 1770 1771 setData() { 1772 this.$el.data(instanceName, this); 1773 1774 return this; 1775 } 1776 1777 setOptions(opts) { 1778 this.options = $.extend(true, {}, PluginBeforeAfter.defaults, opts, { 1779 wrapper: this.$el, 1780 }); 1781 1782 return this; 1783 } 1784 1785 build() { 1786 if ($.isFunction($.fn.twentytwenty)) { 1787 const self = this; 1788 1789 self.options.wrapper.waitForImages(() => { 1790 self.options.wrapper.twentytwenty(self.options); 1791 }); 1792 } else { 1793 theme.fn.showErrorMessage( 1794 "Failed to Load File", 1795 "Failed to load: twentytwenty - Include the following file(s): (vendor/twentytwenty/css/twentytwenty.css, vendor/twentytwenty/js/jquery.event.move.js, vendor/twentytwenty/js/jquery.twentytwenty.js)" 1796 ); 1797 } 1798 1799 return this; 1800 } 1801 } 1802 1803 PluginBeforeAfter.defaults = { 1804 forceInit: true, 1805 default_offset_pct: 0.5, 1806 orientation: "horizontal", 1807 before_label: "Before", 1808 after_label: "After", 1809 no_overlay: false, 1810 move_slider_on_hover: false, 1811 move_with_handle_only: true, 1812 click_to_move: false, 1813 }; 1814 1815 // expose to scope 1816 $.extend(theme, { 1817 PluginBeforeAfter, 1818 }); 1819 1820 // jquery plugin 1821 $.fn.themePluginBeforeAfter = function (opts) { 1822 return this.map(function () { 1823 const $this = $(this); 1824 1825 if ($this.data(instanceName)) { 1826 return $this.data(instanceName); 1827 } else { 1828 return new PluginBeforeAfter($this, opts); 1829 } 1830 }); 1831 }; 1832}).apply(this, [window.theme, jQuery]); 1833 1834// Carousel Light 1835((theme = {}, $) => { 1836 const instanceName = "__carouselLight"; 1837 1838 class PluginCarouselLight { 1839 constructor($el, opts) { 1840 return this.initialize($el, opts); 1841 } 1842 1843 initialize($el, opts) { 1844 if ($el.data(instanceName)) { 1845 return this; 1846 } 1847 1848 this.$el = $el; 1849 this.clickFlag = true; 1850 1851 this.setData() 1852 .setOptions(opts) 1853 .build() 1854 .owlNav() 1855 .owlDots() 1856 .autoPlay() 1857 .events(); 1858 1859 return this; 1860 } 1861 1862 setData() { 1863 this.$el.data(instanceName, this); 1864 1865 return this; 1866 } 1867 1868 setOptions(opts) { 1869 this.options = $.extend(true, {}, PluginCarouselLight.defaults, opts, { 1870 wrapper: this.$el, 1871 }); 1872 1873 return this; 1874 } 1875 1876 build() { 1877 const self = this; 1878 1879 self.$el 1880 .css("opacity", 1) 1881 .find(".owl-item:first-child") 1882 .addClass("active"); 1883 1884 self.$el.trigger("initialized.owl.carousel"); 1885 1886 // Carousel Navigate By ID and item index 1887 self.carouselNavigate(); 1888 1889 return this; 1890 } 1891 1892 changeSlide($nextSlide) { 1893 const self = this, 1894 $prevSlide = self.$el.find(".owl-item.active"); 1895 1896 self.$el.find(".owl-item.active").addClass("removing"); 1897 1898 $prevSlide.removeClass("fadeIn").addClass("fadeOut animated"); 1899 1900 setTimeout(() => { 1901 setTimeout(() => { 1902 $prevSlide.removeClass("active"); 1903 }, 400); 1904 1905 $nextSlide 1906 .addClass("active") 1907 .removeClass("fadeOut") 1908 .addClass("fadeIn animated"); 1909 }, 200); 1910 1911 // Dots 1912 self.$el 1913 .find(".owl-dot") 1914 .removeClass("active") 1915 .eq($nextSlide.index()) 1916 .addClass("active"); 1917 1918 self.$el.trigger({ 1919 type: "change.owl.carousel", 1920 nextSlideIndex: $nextSlide.index(), 1921 prevSlideIndex: $prevSlide.index(), 1922 }); 1923 1924 setTimeout(() => { 1925 self.$el.trigger({ 1926 type: "changed.owl.carousel", 1927 nextSlideIndex: $nextSlide.index(), 1928 prevSlideIndex: $prevSlide.index(), 1929 }); 1930 }, 500); 1931 } 1932 1933 owlNav() { 1934 const self = this, 1935 $owlNext = self.$el.find(".owl-next"), 1936 $owlPrev = self.$el.find(".owl-prev"); 1937 1938 $owlPrev.on("click", (e) => { 1939 e.preventDefault(); 1940 1941 if (self.options.disableAutoPlayOnClick) { 1942 window.clearInterval(self.autoPlayInterval); 1943 } 1944 1945 if (self.avoidMultipleClicks()) { 1946 return false; 1947 } 1948
1949 self.owlPrev(); 1950 }); 1951 1952 $owlNext.on("click", (e) => { 1953 e.preventDefault(); 1954 1955 if (self.options.disableAutoPlayOnClick) { 1956 window.clearInterval(self.autoPlayInterval); 1957 } 1958 1959 if (self.avoidMultipleClicks()) { 1960 return false; 1961 } 1962 1963 self.owlNext(); 1964 }); 1965 1966 return this; 1967 } 1968 1969 owlDots() { 1970 const self = this, 1971 $owlDot = self.$el.find(".owl-dot"); 1972 1973 $owlDot.on("click", function (e) { 1974 $this = $(this); 1975 1976 e.preventDefault(); 1977 1978 if (self.options.disableAutoPlayOnClick) { 1979 window.clearInterval(self.autoPlayInterval); 1980 } 1981 1982 if (self.avoidMultipleClicks()) { 1983 return false; 1984 } 1985 1986 const dotIndex = $(this).index(); 1987 1988 // Do nothing if respective dot slide is active/showing 1989 if ($this.hasClass("active")) { 1990 return false; 1991 } 1992 1993 self.changeSlide(self.$el.find(".owl-item").eq(dotIndex)); 1994 }); 1995 1996 return this; 1997 } 1998 1999 owlPrev() { 2000 const self = this; 2001 2002 if (self.$el.find(".owl-item.active").prev().get(0)) { 2003 self.changeSlide(self.$el.find(".owl-item.active").prev()); 2004 } else { 2005 self.changeSlide(self.$el.find(".owl-item:last-child")); 2006 } 2007 } 2008 2009 owlNext() { 2010 const self = this; 2011 2012 if (self.$el.find(".owl-item.active").next().get(0)) { 2013 self.changeSlide(self.$el.find(".owl-item.active").next()); 2014 } else { 2015 self.changeSlide(self.$el.find(".owl-item").eq(0)); 2016 } 2017 } 2018 2019 avoidMultipleClicks() { 2020 const self = this; 2021 2022 if (!self.clickFlag) { 2023 return true; 2024 } 2025 2026 if (self.clickFlag) { 2027 self.clickFlag = false; 2028 setTimeout(() => { 2029 self.clickFlag = true; 2030 }, 1000); 2031 } 2032 2033 return false; 2034 } 2035 2036 autoPlay() { 2037 const self = this, 2038 $el = this.options.wrapper; 2039 2040 if (self.options.autoplay) { 2041 self.autoPlayInterval = window.setInterval(() => { 2042 self.owlNext(); 2043 }, self.options.autoplayTimeout); 2044 } 2045 2046 return this; 2047 } 2048 2049 carouselNavigate() { 2050 const self = this, 2051 $el = this.options.wrapper, 2052 $carousel = $el; 2053 2054 if ($("[data-carousel-navigate]").get(0)) { 2055 $('[data-carousel-navigate-id="#' + $el.attr("id") + '"]').each( 2056 function () { 2057 const $this = $(this), 2058 hasCarousel = $($this.data("carousel-navigate-id")).get(0), 2059 toIndex = $this.data("carousel-navigate-to"); 2060 2061 if (hasCarousel) { 2062 $this.on("click", () => { 2063 if (self.options.disableAutoPlayOnClick) { 2064 window.clearInterval(self.autoPlayInterval); 2065 } 2066 2067 self.changeSlide( 2068 self.$el.find(".owl-item").eq(parseInt(toIndex) - 1) 2069 ); 2070 }); 2071 } 2072 } 2073 ); 2074 2075 $el.on("change.owl.carousel", (e) => { 2076 $( 2077 '[data-carousel-navigate-id="#' + $el.attr("id") + '"]' 2078 ).removeClass("active"); 2079 }); 2080 2081 $el.on("changed.owl.carousel", ({ nextSlideIndex }) => { 2082 $( 2083 '[data-carousel-navigate-id="#' + 2084 $el.attr("id") + 2085 '"][data-carousel-navigate-to="' + 2086 (nextSlideIndex + 1) + 2087 '"]' 2088 ).addClass("active"); 2089 }); 2090 } 2091 2092 return this; 2093 } 2094 2095 events() { 2096 const self = this; 2097 2098 self.$el.on("change.owl.carousel", (event) => { 2099 // Hide elements inside carousel 2100 self.$el 2101 .find( 2102 "[data-appear-animation]:not(.background-image-wrapper), [data-plugin-animated-letters]" 2103 ) 2104 .addClass("invisible"); 2105 2106 // Animated Letters 2107 self.$el 2108 .find("[data-plugin-animated-letters]") 2109 .trigger("animated.letters.destroy"); 2110 2111 // Remove "d-none" class before show the element. This is useful when using background images inside a carousel. Like ken burns effect 2112 self.$el 2113 .find(".owl-item:not(.active) [data-carousel-onchange-show]") 2114 .removeClass("d-none"); 2115 }); 2116 2117 self.$el.on("changed.owl.carousel", (event) => { 2118 setTimeout(() => { 2119 // Appear Animation 2120 if ( 2121 self.$el.find(".owl-item.cloned [data-appear-animation]").get(0) 2122 ) { 2123 self.$el 2124 .find(".owl-item.cloned [data-appear-animation]") 2125 .each(function () { 2126 const $this = $(this); 2127 let opts; 2128 2129 const pluginOptions = theme.fn.getOptions( 2130 $this.data("plugin-options") 2131 ); 2132 if (pluginOptions) opts = pluginOptions; 2133 2134 $this.themePluginAnimate(opts); 2135 }); 2136 } 2137 2138 // Show elements inside carousel 2139 self.$el 2140 .find( 2141 ".owl-item.active [data-appear-animation]:not(.background-image-wrapper), [data-plugin-animated-letters]" 2142 ) 2143 .removeClass("invisible"); 2144 2145 // Animated Letters 2146 self.$el 2147 .find(".owl-item.active [data-plugin-animated-letters]") 2148 .trigger("animated.letters.initialize"); 2149
2150 // Background Video 2151 self.$el 2152 .find(".owl-item.cloned.active [data-plugin-video-background]") 2153 .trigger("video.background.initialize"); 2154 }, 500); 2155 }); 2156 2157 if (self.options.swipeEvents) { 2158 self.$el.swipe({ 2159 swipe(event, direction, distance, duration, fingerCount, fingerData) { 2160 switch (direction) { 2161 case "right": 2162 self.owlPrev(); 2163 break; 2164 2165 case "left": 2166 self.owlNext(); 2167 break; 2168 } 2169 }, 2170 allowPageScroll: "vertical", 2171 }); 2172 } 2173 } 2174 } 2175 2176 PluginCarouselLight.defaults = { 2177 autoplay: true, 2178 autoplayTimeout: 7000, 2179 disableAutoPlayOnClick: true, 2180 swipeEvents: true, 2181 }; 2182 2183 // expose to scope 2184 $.extend(theme, { 2185 PluginCarouselLight, 2186 }); 2187 2188 // jquery plugin 2189 $.fn.themePluginCarouselLight = function (opts) { 2190 return this.map(function () { 2191 const $this = $(this); 2192 2193 if ($this.data(instanceName)) { 2194 return $this.data(instanceName); 2195 } else { 2196 return new PluginCarouselLight($this, opts); 2197 } 2198 }); 2199 }; 2200}).apply(this, [window.theme, jQuery]); 2201 2202// Carousel 2203((theme = {}, $) => { 2204 const instanceName = "__carousel"; 2205 2206 class PluginCarousel { 2207 constructor($el, opts) { 2208 return this.initialize($el, opts); 2209 } 2210 2211 initialize($el, opts) { 2212 if ($el.data(instanceName)) { 2213 return this; 2214 } 2215 2216 this.$el = $el; 2217 2218 // If has data-icon inside, initialize only after icons get rendered 2219 // Prevent flicking issues 2220 if ($el.find("[data-icon]").get(0)) { 2221 const self = this; 2222 2223 $(window).on("icon.rendered", function () { 2224 if ($el.data(instanceName)) { 2225 return this; 2226 } 2227 2228 setTimeout(() => { 2229 self.setData().setOptions(opts).build(); 2230 }, 1000); 2231 }); 2232 2233 return this; 2234 } 2235 2236 this.setData().setOptions(opts).build(); 2237 2238 return this; 2239 } 2240 2241 setData() { 2242 this.$el.data(instanceName, this); 2243 2244 return this; 2245 } 2246 2247 setOptions(opts) { 2248 this.options = $.extend(true, {}, PluginCarousel.defaults, opts, { 2249 wrapper: this.$el, 2250 }); 2251 2252 return this; 2253 } 2254 2255 build() { 2256 if (!$.isFunction($.fn.owlCarousel)) { 2257 return this; 2258 } 2259 2260 const self = this, 2261 $el = this.options.wrapper; 2262 2263 // Add Theme Class 2264 $el.addClass("owl-theme"); 2265 2266 // Add Loading 2267 $el.addClass("owl-loading"); 2268 2269 // Force RTL according to HTML dir attribute 2270 if ($("html").attr("dir") == "rtl") { 2271 this.options = $.extend(true, {}, this.options, { 2272 rtl: true, 2273 }); 2274 } 2275 2276 if (this.options.items == 1) { 2277 this.options.responsive = {}; 2278 } 2279 2280 if (this.options.items > 4) { 2281 this.options = $.extend(true, {}, this.options, { 2282 responsive: { 2283 1199: { 2284 items: this.options.items, 2285 }, 2286 }, 2287 }); 2288 } 2289 2290 // Auto Height Fixes 2291 if (this.options.autoHeight) { 2292 const itemsHeight = []; 2293 2294 $el.find(".owl-item").each(function () { 2295 if ($(this).hasClass("active")) { 2296 itemsHeight.push($(this).height()); 2297 } 2298 }); 2299 2300 $(window).afterResize(() => { 2301 $el 2302 .find(".owl-stage-outer") 2303 .height(Math.max.apply(null, itemsHeight)); 2304 }); 2305 2306 $(window).on("load", () => { 2307 $el 2308 .find(".owl-stage-outer") 2309 .height(Math.max.apply(null, itemsHeight)); 2310 }); 2311 } 2312 2313 // Initialize OwlCarousel 2314 $el 2315 .owlCarousel(this.options) 2316 .addClass("owl-carousel-init animated fadeIn"); 2317 2318 // Remove "animated fadeIn" class to prevent conflicts 2319 setTimeout(() => { 2320 $el.removeClass("animated fadeIn"); 2321 }, 1000); 2322 2323 // Owl Carousel Wrapper 2324 if ($el.closest(".owl-carousel-wrapper").get(0)) { 2325 setTimeout(() => { 2326 $el.closest(".owl-carousel-wrapper").css({ 2327 height: "", 2328 }); 2329 }, 500); 2330 } 2331 2332 // Owl Carousel Loader 2333 if ($el.prev().hasClass("owl-carousel-loader")) { 2334 $el.prev().remove(); 2335 } 2336
2337 // Nav Offset 2338 self.navigationOffsets(); 2339 2340 // Nav Outside 2341 if ($el.hasClass("nav-outside")) { 2342 $(window).on("owl.carousel.nav.outside", () => { 2343 if ($(window).width() < 992) { 2344 self.options.stagePadding = 40; 2345 $el.addClass("stage-margin"); 2346 } else { 2347 self.options.stagePadding = 0; 2348 $el.removeClass("stage-margin"); 2349 } 2350 2351 $el.owlCarousel("destroy").owlCarousel(self.options); 2352 2353 // Nav Offset 2354 self.navigationOffsets(); 2355 }); 2356 2357 // Window Resize 2358 $(window).on("load", () => { 2359 $(window).afterResize(() => { 2360 $(window).trigger("owl.carousel.nav.outside"); 2361 }); 2362 }); 2363 2364 // First Load 2365 $(window).trigger("owl.carousel.nav.outside"); 2366 } 2367 2368 // Nav style 5 (SVG Arrows) 2369 if ($el.hasClass("nav-svg-arrows-1")) { 2370 const svg_arrow = 2371 "" + 2372 '<svg version="1.1" viewBox="0 0 15.698 8.706" width="17" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' + 2373 '<polygon stroke="#212121" stroke-width="0.1" fill="#212121" points="11.354,0 10.646,0.706 13.786,3.853 0,3.853 0,4.853 13.786,4.853 10.646,8 11.354,8.706 15.698,4.353 "/>' + 2374 "</svg>"; 2375 2376 $el.find(".owl-next, .owl-prev").append(svg_arrow); 2377 } 2378 2379 // Sync 2380 if ($el.attr("data-sync")) { 2381 $el.on( 2382 "change.owl.carousel", 2383 ({ namespace, property, relatedTarget }) => { 2384 if (namespace && property.name === "position") { 2385 const target = relatedTarget.relative(property.value, true); 2386 $($el.data("sync")).owlCarousel("to", target, 300, true); 2387 } 2388 } 2389 ); 2390 } 2391 2392 // Carousel Center Active Item 2393 if ($el.hasClass("carousel-center-active-item")) { 2394 const itemsActive = $el.find(".owl-item.active"), 2395 indexCenter = Math.floor( 2396 ($el.find(".owl-item.active").length - 1) / 2 2397 ),
2398 itemCenter = itemsActive.eq(indexCenter); 2399 2400 itemCenter.addClass("current"); 2401 2402 $el.on("change.owl.carousel", (event) => { 2403 $el.find(".owl-item").removeClass("current"); 2404 2405 setTimeout(() => { 2406 const itemsActive = $el.find(".owl-item.active"), 2407 indexCenter = Math.floor( 2408 ($el.find(".owl-item.active").length - 1) / 2 2409 ), 2410 itemCenter = itemsActive.eq(indexCenter); 2411 2412 itemCenter.addClass("current"); 2413 }, 100); 2414 }); 2415 2416 // Refresh 2417 $el.trigger("refresh.owl.carousel"); 2418 } 2419 2420 // AnimateIn / AnimateOut Fix 2421 if (self.options.animateIn || self.options.animateOut) { 2422 $el.on("change.owl.carousel", (event) => { 2423 // Hide elements inside carousel 2424 $el 2425 .find("[data-appear-animation], [data-plugin-animated-letters]") 2426 .addClass("d-none"); 2427 2428 // Animated Letters 2429 $el 2430 .find("[data-plugin-animated-letters]") 2431 .trigger("animated.letters.destroy"); 2432 2433 // Remove "d-none" class before show the element. This is useful when using background images inside a carousel. Like ken burns effect 2434 $el 2435 .find(".owl-item:not(.active) [data-carousel-onchange-show]") 2436 .removeClass("d-none"); 2437 }); 2438 2439 $el.on("changed.owl.carousel", (event) => { 2440 setTimeout(() => { 2441 // Appear Animation 2442 $el.find("[data-appear-animation]").each(function () { 2443 const $this = $(this); 2444 let opts; 2445 2446 const pluginOptions = theme.fn.getOptions( 2447 $this.data("plugin-options") 2448 ); 2449 if (pluginOptions) opts = pluginOptions; 2450 2451 $this.themePluginAnimate(opts); 2452 }); 2453 2454 // Show elements inside carousel 2455 $el 2456 .find( 2457 ".owl-item.active [data-appear-animation], [data-plugin-animated-letters]" 2458 ) 2459 .removeClass("d-none"); 2460 2461 // Animated Letters 2462 $el 2463 .find(".owl-item.active [data-plugin-animated-letters]") 2464 .trigger("animated.letters.initialize"); 2465 2466 // Background Video 2467 $el 2468 .find(".owl-item.cloned.active [data-plugin-video-background]") 2469 .trigger("video.background.initialize"); 2470 }, 10); 2471 }); 2472 } 2473 2474 // data-icon inside carousel 2475 if ($el.find("[data-icon]").length) { 2476 $el.on("change.owl.carousel drag.owl.carousel", () => { 2477 $el.find(".owl-item.cloned [data-icon]").each(function () { 2478 const $this = $(this); 2479 let opts; 2480 2481 const pluginOptions = theme.fn.getOptions( 2482 $this.data("plugin-options") 2483 ); 2484 if (pluginOptions) opts = pluginOptions; 2485 2486 $this.themePluginIcon(opts); 2487 }); 2488 }); 2489 } 2490 2491 // Render Background Videos inside carousel. Just a trigger on window is sufficient to render 2492 if ($el.find("[data-plugin-video-background]").get(0)) { 2493 $(window).resize(); 2494 } 2495 2496 // Remove Loading 2497 $el.removeClass("owl-loading"); 2498 2499 // Remove Height 2500 $el.css("height", "auto"); 2501 2502 // Carousel Navigate By ID and item index 2503 self.carouselNavigate(); 2504 2505 // Refresh Carousel 2506 if (self.options.refresh) { 2507 $el.owlCarousel("refresh"); 2508 } 2509 2510 return this; 2511 } 2512 2513 navigationOffsets() { 2514 const self = this, 2515 $el = this.options.wrapper, 2516 navHasTransform = 2517 $el.find(".owl-nav").css("transform") == "none" ? false : true, 2518 dotsHasTransform = 2519 $el.find(".owl-dots").css("transform") == "none" ? false : true; 2520 2521 // ************* NAV ***************** 2522 // Nav Offset - Horizontal 2523 if (self.options.navHorizontalOffset && !self.options.navVerticalOffset) { 2524 if (!navHasTransform) { 2525 $el.find(".owl-nav").css({ 2526 transform: 2527 "translate3d(" + self.options.navHorizontalOffset + ", 0, 0)", 2528 }); 2529 } else { 2530 $el.find(".owl-nav").css({ 2531 left: self.options.navHorizontalOffset, 2532 }); 2533 } 2534 } 2535
2536 // Nav Offset - Vertical 2537 if (self.options.navVerticalOffset && !self.options.navHorizontalOffset) { 2538 if (!navHasTransform) { 2539 $el.find(".owl-nav").css({ 2540 transform: 2541 "translate3d(0, " + self.options.navVerticalOffset + ", 0)", 2542 }); 2543 } else { 2544 $el.find(".owl-nav").css({ 2545 top: "calc( 50% - " + self.options.navVerticalOffset + " )", 2546 }); 2547 } 2548 } 2549 2550 // Nav Offset - Horizontal & Vertical 2551 if (self.options.navVerticalOffset && self.options.navHorizontalOffset) { 2552 if (!navHasTransform) { 2553 $el.find(".owl-nav").css({ 2554 transform: 2555 "translate3d(" + 2556 self.options.navHorizontalOffset + 2557 ", " + 2558 self.options.navVerticalOffset + 2559 ", 0)", 2560 }); 2561 } else { 2562 $el.find(".owl-nav").css({ 2563 top: "calc( 50% - " + self.options.navVerticalOffset + " )", 2564 left: self.options.navHorizontalOffset, 2565 }); 2566 } 2567 } 2568 2569 // ********** DOTS ********************* 2570 // Dots Offset - Horizontal 2571 if ( 2572 self.options.dotsHorizontalOffset && 2573 !self.options.dotsVerticalOffset 2574 ) { 2575 $el.find(".owl-dots").css({ 2576 transform: 2577 "translate3d(" + self.options.dotsHorizontalOffset + ", 0, 0)", 2578 }); 2579 } 2580 2581 // Dots Offset - Vertical 2582 if ( 2583 self.options.dotsVerticalOffset && 2584 !self.options.dotsHorizontalOffset 2585 ) { 2586 if (!dotsHasTransform) { 2587 $el.find(".owl-dots").css({ 2588 transform: 2589 "translate3d(0, " + self.options.dotsVerticalOffset + ", 0)", 2590 }); 2591 } else { 2592 $el.find(".owl-dots").css({ 2593 top: "calc( 50% - " + self.options.dotsVerticalOffset + " )", 2594 }); 2595 } 2596 } 2597 2598 // Dots Offset - Horizontal & Vertical 2599 if ( 2600 self.options.dotsVerticalOffset && 2601 self.options.dotsHorizontalOffset 2602 ) { 2603 $el.find(".owl-dots").css({ 2604 transform: 2605 "translate3d(" + 2606 self.options.dotsHorizontalOffset + 2607 ", " + 2608 self.options.dotsVerticalOffset + 2609 ", 0)", 2610 }); 2611 } 2612 2613 return this; 2614 } 2615 2616 carouselNavigate() { 2617 const self = this, 2618 $el = this.options.wrapper, 2619 $carousel = $el.data("owl.carousel"); 2620 2621 if ($("[data-carousel-navigate]").get(0)) { 2622 $('[data-carousel-navigate-id="#' + $el.attr("id") + '"]').each( 2623 function () { 2624 const $this = $(this), 2625 hasCarousel = $($this.data("carousel-navigate-id")).get(0), 2626 toIndex = $this.data("carousel-navigate-to"); 2627 2628 if (hasCarousel) { 2629 $this.on("click", () => { 2630 $carousel.to(parseInt(toIndex) - 1); 2631 }); 2632 } 2633 } 2634 ); 2635 2636 $el.on("change.owl.carousel", () => { 2637 $( 2638 '[data-carousel-navigate-id="#' + $el.attr("id") + '"]' 2639 ).removeClass("active"); 2640 }); 2641 2642 $el.on("changed.owl.carousel", ({ item }) => { 2643 $( 2644 '[data-carousel-navigate-id="#' + 2645 $el.attr("id") + 2646 '"][data-carousel-navigate-to="' + 2647 (item.index + 1) + 2648 '"]' 2649 ).addClass("active"); 2650 }); 2651 } 2652 2653 return this; 2654 } 2655 } 2656 2657 PluginCarousel.defaults = { 2658 loop: true, 2659 responsive: { 2660 0: { 2661 items: 1, 2662 }, 2663 479: { 2664 items: 1, 2665 }, 2666 768: { 2667 items: 2, 2668 }, 2669 979: { 2670 items: 3, 2671 }, 2672 1199: { 2673 items: 4, 2674 }, 2675 }, 2676 navText: [], 2677 refresh: false, 2678 }; 2679 2680 // expose to scope 2681 $.extend(theme, { 2682 PluginCarousel, 2683 }); 2684 2685 // jquery plugin 2686 $.fn.themePluginCarousel = function (opts) { 2687 return this.map(function () { 2688 const $this = $(this); 2689 2690 if ($this.data(instanceName)) { 2691 return $this.data(instanceName); 2692 } else { 2693 return new PluginCarousel($this, opts); 2694 } 2695 });
2696 }; 2697}).apply(this, [window.theme, jQuery]); 2698 2699// Chart Circular 2700((theme = {}, $) => { 2701 const instanceName = "__chartCircular"; 2702 2703 class PluginChartCircular { 2704 constructor($el, opts) { 2705 return this.initialize($el, opts); 2706 } 2707 2708 initialize($el, opts) { 2709 if ($el.data(instanceName)) { 2710 return this; 2711 } 2712 2713 this.$el = $el; 2714 2715 this.setData().setOptions(opts).build(); 2716 2717 return this; 2718 } 2719 2720 setData() { 2721 this.$el.data(instanceName, this); 2722 2723 return this; 2724 } 2725 2726 setOptions(opts) { 2727 this.options = $.extend(true, {}, PluginChartCircular.defaults, opts, { 2728 wrapper: this.$el, 2729 }); 2730 2731 return this; 2732 } 2733 2734 build() { 2735 if (!$.isFunction($.fn.easyPieChart)) { 2736 return this; 2737 } 2738 2739 const self = this, 2740 $el = this.options.wrapper, 2741 value = $el.attr("data-percent") ? $el.attr("data-percent") : 0, 2742 percentEl = $el.find(".percent"); 2743 2744 $.extend(true, self.options, { 2745 onStep(from, to, currentValue) { 2746 percentEl.html(parseInt(currentValue)); 2747 }, 2748 }); 2749 2750 $el.attr("data-percent", 0); 2751 2752 $el.easyPieChart(self.options); 2753 2754 setTimeout(() => { 2755 $el.data("easyPieChart").update(value); 2756 $el.attr("data-percent", value); 2757 }, self.options.delay); 2758 2759 return this; 2760 } 2761 } 2762 2763 PluginChartCircular.defaults = { 2764 accX: 0, 2765 accY: -150, 2766 delay: 1, 2767 barColor: "#0088CC", 2768 trackColor: "#f2f2f2", 2769 scaleColor: false, 2770 scaleLength: 5, 2771 lineCap: "round", 2772 lineWidth: 13, 2773 size: 175, 2774 rotate: 0, 2775 animate: { 2776 duration: 2500, 2777 enabled: true, 2778 }, 2779 }; 2780 2781 // expose to scope 2782 $.extend(theme, { 2783 PluginChartCircular, 2784 }); 2785 2786 // jquery plugin 2787 $.fn.themePluginChartCircular = function (opts) { 2788 return this.map(function () { 2789 const $this = $(this); 2790 2791 if ($this.data(instanceName)) { 2792 return $this.data(instanceName); 2793 } else { 2794 return new PluginChartCircular($this, opts); 2795 } 2796 }); 2797 }; 2798}).apply(this, [window.theme, jQuery]); 2799 2800// Countdown 2801((theme = {}, $) => { 2802 const instanceName = "__countdown"; 2803 2804 class PluginCountdown { 2805 constructor($el, opts) { 2806 return this.initialize($el, opts); 2807 } 2808 2809 initialize($el, opts) { 2810 if ($el.data(instanceName)) { 2811 return this; 2812 } 2813 2814 this.$el = $el; 2815 2816 this.setData().setOptions(opts).build(); 2817 2818 return this; 2819 } 2820 2821 setData() { 2822 this.$el.data(instanceName, this); 2823 2824 return this; 2825 } 2826 2827 setOptions(opts) { 2828 this.options = $.extend(true, {}, PluginCountdown.defaults, opts, { 2829 wrapper: this.$el, 2830 }); 2831 2832 return this; 2833 } 2834 2835 build() { 2836 if (!$.isFunction($.fn.countTo)) { 2837 return this; 2838 } 2839 2840 const self = this, 2841 $el = this.options.wrapper, 2842 numberClass = self.options.numberClass 2843 ? " " + self.options.numberClass 2844 : "", 2845 wrapperClass = self.options.wrapperClass 2846 ? " " + self.options.wrapperClass 2847 : ""; 2848 2849 if (self.options.uppercase) { 2850 $el 2851 .countdown(self.options.date) 2852 .on("update.countdown", function (event) { 2853 const $this = $(this).html( 2854 event.strftime( 2855 self.options.insertHTMLbefore + 2856 '<span class="days' + 2857 wrapperClass + 2858 '"><span class="' + 2859 numberClass + 2860 '">%D</span> ' + 2861 self.options.textDay + 2862 "</span> " + 2863 '<span class="hours' + 2864 wrapperClass + 2865 '"><span class="' + 2866 numberClass + 2867 '">%H</span> ' + 2868 self.options.textHour + 2869 "</span> " + 2870 '<span class="minutes' + 2871 wrapperClass + 2872 '"><span class="' + 2873 numberClass + 2874 '">%M</span> ' + 2875 self.options.textMin + 2876 "</span> " + 2877 '<span class="seconds' + 2878 wrapperClass + 2879 '"><span class="' + 2880 numberClass + 2881 '">%S</span> ' + 2882 self.options.textSec + 2883 "</span> " + 2884 self.options.insertHTMLafter 2885 ) 2886 ); 2887 }); 2888 } else { 2889 $el 2890 .countdown(self.options.date) 2891 .on("update.countdown", function (event) { 2892 const $this = $(this).html( 2893 event.strftime( 2894 self.options.insertHTMLbefore + 2895 '<span class="days' + 2896 wrapperClass + 2897 '"><span class="' + 2898 numberClass + 2899 '">%D</span> ' + 2900 self.options.textDay + 2901 "</span> " + 2902 '<span class="hours' + 2903 wrapperClass + 2904 '"><span class="' + 2905 numberClass + 2906 '">%H</span> ' + 2907 self.options.textHour + 2908 "</span> " + 2909 '<span class="minutes' + 2910 wrapperClass + 2911 '"><span class="' + 2912 numberClass + 2913 '">%M</span> ' + 2914 self.options.textMin + 2915 "</span> " + 2916 '<span class="seconds' + 2917 wrapperClass + 2918 '"><span class="' + 2919 numberClass + 2920 '">%S</span> ' + 2921 self.options.textSec + 2922 "</span> " + 2923 self.options.insertHTMLafter 2924 ) 2925 ); 2926 }); 2927 } 2928 2929 return this; 2930 } 2931 } 2932 2933 PluginCountdown.defaults = { 2934 date: "2030/06/10 12:00:00", 2935 textDay: "DAYS", 2936 textHour: "HRS", 2937 textMin: "MIN", 2938 textSec: "SEC", 2939 uppercase: true, 2940 numberClass: "", 2941 wrapperClass: "", 2942 insertHTMLbefore: "", 2943 insertHTMLafter: "", 2944 }; 2945 2946 // expose to scope 2947 $.extend(theme, { 2948 PluginCountdown, 2949 }); 2950 2951 // jquery plugin 2952 $.fn.themePluginCountdown = function (opts) { 2953 return this.map(function () { 2954 const $this = $(this); 2955 2956 if ($this.data(instanceName)) { 2957 return $this.data(instanceName); 2958 } else { 2959 return new PluginCountdown($this, opts); 2960 } 2961 });
2962 }; 2963}).apply(this, [window.theme, jQuery]); 2964 2965// Counter 2966((theme = {}, $) => { 2967 const instanceName = "__counter"; 2968 2969 class PluginCounter { 2970 constructor($el, opts) { 2971 return this.initialize($el, opts); 2972 } 2973 2974 initialize($el, opts) { 2975 if ($el.data(instanceName)) { 2976 return this; 2977 } 2978 2979 this.$el = $el; 2980 2981 this.setData().setOptions(opts).build(); 2982 2983 return this; 2984 } 2985 2986 setData() { 2987 this.$el.data(instanceName, this); 2988 2989 return this; 2990 } 2991 2992 setOptions(opts) { 2993 this.options = $.extend(true, {}, PluginCounter.defaults, opts, { 2994 wrapper: this.$el, 2995 }); 2996 2997 return this; 2998 } 2999 3000 build() { 3001 if (!$.isFunction($.fn.countTo)) { 3002 return this; 3003 } 3004 3005 const self = this, 3006 $el = this.options.wrapper; 3007 3008 if (self.options.comma) { 3009 self.options.formatter = (value, { decimals }) => 3010 value.toFixed(decimals).toString().replace(".", ","); 3011 } 3012 3013 $.extend(self.options, { 3014 onComplete() { 3015 if ($el.data("append")) { 3016 if (self.options.appendWrapper) { 3017 const appendWrapper = $(self.options.appendWrapper); 3018 3019 appendWrapper.append($el.data("append")); 3020 3021 $el.html($el.html() + appendWrapper[0].outerHTML); 3022 } else { 3023 $el.html($el.html() + $el.data("append")); 3024 } 3025 } 3026 3027 if ($el.data("prepend")) { 3028 if (self.options.prependWrapper) { 3029 const prependWrapper = $(self.options.prependWrapper); 3030 3031 prependWrapper.append($el.data("prepend")); 3032 3033 $el.html($el.html() + prependWrapper[0].outerHTML); 3034 } else { 3035 $el.html($el.data("prepend") + $el.html()); 3036 } 3037 } 3038 }, 3039 }); 3040 3041 $el.countTo(self.options); 3042 3043 return this; 3044 } 3045 } 3046 3047 PluginCounter.defaults = { 3048 accX: 0, 3049 accY: 0, 3050 appendWrapper: false, 3051 prependWrapper: false, 3052 speed: 3000, 3053 refreshInterval: 100, 3054 decimals: 0, 3055 comma: false, 3056 onUpdate: null, 3057 onComplete: null, 3058 }; 3059 3060 // expose to scope 3061 $.extend(theme, { 3062 PluginCounter, 3063 }); 3064 3065 // jquery plugin 3066 $.fn.themePluginCounter = function (opts) { 3067 return this.map(function () { 3068 const $this = $(this); 3069 3070 if ($this.data(instanceName)) { 3071 return $this.data(instanceName); 3072 } else { 3073 return new PluginCounter($this, opts); 3074 } 3075 }); 3076 }; 3077}).apply(this, [window.theme, jQuery]); 3078 3079// CursorEffect 3080((theme = {}, $) => { 3081 const instanceName = "__cursorEffect"; 3082 3083 class PluginCursorEffect { 3084 constructor($el, opts) { 3085 return this.initialize($el, opts); 3086 } 3087 3088 initialize($el, opts) { 3089 if ($el.data(instanceName)) { 3090 return this; 3091 } 3092 3093 this.$el = $el; 3094 3095 this.setData().setOptions(opts).build().events(); 3096 3097 return this; 3098 } 3099 3100 setData() { 3101 this.$el.data(instanceName, this); 3102 3103 return this; 3104 } 3105 3106 setOptions(opts) { 3107 this.options = $.extend(true, {}, PluginCursorEffect.defaults, opts, { 3108 wrapper: this.$el, 3109 }); 3110 3111 return this; 3112 } 3113 3114 build() { 3115 const self = this; 3116 3117 // Global Variables for cursor position 3118 self.clientX = -100; 3119 self.clientY = -100; 3120 3121 // Hide Mouse Cursor 3122 if (self.options.hideMouseCursor) { 3123 self.$el.addClass("hide-mouse-cursor"); 3124 } 3125 3126 // Creates the cursor wrapper node 3127 const cursorOuter = document.createElement("DIV"); 3128 cursorOuter.className = "cursor-outer"; 3129 3130 // Creates the cursor inner node 3131 const cursorInner = document.createElement("DIV"); 3132 cursorInner.className = "cursor-inner"; 3133 3134 // Custom Cursor Outer Color 3135 if (self.options.cursorOuterColor) { 3136 cursorOuter.style = 3137 "border-color: " + self.options.cursorOuterColor + ";"; 3138 } 3139 3140 // Custom Cursor Inner Color 3141 if (self.options.cursorInnerColor) { 3142 cursorInner.style = 3143 "background-color: " + self.options.cursorInnerColor + ";"; 3144 } 3145 3146 // Size 3147 if (self.options.size) { 3148 switch (self.options.size) { 3149 case "small": 3150 self.$el.addClass("cursor-effect-size-small"); 3151 break; 3152 3153 case "big": 3154 self.$el.addClass("cursor-effect-size-big"); 3155 break; 3156 } 3157 } 3158 3159 // Style 3160 if (self.options.style) { 3161 self.$el.addClass(self.options.style); 3162 } 3163 3164 // Prepend cursor wrapper node to the body 3165 document.body.prepend(cursorOuter); 3166 3167 // Prepend cursor inner node to the body 3168 document.body.prepend(cursorInner); 3169 3170 // Loop for render 3171 const render = () => { 3172 cursorOuter.style.transform = 3173 "translate(" + self.clientX + "px, " + self.clientY + "px)"; 3174 cursorInner.style.transform = 3175 "translate(" + self.clientX + "px, " + self.clientY + "px)"; 3176 3177 self.loopInside = requestAnimationFrame(render); 3178 }; 3179 self.loop = requestAnimationFrame(render); 3180 3181 return this; 3182 } 3183 3184 events() { 3185 const self = this, 3186 $cursorOuter = $(".cursor-outer"), 3187 $cursorInner = $(".cursor-inner"); 3188
3189 const initialCursorOuterBox = $cursorOuter[0].getBoundingClientRect(), 3190 initialCursorOuterRadius = $cursorOuter.css("border-radius"); 3191 3192 // Update Cursor Position 3193 document.addEventListener("mousemove", ({ clientX, clientY }) => { 3194 if (!self.isStuck) { 3195 self.clientX = clientX - 20; 3196 self.clientY = clientY - 20; 3197 } 3198 3199 $cursorOuter.removeClass("opacity-0"); 3200 }); 3201 3202 self.isStuck = false; 3203 $("[data-cursor-effect-hover]").on("mouseenter", function (e) { 3204 // Identify Event With Hover Class 3205 $cursorOuter.addClass("cursor-outer-hover"); 3206 $cursorInner.addClass("cursor-inner-hover"); 3207 3208 // Hover Color 3209 const hoverColor = $(this).data("cursor-effect-hover-color"); 3210 $cursorOuter.addClass("cursor-color-" + hoverColor); 3211 $cursorInner.addClass("cursor-color-" + hoverColor); 3212 3213 // Effect Types 3214 switch ($(this).data("cursor-effect-hover")) { 3215 case "fit": 3216 const thisBox = $(this)[0].getBoundingClientRect(); 3217 3218 self.clientX = thisBox.x; 3219 self.clientY = thisBox.y; 3220 3221 $cursorOuter 3222 .css({ 3223 width: thisBox.width, 3224 height: thisBox.height, 3225 "border-radius": $(this).css("border-radius"), 3226 }) 3227 .addClass("cursor-outer-fit"); 3228 3229 $cursorInner.addClass("opacity-0"); 3230 3231 self.isStuck = true; 3232 break; 3233 3234 case "plus": 3235 $cursorInner.addClass("cursor-inner-plus"); 3236 break; 3237 } 3238 }); 3239 3240 $("[data-cursor-effect-hover]").on("mouseleave", function () { 3241 // Identify Event With Hover Class 3242 $cursorOuter.removeClass("cursor-outer-hover"); 3243 $cursorInner.removeClass("cursor-inner-hover"); 3244 3245 // Remove Color Class 3246 const hoverColor = $(this).data("cursor-effect-hover-color"); 3247 $cursorOuter.removeClass("cursor-color-" + hoverColor); 3248 $cursorInner.removeClass("cursor-color-" + hoverColor); 3249 3250 // Effect Types 3251 switch ($(this).data("cursor-effect-hover")) { 3252 case "fit": 3253 $cursorOuter 3254 .css({ 3255 width: initialCursorOuterBox.width, 3256 height: initialCursorOuterBox.height, 3257 "border-radius": initialCursorOuterRadius, 3258 }) 3259 .removeClass("cursor-outer-fit"); 3260 3261 $cursorInner.removeClass("opacity-0"); 3262 3263 self.isStuck = false; 3264 break; 3265 3266 case "plus": 3267 $cursorInner.removeClass("cursor-inner-plus"); 3268 break; 3269 } 3270 }); 3271 3272 $(window).on("scroll", () => { 3273 if ($cursorOuter.hasClass("cursor-outer-fit")) { 3274 $cursorOuter.addClass("opacity-0").removeClass("cursor-outer-fit"); 3275 } 3276 }); 3277 3278 return this; 3279 } 3280 3281 destroy() { 3282 const self = this; 3283 3284 self.$el.removeClass( 3285 "hide-mouse-cursor cursor-effect-size-small cursor-effect-size-big cursor-effect-style-square" 3286 ); 3287 3288 cancelAnimationFrame(self.loop); 3289 cancelAnimationFrame(self.loopInside); 3290 3291 document.querySelector(".cursor-outer").remove(); 3292 document.querySelector(".cursor-inner").remove(); 3293 3294 self.$el.removeData(instanceName, self); 3295 } 3296 } 3297 3298 PluginCursorEffect.defaults = {}; 3299 3300 // expose to scope 3301 $.extend(theme, { 3302 PluginCursorEffect, 3303 }); 3304 3305 // jquery plugin 3306 $.fn.themePluginCursorEffect = function (opts) { 3307 return this.map(function () { 3308 const $this = $(this); 3309 3310 if ($this.data(instanceName)) { 3311 return $this.data(instanceName); 3312 } else { 3313 return new PluginCursorEffect($this, opts); 3314 } 3315 }); 3316 }; 3317}).apply(this, [window.theme, jQuery]); 3318 3319// Float Element 3320((theme = {}, $) => { 3321 const instanceName = "__floatElement"; 3322 3323 class PluginFloatElement { 3324 constructor($el, opts) { 3325 return this.initialize($el, opts); 3326 } 3327 3328 initialize($el, opts) { 3329 if ($el.data(instanceName)) { 3330 return this; 3331 } 3332 3333 this.$el = $el; 3334 3335 this.setData().setOptions(opts).build(); 3336 3337 return this; 3338 } 3339 3340 setData() { 3341 this.$el.data(instanceName, this); 3342 3343 return this; 3344 } 3345 3346 setOptions(opts) { 3347 this.options = $.extend(true, {}, PluginFloatElement.defaults, opts, { 3348 wrapper: this.$el, 3349 }); 3350 3351 return this; 3352 } 3353 3354 build() { 3355 const self = this; 3356 const $el = this.options.wrapper; 3357 const $window = $(window); 3358 let minus; 3359 3360 // If has floating elements inside a SVG. 3361 // Intersection Observer API do not check elements inside SVG's, so we need initialize trough top parent SVG 3362 if ($el.data("plugin-float-element-svg")) { 3363 $el.find("[data-plugin-float-element]").each(function () { 3364 const $this = $(this); 3365 let opts; 3366 3367 const pluginOptions = theme.fn.getOptions( 3368 $this.data("plugin-options") 3369 ); 3370 if (pluginOptions) opts = pluginOptions; 3371 3372 $this.themePluginFloatElement(opts); 3373 }); 3374 3375 return this; 3376 } 3377 3378 if (self.options.style) { 3379 $el.attr("style", self.options.style); 3380 } 3381 3382 if ($window.width() > self.options.minWindowWidth) { 3383 // Set Start Position 3384 if (self.options.startPos == "none") { 3385 minus = ""; 3386 } else if (self.options.startPos == "top") { 3387 $el.css({ 3388 top: 0, 3389 }); 3390 minus = ""; 3391 } else { 3392 $el.css({ 3393 bottom: 0, 3394 }); 3395 minus = "-"; 3396 } 3397 3398 // Set Transition 3399 if (self.options.transition) { 3400 $el.css({ 3401 transition: 3402 "ease-out transform " + 3403 self.options.transitionDuration + 3404 "ms " + 3405 self.options.transitionDelay + 3406 "ms", 3407 }); 3408 } 3409 3410 // First Load 3411 self.movement(minus); 3412 3413 // Scroll 3414 $window.on("scroll", () => { 3415 self.movement(minus); 3416 }); 3417 } 3418 3419 return this; 3420 } 3421 3422 movement(minus) { 3423 const self = this, 3424 $el = this.options.wrapper, 3425 $window = $(window), 3426 scrollTop = $window.scrollTop(), 3427 elementOffset = $el.offset().top, 3428 currentElementOffset = elementOffset - scrollTop, 3429 factor = self.options.isInsideSVG ? 2 : 100; 3430 3431 const scrollPercent = (factor * currentElementOffset) / $window.height(); 3432 3433 if ($el.visible(true)) { 3434 if (!self.options.horizontal) { 3435 $el.css({ 3436 transform: 3437 "translate3d(0, " + 3438 minus + 3439 scrollPercent / self.options.speed + 3440 "%, 0)", 3441 }); 3442 } else { 3443 $el.css({ 3444 transform: 3445 "translate3d(" + 3446 minus + 3447 scrollPercent / self.options.speed + 3448 "%, 0, 0)", 3449 }); 3450 } 3451 } 3452 } 3453 } 3454 3455 PluginFloatElement.defaults = { 3456 startPos: "top", 3457 speed: 3, 3458 horizontal: false, 3459 isInsideSVG: false, 3460 transition: false, 3461 transitionDelay: 0, 3462 transitionDuration: 500, 3463 minWindowWidth: 991, 3464 }; 3465 3466 // expose to scope 3467 $.extend(theme, { 3468 PluginFloatElement, 3469 }); 3470 3471 // jquery plugin 3472 $.fn.themePluginFloatElement = function (opts) { 3473 return this.map(function () { 3474 const $this = $(this); 3475 3476 if ($this.data(instanceName)) { 3477 return $this.data(instanceName); 3478 } else { 3479 return new PluginFloatElement($this, opts); 3480 } 3481 });
3482 }; 3483}).apply(this, [window.theme, jQuery]); 3484 3485// GDPR 3486((theme = {}, $) => { 3487 const instanceName = "__gdpr"; 3488 3489 class PluginGDPR { 3490 constructor($el, opts) { 3491 return this.initialize($el, opts); 3492 } 3493 3494 initialize($el, opts) { 3495 const self = this; 3496 3497 this.$el = $el; 3498 3499 this.setData().setOptions(opts).build().events(); 3500 3501 return this; 3502 } 3503 3504 setData() { 3505 this.$el.data(instanceName, this); 3506 3507 return this; 3508 } 3509 3510 setOptions(opts) { 3511 this.options = $.extend(true, {}, PluginGDPR.defaults, opts, { 3512 wrapper: this.$el, 3513 }); 3514 3515 return this; 3516 } 3517 3518 build() { 3519 const self = this; 3520 3521 // Show 3522 if (!$.cookie("porto-privacy-bar")) { 3523 setTimeout(() => { 3524 self.options.wrapper.addClass("show"); 3525 }, self.options.cookieBarShowDelay); 3526 } 3527 3528 // If already has preferences cookie, check inputs according preferences cookie data 3529 if ($.cookie("porto-gdpr-preferences")) { 3530 const preferencesArr = $.cookie("porto-gdpr-preferences").split(","); 3531 3532 for (let i = 0; i < preferencesArr.length; i++) { 3533 if ($('input[value="' + preferencesArr[i] + '"]').get(0)) { 3534 if ($('input[value="' + preferencesArr[i] + '"]').is(":checkbox")) { 3535 $('input[value="' + preferencesArr[i] + '"]').prop( 3536 "checked", 3537 true 3538 ); 3539 } 3540 } 3541 } 3542 } 3543 3544 return this; 3545 } 3546 3547 events() { 3548 const self = this; 3549 3550 // Agree Trigger
3551 self.options.wrapper.find(".gdpr-agree-trigger").on("click", (e) => { 3552 e.preventDefault(); 3553 3554 $(".gdpr-preferences-form") 3555 .find(".gdpr-input") 3556 .each(function () { 3557 if ($(this).is(":checkbox") || $(this).is(":hidden")) { 3558 $(this).prop("checked", true); 3559 } 3560 }); 3561 3562 $(".gdpr-preferences-form").trigger("submit").removeClass("show"); 3563 3564 self.removeCookieBar(); 3565 }); 3566 3567 // Preferences Trigger 3568 self.options.wrapper 3569 .find(".gdpr-preferences-trigger") 3570 .on("click", (e) => { 3571 e.preventDefault(); 3572 3573 $(".gdpr-preferences-popup").addClass("show"); 3574 }); 3575 3576 // Close Popup Button 3577 $(".gdpr-close-popup").on("click", (e) => { 3578 e.preventDefault(); 3579 3580 $(".gdpr-preferences-popup").removeClass("show"); 3581 }); 3582 3583 // Close Popup When Click Outside of popup area 3584 $(".gdpr-preferences-popup").on("click", ({ target }) => { 3585 if (!$(target).closest(".gdpr-preferences-popup-content").get(0)) { 3586 $(".gdpr-preferences-popup").removeClass("show"); 3587 } 3588 }); 3589 3590 // Preference Form 3591 $(".gdpr-preferences-form").on("submit", function (e) { 3592 e.preventDefault(); 3593 3594 const $this = $(this); 3595 3596 // Save Preferences Button 3597 $this.find('button[type="submit"]').text("SAVING..."); 3598 3599 // Form Data 3600 const formData = []; 3601 $this.find(".gdpr-input").each(function () { 3602 if ( 3603 ($(this).is(":checkbox") && $(this).is(":checked")) || 3604 $(this).is(":hidden") 3605 ) { 3606 formData.push($(this).val()); 3607 } 3608 }); 3609 3610 $.cookie("porto-privacy-bar", true, { expires: self.options.expires }); 3611 3612 setTimeout(() => { 3613 $this 3614 .find('button[type="submit"]') 3615 .text("SAVED!") 3616 .removeClass("btn-primary") 3617 .addClass("btn-success"); 3618 3619 setTimeout(() => { 3620 $(".gdpr-preferences-popup").removeClass("show"); 3621 self.removeCookieBar(); 3622 3623 $this 3624 .find('button[type="submit"]') 3625 .text("SAVE PREFERENCES") 3626 .removeClass("btn-success") 3627 .addClass("btn-primary"); 3628 3629 if ($.cookie("porto-gdpr-preferences")) { 3630 $.cookie("porto-gdpr-preferences", formData, { 3631 expires: self.options.expires, 3632 }); 3633 location.reload(); 3634 } else { 3635 $.cookie("porto-gdpr-preferences", formData, { 3636 expires: self.options.expires, 3637 }); 3638 3639 if ( 3640 $.isFunction($.fn["themePluginGDPRWrapper"]) && 3641 $("[data-plugin-gdpr-wrapper]").length 3642 ) { 3643 $(() => { 3644 $("[data-plugin-gdpr-wrapper]:not(.manual)").each( 3645 function () { 3646 const $this = $(this); 3647 let opts; 3648 3649 $this.removeData("__gdprwrapper"); 3650 3651 const pluginOptions = theme.fn.getOptions( 3652 $this.data("plugin-options") 3653 ); 3654 if (pluginOptions) opts = pluginOptions; 3655 3656 $this.themePluginGDPRWrapper(opts); 3657 } 3658 ); 3659 }); 3660 } 3661 } 3662 }, 500); 3663 }, 1000); 3664 }); 3665 3666 // Remove/Reset Cookies
3667 $(".gdpr-reset-cookies").on("click", (e) => { 3668 e.preventDefault(); 3669 3670 self.clearCookies(); 3671 3672 location.reload(); 3673 }); 3674 3675 // Open Preferences 3676 $(".gdpr-open-preferences").on("click", (e) => { 3677 e.preventDefault(); 3678 3679 $(".gdpr-preferences-popup").toggleClass("show"); 3680 }); 3681 3682 return this; 3683 } 3684 3685 removeCookieBar() { 3686 const self = this; 3687 3688 self.options.wrapper.addClass("removing").on("transitionend", () => { 3689 setTimeout(() => { 3690 self.options.wrapper.removeClass("show removing"); 3691 }, 500); 3692 }); 3693 3694 return this; 3695 } 3696 3697 clearCookies() { 3698 const self = this; 3699 3700 $.removeCookie("porto-privacy-bar"); 3701 $.removeCookie("porto-gdpr-preferences"); 3702 3703 return this; 3704 } 3705 } 3706 3707 PluginGDPR.defaults = { 3708 cookieBarShowDelay: 3000, 3709 expires: 365, 3710 }; 3711 3712 // expose to scope 3713 $.extend(theme, { 3714 PluginGDPR, 3715 }); 3716 3717 // jquery plugin 3718 $.fn.themePluginGDPR = function (opts) { 3719 return this.map(function () { 3720 const $this = $(this); 3721 3722 if ($this.data(instanceName)) { 3723 return $this.data(instanceName); 3724 } else { 3725 return new PluginGDPR($this, opts); 3726 } 3727 }); 3728 }; 3729}).apply(this, [window.theme, jQuery]); 3730 3731// GDPR Wrapper 3732((theme = {}, $) => { 3733 const instanceName = "__gdprwrapper"; 3734 3735 class PluginGDPRWrapper { 3736 constructor($el, opts) { 3737 return this.initialize($el, opts); 3738 } 3739 3740 initialize($el, opts) { 3741 const self = this; 3742 3743 this.$el = $el; 3744 3745 this.setData().setOptions(opts).build(); 3746 3747 return this; 3748 } 3749 3750 setData() { 3751 this.$el.data(instanceName, this); 3752 3753 return this; 3754 } 3755 3756 setOptions(opts) { 3757 this.options = $.extend(true, {}, PluginGDPRWrapper.defaults, opts, { 3758 wrapper: this.$el, 3759 }); 3760 3761 return this; 3762 } 3763 3764 build() { 3765 const self = this; 3766 3767 if ( 3768 $.cookie("porto-gdpr-preferences") && 3769 $.cookie("porto-gdpr-preferences").includes(self.options.checkCookie) 3770 ) { 3771 $.ajax({
3772 url: self.options.ajaxURL, 3773 cache: false, 3774 complete({ responseText }) { 3775 setTimeout(() => { 3776 self.options.wrapper.html(responseText).addClass("show"); 3777 }, 1000); 3778 }, 3779 }); 3780 } else { 3781 self.options.wrapper.addClass("show"); 3782 } 3783 3784 return this; 3785 } 3786 } 3787 3788 PluginGDPRWrapper.defaults = {}; 3789 3790 // expose to scope 3791 $.extend(theme, { 3792 PluginGDPRWrapper, 3793 }); 3794 3795 // jquery plugin 3796 $.fn.themePluginGDPRWrapper = function (opts) { 3797 return this.map(function () { 3798 const $this = $(this); 3799 3800 if ($this.data(instanceName)) { 3801 return $this.data(instanceName); 3802 } else { 3803 return new PluginGDPRWrapper($this, opts); 3804 } 3805 }); 3806 }; 3807}).apply(this, [window.theme, jQuery]); 3808 3809// Hover Effect 3810((theme = {}, $) => { 3811 const instanceName = "__hoverEffect"; 3812 3813 class PluginHoverEffect { 3814 constructor($el, opts) { 3815 return this.initialize($el, opts); 3816 } 3817 3818 initialize($el, opts) { 3819 if ($el.data(instanceName)) { 3820 return this; 3821 } 3822 3823 this.$el = $el; 3824 3825 this.setData().setOptions(opts).build(); 3826 3827 return this; 3828 } 3829 3830 setData() { 3831 this.$el.data(instanceName, this); 3832 3833 return this; 3834 } 3835 3836 setOptions(opts) { 3837 this.options = $.extend(true, {}, PluginHoverEffect.defaults, opts, { 3838 wrapper: this.$el, 3839 }); 3840 3841 return this; 3842 } 3843 3844 build() { 3845 const self = this; 3846 3847 if (self.$el.hasClass("hover-effect-3d")) { 3848 self.options.effect = "3d"; 3849 } 3850 3851 // Magnetic 3852 if (self.options.effect == "magnetic") { 3853 self.magnetic(); 3854 } 3855 3856 // 3d 3857 if (self.options.effect == "3d") { 3858 self.hover3d(); 3859 } 3860 3861 return this; 3862 } 3863 3864 magnetic() { 3865 const self = this; 3866 3867 self.$el.mousemove(function ({ clientX, clientY }) { 3868 const pos = this.getBoundingClientRect(); 3869 const mx = clientX - pos.left - pos.width / 2; 3870 const my = clientY - pos.top - pos.height / 2; 3871 3872 this.style.transform = 3873 "translate(" + 3874 mx * self.options.magneticMx + 3875 "px, " + 3876 my * self.options.magneticMx + 3877 "px)"; 3878 }); 3879 3880 self.$el.mouseleave(function (e) { 3881 this.style.transform = "translate3d(0px, 0px, 0px)"; 3882 }); 3883 3884 return this; 3885 } 3886 3887 hover3d() { 3888 const self = this; 3889 3890 if ($.isFunction($.fn["hover3d"])) { 3891 self.$el.hover3d({ 3892 selector: self.options.selector, 3893 sensitivity: self.options.sensitivity, 3894 }); 3895 } 3896 3897 return this; 3898 } 3899 } 3900 3901 PluginHoverEffect.defaults = { 3902 effect: "magnetic", 3903 magneticMx: 0.15, 3904 magneticMy: 0.3, 3905 magneticDeg: 12, 3906 selector: ".thumb-info, .hover-effect-3d-wrapper", 3907 sensitivity: 20, 3908 }; 3909 3910 // expose to scope 3911 $.extend(theme, { 3912 PluginHoverEffect, 3913 }); 3914 3915 // jquery plugin 3916 $.fn.themePluginHoverEffect = function (opts) { 3917 return this.map(function () { 3918 const $this = $(this); 3919 3920 if ($this.data(instanceName)) { 3921 return $this.data(instanceName); 3922 } else { 3923 return new PluginHoverEffect($this, opts); 3924 } 3925 }); 3926 }; 3927}).apply(this, [window.theme, jQuery]); 3928 3929// Icon 3930((theme = {}, $) => { 3931 const instanceName = "__icon"; 3932 3933 class PluginIcon { 3934 constructor($el, opts) { 3935 return this.initialize($el, opts); 3936 } 3937 3938 initialize($el, opts) { 3939 if ($el.data(instanceName)) { 3940 return this; 3941 } 3942 3943 this.$el = $el; 3944 3945 this.setData().setOptions(opts).build(); 3946 3947 return this; 3948 } 3949 3950 setData() { 3951 this.$el.data(instanceName, this); 3952 3953 return this; 3954 } 3955 3956 setOptions(opts) { 3957 this.options = $.extend(true, {}, PluginIcon.defaults, opts, { 3958 wrapper: this.$el, 3959 }); 3960 3961 return this; 3962 } 3963 3964 build() { 3965 const self = this; 3966 let $el = this.options.wrapper; 3967 const color = self.options.color; 3968 const elTopDistance = $el.offset().top; 3969 const windowTopDistance = $(window).scrollTop(); 3970 let duration = 3971 self.options.animated && !self.options.strokeBased ? 200 : 100; 3972 3973 // Check origin 3974 if (window.location.protocol === "file:") { 3975 $el.css({ 3976 opacity: 1, 3977 width: $el.attr("width"), 3978 }); 3979 3980 if (self.options.extraClass) { 3981 $el.addClass(self.options.extraClass); 3982 } 3983 3984 if (self.options.extraClass.indexOf("-color-light") > 0) { 3985 $el.css({ 3986 filter: "invert(1)", 3987 }); 3988 } 3989 3990 $(window).trigger("icon.rendered"); 3991 return; 3992 } 3993 3994 // Duration 3995 if (self.options.duration) { 3996 duration = self.options.duration; 3997 } 3998 3999 // SVG Content
4000 const SVGContent = $.get({ 4001 url: $el.attr("src"), 4002 success(data, status, { responseText }) { 4003 const iconWrapper = self.options.fadeIn 4004 ? $( 4005 '<div class="animated-icon animated fadeIn">' + 4006 responseText + 4007 "</div>" 4008 ) 4009 : $( 4010 '<div class="animated-icon animated">' + 4011 responseText + 4012 "</div>" 4013 ), 4014 uniqid = "icon_" + Math.floor(Math.random() * 26) + Date.now(); 4015 4016 // Add ID 4017 iconWrapper.find("svg").attr("id", uniqid); 4018 4019 // Identify with filename 4020 iconWrapper.find("svg").attr( 4021 "data-filename", 4022 $el 4023 .attr("src") 4024 .split(/(\\|\/)/g) 4025 .pop() 4026 ); 4027 4028 if ($el.attr("width")) { 4029 iconWrapper 4030 .find("svg") 4031 .attr("width", $el.attr("width")) 4032 .attr("height", $el.attr("width")); 4033 } 4034 4035 if ($el.attr("height")) { 4036 iconWrapper.find("svg").attr("height", $el.attr("height")); 4037 } 4038 4039 if (self.options.svgViewBox) { 4040 iconWrapper.find("svg").attr("viewBox", self.options.svgViewBox); 4041 } 4042 4043 $el.replaceWith(iconWrapper); 4044 4045 if (self.options.extraClass) { 4046 iconWrapper.addClass(self.options.extraClass); 4047 } 4048 4049 if (self.options.removeClassAfterInit) { 4050 iconWrapper.removeClass(self.options.removeClassAfterInit); 4051 } 4052 4053 if (self.options.onlySVG) { 4054 $(window).trigger("icon.rendered"); 4055 return this; 4056 } 4057 4058 $el = iconWrapper; 4059 4060 const icon = new Vivus(uniqid, { 4061 start: "manual", 4062 type: "sync", 4063 selfDestroy: true, 4064 duration, 4065 onReady({ el }) { 4066 const styleElement = document.createElementNS( 4067 "http://www.w3.org/2000/svg", 4068 "style" 4069 ); 4070 let animateStyle = ""; 4071 4072 // SVG Fill Based 4073 if ( 4074 (self.options.animated && !self.options.strokeBased) || 4075 (!self.options.animated && color && !self.options.strokeBased) 4076 ) { 4077 animateStyle = 4078 "stroke-width: 0.1px; fill-opacity: 0; transition: ease fill-opacity 300ms;"; 4079 4080 // Set Style on SVG inside object 4081 styleElement.textContent = 4082 "#" + 4083 uniqid + 4084 " path, #" + 4085 uniqid + 4086 " line, #" + 4087 uniqid + 4088 " rect, #" + 4089 uniqid + 4090 " circle, #" + 4091 uniqid + 4092 " polyline { fill: " + 4093 color + 4094 "; stroke: " + 4095 color + 4096 "; " + 4097 animateStyle + 4098 (self.options.svgStyle ? self.options.svgStyle : "") + 4099 " } .finished path { fill-opacity: 1; }"; 4100 el.appendChild(styleElement); 4101 } 4102 4103 // SVG Stroke Based 4104 if ( 4105 (self.options.animated && self.options.strokeBased) || 4106 (!self.options.animated && color && self.options.strokeBased) 4107 ) { 4108 // Set Style on SVG inside object 4109 styleElement.textContent = 4110 "#" + 4111 uniqid + 4112 " path, #" + 4113 uniqid + 4114 " line, #" + 4115 uniqid + 4116 " rect, #" + 4117 uniqid + 4118 " circle, #" + 4119 uniqid + 4120 " polyline { stroke: " + 4121 color + 4122 "; " + 4123 (self.options.svgStyle ? self.options.svgStyle : "") + 4124 "}"; 4125 el.appendChild(styleElement); 4126 } 4127 4128 $.event.trigger("theme.plugin.icon.svg.ready"); 4129 }, 4130 }); 4131 4132 // Isn't animated 4133 if (!self.options.animated) { 4134 setTimeout(() => { 4135 icon.finish(); 4136 }, 10); 4137 $el.css({ opacity: 1 }); 4138 } 4139 4140 // Animated 4141 if (self.options.animated && $(window).width() > 767) { 4142 // First Load 4143 if ($el.visible(true)) { 4144 self.startIconAnimation(icon, $el); 4145 } else if (elTopDistance < windowTopDistance) { 4146 self.startIconAnimation(icon, $el); 4147 } 4148 4149 // On Scroll 4150 $(window).on("scroll", () => { 4151 if ($el.visible(true)) { 4152 self.startIconAnimation(icon, $el); 4153 } 4154 }); 4155 } else { 4156 $el.css({ opacity: 1 }); 4157 icon.finish(); 4158 4159 $(window).on("theme.plugin.icon.svg.ready", () => { 4160 setTimeout(() => { 4161 icon.el.setAttribute("class", "finished"); 4162 icon.finish(); 4163 }, 300); 4164 }); 4165 } 4166 4167 $(window).trigger("icon.rendered"); 4168 }, 4169 }); 4170 4171 return this; 4172 } 4173 4174 startIconAnimation(icon, $el) { 4175 const self = this; 4176 4177 // Animate for better performance 4178 $({ to: 0 }).animate( 4179 { to: 1 }, 4180 self.options.strokeBased 4181 ? self.options.delay 4182 : self.options.delay + 300, 4183 () => { 4184 $el.css({ opacity: 1 }); 4185 } 4186 ); 4187 4188 $({ to: 0 }).animate({ to: 1 }, self.options.delay, () => { 4189 icon.play(1); 4190 4191 setTimeout(() => { 4192 icon.el.setAttribute("class", "finished"); 4193 }, icon.duration * 5); 4194 }); 4195 } 4196 } 4197 4198 PluginIcon.defaults = { 4199 color: "#2388ED", 4200 animated: false, 4201 delay: 300, 4202 onlySVG: false, 4203 removeClassAfterInit: false, 4204 fadeIn: true, 4205 accY: 0, 4206 }; 4207 4208 // expose to scope 4209 $.extend(theme, { 4210 PluginIcon, 4211 }); 4212 4213 // jquery plugin 4214 $.fn.themePluginIcon = function (opts) { 4215 return this.map(function () { 4216 const $this = $(this); 4217 4218 if ($this.data(instanceName)) { 4219 return $this.data(instanceName); 4220 } else { 4221 return new PluginIcon($this, opts); 4222 } 4223 });
4224 }; 4225}).apply(this, [window.theme, jQuery]); 4226 4227// In Viewport Style 4228((theme = {}, $) => { 4229 const instanceName = "__inviewportstyle"; 4230 4231 class PluginInViewportStyle { 4232 constructor($el, opts) { 4233 return this.initialize($el, opts); 4234 } 4235 4236 initialize($el, opts) { 4237 if ($el.data(instanceName)) { 4238 return this; 4239 } 4240 4241 this.$el = $el; 4242 4243 this.setData().setOptions(opts).build(); 4244 4245 return this; 4246 } 4247 4248 setData() { 4249 this.$el.data(instanceName, this); 4250 4251 return this; 4252 } 4253 4254 setOptions(opts) { 4255 this.options = $.extend( 4256 true, 4257 {}, 4258 PluginInViewportStyle.defaults, 4259 opts, 4260 {} 4261 ); 4262 4263 return this; 4264 } 4265 4266 build() { 4267 const self = this, 4268 el = self.$el.get(0); 4269 4270 self.$el.css(self.options.style); 4271 4272 if (typeof window.IntersectionObserver === "function") { 4273 const un = observeElementInViewport.observeElementInViewport( 4274 el, 4275 () => { 4276 self.$el.css(self.options.styleIn); 4277 self.$el 4278 .addClass(self.options.classIn) 4279 .removeClass(self.options.classOut); 4280 }, 4281 () => { 4282 self.$el.css(self.options.styleOut); 4283 self.$el 4284 .addClass(self.options.classOut) 4285 .removeClass(self.options.classIn); 4286 }, 4287 { 4288 viewport: self.options.viewport, 4289 threshold: self.options.threshold, 4290 modTop: self.options.modTop, 4291 modBottom: self.options.modBottom, 4292 } 4293 ); 4294 } 4295 4296 return this; 4297 } 4298 } 4299 4300 PluginInViewportStyle.defaults = { 4301 viewport: window, 4302 threshold: [0], 4303 modTop: "-200px", 4304 modBottom: "-200px", 4305 style: { transition: "all 1s ease-in-out" }, 4306 styleIn: "", 4307 styleOut: "", 4308 classIn: "", 4309 classOut: "", 4310 }; 4311 4312 // expose to scope 4313 $.extend(theme, { 4314 PluginInViewportStyle, 4315 }); 4316 4317 // jquery plugin 4318 $.fn.themePluginInViewportStyle = function (opts) { 4319 return this.map(function () { 4320 const $this = $(this); 4321 4322 if ($this.data(instanceName)) { 4323 return $this.data(instanceName); 4324 } else { 4325 return new PluginInViewportStyle($this, opts); 4326 } 4327 }); 4328 }; 4329}).apply(this, [window.theme, jQuery]); 4330 4331// Lightbox 4332((theme = {}, $) => { 4333 const instanceName = "__lightbox"; 4334 4335 class PluginLightbox { 4336 constructor($el, opts) { 4337 return this.initialize($el, opts); 4338 } 4339 4340 initialize($el, opts) { 4341 if ($el.data(instanceName)) { 4342 return this; 4343 } 4344 4345 this.$el = $el; 4346 4347 this.setData().setOptions(opts).build(); 4348 4349 return this; 4350 } 4351 4352 setData() { 4353 this.$el.data(instanceName, this); 4354 4355 return this; 4356 } 4357 4358 setOptions(opts) { 4359 this.options = $.extend(true, {}, PluginLightbox.defaults, opts, { 4360 wrapper: this.$el, 4361 }); 4362 4363 return this; 4364 } 4365 4366 build() { 4367 if (!$.isFunction($.fn.magnificPopup)) { 4368 return this; 4369 } 4370 4371 this.options.wrapper.magnificPopup(this.options); 4372 4373 return this; 4374 } 4375 } 4376 4377 PluginLightbox.defaults = { 4378 tClose: "Close (Esc)", // Alt text on close button 4379 tLoading: "Loading...", // Text that is displayed during loading. Can contain %curr% and %total% keys 4380 gallery: { 4381 tPrev: "Previous (Left arrow key)", // Alt text on left arrow 4382 tNext: "Next (Right arrow key)", // Alt text on right arrow 4383 tCounter: "%curr% of %total%", // Markup for "1 of 7" counter 4384 }, 4385 image: { 4386 tError: '<a href="%url%">The image</a> could not be loaded.', // Error message when image could not be loaded 4387 }, 4388 ajax: { 4389 tError: '<a href="%url%">The content</a> could not be loaded.', // Error message when ajax request failed 4390 }, 4391 callbacks: { 4392 open() { 4393 $("html").addClass("lightbox-opened"); 4394 }, 4395 close() { 4396 $("html").removeClass("lightbox-opened"); 4397 }, 4398 }, 4399 }; 4400 4401 // expose to scope 4402 $.extend(theme, { 4403 PluginLightbox, 4404 }); 4405 4406 // jquery plugin 4407 $.fn.themePluginLightbox = function (opts) { 4408 return this.map(function () { 4409 const $this = $(this); 4410 4411 if ($this.data(instanceName)) { 4412 return $this.data(instanceName); 4413 } else { 4414 return new PluginLightbox($this, opts); 4415 } 4416 });
4417 }; 4418}).apply(this, [window.theme, jQuery]); 4419 4420// Loading Overlay 4421((theme = {}, $) => { 4422 // Default 4423 const loadingOverlayDefaultTemplate = [ 4424 '<div class="loading-overlay">', 4425 '<div class="bounce-loader"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>', 4426 "</div>", 4427 ].join(""); 4428 4429 // Percentage 4430 const loadingOverlayPercentageTemplate = [ 4431 '<div class="loading-overlay loading-overlay-percentage">', 4432 '<div class="page-loader-progress-wrapper"><span class="page-loader-progress">0</span><span class="page-loader-progress-symbol">%</span></div>', 4433 "</div>", 4434 ].join(""); 4435 4436 // Cubes 4437 const loadingOverlayCubesTemplate = [ 4438 '<div class="loading-overlay">', 4439 '<div class="bounce-loader"><div class="cssload-thecube"><div class="cssload-cube cssload-c1"></div><div class="cssload-cube cssload-c2"></div><div class="cssload-cube cssload-c4"></div><div class="cssload-cube cssload-c3"></div></div></div>', 4440 "</div>", 4441 ].join(""); 4442 4443 // Cube Progress 4444 const loadingOverlayCubeProgressTemplate = [ 4445 '<div class="loading-overlay">', 4446 '<div class="bounce-loader"><span class="cssload-cube-progress"><span class="cssload-cube-progress-inner"></span></span></div>', 4447 "</div>", 4448 ].join(""); 4449 4450 // Float Rings 4451 const loadingOverlayFloatRingsTemplate = [ 4452 '<div class="loading-overlay">', 4453 '<div class="bounce-loader"><div class="cssload-float-rings-loader"><div class="cssload-float-rings-inner cssload-one"></div><div class="cssload-float-rings-inner cssload-two"></div><div class="cssload-float-rings-inner cssload-three"></div></div></div>', 4454 "</div>", 4455 ].join(""); 4456 4457 // Floating Bars 4458 const loadingOverlayFloatBarsTemplate = [ 4459 '<div class="loading-overlay">', 4460 '<div class="bounce-loader"><div class="cssload-float-bars-container"><ul class="cssload-float-bars-flex-container"><li><span class="cssload-float-bars-loading"></span></li></div></div></div>', 4461 "</div>", 4462 ].join(""); 4463 4464 // Speeding Wheel 4465 const loadingOverlaySpeedingWheelTemplate = [ 4466 '<div class="loading-overlay">', 4467 '<div class="bounce-loader"><div class="cssload-speeding-wheel-container"><div class="cssload-speeding-wheel"></div></div></div>', 4468 "</div>", 4469 ].join(""); 4470 4471 // Zenith 4472 const loadingOverlayZenithTemplate = [ 4473 '<div class="loading-overlay">', 4474 '<div class="bounce-loader"><div class="cssload-zenith-container"><div class="cssload-zenith"></div></div></div>', 4475 "</div>", 4476 ].join(""); 4477 4478 // Spinning Square 4479 const loadingOverlaySpinningSquareTemplate = [ 4480 '<div class="loading-overlay">', 4481 '<div class="bounce-loader"><div class="cssload-spinning-square-loading"></div></div>', 4482 "</div>", 4483 ].join(""); 4484 4485 // Pulse 4486 const loadingOverlayPulseTemplate = [ 4487 '<div class="loading-overlay">', 4488 '<div class="bounce-loader"><div class="wrapper-pulse"><div class="cssload-pulse-loader"></div></div></div>', 4489 "</div>", 4490 ].join(""); 4491 4492 const LoadingOverlay = function ($wrapper, options, noInheritOptions) { 4493 return this.initialize($wrapper, options, noInheritOptions); 4494 }; 4495 4496 LoadingOverlay.prototype = { 4497 options: { 4498 css: {}, 4499 hideDelay: 500, 4500 progressMinTimeout: 0, 4501 effect: "default", 4502 }, 4503 4504 initialize($wrapper, options, noInheritOptions) { 4505 this.$wrapper = $wrapper; 4506 4507 this.setVars() 4508 .setOptions(options, noInheritOptions) 4509 .build() 4510 .events() 4511 .dynamicShowHideEvents(); 4512 4513 this.$wrapper.data("loadingOverlay", this); 4514 }, 4515 4516 setVars() { 4517 this.$overlay = this.$wrapper.find(".loading-overlay"); 4518 this.pageStatus = null; 4519 this.progress = null; 4520 this.animationInterval = 33; 4521 4522 return this; 4523 }, 4524 4525 setOptions(options, noInheritOptions) { 4526 if (!this.$overlay.get(0)) { 4527 this.matchProperties(); 4528 } 4529 4530 if (noInheritOptions) { 4531 this.options = $.extend(true, {}, this.options, options); 4532 } else { 4533 this.options = $.extend( 4534 true, 4535 {}, 4536 this.options, 4537 options, 4538 theme.fn.getOptions(this.$wrapper.data("plugin-options")) 4539 ); 4540 } 4541 4542 this.loaderClass = this.getLoaderClass(this.options.css.backgroundColor); 4543 4544 return this; 4545 }, 4546 4547 build() { 4548 const _self = this; 4549 4550 if (!this.$overlay.closest(document.documentElement).get(0)) { 4551 if (!this.$cachedOverlay) { 4552 switch (_self.options.effect) { 4553 case "percentageProgress1":
4554 this.$overlay = $(loadingOverlayPercentageTemplate).clone(); 4555 break; 4556 4557 case "percentageProgress2": 4558 this.$overlay = $(loadingOverlayPercentageTemplate).clone(); 4559 this.$overlay 4560 .addClass("loading-overlay-percentage-effect-2") 4561 .prepend( 4562 '<div class="loading-overlay-background-layer"></div>' 4563 ); 4564 break; 4565 4566 case "cubes": 4567 this.$overlay = $(loadingOverlayCubesTemplate).clone(); 4568 break; 4569 4570 case "cubeProgress": 4571 this.$overlay = $(loadingOverlayCubeProgressTemplate).clone(); 4572 break; 4573 4574 case "floatRings": 4575 this.$overlay = $(loadingOverlayFloatRingsTemplate).clone(); 4576 break; 4577 4578 case "floatBars": 4579 this.$overlay = $(loadingOverlayFloatBarsTemplate).clone(); 4580 break; 4581 4582 case "speedingWheel": 4583 this.$overlay = $(loadingOverlaySpeedingWheelTemplate).clone(); 4584 break; 4585 4586 case "zenith": 4587 this.$overlay = $(loadingOverlayZenithTemplate).clone(); 4588 break; 4589 4590 case "spinningSquare": 4591 this.$overlay = $(loadingOverlaySpinningSquareTemplate).clone(); 4592 break; 4593 4594 case "pulse": 4595 this.$overlay = $(loadingOverlayPulseTemplate).clone(); 4596 break; 4597 4598 case "default": 4599 default: 4600 this.$overlay = $(loadingOverlayDefaultTemplate).clone(); 4601 break; 4602 } 4603 4604 if (this.options.css) { 4605 this.$overlay.css(this.options.css); 4606 this.$overlay.find(".loader").addClass(this.loaderClass); 4607 } 4608 } else { 4609 this.$overlay = this.$cachedOverlay.clone(); 4610 } 4611 4612 this.$wrapper.prepend(this.$overlay); 4613 } 4614 4615 if (!this.$cachedOverlay) { 4616 this.$cachedOverlay = this.$overlay.clone(); 4617 } 4618 4619 if ( 4620 ["percentageProgress1", "percentageProgress2"].includes( 4621 _self.options.effect 4622 ) 4623 ) { 4624 _self.updateProgress(); 4625 4626 if (_self.options.isDynamicHideShow) { 4627 setTimeout(() => { 4628 _self.progress = "complete"; 4629 4630 $(".page-loader-progress").text(100); 4631 4632 if (["percentageProgress2"].includes(_self.options.effect)) { 4633 $(".loading-overlay-background-layer").css({ 4634 width: "100%", 4635 }); 4636 } 4637 }, 2800); 4638 } 4639 } 4640 4641 return this; 4642 }, 4643 4644 events() { 4645 const _self = this; 4646 4647 if (this.options.startShowing) { 4648 _self.show(); 4649 } 4650 4651 if (this.$wrapper.is("body") || this.options.hideOnWindowLoad) { 4652 $(window).on("load error", () => { 4653 setTimeout(() => { 4654 _self.hide(); 4655 }, _self.options.progressMinTimeout); 4656 }); 4657 } 4658 4659 if (this.options.listenOn) { 4660 $(this.options.listenOn) 4661 .on("loading-overlay:show beforeSend.ic", (e) => { 4662 e.stopPropagation(); 4663 _self.show(); 4664 }) 4665 .on("loading-overlay:hide complete.ic", (e) => { 4666 e.stopPropagation(); 4667 _self.hide(); 4668 }); 4669 } 4670 4671 this.$wrapper 4672 .on("loading-overlay:show beforeSend.ic", (e) => { 4673 if (e.target === _self.$wrapper.get(0)) { 4674 e.stopPropagation(); 4675 _self.show(); 4676 return true; 4677 } 4678 return false; 4679 }) 4680 .on("loading-overlay:hide complete.ic", (e) => { 4681 if (e.target === _self.$wrapper.get(0)) { 4682 e.stopPropagation(); 4683 _self.hide(); 4684 return true; 4685 } 4686 return false; 4687 }); 4688 4689 if ( 4690 ["percentageProgress1", "percentageProgress2"].includes( 4691 _self.options.effect 4692 ) 4693 ) { 4694 $(window).on("load", () => { 4695 setTimeout(() => { 4696 _self.pageStatus = "complete"; 4697 4698 $(".page-loader-progress").text(100); 4699 4700 if (["percentageProgress2"].includes(_self.options.effect)) { 4701 $(".loading-overlay-background-layer").css({ 4702 width: "100%", 4703 }); 4704 } 4705 }, _self.options.progressMinTimeout); 4706 }); 4707 } 4708 4709 return this; 4710 }, 4711 4712 show() { 4713 this.build(); 4714 4715 this.position = this.$wrapper.css("position").toLowerCase(); 4716 if ( 4717 this.position != "relative" || 4718 this.position != "absolute" || 4719 this.position != "fixed" 4720 ) { 4721 this.$wrapper.css({ 4722 position: "relative", 4723 }); 4724 } 4725 this.$wrapper.addClass("loading-overlay-showing"); 4726 }, 4727 4728 hide() { 4729 const _self = this; 4730 4731 setTimeout(function () { 4732 _self.$wrapper.removeClass("loading-overlay-showing"); 4733 4734 if ( 4735 this.position != "relative" || 4736 this.position != "absolute" || 4737 this.position != "fixed" 4738 ) { 4739 _self.$wrapper.css({ position: "" }); 4740 } 4741 4742 $(window).trigger("loading.overlay.ready"); 4743 }, _self.options.hideDelay); 4744 }, 4745 4746 updateProgress() { 4747 const _self = this; 4748 4749 const render = () => { 4750 if (_self.pageStatus == "complete") { 4751 $(".page-loader-progress").text(100); 4752 setTimeout(() => { 4753 $(".page-loader-progress").addClass("d-none"); 4754 }, 700); 4755 } else { 4756 if (_self.progress == null) { 4757 _self.progress = 1; 4758 } 4759 4760 _self.progress = _self.progress + 1; 4761 if (_self.progress >= 0 && _self.progress <= 30) { 4762 _self.animationInterval += 1; 4763 $(".page-loader-progress").text(_self.progress); 4764 } else if (_self.progress > 30 && _self.progress <= 60) { 4765 _self.animationInterval += 2; 4766 $(".page-loader-progress").text(_self.progress); 4767 } else if (_self.progress > 60 && _self.progress <= 80) { 4768 _self.animationInterval += 40; 4769 $(".page-loader-progress").text(_self.progress); 4770 } else if (_self.progress > 80 && _self.progress <= 90) { 4771 _self.animationInterval += 80; 4772 $(".page-loader-progress").text(_self.progress); 4773 } else if (_self.progress > 90 && _self.progress <= 95) { 4774 _self.animationInterval += 150; 4775 $(".page-loader-progress").text(_self.progress); 4776 } else if (_self.progress > 95 && _self.progress <= 99) { 4777 _self.animationInterval += 400; 4778 $(".page-loader-progress").text(_self.progress); 4779 } else if (_self.progress >= 100) { 4780 $(".page-loader-progress").text(99); 4781 } 4782 4783 if (["percentageProgress2"].includes(_self.options.effect)) { 4784 $(".loading-overlay-background-layer").css({ 4785 width: _self.progress + "%", 4786 }); 4787 } 4788 4789 self.loopInside = setTimeout(render, _self.animationInterval); 4790 } 4791 }; 4792 render(); 4793 4794 return this; 4795 }, 4796 4797 matchProperties() { 4798 let i, l, properties; 4799 4800 properties = ["backgroundColor", "borderRadius"]; 4801 4802 l = properties.length; 4803 4804 for (i = 0; i < l; i++) { 4805 const obj = {}; 4806 obj[properties[i]] = this.$wrapper.css(properties[i]); 4807 4808 $.extend(this.options.css, obj); 4809 } 4810 }, 4811 4812 getLoaderClass(backgroundColor) { 4813 if ( 4814 !backgroundColor || 4815 backgroundColor === "transparent" || 4816 backgroundColor === "inherit" 4817 ) { 4818 return "black"; 4819 } 4820 4821 let hexColor, r, g, b, yiq; 4822
4823 const colorToHex = (color) => { 4824 let hex, rgb; 4825 4826 if (color.includes("#")) { 4827 hex = color.replace("#", ""); 4828 } else { 4829 rgb = color.match(/\d+/g); 4830 hex = 4831 ("0" + parseInt(rgb[0], 10).toString(16)).slice(-2) + 4832 ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + 4833 ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2); 4834 } 4835 4836 if (hex.length === 3) { 4837 hex = hex + hex; 4838 } 4839 4840 return hex; 4841 }; 4842 4843 hexColor = colorToHex(backgroundColor); 4844 4845 r = parseInt(hexColor.substr(0, 2), 16); 4846 g = parseInt(hexColor.substr(2, 2), 16); 4847 b = parseInt(hexColor.substr(4, 2), 16); 4848 yiq = (r * 299 + g * 587 + b * 114) / 1000; 4849 4850 return yiq >= 128 ? "black" : "white"; 4851 }, 4852 4853 dynamicShowHide(effect) { 4854 const _self = this; 4855 4856 // Remove Loading Overlay Data 4857 $("body").removeData("loadingOverlay"); 4858 4859 // Remove Html Of Loading Overlay 4860 $(".loading-overlay").remove(); 4861 4862 if (effect == "") { 4863 return this; 4864 } 4865 4866 // Initialize New Loading Overlay (second parameter is to NO inherit data-plugin-options) 4867 $("body").loadingOverlay( 4868 { 4869 effect: effect ? effect : "pulse", 4870 isDynamicHideShow: true, 4871 }, 4872 true 4873 ); 4874 4875 // Show Loading Overlay Loader 4876 $("body").data("loadingOverlay").show(); 4877 4878 // Hide Loading Overlay Loader 4879 setTimeout(() => { 4880 $("body").data("loadingOverlay").hide(); 4881 }, 3000); 4882 4883 return this; 4884 }, 4885 4886 dynamicShowHideEvents() { 4887 const _self = this; 4888 4889 // Button 4890 $(document) 4891 .off("click.loading-overlay-button") 4892 .on( 4893 "click.loading-overlay-button", 4894 ".loading-overlay-button", 4895 function (e) { 4896 e.preventDefault(); 4897 4898 _self.dynamicShowHide($(this).data("effect")); 4899 } 4900 ); 4901 4902 // Select 4903 $(document) 4904 .off("change.loading-overlay-select") 4905 .on( 4906 "change.loading-overlay-select", 4907 ".loading-overlay-select", 4908 function () { 4909 _self.dynamicShowHide($(this).val()); 4910 } 4911 ); 4912 4913 return this; 4914 }, 4915 }; 4916 4917 // expose to scope 4918 $.extend(theme, { 4919 LoadingOverlay, 4920 }); 4921 4922 // expose as a jquery plugin 4923 $.fn.loadingOverlay = function (opts, noInheritOptions) { 4924 return this.each(function () { 4925 const $this = $(this); 4926 4927 const loadingOverlay = $this.data("loadingOverlay"); 4928 if (loadingOverlay) { 4929 return loadingOverlay; 4930 } else { 4931 const options = opts || $this.data("loading-overlay-options") || {}; 4932 return new LoadingOverlay($this, options, noInheritOptions); 4933 } 4934 }); 4935 }; 4936 4937 // auto init 4938 $("[data-loading-overlay]").loadingOverlay(); 4939}).apply(this, [window.theme, jQuery]); 4940 4941// Masonry 4942((theme = {}, $) => { 4943 const instanceName = "__masonry"; 4944 4945 class PluginMasonry { 4946 constructor($el, opts) { 4947 return this.initialize($el, opts); 4948 } 4949 4950 initialize($el, opts) { 4951 if ($el.data(instanceName)) { 4952 return this; 4953 } 4954 4955 this.$el = $el; 4956 4957 this.setData().setOptions(opts).build(); 4958 4959 return this; 4960 } 4961 4962 setData() { 4963 this.$el.data(instanceName, this); 4964 4965 return this; 4966 } 4967 4968 setOptions(opts) { 4969 this.options = $.extend(true, {}, PluginMasonry.defaults, opts, { 4970 wrapper: this.$el, 4971 }); 4972 4973 return this; 4974 } 4975 4976 build() { 4977 if (!$.isFunction($.fn.isotope)) { 4978 return this; 4979 } 4980 4981 const self = this, 4982 $window = $(window); 4983 4984 self.$loader = false; 4985 4986 if (self.options.wrapper.parents(".masonry-loader").get(0)) { 4987 self.$loader = self.options.wrapper.parents(".masonry-loader"); 4988 self.createLoader(); 4989 } 4990 4991 self.options.wrapper.one("layoutComplete", (event, laidOutItems) => { 4992 self.removeLoader(); 4993 }); 4994 4995 self.options.wrapper.waitForImages(() => { 4996 self.options.wrapper.isotope(self.options); 4997 }); 4998 4999 $(window).on("resize", () => { 5000 setTimeout(() => { 5001 self.options.wrapper.isotope("layout"); 5002 }, 300); 5003 }); 5004 5005 setTimeout(() => { 5006 self.removeLoader(); 5007 }, 3000); 5008 5009 return this; 5010 } 5011 5012 createLoader() { 5013 const self = this; 5014 5015 const loaderTemplate = [ 5016 '<div class="bounce-loader">', 5017 '<div class="bounce1"></div>', 5018 '<div class="bounce2"></div>', 5019 '<div class="bounce3"></div>', 5020 "</div>", 5021 ].join(""); 5022 5023 self.$loader.append(loaderTemplate); 5024 5025 return this; 5026 } 5027 5028 removeLoader() { 5029 const self = this; 5030 5031 if (self.$loader) { 5032 self.$loader.removeClass("masonry-loader-showing"); 5033 5034 setTimeout(() => { 5035 self.$loader.addClass("masonry-loader-loaded"); 5036 }, 300); 5037 } 5038 } 5039 } 5040 5041 PluginMasonry.defaults = {}; 5042 5043 // expose to scope 5044 $.extend(theme, { 5045 PluginMasonry, 5046 }); 5047 5048 // jquery plugin 5049 $.fn.themePluginMasonry = function (opts) { 5050 return this.map(function () { 5051 const $this = $(this); 5052 5053 if ($this.data(instanceName)) { 5054 return $this.data(instanceName); 5055 } else { 5056 return new PluginMasonry($this, opts); 5057 } 5058 });
5059 }; 5060}).apply(this, [window.theme, jQuery]); 5061 5062// Match Height 5063((theme = {}, $) => { 5064 const instanceName = "__matchHeight"; 5065 5066 class PluginMatchHeight { 5067 constructor($el, opts) { 5068 return this.initialize($el, opts); 5069 } 5070 5071 initialize($el, opts) { 5072 if ($el.data(instanceName)) { 5073 return this; 5074 } 5075 5076 this.$el = $el; 5077 5078 this.setData().setOptions(opts).build(); 5079 5080 return this; 5081 } 5082 5083 setData() { 5084 this.$el.data(instanceName, this); 5085 5086 return this; 5087 } 5088 5089 setOptions(opts) { 5090 this.options = $.extend(true, {}, PluginMatchHeight.defaults, opts, { 5091 wrapper: this.$el, 5092 }); 5093 5094 return this; 5095 } 5096 5097 build() { 5098 if (!$.isFunction($.fn.matchHeight)) { 5099 return this; 5100 } 5101 5102 const self = this; 5103 5104 self.options.wrapper.matchHeight(self.options); 5105 5106 return this; 5107 } 5108 } 5109 5110 PluginMatchHeight.defaults = { 5111 byRow: true, 5112 property: "height", 5113 target: null, 5114 remove: false, 5115 }; 5116 5117 // expose to scope 5118 $.extend(theme, { 5119 PluginMatchHeight, 5120 }); 5121 5122 // jquery plugin 5123 $.fn.themePluginMatchHeight = function (opts) { 5124 return this.map(function () { 5125 const $this = $(this); 5126 5127 if ($this.data(instanceName)) { 5128 return $this.data(instanceName); 5129 } else { 5130 return new PluginMatchHeight($this, opts); 5131 } 5132 }); 5133 }; 5134}).apply(this, [window.theme, jQuery]); 5135 5136// Parallax 5137((theme = {}, $) => { 5138 const instanceName = "__parallax"; 5139 5140 class PluginParallax { 5141 constructor($el, opts) { 5142 return this.initialize($el, opts); 5143 } 5144 5145 initialize($el, opts) { 5146 if ($el.data(instanceName)) { 5147 return this; 5148 } 5149 5150 this.$el = $el; 5151 5152 this.setData().setOptions(opts).build(); 5153 5154 return this; 5155 } 5156 5157 setData() { 5158 this.$el.data(instanceName, this); 5159 5160 return this; 5161 } 5162 5163 setOptions(opts) { 5164 this.options = $.extend(true, {}, PluginParallax.defaults, opts, { 5165 wrapper: this.$el, 5166 }); 5167 5168 return this; 5169 } 5170 5171 build() { 5172 const self = this; 5173 const $window = $(window); 5174 let offset; 5175 let yPos; 5176 let plxPos; 5177 let background; 5178 let rotateY; 5179 5180 // Mouse Parallax 5181 if (self.options.mouseParallax) { 5182 $window.mousemove(({ clientX, clientY }) => { 5183 $(".parallax-mouse-object", self.options.wrapper).each(function () { 5184 const moving_value = $(this).attr("data-value"); 5185 const x = (clientX * moving_value) / 250; 5186 const y = (clientY * moving_value) / 250; 5187 5188 $(this).css( 5189 "transform", 5190 "translateX(" + x + "px) translateY(" + y + "px)" 5191 ); 5192 }); 5193 }); 5194 5195 return this; 5196 } 5197 5198 // Scrollable 5199 if ( 5200 self.options.scrollableParallax && 5201 $(window).width() > self.options.scrollableParallaxMinWidth 5202 ) { 5203 const $scrollableWrapper = self.options.wrapper.find( 5204 ".scrollable-parallax-wrapper" 5205 ); 5206 5207 if ($scrollableWrapper.get(0)) { 5208 let progress = 5209 $(window).scrollTop() > 5210 self.options.wrapper.offset().top + $(window).outerHeight() 5211 ? self.options.cssValueEnd 5212 : self.options.cssValueStart; 5213 const cssValueUnit = self.options.cssValueUnit 5214 ? self.options.cssValueUnit 5215 : ""; 5216 5217 $scrollableWrapper.css({ 5218 "background-image": 5219 "url(" + self.options.wrapper.data("image-src") + ")", 5220 "background-size": "cover", 5221 "background-position": "center", 5222 "background-attachment": "fixed", 5223 transition: 5224 "ease " + 5225 self.options.cssProperty + 5226 " " + 5227 self.options.transitionDuration, 5228 width: progress + "%", 5229 }); 5230 5231 $(window).on("scroll", (e) => { 5232 if (self.options.wrapper.visible(true)) { 5233 const $window = $(window), 5234 scrollTop = $window.scrollTop(), 5235 elementOffset = self.options.wrapper.offset().top, 5236 currentElementOffset = elementOffset - scrollTop; 5237 5238 const scrollPercent = Math.abs( 5239 +(currentElementOffset - $window.height()) / 5240 (self.options.startOffset ? self.options.startOffset : 7) 5241 ); 5242 5243 // Increment progress value according scroll position 5244 if ( 5245 scrollPercent <= self.options.cssValueEnd && 5246 progress <= self.options.cssValueEnd 5247 ) { 5248 progress = self.options.cssValueStart + scrollPercent; 5249 } 5250 5251 // Adjust CSS end value 5252 if (progress > self.options.cssValueEnd) { 5253 progress = self.options.cssValueEnd; 5254 } 5255 5256 // Adjust CSS start value 5257 if (progress < self.options.cssValueStart) { 5258 progress = self.options.cssValueStart; 5259 } 5260 5261 const styles = {}; 5262 styles[self.options.cssProperty] = progress + cssValueUnit; 5263 5264 $scrollableWrapper.css(styles); 5265 } 5266 }); 5267 } 5268 5269 return; 5270 } 5271 5272 // Create Parallax Element 5273 if (self.options.fadeIn) { 5274 background = $( 5275 '<div class="parallax-background fadeIn animated"></div>' 5276 ); 5277 } else { 5278 background = $('<div class="parallax-background"></div>'); 5279 } 5280 5281 // Set Style for Parallax Element 5282 background.css({ 5283 "background-image": 5284 "url(" + self.options.wrapper.data("image-src") + ")", 5285 "background-size": "cover", 5286 position: "absolute",
5287 top: 0, 5288 left: 0, 5289 width: "100%", 5290 height: self.options.parallaxHeight, 5291 }); 5292 5293 if (self.options.parallaxScale) { 5294 background.css({ 5295 transition: "transform 500ms ease-out", 5296 }); 5297 } 5298 5299 // Add Parallax Element on DOM 5300 self.options.wrapper.prepend(background); 5301 5302 // Set Overlfow Hidden and Position Relative to Parallax Wrapper 5303 self.options.wrapper.css({ 5304 position: "relative", 5305 overflow: "hidden", 5306 }); 5307 5308 // Parallax Effect on Scroll & Resize 5309 const parallaxEffectOnScrolResize = () => { 5310 $window.on("scroll resize", () => { 5311 offset = self.options.wrapper.offset(); 5312 yPos = 5313 -($window.scrollTop() - (offset.top - 100)) / 5314 (self.options.speed + 2); 5315 plxPos = yPos < 0 ? Math.abs(yPos) : -Math.abs(yPos); 5316 rotateY = $('html[dir="rtl"]').get(0) ? " rotateY(180deg)" : ""; // RTL 5317 5318 offset = self.options.wrapper.offset(); 5319 yPos = 5320 -($window.scrollTop() - (offset.top - 100)) / 5321 (self.options.speed + 2); 5322 plxPos = yPos < 0 ? Math.abs(yPos) : -Math.abs(yPos); 5323 rotateY = $('html[dir="rtl"]').get(0) ? " rotateY(180deg)" : ""; // RTL 5324 5325 if (!self.options.parallaxScale) { 5326 if (self.options.parallaxDirection == "bottom") { 5327 self.options.offset = 250; 5328 } 5329 5330 let y = plxPos - 50 + self.options.offset; 5331 if (self.options.parallaxDirection == "bottom") { 5332 y = y < 0 ? Math.abs(y) : -Math.abs(y); 5333 } 5334 5335 background.css({ 5336 transform: "translate3d(0, " + y + "px, 0)" + rotateY, 5337 "background-position-x": self.options.horizontalPosition, 5338 }); 5339 } else { 5340 const scrollTop = $window.scrollTop(); 5341 const elementOffset = self.options.wrapper.offset().top; 5342 const currentElementOffset = elementOffset - scrollTop; 5343 let scrollPercent = Math.abs( 5344 +(currentElementOffset - $window.height()) / 5345 (self.options.startOffset ? self.options.startOffset : 7) 5346 ); 5347 5348 scrollPercent = parseInt( 5349 scrollPercent >= 100 ? 100 : scrollPercent 5350 ); 5351 5352 const currentScale = (scrollPercent / 100) * 50; 5353 5354 if (!self.options.parallaxScaleInvert) { 5355 background.css({ 5356 transform: 5357 "scale(1." + 5358 String(currentScale).padStart(2, "0") + 5359 ", 1." + 5360 String(currentScale).padStart(2, "0") + 5361 ")", 5362 }); 5363 } else { 5364 background.css({ 5365 transform: 5366 "scale(1." + 5367 String(50 - currentScale).padStart(2, "0") + 5368 ", 1." + 5369 String(50 - currentScale).padStart(2, "0") + 5370 ")", 5371 }); 5372 } 5373 } 5374 }); 5375 5376 $window.trigger("scroll"); 5377 }; 5378 5379 if (!$.browser.mobile) { 5380 parallaxEffectOnScrolResize(); 5381 } else { 5382 if (self.options.enableOnMobile == true) { 5383 parallaxEffectOnScrolResize(); 5384 } else { 5385 self.options.wrapper.addClass("parallax-disabled"); 5386 } 5387 } 5388 5389 return this; 5390 } 5391 } 5392 5393 PluginParallax.defaults = { 5394 speed: 1.5, 5395 horizontalPosition: "50%", 5396 offset: 0, 5397 parallaxDirection: "top", 5398 parallaxHeight: "180%", 5399 parallaxScale: false, 5400 parallaxScaleInvert: false, 5401 scrollableParallax: false, 5402 scrollableParallaxMinWidth: 991, 5403 startOffset: 7, 5404 transitionDuration: "200ms", 5405 cssProperty: "width", 5406 cssValueStart: 40, 5407 cssValueEnd: 100, 5408 cssValueUnit: "vw", 5409 mouseParallax: false, 5410 enableOnMobile: true, 5411 }; 5412 5413 // expose to scope 5414 $.extend(theme, { 5415 PluginParallax, 5416 }); 5417 5418 // jquery plugin 5419 $.fn.themePluginParallax = function (opts) { 5420 return this.map(function () { 5421 const $this = $(this); 5422 5423 if ($this.data(instanceName)) { 5424 return $this.data(instanceName); 5425 } else { 5426 return new PluginParallax($this, opts); 5427 } 5428 });
5429 }; 5430}).apply(this, [window.theme, jQuery]); 5431 5432// Progress Bar 5433((theme = {}, $) => { 5434 const instanceName = "__progressBar"; 5435 5436 class PluginProgressBar { 5437 constructor($el, opts) { 5438 return this.initialize($el, opts); 5439 } 5440 5441 initialize($el, opts) { 5442 if ($el.data(instanceName)) { 5443 return this; 5444 } 5445 5446 this.$el = $el; 5447 5448 this.setData().setOptions(opts).build(); 5449 5450 return this; 5451 } 5452 5453 setData() { 5454 this.$el.data(instanceName, this); 5455 5456 return this; 5457 } 5458 5459 setOptions(opts) { 5460 this.options = $.extend(true, {}, PluginProgressBar.defaults, opts, { 5461 wrapper: this.$el, 5462 }); 5463 5464 return this; 5465 } 5466 5467 build() { 5468 const self = this; 5469 const $el = this.options.wrapper; 5470 let delay = 1; 5471 5472 delay = $el.attr("data-appear-animation-delay") 5473 ? $el.attr("data-appear-animation-delay") 5474 : self.options.delay; 5475 5476 $el.addClass($el.attr("data-appear-animation")); 5477 5478 setTimeout(() => { 5479 $el.animate( 5480 { 5481 width: $el.attr("data-appear-progress-animation"), 5482 }, 5483 1500, 5484 "easeOutQuad", 5485 () => { 5486 $el.find(".progress-bar-tooltip").animate( 5487 { 5488 opacity: 1, 5489 }, 5490 500, 5491 "easeOutQuad" 5492 ); 5493 } 5494 ); 5495 }, delay); 5496 5497 return this; 5498 } 5499 } 5500 5501 PluginProgressBar.defaults = { 5502 accX: 0, 5503 accY: -50, 5504 delay: 1, 5505 }; 5506 5507 // expose to scope 5508 $.extend(theme, { 5509 PluginProgressBar, 5510 }); 5511 5512 // jquery plugin 5513 $.fn.themePluginProgressBar = function (opts) { 5514 return this.map(function () { 5515 const $this = $(this); 5516 5517 if ($this.data(instanceName)) { 5518 return $this.data(instanceName); 5519 } else { 5520 return new PluginProgressBar($this, opts); 5521 } 5522 }); 5523 }; 5524}).apply(this, [window.theme, jQuery]); 5525 5526// Random Images 5527((theme = {}, $) => { 5528 const instanceName = "__randomimages"; 5529 5530 class PluginRandomImages { 5531 constructor($el, opts) { 5532 return this.initialize($el, opts); 5533 } 5534 5535 initialize($el, opts) { 5536 this.$el = $el; 5537 this.st = ""; 5538 this.times = 0; 5539 this.perImageIndex = 0; 5540 5541 if ($el.is("img") && typeof opts.imagesListURL == "undefined") { 5542 return false; 5543 } 5544 5545 this.setData().setOptions(opts).build(); 5546 5547 return this; 5548 } 5549 5550 setData() { 5551 this.$el.data(instanceName, this); 5552 5553 return this; 5554 } 5555 5556 setOptions(opts) { 5557 this.options = $.extend(true, {}, PluginRandomImages.defaults, opts, { 5558 wrapper: this.$el, 5559 }); 5560 5561 return this; 5562 } 5563 5564 build() { 5565 const self = this; 5566 5567 // Control the screens size we want to have the plugin working 5568 if ($(window).width() < self.options.minWindowWidth) { 5569 return false; 5570 } 5571 5572 // Check if is single image or wrapper with images inside 5573 if (self.$el.is("img")) { 5574 // Check it's inside a lightbox 5575 self.isInsideLightbox = self.$el.closest(".lightbox").length 5576 ? true 5577 : false; 5578 5579 // Push the initial image to lightbox list/array 5580 if (self.isInsideLightbox && self.options.lightboxImagesListURL) { 5581 self.options.lightboxImagesListURL.push( 5582 self.$el.closest(".lightbox").attr("href") 5583 ); 5584 } 5585 5586 // Push the current image src to the array 5587 self.options.imagesListURL.push(self.$el.attr("src")); 5588 5589 // Start with lastIndex as the first image loaded on the page 5590 self.lastIndex = self.options.imagesListURL.length - 1; 5591 5592 // Identify the last random image element (if has more than one on the page) 5593 if (self.options.random == false) { 5594 $(".plugin-random-images").each(function (i) { 5595 if (i == $(".plugin-random-images").length - 1) { 5596 $(this).addClass("the-last"); 5597 } 5598 }); 5599 } 5600 5601 // Start the recursive timeout 5602 setTimeout( 5603 () => { 5604 self.recursiveTimeout( 5605 self.perImageTag, 5606 self.options.delay == null ? 3000 : self.options.delay 5607 ); 5608 }, 5609 self.options.delay == null ? 300 : self.options.delay / 3 5610 ); 5611 } else { 5612 // Start the recursive timeout 5613 setTimeout( 5614 self.recursiveTimeout( 5615 self.perWrapper, 5616 self.options.delay ? self.options.delay : getPerWrapperHighDelay(), 5617 false 5618 ), 5619 300 5620 ); 5621 } 5622 5623 // Stop After Few Seconds 5624 if (self.options.stopAfterFewSeconds) { 5625 setTimeout(() => { 5626 clearTimeout(self.st); 5627 }, self.options.stopAfterFewSeconds); 5628 } 5629 5630 return this; 5631 } 5632 5633 perImageTag() { 5634 const self = this; 5635 5636 // Generate a random index to make the images rotate randomly 5637 let index = self.options.random 5638 ? Math.floor(Math.random() * self.options.imagesListURL.length) 5639 : self.lastIndex; 5640 5641 // Avoid repeat the same image 5642 if (self.lastIndex !== "" && self.lastIndex == index) { 5643 if (self.options.random) { 5644 while (index == self.lastIndex) { 5645 index = Math.floor( 5646 Math.random() * self.options.imagesListURL.length 5647 ); 5648 } 5649 } else { 5650 index = index - 1; 5651 if (index == -1) { 5652 index = self.options.imagesListURL.length - 1; 5653 } 5654 } 5655 } 5656 5657 // Turn the image ready for animations 5658 self.$el.addClass("animated"); 5659 5660 // Remove the entrance animation class and add the out animation class 5661 self.$el 5662 .removeClass(self.options.animateIn) 5663 .addClass(self.options.animateOut); 5664 5665 // Change the image src and add the class for entrance animation 5666 setTimeout(() => { 5667 self.$el 5668 .attr("src", self.options.imagesListURL[index]) 5669 .removeClass(self.options.animateOut) 5670 .addClass(self.options.animateIn); 5671 5672 if (self.isInsideLightbox && self.options.lightboxImagesListURL) { 5673 self.$el 5674 .closest(".lightbox") 5675 .attr("href", self.options.lightboxImagesListURL[index]); 5676 } 5677 }, 1000); 5678 5679 // Save the last index for future checks 5680 self.lastIndex = index; 5681 5682 // Increment the times var 5683 self.times++; 5684 5685 // Save the index for stopAtImageIndex option 5686 self.perImageIndex = index; 5687 5688 return this; 5689 } 5690 5691 // Iterate the imaes loop and get the higher value 5692 getPerWrapperHighDelay() { 5693 const self = this; 5694 const $wrapper = self.$el; 5695 let delay = 0; 5696 5697 $wrapper.find("img").each(function () { 5698 const $image = $(this); 5699 5700 if ( 5701 $image.data("rimage-delay") && 5702 parseInt($image.data("rimage-delay")) > delay 5703 ) {
5704 delay = parseInt($image.data("rimage-delay")); 5705 } 5706 }); 5707 5708 return delay; 5709 } 5710 5711 perWrapper() { 5712 const self = this, 5713 $wrapper = self.$el; 5714 5715 // Turns the imageLlistURL into an array 5716 self.options.imagesListURL = []; 5717 5718 // Find all images inside the element wrapper and push their sources to image list array 5719 $wrapper.find("img").each(function () { 5720 const $image = $(this); 5721 self.options.imagesListURL.push($image.attr("src")); 5722 }); 5723 5724 // Shuffle the images list array (random effect) 5725 self.options.imagesListURL = self.shuffle(self.options.imagesListURL); 5726 5727 // Iterate over each image and make some checks like delay for each image, animations, etc... 5728 $wrapper.find("img").each(function (index) { 5729 const $image = $(this), 5730 animateIn = $image.data("rimage-animate-in") 5731 ? $image.data("rimage-animate-in") 5732 : self.options.animateIn, 5733 animateOut = $image.data("rimage-animate-out") 5734 ? $image.data("rimage-animate-out") 5735 : self.options.animateOut, 5736 delay = $image.data("rimage-delay") 5737 ? $image.data("rimage-delay") 5738 : 2000; 5739 5740 $image.addClass("animated"); 5741 5742 setTimeout(() => { 5743 $image.removeClass(animateIn).addClass(animateOut); 5744 }, delay / 2); 5745 5746 setTimeout(() => { 5747 $image 5748 .attr("src", self.options.imagesListURL[index]) 5749 .removeClass(animateOut) 5750 .addClass(animateIn); 5751 }, delay); 5752 }); 5753 5754 // Increment the times variable 5755 self.times++; 5756 5757 return this; 5758 } 5759 5760 recursiveTimeout(callback, delay) { 5761 const self = this; 5762 5763 const timeout = () => { 5764 if (callback !== null) { 5765 callback.call(self); 5766 } 5767 5768 // Recursive 5769 self.st = setTimeout(timeout, delay == null ? 1000 : delay); 5770 5771 if (self.options.random == false) { 5772 if (self.$el.hasClass("the-last")) { 5773 $(".plugin-random-images").trigger("rimages.start"); 5774 } else { 5775 clearTimeout(self.st); 5776 } 5777 } 5778 5779 // Stop At Image Index 5780 if ( 5781 self.options.stopAtImageIndex && 5782 parseInt(self.options.stopAtImageIndex) == self.perImageIndex 5783 ) { 5784 clearTimeout(self.st); 5785 } 5786 5787 // Stop After X Timers 5788 if (self.options.stopAfterXTimes == self.times) { 5789 clearTimeout(self.st); 5790 } 5791 }; 5792 timeout(); 5793 5794 self.$el.on("rimages.start", () => { 5795 clearTimeout(self.st); 5796 self.st = setTimeout(timeout, delay == null ? 1000 : delay); 5797 }); 5798 } 5799 5800 shuffle(array) { 5801 for (let i = array.length - 1; i > 0; i--) { 5802 const j = Math.floor(Math.random() * (i + 1)); 5803 const temp = array[i]; 5804 array[i] = array[j]; 5805 array[j] = temp; 5806 } 5807 5808 return array; 5809 } 5810 } 5811 5812 PluginRandomImages.defaults = { 5813 minWindowWidth: 0, 5814 random: true, 5815 imagesListURL: null, 5816 lightboxImagesListURL: null, 5817 delay: null, 5818 animateIn: "fadeIn", 5819 animateOut: "fadeOut",
5820 stopAtImageIndex: false, // The value shoudl be the index value of array with images as string. Eg: '2' 5821 stopAfterFewSeconds: false, // The value should be in mili-seconds. Eg: 10000 = 10 seconds 5822 stopAfterXTimes: false, 5823 accY: 0, 5824 }; 5825 5826 // expose to scope 5827 $.extend(theme, { 5828 PluginRandomImages, 5829 }); 5830 5831 // jquery plugin 5832 $.fn.themePluginRandomImages = function (opts) { 5833 return this.map(function () { 5834 const $this = $(this); 5835 5836 if ($this.data(instanceName)) { 5837 return $this.data(instanceName); 5838 } else { 5839 return new PluginRandomImages($this, opts); 5840 } 5841 }); 5842 }; 5843}).apply(this, [window.theme, jQuery]); 5844 5845// Read More 5846((theme = {}, $) => { 5847 const instanceName = "__readmore"; 5848 5849 class PluginReadMore { 5850 constructor($el, opts) { 5851 return this.initialize($el, opts); 5852 } 5853 5854 initialize($el, opts) { 5855 const self = this; 5856 5857 this.$el = $el; 5858 5859 this.setData().setOptions(opts).build().events(); 5860 5861 if (self.options.startOpened) { 5862 self.options.wrapper 5863 .find(".readmore-button-wrapper > a") 5864 .trigger("click"); 5865 } 5866 5867 return this; 5868 } 5869 5870 setData() { 5871 this.$el.data(instanceName, this); 5872 5873 return this; 5874 } 5875 5876 setOptions(opts) { 5877 this.options = $.extend(true, {}, PluginReadMore.defaults, opts, { 5878 wrapper: this.$el, 5879 }); 5880 5881 return this; 5882 } 5883 5884 build() { 5885 const self = this; 5886 5887 self.options.wrapper.addClass("position-relative"); 5888 5889 // Overlay 5890 self.options.wrapper.append('<div class="readmore-overlay"></div>'); 5891 5892 // Check if is Safari 5893 let backgroundCssValue = 5894 "linear-gradient(180deg, rgba(2, 0, 36, 0) 0%, " + 5895 self.options.overlayColor + 5896 " 100%)"; 5897 if ($("html").hasClass("safari")) { 5898 backgroundCssValue = 5899 "-webkit-linear-gradient(top, rgba(2, 0, 36, 0) 0%, " + 5900 self.options.overlayColor + 5901 " 100%)"; 5902 } 5903 5904 self.options.wrapper.find(".readmore-overlay").css({ 5905 background: backgroundCssValue, 5906 position: "absolute", 5907 bottom: 0, 5908 left: 0, 5909 width: "100%", 5910 height: self.options.overlayHeight, 5911 "z-index": 1, 5912 }); 5913 5914 // Read More Button 5915 self.options.wrapper 5916 .find(".readmore-button-wrapper") 5917 .removeClass("d-none") 5918 .css({ 5919 position: "absolute", 5920 bottom: 0, 5921 left: 0, 5922 width: "100%", 5923 "z-index": 2, 5924 }); 5925 5926 // Button Label 5927 self.options.wrapper 5928 .find(".readmore-button-wrapper > a") 5929 .html(self.options.buttonOpenLabel); 5930 5931 self.options.wrapper.css({ 5932 height: self.options.maxHeight, 5933 "overflow-y": "hidden", 5934 }); 5935 5936 // Alignment 5937 switch (self.options.align) { 5938 case "center": 5939 self.options.wrapper 5940 .find(".readmore-button-wrapper") 5941 .addClass("text-center"); 5942 break; 5943 5944 case "right": 5945 self.options.wrapper 5946 .find(".readmore-button-wrapper") 5947 .addClass("text-end"); 5948 break; 5949 5950 case "left": 5951 default: 5952 self.options.wrapper 5953 .find(".readmore-button-wrapper") 5954 .addClass("text-start"); 5955 break; 5956 } 5957 5958 return this; 5959 } 5960 5961 events() { 5962 const self = this; 5963 5964 // Read More 5965 self.readMore = () => { 5966 self.options.wrapper 5967 .find(".readmore-button-wrapper > a:not(.readless)") 5968 .on("click", function (e) { 5969 e.preventDefault(); 5970 5971 const $this = $(this); 5972 5973 setTimeout(() => { 5974 self.options.wrapper.animate( 5975 { 5976 height: self.options.wrapper[0].scrollHeight, 5977 }, 5978 () => { 5979 if (!self.options.enableToggle) { 5980 $this.fadeOut(); 5981 } 5982 5983 $this
5984 .html(self.options.buttonCloseLabel) 5985 .addClass("readless") 5986 .off("click"); 5987 5988 self.readLess(); 5989 5990 self.options.wrapper.find(".readmore-overlay").fadeOut(); 5991 self.options.wrapper.css({ 5992 "max-height": "none", 5993 overflow: "visible", 5994 }); 5995 5996 self.options.wrapper 5997 .find(".readmore-button-wrapper") 5998 .animate({ 5999 bottom: -20, 6000 }); 6001 } 6002 ); 6003 }, 200); 6004 }); 6005 }; 6006 6007 // Read Less 6008 self.readLess = () => { 6009 self.options.wrapper 6010 .find(".readmore-button-wrapper > a.readless") 6011 .on("click", function (e) { 6012 e.preventDefault(); 6013 6014 const $this = $(this); 6015 6016 // Button 6017 self.options.wrapper.find(".readmore-button-wrapper").animate({ 6018 bottom: 0, 6019 }); 6020 6021 // Overlay 6022 self.options.wrapper.find(".readmore-overlay").fadeIn(); 6023 6024 setTimeout(() => { 6025 self.options.wrapper 6026 .height(self.options.wrapper[0].scrollHeight) 6027 .animate( 6028 { 6029 height: self.options.maxHeight, 6030 }, 6031 () => { 6032 $this 6033 .html(self.options.buttonOpenLabel) 6034 .removeClass("readless") 6035 .off("click"); 6036 6037 self.readMore(); 6038 6039 self.options.wrapper.css({ 6040 overflow: "hidden", 6041 }); 6042 } 6043 ); 6044 }, 200); 6045 }); 6046 }; 6047 6048 // First Load 6049 self.readMore(); 6050 6051 return this; 6052 } 6053 } 6054 6055 PluginReadMore.defaults = { 6056 buttonOpenLabel: 6057 'Read More <i class="fas fa-chevron-down text-2 ms-1"></i>', 6058 buttonCloseLabel: 'Read Less <i class="fas fa-chevron-up text-2 ms-1"></i>', 6059 enableToggle: true, 6060 maxHeight: 110, 6061 overlayColor: "#FFF", 6062 overlayHeight: 100, 6063 startOpened: false, 6064 align: "left", 6065 }; 6066 6067 // expose to scope 6068 $.extend(theme, { 6069 PluginReadMore, 6070 }); 6071 6072 // jquery plugin 6073 $.fn.themePluginReadMore = function (opts) { 6074 return this.map(function () { 6075 const $this = $(this); 6076 6077 if ($this.data(instanceName)) { 6078 return $this.data(instanceName); 6079 } else { 6080 return new PluginReadMore($this, opts); 6081 } 6082 }); 6083 }; 6084}).apply(this, [window.theme, jQuery]); 6085 6086// Revolution Slider 6087((theme = {}, $) => { 6088 const instanceName = "__revolution"; 6089 6090 class PluginRevolutionSlider { 6091 constructor($el, opts) { 6092 return this.initialize($el, opts); 6093 } 6094 6095 initialize($el, opts) { 6096 if ($el.data(instanceName)) { 6097 return this; 6098 } 6099 6100 this.$el = $el; 6101 6102 this.setData().setOptions(opts).build().events(); 6103 6104 return this; 6105 } 6106 6107 setData() { 6108 this.$el.data(instanceName, this); 6109 6110 return this; 6111 } 6112 6113 setOptions(opts) { 6114 this.options = $.extend(true, {}, PluginRevolutionSlider.defaults, opts, { 6115 wrapper: this.$el, 6116 }); 6117 6118 return this; 6119 } 6120 6121 build() { 6122 if (!$.isFunction($.fn.revolution)) { 6123 return this; 6124 } 6125 6126 // Single Slider Class 6127 if (this.options.wrapper.find("> ul > li").length == 1) { 6128 this.options.wrapper.addClass("slider-single-slide"); 6129 6130 // Remove Bullets 6131 // this.options.navigation.bullets.enable = false; 6132 $.extend(this.options.navigation, { 6133 bullets: { 6134 enable: false, 6135 }, 6136 }); 6137 } 6138 6139 // Full Screen Class 6140 if (this.options.sliderLayout == "fullscreen") { 6141 this.options.wrapper 6142 .closest(".slider-container") 6143 .addClass("fullscreen-slider"); 6144 } 6145 6146 // Initialize Revolution Slider 6147 this.options.wrapper.revolution(this.options); 6148 6149 // Addon Init - Typewriter 6150 if (this.options.addOnTypewriter.enable) { 6151 RsTypewriterAddOn($, this.options.wrapper); 6152 } 6153 6154 // Addon Init - Whiteboard 6155 if (this.options.addOnWhiteboard.enable) { 6156 this.options.wrapper.rsWhiteBoard(); 6157 } 6158 6159 // Addon Init - Particles 6160 if (this.options.addOnParticles.enable) { 6161 RsParticlesAddOn(this.options.wrapper); 6162 } 6163 6164 // Addon Init - Countdown 6165 if (this.options.addOnCountdown.enable) { 6166 tp_countdown( 6167 this.options.wrapper, 6168 this.options.addOnCountdown.targetdate, 6169 this.options.addOnCountdown.slidechanges 6170 ); 6171 } 6172 6173 // Addon Init - Slicey 6174 if (this.options.addOnSlicey.enable) { 6175 this.options.wrapper.revSliderSlicey(); 6176 } 6177 6178 // Addon Init - Filmstrip 6179 if (this.options.addOnFilmstrip.enable) { 6180 RsFilmstripAddOn( 6181 $, 6182 this.options.wrapper, 6183 "../vendor/rs-plugin/revolution-addons/filmstrip/", 6184 false 6185 ); 6186 } 6187 6188 // Addon Init - Before After
6189 if (this.options.addOnBeforeAfter.enable) { 6190 RevSliderBeforeAfter( 6191 $, 6192 this.options.wrapper, 6193 this.options.addOnBeforeAfter.options 6194 ); 6195 } 6196 6197 // Addon Init - Panorama 6198 if (this.options.addOnPanorama.enable) { 6199 RsAddonPanorama($, this.options.wrapper); 6200 } 6201 6202 // Addon Init - Revealer 6203 if (this.options.addOnRevealer.enable) { 6204 RsRevealerAddOn( 6205 $, 6206 this.options.wrapper, 6207 this.options.revealer.spinnerHtml 6208 ); 6209 } 6210 6211 // Addon Init - Duotone 6212 if (this.options.addOnDuotone.enable) { 6213 RsAddonDuotone( 6214 $, 6215 this.options.wrapper, 6216 true, 6217 "cubic-bezier(0.645, 0.045, 0.355, 1.000)", 6218 "1000" 6219 ); 6220 } 6221 6222 // Addon Init - Bubblemorph 6223 if (this.options.addOnBubblemorph.enable) { 6224 BubbleMorphAddOn($, this.options.wrapper, false); 6225 } 6226 6227 // Addon Init - Distortion 6228 if (this.options.addOnDistortion.enable) { 6229 RsLiquideffectAddOn($, this.options.wrapper); 6230 } 6231 6232 return this; 6233 } 6234 6235 events() { 6236 return this; 6237 } 6238 } 6239 6240 PluginRevolutionSlider.defaults = { 6241 sliderType: "standard", 6242 sliderLayout: "fullwidth", 6243 delay: 9000, 6244 gridwidth: 1170, 6245 gridheight: 500, 6246 spinner: "spinner3", 6247 disableProgressBar: "on", 6248 parallax: { 6249 type: "off", 6250 bgparallax: "off", 6251 }, 6252 navigation: { 6253 keyboardNavigation: "off", 6254 keyboard_direction: "horizontal", 6255 mouseScrollNavigation: "off", 6256 onHoverStop: "off", 6257 touch: { 6258 touchenabled: "on", 6259 swipe_threshold: 75, 6260 swipe_min_touches: 1, 6261 swipe_direction: "horizontal", 6262 drag_block_vertical: false, 6263 }, 6264 arrows: { 6265 enable: true, 6266 hide_onmobile: false, 6267 hide_under: 0, 6268 hide_onleave: true, 6269 hide_delay: 200, 6270 hide_delay_mobile: 1200, 6271 left: { 6272 h_align: "left", 6273 v_align: "center", 6274 h_offset: 30, 6275 v_offset: 0, 6276 }, 6277 right: { 6278 h_align: "right", 6279 v_align: "center", 6280 h_offset: 30, 6281 v_offset: 0, 6282 }, 6283 }, 6284 }, 6285 6286 /* ADDONS */ 6287 addOnTypewriter: { 6288 enable: false, 6289 }, 6290 addOnWhiteboard: { 6291 enable: false, 6292 }, 6293 whiteboard: { 6294 movehand: { 6295 src: "../vendor/rs-plugin/revolution-addons/whiteboard/assets/images/hand_point_right.png", 6296 width: 400, 6297 height: 1000, 6298 handtype: "right", 6299 transform: { 6300 transformX: 50, 6301 transformY: 50, 6302 }, 6303 jittering: { 6304 distance: "80", 6305 distance_horizontal: "100", 6306 repeat: "5", 6307 offset: "10", 6308 offset_horizontal: "0", 6309 }, 6310 rotation: { 6311 angle: "10", 6312 repeat: "3", 6313 }, 6314 }, 6315 writehand: { 6316 src: "../vendor/rs-plugin/revolution-addons/whiteboard/assets/images/write_right_angle.png", 6317 width: 572, 6318 height: 691, 6319 handtype: "right", 6320 transform: { 6321 transformX: 50, 6322 transformY: 50, 6323 }, 6324 jittering: { 6325 distance: "80", 6326 distance_horizontal: "100", 6327 repeat: "5", 6328 offset: "10", 6329 offset_horizontal: "0", 6330 }, 6331 rotation: { 6332 angle: "10", 6333 repeat: "3", 6334 }, 6335 }, 6336 }, 6337 addOnParticles: { 6338 enable: false, 6339 }, 6340 particles: { 6341 startSlide: "first", 6342 endSlide: "last", 6343 zIndex: "1", 6344 particles: { 6345 number: { value: 80 }, 6346 color: { value: "#ffffff" }, 6347 shape: { 6348 type: "circle", 6349 stroke: { width: 0, color: "#ffffff", opacity: 1 }, 6350 image: { src: "" }, 6351 }, 6352 opacity: { 6353 value: 0.5, 6354 random: true, 6355 min: 0.25, 6356 anim: { enable: false, speed: 3, opacity_min: 0, sync: false }, 6357 }, 6358 size: { 6359 value: 2, 6360 random: false, 6361 min: 30, 6362 anim: { enable: false, speed: 40, size_min: 1, sync: false }, 6363 }, 6364 line_linked: { 6365 enable: true, 6366 distance: 150, 6367 color: "#ffffff", 6368 opacity: 0.4, 6369 width: 1, 6370 }, 6371 move: { 6372 enable: true, 6373 speed: 6,
6374 direction: "none", 6375 random: true, 6376 min_speed: 6, 6377 straight: false, 6378 out_mode: "out", 6379 }, 6380 }, 6381 interactivity: { 6382 events: { 6383 onhover: { enable: false, mode: "repulse" }, 6384 onclick: { enable: false, mode: "repulse" }, 6385 }, 6386 modes: { 6387 grab: { distance: 400, line_linked: { opacity: 0.5 } }, 6388 bubble: { distance: 400, size: 40, opacity: 0.4 }, 6389 repulse: { distance: 200 }, 6390 }, 6391 }, 6392 }, 6393 addOnCountdown: { 6394 enable: false, 6395 targetdate: new Date().getTime() + 864000000, // http://www.freeformatter.com/epoch-timestamp-to-date-converter.html 6396 slidechanges: [{ days: 0, hours: 0, minutes: 0, seconds: 0, slide: 2 }], 6397 }, 6398 addOnSlicey: { 6399 enable: false, 6400 }, 6401 addOnFilmstrip: { 6402 enable: false, 6403 }, 6404 addOnBeforeAfter: { 6405 enable: false, 6406 options: { 6407 cursor: "move", 6408 carousel: false, 6409 arrowStyles: { 6410 leftIcon: "fa-icon-caret-left", 6411 rightIcon: "fa-icon-caret-right", 6412 topIcon: "fa-icon-caret-up", 6413 bottomIcon: "fa-icon-caret-down", 6414 size: "35", 6415 color: "#ffffff", 6416 spacing: "10", 6417 bgColor: "transparent", 6418 padding: "0", 6419 borderRadius: "0", 6420 }, 6421 dividerStyles: { 6422 width: "1", 6423 color: "rgba(255, 255, 255, 0.5)", 6424 }, 6425 }, 6426 }, 6427 addOnPanorama: { 6428 enable: false, 6429 }, 6430 addOnRevealer: { 6431 enable: false, 6432 }, 6433 revealer: { 6434 direction: "open_horizontal", 6435 color: "#ffffff", 6436 duration: "1500", 6437 delay: "0", 6438 easing: "Power2.easeInOut", 6439 overlay_enabled: true, 6440 overlay_color: "#000000", 6441 overlay_duration: "1500", 6442 overlay_delay: "0", 6443 overlay_easing: "Power2.easeInOut", 6444 spinner: "1", 6445 spinnerColor: "#006dd2", 6446 spinnerHtml: 6447 "<div class='rsaddon-revealer-spinner rsaddon-revealer-spinner-1'><div class='rsaddon-revealer-1'><span style='background: {{color}}'></span><span style='background: {{color}}'></span><span style='background: {{color}}'></span><span style='background: {{color}}'></span><span style='background: {{color}}'></span><span style='background: {{color}}'></span><span style='background: {{color}}'></span><span style='background: {{color}}'></span><span style='background: {{color}}'></span><span style='background: {{color}}'></span></div></div />", 6448 }, 6449 addOnDuotone: { 6450 enable: false, 6451 }, 6452 addOnBubblemorph: { 6453 enable: false, 6454 }, 6455 addOnDistortion: { 6456 enable: false, 6457 }, 6458 }; 6459 6460 // expose to scope 6461 $.extend(theme, { 6462 PluginRevolutionSlider, 6463 }); 6464 6465 // jquery plugin 6466 $.fn.themePluginRevolutionSlider = function (opts) { 6467 return this.map(function () { 6468 const $this = $(this); 6469 6470 if ($this.data(instanceName)) { 6471 return $this.data(instanceName); 6472 } else { 6473 return new PluginRevolutionSlider($this, opts); 6474 } 6475 }); 6476 }; 6477}).apply(this, [window.theme, jQuery]); 6478 6479// Scroll Spy 6480((theme = {}, $) => { 6481 const instanceName = "__scrollSpy"; 6482 6483 class PluginScrollSpy { 6484 constructor($el, opts) { 6485 return this.initialize($el, opts); 6486 } 6487 6488 initialize($el, opts) { 6489 if (document.querySelector(opts.target) == null) { 6490 return false; 6491 } 6492 6493 this.$el = $el; 6494 6495 this.setData().setOptions(opts); 6496 6497 this.build(); 6498 6499 return this; 6500 } 6501 6502 setData() { 6503 this.$el.data(instanceName, this); 6504 6505 return this; 6506 } 6507 6508 setOptions(opts) { 6509 this.options = $.extend(true, {}, PluginScrollSpy.defaults, opts, { 6510 wrapper: this.$el, 6511 }); 6512 6513 return this; 6514 } 6515 6516 build() { 6517 const self = this, 6518 target = 6519 document.querySelector(self.options.target) != null 6520 ? document.querySelector(self.options.target) 6521 : false, 6522 navItems = 6523 target == "#header" || target == ".wrapper-spy" 6524 ? target.querySelectorAll(".header-nav .nav > li a") 6525 : target.querySelectorAll(".nav > li a"); 6526 6527 // Get all section ID's 6528 let sectionIDs = Object.keys(navItems).map( 6529 (key, index) => navItems[key].hash 6530 ); 6531 6532 // Remove empty values from sectionIDs array 6533 sectionIDs = sectionIDs.filter((value) => value != ""); 6534 6535 // Store in a global variable 6536 self.sectionIDs = sectionIDs; 6537 6538 for (let i = 0; i < sectionIDs.length; i++) { 6539 // Default Root Margin
6540 let rootMargin = "-20% 0px -79.9% 0px"; 6541 6542 // Spy Offset 6543 if ($(sectionIDs[i]).data("spy-offset")) { 6544 const rootMarginOffset = $(sectionIDs[i]).data("spy-offset"), 6545 isNegativeOffset = parseInt(rootMarginOffset) < 0 ? true : false; 6546 6547 // Mount a new rootMargin based on offset value 6548 rootMargin = rootMargin 6549 .split(" ") 6550 .map((element, index) => { 6551 if (element.indexOf("%") > 0) { 6552 const valueToInt = parseInt(element.replace("%", "")); 6553 let newValue = 0; 6554 6555 switch (index) { 6556 case 0: 6557 if (isNegativeOffset) { 6558 newValue = valueToInt - rootMarginOffset; 6559 } else { 6560 newValue = Math.abs(valueToInt) + rootMarginOffset; 6561 } 6562 break; 6563 6564 case 2: 6565 if (isNegativeOffset) { 6566 newValue = valueToInt + rootMarginOffset; 6567 } else { 6568 newValue = Math.abs(valueToInt) - rootMarginOffset; 6569 } 6570 break; 6571 } 6572 6573 if (isNegativeOffset) { 6574 newValue = newValue + "%"; 6575 } else { 6576 newValue = "-" + newValue + "%"; 6577 } 6578 6579 return newValue; 6580 } else { 6581 return element; 6582 } 6583 }) 6584 .join(" "); 6585 } 6586 6587 const selector = sectionIDs[i], 6588 callback = function () { 6589 const $section = $(this); 6590 6591 if (target == "#header" || target == ".wrapper-spy") { 6592 $("#header .header-nav .nav > li a").removeClass("active"); 6593 $( 6594 '#header .header-nav .nav > li a[href="#' + 6595 $section[0].id + 6596 '"]' 6597 ).addClass("active"); 6598 } else { 6599 $(target).find(".nav > li a").removeClass("active"); 6600 $(target) 6601 .find('.nav > li a[href="#' + $section[0].id + '"]') 6602 .addClass("active"); 6603 } 6604 }; 6605 6606 this.scrollSpyIntObs( 6607 selector, 6608 callback, 6609 { 6610 rootMargin, 6611 threshold: 0, 6612 }, 6613 true, 6614 i, 6615 true 6616 ); 6617 } 6618 6619 return this; 6620 } 6621 6622 scrollSpyIntObs( 6623 selector, 6624 functionName, 6625 intObsOptions, 6626 alwaysObserve, 6627 index, 6628 firstLoad 6629 ) { 6630 const self = this; 6631 6632 const $el = document.querySelectorAll(selector); 6633 let intersectionObserverOptions = { 6634 rootMargin: "0px 0px 200px 0px", 6635 }; 6636 6637 if (Object.keys(intObsOptions).length) { 6638 intersectionObserverOptions = $.extend( 6639 intersectionObserverOptions, 6640 intObsOptions 6641 ); 6642 } 6643 6644 const observer = new IntersectionObserver((entries) => { 6645 for (const entry of entries) { 6646 if (entry.intersectionRatio > 0) { 6647 if (typeof functionName === "string") { 6648 const func = Function("return " + functionName)(); 6649 } else { 6650 const callback = functionName; 6651 6652 callback.call($(entry.target)); 6653 } 6654 6655 // Unobserve 6656 if (!alwaysObserve) { 6657 observer.unobserve(entry.target); 6658 } 6659 } else { 6660 if (firstLoad == false) { 6661 if (index == self.sectionIDs.length - 1) { 6662 $("#header .header-nav .nav > li a").removeClass("active"); 6663 $( 6664 '#header .header-nav .nav > li a[href="#' + 6665 entry.target.id + 6666 '"]' 6667 ) 6668 .parent() 6669 .prev() 6670 .find("a") 6671 .addClass("active"); 6672 } 6673 } 6674 firstLoad = false; 6675 } 6676 } 6677 }, intersectionObserverOptions); 6678 6679 $($el).each(function () { 6680 observer.observe($(this)[0]); 6681 }); 6682 6683 return this; 6684 } 6685 } 6686 6687 PluginScrollSpy.defaults = { 6688 target: "#header", 6689 }; 6690 6691 // expose to scope 6692 $.extend(theme, { 6693 PluginScrollSpy, 6694 }); 6695 6696 // jquery plugin 6697 $.fn.themePluginScrollSpy = function (opts) { 6698 return this.map(function () { 6699 const $this = $(this); 6700 6701 if ($this.data(instanceName)) { 6702 return $this.data(instanceName); 6703 } else { 6704 return new PluginScrollSpy($this, opts); 6705 } 6706 });
6707 }; 6708}).apply(this, [window.theme, jQuery]); 6709 6710// Scroll to Top 6711((theme = {}, $) => { 6712 $.extend(theme, { 6713 PluginScrollToTop: { 6714 defaults: { 6715 wrapper: $("body"), 6716 offset: 150, 6717 buttonClass: "scroll-to-top", 6718 buttonAriaLabel: "Scroll To Top", 6719 iconClass: "fas fa-chevron-up", 6720 delay: 1000, 6721 visibleMobile: false, 6722 label: false, 6723 easing: "easeOutBack", 6724 }, 6725 6726 initialize(opts) { 6727 initialized = true; 6728 6729 // Don't initialize if the page has Section Scroll 6730 if ($("body[data-plugin-section-scroll]").get(0)) { 6731 return; 6732 } 6733 6734 this.setOptions(opts).build().events(); 6735 6736 return this; 6737 }, 6738 6739 setOptions(opts) { 6740 this.options = $.extend(true, {}, this.defaults, opts); 6741 6742 return this; 6743 }, 6744 6745 build() { 6746 const self = this; 6747 let $el; 6748 6749 // Base HTML Markup 6750 $el = $("<a />") 6751 .addClass(self.options.buttonClass) 6752 .attr({ 6753 href: "#", 6754 "aria-label": self.options.buttonAriaLabel, 6755 }) 6756 .append($("<i />").addClass(self.options.iconClass)); 6757 6758 // Visible Mobile 6759 if (!self.options.visibleMobile) { 6760 $el.addClass("hidden-mobile"); 6761 } 6762 6763 // Label 6764 if (self.options.label) { 6765 $el.append($("<span />").html(self.options.label)); 6766 } 6767 6768 this.options.wrapper.append($el); 6769 6770 this.$el = $el; 6771 6772 return this; 6773 }, 6774 6775 events() { 6776 const self = this; 6777 let _isScrolling = false; 6778 6779 // Click Element Action 6780 self.$el.on("click", (e) => { 6781 e.preventDefault(); 6782 $("html").animate( 6783 { 6784 scrollTop: 0, 6785 }, 6786 self.options.delay, 6787 self.options.easing 6788 ); 6789 return false; 6790 }); 6791 6792 // Show/Hide Button on Window Scroll event. 6793 $(window).scroll(() => { 6794 if (!_isScrolling) { 6795 _isScrolling = true; 6796 6797 if ($(window).scrollTop() > self.options.offset) { 6798 self.$el.stop(true, true).addClass("visible"); 6799 _isScrolling = false; 6800 } else { 6801 self.$el.stop(true, true).removeClass("visible"); 6802 _isScrolling = false; 6803 } 6804 } 6805 }); 6806 6807 return this; 6808 }, 6809 }, 6810 }); 6811}).apply(this, [window.theme, jQuery]); 6812 6813// Scrollable 6814((theme = {}, $) => { 6815 const instanceName = "__scrollable"; 6816 6817 class PluginScrollable { 6818 constructor($el, opts) { 6819 return this.initialize($el, opts); 6820 } 6821 6822 static updateModals() { 6823 PluginScrollable.updateBootstrapModal(); 6824 } 6825 6826 static updateBootstrapModal() { 6827 let updateBoostrapModal; 6828 6829 updateBoostrapModal = typeof $.fn.modal !== "undefined"; 6830 updateBoostrapModal = 6831 updateBoostrapModal && typeof $.fn.modal.Constructor !== "undefined"; 6832 updateBoostrapModal = 6833 updateBoostrapModal && 6834 typeof $.fn.modal.Constructor.prototype !== "undefined"; 6835 updateBoostrapModal = 6836 updateBoostrapModal && 6837 typeof $.fn.modal.Constructor.prototype.enforceFocus !== "undefined"; 6838 6839 if (!updateBoostrapModal) { 6840 return false; 6841 } 6842 6843 const originalFocus = $.fn.modal.Constructor.prototype.enforceFocus; 6844 $.fn.modal.Constructor.prototype.enforceFocus = function () { 6845 originalFocus.apply(this); 6846 6847 const $scrollable = this.$element.find(".scrollable"); 6848 if ($scrollable) { 6849 if ($.isFunction($.fn["themePluginScrollable"])) { 6850 $scrollable.themePluginScrollable(); 6851 } 6852 6853 if ($.isFunction($.fn["nanoScroller"])) { 6854 $scrollable.nanoScroller(); 6855 } 6856 } 6857 }; 6858 } 6859 6860 initialize($el, opts) { 6861 if ($el.data(instanceName)) { 6862 return this; 6863 } 6864 6865 this.$el = $el; 6866 6867 this.setData().setOptions(opts).build(); 6868 6869 return this; 6870 } 6871 6872 setData() { 6873 this.$el.data(instanceName, this); 6874 6875 return this; 6876 } 6877 6878 setOptions(opts) { 6879 this.options = $.extend(true, {}, PluginScrollable.defaults, opts, { 6880 wrapper: this.$el, 6881 }); 6882 6883 return this; 6884 } 6885 6886 build() { 6887 this.options.wrapper.nanoScroller(this.options); 6888 6889 return this; 6890 } 6891 } 6892 6893 PluginScrollable.defaults = { 6894 contentClass: "scrollable-content", 6895 paneClass: "scrollable-pane", 6896 sliderClass: "scrollable-slider", 6897 alwaysVisible: true, 6898 preventPageScrolling: true, 6899 }; 6900 6901 // expose to scope 6902 $.extend(theme, { 6903 PluginScrollable, 6904 }); 6905 6906 // jquery plugin 6907 $.fn.themePluginScrollable = function (opts) { 6908 return this.each(function () { 6909 const $this = $(this); 6910 6911 if ($this.data(instanceName)) { 6912 return $this.data(instanceName); 6913 } else { 6914 return new PluginScrollable($this, opts); 6915 } 6916 });
6917 }; 6918 6919 $(() => { 6920 PluginScrollable.updateModals(); 6921 }); 6922}).apply(this, [window.theme, jQuery]); 6923 6924// Section Scroll 6925((theme = {}, $) => { 6926 const instanceName = "__sectionScroll"; 6927 6928 class PluginSectionScroll { 6929 constructor($el, opts) { 6930 return this.initialize($el, opts); 6931 } 6932 6933 initialize($el, opts) { 6934 if ($el.data(instanceName)) { 6935 return this; 6936 } 6937 6938 this.$el = $el; 6939 6940 this.setData().setOptions(opts).build().events(); 6941 6942 return this; 6943 } 6944 6945 setData() { 6946 this.$el.data(instanceName, this); 6947 6948 return this; 6949 } 6950 6951 setOptions(opts) { 6952 this.options = $.extend(true, {}, PluginSectionScroll.defaults, opts, { 6953 wrapper: this.$el, 6954 }); 6955 6956 return this; 6957 } 6958 6959 build() { 6960 const self = this, 6961 $el = this.options.wrapper; 6962 6963 // Check type of header and change the target for header (by change header color purpose) 6964 if ($("html").hasClass("side-header-overlay-full-screen")) { 6965 self.$header = $(".sticky-wrapper"); 6966 } else { 6967 self.$header = $("#header"); 6968 } 6969 6970 // Turn the section full height or not depeding on the content size 6971 self.updateSectionsHeight(); 6972 6973 // Wrap all sections in a section wrapper 6974 $(this.options.targetClass).wrap('<div class="section-wrapper"></div>'); 6975 6976 // Set the section wrapper height 6977 $(".section-wrapper").each(function () { 6978 $(this).height($(this).find(".section-scroll").outerHeight()); 6979 }); 6980 6981 // Add active class to the first section on page load 6982 $(".section-wrapper").first().addClass("active"); 6983 6984 let flag = false, 6985 scrollableFlag = false, 6986 touchDirection = "", 6987 touchstartY = 0, 6988 touchendY = 0; 6989 6990 $(window).on("touchstart", ({ changedTouches }) => { 6991 touchstartY = changedTouches[0].screenY; 6992 }); 6993 6994 let wheelEvent = 6995 "onwheel" in document 6996 ? "wheel" 6997 : document.onmousewheel !== undefined 6998 ? "mousewheel" 6999 : "DOMMouseScroll"; 7000 if ($(window).width() < 992 && $("html").hasClass("touch")) { 7001 wheelEvent = 7002 "onwheel" in document 7003 ? "wheel touchend" 7004 : document.onmousewheel !== undefined 7005 ? "mousewheel touchend" 7006 : "DOMMouseScroll touchend"; 7007 } 7008 7009 if ($(window).width() < 992) { 7010 $("html").removeClass("overflow-hidden"); 7011 $(window).on("scroll", () => { 7012 let index = 0; 7013 $(".section-scroll").each(function () { 7014 if ($(this).offset().top <= $(window).scrollTop() + 50) { 7015 const $currentSection2 = $(".section-wrapper") 7016 .eq(index) 7017 .find(".section-scroll"); 7018 7019 $(".section-scroll-dots-navigation > ul > li").removeClass( 7020 "active" 7021 ); 7022 $(".section-scroll-dots-navigation > ul > li") 7023 .eq(index) 7024 .addClass("active"); 7025 7026 $(window).trigger({ 7027 type: "section.scroll.mobile.change.header.color", 7028 currentSection: $currentSection2, 7029 }); 7030 } 7031 7032 index++; 7033 }); 7034 }); 7035 7036 $(window).on( 7037 "section.scroll.mobile.change.header.color", 7038 ({ currentSection }) => { 7039 if (typeof currentSection == "undefined") { 7040 return; 7041 } 7042 7043 const $currentSection = currentSection, 7044 headerColor = $currentSection.data("section-scroll-header-color"); 7045 7046 $("#header .header-nav") 7047 .removeClass("header-nav-light-text header-nav-dark-text") 7048 .addClass("header-nav-" + headerColor + "-text"); 7049 $("#header .header-nav-features") 7050 .removeClass("header-nav-features-dark header-nav-features-light") 7051 .addClass("header-nav-features-" + headerColor); 7052 $("#header .header-social-icons") 7053 .removeClass("social-icons-icon-dark social-icons-icon-light") 7054 .addClass("social-icons-icon-" + headerColor); 7055 7056 // Change Logo 7057 if (self.options.changeHeaderLogo && headerColor != undefined) { 7058 if (headerColor == "light") { 7059 $("#header .header-logo img").attr( 7060 "src", 7061 self.options.headerLogoLight 7062 ); 7063 } else if (headerColor == "dark") { 7064 $("#header .header-logo img").attr( 7065 "src", 7066 self.options.headerLogoDark 7067 ); 7068 } 7069 } 7070 7071 self.$header.css({ 7072 opacity: 1, 7073 }); 7074 } 7075 ); 7076 } 7077 7078 $(window).on(wheelEvent, ({ target, originalEvent }) => { 7079 if ($(window).width() < 992) { 7080 return; 7081 } 7082 7083 if ($(window).width() < 992 && $("html").hasClass("touch")) { 7084 if ( 7085 $(target).closest(".section-scroll-dots-navigation").get(0) || 7086 $(target).closest(".header-body").get(0) || 7087 $(target).closest(".owl-carousel").get(0) 7088 ) { 7089 return; 7090 } 7091 } 7092 7093 // Side Header Overlay Full Screen 7094 if ($("html.side-header-overlay-full-screen.side-header-hide").get(0)) { 7095 return; 7096 } 7097 7098 const wheelDirection = 7099 originalEvent.wheelDelta == undefined 7100 ? originalEvent.deltaY > 0 7101 : originalEvent.wheelDelta < 0; 7102 if ($(window).width() < 992 && $("html").hasClass("touch")) { 7103 touchendY = event.changedTouches[0].screenY; 7104 7105 if (touchendY <= touchstartY) { 7106 touchDirection = "up"; 7107 } 7108 7109 if (touchendY >= touchstartY) { 7110 touchDirection = "down"; 7111 } 7112 7113 if (touchendY == touchstartY) { 7114 return; 7115 } 7116 } 7117 7118 const $currentSection = $(".section-wrapper") 7119 .eq(self.getCurrentIndex()) 7120 .find(".section-scroll"); 7121 const $nextSection = self.getNextSection( 7122 wheelDirection, 7123 touchDirection 7124 ); 7125 let nextSectionOffsetTop; 7126 7127 // If is the last section, then change the offsetTop value 7128 if (self.getCurrentIndex() == $(".section-wrapper").length - 1) { 7129 nextSectionOffsetTop = $(document).height(); 7130 } else { 7131 nextSectionOffsetTop = $nextSection.offset().top; 7132 } 7133 7134 if ($(window).width() < 992 && $("html").hasClass("touch")) { 7135 setTimeout(() => { 7136 if ( 7137 $(".section-wrapper") 7138 .eq(self.getCurrentIndex()) 7139 .find(".section-scroll") 7140 .hasClass("section-scroll-scrollable") 7141 ) { 7142 $("html").removeClass("overflow-hidden"); 7143 } else { 7144 $("html").addClass("overflow-hidden"); 7145 } 7146 }, 1200); 7147 } 7148 7149 // For non full height sections 7150 if ($currentSection.hasClass("section-scroll-scrollable")) { 7151 if (!flag && !scrollableFlag) { 7152 // Scroll Direction 7153 if (wheelDirection || touchDirection == "up") { 7154 if ( 7155 $(window).scrollTop() + $(window).height() >= 7156 nextSectionOffsetTop 7157 ) { 7158 flag = true; 7159 setTimeout(() => { 7160 $(window).trigger("section.scroll.change.header.color"); 7161 7162 setTimeout(() => { 7163 flag = false; 7164 }, 500); 7165 }, 1000); 7166 7167 if ( 7168 self.getCurrentIndex() == 7169 $(".section-wrapper").length - 1 7170 ) { 7171 return false; 7172 } 7173 7174 // Move to the next section 7175 self.moveTo( 7176 $currentSection.offset().top + $currentSection.outerHeight() 7177 ); 7178 7179 // Change Section Active Class 7180 self.changeSectionActiveState($nextSection); 7181 7182 self.$header.css({ 7183 opacity: 0, 7184 transition: "ease opacity 500ms", 7185 }); 7186 } 7187 7188 if (!$("html").hasClass("touch")) { 7189 for (var i = 1; i < 100; i++) { 7190 $("body, html").scrollTop($(window).scrollTop() + 1); 7191 7192 if ( 7193 $(window).scrollTop() + $(window).height() >= 7194 nextSectionOffsetTop 7195 ) { 7196 scrollableFlag = true; 7197 setTimeout(() => { 7198 $(window).trigger("section.scroll.change.header.color"); 7199 scrollableFlag = false; 7200 }, 500); 7201 break; 7202 } 7203 } 7204 } 7205 } else { 7206 if ($(window).scrollTop() <= $currentSection.offset().top) { 7207 flag = true; 7208 setTimeout(() => { 7209 $(window).trigger("section.scroll.change.header.color"); 7210 7211 setTimeout(() => { 7212 flag = false; 7213 }, 500); 7214 }, 1000); 7215 7216 if (self.getCurrentIndex() == 0) { 7217 return false; 7218 } 7219 7220 // Move to the next section 7221 self.moveTo($currentSection.offset().top - $(window).height()); 7222 7223 // Change Section Active Class 7224 self.changeSectionActiveState($nextSection); 7225 7226 self.$header.css({ 7227 opacity: 0, 7228 transition: "ease opacity 500ms", 7229 }); 7230 } 7231 7232 if (!$("html").hasClass("touch")) { 7233 for (var i = 1; i < 100; i++) { 7234 $("body, html").scrollTop($(window).scrollTop() - 1); 7235 7236 if ($(window).scrollTop() <= $currentSection.offset().top) { 7237 scrollableFlag = true; 7238 setTimeout(() => { 7239 $(window).trigger("section.scroll.change.header.color"); 7240 scrollableFlag = false; 7241 }, 500); 7242 break; 7243 } 7244 } 7245 } 7246 } 7247 7248 // Change Dots Active Class 7249 self.changeDotsActiveState(); 7250 7251 return; 7252 } 7253 } 7254 7255 // For full height sections 7256 if (!flag && !scrollableFlag) { 7257 if (wheelDirection || touchDirection == "up") { 7258 if (self.getCurrentIndex() == $(".section-wrapper").length - 1) { 7259 return false; 7260 } 7261 7262 // Change Section Active Class 7263 self.changeSectionActiveState($nextSection); 7264 7265 setTimeout(() => { 7266 // Move to the next section 7267 self.moveTo($nextSection.offset().top); 7268 }, 150); 7269 } else { 7270 if (self.getCurrentIndex() == 0) { 7271 return false; 7272 } 7273 7274 // Change Section Active Class 7275 self.changeSectionActiveState($nextSection); 7276 7277 if ($nextSection.height() > $(window).height()) { 7278 // Move to the next section 7279 self.moveTo($currentSection.offset().top - $(window).height()); 7280 } else { 7281 setTimeout(() => { 7282 // Move to the next section 7283 self.moveTo($nextSection.offset().top); 7284 }, 150); 7285 } 7286 } 7287 7288 // Change Dots Active Class 7289 self.changeDotsActiveState(); 7290 7291 self.$header.css({ 7292 opacity: 0, 7293 transition: "ease opacity 500ms", 7294 }); 7295 7296 // Style next section 7297 $nextSection.css({ 7298 position: "relative", 7299 opacity: 1, 7300 "z-index": 1,
7301 transform: "translate3d(0,0,0) scale(1)", 7302 }); 7303 7304 // Style previous section 7305 $currentSection.css({ 7306 position: "fixed", 7307 width: "100%", 7308 top: 0, 7309 left: 0, 7310 opacity: 0, 7311 "z-index": 0, 7312 transform: "translate3d(0,0,-10px) scale(0.7)", 7313 transition: "ease transform 600ms, ease opacity 600ms", 7314 }); 7315 7316 setTimeout(() => { 7317 $currentSection.css({ 7318 position: "relative", 7319 opacity: 1, 7320 transform: "translate3d(0,0,-10px) scale(1)", 7321 }); 7322 7323 $(window).trigger("section.scroll.change.header.color"); 7324 7325 setTimeout(() => { 7326 flag = false; 7327 }, 500); 7328 }, 1000); 7329 7330 flag = true; 7331 } 7332 7333 return; 7334 }); 7335 7336 // Dots Navigation 7337 if (this.options.dotsNav) { 7338 self.dotsNavigation(); 7339 } 7340 7341 // First Load 7342 setTimeout(() => { 7343 if ($(window.location.hash).get(0)) { 7344 self.moveTo($(window.location.hash).parent().offset().top); 7345 7346 self.changeSectionActiveState($(window.location.hash)); 7347 7348 // Change Dots Active Class 7349 self.changeDotsActiveState(); 7350 7351 self.updateHash(true); 7352 } else { 7353 const hash = window.location.hash; 7354 let index = hash.replace("#", ""); 7355 7356 if (!hash) { 7357 index = 1; 7358 } 7359 7360 self.moveTo( 7361 $(".section-wrapper") 7362 .eq(index - 1) 7363 .offset().top 7364 ); 7365 7366 self.changeSectionActiveState( 7367 $(".section-wrapper") 7368 .eq(index - 1) 7369 .find(".section-scroll") 7370 ); 7371 7372 // Change Dots Active Class 7373 self.changeDotsActiveState(); 7374 7375 self.updateHash(true); 7376 } 7377 7378 $(window).trigger("section.scroll.ready"); 7379 $(window).trigger("section.scroll.change.header.color"); 7380 }, 500); 7381 7382 return this; 7383 } 7384 7385 updateSectionsHeight() { 7386 const self = this; 7387 7388 $(".section-scroll").css({ height: "" }); 7389 7390 $(".section-scroll").each(function () { 7391 if ($(this).outerHeight() < $(window).height() + 3) { 7392 $(this).css({ height: "100vh" }); 7393 } else { 7394 $(this).addClass("section-scroll-scrollable"); 7395 } 7396 }); 7397 7398 // Set the section wrapper height 7399 $(".section-wrapper").each(function () { 7400 $(this).height($(this).find(".section-scroll").outerHeight()); 7401 }); 7402 7403 return this; 7404 } 7405 7406 updateHash(first_load) { 7407 const self = this; 7408 7409 if (!window.location.hash) { 7410 window.location.hash = 1; 7411 } else { 7412 if (!first_load) { 7413 const $section = $(".section-wrapper") 7414 .eq(self.getCurrentIndex()) 7415 .find(".section-scroll"), 7416 section_id = $section.attr("id") 7417 ? $section.attr("id") 7418 : $section.parent().index() + 1; 7419 7420 window.location.hash = section_id; 7421 } 7422 } 7423 7424 return this; 7425 } 7426 7427 getCurrentIndex() { 7428 const self = this; 7429 let currentIndex = 0; 7430 7431 currentIndex = $(".section-wrapper.active").index(); 7432 7433 return currentIndex; 7434 } 7435 7436 moveTo($scrollTopValue, first_load) { 7437 const self = this; 7438 7439 $("body, html").animate( 7440 { 7441 scrollTop: $scrollTopValue, 7442 }, 7443 1000, 7444 "easeOutQuint" 7445 ); 7446 7447 setTimeout(() => { 7448 self.updateHash(); 7449 }, 500); 7450 7451 return this; 7452 } 7453 7454 getNextSection(wheelDirection, touchDirection) { 7455 const self = this; 7456 let $nextSection = ""; 7457 7458 // Scroll Direction 7459 if (wheelDirection || touchDirection == "up") { 7460 $nextSection = $(".section-wrapper") 7461 .eq(self.getCurrentIndex() + 1) 7462 .find(".section-scroll"); 7463 } else { 7464 $nextSection = $(".section-wrapper") 7465 .eq(self.getCurrentIndex() - 1) 7466 .find(".section-scroll"); 7467 } 7468 7469 return $nextSection; 7470 } 7471 7472 changeSectionActiveState($nextSection) { 7473 const self = this; 7474 7475 $(".section-wrapper").removeClass("active"); 7476 $nextSection.parent().addClass("active"); 7477 7478 return this; 7479 } 7480 7481 changeDotsActiveState() { 7482 const self = this; 7483 7484 $(".section-scroll-dots-navigation > ul > li").removeClass("active"); 7485 $(".section-scroll-dots-navigation > ul > li") 7486 .eq(self.getCurrentIndex()) 7487 .addClass("active"); 7488 7489 return this; 7490 } 7491 7492 dotsNavigation() { 7493 const self = this; 7494 7495 const dotsNav = $( 7496 '<div class="section-scroll-dots-navigation"><ul class="list list-unstyled"></ul></div>' 7497 ), 7498 currentSectionIndex = self.getCurrentIndex(); 7499 7500 if (self.options.dotsClass) { 7501 dotsNav.addClass(self.options.dotsClass); 7502 } 7503 7504 for (let i = 0; i < $(".section-scroll").length; i++) { 7505 const title = $(".section-wrapper") 7506 .eq(i) 7507 .find(".section-scroll") 7508 .data("section-scroll-title"); 7509 7510 dotsNav 7511 .find("> ul") 7512 .append( 7513 "<li" + 7514 (currentSectionIndex == i ? ' class="active"' : "") + 7515 '><a href="#' + 7516 i + 7517 '" data-nav-id="' + 7518 i + 7519 '"><span>' + 7520 title + 7521 "</span></a></li>" 7522 ); 7523 } 7524 7525 $(".body").append(dotsNav); 7526 7527 dotsNav.find("a[data-nav-id]").on("click touchstart", function (e) { 7528 e.preventDefault(); 7529 const $this = $(this); 7530 7531 $(".section-scroll").css({ 7532 opacity: 0, 7533 transition: "ease opacity 300ms", 7534 }); 7535 7536 self.$header.css({ 7537 opacity: 0, 7538 transition: "ease opacity 500ms", 7539 }); 7540 7541 setTimeout(() => { 7542 self.moveTo( 7543 $(".section-wrapper").eq($this.data("nav-id")).offset().top 7544 ); 7545 7546 $(".section-wrapper").removeClass("active"); 7547 $(".section-wrapper").eq($this.data("nav-id")).addClass("active"); 7548 7549 $(".section-wrapper") 7550 .eq(self.getCurrentIndex()) 7551 .find(".section-scroll") 7552 .css({ 7553 opacity: 1, 7554 }); 7555 7556 setTimeout(() => { 7557 $(".section-scroll").css({ opacity: 1 }); 7558 7559 $(window).trigger("section.scroll.change.header.color"); 7560 }, 500); 7561 7562 if ($(window).width() > 991) { 7563 self.changeDotsActiveState(); 7564 } 7565 }, 500); 7566 }); 7567 7568 return this; 7569 } 7570 7571 events() { 7572 const self = this; 7573 7574 $(window).on("section.scroll.ready", () => { 7575 $(window).scrollTop(0); 7576 }); 7577 7578 $(window).on("section.scroll.change.header.color", () => { 7579 const headerColor = $(".section-wrapper") 7580 .eq(self.getCurrentIndex()) 7581 .find(".section-scroll") 7582 .data("section-scroll-header-color"); 7583 7584 $("#header .header-nav") 7585 .removeClass("header-nav-light-text header-nav-dark-text") 7586 .addClass("header-nav-" + headerColor + "-text"); 7587 $("#header .header-nav-features") 7588 .removeClass("header-nav-features-dark header-nav-features-light") 7589 .addClass("header-nav-features-" + headerColor); 7590 $("#header .header-social-icons") 7591 .removeClass("social-icons-icon-dark social-icons-icon-light") 7592 .addClass("social-icons-icon-" + headerColor); 7593 7594 // Change Logo 7595 if (self.options.changeHeaderLogo && headerColor != undefined) { 7596 if (headerColor == "light") { 7597 $("#header .header-logo img").attr( 7598 "src", 7599 self.options.headerLogoLight 7600 ); 7601 } else if (headerColor == "dark") { 7602 $("#header .header-logo img").attr( 7603 "src", 7604 self.options.headerLogoDark 7605 ); 7606 } 7607 } 7608 7609 self.$header.css({ 7610 opacity: 1, 7611 }); 7612 }); 7613 7614 $(document).ready(() => { 7615 $(window).afterResize(() => { 7616 self.updateSectionsHeight(); 7617 7618 if ($(window).width() < 992) { 7619 $("html").removeClass("overflow-hidden"); 7620 } 7621 }); 7622 }); 7623 7624 return this; 7625 } 7626 } 7627 7628 PluginSectionScroll.defaults = { 7629 targetClass: ".section", 7630 dotsNav: true, 7631 changeHeaderLogo: true, 7632 headerLogoDark: "img/logo-default-slim.png", 7633 headerLogoLight: "img/logo-default-slim-dark.png", 7634 }; 7635 7636 // expose to scope 7637 $.extend(theme, { 7638 PluginSectionScroll, 7639 }); 7640 7641 // jquery plugin 7642 $.fn.themePluginSectionScroll = function (opts) { 7643 return this.map(function () { 7644 const $this = $(this); 7645 7646 if ($this.data(instanceName)) { 7647 return $this.data(instanceName); 7648 } else { 7649 return new PluginSectionScroll($this, opts); 7650 } 7651 });
7652 }; 7653}).apply(this, [window.theme, jQuery]); 7654 7655// Sort 7656((theme = {}, $) => { 7657 const instanceName = "__sort"; 7658 7659 class PluginSort { 7660 constructor($el, opts) { 7661 return this.initialize($el, opts); 7662 } 7663 7664 initialize($el, opts) { 7665 if ($el.data(instanceName)) { 7666 return this; 7667 } 7668 7669 this.$el = $el; 7670 7671 this.setData().setOptions(opts).build(); 7672 7673 return this; 7674 } 7675 7676 setData() { 7677 this.$el.data(instanceName, this); 7678 7679 return this; 7680 } 7681 7682 setOptions(opts) { 7683 this.options = $.extend(true, {}, PluginSort.defaults, opts, { 7684 wrapper: this.$el, 7685 }); 7686 7687 return this; 7688 } 7689 7690 build() { 7691 if (!$.isFunction($.fn.isotope)) { 7692 return this; 7693 } 7694 7695 const self = this, 7696 $source = this.options.wrapper, 7697 $destination = $( 7698 '.sort-destination[data-sort-id="' + 7699 $source.attr("data-sort-id") + 7700 '"]' 7701 ), 7702 $window = $(window); 7703 7704 if ($destination.get(0)) { 7705 self.$source = $source; 7706 self.$destination = $destination; 7707 self.$loader = false; 7708 7709 self.setParagraphHeight($destination); 7710 7711 if (self.$destination.parents(".sort-destination-loader").get(0)) { 7712 self.$loader = self.$destination.parents(".sort-destination-loader"); 7713 self.createLoader(); 7714 } 7715 7716 $destination.attr("data-filter", "*"); 7717 7718 $destination.one("layoutComplete", (event, laidOutItems) => { 7719 self.removeLoader(); 7720 7721 // If has data-plugin-sticky on the page we need recalculate sticky position 7722 if ($("[data-plugin-sticky]").length) { 7723 setTimeout(() => { 7724 $("[data-plugin-sticky]").each(function () { 7725 $(this).data("__sticky").build(); 7726 $(window).trigger("resize"); 7727 }); 7728 }, 500); 7729 } 7730 }); 7731 7732 if ($("#" + self.options.filterFieldId).length) { 7733 const $filterField = $("#" + self.options.filterFieldId); 7734 7735 $filterField.keyup(function () { 7736 self.options.filterFieldText = $(this).val(); 7737 self.setFilter(self.options.filter); 7738 }); 7739 } 7740 7741 $destination.waitForImages(() => { 7742 $destination.isotope(self.options); 7743 self.events(); 7744 }); 7745 7746 setTimeout(() => { 7747 self.removeLoader(); 7748 }, 3000); 7749 } 7750 7751 return this; 7752 } 7753 7754 events() { 7755 const self = this; 7756 let filter = null; 7757 const $window = $(window); 7758 7759 self.$source.find("a").click(function (e) { 7760 e.preventDefault(); 7761 7762 filter = $(this).parent().data("option-value"); 7763 7764 self.setFilter(filter); 7765 7766 if (e.originalEvent) { 7767 self.$source.trigger("filtered"); 7768 } 7769 7770 return this; 7771 }); 7772 7773 self.$destination.trigger("filtered"); 7774 self.$source.trigger("filtered"); 7775 7776 if (self.options.useHash) { 7777 self.hashEvents(); 7778 } 7779 7780 $window.on("resize sort.resize", () => { 7781 setTimeout(() => { 7782 self.$destination.isotope("layout"); 7783 }, 300); 7784 }); 7785 7786 setTimeout(() => { 7787 $window.trigger("sort.resize"); 7788 }, 300); 7789 7790 return this; 7791 } 7792 7793 setFilter(filter) { 7794 const self = this; 7795 const page = false; 7796 let currentFilter = filter; 7797 7798 self.$source.find(".active").removeClass("active"); 7799 self.$source 7800 .find( 7801 'li[data-option-value="' + 7802 filter + 7803 '"], li[data-option-value="' + 7804 filter + 7805 '"] > a' 7806 ) 7807 .addClass("active"); 7808 7809 self.options.filter = currentFilter; 7810 7811 if (self.$destination.attr("data-current-page")) { 7812 currentFilter = 7813 currentFilter + 7814 "[data-page-rel=" + 7815 self.$destination.attr("data-current-page") + 7816 "]"; 7817 } 7818 7819 if (self.options.filterFieldText != "") { 7820 currentFilter = 7821 currentFilter + 7822 "[data-sort-search*=" + 7823 self.options.filterFieldText.toLowerCase() + 7824 "]"; 7825 } 7826 7827 self.$destination 7828 .attr("data-filter", filter) 7829 .isotope({ 7830 filter: currentFilter, 7831 }) 7832 .one("arrangeComplete", (event, filteredItems) => { 7833 if (self.options.useHash) { 7834 if ( 7835 window.location.hash != "" || 7836 self.options.filter.replace(".", "") != "*" 7837 ) { 7838 window.location.hash = self.options.filter.replace(".", ""); 7839 } 7840 } 7841 7842 $(window).trigger("scroll"); 7843 }) 7844 .trigger("filtered"); 7845 7846 return this; 7847 } 7848 7849 hashEvents() { 7850 const self = this; 7851 let hash = null; 7852 let hashFilter = null; 7853 let initHashFilter = "." + location.hash.replace("#", ""); 7854 7855 // Check if has scroll to section trough URL hash and prevent the sort plugin from show nothing 7856 if ($(location.hash).length) { 7857 initHashFilter = "."; 7858 } 7859 7860 if (initHashFilter != "." && initHashFilter != ".*") { 7861 self.setFilter(initHashFilter); 7862 } 7863 7864 $(window).on("hashchange", (e) => { 7865 hashFilter = "." + location.hash.replace("#", ""); 7866 hash = hashFilter == "." || hashFilter == ".*" ? "*" : hashFilter; 7867
7868 self.setFilter(hash); 7869 }); 7870 7871 return this; 7872 } 7873 7874 setParagraphHeight() { 7875 const self = this; 7876 let minParagraphHeight = 0; 7877 const paragraphs = $("span.thumb-info-caption p", self.$destination); 7878 7879 paragraphs.each(function () { 7880 if ($(this).height() > minParagraphHeight) { 7881 minParagraphHeight = $(this).height() + 10; 7882 } 7883 }); 7884 7885 paragraphs.height(minParagraphHeight); 7886 7887 return this; 7888 } 7889 7890 createLoader() { 7891 const self = this; 7892 7893 const loaderTemplate = [ 7894 '<div class="bounce-loader">', 7895 '<div class="bounce1"></div>', 7896 '<div class="bounce2"></div>', 7897 '<div class="bounce3"></div>', 7898 "</div>", 7899 ].join(""); 7900 7901 self.$loader.append(loaderTemplate); 7902 7903 return this; 7904 } 7905 7906 removeLoader() { 7907 const self = this; 7908 7909 if (self.$loader) { 7910 self.$loader.removeClass("sort-destination-loader-showing"); 7911 7912 setTimeout(() => { 7913 self.$loader.addClass("sort-destination-loader-loaded"); 7914 }, 300); 7915 } 7916 } 7917 } 7918 7919 PluginSort.defaults = { 7920 useHash: true, 7921 itemSelector: ".isotope-item", 7922 layoutMode: "masonry", 7923 filter: "*", 7924 filterFieldId: false, 7925 filterFieldText: "", 7926 hiddenStyle: { 7927 opacity: 0, 7928 }, 7929 visibleStyle: { 7930 opacity: 1, 7931 }, 7932 stagger: 30, 7933 isOriginLeft: $("html").attr("dir") == "rtl" ? false : true, 7934 }; 7935 7936 // expose to scope 7937 $.extend(theme, { 7938 PluginSort, 7939 }); 7940 7941 // jquery plugin 7942 $.fn.themePluginSort = function (opts) { 7943 return this.map(function () { 7944 const $this = $(this); 7945 7946 if ($this.data(instanceName)) { 7947 return $this.data(instanceName); 7948 } else { 7949 return new PluginSort($this, opts); 7950 } 7951 }); 7952 }; 7953}).apply(this, [window.theme, jQuery]); 7954 7955// Star Rating 7956((theme = {}, $) => { 7957 const instanceName = "__starrating"; 7958 7959 class PluginStarRating { 7960 constructor($el, opts) { 7961 return this.initialize($el, opts); 7962 } 7963 7964 initialize($el, opts) { 7965 this.$el = $el; 7966 7967 this.setData().setOptions(opts).build(); 7968 7969 return this; 7970 } 7971 7972 setData() { 7973 this.$el.data(instanceName, this); 7974 7975 return this; 7976 } 7977 7978 setOptions(opts) { 7979 this.options = $.extend(true, {}, PluginStarRating.defaults, opts, { 7980 wrapper: this.$el, 7981 }); 7982 7983 return this; 7984 } 7985 7986 build() { 7987 if (!$.isFunction($.fn.rating)) { 7988 return this; 7989 } 7990 7991 const self = this; 7992 7993 self.options.wrapper.rating(self.options); 7994 7995 self.options.wrapper 7996 .parents(".rating-container") 7997 .addClass("rating-" + self.options.color); 7998 7999 if (self.options.extraClass) { 8000 self.options.wrapper 8001 .parents(".rating-container") 8002 .addClass(self.options.extraClass); 8003 } 8004 8005 return this; 8006 } 8007 } 8008 8009 PluginStarRating.defaults = { 8010 theme: "krajee-fas", 8011 color: "primary", 8012 showClear: false, 8013 showCaption: false, 8014 }; 8015 8016 // expose to scope 8017 $.extend(theme, { 8018 PluginStarRating, 8019 }); 8020 8021 // jquery plugin 8022 $.fn.themePluginStarRating = function (opts) { 8023 return this.map(function () { 8024 const $this = $(this); 8025 8026 if ($this.data(instanceName)) { 8027 return $this.data(instanceName); 8028 } else { 8029 return new PluginStarRating($this, opts); 8030 } 8031 }); 8032 }; 8033}).apply(this, [window.theme, jQuery]); 8034 8035// Sticky 8036((theme = {}, $) => { 8037 const instanceName = "__sticky"; 8038 8039 class PluginSticky { 8040 constructor($el, opts) { 8041 return this.initialize($el, opts); 8042 } 8043 8044 initialize($el, opts) { 8045 if ($el.data(instanceName)) { 8046 return this; 8047 } 8048 8049 this.$el = $el; 8050 8051 this.setData().setOptions(opts).build().events(); 8052 8053 return this; 8054 } 8055 8056 setData() { 8057 this.$el.data(instanceName, this); 8058 8059 return this; 8060 } 8061 8062 setOptions(opts) { 8063 this.options = $.extend(true, {}, PluginSticky.defaults, opts, { 8064 wrapper: this.$el, 8065 }); 8066 8067 return this; 8068 } 8069 8070 build() { 8071 if (!$.isFunction($.fn.pin)) { 8072 return this; 8073 } 8074 8075 const self = this, 8076 $window = $(window); 8077 8078 self.options.wrapper.pin(self.options); 8079 8080 if (self.options.wrapper.hasClass("sticky-wrapper-transparent")) { 8081 self.options.wrapper.parent().addClass("position-absolute w-100"); 8082 } 8083 8084 $window.afterResize(() => { 8085 self.options.wrapper.removeAttr("style").removeData("pin"); 8086 self.options.wrapper.pin(self.options); 8087 $window.trigger("scroll"); 8088 }); 8089 8090 // Change Logo Src 8091 if (self.options.wrapper.find("img").attr("data-change-src")) { 8092 const $logo = self.options.wrapper.find("img"), 8093 logoSrc = $logo.attr("src"), 8094 logoNewSrc = $logo.attr("data-change-src"); 8095 8096 self.changeLogoSrc = (activate) => { 8097 if (activate) { 8098 $logo.attr("src", logoNewSrc); 8099 } else { 8100 $logo.attr("src", logoSrc); 8101 } 8102 }; 8103 } 8104 8105 return this; 8106 } 8107 8108 events() { 8109 const self = this; 8110 const $window = $(window); 8111 const $logo = self.options.wrapper.find("img"); 8112 let sticky_activate_flag = true; 8113 let sticky_deactivate_flag = false; 8114 const class_to_check = self.options.wrapper.hasClass( 8115 "sticky-wrapper-effect-1" 8116 ) 8117 ? "sticky-effect-active" 8118 : "sticky-active"; 8119 8120 $window.on("scroll sticky.effect.active", () => { 8121 if (self.options.wrapper.hasClass(class_to_check)) { 8122 if (sticky_activate_flag) { 8123 if ($logo.attr("data-change-src")) { 8124 self.changeLogoSrc(true); 8125 } 8126 8127 sticky_activate_flag = false; 8128 sticky_deactivate_flag = true; 8129 } 8130 } else { 8131 if (sticky_deactivate_flag) { 8132 if ($logo.attr("data-change-src")) { 8133 self.changeLogoSrc(false); 8134 } 8135 8136 sticky_deactivate_flag = false; 8137 sticky_activate_flag = true; 8138 } 8139 } 8140 }); 8141 8142 let is_backing = false; 8143 if (self.options.stickyStartEffectAt) { 8144 // First Load 8145 if (self.options.stickyStartEffectAt < $window.scrollTop()) { 8146 self.options.wrapper.addClass("sticky-effect-active"); 8147 8148 $window.trigger("sticky.effect.active"); 8149 } 8150 8151 $window.on("scroll", () => { 8152 if (self.options.stickyStartEffectAt < $window.scrollTop()) { 8153 self.options.wrapper.addClass("sticky-effect-active"); 8154 is_backing = true; 8155 8156 $window.trigger("sticky.effect.active"); 8157 } else { 8158 if (is_backing) { 8159 self.options.wrapper 8160 .find(".sticky-body") 8161 .addClass("position-fixed"); 8162 is_backing = false; 8163 } 8164 8165 if ($window.scrollTop() == 0) { 8166 self.options.wrapper 8167 .find(".sticky-body") 8168 .removeClass("position-fixed"); 8169 } 8170 8171 self.options.wrapper.removeClass("sticky-effect-active"); 8172 } 8173 }); 8174 } 8175 8176 // Refresh Sticky Plugin if click in a data-toggle="collapse" 8177 if ($('[data-bs-toggle="collapse"]').get(0)) { 8178 $('[data-bs-toggle="collapse"]').on("click", () => { 8179 setTimeout(() => { 8180 self.build(); 8181 $(window).trigger("scroll"); 8182 }, 1000); 8183 }); 8184 } 8185 } 8186 } 8187 8188 PluginSticky.defaults = { 8189 minWidth: 991, 8190 activeClass: "sticky-active", 8191 }; 8192 8193 // expose to scope 8194 $.extend(theme, { 8195 PluginSticky, 8196 }); 8197 8198 // jquery plugin 8199 $.fn.themePluginSticky = function (opts) { 8200 return this.map(function () { 8201 const $this = $(this); 8202 8203 if ($this.data(instanceName)) { 8204 return $this.data(instanceName); 8205 } else { 8206 return new PluginSticky($this, opts); 8207 } 8208 });
8209 }; 8210}).apply(this, [window.theme, jQuery]); 8211 8212// Toggle 8213((theme = {}, $) => { 8214 const instanceName = "__toggle"; 8215 8216 class PluginToggle { 8217 constructor($el, opts) { 8218 return this.initialize($el, opts); 8219 } 8220 8221 initialize($el, opts) { 8222 if ($el.data(instanceName)) { 8223 return this; 8224 } 8225 8226 this.$el = $el; 8227 8228 this.setData().setOptions(opts).build(); 8229 8230 return this; 8231 } 8232 8233 setData() { 8234 this.$el.data(instanceName, this); 8235 8236 return this; 8237 } 8238 8239 setOptions(opts) { 8240 this.options = $.extend(true, {}, PluginToggle.defaults, opts, { 8241 wrapper: this.$el, 8242 }); 8243 8244 return this; 8245 } 8246 8247 build() { 8248 const self = this; 8249 const $wrapper = this.options.wrapper; 8250 const $items = $wrapper.find("> .toggle"); 8251 let $el = null; 8252 8253 $items.each(function () { 8254 $el = $(this); 8255 8256 if ($el.hasClass("active")) { 8257 $el.find("> p").addClass("preview-active"); 8258 $el.find("> .toggle-content").slideDown(self.options.duration); 8259 } 8260 8261 self.events($el); 8262 }); 8263 8264 if (self.options.isAccordion) { 8265 self.options.duration = self.options.duration / 2; 8266 } 8267 8268 return this; 8269 } 8270 8271 events($el) { 8272 const self = this; 8273 let previewParCurrentHeight = 0; 8274 let previewParAnimateHeight = 0; 8275 let toggleContent = null; 8276 8277 $el.find("> label, > .toggle-title").click(function ({ originalEvent }) { 8278 const $this = $(this); 8279 const parentSection = $this.parent(); 8280 const parentWrapper = $this.parents(".toggle"); 8281 let previewPar = null; 8282 let closeElement = null; 8283 8284 if (self.options.isAccordion && typeof originalEvent != "undefined") { 8285 closeElement = parentWrapper.find( 8286 ".toggle.active > label, .toggle.active > .toggle-title" 8287 ); 8288 8289 if (closeElement[0] == $this[0]) { 8290 return; 8291 } 8292 } 8293 8294 parentSection.toggleClass("active"); 8295 8296 // Preview Paragraph 8297 if (parentSection.find("> p").get(0)) { 8298 previewPar = parentSection.find("> p"); 8299 previewParCurrentHeight = previewPar.css("height"); 8300 previewPar.css("height", "auto"); 8301 previewParAnimateHeight = previewPar.css("height"); 8302 previewPar.css("height", previewParCurrentHeight); 8303 } 8304 8305 // Content 8306 toggleContent = parentSection.find("> .toggle-content"); 8307 8308 if (parentSection.hasClass("active")) { 8309 $(previewPar).animate( 8310 { 8311 height: previewParAnimateHeight, 8312 }, 8313 self.options.duration, 8314 function () { 8315 $(this).addClass("preview-active"); 8316 } 8317 ); 8318 8319 toggleContent.slideDown(self.options.duration, () => { 8320 if (closeElement) { 8321 closeElement.trigger("click"); 8322 } 8323 }); 8324 } else { 8325 $(previewPar).animate( 8326 { 8327 height: 0, 8328 }, 8329 self.options.duration, 8330 function () { 8331 $(this).removeClass("preview-active"); 8332 } 8333 ); 8334 8335 toggleContent.slideUp(self.options.duration); 8336 } 8337 }); 8338 } 8339 } 8340 8341 PluginToggle.defaults = { 8342 duration: 350, 8343 isAccordion: false, 8344 }; 8345 8346 // expose to scope 8347 $.extend(theme, { 8348 PluginToggle, 8349 }); 8350 8351 // jquery plugin 8352 $.fn.themePluginToggle = function (opts) { 8353 return this.map(function () { 8354 const $this = $(this); 8355 8356 if ($this.data(instanceName)) { 8357 return $this.data(instanceName); 8358 } else { 8359 return new PluginToggle($this, opts); 8360 } 8361 }); 8362 }; 8363}).apply(this, [window.theme, jQuery]); 8364 8365// Validation 8366((theme = {}, $) => { 8367 $.extend(theme, { 8368 PluginValidation: { 8369 defaults: { 8370 formClass: "needs-validation", 8371 validator: { 8372 highlight(element) { 8373 $(element) 8374 .addClass("is-invalid") 8375 .removeClass("is-valid") 8376 .parent() 8377 .removeClass("has-success") 8378 .addClass("has-danger"); 8379 }, 8380 success(label, element) { 8381 $(element) 8382 .removeClass("is-invalid") 8383 .addClass("is-valid") 8384 .parent() 8385 .removeClass("has-danger") 8386 .addClass("has-success") 8387 .find("label.error") 8388 .remove(); 8389 }, 8390 errorPlacement(error, element) { 8391 if ( 8392 element.attr("type") == "radio" || 8393 element.attr("type") == "checkbox" 8394 ) { 8395 error.appendTo(element.parent().parent()); 8396 } else { 8397 error.insertAfter(element); 8398 } 8399 }, 8400 }, 8401 }, 8402 8403 initialize(opts) { 8404 initialized = true; 8405 8406 this.setOptions(opts).build(); 8407 8408 return this; 8409 }, 8410 8411 setOptions(opts) { 8412 this.options = $.extend(true, {}, this.defaults, opts); 8413 8414 return this; 8415 }, 8416 8417 build() { 8418 const self = this; 8419 8420 if (!$.isFunction($.validator)) { 8421 return this; 8422 } 8423 8424 self.setMessageGroups(); 8425 8426 $.validator.setDefaults(self.options.validator); 8427
8428 $("." + self.options.formClass).validate(); 8429 8430 return this; 8431 }, 8432 8433 setMessageGroups() { 8434 $( 8435 ".checkbox-group[data-msg-required], .radio-group[data-msg-required]" 8436 ).each(function () { 8437 const message = $(this).data("msg-required"); 8438 $(this).find("input").attr("data-msg-required", message); 8439 }); 8440 }, 8441 }, 8442 }); 8443}).apply(this, [window.theme, jQuery]); 8444 8445// Video Background 8446((theme = {}, $) => { 8447 const instanceName = "__videobackground"; 8448 8449 class PluginVideoBackground { 8450 constructor($el, opts) { 8451 return this.initialize($el, opts); 8452 } 8453 8454 initialize($el, opts) { 8455 this.$el = $el; 8456 8457 this.setData().setOptions(opts).build().events(); 8458 8459 return this; 8460 } 8461 8462 setData() { 8463 this.$el.data(instanceName, this); 8464 8465 return this; 8466 } 8467 8468 setOptions(opts) { 8469 this.options = $.extend(true, {}, PluginVideoBackground.defaults, opts, { 8470 path: this.$el.data("video-path"), 8471 wrapper: this.$el, 8472 }); 8473 8474 return this; 8475 } 8476 8477 build() { 8478 const self = this; 8479 8480 if (!$.isFunction($.fn.vide) || !this.options.path) { 8481 return this; 8482 } 8483 8484 if (this.options.overlay) { 8485 const overlayClass = this.options.overlayClass; 8486 8487 this.options.wrapper.prepend($("<div />").addClass(overlayClass)); 8488 } 8489 8490 this.options.wrapper 8491 .vide(this.options.path, this.options) 8492 .first() 8493 .css("z-index", 0); 8494 8495 // Change Poster 8496 self.changePoster(); 8497 8498 // Initialize Vide inside a carousel 8499 if (self.options.wrapper.closest(".owl-carousel").get(0)) { 8500 self.options.wrapper 8501 .closest(".owl-carousel") 8502 .on("initialized.owl.carousel", () => { 8503 $(".owl-item.cloned") 8504 .find("[data-plugin-video-background] .vide-video-wrapper") 8505 .remove(); 8506 8507 $(".owl-item.cloned") 8508 .find("[data-plugin-video-background]") 8509 .vide(self.options.path, self.options) 8510 .first() 8511 .css("z-index", 0); 8512 8513 self.changePoster(self.options.wrapper.closest(".owl-carousel")); 8514 }); 8515 } 8516 8517 // Play Video Button 8518 const $playButton = self.options.wrapper.find(".video-background-play"); 8519 8520 if ($playButton.get(0)) { 8521 const $playWrapper = self.options.wrapper.find( 8522 ".video-background-play-wrapper" 8523 ); 8524 8525 self.options.wrapper.find(".video-background-play").on("click", (e) => { 8526 e.preventDefault(); 8527 8528 if ($playWrapper.get(0)) { 8529 $playWrapper.animate( 8530 { 8531 opacity: 0, 8532 }, 8533 300, 8534 () => { 8535 $playWrapper.parent().height($playWrapper.outerHeight()); 8536 $playWrapper.remove(); 8537 } 8538 ); 8539 } else { 8540 $playButton.animate( 8541 { 8542 opacity: 0, 8543 }, 8544 300, 8545 () => { 8546 $playButton.remove(); 8547 } 8548 ); 8549 } 8550 8551 setTimeout(() => { 8552 self.options.wrapper.find("video")[0].play(); 8553 }, 500); 8554 }); 8555 } 8556 8557 $(window).trigger("vide.video.inserted.on.dom"); 8558 8559 return this; 8560 } 8561 8562 changePoster($carousel) { 8563 const self = this; 8564 8565 // If it's inside carousel 8566 if ($carousel && self.options.changePoster) { 8567 $carousel 8568 .find(".owl-item [data-plugin-video-background] .vide-video-wrapper") 8569 .css({ 8570 "background-image": "url(" + self.options.changePoster + ")", 8571 }); 8572 8573 return this; 8574 } 8575 8576 if (self.options.changePoster) { 8577 self.options.wrapper.find(".vide-video-wrapper").css({ 8578 "background-image": "url(" + self.options.changePoster + ")", 8579 }); 8580 } 8581 8582 return this; 8583 } 8584 8585 events() { 8586 const self = this; 8587 8588 // Initialize 8589 self.options.wrapper.on("video.background.initialize", () => { 8590 self.build(); 8591 }); 8592 8593 return this; 8594 } 8595 } 8596
8597 PluginVideoBackground.defaults = { 8598 overlay: false, 8599 volume: 1, 8600 playbackRate: 1, 8601 muted: true, 8602 loop: true, 8603 autoplay: true, 8604 position: "50% 50%", 8605 posterType: "detect", 8606 className: "vide-video-wrapper", 8607 }; 8608 8609 // expose to scope 8610 $.extend(theme, { 8611 PluginVideoBackground, 8612 }); 8613 8614 // jquery plugin 8615 $.fn.themePluginVideoBackground = function (opts) { 8616 return this.map(function () { 8617 const $this = $(this); 8618 8619 if ($this.data(instanceName)) { 8620 return $this.data(instanceName); 8621 } else { 8622 return new PluginVideoBackground($this, opts); 8623 } 8624 }); 8625 }; 8626}).apply(this, [window.theme, jQuery]); 8627 8628// Account 8629((theme = {}, $) => { 8630 let initialized = false; 8631 8632 $.extend(theme, { 8633 Account: { 8634 defaults: { 8635 wrapper: $("#headerAccount"), 8636 }, 8637 8638 initialize($wrapper, opts) { 8639 if (initialized) { 8640 return this; 8641 } 8642 8643 initialized = true; 8644 this.$wrapper = $wrapper || this.defaults.wrapper; 8645 8646 this.setOptions(opts).events(); 8647 8648 return this; 8649 }, 8650 8651 setOptions(opts) { 8652 this.options = $.extend( 8653 true, 8654 {}, 8655 this.defaults, 8656 opts, 8657 theme.fn.getOptions(this.$wrapper.data("plugin-options")) 8658 ); 8659 8660 return this; 8661 }, 8662 8663 events() { 8664 const self = this; 8665 8666 $(window).on("load", () => { 8667 $(document).ready(() => { 8668 setTimeout(() => { 8669 self.$wrapper.find("input").on("focus", () => { 8670 self.$wrapper.addClass("open"); 8671 8672 $(document).mouseup(({ target }) => { 8673 if ( 8674 !self.$wrapper.is(target) && 8675 self.$wrapper.has(target).length === 0 8676 ) { 8677 self.$wrapper.removeClass("open"); 8678 } 8679 }); 8680 }); 8681 }, 1500); 8682 }); 8683 }); 8684 8685 $("#headerSignUp").on("click", (e) => { 8686 e.preventDefault(); 8687 self.$wrapper 8688 .addClass("signup") 8689 .removeClass("signin") 8690 .removeClass("recover"); 8691 self.$wrapper.find(".signup-form input:first").focus(); 8692 }); 8693 8694 $("#headerSignIn").on("click", (e) => { 8695 e.preventDefault(); 8696 self.$wrapper 8697 .addClass("signin") 8698 .removeClass("signup") 8699 .removeClass("recover"); 8700 self.$wrapper.find(".signin-form input:first").focus(); 8701 }); 8702 8703 $("#headerRecover").on("click", (e) => { 8704 e.preventDefault(); 8705 self.$wrapper 8706 .addClass("recover") 8707 .removeClass("signup") 8708 .removeClass("signin"); 8709 self.$wrapper.find(".recover-form input:first").focus(); 8710 }); 8711 8712 $("#headerRecoverCancel").on("click", (e) => { 8713 e.preventDefault(); 8714 self.$wrapper 8715 .addClass("signin") 8716 .removeClass("signup") 8717 .removeClass("recover"); 8718 self.$wrapper.find(".signin-form input:first").focus(); 8719 }); 8720 }, 8721 }, 8722 }); 8723}).apply(this, [window.theme, jQuery]); 8724 8725// Nav 8726((theme = {}, $) => { 8727 let initialized = false; 8728 8729 $.extend(theme, { 8730 Nav: { 8731 defaults: { 8732 wrapper: $("#mainNav"), 8733 scrollDelay: 600, 8734 scrollAnimation: "easeOutQuad", 8735 }, 8736 8737 initialize($wrapper, opts) { 8738 if (initialized) { 8739 return this; 8740 } 8741 8742 initialized = true; 8743 this.$wrapper = $wrapper || this.defaults.wrapper; 8744 8745 this.setOptions(opts).build().events(); 8746 8747 return this; 8748 }, 8749 8750 setOptions(opts) { 8751 this.options = $.extend( 8752 true, 8753 {}, 8754 this.defaults, 8755 opts, 8756 theme.fn.getOptions(this.$wrapper.data("plugin-options")) 8757 ); 8758 8759 return this; 8760 }, 8761 8762 build() { 8763 const self = this; 8764 const $html = $("html"); 8765 const $header = $("#header"); 8766 const $headerNavMain = $("#header .header-nav-main"); 8767 let thumbInfoPreview; 8768 8769 // Preview Thumbs 8770 if (self.$wrapper.find("a[data-thumb-preview]").length) { 8771 self.$wrapper.find("a[data-thumb-preview]").each(function () { 8772 thumbInfoPreview = $("<span />") 8773 .addClass("thumb-info thumb-info-preview") 8774 .append( 8775 $("<span />") 8776 .addClass("thumb-info-wrapper") 8777 .append( 8778 $("<span />") 8779 .addClass("thumb-info-image") 8780 .css( 8781 "background-image", 8782 "url(" + $(this).data("thumb-preview") + ")" 8783 ) 8784 ) 8785 ); 8786 8787 $(this).append(thumbInfoPreview); 8788 }); 8789 } 8790 8791 // Side Header / Side Header Hamburguer Sidebar (Reverse Dropdown) 8792 if ( 8793 $html.hasClass("side-header") || 8794 $html.hasClass("side-header-hamburguer-sidebar") 8795 ) { 8796 // Side Header Right / Side Header Hamburguer Sidebar Right 8797 if ( 8798 $html.hasClass("side-header-right") || 8799 $html.hasClass("side-header-hamburguer-sidebar-right") 8800 ) { 8801 if (!$html.hasClass("side-header-right-no-reverse")) { 8802 $header.find(".dropdown-submenu").addClass("dropdown-reverse"); 8803 } 8804 } 8805 } else { 8806 // Reverse 8807 let checkReverseFlag = false; 8808 self.checkReverse = () => { 8809 if (!checkReverseFlag) { 8810 self.$wrapper 8811 .find(".dropdown, .dropdown-submenu") 8812 .removeClass("dropdown-reverse"); 8813 8814 self.$wrapper 8815 .find( 8816 ".dropdown:not(.manual):not(.dropdown-mega), .dropdown-submenu:not(.manual)" 8817 ) 8818 .each(function () { 8819 if ( 8820 !$(this) 8821 .find(".dropdown-menu") 8822 .visible(false, true, "horizontal") 8823 ) { 8824 $(this).addClass("dropdown-reverse"); 8825 } 8826 }); 8827 8828 checkReverseFlag = true; 8829 } 8830 }; 8831 8832 $(window).on("resize", () => { 8833 checkReverseFlag = false; 8834 }); 8835 8836 $header.on("mouseover", () => { 8837 self.checkReverse(); 8838 }); 8839 } 8840 8841 // Clone Items 8842 if ($headerNavMain.hasClass("header-nav-main-clone-items")) { 8843 $headerNavMain.find("nav > ul > li > a").each(function () { 8844 const parent = $(this).parent(), 8845 clone = $(this).clone(), 8846 clone2 = $(this).clone(), 8847 wrapper = $('<span class="wrapper-items-cloned"></span>'); 8848 8849 // Config Classes 8850 $(this).addClass("item-original"); 8851 clone2.addClass("item-two"); 8852 8853 // Insert on DOM
8854 parent.prepend(wrapper); 8855 wrapper.append(clone).append(clone2); 8856 }); 8857 } 8858 8859 // Floating 8860 if ( 8861 $("#header.header-floating-icons").length && 8862 $(window).width() > 991 8863 ) { 8864 const menuFloatingAnim = { 8865 $menuFloating: $( 8866 "#header.header-floating-icons .header-container > .header-row" 8867 ), 8868 8869 build() { 8870 const self = this; 8871 8872 self.init(); 8873 }, 8874 init() { 8875 const self = this; 8876 let divisor = 0; 8877 8878 $(window).scroll(function () { 8879 const scrollPercent = 8880 (100 * $(window).scrollTop()) / 8881 ($(document).height() - $(window).height()), 8882 st = $(this).scrollTop(); 8883 8884 divisor = $(document).height() / $(window).height(); 8885 8886 self.$menuFloating.find(".header-column > .header-row").css({ 8887 transform: 8888 "translateY( calc(" + 8889 scrollPercent + 8890 "vh - " + 8891 st / divisor + 8892 "px) )", 8893 }); 8894 }); 8895 }, 8896 }; 8897 8898 menuFloatingAnim.build(); 8899 } 8900 8901 // Slide 8902 if ($(".header-nav-links-vertical-slide").length) { 8903 const slideNavigation = { 8904 $mainNav: $("#mainNav"), 8905 $mainNavItem: $("#mainNav li"), 8906 8907 build() { 8908 const self = this; 8909 8910 self.menuNav(); 8911 }, 8912 menuNav() { 8913 const self = this; 8914 8915 self.$mainNavItem.on("click", function (e) { 8916 const currentMenuItem = $(this), 8917 currentMenu = $(this).parent(), 8918 nextMenu = $(this).find("ul").first(), 8919 prevMenu = $(this).closest(".next-menu"), 8920 isSubMenu = 8921 currentMenuItem.hasClass("dropdown") || 8922 currentMenuItem.hasClass("dropdown-submenu"), 8923 isBack = currentMenuItem.hasClass("back-button"), 8924 nextMenuHeightDiff = 8925 nextMenu.find("> li").length * 8926 nextMenu.find("> li").outerHeight() - 8927 nextMenu.outerHeight(), 8928 prevMenuHeightDiff = 8929 prevMenu.find("> li").length * 8930 prevMenu.find("> li").outerHeight() - 8931 prevMenu.outerHeight(); 8932 8933 if (isSubMenu) { 8934 currentMenu.addClass("next-menu"); 8935 nextMenu.addClass("visible"); 8936 currentMenu.css({ 8937 overflow: "visible", 8938 "overflow-y": "visible", 8939 }); 8940 8941 if (nextMenuHeightDiff > 0) { 8942 nextMenu.css({ 8943 overflow: "hidden", 8944 "overflow-y": "scroll", 8945 }); 8946 } 8947 8948 for (i = 0; i < nextMenu.find("> li").length; i++) { 8949 if ( 8950 nextMenu.outerHeight() < 8951 $(".header-row-side-header").outerHeight() - 100 8952 ) { 8953 nextMenu.css({ 8954 height: 8955 nextMenu.outerHeight() + 8956 nextMenu.find("> li").outerHeight(), 8957 }); 8958 } 8959 } 8960 8961 nextMenu.css({ 8962 "padding-top": nextMenuHeightDiff + "px", 8963 }); 8964 } 8965 8966 if (isBack) { 8967 currentMenu.parent().parent().removeClass("next-menu"); 8968 currentMenu.removeClass("visible"); 8969 8970 if (prevMenuHeightDiff > 0) { 8971 prevMenu.css({ 8972 overflow: "hidden", 8973 "overflow-y": "scroll", 8974 }); 8975 } 8976 } 8977 8978 e.stopPropagation(); 8979 }); 8980 }, 8981 }; 8982 8983 $(window).trigger("resize"); 8984 8985 if ($(window).width() > 991) { 8986 slideNavigation.build(); 8987 } 8988 8989 $(document).ready(() => { 8990 $(window).afterResize(() => { 8991 if ($(window).width() > 991) { 8992 slideNavigation.build(); 8993 } 8994 }); 8995 }); 8996 } 8997 8998 // Header Nav Main Mobile Dark 8999 if ($(".header-nav-main-mobile-dark").length) { 9000 $( 9001 "#header:not(.header-transparent-dark-bottom-border):not(.header-transparent-light-bottom-border)" 9002 ).addClass("header-no-border-bottom"); 9003 } 9004 9005 // Keyboard Navigation / Accessibility 9006 if ($(window).width() > 991) { 9007 let focusFlag = false; 9008 $header 9009 .find(".header-nav-main nav > ul > li > a") 9010 .on("focus", function () { 9011 if ($(window).width() > 991) { 9012 if (!focusFlag) { 9013 focusFlag = true; 9014 $(this).trigger("blur"); 9015 9016 self.focusMenuWithChildren();
9017 } 9018 } 9019 }); 9020 } 9021 9022 return this; 9023 }, 9024 9025 focusMenuWithChildren() { 9026 // Get all the link elements within the primary menu. 9027 let links; 9028 9029 let i; 9030 let len; 9031 const menu = document.querySelector( 9032 "html:not(.side-header):not(.side-header-hamburguer-sidebar):not(.side-header-overlay-full-screen) .header-nav-main > nav" 9033 ); 9034 9035 if (!menu) { 9036 return false; 9037 } 9038 9039 links = menu.getElementsByTagName("a"); 9040 9041 // Each time a menu link is focused or blurred, toggle focus. 9042 for (i = 0, len = links.length; i < len; i++) { 9043 links[i].addEventListener("focus", toggleFocus, true); 9044 links[i].addEventListener("blur", toggleFocus, true); 9045 } 9046 9047 //Sets or removes the .focus class on an element. 9048 function toggleFocus() { 9049 let self = this; 9050 9051 // Move up through the ancestors of the current link until we hit .primary-menu. 9052 while (!self.className.includes("header-nav-main")) { 9053 // On li elements toggle the class .focus. 9054 if ("li" === self.tagName.toLowerCase()) { 9055 if (self.className.includes("accessibility-open")) { 9056 self.className = self.className.replace( 9057 " accessibility-open", 9058 "" 9059 ); 9060 } else { 9061 self.className += " accessibility-open"; 9062 } 9063 } 9064 self = self.parentElement; 9065 } 9066 } 9067 }, 9068 9069 events() { 9070 const self = this; 9071 const $html = $("html"); 9072 let $header = $("#header"); 9073 const $window = $(window); 9074 let headerBodyHeight = $(".header-body").outerHeight(); 9075 9076 if ($header.hasClass("header")) { 9077 $header = $(".header"); 9078 } 9079 9080 $header.find('a[href="#"]').on("click", (e) => { 9081 e.preventDefault(); 9082 }); 9083 9084 // Mobile Arrows 9085 if ($html.hasClass("side-header-hamburguer-sidebar")) { 9086 $header 9087 .find(".dropdown-toggle, .dropdown-submenu > a") 9088 .append('<i class="fas fa-chevron-down fa-chevron-right"></i>'); 9089 } else { 9090 $header 9091 .find(".dropdown-toggle, .dropdown-submenu > a") 9092 .append('<i class="fas fa-chevron-down"></i>'); 9093 } 9094 9095 $header 9096 .find( 9097 '.dropdown-toggle[href="#"], .dropdown-submenu a[href="#"], .dropdown-toggle[href!="#"] .fa-chevron-down, .dropdown-submenu a[href!="#"] .fa-chevron-down' 9098 ) 9099 .on("click", function (e) { 9100 e.preventDefault(); 9101 if ($window.width() < 992) { 9102 $(this).closest("li").toggleClass("open"); 9103 9104 // Adjust Header Body Height 9105 const height = 9106 $header.hasClass("header-effect-shrink") && 9107 $html.hasClass("sticky-header-active") 9108 ? theme.StickyHeader.options.stickyHeaderContainerHeight 9109 : headerBodyHeight; 9110 $(".header-body").animate( 9111 { 9112 height: 9113 $(".header-nav-main nav").outerHeight(true) + height + 10, 9114 }, 9115 0 9116 ); 9117 } 9118 }); 9119 9120 $header.find("li a.active").addClass("current-page-active"); 9121 9122 // Add Open Class 9123 $header 9124 .find( 9125 '.header-nav-click-to-open .dropdown-toggle[href="#"], .header-nav-click-to-open .dropdown-submenu a[href="#"], .header-nav-click-to-open .dropdown-toggle > i' 9126 ) 9127 .on("click", function (e) { 9128 if ( 9129 !$("html").hasClass("side-header-hamburguer-sidebar") && 9130 $window.width() > 991 9131 ) { 9132 e.preventDefault(); 9133 e.stopPropagation(); 9134 } 9135 9136 if ($window.width() > 991) { 9137 e.preventDefault(); 9138 e.stopPropagation(); 9139 9140 $header.find("li a.active").removeClass("active"); 9141 9142 if ($(this).prop("tagName") == "I") { 9143 $(this).parent().addClass("active"); 9144 } else { 9145 $(this).addClass("active"); 9146 } 9147 9148 if (!$(this).closest("li").hasClass("open")) { 9149 const $li = $(this).closest("li"); 9150 let isSub = false; 9151 9152 if ($(this).prop("tagName") == "I") { 9153 $("#header .dropdown.open").removeClass("open"); 9154 $( 9155 "#header .dropdown-menu .dropdown-submenu.open" 9156 ).removeClass("open"); 9157 } 9158 9159 if ($(this).parent().hasClass("dropdown-submenu")) { 9160 isSub = true; 9161 } 9162 9163 $(this) 9164 .closest(".dropdown-menu") 9165 .find(".dropdown-submenu.open") 9166 .removeClass("open"); 9167 $(this) 9168 .parent(".dropdown") 9169 .parent() 9170 .find(".dropdown.open") 9171 .removeClass("open"); 9172 9173 if (!isSub) { 9174 $(this) 9175 .parent() 9176 .find(".dropdown-submenu.open") 9177 .removeClass("open"); 9178 } 9179 9180 $li.addClass("open"); 9181 9182 $(document)
9183 .off("click.nav-click-to-open") 9184 .on("click.nav-click-to-open", ({ target }) => { 9185 if (!$li.is(target) && $li.has(target).length === 0) { 9186 $li.removeClass("open"); 9187 $li.parents(".open").removeClass("open"); 9188 $header.find("li a.active").removeClass("active"); 9189 $header 9190 .find("li a.current-page-active") 9191 .addClass("active"); 9192 } 9193 }); 9194 } else { 9195 $(this).closest("li").removeClass("open"); 9196 $header.find("li a.active").removeClass("active"); 9197 $header.find("li a.current-page-active").addClass("active"); 9198 } 9199 9200 $window.trigger({ 9201 type: "resize", 9202 from: "header-nav-click-to-open", 9203 }); 9204 } 9205 }); 9206 9207 // Collapse Nav 9208 $header.find("[data-collapse-nav]").on("click", function (e) { 9209 $(this).parents(".collapse").removeClass("show"); 9210 }); 9211 9212 // Top Features 9213 $header.find(".header-nav-features-toggle").on("click", function (e) { 9214 e.preventDefault(); 9215 9216 const $toggleParent = $(this).parent(); 9217 9218 if ( 9219 !$(this).siblings(".header-nav-features-dropdown").hasClass("show") 9220 ) { 9221 const $dropdown = $(this).siblings(".header-nav-features-dropdown"); 9222 9223 $(".header-nav-features-dropdown.show").removeClass("show"); 9224 9225 $dropdown.addClass("show"); 9226 9227 $(document) 9228 .off("click.header-nav-features-toggle") 9229 .on("click.header-nav-features-toggle", ({ target }) => { 9230 if ( 9231 !$toggleParent.is(target) && 9232 $toggleParent.has(target).length === 0 9233 ) { 9234 $(".header-nav-features-dropdown.show").removeClass("show"); 9235 } 9236 }); 9237 9238 if ($(this).attr("data-focus")) { 9239 $("#" + $(this).attr("data-focus")).focus(); 9240 } 9241 } else { 9242 $(this) 9243 .siblings(".header-nav-features-dropdown") 9244 .removeClass("show"); 9245 } 9246 }); 9247 9248 // Hamburguer Menu 9249 const $hamburguerMenuBtn = $(".hamburguer-btn:not(.side-panel-toggle)"), 9250 $hamburguerSideHeader = $( 9251 "#header.side-header, #header.side-header-overlay-full-screen" 9252 ); 9253 9254 $hamburguerMenuBtn.on("click", function () { 9255 if ($(this).attr("data-set-active") != "false") { 9256 $(this).toggleClass("active"); 9257 } 9258 $hamburguerSideHeader.toggleClass("side-header-hide"); 9259 $html.toggleClass("side-header-hide"); 9260 9261 $window.trigger("resize"); 9262 }); 9263 9264 // Toggle Side Header 9265 $(".toggle-side-header").on("click", () => { 9266 $(".hamburguer-btn-side-header.active").trigger("click"); 9267 }); 9268 9269 $(".hamburguer-close:not(.side-panel-toggle)").on("click", () => { 9270 $( 9271 ".hamburguer-btn:not(.hamburguer-btn-side-header-mobile-show)" 9272 ).trigger("click"); 9273 }); 9274 9275 // Set Header Body Height when open mobile menu 9276 $(".header-nav-main nav").on("show.bs.collapse", function () { 9277 $(this).removeClass("closed"); 9278 9279 // Add Mobile Menu Opened Class 9280 $("html").addClass("mobile-menu-opened"); 9281 9282 $(".header-body").animate({ 9283 height: 9284 $(".header-body").outerHeight() + 9285 $(".header-nav-main nav").outerHeight(true) + 9286 10, 9287 }); 9288 9289 // Header Below Slider / Header Bottom Slider - Scroll to menu position 9290 if ( 9291 $("#header").is(".header-bottom-slider, .header-below-slider") && 9292 !$("html").hasClass("sticky-header-active") 9293 ) { 9294 self.scrollToTarget($("#header"), 0); 9295 } 9296 }); 9297 9298 // Set Header Body Height when collapse mobile menu 9299 $(".header-nav-main nav").on("hide.bs.collapse", function () { 9300 $(this).addClass("closed"); 9301 9302 // Remove Mobile Menu Opened Class 9303 $("html").removeClass("mobile-menu-opened"); 9304 9305 $(".header-body").animate( 9306 { 9307 height: 9308 $(".header-body").outerHeight() - 9309 $(".header-nav-main nav").outerHeight(true), 9310 }, 9311 function () { 9312 $(this).height("auto"); 9313 } 9314 ); 9315 }); 9316 9317 // Header Effect Shrink - Adjust header body height on mobile 9318 $window.on("stickyHeader.activate", () => { 9319 if ( 9320 $window.width() < 992 && 9321 $header.hasClass("header-effect-shrink") 9322 ) { 9323 if ($(".header-btn-collapse-nav").attr("aria-expanded") == "true") { 9324 $(".header-body").animate({ 9325 height: 9326 $(".header-nav-main nav").outerHeight(true) + 9327 theme.StickyHeader.options.stickyHeaderContainerHeight + 9328 ($(".header-nav-bar").length 9329 ? $(".header-nav-bar").outerHeight() 9330 : 0), 9331 }); 9332 } 9333 } 9334 }); 9335 9336 $window.on("stickyHeader.deactivate", () => { 9337 if ( 9338 $window.width() < 992 && 9339 $header.hasClass("header-effect-shrink") 9340 ) { 9341 if ($(".header-btn-collapse-nav").attr("aria-expanded") == "true") { 9342 $(".header-body").animate({ 9343 height: 9344 headerBodyHeight + 9345 $(".header-nav-main nav").outerHeight(true) + 9346 10, 9347 }); 9348 } 9349 } 9350 }); 9351 9352 // Remove Open Class on Resize 9353 $window.on("resize.removeOpen", ({ from }) => { 9354 if (from == "header-nav-click-to-open") { 9355 return; 9356 } 9357 9358 setTimeout(() => { 9359 if ($window.width() > 991) { 9360 $header.find(".dropdown.open").removeClass("open"); 9361 } 9362 }, 100); 9363 }); 9364 9365 // Side Header - Change value of initial header body height 9366 $(document).ready(() => { 9367 if ($window.width() > 991) { 9368 let flag = false; 9369 9370 $window.on("resize", ({ from }) => { 9371 if (from == "header-nav-click-to-open") { 9372 return; 9373 } 9374 9375 $header.find(".dropdown.open").removeClass("open"); 9376 9377 if ($window.width() < 992 && flag == false) { 9378 headerBodyHeight = $(".header-body").outerHeight(); 9379 flag = true; 9380 9381 setTimeout(() => { 9382 flag = false; 9383 }, 500); 9384 } 9385 }); 9386 } 9387 }); 9388 9389 // Side Header - Set header height on mobile 9390 if ($html.hasClass("side-header")) { 9391 if ($window.width() < 992) { 9392 $header.css({ 9393 height: 9394 $(".header-body .header-container").outerHeight() + 9395 (parseInt($(".header-body").css("border-top-width")) + 9396 parseInt($(".header-body").css("border-bottom-width"))), 9397 }); 9398 } 9399 9400 $(document).ready(() => { 9401 $window.afterResize(() => { 9402 if ($window.width() < 992) { 9403 $header.css({ 9404 height: 9405 $(".header-body .header-container").outerHeight() + 9406 (parseInt($(".header-body").css("border-top-width")) + 9407 parseInt($(".header-body").css("border-bottom-width"))), 9408 }); 9409 } else { 9410 $header.css({ 9411 height: "", 9412 }); 9413 } 9414 }); 9415 }); 9416 } 9417 9418 // Anchors Position 9419 if ($("[data-hash]").length) { 9420 $("[data-hash]").on("mouseover", function () { 9421 const $this = $(this); 9422 9423 if (!$this.data("__dataHashBinded")) { 9424 let target = $this.attr("href"); 9425 let offset = $this.is("[data-hash-offset]") 9426 ? $this.data("hash-offset") 9427 : 0;
9428 const delay = $this.is("[data-hash-delay]") 9429 ? $this.data("hash-delay") 9430 : 0; 9431 const force = $this.is("[data-hash-force]") ? true : false; 9432 const windowWidth = $(window).width(); 9433 9434 // Hash Offset SM 9435 if ($this.is("[data-hash-offset-sm]") && windowWidth > 576) { 9436 offset = $this.data("hash-offset-sm"); 9437 } 9438 9439 // Hash Offset MD 9440 if ($this.is("[data-hash-offset-md]") && windowWidth > 768) { 9441 offset = $this.data("hash-offset-md"); 9442 } 9443 9444 // Hash Offset LG 9445 if ($this.is("[data-hash-offset-lg]") && windowWidth > 992) { 9446 offset = $this.data("hash-offset-lg"); 9447 } 9448 9449 // Hash Offset XL 9450 if ($this.is("[data-hash-offset-xl]") && windowWidth > 1200) { 9451 offset = $this.data("hash-offset-xl"); 9452 } 9453 9454 // Hash Offset XXL 9455 if ($this.is("[data-hash-offset-xxl]") && windowWidth > 1400) { 9456 offset = $this.data("hash-offset-xxl"); 9457 } 9458 9459 if (!$(target).length) { 9460 target = target.split("#"); 9461 target = "#" + target[1]; 9462 } 9463 9464 if (target.includes("#") && $(target).length) { 9465 $this.on("click", (e) => { 9466 e.preventDefault(); 9467 9468 if (!$(e.target).is("i") || force) { 9469 setTimeout(() => { 9470 // Close Collapse if open 9471 $this.parents(".collapse.show").collapse("hide"); 9472 9473 // Close Side Header 9474 $hamburguerSideHeader.addClass("side-header-hide"); 9475 $html.addClass("side-header-hide"); 9476 9477 $window.trigger("resize"); 9478 9479 self.scrollToTarget(target, offset); 9480 9481 // Data Hash Trigger Click 9482 if ($this.data("hash-trigger-click")) { 9483 const $clickTarget = $( 9484 $this.data("hash-trigger-click") 9485 ), 9486 clickDelay = $this.data("hash-trigger-click-delay") 9487 ? $this.data("hash-trigger-click-delay") 9488 : 0; 9489 9490 if ($clickTarget.length) { 9491 setTimeout(() => { 9492 // If is a "Tabs" plugin link 9493 if ($clickTarget.closest(".nav-tabs").length) { 9494 new bootstrap.Tab($clickTarget[0]).show(); 9495 } else { 9496 $clickTarget.trigger("click"); 9497 } 9498 }, clickDelay); 9499 } 9500 } 9501 }, delay); 9502 } 9503 9504 return; 9505 }); 9506 } 9507 9508 $(this).data("__dataHashBinded", true); 9509 } 9510 }); 9511 } 9512 9513 // Floating 9514 if ($("#header.header-floating-icons").length) { 9515 $("#header.header-floating-icons [data-hash]") 9516 .off() 9517 .each(function () { 9518 const target = $(this).attr("href"), 9519 offset = $(this).is("[data-hash-offset]") 9520 ? $(this).data("hash-offset") 9521 : 0; 9522 9523 if ($(target).length) { 9524 $(this).on("click", (e) => { 9525 e.preventDefault(); 9526 9527 $("html, body").animate( 9528 { 9529 scrollTop: $(target).offset().top - offset, 9530 }, 9531 600, 9532 "easeOutQuad", 9533 () => {} 9534 ); 9535 9536 return; 9537 }); 9538 } 9539 }); 9540 } 9541 9542 // Side Panel Toggle 9543 if ($(".side-panel-toggle").length) { 9544 const init_html_class = $("html").attr("class"); 9545 9546 $(".side-panel-toggle").on("click", function (e) { 9547 const extra_class = $(this).data("extra-class"),
9548 delay = extra_class ? 100 : 0, 9549 isActive = $(this).data("is-active") 9550 ? $(this).data("is-active") 9551 : false; 9552 9553 e.preventDefault(); 9554 9555 if (isActive) { 9556 $("html").removeClass("side-panel-open"); 9557 $(this).data("is-active", false); 9558 return false; 9559 } 9560 9561 if (extra_class) { 9562 $(".side-panel-wrapper").css("transition", "none"); 9563 $("html") 9564 .removeClass() 9565 .addClass(init_html_class) 9566 .addClass(extra_class); 9567 } 9568 setTimeout(() => { 9569 $(".side-panel-wrapper").css("transition", ""); 9570 $("html").toggleClass("side-panel-open"); 9571 }, delay); 9572 9573 $(this).data("is-active", true); 9574 }); 9575 9576 $(document).on("click", ({ target }) => { 9577 if ( 9578 !$(target).closest(".side-panel-wrapper").length && 9579 !$(target).hasClass("side-panel-toggle") 9580 ) { 9581 $( 9582 ".hamburguer-btn.side-panel-toggle:not(.side-panel-close)" 9583 ).removeClass("active"); 9584 $("html").removeClass("side-panel-open"); 9585 $(".side-panel-toggle").data("is-active", false); 9586 } 9587 }); 9588 } 9589 9590 return this; 9591 }, 9592 9593 scrollToTarget(target, offset) { 9594 const self = this, 9595 targetPosition = $(target).offset().top; 9596 9597 $("body").addClass("scrolling"); 9598 9599 $("html, body").animate( 9600 { 9601 scrollTop: $(target).offset().top - offset, 9602 }, 9603 self.options.scrollDelay, 9604 self.options.scrollAnimation, 9605 () => { 9606 $("body").removeClass("scrolling"); 9607 9608 // If by some reason the scroll finishes in a wrong position, this code will run the scrollToTarget() again until get the correct position 9609 // We need do it just one time to prevent infinite recursive loop at scrollToTarget() function 9610 if ($(target).offset().top != targetPosition) { 9611 $("html, body").animate( 9612 { 9613 scrollTop: $(target).offset().top - offset, 9614 }, 9615 1, 9616 self.options.scrollAnimation, 9617 () => {} 9618 ); 9619 } 9620 } 9621 ); 9622 9623 return this; 9624 }, 9625 }, 9626 }); 9627}).apply(this, [window.theme, jQuery]); 9628 9629// Newsletter 9630((theme = {}, $) => { 9631 let initialized = false; 9632 9633 $.extend(theme, { 9634 Newsletter: { 9635 defaults: { 9636 wrapper: $("#newsletterForm"), 9637 }, 9638 9639 initialize($wrapper, opts) { 9640 if (initialized) { 9641 return this; 9642 } 9643 9644 initialized = true; 9645 this.$wrapper = $wrapper || this.defaults.wrapper; 9646 9647 this.setOptions(opts).build(); 9648 9649 return this; 9650 }, 9651 9652 setOptions(opts) { 9653 this.options = $.extend( 9654 true, 9655 {}, 9656 this.defaults, 9657 opts, 9658 theme.fn.getOptions(this.$wrapper.data("plugin-options")) 9659 ); 9660 9661 return this; 9662 }, 9663 9664 build() { 9665 if (!$.isFunction($.fn.validate)) { 9666 return this; 9667 } 9668 9669 const self = this, 9670 $email = self.$wrapper.find("#newsletterEmail"), 9671 $success = $("#newsletterSuccess"), 9672 $error = $("#newsletterError"); 9673 9674 self.$wrapper.validate({ 9675 submitHandler(form) { 9676 $.ajax({
9677 type: "POST", 9678 url: self.$wrapper.attr("action"), 9679 data: { 9680 email: $email.val(), 9681 }, 9682 dataType: "json", 9683 success({ response, message }) { 9684 if (response == "success") { 9685 $success.removeClass("d-none"); 9686 $error.addClass("d-none"); 9687 9688 $email 9689 .val("") 9690 .blur() 9691 .closest(".control-group") 9692 .removeClass("success") 9693 .removeClass("error"); 9694 } else { 9695 $error.html(message); 9696 $error.removeClass("d-none"); 9697 $success.addClass("d-none"); 9698 9699 $email 9700 .blur() 9701 .closest(".control-group") 9702 .removeClass("success") 9703 .addClass("error"); 9704 } 9705 }, 9706 }); 9707 }, 9708 rules: { 9709 newsletterEmail: { 9710 required: true, 9711 email: true, 9712 }, 9713 }, 9714 errorPlacement(error, element) {}, 9715 }); 9716 9717 return this; 9718 }, 9719 }, 9720 }); 9721}).apply(this, [window.theme, jQuery]); 9722 9723// Search 9724((theme = {}, $) => { 9725 let initialized = false; 9726 9727 $.extend(theme, { 9728 Search: { 9729 defaults: { 9730 wrapper: $("#searchForm"), 9731 }, 9732 9733 initialize($wrapper, opts) { 9734 if (initialized) { 9735 return this; 9736 } 9737 9738 initialized = true; 9739 this.$wrapper = $wrapper || this.defaults.wrapper; 9740 9741 this.setOptions(opts).build(); 9742 9743 return this; 9744 }, 9745 9746 setOptions(opts) { 9747 this.options = $.extend( 9748 true, 9749 {}, 9750 this.defaults, 9751 opts, 9752 theme.fn.getOptions(this.$wrapper.data("plugin-options")) 9753 ); 9754 9755 return this; 9756 }, 9757 9758 build() { 9759 if (!$.isFunction($.fn.validate)) { 9760 return this; 9761 } 9762 9763 this.$wrapper.validate({ 9764 errorPlacement(error, element) {}, 9765 }); 9766 9767 // Search Reveal 9768 theme.fn.execOnceTroughEvent( 9769 "#header", 9770 "mouseover.search.reveal", 9771 () => { 9772 $(".header-nav-features-search-reveal").each(function () { 9773 const $el = $(this), 9774 $header = $("#header"), 9775 $html = $("html"); 9776 9777 $el 9778 .find(".header-nav-features-search-show-icon") 9779 .on("click", () => { 9780 $el.addClass("show"); 9781 $header.addClass("search-show"); 9782 $html.addClass("search-show"); 9783 $("#headerSearch").focus(); 9784 }); 9785 9786 $el 9787 .find(".header-nav-features-search-hide-icon") 9788 .on("click", () => { 9789 $el.removeClass("show"); 9790 $header.removeClass("search-show"); 9791 $html.removeClass("search-show"); 9792 }); 9793 }); 9794 } 9795 ); 9796 9797 return this; 9798 }, 9799 }, 9800 }); 9801}).apply(this, [window.theme, jQuery]); 9802 9803// Sticky Header 9804((theme = {}, $) => { 9805 let initialized = false; 9806 9807 $.extend(theme, { 9808 StickyHeader: { 9809 defaults: { 9810 wrapper: $("#header"), 9811 headerBody: $("#header .header-body"), 9812 stickyEnabled: true, 9813 stickyEnableOnBoxed: true, 9814 stickyEnableOnMobile: false, 9815 stickyStartAt: 0, 9816 stickyStartAtElement: false, 9817 stickySetTop: 0, 9818 stickyEffect: "", 9819 stickyHeaderContainerHeight: false, 9820 stickyChangeLogo: false, 9821 stickyChangeLogoWrapper: true, 9822 stickyForce: false, 9823 stickyScrollUp: false, 9824 stickyScrollValue: 0, 9825 }, 9826 9827 initialize($wrapper, opts) { 9828 if (initialized) { 9829 return this; 9830 } 9831 9832 initialized = true; 9833 this.$wrapper = $wrapper || this.defaults.wrapper; 9834 9835 if (this.$wrapper.hasClass("header")) {
9836 this.$wrapper = $(".header[data-plugin-options]"); 9837 } 9838 9839 this.setOptions(opts).build().events(); 9840 9841 return this; 9842 }, 9843 9844 setOptions(opts) { 9845 this.options = $.extend( 9846 true, 9847 {}, 9848 this.defaults, 9849 opts, 9850 theme.fn.getOptions(this.$wrapper.data("plugin-options")) 9851 ); 9852 return this; 9853 }, 9854 9855 build() { 9856 if ( 9857 $(window).width() < 992 && 9858 this.options.stickyEnableOnMobile == false 9859 ) { 9860 $("html").addClass("sticky-header-mobile-disabled"); 9861 return this; 9862 } 9863 9864 if ( 9865 (!this.options.stickyEnableOnBoxed && $("html").hasClass("boxed")) || 9866 ($("html").hasClass("side-header-hamburguer-sidebar") && 9867 !this.options.stickyForce) || 9868 !this.options.stickyEnabled 9869 ) { 9870 return this; 9871 } 9872 9873 const self = this; 9874 9875 if (self.options.wrapper.hasClass("header")) { 9876 self.options.wrapper = $(".header"); 9877 self.options.headerBody = $(".header .header-body"); 9878 } 9879 9880 const $html = $("html"); 9881 const $window = $(window); 9882 const sideHeader = $html.hasClass("side-header"); 9883 const initialHeaderTopHeight = self.options.wrapper 9884 .find(".header-top") 9885 .outerHeight(); 9886 const initialHeaderContainerHeight = self.options.wrapper 9887 .find(".header-container") 9888 .outerHeight(); 9889 let minHeight; 9890 9891 // HTML Classes 9892 $html.addClass("sticky-header-enabled"); 9893 9894 if (parseInt(self.options.stickySetTop) < 0) { 9895 $html.addClass("sticky-header-negative"); 9896 } 9897 9898 if (self.options.stickyScrollUp) { 9899 $html.addClass("sticky-header-scroll-direction"); 9900 } 9901 9902 // Notice Top Bar First Load 9903 if ($(".notice-top-bar").get(0)) { 9904 if ( 9905 parseInt(self.options.stickySetTop) == 1 || 9906 self.options.stickyEffect == "shrink" 9907 ) { 9908 $(".body").on( 9909 "transitionend webkitTransitionEnd oTransitionEnd", 9910 () => { 9911 setTimeout(() => { 9912 if (!$html.hasClass("sticky-header-active")) { 9913 self.options.headerBody.animate( 9914 { 9915 top: $(".notice-top-bar").outerHeight(), 9916 }, 9917 300, 9918 () => { 9919 if ($html.hasClass("sticky-header-active")) { 9920 self.options.headerBody.css("top", 0); 9921 } 9922 } 9923 ); 9924 } 9925 }, 0); 9926 } 9927 ); 9928 } 9929 } 9930 9931 // Set Start At 9932 if (self.options.stickyStartAtElement) { 9933 const $stickyStartAtElement = $(self.options.stickyStartAtElement); 9934 9935 $(window).on("scroll resize sticky.header.resize", () => { 9936 self.options.stickyStartAt = $stickyStartAtElement.offset().top; 9937 }); 9938 9939 $(window).trigger("sticky.header.resize"); 9940 } 9941 9942 // Define Min Height value 9943 if (self.options.wrapper.find(".header-top").get(0)) { 9944 minHeight = initialHeaderTopHeight + initialHeaderContainerHeight; 9945 } else { 9946 minHeight = initialHeaderContainerHeight; 9947 } 9948 9949 // Set Wrapper Min-Height 9950 if (!sideHeader) { 9951 if (!$(".header-logo-sticky-change").get(0)) { 9952 self.options.wrapper.css( 9953 "height", 9954 self.options.headerBody.outerHeight() 9955 ); 9956 } else { 9957 $window.on("stickyChangeLogo.loaded", () => { 9958 self.options.wrapper.css( 9959 "height", 9960 self.options.headerBody.outerHeight() 9961 ); 9962 }); 9963 } 9964 9965 if (self.options.stickyEffect == "shrink") { 9966 // Prevent wrong visualization of header when reload on middle of page 9967 $(document).ready(() => { 9968 if ($window.scrollTop() >= self.options.stickyStartAt) { 9969 self.options.wrapper 9970 .find(".header-container") 9971 .on( 9972 "transitionend webkitTransitionEnd oTransitionEnd", 9973 () => { 9974 self.options.headerBody.css("position", "fixed"); 9975 } 9976 ); 9977 } else { 9978 if (!$html.hasClass("boxed")) { 9979 self.options.headerBody.css("position", "fixed"); 9980 } 9981 } 9982 }); 9983 9984 self.options.wrapper 9985 .find(".header-container") 9986 .css("height", initialHeaderContainerHeight); 9987 self.options.wrapper 9988 .find(".header-top") 9989 .css("height", initialHeaderTopHeight); 9990 } 9991 } 9992 9993 // Sticky Header Container Height 9994 if (self.options.stickyHeaderContainerHeight) { 9995 self.options.wrapper 9996 .find(".header-container") 9997 .css( 9998 "height", 9999 self.options.wrapper.find(".header-container").outerHeight() 10000 ); 10001 } 10002 10003 // Boxed 10004 if ($html.hasClass("boxed") && self.options.stickyEffect == "shrink") { 10005 self.boxedLayout(); 10006 } 10007 10008 // Check Sticky Header / Flags prevent multiple runs at same time 10009 let activate_flag = true; 10010 10011 let deactivate_flag = false; 10012 const initialStickyStartAt = self.options.stickyStartAt; 10013 10014 self.checkStickyHeader = () => { 10015 // Notice Top Bar 10016 const $noticeTopBar = $(".notice-top-bar"); 10017 if ($noticeTopBar.get(0)) { 10018 self.options.stickyStartAt = $noticeTopBar.data("sticky-start-at") 10019 ? $noticeTopBar.data("sticky-start-at") 10020 : $(".notice-top-bar").outerHeight(); 10021 } else { 10022 if ($html.hasClass("boxed")) { 10023 self.options.stickyStartAt = initialStickyStartAt + 25; 10024 } else { 10025 self.options.stickyStartAt = initialStickyStartAt; 10026 } 10027 } 10028 10029 if ($window.width() > 991 && $html.hasClass("side-header")) { 10030 $html.removeClass("sticky-header-active"); 10031 activate_flag = true; 10032 return; 10033 } 10034 10035 if ($window.scrollTop() >= parseInt(self.options.stickyStartAt)) { 10036 if (activate_flag) { 10037 self.activateStickyHeader(); 10038 activate_flag = false; 10039 deactivate_flag = true; 10040 } 10041 } else { 10042 if (deactivate_flag) { 10043 self.deactivateStickyHeader(); 10044 deactivate_flag = false; 10045 activate_flag = true; 10046 } 10047 } 10048 10049 // Scroll Up 10050 if (self.options.stickyScrollUp) { 10051 // Get the new Value 10052 self.options.stickyScrollNewValue = window.pageYOffset; 10053 10054 //Subtract the two and conclude 10055 if ( 10056 self.options.stickyScrollValue - 10057 self.options.stickyScrollNewValue < 10058 0 10059 ) { 10060 $html 10061 .removeClass("sticky-header-scroll-up") 10062 .addClass("sticky-header-scroll-down"); 10063 } else if ( 10064 self.options.stickyScrollValue - 10065 self.options.stickyScrollNewValue > 10066 0 10067 ) { 10068 $html 10069 .removeClass("sticky-header-scroll-down") 10070 .addClass("sticky-header-scroll-up"); 10071 } 10072 10073 // Update the old value 10074 self.options.stickyScrollValue = self.options.stickyScrollNewValue; 10075 } 10076 }; 10077 10078 // Activate Sticky Header 10079 self.activateStickyHeader = () => { 10080 if ($window.width() < 992) { 10081 if (self.options.stickyEnableOnMobile == false) { 10082 self.deactivateStickyHeader(); 10083 self.options.headerBody.css({ 10084 position: "relative", 10085 }); 10086 return false; 10087 } 10088 } else { 10089 if (sideHeader) { 10090 self.deactivateStickyHeader(); 10091 return; 10092 } 10093 } 10094 10095 $html.addClass("sticky-header-active"); 10096 10097 // Sticky Effect - Reveal 10098 if (self.options.stickyEffect == "reveal") { 10099 self.options.headerBody.css( 10100 "top", 10101 "-" + self.options.stickyStartAt + "px" 10102 ); 10103 10104 self.options.headerBody.animate( 10105 { 10106 top: self.options.stickySetTop, 10107 }, 10108 400, 10109 () => {} 10110 ); 10111 } 10112 10113 // Sticky Effect - Shrink 10114 if (self.options.stickyEffect == "shrink") { 10115 // If Header Top 10116 if (self.options.wrapper.find(".header-top").get(0)) { 10117 self.options.wrapper.find(".header-top").css({ 10118 height: 0, 10119 "min-height": 0, 10120 overflow: "hidden", 10121 }); 10122 } 10123 10124 // Header Container 10125 if (self.options.stickyHeaderContainerHeight) { 10126 self.options.wrapper.find(".header-container").css({ 10127 height: self.options.stickyHeaderContainerHeight, 10128 "min-height": 0, 10129 }); 10130 } else { 10131 self.options.wrapper.find(".header-container").css({ 10132 height: (initialHeaderContainerHeight / 3) * 2, // two third of container height 10133 "min-height": 0, 10134 }); 10135 10136 const y = 10137 initialHeaderContainerHeight - 10138 (initialHeaderContainerHeight / 3) * 2; 10139 $(".main") 10140 .css({ 10141 transform: "translate3d(0, -" + y + "px, 0)", 10142 transition: "ease transform 300ms", 10143 }) 10144 .addClass("has-sticky-header-transform"); 10145 10146 if ($html.hasClass("boxed")) { 10147 self.options.headerBody.css("position", "fixed"); 10148 } 10149 } 10150 } 10151 10152 self.options.headerBody.css("top", self.options.stickySetTop); 10153 10154 if (self.options.stickyChangeLogo) { 10155 self.changeLogo(true); 10156 } 10157 10158 // Set Elements Style 10159 if ($("[data-sticky-header-style]").length) { 10160 $("[data-sticky-header-style]").each(function () { 10161 const $el = $(this), 10162 css = theme.fn.getOptions( 10163 $el.data("sticky-header-style-active") 10164 ), 10165 opts = theme.fn.getOptions($el.data("sticky-header-style"));
10166 10167 if ($window.width() > opts.minResolution) { 10168 $el.css(css); 10169 } 10170 }); 10171 } 10172 10173 $.event.trigger({ 10174 type: "stickyHeader.activate", 10175 }); 10176 }; 10177 10178 // Deactivate Sticky Header 10179 self.deactivateStickyHeader = () => { 10180 $html.removeClass("sticky-header-active"); 10181 10182 if ( 10183 $(window).width() < 992 && 10184 self.options.stickyEnableOnMobile == false 10185 ) { 10186 return false; 10187 } 10188 10189 // Sticky Effect - Shrink 10190 if (self.options.stickyEffect == "shrink") { 10191 // Boxed Layout 10192 if ($html.hasClass("boxed")) { 10193 // Set Header Body Position Absolute 10194 self.options.headerBody.css("position", "absolute"); 10195 10196 if ($window.scrollTop() > $(".body").offset().top) { 10197 // Set Header Body Position Fixed 10198 self.options.headerBody.css("position", "fixed"); 10199 } 10200 } else { 10201 // Set Header Body Position Fixed 10202 self.options.headerBody.css("position", "fixed"); 10203 } 10204 10205 // If Header Top 10206 if (self.options.wrapper.find(".header-top").get(0)) { 10207 self.options.wrapper.find(".header-top").css({ 10208 height: initialHeaderTopHeight, 10209 overflow: "visible", 10210 }); 10211 10212 // Fix [data-icon] issue when first load is on middle of the page 10213 if (self.options.wrapper.find(".header-top [data-icon]").length) { 10214 theme.fn.intObsInit( 10215 ".header-top [data-icon]:not(.svg-inline--fa)", 10216 "themePluginIcon" 10217 ); 10218 } 10219 } 10220 10221 // Header Container 10222 self.options.wrapper.find(".header-container").css({ 10223 height: initialHeaderContainerHeight, 10224 }); 10225 } 10226 10227 self.options.headerBody.css("top", 0); 10228 10229 if (self.options.stickyChangeLogo) { 10230 self.changeLogo(false); 10231 } 10232 10233 // Set Elements Style 10234 if ($("[data-sticky-header-style]").length) { 10235 $("[data-sticky-header-style]").each(function () { 10236 const $el = $(this), 10237 css = theme.fn.getOptions( 10238 $el.data("sticky-header-style-deactive") 10239 ), 10240 opts = theme.fn.getOptions($el.data("sticky-header-style")); 10241 10242 if ($window.width() > opts.minResolution) { 10243 $el.css(css); 10244 } 10245 }); 10246 } 10247 10248 $.event.trigger({ 10249 type: "stickyHeader.deactivate", 10250 }); 10251 }; 10252 10253 // Always Sticky 10254 if (parseInt(self.options.stickyStartAt) <= 0) { 10255 self.activateStickyHeader(); 10256 } 10257 10258 // Set Logo 10259 if (self.options.stickyChangeLogo) { 10260 const $logoWrapper = self.options.wrapper.find(".header-logo"), 10261 $logo = $logoWrapper.find("img"), 10262 logoWidth = $logo.attr("width"), 10263 logoHeight = $logo.attr("height"), 10264 logoSmallTop = parseInt( 10265 $logo.attr("data-sticky-top") ? $logo.attr("data-sticky-top") : 0 10266 ), 10267 logoSmallWidth = parseInt( 10268 $logo.attr("data-sticky-width") 10269 ? $logo.attr("data-sticky-width") 10270 : "auto" 10271 ), 10272 logoSmallHeight = parseInt( 10273 $logo.attr("data-sticky-height") 10274 ? $logo.attr("data-sticky-height") 10275 : "auto" 10276 ); 10277 10278 if (self.options.stickyChangeLogoWrapper) { 10279 $logoWrapper.css({ 10280 width: $logo.outerWidth(true), 10281 height: $logo.outerHeight(true), 10282 }); 10283 } 10284 10285 self.changeLogo = (activate) => { 10286 if (activate) { 10287 $logo.css({ 10288 top: logoSmallTop, 10289 width: logoSmallWidth, 10290 height: logoSmallHeight, 10291 }); 10292 } else { 10293 $logo.css({ 10294 top: 0, 10295 width: logoWidth, 10296 height: logoHeight, 10297 }); 10298 } 10299 }; 10300 10301 $.event.trigger({ 10302 type: "stickyChangeLogo.loaded", 10303 }); 10304 } 10305 10306 // Side Header 10307 let headerBodyHeight, 10308 flag = false; 10309 10310 self.checkSideHeader = () => { 10311 if ($window.width() < 992 && flag == false) { 10312 headerBodyHeight = self.options.headerBody.height(); 10313 flag = true; 10314 } 10315 10316 if (self.options.stickyStartAt == 0 && sideHeader) { 10317 self.options.wrapper.css("min-height", 0); 10318 } 10319 10320 if ( 10321 self.options.stickyStartAt > 0 && 10322 sideHeader && 10323 $window.width() < 992
10324 ) { 10325 self.options.wrapper.css("min-height", headerBodyHeight); 10326 } 10327 }; 10328 10329 return this; 10330 }, 10331 10332 events() { 10333 const self = this; 10334 10335 if ( 10336 $(window).width() < 992 && 10337 this.options.stickyEnableOnMobile == false 10338 ) { 10339 return this; 10340 } 10341 10342 if ( 10343 (!this.options.stickyEnableOnBoxed && $("body").hasClass("boxed")) || 10344 ($("html").hasClass("side-header-hamburguer-sidebar") && 10345 !this.options.stickyForce) || 10346 !this.options.stickyEnabled 10347 ) { 10348 return this; 10349 } 10350 10351 if (!self.options.alwaysStickyEnabled) { 10352 $(window).on("scroll resize", () => { 10353 if ( 10354 $(window).width() < 992 && 10355 self.options.stickyEnableOnMobile == false 10356 ) { 10357 self.options.headerBody.css({ 10358 position: "", 10359 }); 10360 10361 if (self.options.stickyEffect == "shrink") { 10362 self.options.wrapper.find(".header-top").css({ 10363 height: "", 10364 }); 10365 } 10366 10367 self.deactivateStickyHeader(); 10368 } else { 10369 self.checkStickyHeader(); 10370 } 10371 }); 10372 } else { 10373 self.activateStickyHeader(); 10374 } 10375 10376 $(window).on("load resize", () => { 10377 self.checkSideHeader(); 10378 }); 10379 10380 $(window).on("layout.boxed", () => { 10381 self.boxedLayout(); 10382 }); 10383 10384 return this; 10385 }, 10386 10387 boxedLayout() { 10388 const self = this, 10389 $window = $(window); 10390 10391 if ( 10392 $("html").hasClass("boxed") && 10393 self.options.stickyEffect == "shrink" 10394 ) { 10395 if ( 10396 parseInt(self.options.stickyStartAt) == 0 && 10397 $window.width() > 991 10398 ) { 10399 self.options.stickyStartAt = 30; 10400 } 10401 10402 // Set Header Body Position Absolute 10403 self.options.headerBody.css({ 10404 position: "absolute", 10405 top: 0, 10406 }); 10407 10408 // Set position absolute because top margin from boxed layout 10409 $window.on("scroll", () => { 10410 if ($window.scrollTop() > $(".body").offset().top) { 10411 self.options.headerBody.css({ 10412 position: "fixed", 10413 top: 0, 10414 }); 10415 } else { 10416 self.options.headerBody.css({ 10417 position: "absolute", 10418 top: 0, 10419 }); 10420 } 10421 }); 10422 } 10423 10424 return this; 10425 }, 10426 }, 10427 }); 10428}).apply(this, [window.theme, jQuery]);
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.