PageSourceSearch

https://www.mhc.on.ca/templates/gridbox/js/gridbox.js?2.20.2.3

js mhc.on.ca collected 2026-10-04 13:44:25 UTC 52,614 bytes, 1,353 lines download raw bytes

1/**
2* @package   Gridbox template
3* @author    Balbooa http://www.balbooa.com/
4* @copyright Copyright @ Balbooa
5* @license   http://www.gnu.org/licenses/gpl.html GNU/GPL
6*/
7
8var recaptchaCommentsOnload = function() {
9    let str = '.ba-item-comments-box > .ba-comments-box-wrapper > .ba-comment-message-wrapper .ba-comments-captcha-wrapper';
10    $g(str).each(function(){
11        app.initCommentsRecaptcha(this);
12    });
13    $g('.ba-login-captcha-wrapper').each(function(){
14        app.initLoginRecaptcha(this);
15    });
16};
17
18var verifyLoginCaptcha = () => {
19    document.querySelectorAll('.login-recaptcha').forEach(function($this){
20        app[app.login ? 'login' : 'checkoutForm'].removeAlertTooltip($this);
21    });
22}
23
24if (window.integrations && window.integrations.facebook) {
25    window.fbAsyncInit = () => {
26        app.facebook.initialize();
27    }
28}
29
30var $g = jQuery,
31    delay = '',
32    itemsInit = [],
33    app = {
34        hash: window.location.hash,
35        view : 'desktop',
36        modules : {},
37        loading : {},
38        edit : {},
39        items : {},
40        isExternal: function(link){
41            return link.indexOf('https://') != -1 || link.indexOf('http://') != -1;
42        },
43        facebook: {
44            load: () => {
45                app.loading.facebook = true;
46                let js = document.createElement('script');
47                if (document.getElementById('facebook-jssdk')) return;
48                js.id = 'facebook-jssdk';
49                js.src = "https://connect.facebook.net/en_US/sdk.js";
50                js.crossorigin = 'anonymous';
51                document.head.append(js);
52            },
53            initialize: () => {
54                FB.init({
55                    appId : window.integrations.facebook,
56                    autoLogAppEvents : true,
57                    xfbml : true,
58                    version : 'v14.0'
59                });
60            },
61            getUserInfo: (response) => {
62                return new Promise((resolve, reject) => {
63                    if (response.status === 'connected') {
64                        FB.api('/'+response.authResponse.userID+'/?fields=id,name,email,picture', 'GET', {}, (fields) => {
65                            let data = {
66                                    name: fields.name,
67                                    email: fields.email,
68                                    avatar: fields.picture.data.url,
69                                    id: fields.id
70                                }
71                            resolve(data);
72                        });
73                    }
74                });
75            }
76        },
77        google: {
78            load: (callback, selector, options) => {
79                let js = document.createElement('script');
80                js.src = 'https://accounts.google.com/gsi/client'
81                js.onload = () => {
82                    app.google.initialize(callback, selector, options);
83                }
84                document.head.append(js);
85            },
86            initialize: (callback, selector, options) => {
87                google.accounts.id.initialize({
88                    client_id: window.integrations.google,
89                    callback: callback
90                });
91                setTimeout(() => {
92                    document.querySelectorAll(selector).forEach((parent) => {
93                        google.accounts.id.renderButton(parent, options);
94                    });
95                }, 1000);
96            },
97            renderButton: (selector, options) => {
98                document.querySelectorAll(selector).forEach((parent) => {
99                    google.accounts.id.renderButton(parent, options);
100                });
101            },
102            JSONWebToken: (token) => {
103                let url = token.split('.')[1],
104                    base = url.replace(/-/g, '+').replace(/_/g, '/'),
105                    json = decodeURIComponent(window.atob(base).split('').map(function(c) {
106                        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
107                    }).join(''));
108
109                return JSON.parse(json);
110            },
111            getUserInfo: function(profile){
112                let data = {
113                        name: profile.name,
114                        email: profile.email,
115                        avatar: profile.picture,
116                        id: profile.sub
117                    }
118
119                return data;
120            }
121        },
122        decimalAdjust: function(type, value, exp){
123            if (typeof exp === 'undefined' || +exp === 0) {
124                return Math[type](value);
125            }
126            value = +value;
127            exp = +exp;
128            if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
129                return NaN;
130            }
131            value = value.toString().split('e');
132            value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
133            value = value.toString().split('e');
134
135            return +(value[0]+'e'+(value[1] ? (+value[1] + exp) : exp));
136        },
137        strrev: function(string){
138            let ret = '', i = 0;
139            for (i = string.length - 1; i >= 0; i--) {
140                ret += string[i];
141            }
142
143            return ret;
144        },
145        renderPrice: function(value, thousand, separator, decimals, rate){
146            rate = !rate ? 1 : rate;
147            value *= rate;
148            value = app.decimalAdjust('round', value, decimals * -1);
149            value = String(value);
150            let delta = value < 0 ? '-' : '',
151                priceArray = value.replace('-', '').trim().split('.'),
152                priceThousand = priceArray[0],
153                priceDecimal = priceArray[1] ? priceArray[1] : '',
154                price = '';
155            if (priceThousand.length > 3 && thousand != '') {
156                for (let i = 0; i < priceThousand.length; i++) {
157                    if (i % 3 == 0 && i != 0) {
158                        price += thousand;
159                    }
160                    price += priceThousand[priceThousand.length - 1 - i];
161                }
162                price = app.strrev(price);
163            } else {
164                price += priceThousand;
165            }
166            if (decimals != 0) {
167                price += separator;
168                for (let i = 0; i < decimals; i++) {
169                    price += priceDecimal[i] ? priceDecimal[i] : '0';
170                }
171            }
172
173            return delta+price;
174        },
175        getObject: function(key){
176            var object = $g.extend(true, {}, app.items[key].desktop);
177            if (app.view != 'desktop') {
178                for (var ind in breakpoints) {
179                    if (!app.items[key][ind]) {
180                        app.items[key][ind] = {};
181                    }
182                    object = $g.extend(true, {}, object, app.items[key][ind]);
183                    if (ind == app.view) {
184                        break;
185                    }
186                }
187            }
188
189            return object;
190        },
191        initLoginRecaptcha: function(parent){
192            if (!recaptchaObject) {
193
194                return false;
195            }
196            let elem = document.createElement('div'),
197                options = {
198                    sitekey: recaptchaObject.public_key,
199                    callback: verifyLoginCaptcha
200                };
201            elem.id = 'login-recaptcha-'+(+new Date());
202            elem.className = 'login-recaptcha';
203            parent.innerHTML = '';
204            parent.append(elem);
205            if (parent.dataset.type == 'recaptcha') {
206                options.theme = recaptchaObject.theme;
207                options.size = recaptchaObject.size;
208            } else {
209                options.badge = recaptchaObject.badge;
210                options.size = 'invisible';
211                parent.classList.add(options.badge+'-style');
212            }
213            recaptchaObject.data[elem.id] = grecaptcha.render(elem, options);
214            if (parent.dataset.type != 'recaptcha') {
215                grecaptcha.execute(recaptchaObject.data[elem.id]);
216            }
217        },
218        initCommentsRecaptcha: function(parent){
219            if (!recaptchaObject) {
220
221                return false;
222            }
223            let elem = document.createElement('div'),
224                options = {
225                    sitekey : recaptchaObject.public_key
226                };
227            elem.id = 'comments-recaptcha-'+(+new Date());
228            elem.className = 'comments-recaptcha';
229            parent.innerHTML = '';
230            parent.append(elem);
231            if (recaptchaObject.type == 'recaptcha') {
232                options.theme = recaptchaObject.theme;
233                options.size = recaptchaObject.size;
234            } else {
235                options.badge = recaptchaObject.badge;
236                options.size = 'invisible';
237                elem.closest('.ba-comments-captcha-wrapper').classList.add(options.badge+'-style');
238            }
239            recaptchaObject.data[elem.id] = grecaptcha.render(elem, options);
240            if (recaptchaObject.type != 'recaptcha') {
241                grecaptcha.execute(recaptchaObject.data[elem.id]);
242            }
243        },
244        hideNotice:function(){
245            app.notification.classList.remove('notification-in');
246            app.notification.classList.add('animation-out');
247        },
248        checkOverlay: function(obj, key){
249            $g('.ba-item-overlay-section').each(function(){
250                $g(this).find('.ba-overlay-section-backdrop').appendTo(document.body);
251            });
252        },
253        _: function(key){
254            if (window.gridboxLanguage && gridboxLanguage[key]) {
255                return gridboxLanguage[key];
256            } else {
257                return key;
258            }
259        },
260        checkGridboxPaymentError: function(){
261            let gridbox_payment_error = localStorage.getItem('gridbox_payment_error');
262            if (gridbox_payment_error) {
263                app.showNotice(gridbox_payment_error, 'ba-alert');
264                localStorage.removeItem('gridbox_payment_error');
265            }
266        },
267        loadNotice: function(){
268            return new Promise(function(resolve, reject) {
269
270                fetch(JUri+'components/com_gridbox/libraries/css/plugins/notification.css').then(function(request){
271                    return request.text();
272                }).then(function(text){
273                    let style = document.createElement('style');
274                    document.head.append(style);
275                    style.innerHTML = text;
276                    app.notification = document.createElement('div');
277                    app.notification.id = 'ba-notification';
278                    app.notification.innerHTML = '<i class="zmdi zmdi-close"></i><h4>'+app._('ERROR')+'</h4><p></p>';
279                    app.notification.querySelector('.zmdi-close').addEventListener('click', function(){
280                        app.hideNotice();
281                    });
282                    document.body.appendChild(app.notification);
283                    resolve();
284                });
285            });
286        },
287        showNotice: function(message, className){
288            if (!app.notification) {
289                app.loadNotice().then(() => {
290                    app.showNotice(message, className);
291                });
292                return false;
293            }
294            app.notification.showCallback = function(){};
295            if (!className) {
296                className = '';
297            }
298            if (app.notification.classList.contains('notification-in')) {
299                app.notification.showCallback = function(){
300                    app.notification.showCallback = function(){};
301                    app.addNoticeText(message, className);
302                };
303            } else {
304                app.addNoticeText(message, className);
305            }
306        },
307        addNoticeText: function(message, className){
308            var time = 3000;
309            if (className == 'ba-alert') {
310                time = 6000;
311            }
312            app.notification.querySelector('p').innerHTML = message;
313            if (className) {
314                app.notification.classList.add(className);
315            } else {
316                app.notification.classList.remove('ba-alert');
317            }
318            app.notification.classList.remove('animation-out')
319            app.notification.classList.add('notification-in');
320            clearTimeout(app.notification.hideDelay);
321            app.notification.hideDelay = setTimeout(function(){
322                app.hideNotice();
323                setTimeout(function(){
324                    if (className) {
325                        app.notification.classList.remove(className);
326                    }
327                    app.notification.showCallback();
328                }, 400);
329            }, time);
330        },
331        disabledAnimation: {
332            'sticky-header': true,
333            'lightbox': true
334        },
335        checkAnimation: function(){
336            app.viewportItems = [];
337            app.motionItems = [];
338            $g('.ba-section, .ba-row, .ba-grid-column').each(function(){
339                if (!app.items[this.id]) {
340                    return;
341                }
342                let object = $g.extend(true, {}, app.items[this.id].desktop.animation);
343                let motion = $g.extend(true, {}, app.items[this.id].desktop.motions ?? {});
344                let inMotion = false;
345                const canAnimate = !app.disabledAnimation[app.items[this.id].type];
346                const motions = {
347                    desktop: motion
348                };
349                if (app.view != 'desktop') {
350                    for (let ind in breakpoints) {
351                        if (!app.items[this.id][ind]) {
352                            app.items[this.id][ind] = {
353                                animation : {}
354                            }
355                        }
356                        object = $g.extend(true, {}, object, app.items[this.id][ind].animation);
357                        if (ind == app.view) {
358                            break;
359                        }
360                    }
361                }
362                for (let ind in breakpoints) {
363                    if (!app.items[this.id][ind]) {
364                        app.items[this.id][ind] = {
365                            animation : {}
366                        }
367                    }
368                    motion = $g.extend(true, {}, motion, app.items[this.id][ind]?.motions ?? motion);
369                    motions[ind] = motion;
370                }
371                if (object.effect && canAnimate) {
372                    app.viewportItems.push({
373                        animation: object,
374                        item: $g(this)
375                    });
376                } else if (!object.effect && canAnimate && $g(this).viewportChecker) {
377                    $g(this).viewportChecker(object)
378                } else if (object.effect) {
379                    this.classList.add('visible');
380                }
381                for (let ind in motions) {
382                    for (let key in motions[ind]) {
383                        if (motions[ind][key].enable) {
384                            app.motionItems.push({
385                                motions: motions,
386                                item: $g(this)
387                            });
388                            inMotion = true;
389                            break;
390                        }
391                    }
392                    if (inMotion) {
393                        break;
394                    }
395                }
396                if ($g(this).motion && !inMotion) {
397                    $g(this).motion(motions);
398                }
399            });
400            $g('.ba-item').each(function(){
401                if (app.items[this.id] && app.items[this.id].desktop && app.items[this.id].desktop.appearance) {
402                    let object = $g.extend(true, {}, app.items[this.id].desktop.appearance),
403                        motion = app.items[this.id].desktop.motions ? $g.extend(true, {}, app.items[this.id].desktop.motions) : {},
404                        inMotion = false,
405                        motions = {
406                            desktop: motion
407                        };
408                    if (app.view != 'desktop') {
409                        for (let ind in breakpoints) {
410                            if (!app.items[this.id][ind]) {
411                                app.items[this.id][ind] = {
412                                    appearance : {}
413                                };
414                            }
415                            object = $g.extend(true, {}, object, app.items[this.id][ind].appearance);
416                            if (ind == app.view) {
417                                break;
418                            }
419                        }
420                    }
421                    for (let ind in breakpoints) {
422                        motion = app.items[this.id][ind].motions ? $g.extend(true, {}, motion, app.items[this.id][ind].motions) : motion;
423                        motions[ind] = motion;
424                    }
425                    if (object.effect) {
426                        app.viewportItems.push({
427                            animation: object,
428                            item: $g(this)
429                        });
430                    } else if (!object.effect && $g(this).viewportChecker) {
431                        $g(this).viewportChecker(object)
432                    } else if (object.effect) {
433                        this.classList.add('visible');
434                    }
435                    for (let ind in motions) {
436                        for (let key in motions[ind]) {
437                            if (motions[ind][key].enable) {
438                                app.motionItems.push({
439                                    motions: motions,
440                                    item: $g(this)
441                                });
442                                inMotion = true;
443                                break;
444                            }
445                        }
446                        if (inMotion) {
447                            break;
448                        }
449                    }
450                    if ($g(this).motion && !inMotion) {
451                        $g(this).motion(motions);
452                    }
453                }
454            });
455            if (app.viewportItems.length > 0 || app.motionItems.length > 0) {
456                app.checkModule('loadAnimations');
457            }
458        },
459        checkModule : function(name, obj){
460            if (name == 'loadVideoApi' && app.modules[name] && obj && obj.data.type != 'youtube+vimeo'
461                && app.modules[name].data.type != 'youtube+vimeo' && app.modules[name].data.type != obj.data.type) {
462                obj.data.type = 'youtube+vimeo';
463            } else if (typeof(obj) != 'undefined') {
464                app.modules[name] = obj;
465            }
466            if (typeof(app[name]) == 'undefined' && !app.loading[name]) {
467                app.loading[name] = true;
468                app.loadModule(name);
469            } else if (typeof(app[name]) != 'undefined') {
470                if (typeof(obj) != 'undefined') {
471                    app[name](obj.data, obj.selector);
472                } else {
473                    app[name]();
474                }
475            }
476        },
477        checkVideoBackground : function(){
478            let flag = false;
479            $g('.ba-section, .ba-row, .ba-grid-column').each(function(){
480                if (app.items[this.id] && app.items[this.id].desktop.background.type == 'video') {
481                    flag = true;
482                    return false;
483                }
484            });
485            $g('.ba-item-flipbox').each(function(){
486                if (app.items[this.id] && app.items[this.id].sides.frontside.desktop.background
487                    && app.items[this.id].sides.frontside.desktop.background.type == 'video') {
488                    flag = true;
489                    return false;
490                }
491                if (app.items[this.id] && app.items[this.id].sides.backside.desktop.background
492                    && app.items[this.id].sides.backside.desktop.background.type == 'video') {
493                    flag = true;
494                    return false;
495                }
496            });
497            if (app.theme.desktop.background.type == 'video') {
498                flag = true;
499            }
500            if (flag) {
501                app.checkModule('createVideo', {});
502            }
503        },
504        loadModule : function(key){
505            if (key != 'setCalendar' && key != 'defaultElementsStyle' && key != 'gridboxLanguage' &&
506                key != 'shapeDividers' && key != 'presetsPatern') {
507                var script = document.createElement('script');
508                script.src = JUri+'components/com_gridbox/libraries/modules/'+key+'.js?'+gridboxVersion;
509                document.head.append(script);
510                return false;
511            }
512            $g.ajax({
513                type:"POST",
514                dataType:'text',
515                url:"index.php?option=com_gridbox&task=editor.loadModule&module="+key+"&"+gridboxVersion,
516                data:{
517                    module : key
518                },
519                complete: function(msg){
520                    let script = document.createElement('script');
521                    document.head.append(script);
522                    script.innerHTML = msg.responseText;
523                }
524            });
525        },
526        checkView: function(){
527            var width = $g(window).width();
528            app.view = 'desktop';
529            for (var ind in breakpoints) {
530                if (width <= breakpoints[ind]) {
531                    app.view = ind;
532                }
533            }
534        },
535        resize: function(){
536            clearTimeout(delay);
537            app.checkView();
538            delay = setTimeout(function(){
539                if ('setPostMasonryHeight' in window) {
540                    $g('.ba-blog-posts-wrapper.ba-masonry-layout').each(function(){
541                        var key = $g(this).closest('.ba-item').attr('id');
542                        setPostMasonryHeight(key);
543                    });
544                }
545                if ('setGalleryMasonryHeight' in window) {
546                    $g('.gridbox-gallery-wrapper.simple-gallery-masonry-layout').each(function(){
547                        setGalleryMasonryHeight(this.closest('.ba-item').id);
548                    });
549                }
550            }, 300);
551        },
552        checkCommentInTabs: function(hash){
553            $g('a.'+hash.replace('#', '')).first().each(function(){
554                let tab = this.closest('.tab-pane, .accordion-body');
555                if (tab && !tab.classList.contains('active') && !tab.classList.contains('in')) {
556                    $g('a[href="#'+tab.id+'"]').trigger('click');
557                }
558            });
559        },
560        gridboxLoaded: function(){
561            app.checkView();
562            app.checkAnimation();
563            checkOnePage();
564            $g(window).on('resize', app.resize);
565            if (!$g('body').hasClass('gridbox')) {
566                $g(window).on('scroll.onepage', checkOnePageActive);
567            }
568            $g(window).on('scroll', function(){
569                var top = window.pageYOffset;
570                if (!('lastPageYOffset' in window)) {
571                    window.lastPageYOffset = top;
572                }
573                $g('header')[top > 40 ? 'addClass' : 'removeClass']('fixed-header');
574                $g('.ba-sticky-header').each(function(){
575                    this.closest('header, footer, .body').classList.add('ba-sticky-header-parent');
576                    if (this.querySelector('.ba-sticky-header > .ba-section')) {
577                        var section = this.querySelector('.ba-sticky-header > .ba-section'),
578                            obj = app.items[section.id],
579                            offset = obj.desktop.offset;
580                        if (app.view != 'desktop') {
581                            for (var ind in breakpoints) {
582                                if (!obj[ind]) {
583                                    obj[ind] = {};
584                                }
585                                offset = obj[ind].offset ? obj[ind].offset : offset;
586                                if (ind == app.view) {
587                                    break;
588                                }
589                            }
590                        }
591                        if (!this.classList.contains('visible-sticky-header')) {
592                            if (top >= offset * 1 &&
593                                (!obj.scrollup || (obj.scrollup && top - window.lastPageYOffset < 0))) {
594                                this.classList.add('visible-sticky-header');
595                                document.body.classList.add('sticky-header-opened');
596                                if (obj.desktop.animation.effect) {
597                                    section.classList.add(obj.desktop.animation.effect);
598                                    setTimeout(function(){
599                                        section.classList.remove(obj.desktop.animation.effect);
600                                    }, obj.desktop.animation.delay * 1000 + obj.desktop.animation.duration * 1000);
601                                }
602                                $g(window).trigger('scroll');
603                            }
604                        }
605                        if ((top < offset * 1 && !obj.scrollup) || (obj.scrollup && (top - window.lastPageYOffset > 0 || top <= offset * 1))) {
606                            this.classList.remove('visible-sticky-header');
607                            document.body.classList.remove('sticky-header-opened');
608                        }
609                    }
610                });
611                window.lastPageYOffset = top;
612            });
613            $g(window).trigger('scroll');
614            $g('.ba-item [contenteditable]').removeAttr('contenteditable');
615            if ($g('.ba-item-overlay-section').length > 0) {
616                app.checkModule('checkOverlay');
617            }
618            $g('.ba-item-main-menu, .ba-item-one-page-menu, .ba-item-overlay-section').each(function(){
619                if (app.items[this.id]) {
620                    var obj = {
621                        data : app.items[this.id],
622                        selector : this.id
623                    };
624                    itemsInit.push(obj);
625                }
626            });
627            $g('.ba-item').not('.ba-item-main-menu, .ba-item-one-page-menu, .ba-item-overlay-section').each(function(){
628                if (app.items[this.id]) {
629                    var obj = {
630                        data : app.items[this.id],
631                        selector : this.id
632                    };
633                    itemsInit.push(obj);
634                }
635            });
636            if (itemsInit.length > 0) {
637                itemsInit.reverse();
638                app.checkModule('initItems', itemsInit.pop());
639            }
640            app.checkVideoBackground();
641            $g('.ba-lightbox-backdrop').on('keyup', function(event){
642                if (event.key == 'Escape') {
643                    $g(this).find('.ba-lightbox-close').first().click();
644                }
645            }).find('.ba-lightbox-close').on('click keyup', function(event){
646                app.AccessibilityHelper.processAction(event, () => {
647                    const lightbox = this.closest('.ba-lightbox-backdrop');
648                    lightboxVideoClose(lightbox);
649                    lightbox.classList.remove('visible-lightbox');
650                    app.AccessibilityHelper.releaseTrap(lightbox.querySelector('.ba-wrapper'));
651                    document.body.classList.remove('lightbox-open');
652                });
653            });
654            $g('.ba-lightbox-backdrop').each(function(){
655                let obj = app.items[this.dataset.id];
656                if (obj.type == 'cookies' || !obj.session.enable) {
657                    initLightbox(this, obj);
658                } else {
659                    let flag = true;
660                    if (localStorage[this.dataset.id]) {
661                        let date =  new Date().getTime(),
662                            expires = new Date(localStorage[this.dataset.id]);
663                        expires.getTime();
664                        if (date >= expires) {
665                            flag = true;
666                            localStorage.removeItem(this.dataset.id);
667                        } else {
668                            flag = false;
669                        }
670                    }
671                    if (flag) {
672                        let expiration = new Date();
673                        expiration.setDate(expiration.getDate() + obj.session.duration * 1);
674                        localStorage.setItem(this.dataset.id, expiration);
675                        initLightbox(this, obj);
676                    }
677                }
678            });
679            $g('.ba-section, .ba-row, .ba-grid-column').each(function(){
680                if (app.items[this.id] && app.items[this.id].parallax && app.items[this.id].parallax.enable) {
681                    app.checkModule('loadParallax');
682                    return false;
683                }
684            });
685            if (document.querySelector('.open-calendar-dialog')) {
686                app.loadModule('calendar');
687            }
688        }
689    };
690
691app.fetch = async function(url, data, isFile) {
692    const module = await import(`${JUri}components/com_gridbox/assets/modules/Request.js`)
693
694    return await module.default.post(url, data, isFile);
695}
696
697app.getFormData = async function(data, isFile) {
698    const module = await import(`${JUri}components/com_gridbox/assets/modules/Request.js`)
699
700    return await module.default.getBody(data, isFile);
701}
702
703app.preloaded = {
704    total: 0,
705    loaded: 0,
706    loadGridbox: function(){
707        app.lazyLoad ? app.lazyLoad.check() : '';
708        app.preloaded.end = true;
709        app.gridboxLoaded();
710    },
711    callback: function(){
712        app.preloaded.loaded++;
713        if (app.preloaded.total <= app.preloaded.loaded && !app.preloaded.end && document.readyState != 'loading') {
714            app.preloaded.loadGridbox();
715        }
716    }
717}
718
719document.querySelectorAll('link[rel="preload"][as="style"]').forEach(function(link){
720    link.onload = app.preloaded.callback;
721    link.onerror = app.preloaded.callback;
722    app.preloaded.total++;
723});
724
725class CustomSelect {
726    constructor(element)
727    {
728        this.$select = $g(element);
729        this.$textInput = this.$select.find('input[type="text"]');
730        this.$hiddenInput = this.$select.find('input[type="hidden"]');
731        this.$list = this.$select.find('ul');
732
733        this.currentIndex = -1;
734
735        this.setupAria();
736        this.attachEvents();
737    }
738
739    getOptions()
740    {
741        return this.$list.find('li');
742    }
743
744    setupAria()
745    {
746        const listId = 'listbox-' + Math.random().toString(36).substr(2, 6);
747
748        this.$select.attr({
749            'role': 'combobox',
750            'aria-haspopup': 'listbox',
751            'aria-expanded': 'false',
752        });
753
754        this.$list.attr({
755            'role': 'listbox',
756            'tabindex': '-1',
757            'id': listId
758        });
759
760        this.$textInput.attr({
761            'readonly': 'true',
762            'aria-controls': listId
763        });
764    }
765
766    attachEvents()
767    {
768        this.$select.on('click', 'i, input', () => {
769            if (!this.$list.hasClass('visible-select')) {
770                setTimeout(() => this.openList(), 100);
771            }
772        });
773
774        this.$select.on('click', 'li', (event) => {
775            const index = this.getOptions().index(event.currentTarget);
776            this.selectOption(index);
777        });
778
779        this.$select.on('keydown', (e) => this.handleKeydown(e));
780    }
781
782    openList()
783    {
784        const options = this.getOptions();
785        this.$list.addClass('visible-select');
786        this.$select.attr('aria-expanded', 'true');
787
788        options.removeClass('focused');
789
790        const selectedIndex = options.index(options.filter('.selected'));
791        this.currentIndex = selectedIndex >= 0 ? selectedIndex : 0;
792
793        if (options.length > 0) {
794            options.eq(this.currentIndex).addClass('focused');
795        }
796
797        this.$select.trigger('show');
798    }
799
800    closeList()
801    {
802        this.$list.removeClass('visible-select');
803        this.$select.attr('aria-expanded', 'false');
804        this.getOptions().removeClass('focused');
805    }
806
807    selectOption(index)
808    {
809        const options = this.getOptions();
810        const $opt = options.eq(index);
811
812        options.removeClass('selected');
813        $opt.addClass('selected');
814
815        this.$textInput.val($opt.text().trim());
816        this.$hiddenInput.val($opt.data('value')).trigger('change');
817
818        this.currentIndex = index;
819
820        this.$select.trigger('customAction');
821        this.closeList();
822    }
823
824    handleKeydown(e)
825    {
826        const options = this.getOptions();
827        if (options.length === 0) return;
828
829        if (e.key === ' ' || e.key === 'Enter') {
830            e.preventDefault();
831            if (!this.$list.hasClass('visible-select')) {
832                this.openList();
833            } else {
834                this.selectOption(this.currentIndex);
835            }
836        } else if (e.key === 'ArrowDown') {
837            e.preventDefault();
838            if (!this.$list.hasClass('visible-select')) {
839                this.openList();
840            } else {
841                this.currentIndex = (this.currentIndex + 1) % options.length;
842                this.updateFocus();
843            }
844        } else if (e.key === 'ArrowUp') {
845            e.preventDefault();
846            if (!this.$list.hasClass('visible-select')) {
847                this.openList();
848            } else {
849                this.currentIndex = (this.currentIndex - 1 + options.length) % options.length;
850                this.updateFocus();
851            }
852        } else if (e.key === 'Escape') {
853            this.closeList();
854        }
855    }
856
857    updateFocus()
858    {
859        const options = this.getOptions();
860        options.removeClass('focused');
861        options.eq(this.currentIndex).addClass('focused');
862    }
863
864    static initAll(selector = '.ba-custom-select')
865    {
866        $g(selector).each(function () {
867            new CustomSelect(this);
868        });
869    }
870}
871
872document.addEventListener("DOMContentLoaded", function(){
873    $g('link[rel="preload"][as="style"]').attr('rel', 'stylesheet');
874    document.body.style.opacity = '';
875    document.body.style.overflow = '';
876    document.body.style.margin = '';
877    let preloader = document.querySelector('.ba-item-preloader');
878    if (preloader) {
879        setTimeout(function(){
880            preloader.classList.add('preloader-animation-out');
881            app.checkGridboxPaymentError();
882        }, preloader.dataset.delay * 1000);
883    } else {
884        app.checkGridboxPaymentError();
885    }
886    if ('setPostMasonryHeight' in window) {
887        $g('.ba-blog-posts-wrapper.ba-masonry-layout').each(function(){
888            var key = $g(this).closest('.ba-item').attr('id');
889            setPostMasonryHeight(key);
890        });
891    }
892    if ('setGalleryMasonryHeight' in window) {
893        $g('.gridbox-gallery-wrapper.simple-gallery-masonry-layout').each(function(){
894            setGalleryMasonryHeight(this.closest('.ba-item').id);
895        });
896    }
897    if (app.hash == '#total-count-wrapper' || app.hash == '#total-reviews-count-wrapper') {
898        let item = $g('a.'+app.hash.replace('#', ''));
899        app.checkCommentInTabs(app.hash);
900        app.scrollIntoView(item);
901    }
902    $g('body').on('click', function(){
903        $g('.visible-select').removeClass('visible-select');
904        if (app.storeSearch && app.storeSearch.visible) {
905            app.storeSearch.clearSearch();
906        }
907    }).on('hide', '.modal', function(){
908        this.classList.add('ba-modal-close');
909        setTimeout(function(){
910            $g('.ba-modal-close').removeClass('ba-modal-close');
911        }, 500);
912    });
913
914    CustomSelect.initAll();
915
916    $g('.intro-post-reviews a, .intro-post-comments a').on('click', function(){
917        let item = $g('a.'+this.hash.replace('#', ''));
918        app.checkCommentInTabs(this.hash);
919        app.scrollIntoView(item);
920    });
921    $g('li.megamenu-item').on('mouseenter', function(){
922        var rectangle = this.getBoundingClientRect(),
923            left = rectangle.left * -1,
924            wrapper = $g(this).find(' > div.tabs-content-wrapper'),
925            width = document.documentElement.clientWidth,
926            maxwidth = width - rectangle.right;
927        if (wrapper.hasClass('megamenu-center') && wrapper.hasClass('ba-container')) {
928            left = $g(this).width() / 2;
929        }
930        if (rectangle.left < maxwidth) {
931            maxwidth = rectangle.left;
932        }
933        if (!wrapper.hasClass('megamenu-center')) {
934            maxwidth = width - rectangle.left;
935        } else if (wrapper.hasClass('ba-container')) {
936            left -= wrapper.outerWidth() / 2;
937        }
938        if (wrapper.hasClass('megamenu-center')) {
939            maxwidth = (maxwidth + (rectangle.right - rectangle.left) / 2) * 2;
940        }
941        if ($g(this).closest('.ba-menu-wrapper').hasClass('vertical-menu')) {
942            maxwidth = width - rectangle.right;
943        }
944        wrapper.css({
945            'margin-left' : left+'px',
946            'width' : width+'px',
947            'max-width' : maxwidth+'px'
948        });
949    });
950    $g('.ba-item-main-menu').closest('.ba-row').addClass('row-with-menu');
951    for (var key in gridboxItems) {
952        if (key != 'theme') {
953            app.items = $g.extend(true, app.items, gridboxItems[key]);
954        }
955    }
956    app.theme = gridboxItems.theme;
957    if (app.preloaded.total == 0) {
958        app.gridboxLoaded();
959    } else if (app.preloaded.total <= app.preloaded.loaded && !app.preloaded.end) {
960        app.preloaded.loadGridbox();
961    }
962});
963
964var lightboxVideo = {};
965
966function lightboxVideoClose(item)
967{
968    var iframes = item.querySelectorAll('.ba-item-custom-html iframe, .ba-item-video iframe');
969    for (var i = 0; i < iframes.length; i++) {
970        var src = iframes[i].src,
971            videoId = iframes[i].id;
972        if (src && src.indexOf('youtube.com') !== -1 && 'pauseVideo' in lightboxVideo[videoId]) {
973            lightboxVideo[videoId].pauseVideo();
974        } else if (src && src.indexOf('vimeo.com') !== -1 && 'pause' in lightboxVideo[videoId]) {
975            lightboxVideo[videoId].pause();
976        }
977    }
978    iframes = item.querySelectorAll('.ba-item-video video, .ba-item-custom-html video');
979    for (var i = 0; i < iframes.length; i++) {
980        var videoId = iframes[i].id;
981        lightboxVideo[videoId].pause();
982    }
983}
984
985function lightboxVideoOpen(item)
986{
987    if (item.querySelectorAll('.video-lazy-load-thumbnail')) {
988        $g(item).find('.video-lazy-load-thumbnail').trigger('click');
989    }
990    var iframes = item.querySelectorAll('.ba-item-custom-html iframe, .ba-item-video iframe'),
991        youtube = false,
992        vimeo = false,
993        id = +new Date();
994    for (var i = 0; i < iframes.length; i++) {
995        var src = iframes[i].src,
996            videoId;
997        if (src && src.indexOf('youtube.com') !== -1) {
998            if (!app.youtube) {
999                youtube = true;
1000            } else {
1001                if (src.indexOf('enablejsapi=1') === -1) {
1002                    if (src.indexOf('?') === -1) {
1003                        src += '?';
1004                    } else {
1005                        src += '&'
1006                    }
1007                    src += 'enablejsapi=1';
1008                    iframes[i].src = src;
1009                }
1010                if (!iframes[i].id) {
1011                    iframes[i].id = id++;
1012                }
1013                videoId = iframes[i].id;
1014                if (!lightboxVideo[videoId] || !('playVideo' in lightboxVideo[videoId])) {
1015                    lightboxVideo[videoId] = new YT.Player(videoId, {
1016                        events: {
1017                            onReady: function(event){
1018                                lightboxVideo[videoId].playVideo();
1019                            }
1020                        }
1021                    });
1022                } else {
1023                    lightboxVideo[videoId].playVideo();
1024                }
1025            }
1026        } else if (src && src.indexOf('vimeo.com') !== -1) {
1027            if (!app.vimeo) {
1028                vimeo = true;
1029            } else {
1030                if (!iframes[i].id) {
1031                    iframes[i].id = id++;
1032                }
1033                videoId = iframes[i].id;
1034                if (!lightboxVideo[videoId] || !('play' in lightboxVideo[videoId])) {
1035                    src = src.split('/');
1036                    src = src.slice(-1);
1037                    src = src[0].split('?');
1038                    src = src[0];
1039                    var options = {
1040                        id: src * 1,
1041                        loop: true,
1042                    };
1043                    lightboxVideo[videoId] = new Vimeo.Player(videoId, options);
1044                }
1045                lightboxVideo[videoId].play();
1046            }
1047        }
1048    }
1049    iframes = item.querySelectorAll('.ba-item-video video, .ba-item-custom-html video');
1050    for (var i = 0; i < iframes.length; i++) {
1051        if (!iframes[i].id) {
1052            iframes[i].id = id++;
1053        }
1054        videoId = iframes[i].id;
1055        if (!lightboxVideo[videoId]) {
1056            lightboxVideo[videoId] = iframes[i];
1057        }
1058        lightboxVideo[videoId].play();
1059    }
1060    if (youtube || vimeo) {
1061        var object = {
1062            data : {}
1063        };
1064        if (youtube && !vimeo) {
1065            object.data.type = 'youtube';
1066        } else if (vimeo && !youtube) {
1067            object.data.type = 'vimeo';
1068        } else {
1069            object.data.type = 'youtube+vimeo';
1070        }
1071        app.checkModule('loadVideoApi', object);
1072    }
1073    if (youtube) {
1074        lightboxVideo.overlay = item;
1075    } else if (vimeo) {
1076        lightboxVideo.overlay = item;
1077    }
1078
1079    return !youtube && !vimeo;
1080}
1081
1082function initLightbox($this, obj)
1083{
1084    var obj = app.items[$this.dataset.id];
1085    if (obj.type == 'cookies') {
1086        if (localStorage['ba-item-cookie']) {
1087            return false;
1088        }
1089        $g($this).find('.ba-item-button[data-cookie="accept"]').on('click', function(event){
1090            event.preventDefault();
1091            localStorage.setItem('ba-item-cookie', 'accept');
1092            $g(this).closest('.ba-lightbox-backdrop').removeClass('visible-lightbox');
1093            $g('body').removeClass('lightbox-open');
1094        });
1095        showLightbox($this);
1096    } else if (obj.trigger.type == 'time-delay') {
1097        setTimeout(function(){
1098            showLightbox($this);
1099        }, obj.trigger.time);
1100    } else if (obj.trigger.type == 'scrolling') {
1101        lightboxScroll($this, obj.trigger.scroll * 1);
1102    } else if (obj.trigger.type == 'exit-intent') {
1103        $g(document).one('mouseleave.ba-lightbox'+$this.dataset.id, function(){
1104            showLightbox($this);
1105        });
1106    } else {
1107        lightboxScroll($this, 100);
1108    }
1109}
1110
1111function lightboxScroll($this, scroll)
1112{
1113    let top, docHeight, htmlHeight;
1114    $g(window).on('scroll.ba-lightbox'+$this.dataset.id+' load.ba-lightbox'+$this.dataset.id, function(){
1115        top = $g(window).scrollTop();
1116        docHeight = document.documentElement.clientHeight
1117        htmlHeight = Math.max(
1118            document.body.scrollHeight, document.documentElement.scrollHeight,
1119            document.body.offsetHeight, document.documentElement.offsetHeight,
1120            document.body.clientHeight, document.documentElement.clientHeight
1121        );
1122        let x = (docHeight + top) * 100 / htmlHeight;
1123        if (x >= scroll || (scroll > 97 && x >= 97)) {
1124            $g(window).off('scroll.ba-lightbox'+$this.dataset.id+' load.ba-lightbox'+$this.dataset.id);
1125            showLightbox($this);
1126        }
1127    });
1128}
1129
1130function showLightbox($this)
1131{
1132    const obj = app.getObject($this.dataset.id);
1133    if (!lightboxVideoOpen($this) || obj.disable == 1) {
1134        return false;
1135    }
1136    const section = $this.querySelector(':scope > .ba-wrapper > .ba-section')
1137    $this.querySelector('.close-lightbox .ba-lightbox-close')?.setAttribute('tabindex', 0);
1138    $this.classList.add('visible-lightbox');
1139
1140    if (obj.animation.effect) {
1141        section.classList.add(obj.animation.effect);
1142        setTimeout(function(){
1143            section.classList.remove(obj.animation.effect);
1144        }, obj.animation.delay * 1000 + obj.animation.duration * 1000);
1145    }
1146
1147    if (obj.position == 'lightbox-center') {
1148        document.body.classList.add('lightbox-open');
1149    }
1150    if (app.AccessibilityHelper) {
1151        app.AccessibilityHelper.trapFocus($this.querySelector('.ba-wrapper'), 350);
1152    }
1153}
1154
1155function compileOnePageValue(item)
1156{
1157    if (item.length == 0) {
1158        return 0;
1159    }
1160    var value = item.offset().top,
1161        header = $g('header.header'),
1162        comp = header[0] ? getComputedStyle(header[0]) : {},
1163        top = window.pageYOffset,
1164        stickies = $g('.ba-sticky-header'),
1165        sticky = 0;
1166    if (item.closest('.ba-wrapper').parent().hasClass('header')) {
1167        value = 0;
1168    } else {
1169        stickies.each(function(){
1170            if (this.offsetHeight > 0) {
1171                let section = this.querySelector('.ba-sticky-header > .ba-section'),
1172                    obj = app.items[section.id],
1173                    offset = obj ? obj.desktop.offset : 0;
1174                if (app.view != 'desktop') {
1175                    for (var ind in breakpoints) {
1176                        if (!obj[ind]) {
1177                            obj[ind] = {};
1178                        }
1179                        offset = obj[ind].offset ? obj[ind].offset : offset;
1180                        if (ind == app.view) {
1181                            break;
1182                        }
1183                    }
1184                }
1185                if (obj && ((!obj.scrollup && offset < value) || (obj.scrollup && offset < value && value < top))) {
1186                    sticky = this.offsetHeight > sticky ? this.offsetHeight : sticky;
1187                }
1188            }
1189        });
1190        if ((!header.hasClass('sidebar-menu') || (app.view != 'desktop' && app.view != 'laptop'))
1191            && comp.position == 'fixed') {
1192            sticky = header[0].offsetHeight > sticky ? header[0].offsetHeight : sticky;
1193            if (header.find('.resizing-header').length > 0) {
1194                var resizingSection = getComputedStyle(header.find('.resizing-header')[0]);
1195                value += resizingSection.paddingTop.replace('px', '') * 1;
1196                value += resizingSection.paddingBottom.replace('px', '') * 1;
1197            }
1198        }
1199        value -= sticky;
1200    }
1201
1202    return Math.ceil(value);
1203}
1204
1205function checkOnePage()
1206{
1207    var alias = location.hash.replace('#', '');
1208    alias = decodeURIComponent(alias);
1209    if (alias && document.querySelector('.main-menu a[data-alias="'+alias+'"]')) {
1210        $g('.main-menu a[data-alias="'+alias+'"]').each(function(){
1211            const id = (this.dataset.anchor || this.hash).replace('#', '');
1212            let item = $g('#' + id);
1213            if ($g(this.parentNode).height() > 0 && id && item.length > 0) {
1214                $g(this).closest('ul').find('.active').removeClass('active');
1215                $g('.main-menu ul.nav.menu').find(`a[href*="#${id}"], a[data-anchor="${id}"]`)
1216                    .parent().addClass('active');
1217                app.scrollIntoView(item);
1218                return false;
1219            }
1220        });
1221    } else if ((alias == 'total-reviews-count-wrapper' || alias == 'total-count-wrapper')
1222        && document.querySelector('a.'+alias)) {
1223        let item = $g('a.'+alias);
1224        app.scrollIntoView(item);
1225    } else {
1226         checkOnePageActive();
1227    }
1228}
1229
1230app.scrollIntoView = function(item){
1231    let value = compileOnePageValue(item);
1232    if (window.pageYOffset != value) {
1233        $g('html, body').stop().animate({
1234            'scrollTop' : value
1235        }, 1000);
1236    }
1237}
1238
1239window.onePageScroll = true;
1240
1241function checkOnePageActive()
1242{
1243    if (!window.onePageScroll) {
1244        return;
1245    }
1246    var items = [],
1247        alias = '',
1248        replace = null,
1249        flag = false;
1250    $g('.main-menu ul li a[data-alias]').each(function(){
1251        const id = this.dataset.anchor ? '#' + this.dataset.anchor : this.hash;
1252        if (this.offsetHeight > 0 && id && $g(id).height() > 0) {
1253            var computed = getComputedStyle(document.querySelector(id));
1254            if (computed.display != 'none') {
1255                items.push(this);
1256            }
1257        }
1258    });
1259    items.sort(function(item1, item2){
1260        var target1 = $g(item1.dataset.anchor ? '#' + item1.dataset.anchor : item1.hash),
1261            target2 = $g(item2.dataset.anchor ? '#' + item2.dataset.anchor : item2.hash),
1262            top1 = target1.closest('header.header').length == 0 ? target1.offset().top : 0,
1263            top2 = target2.closest('header.header').length == 0 ? target2.offset().top : 0;
1264        if (top1 > top2) {
1265            return 1;
1266        } else if (top1 < top2) {
1267            return -1;
1268        } else {
1269            return 0;
1270        }
1271    });
1272    let url = ''
1273    for (var i = items.length - 1; i >= 0; i--) {
1274        alias = items[i].dataset.alias;
1275        if (decodeURI(window.location.hash) == '#'+alias) {
1276            replace = location.href.replace(window.location.hash, '');
1277        }
1278        const id = (items[i].dataset.anchor || items[i].hash).replace('#', '')
1279        const item = $g('#' + id);
1280        let value = compileOnePageValue(item);
1281        if (value <= Math.ceil(window.pageYOffset) + 1) {
1282            flag = true;
1283            url = location.href.replace(window.location.hash, '')+'#'+alias;
1284            $g('.main-menu ul').find(`a[href*="#${id}"], a[data-anchor="${id}"]`)
1285                .closest('ul')
1286                .find('.active').removeClass('active current');
1287            $g('.main-menu ul').find(`a[href*="#${id}"], a[data-anchor="${id}"]`)
1288                .parent().addClass('active');
1289            break;
1290        }
1291    }
1292    if (!flag) {
1293        $g('.main-menu ul.nav.menu .active').removeClass('active');
1294        replace ? window.history.replaceState(null, null, replace) : '';
1295    } else if (decodeURI(window.location.hash) != '#'+alias) {
1296        window.history.replaceState(null, null, url);
1297    }
1298}
1299
1300window.addEventListener('resize', function(){
1301    document.documentElement.style.setProperty('--vh', window.innerHeight * 0.01+'px');
1302});
1303
1304jQuery(window).on('popstate.onepage', function(){
1305    window.onePageScroll = false;
1306    setTimeout(function(){
1307        window.onePageScroll = true;
1308    }, 300);
1309});
1310
1311/*
1312    Default joomla
1313*/
1314
1315document.addEventListener('DOMContentLoaded', function(){
1316    ImportHelper.resolve('AccessibilityHelper', '').then(module => {
1317        /** @type {typeof import('../../../components/com_gridbox/assets/modules/AccessibilityHelper.js').default} */
1318        app.AccessibilityHelper = module;
1319    });
1320    document.documentElement.style.setProperty('--vh', window.innerHeight * 0.01+'px');
1321    $g('*[rel=tooltip]').tooltip();
1322    $g('.radio.btn-group label').addClass('btn');
1323    $g('fieldset.btn-group').each(function() {
1324        if (this.disabled) {
1325            $g(this).css('pointer-events', 'none').off('click');
1326            $g(this).find('.btn').addClass('disabled');
1327        }
1328    });
1329    $g(".btn-group label:not(.active)").click(function(){
1330        var label = $g(this),
1331            input = $g('#'+label.attr('for'));
1332        if (!this.checked) {
1333            label.closest('.btn-group').find("label").removeClass('active btn-success btn-danger btn-primary');
1334            if (input.val() == '') {
1335                label.addClass('active btn-primary');
1336            } else if (input.val() == 0) {
1337                label.addClass('active btn-danger');
1338            } else {
1339                label.addClass('active btn-success');
1340            }
1341            input.prop('checked', true).trigger('change');
1342        }
1343    });
1344    $g(".btn-group input[checked=checked]").each(function(){
1345        if (this.value == '') {
1346            $g("label[for="+this.id+"]").addClass('active btn-primary');
1347        } else if (this.value == 0) {
1348            $g("label[for="+this.id+"]").addClass('active btn-danger');
1349        } else {
1350            $g("label[for="+this.id+"]").addClass('active btn-success');
1351        }
1352    });
1353});

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.