@webority/analytics 0.19.2 → 0.20.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.
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import{readFileSync as Ue}from"node:fs";import{resolve as re}from"node:path";import{parseArgs as Fe}from"node:util";import{existsSync as F,readdirSync as Ee,readFileSync as B}from"node:fs";import{basename as ge,dirname as K,join as $e,relative as G,resolve as j,sep as ye}from"node:path";var u=Object.freeze({SIGNUP_STARTED:"signup_started",SIGNUP_COMPLETED:"signup_completed",LOGIN_SUCCEEDED:"login_succeeded",ONBOARDING_STARTED:"onboarding_started",ONBOARDING_STEP_COMPLETED:"onboarding_step_completed",ONBOARDING_COMPLETED:"onboarding_completed",SUBSCRIPTION_ACTIVATED:"subscription_activated",SUBSCRIPTION_CANCELLED:"subscription_cancelled",PAYMENT_SUCCEEDED:"payment_succeeded",PAYMENT_FAILED:"payment_failed",FEEDBACK_SUBMITTED:"feedback_submitted",LEAD_SUBMITTED:"lead_submitted",LEAD_QUALIFIED:"lead_qualified",WHATSAPP_CLICK:"whatsapp_click",CALCULATOR_USE:"calculator_use",PHONE_CLICK:"phone_click",DEMO_BOOKED:"demo_booked",CONTACT_SUBMITTED:"contact_submitted",TRIAL_START_CLICK:"trial_start_click",SAMPLE_REPORT_DOWNLOAD:"sample_report_download",REPORT_VERIFIED:"report_verified",CONTENT_ENGAGED:"content_engaged"}),Ge=Object.freeze({signupStarted:u.SIGNUP_STARTED,signupCompleted:u.SIGNUP_COMPLETED,loginSucceeded:u.LOGIN_SUCCEEDED,onboardingStarted:u.ONBOARDING_STARTED,onboardingStepCompleted:u.ONBOARDING_STEP_COMPLETED,onboardingCompleted:u.ONBOARDING_COMPLETED,subscriptionActivated:u.SUBSCRIPTION_ACTIVATED,subscriptionCancelled:u.SUBSCRIPTION_CANCELLED,paymentSucceeded:u.PAYMENT_SUCCEEDED,paymentFailed:u.PAYMENT_FAILED,feedbackSubmitted:u.FEEDBACK_SUBMITTED,leadSubmitted:u.LEAD_SUBMITTED,leadQualified:u.LEAD_QUALIFIED,whatsappClick:u.WHATSAPP_CLICK,calculatorUse:u.CALCULATOR_USE,phoneClick:u.PHONE_CLICK,demoBooked:u.DEMO_BOOKED,contactSubmitted:u.CONTACT_SUBMITTED,trialStartClick:u.TRIAL_START_CLICK,sampleReportDownload:u.SAMPLE_REPORT_DOWNLOAD,reportVerified:u.REPORT_VERIFIED,contentEngaged:u.CONTENT_ENGAGED}),T=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;var P={"(":")","[":"]","{":"}"},I=new Set([")","]","}"]),ce=/[A-Za-z_$]/,pe=/[A-Za-z0-9_$]/;function w(e,n=new Map){let s=x(e,"csharp"),o=R(s),t=[],r=/\bconst\s+string\s+(\w+)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([A-Za-z_][\w.]*))\s*;/g;for(let i of s.matchAll(r)){let c=i[2]??null;if(c===null){let a=i[3].split(".");c=a.length>=2&&a.at(-2)==="AnalyticsEvents"?n.get(a.at(-1))??null:null}t.push({name:i[1],value:c,line:o(i.index)})}return t}function M(e){let n=x(e,"javascript"),s=R(n),o=[],t=/([A-Za-z_$][\w$]*)\s*:\s*(?:"((?:[^"\\]|\\.)*)"|'((?:[^'\\]|\\.)*)')/g;for(let r of n.matchAll(t))o.push({name:r[1],value:r[2]??r[3],line:s(r.index)});return o}function U(e,n,s){if(n.length===0)return[];let o=x(e,s),t=n.map(he).join("|"),r=new RegExp(`(?<![\\w$.])(?:${t})((?:\\.[A-Za-z_$][\\w$]*)+)`,"g"),i=R(o),c=[];for(let a of o.matchAll(r)){if(me(o,a.index,s))continue;let p=a[1].split(".").at(-1),l=a.index+a[0].length;/^\s*\(/.test(o.slice(l,l+8))||c.push({constant:p,line:i(a.index),properties:le(o,l,s)})}return c}function le(e,n,s){let o=0,t=null;for(let r=n;r<e.length;r++){let i=S(e,r,s);if(i!==r){r=i-1;continue}let c=e[r];if(o===0){if(c===";"||c==="="&&e[r+1]===">")break;if(c==="{"){let a=de(e,r,s),p=s==="csharp"?ue(e,r,a):fe(e,r,a,s);p.length>0&&(t=[...t??[],...p]),r=a;continue}}if(P[c])o++;else if(I.has(c)){if(o===0)break;o--}}return t}function fe(e,n,s,o){let t=[],r=!0,i=0;for(let c=n+1;c<s;c++){let a=S(e,c,o);if(a!==c){if(r&&i===0&&(e[c]==='"'||e[c]==="'")){let l=e.slice(c+1,a-1);/^\s*:/.test(e.slice(a,s))&&t.push(l)}r=!1,c=a-1;continue}let p=e[c];if(P[p]){i++,r=!1;continue}if(I.has(p)){i--;continue}if(!(i>0)){if(p===","){r=!0;continue}if(!(!r||/\s/.test(p))){if(ce.test(p)){let l=c;for(;l<s&&pe.test(e[l]);)l++;let d=e.slice(l,s).trimStart();(d.startsWith(":")||d.startsWith(",")||d==="")&&t.push(e.slice(c,l)),c=l-1}r=!1}}}return t}function ue(e,n,s){let o=e.slice(n,s+1),t=[];for(let r of o.matchAll(/\[\s*"((?:[^"\\]|\\.)*)"\s*\]\s*=(?!=)/g))t.push(r[1]);for(let r of o.matchAll(/\{\s*"((?:[^"\\]|\\.)*)"\s*,/g))r.index>0&&t.push(r[1]);return t}function de(e,n,s){let o=0;for(let t=n;t<e.length;t++){let r=S(e,t,s);if(r!==t){t=r-1;continue}if(P[e[t]])o++;else if(I.has(e[t])&&--o===0)return t}return e.length-1}function S(e,n,s){let o=e[n];if(s==="csharp"&&o==="@"&&e[n+1]==='"'){let r=n+2;for(;r<e.length;){if(e[r]==='"'&&e[r+1]==='"'){r+=2;continue}if(e[r]==='"')return r+1;r++}return e.length}if(o!=='"'&&o!=="'"&&!(o==="`"&&s==="javascript"))return n;let t=n+1;for(;t<e.length&&e[t]!==o;){if(e[t]==="\\")t++;else if(e[t]===`
3
+ `&&o!=="`")return t;t++}return t+1}function me(e,n,s){let o=e.lastIndexOf(`
4
+ `,n)+1;for(let t=o;t<n;t++){let r=S(e,t,s);if(r!==t){if(r>n)return!0;t=r-1}}return!1}function x(e,n){let s=e.replace(/\r\n?/g,`
5
+ `),o="";for(let t=0;t<s.length;t++){let r=S(s,t,n);if(r!==t){o+=s.slice(t,r),t=r-1;continue}if(s[t]==="/"&&s[t+1]==="/"){let i=s.indexOf(`
6
+ `,t),c=i===-1?s.length:i;o+=" ".repeat(c-t),t=c-1;continue}if(s[t]==="/"&&s[t+1]==="*"){let i=s.indexOf("*/",t+2),c=i===-1?s.length:i+2;o+=s.slice(t,c).replace(/[^\n]/g," "),t=c-1;continue}o+=s[t]}return o}function R(e){let n=[];for(let s=e.indexOf(`
7
+ `);s!==-1;s=e.indexOf(`
8
+ `,s+1))n.push(s);return s=>{let o=0,t=n.length;for(;o<t;){let r=o+t>>>1;n[r]<s?o=r+1:t=r}return o+1}}function he(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var _e={csharp:new Set([".cs"]),javascript:new Set([".js",".jsx",".mjs",".cjs",".ts",".tsx"])},be=/^(node_modules|bin|obj|dist|build|coverage|\.git|\.expo|__tests__|__mocks__|tests?)$|\.Tests?$/i,Se=/\.(test|spec)\.[cm]?[jt]sx?$|\.d\.ts$/i;function Ae(e){let n=new Map;for(let[s,o]of e.events)o.origin==="fleet"&&n.set(ve(s),s);return n}function z(e,n){let s=[],o=(i,c,a)=>s.push({file:i?W(G(n,i)):null,line:c,message:a}),t=Ae(e),r={constants:0,callSites:0,files:0};for(let i of e.sources){let c=new Map,a=new Set(i.ignoreConstants??[]),p=new Set;for(let E of i.constants??[]){let h=j(n,E);if(p.add(h),!F(h)){o(null,null,`${i.sender}: constants file ${E} does not exist`);continue}let $=B(h,"utf8"),D=i.language==="csharp"?w($,t):M($);for(let f of D){if(a.has(f.name))continue;if(r.constants++,f.value===null){o(h,f.line,`${f.name} is not a string literal or an AnalyticsEvents constant, so its event name cannot be read`);continue}if(!T.test(f.value)){o(h,f.line,`${f.name} = "${f.value}" is not a snake_case event name (list it in ignoreConstants if it is not an event)`);continue}e.events.has(f.value)||o(h,f.line,`event "${f.value}" (${f.name}) is not in the ${e.product} tracking plan`);let y=c.get(f.name);y!==void 0&&y!==f.value&&o(h,f.line,`${f.name} is declared twice with different events ("${y}" and "${f.value}")`),c.set(f.name,f.value)}}let l=i.references??[],d=i.language==="csharp",g=d?[...new Set([...l,"AnalyticsEvents"])]:l;if(g.length!==0)for(let E of i.scan??[]){let h=j(n,E);if(!F(h)){o(null,null,`${i.sender}: scan folder ${E} does not exist`);continue}for(let $ of Y(h,_e[i.language],i.exclude??[],n)){if(p.has($))continue;r.files++;let D=B($,"utf8");for(let f of U(D,g,i.language)){if(a.has(f.constant))continue;let y=c.get(f.constant)??(d?t.get(f.constant):void 0);if(y===void 0){i.language==="javascript"&&o($,f.line,`${f.constant} is not an event constant in ${i.constants.join(", ")}`);continue}r.callSites++;let N=e.events.get(y);if(N){N.senders.includes(i.sender)||o($,f.line,`event "${y}" is sent by ${i.sender}, which its plan entry does not list as a sender`);for(let C of f.properties??[])!N.properties.has(C)&&!e.commonProperties.has(C)&&o($,f.line,`event "${y}" sends property "${C}", which the plan does not declare`)}}}}}return{problems:s,summary:r}}function*Y(e,n,s,o){let t=Ee(e,{withFileTypes:!0}).sort((r,i)=>r.name<i.name?-1:r.name>i.name?1:0);for(let r of t){let i=$e(e,r.name),c=W(G(o,i));s.some(a=>c===a||c.startsWith(`${a}/`)||r.name===a)||(r.isDirectory()?be.test(r.name)||(yield*Y(i,n,s,o)):r.isFile()&&n.has(Te(r.name))&&!Se.test(r.name)&&(yield i))}}function Te(e){let n=e.lastIndexOf(".");return n===-1?"":e.slice(n).toLowerCase()}function V(e){let n=K(j(e));return ge(n)===".webority"?K(n):n}function ve(e){return e.split("_").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("")}function W(e){return e.split(ye).join("/")}import{readFileSync as Oe}from"node:fs";import{dirname as De,resolve as X}from"node:path";var q="@webority/analytics/fleet",H=Object.freeze(["acquisition","activation","engagement","retention","revenue","referral","support","quality"]),v=Object.freeze(["none","pseudonymous","personal"]),J=Object.freeze(["string","integer","number","boolean","array","object"]),Q=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/,ee=new Set(["properties","senders"]),Ne=new Set(["$schema","product","extends","description","commonProperties","events","sources"]),Ce=new Set(["description","stage","owner","personalData","senders","properties"]),Pe=new Set(["type","description","values","nullable","personalData"]),Ie=new Set(["sender","language","constants","references","ignoreConstants","scan","exclude"]),xe=new Set(["csharp","javascript"]),Z=4,Re=new URL("./fleet-tracking-plan.json",import.meta.url);function te(e){return ne(X(e),0)}function ne(e,n){let s=typeof e=="string"?e:"fleet-tracking-plan.json",o=[],t;try{t=JSON.parse(Oe(e,"utf8"))}catch(c){return{plan:null,problems:[`${s}: cannot read the plan (${c.message})`]}}if(o.push(...ke(t,s)),o.length>0)return{plan:null,problems:o};let r=null;if(t.extends!==void 0){if(n>=Z)return{plan:null,problems:[`${s}: "extends" is nested more than ${Z} deep`]};let c=t.extends===q?Re:X(De(String(e)),t.extends),a=ne(c,n+1);if(!a.plan)return{plan:null,problems:a.problems};r=a.plan}let i=je(r,t,s);return{plan:i.plan,problems:i.problems}}function je(e,n,s="plan"){let o=[],t=new Map,r=new Map(e?.commonProperties??[]);for(let[a,p]of e?.events??[])t.set(a,{...p,properties:new Map(p.properties),senders:[...p.senders]});for(let[a,p]of Object.entries(n.commonProperties??{})){let l=r.get(a);if(l&&l.type!==p.type){o.push(`${s}: common property "${a}" is ${p.type} here but ${l.type} in the base plan`);continue}r.set(a,{...p,origin:l?.origin??n.product})}for(let[a,p]of Object.entries(n.events??{})){let l=t.get(a);if(!l){let d=["description","stage","owner","personalData"].filter(g=>p[g]===void 0);d.length>0&&o.push(`${s}: event "${a}" is not in the base plan, so it needs description, stage, owner and personalData (missing ${d.join(", ")})`),t.set(a,{name:a,description:p.description,stage:p.stage,owner:p.owner,personalData:p.personalData,senders:[...p.senders??[]],properties:new Map(Object.entries(p.properties??{})),origin:n.product});continue}for(let d of Object.keys(p))ee.has(d)||o.push(`${s}: event "${a}" is defined by the base plan, so it may only add properties or senders (found "${d}")`);for(let d of p.senders??[])l.senders.includes(d)||l.senders.push(d);for(let[d,g]of Object.entries(p.properties??{})){let E=l.properties.get(d);if(E&&E.type!==g.type){o.push(`${s}: "${a}.${d}" is ${g.type} here but ${E.type} in the base plan`);continue}l.properties.set(d,g)}}for(let[a,p]of t)for(let l of p.properties.keys())r.has(l)&&o.push(`${s}: "${a}.${l}" is already a common property, so it must not be declared on the event`);let i=n.sources??[],c=new Set(i.map(a=>a.sender));if(i.length>0)for(let[a,p]of Object.entries(n.events??{}))for(let l of p.senders??[])c.has(l)||o.push(`${s}: event "${a}" names sender "${l}", which no source declares`);return{plan:{product:n.product,events:t,commonProperties:r,sources:i,file:s},problems:o}}function ke(e,n="plan"){let s=[],o=t=>s.push(`${n}: ${t}`);if(!_(e))return o("the plan must be a JSON object"),s;if(O(e,Ne,"the plan",o),(typeof e.product!="string"||!Q.test(e.product))&&o('"product" must be a snake_case product slug'),e.extends!==void 0&&(typeof e.extends!="string"||e.extends.length===0)&&o(`"extends" must be "${q}" or a path to another plan`),!_(e.events))o('"events" must be an object keyed by event name');else for(let[t,r]of Object.entries(e.events))Le(t,r,o);if(e.commonProperties!==void 0&&se("commonProperties",e.commonProperties,o),e.sources!==void 0)if(!Array.isArray(e.sources))o('"sources" must be an array');else for(let[t,r]of e.sources.entries())we(r,t,o);return s}function Le(e,n,s){if(T.test(e)||s(`event "${e}" is not a snake_case name`),!_(n)){s(`event "${e}" must be an object`);return}O(n,Ce,`event "${e}"`,s),Object.keys(n).every(t=>ee.has(t))||((typeof n.description!="string"||n.description.trim()==="")&&s(`event "${e}" needs a description`),H.includes(n.stage)||s(`event "${e}" stage must be one of ${H.join(", ")}`),(typeof n.owner!="string"||n.owner.trim()==="")&&s(`event "${e}" needs an owner`),v.includes(n.personalData)||s(`event "${e}" personalData must be one of ${v.join(", ")}`)),n.senders!==void 0&&(!Array.isArray(n.senders)||n.senders.some(t=>typeof t!="string"))&&s(`event "${e}" senders must be an array of sender names`),n.properties!==void 0&&se(`event "${e}"`,n.properties,s)}function se(e,n,s){if(!_(n)){s(`${e} properties must be an object keyed by property name`);return}for(let[o,t]of Object.entries(n)){if(Q.test(o)||s(`${e} property "${o}" is not a snake_case name`),!_(t)){s(`${e} property "${o}" must be an object`);continue}O(t,Pe,`${e} property "${o}"`,s),J.includes(t.type)||s(`${e} property "${o}" type must be one of ${J.join(", ")}`),t.values!==void 0&&(!Array.isArray(t.values)||t.values.length===0)&&s(`${e} property "${o}" values must be a non-empty array`),t.nullable!==void 0&&typeof t.nullable!="boolean"&&s(`${e} property "${o}" nullable must be true or false`),t.personalData!==void 0&&!v.includes(t.personalData)&&s(`${e} property "${o}" personalData must be one of ${v.join(", ")}`)}}function we(e,n,s){let o=`sources[${n}]`;if(!_(e)){s(`${o} must be an object`);return}O(e,Ie,o,s),(typeof e.sender!="string"||e.sender==="")&&s(`${o} needs a sender`),xe.has(e.language)||s(`${o} language must be csharp or javascript`);for(let t of["constants","references","ignoreConstants","scan","exclude"])e[t]!==void 0&&(!Array.isArray(e[t])||e[t].some(r=>typeof r!="string"))&&s(`${o} ${t} must be an array of strings`);(e.constants?.length??0)===0&&s(`${o} needs at least one constants file`)}function O(e,n,s,o){for(let t of Object.keys(e))n.has(t)||o(`${s} has an unknown field "${t}"`)}function _(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function oe(e,n,s={}){if(typeof n=="string"&&n.startsWith("$"))return[];let o=e.events.get(n);if(!o)return[`event "${n}" is not in the ${e.product} tracking plan`];let t=[];for(let[r,i]of Object.entries(s??{})){if(r.startsWith("$"))continue;let c=o.properties.get(r)??e.commonProperties.get(r);if(!c){t.push(`event "${n}" sends property "${r}", which the plan does not declare`);continue}let a=Me(c,i);a&&t.push(`event "${n}" property "${r}" ${a}`)}return t}function Me(e,n){return n==null?e.nullable?null:"is null, and the plan does not mark it nullable":{string:typeof n=="string",integer:Number.isInteger(n),number:typeof n=="number"&&Number.isFinite(n),boolean:typeof n=="boolean",array:Array.isArray(n),object:_(n)}[e.type]?e.values&&!e.values.includes(n)?`is "${n}", which is not one of ${e.values.join(", ")}`:null:`is ${Array.isArray(n)?"array":typeof n}, but the plan declares ${e.type}`}var ie=`usage: webority-analytics-check-events --plan <tracking-plan.json> [--root <dir>] [--events <file.jsonl>]
9
+ `,m;try{m=Fe({options:{plan:{type:"string"},root:{type:"string"},events:{type:"string"},help:{type:"boolean"}}}).values}catch(e){process.stderr.write(`${e.message}
10
+ ${ie}`),process.exit(2)}(m.help||!m.plan)&&((m.help?process.stdout:process.stderr).write(ie),process.exit(m.help?0:2));var{plan:b,problems:k}=te(m.plan);if(!b||k.length>0){process.stderr.write(`The tracking plan has ${k.length} problem(s):
11
+ `);for(let e of k)process.stderr.write(` ${e}
12
+ `);process.exit(1)}var Be=re(m.root??V(m.plan)),{problems:A,summary:L}=z(b,Be),ae=0;m.events&&Ue(re(m.events),"utf8").split(/\r?\n/).forEach((n,s)=>{if(n.trim()==="")return;let o;try{o=JSON.parse(n)}catch{A.push({file:m.events,line:s+1,message:"not a JSON object"});return}ae++;for(let t of oe(b,o.event,o.properties))A.push({file:m.events,line:s+1,message:t})});if(A.length>0){process.stderr.write(`${A.length} event problem(s) against the ${b.product} tracking plan (${m.plan}):
13
+ `);for(let{file:e,line:n,message:s}of A)process.stderr.write(` ${e?`${e}${n?`:${n}`:""}: `:""}${s}
14
+ `);process.exit(1)}var Ke=m.events?`, ${ae} captured event(s)`:"";process.stdout.write(`OK: ${b.events.size} events in the ${b.product} plan; ${L.constants} constants and ${L.callSites} call sites in ${L.files} files${Ke} all match.
15
+ `);
@@ -0,0 +1 @@
1
+ var Te=["google","googleads","adwords","youtube"],Oe=["meta","facebook","fb","instagram","ig","messenger"],be=["linkedin","lnkd"],Ae=["bing","microsoft","microsoftads","msn"],J=Object.freeze([["chatgpt",["chatgpt.com","chat.openai.com"]],["perplexity",["perplexity.ai"]],["gemini",["gemini.google.com"]],["copilot",["copilot.microsoft.com"]],["claude",["claude.ai"]],["you",["you.com"]],["phind",["phind.com"]],["deepseek",["deepseek.com"]],["grok",["grok.com"]],["meta_ai",["meta.ai"]],["poe",["poe.com"]]]),Ne=["bing.com","duckduckgo.com","search.yahoo.com","ecosia.org","search.brave.com"],ke=["google","yandex"],Le=["facebook.com","fb.com","instagram.com","linkedin.com","lnkd.in","twitter.com","t.co","x.com","reddit.com","pinterest.com","youtube.com","youtu.be","tiktok.com","whatsapp.com","threads.net","t.me","telegram.org"],d=Object.freeze({DIRECT:"direct",GOOGLE:"google",META:"meta",LINKEDIN:"linkedin",MICROSOFT:"microsoft",OTHER:"other",AI_ASSISTANT:"ai_assistant",ORGANIC_SEARCH:"organic_search",ORGANIC_SOCIAL:"organic_social",REFERRAL:"referral"});function I(e){if(!e)return d.DIRECT;let t=p(e.utmSource);if(t){let r=T(t);if(Te.includes(r))return d.GOOGLE;if(Oe.includes(r))return d.META;if(be.includes(r))return d.LINKEDIN;if(Ae.includes(r))return d.MICROSOFT}if(p(e.fbclid))return d.META;if(p(e.gclid)||p(e.gbraid)||p(e.wbraid))return d.GOOGLE;if(p(e.liFatId))return d.LINKEDIN;if(p(e.msclkid))return d.MICROSOFT;if(Q(t))return d.AI_ASSISTANT;if(t||p(e.utmMedium)||p(e.utmCampaign)||p(e.utmContent)||p(e.utmTerm))return d.OTHER;let o=ee(e.referrer);return o?X(o)?d.AI_ASSISTANT:Re(o)?d.ORGANIC_SEARCH:Le.some(r=>Z(o,r))?d.ORGANIC_SOCIAL:d.REFERRAL:d.DIRECT}function R(e){if(!e)return"";let t=Q(p(e.utmSource));if(t)return t;let n=ee(e.referrer);return n?X(n):""}function Q(e){if(!e)return"";let t=T(e);for(let[n,o]of J)if(T(n)===t||o.some(r=>T(r)===t))return n;return""}function X(e){for(let[t,n]of J)if(n.some(o=>Z(e,o)))return t;return""}function Re(e){return Ne.includes(e)?!0:ke.some(t=>{if(!e.startsWith(`${t}.`))return!1;let n=e.slice(t.length+1).split(".");return n.length===1||n.length===2&&(n[0]==="co"||n[0]==="com")})}function Z(e,t){return e===t||e.endsWith(`.${t}`)}function ee(e){let t=p(e);if(!t)return"";try{let n=new URL(/^[a-z][a-z0-9+.-]*:\/\//i.test(t)?t:`https://${t}`).hostname.toLowerCase();return n.startsWith("www.")?n.slice(4):n}catch{return""}}function T(e){return String(e).toLowerCase().replace(/[^\p{L}\p{N}]/gu,"")}function p(e){return String(e??"").trim()}var D=Object.freeze(["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO","GB","CH"]);function De(e){let t=typeof e=="string"?e.trim().toUpperCase():"";return t.length!==2||t==="XX"||t==="T1"?!0:D.includes(t)}var O="webority_cookie_consent",ne="webority-consent-change",oe=365,i={initialized:!1,requiresOptIn:!0,strictOptIn:!1,adStorage:!0,cookieDays:oe,cookieDomain:null,regionCookie:null,region:null,saved:null},re=["eea","other"],v=new Set;function ve(e){let t=e?.strictOptIn??!1;if(typeof t!="boolean")throw new Error("@webority/analytics: initConsent strictOptIn must be true or false, or left out.");if(t){if(e.requiresOptIn!==void 0&&e.requiresOptIn!==!0)throw new Error("@webority/analytics: initConsent strictOptIn asks every visitor to opt in, so requiresOptIn must be true or left out.")}else if(typeof e?.requiresOptIn!="boolean")throw new Error("@webority/analytics: initConsent needs requiresOptIn (true or false), decided from the visitor's country.");if(e.cookieDomain!==void 0&&(typeof e.cookieDomain!="string"||!e.cookieDomain.trim()))throw new Error('@webority/analytics: initConsent cookieDomain must be a domain such as ".example.com", or left out.');if(e.cookieDays!==void 0&&!(Number.isInteger(e.cookieDays)&&e.cookieDays>0))throw new Error("@webority/analytics: initConsent cookieDays must be a whole number of days above zero, or left out.");if(e.adStorage!==void 0&&typeof e.adStorage!="boolean")throw new Error("@webority/analytics: initConsent adStorage must be true or false, or left out.");if(e.regionCookie!==void 0&&(typeof e.regionCookie!="string"||!/^[\w.-]+$/.test(e.regionCookie)))throw new Error('@webority/analytics: initConsent regionCookie must be a cookie name such as "wui_region", or left out.');i.initialized=!0,i.strictOptIn=t,i.requiresOptIn=t||e.requiresOptIn,i.adStorage=e.adStorage??!t,i.cookieDays=e.cookieDays??oe,i.cookieDomain=e.cookieDomain?.trim()??null,i.regionCookie=e.regionCookie??null,i.region=i.regionCookie?Ge(i.regionCookie):null;let{saved:n,entryCount:o}=Me();i.saved=n,i.cookieDomain&&o>1&&n&&ue(n),Fe(),Pe(),i.saved?F(i.saved):se()&&ce()}function xe(e){if(U("setConsentRegion"),!re.includes(e))throw new Error('@webority/analytics: setConsentRegion needs "eea" or "other".');let t=l();if(i.region=e,i.saved)return;let n=l();t.analytics===n.analytics&&t.functional===n.functional&&t.marketing===n.marketing||(ce(),ae(n))}function y(){return i.initialized}function ie(){return i.strictOptIn}function x(){return i.adStorage}function l(){U("getConsent");let e=i.saved;if(e)return{essential:!0,analytics:e.analytics,functional:e.functional,marketing:e.marketing,decided:!0};if(se())return{essential:!0,analytics:!0,functional:!0,marketing:!1,decided:!1};let t=!i.requiresOptIn;return{essential:!0,analytics:t,functional:t,marketing:t,decided:!1}}function Ue(e){U("saveConsent");let t={essential:!0,analytics:e?.analytics===!0,functional:e?.functional===!0,marketing:e?.marketing===!0,timestamp:new Date().toISOString()};ue(t),i.saved=t,F(t),ae(l())}function E(e){return v.add(e),()=>v.delete(e)}function ae(e){for(let t of v)try{t(e)}catch(n){queueMicrotask(()=>{throw n})}typeof window?.dispatchEvent=="function"&&typeof CustomEvent=="function"&&window.dispatchEvent(new CustomEvent(ne,{detail:e}))}function U(e){if(!i.initialized)throw new Error(`@webority/analytics: call initConsent before ${e}.`)}function h(){window.dataLayer=window.dataLayer||[],window.dataLayer.push(arguments)}function Fe(){if(i.strictOptIn){h("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500});return}h("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500,region:[...D]});let e=i.adStorage?"granted":"denied";h("consent","default",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:"granted",functionality_storage:"granted",personalization_storage:"granted",security_storage:"granted"})}function Pe(){h("set","ads_data_redaction",!0),h("set","url_passthrough",!0)}function se(){return i.requiresOptIn&&!i.strictOptIn&&i.region==="other"}function ce(){let e=l();F(e,e.analytics&&i.adStorage)}function F(e,t=e.marketing&&i.adStorage){let n=o=>o?"granted":"denied";h("consent","update",{analytics_storage:n(e.analytics),functionality_storage:n(e.functional),personalization_storage:n(e.functional),ad_storage:n(t),ad_user_data:n(t),ad_personalization:n(t)})}function Me(){let e=`${O}=`,t=(document.cookie||"").split(";").map(o=>o.trim()).filter(o=>o.startsWith(e)),n=t.map(o=>$e(o.slice(e.length))).filter(Boolean);return{saved:Be(n),entryCount:t.length}}function Ge(e){let t=`${e}=`,o=(document.cookie||"").split(";").map(r=>r.trim()).find(r=>r.startsWith(t))?.slice(t.length);return re.includes(o)?o:null}function $e(e){try{let t=JSON.parse(decodeURIComponent(e));return!t||typeof t!="object"?null:{essential:!0,analytics:t.analytics===!0,functional:t.functional===!0,marketing:t.marketing===!0,timestamp:t.timestamp??null}}catch{return null}}function Be(e){if(e.length===0)return null;let t=e.map(o=>typeof o.timestamp=="string"?Date.parse(o.timestamp):Number.NaN);if(t.some(Number.isNaN))return e.at(-1);let n=0;for(let o=1;o<e.length;o++)t[o]>=t[n]&&(n=o);return e[n]}function ue(e){let t=typeof e.timestamp=="string"?Date.parse(e.timestamp):Number.NaN,n=(Number.isNaN(t)?Date.now():t)+i.cookieDays*24*60*60*1e3,o=window.location?.protocol==="https:"?";Secure":"";i.cookieDomain&&te(`${O}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;max-age=0;path=/;SameSite=Lax${o}`);let r=i.cookieDomain?`;domain=${i.cookieDomain}`:"";te(`${O}=${encodeURIComponent(JSON.stringify(e))};expires=${new Date(n).toUTCString()};path=/${r};SameSite=Lax${o}`)}function te(e){document.cookie=e}var A="webority_attribution",ze=2160*60*60*1e3,je=200,P=500,qe=Object.freeze({utm_source:"utmSource",utm_medium:"utmMedium",utm_campaign:"utmCampaign",utm_content:"utmContent",utm_term:"utmTerm",gclid:"gclid",gbraid:"gbraid",wbraid:"wbraid",fbclid:"fbclid",msclkid:"msclkid",li_fat_id:"liFatId"}),le=!1;function Ke(){pe("captureAttribution"),Ye();let e=We();if(!e)return;let t=z(M());fe(M(),{firstTouch:t?.firstTouch??e,lastTouch:e}),He(e)}function He(e){let t={event:"acquisition_touch",acquisition_channel:I(e)};e.aiSource&&(t.ai_source=e.aiSource),window.dataLayer=window.dataLayer||[],window.dataLayer.push(t)}function B(){return pe("getAttribution"),z(M())}function We(){let e=new URLSearchParams(window.location.search),t={};for(let[r,c]of Object.entries(qe)){let a=b(e.get(r),je);a&&(t[c]=a)}let n=b(e.get("referrer"),P)||Ve();if(n&&(t.referrer=n),Object.keys(t).length===0)return null;let o=R(t);return o&&(t.aiSource=o),t.landingPage=b(window.location.pathname,P),t.capturedDateTimeUtc=new Date().toISOString(),t}function Ve(){let e=document.referrer;if(!e)return"";try{return new URL(e).hostname===window.location.hostname?"":b(e,P)}catch{return""}}function Ye(){le||(le=!0,E(e=>{let t=e.marketing?$():G(),n=e.marketing?G():$(),o=z(t);Je(t),o&&fe(n,o)}))}function M(){return l().marketing?G():$()}function G(){try{return window.localStorage}catch{return null}}function $(){try{return window.sessionStorage}catch{return null}}function z(e){try{let t=e?.getItem(A);if(!t)return null;let n=JSON.parse(t),o=de(n?.firstTouch),r=de(n?.lastTouch);return!o&&!r?(e.removeItem(A),null):{firstTouch:o??r,lastTouch:r??o}}catch{return null}}function fe(e,t){try{e?.setItem(A,JSON.stringify(t))}catch{}}function Je(e){try{e?.removeItem(A)}catch{}}function de(e){if(!e||typeof e!="object")return null;let t=Date.parse(e.capturedDateTimeUtc);return Number.isFinite(t)&&Date.now()-t<=ze?e:null}function b(e,t){let n=String(e??"").trim();return n?n.slice(0,t):""}function pe(e){if(!y())throw new Error(`@webority/analytics: call initConsent before ${e}.`)}var s=Object.freeze({SIGNUP_STARTED:"signup_started",SIGNUP_COMPLETED:"signup_completed",LOGIN_SUCCEEDED:"login_succeeded",ONBOARDING_STARTED:"onboarding_started",ONBOARDING_STEP_COMPLETED:"onboarding_step_completed",ONBOARDING_COMPLETED:"onboarding_completed",SUBSCRIPTION_ACTIVATED:"subscription_activated",SUBSCRIPTION_CANCELLED:"subscription_cancelled",PAYMENT_SUCCEEDED:"payment_succeeded",PAYMENT_FAILED:"payment_failed",FEEDBACK_SUBMITTED:"feedback_submitted",LEAD_SUBMITTED:"lead_submitted",LEAD_QUALIFIED:"lead_qualified",WHATSAPP_CLICK:"whatsapp_click",CALCULATOR_USE:"calculator_use",PHONE_CLICK:"phone_click",DEMO_BOOKED:"demo_booked",CONTACT_SUBMITTED:"contact_submitted",TRIAL_START_CLICK:"trial_start_click",SAMPLE_REPORT_DOWNLOAD:"sample_report_download",REPORT_VERIFIED:"report_verified",CONTENT_ENGAGED:"content_engaged"}),kt=Object.freeze({signupStarted:s.SIGNUP_STARTED,signupCompleted:s.SIGNUP_COMPLETED,loginSucceeded:s.LOGIN_SUCCEEDED,onboardingStarted:s.ONBOARDING_STARTED,onboardingStepCompleted:s.ONBOARDING_STEP_COMPLETED,onboardingCompleted:s.ONBOARDING_COMPLETED,subscriptionActivated:s.SUBSCRIPTION_ACTIVATED,subscriptionCancelled:s.SUBSCRIPTION_CANCELLED,paymentSucceeded:s.PAYMENT_SUCCEEDED,paymentFailed:s.PAYMENT_FAILED,feedbackSubmitted:s.FEEDBACK_SUBMITTED,leadSubmitted:s.LEAD_SUBMITTED,leadQualified:s.LEAD_QUALIFIED,whatsappClick:s.WHATSAPP_CLICK,calculatorUse:s.CALCULATOR_USE,phoneClick:s.PHONE_CLICK,demoBooked:s.DEMO_BOOKED,contactSubmitted:s.CONTACT_SUBMITTED,trialStartClick:s.TRIAL_START_CLICK,sampleReportDownload:s.SAMPLE_REPORT_DOWNLOAD,reportVerified:s.REPORT_VERIFIED,contentEngaged:s.CONTENT_ENGAGED}),Lt=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;var u={config:null,posthogInstance:null,posthogInitPromise:null,registeredEvents:new Set(Object.values(s)),warnedUnregisteredEvents:new Set,pendingIdentify:null},xt=50;function Ut(e){u.config=e,u.posthogInstance=null,u.posthogInitPromise=null,u.pendingIdentify=null}function Qe(){let e=u.config;return e?!!(e.enabled&&e.clientKey&&e.environment!=="Local"):!1}function N(){return y()&&l().analytics}function me(){return Qe()&&N()}var k=new Set,ge=new WeakSet,_e=null;function Mt(e){let t=j();if(!t)return!1;try{return t.isFeatureEnabled(e)===!0}catch{return!1}}function Gt(e){let t=j();if(!t)return null;try{return t.getFeatureFlag(e)??null}catch{return null}}function $t(e){k.add(e);let t=j();return(!t||_e===t)&&queueMicrotask(()=>{k.has(e)&&Ee(e)}),()=>k.delete(e)}function ye(e){u.config?.featureFlags!==!0||ge.has(e)||typeof e.onFeatureFlags!="function"||(ge.add(e),e.onFeatureFlags(()=>{_e=e;for(let t of[...k])Ee(t)}))}function j(){return u.config?.featureFlags!==!0||!me()?null:u.posthogInstance??null}function Ee(e){try{e()}catch(t){queueMicrotask(()=>{throw t})}}var Xe=new Set(["token","code","email","access_token","id_token","state","session_state","password"]),Ze=/(?:access_token|id_token|session_state|token|code|state|email|password)=/i,et=["$current_url","$referrer","$pathname","$initial_current_url","$initial_referrer","$initial_pathname","$session_entry_url","$session_entry_referrer","$session_entry_pathname"],tt=4,nt=5,ot=6;function w(e){if(typeof e!="string")return e;let t=e.indexOf("#"),n=t===-1?e:e.slice(0,t),o=t===-1||Ze.test(e.slice(t))?"":e.slice(t),r=n.indexOf("?");if(r===-1)return n+o;let c=n.slice(r+1).split("&"),a=c.filter(_=>!Xe.has(at(_)));if(a.length===c.length)return n+o;let f=n.slice(0,r),C=a.filter(_=>_!=="").join("&");return(C?`${f}?${C}`:f)+o}function Ce(e){if(!e||typeof e!="object")return e;let t=e.properties;for(let r of[t,e.$set,e.$set_once,t?.$set,t?.$set_once])it(r);let n=t?.$heatmap_data;if(n&&typeof n=="object"){let r={};for(let[c,a]of Object.entries(n)){let f=w(c);r[f]=r[f]?r[f].concat(a):a}t.$heatmap_data=r}if(t&&typeof t=="object"){for(let[r,c]of Object.entries(t))if(r.startsWith("$web_vitals_")&&r.endsWith("_event")&&c&&typeof c=="object")for(let a of["$current_url","navigationURL"])typeof c[a]=="string"&&(c[a]=w(c[a]))}let o=t?.$snapshot_data;if(e.event==="$snapshot"&&o&&typeof o=="object")for(let r of Array.isArray(o)?o:[o])rt(r);return e}function rt(e){let t=e?.data;if(!(!t||typeof t!="object")){if(e.type===tt)L(t,["href"]);else if(e.type===nt)L(t.payload,["href"]);else if(e.type===ot&&Array.isArray(t.payload?.requests))for(let n of t.payload.requests)L(n,["name","url"])}}function L(e,t){if(!(!e||typeof e!="object"))for(let n of t)typeof e[n]=="string"&&(e[n]=w(e[n]))}function it(e){L(e,et)}function at(e){let t=e.split("=",1)[0].replace(/\+/g," ");try{return decodeURIComponent(t).toLowerCase()}catch{return t.toLowerCase()}}async function Ht(){if(u.posthogInstance)return u.posthogInstance;if(u.posthogInitPromise)return u.posthogInitPromise;let e=u.config;return u.posthogInitPromise=import("posthog-js").then(t=>{let n=t.default??t,o=q(K(e),N(),e.featureFlags===!0);return n.init(e.clientKey,o),n.register({product:e.product,surface:e.surface,environment:e.environment}),N()?n.opt_in_capturing({captureEventName:!1}):n.opt_out_capturing(),u.posthogInstance=n,ye(n),n}).catch(t=>{throw u.posthogInitPromise=null,t}),u.posthogInitPromise}function q(e,t,n=!1){return t?e:{...e,opt_out_capturing_by_default:!0,...n?{advanced_disable_feature_flags_on_first_load:!0}:{}}}function K(e){let t=e.sessionRecording??{enabled:!1},n={api_host:e.host,autocapture:!1,capture_pageview:"history_change",cookieless_mode:"on_reject",person_profiles:"identified_only",persistence:"localStorage+cookie",cross_subdomain_cookie:!0,disable_session_recording:!t.enabled,enable_heatmaps:e.heatmaps===!0,capture_exceptions:e.captureExceptions===!0,capture_performance:{web_vitals:e.webVitals===!0},disable_surveys:!0,disable_product_tours:!0,disable_conversations:!0,advanced_disable_feature_flags:!(t.enabled||e.featureFlags===!0),before_send:Ce};return t.enabled&&(n.session_recording={maskAllInputs:t.maskAllInputs??!0,...t.maskTextSelector?{maskTextSelector:t.maskTextSelector}:{},maskCapturedNetworkRequestFn:o=>({...o,name:w(o.name)}),recordBody:!1,recordHeaders:!1}),n}var st=()=>import("posthog-js"),m={config:null,posthog:null,loading:null,loadPosthog:st,stopFollowingConsent:null};function ct({host:e,clientKey:t,product:n,surface:o,environment:r,enabled:c=!0,sessionRecording:a,heatmaps:f=!1,captureExceptions:C=!1,webVitals:_=!1}={}){if(!y())throw new Error("@webority/analytics: call initConsent before initSiteAnalytics.");!c||!e||!t||r==="Local"||m.config||(m.config={host:e,clientKey:t,product:n,surface:o,environment:r,sessionRecording:a,heatmaps:f,captureExceptions:C,webVitals:_},m.stopFollowingConsent=E(S=>lt(S.analytics)),m.loading=Promise.resolve().then(m.loadPosthog).then(S=>ut(S.default??S)).catch(()=>{}))}function ut(e){let t=m.config,n=l().analytics;e.init(t.clientKey,q(dt(t),n)),e.register({product:t.product,surface:t.surface,environment:t.environment}),n?e.opt_in_capturing({captureEventName:!1}):e.opt_out_capturing(),m.posthog=e}function lt(e){m.posthog&&(e?m.posthog.opt_in_capturing():m.posthog.opt_out_capturing())}function dt(e){return{...K({host:e.host,sessionRecording:e.sessionRecording,heatmaps:e.heatmaps,captureExceptions:e.captureExceptions,webVitals:e.webVitals}),capture_pageview:!0}}function Se(e,t){let n=m.config;if(!n)return;let o={...t,product:n.product,surface:n.surface,environment:n.environment};m.loading.then(()=>m.posthog?.capture(e,o)).catch(()=>{})}var ft=new Set(Object.values(s));function pt(e,t={}){if(!ft.has(e))return!1;let n=l().analytics,o=B(),r={...t};for(let[c,a]of[["first",o?.firstTouch],["last",o?.lastTouch]])a&&(r[`${c}_touch_channel`]=I(a),a.aiSource&&(r[`${c}_touch_ai_source`]=a.aiSource));return Se(e,r),n?(window.dataLayer=window.dataLayer||[],window.dataLayer.push({...r,event:e}),!0):!1}var mt=["scroll","mousemove","touchstart","keydown","pointerdown"],gt="https://www.googletagmanager.com/gtm.js",he=1500,_t=3e3,yt=100,g={loaded:!1,clarityId:null,clarityLoaded:!1,cancelClaritySchedule:null};function Et(e={}){if(!y())throw new Error("@webority/analytics: call initConsent before loadTags.");if(g.loaded)return;g.loaded=!0;let{gtmId:t,gtmUrl:n=gt,clarityId:o,ahrefsKey:r}=e;if(typeof n!="string"||n.trim()==="")throw new Error("@webority/analytics: gtmUrl must be a non-empty string.");let c=ie();if(r){let a=()=>W("https://analytics.ahrefs.com/analytics.js",{"data-key":r});c?Ie(f=>f.analytics,a):a()}if(t){let a=x(),f=Y=>Y.analytics||Y.marketing&&a,C=()=>{window.dataLayer=window.dataLayer||[],window.dataLayer.push({"gtm.start":Date.now(),event:"gtm.js"}),W(`${n}${n.includes("?")?"&":"?"}id=${encodeURIComponent(t)}`)},_=l(),S=_.decided&&f(_)?Ct:St,V=()=>S(C);c?Ie(f,V):V()}o&&(g.clarityId=o,l().analytics&&ht(),E(a=>{a.analytics&&!g.clarityLoaded?H():g.clarityLoaded&&we(a)}))}function Ie(e,t){if(e(l())){t();return}let n=E(o=>{e(o)&&(n(),t())})}function Ct(e){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e,{once:!0}):e()}function St(e){let t=!1,n=()=>{t||(t=!0,e())};for(let o of mt)window.addEventListener(o,n,{once:!0,passive:!0});document.readyState==="complete"?setTimeout(n,he):window.addEventListener("load",()=>setTimeout(n,he),{once:!0})}function ht(){let e=()=>{window.scrollY>yt&&H()};window.addEventListener("scroll",e,{passive:!0});let t=setTimeout(H,_t);g.cancelClaritySchedule=()=>{window.removeEventListener("scroll",e),clearTimeout(t)}}function H(){g.cancelClaritySchedule?.(),g.cancelClaritySchedule=null,!(g.clarityLoaded||!g.clarityId)&&(g.clarityLoaded=!0,window.clarity=window.clarity||function(){window.clarity.q=window.clarity.q||[],window.clarity.q.push(arguments)},we(l()),W(`https://www.clarity.ms/tag/${encodeURIComponent(g.clarityId)}`,{crossorigin:"anonymous"}))}function we(e){window.clarity("consentv2",{ad_Storage:e.marketing&&x()?"granted":"denied",analytics_Storage:e.analytics?"granted":"denied"})}function W(e,t={}){let n=document.createElement("script");n.async=!0,n.src=e;for(let[o,r]of Object.entries(t))n.setAttribute(o,r);document.head.appendChild(n)}export{De as a,O as b,ne as c,ve as d,xe as e,y as f,l as g,Ue as h,E as i,s as j,kt as k,Lt as l,u as m,xt as n,Ut as o,Qe as p,N as q,Mt as r,Gt as s,$t as t,Ht as u,d as v,I as w,R as x,Ke as y,B as z,ct as A,pt as B,Et as C};
@@ -0,0 +1,169 @@
1
+ {
2
+ "$schema": "./tracking-plan.schema.json",
3
+ "product": "fleet",
4
+ "description": "The fleet event vocabulary every product extends. Changing it is a fleet decision; AnalyticsEvents (C#) and events (JS) must match it.",
5
+ "commonProperties": {
6
+ "product": {
7
+ "type": "string",
8
+ "description": "The product slug, set by the package on every event."
9
+ },
10
+ "surface": {
11
+ "type": "string",
12
+ "description": "Which part of the product sent the event (portal, website, app), set by the package."
13
+ },
14
+ "environment": {
15
+ "type": "string",
16
+ "description": "The deployed environment, set by the package on every event."
17
+ },
18
+ "first_touch_channel": {
19
+ "type": "string",
20
+ "description": "Website events only: the visitor's first acquisition channel, added by trackSiteEvent."
21
+ },
22
+ "first_touch_ai_source": {
23
+ "type": "string",
24
+ "description": "Website events only: the AI assistant behind the first touch, when there was one."
25
+ },
26
+ "last_touch_channel": {
27
+ "type": "string",
28
+ "description": "Website events only: the visitor's latest acquisition channel, added by trackSiteEvent."
29
+ },
30
+ "last_touch_ai_source": {
31
+ "type": "string",
32
+ "description": "Website events only: the AI assistant behind the latest touch, when there was one."
33
+ }
34
+ },
35
+ "events": {
36
+ "signup_started": {
37
+ "description": "A visitor began the signup form.",
38
+ "stage": "acquisition",
39
+ "owner": "fleet",
40
+ "personalData": "pseudonymous"
41
+ },
42
+ "signup_completed": {
43
+ "description": "A new account exists: the signup finished.",
44
+ "stage": "acquisition",
45
+ "owner": "fleet",
46
+ "personalData": "pseudonymous"
47
+ },
48
+ "login_succeeded": {
49
+ "description": "A person signed in.",
50
+ "stage": "engagement",
51
+ "owner": "fleet",
52
+ "personalData": "pseudonymous"
53
+ },
54
+ "onboarding_started": {
55
+ "description": "A new workspace began its onboarding.",
56
+ "stage": "activation",
57
+ "owner": "fleet",
58
+ "personalData": "pseudonymous"
59
+ },
60
+ "onboarding_step_completed": {
61
+ "description": "A workspace finished one onboarding step.",
62
+ "stage": "activation",
63
+ "owner": "fleet",
64
+ "personalData": "pseudonymous"
65
+ },
66
+ "onboarding_completed": {
67
+ "description": "A workspace finished every onboarding step.",
68
+ "stage": "activation",
69
+ "owner": "fleet",
70
+ "personalData": "pseudonymous"
71
+ },
72
+ "subscription_activated": {
73
+ "description": "A paid subscription started.",
74
+ "stage": "revenue",
75
+ "owner": "fleet",
76
+ "personalData": "pseudonymous"
77
+ },
78
+ "subscription_cancelled": {
79
+ "description": "A customer cancelled their subscription.",
80
+ "stage": "retention",
81
+ "owner": "fleet",
82
+ "personalData": "pseudonymous"
83
+ },
84
+ "payment_succeeded": {
85
+ "description": "A charge was taken.",
86
+ "stage": "revenue",
87
+ "owner": "fleet",
88
+ "personalData": "pseudonymous"
89
+ },
90
+ "payment_failed": {
91
+ "description": "A charge was declined or failed.",
92
+ "stage": "revenue",
93
+ "owner": "fleet",
94
+ "personalData": "pseudonymous"
95
+ },
96
+ "feedback_submitted": {
97
+ "description": "A person sent product feedback.",
98
+ "stage": "support",
99
+ "owner": "fleet",
100
+ "personalData": "pseudonymous"
101
+ },
102
+ "lead_submitted": {
103
+ "description": "A website visitor sent an enquiry or lead form.",
104
+ "stage": "acquisition",
105
+ "owner": "fleet",
106
+ "personalData": "none"
107
+ },
108
+ "lead_qualified": {
109
+ "description": "Sales marked a lead as qualified.",
110
+ "stage": "acquisition",
111
+ "owner": "fleet",
112
+ "personalData": "pseudonymous"
113
+ },
114
+ "whatsapp_click": {
115
+ "description": "A website visitor opened a WhatsApp chat.",
116
+ "stage": "acquisition",
117
+ "owner": "fleet",
118
+ "personalData": "none"
119
+ },
120
+ "calculator_use": {
121
+ "description": "A website visitor used a calculator or estimator.",
122
+ "stage": "acquisition",
123
+ "owner": "fleet",
124
+ "personalData": "none"
125
+ },
126
+ "phone_click": {
127
+ "description": "A website visitor tapped a phone number.",
128
+ "stage": "acquisition",
129
+ "owner": "fleet",
130
+ "personalData": "none"
131
+ },
132
+ "demo_booked": {
133
+ "description": "A visitor booked a demo.",
134
+ "stage": "acquisition",
135
+ "owner": "fleet",
136
+ "personalData": "none"
137
+ },
138
+ "contact_submitted": {
139
+ "description": "A website visitor sent the contact form.",
140
+ "stage": "acquisition",
141
+ "owner": "fleet",
142
+ "personalData": "none"
143
+ },
144
+ "trial_start_click": {
145
+ "description": "A website visitor clicked to start a trial.",
146
+ "stage": "acquisition",
147
+ "owner": "fleet",
148
+ "personalData": "none"
149
+ },
150
+ "sample_report_download": {
151
+ "description": "A website visitor downloaded a sample report.",
152
+ "stage": "acquisition",
153
+ "owner": "fleet",
154
+ "personalData": "none"
155
+ },
156
+ "report_verified": {
157
+ "description": "A third party checked a published report's verification code.",
158
+ "stage": "referral",
159
+ "owner": "fleet",
160
+ "personalData": "none"
161
+ },
162
+ "content_engaged": {
163
+ "description": "A visitor read a marketing page deeply: scroll depth, an FAQ item opened, a guide read.",
164
+ "stage": "acquisition",
165
+ "owner": "fleet",
166
+ "personalData": "none"
167
+ }
168
+ }
169
+ }
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import{existsSync as ne,readFileSync as se,writeFileSync as oe}from"node:fs";import{basename as re,resolve as ie}from"node:path";import{parseArgs as ae}from"node:util";var c=Object.freeze({SIGNUP_STARTED:"signup_started",SIGNUP_COMPLETED:"signup_completed",LOGIN_SUCCEEDED:"login_succeeded",ONBOARDING_STARTED:"onboarding_started",ONBOARDING_STEP_COMPLETED:"onboarding_step_completed",ONBOARDING_COMPLETED:"onboarding_completed",SUBSCRIPTION_ACTIVATED:"subscription_activated",SUBSCRIPTION_CANCELLED:"subscription_cancelled",PAYMENT_SUCCEEDED:"payment_succeeded",PAYMENT_FAILED:"payment_failed",FEEDBACK_SUBMITTED:"feedback_submitted",LEAD_SUBMITTED:"lead_submitted",LEAD_QUALIFIED:"lead_qualified",WHATSAPP_CLICK:"whatsapp_click",CALCULATOR_USE:"calculator_use",PHONE_CLICK:"phone_click",DEMO_BOOKED:"demo_booked",CONTACT_SUBMITTED:"contact_submitted",TRIAL_START_CLICK:"trial_start_click",SAMPLE_REPORT_DOWNLOAD:"sample_report_download",REPORT_VERIFIED:"report_verified",CONTENT_ENGAGED:"content_engaged"}),pe=Object.freeze({signupStarted:c.SIGNUP_STARTED,signupCompleted:c.SIGNUP_COMPLETED,loginSucceeded:c.LOGIN_SUCCEEDED,onboardingStarted:c.ONBOARDING_STARTED,onboardingStepCompleted:c.ONBOARDING_STEP_COMPLETED,onboardingCompleted:c.ONBOARDING_COMPLETED,subscriptionActivated:c.SUBSCRIPTION_ACTIVATED,subscriptionCancelled:c.SUBSCRIPTION_CANCELLED,paymentSucceeded:c.PAYMENT_SUCCEEDED,paymentFailed:c.PAYMENT_FAILED,feedbackSubmitted:c.FEEDBACK_SUBMITTED,leadSubmitted:c.LEAD_SUBMITTED,leadQualified:c.LEAD_QUALIFIED,whatsappClick:c.WHATSAPP_CLICK,calculatorUse:c.CALCULATOR_USE,phoneClick:c.PHONE_CLICK,demoBooked:c.DEMO_BOOKED,contactSubmitted:c.CONTACT_SUBMITTED,trialStartClick:c.TRIAL_START_CLICK,sampleReportDownload:c.SAMPLE_REPORT_DOWNLOAD,reportVerified:c.REPORT_VERIFIED,contentEngaged:c.CONTENT_ENGAGED}),O=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;function b(e){return e.split("_").map(o=>o.charAt(0).toUpperCase()+o.slice(1)).join("")}function C(e,{sender:o=null,productOnly:t=!1}={}){return[...e.events.values()].filter(n=>(!o||n.senders.includes(o))&&(!t||n.origin===e.product))}function N(e,{exportName:o="events",keys:t="constant",planLabel:n="tracking-plan.json"}={}){let s=[`// Generated by webority-analytics-generate-events from ${n}. Do not edit: change the plan and run the generator.`,`export const ${o} = Object.freeze({`];for(let r of e)s.push(` // ${v(r.description)} (${r.stage})`),s.push(` ${t==="pascal"?b(r.name):r.name.toUpperCase()}: "${r.name}",`);return s.push("});",""),s.join(`
3
+ `)}function P(e,{namespace:o,className:t,accessibility:n="public",planLabel:s="tracking-plan.json"}){let r=["// <auto-generated>",`// Generated by webority-analytics-generate-events from ${s}. Do not edit: change the plan and run the generator.`,"// </auto-generated>","",`namespace ${o};`,"","/// <summary>",`/// Event names from ${D(s)}.`,"/// </summary>",`${n} static class ${t}`,"{"];return e.forEach((d,f)=>{f>0&&r.push(""),r.push(` /// <summary>${D(v(d.description))} Stage: ${d.stage}.</summary>`),r.push(` public const string ${b(d.name)} = "${d.name}";`)}),r.push("}",""),r.join(`
4
+ `)}function v(e){return String(e??"").replace(/\s+/g," ").trim()}function D(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}import{readFileSync as Y}from"node:fs";import{dirname as z,resolve as k}from"node:path";var R="@webority/analytics/fleet",j=Object.freeze(["acquisition","activation","engagement","retention","revenue","referral","support","quality"]),g=Object.freeze(["none","pseudonymous","personal"]),x=Object.freeze(["string","integer","number","boolean","array","object"]),L=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/,w=new Set(["properties","senders"]),V=new Set(["$schema","product","extends","description","commonProperties","events","sources"]),W=new Set(["description","stage","owner","personalData","senders","properties"]),H=new Set(["type","description","values","nullable","personalData"]),J=new Set(["sender","language","constants","references","ignoreConstants","scan","exclude"]),X=new Set(["csharp","javascript"]),I=4,q=new URL("./fleet-tracking-plan.json",import.meta.url);function U(e){return M(k(e),0)}function M(e,o){let t=typeof e=="string"?e:"fleet-tracking-plan.json",n=[],s;try{s=JSON.parse(Y(e,"utf8"))}catch(f){return{plan:null,problems:[`${t}: cannot read the plan (${f.message})`]}}if(n.push(...Z(s,t)),n.length>0)return{plan:null,problems:n};let r=null;if(s.extends!==void 0){if(o>=I)return{plan:null,problems:[`${t}: "extends" is nested more than ${I} deep`]};let f=s.extends===R?q:k(z(String(e)),s.extends),i=M(f,o+1);if(!i.plan)return{plan:null,problems:i.problems};r=i.plan}let d=Q(r,s,t);return{plan:d.plan,problems:d.problems}}function Q(e,o,t="plan"){let n=[],s=new Map,r=new Map(e?.commonProperties??[]);for(let[i,a]of e?.events??[])s.set(i,{...a,properties:new Map(a.properties),senders:[...a.senders]});for(let[i,a]of Object.entries(o.commonProperties??{})){let l=r.get(i);if(l&&l.type!==a.type){n.push(`${t}: common property "${i}" is ${a.type} here but ${l.type} in the base plan`);continue}r.set(i,{...a,origin:l?.origin??o.product})}for(let[i,a]of Object.entries(o.events??{})){let l=s.get(i);if(!l){let u=["description","stage","owner","personalData"].filter(y=>a[y]===void 0);u.length>0&&n.push(`${t}: event "${i}" is not in the base plan, so it needs description, stage, owner and personalData (missing ${u.join(", ")})`),s.set(i,{name:i,description:a.description,stage:a.stage,owner:a.owner,personalData:a.personalData,senders:[...a.senders??[]],properties:new Map(Object.entries(a.properties??{})),origin:o.product});continue}for(let u of Object.keys(a))w.has(u)||n.push(`${t}: event "${i}" is defined by the base plan, so it may only add properties or senders (found "${u}")`);for(let u of a.senders??[])l.senders.includes(u)||l.senders.push(u);for(let[u,y]of Object.entries(a.properties??{})){let h=l.properties.get(u);if(h&&h.type!==y.type){n.push(`${t}: "${i}.${u}" is ${y.type} here but ${h.type} in the base plan`);continue}l.properties.set(u,y)}}for(let[i,a]of s)for(let l of a.properties.keys())r.has(l)&&n.push(`${t}: "${i}.${l}" is already a common property, so it must not be declared on the event`);let d=o.sources??[],f=new Set(d.map(i=>i.sender));if(d.length>0)for(let[i,a]of Object.entries(o.events??{}))for(let l of a.senders??[])f.has(l)||n.push(`${t}: event "${i}" names sender "${l}", which no source declares`);return{plan:{product:o.product,events:s,commonProperties:r,sources:d,file:t},problems:n}}function Z(e,o="plan"){let t=[],n=s=>t.push(`${o}: ${s}`);if(!m(e))return n("the plan must be a JSON object"),t;if(E(e,V,"the plan",n),(typeof e.product!="string"||!L.test(e.product))&&n('"product" must be a snake_case product slug'),e.extends!==void 0&&(typeof e.extends!="string"||e.extends.length===0)&&n(`"extends" must be "${R}" or a path to another plan`),!m(e.events))n('"events" must be an object keyed by event name');else for(let[s,r]of Object.entries(e.events))ee(s,r,n);if(e.commonProperties!==void 0&&B("commonProperties",e.commonProperties,n),e.sources!==void 0)if(!Array.isArray(e.sources))n('"sources" must be an array');else for(let[s,r]of e.sources.entries())te(r,s,n);return t}function ee(e,o,t){if(O.test(e)||t(`event "${e}" is not a snake_case name`),!m(o)){t(`event "${e}" must be an object`);return}E(o,W,`event "${e}"`,t),Object.keys(o).every(s=>w.has(s))||((typeof o.description!="string"||o.description.trim()==="")&&t(`event "${e}" needs a description`),j.includes(o.stage)||t(`event "${e}" stage must be one of ${j.join(", ")}`),(typeof o.owner!="string"||o.owner.trim()==="")&&t(`event "${e}" needs an owner`),g.includes(o.personalData)||t(`event "${e}" personalData must be one of ${g.join(", ")}`)),o.senders!==void 0&&(!Array.isArray(o.senders)||o.senders.some(s=>typeof s!="string"))&&t(`event "${e}" senders must be an array of sender names`),o.properties!==void 0&&B(`event "${e}"`,o.properties,t)}function B(e,o,t){if(!m(o)){t(`${e} properties must be an object keyed by property name`);return}for(let[n,s]of Object.entries(o)){if(L.test(n)||t(`${e} property "${n}" is not a snake_case name`),!m(s)){t(`${e} property "${n}" must be an object`);continue}E(s,H,`${e} property "${n}"`,t),x.includes(s.type)||t(`${e} property "${n}" type must be one of ${x.join(", ")}`),s.values!==void 0&&(!Array.isArray(s.values)||s.values.length===0)&&t(`${e} property "${n}" values must be a non-empty array`),s.nullable!==void 0&&typeof s.nullable!="boolean"&&t(`${e} property "${n}" nullable must be true or false`),s.personalData!==void 0&&!g.includes(s.personalData)&&t(`${e} property "${n}" personalData must be one of ${g.join(", ")}`)}}function te(e,o,t){let n=`sources[${o}]`;if(!m(e)){t(`${n} must be an object`);return}E(e,J,n,t),(typeof e.sender!="string"||e.sender==="")&&t(`${n} needs a sender`),X.has(e.language)||t(`${n} language must be csharp or javascript`);for(let s of["constants","references","ignoreConstants","scan","exclude"])e[s]!==void 0&&(!Array.isArray(e[s])||e[s].some(r=>typeof r!="string"))&&t(`${n} ${s} must be an array of strings`);(e.constants?.length??0)===0&&t(`${n} needs at least one constants file`)}function E(e,o,t,n){for(let s of Object.keys(e))o.has(s)||n(`${t} has an unknown field "${s}"`)}function m(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var S=`usage: webority-analytics-generate-events --plan <tracking-plan.json> [--js <file> [--js-export <name>] [--js-keys constant|pascal]] [--cs <file> --cs-namespace <ns> --cs-class <name> [--cs-internal]] [--sender <sender>] [--product-only] [--check]
5
+ `,p;try{p=ae({options:{plan:{type:"string"},js:{type:"string"},"js-export":{type:"string"},"js-keys":{type:"string"},cs:{type:"string"},"cs-namespace":{type:"string"},"cs-class":{type:"string"},"cs-internal":{type:"boolean"},sender:{type:"string"},"product-only":{type:"boolean"},check:{type:"boolean"},help:{type:"boolean"}}}).values}catch(e){process.stderr.write(`${e.message}
6
+ ${S}`),process.exit(2)}p.help&&(process.stdout.write(S),process.exit(0));var F=ce(p);F&&(process.stderr.write(`${F}
7
+ ${S}`),process.exit(2));var{plan:G,problems:_}=U(p.plan);if(!G||_.length>0){process.stderr.write(`The tracking plan has ${_.length} problem(s):
8
+ `);for(let e of _)process.stderr.write(` ${e}
9
+ `);process.exit(1)}var T=C(G,{sender:p.sender??null,productOnly:p["product-only"]??!1}),A=re(p.plan),$=[];p.js&&$.push([p.js,N(T,{exportName:p["js-export"]??"events",keys:p["js-keys"]??"constant",planLabel:A})]);p.cs&&$.push([p.cs,P(T,{namespace:p["cs-namespace"],className:p["cs-class"],accessibility:p["cs-internal"]?"internal":"public",planLabel:A})]);var K=0;for(let[e,o]of $){let t=ie(e);if(p.check){let n=ne(t)?se(t,"utf8").replace(/\r\n/g,`
10
+ `):null;n!==o&&(K++,process.stderr.write(`${e} is ${n===null?"missing":"out of date"}; run webority-analytics-generate-events without --check
11
+ `));continue}oe(t,o),process.stdout.write(`Wrote ${T.length} events to ${e}
12
+ `)}K>0&&process.exit(1);p.check&&process.stdout.write(`OK: ${$.length} generated file(s) match ${A}.
13
+ `);function ce(e){return e.plan?!e.js&&!e.cs?"pass --js, --cs or both":e.cs&&(!e["cs-namespace"]||!e["cs-class"])?"--cs needs --cs-namespace and --cs-class":e["js-keys"]&&!["constant","pascal"].includes(e["js-keys"])?"--js-keys is constant or pascal":null:"--plan is required"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{A as P,a as y,b as w,c as C,d as b,e as x,f as u,g as _,h as A,i as c,j as k,k as p,l as d,m as n,n as g,o as h,p as i,q as o,r as m,s,t as N,u as T,v as O,w as R,x as S,z as U}from"./chunk-VYUXRZLH.js";var E=null;function V(e){if(!u())throw new Error("@webority/analytics: call initConsent before initAnalytics.");E?.(),E=c(t=>j(t.analytics)),h({host:e.host,clientKey:e.clientKey,product:e.product,surface:e.surface,environment:e.environment,enabled:e.enabled??!0,logger:e.logger??null,sessionRecording:{enabled:e.sessionRecording?.enabled??!1,maskAllInputs:e.sessionRecording?.maskAllInputs??!0,maskTextSelector:e.sessionRecording?.maskTextSelector??null},heatmaps:e.heatmaps??!1,captureExceptions:e.captureExceptions??!1,webVitals:e.webVitals??!1}),i()&&z()}function z(){let e=()=>{i()&&v()};typeof requestIdleCallback=="function"?requestIdleCallback(e,{timeout:3e3}):setTimeout(e,0)}function v(){s().catch(()=>{})}function j(e){if(i()){if(e){n.posthogInstance?(n.posthogInstance.opt_in_capturing(),I(n.posthogInstance)):s().then(I).catch(()=>{});return}!n.posthogInstance&&!n.posthogInitPromise&&v(),q()}}function I(e){let t=n.pendingIdentify;e&&t&&o()&&e.identify(t.publicId,t.props)}function q(){if(n.posthogInstance){n.posthogInstance.opt_out_capturing();return}n.posthogInitPromise&&n.posthogInitPromise.then(e=>{o()||e?.opt_out_capturing()}).catch(()=>{})}function K(e,t={}){if(!i()){l("identify",{publicId:e,...t});return}n.pendingIdentify={publicId:e,props:t},o()&&s().then(r=>{!r||!o()||r.identify(e,t)}).catch(()=>{})}function M(e,t,r={}){if(!m()){l("group",{type:e,key:t,...r});return}s().then(a=>{!a||!o()||a.group(e,t,r)}).catch(()=>{})}function W(){n.pendingIdentify=null,n.posthogInstance&&n.posthogInstance.reset()}function H(e){for(let t of e){if(!d.test(t))throw new Error(`@webority/analytics: invalid event name "${t}". Expected snake_case.`);n.registeredEvents.add(t)}}function f(e,t={}){if(!n.registeredEvents.has(e)){L(e);return}$(e,t)}function L(e){if(n.warnedUnregisteredEvents.has(e))return;n.warnedUnregisteredEvents.size<g&&n.warnedUnregisteredEvents.add(e);let t=n.config?.logger,r=`@webority/analytics: event "${e}" is not registered, so it was dropped. Call registerEvents() first.`;if(typeof t?.warn=="function"){t.warn(r);return}if(typeof t?.info=="function"){t.info(r);return}console.warn(r)}function $(e,t){if(!i()){l(e,t);return}let r={...t,product:n.config.product,surface:n.config.surface,environment:n.config.environment};s().then(a=>{a?.capture(e,r)}).catch(()=>{})}function l(e,t){n.config?.environment==="Local"&&n.config.logger?.info(e,t)}var D=Object.freeze(Object.fromEntries(Object.entries(p).map(([e,t])=>[e,(r={})=>f(t,r)])));export{C as CONSENT_CHANGE_EVENT,w as CONSENT_COOKIE_NAME,R as captureAttribution,N as channels,k as events,S as getAttribution,_ as getConsent,M as group,K as identify,V as initAnalytics,b as initConsent,P as loadTags,c as onConsentChange,H as registerEvents,y as requiresOptIn,W as resetIdentity,O as resolveAiSource,T as resolveChannel,A as saveConsent,x as setConsentRegion,D as track,f as trackEvent,U as trackSiteEvent};
1
+ import{B as W,C as z,a as C,b,c as _,d as x,e as A,f as p,g as O,h as T,i as f,j as F,k as g,l as d,m as n,n as E,o as m,p as o,q as i,r as N,s as k,t as P,u as a,v as R,w as S,x as U,y as K,z as V}from"./chunk-DL256XM7.js";var h=null,c=new Map,G="workspace";function M(e){if(!p())throw new Error("@webority/analytics: call initConsent before initAnalytics.");h?.(),h=f(t=>q(t.analytics)),c.clear(),m({host:e.host,clientKey:e.clientKey,product:e.product,surface:e.surface,environment:e.environment,enabled:e.enabled??!0,logger:e.logger??null,sessionRecording:{enabled:e.sessionRecording?.enabled??!1,maskAllInputs:e.sessionRecording?.maskAllInputs??!0,maskTextSelector:e.sessionRecording?.maskTextSelector??null},heatmaps:e.heatmaps??!1,captureExceptions:e.captureExceptions??!1,webVitals:e.webVitals??!1,featureFlags:e.featureFlags===!0}),o()&&j()}function j(){let e=()=>{o()&&w()};typeof requestIdleCallback=="function"?requestIdleCallback(e,{timeout:3e3}):setTimeout(e,0)}function w(){a().catch(()=>{})}function q(e){if(o()){if(e){n.posthogInstance?(n.posthogInstance.opt_in_capturing(),I(n.posthogInstance),y(n.posthogInstance)):a().then(t=>{I(t),t&&y(t)}).catch(()=>{});return}!n.posthogInstance&&!n.posthogInitPromise&&w(),H()}}function I(e){if(!e||!i())return;let t=n.pendingIdentify;t&&e.identify(t.publicId,t.props);for(let[r,{key:s,props:v}]of c)e.group(r,s,v)}function y(e){n.config?.featureFlags===!0&&i()&&e.reloadFeatureFlags?.()}function H(){if(n.posthogInstance){n.posthogInstance.opt_out_capturing();return}n.posthogInitPromise&&n.posthogInitPromise.then(e=>{i()||e?.opt_out_capturing()}).catch(()=>{})}function L(e,t={}){if(!o()){l("identify",{publicId:e,...t});return}n.pendingIdentify={publicId:e,props:t},i()&&a().then(r=>{!r||!i()||r.identify(e,t)}).catch(()=>{})}function Y(e,t,r={}){if(typeof e!="string"||!e||typeof t!="string"||!t){n.config?.logger?.warn?.("@webority/analytics: group needs a type and a PublicId string, so it was dropped.");return}if(!o()){l("group",{type:e,key:t,...r});return}c.set(e,{key:t,props:r}),i()&&a().then(s=>{!s||!i()||s.group(e,t,r)}).catch(()=>{})}function $(){n.pendingIdentify=null,c.clear(),n.posthogInstance&&n.posthogInstance.reset()}function D(e){for(let t of e){if(!d.test(t))throw new Error(`@webority/analytics: invalid event name "${t}". Expected snake_case.`);n.registeredEvents.add(t)}}function u(e,t={}){if(!n.registeredEvents.has(e)){B(e);return}J(e,t)}function B(e){if(n.warnedUnregisteredEvents.has(e))return;n.warnedUnregisteredEvents.size<E&&n.warnedUnregisteredEvents.add(e);let t=n.config?.logger,r=`@webority/analytics: event "${e}" is not registered, so it was dropped. Call registerEvents() first.`;if(typeof t?.warn=="function"){t.warn(r);return}if(typeof t?.info=="function"){t.info(r);return}console.warn(r)}function J(e,t){if(!o()){l(e,t);return}let r={...t,product:n.config.product,surface:n.config.surface,environment:n.config.environment};a().then(s=>{s?.capture(e,r)}).catch(()=>{})}function l(e,t){n.config?.environment==="Local"&&n.config.logger?.info(e,t)}var Q=Object.freeze(Object.fromEntries(Object.entries(g).map(([e,t])=>[e,(r={})=>u(t,r)])));export{_ as CONSENT_CHANGE_EVENT,b as CONSENT_COOKIE_NAME,G as WORKSPACE_GROUP_TYPE,K as captureAttribution,R as channels,F as events,V as getAttribution,O as getConsent,k as getFeatureFlag,Y as group,L as identify,M as initAnalytics,x as initConsent,N as isFeatureEnabled,z as loadTags,f as onConsentChange,P as onFeatureFlags,D as registerEvents,C as requiresOptIn,$ as resetIdentity,U as resolveAiSource,S as resolveChannel,T as saveConsent,A as setConsentRegion,Q as track,u as trackEvent,W as trackSiteEvent};
@@ -1 +1 @@
1
- var r=Object.freeze({SIGNUP_STARTED:"signup_started",SIGNUP_COMPLETED:"signup_completed",LOGIN_SUCCEEDED:"login_succeeded",ONBOARDING_STARTED:"onboarding_started",ONBOARDING_STEP_COMPLETED:"onboarding_step_completed",ONBOARDING_COMPLETED:"onboarding_completed",SUBSCRIPTION_ACTIVATED:"subscription_activated",SUBSCRIPTION_CANCELLED:"subscription_cancelled",PAYMENT_SUCCEEDED:"payment_succeeded",PAYMENT_FAILED:"payment_failed",FEEDBACK_SUBMITTED:"feedback_submitted",LEAD_SUBMITTED:"lead_submitted",LEAD_QUALIFIED:"lead_qualified",WHATSAPP_CLICK:"whatsapp_click",CALCULATOR_USE:"calculator_use",PHONE_CLICK:"phone_click",DEMO_BOOKED:"demo_booked",CONTACT_SUBMITTED:"contact_submitted",TRIAL_START_CLICK:"trial_start_click",SAMPLE_REPORT_DOWNLOAD:"sample_report_download",REPORT_VERIFIED:"report_verified",CONTENT_ENGAGED:"content_engaged"}),G=Object.freeze({signupStarted:r.SIGNUP_STARTED,signupCompleted:r.SIGNUP_COMPLETED,loginSucceeded:r.LOGIN_SUCCEEDED,onboardingStarted:r.ONBOARDING_STARTED,onboardingStepCompleted:r.ONBOARDING_STEP_COMPLETED,onboardingCompleted:r.ONBOARDING_COMPLETED,subscriptionActivated:r.SUBSCRIPTION_ACTIVATED,subscriptionCancelled:r.SUBSCRIPTION_CANCELLED,paymentSucceeded:r.PAYMENT_SUCCEEDED,paymentFailed:r.PAYMENT_FAILED,feedbackSubmitted:r.FEEDBACK_SUBMITTED,leadSubmitted:r.LEAD_SUBMITTED,leadQualified:r.LEAD_QUALIFIED,whatsappClick:r.WHATSAPP_CLICK,calculatorUse:r.CALCULATOR_USE,phoneClick:r.PHONE_CLICK,demoBooked:r.DEMO_BOOKED,contactSubmitted:r.CONTACT_SUBMITTED,trialStartClick:r.TRIAL_START_CLICK,sampleReportDownload:r.SAMPLE_REPORT_DOWNLOAD,reportVerified:r.REPORT_VERIFIED,contentEngaged:r.CONTENT_ENGAGED}),I=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;var E=null;function w(e){E=e}async function S(){if(E)return E.PostHog??null;try{let e=await import("posthog-react-native");return e.PostHog??e.default?.PostHog??e.default??null}catch{return null}}function D(e){return{host:e.host,defaultOptIn:!1,personProfiles:"identified_only",captureAppLifecycleEvents:!1,enableSessionReplay:!1,preloadFeatureFlags:!1,disableRemoteFeatureFlags:!0,disableSurveys:!0}}var _="webority_analytics_consent",R=["eea","other"],v=50,N="account",n={config:null,initPromise:null,posthog:null,requiresOptIn:!0,region:null,saved:null,pendingIdentify:null,pendingGroup:null,failureReported:!1},P=new Set(Object.values(r)),u=new Set,d=new Set;function k(e){if(n.initPromise)return n.initPromise;let t=l();return n.config={host:e?.host,clientKey:e?.clientKey,product:e?.product,surface:e?.surface,environment:e?.environment,enabled:e?.enabled??!0,logger:e?.logger??null,storage:e?.storage??null},n.requiresOptIn=e?.requiresOptIn!==!1,n.initPromise=b(t).catch(c),n.initPromise}async function b(e){let t=m(),o=n.saved,i=await U(t);o&&t?await s(()=>t.setItem(_,JSON.stringify(o))):!n.saved&&i&&(n.saved=i);let p=l();if((e.analytics!==p.analytics||e.decided!==p.decided)&&T(p),!f())return;let A=await S();if(!A){c(new Error("@webority/analytics: posthog-react-native is not installed, so nothing is sent."));return}let g=new A(n.config.clientKey,D(n.config));await g.ready?.(),await g.register(C()),n.posthog=g,await y(a())}function H(e){if(!R.includes(e))throw new Error('@webority/analytics: setConsentRegion needs "eea" or "other".');let t=l();n.region=e;let o=l();t.analytics!==o.analytics&&(y(o.analytics),T(o))}async function V(e){let t={analytics:e===!0,savedAtUtc:new Date().toISOString()};n.saved=t,y(t.analytics),T(l());let o=m();o&&await s(()=>o.setItem(_,JSON.stringify(t)))}function l(){return n.saved?{analytics:n.saved.analytics,decided:!0}:{analytics:!n.requiresOptIn||n.region==="other",decided:!1}}function q(e){return d.add(e),()=>d.delete(e)}function z(e,t={}){if(n.config&&!f()){O("identify",{publicId:e,...t});return}n.pendingIdentify={publicId:e,props:t},n.posthog&&a()&&s(()=>n.posthog.identify(e,t))}function Y(e,t={}){if(n.config&&!f()){O("group",{accountPublicId:e,...t});return}n.pendingGroup={accountPublicId:e,props:t},n.posthog&&a()&&s(()=>n.posthog.group(N,e,t))}function W(){n.pendingIdentify=null,n.pendingGroup=null;let e=n.posthog;e&&s(async()=>{e.reset(),await e.register(C()),a()?await e.optIn():await e.optOut()})}function $(e){for(let t of e){if(!I.test(t))throw new Error(`@webority/analytics: invalid event name "${t}". Expected snake_case.`);P.add(t)}}function j(e,t={}){if(!P.has(e)){M(e);return}h(e,t,(o,i)=>o.capture(e,i))}function J(e,t={}){h(e,t,(o,i)=>o.screen(e,i))}function h(e,t,o){if(!f()){O(e,t);return}if(!a())return;let i={...t,...C()};if(n.posthog){s(()=>o(n.posthog,i));return}n.initPromise?.then(()=>{n.posthog&&a()&&s(()=>o(n.posthog,i))})}function y(e){let t=n.posthog;return t?s(async()=>{if(!e){await t.optOut();return}await t.optIn(),L(t)}):Promise.resolve()}function L(e){if(!a())return;let t=n.pendingIdentify;t&&e.identify(t.publicId,t.props);let o=n.pendingGroup;o&&e.group(N,o.accountPublicId,o.props)}function m(){let e=n.config?.storage??null;return n.config&&!e&&c(new Error("@webority/analytics: no storage was passed to initMobileAnalytics, so the choice lasts until the app closes.")),e}async function U(e){if(!e)return null;try{let t=await e.getItem(_);if(!t)return null;let o=JSON.parse(t);return typeof o?.analytics!="boolean"?null:{analytics:o.analytics,savedAtUtc:typeof o.savedAtUtc=="string"?o.savedAtUtc:null}}catch(t){return c(t),null}}function T(e){for(let t of d)try{t(e)}catch(o){c(o)}}function f(){let e=n.config;return!!(e?.enabled&&e.clientKey&&e.host&&e.environment!=="Local")}function a(){return l().analytics}function C(){return{product:n.config.product,surface:n.config.surface,environment:n.config.environment}}function s(e){try{return Promise.resolve(e()).then(void 0,c)}catch(t){return c(t),Promise.resolve()}}function c(e){if(n.failureReported||(n.failureReported=!0,globalThis.__DEV__!==!0))return;let t=n.config?.logger,o=typeof t?.warn=="function"?t.warn:t?.info;if(typeof o=="function")try{o.call(t,`@webority/analytics: ${e?.message??e}`)}catch{}}function M(e){if(u.has(e))return;u.size<v&&u.add(e);let t=n.config?.logger,o=`@webority/analytics: event "${e}" is not registered, so it was dropped. Call registerEvents() first.`;if(typeof t?.warn=="function"){t.warn(o);return}if(typeof t?.info=="function"){t.info(o);return}console.warn(o)}function O(e,t){n.config?.environment==="Local"&&n.config.logger?.info(e,t)}function Q(){n.config=null,n.initPromise=null,n.posthog=null,n.requiresOptIn=!0,n.region=null,n.saved=null,n.pendingIdentify=null,n.pendingGroup=null,n.failureReported=!1,u.clear(),d.clear()}export{_ as CONSENT_STORAGE_KEY,Q as __resetForTests,w as __setNativeModulesForTests,r as events,l as getAnalyticsConsent,Y as group,z as identify,k as initMobileAnalytics,q as onAnalyticsConsentChange,$ as registerEvents,W as resetIdentity,V as setAnalyticsConsent,H as setConsentRegion,j as trackEvent,J as trackScreen};
1
+ var r=Object.freeze({SIGNUP_STARTED:"signup_started",SIGNUP_COMPLETED:"signup_completed",LOGIN_SUCCEEDED:"login_succeeded",ONBOARDING_STARTED:"onboarding_started",ONBOARDING_STEP_COMPLETED:"onboarding_step_completed",ONBOARDING_COMPLETED:"onboarding_completed",SUBSCRIPTION_ACTIVATED:"subscription_activated",SUBSCRIPTION_CANCELLED:"subscription_cancelled",PAYMENT_SUCCEEDED:"payment_succeeded",PAYMENT_FAILED:"payment_failed",FEEDBACK_SUBMITTED:"feedback_submitted",LEAD_SUBMITTED:"lead_submitted",LEAD_QUALIFIED:"lead_qualified",WHATSAPP_CLICK:"whatsapp_click",CALCULATOR_USE:"calculator_use",PHONE_CLICK:"phone_click",DEMO_BOOKED:"demo_booked",CONTACT_SUBMITTED:"contact_submitted",TRIAL_START_CLICK:"trial_start_click",SAMPLE_REPORT_DOWNLOAD:"sample_report_download",REPORT_VERIFIED:"report_verified",CONTENT_ENGAGED:"content_engaged"}),K=Object.freeze({signupStarted:r.SIGNUP_STARTED,signupCompleted:r.SIGNUP_COMPLETED,loginSucceeded:r.LOGIN_SUCCEEDED,onboardingStarted:r.ONBOARDING_STARTED,onboardingStepCompleted:r.ONBOARDING_STEP_COMPLETED,onboardingCompleted:r.ONBOARDING_COMPLETED,subscriptionActivated:r.SUBSCRIPTION_ACTIVATED,subscriptionCancelled:r.SUBSCRIPTION_CANCELLED,paymentSucceeded:r.PAYMENT_SUCCEEDED,paymentFailed:r.PAYMENT_FAILED,feedbackSubmitted:r.FEEDBACK_SUBMITTED,leadSubmitted:r.LEAD_SUBMITTED,leadQualified:r.LEAD_QUALIFIED,whatsappClick:r.WHATSAPP_CLICK,calculatorUse:r.CALCULATOR_USE,phoneClick:r.PHONE_CLICK,demoBooked:r.DEMO_BOOKED,contactSubmitted:r.CONTACT_SUBMITTED,trialStartClick:r.TRIAL_START_CLICK,sampleReportDownload:r.SAMPLE_REPORT_DOWNLOAD,reportVerified:r.REPORT_VERIFIED,contentEngaged:r.CONTENT_ENGAGED}),D=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;var _=null;function R(e){_=e}async function N(){if(_)return _.PostHog??null;try{let e=await import("posthog-react-native");return e.PostHog??e.default?.PostHog??e.default??null}catch{return null}}function w(e){return{host:e.host,defaultOptIn:!1,personProfiles:"identified_only",captureAppLifecycleEvents:!1,enableSessionReplay:!1,preloadFeatureFlags:!1,disableRemoteFeatureFlags:e.featureFlags!==!0,disableSurveys:!0}}var y="webority_analytics_consent",v=["eea","other"],F=50,z="workspace",n={config:null,initPromise:null,posthog:null,requiresOptIn:!0,region:null,saved:null,pendingIdentify:null,pendingGroups:new Map,flagsLoaded:!1,failureReported:!1},P=new Set(Object.values(r)),p=new Set,E=new Set,f=new Set;function W(e){if(n.initPromise)return n.initPromise;let t=c();return n.config={host:e?.host,clientKey:e?.clientKey,product:e?.product,surface:e?.surface,environment:e?.environment,enabled:e?.enabled??!0,logger:e?.logger??null,storage:e?.storage??null,featureFlags:e?.featureFlags===!0},n.requiresOptIn=e?.requiresOptIn!==!1,n.initPromise=U(t).catch(s),n.initPromise}async function U(e){let t=b(),o=n.saved,i=await G(t);o&&t?await a(()=>t.setItem(y,JSON.stringify(o))):!n.saved&&i&&(n.saved=i);let u=c();if((e.analytics!==u.analytics||e.decided!==u.decided)&&A(u),!d())return;let S=await N();if(!S){s(new Error("@webority/analytics: posthog-react-native is not installed, so nothing is sent."));return}let g=new S(n.config.clientKey,w(n.config));await g.ready?.(),await g.register(I()),n.posthog=g,M(g),await T(l())}function Y(e){if(!v.includes(e))throw new Error('@webority/analytics: setConsentRegion needs "eea" or "other".');let t=c();n.region=e;let o=c();t.analytics!==o.analytics&&(T(o.analytics),A(o))}async function $(e){let t={analytics:e===!0,savedAtUtc:new Date().toISOString()};n.saved=t,T(t.analytics),A(c());let o=b();o&&await a(()=>o.setItem(y,JSON.stringify(t)))}function c(){return n.saved?{analytics:n.saved.analytics,decided:!0}:{analytics:!n.requiresOptIn||n.region==="other",decided:!1}}function j(e){return E.add(e),()=>E.delete(e)}function J(e,t={}){if(n.config&&!d()){O("identify",{publicId:e,...t});return}n.pendingIdentify={publicId:e,props:t},n.posthog&&l()&&a(()=>n.posthog.identify(e,t))}function Q(e,t,o={}){if(typeof e!="string"||!e||typeof t!="string"||!t){L("@webority/analytics: group needs a type and a PublicId string, so it was dropped.");return}if(n.config&&!d()){O("group",{type:e,key:t,...o});return}n.pendingGroups.set(e,{key:t,props:o}),n.posthog&&l()&&a(()=>n.posthog.group(e,t,o))}function X(e){let t=C();if(!t)return!1;try{return t.isFeatureEnabled(e)===!0}catch(o){return s(o),!1}}function Z(e){let t=C();if(!t)return null;try{return t.getFeatureFlag(e)??null}catch(o){return s(o),null}}function ee(e){return f.add(e),(!C()||n.flagsLoaded)&&queueMicrotask(()=>{f.has(e)&&m(e)}),()=>f.delete(e)}function te(){n.pendingIdentify=null,n.pendingGroups.clear();let e=n.posthog;e&&a(async()=>{e.reset(),await e.register(I()),l()?await e.optIn():await e.optOut()})}function ne(e){for(let t of e){if(!D.test(t))throw new Error(`@webority/analytics: invalid event name "${t}". Expected snake_case.`);P.add(t)}}function oe(e,t={}){if(!P.has(e)){B(e);return}h(e,t,(o,i)=>o.capture(e,i))}function re(e,t={}){h(e,t,(o,i)=>o.screen(e,i))}function h(e,t,o){if(!d()){O(e,t);return}if(!l())return;let i={...t,...I()};if(n.posthog){a(()=>o(n.posthog,i));return}n.initPromise?.then(()=>{n.posthog&&l()&&a(()=>o(n.posthog,i))})}function T(e){let t=n.posthog;return t?a(async()=>{if(!e){await t.optOut();return}await t.optIn(),x(t),n.config.featureFlags&&await t.reloadFeatureFlagsAsync?.()}):Promise.resolve()}function M(e){!n.config.featureFlags||typeof e.onFeatureFlags!="function"||a(()=>e.onFeatureFlags(()=>{n.flagsLoaded=!0;for(let t of[...f])m(t)}))}function C(){return!n.config?.featureFlags||!d()||!l()?null:n.posthog}function m(e){try{e()}catch(t){L(`@webority/analytics: a feature flag listener threw: ${t?.message??t}`)}}function x(e){if(!l())return;let t=n.pendingIdentify;t&&e.identify(t.publicId,t.props);for(let[o,{key:i,props:u}]of n.pendingGroups)e.group(o,i,u)}function b(){let e=n.config?.storage??null;return n.config&&!e&&s(new Error("@webority/analytics: no storage was passed to initMobileAnalytics, so the choice lasts until the app closes.")),e}async function G(e){if(!e)return null;try{let t=await e.getItem(y);if(!t)return null;let o=JSON.parse(t);return typeof o?.analytics!="boolean"?null:{analytics:o.analytics,savedAtUtc:typeof o.savedAtUtc=="string"?o.savedAtUtc:null}}catch(t){return s(t),null}}function A(e){for(let t of E)try{t(e)}catch(o){s(o)}}function d(){let e=n.config;return!!(e?.enabled&&e.clientKey&&e.host&&e.environment!=="Local")}function l(){return c().analytics}function I(){return{product:n.config.product,surface:n.config.surface,environment:n.config.environment}}function a(e){try{return Promise.resolve(e()).then(void 0,s)}catch(t){return s(t),Promise.resolve()}}function s(e){if(n.failureReported||(n.failureReported=!0,globalThis.__DEV__!==!0))return;let t=n.config?.logger,o=typeof t?.warn=="function"?t.warn:t?.info;if(typeof o=="function")try{o.call(t,`@webority/analytics: ${e?.message??e}`)}catch{}}function L(e){let t=n.config?.logger,o=typeof t?.warn=="function"?t.warn:t?.info;if(typeof o=="function")try{o.call(t,e)}catch{}}function B(e){if(p.has(e))return;p.size<F&&p.add(e);let t=n.config?.logger,o=`@webority/analytics: event "${e}" is not registered, so it was dropped. Call registerEvents() first.`;if(typeof t?.warn=="function"){t.warn(o);return}if(typeof t?.info=="function"){t.info(o);return}console.warn(o)}function O(e,t){n.config?.environment==="Local"&&n.config.logger?.info(e,t)}function ie(){n.config=null,n.initPromise=null,n.posthog=null,n.requiresOptIn=!0,n.region=null,n.saved=null,n.pendingIdentify=null,n.pendingGroups.clear(),n.flagsLoaded=!1,n.failureReported=!1,p.clear(),E.clear(),f.clear()}export{y as CONSENT_STORAGE_KEY,z as WORKSPACE_GROUP_TYPE,ie as __resetForTests,R as __setNativeModulesForTests,r as events,c as getAnalyticsConsent,Z as getFeatureFlag,Q as group,J as identify,W as initMobileAnalytics,X as isFeatureEnabled,j as onAnalyticsConsentChange,ee as onFeatureFlags,ne as registerEvents,te as resetIdentity,$ as setAnalyticsConsent,Y as setConsentRegion,oe as trackEvent,re as trackScreen};
package/dist/site.js CHANGED
@@ -1 +1 @@
1
- import{A as q,a,b,c,d,e,g as f,h as g,i as h,j as i,t as j,u as k,v as l,w as m,x as n,y as o,z as p}from"./chunk-VYUXRZLH.js";export{c as CONSENT_CHANGE_EVENT,b as CONSENT_COOKIE_NAME,m as captureAttribution,j as channels,i as events,n as getAttribution,f as getConsent,d as initConsent,o as initSiteAnalytics,q as loadTags,h as onConsentChange,a as requiresOptIn,l as resolveAiSource,k as resolveChannel,g as saveConsent,e as setConsentRegion,p as trackSiteEvent};
1
+ import{A as o,B as p,C as q,a,b,c,d,e,g as f,h as g,i as h,j as i,v as j,w as k,x as l,y as m,z as n}from"./chunk-DL256XM7.js";export{c as CONSENT_CHANGE_EVENT,b as CONSENT_COOKIE_NAME,m as captureAttribution,j as channels,i as events,n as getAttribution,f as getConsent,d as initConsent,o as initSiteAnalytics,q as loadTags,h as onConsentChange,a as requiresOptIn,l as resolveAiSource,k as resolveChannel,g as saveConsent,e as setConsentRegion,p as trackSiteEvent};
@@ -0,0 +1,321 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Webority tracking plan",
4
+ "description": "One product's analytics event catalogue. It extends the fleet base plan shipped in @webority/analytics; webority-analytics-check-events holds the product's code to it and webority-analytics-generate-events writes its constants.",
5
+ "type": "object",
6
+ "required": ["product", "events"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "$schema": {
10
+ "type": "string"
11
+ },
12
+ "product": {
13
+ "type": "string",
14
+ "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$",
15
+ "description": "The product slug, as the package sends it in the product property."
16
+ },
17
+ "extends": {
18
+ "type": "string",
19
+ "minLength": 1,
20
+ "description": "\"@webority/analytics/fleet\" for the fleet base, or a path to another plan relative to this file."
21
+ },
22
+ "description": {
23
+ "type": "string"
24
+ },
25
+ "commonProperties": {
26
+ "$ref": "#/$defs/properties",
27
+ "description": "Properties that may ride on every event in the plan."
28
+ },
29
+ "events": {
30
+ "type": "object",
31
+ "description": "Every event the product sends, keyed by its snake_case name.",
32
+ "propertyNames": {
33
+ "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$"
34
+ }
35
+ },
36
+ "sources": {
37
+ "type": "array",
38
+ "description": "Where the check finds the product's event constants and the code that sends them.",
39
+ "items": {
40
+ "$ref": "#/$defs/source"
41
+ }
42
+ }
43
+ },
44
+ "allOf": [
45
+ {
46
+ "description": "A plan on the fleet base may list a fleet event only to extend it; every other event needs its full entry.",
47
+ "if": {
48
+ "required": ["extends"],
49
+ "properties": {
50
+ "extends": {
51
+ "const": "@webority/analytics/fleet"
52
+ }
53
+ }
54
+ },
55
+ "then": {
56
+ "properties": {
57
+ "events": {
58
+ "properties": {
59
+ "signup_started": {
60
+ "$ref": "#/$defs/eventExtension"
61
+ },
62
+ "signup_completed": {
63
+ "$ref": "#/$defs/eventExtension"
64
+ },
65
+ "login_succeeded": {
66
+ "$ref": "#/$defs/eventExtension"
67
+ },
68
+ "onboarding_started": {
69
+ "$ref": "#/$defs/eventExtension"
70
+ },
71
+ "onboarding_step_completed": {
72
+ "$ref": "#/$defs/eventExtension"
73
+ },
74
+ "onboarding_completed": {
75
+ "$ref": "#/$defs/eventExtension"
76
+ },
77
+ "subscription_activated": {
78
+ "$ref": "#/$defs/eventExtension"
79
+ },
80
+ "subscription_cancelled": {
81
+ "$ref": "#/$defs/eventExtension"
82
+ },
83
+ "payment_succeeded": {
84
+ "$ref": "#/$defs/eventExtension"
85
+ },
86
+ "payment_failed": {
87
+ "$ref": "#/$defs/eventExtension"
88
+ },
89
+ "feedback_submitted": {
90
+ "$ref": "#/$defs/eventExtension"
91
+ },
92
+ "lead_submitted": {
93
+ "$ref": "#/$defs/eventExtension"
94
+ },
95
+ "lead_qualified": {
96
+ "$ref": "#/$defs/eventExtension"
97
+ },
98
+ "whatsapp_click": {
99
+ "$ref": "#/$defs/eventExtension"
100
+ },
101
+ "calculator_use": {
102
+ "$ref": "#/$defs/eventExtension"
103
+ },
104
+ "phone_click": {
105
+ "$ref": "#/$defs/eventExtension"
106
+ },
107
+ "demo_booked": {
108
+ "$ref": "#/$defs/eventExtension"
109
+ },
110
+ "contact_submitted": {
111
+ "$ref": "#/$defs/eventExtension"
112
+ },
113
+ "trial_start_click": {
114
+ "$ref": "#/$defs/eventExtension"
115
+ },
116
+ "sample_report_download": {
117
+ "$ref": "#/$defs/eventExtension"
118
+ },
119
+ "report_verified": {
120
+ "$ref": "#/$defs/eventExtension"
121
+ },
122
+ "content_engaged": {
123
+ "$ref": "#/$defs/eventExtension"
124
+ }
125
+ },
126
+ "additionalProperties": {
127
+ "$ref": "#/$defs/event"
128
+ }
129
+ }
130
+ }
131
+ }
132
+ },
133
+ {
134
+ "description": "A plan with no base defines every event in full.",
135
+ "if": {
136
+ "not": {
137
+ "required": ["extends"]
138
+ }
139
+ },
140
+ "then": {
141
+ "properties": {
142
+ "events": {
143
+ "additionalProperties": {
144
+ "$ref": "#/$defs/event"
145
+ }
146
+ }
147
+ }
148
+ }
149
+ },
150
+ {
151
+ "description": "A plan extending another file: the schema cannot see that base, so either entry is accepted here and webority-analytics-check-events refuses a short entry for an event the base does not define.",
152
+ "if": {
153
+ "required": ["extends"],
154
+ "properties": {
155
+ "extends": {
156
+ "not": {
157
+ "const": "@webority/analytics/fleet"
158
+ }
159
+ }
160
+ }
161
+ },
162
+ "then": {
163
+ "properties": {
164
+ "events": {
165
+ "additionalProperties": {
166
+ "anyOf": [
167
+ {
168
+ "$ref": "#/$defs/event"
169
+ },
170
+ {
171
+ "$ref": "#/$defs/eventExtension"
172
+ }
173
+ ]
174
+ }
175
+ }
176
+ }
177
+ }
178
+ }
179
+ ],
180
+ "$defs": {
181
+ "event": {
182
+ "type": "object",
183
+ "additionalProperties": false,
184
+ "properties": {
185
+ "description": {
186
+ "type": "string",
187
+ "minLength": 1,
188
+ "description": "What happened, in one sentence a reviewer can read without the code."
189
+ },
190
+ "stage": {
191
+ "enum": ["acquisition", "activation", "engagement", "retention", "revenue", "referral", "support", "quality"]
192
+ },
193
+ "owner": {
194
+ "type": "string",
195
+ "minLength": 1,
196
+ "description": "The product area accountable for the event."
197
+ },
198
+ "personalData": {
199
+ "$ref": "#/$defs/personalData"
200
+ },
201
+ "senders": {
202
+ "type": "array",
203
+ "items": {
204
+ "type": "string"
205
+ },
206
+ "description": "The sources (by sender name) that send it."
207
+ },
208
+ "properties": {
209
+ "$ref": "#/$defs/properties"
210
+ }
211
+ },
212
+ "required": ["description", "stage", "owner", "personalData"],
213
+ "description": "An event this plan defines: every field a reviewer needs is required."
214
+ },
215
+ "properties": {
216
+ "type": "object",
217
+ "propertyNames": {
218
+ "pattern": "^[a-z][a-z0-9]*(_[a-z0-9]+)*$"
219
+ },
220
+ "additionalProperties": {
221
+ "$ref": "#/$defs/property"
222
+ }
223
+ },
224
+ "property": {
225
+ "type": "object",
226
+ "required": ["type"],
227
+ "additionalProperties": false,
228
+ "properties": {
229
+ "type": {
230
+ "enum": ["string", "integer", "number", "boolean", "array", "object"]
231
+ },
232
+ "description": {
233
+ "type": "string"
234
+ },
235
+ "values": {
236
+ "type": "array",
237
+ "minItems": 1,
238
+ "description": "The only values allowed."
239
+ },
240
+ "nullable": {
241
+ "type": "boolean"
242
+ },
243
+ "personalData": {
244
+ "$ref": "#/$defs/personalData"
245
+ }
246
+ }
247
+ },
248
+ "personalData": {
249
+ "enum": ["none", "pseudonymous", "personal"],
250
+ "description": "none: nothing ties it to a person. pseudonymous: tied to a person or workspace only by an opaque public id. personal: names a person."
251
+ },
252
+ "source": {
253
+ "type": "object",
254
+ "required": ["sender", "language", "constants"],
255
+ "additionalProperties": false,
256
+ "properties": {
257
+ "sender": {
258
+ "type": "string",
259
+ "minLength": 1,
260
+ "description": "The name events list in senders, such as server, portal or app."
261
+ },
262
+ "language": {
263
+ "enum": ["csharp", "javascript"]
264
+ },
265
+ "constants": {
266
+ "type": "array",
267
+ "minItems": 1,
268
+ "items": {
269
+ "type": "string"
270
+ },
271
+ "description": "Files declaring the event-name constants, relative to the repo root."
272
+ },
273
+ "references": {
274
+ "type": "array",
275
+ "items": {
276
+ "type": "string"
277
+ },
278
+ "description": "The identifiers call sites use for those constants, such as ProductEvents."
279
+ },
280
+ "ignoreConstants": {
281
+ "type": "array",
282
+ "items": {
283
+ "type": "string"
284
+ },
285
+ "description": "Constants in those files that are not events."
286
+ },
287
+ "scan": {
288
+ "type": "array",
289
+ "items": {
290
+ "type": "string"
291
+ },
292
+ "description": "Folders whose call sites are checked."
293
+ },
294
+ "exclude": {
295
+ "type": "array",
296
+ "items": {
297
+ "type": "string"
298
+ },
299
+ "description": "Paths under the scan folders to skip."
300
+ }
301
+ }
302
+ },
303
+ "eventExtension": {
304
+ "type": "object",
305
+ "additionalProperties": false,
306
+ "description": "An entry for an event the base plan defines, adding only properties or senders.",
307
+ "properties": {
308
+ "senders": {
309
+ "type": "array",
310
+ "items": {
311
+ "type": "string"
312
+ },
313
+ "description": "The sources (by sender name) that send it."
314
+ },
315
+ "properties": {
316
+ "$ref": "#/$defs/properties"
317
+ }
318
+ }
319
+ }
320
+ }
321
+ }
@@ -1 +1 @@
1
- var WeborityAnalytics=(()=>{var D=Object.defineProperty;var kt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var Rt=Object.prototype.hasOwnProperty;var Lt=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(o){throw n=[o],o}};var K=(t,e)=>{for(var n in e)D(t,n,{get:e[n],enumerable:!0})},vt=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Dt(e))!Rt.call(t,r)&&r!==n&&D(t,r,{get:()=>e[r],enumerable:!(o=kt(e,r))||o.enumerable});return t};var xt=t=>vt(D({},"__esModule",{value:!0}),t);var St={};K(St,{default:()=>pe});function fe(){let t=[];t._i=[],t.__SV=1,t.people=[];for(let e of Et)t[e]=(...n)=>{t.push([e,...n])};t.init=(e,n)=>{t._i.push([e,n]);let o=document.createElement("script");o.async=!0,o.crossOrigin="anonymous",o.src=`${n.api_host.replace(/\/+$/,"").replace(".i.posthog.com","-assets.i.posthog.com")}/static/array.js`,document.head.appendChild(o)},window.posthog=t}var Et,Ct,pe,ht=Lt(()=>{Et=["capture","register","opt_in_capturing","opt_out_capturing"];Ct={init(t,e){window.posthog||fe(),window.posthog.init(t,e)}};for(let t of Et)Ct[t]=(...e)=>window.posthog[t](...e);pe=Ct});var Ae={};K(Ae,{CONSENT_CHANGE_EVENT:()=>v,CONSENT_COOKIE_NAME:()=>w,captureAttribution:()=>ft,channels:()=>u,events:()=>s,getAttribution:()=>N,getConsent:()=>l,initConsent:()=>nt,initSiteAnalytics:()=>wt,loadTags:()=>bt,onConsentChange:()=>g,requiresOptIn:()=>X,resolveAiSource:()=>O,resolveChannel:()=>C,saveConsent:()=>it,setConsentRegion:()=>ot,trackSiteEvent:()=>Tt});var Ut=["google","googleads","adwords","youtube"],Pt=["meta","facebook","fb","instagram","ig","messenger"],Mt=["linkedin","lnkd"],$t=["bing","microsoft","microsoftads","msn"],V=Object.freeze([["chatgpt",["chatgpt.com","chat.openai.com"]],["perplexity",["perplexity.ai"]],["gemini",["gemini.google.com"]],["copilot",["copilot.microsoft.com"]],["claude",["claude.ai"]],["you",["you.com"]],["phind",["phind.com"]],["deepseek",["deepseek.com"]],["grok",["grok.com"]],["meta_ai",["meta.ai"]],["poe",["poe.com"]]]),Gt=["bing.com","duckduckgo.com","search.yahoo.com","ecosia.org","search.brave.com"],Ft=["google","yandex"],Bt=["facebook.com","fb.com","instagram.com","linkedin.com","lnkd.in","twitter.com","t.co","x.com","reddit.com","pinterest.com","youtube.com","youtu.be","tiktok.com","whatsapp.com","threads.net","t.me","telegram.org"],u=Object.freeze({DIRECT:"direct",GOOGLE:"google",META:"meta",LINKEDIN:"linkedin",MICROSOFT:"microsoft",OTHER:"other",AI_ASSISTANT:"ai_assistant",ORGANIC_SEARCH:"organic_search",ORGANIC_SOCIAL:"organic_social",REFERRAL:"referral"});function C(t){if(!t)return u.DIRECT;let e=f(t.utmSource);if(e){let r=T(e);if(Ut.includes(r))return u.GOOGLE;if(Pt.includes(r))return u.META;if(Mt.includes(r))return u.LINKEDIN;if($t.includes(r))return u.MICROSOFT}if(f(t.fbclid))return u.META;if(f(t.gclid)||f(t.gbraid)||f(t.wbraid))return u.GOOGLE;if(f(t.liFatId))return u.LINKEDIN;if(f(t.msclkid))return u.MICROSOFT;if(W(e))return u.AI_ASSISTANT;if(e||f(t.utmMedium)||f(t.utmCampaign)||f(t.utmContent)||f(t.utmTerm))return u.OTHER;let o=J(t.referrer);return o?Y(o)?u.AI_ASSISTANT:zt(o)?u.ORGANIC_SEARCH:Bt.some(r=>Q(o,r))?u.ORGANIC_SOCIAL:u.REFERRAL:u.DIRECT}function O(t){if(!t)return"";let e=W(f(t.utmSource));if(e)return e;let n=J(t.referrer);return n?Y(n):""}function W(t){if(!t)return"";let e=T(t);for(let[n,o]of V)if(T(n)===e||o.some(r=>T(r)===e))return n;return""}function Y(t){for(let[e,n]of V)if(n.some(o=>Q(t,o)))return e;return""}function zt(t){return Gt.includes(t)?!0:Ft.some(e=>{if(!t.startsWith(`${e}.`))return!1;let n=t.slice(e.length+1).split(".");return n.length===1||n.length===2&&(n[0]==="co"||n[0]==="com")})}function Q(t,e){return t===e||t.endsWith(`.${e}`)}function J(t){let e=f(t);if(!e)return"";try{let n=new URL(/^[a-z][a-z0-9+.-]*:\/\//i.test(e)?e:`https://${e}`).hostname.toLowerCase();return n.startsWith("www.")?n.slice(4):n}catch{return""}}function T(t){return String(t).toLowerCase().replace(/[^\p{L}\p{N}]/gu,"")}function f(t){return String(t??"").trim()}var R=Object.freeze(["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO","GB","CH"]);function X(t){let e=typeof t=="string"?t.trim().toUpperCase():"";return e.length!==2||e==="XX"||e==="T1"?!0:R.includes(e)}var w="webority_cookie_consent",v="webority-consent-change",tt=365,i={initialized:!1,requiresOptIn:!0,strictOptIn:!1,adStorage:!0,cookieDays:tt,cookieDomain:null,regionCookie:null,region:null,saved:null},et=["eea","other"],L=new Set;function nt(t){let e=t?.strictOptIn??!1;if(typeof e!="boolean")throw new Error("@webority/analytics: initConsent strictOptIn must be true or false, or left out.");if(e){if(t.requiresOptIn!==void 0&&t.requiresOptIn!==!0)throw new Error("@webority/analytics: initConsent strictOptIn asks every visitor to opt in, so requiresOptIn must be true or left out.")}else if(typeof t?.requiresOptIn!="boolean")throw new Error("@webority/analytics: initConsent needs requiresOptIn (true or false), decided from the visitor's country.");if(t.cookieDomain!==void 0&&(typeof t.cookieDomain!="string"||!t.cookieDomain.trim()))throw new Error('@webority/analytics: initConsent cookieDomain must be a domain such as ".example.com", or left out.');if(t.cookieDays!==void 0&&!(Number.isInteger(t.cookieDays)&&t.cookieDays>0))throw new Error("@webority/analytics: initConsent cookieDays must be a whole number of days above zero, or left out.");if(t.adStorage!==void 0&&typeof t.adStorage!="boolean")throw new Error("@webority/analytics: initConsent adStorage must be true or false, or left out.");if(t.regionCookie!==void 0&&(typeof t.regionCookie!="string"||!/^[\w.-]+$/.test(t.regionCookie)))throw new Error('@webority/analytics: initConsent regionCookie must be a cookie name such as "wui_region", or left out.');i.initialized=!0,i.strictOptIn=e,i.requiresOptIn=e||t.requiresOptIn,i.adStorage=t.adStorage??!e,i.cookieDays=t.cookieDays??tt,i.cookieDomain=t.cookieDomain?.trim()??null,i.regionCookie=t.regionCookie??null,i.region=i.regionCookie?Kt(i.regionCookie):null;let{saved:n,entryCount:o}=Ht();i.saved=n,i.cookieDomain&&o>1&&n&&ut(n),jt(),qt(),i.saved?P(i.saved):st()&&ct()}function ot(t){if(U("setConsentRegion"),!et.includes(t))throw new Error('@webority/analytics: setConsentRegion needs "eea" or "other".');let e=l();if(i.region=t,i.saved)return;let n=l();e.analytics===n.analytics&&e.functional===n.functional&&e.marketing===n.marketing||(ct(),at(n))}function h(){return i.initialized}function rt(){return i.strictOptIn}function x(){return i.adStorage}function l(){U("getConsent");let t=i.saved;if(t)return{essential:!0,analytics:t.analytics,functional:t.functional,marketing:t.marketing,decided:!0};if(st())return{essential:!0,analytics:!0,functional:!0,marketing:!1,decided:!1};let e=!i.requiresOptIn;return{essential:!0,analytics:e,functional:e,marketing:e,decided:!1}}function it(t){U("saveConsent");let e={essential:!0,analytics:t?.analytics===!0,functional:t?.functional===!0,marketing:t?.marketing===!0,timestamp:new Date().toISOString()};ut(e),i.saved=e,P(e),at(l())}function g(t){return L.add(t),()=>L.delete(t)}function at(t){for(let e of L)try{e(t)}catch(n){queueMicrotask(()=>{throw n})}typeof window?.dispatchEvent=="function"&&typeof CustomEvent=="function"&&window.dispatchEvent(new CustomEvent(v,{detail:t}))}function U(t){if(!i.initialized)throw new Error(`@webority/analytics: call initConsent before ${t}.`)}function S(){window.dataLayer=window.dataLayer||[],window.dataLayer.push(arguments)}function jt(){if(i.strictOptIn){S("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500});return}S("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500,region:[...R]});let t=i.adStorage?"granted":"denied";S("consent","default",{ad_storage:t,ad_user_data:t,ad_personalization:t,analytics_storage:"granted",functionality_storage:"granted",personalization_storage:"granted",security_storage:"granted"})}function qt(){S("set","ads_data_redaction",!0),S("set","url_passthrough",!0)}function st(){return i.requiresOptIn&&!i.strictOptIn&&i.region==="other"}function ct(){let t=l();P(t,t.analytics&&i.adStorage)}function P(t,e=t.marketing&&i.adStorage){let n=o=>o?"granted":"denied";S("consent","update",{analytics_storage:n(t.analytics),functionality_storage:n(t.functional),personalization_storage:n(t.functional),ad_storage:n(e),ad_user_data:n(e),ad_personalization:n(e)})}function Ht(){let t=`${w}=`,e=(document.cookie||"").split(";").map(o=>o.trim()).filter(o=>o.startsWith(t)),n=e.map(o=>Vt(o.slice(t.length))).filter(Boolean);return{saved:Wt(n),entryCount:e.length}}function Kt(t){let e=`${t}=`,o=(document.cookie||"").split(";").map(r=>r.trim()).find(r=>r.startsWith(e))?.slice(e.length);return et.includes(o)?o:null}function Vt(t){try{let e=JSON.parse(decodeURIComponent(t));return!e||typeof e!="object"?null:{essential:!0,analytics:e.analytics===!0,functional:e.functional===!0,marketing:e.marketing===!0,timestamp:e.timestamp??null}}catch{return null}}function Wt(t){if(t.length===0)return null;let e=t.map(o=>typeof o.timestamp=="string"?Date.parse(o.timestamp):Number.NaN);if(e.some(Number.isNaN))return t.at(-1);let n=0;for(let o=1;o<t.length;o++)e[o]>=e[n]&&(n=o);return t[n]}function ut(t){let e=typeof t.timestamp=="string"?Date.parse(t.timestamp):Number.NaN,n=(Number.isNaN(e)?Date.now():e)+i.cookieDays*24*60*60*1e3,o=window.location?.protocol==="https:"?";Secure":"";i.cookieDomain&&Z(`${w}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;max-age=0;path=/;SameSite=Lax${o}`);let r=i.cookieDomain?`;domain=${i.cookieDomain}`:"";Z(`${w}=${encodeURIComponent(JSON.stringify(t))};expires=${new Date(n).toUTCString()};path=/${r};SameSite=Lax${o}`)}function Z(t){document.cookie=t}var b="webority_attribution",Yt=2160*60*60*1e3,Qt=200,M=500,Jt=Object.freeze({utm_source:"utmSource",utm_medium:"utmMedium",utm_campaign:"utmCampaign",utm_content:"utmContent",utm_term:"utmTerm",gclid:"gclid",gbraid:"gbraid",wbraid:"wbraid",fbclid:"fbclid",msclkid:"msclkid",li_fat_id:"liFatId"}),lt=!1;function ft(){mt("captureAttribution"),ee();let t=Zt();if(!t)return;let e=B($());pt($(),{firstTouch:e?.firstTouch??t,lastTouch:t}),Xt(t)}function Xt(t){let e={event:"acquisition_touch",acquisition_channel:C(t)};t.aiSource&&(e.ai_source=t.aiSource),window.dataLayer=window.dataLayer||[],window.dataLayer.push(e)}function N(){return mt("getAttribution"),B($())}function Zt(){let t=new URLSearchParams(window.location.search),e={};for(let[r,c]of Object.entries(Jt)){let a=A(t.get(r),Qt);a&&(e[c]=a)}let n=A(t.get("referrer"),M)||te();if(n&&(e.referrer=n),Object.keys(e).length===0)return null;let o=O(e);return o&&(e.aiSource=o),e.landingPage=A(window.location.pathname,M),e.capturedDateTimeUtc=new Date().toISOString(),e}function te(){let t=document.referrer;if(!t)return"";try{return new URL(t).hostname===window.location.hostname?"":A(t,M)}catch{return""}}function ee(){lt||(lt=!0,g(t=>{let e=t.marketing?F():G(),n=t.marketing?G():F(),o=B(e);ne(e),o&&pt(n,o)}))}function $(){return l().marketing?G():F()}function G(){try{return window.localStorage}catch{return null}}function F(){try{return window.sessionStorage}catch{return null}}function B(t){try{let e=t?.getItem(b);if(!e)return null;let n=JSON.parse(e),o=dt(n?.firstTouch),r=dt(n?.lastTouch);return!o&&!r?(t.removeItem(b),null):{firstTouch:o??r,lastTouch:r??o}}catch{return null}}function pt(t,e){try{t?.setItem(b,JSON.stringify(e))}catch{}}function ne(t){try{t?.removeItem(b)}catch{}}function dt(t){if(!t||typeof t!="object")return null;let e=Date.parse(t.capturedDateTimeUtc);return Number.isFinite(e)&&Date.now()-e<=Yt?t:null}function A(t,e){let n=String(t??"").trim();return n?n.slice(0,e):""}function mt(t){if(!h())throw new Error(`@webority/analytics: call initConsent before ${t}.`)}var s=Object.freeze({SIGNUP_STARTED:"signup_started",SIGNUP_COMPLETED:"signup_completed",LOGIN_SUCCEEDED:"login_succeeded",ONBOARDING_STARTED:"onboarding_started",ONBOARDING_STEP_COMPLETED:"onboarding_step_completed",ONBOARDING_COMPLETED:"onboarding_completed",SUBSCRIPTION_ACTIVATED:"subscription_activated",SUBSCRIPTION_CANCELLED:"subscription_cancelled",PAYMENT_SUCCEEDED:"payment_succeeded",PAYMENT_FAILED:"payment_failed",FEEDBACK_SUBMITTED:"feedback_submitted",LEAD_SUBMITTED:"lead_submitted",LEAD_QUALIFIED:"lead_qualified",WHATSAPP_CLICK:"whatsapp_click",CALCULATOR_USE:"calculator_use",PHONE_CLICK:"phone_click",DEMO_BOOKED:"demo_booked",CONTACT_SUBMITTED:"contact_submitted",TRIAL_START_CLICK:"trial_start_click",SAMPLE_REPORT_DOWNLOAD:"sample_report_download",REPORT_VERIFIED:"report_verified",CONTENT_ENGAGED:"content_engaged"}),Ue=Object.freeze({signupStarted:s.SIGNUP_STARTED,signupCompleted:s.SIGNUP_COMPLETED,loginSucceeded:s.LOGIN_SUCCEEDED,onboardingStarted:s.ONBOARDING_STARTED,onboardingStepCompleted:s.ONBOARDING_STEP_COMPLETED,onboardingCompleted:s.ONBOARDING_COMPLETED,subscriptionActivated:s.SUBSCRIPTION_ACTIVATED,subscriptionCancelled:s.SUBSCRIPTION_CANCELLED,paymentSucceeded:s.PAYMENT_SUCCEEDED,paymentFailed:s.PAYMENT_FAILED,feedbackSubmitted:s.FEEDBACK_SUBMITTED,leadSubmitted:s.LEAD_SUBMITTED,leadQualified:s.LEAD_QUALIFIED,whatsappClick:s.WHATSAPP_CLICK,calculatorUse:s.CALCULATOR_USE,phoneClick:s.PHONE_CLICK,demoBooked:s.DEMO_BOOKED,contactSubmitted:s.CONTACT_SUBMITTED,trialStartClick:s.TRIAL_START_CLICK,sampleReportDownload:s.SAMPLE_REPORT_DOWNLOAD,reportVerified:s.REPORT_VERIFIED,contentEngaged:s.CONTENT_ENGAGED});var oe=new Set(["token","code","email","access_token","id_token","state","session_state","password"]),re=/(?:access_token|id_token|session_state|token|code|state|email|password)=/i,ie=["$current_url","$referrer","$pathname","$initial_current_url","$initial_referrer","$initial_pathname","$session_entry_url","$session_entry_referrer","$session_entry_pathname"],ae=4,se=5,ce=6;function I(t){if(typeof t!="string")return t;let e=t.indexOf("#"),n=e===-1?t:t.slice(0,e),o=e===-1||re.test(t.slice(e))?"":t.slice(e),r=n.indexOf("?");if(r===-1)return n+o;let c=n.slice(r+1).split("&"),a=c.filter(_=>!oe.has(de(_)));if(a.length===c.length)return n+o;let d=n.slice(0,r),y=a.filter(_=>_!=="").join("&");return(y?`${d}?${y}`:d)+o}function gt(t){if(!t||typeof t!="object")return t;let e=t.properties;for(let r of[e,t.$set,t.$set_once,e?.$set,e?.$set_once])le(r);let n=e?.$heatmap_data;if(n&&typeof n=="object"){let r={};for(let[c,a]of Object.entries(n)){let d=I(c);r[d]=r[d]?r[d].concat(a):a}e.$heatmap_data=r}if(e&&typeof e=="object"){for(let[r,c]of Object.entries(e))if(r.startsWith("$web_vitals_")&&r.endsWith("_event")&&c&&typeof c=="object")for(let a of["$current_url","navigationURL"])typeof c[a]=="string"&&(c[a]=I(c[a]))}let o=e?.$snapshot_data;if(t.event==="$snapshot"&&o&&typeof o=="object")for(let r of Array.isArray(o)?o:[o])ue(r);return t}function ue(t){let e=t?.data;if(!(!e||typeof e!="object")){if(t.type===ae)k(e,["href"]);else if(t.type===se)k(e.payload,["href"]);else if(t.type===ce&&Array.isArray(e.payload?.requests))for(let n of e.payload.requests)k(n,["name","url"])}}function k(t,e){if(!(!t||typeof t!="object"))for(let n of e)typeof t[n]=="string"&&(t[n]=I(t[n]))}function le(t){k(t,ie)}function de(t){let e=t.split("=",1)[0].replace(/\+/g," ");try{return decodeURIComponent(e).toLowerCase()}catch{return e.toLowerCase()}}function _t(t,e){return e?t:{...t,opt_out_capturing_by_default:!0}}function yt(t){let e=t.sessionRecording??{enabled:!1},n={api_host:t.host,autocapture:!1,capture_pageview:"history_change",cookieless_mode:"on_reject",person_profiles:"identified_only",persistence:"localStorage+cookie",cross_subdomain_cookie:!0,disable_session_recording:!e.enabled,enable_heatmaps:t.heatmaps===!0,capture_exceptions:t.captureExceptions===!0,capture_performance:{web_vitals:t.webVitals===!0},disable_surveys:!0,disable_product_tours:!0,disable_conversations:!0,advanced_disable_feature_flags:!e.enabled,before_send:gt};return e.enabled&&(n.session_recording={maskAllInputs:e.maskAllInputs??!0,...e.maskTextSelector?{maskTextSelector:e.maskTextSelector}:{},maskCapturedNetworkRequestFn:o=>({...o,name:I(o.name)}),recordBody:!1,recordHeaders:!1}),n}var me=()=>Promise.resolve().then(()=>(ht(),St)),p={config:null,posthog:null,loading:null,loadPosthog:me,stopFollowingConsent:null};function wt({host:t,clientKey:e,product:n,surface:o,environment:r,enabled:c=!0,sessionRecording:a,heatmaps:d=!1,captureExceptions:y=!1,webVitals:_=!1}={}){if(!h())throw new Error("@webority/analytics: call initConsent before initSiteAnalytics.");!c||!t||!e||r==="Local"||p.config||(p.config={host:t,clientKey:e,product:n,surface:o,environment:r,sessionRecording:a,heatmaps:d,captureExceptions:y,webVitals:_},p.stopFollowingConsent=g(E=>_e(E.analytics)),p.loading=Promise.resolve().then(p.loadPosthog).then(E=>ge(E.default??E)).catch(()=>{}))}function ge(t){let e=p.config,n=l().analytics;t.init(e.clientKey,_t(ye(e),n)),t.register({product:e.product,surface:e.surface,environment:e.environment}),n?t.opt_in_capturing({captureEventName:!1}):t.opt_out_capturing(),p.posthog=t}function _e(t){p.posthog&&(t?p.posthog.opt_in_capturing():p.posthog.opt_out_capturing())}function ye(t){return{...yt({host:t.host,sessionRecording:t.sessionRecording,heatmaps:t.heatmaps,captureExceptions:t.captureExceptions,webVitals:t.webVitals}),capture_pageview:!0}}function It(t,e){let n=p.config;if(!n)return;let o={...e,product:n.product,surface:n.surface,environment:n.environment};p.loading.then(()=>p.posthog?.capture(t,o)).catch(()=>{})}var Ee=new Set(Object.values(s));function Tt(t,e={}){if(!Ee.has(t))return!1;let n=l().analytics,o=N(),r={...e};for(let[c,a]of[["first",o?.firstTouch],["last",o?.lastTouch]])a&&(r[`${c}_touch_channel`]=C(a),a.aiSource&&(r[`${c}_touch_ai_source`]=a.aiSource));return It(t,r),n?(window.dataLayer=window.dataLayer||[],window.dataLayer.push({...r,event:t}),!0):!1}var Ce=["scroll","mousemove","touchstart","keydown","pointerdown"],Se="https://www.googletagmanager.com/gtm.js",Ot=1500,he=3e3,we=100,m={loaded:!1,clarityId:null,clarityLoaded:!1,cancelClaritySchedule:null};function bt(t={}){if(!h())throw new Error("@webority/analytics: call initConsent before loadTags.");if(m.loaded)return;m.loaded=!0;let{gtmId:e,gtmUrl:n=Se,clarityId:o,ahrefsKey:r}=t;if(typeof n!="string"||n.trim()==="")throw new Error("@webority/analytics: gtmUrl must be a non-empty string.");let c=rt();if(r){let a=()=>j("https://analytics.ahrefs.com/analytics.js",{"data-key":r});c?At(d=>d.analytics,a):a()}if(e){let a=x(),d=H=>H.analytics||H.marketing&&a,y=()=>{window.dataLayer=window.dataLayer||[],window.dataLayer.push({"gtm.start":Date.now(),event:"gtm.js"}),j(`${n}${n.includes("?")?"&":"?"}id=${encodeURIComponent(e)}`)},_=l(),E=_.decided&&d(_)?Ie:Te,q=()=>E(y);c?At(d,q):q()}o&&(m.clarityId=o,l().analytics&&Oe(),g(a=>{a.analytics&&!m.clarityLoaded?z():m.clarityLoaded&&Nt(a)}))}function At(t,e){if(t(l())){e();return}let n=g(o=>{t(o)&&(n(),e())})}function Ie(t){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",t,{once:!0}):t()}function Te(t){let e=!1,n=()=>{e||(e=!0,t())};for(let o of Ce)window.addEventListener(o,n,{once:!0,passive:!0});document.readyState==="complete"?setTimeout(n,Ot):window.addEventListener("load",()=>setTimeout(n,Ot),{once:!0})}function Oe(){let t=()=>{window.scrollY>we&&z()};window.addEventListener("scroll",t,{passive:!0});let e=setTimeout(z,he);m.cancelClaritySchedule=()=>{window.removeEventListener("scroll",t),clearTimeout(e)}}function z(){m.cancelClaritySchedule?.(),m.cancelClaritySchedule=null,!(m.clarityLoaded||!m.clarityId)&&(m.clarityLoaded=!0,window.clarity=window.clarity||function(){window.clarity.q=window.clarity.q||[],window.clarity.q.push(arguments)},Nt(l()),j(`https://www.clarity.ms/tag/${encodeURIComponent(m.clarityId)}`,{crossorigin:"anonymous"}))}function Nt(t){window.clarity("consentv2",{ad_Storage:t.marketing&&x()?"granted":"denied",analytics_Storage:t.analytics?"granted":"denied"})}function j(t,e={}){let n=document.createElement("script");n.async=!0,n.src=t;for(let[o,r]of Object.entries(e))n.setAttribute(o,r);document.head.appendChild(n)}return xt(Ae);})();
1
+ var WeborityAnalytics=(()=>{var D=Object.defineProperty;var kt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var Rt=Object.prototype.hasOwnProperty;var Lt=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(o){throw n=[o],o}};var K=(t,e)=>{for(var n in e)D(t,n,{get:e[n],enumerable:!0})},vt=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Dt(e))!Rt.call(t,r)&&r!==n&&D(t,r,{get:()=>e[r],enumerable:!(o=kt(e,r))||o.enumerable});return t};var xt=t=>vt(D({},"__esModule",{value:!0}),t);var St={};K(St,{default:()=>pe});function fe(){let t=[];t._i=[],t.__SV=1,t.people=[];for(let e of Et)t[e]=(...n)=>{t.push([e,...n])};t.init=(e,n)=>{t._i.push([e,n]);let o=document.createElement("script");o.async=!0,o.crossOrigin="anonymous",o.src=`${n.api_host.replace(/\/+$/,"").replace(".i.posthog.com","-assets.i.posthog.com")}/static/array.js`,document.head.appendChild(o)},window.posthog=t}var Et,Ct,pe,ht=Lt(()=>{Et=["capture","register","opt_in_capturing","opt_out_capturing"];Ct={init(t,e){window.posthog||fe(),window.posthog.init(t,e)}};for(let t of Et)Ct[t]=(...e)=>window.posthog[t](...e);pe=Ct});var Ae={};K(Ae,{CONSENT_CHANGE_EVENT:()=>v,CONSENT_COOKIE_NAME:()=>w,captureAttribution:()=>ft,channels:()=>u,events:()=>s,getAttribution:()=>N,getConsent:()=>l,initConsent:()=>nt,initSiteAnalytics:()=>wt,loadTags:()=>bt,onConsentChange:()=>g,requiresOptIn:()=>X,resolveAiSource:()=>O,resolveChannel:()=>C,saveConsent:()=>it,setConsentRegion:()=>ot,trackSiteEvent:()=>Tt});var Ut=["google","googleads","adwords","youtube"],Pt=["meta","facebook","fb","instagram","ig","messenger"],Mt=["linkedin","lnkd"],Ft=["bing","microsoft","microsoftads","msn"],V=Object.freeze([["chatgpt",["chatgpt.com","chat.openai.com"]],["perplexity",["perplexity.ai"]],["gemini",["gemini.google.com"]],["copilot",["copilot.microsoft.com"]],["claude",["claude.ai"]],["you",["you.com"]],["phind",["phind.com"]],["deepseek",["deepseek.com"]],["grok",["grok.com"]],["meta_ai",["meta.ai"]],["poe",["poe.com"]]]),$t=["bing.com","duckduckgo.com","search.yahoo.com","ecosia.org","search.brave.com"],Gt=["google","yandex"],Bt=["facebook.com","fb.com","instagram.com","linkedin.com","lnkd.in","twitter.com","t.co","x.com","reddit.com","pinterest.com","youtube.com","youtu.be","tiktok.com","whatsapp.com","threads.net","t.me","telegram.org"],u=Object.freeze({DIRECT:"direct",GOOGLE:"google",META:"meta",LINKEDIN:"linkedin",MICROSOFT:"microsoft",OTHER:"other",AI_ASSISTANT:"ai_assistant",ORGANIC_SEARCH:"organic_search",ORGANIC_SOCIAL:"organic_social",REFERRAL:"referral"});function C(t){if(!t)return u.DIRECT;let e=f(t.utmSource);if(e){let r=T(e);if(Ut.includes(r))return u.GOOGLE;if(Pt.includes(r))return u.META;if(Mt.includes(r))return u.LINKEDIN;if(Ft.includes(r))return u.MICROSOFT}if(f(t.fbclid))return u.META;if(f(t.gclid)||f(t.gbraid)||f(t.wbraid))return u.GOOGLE;if(f(t.liFatId))return u.LINKEDIN;if(f(t.msclkid))return u.MICROSOFT;if(W(e))return u.AI_ASSISTANT;if(e||f(t.utmMedium)||f(t.utmCampaign)||f(t.utmContent)||f(t.utmTerm))return u.OTHER;let o=J(t.referrer);return o?Y(o)?u.AI_ASSISTANT:zt(o)?u.ORGANIC_SEARCH:Bt.some(r=>Q(o,r))?u.ORGANIC_SOCIAL:u.REFERRAL:u.DIRECT}function O(t){if(!t)return"";let e=W(f(t.utmSource));if(e)return e;let n=J(t.referrer);return n?Y(n):""}function W(t){if(!t)return"";let e=T(t);for(let[n,o]of V)if(T(n)===e||o.some(r=>T(r)===e))return n;return""}function Y(t){for(let[e,n]of V)if(n.some(o=>Q(t,o)))return e;return""}function zt(t){return $t.includes(t)?!0:Gt.some(e=>{if(!t.startsWith(`${e}.`))return!1;let n=t.slice(e.length+1).split(".");return n.length===1||n.length===2&&(n[0]==="co"||n[0]==="com")})}function Q(t,e){return t===e||t.endsWith(`.${e}`)}function J(t){let e=f(t);if(!e)return"";try{let n=new URL(/^[a-z][a-z0-9+.-]*:\/\//i.test(e)?e:`https://${e}`).hostname.toLowerCase();return n.startsWith("www.")?n.slice(4):n}catch{return""}}function T(t){return String(t).toLowerCase().replace(/[^\p{L}\p{N}]/gu,"")}function f(t){return String(t??"").trim()}var R=Object.freeze(["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO","GB","CH"]);function X(t){let e=typeof t=="string"?t.trim().toUpperCase():"";return e.length!==2||e==="XX"||e==="T1"?!0:R.includes(e)}var w="webority_cookie_consent",v="webority-consent-change",tt=365,i={initialized:!1,requiresOptIn:!0,strictOptIn:!1,adStorage:!0,cookieDays:tt,cookieDomain:null,regionCookie:null,region:null,saved:null},et=["eea","other"],L=new Set;function nt(t){let e=t?.strictOptIn??!1;if(typeof e!="boolean")throw new Error("@webority/analytics: initConsent strictOptIn must be true or false, or left out.");if(e){if(t.requiresOptIn!==void 0&&t.requiresOptIn!==!0)throw new Error("@webority/analytics: initConsent strictOptIn asks every visitor to opt in, so requiresOptIn must be true or left out.")}else if(typeof t?.requiresOptIn!="boolean")throw new Error("@webority/analytics: initConsent needs requiresOptIn (true or false), decided from the visitor's country.");if(t.cookieDomain!==void 0&&(typeof t.cookieDomain!="string"||!t.cookieDomain.trim()))throw new Error('@webority/analytics: initConsent cookieDomain must be a domain such as ".example.com", or left out.');if(t.cookieDays!==void 0&&!(Number.isInteger(t.cookieDays)&&t.cookieDays>0))throw new Error("@webority/analytics: initConsent cookieDays must be a whole number of days above zero, or left out.");if(t.adStorage!==void 0&&typeof t.adStorage!="boolean")throw new Error("@webority/analytics: initConsent adStorage must be true or false, or left out.");if(t.regionCookie!==void 0&&(typeof t.regionCookie!="string"||!/^[\w.-]+$/.test(t.regionCookie)))throw new Error('@webority/analytics: initConsent regionCookie must be a cookie name such as "wui_region", or left out.');i.initialized=!0,i.strictOptIn=e,i.requiresOptIn=e||t.requiresOptIn,i.adStorage=t.adStorage??!e,i.cookieDays=t.cookieDays??tt,i.cookieDomain=t.cookieDomain?.trim()??null,i.regionCookie=t.regionCookie??null,i.region=i.regionCookie?Kt(i.regionCookie):null;let{saved:n,entryCount:o}=Ht();i.saved=n,i.cookieDomain&&o>1&&n&&ut(n),jt(),qt(),i.saved?P(i.saved):st()&&ct()}function ot(t){if(U("setConsentRegion"),!et.includes(t))throw new Error('@webority/analytics: setConsentRegion needs "eea" or "other".');let e=l();if(i.region=t,i.saved)return;let n=l();e.analytics===n.analytics&&e.functional===n.functional&&e.marketing===n.marketing||(ct(),at(n))}function h(){return i.initialized}function rt(){return i.strictOptIn}function x(){return i.adStorage}function l(){U("getConsent");let t=i.saved;if(t)return{essential:!0,analytics:t.analytics,functional:t.functional,marketing:t.marketing,decided:!0};if(st())return{essential:!0,analytics:!0,functional:!0,marketing:!1,decided:!1};let e=!i.requiresOptIn;return{essential:!0,analytics:e,functional:e,marketing:e,decided:!1}}function it(t){U("saveConsent");let e={essential:!0,analytics:t?.analytics===!0,functional:t?.functional===!0,marketing:t?.marketing===!0,timestamp:new Date().toISOString()};ut(e),i.saved=e,P(e),at(l())}function g(t){return L.add(t),()=>L.delete(t)}function at(t){for(let e of L)try{e(t)}catch(n){queueMicrotask(()=>{throw n})}typeof window?.dispatchEvent=="function"&&typeof CustomEvent=="function"&&window.dispatchEvent(new CustomEvent(v,{detail:t}))}function U(t){if(!i.initialized)throw new Error(`@webority/analytics: call initConsent before ${t}.`)}function S(){window.dataLayer=window.dataLayer||[],window.dataLayer.push(arguments)}function jt(){if(i.strictOptIn){S("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500});return}S("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500,region:[...R]});let t=i.adStorage?"granted":"denied";S("consent","default",{ad_storage:t,ad_user_data:t,ad_personalization:t,analytics_storage:"granted",functionality_storage:"granted",personalization_storage:"granted",security_storage:"granted"})}function qt(){S("set","ads_data_redaction",!0),S("set","url_passthrough",!0)}function st(){return i.requiresOptIn&&!i.strictOptIn&&i.region==="other"}function ct(){let t=l();P(t,t.analytics&&i.adStorage)}function P(t,e=t.marketing&&i.adStorage){let n=o=>o?"granted":"denied";S("consent","update",{analytics_storage:n(t.analytics),functionality_storage:n(t.functional),personalization_storage:n(t.functional),ad_storage:n(e),ad_user_data:n(e),ad_personalization:n(e)})}function Ht(){let t=`${w}=`,e=(document.cookie||"").split(";").map(o=>o.trim()).filter(o=>o.startsWith(t)),n=e.map(o=>Vt(o.slice(t.length))).filter(Boolean);return{saved:Wt(n),entryCount:e.length}}function Kt(t){let e=`${t}=`,o=(document.cookie||"").split(";").map(r=>r.trim()).find(r=>r.startsWith(e))?.slice(e.length);return et.includes(o)?o:null}function Vt(t){try{let e=JSON.parse(decodeURIComponent(t));return!e||typeof e!="object"?null:{essential:!0,analytics:e.analytics===!0,functional:e.functional===!0,marketing:e.marketing===!0,timestamp:e.timestamp??null}}catch{return null}}function Wt(t){if(t.length===0)return null;let e=t.map(o=>typeof o.timestamp=="string"?Date.parse(o.timestamp):Number.NaN);if(e.some(Number.isNaN))return t.at(-1);let n=0;for(let o=1;o<t.length;o++)e[o]>=e[n]&&(n=o);return t[n]}function ut(t){let e=typeof t.timestamp=="string"?Date.parse(t.timestamp):Number.NaN,n=(Number.isNaN(e)?Date.now():e)+i.cookieDays*24*60*60*1e3,o=window.location?.protocol==="https:"?";Secure":"";i.cookieDomain&&Z(`${w}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;max-age=0;path=/;SameSite=Lax${o}`);let r=i.cookieDomain?`;domain=${i.cookieDomain}`:"";Z(`${w}=${encodeURIComponent(JSON.stringify(t))};expires=${new Date(n).toUTCString()};path=/${r};SameSite=Lax${o}`)}function Z(t){document.cookie=t}var b="webority_attribution",Yt=2160*60*60*1e3,Qt=200,M=500,Jt=Object.freeze({utm_source:"utmSource",utm_medium:"utmMedium",utm_campaign:"utmCampaign",utm_content:"utmContent",utm_term:"utmTerm",gclid:"gclid",gbraid:"gbraid",wbraid:"wbraid",fbclid:"fbclid",msclkid:"msclkid",li_fat_id:"liFatId"}),lt=!1;function ft(){mt("captureAttribution"),ee();let t=Zt();if(!t)return;let e=B(F());pt(F(),{firstTouch:e?.firstTouch??t,lastTouch:t}),Xt(t)}function Xt(t){let e={event:"acquisition_touch",acquisition_channel:C(t)};t.aiSource&&(e.ai_source=t.aiSource),window.dataLayer=window.dataLayer||[],window.dataLayer.push(e)}function N(){return mt("getAttribution"),B(F())}function Zt(){let t=new URLSearchParams(window.location.search),e={};for(let[r,c]of Object.entries(Jt)){let a=A(t.get(r),Qt);a&&(e[c]=a)}let n=A(t.get("referrer"),M)||te();if(n&&(e.referrer=n),Object.keys(e).length===0)return null;let o=O(e);return o&&(e.aiSource=o),e.landingPage=A(window.location.pathname,M),e.capturedDateTimeUtc=new Date().toISOString(),e}function te(){let t=document.referrer;if(!t)return"";try{return new URL(t).hostname===window.location.hostname?"":A(t,M)}catch{return""}}function ee(){lt||(lt=!0,g(t=>{let e=t.marketing?G():$(),n=t.marketing?$():G(),o=B(e);ne(e),o&&pt(n,o)}))}function F(){return l().marketing?$():G()}function $(){try{return window.localStorage}catch{return null}}function G(){try{return window.sessionStorage}catch{return null}}function B(t){try{let e=t?.getItem(b);if(!e)return null;let n=JSON.parse(e),o=dt(n?.firstTouch),r=dt(n?.lastTouch);return!o&&!r?(t.removeItem(b),null):{firstTouch:o??r,lastTouch:r??o}}catch{return null}}function pt(t,e){try{t?.setItem(b,JSON.stringify(e))}catch{}}function ne(t){try{t?.removeItem(b)}catch{}}function dt(t){if(!t||typeof t!="object")return null;let e=Date.parse(t.capturedDateTimeUtc);return Number.isFinite(e)&&Date.now()-e<=Yt?t:null}function A(t,e){let n=String(t??"").trim();return n?n.slice(0,e):""}function mt(t){if(!h())throw new Error(`@webority/analytics: call initConsent before ${t}.`)}var s=Object.freeze({SIGNUP_STARTED:"signup_started",SIGNUP_COMPLETED:"signup_completed",LOGIN_SUCCEEDED:"login_succeeded",ONBOARDING_STARTED:"onboarding_started",ONBOARDING_STEP_COMPLETED:"onboarding_step_completed",ONBOARDING_COMPLETED:"onboarding_completed",SUBSCRIPTION_ACTIVATED:"subscription_activated",SUBSCRIPTION_CANCELLED:"subscription_cancelled",PAYMENT_SUCCEEDED:"payment_succeeded",PAYMENT_FAILED:"payment_failed",FEEDBACK_SUBMITTED:"feedback_submitted",LEAD_SUBMITTED:"lead_submitted",LEAD_QUALIFIED:"lead_qualified",WHATSAPP_CLICK:"whatsapp_click",CALCULATOR_USE:"calculator_use",PHONE_CLICK:"phone_click",DEMO_BOOKED:"demo_booked",CONTACT_SUBMITTED:"contact_submitted",TRIAL_START_CLICK:"trial_start_click",SAMPLE_REPORT_DOWNLOAD:"sample_report_download",REPORT_VERIFIED:"report_verified",CONTENT_ENGAGED:"content_engaged"}),Ue=Object.freeze({signupStarted:s.SIGNUP_STARTED,signupCompleted:s.SIGNUP_COMPLETED,loginSucceeded:s.LOGIN_SUCCEEDED,onboardingStarted:s.ONBOARDING_STARTED,onboardingStepCompleted:s.ONBOARDING_STEP_COMPLETED,onboardingCompleted:s.ONBOARDING_COMPLETED,subscriptionActivated:s.SUBSCRIPTION_ACTIVATED,subscriptionCancelled:s.SUBSCRIPTION_CANCELLED,paymentSucceeded:s.PAYMENT_SUCCEEDED,paymentFailed:s.PAYMENT_FAILED,feedbackSubmitted:s.FEEDBACK_SUBMITTED,leadSubmitted:s.LEAD_SUBMITTED,leadQualified:s.LEAD_QUALIFIED,whatsappClick:s.WHATSAPP_CLICK,calculatorUse:s.CALCULATOR_USE,phoneClick:s.PHONE_CLICK,demoBooked:s.DEMO_BOOKED,contactSubmitted:s.CONTACT_SUBMITTED,trialStartClick:s.TRIAL_START_CLICK,sampleReportDownload:s.SAMPLE_REPORT_DOWNLOAD,reportVerified:s.REPORT_VERIFIED,contentEngaged:s.CONTENT_ENGAGED});var oe=new Set(["token","code","email","access_token","id_token","state","session_state","password"]),re=/(?:access_token|id_token|session_state|token|code|state|email|password)=/i,ie=["$current_url","$referrer","$pathname","$initial_current_url","$initial_referrer","$initial_pathname","$session_entry_url","$session_entry_referrer","$session_entry_pathname"],ae=4,se=5,ce=6;function I(t){if(typeof t!="string")return t;let e=t.indexOf("#"),n=e===-1?t:t.slice(0,e),o=e===-1||re.test(t.slice(e))?"":t.slice(e),r=n.indexOf("?");if(r===-1)return n+o;let c=n.slice(r+1).split("&"),a=c.filter(_=>!oe.has(de(_)));if(a.length===c.length)return n+o;let d=n.slice(0,r),y=a.filter(_=>_!=="").join("&");return(y?`${d}?${y}`:d)+o}function gt(t){if(!t||typeof t!="object")return t;let e=t.properties;for(let r of[e,t.$set,t.$set_once,e?.$set,e?.$set_once])le(r);let n=e?.$heatmap_data;if(n&&typeof n=="object"){let r={};for(let[c,a]of Object.entries(n)){let d=I(c);r[d]=r[d]?r[d].concat(a):a}e.$heatmap_data=r}if(e&&typeof e=="object"){for(let[r,c]of Object.entries(e))if(r.startsWith("$web_vitals_")&&r.endsWith("_event")&&c&&typeof c=="object")for(let a of["$current_url","navigationURL"])typeof c[a]=="string"&&(c[a]=I(c[a]))}let o=e?.$snapshot_data;if(t.event==="$snapshot"&&o&&typeof o=="object")for(let r of Array.isArray(o)?o:[o])ue(r);return t}function ue(t){let e=t?.data;if(!(!e||typeof e!="object")){if(t.type===ae)k(e,["href"]);else if(t.type===se)k(e.payload,["href"]);else if(t.type===ce&&Array.isArray(e.payload?.requests))for(let n of e.payload.requests)k(n,["name","url"])}}function k(t,e){if(!(!t||typeof t!="object"))for(let n of e)typeof t[n]=="string"&&(t[n]=I(t[n]))}function le(t){k(t,ie)}function de(t){let e=t.split("=",1)[0].replace(/\+/g," ");try{return decodeURIComponent(e).toLowerCase()}catch{return e.toLowerCase()}}function _t(t,e,n=!1){return e?t:{...t,opt_out_capturing_by_default:!0,...n?{advanced_disable_feature_flags_on_first_load:!0}:{}}}function yt(t){let e=t.sessionRecording??{enabled:!1},n={api_host:t.host,autocapture:!1,capture_pageview:"history_change",cookieless_mode:"on_reject",person_profiles:"identified_only",persistence:"localStorage+cookie",cross_subdomain_cookie:!0,disable_session_recording:!e.enabled,enable_heatmaps:t.heatmaps===!0,capture_exceptions:t.captureExceptions===!0,capture_performance:{web_vitals:t.webVitals===!0},disable_surveys:!0,disable_product_tours:!0,disable_conversations:!0,advanced_disable_feature_flags:!(e.enabled||t.featureFlags===!0),before_send:gt};return e.enabled&&(n.session_recording={maskAllInputs:e.maskAllInputs??!0,...e.maskTextSelector?{maskTextSelector:e.maskTextSelector}:{},maskCapturedNetworkRequestFn:o=>({...o,name:I(o.name)}),recordBody:!1,recordHeaders:!1}),n}var me=()=>Promise.resolve().then(()=>(ht(),St)),p={config:null,posthog:null,loading:null,loadPosthog:me,stopFollowingConsent:null};function wt({host:t,clientKey:e,product:n,surface:o,environment:r,enabled:c=!0,sessionRecording:a,heatmaps:d=!1,captureExceptions:y=!1,webVitals:_=!1}={}){if(!h())throw new Error("@webority/analytics: call initConsent before initSiteAnalytics.");!c||!t||!e||r==="Local"||p.config||(p.config={host:t,clientKey:e,product:n,surface:o,environment:r,sessionRecording:a,heatmaps:d,captureExceptions:y,webVitals:_},p.stopFollowingConsent=g(E=>_e(E.analytics)),p.loading=Promise.resolve().then(p.loadPosthog).then(E=>ge(E.default??E)).catch(()=>{}))}function ge(t){let e=p.config,n=l().analytics;t.init(e.clientKey,_t(ye(e),n)),t.register({product:e.product,surface:e.surface,environment:e.environment}),n?t.opt_in_capturing({captureEventName:!1}):t.opt_out_capturing(),p.posthog=t}function _e(t){p.posthog&&(t?p.posthog.opt_in_capturing():p.posthog.opt_out_capturing())}function ye(t){return{...yt({host:t.host,sessionRecording:t.sessionRecording,heatmaps:t.heatmaps,captureExceptions:t.captureExceptions,webVitals:t.webVitals}),capture_pageview:!0}}function It(t,e){let n=p.config;if(!n)return;let o={...e,product:n.product,surface:n.surface,environment:n.environment};p.loading.then(()=>p.posthog?.capture(t,o)).catch(()=>{})}var Ee=new Set(Object.values(s));function Tt(t,e={}){if(!Ee.has(t))return!1;let n=l().analytics,o=N(),r={...e};for(let[c,a]of[["first",o?.firstTouch],["last",o?.lastTouch]])a&&(r[`${c}_touch_channel`]=C(a),a.aiSource&&(r[`${c}_touch_ai_source`]=a.aiSource));return It(t,r),n?(window.dataLayer=window.dataLayer||[],window.dataLayer.push({...r,event:t}),!0):!1}var Ce=["scroll","mousemove","touchstart","keydown","pointerdown"],Se="https://www.googletagmanager.com/gtm.js",Ot=1500,he=3e3,we=100,m={loaded:!1,clarityId:null,clarityLoaded:!1,cancelClaritySchedule:null};function bt(t={}){if(!h())throw new Error("@webority/analytics: call initConsent before loadTags.");if(m.loaded)return;m.loaded=!0;let{gtmId:e,gtmUrl:n=Se,clarityId:o,ahrefsKey:r}=t;if(typeof n!="string"||n.trim()==="")throw new Error("@webority/analytics: gtmUrl must be a non-empty string.");let c=rt();if(r){let a=()=>j("https://analytics.ahrefs.com/analytics.js",{"data-key":r});c?At(d=>d.analytics,a):a()}if(e){let a=x(),d=H=>H.analytics||H.marketing&&a,y=()=>{window.dataLayer=window.dataLayer||[],window.dataLayer.push({"gtm.start":Date.now(),event:"gtm.js"}),j(`${n}${n.includes("?")?"&":"?"}id=${encodeURIComponent(e)}`)},_=l(),E=_.decided&&d(_)?Ie:Te,q=()=>E(y);c?At(d,q):q()}o&&(m.clarityId=o,l().analytics&&Oe(),g(a=>{a.analytics&&!m.clarityLoaded?z():m.clarityLoaded&&Nt(a)}))}function At(t,e){if(t(l())){e();return}let n=g(o=>{t(o)&&(n(),e())})}function Ie(t){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",t,{once:!0}):t()}function Te(t){let e=!1,n=()=>{e||(e=!0,t())};for(let o of Ce)window.addEventListener(o,n,{once:!0,passive:!0});document.readyState==="complete"?setTimeout(n,Ot):window.addEventListener("load",()=>setTimeout(n,Ot),{once:!0})}function Oe(){let t=()=>{window.scrollY>we&&z()};window.addEventListener("scroll",t,{passive:!0});let e=setTimeout(z,he);m.cancelClaritySchedule=()=>{window.removeEventListener("scroll",t),clearTimeout(e)}}function z(){m.cancelClaritySchedule?.(),m.cancelClaritySchedule=null,!(m.clarityLoaded||!m.clarityId)&&(m.clarityLoaded=!0,window.clarity=window.clarity||function(){window.clarity.q=window.clarity.q||[],window.clarity.q.push(arguments)},Nt(l()),j(`https://www.clarity.ms/tag/${encodeURIComponent(m.clarityId)}`,{crossorigin:"anonymous"}))}function Nt(t){window.clarity("consentv2",{ad_Storage:t.marketing&&x()?"granted":"denied",analytics_Storage:t.analytics?"granted":"denied"})}function j(t,e={}){let n=document.createElement("script");n.async=!0,n.src=t;for(let[o,r]of Object.entries(e))n.setAttribute(o,r);document.head.appendChild(n)}return xt(Ae);})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webority/analytics",
3
- "version": "0.19.2",
3
+ "version": "0.20.0",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -16,13 +16,18 @@
16
16
  "files": [
17
17
  "dist"
18
18
  ],
19
+ "bin": {
20
+ "webority-analytics-check-events": "dist/check-events.js",
21
+ "webority-analytics-generate-events": "dist/generate-events.js"
22
+ },
19
23
  "scripts": {
20
- "build": "node -e \"require(\\\"node:fs\\\").rmSync(\\\"dist\\\",{recursive:true,force:true})\" && esbuild src/index.js src/site.js --bundle --splitting --format=esm --external:posthog-js --target=es2020 --minify --outdir=dist && esbuild src/site.js --bundle --format=iife --global-name=WeborityAnalytics --alias:posthog-js=./src/site-posthog-snippet.js --target=es2020 --minify --outfile=dist/webority-analytics-site.global.js && esbuild src/react-native/index.js --bundle --format=esm --external:posthog-react-native --target=es2020 --minify --outfile=dist/react-native.js",
24
+ "build": "node -e \"require(\\\"node:fs\\\").rmSync(\\\"dist\\\",{recursive:true,force:true})\" && esbuild src/index.js src/site.js --bundle --splitting --format=esm --external:posthog-js --target=es2020 --minify --outdir=dist && esbuild src/site.js --bundle --format=iife --global-name=WeborityAnalytics --alias:posthog-js=./src/site-posthog-snippet.js --target=es2020 --minify --outfile=dist/webority-analytics-site.global.js && esbuild src/react-native/index.js --bundle --format=esm --external:posthog-react-native --target=es2020 --minify --outfile=dist/react-native.js && esbuild src/catalogue/check-events.js src/catalogue/generate-events.js --bundle --platform=node --format=esm --target=node20 --minify --outdir=dist && node -e \"for (const f of [\\\"fleet-tracking-plan.json\\\", \\\"tracking-plan.schema.json\\\"]) require(\\\"node:fs\\\").copyFileSync(\\\"src/catalogue/\\\" + f, \\\"dist/\\\" + f)\"",
21
25
  "prepack": "npm run build && node ../scripts/package-guard-pack.mjs --output-dirs dist --allow-file ../.webority/package-allow.json",
22
26
  "lint": "biome lint ./src ./test",
23
27
  "format": "biome format --write ./src ./test",
24
28
  "check": "biome check ./src ./test",
25
- "test": "node test/smoke.mjs && node test/site.mjs && node test/react-native.mjs && node test/url-scrub.mjs && npm run build --silent && node test/bundle.mjs"
29
+ "test": "node test/smoke.mjs && node test/site.mjs && node test/react-native.mjs && node test/url-scrub.mjs && node test/catalogue.mjs && node src/catalogue/generate-events.js --plan src/catalogue/fleet-tracking-plan.json --cs ../Webority.Analytics/FleetEventCatalogue.g.cs --cs-namespace Webority.Analytics --cs-class FleetEventCatalogue --cs-internal --check && npm run build --silent && node test/bundle.mjs",
30
+ "catalogue:generate": "node src/catalogue/generate-events.js --plan src/catalogue/fleet-tracking-plan.json --cs ../Webority.Analytics/FleetEventCatalogue.g.cs --cs-namespace Webority.Analytics --cs-class FleetEventCatalogue --cs-internal"
26
31
  },
27
32
  "peerDependencies": {
28
33
  "posthog-js": "^1.417.1",
@@ -1 +0,0 @@
1
- var ye=["google","googleads","adwords","youtube"],Ee=["meta","facebook","fb","instagram","ig","messenger"],Ce=["linkedin","lnkd"],Se=["bing","microsoft","microsoftads","msn"],W=Object.freeze([["chatgpt",["chatgpt.com","chat.openai.com"]],["perplexity",["perplexity.ai"]],["gemini",["gemini.google.com"]],["copilot",["copilot.microsoft.com"]],["claude",["claude.ai"]],["you",["you.com"]],["phind",["phind.com"]],["deepseek",["deepseek.com"]],["grok",["grok.com"]],["meta_ai",["meta.ai"]],["poe",["poe.com"]]]),Ie=["bing.com","duckduckgo.com","search.yahoo.com","ecosia.org","search.brave.com"],he=["google","yandex"],we=["facebook.com","fb.com","instagram.com","linkedin.com","lnkd.in","twitter.com","t.co","x.com","reddit.com","pinterest.com","youtube.com","youtu.be","tiktok.com","whatsapp.com","threads.net","t.me","telegram.org"],l=Object.freeze({DIRECT:"direct",GOOGLE:"google",META:"meta",LINKEDIN:"linkedin",MICROSOFT:"microsoft",OTHER:"other",AI_ASSISTANT:"ai_assistant",ORGANIC_SEARCH:"organic_search",ORGANIC_SOCIAL:"organic_social",REFERRAL:"referral"});function h(e){if(!e)return l.DIRECT;let t=p(e.utmSource);if(t){let r=T(t);if(ye.includes(r))return l.GOOGLE;if(Ee.includes(r))return l.META;if(Ce.includes(r))return l.LINKEDIN;if(Se.includes(r))return l.MICROSOFT}if(p(e.fbclid))return l.META;if(p(e.gclid)||p(e.gbraid)||p(e.wbraid))return l.GOOGLE;if(p(e.liFatId))return l.LINKEDIN;if(p(e.msclkid))return l.MICROSOFT;if(Y(t))return l.AI_ASSISTANT;if(t||p(e.utmMedium)||p(e.utmCampaign)||p(e.utmContent)||p(e.utmTerm))return l.OTHER;let o=X(e.referrer);return o?J(o)?l.AI_ASSISTANT:Te(o)?l.ORGANIC_SEARCH:we.some(r=>Q(o,r))?l.ORGANIC_SOCIAL:l.REFERRAL:l.DIRECT}function L(e){if(!e)return"";let t=Y(p(e.utmSource));if(t)return t;let n=X(e.referrer);return n?J(n):""}function Y(e){if(!e)return"";let t=T(e);for(let[n,o]of W)if(T(n)===t||o.some(r=>T(r)===t))return n;return""}function J(e){for(let[t,n]of W)if(n.some(o=>Q(e,o)))return t;return""}function Te(e){return Ie.includes(e)?!0:he.some(t=>{if(!e.startsWith(`${t}.`))return!1;let n=e.slice(t.length+1).split(".");return n.length===1||n.length===2&&(n[0]==="co"||n[0]==="com")})}function Q(e,t){return e===t||e.endsWith(`.${t}`)}function X(e){let t=p(e);if(!t)return"";try{let n=new URL(/^[a-z][a-z0-9+.-]*:\/\//i.test(t)?t:`https://${t}`).hostname.toLowerCase();return n.startsWith("www.")?n.slice(4):n}catch{return""}}function T(e){return String(e).toLowerCase().replace(/[^\p{L}\p{N}]/gu,"")}function p(e){return String(e??"").trim()}var R=Object.freeze(["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO","GB","CH"]);function Oe(e){let t=typeof e=="string"?e.trim().toUpperCase():"";return t.length!==2||t==="XX"||t==="T1"?!0:R.includes(t)}var O="webority_cookie_consent",ee="webority-consent-change",te=365,i={initialized:!1,requiresOptIn:!0,strictOptIn:!1,adStorage:!0,cookieDays:te,cookieDomain:null,regionCookie:null,region:null,saved:null},ne=["eea","other"],D=new Set;function Ae(e){let t=e?.strictOptIn??!1;if(typeof t!="boolean")throw new Error("@webority/analytics: initConsent strictOptIn must be true or false, or left out.");if(t){if(e.requiresOptIn!==void 0&&e.requiresOptIn!==!0)throw new Error("@webority/analytics: initConsent strictOptIn asks every visitor to opt in, so requiresOptIn must be true or left out.")}else if(typeof e?.requiresOptIn!="boolean")throw new Error("@webority/analytics: initConsent needs requiresOptIn (true or false), decided from the visitor's country.");if(e.cookieDomain!==void 0&&(typeof e.cookieDomain!="string"||!e.cookieDomain.trim()))throw new Error('@webority/analytics: initConsent cookieDomain must be a domain such as ".example.com", or left out.');if(e.cookieDays!==void 0&&!(Number.isInteger(e.cookieDays)&&e.cookieDays>0))throw new Error("@webority/analytics: initConsent cookieDays must be a whole number of days above zero, or left out.");if(e.adStorage!==void 0&&typeof e.adStorage!="boolean")throw new Error("@webority/analytics: initConsent adStorage must be true or false, or left out.");if(e.regionCookie!==void 0&&(typeof e.regionCookie!="string"||!/^[\w.-]+$/.test(e.regionCookie)))throw new Error('@webority/analytics: initConsent regionCookie must be a cookie name such as "wui_region", or left out.');i.initialized=!0,i.strictOptIn=t,i.requiresOptIn=t||e.requiresOptIn,i.adStorage=e.adStorage??!t,i.cookieDays=e.cookieDays??te,i.cookieDomain=e.cookieDomain?.trim()??null,i.regionCookie=e.regionCookie??null,i.region=i.regionCookie?De(i.regionCookie):null;let{saved:n,entryCount:o}=Re();i.saved=n,i.cookieDomain&&o>1&&n&&se(n),ke(),Le(),i.saved?U(i.saved):ie()&&ae()}function be(e){if(x("setConsentRegion"),!ne.includes(e))throw new Error('@webority/analytics: setConsentRegion needs "eea" or "other".');let t=u();if(i.region=e,i.saved)return;let n=u();t.analytics===n.analytics&&t.functional===n.functional&&t.marketing===n.marketing||(ae(),re(n))}function y(){return i.initialized}function oe(){return i.strictOptIn}function v(){return i.adStorage}function u(){x("getConsent");let e=i.saved;if(e)return{essential:!0,analytics:e.analytics,functional:e.functional,marketing:e.marketing,decided:!0};if(ie())return{essential:!0,analytics:!0,functional:!0,marketing:!1,decided:!1};let t=!i.requiresOptIn;return{essential:!0,analytics:t,functional:t,marketing:t,decided:!1}}function Ne(e){x("saveConsent");let t={essential:!0,analytics:e?.analytics===!0,functional:e?.functional===!0,marketing:e?.marketing===!0,timestamp:new Date().toISOString()};se(t),i.saved=t,U(t),re(u())}function E(e){return D.add(e),()=>D.delete(e)}function re(e){for(let t of D)try{t(e)}catch(n){queueMicrotask(()=>{throw n})}typeof window?.dispatchEvent=="function"&&typeof CustomEvent=="function"&&window.dispatchEvent(new CustomEvent(ee,{detail:e}))}function x(e){if(!i.initialized)throw new Error(`@webority/analytics: call initConsent before ${e}.`)}function I(){window.dataLayer=window.dataLayer||[],window.dataLayer.push(arguments)}function ke(){if(i.strictOptIn){I("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500});return}I("consent","default",{ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500,region:[...R]});let e=i.adStorage?"granted":"denied";I("consent","default",{ad_storage:e,ad_user_data:e,ad_personalization:e,analytics_storage:"granted",functionality_storage:"granted",personalization_storage:"granted",security_storage:"granted"})}function Le(){I("set","ads_data_redaction",!0),I("set","url_passthrough",!0)}function ie(){return i.requiresOptIn&&!i.strictOptIn&&i.region==="other"}function ae(){let e=u();U(e,e.analytics&&i.adStorage)}function U(e,t=e.marketing&&i.adStorage){let n=o=>o?"granted":"denied";I("consent","update",{analytics_storage:n(e.analytics),functionality_storage:n(e.functional),personalization_storage:n(e.functional),ad_storage:n(t),ad_user_data:n(t),ad_personalization:n(t)})}function Re(){let e=`${O}=`,t=(document.cookie||"").split(";").map(o=>o.trim()).filter(o=>o.startsWith(e)),n=t.map(o=>ve(o.slice(e.length))).filter(Boolean);return{saved:xe(n),entryCount:t.length}}function De(e){let t=`${e}=`,o=(document.cookie||"").split(";").map(r=>r.trim()).find(r=>r.startsWith(t))?.slice(t.length);return ne.includes(o)?o:null}function ve(e){try{let t=JSON.parse(decodeURIComponent(e));return!t||typeof t!="object"?null:{essential:!0,analytics:t.analytics===!0,functional:t.functional===!0,marketing:t.marketing===!0,timestamp:t.timestamp??null}}catch{return null}}function xe(e){if(e.length===0)return null;let t=e.map(o=>typeof o.timestamp=="string"?Date.parse(o.timestamp):Number.NaN);if(t.some(Number.isNaN))return e.at(-1);let n=0;for(let o=1;o<e.length;o++)t[o]>=t[n]&&(n=o);return e[n]}function se(e){let t=typeof e.timestamp=="string"?Date.parse(e.timestamp):Number.NaN,n=(Number.isNaN(t)?Date.now():t)+i.cookieDays*24*60*60*1e3,o=window.location?.protocol==="https:"?";Secure":"";i.cookieDomain&&Z(`${O}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;max-age=0;path=/;SameSite=Lax${o}`);let r=i.cookieDomain?`;domain=${i.cookieDomain}`:"";Z(`${O}=${encodeURIComponent(JSON.stringify(e))};expires=${new Date(n).toUTCString()};path=/${r};SameSite=Lax${o}`)}function Z(e){document.cookie=e}var b="webority_attribution",Ue=2160*60*60*1e3,Pe=200,P=500,Me=Object.freeze({utm_source:"utmSource",utm_medium:"utmMedium",utm_campaign:"utmCampaign",utm_content:"utmContent",utm_term:"utmTerm",gclid:"gclid",gbraid:"gbraid",wbraid:"wbraid",fbclid:"fbclid",msclkid:"msclkid",li_fat_id:"liFatId"}),ce=!1;function Ge(){de("captureAttribution"),ze();let e=Fe();if(!e)return;let t=B(M());le(M(),{firstTouch:t?.firstTouch??e,lastTouch:e}),$e(e)}function $e(e){let t={event:"acquisition_touch",acquisition_channel:h(e)};e.aiSource&&(t.ai_source=e.aiSource),window.dataLayer=window.dataLayer||[],window.dataLayer.push(t)}function F(){return de("getAttribution"),B(M())}function Fe(){let e=new URLSearchParams(window.location.search),t={};for(let[r,c]of Object.entries(Me)){let a=A(e.get(r),Pe);a&&(t[c]=a)}let n=A(e.get("referrer"),P)||Be();if(n&&(t.referrer=n),Object.keys(t).length===0)return null;let o=L(t);return o&&(t.aiSource=o),t.landingPage=A(window.location.pathname,P),t.capturedDateTimeUtc=new Date().toISOString(),t}function Be(){let e=document.referrer;if(!e)return"";try{return new URL(e).hostname===window.location.hostname?"":A(e,P)}catch{return""}}function ze(){ce||(ce=!0,E(e=>{let t=e.marketing?$():G(),n=e.marketing?G():$(),o=B(t);je(t),o&&le(n,o)}))}function M(){return u().marketing?G():$()}function G(){try{return window.localStorage}catch{return null}}function $(){try{return window.sessionStorage}catch{return null}}function B(e){try{let t=e?.getItem(b);if(!t)return null;let n=JSON.parse(t),o=ue(n?.firstTouch),r=ue(n?.lastTouch);return!o&&!r?(e.removeItem(b),null):{firstTouch:o??r,lastTouch:r??o}}catch{return null}}function le(e,t){try{e?.setItem(b,JSON.stringify(t))}catch{}}function je(e){try{e?.removeItem(b)}catch{}}function ue(e){if(!e||typeof e!="object")return null;let t=Date.parse(e.capturedDateTimeUtc);return Number.isFinite(t)&&Date.now()-t<=Ue?e:null}function A(e,t){let n=String(e??"").trim();return n?n.slice(0,t):""}function de(e){if(!y())throw new Error(`@webority/analytics: call initConsent before ${e}.`)}var s=Object.freeze({SIGNUP_STARTED:"signup_started",SIGNUP_COMPLETED:"signup_completed",LOGIN_SUCCEEDED:"login_succeeded",ONBOARDING_STARTED:"onboarding_started",ONBOARDING_STEP_COMPLETED:"onboarding_step_completed",ONBOARDING_COMPLETED:"onboarding_completed",SUBSCRIPTION_ACTIVATED:"subscription_activated",SUBSCRIPTION_CANCELLED:"subscription_cancelled",PAYMENT_SUCCEEDED:"payment_succeeded",PAYMENT_FAILED:"payment_failed",FEEDBACK_SUBMITTED:"feedback_submitted",LEAD_SUBMITTED:"lead_submitted",LEAD_QUALIFIED:"lead_qualified",WHATSAPP_CLICK:"whatsapp_click",CALCULATOR_USE:"calculator_use",PHONE_CLICK:"phone_click",DEMO_BOOKED:"demo_booked",CONTACT_SUBMITTED:"contact_submitted",TRIAL_START_CLICK:"trial_start_click",SAMPLE_REPORT_DOWNLOAD:"sample_report_download",REPORT_VERIFIED:"report_verified",CONTENT_ENGAGED:"content_engaged"}),ht=Object.freeze({signupStarted:s.SIGNUP_STARTED,signupCompleted:s.SIGNUP_COMPLETED,loginSucceeded:s.LOGIN_SUCCEEDED,onboardingStarted:s.ONBOARDING_STARTED,onboardingStepCompleted:s.ONBOARDING_STEP_COMPLETED,onboardingCompleted:s.ONBOARDING_COMPLETED,subscriptionActivated:s.SUBSCRIPTION_ACTIVATED,subscriptionCancelled:s.SUBSCRIPTION_CANCELLED,paymentSucceeded:s.PAYMENT_SUCCEEDED,paymentFailed:s.PAYMENT_FAILED,feedbackSubmitted:s.FEEDBACK_SUBMITTED,leadSubmitted:s.LEAD_SUBMITTED,leadQualified:s.LEAD_QUALIFIED,whatsappClick:s.WHATSAPP_CLICK,calculatorUse:s.CALCULATOR_USE,phoneClick:s.PHONE_CLICK,demoBooked:s.DEMO_BOOKED,contactSubmitted:s.CONTACT_SUBMITTED,trialStartClick:s.TRIAL_START_CLICK,sampleReportDownload:s.SAMPLE_REPORT_DOWNLOAD,reportVerified:s.REPORT_VERIFIED,contentEngaged:s.CONTENT_ENGAGED}),wt=/^[a-z][a-z0-9]*(_[a-z0-9]+)*$/;var d={config:null,posthogInstance:null,posthogInitPromise:null,registeredEvents:new Set(Object.values(s)),warnedUnregisteredEvents:new Set,pendingIdentify:null},bt=50;function Nt(e){d.config=e,d.posthogInstance=null,d.posthogInitPromise=null,d.pendingIdentify=null}function Ke(){let e=d.config;return e?!!(e.enabled&&e.clientKey&&e.environment!=="Local"):!1}function N(){return y()&&u().analytics}function kt(){return Ke()&&N()}var qe=new Set(["token","code","email","access_token","id_token","state","session_state","password"]),He=/(?:access_token|id_token|session_state|token|code|state|email|password)=/i,Ve=["$current_url","$referrer","$pathname","$initial_current_url","$initial_referrer","$initial_pathname","$session_entry_url","$session_entry_referrer","$session_entry_pathname"],We=4,Ye=5,Je=6;function w(e){if(typeof e!="string")return e;let t=e.indexOf("#"),n=t===-1?e:e.slice(0,t),o=t===-1||He.test(e.slice(t))?"":e.slice(t),r=n.indexOf("?");if(r===-1)return n+o;let c=n.slice(r+1).split("&"),a=c.filter(_=>!qe.has(Ze(_)));if(a.length===c.length)return n+o;let f=n.slice(0,r),C=a.filter(_=>_!=="").join("&");return(C?`${f}?${C}`:f)+o}function fe(e){if(!e||typeof e!="object")return e;let t=e.properties;for(let r of[t,e.$set,e.$set_once,t?.$set,t?.$set_once])Xe(r);let n=t?.$heatmap_data;if(n&&typeof n=="object"){let r={};for(let[c,a]of Object.entries(n)){let f=w(c);r[f]=r[f]?r[f].concat(a):a}t.$heatmap_data=r}if(t&&typeof t=="object"){for(let[r,c]of Object.entries(t))if(r.startsWith("$web_vitals_")&&r.endsWith("_event")&&c&&typeof c=="object")for(let a of["$current_url","navigationURL"])typeof c[a]=="string"&&(c[a]=w(c[a]))}let o=t?.$snapshot_data;if(e.event==="$snapshot"&&o&&typeof o=="object")for(let r of Array.isArray(o)?o:[o])Qe(r);return e}function Qe(e){let t=e?.data;if(!(!t||typeof t!="object")){if(e.type===We)k(t,["href"]);else if(e.type===Ye)k(t.payload,["href"]);else if(e.type===Je&&Array.isArray(t.payload?.requests))for(let n of t.payload.requests)k(n,["name","url"])}}function k(e,t){if(!(!e||typeof e!="object"))for(let n of t)typeof e[n]=="string"&&(e[n]=w(e[n]))}function Xe(e){k(e,Ve)}function Ze(e){let t=e.split("=",1)[0].replace(/\+/g," ");try{return decodeURIComponent(t).toLowerCase()}catch{return t.toLowerCase()}}async function xt(){if(d.posthogInstance)return d.posthogInstance;if(d.posthogInitPromise)return d.posthogInitPromise;let e=d.config;return d.posthogInitPromise=import("posthog-js").then(t=>{let n=t.default??t,o=z(j(e),N());return n.init(e.clientKey,o),n.register({product:e.product,surface:e.surface,environment:e.environment}),N()?n.opt_in_capturing({captureEventName:!1}):n.opt_out_capturing(),d.posthogInstance=n,n}).catch(t=>{throw d.posthogInitPromise=null,t}),d.posthogInitPromise}function z(e,t){return t?e:{...e,opt_out_capturing_by_default:!0}}function j(e){let t=e.sessionRecording??{enabled:!1},n={api_host:e.host,autocapture:!1,capture_pageview:"history_change",cookieless_mode:"on_reject",person_profiles:"identified_only",persistence:"localStorage+cookie",cross_subdomain_cookie:!0,disable_session_recording:!t.enabled,enable_heatmaps:e.heatmaps===!0,capture_exceptions:e.captureExceptions===!0,capture_performance:{web_vitals:e.webVitals===!0},disable_surveys:!0,disable_product_tours:!0,disable_conversations:!0,advanced_disable_feature_flags:!t.enabled,before_send:fe};return t.enabled&&(n.session_recording={maskAllInputs:t.maskAllInputs??!0,...t.maskTextSelector?{maskTextSelector:t.maskTextSelector}:{},maskCapturedNetworkRequestFn:o=>({...o,name:w(o.name)}),recordBody:!1,recordHeaders:!1}),n}var et=()=>import("posthog-js"),m={config:null,posthog:null,loading:null,loadPosthog:et,stopFollowingConsent:null};function tt({host:e,clientKey:t,product:n,surface:o,environment:r,enabled:c=!0,sessionRecording:a,heatmaps:f=!1,captureExceptions:C=!1,webVitals:_=!1}={}){if(!y())throw new Error("@webority/analytics: call initConsent before initSiteAnalytics.");!c||!e||!t||r==="Local"||m.config||(m.config={host:e,clientKey:t,product:n,surface:o,environment:r,sessionRecording:a,heatmaps:f,captureExceptions:C,webVitals:_},m.stopFollowingConsent=E(S=>ot(S.analytics)),m.loading=Promise.resolve().then(m.loadPosthog).then(S=>nt(S.default??S)).catch(()=>{}))}function nt(e){let t=m.config,n=u().analytics;e.init(t.clientKey,z(rt(t),n)),e.register({product:t.product,surface:t.surface,environment:t.environment}),n?e.opt_in_capturing({captureEventName:!1}):e.opt_out_capturing(),m.posthog=e}function ot(e){m.posthog&&(e?m.posthog.opt_in_capturing():m.posthog.opt_out_capturing())}function rt(e){return{...j({host:e.host,sessionRecording:e.sessionRecording,heatmaps:e.heatmaps,captureExceptions:e.captureExceptions,webVitals:e.webVitals}),capture_pageview:!0}}function pe(e,t){let n=m.config;if(!n)return;let o={...t,product:n.product,surface:n.surface,environment:n.environment};m.loading.then(()=>m.posthog?.capture(e,o)).catch(()=>{})}var it=new Set(Object.values(s));function at(e,t={}){if(!it.has(e))return!1;let n=u().analytics,o=F(),r={...t};for(let[c,a]of[["first",o?.firstTouch],["last",o?.lastTouch]])a&&(r[`${c}_touch_channel`]=h(a),a.aiSource&&(r[`${c}_touch_ai_source`]=a.aiSource));return pe(e,r),n?(window.dataLayer=window.dataLayer||[],window.dataLayer.push({...r,event:e}),!0):!1}var st=["scroll","mousemove","touchstart","keydown","pointerdown"],ct="https://www.googletagmanager.com/gtm.js",me=1500,ut=3e3,lt=100,g={loaded:!1,clarityId:null,clarityLoaded:!1,cancelClaritySchedule:null};function dt(e={}){if(!y())throw new Error("@webority/analytics: call initConsent before loadTags.");if(g.loaded)return;g.loaded=!0;let{gtmId:t,gtmUrl:n=ct,clarityId:o,ahrefsKey:r}=e;if(typeof n!="string"||n.trim()==="")throw new Error("@webority/analytics: gtmUrl must be a non-empty string.");let c=oe();if(r){let a=()=>q("https://analytics.ahrefs.com/analytics.js",{"data-key":r});c?ge(f=>f.analytics,a):a()}if(t){let a=v(),f=V=>V.analytics||V.marketing&&a,C=()=>{window.dataLayer=window.dataLayer||[],window.dataLayer.push({"gtm.start":Date.now(),event:"gtm.js"}),q(`${n}${n.includes("?")?"&":"?"}id=${encodeURIComponent(t)}`)},_=u(),S=_.decided&&f(_)?ft:pt,H=()=>S(C);c?ge(f,H):H()}o&&(g.clarityId=o,u().analytics&&mt(),E(a=>{a.analytics&&!g.clarityLoaded?K():g.clarityLoaded&&_e(a)}))}function ge(e,t){if(e(u())){t();return}let n=E(o=>{e(o)&&(n(),t())})}function ft(e){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e,{once:!0}):e()}function pt(e){let t=!1,n=()=>{t||(t=!0,e())};for(let o of st)window.addEventListener(o,n,{once:!0,passive:!0});document.readyState==="complete"?setTimeout(n,me):window.addEventListener("load",()=>setTimeout(n,me),{once:!0})}function mt(){let e=()=>{window.scrollY>lt&&K()};window.addEventListener("scroll",e,{passive:!0});let t=setTimeout(K,ut);g.cancelClaritySchedule=()=>{window.removeEventListener("scroll",e),clearTimeout(t)}}function K(){g.cancelClaritySchedule?.(),g.cancelClaritySchedule=null,!(g.clarityLoaded||!g.clarityId)&&(g.clarityLoaded=!0,window.clarity=window.clarity||function(){window.clarity.q=window.clarity.q||[],window.clarity.q.push(arguments)},_e(u()),q(`https://www.clarity.ms/tag/${encodeURIComponent(g.clarityId)}`,{crossorigin:"anonymous"}))}function _e(e){window.clarity("consentv2",{ad_Storage:e.marketing&&v()?"granted":"denied",analytics_Storage:e.analytics?"granted":"denied"})}function q(e,t={}){let n=document.createElement("script");n.async=!0,n.src=e;for(let[o,r]of Object.entries(t))n.setAttribute(o,r);document.head.appendChild(n)}export{Oe as a,O as b,ee as c,Ae as d,be as e,y as f,u as g,Ne as h,E as i,s as j,ht as k,wt as l,d as m,bt as n,Nt as o,Ke as p,N as q,kt as r,xt as s,l as t,h as u,L as v,Ge as w,F as x,tt as y,at as z,dt as A};