@hifilabs/pixel 0.14.5 → 0.15.0

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 CHANGED
@@ -8,7 +8,7 @@ var ArtistPixel = (() => {
8
8
 
9
9
  // src/browser.ts
10
10
  (function() {
11
- const PIXEL_VERSION = "0.14.4";
11
+ const PIXEL_VERSION = "0.15.0";
12
12
  function parseUserAgent(ua) {
13
13
  let device_type = "desktop";
14
14
  if (/ipad|tablet|android(?!.*mobile)/i.test(ua))
@@ -1281,6 +1281,19 @@ var ArtistPixel = (() => {
1281
1281
  logError(" Failed to identify:", error);
1282
1282
  }
1283
1283
  }
1284
+ function setFanIdHash(hash) {
1285
+ if (!hash || typeof hash !== "string") {
1286
+ logError("setFanIdHash: invalid hash provided");
1287
+ return;
1288
+ }
1289
+ fanIdHash = hash;
1290
+ try {
1291
+ localStorage.setItem(STORAGE_PREFIX + FAN_ID_KEY, hash);
1292
+ log("Fan ID hash set from server:", hash.substring(0, 16) + "...");
1293
+ } catch {
1294
+ storageSet(FAN_ID_KEY, hash);
1295
+ }
1296
+ }
1284
1297
  function purchase(revenue, currency = "USD", properties = {}) {
1285
1298
  const event = buildEvent({
1286
1299
  event_name: "purchase",
@@ -1539,6 +1552,7 @@ var ArtistPixel = (() => {
1539
1552
  getSessionId: () => sessionId,
1540
1553
  getVisitorId: () => visitorId,
1541
1554
  getFanIdHash: () => fanIdHash,
1555
+ setFanIdHash,
1542
1556
  getAttribution: () => attribution,
1543
1557
  setConsent,
1544
1558
  getConsent,
@@ -1,4 +1,4 @@
1
- var ArtistPixel=(()=>{var je=Object.defineProperty;var Ue=(h,b,y)=>b in h?je(h,b,{enumerable:!0,configurable:!0,writable:!0,value:y}):h[b]=y;var K=(h,b,y)=>(Ue(h,typeof b!="symbol"?b+"":b,y),y);(function(){let h="0.14.4";function b(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 y=null;function Kt(){if(!y)try{y=b(navigator.userAgent)}catch{y={device_type:"desktop",browser:"Unknown",os:"Unknown"}}return y}let s=document.currentScript,Y=s?.dataset.artistId,J=s?.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=s?.dataset.emulator==="true",ht=s?.dataset.debug==="true",Z=parseInt(s?.dataset.heartbeatInterval||"120000",10),bt=s?.dataset.heartbeat!=="false",vt=s?.dataset.source,_t=s?.dataset.endpoint,w=window.__artistPixelConfig||{},D=s?.dataset.metaPixelId||w.metaPixelId,E=s?.dataset.tiktokPixelId||w.tiktokPixelId,u=s?.dataset.googleAdsId||w.googleAdsId,kt=s?.dataset.googleAdsConversionLabel||w.googleAdsConversionLabel,M=s?.dataset.googleTagManagerId||w.googleTagManagerId,m=s?.dataset.googleAnalyticsId||w.googleAnalyticsId,x={pageview:(s?.dataset.forwardPageview??w.forwardPageview)!=="false",purchase:(s?.dataset.forwardPurchase??w.forwardPurchase)!=="false",addToCart:(s?.dataset.forwardAddToCart??w.forwardAddToCart)!=="false",lead:(s?.dataset.forwardLead??w.forwardLead)!=="false",custom:(s?.dataset.forwardCustom||w.forwardCustom||"").split(",").filter(Boolean)},O=!!(D||E||u||M||m),tt=s?.dataset.consentUi==="true",Jt=s?.dataset.consentStyle||"brutalist",Xt=s?.dataset.primaryColor,Qt=s?.dataset.bannerPosition||"bottom",xt=s?.dataset.excludePages?.split(",").filter(Boolean)||[],It=s?.dataset.trackFileDownloads==="true",Zt=s?.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 H="pixel";if(!Y){P(" Error: data-artist-id attribute is required");return}let Ct="session_id",et="session_timestamp",St="attribution",G="fan_id_hash",nt="visitor_id",V="artistPixel_consent",ee=365*24*60*60*1e3,ne=30*24*60*60*1e3,ae=60*60*1e3,I="balance_";function oe(t){let e=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp("^"+e+"$")}function ie(t){if(xt.length===0)return!1;try{let e=new URL(t,window.location.origin).pathname;return xt.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",c=o.includes(".")?o.split(".").pop():"unknown";a("File download tracked:",{url:t,fileName:o,fileExtension:c});let d=C({event_name:"custom",metadata:{event_type:"file_download",file_url:t,file_name:o,file_extension:c,link_text:e?.textContent?.trim().substring(0,100)||""}});S(d)}catch(n){P("Failed to track file download:",n)}}let ce="https://e.os.xyz",Et="https://us-central1-artist-os-distro.cloudfunctions.net/ingestEvents",T=_t||(Q?"http://localhost:5001/artist-os-distro/us-central1/ingestEvents":ce),j=null,p=null,f=null,g=null,L={},at={},v=[],ot=null,_="session",A=null,it=0,rt=0,R=0,U=!0,st=0,ct=!1,de=2*60*1e3,Tt=Date.now(),q=!1,le=!ht,a=(...t)=>{ht&&console.log("[artistPixel]",...t)},P=(...t)=>{le||console.error("[artistPixel]",...t)},dt={base:`
1
+ var ArtistPixel=(()=>{var Ue=Object.defineProperty;var qe=(h,b,y)=>b in h?Ue(h,b,{enumerable:!0,configurable:!0,writable:!0,value:y}):h[b]=y;var K=(h,b,y)=>(qe(h,typeof b!="symbol"?b+"":b,y),y);(function(){let h="0.15.0";function b(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 y=null;function Kt(){if(!y)try{y=b(navigator.userAgent)}catch{y={device_type:"desktop",browser:"Unknown",os:"Unknown"}}return y}let s=document.currentScript,Y=s?.dataset.artistId,J=s?.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=s?.dataset.emulator==="true",ht=s?.dataset.debug==="true",Z=parseInt(s?.dataset.heartbeatInterval||"120000",10),bt=s?.dataset.heartbeat!=="false",vt=s?.dataset.source,_t=s?.dataset.endpoint,w=window.__artistPixelConfig||{},O=s?.dataset.metaPixelId||w.metaPixelId,E=s?.dataset.tiktokPixelId||w.tiktokPixelId,f=s?.dataset.googleAdsId||w.googleAdsId,kt=s?.dataset.googleAdsConversionLabel||w.googleAdsConversionLabel,j=s?.dataset.googleTagManagerId||w.googleTagManagerId,m=s?.dataset.googleAnalyticsId||w.googleAnalyticsId,I={pageview:(s?.dataset.forwardPageview??w.forwardPageview)!=="false",purchase:(s?.dataset.forwardPurchase??w.forwardPurchase)!=="false",addToCart:(s?.dataset.forwardAddToCart??w.forwardAddToCart)!=="false",lead:(s?.dataset.forwardLead??w.forwardLead)!=="false",custom:(s?.dataset.forwardCustom||w.forwardCustom||"").split(",").filter(Boolean)},U=!!(O||E||f||j||m),tt=s?.dataset.consentUi==="true",Jt=s?.dataset.consentStyle||"brutalist",Xt=s?.dataset.primaryColor,Qt=s?.dataset.bannerPosition||"bottom",xt=s?.dataset.excludePages?.split(",").filter(Boolean)||[],It=s?.dataset.trackFileDownloads==="true",Zt=s?.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 G="pixel";if(!Y){C(" Error: data-artist-id attribute is required");return}let Ct="session_id",et="session_timestamp",St="attribution",T="fan_id_hash",nt="visitor_id",V="artistPixel_consent",ee=365*24*60*60*1e3,ne=30*24*60*60*1e3,ae=60*60*1e3,v="balance_";function oe(t){let e=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp("^"+e+"$")}function ie(t){if(xt.length===0)return!1;try{let e=new URL(t,window.location.origin).pathname;return xt.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",c=o.includes(".")?o.split(".").pop():"unknown";a("File download tracked:",{url:t,fileName:o,fileExtension:c});let d=S({event_name:"custom",metadata:{event_type:"file_download",file_url:t,file_name:o,file_extension:c,link_text:e?.textContent?.trim().substring(0,100)||""}});P(d)}catch(n){C("Failed to track file download:",n)}}let ce="https://e.os.xyz",Et="https://us-central1-artist-os-distro.cloudfunctions.net/ingestEvents",L=_t||(Q?"http://localhost:5001/artist-os-distro/us-central1/ingestEvents":ce),q=null,p=null,u=null,g=null,A={},at={},_=[],ot=null,k="session",R=null,it=0,rt=0,D=0,F=!0,st=0,ct=!1,de=2*60*1e3,Tt=Date.now(),z=!1,le=!ht,a=(...t)=>{ht&&console.log("[artistPixel]",...t)},C=(...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;
@@ -99,4 +99,4 @@ var ArtistPixel=(()=>{var je=Object.defineProperty;var Ue=(h,b,y)=>b in h?je(h,b
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 Lt=!1,F=!1;function ue(){if(!D)return;if(window.fbq){a("[Platform:Meta] Already loaded, skipping");return}a("[Platform:Meta] Injecting pixel:",D);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",D),x.pageview&&window.fbq("track","PageView"),a("[Platform:Meta] Initialized and PageView tracked")},document.head.appendChild(e)}function fe(){if(!E)return;if(window.ttq?._i?.[E]){a("[Platform:TikTok] Already loaded, skipping");return}a("[Platform:TikTok] Injecting pixel:",E);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(E),x.pageview&&n.page(),a("[Platform:TikTok] Initialized and page() tracked")}function me(){if(!u)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",u);return}a("[Platform:GoogleAds] Injecting gtag:",u),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=${u}`,t.onload=()=>{window.gtag("js",new Date),window.gtag("config",u),a("[Platform:GoogleAds] Initialized")},document.head.appendChild(t)}function we(){if(!M)return;if(document.querySelector(`script[src*="googletagmanager.com/gtm.js?id=${M}"]`)){a("[Platform:GTM] Already loaded, skipping");return}a("[Platform:GTM] Injecting GTM:",M),window.dataLayer=window.dataLayer||[],typeof window.gtag!="function"&&(window.gtag=function(...n){window.dataLayer.push(n)});let t=F?"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=${M}`,e.onload=()=>{a("[Platform:GTM] Initialized")},document.head.appendChild(e)}function pe(){if(!m)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=F?"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",m,{send_page_view:!1});return}a("[Platform:GA4] Injecting gtag:",m);let n=document.createElement("script");n.async=!0,n.src=`https://www.googletagmanager.com/gtag/js?id=${m}`,n.onload=()=>{window.gtag("js",new Date),window.gtag("config",m,{send_page_view:!1}),a("[Platform:GA4] Initialized")},document.head.appendChild(n)}function ye(){if(O){if(Lt){a("[Platform] Already loaded, skipping");return}if(!F){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(F=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(!O||!F)return!1;let e=t.toLowerCase();return e==="pageview"||e==="page_view"?x.pageview:e==="purchase"?x.purchase:e==="addtocart"||e==="add_to_cart"?x.addToCart:e==="lead"||e==="form_submit"?x.lead:x.custom.length>0?x.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"&&m&&window.gtag("event","page_view",{send_to:m}))}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"&&u){let o=kt?`${u}/${kt}`:u;window.gtag("event","conversion",{send_to:o,value:t,currency:e,transaction_id:n?.transactionId}),window.gtag("event","purchase",{send_to:u,value:t,currency:e,transaction_id:n?.transactionId})}typeof window.gtag=="function"&&m&&window.gtag("event","purchase",{send_to:m,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 r=o[n];r?window.fbq("track",r,e):window.fbq("trackCustom",t,e)}if(window.ttq){let r=c[n]||t;window.ttq.track(r,e)}if(typeof window.gtag=="function"&&u){let r=d[n]||t;window.gtag("event",r,{send_to:u,...e})}if(typeof window.gtag=="function"&&m){let r=d[n]||t;window.gtag("event",r,{send_to:m,...e})}}function Rt(){try{return _==="local"?localStorage:sessionStorage}catch{return null}}function B(t){let e=Rt();if(!e)return null;try{let n=I+t,o=e.getItem(n);if(!o&&_==="session")try{o=localStorage.getItem(n)}catch{}return o}catch{return null}}function z(t,e){let n=Rt();if(n)try{n.setItem(I+t,e)}catch{}}function Dt(){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(I)&&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){P(" 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 z(et,Date.now().toString()),t;let n=W();return z(Ct,n),z(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(St);if(t){L=JSON.parse(t),a("Loaded attribution:",L);return}let e=ke();Object.keys(e).length>0&&(L=e,z(St,JSON.stringify(e)),a("Captured attribution:",L))}catch{}}function Ie(){try{f=localStorage.getItem(I+G),f&&a("Loaded fan ID hash:",f.substring(0,16)+"...")}catch{try{f=B(G)}catch{}}}function gt(){try{let t=localStorage.getItem(I+nt);if(t)return t;let e=W();return localStorage.setItem(I+nt,e),a("Created persistent visitor ID:",e.substring(0,8)+"..."),e}catch{return a("localStorage unavailable, using session ID as fallback"),j||W()}}function Ce(){try{p=localStorage.getItem(I+nt),p&&a("Loaded visitor ID:",p.substring(0,8)+"...")}catch{}}function Se(){try{let t=localStorage.getItem(V);if(t){let e=JSON.parse(t);if(e.expiresAt&&Date.now()>e.expiresAt){a("Consent expired - clearing stored consent"),localStorage.removeItem(V),g=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)}g=e.preferences||null,a("Loaded consent:",g)}}catch{}}function Mt(t){let e=g;g=t;try{let o={preferences:t,method:"explicit",version:1,expiresAt:Date.now()+ee};localStorage.setItem(V,JSON.stringify(o)),a("Consent saved with TTL:",t),window._balanceConsentNeedsRefresh=!1}catch(o){P(" Could not save consent:",o)}t.analytics===!0&&(Dt(),p||(p=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{}O&&At(t.marketing===!0)}function Pe(){return g}function Ee(t){return g?.[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),c=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(c)).map(r=>r.toString(16).padStart(2,"0")).join("")}function C(t){let e=Kt(),n={artist_id:Y,fan_session_id:j,visitor_id:p||gt(),fan_id_hash:f||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:H,...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(P(" Failed to send events, trying fallback:",e),T!==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){P(" 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(),U=!0,a("Active time tracking started/resumed")}function jt(){R&&U&&(rt+=Date.now()-R),U=!1,a("Active time tracking paused, accumulated:",rt,"ms")}function Ut(){let t=rt;return U&&R&&(t+=Date.now()-R),t}function De(){Tt=Date.now(),q&&(q=!1,ut(),a("User returned from idle"))}function Me(){if(document.visibilityState==="hidden"){a("Skipping heartbeat - tab hidden");return}if(Date.now()-Tt>de){q||(q=!0,jt(),a("User idle - pausing heartbeat"));return}let t=Ut(),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:U&&!q}});S(n),st++,a("Heartbeat sent:",e,"seconds active")}function ft(){if(!bt){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),bt){let t=it?Date.now()-it:0,e=Ut(),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 $(t={}){let e=t.url||window.location.href;if(ie(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),he()}function wt(t,e={}){let n=C({event_name:"custom",metadata:{event_type:t,...e}});S(n),ve(t,e)}async function qt(t,e={}){try{if(g&&g.analytics===!1){a("Identify skipped - user declined analytics consent");return}f=await Ae(t),g?.analytics===!0&&Dt();try{localStorage.setItem(I+G,f)}catch{z(G,f)}let n=t.split("@"),o=n[0].charAt(0)+"***@"+(n[1]||"");a("Fan identified:",{name:e.name||"(no name)",email:o,hash:f.substring(0,16)+"...",traits:e,storageTier:_});let c=C({event_name:"identify",fan_id_hash:f,metadata:{email_sha256:f,email_display:o,traits:e,consent_preferences:g||void 0,storage_tier:_}});S(c)}catch(n){P(" Failed to identify:",n)}}function Ft(t,e="USD",n={}){let o=C({event_name:"purchase",metadata:{revenue:t,currency:e,...n}});S(o),be(t,e,n)}function zt(){H=te(),a("Tracking source detected:",H),Se(),g?.analytics===!0?(_="local",a("Storage tier: local (analytics consent granted)")):(_="session",a("Storage tier: session (privacy by default)")),j=_e(),Ie(),Ce(),p||(p=gt()),g||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)"),O&&g?.marketing===!0?(a("[Platform] Marketing consent already granted, initializing platform pixels"),At(!0)):O&&a("[Platform] Platform pixels configured:",{meta:D||"(none)",tiktok:E||"(none)",googleAds:u||"(none)"}),xe(),Re(),a("Initialized",{artistId:Y,projectId:X||"(none - will track to all projects)",rawProjectId:J||"(none)",sessionId:j,visitorId:p?p.substring(0,8)+"...":null,fanIdHash:f,consent:g,storageTier:_,trackingSource:H,useEmulator:Q,endpoint:T}),g?.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(r=>{document.addEventListener(r,De,{passive:!0})});let t=window.location.hostname;function e(r){try{let i=new URL(r).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(r){try{return new URL(r,window.location.origin).hostname!==t}catch{return!1}}function o(r,i){let l=e(r),k=Le(r),Vt=k?.title||i?.textContent?.trim().substring(0,100)||"",Bt=k?.id||i?.id||i?.getAttribute("data-link-id")||void 0,Wt=k?.category;a("External link clicked:",{url:r,platform:l,linkText:Vt,linkId:Bt,fromRegistry:!!k}),wt("page_link_click",{link_url:r,link_text:Vt,link_id:Bt,platform:l,link_type:"external",...Wt&&{link_category:Wt},...k&&Object.fromEntries(Object.entries(k).filter(([yt])=>!["title","id","category"].includes(yt)).map(([yt,Oe])=>[`link_${yt}`,Oe]))})}let c=window.open;if(window.open=function(r,i,l){if(r){let k=r.toString();n(k)&&o(k)}return c.call(window,r,i,l)},a("window.open interception enabled (always on)"),s?.dataset.autoTrackLinks==="true"&&(document.addEventListener("click",r=>{let l=r.target.closest("a");if(l&&l.href&&n(l.href)){if(It&&(Pt(l.href)||l.hasAttribute("download")))return;o(l.href,l)}},{capture:!0,passive:!0}),a("External link click listener enabled (opt-in)")),It&&(document.addEventListener("click",r=>{let l=r.target.closest("a");l?.href&&(Pt(l.href)||l.hasAttribute("download"))&&se(l.href,l)},{capture:!0,passive:!0}),a("File download tracking enabled")),Zt){let r=window.location.href;window.addEventListener("hashchange",()=>{let i=window.location.href;i!==r&&(r=i,setTimeout(()=>{$({title:document.title,url:i})},0))}),a("Hash routing tracking enabled")}document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"?(jt(),mt(),N()):(ut(),ct=!1)}),window.addEventListener("pagehide",()=>{mt(),N()}),window.addEventListener("beforeunload",()=>{mt(),N()})}if(window.balance?._version&&window.balance._version!==h){console.warn(`[artistPixel] Version conflict: ${window.balance._version} already loaded, skipping ${h}`);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":qt(n[0],n[1]);break;case"page":$(n[0]);break;case"purchase":Ft(n[0],n[1],n[2]);break;case"setConsent":Mt(n[0]);break;default:a("Unknown queued command:",e)}}}}let $t={track:wt,identify:qt,page:$,purchase:Ft,getSessionId:()=>j,getVisitorId:()=>p,getFanIdHash:()=>f,getAttribution:()=>L,setConsent:Mt,getConsent:Pe,hasConsent:Ee,registerLinks:Te,_version:h};window.artistPixel=$t,window.balance=$t;function Ht(){tt&&!g&&new ge({style:Jt,primaryColor:Xt,position:Qt})}let Gt=window.requestIdleCallback||(t=>setTimeout(t,1));document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{zt(),Nt(),Gt(()=>Ht())}):(zt(),Nt(),Gt(()=>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),I.pageview&&window.fbq("track","PageView"),a("[Platform:Meta] Initialized and PageView tracked")},document.head.appendChild(e)}function fe(){if(!E)return;if(window.ttq?._i?.[E]){a("[Platform:TikTok] Already loaded, skipping");return}a("[Platform:TikTok] Injecting pixel:",E);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(E),I.pageview&&n.page(),a("[Platform:TikTok] Initialized and page() tracked")}function me(){if(!f)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",f);return}a("[Platform:GoogleAds] Injecting gtag:",f),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=${f}`,t.onload=()=>{window.gtag("js",new Date),window.gtag("config",f),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(!m)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",m,{send_page_view:!1});return}a("[Platform:GA4] Injecting gtag:",m);let n=document.createElement("script");n.async=!0,n.src=`https://www.googletagmanager.com/gtag/js?id=${m}`,n.onload=()=>{window.gtag("js",new Date),window.gtag("config",m,{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"?I.pageview:e==="purchase"?I.purchase:e==="addtocart"||e==="add_to_cart"?I.addToCart:e==="lead"||e==="form_submit"?I.lead:I.custom.length>0?I.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"&&m&&window.gtag("event","page_view",{send_to:m}))}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"&&f){let o=kt?`${f}/${kt}`:f;window.gtag("event","conversion",{send_to:o,value:t,currency:e,transaction_id:n?.transactionId}),window.gtag("event","purchase",{send_to:f,value:t,currency:e,transaction_id:n?.transactionId})}typeof window.gtag=="function"&&m&&window.gtag("event","purchase",{send_to:m,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 r=o[n];r?window.fbq("track",r,e):window.fbq("trackCustom",t,e)}if(window.ttq){let r=c[n]||t;window.ttq.track(r,e)}if(typeof window.gtag=="function"&&f){let r=d[n]||t;window.gtag("event",r,{send_to:f,...e})}if(typeof window.gtag=="function"&&m){let r=d[n]||t;window.gtag("event",r,{send_to:m,...e})}}function Rt(){try{return k==="local"?localStorage:sessionStorage}catch{return null}}function B(t){let e=Rt();if(!e)return null;try{let n=v+t,o=e.getItem(n);if(!o&&k==="session")try{o=localStorage.getItem(n)}catch{}return o}catch{return null}}function M(t,e){let n=Rt();if(n)try{n.setItem(v+t,e)}catch{}}function Dt(){if(k!=="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(v)&&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);k="local",a(`Storage tier upgraded, migrated ${t.length} items`)}catch(t){C(" 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 M(et,Date.now().toString()),t;let n=W();return M(Ct,n),M(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(St);if(t){A=JSON.parse(t),a("Loaded attribution:",A);return}let e=ke();Object.keys(e).length>0&&(A=e,M(St,JSON.stringify(e)),a("Captured attribution:",A))}catch{}}function Ie(){try{u=localStorage.getItem(v+T),u&&a("Loaded fan ID hash:",u.substring(0,16)+"...")}catch{try{u=B(T)}catch{}}}function gt(){try{let t=localStorage.getItem(v+nt);if(t)return t;let e=W();return localStorage.setItem(v+nt,e),a("Created persistent visitor ID:",e.substring(0,8)+"..."),e}catch{return a("localStorage unavailable, using session ID as fallback"),q||W()}}function Ce(){try{p=localStorage.getItem(v+nt),p&&a("Loaded visitor ID:",p.substring(0,8)+"...")}catch{}}function Se(){try{let t=localStorage.getItem(V);if(t){let e=JSON.parse(t);if(e.expiresAt&&Date.now()>e.expiresAt){a("Consent expired - clearing stored consent"),localStorage.removeItem(V),g=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)}g=e.preferences||null,a("Loaded consent:",g)}}catch{}}function Mt(t){let e=g;g=t;try{let o={preferences:t,method:"explicit",version:1,expiresAt:Date.now()+ee};localStorage.setItem(V,JSON.stringify(o)),a("Consent saved with TTL:",t),window._balanceConsentNeedsRefresh=!1}catch(o){C(" Could not save consent:",o)}t.analytics===!0&&(Dt(),p||(p=gt()));let n=S({event_name:"consent_updated",metadata:{consent_preferences:t,consent_method:"explicit",previous_consent:e||void 0}});P(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 g}function Ee(t){return g?.[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),c=await crypto.subtle.digest("SHA-256",o);return Array.from(new Uint8Array(c)).map(r=>r.toString(16).padStart(2,"0")).join("")}function S(t){let e=Kt(),n={artist_id:Y,fan_session_id:q,visitor_id:p||gt(),fan_id_hash:u||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:G,...t,...A};return X&&!t.projectId&&(n.projectId=X),n}function P(t){_.push(t),a("Event queued:",t.event_name,"(queue:",_.length,")"),_.length>=10&&H()}async function H(){if(_.length===0)return;let t=[..._];_=[],a("Flushing",t.length,"events to",L);try{let e=await fetch(L,{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(C(" Failed to send events, trying fallback:",e),L!==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){C(" Fallback also failed:",n)}_.length<50&&_.push(...t)}}function Re(){ot&&clearInterval(ot),ot=window.setInterval(()=>{_.length>0&&H()},5e3)}function ut(){D||(it=Date.now()),D=Date.now(),F=!0,a("Active time tracking started/resumed")}function jt(){D&&F&&(rt+=Date.now()-D),F=!1,a("Active time tracking paused, accumulated:",rt,"ms")}function Ut(){let t=rt;return F&&D&&(t+=Date.now()-D),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=S({event_name:"engagement_heartbeat",metadata:{time_on_page_seconds:e,time_on_page_ms:t,heartbeat_interval_ms:Z,is_active:F&&!z}});P(n),st++,a("Heartbeat sent:",e,"seconds active")}function ft(){if(!bt){a('Heartbeat disabled via data-heartbeat="false"');return}R&&clearInterval(R),ut(),R=window.setInterval(()=>{Me()},Z),a("Heartbeat started with interval:",Z,"ms")}function mt(){if(!ct){if(ct=!0,R&&(clearInterval(R),R=null),bt){let t=it?Date.now()-it:0,e=Ut(),n=S({event_name:"engagement_summary",metadata:{total_time_ms:t,active_time_ms:e,heartbeat_samples:st,page_path:window.location.pathname}});if(navigator.sendBeacon&&L){let o=JSON.stringify({events:[n]});navigator.sendBeacon(L,o),a("Engagement summary sent via sendBeacon:",Math.round(e/1e3),"seconds active")}else P(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=S({event_name:"pageview",page_title:t.title||document.title,source_url:e});P(n),he()}function wt(t,e={}){let n=S({event_name:"custom",metadata:{event_type:t,...e}});P(n),ve(t,e)}async function qt(t,e={}){try{if(g&&g.analytics===!1){a("Identify skipped - user declined analytics consent");return}u=await Ae(t),g?.analytics===!0&&Dt();try{localStorage.setItem(v+T,u)}catch{M(T,u)}let n=t.split("@"),o=n[0].charAt(0)+"***@"+(n[1]||"");a("Fan identified:",{name:e.name||"(no name)",email:o,hash:u.substring(0,16)+"...",traits:e,storageTier:k});let c=S({event_name:"identify",fan_id_hash:u,metadata:{email_sha256:u,email_display:o,traits:e,consent_preferences:g||void 0,storage_tier:k}});P(c)}catch(n){C(" Failed to identify:",n)}}function Oe(t){if(!t||typeof t!="string"){C("setFanIdHash: invalid hash provided");return}u=t;try{localStorage.setItem(v+T,t),a("Fan ID hash set from server:",t.substring(0,16)+"...")}catch{M(T,t)}}function Ft(t,e="USD",n={}){let o=S({event_name:"purchase",metadata:{revenue:t,currency:e,...n}});P(o),be(t,e,n)}function zt(){G=te(),a("Tracking source detected:",G),Se(),g?.analytics===!0?(k="local",a("Storage tier: local (analytics consent granted)")):(k="session",a("Storage tier: session (privacy by default)")),q=_e(),Ie(),Ce(),p||(p=gt()),g||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&&g?.marketing===!0?(a("[Platform] Marketing consent already granted, initializing platform pixels"),At(!0)):U&&a("[Platform] Platform pixels configured:",{meta:O||"(none)",tiktok:E||"(none)",googleAds:f||"(none)"}),xe(),Re(),a("Initialized",{artistId:Y,projectId:X||"(none - will track to all projects)",rawProjectId:J||"(none)",sessionId:q,visitorId:p?p.substring(0,8)+"...":null,fanIdHash:u,consent:g,storageTier:k,trackingSource:G,useEmulator:Q,endpoint:L}),g?.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(r=>{document.addEventListener(r,De,{passive:!0})});let t=window.location.hostname;function e(r){try{let i=new URL(r).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(r){try{return new URL(r,window.location.origin).hostname!==t}catch{return!1}}function o(r,i){let l=e(r),x=Le(r),Vt=x?.title||i?.textContent?.trim().substring(0,100)||"",Bt=x?.id||i?.id||i?.getAttribute("data-link-id")||void 0,Wt=x?.category;a("External link clicked:",{url:r,platform:l,linkText:Vt,linkId:Bt,fromRegistry:!!x}),wt("page_link_click",{link_url:r,link_text:Vt,link_id:Bt,platform:l,link_type:"external",...Wt&&{link_category:Wt},...x&&Object.fromEntries(Object.entries(x).filter(([yt])=>!["title","id","category"].includes(yt)).map(([yt,je])=>[`link_${yt}`,je]))})}let c=window.open;if(window.open=function(r,i,l){if(r){let x=r.toString();n(x)&&o(x)}return c.call(window,r,i,l)},a("window.open interception enabled (always on)"),s?.dataset.autoTrackLinks==="true"&&(document.addEventListener("click",r=>{let l=r.target.closest("a");if(l&&l.href&&n(l.href)){if(It&&(Pt(l.href)||l.hasAttribute("download")))return;o(l.href,l)}},{capture:!0,passive:!0}),a("External link click listener enabled (opt-in)")),It&&(document.addEventListener("click",r=>{let l=r.target.closest("a");l?.href&&(Pt(l.href)||l.hasAttribute("download"))&&se(l.href,l)},{capture:!0,passive:!0}),a("File download tracking enabled")),Zt){let r=window.location.href;window.addEventListener("hashchange",()=>{let i=window.location.href;i!==r&&(r=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!==h){console.warn(`[artistPixel] Version conflict: ${window.balance._version} already loaded, skipping ${h}`);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":qt(n[0],n[1]);break;case"page":$(n[0]);break;case"purchase":Ft(n[0],n[1],n[2]);break;case"setConsent":Mt(n[0]);break;default:a("Unknown queued command:",e)}}}}let Ht={track:wt,identify:qt,page:$,purchase:Ft,getSessionId:()=>q,getVisitorId:()=>p,getFanIdHash:()=>u,setFanIdHash:Oe,getAttribution:()=>A,setConsent:Mt,getConsent:Pe,hasConsent:Ee,registerLinks:Te,_version:h};window.artistPixel=Ht,window.balance=Ht;function $t(){tt&&!g&&new ge({style:Jt,primaryColor:Xt,position:Qt})}let Gt=window.requestIdleCallback||(t=>setTimeout(t,1));document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{zt(),Nt(),Gt(()=>$t())}):(zt(),Nt(),Gt(()=>$t())),a("Pixel script loaded")})();})();
package/dist/index.js CHANGED
@@ -1329,12 +1329,14 @@ __export(src_exports, {
1329
1329
  getFanIdHash: () => getFanIdHash,
1330
1330
  getSessionId: () => getSessionId,
1331
1331
  getStorageManager: () => getStorageManager,
1332
+ getVisitorId: () => getVisitorId,
1332
1333
  hasConsent: () => hasConsent,
1333
1334
  identify: () => identify,
1334
1335
  initStorageWithConsent: () => initStorageWithConsent,
1335
1336
  page: () => page,
1336
1337
  purchase: () => purchase,
1337
1338
  setConsent: () => setConsent,
1339
+ setFanIdHash: () => setFanIdHash,
1338
1340
  toBalanceConsent: () => toBalanceConsent,
1339
1341
  track: () => track,
1340
1342
  useArtistOS: () => useArtistOS,
@@ -4700,3 +4702,19 @@ var hasConsent = (type) => {
4700
4702
  return false;
4701
4703
  return window.artistPixel?.hasConsent(type) ?? window.balance?.hasConsent(type) ?? false;
4702
4704
  };
4705
+ var getVisitorId = () => {
4706
+ if (typeof window === "undefined")
4707
+ return null;
4708
+ return window.artistPixel?.getVisitorId() ?? window.balance?.getVisitorId() ?? null;
4709
+ };
4710
+ var setFanIdHash = (hash) => {
4711
+ if (typeof window === "undefined")
4712
+ return;
4713
+ if (window.artistPixel) {
4714
+ window.artistPixel.setFanIdHash(hash);
4715
+ } else if (window.balance) {
4716
+ window.balance.setFanIdHash(hash);
4717
+ } else {
4718
+ console.warn("[artistPixel] setFanIdHash() called before pixel initialized");
4719
+ }
4720
+ };
package/dist/index.mjs CHANGED
@@ -4618,6 +4618,22 @@ var hasConsent = (type) => {
4618
4618
  return false;
4619
4619
  return window.artistPixel?.hasConsent(type) ?? window.balance?.hasConsent(type) ?? false;
4620
4620
  };
4621
+ var getVisitorId = () => {
4622
+ if (typeof window === "undefined")
4623
+ return null;
4624
+ return window.artistPixel?.getVisitorId() ?? window.balance?.getVisitorId() ?? null;
4625
+ };
4626
+ var setFanIdHash = (hash) => {
4627
+ if (typeof window === "undefined")
4628
+ return;
4629
+ if (window.artistPixel) {
4630
+ window.artistPixel.setFanIdHash(hash);
4631
+ } else if (window.balance) {
4632
+ window.balance.setFanIdHash(hash);
4633
+ } else {
4634
+ console.warn("[artistPixel] setFanIdHash() called before pixel initialized");
4635
+ }
4636
+ };
4621
4637
  export {
4622
4638
  ArtistOS,
4623
4639
  ArtistPixelAnalytics,
@@ -4639,12 +4655,14 @@ export {
4639
4655
  getFanIdHash,
4640
4656
  getSessionId,
4641
4657
  getStorageManager,
4658
+ getVisitorId,
4642
4659
  hasConsent,
4643
4660
  identify,
4644
4661
  initStorageWithConsent,
4645
4662
  page,
4646
4663
  purchase,
4647
4664
  setConsent,
4665
+ setFanIdHash,
4648
4666
  toBalanceConsent,
4649
4667
  track,
4650
4668
  useArtistOS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hifilabs/pixel",
3
- "version": "0.14.5",
3
+ "version": "0.15.0",
4
4
  "description": "artistPixel - Lightweight browser tracking script for artist fan analytics",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",