@iann29/rastro 0.4.0 → 0.5.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.
Files changed (92) hide show
  1. package/README.md +122 -17
  2. package/agent/integration.md +26 -10
  3. package/agent/manifest.json +10 -5
  4. package/agent/manifest.schema.json +14 -5
  5. package/dist/client/federation.d.ts +28 -8
  6. package/dist/client/federation.d.ts.map +1 -1
  7. package/dist/client/federation.js +12 -1
  8. package/dist/client/federation.js.map +1 -1
  9. package/dist/client/index.d.ts +262 -9
  10. package/dist/client/index.d.ts.map +1 -1
  11. package/dist/client/index.js +119 -2
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/component/_generated/api.d.ts +6 -0
  14. package/dist/component/_generated/api.d.ts.map +1 -1
  15. package/dist/component/_generated/api.js.map +1 -1
  16. package/dist/component/_generated/component.d.ts +71 -1
  17. package/dist/component/_generated/component.d.ts.map +1 -1
  18. package/dist/component/constants.d.ts +2 -0
  19. package/dist/component/constants.d.ts.map +1 -1
  20. package/dist/component/constants.js +7 -0
  21. package/dist/component/constants.js.map +1 -1
  22. package/dist/component/coverage.d.ts +1 -0
  23. package/dist/component/coverage.d.ts.map +1 -1
  24. package/dist/component/coverage.js +6 -1
  25. package/dist/component/coverage.js.map +1 -1
  26. package/dist/component/eventStore.d.ts +2 -0
  27. package/dist/component/eventStore.d.ts.map +1 -1
  28. package/dist/component/http.d.ts.map +1 -1
  29. package/dist/component/http.js +51 -1
  30. package/dist/component/http.js.map +1 -1
  31. package/dist/component/ingest.d.ts +2 -0
  32. package/dist/component/ingest.d.ts.map +1 -1
  33. package/dist/component/ingest.js +42 -3
  34. package/dist/component/ingest.js.map +1 -1
  35. package/dist/component/origin.d.ts +70 -0
  36. package/dist/component/origin.d.ts.map +1 -0
  37. package/dist/component/origin.js +230 -0
  38. package/dist/component/origin.js.map +1 -0
  39. package/dist/component/platforms.d.ts +33 -0
  40. package/dist/component/platforms.d.ts.map +1 -0
  41. package/dist/component/platforms.js +328 -0
  42. package/dist/component/platforms.js.map +1 -0
  43. package/dist/component/reports.d.ts +27 -72
  44. package/dist/component/reports.d.ts.map +1 -1
  45. package/dist/component/reports.js +51 -10
  46. package/dist/component/reports.js.map +1 -1
  47. package/dist/component/sanitize.d.ts +5 -0
  48. package/dist/component/sanitize.d.ts.map +1 -1
  49. package/dist/component/sanitize.js +33 -1
  50. package/dist/component/sanitize.js.map +1 -1
  51. package/dist/component/schema.d.ts +62 -7
  52. package/dist/component/schema.js +16 -1
  53. package/dist/component/schema.js.map +1 -1
  54. package/dist/component/trackedLinks.d.ts +91 -0
  55. package/dist/component/trackedLinks.d.ts.map +1 -0
  56. package/dist/component/trackedLinks.js +314 -0
  57. package/dist/component/trackedLinks.js.map +1 -0
  58. package/dist/component/useragent.d.ts +6 -0
  59. package/dist/component/useragent.d.ts.map +1 -1
  60. package/dist/component/useragent.js +9 -0
  61. package/dist/component/useragent.js.map +1 -1
  62. package/dist/component/validators.d.ts +51 -11
  63. package/dist/component/validators.d.ts.map +1 -1
  64. package/dist/component/validators.js +35 -1
  65. package/dist/component/validators.js.map +1 -1
  66. package/dist/tracker/generated.d.ts +6 -6
  67. package/dist/tracker/generated.d.ts.map +1 -1
  68. package/dist/tracker/generated.js +6 -6
  69. package/dist/tracker/generated.js.map +1 -1
  70. package/dist/tracker/tracker.d.ts +1 -0
  71. package/dist/tracker/tracker.d.ts.map +1 -1
  72. package/dist/tracker/tracker.js +16 -4
  73. package/dist/tracker/tracker.js.map +1 -1
  74. package/dist/tracker.min.js +1 -1
  75. package/docs/upgrading.md +152 -19
  76. package/llms.txt +6 -1
  77. package/package.json +2 -2
  78. package/src/component/_generated/api.ts +6 -0
  79. package/src/component/_generated/component.ts +152 -1
  80. package/src/component/constants.ts +7 -0
  81. package/src/component/coverage.ts +7 -1
  82. package/src/component/http.ts +56 -1
  83. package/src/component/ingest.ts +54 -1
  84. package/src/component/origin.ts +273 -0
  85. package/src/component/platforms.ts +359 -0
  86. package/src/component/reports.ts +74 -10
  87. package/src/component/sanitize.ts +39 -1
  88. package/src/component/schema.ts +18 -0
  89. package/src/component/trackedLinks.ts +384 -0
  90. package/src/component/useragent.ts +11 -0
  91. package/src/component/validators.ts +71 -0
  92. package/src/tracker/generated.ts +6 -6
@@ -1,3 +1,5 @@
1
+ import { PLATFORMS } from "./platforms.js";
2
+
1
3
  export type ClientClassification = {
2
4
  browser: string;
3
5
  os: string;
@@ -100,6 +102,15 @@ export function classifyUserAgent(userAgent: string): ClientClassification {
100
102
  };
101
103
  }
102
104
 
105
+ /**
106
+ * The platform whose in-app browser sent the request (Instagram, Facebook,
107
+ * TikTok…), from the marker each app appends to the User-Agent. The system
108
+ * browser a messaging app hands a link to carries none.
109
+ */
110
+ export function inAppPlatform(userAgent: string): string | undefined {
111
+ return PLATFORMS.find((row) => row.agent?.test(userAgent))?.id;
112
+ }
113
+
103
114
  function matchAgent(
104
115
  table: readonly (readonly [RegExp, string])[],
105
116
  userAgent: string,
@@ -50,6 +50,9 @@ export const trackerEventValidator = v.object({
50
50
  // Web Vitals measurement: milliseconds, or CLS scaled by 1000. Only "vital"
51
51
  // events carry it; sanitization strips it from every other type.
52
52
  value: v.optional(v.number()),
53
+ // The names of the click-ID keys on the landing URL (`fbclid`, `gclid`…),
54
+ // never their values; sanitization keeps only the known ones (origin.ts).
55
+ clid: v.optional(v.array(v.string())),
53
56
  });
54
57
 
55
58
  export const ingestContextValidator = v.object({
@@ -61,8 +64,41 @@ export const ingestContextValidator = v.object({
61
64
  os: v.optional(v.string()),
62
65
  device: v.optional(v.string()),
63
66
  visitorKey: v.optional(v.string()),
67
+ // The platform whose in-app browser sent the batch (useragent.ts), derived
68
+ // by the HTTP action so the raw User-Agent never reaches a mutation.
69
+ inApp: v.optional(v.string()),
64
70
  });
65
71
 
72
+ // How a session arrived (channel) and which rule proved it (evidence); see
73
+ // origin.ts. "legacy" is never stored: reports mark a session recorded before
74
+ // origins existed with it when they classify that session on read.
75
+ export const channelValidator = v.union(
76
+ v.literal("direct"),
77
+ v.literal("organic_search"),
78
+ v.literal("paid_search"),
79
+ v.literal("organic_social"),
80
+ v.literal("paid_social"),
81
+ v.literal("messaging"),
82
+ v.literal("email"),
83
+ v.literal("affiliate"),
84
+ v.literal("ai"),
85
+ v.literal("display"),
86
+ v.literal("referral"),
87
+ // A link printed off the web: a QR code, a flyer, a receipt. Only a tracked
88
+ // link can say so, since the scan itself carries no referrer.
89
+ v.literal("offline"),
90
+ );
91
+
92
+ export const evidenceValidator = v.union(
93
+ v.literal("utm"),
94
+ v.literal("clickId"),
95
+ v.literal("referrer"),
96
+ v.literal("inApp"),
97
+ v.literal("affiliate"),
98
+ v.literal("none"),
99
+ v.literal("legacy"),
100
+ );
101
+
66
102
  export const batchedEventValidator = trackerEventValidator.extend({
67
103
  ...ingestContextValidator.fields,
68
104
  aggregateCountry: v.optional(v.string()),
@@ -94,6 +130,10 @@ export const sessionFieldsValidator = v.object({
94
130
  exitPath: v.string(),
95
131
  referrer: v.optional(v.string()),
96
132
  source: v.string(),
133
+ // The first touch's origin (origin.ts); absent on sessions recorded before.
134
+ platform: v.optional(v.string()),
135
+ channel: v.optional(channelValidator),
136
+ evidence: v.optional(evidenceValidator),
97
137
  utmSource: v.optional(v.string()),
98
138
  utmMedium: v.optional(v.string()),
99
139
  utmCampaign: v.optional(v.string()),
@@ -155,6 +195,10 @@ export const dimensionTypeValidator = v.union(
155
195
  // host of an outbound click (never its path).
156
196
  v.literal("medium"),
157
197
  v.literal("outbound"),
198
+ // The session's origin platform, channel and evidence (origin.ts).
199
+ v.literal("platform"),
200
+ v.literal("channel"),
201
+ v.literal("evidence"),
158
202
  );
159
203
 
160
204
  export const dimensionSlotValidator = v.object({
@@ -254,6 +298,31 @@ export const affiliateFieldsValidator = v.object({
254
298
  updatedAt: v.number(),
255
299
  });
256
300
 
301
+ // Where a tracked link was published: chosen at creation and carried to the
302
+ // landing page as its utm_medium.
303
+ export const trackedLinkChannelValidator = v.union(
304
+ v.literal("organic_social"),
305
+ v.literal("paid_social"),
306
+ v.literal("messaging"),
307
+ v.literal("email"),
308
+ v.literal("affiliate"),
309
+ v.literal("display"),
310
+ v.literal("referral"),
311
+ v.literal("offline"),
312
+ );
313
+
314
+ export const trackedLinkFieldsValidator = v.object({
315
+ siteId: v.id("sites"),
316
+ slug: v.string(),
317
+ destination: v.string(),
318
+ platform: v.string(),
319
+ channel: trackedLinkChannelValidator,
320
+ campaign: v.optional(v.string()),
321
+ createdAt: v.number(),
322
+ createdBy: v.string(),
323
+ disabledAt: v.optional(v.number()),
324
+ });
325
+
257
326
  export const ingestResultValidator = v.object({
258
327
  accepted: v.number(),
259
328
  duplicates: v.number(),
@@ -278,3 +347,5 @@ export type IngestContext = Infer<typeof ingestContextValidator>;
278
347
  export type EventProperties = Infer<typeof eventPropertiesValidator>;
279
348
  export type FunnelStep = Infer<typeof funnelStepValidator>;
280
349
  export type EventType = Infer<typeof eventTypeValidator>;
350
+ export type Channel = Infer<typeof channelValidator>;
351
+ export type Evidence = Infer<typeof evidenceValidator>;
@@ -1,10 +1,10 @@
1
1
  // Generated by scripts/build-tracker.mjs. Do not edit.
2
- export const RASTRO_VERSION = "0.4.0";
3
- export const TRACKER_SOURCE = "(()=>{const e=document.currentScript,t=e?.dataset.site,n=e?.dataset.endpoint||e?.src&&new URL(\"events\",e.src).href;if(!t||!n)return;const r=()=>crypto.randomUUID?.()||Math.random()+\"\",o=new URLSearchParams(location.search),s=o.get(\"ref\")?.slice(0,64);let a;for(const e of[\"source\",\"medium\",\"campaign\",\"term\",\"content\"]){const t=o.get(\"utm_\"+e)?.slice(0,64);t&&((a??={})[\"utm_\"+e]=t)}let i,c,d,l,h=e.dataset.visitor||\"\";try{h||=localStorage._rv||=r()}catch{}try{c=sessionStorage,d=c._r,i=c._ri==h&&c._rt,l=s||c._a,l&&(c._a=l),a||=c._u&&JSON.parse(c._u),a&&(c._u=JSON.stringify(a))}catch{l=s}let p,u=0;const v=[],g=document.referrer?new URL(document.referrer).origin:void 0,m=e=>{const r=v.splice(0,50);if(!r.length)return;const o=()=>new Blob([JSON.stringify({siteId:t,events:r,sentAt:Date.now()})]);let s=o();for(;s.size>64e3&&r.length>1;)v.unshift(r.pop()),s=o();e&&navigator.sendBeacon(n,s)||fetch(n,{method:\"POST\",body:s,keepalive:1}).catch(()=>{}),v.length&&m(e)},f=(e,t,n)=>{const o=Date.now(),s=o-i;i=o,s<18e5||(d=r(),\"pageview\"!=e&&(y=\"\",_()));try{c._r=d,c._ri=h,c._rt=o}catch{}v.push({eventId:`${d}.${o.toString(36)}.${u}`,sessionId:d,visitorId:h||d,type:e,name:t,path:location.pathname.slice(0,256),referrer:g,timestamp:o,sequence:u++,affiliateSlug:l,...n}),clearTimeout(p),p=setTimeout(m,1200)};let y;const _=()=>{const e=location.pathname;e!=y&&(y=e,f(\"pageview\",void 0,a&&{properties:a}))};window.rastro=(e,t,n)=>{if(\"context\"==e)return{sessionId:d,visitorId:h||d};\"event\"==e&&f(\"custom\",`${t||\"event\"}`.slice(0,80),n&&JSON.stringify(n).length>2e4?void 0:{properties:n})},document.addEventListener(\"click\",e=>{const t=e.target?.closest(\"a,button,[data-rastro-event]\");if(!t)return;const n=t.dataset.rastroEvent,r=t.href,o=r&&new URL(r),s=/^https?:$/.test(o?.protocol),a=s&&o.origin!=location.origin;f(n?\"custom\":a?\"outbound\":\"click\",n,{target:(t.dataset.rastroLabel||t.innerText||t.tagName).slice(0,64),href:s?((a?o.origin:\"\")+o.pathname).slice(0,256):void 0})},1);for(const e of[\"pushState\",\"replaceState\"]){const t=history[e];history[e]=(...e)=>{t.apply(history,e),_()}}addEventListener(\"popstate\",_);let S=0;const w=()=>{f(\"heartbeat\"),m()},I=()=>{S&&(clearInterval(S),S=0,f(\"leave\"),m(1))},L=()=>{document.hidden?I():S||(w(),S=setInterval(w,2e4))};addEventListener(\"pagehide\",I),addEventListener(\"pageshow\",L),document.addEventListener(\"visibilitychange\",L),S=setInterval(w,2e4),_(),L()})();";
4
- export const TRACKER_GZIP_BASE64 = "H4sIAAAAAAACA32VUW/bNhDHv0pCBAKJXFmnTYNCHmus6B48ZG0xt09BljDS2SIqkRp5sutZ+u4DJdlOmm5PEnkn3fH4+99xLtS7XeZsoBNUucuaCi3JrPEeLS0yb2oCUjiTuSYdkGQwhGAf76DNa2cstS3OZPBZkljcnHz985ozXKOlwADjvpCFx+XULPkpte2pFR6p8XY6RPcqppL5bU1Oem1zV339Ov8wk1y07R+ainGTi3PGwKkxxgK1z4rP2usq8NJlmoyzMvS7AoJycoXEmcclEzMZSpMhn8DVpZiWSCd6unSej8c/ccsbFlzjM2TAKsxNUzFgma5qbVaWASP0/Y6zhJbYrRgrR/swDVV37Bx/iERJwrmezdSuEzd7n1tFoos5GMgghxIKhYeSrk0w5HzbMjYlv90Vbavi4coFOa9XKO/8um2V56LLNGXFrotemQoYgnF29IJcZfLOg+kfRqkiSeIbQalC22byTkOZJDy+qFKAbtvo2STJ74tPH2WtfcBobATowa1RvSWQN3ZllluuxT6DUoX+ODU0ajLe6Vrd3MLqiJXHJXqPfrYH5JlFSOfNyth07Ux+MoFK4YFPr9Yy1GNd30xET5KXJdoVFU9hcj1MMcr70j3wmx+y3kWI53lKMACaegho6VdKP2hCad2Gi07cDowE5bjoOZkGGcw/+O7qEl8nyT7yu4upWMvGhsIsiXtZu5qLHj0uppgkVq/NSpPzMqDN36POnOUWgmjbJVJWcAu7Cqlweco+f1p8YfDg8m0a4BtirUuzxvSiE7KvMu/l2glYj8GTpOIoOlgqjkBgj2p26niWmMwLMzXKQfjl4i2+aVueR3qA1XqFa4MbdqowSfhWMQZ3XAjRcxdpUTkM+BT9k5TbM7eWdRMKvuuLOM/T+7Nd3smznZPkFn2x+esrEXea7h5GNud5msPI9zxPi7bNgbY1pghWV5gS1JqK9CDluIqGg6JevbkSsOclXQGZCgPpqk4dBPy7QZth2pyfg14uTWk04aJsVmkJUkrbCchK1P6LqdA1xGsBtQpI+3UFF68mE9H1N78dabpTT7rks9SmeKq2ffEQlvxYUhgh1kmyq72r0ZPBkOpOiG66MTZ3G+l1IO8e3Z5Z8qHBfCemFI5c7/67et10aLPRO0ni100gVzG4P9tR247G7v5QwLcTAXbU+FETVux5foWXsyHz9HHathMdHASr8/y3+ONrEwgtes6y0mTfGBz1Sgolab9CmsmsdAEDcabhoSFyFm5ir3sxHP9Fn+MtGyRNT7VsFR364uDeBwavqB8o4JQ/jhwfYX/5V0FUh1l69lJSDOtmsvaOXOZim1MhSdzYaE6P1zlsTJfczvY1TPWMuYYeXGNzlu6PaGE3nCvlP6Z2rR+wbFuSxlr0X/A7xQXp1UddoXg8FSDmnoZZnAz7ZFLGxLk7cCWeMD+2xHgLF+LZ3IpKXJCmOLo81qXOcFg+GlKFCeT89gZvp8dXxaWUGMkjqeu63PLRBihiJ+i651dduzoMse6GHrk4tPzNoJUlZwVqTw+oiQmouOhgPpgWcZREDc4toV/rki8ELNQkSqdEvcbe/0KIDq6HLw7QFSbP0c7mXKSLtuWxsy2ieg9/2sArvIzq+knOeoWFyZHBXMDPzaFwGwbX4v8oj9p7MKWhbVZou8Le/2dJxNrBdZwjXEz/BQqEd9NnCQAA";
5
- export const TRACKER_RAW_BYTES = 2407;
6
- export const TRACKER_GZIP_BYTES = 1278;
7
- export const TRACKER_HASH = "7fccc2fba6e092cb";
2
+ export const RASTRO_VERSION = "0.5.0";
3
+ export const TRACKER_SOURCE = "(()=>{const t=document.currentScript,e=t?.dataset.site,i=t?.dataset.endpoint||t?.src&&new URL(\"events\",t.src).href;if(!e||!i)return;const n=()=>crypto.randomUUID?.()||Math.random()+\"\",s=new URLSearchParams(location.search),r=s.get(\"ref\")?.slice(0,64);let o;for(const t of[\"source\",\"medium\",\"campaign\",\"term\",\"content\"]){const e=s.get(\"utm_\"+t)?.slice(0,64);e&&((o??={})[\"utm_\"+t]=e)}const a=\"gclid gbraid wbraid msclkid ttclid twclid li_fat_id ScCid rdt_cid dclid epik srsltid mc_cid mc_eid _hsenc igsh igshid fbclid\".split(\" \").filter(t=>s.has(t)).slice(0,8);let c,d,l,h,p=t.dataset.visitor||\"\";try{p||=localStorage._rv||=n()}catch{}try{d=sessionStorage,l=d._r,c=d._ri==p&&d._rt,h=r||d._a,h&&(d._a=h),o||=d._u&&JSON.parse(d._u),o&&(d._u=JSON.stringify(o))}catch{h=r}let g,v=0;const m=[],u=document.referrer.split(\"/\",3).join(\"/\")||void 0,f=t=>{const n=m.splice(0,50);if(!n.length)return;const s=()=>new Blob([JSON.stringify({siteId:e,events:n,sentAt:Date.now()})]);let r=s();for(;r.size>64e3&&n.length>1;)m.unshift(n.pop()),r=s();t&&navigator.sendBeacon(i,r)||fetch(i,{method:\"POST\",body:r,keepalive:1}).catch(()=>{}),m.length&&f(t)},_=(t,e,i)=>{const s=Date.now(),r=s-c;c=s,r<18e5||(l=n(),\"pageview\"!=t&&(y=\"\",S()));try{d._r=l,d._ri=p,d._rt=s}catch{}m.push({eventId:`${l}.${s.toString(36)}.${v}`,sessionId:l,visitorId:p||l,type:t,name:e,path:location.pathname.slice(0,256),referrer:u,timestamp:s,sequence:v++,affiliateSlug:h,...i}),clearTimeout(g),g=setTimeout(f,1200)};let y;const S=()=>{const t=location.pathname;t!=y&&(y=t,_(\"pageview\",void 0,{properties:o,clid:a.length?a:void 0}))};window.rastro=(t,e,i)=>{if(\"context\"==t)return{sessionId:l,visitorId:p||l};\"event\"==t&&_(\"custom\",`${e||\"event\"}`.slice(0,80),i&&JSON.stringify(i).length>2e4?void 0:{properties:i})},document.addEventListener(\"click\",t=>{const e=t.target?.closest(\"a,button,[data-rastro-event]\");if(!e)return;const i=e.dataset.rastroEvent,n=e.href,s=n&&new URL(n),r=/^https?:$/.test(s?.protocol),o=r&&s.origin!=location.origin;_(i?\"custom\":o?\"outbound\":\"click\",i,{target:(e.dataset.rastroLabel||e.innerText||e.tagName).slice(0,64),href:r?((o?s.origin:\"\")+s.pathname).slice(0,256):void 0})},1);for(const t of[\"pushState\",\"replaceState\"]){const e=history[t];history[t]=(...t)=>{e.apply(history,t),S()}}addEventListener(\"popstate\",S);let w=0;const b=()=>{_(\"heartbeat\"),f()},I=()=>{w&&(clearInterval(w),w=0,_(\"leave\"),f(1))},L=()=>{document.hidden?I():w||(b(),w=setInterval(b,2e4))};addEventListener(\"pagehide\",I),addEventListener(\"pageshow\",L),document.addEventListener(\"visibilitychange\",L),w=setInterval(b,2e4),S(),L()})();";
4
+ export const TRACKER_GZIP_BASE64 = "H4sIAAAAAAACA31VWY/bNhD+K14iEEjshNnNhUIuY/R6cLE9UCdPi61DSyOJjUSq5MiOa+m/F5R8bI72RSRnhpqD3zfDuVBvDpmzgWakcpd1DVqSWec9Wlpl3rQEqGghc006IMlgCME8lqDNW2cs9T0tZPBZkljczd79cccZbtFSYEBRLmTlsZibgl9h318Z4ZE6b+eTd6tiKJnft+Sk1zZ3zbt3yx8Xkou+/0VTdRRycc0YBHX0sULts+p37XUTeO0yTcZZGUapAK+CLJE481gwsZChNhnyG3j9UsxrpJmbF87zY/ozV9yz4DqfIQPWYG66hgHLdNNqU1oGjNCPEmcJLbEHcawcntx01KzZNX3mCZOEc7dYqMMg7k82DwrFMF3XipVZbfJZufHa5LPdtDQhqz+YfEY0Kmk3LrVZF5rWJp+tsh9MPvM5rTOTz/JRi635MAs+1BR/kI2aJlujyWfrKqDNZqYM1fgx+azYxEtMhrY2xNmMCVmYmtBzUm+CrHTgJMQ5l2+momWQQw0VtIrOGNiaYMj5vmdsTn5/aPtexdeoV+S8LlGu/bbvleViyDRl1WGIVrkKGIJx9mgFtcrl2kM2LkapNknijqBSvu9zudZQJQmPG1UJcH0fLbsk+Xn126+y1T5gVHYC3GTWqVETyBtbmmLPnThFUCk/xHRK2KqbIwgbdf8A3YUHHgv0Hv2pQs8YvBDyL2ds3Iu+3zqTz26gUHSmkVXNaD6W7NWNGAFvZY22pOpTzIcR8xHJ39duw+8/i/UQubbMU4SJR6mFgJa+o/RHTSit23ExiIfpVbwKXIxwnnsZzD/45vVLfJEkJ89vbueikZ0NlSmIW9m6louRIVzMKUms3ppSk/MyoM2/R505yw140fcFUlZxA4cGqXJ5yn7/bfWWwcbl+9TDB8RW12aL6e0g5FhbPnaVQUBzdJ4kBScxwFpxAgRzaTpBXXKJwTzN5pkK4L+9/QZf9T2vI2aAtbrErcEdu1KUJHyvGIMVF0KMaIsYUTVMoGnHlVQ4Ia2RbRcqfhiLuMzT908O9SCfHIIktxqLzV+8FlGyHd7DEZHLPK3hiOplnrZ9XwPtW0wJrG4wRWg1Vem548RTVJzJ8vzVawEn/KQdkGkwkG7aNEDAvzu0Gabb62vQRWFqowlXdVemFUgpzSAgq1H7t6ZB1xEvBZQqIJ3OBdw+v7kRw/jy+yOaVuqTZv5FaHO6UvuxeARrfikpHEF8aL1r0ZPBkDqInSHVx/db6HQyGoQY5jtjc7eTXgfy7tGLmoJPvfEjMaXoiPXDf1d0mE8TIlonyZqzrAvkGgbvnxyw74/K4f2lA90IMEe2X3hixAnjz/HlYgo0fZyNGcQAZ1LrPP8p/vjOBEKLnrOsNtkHBhcOoyJJ2pdIC5nVLmAgzjRsOiJn4T52vadT+k/HGB/YRHP8lN9G4blDTuajY7AKx1kYx9hlWtpIgGd/VkRtWKRPnkmKbsNCtt6Ry1wtwCmfJEE6b0pjry5PPAnma24WpxqmbsFcRxvX2ZylpxQNHKa8Uv55aHd6g3XfozTWon+LHykeSJe/6gbF44EGMfbUL+JQOwWTMiauwxlr4hMenMEzwK34YuRGdq5IU5y6HttaZzgdH83XygRyfn9PD/PLVnEpJUXkodRtW+/5UQckYncYhi+funVtmHytpr65Ozf/zcSfNWcVak8b1MQEFFwMsJxUuyThIy+XltBvdc13AnbqJtKpRr3F0f5WiAHuphtn0FUmz9Eullyku77nGx4vBqTznzbwHF9Gdn0lZl1iZXJksBTwdXWo3I7Bnfg/lEfubUxtaJ9V2pY42n8tiFg7uIuzhYv5v9gOoJoiCgAA";
5
+ export const TRACKER_RAW_BYTES = 2594;
6
+ export const TRACKER_GZIP_BYTES = 1395;
7
+ export const TRACKER_HASH = "0d369c5fe66dc9cd";
8
8
  export const VITALS_SOURCE = "(()=>{const t=document.currentScript,e=t?.dataset.site,n=t?.dataset.endpoint||t?.src&&new URL(\"events\",t.src).href;if(!e||!n)return;const r=()=>crypto.randomUUID?.()||Math.random()+\"\";let s=t.dataset.visitor||\"\";try{s||=localStorage._rv||=r()}catch{}const o=Date.now();let a;try{a=sessionStorage._ri===s&&o-sessionStorage._rt<18e5&&sessionStorage._r||r(),sessionStorage._r=a,sessionStorage._ri=s,sessionStorage._rt=o}catch{a=r()}const i=s||a,c=location.pathname.slice(0,256),d={},h=[],l=(t,e,n)=>{try{const r=new PerformanceObserver(t=>e(t.getEntries()));r.observe({type:t,buffered:1,...n}),h.push({observer:r,handler:e})}catch{}},f=performance.getEntriesByType?.(\"navigation\")[0];f&&f.responseStart>0&&(d.TTFB=f.responseStart),l(\"paint\",t=>{for(const e of t)\"first-contentful-paint\"===e.name&&(d.FCP=e.startTime)}),l(\"largest-contentful-paint\",t=>{const e=t[t.length-1];e&&(d.LCP=e.startTime)});let m=0,u=0,v=0;l(\"layout-shift\",t=>{for(const e of t)e.hadRecentInput||(m&&e.startTime-v<1e3&&e.startTime-u<5e3?m+=e.value:(m=e.value,u=e.startTime),v=e.startTime,d.CLS=Math.max(d.CLS||0,1e3*m))});const g=[],p=new Set,S=t=>{for(const e of t)e.interactionId&&(p.add(e.interactionId),g.push(e.duration));if(!g.length)return;g.sort((t,e)=>e-t),g.length=Math.min(g.length,10);const e=performance.interactionCount||p.size;d.INP=g[Math.min(g.length-1,Math.floor(e/50))]};l(\"event\",S,{durationThreshold:40}),l(\"first-input\",S);let y=0;const b=()=>{if(y)return;for(const{observer:t,handler:e}of h)e(t.takeRecords()),t.disconnect();const t=Date.now(),r=Object.keys(d).map((e,n)=>({eventId:`${a}.${t.toString(36)}.v${n}`,sessionId:a,visitorId:i,type:\"vital\",name:e,value:Math.round(d[e]),path:c,timestamp:t,sequence:n}));if(!r.length)return;y=1;const s=new Blob([JSON.stringify({siteId:e,events:r,sentAt:t})]),o=navigator.sendBeacon?.bind(navigator);o&&o(n,s)||fetch(n,{method:\"POST\",body:s,keepalive:1}).catch(()=>{})};document.addEventListener(\"visibilitychange\",()=>{\"hidden\"===document.visibilityState&&b()}),addEventListener(\"pagehide\",b)})();";
9
9
  export const VITALS_GZIP_BASE64 = "H4sIAAAAAAACA3VVbW/bNhD+K6lQCORKc/ayFINcJlj6AnjImqBOPwXBSosniatEauTJnSbpvw+i7MSJ22/SkXf33N1zDwmh4rxLrfF4gkLZtKnAIE8b58DgOnW6RgYCL7iSKD0g9xqBmUMLGFVbbbDv8YJ7l8axgW8nnz9dkQi2YNBHDEc75YWDbKkz8gL6/oWhDrBxZjlld2KEkrq2RsudNMpWnz+v3l1wQvv+T4nFzkjoqyhaloAnXuADhq32Gq3r+yhaoms73/eitKks12idzIH/5bZ9LxyhQyoxLbphymrFO4nAjf1GaAgqg7sUHrzX1jy6ayGEj2M7OzrBN4vf4CyOjw763hHKjsxCsu9E98dGFHaHVk7IA2QtfN9Llob6UFvDa4mFkRVwX+oUyJz9cvaaMiW6gRXi7p6VgiADZsZRj9XtGz6O6QZcZl0lTQrXGw9uC46gOAeCPAd8b9Bp8IRSunTcThdIh20NCbJNk2XgQCULxjk3A2UFrxtfkG530yWOFdKoElwCw0PrB5aJ+jHvQaLL9rat4YKTyMitzkN5Eb2b3y+zOM64A19b42GN0uH5PI6J4re3Hy7FsyPKShLVUhuMGIrzLrOOTEXDic1OkEaZdh5nqTUIBrOmnE23hRDAx1aG0B/e3gjgfox4qyugQ4hbSpfD95xDql0agXfISzA5FrPF/XKKd3UUL1CuEnPWiDnbivkyxG9tgzNf6OxH8IEXUn2CFAyuTN1g35Mqjg9Cz7ZvFnD61NS8OYPTi+qVAL6VZQMJqfafrHmCi20Pf5nib6/WIqxgJf8l4bfv52wBpz9VdKxiApePXKsDq9aAbC1+gF0bBCfTcbYrFcek5lIp8sxOWT5xCbhqXCACpUE78l1f9/KRc28dkpHiVJzDDEfX6coOtDZkb2GL+R4uPOHgQfK3thnFrOZe/wdLxVcfb0R+dxRqtmDBlpXWOgI/n80pvR/GCQbVi9iadXvot4UDX9hSJb/OJxZNBNTj9CK2nojQivkO2yaIYacz0u7LfGjk43LhwXLZ7KSg49ai/AqfILVOjWvLkCvtU2sMpEj2peOB6jEnrjd/Q4r8K7SeKMorWRMyyQXpQi0rlXx52cmBv+yQo12j0yYnp6/pwLcvOzN82WvXSiWS7bR4pRLNglJEW42yjNi4WAmwiX2TpNvGKKLu4J6yUcWSlKGuwKOs6gSZh38aMCkkZtgN3z0bfisWu5p8IN5laTfk7o/19UfuA0qdtaQb36yVSoBN71HimAeDv2OCA72nzIqd2ljHPRh1CTK15oJvtFHk4YgubRxbYpinfZ8BpgUxrKsAC6uS6OZ6fRuxjVVt4tlXgFqWegvJYqA8qB4JAx3osHx4ZKVS70c8V9ojGHAkGju30aXGNi2kySFiwSsqtFJgRnV6cH68ukaJEMcbMurTccxa5lBoBRHb0IESuvwfweV+3/MHAAA=";
10
10
  export const VITALS_RAW_BYTES = 2035;