PageSourceSearch

https://geckoconsortium.com/wp-content/themes/gecko/assets/js/main.js?ver=1.2.0.1699270096

js geckoconsortium.com collected 2026-10-04 15:11:29 UTC 77,063 bytes, 2,210 lines download raw bytes

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                '&lt;': '<',
205                '&gt;': '>',
206                '&quot;': '"',
207                '&#039;': "'"
208            };
209
210            return text.replace(/&amp;|&lt;|&gt;|&quot;|&#039;/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.