@gradial/aci 0.1.52-rc.10 → 0.1.52-rc.13

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 (45) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +4 -4
  3. package/dist/audience-data-models.d.ts +87 -0
  4. package/dist/audience-data-models.js +49 -0
  5. package/dist/collect/aci.js +1 -1
  6. package/dist/collect/aci.js.sha256 +1 -1
  7. package/dist/collect/api.d.ts +3 -7
  8. package/dist/collect/api.js +2 -8
  9. package/dist/collect/index.js +1 -1
  10. package/dist/internal/domain/edge/index.d.ts +1 -0
  11. package/dist/internal/domain/edge/index.js +1 -0
  12. package/dist/internal/domain/edge/mimic_token.d.ts +13 -0
  13. package/dist/internal/domain/edge/mimic_token.js +59 -0
  14. package/dist/internal/domain/edge/resolve.js +13 -5
  15. package/dist/internal/domain/edge/types.d.ts +4 -0
  16. package/dist/mimic/core.d.ts +34 -0
  17. package/dist/mimic/core.js +127 -0
  18. package/dist/next/collect-route.d.ts +6 -0
  19. package/dist/next/collect-route.js +15 -0
  20. package/dist/next/hosted-page-target.d.ts +7 -0
  21. package/dist/next/hosted-page-target.js +39 -0
  22. package/dist/next/index.d.ts +0 -1
  23. package/dist/next/index.js +0 -1
  24. package/dist/next/page.d.ts +29 -6
  25. package/dist/next/page.js +46 -24
  26. package/dist/next/personalization-host.d.ts +4 -0
  27. package/dist/next/personalization-host.js +18 -7
  28. package/dist/next/server.js +28 -1
  29. package/dist/next/vercel-s3-personalization.d.ts +1 -0
  30. package/dist/next/vercel-s3-personalization.js +1 -0
  31. package/package.json +7 -7
  32. package/templates/astro/template/package.json.tmpl +1 -1
  33. package/templates/astro/template/src/layouts/SiteLayout.astro +2 -2
  34. package/templates/common/.content/schemas/site.schema.json +1 -1
  35. package/templates/common/.nvmrc +1 -1
  36. package/templates/common/starter-content/.content/config/site.json +1 -1
  37. package/templates/common/starter-content/.content/schemas/site.schema.json +1 -1
  38. package/templates/nextjs/template/package.json.tmpl +2 -1
  39. package/templates/nextjs/template/src/app/_components/c15t-bridge.ts +30 -0
  40. package/templates/nextjs/template/src/app/_components/c15t-consent-ui.tsx +37 -0
  41. package/templates/nextjs/template/src/app/_components/consent-manager.css +63 -0
  42. package/templates/nextjs/template/src/app/_components/consent-manager.tsx +76 -0
  43. package/templates/nextjs/template/src/app/layout.tsx +2 -0
  44. package/dist/next/middleware.d.ts +0 -40
  45. package/dist/next/middleware.js +0 -475
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.52-rc.7 - 2026-08-19
4
+
5
+ ### Fixed
6
+
7
+ - Resolve Vercel SSR base and variant targets from the immutable `__r` path,
8
+ keeping `__variant` target identity separate from the logical public route.
9
+
3
10
  ## 0.1.45 - 2026-07-29
4
11
 
5
12
  ### Fixed
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agentic Content Infrastructure SDK
2
2
 
3
- `@gradial/aci` `0.1.52-rc.10` is a pre-1.0 public-surface reset for the ACI
3
+ `@gradial/aci` `0.1.52-rc.13` is a pre-1.0 public-surface reset for the ACI
4
4
  client SDK. Breaking changes from the old `0.1.x` accidental surface are
5
5
  intentional: the root import is framework-neutral, framework runtime behavior is
6
6
  behind explicit subpaths, and the first required customer path is React/Next.
@@ -8,7 +8,7 @@ behind explicit subpaths, and the first required customer path is React/Next.
8
8
  ## Install
9
9
 
10
10
  ```bash
11
- npm install @gradial/aci@0.1.52-rc.10 zod@^4
11
+ npm install @gradial/aci@0.1.52-rc.13 zod@^4
12
12
  ```
13
13
 
14
14
  ## Root Import
@@ -78,13 +78,13 @@ host bundles select and serve immutable release artifacts.
78
78
  The first RC scaffold path is Next:
79
79
 
80
80
  ```bash
81
- npx @gradial/aci@0.1.52-rc.10 init my-site --template next-starter
81
+ npx @gradial/aci@0.1.52-rc.13 init my-site --template next-starter
82
82
  ```
83
83
 
84
84
  List available templates:
85
85
 
86
86
  ```bash
87
- npx @gradial/aci@0.1.52-rc.10 init --list
87
+ npx @gradial/aci@0.1.52-rc.13 init --list
88
88
  ```
89
89
 
90
90
  ## Personalization: The One-Tag Install
@@ -242,7 +242,51 @@ export declare const audienceDataModel: import("./index.js").DataModelContract<z
242
242
  ruleRef: z.ZodOptional<z.ZodString>;
243
243
  segmentRef: z.ZodOptional<z.ZodString>;
244
244
  providerRef: z.ZodOptional<z.ZodString>;
245
+ externalSegmentId: z.ZodOptional<z.ZodString>;
245
246
  }, z.core.$strip>, "audience">;
247
+ export declare const audienceProviderDataModel: import("./index.js").DataModelContract<z.ZodObject<{
248
+ id: z.ZodString;
249
+ displayName: z.ZodString;
250
+ status: z.ZodEnum<{
251
+ draft: "draft";
252
+ enabled: "enabled";
253
+ disabled: "disabled";
254
+ }>;
255
+ format: z.ZodEnum<{
256
+ "aep-batch-export": "aep-batch-export";
257
+ "mapped-json": "mapped-json";
258
+ }>;
259
+ identity: z.ZodObject<{
260
+ sourceNamespace: z.ZodString;
261
+ resolution: z.ZodOptional<z.ZodArray<z.ZodObject<{
262
+ field: z.ZodString;
263
+ }, z.core.$strict>>>;
264
+ }, z.core.$strict>;
265
+ membershipTtlDays: z.ZodNumber;
266
+ dumpSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
267
+ mapping: z.ZodOptional<z.ZodObject<{
268
+ identity: z.ZodObject<{
269
+ path: z.ZodString;
270
+ }, z.core.$strict>;
271
+ membership: z.ZodObject<{
272
+ segmentIdsPath: z.ZodOptional<z.ZodString>;
273
+ objectNamePattern: z.ZodOptional<z.ZodString>;
274
+ }, z.core.$strict>;
275
+ qualifiedAtPath: z.ZodOptional<z.ZodString>;
276
+ }, z.core.$strict>>;
277
+ discovery: z.ZodObject<{
278
+ mode: z.ZodEnum<{
279
+ draft: "draft";
280
+ "report-only": "report-only";
281
+ }>;
282
+ maxPerImport: z.ZodOptional<z.ZodNumber>;
283
+ }, z.core.$strict>;
284
+ limits: z.ZodOptional<z.ZodObject<{
285
+ maxDumpBytes: z.ZodOptional<z.ZodNumber>;
286
+ maxRecords: z.ZodOptional<z.ZodNumber>;
287
+ maxIdentitiesPerRecord: z.ZodOptional<z.ZodNumber>;
288
+ }, z.core.$strict>>;
289
+ }, z.core.$strip>, "audience_provider">;
246
290
  export declare const audienceRuleDataModel: import("./index.js").DataModelContract<z.ZodObject<{
247
291
  id: z.ZodString;
248
292
  status: z.ZodEnum<{
@@ -710,7 +754,50 @@ export declare const audienceDataModels: (import("./index.js").DataModelContract
710
754
  ruleRef: z.ZodOptional<z.ZodString>;
711
755
  segmentRef: z.ZodOptional<z.ZodString>;
712
756
  providerRef: z.ZodOptional<z.ZodString>;
757
+ externalSegmentId: z.ZodOptional<z.ZodString>;
713
758
  }, z.core.$strip>, "audience"> | import("./index.js").DataModelContract<z.ZodObject<{
759
+ id: z.ZodString;
760
+ displayName: z.ZodString;
761
+ status: z.ZodEnum<{
762
+ draft: "draft";
763
+ enabled: "enabled";
764
+ disabled: "disabled";
765
+ }>;
766
+ format: z.ZodEnum<{
767
+ "aep-batch-export": "aep-batch-export";
768
+ "mapped-json": "mapped-json";
769
+ }>;
770
+ identity: z.ZodObject<{
771
+ sourceNamespace: z.ZodString;
772
+ resolution: z.ZodOptional<z.ZodArray<z.ZodObject<{
773
+ field: z.ZodString;
774
+ }, z.core.$strict>>>;
775
+ }, z.core.$strict>;
776
+ membershipTtlDays: z.ZodNumber;
777
+ dumpSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
778
+ mapping: z.ZodOptional<z.ZodObject<{
779
+ identity: z.ZodObject<{
780
+ path: z.ZodString;
781
+ }, z.core.$strict>;
782
+ membership: z.ZodObject<{
783
+ segmentIdsPath: z.ZodOptional<z.ZodString>;
784
+ objectNamePattern: z.ZodOptional<z.ZodString>;
785
+ }, z.core.$strict>;
786
+ qualifiedAtPath: z.ZodOptional<z.ZodString>;
787
+ }, z.core.$strict>>;
788
+ discovery: z.ZodObject<{
789
+ mode: z.ZodEnum<{
790
+ draft: "draft";
791
+ "report-only": "report-only";
792
+ }>;
793
+ maxPerImport: z.ZodOptional<z.ZodNumber>;
794
+ }, z.core.$strict>;
795
+ limits: z.ZodOptional<z.ZodObject<{
796
+ maxDumpBytes: z.ZodOptional<z.ZodNumber>;
797
+ maxRecords: z.ZodOptional<z.ZodNumber>;
798
+ maxIdentitiesPerRecord: z.ZodOptional<z.ZodNumber>;
799
+ }, z.core.$strict>>;
800
+ }, z.core.$strip>, "audience_provider"> | import("./index.js").DataModelContract<z.ZodObject<{
714
801
  id: z.ZodString;
715
802
  status: z.ZodEnum<{
716
803
  draft: "draft";
@@ -82,6 +82,54 @@ export const audienceDataModel = defineDataModel({
82
82
  ruleRef: z.string().optional(),
83
83
  segmentRef: z.string().optional(),
84
84
  providerRef: z.string().optional(),
85
+ externalSegmentId: z
86
+ .string()
87
+ .min(1)
88
+ .max(256)
89
+ .refine((value) => value.trim() === value, {
90
+ message: 'externalSegmentId must not have leading or trailing whitespace',
91
+ })
92
+ .optional(),
93
+ }),
94
+ });
95
+ const providerIdentityResolutionSchema = z.object({
96
+ field: z.string().regex(/^(cookie|query|header)\..+$/, 'field must be cookie.<name>, query.<name>, or header.<name>'),
97
+ }).strict();
98
+ export const audienceProviderDataModel = defineDataModel({
99
+ type: 'audience_provider',
100
+ schema: z.object({
101
+ id: z.string().regex(/^[A-Za-z0-9_-]+$/, 'id must contain only letters, numbers, underscores, or hyphens'),
102
+ displayName: z.string().min(1),
103
+ status: resourceStatus,
104
+ format: z.enum(['aep-batch-export', 'mapped-json']),
105
+ identity: z.object({
106
+ sourceNamespace: z.string().min(1),
107
+ resolution: z.array(providerIdentityResolutionSchema).optional(),
108
+ }).strict(),
109
+ membershipTtlDays: z.number().int().positive(),
110
+ dumpSchema: z.record(z.string(), z.unknown()).optional(),
111
+ // mapped-json extraction declarations (required for that format; the Go
112
+ // write gate owns the full matrix — exactly one membership source, valid
113
+ // RFC 6901 pointers, a compiling single-capture pattern).
114
+ mapping: z.object({
115
+ identity: z.object({
116
+ path: z.string().regex(/^\//, 'identity.path must be an RFC 6901 JSON pointer'),
117
+ }).strict(),
118
+ membership: z.object({
119
+ segmentIdsPath: z.string().regex(/^\//).optional(),
120
+ objectNamePattern: z.string().min(1).optional(),
121
+ }).strict(),
122
+ qualifiedAtPath: z.string().regex(/^\//).optional(),
123
+ }).strict().optional(),
124
+ discovery: z.object({
125
+ mode: z.enum(['draft', 'report-only']),
126
+ maxPerImport: z.number().int().positive().max(1000).optional(),
127
+ }).strict(),
128
+ limits: z.object({
129
+ maxDumpBytes: z.number().int().positive().optional(),
130
+ maxRecords: z.number().int().positive().optional(),
131
+ maxIdentitiesPerRecord: z.number().int().positive().optional(),
132
+ }).strict().optional(),
85
133
  }),
86
134
  });
87
135
  export const audienceRuleDataModel = defineDataModel({
@@ -151,6 +199,7 @@ export const audienceDataModels = [
151
199
  segmentDataModel,
152
200
  audienceDataModel,
153
201
  audienceRuleDataModel,
202
+ audienceProviderDataModel,
154
203
  visitorProfileDataModel,
155
204
  ...experimentationDataModels,
156
205
  ];
@@ -1 +1 @@
1
- "use strict";(()=>{var Ne=Object.defineProperty;var Le=(t,e,n)=>e in t?Ne(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var y=(t,e,n)=>Le(t,typeof e!="symbol"?e+"":e,n);var x="data-aci-event",Oe="data-aci-on",H="data-aci-prop-",De="data-aci-refresh",q="custom.";function D(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(!(e===""||/[\s/]/.test(e)))return e.startsWith(q)?e:q+e}function Re(t){let e;for(let n of Array.from(t.attributes)){if(!n.name.startsWith(H))continue;let r=n.name.slice(H.length);r!==""&&((e!=null?e:e={})[r]=n.value)}return e}function U(t,e){let n=D(t.getAttribute(x));if(n===void 0){e==null||e("capture",{reason:"malformed_declaration",attr:x});return}return{eventName:n,properties:Re(t)}}function X(t){var e,n;return(n=(e=t.getAttribute(Oe))==null?void 0:e.trim().toLowerCase())!=null?n:"click"}function $(t,e,n){let{document:r,debug:o}=e;r.addEventListener("click",f=>{var l,p;try{let u=f.target;if((l=u==null?void 0:u.closest)==null?void 0:l.call(u,`[${De}]`)){n==null||n();return}let m=(p=u==null?void 0:u.closest)==null?void 0:p.call(u,`[${x}]`);if(!m||X(m)!=="click")return;let g=U(m,o);g&&t(g)}catch(u){o==null||o("capture",{reason:"click_handler_failed",error:String(u)})}});let i=e.intersectionObserver;if(typeof i!="function")return;let s=Array.from(r.querySelectorAll(`[${x}]`)).filter(f=>X(f)==="visible");if(s.length===0)return;let a=new WeakSet,c=new i((f,l)=>{try{for(let p of f){if(!p.isIntersecting||p.intersectionRatio<.5||a.has(p.target))continue;a.add(p.target),l.unobserve(p.target);let u=U(p.target,o);u&&t(u)}}catch(p){o==null||o("capture",{reason:"visible_handler_failed",error:String(p)})}},{threshold:.5});for(let f of s)c.observe(f)}function K(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Y(t,e,n,r){let o=(...a)=>{try{let[c,...f]=a;if(c==="track"){let l=D(f[0]);if(l===void 0){r==null||r("capture",{reason:"malformed_track_name",name:f[0]});return}let p=f[1];if(p!==void 0&&!K(p)){r==null||r("capture",{reason:"malformed_track_properties",name:l});return}n.track(l,p);return}if(c==="consent"){if(e.preset!=="manual"){r==null||r("consent",{reason:"preset_authoritative",preset:e.preset});return}let l=f[0];if(!K(l)){r==null||r("consent",{reason:"malformed_consent_envelope"});return}n.consent({p:l.p,src:l.src});return}r==null||r("capture",{reason:"unknown_command",command:c})}catch(c){r==null||r("capture",{reason:"command_failed",error:String(c)})}},i=t.aci,s=i==null?void 0:i.q;if(t.aci=o,s!=null)for(let a of Array.from(s)){let c=Array.from(a);o(...c)}}var Be="experiment.exposure",Fe='script[type="application/json"][data-aci-assignments]';function Ve(t){if(typeof t!="object"||t===null)return null;let e=t,n=e.experimentId,r=e.armId,o=e.allocationVersion;return typeof n!="string"||n===""||typeof r!="string"||r===""||typeof o!="string"?null:{experimentId:n,armId:r,allocationVersion:o}}function Me(t,e){try{let n=t.querySelector(Fe);if(!n)return[];let r=n.textContent;if(r==null||r.trim()==="")return[];let o=JSON.parse(r);if(typeof o!="object"||o===null)return e==null||e("capture",{reason:"assignments_malformed"}),[];let i=o;if(i.v!==1||!Array.isArray(i.experiments))return e==null||e("capture",{reason:"assignments_malformed"}),[];let s=[];for(let a of i.experiments){let c=Ve(a);c&&s.push(c)}return s}catch(n){return e==null||e("capture",{reason:"assignments_parse_failed",error:String(n)}),[]}}function J(t,e){if(!e||t.experiment!==void 0)return t;let n=e.getActiveAssignments()[0];if(!n)return t;let r={experimentId:n.experimentId,armId:n.armId,allocationVersion:n.allocationVersion};return{...t,experiment:r}}function Q(t){let e=[],n=new Set,r,o=()=>{e=Me(t.document,t.debug);for(let i of e)n.has(i.experimentId)||(n.add(i.experimentId),r==null||r({eventName:Be,url:t.window.location.href,experiment:{experimentId:i.experimentId,armId:i.armId,allocationVersion:i.allocationVersion}}))};return{getActiveAssignments:()=>e.map(i=>({...i})),start(i){r=i,o()},rearm(){n.clear(),o()}}}var Z="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function We(t){globalThis.crypto.getRandomValues(t)}function S(t,e){let n=t!=null?t:Date.now(),r="";for(let c=0;c<10;c++)r=Z[n%32]+r,n=Math.floor(n/32);let o=new Uint8Array(10);(e!=null?e:We)(o);let i="",s=0,a=0;for(let c of o)for(s=s<<8|c,a+=8;a>=5;)i+=Z[s>>>a-5&31],a-=5;return r+i}var Ge=60*1024,je=100,ze=5e3,ee='{"envelopeId":"',te='","events":[',ne="]}",He=26,A=ee.length+He+te.length+ne.length,qe=new TextEncoder,Ue=t=>qe.encode(t).length,T=class{constructor(e){y(this,"options");y(this,"maxBytes");y(this,"queue",[]);y(this,"queuedBytes",0);y(this,"flushing",!1);y(this,"intervalId");var n;this.options=e,this.maxBytes=(n=e.maxBatchBytes)!=null?n:Ge}get pending(){return this.queue.length}push(e){let n=JSON.stringify(e),r=Ue(n);this.queue.push({json:n,bytes:r,eventId:e.eventId}),this.queuedBytes+=r,!this.flushing&&this.envelopeBytes()>=this.maxBytes&&this.flush()}flush(){var e,n;if(!this.flushing){this.flushing=!0;try{(n=(e=this.options).onTick)==null||n.call(e),this.drain()}finally{this.flushing=!1}}}start(){var o,i,s,a;let e=(o=this.options.timers)!=null?o:{setInterval:(c,f)=>setInterval(c,f),clearInterval:c=>clearInterval(c)};this.intervalId=e.setInterval(()=>this.flush(),(i=this.options.flushIntervalMs)!=null?i:ze);let n=(s=this.options.documentTarget)!=null?s:typeof document!="undefined"?document:void 0;n==null||n.addEventListener("visibilitychange",()=>{n.visibilityState==="hidden"&&this.flush()});let r=(a=this.options.windowTarget)!=null?a:typeof window!="undefined"?window:void 0;r==null||r.addEventListener("pagehide",()=>this.flush()),this.flush()}stop(){if(this.intervalId!==void 0){let e=this.options.timers;e?e.clearInterval(this.intervalId):clearInterval(this.intervalId),this.intervalId=void 0}}envelopeBytes(){let e=this.queue.length>1?this.queue.length-1:0;return A+this.queuedBytes+e}drain(){var e,n,r;for(;this.queue.length>0;){let o=this.queue[0];if(A+o.bytes>this.maxBytes){this.queue.shift(),this.queuedBytes-=o.bytes,(n=(e=this.options).debug)==null||n.call(e,"flush",{reason:"oversize_event",eventId:o.eventId,bytes:o.bytes});continue}let i=[],s=A;for(;this.queue.length>0;){let c=this.queue[0];if(A+c.bytes>this.maxBytes||i.length>=je)break;let f=s+c.bytes+(i.length>0?1:0);if(f>this.maxBytes)break;i.push(c.json),s=f,this.queue.shift(),this.queuedBytes-=c.bytes}if(i.length===0)continue;let a=((r=this.options.createEnvelopeId)!=null?r:S)();this.options.send(ee+a+te+i.join(",")+ne)}}};var Xe=new Set(["c15t","onetrust","cookiebot","trustarc","manual"]);function P(t,e){var o;let n=(o=t==null?void 0:t.getAttribute)==null?void 0:o.call(t,e);if(n==null)return;let r=n.trim();return r===""?void 0:r}function re(t){var r;let e=(r=P(t,"data-aci-consent"))==null?void 0:r.toLowerCase(),n=e!==void 0&&Xe.has(e)?e:"manual";return{site:P(t,"data-aci-site"),preset:n,categories:P(t,"data-aci-consent-categories"),debug:P(t,"data-aci-debug")==="1"}}function oe(t,e,n){if(!t)return()=>{};let r=e!=null?e:(i=>console.debug("[aci]",i)),o=n!=null?n:Date.now;return(i,s)=>{try{r({t:o(),kind:i,detail:s})}catch{}}}var R=new TextEncoder,$e=2048,Ke=32,Ye=128,Je=512,Qe=2147483647,Ze=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/,et=/^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g,tt=new Set(["true","all","granted","yes","personalization","personalized"]);function _(t,e=!0){let n=w(t);if(!n)return null;if(e)try{n=decodeURIComponent(n)}catch{}if(n=w(n),!n||R.encode(n).byteLength>$e)return null;if(tt.has(n.toLowerCase()))return{version:0,purposes:["personalization"],grantedAt:""};try{let r=JSON.parse(n),o=typeof r.t=="string"?r.t:"";return!Number.isInteger(r.v)||r.v<0||r.v>Qe||!Array.isArray(r.p)||r.p.length>Ke||!r.p.every(i=>typeof i=="string")||r.p.some(i=>R.encode(i).byteLength>Ye)||r.t!==void 0&&r.t!==null&&(typeof r.t!="string"||r.t===""||!nt(r.t))||r.src!==void 0&&r.src!==null&&typeof r.src!="string"||typeof r.src=="string"&&R.encode(r.src).byteLength>Je?null:{version:r.v,purposes:r.p,grantedAt:o,source:typeof r.src=="string"?r.src:void 0}}catch{return null}}function B(t){return(t==null?void 0:t.purposes.some(e=>w(e).toLowerCase()==="personalization"))||!1}function w(t){return t.replace(et,"")}function nt(t){let e=Ze.exec(t);if(!e||Number.isNaN(Date.parse(t)))return!1;let n=Number(e[1]),r=Number(e[2]),o=Number(e[3]),i=Number(e[4]),s=Number(e[5]),a=Number(e[6]);if(r<1||r>12||o<1||o>rt(n,r)||i>23||s>59||a>59)return!1;let c=e[8];return c==="Z"||Number(c.slice(1,3))<=23&&Number(c.slice(4,6))<=59}function rt(t,e){return e===2?t%4===0&&(t%100!==0||t%400===0)?29:28:[4,6,9,11].includes(e)?30:31}var ie="personalization",F="aci_consent",V=1,ot=365*24*60*60;function it(t,e){var r;let n=`${F}=${t.encoded}; Path=/; Max-Age=${ot}; SameSite=Lax`;((r=e.document.location)==null?void 0:r.protocol)==="https:"&&(n+="; Secure"),e.document.cookie=n}function I(t,e,n){var o;let r=st(t,e,n.now);return r===null?!1:(B(r.snapshot)||(o=n.gapBuffer)==null||o.purge(),it(r,n),!0)}function se(t){for(let e of t.cookie.split(";")){let n=w(e);if(n.startsWith(F+"="))return n.slice(F.length+1)}}function ae(t){return t===void 0||t===""?!1:B(_(t,!0))}function ce(t){var r;if(!Array.isArray(t))return;let e=[];for(let o of t){if(typeof o!="string")return;e.push(w(o))}let n=JSON.stringify({v:V,p:e});return(r=_(n,!1))==null?void 0:r.purposes}function ue(t){var o;if(t!==void 0&&typeof t!="string")return;let e=typeof t=="string"?w(t):"",r=JSON.stringify({v:V,p:[],src:e===""?"manual":e});return(o=_(r,!1))==null?void 0:o.source}function st(t,e,n){try{let r=JSON.stringify({v:V,p:t,t:new Date((n!=null?n:Date.now)()).toISOString(),src:e}),o=_(r,!1);return o===null?null:{encoded:encodeURIComponent(r),snapshot:o}}catch{return null}}var at="cmp-",ct=/^[a-z0-9._-]+$/,ut={c15t:"measurement,marketing",onetrust:"c0002,c0004",cookiebot:"statistics,marketing",trustarc:"functional,advertising"};function M(t,e){let n=e!=null?e:ut[t];if(n===void 0)return null;let r=n.split(",").map(o=>o.trim().toLowerCase()).filter(o=>o!=="");if(r.length===0)return null;for(let o of r)if(!ct.test(o))return null;return r}function ft(t,e){return e.filter(r=>r in t.categories).some(r=>t.categories[r]===!0)?[ie]:[]}function k(t,e,n){var r,o,i,s;try{let a=M(e,n.categories);if(a===null){(r=n.debug)==null||r.call(n,"consent",{reason:"unparseable_mapping",preset:e});return}if(a.filter(l=>l in t.categories).length===0){(o=n.debug)==null||o.call(n,"consent",{reason:"unmappable_cmp_state",preset:e});return}let f=ft(t,a);I(f,at+e,{document:n.document,gapBuffer:n.gapBuffer,now:n.now}),(i=n.debug)==null||i.call(n,"consent",{reason:"written",preset:e,purposes:f})}catch(a){(s=n.debug)==null||s.call(n,"consent",{reason:"consent_bridge_failed",preset:e,error:String(a)})}}var fe=250,lt=1e4;function C(t,e,n){var s;let r=(s=n==null?void 0:n.scheduler)!=null?s:{setTimeout:(a,c)=>setTimeout(a,c),clearTimeout:a=>clearTimeout(a)},o=Math.floor(lt/fe),i=()=>{var c,f;let a;try{a=t()}catch(l){(c=n==null?void 0:n.debug)==null||c.call(n,"consent",{reason:"cmp_read_failed",error:String(l)});return}if(a!==void 0){e(a);return}if(o-=1,o<=0){(f=n==null?void 0:n.debug)==null||f.call(n,"consent",{reason:"cmp_not_found"});return}r.setTimeout(i,fe)};i()}function b(t,e){try{e()}catch(n){t==null||t("consent",{reason:"adapter_failed",error:String(n)})}}var dt="c15t";function pt(t){if(typeof t!="object"||t===null)return;let e={};for(let[n,r]of Object.entries(t))typeof r=="boolean"&&(e[n.toLowerCase()]=r);return{categories:e}}function mt(t,e){return typeof t=="object"&&t!==null?"consents"in t?t.consents:t:e.consents}function le(t){C(()=>{let e=t.window.c15t;return typeof e=="object"&&e!==null?e:void 0},e=>{b(t.debug,()=>{var r;let n=o=>{let i=pt(o);i&&k(i,dt,t)};n(e.consents),(r=e.onConsentChange)==null||r.call(e,o=>b(t.debug,()=>n(mt(o,e))))})},t)}var gt="cookiebot",vt=["CookiebotOnConsentReady","CookiebotOnAccept","CookiebotOnDecline"];function de(t){let e=t.Cookiebot;return typeof e=="object"&&e!==null?e:void 0}function ht(t){if(typeof t!="object"||t===null)return;let e={};for(let[n,r]of Object.entries(t))typeof r=="boolean"&&(e[n.toLowerCase()]=r);return{categories:e}}function pe(t){let e=()=>{let r=de(t.window);if(!r||r.hasResponse!==!0)return;let o=ht(r.consent);o&&k(o,gt,t)},n=t.window;if(typeof n.addEventListener=="function")for(let r of vt)n.addEventListener(r,()=>b(t.debug,e));C(()=>de(t.window),()=>b(t.debug,e),t)}var me="onetrust",bt=/^c\d{4}$/;function yt(t,e){let n={};for(let r of t.split(",")){let o=r.trim().toLowerCase();o!==""&&(n[o]=!0)}for(let r of e!=null?e:[])!(r in n)&&bt.test(r)&&(n[r]=!1);return{categories:n}}function ge(t){let e=t.window,n=()=>{let o=e.OnetrustActiveGroups;if(typeof o!="string")return;let i=M(me,t.categories);k(yt(o,i),me,t)},r=e.OptanonWrapper;e.OptanonWrapper=()=>{if(typeof r=="function")try{r()}catch{}b(t.debug,n)},C(()=>{let o=e.OnetrustActiveGroups;return typeof o=="string"?o:void 0},()=>b(t.debug,n),t)}var Et="trustarc",kt={required:1,functional:2,advertising:3},ve="PrivacyManagerAPI";function he(t){let e=t.truste,n=e==null?void 0:e.cma,r=n==null?void 0:n.callApi;return typeof r=="function"?r.bind(n):void 0}function Ct(t){if(typeof t!="object"||t===null)return;let e=t.consentDecision;if(typeof e!="number"||!Number.isFinite(e)||e<1)return;let n={};for(let[r,o]of Object.entries(kt))n[r]=e>=o;return{categories:n}}function wt(t){return typeof t=="string"?t.includes(ve):typeof t=="object"&&t!==null&&ve in t}function St(t){let e=t.location;return typeof(e==null?void 0:e.hostname)=="string"?e.hostname:void 0}function be(t){let e=()=>{let r=he(t.window);if(!r)return;let o=Ct(r("getConsentDecision",St(t.window)));o&&k(o,Et,t)},n=t.window;typeof n.addEventListener=="function"&&n.addEventListener("message",r=>b(t.debug,()=>{wt(r==null?void 0:r.data)&&e()})),C(()=>he(t.window),()=>b(t.debug,e),t)}var N="aci:buf";var ye="aci_m",L=class{constructor(e){y(this,"events");y(this,"storage");y(this,"debug");this.debug=e==null?void 0:e.debug,this.storage=e==null?void 0:e.storage,this.events=this.restore()}push(e){var n;this.events.push(e),this.events.length>50&&(this.events.splice(0,this.events.length-50),(n=this.debug)==null||n.call(this,"buffer",{reason:"cap_drop_oldest"})),this.persist()}drain(){let e=this.events;return this.events=[],this.persist(),e}purge(){var e;this.events.length>0&&((e=this.debug)==null||e.call(this,"buffer",{reason:"purged",count:this.events.length})),this.events=[],this.persist()}size(){return this.events.length}restore(){var r;let e=this.storage;if(!e)return[];let n;try{n=e.getItem(N)}catch(o){return this.storage=void 0,(r=this.debug)==null||r.call(this,"buffer",{reason:"storage_unavailable",error:String(o)}),[]}if(n==null)return[];try{let o=JSON.parse(n);if(Array.isArray(o))return o}catch{}try{e.removeItem(N)}catch{this.storage=void 0}return[]}persist(){var n;let e=this.storage;if(e)try{this.events.length===0?e.removeItem(N):e.setItem(N,JSON.stringify(this.events))}catch(r){this.storage=void 0,(n=this.debug)==null||n.call(this,"buffer",{reason:"storage_unavailable",error:String(r)})}}};function Ee(t){for(let e of t.cookie.split(";")){let n=e.trim();if(n.startsWith(ye+"="))return n.slice(ye.length+1)!==""}return!1}function ke(t,e){if(e.grants()&&!e.marker()){e.gapBuffer.push(t);return}e.batcher.push(t)}function W(t,e,n,r){if(t.size()===0||!n())return;let o=t.drain();for(let i of o)e.push(i);r==null||r("buffer",{reason:"flushed",count:o.length})}var _t="rum.link_click";function Ce(t,e){var i;let{document:n,debug:r}=e,o=(i=n.defaultView)==null?void 0:i.location;n.addEventListener("click",s=>{var a,c,f;try{let l=s.target,p=(a=l==null?void 0:l.closest)==null?void 0:a.call(l,"a[href]");if(!p)return;let u=p;t({eventName:_t,url:o==null?void 0:o.href,properties:{linkText:(f=(c=u.textContent)==null?void 0:c.trim())!=null?f:"",linkHref:u.href}})}catch(l){r==null||r("capture",{reason:"link_click_failed",error:String(l)})}},{capture:!0})}var xt="rum.page_view";function we(t){let e=t.indexOf("#");return e===-1?t:t.slice(0,e)}function Se(t,e){let n=we(t.location.href),r=()=>{let s=we(t.location.href);if(s!==n){n=s;for(let a of e)a()}},o=t.history,i=s=>{let a=o[s].bind(o);o[s]=(...c)=>{let f=a(...c);return r(),f}};i("pushState"),i("replaceState"),t.addEventListener("popstate",r)}function _e(t,e){let n=()=>t({eventName:xt,url:e.location.href,referrer:e.document.referrer});return n(),n}var G="/collect";function xe(t,e){let n=e==null?void 0:e.debug,r=e!==void 0&&"navigator"in e?e.navigator:globalThis.navigator,o=e!==void 0&&"fetch"in e?e.fetch:globalThis.fetch,i;try{i=new Blob([t],{type:"text/plain"})}catch{n==null||n("flush",{reason:"no_blob"});return}if(r!=null&&r.sendBeacon)try{if(r.sendBeacon(G,i))return}catch{}if(!o){n==null||n("flush",{reason:"no_transport"});return}try{o(G,{method:"POST",body:i,keepalive:!0}).catch(s=>{n==null||n("flush",{reason:"fetch_failed",error:String(s)})})}catch(s){n==null||n("flush",{reason:"fetch_failed",error:String(s)})}}function Ae(t){var n,r;let e=t!==void 0&&"fetch"in t?t.fetch:globalThis.fetch;if(!e)return Promise.resolve(!1);try{let o=((n=t==null?void 0:t.createEnvelopeId)!=null?n:S)(),i=new Blob([`{"envelopeId":"${o}","events":[]}`],{type:"text/plain"});return e(G,{method:"POST",body:i,keepalive:!0,credentials:"same-origin"}).then(s=>{var a;return typeof s=="object"&&s!==null&&"ok"in s&&s.ok===!1?((a=t==null?void 0:t.debug)==null||a.call(t,"flush",{reason:"refresh_failed",status:"not_ok"}),!1):!0}).catch(s=>{var a;return(a=t==null?void 0:t.debug)==null||a.call(t,"flush",{reason:"refresh_failed",error:String(s)}),!1})}catch(o){return(r=t==null?void 0:t.debug)==null||r.call(t,"flush",{reason:"refresh_failed",error:String(o)}),Promise.resolve(!1)}}var At="rum.variation_view",j="data-aci-variation";function Te(t,e){var f,l,p;let{document:n,debug:r}=e,o=e.MutationObserver;if(typeof o!="function")return;let i=(f=n.defaultView)==null?void 0:f.location,s=new WeakSet,a=u=>{let h=u.getAttribute(j);h!=null&&(s.has(u)||(s.add(u),t({eventName:At,url:i==null?void 0:i.href,properties:{variantKey:h}})))},c=u=>{try{u.hasAttribute(j)&&a(u);for(let h of Array.from(u.querySelectorAll(`[${j}]`)))a(h)}catch(h){r==null||r("capture",{reason:"variation_scan_failed",error:String(h)})}};try{let u=(l=n.body)!=null?l:n.documentElement;u&&c(u)}catch(u){r==null||r("capture",{reason:"variation_initial_scan_failed",error:String(u)})}try{let u=(p=n.body)!=null?p:n.documentElement;if(!u)return;new o(m=>{try{for(let g of m)for(let d=0;d<g.addedNodes.length;d++){let v=g.addedNodes[d];if((v==null?void 0:v.nodeType)!==1)continue;let E=v.element;E&&c(E)}}catch(g){r==null||r("capture",{reason:"variation_observer_failed",error:String(g)})}}).observe(u,{subtree:!0,childList:!0})}catch(u){r==null||r("capture",{reason:"variation_observe_failed",error:String(u)})}}var Tt="rum.web_vital";function Pe(t,e){var h,m,g;let n=e.PerformanceObserver;if(typeof n!="function")return;let{performance:r,debug:o}=e,i=(m=(h=e.window)==null?void 0:h.location)==null?void 0:m.href,s=e.document,a=new Set,c=(d,v)=>{a.has(d)||(a.add(d),t({eventName:Tt,url:i,properties:{vitalName:d,vitalValue:v}}))};try{let d=r==null?void 0:r.getEntriesByType("navigation")[0];d&&typeof d.responseStart=="number"&&typeof d.requestStart=="number"&&c("TTFB",d.responseStart-d.requestStart)}catch(d){o==null||o("capture",{reason:"ttfb_failed",error:String(d)})}let f=0,l=0,p=(d,v)=>{try{new n(Ie=>{try{for(let O of Ie.getEntries())v(O)}catch(O){o==null||o("capture",{reason:`${d}_handler_failed`,error:String(O)})}}).observe({type:d,buffered:!0})}catch(E){o==null||o("capture",{reason:`${d}_observe_failed`,error:String(E)})}};p("largest-contentful-paint",d=>{c("LCP",d.startTime)}),p("first-input",d=>{c("FID",d.startTime)}),p("layout-shift",d=>{var v;d.hadRecentInput||(f+=(v=d.value)!=null?v:0)}),p("event",d=>{var E;let v=(E=d.value)!=null?E:0;v>l&&(l=v)}),p("paint",d=>{d.name==="first-contentful-paint"&&c("FCP",d.startTime)});let u=()=>{try{a.has("CLS")||c("CLS",f),a.has("INP")||c("INP",l)}catch(d){o==null||o("capture",{reason:"visibility_handler_failed",error:String(d)})}};s&&s.addEventListener("visibilitychange",()=>{s.visibilityState==="hidden"&&u()}),(g=e.window)==null||g.addEventListener("pagehide",u)}var z={c15t:le,onetrust:ge,cookiebot:pe,trustarc:be};function Pt(t){var e,n;return typeof((e=t.navigator)==null?void 0:e.sendBeacon)=="function"&&typeof t.IntersectionObserver=="function"&&typeof((n=t.crypto)==null?void 0:n.getRandomValues)=="function"}function It(t){try{return t.sessionStorage}catch{return}}function Nt(t){var o;let e=t!=null?t:typeof window!="undefined"?window:void 0;if(!e||e.__aci_loaded||(e.__aci_loaded=!0,!Pt(e)))return;let n=re(e.document.currentScript),r=oe(n.debug);try{let i=e.document,s=new L({storage:It(e),debug:r}),a=()=>{try{return ae(se(i))}catch{return!1}},c=()=>{try{return Ee(i)}catch{return!1}},f={navigator:e.navigator,fetch:typeof e.fetch=="function"?e.fetch.bind(e):void 0,debug:r},l;l=new T({send:m=>xe(m,f),debug:r,onTick:()=>W(s,l,c,r),timers:{setInterval:(m,g)=>e.setInterval(m,g),clearInterval:m=>e.clearInterval(m)},documentTarget:i,windowTarget:e});let p=Q({document:i,window:e,debug:r}),u=m=>{ke({...J(m,p),eventId:S(void 0,g=>e.crypto.getRandomValues(g))},{grants:a,marker:c,gapBuffer:s,batcher:l})};p.start(u),Y(e,n,{track:(m,g)=>u({eventName:m,properties:g}),consent:({p:m,src:g})=>{let d=ce(m);if(d===void 0){r("consent",{reason:"malformed_purposes"});return}let v=ue(g);if(v===void 0){r("consent",{reason:"malformed_source"});return}I(d,v,{document:i,gapBuffer:s})||r("consent",{reason:"oversized_envelope"})}},r);let h=_e(u,e);Se(e,[()=>p.rearm(),h]),$(u,{document:i,intersectionObserver:e.IntersectionObserver,debug:r},()=>{Ae(f).then(m=>{m&&e.location.reload()})}),Ce(u,{document:i,debug:r}),Pe(u,{performance:e.performance,PerformanceObserver:e.PerformanceObserver,window:e,document:i,debug:r}),Te(u,{document:i,MutationObserver:e.MutationObserver,debug:r}),n.preset!=="manual"&&((o=z[n.preset])==null||o.call(z,{window:e,document:i,categories:n.categories,gapBuffer:s,debug:r,scheduler:{setTimeout:(m,g)=>e.setTimeout(m,g),clearTimeout:m=>e.clearTimeout(m)}})),l.start(),W(s,l,c,r),r("init",{config:n})}catch(i){r("init",{error:String(i)})}}Nt();})();
1
+ "use strict";(()=>{var Ne=Object.defineProperty;var Le=(n,e,t)=>e in n?Ne(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var y=(n,e,t)=>Le(n,typeof e!="symbol"?e+"":e,t);var x="data-aci-event",Oe="data-aci-on",H="data-aci-prop-",De="data-aci-refresh",q="custom.";function D(n){if(typeof n!="string")return;let e=n.trim().toLowerCase();if(!(e===""||/[\s/]/.test(e)))return e.startsWith(q)?e:q+e}function Re(n){let e;for(let t of Array.from(n.attributes)){if(!t.name.startsWith(H))continue;let r=t.name.slice(H.length);r!==""&&((e!=null?e:e={})[r]=t.value)}return e}function U(n,e){let t=D(n.getAttribute(x));if(t===void 0){e==null||e("capture",{reason:"malformed_declaration",attr:x});return}return{eventName:t,properties:Re(n)}}function X(n){var e,t;return(t=(e=n.getAttribute(Oe))==null?void 0:e.trim().toLowerCase())!=null?t:"click"}function $(n,e,t){let{document:r,debug:o}=e;r.addEventListener("click",f=>{var d,p;try{let u=f.target;if((d=u==null?void 0:u.closest)==null?void 0:d.call(u,`[${De}]`)){t==null||t();return}let m=(p=u==null?void 0:u.closest)==null?void 0:p.call(u,`[${x}]`);if(!m||X(m)!=="click")return;let g=U(m,o);g&&n(g)}catch(u){o==null||o("capture",{reason:"click_handler_failed",error:String(u)})}});let i=e.intersectionObserver;if(typeof i!="function")return;let s=Array.from(r.querySelectorAll(`[${x}]`)).filter(f=>X(f)==="visible");if(s.length===0)return;let a=new WeakSet,c=new i((f,d)=>{try{for(let p of f){if(!p.isIntersecting||p.intersectionRatio<.5||a.has(p.target))continue;a.add(p.target),d.unobserve(p.target);let u=U(p.target,o);u&&n(u)}}catch(p){o==null||o("capture",{reason:"visible_handler_failed",error:String(p)})}},{threshold:.5});for(let f of s)c.observe(f)}function K(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function Y(n,e,t){let r=(...s)=>{try{let[a,...c]=s;if(a==="track"){let f=D(c[0]);if(f===void 0){t==null||t("capture",{reason:"malformed_track_name",name:c[0]});return}let d=c[1];if(d!==void 0&&!K(d)){t==null||t("capture",{reason:"malformed_track_properties",name:f});return}e.track(f,d);return}if(a==="consent"){let f=c[0];if(!K(f)){t==null||t("consent",{reason:"malformed_consent_envelope"});return}e.consent({p:f.p,src:f.src});return}t==null||t("capture",{reason:"unknown_command",command:a})}catch(a){t==null||t("capture",{reason:"command_failed",error:String(a)})}},o=n.aci,i=o==null?void 0:o.q;if(n.aci=r,i!=null)for(let s of Array.from(i)){let a=Array.from(s);r(...a)}}var Be="experiment.exposure",Fe='script[type="application/json"][data-aci-assignments]';function Ve(n){if(typeof n!="object"||n===null)return null;let e=n,t=e.experimentId,r=e.armId,o=e.allocationVersion;return typeof t!="string"||t===""||typeof r!="string"||r===""||typeof o!="string"?null:{experimentId:t,armId:r,allocationVersion:o}}function Me(n,e){try{let t=n.querySelector(Fe);if(!t)return[];let r=t.textContent;if(r==null||r.trim()==="")return[];let o=JSON.parse(r);if(typeof o!="object"||o===null)return e==null||e("capture",{reason:"assignments_malformed"}),[];let i=o;if(i.v!==1||!Array.isArray(i.experiments))return e==null||e("capture",{reason:"assignments_malformed"}),[];let s=[];for(let a of i.experiments){let c=Ve(a);c&&s.push(c)}return s}catch(t){return e==null||e("capture",{reason:"assignments_parse_failed",error:String(t)}),[]}}function J(n,e){if(!e||n.experiment!==void 0)return n;let t=e.getActiveAssignments()[0];if(!t)return n;let r={experimentId:t.experimentId,armId:t.armId,allocationVersion:t.allocationVersion};return{...n,experiment:r}}function Q(n){let e=[],t=new Set,r,o=()=>{e=Me(n.document,n.debug);for(let i of e)t.has(i.experimentId)||(t.add(i.experimentId),r==null||r({eventName:Be,url:n.window.location.href,experiment:{experimentId:i.experimentId,armId:i.armId,allocationVersion:i.allocationVersion}}))};return{getActiveAssignments:()=>e.map(i=>({...i})),start(i){r=i,o()},rearm(){t.clear(),o()}}}var Z="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function We(n){globalThis.crypto.getRandomValues(n)}function S(n,e){let t=n!=null?n:Date.now(),r="";for(let c=0;c<10;c++)r=Z[t%32]+r,t=Math.floor(t/32);let o=new Uint8Array(10);(e!=null?e:We)(o);let i="",s=0,a=0;for(let c of o)for(s=s<<8|c,a+=8;a>=5;)i+=Z[s>>>a-5&31],a-=5;return r+i}var Ge=60*1024,je=100,ze=5e3,ee='{"envelopeId":"',te='","events":[',ne="]}",He=26,A=ee.length+He+te.length+ne.length,qe=new TextEncoder,Ue=n=>qe.encode(n).length,T=class{constructor(e){y(this,"options");y(this,"maxBytes");y(this,"queue",[]);y(this,"queuedBytes",0);y(this,"flushing",!1);y(this,"intervalId");var t;this.options=e,this.maxBytes=(t=e.maxBatchBytes)!=null?t:Ge}get pending(){return this.queue.length}push(e){let t=JSON.stringify(e),r=Ue(t);this.queue.push({json:t,bytes:r,eventId:e.eventId}),this.queuedBytes+=r,!this.flushing&&this.envelopeBytes()>=this.maxBytes&&this.flush()}flush(){var e,t;if(!this.flushing){this.flushing=!0;try{(t=(e=this.options).onTick)==null||t.call(e),this.drain()}finally{this.flushing=!1}}}start(){var o,i,s,a;let e=(o=this.options.timers)!=null?o:{setInterval:(c,f)=>setInterval(c,f),clearInterval:c=>clearInterval(c)};this.intervalId=e.setInterval(()=>this.flush(),(i=this.options.flushIntervalMs)!=null?i:ze);let t=(s=this.options.documentTarget)!=null?s:typeof document!="undefined"?document:void 0;t==null||t.addEventListener("visibilitychange",()=>{t.visibilityState==="hidden"&&this.flush()});let r=(a=this.options.windowTarget)!=null?a:typeof window!="undefined"?window:void 0;r==null||r.addEventListener("pagehide",()=>this.flush()),this.flush()}stop(){if(this.intervalId!==void 0){let e=this.options.timers;e?e.clearInterval(this.intervalId):clearInterval(this.intervalId),this.intervalId=void 0}}envelopeBytes(){let e=this.queue.length>1?this.queue.length-1:0;return A+this.queuedBytes+e}drain(){var e,t,r;for(;this.queue.length>0;){let o=this.queue[0];if(A+o.bytes>this.maxBytes){this.queue.shift(),this.queuedBytes-=o.bytes,(t=(e=this.options).debug)==null||t.call(e,"flush",{reason:"oversize_event",eventId:o.eventId,bytes:o.bytes});continue}let i=[],s=A;for(;this.queue.length>0;){let c=this.queue[0];if(A+c.bytes>this.maxBytes||i.length>=je)break;let f=s+c.bytes+(i.length>0?1:0);if(f>this.maxBytes)break;i.push(c.json),s=f,this.queue.shift(),this.queuedBytes-=c.bytes}if(i.length===0)continue;let a=((r=this.options.createEnvelopeId)!=null?r:S)();this.options.send(ee+a+te+i.join(",")+ne)}}};var Xe=new Set(["c15t","onetrust","cookiebot","trustarc","manual"]);function P(n,e){var o;let t=(o=n==null?void 0:n.getAttribute)==null?void 0:o.call(n,e);if(t==null)return;let r=t.trim();return r===""?void 0:r}function re(n){var r;let e=(r=P(n,"data-aci-consent"))==null?void 0:r.toLowerCase(),t=e!==void 0&&Xe.has(e)?e:"manual";return{site:P(n,"data-aci-site"),preset:t,categories:P(n,"data-aci-consent-categories"),debug:P(n,"data-aci-debug")==="1"}}function oe(n,e,t){if(!n)return()=>{};let r=e!=null?e:(i=>console.debug("[aci]",i)),o=t!=null?t:Date.now;return(i,s)=>{try{r({t:o(),kind:i,detail:s})}catch{}}}var R=new TextEncoder,$e=2048,Ke=32,Ye=128,Je=512,Qe=2147483647,Ze=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/,et=/^[\t\n\v\f\r ]+|[\t\n\v\f\r ]+$/g,tt=new Set(["true","all","granted","yes","personalization","personalized"]);function _(n,e=!0){let t=w(n);if(!t)return null;if(e)try{t=decodeURIComponent(t)}catch{}if(t=w(t),!t||R.encode(t).byteLength>$e)return null;if(tt.has(t.toLowerCase()))return{version:0,purposes:["personalization"],grantedAt:""};try{let r=JSON.parse(t),o=typeof r.t=="string"?r.t:"";return!Number.isInteger(r.v)||r.v<0||r.v>Qe||!Array.isArray(r.p)||r.p.length>Ke||!r.p.every(i=>typeof i=="string")||r.p.some(i=>R.encode(i).byteLength>Ye)||r.t!==void 0&&r.t!==null&&(typeof r.t!="string"||r.t===""||!nt(r.t))||r.src!==void 0&&r.src!==null&&typeof r.src!="string"||typeof r.src=="string"&&R.encode(r.src).byteLength>Je?null:{version:r.v,purposes:r.p,grantedAt:o,source:typeof r.src=="string"?r.src:void 0}}catch{return null}}function B(n){return(n==null?void 0:n.purposes.some(e=>w(e).toLowerCase()==="personalization"))||!1}function w(n){return n.replace(et,"")}function nt(n){let e=Ze.exec(n);if(!e||Number.isNaN(Date.parse(n)))return!1;let t=Number(e[1]),r=Number(e[2]),o=Number(e[3]),i=Number(e[4]),s=Number(e[5]),a=Number(e[6]);if(r<1||r>12||o<1||o>rt(t,r)||i>23||s>59||a>59)return!1;let c=e[8];return c==="Z"||Number(c.slice(1,3))<=23&&Number(c.slice(4,6))<=59}function rt(n,e){return e===2?n%4===0&&(n%100!==0||n%400===0)?29:28:[4,6,9,11].includes(e)?30:31}var ie="personalization",F="aci_consent",V=1,ot=365*24*60*60;function it(n,e){var r;let t=`${F}=${n.encoded}; Path=/; Max-Age=${ot}; SameSite=Lax`;((r=e.document.location)==null?void 0:r.protocol)==="https:"&&(t+="; Secure"),e.document.cookie=t}function I(n,e,t){var o;let r=st(n,e,t.now);return r===null?!1:(B(r.snapshot)||(o=t.gapBuffer)==null||o.purge(),it(r,t),!0)}function se(n){for(let e of n.cookie.split(";")){let t=w(e);if(t.startsWith(F+"="))return t.slice(F.length+1)}}function ae(n){return n===void 0||n===""?!1:B(_(n,!0))}function ce(n){var r;if(!Array.isArray(n))return;let e=[];for(let o of n){if(typeof o!="string")return;e.push(w(o))}let t=JSON.stringify({v:V,p:e});return(r=_(t,!1))==null?void 0:r.purposes}function ue(n){var o;if(n!==void 0&&typeof n!="string")return;let e=typeof n=="string"?w(n):"",r=JSON.stringify({v:V,p:[],src:e===""?"manual":e});return(o=_(r,!1))==null?void 0:o.source}function st(n,e,t){try{let r=JSON.stringify({v:V,p:n,t:new Date((t!=null?t:Date.now)()).toISOString(),src:e}),o=_(r,!1);return o===null?null:{encoded:encodeURIComponent(r),snapshot:o}}catch{return null}}var at="cmp-",ct=/^[a-z0-9._-]+$/,ut={c15t:"measurement,marketing",onetrust:"c0002,c0004",cookiebot:"statistics,marketing",trustarc:"functional,advertising"};function M(n,e){let t=e!=null?e:ut[n];if(t===void 0)return null;let r=t.split(",").map(o=>o.trim().toLowerCase()).filter(o=>o!=="");if(r.length===0)return null;for(let o of r)if(!ct.test(o))return null;return r}function ft(n,e){return e.filter(r=>r in n.categories).some(r=>n.categories[r]===!0)?[ie]:[]}function k(n,e,t){var r,o,i,s;try{let a=M(e,t.categories);if(a===null){(r=t.debug)==null||r.call(t,"consent",{reason:"unparseable_mapping",preset:e});return}if(a.filter(d=>d in n.categories).length===0){(o=t.debug)==null||o.call(t,"consent",{reason:"unmappable_cmp_state",preset:e});return}let f=ft(n,a);I(f,at+e,{document:t.document,gapBuffer:t.gapBuffer,now:t.now}),(i=t.debug)==null||i.call(t,"consent",{reason:"written",preset:e,purposes:f})}catch(a){(s=t.debug)==null||s.call(t,"consent",{reason:"consent_bridge_failed",preset:e,error:String(a)})}}var fe=250,lt=1e4;function C(n,e,t){var s;let r=(s=t==null?void 0:t.scheduler)!=null?s:{setTimeout:(a,c)=>setTimeout(a,c),clearTimeout:a=>clearTimeout(a)},o=Math.floor(lt/fe),i=()=>{var c,f;let a;try{a=n()}catch(d){(c=t==null?void 0:t.debug)==null||c.call(t,"consent",{reason:"cmp_read_failed",error:String(d)});return}if(a!==void 0){e(a);return}if(o-=1,o<=0){(f=t==null?void 0:t.debug)==null||f.call(t,"consent",{reason:"cmp_not_found"});return}r.setTimeout(i,fe)};i()}function b(n,e){try{e()}catch(t){n==null||n("consent",{reason:"adapter_failed",error:String(t)})}}var dt="c15t";function pt(n){if(typeof n!="object"||n===null)return;let e={};for(let[t,r]of Object.entries(n))typeof r=="boolean"&&(e[t.toLowerCase()]=r);return{categories:e}}function mt(n,e){return typeof n=="object"&&n!==null?"consents"in n?n.consents:n:e.consents}function le(n){C(()=>{let e=n.window.c15t;return typeof e=="object"&&e!==null?e:void 0},e=>{b(n.debug,()=>{var r;let t=o=>{let i=pt(o);i&&k(i,dt,n)};t(e.consents),(r=e.onConsentChange)==null||r.call(e,o=>b(n.debug,()=>t(mt(o,e))))})},n)}var gt="cookiebot",vt=["CookiebotOnConsentReady","CookiebotOnAccept","CookiebotOnDecline"];function de(n){let e=n.Cookiebot;return typeof e=="object"&&e!==null?e:void 0}function ht(n){if(typeof n!="object"||n===null)return;let e={};for(let[t,r]of Object.entries(n))typeof r=="boolean"&&(e[t.toLowerCase()]=r);return{categories:e}}function pe(n){let e=()=>{let r=de(n.window);if(!r||r.hasResponse!==!0)return;let o=ht(r.consent);o&&k(o,gt,n)},t=n.window;if(typeof t.addEventListener=="function")for(let r of vt)t.addEventListener(r,()=>b(n.debug,e));C(()=>de(n.window),()=>b(n.debug,e),n)}var me="onetrust",bt=/^c\d{4}$/;function yt(n,e){let t={};for(let r of n.split(",")){let o=r.trim().toLowerCase();o!==""&&(t[o]=!0)}for(let r of e!=null?e:[])!(r in t)&&bt.test(r)&&(t[r]=!1);return{categories:t}}function ge(n){let e=n.window,t=()=>{let o=e.OnetrustActiveGroups;if(typeof o!="string")return;let i=M(me,n.categories);k(yt(o,i),me,n)},r=e.OptanonWrapper;e.OptanonWrapper=()=>{if(typeof r=="function")try{r()}catch{}b(n.debug,t)},C(()=>{let o=e.OnetrustActiveGroups;return typeof o=="string"?o:void 0},()=>b(n.debug,t),n)}var Et="trustarc",kt={required:1,functional:2,advertising:3},ve="PrivacyManagerAPI";function he(n){let e=n.truste,t=e==null?void 0:e.cma,r=t==null?void 0:t.callApi;return typeof r=="function"?r.bind(t):void 0}function Ct(n){if(typeof n!="object"||n===null)return;let e=n.consentDecision;if(typeof e!="number"||!Number.isFinite(e)||e<1)return;let t={};for(let[r,o]of Object.entries(kt))t[r]=e>=o;return{categories:t}}function wt(n){return typeof n=="string"?n.includes(ve):typeof n=="object"&&n!==null&&ve in n}function St(n){let e=n.location;return typeof(e==null?void 0:e.hostname)=="string"?e.hostname:void 0}function be(n){let e=()=>{let r=he(n.window);if(!r)return;let o=Ct(r("getConsentDecision",St(n.window)));o&&k(o,Et,n)},t=n.window;typeof t.addEventListener=="function"&&t.addEventListener("message",r=>b(n.debug,()=>{wt(r==null?void 0:r.data)&&e()})),C(()=>he(n.window),()=>b(n.debug,e),n)}var N="aci:buf";var ye="aci_m",L=class{constructor(e){y(this,"events");y(this,"storage");y(this,"debug");this.debug=e==null?void 0:e.debug,this.storage=e==null?void 0:e.storage,this.events=this.restore()}push(e){var t;this.events.push(e),this.events.length>50&&(this.events.splice(0,this.events.length-50),(t=this.debug)==null||t.call(this,"buffer",{reason:"cap_drop_oldest"})),this.persist()}drain(){let e=this.events;return this.events=[],this.persist(),e}purge(){var e;this.events.length>0&&((e=this.debug)==null||e.call(this,"buffer",{reason:"purged",count:this.events.length})),this.events=[],this.persist()}size(){return this.events.length}restore(){var r;let e=this.storage;if(!e)return[];let t;try{t=e.getItem(N)}catch(o){return this.storage=void 0,(r=this.debug)==null||r.call(this,"buffer",{reason:"storage_unavailable",error:String(o)}),[]}if(t==null)return[];try{let o=JSON.parse(t);if(Array.isArray(o))return o}catch{}try{e.removeItem(N)}catch{this.storage=void 0}return[]}persist(){var t;let e=this.storage;if(e)try{this.events.length===0?e.removeItem(N):e.setItem(N,JSON.stringify(this.events))}catch(r){this.storage=void 0,(t=this.debug)==null||t.call(this,"buffer",{reason:"storage_unavailable",error:String(r)})}}};function Ee(n){for(let e of n.cookie.split(";")){let t=e.trim();if(t.startsWith(ye+"="))return t.slice(ye.length+1)!==""}return!1}function ke(n,e){if(e.grants()&&!e.marker()){e.gapBuffer.push(n);return}e.batcher.push(n)}function W(n,e,t,r){if(n.size()===0||!t())return;let o=n.drain();for(let i of o)e.push(i);r==null||r("buffer",{reason:"flushed",count:o.length})}var _t="rum.link_click";function Ce(n,e){var i;let{document:t,debug:r}=e,o=(i=t.defaultView)==null?void 0:i.location;t.addEventListener("click",s=>{var a,c,f;try{let d=s.target,p=(a=d==null?void 0:d.closest)==null?void 0:a.call(d,"a[href]");if(!p)return;let u=p;n({eventName:_t,url:o==null?void 0:o.href,properties:{linkText:(f=(c=u.textContent)==null?void 0:c.trim())!=null?f:"",linkHref:u.href}})}catch(d){r==null||r("capture",{reason:"link_click_failed",error:String(d)})}},{capture:!0})}var xt="rum.page_view";function we(n){let e=n.indexOf("#");return e===-1?n:n.slice(0,e)}function Se(n,e){let t=we(n.location.href),r=()=>{let s=we(n.location.href);if(s!==t){t=s;for(let a of e)a()}},o=n.history,i=s=>{let a=o[s].bind(o);o[s]=(...c)=>{let f=a(...c);return r(),f}};i("pushState"),i("replaceState"),n.addEventListener("popstate",r)}function _e(n,e){let t=()=>n({eventName:xt,url:e.location.href,referrer:e.document.referrer});return t(),t}var G="/collect";function xe(n,e){let t=e==null?void 0:e.debug,r=e!==void 0&&"navigator"in e?e.navigator:globalThis.navigator,o=e!==void 0&&"fetch"in e?e.fetch:globalThis.fetch,i;try{i=new Blob([n],{type:"text/plain"})}catch{t==null||t("flush",{reason:"no_blob"});return}if(r!=null&&r.sendBeacon)try{if(r.sendBeacon(G,i))return}catch{}if(!o){t==null||t("flush",{reason:"no_transport"});return}try{o(G,{method:"POST",body:i,keepalive:!0}).catch(s=>{t==null||t("flush",{reason:"fetch_failed",error:String(s)})})}catch(s){t==null||t("flush",{reason:"fetch_failed",error:String(s)})}}function Ae(n){var t,r;let e=n!==void 0&&"fetch"in n?n.fetch:globalThis.fetch;if(!e)return Promise.resolve(!1);try{let o=((t=n==null?void 0:n.createEnvelopeId)!=null?t:S)(),i=new Blob([`{"envelopeId":"${o}","events":[]}`],{type:"text/plain"});return e(G,{method:"POST",body:i,keepalive:!0,credentials:"same-origin"}).then(s=>{var a;return typeof s=="object"&&s!==null&&"ok"in s&&s.ok===!1?((a=n==null?void 0:n.debug)==null||a.call(n,"flush",{reason:"refresh_failed",status:"not_ok"}),!1):!0}).catch(s=>{var a;return(a=n==null?void 0:n.debug)==null||a.call(n,"flush",{reason:"refresh_failed",error:String(s)}),!1})}catch(o){return(r=n==null?void 0:n.debug)==null||r.call(n,"flush",{reason:"refresh_failed",error:String(o)}),Promise.resolve(!1)}}var At="rum.variation_view",j="data-aci-variation";function Te(n,e){var f,d,p;let{document:t,debug:r}=e,o=e.MutationObserver;if(typeof o!="function")return;let i=(f=t.defaultView)==null?void 0:f.location,s=new WeakSet,a=u=>{let h=u.getAttribute(j);h!=null&&(s.has(u)||(s.add(u),n({eventName:At,url:i==null?void 0:i.href,properties:{variantKey:h}})))},c=u=>{try{u.hasAttribute(j)&&a(u);for(let h of Array.from(u.querySelectorAll(`[${j}]`)))a(h)}catch(h){r==null||r("capture",{reason:"variation_scan_failed",error:String(h)})}};try{let u=(d=t.body)!=null?d:t.documentElement;u&&c(u)}catch(u){r==null||r("capture",{reason:"variation_initial_scan_failed",error:String(u)})}try{let u=(p=t.body)!=null?p:t.documentElement;if(!u)return;new o(m=>{try{for(let g of m)for(let l=0;l<g.addedNodes.length;l++){let v=g.addedNodes[l];if((v==null?void 0:v.nodeType)!==1)continue;let E=v.element;E&&c(E)}}catch(g){r==null||r("capture",{reason:"variation_observer_failed",error:String(g)})}}).observe(u,{subtree:!0,childList:!0})}catch(u){r==null||r("capture",{reason:"variation_observe_failed",error:String(u)})}}var Tt="rum.web_vital";function Pe(n,e){var h,m,g;let t=e.PerformanceObserver;if(typeof t!="function")return;let{performance:r,debug:o}=e,i=(m=(h=e.window)==null?void 0:h.location)==null?void 0:m.href,s=e.document,a=new Set,c=(l,v)=>{a.has(l)||(a.add(l),n({eventName:Tt,url:i,properties:{vitalName:l,vitalValue:v}}))};try{let l=r==null?void 0:r.getEntriesByType("navigation")[0];l&&typeof l.responseStart=="number"&&typeof l.requestStart=="number"&&c("TTFB",l.responseStart-l.requestStart)}catch(l){o==null||o("capture",{reason:"ttfb_failed",error:String(l)})}let f=0,d=0,p=(l,v)=>{try{new t(Ie=>{try{for(let O of Ie.getEntries())v(O)}catch(O){o==null||o("capture",{reason:`${l}_handler_failed`,error:String(O)})}}).observe({type:l,buffered:!0})}catch(E){o==null||o("capture",{reason:`${l}_observe_failed`,error:String(E)})}};p("largest-contentful-paint",l=>{c("LCP",l.startTime)}),p("first-input",l=>{c("FID",l.startTime)}),p("layout-shift",l=>{var v;l.hadRecentInput||(f+=(v=l.value)!=null?v:0)}),p("event",l=>{var E;let v=(E=l.value)!=null?E:0;v>d&&(d=v)}),p("paint",l=>{l.name==="first-contentful-paint"&&c("FCP",l.startTime)});let u=()=>{try{a.has("CLS")||c("CLS",f),a.has("INP")||c("INP",d)}catch(l){o==null||o("capture",{reason:"visibility_handler_failed",error:String(l)})}};s&&s.addEventListener("visibilitychange",()=>{s.visibilityState==="hidden"&&u()}),(g=e.window)==null||g.addEventListener("pagehide",u)}var z={c15t:le,onetrust:ge,cookiebot:pe,trustarc:be};function Pt(n){var e,t;return typeof((e=n.navigator)==null?void 0:e.sendBeacon)=="function"&&typeof n.IntersectionObserver=="function"&&typeof((t=n.crypto)==null?void 0:t.getRandomValues)=="function"}function It(n){try{return n.sessionStorage}catch{return}}function Nt(n){var o;let e=n!=null?n:typeof window!="undefined"?window:void 0;if(!e||e.__aci_loaded||(e.__aci_loaded=!0,!Pt(e)))return;let t=re(e.document.currentScript),r=oe(t.debug);try{let i=e.document,s=new L({storage:It(e),debug:r}),a=()=>{try{return ae(se(i))}catch{return!1}},c=()=>{try{return Ee(i)}catch{return!1}},f={navigator:e.navigator,fetch:typeof e.fetch=="function"?e.fetch.bind(e):void 0,debug:r},d;d=new T({send:m=>xe(m,f),debug:r,onTick:()=>W(s,d,c,r),timers:{setInterval:(m,g)=>e.setInterval(m,g),clearInterval:m=>e.clearInterval(m)},documentTarget:i,windowTarget:e});let p=Q({document:i,window:e,debug:r}),u=m=>{ke({...J(m,p),eventId:S(void 0,g=>e.crypto.getRandomValues(g))},{grants:a,marker:c,gapBuffer:s,batcher:d})};p.start(u),Y(e,{track:(m,g)=>u({eventName:m,properties:g}),consent:({p:m,src:g})=>{let l=ce(m);if(l===void 0){r("consent",{reason:"malformed_purposes"});return}let v=ue(g);if(v===void 0){r("consent",{reason:"malformed_source"});return}I(l,v,{document:i,gapBuffer:s})||r("consent",{reason:"oversized_envelope"})}},r);let h=_e(u,e);Se(e,[()=>p.rearm(),h]),$(u,{document:i,intersectionObserver:e.IntersectionObserver,debug:r},()=>{Ae(f).then(m=>{m&&e.location.reload()})}),Ce(u,{document:i,debug:r}),Pe(u,{performance:e.performance,PerformanceObserver:e.PerformanceObserver,window:e,document:i,debug:r}),Te(u,{document:i,MutationObserver:e.MutationObserver,debug:r}),t.preset!=="manual"&&((o=z[t.preset])==null||o.call(z,{window:e,document:i,categories:t.categories,gapBuffer:s,debug:r,scheduler:{setTimeout:(m,g)=>e.setTimeout(m,g),clearTimeout:m=>e.clearTimeout(m)}})),d.start(),W(s,d,c,r),r("init",{config:t})}catch(i){r("init",{error:String(i)})}}Nt();})();
@@ -1 +1 @@
1
- 46f87bbce4c938e9540939102be1094f5cd956d0f3a5836e9af5c3b0b8c582ad
1
+ 71dca62a909ba063d17ff8e8af11d33c755fb4e192e4e469ad212dc72498f4ac
@@ -2,23 +2,19 @@ import type { DebugFn } from "./config.js";
2
2
  export interface CommandHandlers {
3
3
  /** Receives the normalized custom.* event name. */
4
4
  track: (name: string, properties?: Record<string, unknown>) => void;
5
- /** Manual consent write; only reachable under the manual preset. */
5
+ /** Manual consent write; reachable under every preset — with no CMP installed the JS API is the only writer. */
6
6
  consent: (envelope: {
7
7
  p: unknown;
8
8
  src: unknown;
9
9
  }) => void;
10
10
  }
11
- export interface CommandQueueConfig {
12
- preset: string;
13
- }
14
11
  interface AciHost {
15
12
  aci?: unknown;
16
13
  }
17
14
  /**
18
15
  * installCommandQueue replaces any pre-load stub on window.aci with the live
19
16
  * dispatcher, draining queued calls in order first. Malformed or unknown
20
- * commands are ignored after a debug record; the CMP preset is authoritative
21
- * over consent commands (manual mode only).
17
+ * commands are ignored after a debug record.
22
18
  */
23
- export declare function installCommandQueue(win: AciHost, cfg: CommandQueueConfig, handlers: CommandHandlers, debug?: DebugFn): void;
19
+ export declare function installCommandQueue(win: AciHost, handlers: CommandHandlers, debug?: DebugFn): void;
24
20
  export {};
@@ -9,10 +9,9 @@ function isPlainObjectLike(value) {
9
9
  /**
10
10
  * installCommandQueue replaces any pre-load stub on window.aci with the live
11
11
  * dispatcher, draining queued calls in order first. Malformed or unknown
12
- * commands are ignored after a debug record; the CMP preset is authoritative
13
- * over consent commands (manual mode only).
12
+ * commands are ignored after a debug record.
14
13
  */
15
- export function installCommandQueue(win, cfg, handlers, debug) {
14
+ export function installCommandQueue(win, handlers, debug) {
16
15
  const dispatch = (...args) => {
17
16
  try {
18
17
  const [command, ...rest] = args;
@@ -31,11 +30,6 @@ export function installCommandQueue(win, cfg, handlers, debug) {
31
30
  return undefined;
32
31
  }
33
32
  if (command === "consent") {
34
- if (cfg.preset !== "manual") {
35
- // The CMP is authoritative (design/04 consent-writer precedence).
36
- debug?.("consent", { reason: "preset_authoritative", preset: cfg.preset });
37
- return undefined;
38
- }
39
33
  const envelope = rest[0];
40
34
  if (!isPlainObjectLike(envelope)) {
41
35
  debug?.("consent", { reason: "malformed_consent_envelope" });
@@ -113,7 +113,7 @@ export function init(win) {
113
113
  // match a goal (review-quorum finding). Consent commands drained after
114
114
  // this stay safe — events wait in the gap buffer until grants resolve.
115
115
  assignments.start(emit);
116
- installCommandQueue(w, cfg, {
116
+ installCommandQueue(w, {
117
117
  track: (name, properties) => emit({ eventName: name, properties }),
118
118
  consent: ({ p, src }) => {
119
119
  const purposes = sanitizePurposes(p);
@@ -1,5 +1,6 @@
1
1
  export * from './types.js';
2
2
  export * from './personalization-core.js';
3
3
  export * from './identity.js';
4
+ export * from './mimic_token.js';
4
5
  export * from './compose.js';
5
6
  export { resolvePersonalizationRequest, } from './resolve.js';
@@ -3,5 +3,6 @@
3
3
  export * from './types.js';
4
4
  export * from './personalization-core.js';
5
5
  export * from './identity.js';
6
+ export * from './mimic_token.js';
6
7
  export * from './compose.js';
7
8
  export { resolvePersonalizationRequest, } from './resolve.js';
@@ -0,0 +1,13 @@
1
+ export interface MimicClaims {
2
+ scope: string;
3
+ siteId: string;
4
+ aud?: string[];
5
+ seg?: string[];
6
+ sub?: string;
7
+ jti?: string;
8
+ iat: string;
9
+ expiresAt: string;
10
+ }
11
+ export declare const MIMIC_MAX_MEMBERSHIPS = 32;
12
+ export declare const MIMIC_MAX_TOKEN_BYTES = 2048;
13
+ export declare function validateMimicToken(token: string, signingKey: string, siteId: string): Promise<MimicClaims | null>;
@@ -0,0 +1,59 @@
1
+ // Mimic token validation for the edge runtime (specs/features/audience-mimic).
2
+ //
3
+ // Same HS256 envelope and signing key as preview; the scope claim makes the
4
+ // tokens non-interchangeable (D-6). This validator is the twin of
5
+ // internal/domain/edge/routing/mimic.go, pinned by the shared vector file
6
+ // (internal/domain/edge/routing/testdata/mimic_token_vectors.json); the SDK
7
+ // mirror for framework hosts is packages/sdk/src/mimic/core.ts.
8
+ export const MIMIC_MAX_MEMBERSHIPS = 32;
9
+ export const MIMIC_MAX_TOKEN_BYTES = 2048;
10
+ export async function validateMimicToken(token, signingKey, siteId) {
11
+ if (!token || token.length > MIMIC_MAX_TOKEN_BYTES || !signingKey || !siteId)
12
+ return null;
13
+ const parts = token.split('.');
14
+ if (parts.length !== 3)
15
+ return null;
16
+ const signingInput = parts[0] + '.' + parts[1];
17
+ let signatureBytes;
18
+ try {
19
+ signatureBytes = base64URLDecode(parts[2]);
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ const key = await crypto.subtle.importKey('raw', new TextEncoder().encode(signingKey), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
25
+ const valid = await crypto.subtle.verify('HMAC', key, signatureBytes, new TextEncoder().encode(signingInput));
26
+ if (!valid)
27
+ return null;
28
+ let claims;
29
+ try {
30
+ claims = JSON.parse(new TextDecoder().decode(base64URLDecode(parts[1])));
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ if (claims.scope !== 'mimic')
36
+ return null;
37
+ if (typeof claims.siteId !== 'string' || claims.siteId !== siteId)
38
+ return null;
39
+ const aud = Array.isArray(claims.aud) ? claims.aud : [];
40
+ const seg = Array.isArray(claims.seg) ? claims.seg : [];
41
+ if (aud.length + seg.length === 0)
42
+ return null;
43
+ if (aud.length > MIMIC_MAX_MEMBERSHIPS || seg.length > MIMIC_MAX_MEMBERSHIPS)
44
+ return null;
45
+ const expiresAt = new Date(claims.expiresAt);
46
+ if (Number.isNaN(expiresAt.getTime()) || expiresAt.getTime() <= Date.now())
47
+ return null;
48
+ return { ...claims, aud, seg };
49
+ }
50
+ function base64URLDecode(value) {
51
+ const padded = value.replace(/-/g, '+').replace(/_/g, '/')
52
+ + '='.repeat((4 - value.length % 4) % 4);
53
+ const binary = atob(padded);
54
+ const bytes = new Uint8Array(binary.length);
55
+ for (let index = 0; index < binary.length; index += 1) {
56
+ bytes[index] = binary.charCodeAt(index);
57
+ }
58
+ return bytes;
59
+ }
@@ -19,13 +19,19 @@ export async function resolvePersonalizationRequest(request, config) {
19
19
  // (no non-essential cookie before consent).
20
20
  //
21
21
  // GPC/DNT deny fully: no read, no identity, no experiment bucketing.
22
- const rawIdentity = consent.privacyDenied
22
+ //
23
+ // Mimic (specs/features/audience-mimic): a validated mimicClaims input
24
+ // bypasses identity resolution entirely — the session reads no aci_id and
25
+ // no aci_claims (D-2/D-7), so identityHash stays empty and the experiment
26
+ // tier is structurally skipped (D-5).
27
+ const mimic = config.mimicClaims;
28
+ const rawIdentity = mimic || consent.privacyDenied
23
29
  ? null
24
30
  : await verifyIdentityCookie(cookies.get('aci_id') || '', config.identityKeys);
25
31
  // The identity hash feeds experiment bucketing for identified visitors.
26
32
  // Claims are a signed cookie written by /collect; the EdgeRouter
27
33
  // never reads the customer object store to refresh or revoke them.
28
- let signedClaims = cookies.get('aci_claims') || '';
34
+ let signedClaims = mimic ? '' : cookies.get('aci_claims') || '';
29
35
  let identityHash = '';
30
36
  if (rawIdentity) {
31
37
  identityHash = await identityHashHex('aci_id', rawIdentity);
@@ -38,9 +44,11 @@ export async function resolvePersonalizationRequest(request, config) {
38
44
  const matchedRoute = config.route;
39
45
  let variantKey = '';
40
46
  if (matchedRoute) {
41
- const claims = consent.allowsIdentityTier
42
- ? await verifyClaims(signedClaims, config.claimsKeys || {}, now)
43
- : null;
47
+ const claims = mimic
48
+ ? { aud: mimic.aud, seg: mimic.seg, iat: 0, exp: 0 }
49
+ : consent.allowsIdentityTier
50
+ ? await verifyClaims(signedClaims, config.claimsKeys || {}, now)
51
+ : null;
44
52
  const decision = resolvePersonalizationDecision(toPersonalizationRequestContext(request), matchedRoute, claims, config.experiments, identityHash
45
53
  ? { usable: true, siteId: config.siteId, namespace: 'aci_id', identityHash }
46
54
  : undefined);
@@ -170,6 +170,10 @@ export interface PersonalizationHostConfig {
170
170
  secureCookies?: boolean;
171
171
  now?: () => Date;
172
172
  randomBytes?: (length: number) => Uint8Array;
173
+ mimicClaims?: {
174
+ aud?: string[];
175
+ seg?: string[];
176
+ };
173
177
  }
174
178
  export interface PersonalizationResolution {
175
179
  variantKey: string;
@@ -0,0 +1,34 @@
1
+ export interface MimicClaims {
2
+ scope: string;
3
+ siteId: string;
4
+ aud?: string[];
5
+ seg?: string[];
6
+ sub?: string;
7
+ jti?: string;
8
+ iat: string;
9
+ expiresAt: string;
10
+ }
11
+ export declare const MIMIC_PARAM = "aci_mimic";
12
+ export declare const MIMIC_COOKIE = "aci_mimic";
13
+ export declare const MIMIC_EXIT = "exit";
14
+ export declare const MIMIC_MAX_MEMBERSHIPS = 32;
15
+ export declare const MIMIC_MAX_TOKEN_BYTES = 2048;
16
+ export declare function validateMimicToken(token: string, signKey: string, siteId: string): Promise<MimicClaims | null>;
17
+ export interface MimicCookie {
18
+ name: string;
19
+ value: string;
20
+ options: {
21
+ httpOnly: boolean;
22
+ sameSite: 'lax';
23
+ maxAge: number;
24
+ path: string;
25
+ secure?: boolean;
26
+ };
27
+ }
28
+ export declare function createMimicEntryCookie(token: string, expiresAt: string, secure?: boolean): MimicCookie;
29
+ export declare function createMimicClearCookie(secure?: boolean): MimicCookie;
30
+ export declare function createMimicBannerHTML(claims: Pick<MimicClaims, 'aud' | 'seg'>, expiresAt: string): string;
31
+ export declare function injectMimicBannerIntoHTML(html: string, banner: string): string;
32
+ export declare const MIMIC_BANNER_HEADER = "x-aci-mimic-banner";
33
+ export declare function encodeMimicBanner(claims: MimicClaims): string;
34
+ export declare function decodeMimicBanner(encoded: string): string;