/**
 * Light interactions for Aura Builder front widgets (tabs, accordion, toggle, carousel, loop slider).
 */
(function () {
  "use strict";
  function onReady(fn) {
    if (document.readyState !== "loading") fn();
    else document.addEventListener("DOMContentLoaded", fn);
  }
  onReady(function () {
    document.addEventListener("click", function (e) {
      var navTog = e.target.closest("[data-ab-nav-toggle]");
      if (navTog) {
        e.preventDefault();
        e.stopPropagation();
        var nav = navTog.closest("[data-ab-nav-menu]");
        if (!nav) return;
        // Close other open drawers first.
        document.querySelectorAll("[data-ab-nav-menu].is-open").forEach(function (other) {
          if (other === nav) return;
          other.classList.remove("is-open");
          var ot = other.querySelector("[data-ab-nav-toggle]");
          if (ot) ot.setAttribute("aria-expanded", "false");
        });
        var open = nav.classList.toggle("is-open");
        navTog.setAttribute("aria-expanded", open ? "true" : "false");
        return;
      }
      // Touch / click: toggle dropdown parent on small screens or when hover unavailable.
      var parentLink = e.target.closest(
        ".ab-nav-menu__item.has-children > .ab-nav-menu__link"
      );
      if (parentLink) {
        var parentLi = parentLink.closest(".ab-nav-menu__item.has-children");
        var navRoot = parentLink.closest("[data-ab-nav-menu]");
        var isTouch =
          window.matchMedia && window.matchMedia("(hover: none)").matches;
        var isMobile =
          window.matchMedia && window.matchMedia("(max-width: 767px)").matches;
        if (parentLi && navRoot && (isTouch || isMobile)) {
          // On mobile drawer, links just navigate; submenus are always visible.
          if (navRoot.classList.contains("is-open") || isMobile) {
            // allow default for real links with href that aren't "#"
          } else {
            e.preventDefault();
            var wasOpen = parentLi.classList.contains("is-open");
            navRoot
              .querySelectorAll(".ab-nav-menu__item.has-children.is-open")
              .forEach(function (li) {
                if (li !== parentLi) {
                  li.classList.remove("is-open");
                  var a = li.querySelector(".ab-nav-menu__link");
                  if (a) a.setAttribute("aria-expanded", "false");
                }
              });
            parentLi.classList.toggle("is-open", !wasOpen);
            parentLink.setAttribute("aria-expanded", !wasOpen ? "true" : "false");
            return;
          }
        }
      }
      // Click outside closes mobile drawer + open dropdowns.
      if (!e.target.closest("[data-ab-nav-menu]")) {
        document.querySelectorAll("[data-ab-nav-menu].is-open").forEach(function (nav) {
          nav.classList.remove("is-open");
          var t = nav.querySelector("[data-ab-nav-toggle]");
          if (t) t.setAttribute("aria-expanded", "false");
        });
        document
          .querySelectorAll(".ab-nav-menu__item.has-children.is-open")
          .forEach(function (li) {
            li.classList.remove("is-open");
          });
      }
      var tab = e.target.closest("[data-ab-tabs] .ab-tabs__tab");
      if (tab) {
        var root = tab.closest("[data-ab-tabs]");
        if (!root) return;
        var id = tab.getAttribute("data-tab");
        root.querySelectorAll(".ab-tabs__tab").forEach(function (t) {
          t.classList.toggle("is-active", t === tab);
        });
        root.querySelectorAll(".ab-tabs__panel").forEach(function (p) {
          p.classList.toggle("is-active", p.id === id);
        });
        return;
      }
      var acc = e.target.closest("[data-ab-accordion] .ab-accordion__head");
      if (acc) {
        var item = acc.closest(".ab-accordion__item");
        var rootA = acc.closest("[data-ab-accordion]");
        if (!item || !rootA) return;
        var open = item.classList.contains("is-open");
        var multi = rootA.getAttribute("data-multiple") === "1";
        if (!multi) {
          rootA.querySelectorAll(".ab-accordion__item").forEach(function (it) {
            if (it !== item) it.classList.remove("is-open");
          });
        }
        item.classList.toggle("is-open", !open);
        return;
      }
      var tog = e.target.closest("[data-ab-toggle] .ab-toggle-w__head");
      if (tog) {
        var wrap = tog.closest("[data-ab-toggle]");
        if (wrap) wrap.classList.toggle("is-open");
      }
    });

    // ── Shared slider engines (gallery + carousel) ──────────────────────
    // Document-level delegation so clicks always work even if DOM re-renders.
    var galState = new WeakMap();
    var carState = new WeakMap();

    function galleryStep(el) {
      var track = el.querySelector(".ab-gallery__track");
      var items = el.querySelectorAll(".ab-gallery__item");
      if (!track || !items.length) return 0;
      var gap = parseFloat(getComputedStyle(el).getPropertyValue("--ab-gal-gap")) || 8;
      var w = items[0].offsetWidth || items[0].getBoundingClientRect().width || el.clientWidth || 0;
      return w + gap;
    }

    function galleryGo(el, n) {
      var st = galState.get(el);
      if (!st) {
        st = { i: 0 };
        galState.set(el, st);
      }
      var track = el.querySelector(".ab-gallery__track");
      var items = Array.prototype.slice.call(el.querySelectorAll(".ab-gallery__item"));
      if (!track || items.length < 2) return;
      var per = parseInt(el.getAttribute("data-per"), 10) || 1;
      var max = Math.max(0, items.length - per);
      st.i = ((n % (max + 1)) + (max + 1)) % (max + 1);
      var w = galleryStep(el);
      if (w < 2) {
        requestAnimationFrame(function () {
          w = galleryStep(el);
          track.style.transform = "translate3d(-" + st.i * Math.max(w, 0) + "px,0,0)";
        });
      } else {
        track.style.transform = "translate3d(-" + st.i * w + "px,0,0)";
      }
      items.forEach(function (it, idx) {
        it.classList.toggle("is-active", idx === st.i);
      });
    }

    function carouselGo(el, n) {
      var st = carState.get(el);
      if (!st) {
        st = { i: 0 };
        carState.set(el, st);
      }
      var slides = Array.prototype.slice.call(el.querySelectorAll(".ab-carousel__slide"));
      if (slides.length < 2) return;
      var layout =
        el.getAttribute("data-layout") ||
        (el.classList.contains("ab-carousel--multi") ? "multi" : "single");
      var per = parseInt(el.getAttribute("data-per"), 10) || 1;
      var track = el.querySelector(".ab-carousel__track");
      var dots = Array.prototype.slice.call(
        el.querySelectorAll("[data-ab-car-dot], .ab-carousel__dot")
      );
      var max = layout === "multi" ? Math.max(0, slides.length - per) : slides.length - 1;
      st.i = ((n % (max + 1)) + (max + 1)) % (max + 1);
      if (layout === "multi" && track) {
        var gap = parseFloat(getComputedStyle(el).getPropertyValue("--ab-carousel-gap")) || 8;
        var slideW =
          (slides[0].offsetWidth || slides[0].getBoundingClientRect().width || 0) + gap;
        track.style.transform = "translate3d(-" + st.i * slideW + "px,0,0)";
      } else {
        slides.forEach(function (s, idx) {
          s.classList.toggle("is-active", idx === st.i);
        });
      }
      dots.forEach(function (d, idx) {
        d.classList.toggle("is-active", idx === st.i);
      });
    }

    // Click once on document — works even if kses strips data-* attrs
    // (class selectors are the reliable fallback).
    document.addEventListener(
      "click",
      function (e) {
        var galPrev = e.target.closest(
          "[data-ab-gal-prev], .ab-gallery__nav--prev"
        );
        var galNext = e.target.closest(
          "[data-ab-gal-next], .ab-gallery__nav--next"
        );
        if (galPrev || galNext) {
          var gal = (galPrev || galNext).closest(
            "[data-ab-gallery-slider], .ab-gallery--slider"
          );
          if (gal) {
            e.preventDefault();
            e.stopPropagation();
            var gst = galState.get(gal) || { i: 0 };
            galleryGo(gal, gst.i + (galNext ? 1 : -1));
            return;
          }
        }
        var carPrev = e.target.closest(
          "[data-ab-car-prev], .ab-carousel__nav--prev"
        );
        var carNext = e.target.closest(
          "[data-ab-car-next], .ab-carousel__nav--next"
        );
        if (carPrev || carNext) {
          var car = (carPrev || carNext).closest(
            "[data-ab-carousel], .ab-carousel, .ab-img-carousel"
          );
          if (car) {
            e.preventDefault();
            e.stopPropagation();
            var cst = carState.get(car) || { i: 0 };
            carouselGo(car, cst.i + (carNext ? 1 : -1));
            return;
          }
        }
        var carDot = e.target.closest(
          "[data-ab-car-dot], .ab-carousel__dot, .ab-img-carousel__dot"
        );
        if (carDot) {
          var car2 = carDot.closest(
            "[data-ab-carousel], .ab-carousel, .ab-img-carousel"
          );
          if (car2) {
            e.preventDefault();
            e.stopPropagation();
            var idx = parseInt(
              carDot.getAttribute("data-ab-car-dot") ||
                carDot.getAttribute("data-index") ||
                "0",
              10
            );
            // If no data-index, use sibling position
            if (isNaN(idx)) {
              var dots = car2.querySelectorAll(
                ".ab-carousel__dot, .ab-img-carousel__dot, [data-ab-car-dot]"
              );
              idx = Array.prototype.indexOf.call(dots, carDot);
            }
            if (!isNaN(idx) && idx >= 0) carouselGo(car2, idx);
          }
        }
      },
      true
    ); // capture — beat other handlers

    // Init carousels (position + autoplay)
    document.querySelectorAll("[data-ab-carousel], .ab-carousel").forEach(function (el) {
      if (el._abCarInit) return;
      el._abCarInit = true;
      var slides = el.querySelectorAll(".ab-carousel__slide");
      if (slides.length < 2) return;
      carState.set(el, { i: 0 });
      carouselGo(el, 0);
      var autoplay = el.getAttribute("data-autoplay") !== "0";
      if (autoplay) {
        setInterval(function () {
          var st = carState.get(el) || { i: 0 };
          carouselGo(el, st.i + 1);
        }, 4500);
      }
    });

    // Init gallery sliders (+ optional autoplay)
    function initGalleries() {
      document
        .querySelectorAll("[data-ab-gallery-slider], .ab-gallery--slider")
        .forEach(function (el) {
          if (el._abGalInit) return;
          el._abGalInit = true;
          if (!el.getAttribute("data-ab-gallery-slider")) {
            el.setAttribute("data-ab-gallery-slider", "1");
          }
          galState.set(el, { i: 0 });
          galleryGo(el, 0);
          el.querySelectorAll("img").forEach(function (img) {
            if (!img.complete) {
              img.addEventListener("load", function () {
                var st = galState.get(el) || { i: 0 };
                galleryGo(el, st.i);
              });
            }
          });
          // Autoplay: data-autoplay="0" disables; missing defaults to on for sliders.
          var autoplay = el.getAttribute("data-autoplay");
          if (autoplay === null || autoplay === "") autoplay = "1";
          if (autoplay !== "0" && autoplay !== "false") {
            var ms = parseInt(el.getAttribute("data-autoplay-ms") || "4500", 10);
            if (isNaN(ms) || ms < 1500) ms = 4500;
            if (ms > 20000) ms = 20000;
            // Pause when tab hidden; resume when visible.
            var timer = null;
            function tick() {
              var st = galState.get(el) || { i: 0 };
              galleryGo(el, st.i + 1);
            }
            function start() {
              if (timer) return;
              if (document.hidden) return;
              timer = setInterval(tick, ms);
            }
            function stop() {
              if (timer) {
                clearInterval(timer);
                timer = null;
              }
            }
            start();
            document.addEventListener("visibilitychange", function () {
              if (document.hidden) stop();
              else start();
            });
            // Pause on hover (desktop) / resume on leave.
            el.addEventListener("mouseenter", stop);
            el.addEventListener("mouseleave", start);
            // After manual nav, restart timer so user doesn't fight autoplay.
            el.addEventListener(
              "click",
              function (e) {
                if (
                  e.target.closest &&
                  e.target.closest(
                    "[data-ab-gal-prev], [data-ab-gal-next], .ab-gallery__nav"
                  )
                ) {
                  stop();
                  start();
                }
              },
              true
            );
          }
        });
    }
    initGalleries();
    setTimeout(initGalleries, 200);
    setTimeout(initGalleries, 800);
    window.addEventListener("resize", function () {
      document
        .querySelectorAll("[data-ab-gallery-slider], .ab-gallery--slider")
        .forEach(function (el) {
          var st = galState.get(el);
          if (st) galleryGo(el, st.i);
        });
      document.querySelectorAll("[data-ab-carousel], .ab-carousel").forEach(function (el) {
        var st = carState.get(el);
        if (st) carouselGo(el, st.i);
      });
    });

    // Motion effects — entrance when element enters viewport
    if ("IntersectionObserver" in window) {
      var reduce =
        window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
      var fxEls = document.querySelectorAll(".ab-fx-entrance, [data-ab-fx]");
      if (reduce) {
        fxEls.forEach(function (el) {
          el.classList.add("ab-fx-in");
        });
      } else {
        var io = new IntersectionObserver(
          function (entries) {
            entries.forEach(function (entry) {
              if (entry.isIntersecting) {
                entry.target.classList.add("ab-fx-in");
                io.unobserve(entry.target);
              }
            });
          },
          { threshold: 0.15, rootMargin: "0px 0px -40px 0px" }
        );
        document.querySelectorAll(".ab-fx-entrance").forEach(function (el) {
          io.observe(el);
        });
      }
    } else {
      document.querySelectorAll(".ab-fx-entrance").forEach(function (el) {
        el.classList.add("ab-fx-in");
      });
    }

    // Creative cards — click tile to load panel content
    document.querySelectorAll("[data-ab-creative]").forEach(function (root) {
      var cards = root.querySelectorAll(".ab-creative-card");
      var panels = root.querySelectorAll(".ab-creative-panel");
      function openIdx(idx) {
        cards.forEach(function (c) {
          c.classList.toggle("is-active", c.getAttribute("data-ab-cc-idx") === String(idx));
        });
        panels.forEach(function (p) {
          p.classList.toggle("is-open", p.getAttribute("data-ab-cc-panel") === String(idx));
        });
        // Position caret under active card
        var active = root.querySelector('.ab-creative-card.is-active');
        var openPanel = root.querySelector(".ab-creative-panel.is-open");
        if (active && openPanel) {
          var caret = openPanel.querySelector(".ab-creative-panel__caret");
          if (caret) {
            var rootRect = root.getBoundingClientRect();
            var cardRect = active.getBoundingClientRect();
            var left = cardRect.left + cardRect.width / 2 - rootRect.left;
            caret.style.left = left + "px";
          }
        }
      }
      cards.forEach(function (card) {
        card.addEventListener("click", function () {
          var idx = card.getAttribute("data-ab-cc-idx");
          var already = card.classList.contains("is-active");
          if (already) {
            cards.forEach(function (c) { c.classList.remove("is-active"); });
            panels.forEach(function (p) { p.classList.remove("is-open"); });
            return;
          }
          openIdx(idx);
        });
      });
      root.querySelectorAll("[data-ab-cc-close]").forEach(function (btn) {
        btn.addEventListener("click", function (e) {
          e.preventDefault();
          e.stopPropagation();
          cards.forEach(function (c) { c.classList.remove("is-active"); });
          panels.forEach(function (p) { p.classList.remove("is-open"); });
        });
      });
    });

    // Loop grid as post slider + dots
    document.querySelectorAll("[data-ab-loop-slider]").forEach(function (root) {
      var track = root.querySelector(".ab-loop-slider__track, .ab-loop-grid__list");
      if (!track) return;
      var cards = Array.prototype.slice.call(track.querySelectorAll(".ab-loop-card"));
      if (cards.length < 1) return;
      var dots = Array.prototype.slice.call(root.querySelectorAll("[data-ab-loop-dot]"));
      var i = 0;

      function layout() {
        track.style.display = "flex";
        track.style.transition = "transform .4s ease";
        track.style.willChange = "transform";
        cards.forEach(function (c) {
          c.style.flex = "0 0 100%";
          c.style.minWidth = "100%";
          c.style.maxWidth = "100%";
          c.style.boxSizing = "border-box";
        });
      }

      function go(n) {
        if (!cards.length) return;
        i = ((n % cards.length) + cards.length) % cards.length;
        track.style.transform = "translate3d(-" + i * 100 + "%,0,0)";
        cards.forEach(function (c, idx) {
          c.classList.toggle("is-active-slide", idx === i);
        });
        dots.forEach(function (d, idx) {
          d.classList.toggle("is-active", idx === i);
        });
      }

      layout();
      go(0);

      var prev = root.querySelector("[data-ab-loop-prev]");
      var next = root.querySelector("[data-ab-loop-next]");
      if (prev) prev.addEventListener("click", function (e) { e.preventDefault(); go(i - 1); });
      if (next) next.addEventListener("click", function (e) { e.preventDefault(); go(i + 1); });
      dots.forEach(function (d) {
        d.addEventListener("click", function (e) {
          e.preventDefault();
          var idx = parseInt(d.getAttribute("data-ab-loop-dot"), 10);
          if (!isNaN(idx)) go(idx);
        });
      });

      // Auto-advance
      if (cards.length > 1) {
        setInterval(function () {
          go(i + 1);
        }, 5000);
      }
    });

    // Counter — numbers count up when visible
    (function initCounters() {
      function parseTarget(raw) {
        var s = String(raw == null ? "0" : raw).trim().replace(/\s/g, "").replace(",", ".");
        var n = parseFloat(s);
        return isNaN(n) ? 0 : n;
      }
      function formatNum(n, targetRaw) {
        var raw = String(targetRaw == null ? "" : targetRaw);
        // Keep integer if target looks like integer
        if (/^\d+$/.test(raw.replace(/\s/g, ""))) return String(Math.round(n));
        var dec = (raw.split(".")[1] || "").length;
        return n.toFixed(Math.min(2, dec || 0));
      }
      function run(el) {
        if (!el || el.getAttribute("data-ab-counted") === "1") return;
        var root = el.closest("[data-ab-counter]") || el.parentElement;
        if (root && root.getAttribute("data-animate") === "0") {
          var p0 = el.getAttribute("data-prefix") || "";
          var s0 = el.getAttribute("data-suffix") || "";
          var t0 = el.getAttribute("data-target") || "0";
          el.textContent = p0 + t0 + s0;
          el.setAttribute("data-ab-counted", "1");
          return;
        }
        el.setAttribute("data-ab-counted", "1");
        var target = parseTarget(el.getAttribute("data-target"));
        var prefix = el.getAttribute("data-prefix") || "";
        var suffix = el.getAttribute("data-suffix") || "";
        var duration = parseInt(el.getAttribute("data-duration"), 10) || 1600;
        var start = null;
        var from = 0;
        function frame(ts) {
          if (start == null) start = ts;
          var p = Math.min(1, (ts - start) / duration);
          // easeOutCubic
          var eased = 1 - Math.pow(1 - p, 3);
          var cur = from + (target - from) * eased;
          el.textContent = prefix + formatNum(cur, el.getAttribute("data-target")) + suffix;
          if (p < 1) requestAnimationFrame(frame);
          else el.textContent = prefix + (el.getAttribute("data-target") || "0") + suffix;
        }
        requestAnimationFrame(frame);
      }
      var nodes = document.querySelectorAll(
        ".ab-counter__number[data-target], [data-ab-counter] .ab-counter__number"
      );
      if (!nodes.length) return;
      if ("IntersectionObserver" in window) {
        var io = new IntersectionObserver(
          function (entries) {
            entries.forEach(function (en) {
              if (en.isIntersecting) {
                run(en.target);
                io.unobserve(en.target);
              }
            });
          },
          { threshold: 0.35 }
        );
        nodes.forEach(function (n) {
          io.observe(n);
        });
      } else {
        nodes.forEach(run);
      }
    })();

    // Advanced accordion
    document.querySelectorAll("[data-ab-adv-acc]").forEach(function (root) {
      var multiple = root.getAttribute("data-multiple") === "1";
      root.querySelectorAll(".ab-adv-acc__head").forEach(function (btn) {
        btn.addEventListener("click", function () {
          var item = btn.closest(".ab-adv-acc__item");
          if (!item) return;
          var open = item.classList.contains("is-open");
          if (!multiple) {
            root.querySelectorAll(".ab-adv-acc__item").forEach(function (it) {
              it.classList.remove("is-open");
            });
          }
          if (open) item.classList.remove("is-open");
          else item.classList.add("is-open");
        });
      });
    });

    // Text animation (typing / fade / slide / bounce)
    document.querySelectorAll("[data-ab-text-anim]").forEach(function (el) {
      var raw = el.getAttribute("data-words") || "[]";
      var words = [];
      try {
        words = JSON.parse(raw);
      } catch (e) {
        words = [];
      }
      if (!words || words.length < 2) return;
      var effect = el.getAttribute("data-effect") || "typing";
      var speed = parseInt(el.getAttribute("data-speed"), 10) || 80;
      var pause = parseInt(el.getAttribute("data-pause"), 10) || 2000;
      var wordEl = el.querySelector(".ab-text-anim__word");
      if (!wordEl) return;
      var idx = 0;

      function showNext() {
        idx = (idx + 1) % words.length;
        var next = words[idx];
        if (effect === "typing") {
          typeWord(next, function () {
            setTimeout(showNext, pause);
          });
        } else {
          wordEl.classList.remove("is-swap");
          // reflow
          void wordEl.offsetWidth;
          wordEl.textContent = next;
          wordEl.classList.add("is-swap");
          setTimeout(showNext, pause);
        }
      }

      function typeWord(text, done) {
        var i = 0;
        wordEl.textContent = "";
        function tick() {
          if (i <= text.length) {
            wordEl.textContent = text.slice(0, i);
            i++;
            setTimeout(tick, speed);
          } else {
            done();
          }
        }
        tick();
      }

      if (effect === "typing") {
        setTimeout(function () {
          typeWord(words[0], function () {
            setTimeout(showNext, pause);
          });
        }, pause);
      } else if (effect !== "gradient") {
        setTimeout(showNext, pause);
      }
    });

    // Image carousel pro
    document.querySelectorAll("[data-ab-img-carousel]").forEach(function (root) {
      var slides = Array.prototype.slice.call(root.querySelectorAll(".ab-img-carousel__slide"));
      if (slides.length < 2) return;
      var dots = Array.prototype.slice.call(root.querySelectorAll("[data-ab-ic-dot]"));
      var i = 0;
      var autoplay = root.getAttribute("data-autoplay") !== "0";
      var interval = parseInt(root.getAttribute("data-interval"), 10) || 4500;
      var timer = null;

      function go(n) {
        i = ((n % slides.length) + slides.length) % slides.length;
        slides.forEach(function (s, idx) {
          s.classList.toggle("is-active", idx === i);
        });
        dots.forEach(function (d, idx) {
          d.classList.toggle("is-active", idx === i);
        });
      }

      function arm() {
        if (!autoplay) return;
        clearInterval(timer);
        timer = setInterval(function () {
          go(i + 1);
        }, interval);
      }

      var prev = root.querySelector("[data-ab-ic-prev]");
      var next = root.querySelector("[data-ab-ic-next]");
      if (prev)
        prev.addEventListener("click", function (e) {
          e.preventDefault();
          go(i - 1);
          arm();
        });
      if (next)
        next.addEventListener("click", function (e) {
          e.preventDefault();
          go(i + 1);
          arm();
        });
      dots.forEach(function (d) {
        d.addEventListener("click", function (e) {
          e.preventDefault();
          var idx = parseInt(d.getAttribute("data-ab-ic-dot"), 10);
          if (!isNaN(idx)) go(idx);
          arm();
        });
      });
      arm();
    });

    // ── Site background carousel ──────────────────────────────────────
    document.querySelectorAll("[data-ab-site-bg-carousel]").forEach(function (root) {
      if (root._abBgBound) return;
      root._abBgBound = true;
      var slides = Array.prototype.slice.call(root.querySelectorAll(".ab-site-bg-carousel__slide"));
      if (slides.length < 2) return;
      var i = 0;
      var speed = parseInt(root.getAttribute("data-speed"), 10) || 5000;
      var fx = root.getAttribute("data-fx") || "fade";
      root.classList.add("ab-site-bg-carousel--fx-" + fx);
      setInterval(function () {
        i = (i + 1) % slides.length;
        slides.forEach(function (s, idx) {
          s.classList.toggle("is-active", idx === i);
        });
      }, Math.max(1500, speed));
    });

    // ── Popups (page markers + global AuraBuilderPopups) ──────────────
    function popupStorageKey(cfg) {
      return "ab_popup_" + String(cfg.id || "x") + "_" + String(cfg.post_id || "");
    }
    function popupAllowed(cfg) {
      var freq = cfg.frequency || "session";
      if (freq === "every") return true;
      var key = popupStorageKey(cfg);
      try {
        if (freq === "session") {
          return !sessionStorage.getItem(key);
        }
        if (freq === "once") {
          return !localStorage.getItem(key);
        }
      } catch (e) {}
      return true;
    }
    function popupMarkSeen(cfg) {
      var freq = cfg.frequency || "session";
      if (freq === "every") return;
      var key = popupStorageKey(cfg);
      try {
        if (freq === "session") sessionStorage.setItem(key, "1");
        else if (freq === "once") localStorage.setItem(key, "1");
      } catch (e) {}
    }
    function openAuraPopup(cfg) {
      if (!cfg || !cfg.images || !cfg.images.length) return;
      if (!popupAllowed(cfg)) return;
      if (document.querySelector('.ab-popup-modal[data-popup-id="' + String(cfg.id || "") + '"]')) return;

      var overlay = document.createElement("div");
      overlay.className = "ab-popup-modal";
      overlay.setAttribute("data-popup-id", String(cfg.id || ""));
      overlay.setAttribute("role", "dialog");
      overlay.setAttribute("aria-modal", "true");
      if (cfg.overlay !== false) overlay.classList.add("ab-popup-modal--overlay");
      var fx = (cfg.open_effect || "fadein").replace(/[^a-z]/gi, "").toLowerCase();
      if (fx && fx !== "none") overlay.classList.add("ab-popup-modal--fx-" + fx);

      var maxW = parseInt(cfg.max_width, 10) || 720;
      var imgs = cfg.images.slice();
      var mode = cfg.mode || (imgs.length > 1 ? "carousel" : "image");
      var slideFx = cfg.slide_effect || "fade";
      var html =
        '<div class="ab-popup-modal__dialog" style="max-width:' +
        maxW +
        'px">' +
        (cfg.show_close !== false
          ? '<button type="button" class="ab-popup-modal__close" aria-label="Fechar">&times;</button>'
          : "") +
        '<div class="ab-popup-modal__body ab-popup-modal__body--' +
        slideFx +
        '">';
      if (mode === "carousel" && imgs.length > 1) {
        html += '<div class="ab-popup-modal__track">';
        imgs.forEach(function (u, idx) {
          html +=
            '<figure class="ab-popup-modal__slide' +
            (idx === 0 ? " is-active" : "") +
            '"><img src="' +
            String(u).replace(/"/g, "&quot;") +
            '" alt=""/></figure>';
        });
        html += "</div>";
        html +=
          '<button type="button" class="ab-popup-modal__nav ab-popup-modal__nav--prev" aria-label="Anterior">‹</button>' +
          '<button type="button" class="ab-popup-modal__nav ab-popup-modal__nav--next" aria-label="Próximo">›</button>' +
          '<div class="ab-popup-modal__dots">';
        imgs.forEach(function (_, idx) {
          html +=
            '<button type="button" class="ab-popup-modal__dot' +
            (idx === 0 ? " is-active" : "") +
            '" data-dot="' +
            idx +
            '"></button>';
        });
        html += "</div>";
      } else {
        html +=
          '<figure class="ab-popup-modal__slide is-active"><img src="' +
          String(imgs[0]).replace(/"/g, "&quot;") +
          '" alt=""/></figure>';
      }
      html += "</div></div>";
      overlay.innerHTML = html;
      document.body.appendChild(overlay);
      requestAnimationFrame(function () {
        overlay.classList.add("is-open");
      });
      popupMarkSeen(cfg);

      function close() {
        overlay.classList.remove("is-open");
        setTimeout(function () {
          if (overlay.parentNode) overlay.parentNode.removeChild(overlay);
        }, 280);
        document.removeEventListener("keydown", onKey);
      }
      function onKey(e) {
        if (e.key === "Escape") close();
      }
      document.addEventListener("keydown", onKey);
      var closeBtn = overlay.querySelector(".ab-popup-modal__close");
      if (closeBtn) closeBtn.addEventListener("click", function (e) {
        e.preventDefault();
        close();
      });
      overlay.addEventListener("click", function (e) {
        if (e.target === overlay) close();
      });

      if (mode === "carousel" && imgs.length > 1) {
        var slides = Array.prototype.slice.call(overlay.querySelectorAll(".ab-popup-modal__slide"));
        var dots = Array.prototype.slice.call(overlay.querySelectorAll(".ab-popup-modal__dot"));
        var si = 0;
        var slideTime = parseInt(cfg.slide_time, 10) || 4000;
        function go(n) {
          si = ((n % slides.length) + slides.length) % slides.length;
          slides.forEach(function (s, idx) {
            s.classList.toggle("is-active", idx === si);
          });
          dots.forEach(function (d, idx) {
            d.classList.toggle("is-active", idx === si);
          });
        }
        var prev = overlay.querySelector(".ab-popup-modal__nav--prev");
        var next = overlay.querySelector(".ab-popup-modal__nav--next");
        if (prev) prev.addEventListener("click", function (e) {
          e.preventDefault();
          go(si - 1);
        });
        if (next) next.addEventListener("click", function (e) {
          e.preventDefault();
          go(si + 1);
        });
        dots.forEach(function (d) {
          d.addEventListener("click", function (e) {
            e.preventDefault();
            var idx = parseInt(d.getAttribute("data-dot"), 10);
            if (!isNaN(idx)) go(idx);
          });
        });
        if (cfg.autoplay !== false) {
          setInterval(function () {
            go(si + 1);
          }, Math.max(1000, slideTime));
        }
      }
    }

    function schedulePopup(cfg) {
      if (!cfg) return;
      var delay = parseInt(cfg.delay, 10);
      if (isNaN(delay) || delay < 0) delay = 800;
      setTimeout(function () {
        openAuraPopup(cfg);
      }, delay);
    }

    // Page-level sources
    document.querySelectorAll("[data-ab-popup]").forEach(function (el) {
      var raw = el.getAttribute("data-ab-popup");
      if (!raw) return;
      try {
        schedulePopup(JSON.parse(raw));
      } catch (e) {}
    });
    // Global (home / all pages)
    if (window.AuraBuilderPopups && Array.isArray(window.AuraBuilderPopups)) {
      window.AuraBuilderPopups.forEach(schedulePopup);
    }
  });
})();
