/* ms-analytics izleme betiği * Kullanım: * Nitelikler: * data-site site anahtarı (yoksa location.hostname) * data-endpoint toplayıcı kökü (yoksa betiğin geldiği adres) * data-hash="1" hash (#) değişimlerini de sayfa görüntüleme say * API: ms('event', 'ad', 'değer') ms('pageview') * Kendini hariç tutmak için sayfayı bir kez ?ms_ignore=1 ile aç (ms_ignore=0 geri alır). */ (function () { 'use strict'; if (typeof window === 'undefined' || !window.document) return; if (navigator.webdriver) return; var script = document.currentScript || (function () { var s = document.getElementsByTagName('script'); for (var i = s.length - 1; i >= 0; i--) if (/ms\.js(\?|$)/.test(s[i].src)) return s[i]; return null; })(); if (!script) return; var base = script.getAttribute('data-endpoint') || script.src.replace(/\/ms\.js(\?.*)?$/, ''); var endpoint = base.replace(/\/$/, '') + '/collect'; var site = script.getAttribute('data-site') || location.hostname; var trackHash = script.getAttribute('data-hash') === '1'; var HEARTBEAT = 15000; var SESSION_TIMEOUT = 30 * 60 * 1000; function store(key, val) { try { if (val === undefined) return localStorage.getItem(key); if (val === null) localStorage.removeItem(key); else localStorage.setItem(key, val); return val; } catch (e) { return null; } } // Sahibin kendini hariç tutması var m = /[?&]ms_ignore=([01])/.exec(location.search); if (m) store('_ms_ignore', m[1] === '1' ? '1' : null); if (store('_ms_ignore') === '1') return; function uuid() { if (window.crypto && crypto.randomUUID) return crypto.randomUUID(); var a = new Array(36), h = '0123456789abcdef'; for (var i = 0; i < 36; i++) a[i] = h[(Math.random() * 16) | 0]; a[8] = a[13] = a[18] = a[23] = '-'; a[14] = '4'; return a.join(''); } var visitor = store('_ms_v'); if (!visitor || !/^[A-Za-z0-9_-]{8,64}$/.test(visitor)) visitor = store('_ms_v', uuid()); var isTabletMac = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1; function send(payload) { payload.s = site; if (visitor) payload.v = visitor; payload.u = location.href; var body = JSON.stringify(payload); try { if (navigator.sendBeacon && navigator.sendBeacon(endpoint, body)) return; } catch (e) { /* beacon reddedildi, aşağıya düş */ } try { if (window.fetch) { fetch(endpoint, { method: 'POST', body: body, keepalive: true, headers: { 'Content-Type': 'text/plain' } }).catch(function () {}); } else { var x = new XMLHttpRequest(); x.open('POST', endpoint, true); x.setRequestHeader('Content-Type', 'text/plain'); x.send(body); } } catch (e) { /* sessiz */ } } // Sayfada görünür geçirilen süre (etkin süre) var visibleSince = document.visibilityState === 'visible' ? Date.now() : 0; var engaged = 0; function engagedMs() { return engaged + (visibleSince ? Date.now() - visibleSince : 0); } var lastPath = ''; var lastActivity = Date.now(); function currentPath() { return location.pathname + (trackHash ? location.hash : ''); } // force: aynı yolda da say (uzun aradan sonra dönüş, elle ms('pageview') çağrısı) function pageview(force) { var p = currentPath(); if (!force && p === lastPath) return; // SPA'da aynı yola tekrar yönlenme sayılmaz var now = Date.now(); lastPath = p; lastActivity = now; engaged = 0; visibleSince = document.visibilityState === 'visible' ? now : 0; send({ t: 'pv', r: document.referrer || '', tt: document.title || '', sw: screen && screen.width, sh: screen && screen.height, l: navigator.language || '', d: isTabletMac ? 'tablet' : '' }); } function heartbeat() { if (!lastPath) return; lastActivity = Date.now(); send({ t: 'hb', e: engagedMs() }); } // Görünürlük: gizlenince son bir kalp atışı, görünür olunca devam (uzun aradan sonra yeni sayfa görüntüleme) document.addEventListener('visibilitychange', function () { if (document.visibilityState === 'hidden') { if (visibleSince) { engaged += Date.now() - visibleSince; visibleSince = 0; } heartbeat(); } else { visibleSince = Date.now(); if (Date.now() - lastActivity > SESSION_TIMEOUT) pageview(true); else heartbeat(); } }); window.addEventListener('pagehide', function () { if (visibleSince) { engaged += Date.now() - visibleSince; visibleSince = 0; } heartbeat(); }); setInterval(function () { if (document.visibilityState === 'visible') heartbeat(); }, HEARTBEAT); // SPA yönlendirmeleri (pushState + geri/ileri; replaceState sayılmaz, çoğu site onu sorgu güncellemek için kullanır) function onNavigate() { setTimeout(function () { pageview(false); }, 0); } if (history.pushState) { var origPush = history.pushState; history.pushState = function () { var r = origPush.apply(this, arguments); onNavigate(); return r; }; } window.addEventListener('popstate', onNavigate); if (trackHash) window.addEventListener('hashchange', onNavigate); // Genel API var queue = window.ms && window.ms.q ? window.ms.q : []; window.ms = function (cmd, name, value) { if (cmd === 'event' && name) send({ t: 'ev', n: String(name), val: value === undefined ? '' : String(value) }); else if (cmd === 'pageview') pageview(true); }; for (var i = 0; i < queue.length; i++) window.ms.apply(null, queue[i]); // Ön işleme (prerender) sırasında sayma; gerçek görüntülemeyi bekle if (document.prerendering) { document.addEventListener('prerenderingchange', function () { pageview(true); }, { once: true }); } else { pageview(true); } })();