PageSourceSearch

https://www.puma-catchup.com/wp-content/themes/puma-catchup-theme/public/js/main.js?ver=1.0

js puma-catchup.com collected 2026-10-02 11:11:34 UTC 23,543 bytes, 796 lines download raw bytes

1const bpMobile = 980;
2let isMobile = window.innerWidth <= bpMobile;
3const inEditor = window.pagenow && ["post", "page", "specialpage"].includes(pagenow);
4let canvOrigElements = [];
5let canvElements = [];
6let allSwipers = [];
7
8function updateCanvasPositions()
9{
10    for (let i = 0; i < canvElements.length; i++)
11    {
12        const ne = canvElements[i];
13        const r = canvOrigElements[i].getBoundingClientRect();
14        if (!ne) return;
15        const curr = ne.getBoundingClientRect();
16        if (curr)
17            if (Math.floor(r.top) != Math.floor(curr.top) || Math.floor(r.width) != Math.floor(curr.width) || Math.floor(r.height) != Math.floor(curr.height))
18            {
19                ne.style.top = r.y + window.scrollY + "px";
20                ne.style.zIndex = 1;
21                ne.style.left = r.x + "px";
22                ne.style.width = r.width + "px";
23                ne.style.height = r.height + "px";
24                ne.setAttribute("width", r.width * window.devicePixelRatio);
25                ne.setAttribute("height", r.height * window.devicePixelRatio);
26            }
27    }
28}
29
30function cloneAsCanvas(q, addclass)
31{
32    const elements = document.querySelectorAll(q);
33
34    for (let i = 0; i < elements.length; i++)
35    {
36        const r = elements[i].getBoundingClientRect();
37        const ne = document.createElement("canvas");
38        ne.style.position = "absolute";
39        // ne.style.border = "1px solid red";
40        ne.style.backgroundColor = "gray";
41        ne.style.zIndex = 1;
42        ne.classList.add("bggradient");
43        ne.dataset.gradient = addclass;
44
45        canvElements.push(ne);
46        canvOrigElements.push(elements[i]);
47
48        // elements[i].prepend(ne);
49        document.body.appendChild(ne);
50    }
51
52}
53
54const map = function (x, _oldMin, _oldMax, _newMin, _newMax, _easing = 0, clamp = true)
55{
56    if (clamp)
57    {
58        if (x >= _oldMax) return _newMax;
59        if (x <= _oldMin) return _newMin;
60    }
61
62    let reverseInput = false;
63    const oldMin = Math.min(_oldMin, _oldMax);
64    const oldMax = Math.max(_oldMin, _oldMax);
65    if (oldMin != _oldMin) reverseInput = true;
66
67    let reverseOutput = false;
68    const newMin = Math.min(_newMin, _newMax);
69    const newMax = Math.max(_newMin, _newMax);
70    if (newMin != _newMin) reverseOutput = true;
71
72    let portion = 0;
73    let r = 0;
74
75    if (reverseInput) portion = ((oldMax - x) * (newMax - newMin)) / (oldMax - oldMin);
76    else portion = ((x - oldMin) * (newMax - newMin)) / (oldMax - oldMin);
77
78    if (reverseOutput) r = newMax - portion;
79    else r = portion + newMin;
80
81    if (!_easing) return r;
82    if (_easing == 1)
83    {
84        // smoothstep
85        x = Math.max(0, Math.min(1, (r - _newMin) / (_newMax - _newMin)));
86        return _newMin + x * x * (3 - 2 * x) * (_newMax - _newMin);
87    }
88    if (_easing == 2)
89    {
90        // smootherstep
91        x = Math.max(0, Math.min(1, (r - _newMin) / (_newMax - _newMin)));
92        return _newMin + x * x * x * (x * (x * 6 - 15) + 10) * (_newMax - _newMin);
93    }
94
95    return r;
96};
97
98function setupSwiper(el)
99{
100    if (!el || el.classList.contains("initialized")) return;
101
102    let numSlides = parseFloat(el.dataset.ssize);
103    if (numSlides == 2) numSlides = 1;
104    if (numSlides == 3) numSlides = 3.5;
105    if (numSlides == 4) numSlides = 4.5;
106    if (isMobile) numSlides = Math.min(numSlides, 1.5);
107
108    const center = numSlides == 1;
109    let loop = true;
110
111    const slides = el.getElementsByClassName("swiper-slide");
112    if (slides.length < Math.floor(numSlides) + 1) loop = false;
113
114    // if (window.swiper)window.swiper.destroy(true);
115    const o = {
116        "direction": "horizontal",
117        "loop": loop,
118        "slidesPerView": numSlides,
119        "allowTouchMove": !inEditor,
120
121        "centeredSlides": center,
122        "spaceBetween": 20,
123        "controller": {
124            "inverse": true,
125        },
126
127        "navigation": {
128            "nextEl": ".swipenext" + el.dataset.id,
129            "prevEl": ".swipeprev" + el.dataset.id,
130        },
131
132    };
133
134    if (el.dataset.pagination)
135        o.pagination = {
136            "el": ".swipepagination",
137            "type": "fraction",
138        };
139
140    // if (numSlides != 3)
141    //     o.navigation = {
142    //         "nextEl": ".swipenext" + el.dataset.id,
143    //         "prevEl": ".swipeprev" + el.dataset.id,
144    //     };
145
146    const swiper = new Swiper(el, o);
147    el.classList.add("initialized");
148    allSwipers.push(swiper);
149
150    // swiper.disable();
151    return swiper;
152}
153
154function closeBurgerMenu()
155{
156    document.getElementById("burgerMenu").style.display = "none";
157    document.getElementById("burgerMenuButton").classList.add("iconBurger");
158    document.getElementById("burgerMenuButton").classList.remove("iconX");
159    document.body.style.overflow = "auto";
160
161}
162
163function toggleBrgsBrgsMenu()
164{
165    if (document.getElementById("burgerMenu").style.display == "block")
166    {
167        // hide
168        closeBurgerMenu();
169    }
170    else
171    {
172        // show
173        document.getElementById("burgerMenu").style.display = "block";
174        document.getElementById("burgerMenuButton").classList.remove("iconBurger");
175        document.getElementById("burgerMenuButton").classList.add("iconX");
176        document.body.style.overflow = "hidden";
177    }
178}
179
180function closeModalGallery()
181{
182    document.getElementById("modalGallery").innerHTML = "";
183    document.getElementById("modalBg").style.display = "none";
184    document.getElementById("modalClose").style.display = "none";
185    document.getElementById("modalGallery").style.display = "none";
186}
187
188function modalGallery(ele, idx)
189{
190    let images = JSON.parse(ele.parentElement.dataset.tdn);
191    images = images.filter((image) => { return image.id !== "placeholder"; });
192
193    let str =
194        "<div id=\"modalGalleryInner\"  class=\"swiper myswiper\" data-ssize=\"1\" data-id=\"Modal\">" +
195        "<div class=\"swiper-wrapper\">";
196
197    for (let i = idx; i < images.length + idx; i++)
198    {
199        str +=
200            "<div class=\"swiper-slide modalSlide\"> " +
201            "<div class=\"sizer\"" +
202            " style=\"background-image:url(" + images[i % images.length].url + ");background-position:50% 50%;background-repeat:no-repeat;background-size:contain;" +
203            "\">" +
204            "</div>" +
205            "</div>";
206    }
207
208    str +=
209        "</div>" +
210        "</div>" +
211        "<div class='swiperArrow swiper-button-next swipenextModal'></div>" +
212        "<div class='swiperArrow swiper-button-prev swipeprevModal'></div>";
213
214    document.getElementById("modalGallery").innerHTML = str;
215    document.getElementById("modalBg").style.display = "block";
216    document.getElementById("modalGallery").style.display = "block";
217    document.getElementById("modalClose").style.display = "block";
218    setupSwiper(document.getElementById("modalGalleryInner"));
219}
220
221function setupHero()
222{
223    const m = window.innerWidth <= bpMobile;
224    if (m != isMobile)
225    {
226        isMobile = m;
227        pageLoadActions();
228    }
229
230    if (isMobile)
231    {
232        const elGradient = document.getElementById("heroGradient");
233        const elHeroText = document.getElementById("heroHeaderText");
234        if (elGradient) elGradient.remove();
235        if (elHeroText) elHeroText.parentElement.classList.add(elHeroText.dataset.gradient);
236        if (elHeroText) elHeroText.parentElement.style.paddingBottom = "var(--spacing)";
237
238    }
239    else
240    {
241        const img = document.getElementById("postHeaderImage");
242        const pht = document.getElementById("postHeaderText");
243        const socialBar = document.getElementById("headerSocialIcons");
244        if (img && socialBar)
245        {
246            const r = img.getBoundingClientRect();
247            const rpht = pht.getBoundingClientRect();
248            socialBar.style.marginLeft = r.left - rpht.left + "px";
249        }
250
251        const elGradient = document.getElementById("heroGradient");
252        const elHImage = document.getElementById("heroImage");
253        if (elHImage && elGradient)
254        {
255            const rect = elHImage.getBoundingClientRect();
256            elGradient.style.height = rect.height + "px";
257        }
258    }
259
260}
261
262function updateSliderButtons()
263{
264    const elArrows = document.getElementsByClassName("arrowCircleCenter");
265    for (let i = 0; i < elArrows.length; i++)
266    {
267        let parent = elArrows[i].parentElement;
268        if (elArrows[i].dataset.centerin)
269        {
270            parent = document.querySelector(elArrows[i].dataset.centerin) || parent;
271        }
272        const pr = parent.getBoundingClientRect();
273        if (isMobile)
274        {
275            if (elArrows[i].classList.contains("swiperoutside-button-prev"))
276            {
277                elArrows[i].style.left = 5 + "px";
278            }
279            else
280            {
281                elArrows[i].style.left = "unset";
282                elArrows[i].style.right = 34 + 25 + "px";
283            }
284            elArrows[i].style.marginTop = (pr.height / 2 - 40) + "px";
285        }
286        else
287        {
288            elArrows[i].style.marginTop = (pr.height / 2 - 40) + "px";
289        }
290    }
291}
292
293function updatesliders(eles = null, forceUpdate = false)
294{
295    if (!eles) eles = document.getElementsByClassName("myswiper");
296    for (let i = 0; i < eles.length; i++)
297    {
298        const el = eles[i];
299        if (forceUpdate) el.classList.remove("initialized");
300        setupSwiper(el);
301    }
302    updateSliderButtons();
303}
304
305function initSearch()
306{
307    const si = document.getElementById("pumasearch");
308    if (si)
309    {
310        si.addEventListener("keyup", (e) =>
311        {
312            if (e.code == "Enter") document.location.href = "/?s=" + si.value;
313        });
314        si.focus();
315    }
316}
317
318function getCookies()
319{
320    return Object.fromEntries(document.cookie.split("; ").map((v) =>
321    {
322        return v.split(/=(.*)/s).map(decodeURIComponent);
323    }));
324}
325
326function getUserConsent()
327{
328    if (!themeConfig.consentManager.load)
329    {
330        const cookies = getCookies();
331        return cookies.givenConsent ? JSON.parse(cookies.givenConsent) : {};
332    }
333    else
334    {
335        return true;
336    }
337}
338
339function userGaveConsent(category)
340{
341    if (!themeConfig.consentManager.load)
342    {
343        const userConsent = getUserConsent();
344        return userConsent[category];
345    }
346    else
347    {
348        return true;
349    }
350}
351
352function acceptCookies()
353{
354    const expirationDate = new Date();
355    expirationDate.setFullYear(expirationDate.getFullYear() + 1);
356    document.cookie = "cookieConsent=true;expires=" + expirationDate.toUTCString() + ";path=/";
357    document.getElementById("cookieBanner").style.display = "none";
358}
359
360function cookieBanner()
361{
362    const cookies = getCookies();
363    const wasWarned = cookies.cookieConsent;
364    if (!wasWarned)
365    {
366        const cookieBanner = document.getElementById("cookieBanner");
367        if (cookieBanner) cookieBanner.style.display = "block";
368    }
369}
370
371function toggleDarkMode()
372{
373    const dm = localStorage.getItem("darkMode") == "true";
374    localStorage.setItem("darkMode", String(!dm));
375    updateDarkMode();
376    closeBurgerMenu();
377}
378
379function updateDarkMode()
380{
381    // const el = document.getElementsByClassName("wp-block-post-content")[0] || document.body;
382    const el = document.body;
383    if (!el) return console.log("no darkmode ele found");
384    el.classList.remove("dark");
385    el.classList.remove("bright");
386
387    if (localStorage.getItem("darkMode") === "true") el.classList.add("dark");
388    else el.classList.add("bright");
389}
390
391function updateHeaderScrollSize()
392{
393    const maxScroll = 700;
394    isMobile = window.innerWidth <= bpMobile;
395
396    let min = 0;
397    if (isMobile) min = 10;
398
399    const p = map(window.scrollY, 0, maxScroll, 30, min, 1);
400    const el = document.getElementsByClassName("rowHeader")[0];
401
402    if (!el) return;
403    el.style.paddingTop = p + "px";
404    el.style.paddingBottom = p + "px";
405
406    const s = map(window.scrollY, 0, maxScroll, 38, 20, 1);
407    const el3 = document.getElementsByClassName("stickyVertCenter");
408    const s2 = map(window.scrollY, 0, maxScroll, 5, 20, 1);
409    for (let i = 0; i < el3.length; i++)
410    {
411        el3[i].style.paddingTop = s + "px";
412        el3[i].style.paddingBottom = s2 + "px";
413    }
414
415    const logo = document.getElementsByClassName("site-logo")[0];
416    const rightnav = document.getElementsByClassName("rightnav")[0];
417    const s3 = map(window.scrollY, 0, maxScroll, 0, 20, 1);
418    if (logo) logo.style.height = 50 - s3 + "px";
419    if (logo) logo.style.marginTop = s3 / 2 + "px";
420    if (rightnav) rightnav.style.height = 40 - s3 + "px";
421
422    const elLangSelect = document.getElementsByClassName("langSelectContainer")[0];
423    const elPopup = document.getElementsByClassName("opopup")[0];
424    if (elPopup)
425    {
426        const s4 = map(window.scrollY, 0, maxScroll, 0, 2, 1);
427        elPopup.style.marginTop = Math.floor(elLangSelect.getBoundingClientRect().height + elLangSelect.getBoundingClientRect().top - 44) / 2 + s4 + "px";
428    }
429
430    const header = document.getElementsByTagName("header")[0];
431    // const headerSpacer = document.getElementById("headerspacer");
432    // if (header && headerSpacer)headerSpacer.style.height =
433    document.documentElement.style.setProperty("--headSpace", header.getBoundingClientRect().height + "px");
434    // document.documentElement.style.setProperty("--headSpace", 130 + "px");
435
436}
437
438function initAccessibility()
439{
440    const clickableElements = document.getElementsByClassName("clickable");
441    for (let i = 0; i < clickableElements.length; i++)
442    {
443        if (clickableElements[i].onclick)
444        {
445            clickableElements[i].onkeypress = clickableElements[i].onclick;
446            clickableElements[i].setAttribute("tabindex", "0");
447        }
448    }
449
450    document.body.addEventListener("keyup", (e) =>
451    {
452        if (e.code == "Tab")
453        {
454            console.log("tabbb");
455            for (let i = 0; i < allSwipers.length; i++)
456            {
457                allSwipers[i].disable();
458            }
459            const clickableElements = document.getElementsByClassName("swiper-wrapper");
460            for (let i = 0; i < clickableElements.length; i++)
461            {
462                clickableElements[i].style.overflow = "auto";
463            }
464            const headerEle = document.getElementById("heroHeaderText");
465            headerEle.style.overflow = "initial";
466
467        }
468    });
469}
470
471function loadArticles(what, elementSelector, button, replace = false, paramOverride = false)
472{
473    const oldText = button.innerText;
474    const text = button.querySelector(".text");
475    text.innerText = button.dataset.loadingtxt;
476    const indicator = button.querySelector(".loadingIndicator");
477    if (indicator) indicator.classList.remove("hidden");
478
479    const allTargets = document.querySelectorAll(elementSelector);
480    const targetElement = allTargets[0];
481    const page = replace ? 1 : parseInt(button.dataset.nextpage);
482    const param = paramOverride || button.dataset.param;
483    const options = {
484        "method": "POST",
485        "body": JSON.stringify({
486            what,
487            param,
488            page
489        })
490    };
491    fetch("/wp-json/frontend/articles/more", options).then((response) =>
492    {
493        response.text().then((content) =>
494        {
495            if (replace)
496            {
497                button.dataset.param = param;
498                button.dataset.nextpage = "2";
499                targetElement.outerHTML = content;
500                for (let i = 1; i < allTargets.length; i++)
501                {
502                    allTargets[i].remove();
503                }
504            }
505            else
506            {
507                button.dataset.param = param;
508                button.dataset.nextpage = String(page + 1);
509                const template = document.createElement("div");
510                template.innerHTML = content.trim();
511                targetElement.appendChild(template.querySelector(".articlegrid"));
512                // targetElement.innerHTML += content;
513            }
514            if (button)
515            {
516                text.innerText = oldText;
517                if (response.headers && response.headers.get("x-last-page"))
518                {
519                    button.classList.add("hidden");
520                }
521                else
522                {
523                    button.classList.remove("hidden");
524                }
525            }
526            if (indicator) indicator.classList.add("hidden");
527        });
528    }).catch((e) =>
529    {
530        console.error("E", e);
531    });
532}
533
534function addFilter(element, event)
535{
536    event.preventDefault();
537    event.stopPropagation();
538    if (element.classList.contains("active")) return;
539    element.classList.add("active");
540    const filterElement = element.closest("#filters");
541    const activeElements = Array.from(filterElement.querySelectorAll(".button.active"));
542    if (activeElements.length === 1)
543    {
544        const url = new URL(element.href);
545        window.history.pushState(null, null, url.pathname);
546        window.addEventListener("popstate", () =>
547        {
548            document.location.href = window.location.href;
549        });
550    }
551
552    const param = activeElements.map((activeElement) =>
553    {
554        return activeElement.dataset.catid;
555    }).join(",");
556    loadArticles("category", ".articlegrid", document.getElementById("loadMore"), true, param);
557
558    if (activeElements.length !== 0)
559    {
560        const removeAll = document.getElementById("removeAll");
561        if (removeAll) removeAll.classList.remove("hidden");
562    }
563    else
564    {
565        const removeAll = document.getElementById("removeAll");
566        if (removeAll) removeAll.classList.add("hidden");
567    }
568
569}
570
571function removeFilter(element, event)
572{
573    event.preventDefault();
574    event.stopPropagation();
575    const filterLink = element.closest(".active");
576    if (!filterLink) return;
577
578    const filterElement = element.closest("#filters");
579    let activeElements = Array.from(filterElement.querySelectorAll(".button.active"));
580    if (activeElements.length === 1)
581    {
582        document.location.href = filterElement.dataset.parenturl;
583        return;
584    }
585    filterLink.classList.remove("active");
586    activeElements = Array.from(filterElement.querySelectorAll(".button.active"));
587    if (activeElements.length === 1)
588    {
589        const url = new URL(activeElements[0].href);
590        window.history.pushState(null, null, url.pathname);
591        window.addEventListener("popstate", () =>
592        {
593            document.location.href = window.location.href;
594        });
595    }
596
597    const param = activeElements.map((activeElement) =>
598    {
599        return activeElement.dataset.catid;
600    }).join(",");
601    loadArticles("category", ".articlegrid", document.getElementById("loadMore"), true, param);
602
603    if (activeElements.length !== 0)
604    {
605        const removeAll = document.getElementById("removeAll");
606        if (removeAll) removeAll.classList.remove("hidden");
607    }
608    else
609    {
610        const removeAll = document.getElementById("removeAll");
611        if (removeAll) removeAll.classList.add("hidden");
612    }
613
614}
615
616/// /////////////////////////////////
617// init stuff...
618
619const pageLoadActions = () =>
620{
621    updateDarkMode();
622    updatesliders();
623    // setupHero();
624    updateSliderButtons();
625    initSearch();
626    initAccessibility();
627
628    setTimeout(() =>
629    {
630        updateHeaderScrollSize();
631        setupHero();
632    }, 100);
633};
634
635// on page load
636document.addEventListener("DOMContentLoaded", () =>
637{
638    if (inEditor)
639    {
640        const partials = document.querySelectorAll("[type='text/x-handlebars-partial']");
641        partials.forEach((partialElement) =>
642        {
643            const template = decodeHTML(partialElement.textContent);
644            Handlebars.registerPartial(partialElement.dataset.name, template);
645        });
646    }
647    else
648    {
649        pageLoadActions();
650    }
651});
652
653window.addEventListener("editorBlockAdded", ({ "detail": blockIds }) =>
654{
655    // console.log("added", blocks);
656});
657
658window.addEventListener("editorBlockLoaded", ({ "detail": data }) =>
659{
660    const attributes = data.attributes;
661    const element = data.element;
662    if (element)
663    {
664        const sliders = element.querySelectorAll(".myswiper");
665        if (sliders)
666        {
667            setTimeout(updatesliders, 1000); // TODO: remove this timeout
668        }
669    }
670});
671
672window.addEventListener("editorBlockSaved", ({ "detail": data }) =>
673{
674    // const attributes = data.attributes;
675    // const element = data.element;
676    // console.log("saved", blocks);
677});
678
679window.addEventListener("editorBlockRemoved", ({ "detail": blockIds }) =>
680{
681    // console.log("removed", blocks);
682});
683
684window.addEventListener("editorReady", () =>
685{
686    // console.log("editor ready");
687    pageLoadActions();
688});
689
690window.addEventListener("load", () =>
691{
692    cookieBanner();
693    if (inEditor)
694    {
695        updateDarkMode();
696    }
697});
698
699window.addEventListener("resize", () =>
700{
701    setTimeout(() =>
702    {
703        updateSliderButtons();
704        setupHero();
705        updateHeaderScrollSize();
706        updateCanvasPositions();
707    }, 50);
708});
709
710document.addEventListener("scroll", () =>
711{
712    updateHeaderScrollSize();
713});
714
715// when cables stuff loaded
716document.addEventListener("CABLES.jsLoaded", function (event)
717{
718    function showError(initiator, ...args)
719    {
720        CABLES.logErrorConsole("[" + initiator + "]", ...args);
721        document.body.classList.remove("glgradients");
722    }
723
724    if (inEditor || isMobile) return;
725
726    // CABLES.patch = new CABLES.Patch({
727    //     "patch": CABLES.exportedPatch,
728    //     "prefixAssetPath": "",
729    //     "assetPath": "assets/",
730    //     "jsPath": "js/",
731    //     "onError": showError,
732    //     "doRequestAnimation": false,
733    //     "containerElement": document.body
734    //     // "onPatchLoaded": patchInitialized,
735    //     // "onFinishedLoading": patchFinishedLoading,
736    //     // "canvas": { "alpha": true, "premultipliedAlpha": true } // make canvas transparent
737    // });
738
739    cloneAsCanvas(".gradient1", "1");
740    cloneAsCanvas(".gradient2", "2");
741    cloneAsCanvas(".gradient3", "3");
742    cloneAsCanvas(".gradient4", "4");
743    cloneAsCanvas(".gradient5", "5");
744    updateCanvasPositions();
745
746    setInterval(() =>
747    {
748        updateCanvasPositions();
749    }, 500);
750    console.log("aaa", document.documentElement.style.getPropertyValue("--wp-admin--admin-bar--height"));
751    const eles = document.getElementsByClassName("navEle");
752    for (let i = 0; i < eles.length; i++)
753    {
754        console.log(
755            document.getElementsByClassName("navEle")[i].getBoundingClientRect()
756        );
757    }
758
759    CABLES.patchGradients = new CABLES.Patch({
760        "patch": CABLES.exportedPatches.zwNKaV,
761        "prefixAssetPath": "",
762        "assetPath": "assets/",
763        "jsPath": "js/",
764        "onError": showError,
765        "glCanvasId": "glcanvas",
766        "glCanvasResizeToWindow": true,
767        // "containerElement": document.body
768        // "onPatchLoaded": patchInitialized,
769        "onFinishedLoading": () =>
770        {
771            document.body.classList.add("glgradients");
772        },
773        "canvas": {
774            "alpha": true,
775            "premultipliedAlpha": true
776        } // make canvas transparent
777    });
778});
779const darkmodeInterval = setInterval(() =>
780{
781
782    if (!document.body) return;
783    if (
784        !document.body.classList.contains("dark") &&
785        !document.body.classList.contains("bright")
786    )
787    {
788        console.warn("content has no bright/dark mode class....");
789        updateDarkMode();
790    }
791    else
792    {
793        clearInterval(darkmodeInterval);
794    }
795
796}, 500);

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.