(function () {
    "use strict";

    const reducedMotion = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;

    function isObservableNode(node) {
        return Boolean(node && typeof node.nodeType === "number");
    }

    function initTabs(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        const buttons = Array.from(root.querySelectorAll("[data-h4-addon-tab-target]"));
        buttons.forEach(function (button) {
            button.addEventListener("click", function () {
                const target = String(button.getAttribute("data-h4-addon-tab-target") || "");
                buttons.forEach(function (candidate) {
                    const active = candidate === button;
                    candidate.classList.toggle("is-active", active);
                    candidate.setAttribute("aria-selected", active ? "true" : "false");
                });
                root.querySelectorAll(".h4-addon-tab-panel").forEach(function (panel) {
                    const active = panel.id === target;
                    panel.classList.toggle("is-active", active);
                    panel.hidden = !active;
                });
            });
        });
    }

    function initOverlay(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        const trigger = root.querySelector("[data-h4-pro-overlay-open]");
        const overlay = root.querySelector("[data-h4-pro-overlay]");
        const panel = root.querySelector(".h4-pro-overlay-panel");
        if (!(trigger instanceof HTMLElement) || !(overlay instanceof HTMLElement) || !(panel instanceof HTMLElement)) return;
        let lastFocus = null;

        function close() {
            overlay.hidden = true;
            document.documentElement.classList.remove("h4-pro-overlay-open");
            trigger.setAttribute("aria-expanded", "false");
            if (lastFocus instanceof HTMLElement) lastFocus.focus();
        }

        trigger.addEventListener("click", function () {
            lastFocus = document.activeElement;
            overlay.hidden = false;
            document.documentElement.classList.add("h4-pro-overlay-open");
            trigger.setAttribute("aria-expanded", "true");
            panel.focus();
        });
        overlay.querySelectorAll("[data-h4-pro-overlay-close]").forEach(function (button) {
            button.addEventListener("click", close);
        });
        overlay.addEventListener("keydown", function (event) {
            if (event.key === "Escape") close();
            if (event.key !== "Tab") return;
            const focusable = Array.from(overlay.querySelectorAll("a[href],button,input,select,textarea,[tabindex]:not([tabindex='-1'])")).filter(function (item) {
                return !item.hidden;
            });
            if (!focusable.length) return;
            const first = focusable[0];
            const last = focusable[focusable.length - 1];
            if (event.shiftKey && document.activeElement === first) {
                event.preventDefault();
                last.focus();
            } else if (!event.shiftKey && document.activeElement === last) {
                event.preventDefault();
                first.focus();
            }
        });
    }

    function initToggle(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        const tabs = Array.from(root.querySelectorAll("[data-h4-pro-toggle-tab]"));
        const panels = Array.from(root.querySelectorAll("[data-h4-pro-toggle-panel]"));
        tabs.forEach(function (tab) {
            tab.addEventListener("click", function () {
                const index = String(tab.getAttribute("data-h4-pro-toggle-tab") || "0");
                tabs.forEach(function (candidate) {
                    candidate.setAttribute("aria-selected", candidate === tab ? "true" : "false");
                });
                panels.forEach(function (panel) {
                    panel.hidden = panel.getAttribute("data-h4-pro-toggle-panel") !== index;
                });
            });
        });
    }

    function initImageCompare(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        const input = root.querySelector("input[type='range']");
        if (!(input instanceof HTMLInputElement)) return;
        input.addEventListener("input", function () {
            root.style.setProperty("--h4-pro-compare", input.value + "%");
        });
    }

    function initLightbox(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        root.querySelectorAll("[data-h4-pro-lightbox-item]").forEach(function (link) {
            link.addEventListener("click", function (event) {
                event.preventDefault();
                const image = link.querySelector("img");
                if (!(image instanceof HTMLImageElement)) return;
                const dialog = document.createElement("dialog");
                dialog.className = "h4-pro-lightbox-dialog";
                const close = document.createElement("button");
                close.type = "button";
                close.className = "h4-pro-lightbox-close";
                close.setAttribute("aria-label", "Close image");
                close.textContent = "×";
                const full = document.createElement("img");
                full.src = String(link.getAttribute("href") || image.src);
                full.alt = image.alt;
                dialog.append(close, full);
                document.body.appendChild(dialog);
                close.addEventListener("click", function () { dialog.close(); });
                dialog.addEventListener("click", function (clickEvent) {
                    if (clickEvent.target === dialog) dialog.close();
                });
                dialog.addEventListener("close", function () { dialog.remove(); });
                dialog.showModal();
            });
        });
    }

    function initCounter(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        const output = root.querySelector("strong");
        if (!(output instanceof HTMLElement)) return;
        const target = Number(root.getAttribute("data-h4-pro-counter") || "0");
        const prefix = String(root.getAttribute("data-prefix") || "");
        const suffix = String(root.getAttribute("data-suffix") || "");
        let started = false;
        function run() {
            if (started) return;
            started = true;
            if (reducedMotion) {
                output.textContent = prefix + target.toLocaleString() + suffix;
                return;
            }
            const duration = 1100;
            const start = performance.now();
            function frame(now) {
                const ratio = Math.min(1, (now - start) / duration);
                const eased = 1 - Math.pow(1 - ratio, 3);
                const value = Math.round(target * eased);
                output.textContent = prefix + value.toLocaleString() + suffix;
                if (ratio < 1) window.requestAnimationFrame(frame);
            }
            window.requestAnimationFrame(frame);
        }
        if ("IntersectionObserver" in window) {
            const observer = new IntersectionObserver(function (entries) {
                if (entries.some(function (entry) { return entry.isIntersecting; })) {
                    observer.disconnect();
                    run();
                }
            }, { threshold: 0.25 });
            if (isObservableNode(root)) observer.observe(root);
        } else {
            run();
        }
    }

    function initAnimatedHeading(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        const output = root.querySelector("strong");
        let words = [];
        try { words = JSON.parse(String(root.getAttribute("data-words") || "[]")); } catch (error) { words = []; }
        if (!(output instanceof HTMLElement) || words.length < 2 || reducedMotion) return;
        const speed = Math.max(800, Math.min(10000, parseInt(root.getAttribute("data-speed") || "2400", 10) || 2400));
        let index = 0;
        window.setInterval(function () {
            index = (index + 1) % words.length;
            output.classList.add("is-changing");
            window.setTimeout(function () {
                output.textContent = String(words[index]);
                output.classList.remove("is-changing");
            }, 160);
        }, speed);
    }

    function initToc(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        const list = root.querySelector("ol");
        if (!(list instanceof HTMLOListElement)) return;
        const selector = String(root.getAttribute("data-selector") || "h2,h3");
        const headings = Array.from(document.querySelectorAll(selector)).filter(function (heading) {
            return !root.contains(heading) && String(heading.textContent || "").trim() !== "";
        }).slice(0, 80);
        headings.forEach(function (heading, index) {
            if (!heading.id) heading.id = "h4-section-" + (index + 1);
            const item = document.createElement("li");
            if (heading.tagName === "H3" || heading.tagName === "H4") item.className = "is-child";
            const link = document.createElement("a");
            link.href = "#" + heading.id;
            link.textContent = String(heading.textContent || "").trim();
            item.appendChild(link);
            list.appendChild(item);
        });
        root.hidden = headings.length === 0;
    }

    function initReadingProgress(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        const bar = root.querySelector("span");
        if (!(bar instanceof HTMLElement)) return;
        function update() {
            const max = Math.max(1, document.documentElement.scrollHeight - window.innerHeight);
            const value = Math.max(0, Math.min(1, window.scrollY / max));
            bar.style.transform = "scaleX(" + value.toFixed(4) + ")";
        }
        update();
        window.addEventListener("scroll", update, { passive: true });
        window.addEventListener("resize", update, { passive: true });
    }

    function initScrollTop(button) {
        if (!(button instanceof HTMLButtonElement) || button.dataset.h4ProInit === "1") return;
        button.dataset.h4ProInit = "1";
        const showAfter = Math.max(0, Math.min(10000, parseInt(button.dataset.showAfter || "480", 10) || 0));
        function update() { button.classList.toggle("is-visible", window.scrollY > showAfter); }
        button.addEventListener("click", function () { window.scrollTo({ top: 0, behavior: reducedMotion ? "auto" : "smooth" }); });
        window.addEventListener("scroll", update, { passive: true });
        update();
    }

    function initStickyVideo(root) {
        if (!(root instanceof HTMLElement) || root.dataset.h4ProInit === "1") return;
        root.dataset.h4ProInit = "1";
        if (!root.classList.contains("is-sticky-enabled")) return;
        const video = root.querySelector("video");
        if (!(video instanceof HTMLVideoElement)) return;
        video.addEventListener("play", function () { root.classList.add("is-playing"); });
        video.addEventListener("pause", function () { root.classList.remove("is-playing"); });
        if ("IntersectionObserver" in window) {
            const observer = new IntersectionObserver(function (entries) {
                root.classList.toggle("is-floating", root.classList.contains("is-playing") && !entries[0].isIntersecting);
            }, { threshold: 0.2 });
            if (isObservableNode(root)) observer.observe(root);
        }
    }

    function initialize(scope) {
        const root = scope instanceof Element || scope instanceof Document ? scope : document;
        root.querySelectorAll("[data-h4-addon-tabs]").forEach(initTabs);
        root.querySelectorAll("[data-h4-pro-overlay-widget]").forEach(initOverlay);
        root.querySelectorAll("[data-h4-pro-toggle]").forEach(initToggle);
        root.querySelectorAll("[data-h4-pro-image-compare]").forEach(initImageCompare);
        root.querySelectorAll("[data-h4-pro-lightbox]").forEach(initLightbox);
        root.querySelectorAll("[data-h4-pro-counter]").forEach(initCounter);
        root.querySelectorAll("[data-h4-pro-animated-heading]").forEach(initAnimatedHeading);
        root.querySelectorAll("[data-h4-pro-toc]").forEach(initToc);
        root.querySelectorAll("[data-h4-pro-reading-progress]").forEach(initReadingProgress);
        root.querySelectorAll("[data-h4-pro-scroll-top]").forEach(initScrollTop);
        root.querySelectorAll("[data-h4-pro-sticky-video]").forEach(initStickyVideo);
        root.querySelectorAll("[data-h4-pro-alert-close]").forEach(function (button) {
            if (button.dataset.h4ProInit === "1") return;
            button.dataset.h4ProInit = "1";
            button.addEventListener("click", function () {
                const alert = button.closest(".h4-pro-alert");
                if (alert) alert.remove();
            });
        });
    }

    if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", function () { initialize(document); });
    } else {
        initialize(document);
    }

    if ("MutationObserver" in window) {
        const observer = new MutationObserver(function (mutations) {
            mutations.forEach(function (mutation) {
                mutation.addedNodes.forEach(function (node) {
                    if (node instanceof Element) initialize(node);
                });
            });
        });
        if (isObservableNode(document.documentElement)) {
            observer.observe(document.documentElement, { childList: true, subtree: true });
        }
    }
})();
