1(function ($) { 2 'use strict'; 3 4 var config = { 5 mobileBreakPoint: 600, 6 ease: CustomEase.create("sr", "0.5, 0, 0, 1"), 7 easeJelly: CustomEase.create("sr", "0.5,-0.39,0.26,1.61"), 8 easeInOut: CustomEase.create("custom", "M0,0,C0.122,0.384,0.716,0.737,0.77,0.778,0.86,0.846,0.914,0.882,1,1") 9 }; 10 11 var main = { 12 init: function () { 13 var self = this; 14 15 self.isScrolling = false; 16 self.scrollY = 0; 17 self._header = document.querySelector('header.header'); 18 self.studiesRowWrap = '.studies-row-wrap'; 19 self.scrollToSection = '.scroll-to-section'; 20 21 self.setViewPortHeight(); 22 self.bindEvents(); 23 self.addTargetBlankExternalLinks(); 24 25 $(self.studiesRowWrap).each(function () { 26 $(this).scrollBar(); 27 }) 28 29 $(document.body).on('ajax_page_loaded ajax_switch_page_loaded', function () { 30 window.addEventListener('scroll', self.animateProgressBar, {passive: true}); 31 32 timeline.init(); 33 }); 34 35 $(document.body).on('ajax_switch_page_loaded ajax_page_loaded', function () { 36 $(self.studiesRowWrap).each(function () { 37 $(this).scrollBar(); 38 }) 39 }); 40 41 $(document.body).on('click', self.scrollToSection, function (e) { 42 var $el = $(this.getAttribute('href')); 43 44 e.preventDefault(); 45 46 if($el.length) { 47 window.scroll({ 48 top: $(this.getAttribute('href')).offset().top - $('header.header').height() - 60, 49 behavior: 'instant' 50 }); 51 } 52 }); 53 }, 54 55 bindEvents: function () { 56 var self = this; 57 58 if (document.body.classList.contains('sticky-header')) { 59 window.addEventListener('scroll', self.scrollHandler, {passive: true}); 60 } 61 62 window.addEventListener('scroll', self.animateProgressBar, {passive: true}); 63 64 $(window).on( "orientationchange", function(){ 65 self.setViewPortHeight(); 66 67 setTimeout(function(){ 68 timeline.init(); 69 }, 300); 70 71 }); 72 73 $(document.body).on('click', '.burger-menu-btn', function (e) { 74 e.preventDefault(); 75 self.toggleMenu(!document.body.classList.contains('menu-opened')); 76 }); 77 78 $(document.body).on('click', 'span[data-tooltip]', function (e) { 79 e.preventDefault(); 80 81 $.fn.modal.showModal('#glossary-modal', this); 82 }); 83 84 $('#glossary-modal').on('show_modal', function (e) { 85 var _modal = this; 86 _modal.querySelector('.modal-title').innerText = e.relatedTarget.innerText; 87 _modal.querySelector('.modal-body').innerHTML = self.decodeHtml(e.relatedTarget.dataset.tooltip); 88 }) 89 90 }, 91 92 toggleMenu: function (state, callback) { 93 if (state) { 94 document.body.classList.add('menu-opened'); 95 } else { 96 document.body.classList.add('menu-closing'); 97 document.body.classList.remove('menu-opened'); 98 99 setTimeout(function () { 100 document.body.classList.remove('menu-closing'); 101 102 if (callback) { 103 callback(); 104 } 105 106 }, 1000); 107 } 108 }, 109 110 scrollHandler: function () { 111 var self = main; 112 113 if (!self.isScrolling) { 114 window.requestAnimationFrame(function () { 115 self.headerSticky(); 116 117 self.isScrolling = false; 118 }); 119 self.isScrolling = true; 120 } 121 }, 122 123 animateProgressBar: function () { 124 var self = main, 125 $studyProgress = $('.study-progress'); 126 127 if ($studyProgress.length === 0) { 128 window.removeEventListener('scroll', self.animateProgressBar); 129 return; 130 } 131 132 var width = getComputedStyle($studyProgress.get(0)).getPropertyValue('--percent'), 133 tl = gsap.timeline({ 134 ease: config.ease, 135 delay: 0.2, 136 yoyo: true 137 }); 138 139 if (isElementInViewport($studyProgress.get(0)) && !$studyProgress.hasClass('progress-animated')) { 140 $studyProgress.addClass('progress-animated'); 141 tl.to($studyProgress.find('.progress-bar'), { 142 width: width, 143 duration: 0.6, 144 delay: 0.2 145 }); 146 147 tl.to($studyProgress.find('.label-now'), { 148 opacity: 1, 149 duration: 0.4, 150 delay: 0.2 151 }); 152 153 window.removeEventListener('scroll', self.animateProgressBar); 154 } 155 }, 156 157 headerSticky: function () { 158 var self = this; 159 160 if (!document.body.classList.contains('sticky-header')) { 161 return; 162 } 163 164 if (window.scrollY > self._header.clientHeight) { 165 if (window.scrollY > self.scrollY) { 166 self.headerStickyOut(); 167 } else { 168 self.headerStickyIn(); 169 } 170 } 171 172 self.scrollY = window.scrollY; 173 }, 174 175 headerStickyOut: function () { 176 var self = this; 177 self._header.classList.add('sticky-header-out'); 178 }, 179 180 headerStickyIn: function () { 181 var self = this; 182 self._header.classList.remove('sticky-header-out'); 183 }, 184
185 setViewPortHeight: function () { 186 // We execute the same script as before 187 let vh = window.innerHeight * 0.01; 188 document.documentElement.style.setProperty('--vh', vh + 'px'); 189 }, 190 191 addTargetBlankExternalLinks: function () { 192 var a = new RegExp('/' + window.location.host + '/'); 193 194 $(document.body).on('click', 'a', function () { 195 if (this.href && !a.test(this.href)) { 196 this.target = '_blank'; 197 } 198 }); 199 }, 200 201 decodeHtml: function (text) { 202 var map = { 203 '&': '&', 204 '<': '<', 205 '>': '>', 206 '"': '"', 207 ''': "'" 208 }; 209 210 return text.replace(/&|<|>|"|'/g, function (m) { 211 return map[m]; 212 }); 213 } 214 215 }; 216 217 var ajaxPage = { 218 init: function () { 219 var self = this; 220 221 self.re = new RegExp('/' + window.location.host + '/'); 222 223 self.tl = false; 224 self.animating = false; 225 self.onLoadDone = false; 226 227 if (self.parseUrl(window.location.href).hash) { 228 self.jumpToHash(window.location.href); 229 } 230 231 self.bindEvents(); 232 }, 233 234 onLoad: function () { 235 var self = this; 236 237 document.documentElement.classList.add('loaded'); 238 239 if (document.querySelectorAll('[data-anim]').length === 0) { 240 document.documentElement.classList.add('animated'); 241 self.onLoadDone = true; 242 } else { 243 self.doAnimation(function () { 244 document.documentElement.classList.add('animated'); 245 self.onLoadDone = true; 246 }, false, false, true); 247 } 248 }, 249 250 bindEvents: function () { 251 var self = ajaxPage, 252 stateName = 'site'; 253 254 $(document.body).on('click', 'a', self.clickHandler); 255 256 if ('scrollRestoration' in history) { 257 history.scrollRestoration = 'manual'; 258 } 259 260 if (history.state !== null) { 261 stateName = history.state.name; 262 } 263 264 history.replaceState({name: stateName, scrollY: window.scrollY}, null, null); 265 window.addEventListener('popstate', self.historyHandler); 266 267 /*$(document.body).on('ajax_load_more_posts_loaded', function () { 268 self.doAnimation(null, false, '.posts-container .posts-wrapper'); 269 }); 270 271 $(document.body).on('ajax_filter_posts_loaded', function () { 272 self.doAnimation(null, false, '.posts-container .posts-wrapper'); 273 self.doAnimation(null, false, 'footer.footer'); 274 }); 275 276 $(document.body).on('ajax_search_load_more_posts_loaded', function (e, _wrapper) { 277 self.doAnimation(null, false, _wrapper); 278 });*/ 279 280 $(document.body).on('click', '.switcher-toggle', function (e) { 281 e.preventDefault(); 282 self.switchPage(true); 283 }); 284 }, 285 286 clickHandler: function (e) { 287 var self = ajaxPage, 288 _this = this, 289 href = this.getAttribute('href'), 290 parseUrl = false; 291 292 if (!href) { 293 return; 294 } 295 296 if (self.animating) { 297 e.preventDefault(); 298 return; 299 } 300 301 parseUrl = self.parseUrl(href); 302 303 /*if (parseUrl.href === window.location.href) { 304 if (parseUrl.hash) { 305 self.jumpToHash(href, true); 306 } 307 308 e.preventDefault(); 309 return; 310 }*/ 311 312 if (href === window.location.href) { 313 if (parseUrl.hash) { 314 self.jumpToHash(href, true); 315 } 316 317 e.preventDefault(); 318 return; 319 } 320 321 if (_this.dataset.ajax && _this.dataset.ajax === 'false') { 322 return; 323 } 324 325 if (e.target.closest('#wpadminbar')) { 326 return; 327 } 328 329 if (e.target.closest('.switcher-wrap')) { 330 return; 331 } 332 333 if (href.indexOf('wp-admin') !== -1) { 334 return; 335 } 336 337 if (!self.re.test(href)) { 338 return; 339 } 340 341 //$('body.menu-opened').removeClass('menu-opened'); 342 343 e.preventDefault(); 344 345 history.replaceState({name: 'site', scrollY: window.scrollY}, null, null); 346 347 $.when(self.doAnimationOut(true, false, true), self.doAjaxRequest(href)).then(function (response1, response2) { 348 self.handlePageAjaxResponse(response2, href, true); 349 }); 350 351 }, 352 353 historyHandler: function (e) { 354 var self = ajaxPage, 355 href = document.location.href; 356 357 if (e.state !== null && e.state.name === 'site') { 358 359 var parseUrl = self.parseUrl(href), 360 _switchToggle = document.querySelector('.switcher-toggle'); 361 362 if (_switchToggle.dataset.type === 'broad-type' && document.location.href.indexOf('technical') !== -1) { 363 //console.log('switch to technical') 364 self.switchPage(false); 365 } else if (_switchToggle.dataset.type === 'technical-type' && document.location.href.indexOf('technical') === -1) { 366 //console.log('switch to broad') 367 self.switchPage(false); 368 } else { 369 //console.log('regular') 370 371 main.isScrolling = true; 372 373 $.when(self.doAnimationOut(true, false, true), self.doAjaxRequest(href)).then(function (response1, response2) { 374 if (self.parseUrl(href).hash) { 375 self.jumpToHash(href); 376 } else { 377 window.scrollTo({ 378 top: e.state.scrollY, 379 left: 0 380 }); 381 } 382 383 self.handlePageAjaxResponse(response2, href, false); 384 }); 385 } 386 387 } else { 388 e.preventDefault(); 389 return false;
390 } 391 }, 392 393 doAjaxRequest: function (href, callback) { 394 var self = ajaxPage, 395 parseUrl = self.parseUrl(href); 396 397 $(document.body).trigger('ajax_page_before_request'); 398 399 return $.get(updateQueryStringParameter(parseUrl.href, '_ajax', '1')) 400 .done(function (response) { 401 //console.log('Ajax response: ' + new Date()); 402 }).fail(function (response) { 403 setTimeout(function () { 404 alert('Ops! Something went wrong. Please reload the page'); 405 406 self.doAnimation(function () { 407 main.isScrolling = false; 408 }, false, false, false); 409 }, 500); 410 }); 411 }, 412 413 handlePageAjaxResponse: function (response, href, pushState) { 414 var self = ajaxPage, 415 $response = $('<div>' + response + '</div>'), 416 documentTitle = $response.find('#wp_title').text(), 417 bodyClass = $response.find('#wp_body').text(), 418 menuCurrentItem = $response.find('#wp_menu_current_item').text(); 419 420 $('#main').replaceWith($response.find('#main')); 421 self.menuSetCurrentItem(menuCurrentItem); 422 423 if (pushState) { 424 document.title = documentTitle; 425 history.pushState({name: 'site', scrollY: window.scrollY}, documentTitle, href); 426 427 window.scrollTo({ 428 top: 0, 429 left: 0 430 }); 431 432 history.replaceState({name: 'site', scrollY: window.scrollY}, null, null); 433 } 434 435 document.body.setAttribute('class', bodyClass); 436 437 if (pushState && self.parseUrl(href).hash) { 438 self.jumpToHash(href); 439 } 440 441 self.doAnimation(function () { 442 main.isScrolling = false; 443 $(document.body).trigger('ajax_page_loaded_animated'); 444 }, false, false, true); 445 446 $(document.body).trigger('ajax_page_loaded'); 447 }, 448 449 animateHeader: function () { 450 var self = this, def = $.Deferred(), 451 _header = document.querySelector('.header'); 452 453 if (_header !== null && !_header.classList.contains('sticky-header-out')) { 454 def.resolve(); 455 } 456 457 if (_header !== null) { 458 _header.classList.remove('sticky-header-out'); 459 } 460 461 $(_header).one(transitionEvent, function () { 462 def.resolve(); 463 }); 464 465 if (window.innerWidth < 640) { 466 def.resolve(); 467 } 468 469 return def.promise(); 470 }, 471 472 animateBlocks: function (reverse, wrap, force) { 473 var self = this, def = $.Deferred(), 474 elements = document.querySelectorAll('[data-anim]'); 475 476 if (typeof (wrap) === 'string') { 477 elements = document.querySelectorAll(wrap + ' [data-anim]'); 478 } else if (typeof (wrap) === 'object') { 479 elements = wrap.querySelectorAll('[data-anim]'); 480 } 481 482 if (elements.length === 0) { 483 def.resolve(); 484 } 485 486 var duration = !reverse ? 0.4 : 0.4, 487 overlayTime = !reverse ? '-=0.3' : '-=0.3', 488 delay = self.onLoadDone ? 0 : 0.4; 489 490 self.tl = gsap.timeline({ 491 duration: duration, 492 delay: delay, 493 ease: config.ease, 494 onComplete: function () { 495 $(document.body).trigger('page_animation_finished', { 496 reverse: reverse, wrap: wrap, force: force 497 }); 498 def.resolve(); 499 } 500 }); 501 502 if (reverse) { 503 elements = Array.prototype.slice.call(elements).reverse(); 504 } 505 506 if (force === false) { 507 elements = Array.prototype.slice.call(elements).filter(function (_element) { 508 if (!_element.classList.contains('animated')) { 509 return _element; 510 } 511 }); 512 } 513
514 elements.forEach(function (_element) { 515 var animationType = _element.dataset.anim, 516 parents = $(_element).parents('[data-anim]').length; 517 518 if (reverse) { 519 _element.classList.remove('animated'); 520 } else { 521 _element.classList.add('animated'); 522 } 523 524 var animDelayIn = _element.dataset.animDelayIn ? _element.dataset.animDelayIn : 0, 525 animDelayOut = _element.dataset.animDelayOut ? _element.dataset.animDelayOut : 0, 526 animIn = (!(_element.dataset.animIn && _element.dataset.animIn === 'false')), 527 animOut = (!(_element.dataset.animOut && _element.dataset.animOut === 'false')); 528 529 switch (animationType) { 530 case 'fade-zoom-in': 531 if (isElementPartInViewport(_element)) { 532 if (reverse) { 533 self.tl.to(_element, { 534 duration: duration, 535 scale: 1, 536 opacity: 1, 537 }, overlayTime); 538 } else { 539 self.tl.to(_element, { 540 duration: duration, 541 scale: 0.85, 542 opacity: 0, 543 }, overlayTime); 544 } 545 } else { 546 if (!reverse) { 547 self.tl.set(_element, { 548 scale: 1, 549 opacity: 1, 550 }); 551 } else { 552 self.tl.set(_element, { 553 scale: 0.85, 554 opacity: 0, 555 }); 556 } 557 } 558 559 break; 560 case 'fade-slide-up': 561 if (isElementPartInViewport(_element, 75 * (parents + 1))) { 562 if (!reverse) { 563 self.tl.to(_element, { 564 duration: duration, 565 y: 0, 566 opacity: 1, 567 }, overlayTime); 568 } else { 569 self.tl.to(_element, { 570 duration: duration, 571 y: 75, 572 opacity: 0, 573 }, overlayTime); 574 } 575 } else { 576 if (!reverse) { 577 self.tl.set(_element, { 578 y: 0, 579 opacity: 1, 580 }); 581 } else { 582 self.tl.set(_element, { 583 y: 75, 584 opacity: 0, 585 }); 586 } 587 } 588 589 break; 590 case 'fade-slide-right': 591 if (isElementPartInViewport(_element, 100)) { 592 if (!reverse && animIn) { 593 self.tl.to(_element, { 594 duration: duration, 595 x: 0, 596 opacity: 1, 597 delay: animDelayIn 598 }, overlayTime); 599 } else if (animOut) { 600 self.tl.to(_element, { 601 duration: duration, 602 x: 75, 603 opacity: 0, 604 delay: animDelayOut 605 }, overlayTime); 606 } 607 } else { 608 if (!reverse) { 609 self.tl.set(_element, { 610 x: 0, 611 opacity: 1, 612 }); 613 } else { 614 self.tl.set(_element, { 615 x: 75, 616 opacity: 0, 617 }); 618 } 619 } 620 621 break; 622 case 'fade': 623 if (isElementPartInViewport(_element, 100)) { 624 if (!reverse && animIn) { 625 self.tl.to(_element, { 626 duration: duration, 627 opacity: 1, 628 delay: animDelayIn 629 }, overlayTime); 630 } else if (animOut) { 631 self.tl.to(_element, { 632 duration: duration, 633 opacity: 0, 634 delay: animDelayOut 635 }, overlayTime); 636 } 637 } else { 638 if (!reverse) { 639 self.tl.set(_element, { 640 opacity: 1, 641 }); 642 } else { 643 self.tl.set(_element, { 644 opacity: 0, 645 }); 646 } 647 } 648 649 break; 650 } 651 652 }); 653 654 return def.promise(); 655 }, 656 657 doAnimation: function (callback, reverse, wrap, force) { 658 var self = this; 659 660 self.animating = true; 661 662 $.when(self.animateHeader(), self.animateBlocks(reverse, wrap, force)).then(function () { 663 self.animating = false;
664 665 if (callback) { 666 callback() 667 } 668 }); 669 }, 670 671 doAnimationOut: function (reverse, wrap, force) { 672 var self = ajaxPage, 673 $deferred = $.Deferred(); 674 675 self.animating = true; 676 677 function doAnim() { 678 self.doAnimation(function () { 679 /** 680 * Set short timeout between animation 681 */ 682 setTimeout(function () { 683 $deferred.resolve(); 684 }, 500); 685 }, reverse, wrap, force); 686 } 687 688 if (document.body.classList.contains('menu-opened')) { 689 main.toggleMenu(false); 690 setTimeout(function () { 691 doAnim(); 692 }, 300); 693 } else { 694 doAnim(); 695 } 696 697 return $deferred.promise(); 698 }, 699 700 menuSetCurrentItem: function (menuCurrentItem) { 701 var _items = document.querySelectorAll('li.menu-item'); 702 703 _items.forEach(function (_item) { 704 _item.classList.remove('current-menu-item'); 705 706 if (menuCurrentItem !== '' && _item.classList.contains('menu-item-' + menuCurrentItem)) { 707 _item.classList.add('current-menu-item'); 708 } 709 }); 710 }, 711 712 switchPage: function (pushState) { 713 var self = ajaxPage, 714 _switchToggle = document.querySelector('.switcher-toggle'), 715 type = _switchToggle.dataset.type, 716 _switchWrap = document.querySelector('.switch-wrap'), 717 _wrapper = document.body.querySelector('.wrapper'), 718 switchToType = '', 719 parseUrl = self.parseUrl(window.location.href), 720 href = parseUrl.href, 721 hash = parseUrl.hash ? '#' + parseUrl.hash : ''; 722 723 if (type === 'technical-type') { 724 switchToType = 'broad-type'; 725 href = href.replace('technical/', ''); 726 } else { 727 switchToType = 'technical-type'; 728 href = href + 'technical/'; 729 } 730 731 timeline.resetAnimateClasses(); 732 733 _switchToggle.querySelector('span.' + type).classList.remove('active'); 734 _switchToggle.querySelector('span.' + switchToType).classList.add('active'); 735 736 $.get(href).done(function (response) { 737 var $response = $('<div>' + response + '</div>'), 738 $wrapper = $response.find(".wrapper"), 739 documentTitle = '', 740 _switchWrapper, 741 windowTop = window.scrollY; 742 743 if ($response.find('title').length > 1) { 744 documentTitle = $response.find('title')[1].innerText; 745 } else { 746 documentTitle = $response.find('title').text(); 747 } 748 749 $response = null; 750 751 $wrapper.find('.header.sticky-header-out').removeClass('sticky-header-out'); 752 $wrapper.find('[data-anim]').each(function () { 753 var _this = this; 754 755 _this.classList.add('animated'); 756 757 switch (_this.dataset.anim) { 758 case 'fade-slide-up': 759 _this.style.opacity = 1; 760 _this.style.transform = 'translate(0px, 0px)'; 761 break; 762 case 'fade': 763 _this.style.opacity = 1; 764 break; 765 } 766 }); 767 768 document.body.classList.add('switching'); 769 770 if (switchToType === 'technical-type') { 771 document.body.classList.add('direct'); 772 } else { 773 document.body.classList.add('reverse'); 774 } 775 776 _switchWrap.innerHTML = _wrapper.outerHTML; 777 _wrapper.outerHTML = $wrapper[0].outerHTML; 778 _wrapper = document.body.querySelector('.wrapper') 779 _switchWrapper = _switchWrap.querySelector('.wrapper'); 780 781 _wrapper.scrollTo(0, windowTop); 782 _switchWrapper.scrollTo(0, windowTop); 783 784 if (pushState) { 785 document.title = documentTitle; 786 history.pushState({name: 'site', scrollY: windowTop}, documentTitle, href); 787 } 788
789 $(document.body).trigger('ajax_switch_page_loaded'); 790 791 setTimeout(function () { 792 document.body.classList.add('anim'); 793 794 if (switchToType === 'technical-type') { 795 //$(_wrapper).one(transitionEvent, function () { 796 setTimeout(function () { 797 _switchWrap.innerHTML = ''; 798 document.body.classList.remove('switching', 'anim', 'reverse', 'direct'); 799 window.scrollTo(0, windowTop); 800 }, 600); 801 //}); 802 } else { 803 //$(_switchWrapper).one(transitionEvent, function () { 804 setTimeout(function () { 805 _switchWrap.innerHTML = ''; 806 document.body.classList.remove('switching', 'anim', 'reverse', 'direct'); 807 window.scrollTo(0, windowTop); 808 }, 600); 809 //}); 810 } 811 812 }, 200); 813 814 }); 815 }, 816 817 parseUrl: function (href) { 818 const parseUrl = href.split('#'); 819 820 return { 821 href: parseUrl[0], 822 hash: (typeof (parseUrl[1]) !== 'undefined') ? parseUrl[1] : false 823 }; 824 }, 825 826 jumpToHash: function (href, animated) { 827 var self = ajaxPage, 828 parseUrl = self.parseUrl(href), 829 _element = false; 830 831 if (!parseUrl.hash) { 832 return; 833 } 834 835 _element = document.getElementById(parseUrl.hash); 836 837 if (!_element) { 838 return; 839 } 840 841 if (animated) { 842 $('html, body').animate({ 843 scrollTop: $(_element).offset().top - 100 844 }, 600); 845 } else { 846 window.scrollTo({ 847 top: $(_element).offset().top - 100, 848 left: 0 849 }); 850 } 851 } 852 853 }; 854 855 var frontPage = { 856 857 init: function () { 858 var self = this; 859 860 self.studiesWrap = '.studies-content-area'; 861 self.$studies = false; 862 self.locationFilter = '.location-filter-wrap'; 863 864 self.initIsotop(); 865 self.bindEvents(); 866 self.bindHadrEvents(); 867 $(self.locationFilter).scrollBar(); 868 869 $(document.body).on('ajax_page_loaded ajax_switch_page_loaded', function () { 870 if ($(self.studiesWrap).length) { 871 self.$studies = false; 872 873 self.initIsotop(); 874 self.bindHadrEvents(); 875 } 876 877 if ($(self.locationFilter).length) { 878 $(self.locationFilter).scrollBar(); 879 } 880 }); 881 }, 882 883 bindEvents: function () { 884 var self = this; 885 886 $(document.body).on('click', '.location-filter button', function () { 887 $(self.studiesWrap).find('button.active').removeClass('active'); 888 $(this).addClass('active'); 889 890 if (false !== self.$studies) { 891 self.$studies.isotope({filter: this.dataset.filter}); 892 } 893 }); 894 895 /*$(document.body).CustomResize({ 896 resize: function () { 897 if (false !== self.$studies) { 898 if( window.innerWidth >= 1024 ){ 899 self.$studies.isotope({sortBy: 'desktopOrder'}); 900 } else { 901 self.$studies.isotope({sortBy: 'originalOrder'}); 902 } 903 } 904 }, 905 timeout: 100 906 });*/ 907 908 }, 909 910 bindHadrEvents: function () { 911 var self = this; 912 913 document.querySelectorAll(self.studiesWrap + ' .study-card').forEach(function (_card) { 914 var moved = false; 915 916 _card.addEventListener('touchstart', function () { 917 var _flipped = document.querySelector(self.studiesWrap + ' .study-card.flipped'); 918 919 if (_flipped !== null) { 920 _flipped.classList.remove('flipped'); 921 } 922 923 moved = false;
924 }); 925 926 _card.addEventListener('touchmove', function () { 927 moved = true; 928 }); 929 930 _card.addEventListener('touchend', function () { 931 if (!moved) { 932 $(this).toggleClass('flipped'); 933 } 934 }) 935 }); 936 }, 937 938 initIsotop: function () { 939 var self = this; 940 941 if (!document.querySelector(self.studiesWrap)) { 942 return; 943 } 944 945 self.calculateCardHeight(); 946 947 self.$studies = $(self.studiesWrap).find('.content-area-inner').isotope({ 948 itemSelector: '.study-card', 949 percentPosition: false, 950 //layoutMode: 'fitRows', 951 stamp: '.stamp', 952 masonry: { 953 // use element for option 954 columnWidth: '.study-sizer' 955 }, 956 getSortData: { 957 originalOrder: '.study-num parseInt', 958 desktopOrder: function (_item) { 959 var num = parseInt(_item.querySelector('.study-num').innerText), 960 delim = (num % 3); 961 962 if (delim === 1) { 963 num = num + 1; 964 } else if (delim === 2) { 965 num = num - 1; 966 } 967 968 return num; 969 } 970 } 971 }); 972 973 self.$studies.imagesLoaded(function () { 974 self.$studies.isotope('layout'); 975 }); 976 977 /*if( window.innerWidth >= 1024 ){ 978 self.$studies.isotope({sortBy: 'desktopOrder'}); 979 } else { 980 self.$studies.isotope({sortBy: 'originalOrder'}); 981 }*/ 982 }, 983 984 calculateCardHeight: function () { 985 var self = this; 986 987 if (!document.querySelector(self.studiesWrap)) { 988 return; 989 } 990 991 document.querySelector(self.studiesWrap) 992 .querySelectorAll('.study-card-container') 993 .forEach(function (_card, key) { 994 var _inner = _card.querySelector('.study-card-inner'), 995 _frontHeight = 70, 996 _backHeight = 62; 997 998 _card.querySelectorAll('.study-card-front > *').forEach(function (_el) { 999 _frontHeight += _el.clientHeight; 1000 }); 1001 1002 _card.querySelectorAll('.study-card-back > *').forEach(function (_el) { 1003 _backHeight += _el.clientHeight; 1004 }); 1005 1006 if (window.innerWidth > 640) { 1007 if (_backHeight > _frontHeight) { 1008 _inner.style.height = _backHeight + 'px'; 1009 } else { 1010 _inner.style.height = _frontHeight + 'px'; 1011 } 1012 } else { 1013 _inner.style.height = null; 1014 } 1015 }); 1016 1017 if (false !== self.$studies) { 1018 self.$studies.isotope('layout'); 1019 } 1020 } 1021 1022 }; 1023 1024 var memberSinglePage = { 1025 1026 init: function () { 1027 var self = this; 1028 1029 self.researchSliderWrap = '.member-research-outputs'; 1030 1031 self.initResearchSlider(); 1032 1033 $(document.body).on('ajax_page_loaded ajax_switch_page_loaded', function () { 1034 self.initResearchSlider(); 1035 }); 1036 }, 1037 1038 bindEvents: function () { 1039 var self = this; 1040 }, 1041 1042 initResearchSlider: function () { 1043 var self = this; 1044 1045 self._researchSliderWrap = document.querySelector(self.researchSliderWrap) 1046 1047 if (self._researchSliderWrap === null) { 1048 return 1049 } 1050 1051 self._sliderNav = self._researchSliderWrap.querySelector('.slider-nav'); 1052 self._slides = self._researchSliderWrap.querySelector('.research-outputs'); 1053 self.$slider = false;
1054 1055 $(self.researchSliderWrap).on('init', function (event, slick) { 1056 self.toggleArrows(slick.slideCount); 1057 }); 1058 1059 self.$slider = $(self._slides).slick({ 1060 infinite: false, 1061 slidesToShow: 6, 1062 slidesToScroll: 6, 1063 prevArrow: self._researchSliderWrap.querySelector('.slider-nav-prev'), 1064 nextArrow: self._researchSliderWrap.querySelector('.slider-nav-next'), 1065 touchThreshold: 10, 1066 responsive: [ 1067 { 1068 breakpoint: 989, 1069 settings: { 1070 slidesToShow: 4, 1071 slidesToScroll: 4, 1072 } 1073 }, 1074 { 1075 breakpoint: 690, 1076 settings: { 1077 slidesToShow: 3, 1078 slidesToScroll: 3, 1079 } 1080 }, 1081 { 1082 breakpoint: 600, 1083 settings: { 1084 slidesToShow: 2, 1085 slidesToScroll: 2, 1086 } 1087 } 1088 ] 1089 }); 1090 1091 self.$slider.on('breakpoint', function (event, slick, breakpoint) { 1092 self.toggleArrows(slick.slideCount); 1093 }); 1094 }, 1095 1096 toggleArrows: function (count) { 1097 var self = this, 1098 necessaryCount = 0; 1099 1100 if (window.innerWidth > 989) { 1101 necessaryCount = 6; 1102 } else if (window.innerWidth <= 989 && window.innerWidth > 659) { 1103 necessaryCount = 4; 1104 } else { 1105 necessaryCount = 2; 1106 } 1107 1108 if (count > necessaryCount) { 1109 self._sliderNav.style.visibility = 'visible'; 1110 } else { 1111 self._sliderNav.style.visibility = 'hidden'; 1112 } 1113 } 1114 1115 }; 1116 1117 var filter = { 1118 1119 init: function (wrapper) { 1120 var self = this; 1121 1122 self.$wrapper = $(wrapper); 1123 1124 if (self.$wrapper.length === 0) { 1125 return; 1126 } 1127 1128 self.historyKey = wrapper; 1129 self.actionUrl = self.$wrapper.find('form[action]').attr('action'); 1130 1131 self.contentPosts = self.$wrapper.data('content-posts'); 1132 self.contentFilter = self.$wrapper.data('content-filter'); 1133 1134 self.termsCheckBox = 'input[type="checkbox"].term'; 1135 self.taxonomyTermsValue = '.taxonomy-terms-value'; 1136 self.searchValue = '.filter-search input.search-value'; 1137 self.searchButton = '.filter-search button.btn-search'; 1138 1139 history.replaceState(self.historyKey, null, null); 1140 self.bindEvents(); 1141 1142 self.searchPopup.init('#sidebar-search-content'); 1143 }, 1144 1145 bindEvents: function () { 1146 var self = this; 1147 1148 self.$wrapper.on('submit', '.filter-body form', function () { 1149 self.filterAction($(this).serialize(), true); 1150 1151 return false; 1152 }); 1153 1154 self.$wrapper.on('change', self.termsCheckBox, function () { 1155 self.onChangeCheckBox($(this)); 1156 }); 1157 1158 self.$wrapper.on('click', '.btn-reset-filter', function (e) { 1159 e.preventDefault(); 1160 self.filterAction('', true); 1161 }); 1162 1163 self.$wrapper.on('click', '.btn-show-all', function (e) { 1164 e.preventDefault(); 1165 1166 var $wrapper = $(this).closest('.taxonomy-filter'); 1167 1168 if (!this.classList.contains('less')) { 1169 this.classList.add('less'); 1170 $wrapper.find('.term-label.hidden').addClass('shown'); 1171 this.innerText = this.dataset.showLess; 1172 } else { 1173 this.classList.remove('less'); 1174 $wrapper.find('.term-label.hidden').removeClass('shown'); 1175 this.innerText = this.dataset.showAll; 1176 } 1177 }); 1178 1179 $(self.contentPosts).on('change', '.filter-selected-terms input.term', function (e) { 1180 e.preventDefault(); 1181 1182 var termValue = this.value,
1183 urlParams = new URLSearchParams(window.location.search), 1184 buildActionUrl = [], values, newValues = []; 1185 1186 for (const key of urlParams.keys()) { 1187 values = urlParams.get(key).split(','); 1188 newValues = []; 1189 1190 for (const value of values) { 1191 if (termValue !== value) { 1192 newValues.push(value) 1193 } 1194 } 1195 1196 if (newValues.length > 0) { 1197 buildActionUrl.push(key + '=' + newValues.join(',')); 1198 } 1199 } 1200 1201 self.filterAction(buildActionUrl.join('&'), true); 1202 }); 1203 1204 window.addEventListener('popstate', self.filterHistoryHandler); 1205 1206 $.fn.scrollBar.init('.filter-selected-terms'); 1207 }, 1208 1209 onChangeCheckBox: function ($this) { 1210 var self = this, 1211 $form = $this.closest('form'), 1212 $taxonomy = $this.closest('.filter-terms'), 1213 $taxonomyTermsValue = $taxonomy.find(self.taxonomyTermsValue), 1214 values = this.prepareValues($taxonomy); 1215 1216 if (values.length === 0) { 1217 $taxonomyTermsValue.prop('disabled', true); 1218 } else { 1219 $taxonomyTermsValue.prop('disabled', false); 1220 } 1221 1222 self.propSearch(); 1223 1224 $taxonomyTermsValue.val(values.join(',')); 1225 $form.trigger('submit'); 1226 }, 1227 1228 filterAction: function (actionData, pushState) { 1229 var self = this, 1230 historyUrl = self.actionUrl, 1231 visibility = []; 1232 1233 $(self.contentFilter).find('.filter-terms').each(function () { 1234 if ($(this).find('.btn-show-all').hasClass('less')) { 1235 visibility.push($(this).attr('id')); 1236 } 1237 }); 1238 1239 $.get(self.actionUrl + '?_ajax=1', actionData).done(function (response) { 1240 var $response = $('<div>' + response + '</div>'), 1241 title = $response.find('#wp_title').text(); 1242 1243 $(self.contentPosts).html($(response).find(self.contentPosts).html()); 1244 $(self.contentFilter).html($(response).find(self.contentFilter).html()); 1245 $('.total-posts').html($(response).find('.total-posts').html()); 1246 1247 visibility.forEach(function (taxonomy) { 1248 var $taxonomyFilter = $('#' + taxonomy), 1249 $showButton = $taxonomyFilter.find('.btn-show-all'); 1250 1251 $taxonomyFilter.find('.taxonomy-filter .term-label.hidden').addClass('shown'); 1252 1253 if ($showButton.length) { 1254 $showButton.get(0).classList.add('less'); 1255 $showButton.get(0).innerText = $showButton.get(0).dataset.showLess; 1256 } 1257 }); 1258 1259 grid.resizeGrid($(self.contentPosts).find('.grid')); 1260 1261 if (actionData !== '' && actionData !== 'paged=1') { 1262 historyUrl = '?' + actionData; 1263 } 1264 1265 if (pushState === true) { 1266 history.pushState(self.historyKey, title, removeURLParameter(historyUrl, 'paged')); 1267 document.title = title; 1268 } 1269 1270 self.propSearch(false); 1271 }); 1272 }, 1273 1274 filterHistoryHandler: function (e) { 1275 var self = filter; 1276 1277 if (e.state === self.historyKey) { 1278 self.filterAction(document.location.search.replace('?', ''), false); 1279 } else { 1280 e.preventDefault(); 1281 return false; 1282 } 1283 }, 1284 1285 prepareValues: function ($taxonomy) { 1286 var self = this; 1287 1288 let values = []; 1289 1290 $taxonomy.find(self.termsCheckBox + ':checked').filter(function () { 1291 values.push(this.value); 1292 }); 1293 1294 return values; 1295 }, 1296 1297 getQueryParameters: function (str) { 1298 var self = this; 1299 1300 return (str || document.location.search).replace(/(^\?)/, '').split("&").map(function (n) { 1301 return n = n.split("="), this[n[0]] = n[1], this 1302 }.bind({}))[0]; 1303 }, 1304 1305 propSearch: function (state) { 1306 var self = this; 1307 1308 if (document.querySelector(self.searchValue) === null) { 1309 return; 1310 } 1311 1312 if (state !== undefined) { 1313 document.querySelector(self.searchValue).disabled = state; 1314 return; 1315 } 1316 1317 if (document.querySelector(self.searchValue).value === '') { 1318 document.querySelector(self.searchValue).disabled = true; 1319 } else { 1320 document.querySelector(self.searchValue).disabled = false;
1321 } 1322 }, 1323 1324 searchPopup: { 1325 init: function (searchInput) { 1326 var self = this; 1327 1328 if (document.querySelector(searchInput) === null) { 1329 return; 1330 } 1331 1332 self.keyPressTimer = 0; 1333 self.searchInput = searchInput; 1334 self.resultCache = []; 1335 self.ajaxAction = document.querySelector(searchInput).dataset.ajaxAction; 1336 1337 self._filterBody = document.querySelector('.filter-body'); 1338 self._searchResultProducts = document.querySelector('.search-body'); 1339 1340 self.bindEvents(); 1341 }, 1342 1343 bindEvents: function () { 1344 var self = this; 1345 1346 document.querySelector(self.searchInput).closest('form') 1347 .addEventListener('submit', function (e) { 1348 e.preventDefault(); 1349 }); 1350 1351 $(document.body).on('input', self.searchInput, function (e) { 1352 e.preventDefault(); 1353 1354 var keyword = this.value; 1355 1356 clearTimeout(self.keyPressTimer); 1357 1358 self.keyPressTimer = setTimeout(function () { 1359 self.sendRequest(keyword); 1360 }, 400); 1361 }); 1362 }, 1363 1364 sendRequest: function (keyword) { 1365 var self = this; 1366 1367 if (keyword.length < 3) { 1368 self.showResult(false); 1369 return; 1370 } 1371 1372 if (self.resultCache[keyword]) { 1373 self.showResult(self.resultCache[keyword]); 1374 return; 1375 } 1376 1377 $.ajax({ 1378 url: theme_params.ajax_url, 1379 method: "POST", 1380 dataType: 'json', 1381 data: { 1382 action: 'theme_ajax', 1383 ajax_action: self.ajaxAction, 1384 keyword: keyword 1385 }, 1386 beforeSend: function () { 1387 self._searchResultProducts.classList.add('loading'); 1388 }, 1389 complete: function () { 1390 self._searchResultProducts.classList.remove('loading'); 1391 }, 1392 success: function (response) { 1393 self.resultCache[keyword] = response.data; 1394 self.showResult(response.data); 1395 }, 1396 }); 1397 }, 1398 1399 showResult: function (data) { 1400 var self = this; 1401 1402 self._searchResultProducts.innerHTML = ''; 1403 1404 if (false === data) { 1405 self._filterBody.style.display = 'block'; 1406 self._searchResultProducts.style.display = 'none'; 1407 return; 1408 } 1409 1410 self._filterBody.style.display = 'none'; 1411 self._searchResultProducts.style.display = 'block'; 1412 1413 var regExp = new RegExp(data.keyword, "gi"); 1414 1415 if (data.found_products !== 0) { 1416 data.products.forEach(function (product) { 1417 product.title = product.title.replace(regExp, function (match) { 1418 return `<mark>${match}</mark>`; 1419 }); 1420 1421 const markup = ` 1422 <div class="search-post"> 1423 <a href="${product.url}"> 1424 <div class="post-title"> 1425 ${product.title} 1426 </div> 1427 </a> 1428 </div>`; 1429 1430 self._searchResultProducts.insertAdjacentHTML('afterbegin', markup); 1431 }); 1432 } else { 1433 const markup = `<p class="nothing-found">${data.message}</p>`; 1434 1435 self._searchResultProducts.insertAdjacentHTML('afterbegin', markup); 1436 } 1437 } 1438 } 1439 1440 }; 1441 1442 var search = { 1443 init: function () { 1444 var self = this; 1445 1446 self.searchInput = '#site-search-content'; 1447
1448 if (document.querySelector(self.searchInput) === null) { 1449 return; 1450 } 1451 1452 self.keyPressTimer = 0; 1453 self.resultCache = []; 1454 1455 self._trendingBody = document.querySelector('#search-sidebar .trending-body'); 1456 self._searchResult = document.querySelector('#search-sidebar .search-body'); 1457 self._showMoreResults = document.querySelector('#search-sidebar .show-more-results'); 1458 1459 self.bindEvents(); 1460 }, 1461 1462 bindEvents: function () { 1463 var self = this; 1464 1465 $(document.body).on('input', self.searchInput, function (e) { 1466 e.preventDefault(); 1467 1468 var keyword = this.value; 1469 1470 clearTimeout(self.keyPressTimer); 1471 1472 self.keyPressTimer = setTimeout(function () { 1473 self.sendRequest(keyword); 1474 }, 400); 1475 }); 1476 1477 $(document.body).on('click', '.load-more-search .load-more-button', function (e) { 1478 e.preventDefault(); 1479 1480 self.loadMore(this, this.dataset.paged, this.dataset.post_type, this.dataset.search_term); 1481 }); 1482 }, 1483 1484 sendRequest: function (keyword) { 1485 var self = this; 1486 1487 if (keyword.length < 3) { 1488 self.showResult(false); 1489 return; 1490 } 1491 1492 if (self.resultCache[keyword]) { 1493 self.showResult(self.resultCache[keyword]); 1494 return; 1495 } 1496 1497 $.ajax({ 1498 url: theme_params.ajax_url, 1499 method: "POST", 1500 dataType: 'json', 1501 data: { 1502 action: 'theme_ajax', 1503 ajax_action: 'site_search', 1504 keyword: keyword 1505 }, 1506 beforeSend: function () { 1507 self._searchResult.classList.add('loading'); 1508 }, 1509 complete: function () { 1510 self._searchResult.classList.remove('loading'); 1511 }, 1512 success: function (response) { 1513 self.resultCache[keyword] = response.data; 1514 self.showResult(response.data); 1515 }, 1516 }); 1517 }, 1518 1519 showResult: function (data) { 1520 var self = this, 1521 resultHtml = ''; 1522 1523 self._searchResult.innerHTML = ''; 1524 1525 if (false === data) { 1526 self._trendingBody.style.display = 'block'; 1527 self._searchResult.style.display = 'none'; 1528 self._showMoreResults.style.visibility = 'hidden'; 1529 return; 1530 } 1531 1532 self._trendingBody.style.display = 'none'; 1533 self._searchResult.style.display = 'block'; 1534 self._showMoreResults.style.visibility = 'hidden'; 1535 1536 if (data.count_posts !== 0) { 1537 resultHtml += self.getPostsLayout(data.central_banks, theme_params.labels.central_banks_title, data.keyword); 1538 resultHtml += self.getPostsLayout(data.posts, theme_params.labels.news_title, data.keyword); 1539 resultHtml += self.getPostsLayout(data.research, theme_params.labels.research_title, data.keyword); 1540 1541 self._searchResult.insertAdjacentHTML('afterbegin', resultHtml); 1542 self._showMoreResults.style.visibility = 'visible'; 1543 } else { 1544 const markup = `<p class="nothing-found">${data.message}</p>`; 1545 1546 self._searchResult.insertAdjacentHTML('afterbegin', markup); 1547 } 1548 }, 1549 1550 getPostsLayout: function (posts, title, keyword) { 1551 var markup = '', 1552 regExp = new RegExp(keyword, "gi"); 1553 1554 if (posts.length > 0) { 1555 1556 markup += `<div class="search-post">`; 1557 markup += `<span class="title-search-label">${title}</span>`; 1558 markup += `<ul>`; 1559 1560 posts.forEach(function (post) {
1561 post.title = post.title.replace(regExp, function (match) { 1562 return `<mark>${match}</mark>`; 1563 }); 1564 1565 markup += ` 1566 <li> 1567 <a href="${post.url}"> 1568 <div class="post-title"> 1569 ${post.title} 1570 </div> 1571 </a> 1572 </li>`; 1573 }); 1574 1575 markup += `</ul></div>`; 1576 } 1577 1578 return markup; 1579 }, 1580 1581 loadMore: function (_button, paged, post_type, keyword) { 1582 1583 $.ajax({ 1584 url: theme_params.ajax_url, 1585 method: "POST", 1586 dataType: 'json', 1587 data: { 1588 action: 'theme_ajax', 1589 ajax_action: 'search_load_more', 1590 keyword: keyword, 1591 paged: paged, 1592 post_type: post_type 1593 }, 1594 beforeSend: function () { 1595 //self._searchResult.classList.add('loading'); 1596 }, 1597 complete: function () { 1598 //self._searchResult.classList.remove('loading'); 1599 }, 1600 success: function (response) { 1601 //console.log(response.data); 1602 1603 if (response.data.post_count > 0) { 1604 var loopPosts = _button.closest('.search-result').querySelector('.loop-posts'); 1605 1606 loopPosts.insertAdjacentHTML('beforeend', response.data.posts_html); 1607 1608 grid.resizeGrid($(loopPosts)); 1609 1610 if (response.data.next_paged !== '') { 1611 _button.dataset.paged = response.data.next_paged; 1612 } else { 1613 _button.parentNode.remove(); 1614 } 1615 } else { 1616 _button.parentNode.remove(); 1617 } 1618 }, 1619 }); 1620 1621 } 1622 1623 }; 1624 1625 var loadMore = { 1626 1627 init: function () { 1628 var self = this; 1629 1630 self.posts = '.loop-posts'; 1631 1632 self.pagination = '.load-more-pagination'; 1633 1634 $(document.body).on('click', '.load-more-pagination .load-more-button', function (e) { 1635 e.preventDefault(); 1636 self.loadPosts(this); 1637 }); 1638 1639 }, 1640 1641 loadPosts: function (_button) { 1642 var self = loadMore, 1643 loadMoreUrl = _button.getAttribute('href'), 1644 $posts = $(self.posts), 1645 $pagination = $(self.pagination); 1646 1647 if (loadMoreUrl === '#') { 1648 return; 1649 } 1650 1651 if ($pagination.hasClass('loading')) { 1652 return; 1653 } 1654 1655 $.ajax({ 1656 method: "GET", 1657 url: updateQueryStringParameter(loadMoreUrl, '_ajax', 1), 1658 beforeSend: function () { 1659 $pagination.addClass('loading'); 1660 }, 1661 complete: function () { 1662 $pagination.removeClass('loading'); 1663 } 1664 }).done(function (response) { 1665 var $parsedPosts = $(response).find(self.posts).children(); 1666 1667 $pagination.html($(response).find(self.pagination).html()); 1668 1669 $.each($parsedPosts, function (key, _post) { 1670 $posts.append(_post); 1671 1672 grid.resizeGridItem($(_post)); 1673 1674 /*gsap.set(_post, {opacity: 0, scale: 0}); 1675 gsap.to(_post, {duration: 0.4, opacity: 1, scale: 1});*/ 1676 }); 1677 1678 self._paginationBtn = document.querySelector(self.pagination); 1679 $(document.body).trigger('inspiration_load_more_posts_loaded', self._paginationBtn); 1680 }); 1681 }, 1682 1683 }; 1684 1685 var shareButton = { 1686 init: function () { 1687 var self = this; 1688 1689 $('.entry-share .share-buttons').on('click', 'a.btn-share', self.shareButtonHandler); 1690 }, 1691 1692 shareButtonHandler: function (e) { 1693 var self = shareButton, url, 1694 _this = this, 1695 _share = _this.parentNode, 1696 windowArgs = 'toolbar=no,scrollbars=yes,resizable=yes,width=700,height=700'; 1697 1698 e.preventDefault(); 1699 1700 switch (_this.dataset.type) { 1701 case 'facebook': 1702 url = 'https://www.facebook.com/sharer/?u=' + encodeURIComponent(_share.dataset.permalink); 1703 window.open(url, '_blank', windowArgs); 1704 break; 1705 case 'pinterest': 1706 url = 'https://pinterest.com/pin/create/bookmarklet/?media=' + encodeURIComponent(_share.dataset.thumbnail) + '&url=' + encodeURIComponent(_share.dataset.permalink); 1707 window.open(url, '_blank', windowArgs); 1708 break; 1709 case 'twitter': 1710 url = 'https://twitter.com/intent/tweet?text=' + encodeURIComponent(_share.dataset.title) + '&url=' + encodeURIComponent(_share.dataset.permalink); 1711 window.open(url, '_blank', windowArgs); 1712 break; 1713 case 'linkedin': 1714 var imgUrl = $('.woocommerce-product-gallery__image img').attr('src'); 1715 url = 'https://www.linkedin.com/shareArticle/?mini=true&title=' + encodeURIComponent(_share.dataset.title) + '&url=' + encodeURIComponent(_share.dataset.permalink); 1716 window.open(url, '_blank', windowArgs); 1717 break; 1718 case 'email': 1719 url = 'mailto:?subject=' + encodeURIComponent(_share.dataset.title) + '&body=' + encodeURIComponent('Your message...\n\n\n Read more: ' + _share.dataset.permalink); 1720 window.open(url, '_blank'); 1721 break; 1722 } 1723 } 1724 }; 1725 1726 var mailchimpEmbed = { 1727 1728 init: function () { 1729 var self = this; 1730 1731 self.mailchimp = 'form#mc-embedded-subscribe-form'; 1732 self.fnames = []; 1733 self.ftypes = []; 1734 1735 /*self.fnames[1] = "FNAME"; 1736 self.ftypes[1] = "text";*/ 1737 self.fnames[0] = "EMAIL"; 1738 self.ftypes[0] = "email"; 1739 1740 $(document.body).on('submit', self.mailchimp, self.submitHandler); 1741 1742 }, 1743 1744 submitHandler: function (e) { 1745 var self = mailchimpEmbed, 1746 $form = $(this), 1747 errors = 0; 1748 1749 e.preventDefault(); 1750 1751 $('#mce-success-response').hide(); 1752 $('#mce-error-response').hide(); 1753 1754 $form.find('.mc-field-group.invalid').removeClass('invalid'); 1755 $form.find('.mce_inline_error').remove(); 1756 1757 if ($form.find('[name="' + self.fnames[0] + '"]').val() === '') { 1758 $form.find('[name="' + self.fnames[0] + '"]').closest('.mc-field-group').addClass('invalid'); 1759 errors++; 1760 } 1761 1762 if (!self.validateEmail($form.find('[name="' + self.fnames[0] + '"]').val())) { 1763 $form.find('[name="' + self.fnames[0] + '"]').closest('.mc-field-group').addClass('invalid'); 1764 errors++; 1765 } 1766 1767 if (errors > 0) { 1768 return; 1769 } 1770 1771 $.ajax({ 1772 url: self.getAjaxSubmitUrl($form), 1773 type: 'GET', 1774 dataType: 'json', 1775 contentType: "application/json; charset=utf-8", 1776 data: $form.serializeArray(), 1777 success: function (response) { 1778 self.onSuccessCallback(response, $form) 1779 } 1780 }); 1781 }, 1782 1783 getAjaxSubmitUrl: function ($form) { 1784 var url = $form.attr("action"); 1785 url = url.replace("/post?u=", "/post-json?u="); 1786 url += "&c=?"; 1787 return url; 1788 }, 1789 1790 onSuccessCallback: function (resp, $form) { 1791 var self = mailchimpEmbed; 1792 1793 // On successful form submission, display a success message and reset the form 1794 if (resp.result === "success") { 1795 $('#mce-' + resp.result + '-response').show(); 1796 $('#mce-' + resp.result + '-response').html(resp.msg); 1797 $('#mc-embedded-subscribe-form').each(function () { 1798 this.reset(); 1799 }); 1800 1801 // If the form has errors, display them, inline if possible, or appended to #mce-error-response 1802 } else { 1803 if (resp.msg === "captcha") { 1804 var url = $("form#mc-embedded-subscribe-form").attr("action"); 1805 var parameters = $.param(resp.params); 1806 url = url.split("?")[0]; 1807 url += "?"; 1808 url += parameters; 1809 window.open(url); 1810 } 1811 1812 // Example errors - Note: You only get one back at a time even if you submit several that are bad. 1813 // Error structure - number indicates the index of the merge field that was invali
1813d, then details 1814 // Object {result: "error", msg: "6 - Please enter the date"} 1815 // Object {result: "error", msg: "4 - Please enter a value"} 1816 // Object {result: "error", msg: "9 - Please enter a complete address"} 1817 1818 // Try to parse the error into a field index and a message. 1819 // On failure, just put the dump thing into in the msg variable. 1820 var index = -1; 1821 var msg; 1822 try { 1823 var parts = resp.msg.split(' - ', 2); 1824 if (parts[1] == undefined) { 1825 msg = resp.msg; 1826 } else { 1827 const i = parseInt(parts[0]); 1828 if (i.toString() == parts[0]) { 1829 index = parts[0]; 1830 msg = parts[1]; 1831 } else { 1832 index = -1; 1833 msg = resp.msg; 1834 } 1835 } 1836 } catch (e) { 1837 index = -1; 1838 msg = resp.msg; 1839 } 1840 1841 try { 1842 // If index is -1 if means we don't have data on specifically which field was invalid. 1843 // Just lump the error message into the generic response div. 1844 if (index === -1) { 1845 $('#mce-' + resp.result + '-response').show(); 1846 $('#mce-' + resp.result + '-response').html(msg); 1847 1848 } else { 1849 var fieldName = $("input[name*='" + self.fnames[index] + "']").attr('name'); // Make sure this exists (they haven't deleted the fnames array lookup) 1850 var data = {}; 1851 data[fieldName] = msg; 1852 1853 $.each(data, function (name, message) { 1854 $form.find('[name="' + name + '"]').closest('.mc-field-group').addClass('invalid'); 1855 $form.find('[name="' + name + '"]').closest('.mc-field-group').append('<div class="mce_inline_error">' + message + '</div>'); 1856 }); 1857 } 1858 } catch (e) { 1859 $('#mce-' + resp.result + '-response').show(); 1860 $('#mce-' + resp.result + '-response').html(msg); 1861 } 1862 } 1863 }, 1864 1865 validateEmail: function (email) { 1866 const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 1867 return re.test(String(email).toLowerCase()); 1868 } 1869 1870 }; 1871 1872 var studiesCards = { 1873 init: function () { 1874 var self = this; 1875 1876 self.studyCardsInner = '.study-card-inner'; 1877 1878 if (window.innerWidth > 640) { 1879 self.bindEvents(); 1880 } 1881 1882 $(document.body).on('ajax_page_loaded ajax_switch_page_loaded', function () { 1883 if (window.innerWidth > 640) { 1884 self.bindEvents(); 1885 } 1886 }); 1887 1888 }, 1889 1890 bindEvents: function () { 1891 var self = this; 1892 1893 if (document.querySelectorAll(self.studyCardsInner)) { 1894 document.querySelectorAll(self.studyCardsInner).forEach(function (studyCard) { 1895 var moved = false; 1896 1897 studyCard.addEventListener('mouseenter', function (e) { 1898 self.toggleOverlay($(this), e, true); 1899 }); 1900 1901 studyCard.addEventListener('mouseleave', function (e) { 1902 self.toggleOverlay($(this), e, false); 1903 }); 1904 1905 studyCard.addEventListener('touchend', function (e) { 1906 if (!moved) { 1907 if ($(this).hasClass('overlay-active')) { 1908 self.toggleOverlay($(this), e, false); 1909 } else { 1910 self.toggleOverlay($(this), e, true); 1911 } 1912 } 1913 }); 1914 1915 studyCard.addEventListener('touchstart', function () { 1916 moved = false;
1917 }); 1918 1919 studyCard.addEventListener('touchmove', function () { 1920 moved = true; 1921 }); 1922 }); 1923 } 1924 1925 }, 1926 1927 toggleOverlay: function ($el, e, toggle) { 1928 var offset = $el.offset(); 1929 var $overlay = $el.find('.study-card-back'); 1930 var x, y; 1931 1932 if (e.type === 'touchend') { 1933 x = Math.floor(e.changedTouches[0].pageX - offset.left); 1934 y = Math.floor(e.changedTouches[0].pageY - offset.top); 1935 } else { 1936 x = Math.floor(e.pageX - offset.left); 1937 y = Math.floor(e.pageY - offset.top); 1938 } 1939 1940 if (toggle) { 1941 $el.addClass('overlay-active'); 1942 gsap.set($overlay.get(0), {clipPath: 'circle(0% at ' + x + 'px ' + y + 'px)'}); 1943 gsap.to($overlay.get(0), 0.5, {clipPath: 'circle(150% at ' + x + 'px ' + y + 'px)'}); 1944 } else { 1945 $el.removeClass('overlay-active'); 1946 gsap.to($overlay.get(0), {clipPath: 'circle(0% at ' + x + 'px ' + y + 'px)'}) 1947 } 1948 1949 } 1950 1951 }; 1952 1953 var studySinglePage = { 1954 1955 init: function () { 1956 var self = this; 1957 1958 self.studyMap = '.single-study-map .map-container'; 1959 self.scale = 1; 1960 self.scaleDivide = false; 1961 self.shiftPoint = { 1962 x: 0.8, 1963 y: 0.3 1964 } 1965 1966 self.initMap(); 1967 1968 $(document.body).on('ajax_page_loaded', function () { 1969 self.initMap(); 1970 }); 1971 1972 $(document.body).on('ajax_switch_page_loaded', function () { 1973 self.initMap(); 1974 }); 1975 1976 var t = false; 1977 1978 window.addEventListener('resize', function () { 1979 self.setCountryCenter(); 1980 }, {passive: true}); 1981 }, 1982 1983 initMap: function (status) { 1984 var self = this; 1985 1986 self._map = document.querySelector(self.studyMap); 1987 1988 if (null === self._map) { 1989 return false; 1990 } 1991 1992 self._svgMap = self._map.querySelector('svg') 1993 self.countryCode = self._map.dataset.countryCode; 1994 self._country = self._map.querySelector('path#' + self.countryCode); 1995 1996 if (null === self._country) { 1997 return false; 1998 } 1999 2000 self._map.classList.add('country-map-zoomed'); 2001 self._country.classList.add('current'); 2002 self._countryPos = self._country.getBoundingClientRect(); 2003 2004 if (self._countryPos.width <= 50) { 2005 self.scale = 4; 2006 } else if (self._countryPos.width > 50 && self._countryPos.width <= 100) { 2007 self.scale = 3; 2008 } else if (self._countryPos.width > 100 && self._countryPos.width <= 200) { 2009 self.scale = 2; 2010 } else if (self._countryPos.width > 200 && self._countryPos.width <= 500) { 2011 self.scale = 1; 2012 } else { 2013 self.scale = 1; 2014 } 2015 2016 self.setCountryCenter(); 2017 self._svgMap.classList.add('init'); 2018 }, 2019 2020 setCountryCenter: function () { 2021 var self = this; 2022 2023 if (null === self._map) { 2024 return false; 2025 } 2026 2027 var _svgMap = self._map.querySelector('svg'), 2028 _country = self._map.querySelector('path.current'); 2029 2030 var mapSizes = self._map.getBoundingClientRect(), 2031 mapPos = { 2032 x: mapSizes.width * self.shiftPoint.x, 2033 y: mapSizes.top + mapSizes.height * self.shiftPoint.y 2034 }; 2035 2036 var newPos = self.screenToSVG(_svgMap, mapPos.x, mapPos.y); 2037 var circle = _svgMap.querySelector('circle'); 2038 2039 if (!circle) { 2040 circle = document.createElementNS("http://www.w3.org/2000/svg", 'circle'); 2041 2042 circle.setAttributeNS(null, 'cx', newPos.x / self.scale); 2043 circle.setAttributeNS(null, 'cy', newPos.y / self.scale); 2044 circle.setAttributeNS(null, 'r', 2); 2045 circle.setAttributeNS(null, 'style', 'fill: none; stroke: none; stroke-width: 1px;'); 2046 _svgMap.appendChild(circle); 2047 } 2048 2049 self._svgMap.style.transform = 'scale(' + self.scale + ') translate(0px, 0px)'; 2050 2051 var calcPos = { 2052 x: circle.getBoundingClientRect().x - (_country.getBoundingClientRect().x + (_country.getBoundingClientRect().width / 2)), 2053 y: circle.getBoundingClientRect().y - _country.getBoundingClientRect().y, 2054 } 2055 2056 if (self.scale > 1) { 2057 calcPos.x = calcPos.x / self.scale; 2058 calcPos.y = calcPos.y / self.scale; 2059 } 2060 2061 _svgMap.style.transform = 'scale(' + self.scale + ') translate(' + (calcPos.x) + 'px, ' + (calcPos.y) + 'px)'; 2062 }, 2063 2064 screenToSVG: function (_svgMap, screenX, screenY) { 2065 var p = _svgMap.createSVGPoint() 2066 p.x = screenX 2067 p.y = screenY 2068 return p.matrixTransform(_svgMap.getScreenCTM().inverse()); 2069 }, 2070 2071 SVGToScreen: function (_svgMap, svgX, svgY) { 2072 var p = _svgMap.createSVGPoint() 2073 p.x = svgX 2074 p.y = svgY 2075 return p.matrixTransform(_svgMap.getScreenCTM()); 2076 } 2077 2078 }; 2079 2080 var timeline = { 2081 init: function() { 2082 var self = this; 2083 2084 this.$container = $('.section-timeline__container'); 2085 this.$timeline = this.$container.find('.timeline'); 2086 this.$dots = this.$container.find('.timeline__dot'); 2087 this.$dotsProgress = this.$container.find('.timeline__dots-progress'); 2088 this.$content = this.$container.find('.timeline-content-item__wrap'); 2089 2090 if(this.$timeline.length === 0) { 2091 window.removeEventListener('scroll', self.timelineScrollHandler); 2092 return; 2093 } 2094 2095 this.setTimelineHeight(); 2096 this.setTimelineContentHeight(); 2097 this.bindEvents(); 2098 }, 2099 2100 setTimelineHeight: function () { 2101 if(this.$dots.length === 0) { 2102 return; 2103 } 2104 2105 var height = parseInt(this.$timeline.data('dots-count')) * this.$container.height(); 2106 var $section = this.$container.closest('.section-timeline'); 2107 $section.height(height); 2108 }, 2109 2110 2111 setTimelineContentHeight: function () { 2112 var height = 0; 2113 2114 if(this.$content.length === 0) { 2115 return; 2116 } 2117 2118 this.$content.each(function(){ 2119 height = Math.max(height, $(this).height()); 2120 }); 2121 2122 this.$content.closest('.section-timeline__content').height(height); 2123 }, 2124 2125 bindEvents: function() { 2126 var self = this; 2127 2128 window.addEventListener('scroll', self.timelineScrollHandler, {passive: true}); 2129 }, 2130 2131 timelineScrollHandler: function () { 2132 var self = timeline; 2133 2134 var $section = $('.section-timeline'); 2135 2136 if ($section.length === 0) { 2137 window.removeEventListener('scroll', self.timelineScrollHandler); 2138 return; 2139 } 2140 2141 var topPosition = $section.offset().top; 2142 var $items = $section.find('.timeline-content-item'); 2143 2144 $items.each(function () { 2145 var containerHeight = self.$container.height(); 2146 var index = $(this).index(); 2147 var scrollTop = $(window).scrollTop() + 0.5 * $(window).height(); 2148 2149 if (!$(this).hasClass('active') && scrollTop >= topPosition + index * containerHeight && scrollTop < topPosition + index * containerHeight + containerHeight) { 2150 $section.find('.active').removeClass('active'); 2151 $(this).addClass('active'); 2152 2153 if(self.$dots.length > 0){ 2154 if($(this).hasClass('milestone-item')){ 2155 self.$dots.filter('.active').removeClass('active'); 2156 self.$dots.eq($(this).index() - 1).addClass('active'); 2157 } 2158 2159 var $activeDot = self.$dots.filter('.active'); 2160 2161 if($activeDot.length > 0) { 2162 var progressWidth = $($activeDot).get(0).style.getPropertyValue('--position-x'); 2163 self.$dotsProgress.get(0).style.setProperty('--dots-progress', progressWidth); 2164 } else { 2165 self.$dotsProgress.get(0).style.setProperty('--dots-progress', '0%'); 2166 } 2167 } 2168 } 2169 }); 2170 2171 if (isElementInCenterOfViewport('.section-timeline__container') && !self.$timeline.hasClass('progress-animate')) { 2172 self.$timeline.addClass('progress-animate'); 2173 2174 setTimeout(function(){ 2175 self.$timeline.addClass('progress-animated'); 2176 }, 800); 2177 } 2178 }, 2179 2180 resetAnimateClasses: function() { 2181 if(this.$timeline.length > 0) { 2182 this.$timeline.removeClass('progress-animate progress-animated'); 2183 } 2184 } 2185 2186 }; 2187 2188 $(document).ready(function () { 2189 main.init(); 2190 studiesCards.init();
2191 ajaxPage.init(); 2192 frontPage.init(); 2193 memberSinglePage.init(); 2194 mailchimpEmbed.init(); 2195 studySinglePage.init(); 2196 timeline.init(); 2197 }); 2198 2199 $(window).on('load', function () { 2200 ajaxPage.onLoad(); 2201 }); 2202 2203 $(document.body).CustomResize({ 2204 resize: function () { 2205 frontPage.calculateCardHeight(); 2206 }, 2207 timeout: 200 2208 }); 2209 2210}(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.