@hifilabs/pixel 0.16.2 → 0.16.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +68 -26
- package/dist/browser.min.js +5 -5
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -8,18 +8,7 @@ var ArtistPixel = (() => {
|
|
|
8
8
|
|
|
9
9
|
// src/browser.ts
|
|
10
10
|
(function() {
|
|
11
|
-
const PIXEL_VERSION = "0.16.
|
|
12
|
-
const currentScript = document.currentScript;
|
|
13
|
-
const debug = currentScript?.dataset.debug === "true";
|
|
14
|
-
const SILENT_MODE = !debug;
|
|
15
|
-
const log = (...args) => {
|
|
16
|
-
if (debug)
|
|
17
|
-
console.log("[artistPixel]", ...args);
|
|
18
|
-
};
|
|
19
|
-
const logError = (...args) => {
|
|
20
|
-
if (!SILENT_MODE)
|
|
21
|
-
console.error("[artistPixel]", ...args);
|
|
22
|
-
};
|
|
11
|
+
const PIXEL_VERSION = "0.16.4";
|
|
23
12
|
function parseUserAgent(ua) {
|
|
24
13
|
let device_type = "desktop";
|
|
25
14
|
if (/ipad|tablet|android(?!.*mobile)/i.test(ua))
|
|
@@ -63,6 +52,7 @@ var ArtistPixel = (() => {
|
|
|
63
52
|
}
|
|
64
53
|
return cachedDeviceInfo;
|
|
65
54
|
}
|
|
55
|
+
const currentScript = document.currentScript;
|
|
66
56
|
const artistId = currentScript?.dataset.artistId;
|
|
67
57
|
const rawProjectId = currentScript?.dataset.projectId;
|
|
68
58
|
const projectId = rawProjectId ? normalizeProjectId(rawProjectId) : void 0;
|
|
@@ -75,6 +65,7 @@ var ArtistPixel = (() => {
|
|
|
75
65
|
return `custom_${id}`;
|
|
76
66
|
}
|
|
77
67
|
const useEmulator = currentScript?.dataset.emulator === "true";
|
|
68
|
+
const debug = currentScript?.dataset.debug === "true";
|
|
78
69
|
const heartbeatInterval = parseInt(currentScript?.dataset.heartbeatInterval || "120000", 10);
|
|
79
70
|
const heartbeatEnabled = currentScript?.dataset.heartbeat !== "false";
|
|
80
71
|
const explicitSource = currentScript?.dataset.source;
|
|
@@ -236,6 +227,15 @@ var ArtistPixel = (() => {
|
|
|
236
227
|
const IDLE_TIMEOUT = 2 * 60 * 1e3;
|
|
237
228
|
let lastActivityTime = Date.now();
|
|
238
229
|
let isIdle = false;
|
|
230
|
+
const SILENT_MODE = !debug;
|
|
231
|
+
const log = (...args) => {
|
|
232
|
+
if (debug)
|
|
233
|
+
console.log("[artistPixel]", ...args);
|
|
234
|
+
};
|
|
235
|
+
const logError = (...args) => {
|
|
236
|
+
if (!SILENT_MODE)
|
|
237
|
+
console.error("[artistPixel]", ...args);
|
|
238
|
+
};
|
|
239
239
|
const CONSENT_STYLES = {
|
|
240
240
|
base: `
|
|
241
241
|
:host {
|
|
@@ -912,14 +912,20 @@ var ArtistPixel = (() => {
|
|
|
912
912
|
}
|
|
913
913
|
function loadFanId() {
|
|
914
914
|
try {
|
|
915
|
+
if (consent?.analytics !== true) {
|
|
916
|
+
log("Skipping fan ID load - no analytics consent");
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
915
919
|
fanIdHash = localStorage.getItem(STORAGE_PREFIX + FAN_ID_KEY);
|
|
916
920
|
if (fanIdHash) {
|
|
917
921
|
log("Loaded fan ID hash:", fanIdHash.substring(0, 16) + "...");
|
|
918
922
|
}
|
|
919
923
|
} catch (e) {
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
924
|
+
if (consent?.analytics === true) {
|
|
925
|
+
try {
|
|
926
|
+
fanIdHash = storageGet(FAN_ID_KEY);
|
|
927
|
+
} catch {
|
|
928
|
+
}
|
|
923
929
|
}
|
|
924
930
|
}
|
|
925
931
|
}
|
|
@@ -993,6 +999,26 @@ var ArtistPixel = (() => {
|
|
|
993
999
|
if (!visitorId) {
|
|
994
1000
|
visitorId = getOrCreateVisitorId();
|
|
995
1001
|
}
|
|
1002
|
+
if (fanIdHash) {
|
|
1003
|
+
try {
|
|
1004
|
+
localStorage.setItem(STORAGE_PREFIX + FAN_ID_KEY, fanIdHash);
|
|
1005
|
+
log("Fan ID hash persisted after consent granted");
|
|
1006
|
+
} catch {
|
|
1007
|
+
storageSet(FAN_ID_KEY, fanIdHash);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
if (preferences.analytics !== true) {
|
|
1012
|
+
try {
|
|
1013
|
+
localStorage.removeItem(STORAGE_PREFIX + FAN_ID_KEY);
|
|
1014
|
+
} catch {
|
|
1015
|
+
}
|
|
1016
|
+
try {
|
|
1017
|
+
sessionStorage.removeItem(STORAGE_PREFIX + FAN_ID_KEY);
|
|
1018
|
+
} catch {
|
|
1019
|
+
}
|
|
1020
|
+
fanIdHash = null;
|
|
1021
|
+
log("Fan ID hash cleared from storage and memory (consent revoked)");
|
|
996
1022
|
}
|
|
997
1023
|
const event = buildEvent({
|
|
998
1024
|
event_name: "consent_updated",
|
|
@@ -1262,18 +1288,20 @@ var ArtistPixel = (() => {
|
|
|
1262
1288
|
}
|
|
1263
1289
|
async function identify(email, traits = {}) {
|
|
1264
1290
|
try {
|
|
1265
|
-
if (consent
|
|
1266
|
-
log("
|
|
1291
|
+
if (consent?.analytics !== true) {
|
|
1292
|
+
log("identify() skipped - no analytics consent");
|
|
1267
1293
|
return;
|
|
1268
1294
|
}
|
|
1269
1295
|
fanIdHash = await hashEmail(email);
|
|
1270
1296
|
if (consent?.analytics === true) {
|
|
1271
1297
|
upgradeStorageTier();
|
|
1272
1298
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1299
|
+
if (consent?.analytics === true) {
|
|
1300
|
+
try {
|
|
1301
|
+
localStorage.setItem(STORAGE_PREFIX + FAN_ID_KEY, fanIdHash);
|
|
1302
|
+
} catch {
|
|
1303
|
+
storageSet(FAN_ID_KEY, fanIdHash);
|
|
1304
|
+
}
|
|
1277
1305
|
}
|
|
1278
1306
|
const emailParts = email.split("@");
|
|
1279
1307
|
const maskedEmail = emailParts[0].charAt(0) + "***@" + (emailParts[1] || "");
|
|
@@ -1308,11 +1336,15 @@ var ArtistPixel = (() => {
|
|
|
1308
1336
|
return;
|
|
1309
1337
|
}
|
|
1310
1338
|
fanIdHash = hash;
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1339
|
+
if (consent?.analytics === true) {
|
|
1340
|
+
try {
|
|
1341
|
+
localStorage.setItem(STORAGE_PREFIX + FAN_ID_KEY, hash);
|
|
1342
|
+
log("Fan ID hash persisted:", hash.substring(0, 16) + "...");
|
|
1343
|
+
} catch {
|
|
1344
|
+
storageSet(FAN_ID_KEY, hash);
|
|
1345
|
+
}
|
|
1346
|
+
} else {
|
|
1347
|
+
log("Fan ID hash set (memory only - no consent):", hash.substring(0, 16) + "...");
|
|
1316
1348
|
}
|
|
1317
1349
|
}
|
|
1318
1350
|
function purchase(revenue, currency = "USD", properties = {}) {
|
|
@@ -1331,6 +1363,16 @@ var ArtistPixel = (() => {
|
|
|
1331
1363
|
trackingSource = detectTrackingSource();
|
|
1332
1364
|
log("Tracking source detected:", trackingSource);
|
|
1333
1365
|
loadConsent();
|
|
1366
|
+
if (consent?.analytics !== true) {
|
|
1367
|
+
try {
|
|
1368
|
+
localStorage.removeItem(STORAGE_PREFIX + FAN_ID_KEY);
|
|
1369
|
+
} catch {
|
|
1370
|
+
}
|
|
1371
|
+
try {
|
|
1372
|
+
sessionStorage.removeItem(STORAGE_PREFIX + FAN_ID_KEY);
|
|
1373
|
+
} catch {
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1334
1376
|
if (consent?.analytics === true) {
|
|
1335
1377
|
currentStorageTier = "local";
|
|
1336
1378
|
log("Storage tier: local (analytics consent granted)");
|
package/dist/browser.min.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var ArtistPixel=(()=>{var Ue=Object.defineProperty;var
|
|
1
|
+
var ArtistPixel=(()=>{var Ue=Object.defineProperty;var Fe=(_,k,v)=>k in _?Ue(_,k,{enumerable:!0,configurable:!0,writable:!0,value:v}):_[k]=v;var K=(_,k,v)=>(Fe(_,typeof k!="symbol"?k+"":k,v),v);(function(){let _="0.16.4";function k(t){let e="desktop";/ipad|tablet|android(?!.*mobile)/i.test(t)?e="tablet":/mobile|iphone|android.*mobile|blackberry|iemobile/i.test(t)&&(e="mobile");let n="Unknown";/edg/i.test(t)?n="Edge":/opr|opera/i.test(t)?n="Opera":/firefox/i.test(t)?n="Firefox":/chrome/i.test(t)?n="Chrome":/safari/i.test(t)&&(n="Safari");let o="Unknown";return/iphone|ipad/i.test(t)?o="iOS":/android/i.test(t)?o="Android":/windows/i.test(t)?o="Windows":/mac os/i.test(t)?o="macOS":/linux/i.test(t)?o="Linux":/cros/i.test(t)&&(o="ChromeOS"),{device_type:e,browser:n,os:o}}let v=null;function Kt(){if(!v)try{v=k(navigator.userAgent)}catch{v={device_type:"desktop",browser:"Unknown",os:"Unknown"}}return v}let r=document.currentScript,Y=r?.dataset.artistId,J=r?.dataset.projectId,X=J?Yt(J):void 0;function Yt(t){return!t||t.startsWith("release_")||t.startsWith("merch_")||t.startsWith("link_")||t.startsWith("custom_")?t:`custom_${t}`}let Q=r?.dataset.emulator==="true",ht=r?.dataset.debug==="true",Z=parseInt(r?.dataset.heartbeatInterval||"120000",10),bt=r?.dataset.heartbeat!=="false",vt=r?.dataset.source,_t=r?.dataset.endpoint,f=window.__artistPixelConfig||{},O=r?.dataset.metaPixelId||f.metaPixelId,L=r?.dataset.tiktokPixelId||f.tiktokPixelId,p=r?.dataset.googleAdsId||f.googleAdsId,kt=r?.dataset.googleAdsConversionLabel||f.googleAdsConversionLabel,j=r?.dataset.googleTagManagerId||f.googleTagManagerId,y=r?.dataset.googleAnalyticsId||f.googleAnalyticsId,m={pageview:(r?.dataset.forwardPageview??f.forwardPageview)!=="false",purchase:(r?.dataset.forwardPurchase??f.forwardPurchase)!=="false",addToCart:(r?.dataset.forwardAddToCart??f.forwardAddToCart)!=="false",lead:(r?.dataset.forwardLead??f.forwardLead)!=="false",viewContent:(r?.dataset.forwardViewContent??f.forwardViewContent)!=="false",initiateCheckout:(r?.dataset.forwardInitiateCheckout??f.forwardInitiateCheckout)!=="false",completeRegistration:(r?.dataset.forwardCompleteRegistration??f.forwardCompleteRegistration)!=="false",subscribe:(r?.dataset.forwardSubscribe??f.forwardSubscribe)!=="false",search:(r?.dataset.forwardSearch??f.forwardSearch)!=="false",contact:(r?.dataset.forwardContact??f.forwardContact)!=="false",custom:(r?.dataset.forwardCustom||f.forwardCustom||"").split(",").filter(Boolean)},U=!!(O||L||p||j||y),tt=r?.dataset.consentUi==="true",Jt=r?.dataset.consentStyle||"brutalist",Xt=r?.dataset.primaryColor,Qt=r?.dataset.bannerPosition||"bottom",It=r?.dataset.excludePages?.split(",").filter(Boolean)||[],xt=r?.dataset.trackFileDownloads==="true",Zt=r?.dataset.hashRouting==="true";function te(){if(vt)return vt;let t=typeof window.dataLayer<"u"&&Array.isArray(window.dataLayer),e=typeof window.gtag=="function";return t&&e?"gtm":"pixel"}let V="pixel";if(!Y){S(" Error: data-artist-id attribute is required");return}let Ct="session_id",et="session_timestamp",St="attribution",h="fan_id_hash",nt="visitor_id",G="artistPixel_consent",ee=365*24*60*60*1e3,ne=30*24*60*60*1e3,ae=60*60*1e3,w="balance_";function oe(t){let e=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp("^"+e+"$")}function ie(t){if(It.length===0)return!1;try{let e=new URL(t,window.location.origin).pathname;return It.some(n=>oe(n).test(e))}catch{return!1}}let re=[".pdf",".zip",".tar",".gz",".rar",".7z",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".mp3",".wav",".flac",".aac",".ogg",".mp4",".mov",".avi",".mkv",".webm",".exe",".dmg",".pkg",".deb",".rpm",".csv",".json",".xml",".txt"];function Pt(t){try{let e=new URL(t,window.location.origin).pathname.toLowerCase();return re.some(n=>e.endsWith(n))}catch{return!1}}function se(t,e){try{let o=new URL(t,window.location.origin).pathname.split("/").pop()||"unknown",d=o.includes(".")?o.split(".").pop():"unknown";a("File download tracked:",{url:t,fileName:o,fileExtension:d});let l=P({event_name:"custom",metadata:{event_type:"file_download",file_url:t,file_name:o,file_extension:d,link_text:e?.textContent?.trim().substring(0,100)||""}});E(l)}catch(n){S("Failed to track file download:",n)}}let ce="https://e.os.xyz",Et="https://us-central1-artist-os-distro.cloudfunctions.net/ingestEvents",A=_t||(Q?"http://localhost:5001/artist-os-distro/us-central1/ingestEvents":ce),F=null,b=null,g=null,c=null,R={},at={},I=[],ot=null,x="session",D=null,it=0,rt=0,M=0,q=!0,st=0,ct=!1,de=2*60*1e3,Tt=Date.now(),z=!1,le=!ht,a=(...t)=>{ht&&console.log("[artistPixel]",...t)},S=(...t)=>{le||console.error("[artistPixel]",...t)},dt={base:`
|
|
2
2
|
:host {
|
|
3
3
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
4
4
|
position: fixed;
|
|
@@ -83,12 +83,12 @@ var ArtistPixel=(()=>{var Ue=Object.defineProperty;var qe=(y,i,x)=>i in y?Ue(y,i
|
|
|
83
83
|
}
|
|
84
84
|
.btn.accept { background: #fff; color: #000; border-color: #fff; }
|
|
85
85
|
.btn:hover { opacity: 0.8; }
|
|
86
|
-
`};class ge{constructor(e){K(this,"container",null);K(this,"shadow",null);K(this,"config");if(this.config=e,this.hasStoredConsent()){a("ConsentManager: Consent already exists, not showing banner");return}this.container=document.createElement("div"),this.container.id="artistPixel-consent-manager",this.shadow=this.container.attachShadow({mode:"closed"}),this.render(),document.body.appendChild(this.container),a("ConsentManager: Banner rendered")}hasStoredConsent(){try{return window._balanceConsentNeedsRefresh?!1:localStorage.getItem(G)!==null}catch{return!1}}render(){if(!this.shadow)return;let e=this.config.style||"brutalist",n=dt.base,o=dt[e]||dt.brutalist,
|
|
86
|
+
`};class ge{constructor(e){K(this,"container",null);K(this,"shadow",null);K(this,"config");if(this.config=e,this.hasStoredConsent()){a("ConsentManager: Consent already exists, not showing banner");return}this.container=document.createElement("div"),this.container.id="artistPixel-consent-manager",this.shadow=this.container.attachShadow({mode:"closed"}),this.render(),document.body.appendChild(this.container),a("ConsentManager: Banner rendered")}hasStoredConsent(){try{return window._balanceConsentNeedsRefresh?!1:localStorage.getItem(G)!==null}catch{return!1}}render(){if(!this.shadow)return;let e=this.config.style||"brutalist",n=dt.base,o=dt[e]||dt.brutalist,d=this.config.position==="top"?"top: 0;":"bottom: 0;",l=this.config.primaryColor?`.btn.accept { background: ${this.config.primaryColor} !important; border-color: ${this.config.primaryColor} !important; color: #fff !important; }`:"";this.shadow.innerHTML=`
|
|
87
87
|
<style>
|
|
88
88
|
${n}
|
|
89
|
-
:host { ${
|
|
89
|
+
:host { ${d} }
|
|
90
90
|
${o}
|
|
91
|
-
${
|
|
91
|
+
${l}
|
|
92
92
|
</style>
|
|
93
93
|
<div class="banner" role="dialog" aria-label="Cookie consent" aria-modal="false">
|
|
94
94
|
<p class="text">
|
|
@@ -99,4 +99,4 @@ var ArtistPixel=(()=>{var Ue=Object.defineProperty;var qe=(y,i,x)=>i in y?Ue(y,i
|
|
|
99
99
|
<button id="accept" class="btn accept">Accept</button>
|
|
100
100
|
</div>
|
|
101
101
|
</div>
|
|
102
|
-
`,this.shadow.getElementById("accept")?.addEventListener("click",()=>this.handleConsent(!0)),this.shadow.getElementById("decline")?.addEventListener("click",()=>this.handleConsent(!1))}handleConsent(e){window.balance?.setConsent&&window.balance.setConsent({analytics:e,marketing:e,personalization:e,timestamp:new Date().toISOString()}),e&&!window._balanceInitialPageviewFired&&(window._balanceInitialPageviewFired=!0,window.balance?.page&&window.balance.page(),ft(),a("Initial pageview fired after consent granted")),this.remove()}remove(){this.container&&(this.container.remove(),this.container=null,this.shadow=null,a("ConsentManager: Banner removed"))}}let Tt=!1,z=!1;function ue(){if(!M)return;if(window.fbq){a("[Platform:Meta] Already loaded, skipping");return}a("[Platform:Meta] Injecting pixel:",M);let t=function(...n){t.callMethod?t.callMethod.apply(t,n):t.queue.push(n)};window._fbq||(window._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[],window.fbq=t;let e=document.createElement("script");e.async=!0,e.src="https://connect.facebook.net/en_US/fbevents.js",e.onload=()=>{window.fbq("init",M),f.pageview&&window.fbq("track","PageView"),a("[Platform:Meta] Initialized and PageView tracked")},document.head.appendChild(e)}function fe(){if(!P)return;if(window.ttq?._i?.[P]){a("[Platform:TikTok] Already loaded, skipping");return}a("[Platform:TikTok] Injecting pixel:",P);let t=window,e="ttq";t.TiktokAnalyticsObject=e;let n=t[e]=t[e]||[];n.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],n.setAndDefer=function(o,c){o[c]=function(...d){o.push([c].concat(d))}};for(let o=0;o<n.methods.length;o++)n.setAndDefer(n,n.methods[o]);n.instance=function(o){let c=n._i[o]||[];for(let d=0;d<n.methods.length;d++)n.setAndDefer(c,n.methods[d]);return c},n.load=function(o){let c="https://analytics.tiktok.com/i18n/pixel/events.js";n._i=n._i||{},n._i[o]=[],n._i[o]._u=c,n._t=n._t||{},n._t[o]=+new Date,n._o=n._o||{};let d=document.createElement("script");d.type="text/javascript",d.async=!0,d.src=c+"?sdkid="+o+"&lib="+e,document.head.appendChild(d)},n.load(P),f.pageview&&n.page(),a("[Platform:TikTok] Initialized and page() tracked")}function me(){if(!w)return;if(window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...e){window.dataLayer.push(e)}),document.querySelector('script[src*="googletagmanager.com/gtag/js"]')){a("[Platform:GoogleAds] gtag.js already loaded, configuring"),window.gtag("config",w);return}a("[Platform:GoogleAds] Injecting gtag:",w),window.gtag("consent","default",{ad_storage:"granted",ad_user_data:"granted",ad_personalization:"granted",analytics_storage:"granted"});let t=document.createElement("script");t.async=!0,t.src=`https://www.googletagmanager.com/gtag/js?id=${w}`,t.onload=()=>{window.gtag("js",new Date),window.gtag("config",w),a("[Platform:GoogleAds] Initialized")},document.head.appendChild(t)}function we(){if(!O)return;if(document.querySelector(`script[src*="googletagmanager.com/gtm.js?id=${O}"]`)){a("[Platform:GTM] Already loaded, skipping");return}a("[Platform:GTM] Injecting GTM:",O),window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...n){window.dataLayer.push(n)});let t=z?"granted":"denied";window.gtag("consent","default",{ad_storage:t,ad_user_data:t,ad_personalization:t,analytics_storage:t}),window.gtag("set","wait_for_update",500),window.dataLayer.push({"gtm.start":new Date().getTime(),event:"gtm.js"});let e=document.createElement("script");e.async=!0,e.src=`https://www.googletagmanager.com/gtm.js?id=${O}`,e.onload=()=>{a("[Platform:GTM] Initialized")},document.head.appendChild(e)}function pe(){if(!p)return;let t=document.querySelector('script[src*="googletagmanager.com/gtag/js"]');window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...o){window.dataLayer.push(o)});let e=z?"granted":"denied";if(window.gtag("consent","default",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:e}),t){a("[Platform:GA4] gtag.js already loaded, configuring"),window.gtag("config",p,{send_page_view:!1});return}a("[Platform:GA4] Injecting gtag:",p);let n=document.createElement("script");n.async=!0,n.src=`https://www.googletagmanager.com/gtag/js?id=${p}`,n.onload=()=>{window.gtag("js",new Date),window.gtag("config",p,{send_page_view:!1}),a("[Platform:GA4] Initialized")},document.head.appendChild(n)}function he(){if(j){if(Tt){a("[Platform] Already loaded, skipping");return}if(!z){a("[Platform] Marketing consent not granted, deferring");return}a("[Platform] Injecting platform pixels (consent granted)"),Tt=!0,ue(),fe(),me(),we(),pe()}}function Lt(t){if(z=t,a("[Platform] Marketing consent:",t?"granted":"denied"),t&&he(),window.ttq&&(t?window.ttq.grantConsent?.():window.ttq.revokeConsent?.()),typeof window.gtag=="function"){let e=t?"granted":"denied";window.gtag("consent","update",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:e})}}function lt(t){if(!j||!z)return!1;let e=t.toLowerCase();return e==="pageview"||e==="page_view"?f.pageview:e==="purchase"?f.purchase:e==="addtocart"||e==="add_to_cart"?f.addToCart:e==="lead"||e==="form_submit"?f.lead:e==="viewcontent"||e==="view_content"?f.viewContent:e==="initiatecheckout"||e==="initiate_checkout"?f.initiateCheckout:e==="completeregistration"||e==="complete_registration"?f.completeRegistration:e==="subscribe"?f.subscribe:e==="search"?f.search:e==="contact"?f.contact:f.custom.length>0?f.custom.some(n=>n.toLowerCase()===e):!1}function ye(){lt("pageview")&&(a("[Platform] Forwarding PageView"),window.fbq&&window.fbq("track","PageView"),window.ttq&&window.ttq.page(),typeof window.gtag=="function"&&p&&window.gtag("event","page_view",{send_to:p}))}function be(t,e,n){if(lt("purchase")){if(a("[Platform] Forwarding Purchase:",t,e),window.fbq&&window.fbq("track","Purchase",{value:t,currency:e,content_ids:n?.contentIds,content_type:n?.contentType||"product",order_id:n?.transactionId}),window.ttq&&window.ttq.track("CompletePayment",{value:t,currency:e,order_id:n?.transactionId}),typeof window.gtag=="function"&&w){let o=_t?`${w}/${_t}`:w;window.gtag("event","conversion",{send_to:o,value:t,currency:e,transaction_id:n?.transactionId}),window.gtag("event","purchase",{send_to:w,value:t,currency:e,transaction_id:n?.transactionId})}typeof window.gtag=="function"&&p&&window.gtag("event","purchase",{send_to:p,value:t,currency:e,transaction_id:n?.transactionId,items:n?.items})}}function ve(t,e){if(!lt(t))return;let n=t.toLowerCase();a("[Platform] Forwarding custom event:",t);let o={addtocart:"AddToCart",add_to_cart:"AddToCart",lead:"Lead",form_submit:"Lead",viewcontent:"ViewContent",view_content:"ViewContent",search:"Search",subscribe:"Subscribe",contact:"Contact",completeregistration:"CompleteRegistration",complete_registration:"CompleteRegistration",initiatecheckout:"InitiateCheckout",initiate_checkout:"InitiateCheckout"},c={addtocart:"AddToCart",add_to_cart:"AddToCart",lead:"SubmitForm",form_submit:"SubmitForm",viewcontent:"ViewContent",view_content:"ViewContent",search:"Search",subscribe:"Subscribe",contact:"Contact",completeregistration:"CompleteRegistration",complete_registration:"CompleteRegistration",initiatecheckout:"InitiateCheckout",initiate_checkout:"InitiateCheckout"},d={addtocart:"add_to_cart",add_to_cart:"add_to_cart",lead:"generate_lead",form_submit:"generate_lead",viewcontent:"view_item",view_content:"view_item",search:"search",subscribe:"subscribe",contact:"contact",completeregistration:"sign_up",complete_registration:"sign_up",initiatecheckout:"begin_checkout",initiate_checkout:"begin_checkout"};if(window.fbq){let s=o[n];s?window.fbq("track",s,e):window.fbq("trackCustom",t,e)}if(window.ttq){let s=c[n]||t;window.ttq.track(s,e)}if(typeof window.gtag=="function"&&w){let s=d[n]||t;window.gtag("event",s,{send_to:w,...e})}if(typeof window.gtag=="function"&&p){let s=d[n]||t;window.gtag("event",s,{send_to:p,...e})}}function At(){try{return _==="local"?localStorage:sessionStorage}catch{return null}}function B(t){let e=At();if(!e)return null;try{let n=b+t,o=e.getItem(n);if(!o&&_==="session")try{o=localStorage.getItem(n)}catch{}return o}catch{return null}}function D(t,e){let n=At();if(n)try{n.setItem(b+t,e)}catch{}}function Rt(){if(_!=="local"){a("Upgrading storage tier: session -> local");try{let t=[];for(let e=0;e<sessionStorage.length;e++){let n=sessionStorage.key(e);n?.startsWith(b)&&t.push(n)}for(let e of t){let n=sessionStorage.getItem(e);n&&localStorage.setItem(e,n)}for(let e of t)sessionStorage.removeItem(e);_="local",a(`Storage tier upgraded, migrated ${t.length} items`)}catch(t){I(" Storage migration failed:",t)}}}function W(){return crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}function _e(){try{let t=B(It),e=B(et);if(t&&e&&Date.now()-parseInt(e,10)<oe)return D(et,Date.now().toString()),t;let n=W();return D(It,n),D(et,Date.now().toString()),n}catch{return W()}}function ke(){let t=new URLSearchParams(window.location.search),e={};return["source","medium","campaign","content","term"].forEach(n=>{let o=t.get(`utm_${n}`);o&&(e[`utm_${n}`]=o)}),e}function xe(){try{let t=B(Ct);if(t){L=JSON.parse(t),a("Loaded attribution:",L);return}let e=ke();Object.keys(e).length>0&&(L=e,D(Ct,JSON.stringify(e)),a("Captured attribution:",L))}catch{}}function Ie(){try{m=localStorage.getItem(b+E),m&&a("Loaded fan ID hash:",m.substring(0,16)+"...")}catch{try{m=B(E)}catch{}}}function gt(){try{let t=localStorage.getItem(b+nt);if(t)return t;let e=W();return localStorage.setItem(b+nt,e),a("Created persistent visitor ID:",e.substring(0,8)+"..."),e}catch{return a("localStorage unavailable, using session ID as fallback"),U||W()}}function Ce(){try{h=localStorage.getItem(b+nt),h&&a("Loaded visitor ID:",h.substring(0,8)+"...")}catch{}}function Se(){try{let t=localStorage.getItem(G);if(t){let e=JSON.parse(t);if(e.expiresAt&&Date.now()>e.expiresAt){a("Consent expired - clearing stored consent"),localStorage.removeItem(G),u=null;return}if(e.expiresAt){let n=e.expiresAt-Date.now();n>0&&n<ae&&(a("Consent nearing expiration - will prompt for refresh"),window._balanceConsentNeedsRefresh=!0)}u=e.preferences||null,a("Loaded consent:",u)}}catch{}}function Dt(t){let e=u;u=t;try{let o={preferences:t,method:"explicit",version:1,expiresAt:Date.now()+ne};localStorage.setItem(G,JSON.stringify(o)),a("Consent saved with TTL:",t),window._balanceConsentNeedsRefresh=!1}catch(o){I(" Could not save consent:",o)}t.analytics===!0&&(Rt(),h||(h=gt()));let n=C({event_name:"consent_updated",metadata:{consent_preferences:t,consent_method:"explicit",previous_consent:e||void 0}});S(n);try{window.dispatchEvent(new CustomEvent("artistPixel:consent:updated",{detail:t})),a("DOM event artistPixel:consent:updated dispatched")}catch{}j&&Lt(t.marketing===!0)}function Pe(){return u}function Ee(t){return u?.[t]===!0}function Te(t){for(let[e,n]of Object.entries(t))try{let o=Mt(e);at[o]=n}catch{at[e]=n}a("Registered",Object.keys(t).length,"links for tracking enrichment")}function Mt(t){try{let e=new URL(t);return`${e.protocol}//${e.host}${e.pathname}${e.search}`}catch{return t}}function Le(t){let e=Mt(t);return at[e]||null}async function Ae(t){let e=t.toLowerCase().trim(),o=new TextEncoder().encode(e),c=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(c)).map(s=>s.toString(16).padStart(2,"0")).join("")}function C(t){let e=Yt(),n={artist_id:Y,fan_session_id:U,visitor_id:h||gt(),fan_id_hash:m||void 0,timestamp:new Date().toISOString(),source_url:window.location.href,referrer_url:document.referrer||void 0,user_agent:navigator.userAgent,device_type:e.device_type,browser:e.browser,os:e.os,tracking_source:V,...t,...L};return X&&!t.projectId&&(n.projectId=X),n}function S(t){v.push(t),a("Event queued:",t.event_name,"(queue:",v.length,")"),v.length>=10&&N()}async function N(){if(v.length===0)return;let t=[...v];v=[],a("Flushing",t.length,"events to",T);try{let e=await fetch(T,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:t}),keepalive:!0});if(!e.ok)throw new Error(`HTTP ${e.status}`);a("Events sent successfully")}catch(e){if(I(" Failed to send events, trying fallback:",e),T!==Pt&&!Q)try{if((await fetch(Pt,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:t}),keepalive:!0})).ok){a("Events sent via fallback (no geo)");return}}catch(n){I(" Fallback also failed:",n)}v.length<50&&v.push(...t)}}function Re(){ot&&clearInterval(ot),ot=window.setInterval(()=>{v.length>0&&N()},5e3)}function ut(){R||(it=Date.now()),R=Date.now(),q=!0,a("Active time tracking started/resumed")}function Ot(){R&&q&&(rt+=Date.now()-R),q=!1,a("Active time tracking paused, accumulated:",rt,"ms")}function jt(){let t=rt;return q&&R&&(t+=Date.now()-R),t}function De(){Et=Date.now(),F&&(F=!1,ut(),a("User returned from idle"))}function Me(){if(document.visibilityState==="hidden"){a("Skipping heartbeat - tab hidden");return}if(Date.now()-Et>le){F||(F=!0,Ot(),a("User idle - pausing heartbeat"));return}let t=jt(),e=Math.round(t/1e3),n=C({event_name:"engagement_heartbeat",metadata:{time_on_page_seconds:e,time_on_page_ms:t,heartbeat_interval_ms:Z,is_active:q&&!F}});S(n),st++,a("Heartbeat sent:",e,"seconds active")}function ft(){if(!yt){a('Heartbeat disabled via data-heartbeat="false"');return}A&&clearInterval(A),ut(),A=window.setInterval(()=>{Me()},Z),a("Heartbeat started with interval:",Z,"ms")}function mt(){if(!ct){if(ct=!0,A&&(clearInterval(A),A=null),yt){let t=it?Date.now()-it:0,e=jt(),n=C({event_name:"engagement_summary",metadata:{total_time_ms:t,active_time_ms:e,heartbeat_samples:st,page_path:window.location.pathname}});if(navigator.sendBeacon&&T){let o=JSON.stringify({events:[n]});navigator.sendBeacon(T,o),a("Engagement summary sent via sendBeacon:",Math.round(e/1e3),"seconds active")}else S(n),a("Engagement summary enqueued:",Math.round(e/1e3),"seconds active")}st=0}}function H(t={}){let e=t.url||window.location.href;if(re(e)){a("Page excluded from tracking:",e);return}let n=C({event_name:"pageview",page_title:t.title||document.title,source_url:e});S(n),ye()}function wt(t,e={}){let n=C({event_name:"custom",metadata:{event_type:t,...e}});S(n),ve(t,e)}async function Ut(t,e={}){try{if(u&&u.analytics===!1){a("Identify skipped - user declined analytics consent");return}m=await Ae(t),u?.analytics===!0&&Rt();try{localStorage.setItem(b+E,m)}catch{D(E,m)}let n=t.split("@"),o=n[0].charAt(0)+"***@"+(n[1]||"");a("Fan identified:",{name:e.name||"(no name)",email:o,hash:m.substring(0,16)+"...",traits:e,storageTier:_});let c=C({event_name:"identify",fan_id_hash:m,metadata:{email_sha256:m,email_display:o,traits:e,consent_preferences:u||void 0,storage_tier:_}});S(c)}catch(n){I(" Failed to identify:",n)}}function Oe(t){if(!t||typeof t!="string"){I("setFanIdHash: invalid hash provided");return}m=t;try{localStorage.setItem(b+E,t),a("Fan ID hash set from server:",t.substring(0,16)+"...")}catch{D(E,t)}}function qt(t,e="USD",n={}){let o=C({event_name:"purchase",metadata:{revenue:t,currency:e,...n}});S(o),be(t,e,n)}function Ft(){V=ee(),a("Tracking source detected:",V),Se(),u?.analytics===!0?(_="local",a("Storage tier: local (analytics consent granted)")):(_="session",a("Storage tier: session (privacy by default)")),U=_e(),Ie(),Ce(),h||(h=gt()),u||a(tt?"Consent UI enabled, waiting for explicit user consent (Tier 0 mode)":"No consent - operating in privacy-first mode (session storage only, limited tracking)"),j&&u?.marketing===!0?(a("[Platform] Marketing consent already granted, initializing platform pixels"),Lt(!0)):j&&a("[Platform] Platform pixels configured:",{meta:M||"(none)",tiktok:P||"(none)",googleAds:w||"(none)"}),xe(),Re(),a("Initialized",{artistId:Y,projectId:X||"(none - will track to all projects)",rawProjectId:J||"(none)",sessionId:U,visitorId:h?h.substring(0,8)+"...":null,fanIdHash:m,consent:u,storageTier:_,trackingSource:V,useEmulator:Q,endpoint:T}),u?.analytics===!0?(window._balanceInitialPageviewFired=!0,H(),ft(),a("Full tracking enabled (user consented)")):tt?a("Tracking dormant - waiting for explicit consent via ConsentManager"):(window._balanceInitialPageviewFired=!0,H(),ft(),a("Privacy-first tracking enabled (session-scoped, visitor_id for deduplication)")),["mousemove","keydown","scroll","touchstart"].forEach(s=>{document.addEventListener(s,De,{passive:!0})});let t=window.location.hostname;function e(s){try{let r=new URL(s).hostname.toLowerCase();return r.includes("spotify")?"spotify":r.includes("apple")||r.includes("music.apple")?"apple_music":r.includes("youtube")||r.includes("youtu.be")?"youtube":r.includes("soundcloud")?"soundcloud":r.includes("tidal")?"tidal":r.includes("deezer")?"deezer":r.includes("amazon")||r.includes("music.amazon")?"amazon_music":r.includes("bandcamp")?"bandcamp":r.includes("lnk.to")||r.includes("linkfire")?"linkfire":r.includes("linktr.ee")?"linktree":r.includes("shop")||r.includes("store")||r.includes("merch")?"shop":r.includes("ticketmaster")||r.includes("eventbrite")||r.includes("dice.fm")?"tickets":r.includes("instagram")?"instagram":r.includes("twitter")||r.includes("x.com")?"twitter":r.includes("tiktok")?"tiktok":r.includes("facebook")?"facebook":"external"}catch{return"external"}}function n(s){try{return new URL(s,window.location.origin).hostname!==t}catch{return!1}}function o(s,r){let l=e(s),k=Le(s),Vt=k?.title||r?.textContent?.trim().substring(0,100)||"",Gt=k?.id||r?.id||r?.getAttribute("data-link-id")||void 0,Bt=k?.category;a("External link clicked:",{url:s,platform:l,linkText:Vt,linkId:Gt,fromRegistry:!!k}),wt("page_link_click",{link_url:s,link_text:Vt,link_id:Gt,platform:l,link_type:"external",...Bt&&{link_category:Bt},...k&&Object.fromEntries(Object.entries(k).filter(([ht])=>!["title","id","category"].includes(ht)).map(([ht,je])=>[`link_${ht}`,je]))})}let c=window.open;if(window.open=function(s,r,l){if(s){let k=s.toString();n(k)&&o(k)}return c.call(window,s,r,l)},a("window.open interception enabled (always on)"),i?.dataset.autoTrackLinks==="true"&&(document.addEventListener("click",s=>{let l=s.target.closest("a");if(l&&l.href&&n(l.href)){if(xt&&(St(l.href)||l.hasAttribute("download")))return;o(l.href,l)}},{capture:!0,passive:!0}),a("External link click listener enabled (opt-in)")),xt&&(document.addEventListener("click",s=>{let l=s.target.closest("a");l?.href&&(St(l.href)||l.hasAttribute("download"))&&ce(l.href,l)},{capture:!0,passive:!0}),a("File download tracking enabled")),te){let s=window.location.href;window.addEventListener("hashchange",()=>{let r=window.location.href;r!==s&&(s=r,setTimeout(()=>{H({title:document.title,url:r})},0))}),a("Hash routing tracking enabled")}document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?(Ot(),mt(),N()):(ut(),ct=!1)}),window.addEventListener("pagehide",()=>{mt(),N()}),window.addEventListener("beforeunload",()=>{mt(),N()})}if(window.balance?._version&&window.balance._version!==y){console.warn(`[artistPixel] Version conflict: ${window.balance._version} already loaded, skipping ${y}`);return}let pt=window.balance?.q||[];function zt(){if(pt.length>0){a("Processing",pt.length,"queued commands");for(let t of pt){let[e,...n]=t;switch(e){case"track":wt(n[0],n[1]);break;case"identify":Ut(n[0],n[1]);break;case"page":H(n[0]);break;case"purchase":qt(n[0],n[1],n[2]);break;case"setConsent":Dt(n[0]);break;default:a("Unknown queued command:",e)}}}}let Nt={track:wt,identify:Ut,page:H,purchase:qt,getSessionId:()=>U,getVisitorId:()=>h,getFanIdHash:()=>m,setFanIdHash:Oe,getAttribution:()=>L,setConsent:Dt,getConsent:Pe,hasConsent:Ee,registerLinks:Te,_version:y};window.artistPixel=Nt,window.balance=Nt;function Ht(){tt&&!u&&new ge({style:Xt,primaryColor:Qt,position:Zt})}let $t=window.requestIdleCallback||(t=>setTimeout(t,1));document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{Ft(),zt(),$t(()=>Ht())}):(Ft(),zt(),$t(()=>Ht())),a("Pixel script loaded")})();})();
|
|
102
|
+
`,this.shadow.getElementById("accept")?.addEventListener("click",()=>this.handleConsent(!0)),this.shadow.getElementById("decline")?.addEventListener("click",()=>this.handleConsent(!1))}handleConsent(e){window.balance?.setConsent&&window.balance.setConsent({analytics:e,marketing:e,personalization:e,timestamp:new Date().toISOString()}),e&&!window._balanceInitialPageviewFired&&(window._balanceInitialPageviewFired=!0,window.balance?.page&&window.balance.page(),ft(),a("Initial pageview fired after consent granted")),this.remove()}remove(){this.container&&(this.container.remove(),this.container=null,this.shadow=null,a("ConsentManager: Banner removed"))}}let Lt=!1,N=!1;function ue(){if(!O)return;if(window.fbq){a("[Platform:Meta] Already loaded, skipping");return}a("[Platform:Meta] Injecting pixel:",O);let t=function(...n){t.callMethod?t.callMethod.apply(t,n):t.queue.push(n)};window._fbq||(window._fbq=t),t.push=t,t.loaded=!0,t.version="2.0",t.queue=[],window.fbq=t;let e=document.createElement("script");e.async=!0,e.src="https://connect.facebook.net/en_US/fbevents.js",e.onload=()=>{window.fbq("init",O),m.pageview&&window.fbq("track","PageView"),a("[Platform:Meta] Initialized and PageView tracked")},document.head.appendChild(e)}function fe(){if(!L)return;if(window.ttq?._i?.[L]){a("[Platform:TikTok] Already loaded, skipping");return}a("[Platform:TikTok] Injecting pixel:",L);let t=window,e="ttq";t.TiktokAnalyticsObject=e;let n=t[e]=t[e]||[];n.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],n.setAndDefer=function(o,d){o[d]=function(...l){o.push([d].concat(l))}};for(let o=0;o<n.methods.length;o++)n.setAndDefer(n,n.methods[o]);n.instance=function(o){let d=n._i[o]||[];for(let l=0;l<n.methods.length;l++)n.setAndDefer(d,n.methods[l]);return d},n.load=function(o){let d="https://analytics.tiktok.com/i18n/pixel/events.js";n._i=n._i||{},n._i[o]=[],n._i[o]._u=d,n._t=n._t||{},n._t[o]=+new Date,n._o=n._o||{};let l=document.createElement("script");l.type="text/javascript",l.async=!0,l.src=d+"?sdkid="+o+"&lib="+e,document.head.appendChild(l)},n.load(L),m.pageview&&n.page(),a("[Platform:TikTok] Initialized and page() tracked")}function me(){if(!p)return;if(window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...e){window.dataLayer.push(e)}),document.querySelector('script[src*="googletagmanager.com/gtag/js"]')){a("[Platform:GoogleAds] gtag.js already loaded, configuring"),window.gtag("config",p);return}a("[Platform:GoogleAds] Injecting gtag:",p),window.gtag("consent","default",{ad_storage:"granted",ad_user_data:"granted",ad_personalization:"granted",analytics_storage:"granted"});let t=document.createElement("script");t.async=!0,t.src=`https://www.googletagmanager.com/gtag/js?id=${p}`,t.onload=()=>{window.gtag("js",new Date),window.gtag("config",p),a("[Platform:GoogleAds] Initialized")},document.head.appendChild(t)}function we(){if(!j)return;if(document.querySelector(`script[src*="googletagmanager.com/gtm.js?id=${j}"]`)){a("[Platform:GTM] Already loaded, skipping");return}a("[Platform:GTM] Injecting GTM:",j),window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...n){window.dataLayer.push(n)});let t=N?"granted":"denied";window.gtag("consent","default",{ad_storage:t,ad_user_data:t,ad_personalization:t,analytics_storage:t}),window.gtag("set","wait_for_update",500),window.dataLayer.push({"gtm.start":new Date().getTime(),event:"gtm.js"});let e=document.createElement("script");e.async=!0,e.src=`https://www.googletagmanager.com/gtm.js?id=${j}`,e.onload=()=>{a("[Platform:GTM] Initialized")},document.head.appendChild(e)}function pe(){if(!y)return;let t=document.querySelector('script[src*="googletagmanager.com/gtag/js"]');window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...o){window.dataLayer.push(o)});let e=N?"granted":"denied";if(window.gtag("consent","default",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:e}),t){a("[Platform:GA4] gtag.js already loaded, configuring"),window.gtag("config",y,{send_page_view:!1});return}a("[Platform:GA4] Injecting gtag:",y);let n=document.createElement("script");n.async=!0,n.src=`https://www.googletagmanager.com/gtag/js?id=${y}`,n.onload=()=>{window.gtag("js",new Date),window.gtag("config",y,{send_page_view:!1}),a("[Platform:GA4] Initialized")},document.head.appendChild(n)}function ye(){if(U){if(Lt){a("[Platform] Already loaded, skipping");return}if(!N){a("[Platform] Marketing consent not granted, deferring");return}a("[Platform] Injecting platform pixels (consent granted)"),Lt=!0,ue(),fe(),me(),we(),pe()}}function At(t){if(N=t,a("[Platform] Marketing consent:",t?"granted":"denied"),t&&ye(),window.ttq&&(t?window.ttq.grantConsent?.():window.ttq.revokeConsent?.()),typeof window.gtag=="function"){let e=t?"granted":"denied";window.gtag("consent","update",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:e})}}function lt(t){if(!U||!N)return!1;let e=t.toLowerCase();return e==="pageview"||e==="page_view"?m.pageview:e==="purchase"?m.purchase:e==="addtocart"||e==="add_to_cart"?m.addToCart:e==="lead"||e==="form_submit"?m.lead:e==="viewcontent"||e==="view_content"?m.viewContent:e==="initiatecheckout"||e==="initiate_checkout"?m.initiateCheckout:e==="completeregistration"||e==="complete_registration"?m.completeRegistration:e==="subscribe"?m.subscribe:e==="search"?m.search:e==="contact"?m.contact:m.custom.length>0?m.custom.some(n=>n.toLowerCase()===e):!1}function he(){lt("pageview")&&(a("[Platform] Forwarding PageView"),window.fbq&&window.fbq("track","PageView"),window.ttq&&window.ttq.page(),typeof window.gtag=="function"&&y&&window.gtag("event","page_view",{send_to:y}))}function be(t,e,n){if(lt("purchase")){if(a("[Platform] Forwarding Purchase:",t,e),window.fbq&&window.fbq("track","Purchase",{value:t,currency:e,content_ids:n?.contentIds,content_type:n?.contentType||"product",order_id:n?.transactionId}),window.ttq&&window.ttq.track("CompletePayment",{value:t,currency:e,order_id:n?.transactionId}),typeof window.gtag=="function"&&p){let o=kt?`${p}/${kt}`:p;window.gtag("event","conversion",{send_to:o,value:t,currency:e,transaction_id:n?.transactionId}),window.gtag("event","purchase",{send_to:p,value:t,currency:e,transaction_id:n?.transactionId})}typeof window.gtag=="function"&&y&&window.gtag("event","purchase",{send_to:y,value:t,currency:e,transaction_id:n?.transactionId,items:n?.items})}}function ve(t,e){if(!lt(t))return;let n=t.toLowerCase();a("[Platform] Forwarding custom event:",t);let o={addtocart:"AddToCart",add_to_cart:"AddToCart",lead:"Lead",form_submit:"Lead",viewcontent:"ViewContent",view_content:"ViewContent",search:"Search",subscribe:"Subscribe",contact:"Contact",completeregistration:"CompleteRegistration",complete_registration:"CompleteRegistration",initiatecheckout:"InitiateCheckout",initiate_checkout:"InitiateCheckout"},d={addtocart:"AddToCart",add_to_cart:"AddToCart",lead:"SubmitForm",form_submit:"SubmitForm",viewcontent:"ViewContent",view_content:"ViewContent",search:"Search",subscribe:"Subscribe",contact:"Contact",completeregistration:"CompleteRegistration",complete_registration:"CompleteRegistration",initiatecheckout:"InitiateCheckout",initiate_checkout:"InitiateCheckout"},l={addtocart:"add_to_cart",add_to_cart:"add_to_cart",lead:"generate_lead",form_submit:"generate_lead",viewcontent:"view_item",view_content:"view_item",search:"search",subscribe:"subscribe",contact:"contact",completeregistration:"sign_up",complete_registration:"sign_up",initiatecheckout:"begin_checkout",initiate_checkout:"begin_checkout"};if(window.fbq){let s=o[n];s?window.fbq("track",s,e):window.fbq("trackCustom",t,e)}if(window.ttq){let s=d[n]||t;window.ttq.track(s,e)}if(typeof window.gtag=="function"&&p){let s=l[n]||t;window.gtag("event",s,{send_to:p,...e})}if(typeof window.gtag=="function"&&y){let s=l[n]||t;window.gtag("event",s,{send_to:y,...e})}}function Rt(){try{return x==="local"?localStorage:sessionStorage}catch{return null}}function B(t){let e=Rt();if(!e)return null;try{let n=w+t,o=e.getItem(n);if(!o&&x==="session")try{o=localStorage.getItem(n)}catch{}return o}catch{return null}}function T(t,e){let n=Rt();if(n)try{n.setItem(w+t,e)}catch{}}function Dt(){if(x!=="local"){a("Upgrading storage tier: session -> local");try{let t=[];for(let e=0;e<sessionStorage.length;e++){let n=sessionStorage.key(e);n?.startsWith(w)&&t.push(n)}for(let e of t){let n=sessionStorage.getItem(e);n&&localStorage.setItem(e,n)}for(let e of t)sessionStorage.removeItem(e);x="local",a(`Storage tier upgraded, migrated ${t.length} items`)}catch(t){S(" Storage migration failed:",t)}}}function W(){return crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}function _e(){try{let t=B(Ct),e=B(et);if(t&&e&&Date.now()-parseInt(e,10)<ae)return T(et,Date.now().toString()),t;let n=W();return T(Ct,n),T(et,Date.now().toString()),n}catch{return W()}}function ke(){let t=new URLSearchParams(window.location.search),e={};return["source","medium","campaign","content","term"].forEach(n=>{let o=t.get(`utm_${n}`);o&&(e[`utm_${n}`]=o)}),e}function Ie(){try{let t=B(St);if(t){R=JSON.parse(t),a("Loaded attribution:",R);return}let e=ke();Object.keys(e).length>0&&(R=e,T(St,JSON.stringify(e)),a("Captured attribution:",R))}catch{}}function xe(){try{if(c?.analytics!==!0){a("Skipping fan ID load - no analytics consent");return}g=localStorage.getItem(w+h),g&&a("Loaded fan ID hash:",g.substring(0,16)+"...")}catch{if(c?.analytics===!0)try{g=B(h)}catch{}}}function gt(){try{let t=localStorage.getItem(w+nt);if(t)return t;let e=W();return localStorage.setItem(w+nt,e),a("Created persistent visitor ID:",e.substring(0,8)+"..."),e}catch{return a("localStorage unavailable, using session ID as fallback"),F||W()}}function Ce(){try{b=localStorage.getItem(w+nt),b&&a("Loaded visitor ID:",b.substring(0,8)+"...")}catch{}}function Se(){try{let t=localStorage.getItem(G);if(t){let e=JSON.parse(t);if(e.expiresAt&&Date.now()>e.expiresAt){a("Consent expired - clearing stored consent"),localStorage.removeItem(G),c=null;return}if(e.expiresAt){let n=e.expiresAt-Date.now();n>0&&n<ne&&(a("Consent nearing expiration - will prompt for refresh"),window._balanceConsentNeedsRefresh=!0)}c=e.preferences||null,a("Loaded consent:",c)}}catch{}}function Mt(t){let e=c;c=t;try{let o={preferences:t,method:"explicit",version:1,expiresAt:Date.now()+ee};localStorage.setItem(G,JSON.stringify(o)),a("Consent saved with TTL:",t),window._balanceConsentNeedsRefresh=!1}catch(o){S(" Could not save consent:",o)}if(t.analytics===!0&&(Dt(),b||(b=gt()),g))try{localStorage.setItem(w+h,g),a("Fan ID hash persisted after consent granted")}catch{T(h,g)}if(t.analytics!==!0){try{localStorage.removeItem(w+h)}catch{}try{sessionStorage.removeItem(w+h)}catch{}g=null,a("Fan ID hash cleared from storage and memory (consent revoked)")}let n=P({event_name:"consent_updated",metadata:{consent_preferences:t,consent_method:"explicit",previous_consent:e||void 0}});E(n);try{window.dispatchEvent(new CustomEvent("artistPixel:consent:updated",{detail:t})),a("DOM event artistPixel:consent:updated dispatched")}catch{}U&&At(t.marketing===!0)}function Pe(){return c}function Ee(t){return c?.[t]===!0}function Te(t){for(let[e,n]of Object.entries(t))try{let o=Ot(e);at[o]=n}catch{at[e]=n}a("Registered",Object.keys(t).length,"links for tracking enrichment")}function Ot(t){try{let e=new URL(t);return`${e.protocol}//${e.host}${e.pathname}${e.search}`}catch{return t}}function Le(t){let e=Ot(t);return at[e]||null}async function Ae(t){let e=t.toLowerCase().trim(),o=new TextEncoder().encode(e),d=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(d)).map(s=>s.toString(16).padStart(2,"0")).join("")}function P(t){let e=Kt(),n={artist_id:Y,fan_session_id:F,visitor_id:b||gt(),fan_id_hash:g||void 0,timestamp:new Date().toISOString(),source_url:window.location.href,referrer_url:document.referrer||void 0,user_agent:navigator.userAgent,device_type:e.device_type,browser:e.browser,os:e.os,tracking_source:V,...t,...R};return X&&!t.projectId&&(n.projectId=X),n}function E(t){I.push(t),a("Event queued:",t.event_name,"(queue:",I.length,")"),I.length>=10&&H()}async function H(){if(I.length===0)return;let t=[...I];I=[],a("Flushing",t.length,"events to",A);try{let e=await fetch(A,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:t}),keepalive:!0});if(!e.ok)throw new Error(`HTTP ${e.status}`);a("Events sent successfully")}catch(e){if(S(" Failed to send events, trying fallback:",e),A!==Et&&!Q)try{if((await fetch(Et,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({events:t}),keepalive:!0})).ok){a("Events sent via fallback (no geo)");return}}catch(n){S(" Fallback also failed:",n)}I.length<50&&I.push(...t)}}function Re(){ot&&clearInterval(ot),ot=window.setInterval(()=>{I.length>0&&H()},5e3)}function ut(){M||(it=Date.now()),M=Date.now(),q=!0,a("Active time tracking started/resumed")}function jt(){M&&q&&(rt+=Date.now()-M),q=!1,a("Active time tracking paused, accumulated:",rt,"ms")}function Ut(){let t=rt;return q&&M&&(t+=Date.now()-M),t}function De(){Tt=Date.now(),z&&(z=!1,ut(),a("User returned from idle"))}function Me(){if(document.visibilityState==="hidden"){a("Skipping heartbeat - tab hidden");return}if(Date.now()-Tt>de){z||(z=!0,jt(),a("User idle - pausing heartbeat"));return}let t=Ut(),e=Math.round(t/1e3),n=P({event_name:"engagement_heartbeat",metadata:{time_on_page_seconds:e,time_on_page_ms:t,heartbeat_interval_ms:Z,is_active:q&&!z}});E(n),st++,a("Heartbeat sent:",e,"seconds active")}function ft(){if(!bt){a('Heartbeat disabled via data-heartbeat="false"');return}D&&clearInterval(D),ut(),D=window.setInterval(()=>{Me()},Z),a("Heartbeat started with interval:",Z,"ms")}function mt(){if(!ct){if(ct=!0,D&&(clearInterval(D),D=null),bt){let t=it?Date.now()-it:0,e=Ut(),n=P({event_name:"engagement_summary",metadata:{total_time_ms:t,active_time_ms:e,heartbeat_samples:st,page_path:window.location.pathname}});if(navigator.sendBeacon&&A){let o=JSON.stringify({events:[n]});navigator.sendBeacon(A,o),a("Engagement summary sent via sendBeacon:",Math.round(e/1e3),"seconds active")}else E(n),a("Engagement summary enqueued:",Math.round(e/1e3),"seconds active")}st=0}}function $(t={}){let e=t.url||window.location.href;if(ie(e)){a("Page excluded from tracking:",e);return}let n=P({event_name:"pageview",page_title:t.title||document.title,source_url:e});E(n),he()}function wt(t,e={}){let n=P({event_name:"custom",metadata:{event_type:t,...e}});E(n),ve(t,e)}async function Ft(t,e={}){try{if(c?.analytics!==!0){a("identify() skipped - no analytics consent");return}if(g=await Ae(t),c?.analytics===!0&&Dt(),c?.analytics===!0)try{localStorage.setItem(w+h,g)}catch{T(h,g)}let n=t.split("@"),o=n[0].charAt(0)+"***@"+(n[1]||"");a("Fan identified:",{name:e.name||"(no name)",email:o,hash:g.substring(0,16)+"...",traits:e,storageTier:x});let d=P({event_name:"identify",fan_id_hash:g,metadata:{email_sha256:g,email_display:o,traits:e,consent_preferences:c||void 0,storage_tier:x}});E(d)}catch(n){S(" Failed to identify:",n)}}function Oe(t){if(!t||typeof t!="string"){S("setFanIdHash: invalid hash provided");return}if(g=t,c?.analytics===!0)try{localStorage.setItem(w+h,t),a("Fan ID hash persisted:",t.substring(0,16)+"...")}catch{T(h,t)}else a("Fan ID hash set (memory only - no consent):",t.substring(0,16)+"...")}function qt(t,e="USD",n={}){let o=P({event_name:"purchase",metadata:{revenue:t,currency:e,...n}});E(o),be(t,e,n)}function zt(){if(V=te(),a("Tracking source detected:",V),Se(),c?.analytics!==!0){try{localStorage.removeItem(w+h)}catch{}try{sessionStorage.removeItem(w+h)}catch{}}c?.analytics===!0?(x="local",a("Storage tier: local (analytics consent granted)")):(x="session",a("Storage tier: session (privacy by default)")),F=_e(),xe(),Ce(),b||(b=gt()),c||a(tt?"Consent UI enabled, waiting for explicit user consent (Tier 0 mode)":"No consent - operating in privacy-first mode (session storage only, limited tracking)"),U&&c?.marketing===!0?(a("[Platform] Marketing consent already granted, initializing platform pixels"),At(!0)):U&&a("[Platform] Platform pixels configured:",{meta:O||"(none)",tiktok:L||"(none)",googleAds:p||"(none)"}),Ie(),Re(),a("Initialized",{artistId:Y,projectId:X||"(none - will track to all projects)",rawProjectId:J||"(none)",sessionId:F,visitorId:b?b.substring(0,8)+"...":null,fanIdHash:g,consent:c,storageTier:x,trackingSource:V,useEmulator:Q,endpoint:A}),c?.analytics===!0?(window._balanceInitialPageviewFired=!0,$(),ft(),a("Full tracking enabled (user consented)")):tt?a("Tracking dormant - waiting for explicit consent via ConsentManager"):(window._balanceInitialPageviewFired=!0,$(),ft(),a("Privacy-first tracking enabled (session-scoped, visitor_id for deduplication)")),["mousemove","keydown","scroll","touchstart"].forEach(s=>{document.addEventListener(s,De,{passive:!0})});let t=window.location.hostname;function e(s){try{let i=new URL(s).hostname.toLowerCase();return i.includes("spotify")?"spotify":i.includes("apple")||i.includes("music.apple")?"apple_music":i.includes("youtube")||i.includes("youtu.be")?"youtube":i.includes("soundcloud")?"soundcloud":i.includes("tidal")?"tidal":i.includes("deezer")?"deezer":i.includes("amazon")||i.includes("music.amazon")?"amazon_music":i.includes("bandcamp")?"bandcamp":i.includes("lnk.to")||i.includes("linkfire")?"linkfire":i.includes("linktr.ee")?"linktree":i.includes("shop")||i.includes("store")||i.includes("merch")?"shop":i.includes("ticketmaster")||i.includes("eventbrite")||i.includes("dice.fm")?"tickets":i.includes("instagram")?"instagram":i.includes("twitter")||i.includes("x.com")?"twitter":i.includes("tiktok")?"tiktok":i.includes("facebook")?"facebook":"external"}catch{return"external"}}function n(s){try{return new URL(s,window.location.origin).hostname!==t}catch{return!1}}function o(s,i){let u=e(s),C=Le(s),Gt=C?.title||i?.textContent?.trim().substring(0,100)||"",Bt=C?.id||i?.id||i?.getAttribute("data-link-id")||void 0,Wt=C?.category;a("External link clicked:",{url:s,platform:u,linkText:Gt,linkId:Bt,fromRegistry:!!C}),wt("page_link_click",{link_url:s,link_text:Gt,link_id:Bt,platform:u,link_type:"external",...Wt&&{link_category:Wt},...C&&Object.fromEntries(Object.entries(C).filter(([yt])=>!["title","id","category"].includes(yt)).map(([yt,je])=>[`link_${yt}`,je]))})}let d=window.open;if(window.open=function(s,i,u){if(s){let C=s.toString();n(C)&&o(C)}return d.call(window,s,i,u)},a("window.open interception enabled (always on)"),r?.dataset.autoTrackLinks==="true"&&(document.addEventListener("click",s=>{let u=s.target.closest("a");if(u&&u.href&&n(u.href)){if(xt&&(Pt(u.href)||u.hasAttribute("download")))return;o(u.href,u)}},{capture:!0,passive:!0}),a("External link click listener enabled (opt-in)")),xt&&(document.addEventListener("click",s=>{let u=s.target.closest("a");u?.href&&(Pt(u.href)||u.hasAttribute("download"))&&se(u.href,u)},{capture:!0,passive:!0}),a("File download tracking enabled")),Zt){let s=window.location.href;window.addEventListener("hashchange",()=>{let i=window.location.href;i!==s&&(s=i,setTimeout(()=>{$({title:document.title,url:i})},0))}),a("Hash routing tracking enabled")}document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?(jt(),mt(),H()):(ut(),ct=!1)}),window.addEventListener("pagehide",()=>{mt(),H()}),window.addEventListener("beforeunload",()=>{mt(),H()})}if(window.balance?._version&&window.balance._version!==_){console.warn(`[artistPixel] Version conflict: ${window.balance._version} already loaded, skipping ${_}`);return}let pt=window.balance?.q||[];function Nt(){if(pt.length>0){a("Processing",pt.length,"queued commands");for(let t of pt){let[e,...n]=t;switch(e){case"track":wt(n[0],n[1]);break;case"identify":Ft(n[0],n[1]);break;case"page":$(n[0]);break;case"purchase":qt(n[0],n[1],n[2]);break;case"setConsent":Mt(n[0]);break;default:a("Unknown queued command:",e)}}}}let Ht={track:wt,identify:Ft,page:$,purchase:qt,getSessionId:()=>F,getVisitorId:()=>b,getFanIdHash:()=>g,setFanIdHash:Oe,getAttribution:()=>R,setConsent:Mt,getConsent:Pe,hasConsent:Ee,registerLinks:Te,_version:_};window.artistPixel=Ht,window.balance=Ht;function $t(){tt&&!c&&new ge({style:Jt,primaryColor:Xt,position:Qt})}let Vt=window.requestIdleCallback||(t=>setTimeout(t,1));document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{zt(),Nt(),Vt(()=>$t())}):(zt(),Nt(),Vt(()=>$t())),a("Pixel script loaded")})();})();
|