/* MEXEM post-consent engagement signals. Add this block to the existing Zaraz Custom HTML that runs AFTER Analytics consent. Keep the existing session-id / consent-context / ConsentPageview code unchanged. */ (function () { if (window.__mexemEngagementTrackingV1) return; window.__mexemEngagementTrackingV1 = true; var fired = Object.create(null); function trackOnce(name) { if (fired[name]) return; fired[name] = true; try { if (window.zaraz && typeof window.zaraz.track === "function") { window.zaraz.track(name, { engagement_tracking_version: "v1" }); } } catch (_) { // Analytics must never interfere with the page UX. } } // Marker used by the dashboard so historical sessions collected before // this instrumentation are never misclassified as zero-engagement/bots. trackOnce("engagement_tracking_ready"); // If the visitor had already scrolled before accepting analytics consent, // preserve that fact immediately. if ( window.scrollY > 0 || document.documentElement.scrollTop > 0 || (document.body && document.body.scrollTop > 0) ) { trackOnce("first_scroll"); } function onFirstScroll() { trackOnce("first_scroll"); window.removeEventListener("scroll", onFirstScroll); } window.addEventListener("scroll", onFirstScroll, { passive: true }); var interactionEvents = [ "pointerdown", "touchstart", "keydown" ]; function onFirstInteraction() { trackOnce("first_interaction"); for (var i = 0; i < interactionEvents.length; i++) { window.removeEventListener( interactionEvents[i], onFirstInteraction ); } } for (var i = 0; i < interactionEvents.length; i++) { window.addEventListener( interactionEvents[i], onFirstInteraction, { passive: true } ); } // Count only time during which the page is actually visible. // A tab sitting in the background does not become an engaged visit. var visibleMs = 0; var visibleSince = document.visibilityState === "visible" ? performance.now() : null; var thresholds = [ { ms: 2000, event: "engaged_2s" }, { ms: 5000, event: "engaged_5s" }, { ms: 10000, event: "engaged_10s" } ]; function updateVisibleTime() { var now = performance.now(); if (visibleSince !== null) { visibleMs += now - visibleSince; visibleSince = now; } for (var i = 0; i < thresholds.length; i++) { if (visibleMs >= thresholds[i].ms) { trackOnce(thresholds[i].event); } } } document.addEventListener("visibilitychange", function () { updateVisibleTime(); visibleSince = document.visibilityState === "visible" ? performance.now() : null; }); window.setInterval(updateVisibleTime, 250); })();