PageSourceSearch

https://www.paddletheohio.com/js/analytics.js?v=20260910-location1

js paddletheohio.com collected 2026-10-05 18:13:36 UTC 2,806 bytes, 96 lines download raw bytes

1/**
2 * Lightweight session analytics tracker for Paddle the Ohio.
3 * Usage: PTO.Analytics.track('event_type', { optional: 'data' })
4 */
5window.PTO = window.PTO || {};
6
7PTO.Analytics = (function() {
8    var sessionId = '';
9    var buffer = [];
10    var flushInterval = null;
11    var metadata = {};
12
13    function generateSessionId() {
14        var arr = new Uint8Array(16);
15        crypto.getRandomValues(arr);
16        return Array.from(arr, function(b) { return b.toString(16).padStart(2, '0'); }).join('');
17    }
18
19    function getDeviceType() {
20        var w = window.innerWidth;
21        if (w < 768) return 'mobile';
22        if (w <= 1024) return 'tablet';
23        return 'desktop';
24    }
25
26    function getUTMParams() {
27        var params = new URLSearchParams(window.location.search);
28        return {
29            utm_source: params.get('utm_source') || null,
30            utm_medium: params.get('utm_medium') || null,
31            utm_campaign: params.get('utm_campaign') || null
32        };
33    }
34
35    function buildPayload() {
36        var payload = {
37            sid: sessionId,
38            ref: document.referrer || null,
39            device: metadata.device,
40            sw: window.innerWidth,
41            ua: navigator.userAgent,
42            events: buffer.splice(0)
43        };
44        var utm = metadata.utm;
45        if (utm.utm_source) payload.utm_source = utm.utm_source;
46        if (utm.utm_medium) payload.utm_medium = utm.utm_medium;
47        if (utm.utm_campaign) payload.utm_campaign = utm.utm_campaign;
48        return payload;
49    }
50
51    function flush() {
52        if (buffer.length === 0) return;
53        var payload = buildPayload();
54        var json = JSON.stringify(payload);
55
56        if (navigator.sendBeacon) {
57            var blob = new Blob([json], { type: 'application/json' });
58            navigator.sendBeacon('api/track.php', blob);
59        } else {
60            fetch('api/track.php', {
61                method: 'POST',
62                headers: { 'Content-Type': 'application/json' },
63                body: json,
64                keepalive: true
65            }).catch(function() {});
66        }
67    }
68
69    function track(eventType, eventData) {
70        buffer.push({
71            t: eventType,
72            d: eventData || null,
73            ts: Math.floor(Date.now() / 1000)
74        });
75    }
76
77    function init() {
78        sessionId = generateSessionId();
79        metadata.device = getDeviceType();
80        metadata.utm = getUTMParams();
81
82        track('page_view');
83
84        flushInterval = setInterval(flush, 15000);
85
86        document.addEventListener('visibilitychange', function() {
87            if (document.visibilityState === 'hidden') flush();
88        });
89        window.addEventListener('pagehide', flush);
90    }
91
92    return {
93        init: init,
94        track: track
95    };
96})();

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.