Copy (()=>{var STORE_ID="ENTER_WORKSPACE_ID_HERE";var Cookie={prefix:function(){return"__grp_"},set:function(name,value,days=365){const expires=new Date(Date.now()+days*864e5).toUTCString();document.cookie=this.prefix()+name+"="+encodeURIComponent(value)+"; expires="+expires+"; path=/; SameSite=Lax"},get:function(name){const key=this.prefix()+name+"=";const cookies=document.cookie.split(";");for(let cookie of cookies){cookie=cookie.trim();if(cookie.indexOf(key)===0){return decodeURIComponent(cookie.substring(key.length))}}return""},delete:function(name){this.set(name,"",-1)},exists:function(name){return this.get(name)!==""},setUTMs:function(){const params=new URLSearchParams(window.location.search);const utms={};const utmKeys=["utm_source","utm_medium","utm_campaign","utm_term","utm_content","utm_source_platform","utm_creative_format","utm_marketing_tactic"];let anyFound=false;for(const key of utmKeys){const value=params.get(key);if(value){utms[key]=value;anyFound=true}}if(anyFound){this.set("utm",JSON.stringify(utms))}},getUTM:function(key){if(this.exists("utm")){const utms=JSON.parse(this.get("utm"));return utms[key]||""}return""}};var Fingerprint={get:function(){const navigatorInfo=navigator.userAgent;const screenInfo=window.screen.width+"x"+window.screen.height+"x"+window.screen.colorDepth;const timezone=new Date().getTimezoneOffset();return btoa(navigatorInfo+screenInfo+timezone)}};var Helper={now:function(){return return Math.floor(Date.now())},utmMap:{utm_source:["gr_source","tw_source","utm_source"],utm_campaign:["gr_campaign","tw_campaign","fbc_id","fb_campaignid","utm_campaign"],utm_medium:["utm_medium"],utm_term:["gr_term","fb_adsetid","utm_term"],utm_content:["gr_content","utm_content"],utm_adid:["gr_gadid","tw_adid","h_ad_id","fb_adid","gr_fbadid","utm_id"]},parseUTMs:function(){const params=new URLSearchParams(window.location.search);const utms={};Object.keys(this.utmMap).forEach(key=>{let found=false;for(const altKey of this.utmMap[key]){const value=params.get(altKey);if(value){utms[key]=value;found=true;break}}if(!found){const cookieValue=Cookie.getUTM(key);utms[key]=cookieValue||""}});return utms},grabOrderDataIfAny:function(){if(window.Shopify&&window.Shopify.checkout){return{order_id:window.Shopify.checkout.order_id,total_price:window.Shopify.checkout.total_price,currency:window.Shopify.checkout.currency,line_items:window.Shopify.checkout.line_items,customer:window.Shopify.checkout.customer}}return null},async domainName(url){const commonTLDs=["com","org","net","gov","edu","co","io","ac","biz","info","mobi","pro","name","shop","club","uk","us","eu","ca","au","pk","de","fr","it","es","in","nl","ru","br","jp","ch","se","no","be","at","dk","fi","za","nz","mx","ar","pl","id","ie","sg","my","gr","pt","hk","il","ph","vn","tr","si","cz","sk","lt","lv","ee","uy","bg","hr","tw","ro","is","hu","rs","lu","vn","ma","ba","ua","kr","cn","ae","qa","ng","pe","app","online","site","store","tech","blog","xyz","design","art","ai",""];const _url=new URL(url);const hostname=_url.hostname.replace("www.","");const domainParts=hostname.split(".");let domainIndex=-1;for(let i=domainParts.length-1;i>=0;i--){if(!commonTLDs.includes(domainParts[i].toLowerCase())){domainIndex=i;break}}return domainIndex>=0?domainParts[domainIndex]:domainParts[0]},async fuzzySourceDetection(source,url){const fb=["Facebook","facebook","Facebook_Ad","Facebook_Ads","facebook_Ad","Facebook_ads","facebook_ad","fb","Fb","Ig","ig","Fb_ig","fb_ig","Fb/ig","fb/ig","Instagram","instagram","IGShopping","igshopping"];const tiktok=["tiktok","tt","tiktok_ads","tiktokads","tiktok_ad","tiktokads"];const google=["google","gads","google_ads","google_ad","googleads","googlead"];source=(source||"").toLowerCase();if(fb.includes(source)||url.includes("fbclid")){return"facebook"}if(tiktok.includes(source)||url.includes("ttclid")){return"tiktok"}if(google.includes(source)||url.includes("gclid")){return"google"}return source},async detectSourceSmartly(){const utms=this.parseUTMs();let source=utms.utm_source;if(source){return await this.fuzzySourceDetection(source,window.location.href)}if(document.referrer){const domain2=await this.domainName(document.referrer);return await this.fuzzySourceDetection(domain2,document.referrer)}const domain=await this.domainName(window.location.href);return await this.fuzzySourceDetection(domain,window.location.href)},getBrowserNameAndVersion:function(){const ua=navigator.userAgent;let tem;let M=ua.match(/(opera|chrome|safari|firefox|msie|trident)\/?\s*(\d+)/i)||[];if(/trident/i.test(M[1])){tem=/\brv[ :]+(\d+)/g.exec(ua)||[];return"IE "+(tem[1]||"")}if(M[1]==="Chrome"){tem=ua.match(/\b(OPR|Edge)\/(\d+)/);if(tem!=null){return tem.slice(1).join(" ").replace("OPR","Opera")}}M=M[2]?[M[1],M[2]]:[navigator.appName,navigator.appVersion,"-?"];if((tem=ua.match(/version\/(\d+)/i))!=null){M.splice(1,1,tem[1])}return M.join(" ")},isMobileDevice:function(){return"ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0},getUserAgent:function(){return navigator.userAgent}};var Validator={validateConversionDTO(dto){const errors=[];const hasValue=typeof dto.value==="number";const hasProducts=Array.isArray(dto.products)&&dto.products.length>0&&dto.products.every(p=>typeof p.productQuantity==="number"&&p.productQuantity>0&&typeof p.purchaseValue==="number"&&p.purchaseValue>0);if(!hasValue&&!hasProducts){errors.push("Conversion DTO must include either value or a valid products array.")}return errors}};Cookie.setUTMs();var script=document.currentScript||document.querySelector("script[data-website-id]");var ENDPOINT_MAP={api_v2:"https://us-central1-growify-346505.cloudfunctions.net/grpV2"};var Config={id:script?.getAttribute("data-website-id")||STORE_ID||null,endpointKey:script?.getAttribute("data-endpoint")||"api_v2",version:"1.0.0",platform:script?.getAttribute("data-platform")||"web",params:{}};if(!Config.id){console.error("GRP: Missing website id. Use <script data-website-id=xxx>")}function resolveEndpoint(){return ENDPOINT_MAP[Config.endpointKey]||Config.endpointKey}function getVisitorId(){let visitorId=Cookie.get("grp_uid");if(!visitorId){visitorId=Fingerprint.get();Cookie.set("grp_uid",visitorId)}return visitorId}async function buildPayload(eventName,optionalData={}){const utms=Helper.parseUTMs();const source=await Helper.detectSourceSmartly();let ed="";if(typeof optionalData==="object"){ed=JSON.stringify(optionalData)}else{ed=optionalData}return{id:Config.id,uid:getVisitorId(),ev:eventName,ed,v:Config.version,platform:Config.platform,source,dl:window.location.href,rl:document.referrer,ts:Helper.now(),de:document.characterSet,sr:window.screen.width+"x"+window.screen.height,vp:window.innerWidth+"x"+window.innerHeight,cd:window.screen.colorDepth,dt:document.title,bn:Helper.getBrowserNameAndVersion(),md:Helper.isMobileDevice()?"true":"false",ua:Helper.getUserAgent(),tz:new Date().getTimezoneOffset(),gaid:(document.cookie.match(/_ga=([^;]+)/)||[])[1]||"",fbid:(document.cookie.match(/_fbp=([^;]+)/)||[])[1]||"",gr_user_id:getVisitorId(),utm_source:utms.utm_source||"",utm_medium:utms.utm_medium||"",utm_campaign:utms.utm_campaign||"",utm_term:utms.utm_term||"",utm_content:utms.utm_content||"",utm_source_platform:utms.utm_source_platform||"",utm_creative_format:utms.utm_creative_format||"",utm_marketing_tactic:utms.utm_marketing_tactic||"",...Config.params}}async function sendEvent(eventName,optionalData){const payload=await buildPayload(eventName,optionalData);const endpoint=resolveEndpoint();const blob=new Blob([JSON.stringify(payload)],{type:"application/json"});const beaconSuccess=navigator.sendBeacon(endpoint,blob);if(!beaconSuccess){console.warn("\u2757 sendBeacon failed, falling back to fetch...");fetch(endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(payload)}).catch(err=>console.error("\u2757 Fetch fallback failed:",err))}else{console.log("\u2705 GRP Event sent: "+eventName)}}window.addEventListener("load",()=>{sendEvent("pageload")});window.addEventListener("beforeunload",()=>{sendEvent("pageclosed")});window.grp=function(command,data){console.log("[GRP] Called with:",command,data);if(command==="conversion"){const errors=Validator.validateConversionDTO(data);if(errors.length){errors.forEach(error=>console.error(error));return}sendEvent("purchase",data)}if(command==="lead-generated"){const product=[{productName:"Lead Generated",purchaseValue:1}];const payload={...data,products:product};sendEvent("purchase",payload)}if(command==="init"){Config.id=data}if(command==="event"&&data?.name){console.log("Got event: ",data.name);sendEvent(data.name,data.payload||{})}};if(Array.isArray(window.grpQueue)){for(const args of window.grpQueue){try{window.grp.apply(null,args)}catch(error){console.error("Failed to replay queued grp call:",error)}}window.grpQueue=[]}if(typeof analytics!=="undefined"&&typeof analytics.subscribe==="function"){try{analytics.subscribe("page_viewed",event=>{sendEvent("pageload");console.log("\u2705 Shopify pageload"+event)});analytics.subscribe("payment_info_submitted",event=>{sendEvent("payment_info_submitted");console.log("\u2705 Shopify payment_info_submitted "+event)});analytics.subscribe("checkout_started",event=>{sendEvent("checkout_started");console.log("\u2705 Shopify Conversion Started "+event)});analytics.subscribe("checkout_completed",event=>{const products=[];const lineItems=((event.data||{}).checkout||{}).lineItems||[];for(let product of lineItems){const{variant={},quantity=0,finalLinePrice={}}=product||{};products.push({productId:((variant||{}).product||{}).id||"",productName:((variant||{}).product||{}).title||"",productPrice:((variant||{}).price||{}).amount||0,productBrand:((variant||{}).price||{}).vendor||"",productQuantity:quantity||0,purchaseValue:finalLinePrice.amount||0})}const checkout=(event.data||{}).checkout||{};const{order={},email="",billingAddress={},totalTax={}}=checkout;const payload={orderId:(order||{}).id||"",userId:((order||{}).customer||{}).id||"",userEmail:email||"",userFirstName:billingAddress.firstName||"",userLastName:billingAddress.lastName||"",tax:totalTax.amount||0,products};sendEvent("purchase",payload);console.log("\u2705 Shopify Conversion complete ended "+event)})}catch(err){console.warn("Shopify Customer Events subscription failed:",err)}}})();