(function () { const iav = {}; const scriptTag = document.currentScript || (() => { const scripts = document.getElementsByTagName("script"); return scripts[scripts.length - 1]; })(); const id = scriptTag.id || (() => { const src = scriptTag.src; const url = new URL(src); return url.searchParams.get("id"); })(); iav.sendRequest = function (props) { const payload = JSON.stringify({ ...props, id: id, tf: "tr" }); const trackingURL = "https://t.webmetic.de/tr"; fetch(trackingURL, { method: "POST", headers: { "Content-Type": "application/json", }, body: payload, }) .then((response) => { if (!response.ok) { throw new Error(); } return response.json(); }) .then(() => {}) .catch(() => { if (typeof props.eventValue === "object") { props.eventValue = JSON.stringify(props.eventValue); } props.tf = "png"; const baseURL = "https://t.webmetic.de/d.png"; const trackingURL = new URL(baseURL); const params = new URLSearchParams(props); trackingURL.search = params.toString(); const img = new Image(); img.src = trackingURL.href; }); }; iav.generateImg = function () { return Math.round(2147483647 * Math.random()).toString(); }; let maxScrollDepthReached = 0; const SCROLL_THRESHOLDS = [25, 50, 75, 90]; let lastReportedThreshold = 0; function getScrollDepth() { const scrollY = window.scrollY || window.pageYOffset; const viewportHeight = window.innerHeight || document.documentElement.clientHeight; const documentHeight = Math.max( document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight ); return Math.floor(((scrollY + viewportHeight) / documentHeight) * 100); } function updateMaxScrollDepth() { const currentScrollDepth = getScrollDepth(); if (currentScrollDepth > maxScrollDepthReached) { maxScrollDepthReached = currentScrollDepth; const nextThreshold = SCROLL_THRESHOLDS.find( (threshold) => threshold > lastReportedThreshold && maxScrollDepthReached >= threshold ); if (nextThreshold) { sendMaxScrollDepth(nextThreshold); lastReportedThreshold = nextThreshold; } } } function debounce(func, delay) { let debounceTimer; return function () { const context = this; const args = arguments; clearTimeout(debounceTimer); debounceTimer = setTimeout(() => func.apply(context, args), delay); }; } function handleInputEvent(event) { const iE = event.target; const iV = iE.value.trim(); const drm = /\b(?:http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5})(?:\/|$)/i; const eR = /@([\w.-]+\.[a-zA-Z]{2,6})$/i; const eM = iV.match(eR); const dM = eM ? null : iV.match(drm); const d = dM ? dM[1] : null; const e = eM ? eM[1] : null; if (d || e) { const iED = { event_name: d ? "doInput" : "emInput", event_value: d || e, elementClass: iE.className, parentElementInfo: `${iE.parentElement.tagName}#${iE.parentElement.id}`, xpath: getXPathForElement(iE), viewportX: iE.getBoundingClientRect().left, viewportY: iE.getBoundingClientRect().top, }; iav.sendEvent(iED.event_name, iED); } } document.addEventListener("click", hce); document.addEventListener("touchend", hce); const inputs = document.getElementsByTagName("input"); for (let i = 0; i < inputs.length; i++) { inputs[i].addEventListener("blur", debounce(handleInputEvent, 200)); inputs[i].addEventListener("change", debounce(handleInputEvent, 200)); inputs[i].addEventListener("touchend", debounce(handleInputEvent, 200)); } function sendMaxScrollDepth(threshold) { const scrollDepthDetails = { eventScroll: "maxScrollDepth", sde: threshold, bu: window.location.origin, dl: document.location.href, ua: navigator.userAgent, sr: `${screen.width}x${screen.height}`, aid: id, pl: navigator.platform || "Unknown", np: navigator.plugins ? navigator.plugins.length : 0, vp: window.innerWidth + "x" + window.innerHeight, cs: window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light", ul: window.navigator.userLanguage || window.navigator.language, }; iav.sendRequest(scrollDepthDetails); } window.addEventListener("scroll", debounce(updateMaxScrollDepth, 250), { passive: true, }); function ggd() { const cks = document.cookie.split(";"); let gd = { gci: null, gsi: null, gsn: null, }; for (let ck of cks) { ck = ck.trim(); if (ck.startsWith("_ga=")) { const decodedValue = decodeURIComponent(ck.split("=")[1]); const parts = decodedValue.split("."); if (parts.length > 2) { gd.gci = parts.slice(-2).join("."); } } else if (ck.startsWith("_ga_")) { const pattern = /=GS\d\.\d\.(.+?)(?:;|$)/; const match = ck.match(pattern); const parts = match?.[1].split("."); if (parts && parts.length >= 2) { gd.gsi = parts[0]; gd.gsn = parts[1]; } } } return gd; } function ptd(eventType, ad) { ad = ad || {}; const gd = ggd(); const props = { v: 1, aid: id, t: eventType, bu: window.location.origin, ul: window.navigator.userLanguage || window.navigator.language, cd: screen.colorDepth + "-bit", sr: screen.width + "x" + screen.height, de: document.characterSet, dl: document.location.href, dt: document.title, dr: document.referrer, ua: navigator.userAgent, ep: document.location.pathname, vp: window.innerWidth + "x" + window.innerHeight, ce: navigator.cookieEnabled, ct: navigator.connection ? navigator.connection.effectiveType : "unknown", cs: window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light", pl: navigator.platform || "Unknown", np: navigator.plugins ? navigator.plugins.length : 0, gci: gd.gci, gsi: gd.gsi, gsn: gd.gsn, }; for (const key in ad) { if (ad.hasOwnProperty(key)) { props[key] = ad[key]; } } if (props.eventValue === "" || typeof props.eventValue === "undefined") { delete props.eventValue; } if (props.link_url === "" || typeof props.link_url === "undefined") { delete props.link_url; } iav.sendRequest(props); } iav.sendEvent = function (name, value, link_url = "") { const eventDetails = { eventName: name, eventValue: value, link_url: link_url, }; ptd("interaction", eventDetails); }; function hce(event) { const clickedElement = event.target; const link_url = clickedElement.tagName.toLowerCase() === "a" ? clickedElement.href : ""; const elementClass = clickedElement.className; const parentElementInfo = clickedElement.parentElement ? `${clickedElement.parentElement.tagName}#${clickedElement.parentElement.id}` : "No parent element"; const xpath = getXPathForElement(clickedElement); const viewportX = clickedElement.getBoundingClientRect().left; const viewportY = clickedElement.getBoundingClientRect().top; const newEvent = { event_name: "click", event_value: `${clickedElement.tagName}#${clickedElement.id}`, link_url: link_url, elementclass: elementClass, parentelementinfo: parentElementInfo, xpath: xpath, viewportx: viewportX, viewporty: viewportY, }; iav.sendEvent("click", newEvent); } document.addEventListener("focusin", function (event) { const focusEventDetails = { event_name: "focus", event_value: event.target.tagName + "#" + event.target.id, elementclass: event.target.className, parentelementinfo: `${event.target.parentElement.tagName}#${event.target.parentElement.id}`, xpath: getXPathForElement(event.target), viewportx: event.target.getBoundingClientRect().left, viewporty: event.target.getBoundingClientRect().top, }; iav.sendEvent("focus", focusEventDetails); }); function getXPathForElement(el) { let xpath = el.tagName; let parent = el.parentElement; while (parent) { xpath = `${parent.tagName}/${xpath}`; parent = parent.parentElement; } return xpath; } window.addEventListener("beforeunload", () => { const finalThreshold = SCROLL_THRESHOLDS.findLast( (threshold) => maxScrollDepthReached >= threshold ); if (finalThreshold && finalThreshold > lastReportedThreshold) { sendMaxScrollDepth(finalThreshold); } }); ptd("page_load"); })();