PageSourceSearch

https://konakit.be/wp-content/plugins/opinly-analytics/assets/opinly-pixel.js?ver=1.0.0

js konakit.be collected 2026-10-01 15:57:31 UTC 16,402 bytes, 486 lines download raw bytes

1(function () {
2  if (typeof window === 'undefined' || typeof document === 'undefined') return;
3
4  var scriptEl = document.currentScript;
5  var writeKey = scriptEl && scriptEl.dataset && scriptEl.dataset.key;
6  if (!writeKey) return;
7
8  var apiHost;
9  try {
10    apiHost = (scriptEl.dataset && scriptEl.dataset.apiHost) || new URL(scriptEl.src).origin;
11  } catch (e) { return; }
12  if (!apiHost) return;
13  apiHost = apiHost.replace(/\/$/, '');
14
15  var ANON_KEY = '_opinly_anon';
16  var FIRST_VISIT_KEY = '_opinly_first_visit_sent';
17  var UTM_KEY = '_opinly_utm';
18  var SESSION_KEY = '_opinly_session';
19  var SESSION_TIMEOUT_MS = 1800000;
20
21  function safeGet(getArea, key) { try { return getArea().getItem(key); } catch (e) { return null; } }
22  function safeSet(getArea, key, val) { try { getArea().setItem(key, val); } catch (e) {} }
23  function lsArea() { return window.localStorage; }
24  function ssArea() { return window.sessionStorage; }
25  function ls(key, val) { return val === undefined ? safeGet(lsArea, key) : safeSet(lsArea, key, val); }
26  function ss(key, val) { return val === undefined ? safeGet(ssArea, key) : safeSet(ssArea, key, val); }
27
28  function uuid() {
29    return (typeof crypto !== 'undefined' && crypto.randomUUID)
30      ? crypto.randomUUID()
31      : Date.now() + '-' + Math.random().toString(36).slice(2);
32  }
33
34  function getAnonId() {
35    var id = ls(ANON_KEY);
36    if (!id) { id = uuid(); ls(ANON_KEY, id); }
37    return id;
38  }
39
40  function getSessionId() {
41    var now = Date.now();
42    var s = null;
43    try { s = JSON.parse(ss(SESSION_KEY)); } catch (e) {}
44    if (!s || !s.id || (now - s.last) > SESSION_TIMEOUT_MS) {
45      s = { id: uuid(), last: now };
46    } else {
47      s.last = now;
48    }
49    ss(SESSION_KEY, JSON.stringify(s));
50    return s.id;
51  }
52
53  var CLICK_ID_PARAMS = ['gclid', 'gbraid', 'wbraid', 'fbclid', 'ttclid', 'msclkid', 'li_fat_id', 'twclid', 'epik', 'rdt_cid', 'dclid'];
54
55  function getFirstTouch() {
56    var p;
57    try { p = new URLSearchParams(window.location.search); } catch (e) { p = { get: function () { return null; } }; }
58
59    var clickIds = {};
60    for (var i = 0; i < CLICK_ID_PARAMS.length; i++) {
61      var v = p.get(CLICK_ID_PARAMS[i]);
62      if (v) clickIds[CLICK_ID_PARAMS[i]] = v;
63    }
64
65    var UTM_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'utm_id'];
66    var hasFreshCampaign = Object.keys(clickIds).length > 0;
67    for (var j = 0; j < UTM_PARAMS.length; j++) {
68      if (p.get(UTM_PARAMS[j])) { hasFreshCampaign = true; break; }
69    }
70
71    if (!hasFreshCampaign) {
72      var stored = ls(UTM_KEY);
73      if (stored) {
74        try {
75          var parsed = JSON.parse(stored);
76          if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) return parsed;
77        } catch (e) {}
78      }
79    }
80
81    var touch = {
82      utm_source: p.get('utm_source') || undefined,
83      utm_medium: p.get('utm_medium') || undefined,
84      utm_campaign: p.get('utm_campaign') || undefined,
85      utm_term: p.get('utm_term') || undefined,
86      utm_content: p.get('utm_content') || undefined,
87      utm_id: p.get('utm_id') || undefined,
88      referrer: document.referrer || undefined,
89      click_ids: Object.keys(clickIds).length ? clickIds : undefined
90    };
91
92    if (touch.utm_source || touch.click_ids || touch.referrer) {
93      ls(UTM_KEY, JSON.stringify(touch));
94    }
95    return touch;
96  }
97
98  function primaryClickId(touch) {
99    if (!touch.click_ids) return undefined;
100    for (var i = 0; i < CLICK_ID_PARAMS.length; i++) {
101      if (touch.click_ids[CLICK_ID_PARAMS[i]]) return touch.click_ids[CLICK_ID_PARAMS[i]];
102    }
103    return undefined;
104  }
105
106  var anonId = getAnonId();
107
108  function safePageUrl() {
109    return window.location.origin + window.location.pathname;
110  }
111
112  function deviceContext() {
113    var tz;
114    try { tz = Intl.DateTimeFormat().resolvedOptions().timeZone; } catch (e) {}
115    return {
116      page_path: window.location.pathname,
117      page_title: document.title || undefined,
118      page_hostname: window.location.hostname,
119      screen: window.screen ? (window.screen.width + 'x' + window.screen.height) : undefined,
120      viewport: window.innerWidth + 'x' + window.innerHeight,
121      language: navigator.language || undefined,
122      timezone: tz
123    };
124  }
125
126  function send(payload) {
127    try {
128      fetch(apiHost + '/track', {
129        method: 'POST',
130        headers: { 'content-type': 'application/json', 'x-api-key': writeKey },
131        body: JSON.stringify(Object.assign({ anon_id: anonId }, payload)),
132        keepalive: true
133      }).catch(function () {});
134    } catch (e) {}
135  }
136
137  function emit(eventName, props, extra) {
138    var touch = getFirstTouch();
139    var payload = {
140      event_name: eventName,
141      page_url: safePageUrl(),
142      utm_source: touch.utm_source,
143      utm_medium: touch.utm_medium,
144      utm_campaign: touch.utm_campaign,
145      referrer: touch.referrer,
146      click_id: primaryClickId(touch),
147      properties: Object.assign({ session_id: getSessionId() }, deviceContext(), props || {})
148    };
149    if (extra) Object.assign(payload, extra);
150    send(payload);
151  }
152
153  var lastPath;
154  var currentPageUrl;
155  var pageviewId;
156  var engagedMs = 0;
157  var sentEngagedMs = 0;
158  var engagedStart = 0;
159  var engagementBound = false;
160
161  var currentDocumentHeight = 0;
162  var maxScrollDepthPx = 0;
163  var sentScrollDepthPct = -1;
164
165  function getDocumentHeight() {
166    var body = document.body || {};
167    var el = document.documentElement || {};
168    return Math.max(
169      body.scrollHeight || 0, body.offsetHeight || 0, body.clientHeight || 0,
170      el.scrollHeight || 0, el.offsetHeight || 0, el.clientHeight || 0
171    );
172  }
173
174  function getScrollDepthPx() {
175    var viewportH = window.innerHeight || 0;
176    var scrollTop = window.scrollY || window.pageYOffset || 0;
177    return currentDocumentHeight <= viewportH ? currentDocumentHeight : scrollTop + viewportH;
178  }
179
180  function getScrollDepthPct() {
181    if (!currentDocumentHeight) return 0;
182    return Math.min(100, Math.round((maxScrollDepthPx / currentDocumentHeight) * 100));
183  }
184
185  function initScrollTracking() {
186    currentDocumentHeight = getDocumentHeight();
187    maxScrollDepthPx = getScrollDepthPx();
188    document.addEventListener('scroll', function () {
189      var d = getScrollDepthPx();
190      if (d > maxScrollDepthPx) maxScrollDepthPx = d;
191    });
192    if (window.ResizeObserver) {
193      new ResizeObserver(function () { currentDocumentHeight = getDocumentHeight(); }).observe(document.documentElement);
194    } else {
195      window.addEventListener('resize', function () { currentDocumentHeight = getDocumentHeight(); });
196    }
197  }
198
199  function isEngaged() {
200    return document.visibilityState === 'visible' && (document.hasFocus ? document.hasFocus() : true);
201  }
202
203  function accrueEngagement() {
204    if (engagedStart) {
205      engagedMs += Date.now() - engagedStart;
206      engagedStart = 0;
207    }
208  }
209
210  function flushEngagement() {
211    accrueEngagement();
212    var delta = engagedMs - sentEngagedMs;
213    var sdPct = getScrollDepthPct();
214
215    if ((delta < 3000 && sdPct <= sentScrollDepthPct) || !currentPageUrl) return;
216    sentEngagedMs = engagedMs;
217    sentScrollDepthPct = sdPct;
218    var touch = getFirstTouch();
219    send({
220      event_name: 'page_leave',
221      page_url: currentPageUrl,
222      utm_source: touch.utm_source,
223      utm_medium: touch.utm_medium,
224      utm_campaign: touch.utm_campaign,
225      referrer: touch.referrer,
226      click_id: primaryClickId(touch),
227      properties: { session_id: getSessionId(), pageview_id: pageviewId, duration_ms: delta, scroll_depth: sdPct }
228    });
229  }
230
231  function onEngagementChange() {
232    if (isEngaged()) {
233      if (!engagedStart) engagedStart = Date.now();
234    } else {
235      flushEngagement();
236    }
237  }
238
239  function bindEngagement() {
240    if (engagementBound) return;
241    engagementBound = true;
242    document.addEventListener('visibilitychange', onEngagementChange, true);
243    window.addEventListener('blur', onEngagementChange, true);
244    window.addEventListener('focus', onEngagementChange, true);
245    window.addEventListener('pagehide', flushEngagement, true);
246  }
247
248  function pageView(isSpa, attribution) {
249    if (isSpa && lastPath === window.location.pathname) return;
250    if (pageviewId) flushEngagement();
251    lastPath = window.location.pathname;
252    currentPageUrl = safePageUrl();
253    pageviewId = uuid();
254    engagedMs = 0;
255    sentEngagedMs = 0;
256    engagedStart = Date.now();
257    currentDocumentHeight = getDocumentHeight();
258    maxScrollDepthPx = getScrollDepthPx();
259    sentScrollDepthPct = -1;
260    var props = { pageview_id: pageviewId, referrer: document.referrer || undefined };
261    if (attribution) props.first_touch = attribution;
262    emit('page_view', props);
263    bindEngagement();
264  }
265
266  var CLICKABLE = 'a, button, input[type=submit], input[type=button], [role=button]';
267
268  function elementText(el) {
269    var t = (el.innerText || el.textContent || '').trim().replace(/\s+/g, ' ');
270    return t ? t.slice(0, 255) : undefined;
271  }
272
273  function serializeElement(el) {
274    var tag = el.tagName.toLowerCase();
275    var info = { tag: tag };
276    var text = elementText(el);
277    if (text) info.text = text;
278    if (el.id) info.id = el.id;
279    if (typeof el.className === 'string' && el.className.trim()) {
280      info.classes = el.className.trim().split(/\s+/).slice(0, 10);
281    }
282    if (el.name) info.name = el.name;
283    var type = el.getAttribute && el.getAttribute('type');
284    if (type) info.type = type;
285    if (tag === 'a') {
286      var href = el.getAttribute('href');
287      if (href) {
288        try {
289          var u = new URL(href, window.location.href);
290          info.href = u.origin + u.pathname;
291          info.external = !!u.host && u.host !== window.location.host;
292        } catch (e) {}
293      }
294    }
295    return info;
296  }
297
298  function onClick(e) {
299    try {
300      var el = e.target && e.target.closest ? e.target.closest(CLICKABLE) : null;
301      if (!el) return;
302      if (el.closest('[data-opinly-no-capture]')) return;
303      emit('click', { element: serializeElement(el) });
304    } catch (err) {}
305  }
306
307  var MAX_FIELDS = 50;
308
309  function serializeFormMeta(form) {
310    var info = { method: (form.method || 'get').toLowerCase() };
311    if (form.id) info.id = form.id;
312    var name = form.getAttribute && form.getAttribute('name');
313    if (name) info.name = name;
314    var action = form.getAttribute && form.getAttribute('action');
315    if (action) {
316      try {
317        var u = new URL(action, window.location.href);
318        info.action = u.origin + u.pathname;
319      } catch (e) {}
320    }
321    return info;
322  }
323
324  var SENSITIVE_KEY_RE = /pass|token|secret|csrf|nonce|cvv|cvc|ssn|card.?num|credit.?card/i;
325
326  var IDENTIFIED_KEY = 'opinly_identified_email';
327  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
328  var EMAIL_HINT_RE = /e-?mail/i;
329  var NOT_SELF_RE = /friend|recipient|refer|gift|share|colleague/i;
330
331  function fieldText(el) {
332    var label = '';
333    try {
334      if (el.id) {
335        var sel = window.CSS && CSS.escape ? CSS.escape(el.id) : el.id;
336        var l = document.querySelector('label[for="' + sel + '"]');
337        if (l) label = l.textContent || '';
338      }
339    } catch (e) {}
340    return [el.name, el.id, el.getAttribute('placeholder'), el.getAttribute('aria-label'), el.getAttribute('autocomplete'), label].join(' ');
341  }
342
343  function isEmailField(el) {
344    if (!el || el.tagName !== 'INPUT') return false;
345    var text = fieldText(el);
346    if (NOT_SELF_RE.test(text)) return false;
347    if ((el.type || '').toLowerCase() === 'email') return true;
348    if ((el.getAttribute('autocomplete') || '').toLowerCase().indexOf('email') !== -1) return true;
349    return EMAIL_HINT_RE.test(text);
350  }
351
352  function isVisibleInput(el) {
353    if (el.disabled || el.readOnly) return false;
354    if ((el.type || '').toLowerCase() === 'hidden') return false;
355    return !!(el.offsetParent !== null || el.offsetWidth || el.offsetHeight || el.getClientRects().length);
356  }
357
358  function sameSiteEmail(email) {
359    var at = email.lastIndexOf('@');
360    if (at < 0) return false;
361    var dom = email.slice(at + 1).toLowerCase().replace(/^www\./, '');
362    var host = (location.hostname || '').toLowerCase().replace(/^www\./, '');
363    if (!dom || !host) return false;
364    if (dom === host) return true;
365    if (host.length > dom.length && host.slice(-(dom.length + 1)) === '.' + dom) return true;
366    if (dom.length > host.length && dom.slice(-(host.length + 1)) === '.' + host) return true;
367    return false;
368  }
369
370  function tryIdentify(el, viaSubmit) {
371    try {
372      if (!isEmailField(el) || !isVisibleInput(el)) return;
373      if (el.closest && el.closest('[data-opinly-no-capture]')) return;
374      if (!viaSubmit && !el._opinlyDirty) return;
375      var email = String(el.value || '').trim();
376      if (!EMAIL_RE.test(email)) return;
377      if (sameSiteEmail(email)) return;
378      var key = email.toLowerCase();
379      if (ls(IDENTIFIED_KEY) === key) return;
380      ls(IDENTIFIED_KEY, key);
381      send({ event_name: 'identify', email: email });
382    } catch (e) {}
383  }
384
385  function identifyFromForm(form) {
386    try {
387      var els = form.elements;
388      if (!els) return;
389      for (var i = 0; i < els.length; i++) {
390        if (isEmailField(els[i]) && isVisibleInput(els[i]) && els[i].value) {
391          tryIdentify(els[i], true);
392          break;
393        }
394      }
395    } catch (e) {}
396  }
397
398  function serializeFieldNames(form) {
399    var names = [];
400    var els = form.elements;
401    if (!els) return names;
402    for (var i = 0; i < els.length && names.length < MAX_FIELDS; i++) {
403      var el = els[i];
404      var type = (el.type || '').toLowerCase();
405      if (type === 'password' || type === 'hidden') continue;
406      if (el.closest && el.closest('[data-opinly-no-capture]')) continue;
407      var key = el.name || el.id;
408      if (!key || SENSITIVE_KEY_RE.test(key)) continue;
409      names.push(key);
410    }
411    return names;
412  }
413
414  function onSubmit(e) {
415    try {
416      var form = e.target;
417      if (!form || form.tagName !== 'FORM') return;
418      if (form.closest && form.closest('[data-opinly-no-capture]')) return;
419      identifyFromForm(form);
420      var meta = serializeFormMeta(form);
421      var names = serializeFieldNames(form);
422      meta.field_count = names.length;
423      emit('form_submit', { form: meta, field_names: names });
424    } catch (err) {}
425  }
426
427  window.opinly = {
428    anonId: anonId,
429    track: function (event, props, opts) {
430      emit(event, props, opts && opts.externalEventId ? { external_event_id: opts.externalEventId } : undefined);
431    },
432    identify: function (identity) {
433      if (!identity || !identity.email) return;
434      send({ event_name: 'identify', email: identity.email, user_id: identity.userId });
435    },
436    page: function () { pageView(false); }
437  };
438
439  try { window.dispatchEvent(new Event('opinly:ready')); } catch (e) {}
440
441  var firstTouch = getFirstTouch();
442  var isFirstVisit = !ls(FIRST_VISIT_KEY);
443
444  if (isFirstVisit) {
445    send({
446      page_url: safePageUrl(),
447      utm_source: firstTouch.utm_source,
448      utm_medium: firstTouch.utm_medium,
449      utm_campaign: firstTouch.utm_campaign,
450      utm_term: firstTouch.utm_term,
451      utm_content: firstTouch.utm_content,
452      utm_id: firstTouch.utm_id,
453      referrer: firstTouch.referrer,
454      click_id: primaryClickId(firstTouch),
455      click_ids: firstTouch.click_ids
456    });
457    ls(FIRST_VISIT_KEY, '1');
458  }
459
460  initScrollTracking();
461  pageView(false, isFirstVisit ? firstTouch : null);
462
463  function hookHistory(method) {
464    var orig = window.history[method];
465    if (typeof orig !== 'function') return;
466    window.history[method] = function () {
467      var r = orig.apply(this, arguments);
468      pageView(true);
469      return r;
470    };
471  }
472  hookHistory('pushState');
473  hookHistory('replaceState');
474  window.addEventListener('popstate', function () { pageView(true); });
475  window.addEventListener('pageshow', function (e) { if (e.persisted) pageView(false); });
476
477  document.addEventListener('click', onClick, true);
478  document.addEventListener('submit', onSubmit, true);
479
480  document.addEventListener('input', function (e) {
481    var t = e.target;
482    if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA')) t._opinlyDirty = true;
483  }, true);
484  document.addEventListener('focusout', function (e) { tryIdentify(e.target, false); }, true);
485  document.addEventListener('change', function (e) { tryIdentify(e.target, false); }, true);
486})();

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.