-
-
Save hexalys/9ede789cc553042c4389a810e1952286 to your computer and use it in GitHub Desktop.
tag.js Snippet (Analytics Tracking Script with GA4 Enhanced Measurements w/gtag functionality)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!(function(r, f, e, o, k) { | |
if (!((typeof module === o && module[e] && f(e)) || typeof define === 'function' && define.amd && !define([], f))) { | |
(typeof e === o ? e : r)[k] = f(e)[k] | |
} | |
}(this, ((E, o, f, k) => ((D, O, G, J, S, X, M, V, C, _, x, y, z) => { | |
'use strict'; | |
const W = typeof window !== V ? window : typeof global === k ? global : self, | |
N = navigator, | |
e = { | |
0: (e, t) => { | |
let J = 0, | |
H, R; | |
const L = localStorage, | |
I = Date.now, | |
A = [ | |
[I()] | |
], | |
_ = (e = null, k, r, o = 'object', b = 'boolean', n = 'number') => { | |
const t = (a, e) => { | |
const i = a.length - 1, | |
[, t] = a[i]; | |
e ? t && a.push([I()]) : t || a[i].push(I()) | |
}; | |
return k && k != !0 && r !== !1 ? (!e && e !== 0) ? r : (k.length === 1 ? (typeof e === (k === 'o' ? o : (k === 's' ? 'string' : (k === 'n' ? n : b))) ? e : r) : ((r && !(k in e) && (o = r)) || (b = typeof e[k] === b) || (n = typeof e[k] === n) || (o = e[k])) && ((o = b | n ? e[k] * 1 : o.trim()) || o === 0) && (r || delete e[k]) && (o >= 0 ? (r === '' ? o + r : o * 1) : o)) : e !== null ? (e > 0 ? (typeof k === b ? t(A[e], k) || (r ? _(e) : k) : A[e] ? A[e].reduce(((e, [t, n = I()]) => e + (n - t)), 0) + '' : 0) : O.keys(e).map((t => (z.includes(t) || x.includes(t) || (t in X && t.replace(X[t], x[4])) || t.includes('.') || t.slice(-1) >= 0) ? [t, e[t]] : [((_(r = e[t], 'n') || r >= 0) ? 'epn.' : 'ep.') + (k ? k + t : t), r === V ? V : (k && r === '' ? '' : (r + '').trim())]))) : (A[++J] = [ | |
[I()] | |
], | |
J) | |
}, | |
i = (k, n) => { | |
const c = _(k, 'n'), | |
t = () => ~~((n || I()) / 1e3 + (c ? k : 0)); | |
return (c || (!k || _(n, 'n') >= 0)) ? t() : n.length > 16 ? n : ~~(Math.random() * 2147483648) + (k ? '.' + (n > 0 ? n : t()) : '') | |
}, | |
g = (k, n) => S[k] || L[k] || (L[k] = i(k, n)), | |
s = (k, n) => { | |
const c = S.sc || L[C.sc] || 0, | |
p = c * 1 + (!c || i(-60 * C.sl) > ((n || S).st || L[C.si])), | |
t = p > c && !k ? L[C.si] = i(0) : S.si || L[C.si] || 0; | |
return { | |
s: (p > c) * 1, | |
e: L[C.se] = p > c ? 0 : L[C.se], | |
c: L[C.sc] = p, | |
si: n = t || g(C.si, (k || 0) * 1), | |
ci: g(C.ci, (n || 0) + ''), | |
st: L[C.st] = i(0), | |
f: !c * 1 | |
} | |
}, | |
u = (k, n) => { | |
const c = 'hostname', | |
l = D.location, | |
{ | |
[c]: d, | |
href: h, | |
pathname: u, | |
origin: o, | |
protocol: p, | |
search: s, | |
searchParams: f | |
} = new URL(k ? (k[0] === '/' ? l.origin + k : k) : l.href), | |
r = s => s.replace(new RegExp(`(&|\\?)(${C.pi})=[^&]+`), ''); | |
k = o + u + s; | |
H = n && R && R !== k; | |
k = { | |
l: r(_(n, y[3]) || k), | |
h: h, | |
o: o, | |
d: d, | |
u: u, | |
p: p + '//', | |
r: n ? r(n[y[4]] || (H ? R : D.referrer)) : V, | |
t: _(n, y[5], D.title), | |
a: s, | |
f: f, | |
e: (d !== l[c]) * 1, | |
s: p[4] === 's' | |
}; | |
n && (R = k.l); | |
return k | |
}; | |
M(t, { | |
d: () => (e, t = 300, n = 0) => (...o) => (clearTimeout(n), | |
n = setTimeout(e, t, ...o)), | |
p: () => (e, t) => ((t = ~~(100 * Math.abs(e.scrollTop / (e.scrollHeight - e.clientHeight)))) >= 0) ? t : 100, | |
l: () => (e, t) => t ? L[e] = t : L[e], | |
c: () => (e, t) => ((e = (D.cookie.match('(^|;)' + e + '=([^;]*)') || 0)[2]) && t ? e.slice(t) : e) || '', | |
_: () => _, | |
i: () => i, | |
g: () => g, | |
s: () => s, | |
u: () => u | |
}) | |
}, | |
1: (e, t) => { | |
_(t, 'M', v), | |
C = t.c = { | |
tn: X, | |
ci: X + 'cid', | |
si: X + 'sid', | |
sc: X + 'sct', | |
st: X + 'set', | |
se: X + 'seg', | |
tu: 'www.google-analytics.com/g/collect', | |
sl: 30, | |
et: 10 * 1e3, | |
pi: 'email|phone|password', | |
mp: [10, 25, 50, 75], | |
sp: [10, 50, 90], | |
sq: ['q', 's'], | |
fi: '', | |
re: '', | |
}; | |
t.p = { | |
send_page_view: !0, | |
transport_url: 'tu', | |
language: 'ul', | |
page_location: 'dl', | |
page_referrer: 'dr', | |
page_title: 'dt', | |
ignore_referrer: 'ir', | |
currency: 'cu', | |
client_id: 'cid', | |
user_id: 'uid', | |
traffic_type: 'tt', | |
conversion: '_c', | |
debug_mode: '_dbg', | |
allow_google_signals: 'ngs', | |
cookie_name: '_ga', | |
}; | |
t.i = { | |
m_id: 'id', | |
m_name: 'nm', | |
t_id: 'li', | |
t_name: 'ln', | |
n_id: 'pi', | |
n_name: 'pn', | |
e_name: 'cn', | |
e_slot: 'cs', | |
ion: 'af', | |
pon: 'cp', | |
nt: 'ds', | |
ex: 'lp', | |
and: 'br', | |
ry: 'ca', | |
y2: 'c2', | |
y3: 'c3', | |
y4: 'c4', | |
y5: 'c5', | |
ant: 'va', | |
n_id: 'lo', | |
ce: 'pr', | |
ty: 'qt' | |
}; | |
X = t.k = { | |
p: '_p', | |
fv: '_fv', | |
ss: '_ss', | |
s: '_s', | |
et: '_et', | |
eu: '_eu', | |
ee: '_ee', | |
nsi: '_nsi', | |
en: 'en' | |
} | |
} | |
}, | |
t = {}, | |
v = { | |
value: !0 | |
}, | |
n = (o, s) => (t[o] ? t[o][E] : e[o](s = t[o] = { | |
[E]: {} | |
}, s[E]), | |
s[E]); | |
D = W[D]; | |
_ = O.defineProperty; | |
M = (e, t) => { | |
f = O.prototype.hasOwnProperty; | |
_(e, Symbol.toStringTag, { | |
value: 'Module' | |
}), | |
_(e, 'M', v); | |
for (k in t) | |
f.call(t, k) && !f.call(e, k) && _(e, k, { | |
O: !0, | |
get: t[k] | |
}) | |
}; | |
return (o => { | |
const c = ['js', 'set', 'config', 'event'], | |
$ = 'page_view', | |
U = {}, | |
u = n(0), | |
i = n(1), | |
_ = u._, | |
M = O.assign, | |
R = (t, e, o, d, a, l, r, n, v, p, $ = 'purchase', k = 0) => { | |
const Q = a => new URLSearchParams(a.filter((([, e]) => e === '' || e))), | |
R = 'sendBeacon', | |
m = W.screen, | |
i = _(d, 'n'), | |
b = E.length; | |
p = b ? Q(_(e)) : ''; | |
while (k < b) { | |
p += '\n' + Q(E[k++]) | |
} | |
E = []; | |
$ = (n === $ || p.includes($) || P[y[11]] === 1) * 1; | |
a = [ | |
['v', 2], | |
['tid', t], | |
[z[8], P[y[8]] || S.ci], | |
[z[9], P[y[9]] || V], | |
[z[10], P[y[10]] || V], | |
['sid', S.si], | |
['sct', S.c], | |
['seg', S.e * 1 || u.l(C.se, $ || (!S.s && (n === v || p.includes(v) || _(I) > C.et)) * 1)], | |
['uaflv', C.f], | |
['uap', C.p], | |
['uamb', C.m + ''], | |
[z[2], (P[y[2]] || N[y[2]] || '').toLowerCase()], | |
['sr', m.width + 'x' + m.height], | |
[z[3], l.l], | |
[z[4], l.r], | |
[z[5], l.t], | |
[z[6], P[y[6]]], | |
[z[7], P[y[7]]], | |
[x[8], b ? V : e.en], | |
].concat(_(o), a, [ | |
[x[0], g.hid], | |
[x[1], S.f + $], | |
[x[2], S.s + $], | |
[x[3], H + ''], | |
[x[4], b || S.s ? V : e.et], | |
[x[5], i ? ('AE' + (d > 1 ? 'E' : 'A')) : V], | |
[x[6], (X && (!i || d !== 0)) * 1], | |
[x[7], (S.s && X === !1) * 1], | |
[z[11], $], | |
[z[12], (P[y[12]] || Z) * 1], | |
[z[13], P[y[13]] === 0 ? 1 : V] | |
]); | |
r = l.p + r.replace('https://', '') + '?' + Q(a); | |
l.s && N[R] && N[R](r, p) || (o = new XMLHttpRequest(), | |
o.open('POST', r, !0), | |
o.send(p)) | |
}, | |
F = (D) => { | |
const F = [], | |
l = 'EventListener', | |
x = 'documentElement', | |
r = s => s && s.replace(/.*?\[(.*)\].*/, '$1') || V, | |
q = (k, o, v, e) => !v ? [ | |
[V, V] | |
] : _(e ? M({ | |
id: r(e.id), | |
name: r(e.name) | |
}, o) : o, k + '_', !1), | |
w = u.d(e => { | |
if (Y < 90) { | |
let n = u.p(e.target[x]), | |
a = C.sp, | |
l = a.length, | |
i = -l; | |
while (l > 0 && n > Y && i < 0 && a[--l]) { | |
i = Y < a[l] && n >= a[l] ? a[l] : -l | |
} | |
if (i > 0) { | |
T(e.type, { | |
'percent_scrolled': Y = i | |
}, Y >= 90 ? 1 : 0) | |
} | |
} | |
}), | |
d = u.d(e => (D.dispatchEvent(new Event('sessiontimeout')) && delete G[y[9]]) || (S.st = u.i(0))), | |
i = e => { | |
let t = e.type[0]; | |
(t === 'm' && (t = e.type[5] === 'o')) || _(I, t = t === 'f' || t === 'v' && D.visibilityState[0] === t); | |
(t && u.l(C.st, u.i(0))) || (S.st = u.i(0)); | |
G[y[9]] && ((t && E && clearTimeout(E)) || (E = d())) | |
}, | |
o = e => { | |
W.dispatchEvent(new CustomEvent('beforehide', { | |
detail: (e ? 'out' : 'in') + 'bound' | |
})) | |
}, | |
f = e => { | |
let t = _(e.target, 'o'), | |
f = ('form' in t && t.form) || t.elements && t; | |
if (f) { | |
const s = e.type === 'submit', | |
a = f ? f.action : V, | |
i = f ? [].indexOf.call(D.forms, f) + 1 : 0, | |
p = [].indexOf.call(f, t), | |
c = f.querySelectorAll('input[type=hidden]').length, | |
n = f.querySelectorAll('button,input[type]').length - c; | |
((s && !o(!a.includes(L.o))) || (!F[i] && (F[i] = i))) && T('form_' + (s ? 'submit' : 'start'), [].concat(q('form', { | |
destination: u.u(a).h, | |
length: n | |
}, 1, f), q('first_field', { | |
type: t.type, | |
position: p - c | |
}, t.form, t)), 2) | |
} else if (P && t.type === 'text' && t.name === 's' && t.value.length > 3) { | |
T('search', { | |
'search_term': t.value | |
}) | |
} | |
}, | |
c = e => { | |
let t = _(e.target, 'o'); | |
if (t && !t.form) { | |
const c = t.classList, | |
n = 'textContent', | |
h = t.getAttribute('href'), | |
f = h && h[0] === '#', | |
p = c.contains('call') && t[n].replace(/[^\d]/g, ''), | |
e = c.contains('email') && t[n].toLowerCase(), | |
a = p || e || (h && !f && (h[0] === 't' || h[0] === 'm')), | |
d = t.getAttribute('download'), | |
v = 'type' in t || a, | |
l = h && u.u(h), | |
k = l && l.u.slice((l.u.lastIndexOf('.') - 1 >>> 0) + 2), | |
i = k && (C.fi || 'aspcfmcgiplhtmljsphp').includes(k), | |
m = k && (C.fi && i || !i); | |
l && !f && o(l.e); | |
(v && (a || m || (l && l.e))) && T(m ? 'file_download' : a ? 'launch' : 'click', _({ | |
'method': a ? p ? 'Phone' : 'Email' : V, | |
'outbound': l ? l.e : V | |
}).concat(q('link', { | |
text: t[n], | |
url: a ? p ? 'tel:+' + p : (e ? 'mailto:' + e : h) : l.l, | |
domain: a ? V : l.d | |
}, a, t), q('file', { | |
name: d ? d.slice(0, d.lastIndexOf('.') + 1) : l ? l.u : V, | |
extension: k | |
}, m)), a ? 0 : 1, a ? 0 : V) | |
} | |
}, | |
m = e => { | |
const t = e.type, | |
m = e.target, | |
s = m.currentSrc, | |
v = m.tagName.toLowerCase(), | |
k = s.slice(s.lastIndexOf('/') + 1, -5), | |
d = m.duration, | |
c = m.currentTime, | |
a = C.mp, | |
u = t[0] === 't', | |
n = c / d * 100; | |
let l = a.length, | |
i = -l, | |
p = M[k] || 0; | |
while (l > 0 && n > p && i < 0 && a[--l]) { | |
i = p < a[l] && n >= a[l] ? a[l] : -l | |
} | |
if (i > 0 || !u) { | |
l = m.getBoundingClientRect(); | |
e = t[0] === 'p'; | |
if (!(e && p > 0)) { | |
M[k] = u ? i : (p > 0 ? 100 : 0); | |
T(v + '_' + (e ? 'start' : (u ? 'progress' : 'complete')), q(v, { | |
duration: ~~d, | |
current_time: ~~c || 0, | |
percent: P[k], | |
url: s, | |
provider: '', | |
title: m.title || V, | |
visible: (l && l.bottom >= 0 && l.top <= D[x].clientHeight) * 1 + '' | |
}, !0), 2) | |
} | |
} | |
}, | |
b = u.d((e, t) => { | |
e[t]('scroll', w), | |
e[t]('click', c), | |
e[t]('change', f), | |
e[t]('submit', f), | |
e[t]('visibilitychange', i), | |
C.m || (!e[t](p + 'over', i), | |
e[t](p + 'leave', i)), | |
W[t]('blur', i), | |
W[t]('focus', i), | |
W[t]('pagehide', (e) => { | |
T('user_engagement', {}, 0, 1) | |
}) | |
}, 0), | |
n = u.d((e, t) => { | |
P = []; | |
t = (B ? 'remove' : a) + l; | |
e.querySelectorAll('audio,video').forEach(n => { | |
n[t]('play', m), | |
n[t]('timeupdate', m), | |
n[t]('ended', m) | |
}) | |
}, B ? 0 : 600), | |
v = u.d((e, t) => { | |
Y = 0; | |
H || b(D, a + l); | |
B || n(D); | |
P || (P = t); | |
B = 0; | |
I = _(); | |
T($, {}, H ? 2 : 0); | |
n(D) | |
}, 0); | |
var k, a = 'add', | |
s = 'state', | |
p = 'mouse', | |
h = W.history, | |
e = { | |
pushState: 'onpush' + s, | |
replaceState: 'onreplace' + s | |
}, | |
P, S = [], | |
E = 0; | |
if (G[y[0]]) { | |
for (k in e) { | |
let n = k, | |
f = h[k]; | |
h[k] = (o, t, u) => { | |
h[e[k]] && h[e[k]]({ | |
[s]: o | |
}), | |
v(o, n), | |
f.apply(h, [o, t, u]) | |
} | |
} | |
} | |
W[a + l]('pageshow', v); | |
W[a + l]('pop' + s, v) | |
}, | |
T = (n, o = {}, d, a = [], q) => { | |
var j = 0, | |
k = _(d, 's', ''), | |
l, m, s = ''; | |
I || A(a); | |
const v = n === $, | |
r = !v && S.st && u.i(-60 * C.sl) > S.st && (I = _()), | |
e = I - v * 1, | |
g = k && k.codePointAt(0) > 96 ? k : 0, | |
t = k.includes('-') || k > 0 ? { | |
[k]: !0 | |
} : 0, | |
x = o[0], | |
b = a === 0 && J || (!a || !a.length), | |
D = (t, p, o, d, a, l, x) => { | |
if (X <= x) { | |
H++; | |
s = X ? S = u.s() : S; | |
for (k in t) { | |
R(k, p, o, d, a === 1 ? [] : a, l, C.tu, n, $) | |
} | |
B = I; | |
X++; | |
K = []; | |
P = [] | |
} | |
}, | |
T = u.d((...s) => { | |
D(...s) | |
}, ((v && (b > 1 && clearTimeout(J))) ? 0 : (X ? 800 : 1200))), | |
Q = (...s) => { | |
if (b && K[0]) { | |
E.push(_(p).concat(v ? [ | |
[z[3], L.h], | |
[z[4], L.r], | |
[z[5], L.t] | |
] : x ? a : _(o))); | |
b > 1 && (J = T(K)) | |
} else { | |
(a === 1 && D(...s)) || ((K = O.values({ | |
...s | |
})) && (J = T(...s))); | |
v && q && E.push(_({ | |
en: 'view_search_results', | |
'search_term': q, | |
et: p.et | |
}, d)) | |
} | |
}, | |
p = { | |
en: n, | |
et: e > 0 ? Math.round(_(e) / 50) * 50 : V | |
}; | |
a = x ? o : (!a ? [] : a); | |
X || (Z = G[y[12]] || d); | |
for (k in o = M(x ? {} : o, G)) { | |
i.p[k] && (P[k] = _(o, k)) | |
} | |
if (l = o.items) { | |
while (j < l.length) { | |
for (k in l[j]) { | |
for (m in i.i) { | |
k.endsWith(m) && (s += '~' + i.i[m] + l[j][k]) | |
} | |
} | |
o['pr' + (++j)] = s | |
} | |
delete o.items | |
} | |
if (!B ^ K[0]) { | |
L = u.u(P[z[2]], P); | |
for (k in C.sq) { | |
q = q || L.f.get(C.sq[k]) | |
} | |
} | |
if (!t && U.length > 1) { | |
s = 'groups'; | |
for (k in U) { | |
m = U[k]; | |
((!m[s] && !g || g === 'default') || m[s] && m[s] === g) && (l[k] = m) | |
} | |
} else { | |
if (t) { | |
(U[t] || (U[t] = {})); | |
for (k in o = M(o, U[t])) { | |
k in i.p && (P[k] = _(o, k)) | |
} | |
} | |
} | |
(v && P[y[0]] === 0 && b) || Q(t || U, p, o, d, a, L, X) | |
}, | |
Q = (e, n, p, d = !1) => { | |
k = e > -1 ? k : c.indexOf(e); | |
(k > 2 && !T(n, p = p || {}, _(p, 'send_to') || d)) || (k > 1 && (n in U && M(U, p = (p || {}) && M(U, G)) || (U[n] = (p)))) || (k > 0 && M(G, _(n, 'o', { | |
[n]: p | |
}))) | |
}, | |
A = (a, s) => { | |
a = a.sort((e, t) => c.indexOf(e[0]) - c.indexOf(t[0])); | |
while (++Y < a.length) { | |
Q(...a[Y]) | |
} | |
k = a[0]; | |
s = k ? k[1] : V; | |
k && k.callee.name, | |
k !== t && (W[k] = Q), | |
p = k && k[2]; | |
u.l(C.ci) || (!p || (k = _(p, 's'))) && (u.g(C.ci, u.c(k || z[14], k ? 0 : 6)) && k || (X = !1)), | |
g.vid = (S = u.s(s, {})).ci; | |
F(D) | |
}; | |
var g = 'gaGlobal', | |
t = X, | |
s, P = {}, | |
E = [], | |
K = [], | |
I = 0, | |
Z, Y = -1, | |
X = 0, | |
B = 0, | |
H = 0, | |
L = {}, | |
k = N.userAgentData || {}, | |
d = 'dataLayer', | |
b = 'brand', | |
m = 'mobile', | |
p = 'platform'; | |
x = O.values(i.k), | |
y = O.keys(i.p), | |
z = O.values(i.p), | |
C = M(C, { | |
f: k[b + 's'] ? k[b + 's'].map((o) => o[b] + ';' + o.version).join('|') : V, | |
p: k[p] || /Mac|iP/.test(N[p]) ? 'macOS' : V, | |
m: (k[m] || /Mob|Pho/.test(N.userAgent) && N.maxTouchPoints > 1) * 1 | |
}); | |
g = W[g] = W[g] || { | |
from_cookie: !1, | |
hid: u.i() | |
}; | |
W[d] && A(W[d]); | |
o.tag = (...o) => _(o[1], 's') in i.p ? Q(o[2] ? 'config' : 'set', ...o) : c.indexOf(o[0]) > -1 ? Q(...o) : T(...o) | |
})(o = {}), | |
o | |
})('document', Object, {}, 0, {}, 'tag.')), 'exports', 'object', 'tag')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment