consentlayer 0.0.0-stage → 1.0.0-rc.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 (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +88 -2
  3. package/dist/adapters/google-consent-mode.d.ts +20 -0
  4. package/dist/adapters/google-consent-mode.js +18 -0
  5. package/dist/adapters/google-consent-mode.js.map +1 -0
  6. package/dist/adapters/shopify.d.ts +49 -0
  7. package/dist/adapters/shopify.js +85 -0
  8. package/dist/adapters/shopify.js.map +1 -0
  9. package/dist/adapters/tcf.d.ts +20 -0
  10. package/dist/adapters/tcf.js +64 -0
  11. package/dist/adapters/tcf.js.map +1 -0
  12. package/dist/analytics-provider-07mxUgIK.d.ts +36 -0
  13. package/dist/angular.d.ts +56 -0
  14. package/dist/angular.js +120 -0
  15. package/dist/angular.js.map +1 -0
  16. package/dist/auto-tracking.d.ts +11 -0
  17. package/dist/auto-tracking.js +72 -0
  18. package/dist/auto-tracking.js.map +1 -0
  19. package/dist/chunk-7XLGT6U3.js +34 -0
  20. package/dist/chunk-7XLGT6U3.js.map +1 -0
  21. package/dist/chunk-BWPWDN4G.js +61 -0
  22. package/dist/chunk-BWPWDN4G.js.map +1 -0
  23. package/dist/chunk-DK45XPEY.js +77 -0
  24. package/dist/chunk-DK45XPEY.js.map +1 -0
  25. package/dist/chunk-ETU64ZV3.js +98 -0
  26. package/dist/chunk-ETU64ZV3.js.map +1 -0
  27. package/dist/chunk-FDJMIJFV.js +367 -0
  28. package/dist/chunk-FDJMIJFV.js.map +1 -0
  29. package/dist/chunk-HJGBVDPM.js +47 -0
  30. package/dist/chunk-HJGBVDPM.js.map +1 -0
  31. package/dist/chunk-J3KUPF4R.js +69 -0
  32. package/dist/chunk-J3KUPF4R.js.map +1 -0
  33. package/dist/chunk-LBEIEAJX.js +55 -0
  34. package/dist/chunk-LBEIEAJX.js.map +1 -0
  35. package/dist/chunk-LEAQJXJU.js +582 -0
  36. package/dist/chunk-LEAQJXJU.js.map +1 -0
  37. package/dist/chunk-R6I7OYQB.js +69 -0
  38. package/dist/chunk-R6I7OYQB.js.map +1 -0
  39. package/dist/chunk-RK2M57GW.js +54 -0
  40. package/dist/chunk-RK2M57GW.js.map +1 -0
  41. package/dist/chunk-RZ4TYRNY.js +128 -0
  42. package/dist/chunk-RZ4TYRNY.js.map +1 -0
  43. package/dist/chunk-TVSZJLRC.js +112 -0
  44. package/dist/chunk-TVSZJLRC.js.map +1 -0
  45. package/dist/chunk-TYOQYV45.js +79 -0
  46. package/dist/chunk-TYOQYV45.js.map +1 -0
  47. package/dist/chunk-UAIZU5WD.js +52 -0
  48. package/dist/chunk-UAIZU5WD.js.map +1 -0
  49. package/dist/chunk-VIIGBALD.js +14 -0
  50. package/dist/chunk-VIIGBALD.js.map +1 -0
  51. package/dist/consent-controller-DyHPNfyT.d.ts +47 -0
  52. package/dist/consentlayer-banner.global.js +20 -0
  53. package/dist/consentlayer.global.js +9 -0
  54. package/dist/create-analytics-Bzvm1UpE.d.ts +44 -0
  55. package/dist/ecommerce.d.ts +41 -0
  56. package/dist/ecommerce.js +43 -0
  57. package/dist/ecommerce.js.map +1 -0
  58. package/dist/index.d.ts +58 -0
  59. package/dist/index.js +42 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/next.d.ts +16 -0
  62. package/dist/next.js +27 -0
  63. package/dist/next.js.map +1 -0
  64. package/dist/nuxt/config.d.ts +7 -0
  65. package/dist/nuxt/config.js +6 -0
  66. package/dist/nuxt/config.js.map +1 -0
  67. package/dist/nuxt/index.d.ts +11 -0
  68. package/dist/nuxt/index.js +35 -0
  69. package/dist/nuxt/index.js.map +1 -0
  70. package/dist/nuxt/plugin.d.ts +5 -0
  71. package/dist/nuxt/plugin.js +24 -0
  72. package/dist/nuxt/plugin.js.map +1 -0
  73. package/dist/providers/contentsquare.d.ts +27 -0
  74. package/dist/providers/contentsquare.js +58 -0
  75. package/dist/providers/contentsquare.js.map +1 -0
  76. package/dist/providers/ga4.d.ts +46 -0
  77. package/dist/providers/ga4.js +3 -0
  78. package/dist/providers/ga4.js.map +1 -0
  79. package/dist/providers/gtm.d.ts +28 -0
  80. package/dist/providers/gtm.js +83 -0
  81. package/dist/providers/gtm.js.map +1 -0
  82. package/dist/providers/hotjar.d.ts +38 -0
  83. package/dist/providers/hotjar.js +68 -0
  84. package/dist/providers/hotjar.js.map +1 -0
  85. package/dist/providers/meta.d.ts +42 -0
  86. package/dist/providers/meta.js +65 -0
  87. package/dist/providers/meta.js.map +1 -0
  88. package/dist/providers/posthog.d.ts +42 -0
  89. package/dist/providers/posthog.js +91 -0
  90. package/dist/providers/posthog.js.map +1 -0
  91. package/dist/providers/sentry.d.ts +38 -0
  92. package/dist/providers/sentry.js +82 -0
  93. package/dist/providers/sentry.js.map +1 -0
  94. package/dist/providers/tiktok.d.ts +46 -0
  95. package/dist/providers/tiktok.js +72 -0
  96. package/dist/providers/tiktok.js.map +1 -0
  97. package/dist/providers/vercel.d.ts +14 -0
  98. package/dist/providers/vercel.js +17 -0
  99. package/dist/providers/vercel.js.map +1 -0
  100. package/dist/react/index.d.ts +78 -0
  101. package/dist/react/index.js +79 -0
  102. package/dist/react/index.js.map +1 -0
  103. package/dist/sentry/next.d.ts +1 -0
  104. package/dist/sentry/next.js +3 -0
  105. package/dist/sentry/next.js.map +1 -0
  106. package/dist/sentry/server.d.ts +24 -0
  107. package/dist/sentry/server.js +28 -0
  108. package/dist/sentry/server.js.map +1 -0
  109. package/dist/sentry-replay-HSFVEFCM.js +3 -0
  110. package/dist/sentry-replay-HSFVEFCM.js.map +1 -0
  111. package/dist/sentry-sdk-YQOGKGWD.js +3 -0
  112. package/dist/sentry-sdk-YQOGKGWD.js.map +1 -0
  113. package/dist/sentry-tracing-KWT7ITHF.js +3 -0
  114. package/dist/sentry-tracing-KWT7ITHF.js.map +1 -0
  115. package/dist/server/ga4.d.ts +15 -0
  116. package/dist/server/ga4.js +29 -0
  117. package/dist/server/ga4.js.map +1 -0
  118. package/dist/server/index.d.ts +116 -0
  119. package/dist/server/index.js +206 -0
  120. package/dist/server/index.js.map +1 -0
  121. package/dist/server/meta.d.ts +14 -0
  122. package/dist/server/meta.js +63 -0
  123. package/dist/server/meta.js.map +1 -0
  124. package/dist/server/sgtm.d.ts +18 -0
  125. package/dist/server/sgtm.js +34 -0
  126. package/dist/server/sgtm.js.map +1 -0
  127. package/dist/server/tiktok.d.ts +15 -0
  128. package/dist/server/tiktok.js +64 -0
  129. package/dist/server/tiktok.js.map +1 -0
  130. package/dist/solid.d.ts +59 -0
  131. package/dist/solid.js +3 -0
  132. package/dist/solid.js.map +1 -0
  133. package/dist/solidstart.d.ts +16 -0
  134. package/dist/solidstart.js +22 -0
  135. package/dist/solidstart.js.map +1 -0
  136. package/dist/svelte/GtmNoscript.svelte +18 -0
  137. package/dist/svelte/MetaPixelNoscript.svelte +18 -0
  138. package/dist/svelte.d.ts +55 -0
  139. package/dist/svelte.js +3 -0
  140. package/dist/svelte.js.map +1 -0
  141. package/dist/sveltekit.d.ts +18 -0
  142. package/dist/sveltekit.js +16 -0
  143. package/dist/sveltekit.js.map +1 -0
  144. package/dist/testing.d.ts +11 -0
  145. package/dist/testing.js +50 -0
  146. package/dist/testing.js.map +1 -0
  147. package/dist/types-BV_AFZKQ.d.ts +407 -0
  148. package/dist/vue.d.ts +92 -0
  149. package/dist/vue.js +97 -0
  150. package/dist/vue.js.map +1 -0
  151. package/package.json +281 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/svelte.ts"],"names":[],"mappings":";;;;;;AAkCO,IAAM,iBAAA,GACX;AAQK,IAAM,WAAA,GACX;AAEF,IAAM,YAAA,0BAAsB,wBAAwB,CAAA;AACpD,IAAM,aAAA,0BAAuB,yBAAyB,CAAA;AAG/C,SAAS,aAAa,EAAE,SAAA,EAAW,eAAe,IAAA,EAAM,GAAG,SAAQ,EAA2C;AACnH,EAAA,MAAM,UAAA,GAAa,uBAAA,CAAwB,SAAA,EAAW,OAAO,CAAA;AAC7D,EAAA,MAAM,YAAY,gBAAA,CAAiB,CAAC,WAAW,UAAA,CAAW,SAAA,CAAU,MAAM,CAAC,CAAA;AAC3E,EAAA,MAAM,OAAO,MAAM;AACjB,IAAA,SAAA,EAAU;AACV,IAAA,OAAO,WAAW,WAAA,EAAY;AAAA,EAChC,CAAA;AACA,EAAA,MAAM,EAAA,GAAwB;AAAA,IAC5B,IAAI,KAAA,GAAQ;AACV,MAAA,OAAO,MAAK,CAAE,KAAA;AAAA,IAChB,CAAA;AAAA,IACA,IAAI,KAAA,GAAQ;AACV,MAAA,OAAO,MAAK,CAAE,KAAA;AAAA,IAChB,CAAA;AAAA,IACA,IAAI,aAAA,GAAgB;AAClB,MAAA,OAAO,MAAK,CAAE,aAAA;AAAA,IAChB,CAAA;AAAA,IACA,IAAI,aAAA,GAAgB;AAClB,MAAA,OAAO,MAAK,CAAE,aAAA;AAAA,IAChB,CAAA;AAAA,IACA,IAAI,UAAA,GAAa;AACf,MAAA,OAAO,MAAK,CAAE,UAAA;AAAA,IAChB,CAAA;AAAA,IACA,IAAI,GAAA,GAAM;AACR,MAAA,OAAO,MAAK,CAAE,GAAA;AAAA,IAChB,CAAA;AAAA,IACA,IAAI,KAAA,GAAQ;AACV,MAAA,OAAO,MAAK,CAAE,KAAA;AAAA,IAChB,CAAA;AAAA,IACA,GAAG,UAAA,CAAW;AAAA,GAChB;AACA,EAAA,UAAA,CAAW,cAAc,SAAS,CAAA;AAClC,EAAA,UAAA,CAAW,eAAe,EAAE,CAAA;AAE5B,EAAA,aAAA,GAAgB,CAAC,EAAE,EAAA,EAAG,KAAM;AAC1B,IAAA,IAAI,EAAA,aAAe,QAAA,CAAS,EAAA,CAAG,IAAI,QAAA,GAAW,EAAA,CAAG,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAAA,EACnE,CAAC,CAAA;AACD,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAA,IAAI,CAAC,aAAA,EAAe,UAAA,CAAW,QAAA,CAAS,WAAW,IAAI,CAAA;AACvD,IAAA,OAAO,WAAW,KAAA,EAAM;AAAA,EAC1B,CAAC,CAAA;AACD,EAAA,OAAO,EAAA;AACT;AAGO,SAAS,YAAA,GAA0B;AACxC,EAAA,MAAM,SAAA,GAAY,UAAA,CAAkC,YAAY,CAAA,IAAK,eAAA,EAAgB;AACrF,EAAA,IAAI,CAAC,SAAA,EAAW,MAAM,IAAI,MAAM,qEAAqE,CAAA;AACrG,EAAA,OAAO,SAAA;AACT;AAGO,SAAS,UAAA,GAKd;AACA,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,SAAA,GAAY,iBAAiB,CAAC,MAAA,KAAW,UAAU,OAAA,CAAQ,SAAA,CAAU,MAAM,CAAC,CAAA;AAClF,EAAA,OAAO;AAAA,IACL,IAAI,OAAA,GAAU;AACZ,MAAA,SAAA,EAAU;AACV,MAAA,OAAO,SAAA,CAAU,QAAQ,UAAA,EAAW;AAAA,IACtC,CAAA;AAAA,IACA,QAAQ,SAAA,CAAU,OAAA;AAAA,IAClB,YAAY,CAAC,IAAA,KAAS,SAAA,CAAU,OAAA,CAAQ,WAAW,IAAI,CAAA;AAAA,IACvD,QAAQ,CAAC,OAAA,KAAY,SAAA,CAAU,OAAA,CAAQ,OAAO,OAAO;AAAA,GACvD;AACF;AAGO,SAAS,oBAAA,GAA0C;AACxD,EAAA,MAAM,UAAA,GAAa,WAA0C,aAAa,CAAA;AAC1E,EAAA,IAAI,CAAC,UAAA,EAAY,MAAM,IAAI,MAAM,iEAAiE,CAAA;AAClG,EAAA,OAAO,UAAA;AACT","file":"chunk-TYOQYV45.js","sourcesContent":["import { getContext, onMount, setContext, type Component } from 'svelte'\nimport { createSubscriber } from 'svelte/reactivity'\nimport {\n createConsentController,\n type ConsentControllerActions,\n type ConsentControllerOptions,\n type ConsentControllerState,\n} from './core/consent-controller'\nimport { latestAnalytics } from './core/create-analytics'\nimport type { Analytics, ConsentApi, ConsentState, PageViewPayload } from './core/types'\nimport type { HTMLIframeAttributes, HTMLImgAttributes } from 'svelte/elements'\nimport GtmNoscriptComponent from './svelte/GtmNoscript.svelte'\nimport MetaPixelNoscriptComponent from './svelte/MetaPixelNoscript.svelte'\n\n/** The part of SvelteKit's `afterNavigate` ConsentLayer uses. */\nexport type AfterNavigateLike = (callback: (navigation: { to: { url: URL } | null }) => void) => void\n\n/** Options for `consentLayer()`. */\nexport type ConsentLayerOptions = ConsentControllerOptions & {\n analytics: Analytics\n /** SvelteKit's `afterNavigate`; sends a page view on every navigation. Without it, one page view is sent for the page load. */\n afterNavigate?: AfterNavigateLike\n page?: PageViewPayload\n}\n\n/** What `useConsentController()` returns: the UI state as reactive properties, and the actions. */\nexport type ConsentController = Readonly<ConsentControllerState> & ConsentControllerActions\n\n/**\n * Meta's `<noscript>` PageView pixel. It fires only for visitors without\n * JavaScript, who never see the consent banner, so it tracks them without\n * consent. Render it only where that is lawful for you. Renders nothing without\n * `enabled` or while `pixelId` is unset. Other attributes go to the `<img>`.\n */\nexport const MetaPixelNoscript: Component<{ pixelId: string | undefined; enabled?: boolean } & HTMLImgAttributes> =\n MetaPixelNoscriptComponent\n\n/**\n * Google Tag Manager's `<noscript>` iframe. It loads the container only for\n * visitors without JavaScript, who never see the consent banner, so its tags\n * run without consent. Render it only where that is lawful for you. Renders\n * nothing without `enabled` or while `containerId` is unset. Other attributes go to the `<iframe>`.\n */\nexport const GtmNoscript: Component<{ containerId: string | undefined; enabled?: boolean } & HTMLIframeAttributes> =\n GtmNoscriptComponent\n\nconst AnalyticsKey = Symbol('consentlayer.analytics')\nconst ControllerKey = Symbol('consentlayer.controller')\n\n/** Boots analytics, sends page views on navigation and provides the state for your consent UI. Call it in your root component. */\nexport function consentLayer({ analytics, afterNavigate, page, ...options }: ConsentLayerOptions): ConsentController {\n const controller = createConsentController(analytics, options)\n const subscribe = createSubscriber((update) => controller.subscribe(update))\n const read = () => {\n subscribe()\n return controller.getSnapshot()\n }\n const ui: ConsentController = {\n get ready() {\n return read().ready\n },\n get error() {\n return read().error\n },\n get bannerVisible() {\n return read().bannerVisible\n },\n get dialogVisible() {\n return read().dialogVisible\n },\n get categories() {\n return read().categories\n },\n get gpc() {\n return read().gpc\n },\n get prefs() {\n return read().prefs\n },\n ...controller.actions,\n }\n setContext(AnalyticsKey, analytics)\n setContext(ControllerKey, ui)\n\n afterNavigate?.(({ to }) => {\n if (to) controller.setRoute(to.url.pathname + to.url.search, page)\n })\n onMount(() => {\n if (!afterNavigate) controller.setRoute('default', page)\n return controller.start()\n })\n return ui\n}\n\n/** The instance from `consentLayer()`, else the one `createAnalytics()` made. */\nexport function useAnalytics(): Analytics {\n const analytics = getContext<Analytics | undefined>(AnalyticsKey) ?? latestAnalytics()\n if (!analytics) throw new Error('useAnalytics needs createAnalytics() to have run, or consentLayer()')\n return analytics\n}\n\n/** Current consent as a reactive property, `null` before a choice. */\nexport function useConsent(): {\n readonly consent: ConsentState | null\n engine: ConsentApi\n setConsent: (consent: ConsentState) => Promise<void>\n update: (partial: Partial<ConsentState>) => Promise<void>\n} {\n const analytics = useAnalytics()\n const subscribe = createSubscriber((update) => analytics.consent.subscribe(update))\n return {\n get consent() {\n subscribe()\n return analytics.consent.getConsent()\n },\n engine: analytics.consent,\n setConsent: (next) => analytics.consent.setConsent(next),\n update: (partial) => analytics.consent.update(partial),\n }\n}\n\n/** State and actions for building your own consent UI. */\nexport function useConsentController(): ConsentController {\n const controller = getContext<ConsentController | undefined>(ControllerKey)\n if (!controller) throw new Error('useConsentController needs consentLayer() in a parent component')\n return controller\n}\n"]}
@@ -0,0 +1,52 @@
1
+ import { createConsentController, latestAnalytics } from './chunk-FDJMIJFV.js';
2
+ import { createContext, useState, useSyncExternalStore, useMemo, useEffect, useContext } from 'react';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ var AnalyticsContext = createContext(void 0);
6
+ var ConsentControllerContext = createContext(void 0);
7
+ function AnalyticsProvider({
8
+ analytics,
9
+ children,
10
+ routeKey = "default",
11
+ page,
12
+ boot,
13
+ autoShowBanner,
14
+ openConsentGlobalKey
15
+ }) {
16
+ const [controller] = useState(
17
+ () => createConsentController(analytics, { boot, autoShowBanner, openConsentGlobalKey })
18
+ );
19
+ const state = useSyncExternalStore(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
20
+ const value = useMemo(() => ({ ...controller.actions, ...state }), [controller, state]);
21
+ useEffect(() => controller.start(), [controller]);
22
+ useEffect(() => controller.setRoute(routeKey, page), [controller, routeKey, page]);
23
+ return /* @__PURE__ */ jsx(AnalyticsContext.Provider, { value: analytics, children: /* @__PURE__ */ jsx(ConsentControllerContext.Provider, { value, children }) });
24
+ }
25
+ function useAnalytics() {
26
+ const analytics = useContext(AnalyticsContext) ?? latestAnalytics();
27
+ if (!analytics) throw new Error("useAnalytics needs createAnalytics() to have run, or an AnalyticsProvider above it");
28
+ return analytics;
29
+ }
30
+ function useConsent() {
31
+ const analytics = useAnalytics();
32
+ const consent = useSyncExternalStore(
33
+ (listener) => analytics.consent.subscribe(listener),
34
+ () => analytics.consent.getConsent(),
35
+ () => analytics.consent.getConsent()
36
+ );
37
+ return {
38
+ consent,
39
+ engine: analytics.consent,
40
+ setConsent: (next) => analytics.consent.setConsent(next),
41
+ update: (partial) => analytics.consent.update(partial)
42
+ };
43
+ }
44
+ function useConsentController() {
45
+ const value = useContext(ConsentControllerContext);
46
+ if (!value) throw new Error("useConsentController must be used within AnalyticsProvider");
47
+ return value;
48
+ }
49
+
50
+ export { AnalyticsContext, AnalyticsProvider, useAnalytics, useConsent, useConsentController };
51
+ //# sourceMappingURL=chunk-UAIZU5WD.js.map
52
+ //# sourceMappingURL=chunk-UAIZU5WD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/analytics-provider.tsx"],"names":[],"mappings":";;;;AAWO,IAAM,gBAAA,GAAmB,cAAqC,MAAS;AAI9E,IAAM,wBAAA,GAA2B,cAAkD,MAAS,CAAA;AAiBrF,SAAS,iBAAA,CAAkB;AAAA,EAChC,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA,GAAW,SAAA;AAAA,EACX,IAAA;AAAA,EACA,IAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,EAA2B;AACzB,EAAA,MAAM,CAAC,UAAU,CAAA,GAAI,QAAA;AAAA,IAAS,MAC5B,uBAAA,CAAwB,SAAA,EAAW,EAAE,IAAA,EAAM,cAAA,EAAgB,sBAAsB;AAAA,GACnF;AACA,EAAA,MAAM,QAAQ,oBAAA,CAAqB,UAAA,CAAW,WAAW,UAAA,CAAW,WAAA,EAAa,WAAW,WAAW,CAAA;AACvG,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAgC,OAAO,EAAE,GAAG,UAAA,CAAW,OAAA,EAAS,GAAG,KAAA,EAAM,CAAA,EAAI,CAAC,UAAA,EAAY,KAAK,CAAC,CAAA;AAE9G,EAAA,SAAA,CAAU,MAAM,UAAA,CAAW,KAAA,EAAM,EAAG,CAAC,UAAU,CAAC,CAAA;AAChD,EAAA,SAAA,CAAU,MAAM,UAAA,CAAW,QAAA,CAAS,QAAA,EAAU,IAAI,GAAG,CAAC,UAAA,EAAY,QAAA,EAAU,IAAI,CAAC,CAAA;AAEjF,EAAA,uBACE,GAAA,CAAC,gBAAA,CAAiB,QAAA,EAAjB,EAA0B,KAAA,EAAO,SAAA,EAChC,QAAA,kBAAA,GAAA,CAAC,wBAAA,CAAyB,QAAA,EAAzB,EAAkC,KAAA,EAAe,QAAA,EAAS,CAAA,EAC7D,CAAA;AAEJ;AAGO,SAAS,YAAA,GAA0B;AACxC,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,gBAAgB,CAAA,IAAK,eAAA,EAAgB;AAClE,EAAA,IAAI,CAAC,SAAA,EAAW,MAAM,IAAI,MAAM,oFAAoF,CAAA;AACpH,EAAA,OAAO,SAAA;AACT;AAGO,SAAS,UAAA,GAKd;AACA,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,OAAA,GAAU,oBAAA;AAAA,IACd,CAAC,QAAA,KAAa,SAAA,CAAU,OAAA,CAAQ,UAAU,QAAQ,CAAA;AAAA,IAClD,MAAM,SAAA,CAAU,OAAA,CAAQ,UAAA,EAAW;AAAA,IACnC,MAAM,SAAA,CAAU,OAAA,CAAQ,UAAA;AAAW,GACrC;AACA,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,QAAQ,SAAA,CAAU,OAAA;AAAA,IAClB,YAAY,CAAC,IAAA,KAAS,SAAA,CAAU,OAAA,CAAQ,WAAW,IAAI,CAAA;AAAA,IACvD,QAAQ,CAAC,OAAA,KAAY,SAAA,CAAU,OAAA,CAAQ,OAAO,OAAO;AAAA,GACvD;AACF;AAGO,SAAS,oBAAA,GAA+C;AAC7D,EAAA,MAAM,KAAA,GAAQ,WAAW,wBAAwB,CAAA;AACjD,EAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,MAAM,4DAA4D,CAAA;AACxF,EAAA,OAAO,KAAA;AACT","file":"chunk-UAIZU5WD.js","sourcesContent":["'use client'\n\nimport { createContext, useContext, useEffect, useMemo, useState, useSyncExternalStore, type ReactNode } from 'react'\nimport type { Analytics, ConsentApi, ConsentState, LazyBootConfig, PageViewPayload } from '../core/types'\nimport { latestAnalytics } from '../core/create-analytics'\nimport {\n createConsentController,\n type ConsentControllerActions,\n type ConsentControllerState,\n} from '../core/consent-controller'\n\nexport const AnalyticsContext = createContext<Analytics | undefined>(undefined)\n\ntype ConsentControllerValue = ConsentControllerState & ConsentControllerActions\n\nconst ConsentControllerContext = createContext<ConsentControllerValue | undefined>(undefined)\n\n/** Props for `<AnalyticsProvider>`. */\nexport type AnalyticsProviderProps = {\n analytics: Analytics\n children: ReactNode\n /** Changes on every navigation; a page view is sent once per key. `null` holds page views until the route is known. */\n routeKey?: string | null\n page?: PageViewPayload\n /** When providers load. Defaults to `{ mode: 'immediate' }`. */\n boot?: LazyBootConfig\n autoShowBanner?: boolean\n /** Defaults to the configured name (plus `ACM_openConsent` with `names.legacy`). */\n openConsentGlobalKey?: string\n}\n\n/** Boots analytics, sends page views on navigation and provides the state for your consent UI. */\nexport function AnalyticsProvider({\n analytics,\n children,\n routeKey = 'default',\n page,\n boot,\n autoShowBanner,\n openConsentGlobalKey,\n}: AnalyticsProviderProps) {\n const [controller] = useState(() =>\n createConsentController(analytics, { boot, autoShowBanner, openConsentGlobalKey }),\n )\n const state = useSyncExternalStore(controller.subscribe, controller.getSnapshot, controller.getSnapshot)\n const value = useMemo<ConsentControllerValue>(() => ({ ...controller.actions, ...state }), [controller, state])\n\n useEffect(() => controller.start(), [controller])\n useEffect(() => controller.setRoute(routeKey, page), [controller, routeKey, page])\n\n return (\n <AnalyticsContext.Provider value={analytics}>\n <ConsentControllerContext.Provider value={value}>{children}</ConsentControllerContext.Provider>\n </AnalyticsContext.Provider>\n )\n}\n\n/** The instance from `<AnalyticsProvider>`, else the one `createAnalytics()` made. */\nexport function useAnalytics(): Analytics {\n const analytics = useContext(AnalyticsContext) ?? latestAnalytics()\n if (!analytics) throw new Error('useAnalytics needs createAnalytics() to have run, or an AnalyticsProvider above it')\n return analytics\n}\n\n/** Current consent, re-rendering when it changes. */\nexport function useConsent(): {\n consent: ConsentState | null\n engine: ConsentApi\n setConsent: (consent: ConsentState) => Promise<void>\n update: (partial: Partial<ConsentState>) => Promise<void>\n} {\n const analytics = useAnalytics()\n const consent = useSyncExternalStore(\n (listener) => analytics.consent.subscribe(listener),\n () => analytics.consent.getConsent(),\n () => analytics.consent.getConsent(),\n )\n return {\n consent,\n engine: analytics.consent,\n setConsent: (next) => analytics.consent.setConsent(next),\n update: (partial) => analytics.consent.update(partial),\n }\n}\n\n/** State and actions for building your own consent UI. */\nexport function useConsentController(): ConsentControllerValue {\n const value = useContext(ConsentControllerContext)\n if (!value) throw new Error('useConsentController must be used within AnalyticsProvider')\n return value\n}\n"]}
@@ -0,0 +1,14 @@
1
+ // src/core/noscript.ts
2
+ var metaNoscriptSrc = (pixelId) => `https://www.facebook.com/tr?id=${encodeURIComponent(pixelId)}&ev=PageView&noscript=1`;
3
+ var gtmNoscriptSrc = (containerId) => `https://www.googletagmanager.com/ns.html?id=${encodeURIComponent(containerId)}`;
4
+ var entities = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
5
+ var escapeAttribute = (value) => String(value).replace(/[&"<>]/g, (char) => entities[char]);
6
+ var attributes = (attrs) => Object.entries(attrs).filter(
7
+ ([name, value]) => /^[\w:-]+$/.test(name) && value != null && value !== false && typeof value !== "function"
8
+ ).map(([name, value]) => value === true ? name : `${name}="${escapeAttribute(value)}"`).join(" ");
9
+ var metaNoscriptImg = (pixelId, attrs) => `<img ${attributes({ height: 1, width: 1, style: "display:none", ...attrs, alt: "", src: metaNoscriptSrc(pixelId) })}>`;
10
+ var gtmNoscriptIframe = (containerId, attrs) => `<iframe ${attributes({ title: "Google Tag Manager", height: 0, width: 0, style: "display:none;visibility:hidden", ...attrs, src: gtmNoscriptSrc(containerId) })}></iframe>`;
11
+
12
+ export { gtmNoscriptIframe, gtmNoscriptSrc, metaNoscriptImg, metaNoscriptSrc };
13
+ //# sourceMappingURL=chunk-VIIGBALD.js.map
14
+ //# sourceMappingURL=chunk-VIIGBALD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/noscript.ts"],"names":[],"mappings":";AAAO,IAAM,kBAAkB,CAAC,OAAA,KAC9B,CAAA,+BAAA,EAAkC,kBAAA,CAAmB,OAAO,CAAC,CAAA,uBAAA;AAExD,IAAM,iBAAiB,CAAC,WAAA,KAC7B,CAAA,4CAAA,EAA+C,kBAAA,CAAmB,WAAW,CAAC,CAAA;AAEhF,IAAM,QAAA,GAAmC,EAAE,GAAA,EAAK,OAAA,EAAS,KAAK,QAAA,EAAU,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,MAAA,EAAO;AACjG,IAAM,eAAA,GAAkB,CAAC,KAAA,KAAmB,MAAA,CAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,SAAA,EAAW,CAAC,IAAA,KAAS,QAAA,CAAS,IAAI,CAAC,CAAA;AAErG,IAAM,aAAa,CAAC,KAAA,KAClB,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CACjB,MAAA;AAAA,EACC,CAAC,CAAC,IAAA,EAAM,KAAK,MAAM,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,IAAK,KAAA,IAAS,IAAA,IAAQ,KAAA,KAAU,KAAA,IAAS,OAAO,KAAA,KAAU;AACpG,CAAA,CACC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAA,KAAO,UAAU,IAAA,GAAO,IAAA,GAAO,CAAA,EAAG,IAAI,KAAK,eAAA,CAAgB,KAAK,CAAC,CAAA,CAAA,CAAI,CAAA,CACtF,KAAK,GAAG,CAAA;AAGN,IAAM,eAAA,GAAkB,CAAC,OAAA,EAAiB,KAAA,KAC/C,QAAQ,UAAA,CAAW,EAAE,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAO,CAAA,EAAG,OAAO,cAAA,EAAgB,GAAG,OAAO,GAAA,EAAK,EAAA,EAAI,KAAK,eAAA,CAAgB,OAAO,CAAA,EAAG,CAAC,CAAA,CAAA;AAE/G,IAAM,iBAAA,GAAoB,CAAC,WAAA,EAAqB,KAAA,KACrD,WAAW,UAAA,CAAW,EAAE,KAAA,EAAO,oBAAA,EAAsB,MAAA,EAAQ,CAAA,EAAG,OAAO,CAAA,EAAG,KAAA,EAAO,kCAAkC,GAAG,KAAA,EAAO,KAAK,cAAA,CAAe,WAAW,CAAA,EAAG,CAAC,CAAA,UAAA","file":"chunk-VIIGBALD.js","sourcesContent":["export const metaNoscriptSrc = (pixelId: string) =>\n `https://www.facebook.com/tr?id=${encodeURIComponent(pixelId)}&ev=PageView&noscript=1`\n\nexport const gtmNoscriptSrc = (containerId: string) =>\n `https://www.googletagmanager.com/ns.html?id=${encodeURIComponent(containerId)}`\n\nconst entities: Record<string, string> = { '&': '&amp;', '\"': '&quot;', '<': '&lt;', '>': '&gt;' }\nconst escapeAttribute = (value: unknown) => String(value).replace(/[&\"<>]/g, (char) => entities[char])\n\nconst attributes = (attrs: Record<string, unknown>) =>\n Object.entries(attrs)\n .filter(\n ([name, value]) => /^[\\w:-]+$/.test(name) && value != null && value !== false && typeof value !== 'function',\n )\n .map(([name, value]) => (value === true ? name : `${name}=\"${escapeAttribute(value)}\"`))\n .join(' ')\n\n// Browsers with JavaScript parse `<noscript>` content as text, so it hydrates only as an HTML string.\nexport const metaNoscriptImg = (pixelId: string, attrs: Record<string, unknown>) =>\n `<img ${attributes({ height: 1, width: 1, style: 'display:none', ...attrs, alt: '', src: metaNoscriptSrc(pixelId) })}>`\n\nexport const gtmNoscriptIframe = (containerId: string, attrs: Record<string, unknown>) =>\n `<iframe ${attributes({ title: 'Google Tag Manager', height: 0, width: 0, style: 'display:none;visibility:hidden', ...attrs, src: gtmNoscriptSrc(containerId) })}></iframe>`\n"]}
@@ -0,0 +1,47 @@
1
+ import { k as ConsentCategory, n as PageViewPayload, o as LazyBootConfig, m as Analytics } from './types-BV_AFZKQ.js';
2
+
3
+ type Prefs = Record<ConsentCategory, boolean>;
4
+ /** The state your consent UI renders. */
5
+ type ConsentControllerState = {
6
+ ready: boolean;
7
+ error: string | null;
8
+ bannerVisible: boolean;
9
+ dialogVisible: boolean;
10
+ /** The categories the dialog shows, from `analytics.consent.categories`. */
11
+ categories: readonly ConsentCategory[];
12
+ /** Whether the browser's Global Privacy Control signal is honored: `acceptAll` then leaves marketing off. */
13
+ gpc: boolean;
14
+ /** The dialog's toggles, one per category in `analytics.consent.categories`. */
15
+ prefs: Prefs;
16
+ };
17
+ /** Actions for your consent UI. */
18
+ type ConsentControllerActions = {
19
+ setPrefs: (next: Prefs) => void;
20
+ showBanner: () => void;
21
+ hideBanner: () => void;
22
+ openDialog: () => void;
23
+ closeDialog: () => void;
24
+ acceptAll: () => Promise<void>;
25
+ rejectNonEssential: () => Promise<void>;
26
+ savePreferences: () => Promise<void>;
27
+ };
28
+ type ConsentControllerOptions = {
29
+ /** When providers load. Defaults to `{ mode: 'immediate' }`. */
30
+ boot?: LazyBootConfig;
31
+ autoShowBanner?: boolean;
32
+ /** Defaults to the configured name (plus `ACM_openConsent` with `names.legacy`). */
33
+ openConsentGlobalKey?: string;
34
+ };
35
+ type ConsentController = {
36
+ actions: ConsentControllerActions;
37
+ getSnapshot: () => ConsentControllerState;
38
+ subscribe: (listener: () => void) => () => void;
39
+ /** Bootstraps consent, schedules boot and starts sending page views. Returns a function that stops it. */
40
+ start: () => () => void;
41
+ /** Changes on every navigation; a page view is sent once per key. `null` holds page views until the route is known. */
42
+ setRoute: (routeKey: string | null, page?: PageViewPayload) => void;
43
+ };
44
+ /** Boots `analytics`, sends a page view per route and holds the state of a consent banner and settings dialog. */
45
+ declare function createConsentController(analytics: Analytics, { boot, autoShowBanner, openConsentGlobalKey }?: ConsentControllerOptions): ConsentController;
46
+
47
+ export { type ConsentControllerState as C, type ConsentControllerActions as a, type ConsentControllerOptions as b, type ConsentController as c, createConsentController as d };
@@ -0,0 +1,20 @@
1
+ "use strict";(()=>{var L={title:"Cookies",message:"We use cookies to run this site and, with your consent, for preferences, analytics and marketing.",privacyPolicy:"Privacy policy",gpc:"Your browser's Global Privacy Control signal is on, so marketing is off unless you switch it on.",rejectNonEssential:"Reject non-essential",customize:"Customize",acceptAll:"Accept all",settingsTitle:"Cookie settings",necessaryLabel:"Necessary",necessaryDescription:"Needed for the site to work, such as remembering this choice. Always on.",preferencesLabel:"Preferences",preferencesDescription:"Remember settings such as language or region.",analyticsLabel:"Analytics",analyticsDescription:"Help us understand how the site is used.",marketingLabel:"Marketing",marketingDescription:"Measure our ads and show relevant ones on other sites.",close:"Close",save:"Save"},w=`
2
+ .consentlayer-banner,.consentlayer-dialog[open]{display:grid;gap:.75rem;box-sizing:border-box;padding:1.25rem;
3
+ border:1px solid var(--consentlayer-border,#e5e7eb);border-radius:var(--consentlayer-radius,.75rem);
4
+ background:var(--consentlayer-background,#fff);color:var(--consentlayer-color,#111827);
5
+ box-shadow:0 10px 30px rgb(0 0 0/.12);font:var(--consentlayer-font,.95rem/1.45 system-ui,sans-serif)}
6
+ .consentlayer-banner{position:fixed;z-index:var(--consentlayer-z-index,1000);inset:auto 1rem 1rem;max-width:40rem;margin-inline:auto}
7
+ .consentlayer-banner[hidden]{display:none}
8
+ .consentlayer-dialog{width:min(30rem,calc(100vw - 2rem))}
9
+ .consentlayer-dialog::backdrop{background:var(--consentlayer-backdrop,rgb(0 0 0/.3))}
10
+ .consentlayer-banner h2,.consentlayer-dialog h2{margin:0;color:inherit;font-size:1.1rem}
11
+ .consentlayer-banner p{margin:0}
12
+ .consentlayer-banner a{color:inherit}
13
+ .consentlayer-dialog label{display:flex;gap:.6rem;align-items:start}
14
+ .consentlayer-dialog input{margin-top:.3rem;accent-color:var(--consentlayer-accent,#111827)}
15
+ .consentlayer-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:.5rem}
16
+ .consentlayer-actions button{padding:.5rem .9rem;border:1px solid var(--consentlayer-border,#e5e7eb);
17
+ border-radius:var(--consentlayer-button-radius,.5rem);background:transparent;color:inherit;font:inherit;cursor:pointer}
18
+ .consentlayer-actions .consentlayer-primary{border-color:var(--consentlayer-accent,#111827);
19
+ background:var(--consentlayer-accent,#111827);color:var(--consentlayer-accent-color,#fff)}
20
+ .consentlayer-banner :focus-visible,.consentlayer-dialog :focus-visible{outline:2px solid var(--consentlayer-accent,#111827);outline-offset:2px}`;function E(e,i){let p={...e?.text},s=e?.privacyPolicyUrl,n=i instanceof HTMLScriptElement?i.dataset:{};for(let[r,y]of Object.entries(n))y!==void 0&&(r==="privacyPolicyUrl"?s=y:/^text[A-Z]/.test(r)&&(p[r[4].toLowerCase()+r.slice(5)]=y));return{privacyPolicyUrl:s,text:p}}function t(e,i={},...p){let s=document.createElement(e);for(let[n,r]of Object.entries(i))s.setAttribute(n,r);return s.append(...p),s}function P(e,{privacyPolicyUrl:i,text:p}={},s=""){let n={...L,...p},r=(a,l,o=!1)=>{let d=t("button",{type:"button",...o&&{class:"consentlayer-primary"}},a);return d.addEventListener("click",()=>{e.actions[l]()}),d},y=(...a)=>t("div",{class:"consentlayer-actions"},...a),b=(a,l,o)=>t("label",{},o,t("span",{},t("strong",{},a),` ${l}`)),f=t("style",s?{nonce:s}:{},w),g=t("section",{class:"consentlayer-banner",role:"dialog","aria-labelledby":"consentlayer-banner-title",hidden:""},t("h2",{id:"consentlayer-banner-title"},n.title),t("p",{},n.message,...i?[" ",t("a",{href:i},n.privacyPolicy)]:[]),...e.getSnapshot().gpc?[t("p",{class:"consentlayer-gpc"},n.gpc)]:[],y(r(n.rejectNonEssential,"rejectNonEssential"),r(n.customize,"openDialog"),r(n.acceptAll,"acceptAll",!0))),x=t("input",{type:"checkbox",checked:"",disabled:""}),m=t("div",{class:"consentlayer-categories"}),c=t("dialog",{class:"consentlayer-dialog","aria-labelledby":"consentlayer-dialog-title"},t("h2",{id:"consentlayer-dialog-title"},n.settingsTitle),b(n.necessaryLabel,n.necessaryDescription,x),m,y(r(n.close,"closeDialog"),r(n.save,"savePreferences",!0))),k=()=>{let{categories:a,prefs:l}=e.getSnapshot();m.replaceChildren(...a.map(o=>{let d=t("input",{type:"checkbox"});return d.checked=l[o],d.addEventListener("change",()=>e.actions.setPrefs({...e.getSnapshot().prefs,[o]:d.checked})),b(n[`${o}Label`]??o,n[`${o}Description`]??"",d)}))},v=()=>{let{ready:a,bannerVisible:l,dialogVisible:o}=e.getSnapshot();g.hidden=!a||!l,o&&!c.open&&(k(),c.showModal()),!o&&c.open&&c.close()};c.addEventListener("close",()=>e.actions.closeDialog()),document.head.append(f),document.body.prepend(g,c);let C=e.subscribe(v);return v(),()=>{C(),f.remove(),g.remove(),c.remove()}}var h=document.currentScript,u=()=>{let e=window.ConsentLayer;!e||!("controller"in e)?addEventListener("consentlayer:ready",u,{once:!0}):document.readyState==="loading"?document.addEventListener("DOMContentLoaded",u,{once:!0}):P(e.controller,E(e.banner,h),h?.nonce)};u();})();
@@ -0,0 +1,9 @@
1
+ "use strict";(()=>{var Zt=Object.defineProperty;var X=(e,t)=>()=>(e&&(t=e(e=0)),t);var be=(e,t)=>{for(var n in t)Zt(e,n,{get:t[n],enumerable:!0})};function ve(e,t){let n=e.toUpperCase();return{prefix:e,legacy:t,consentStorageKey:`${e}_consent`,identityStorageKey:`${e}_user_identity`,consentEventName:`${e}:consent`,consentGlobalKey:`${n}_CONSENT`,openConsentGlobalKey:`${n}_openConsent`,autoTrackingEvents:{pageSessionStart:`${e}.page_session_start`,scrollDepth:`${e}.scroll_depth`,timeOnPage:`${e}.time_on_page`,uiClick:`${e}.ui_click`}}}function He(e={}){let t=ve(e.prefix??Be,e.legacy??!1),n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));return U={...t,...n,autoTrackingEvents:{...t.autoTrackingEvents,...e.autoTrackingEvents}},U}function F(){return U}function he(e){return U.legacy?e===U.consentStorageKey&&e!==K.consentStorageKey?[K.consentStorageKey]:e===U.identityStorageKey&&e!==K.identityStorageKey?[K.identityStorageKey]:[]:[]}function oe(e){let t=e(U),n=e(K);return U.legacy&&n!==t?[t,n]:[t]}function T(e){if(typeof window>"u")return;let t=window;return t[`__${U.prefix}${e}`]??(U.legacy?t[`__${K.prefix}${e}`]:void 0)}function R(e,t){if(typeof window>"u")return t;let n=window;return n[`__${U.prefix}${e}`]=t,U.legacy&&(n[`__${K.prefix}${e}`]=t),t}var Be,K,U,Z=X(()=>{"use strict";Be="consentlayer";K=ve("acm",!1),U=ve(Be,!1)});function j(e,t){return{id:e,requiredConsent:"none",setup:n=>n.log(`${e} is off: ${t} is not set.`)}}function x(e,t={}){if(typeof document>"u")return Promise.resolve();let n=new URL(e,document.baseURI).href,r=Ce.get(n);if(r)return r;if([...document.scripts].some(a=>a.src===n))return Promise.resolve();let d=new Promise((a,c)=>{let o=document.createElement("script");o.async=!0,o.src=n;for(let[i,u]of Object.entries(t))o.setAttribute(i,u);o.onload=()=>a(),o.onerror=()=>{o.remove(),Ce.delete(n),c(new Error(`Failed to load ${e}`))},document.head.appendChild(o)});return Ce.set(n,d),d}var Ce,L=X(()=>{"use strict";Z();Ce=new Map});function Pt(e="https://us.i.posthog.com"){Et=e.replace(".i.posthog.com","-assets.i.posthog.com").replace(/\/$/,"")}var Et,le,ue=X(()=>{"use strict";Et="https://us-assets.i.posthog.com";le=e=>`${Et}/static/${e}.js`});var At={};be(At,{then:()=>_n});function _n(e,t){x(le("lazy-recorder")).then(()=>e({}),t)}var Tt=X(()=>{"use strict";L();ue()});var xt={};be(xt,{then:()=>In});function In(e,t){x(le("array")).then(()=>e({default:window.posthog}),t)}var Ot=X(()=>{"use strict";L();ue()});var fe={};be(fe,{then:()=>Pn});function Pn(e,t){x(En,{crossorigin:"anonymous"}).then(()=>e(window.Sentry),t)}var En,pe=X(()=>{"use strict";L();En="https://browser.sentry-cdn.com/11.7.0/bundle.tracing.replay.min.js"});L();var ke=e=>({ad_user_data:e?.marketing?"granted":"denied",ad_personalization:e?.marketing?"granted":"denied",ad_storage:e?.marketing?"granted":"denied",analytics_storage:e?.analytics?"granted":"denied",functionality_storage:e?.preferences?"granted":"denied",security_storage:"granted"}),Qt=/^[A-Z]{2}(-[A-Z0-9]{1,3})?$/;function re(){window.dataLayer=window.dataLayer??[],window.gtag=window.gtag??function(){window.dataLayer?.push(arguments)}}function Se(e={}){let{regions:t=[],waitForUpdate:n,urlPassthrough:r,adsDataRedaction:d}=e;for(let{region:i}of t)if(!i.length||!i.every(u=>Qt.test(u)))throw new Error(`[consentlayer] googleConsentMode regions: ${JSON.stringify(i)} is not a list of ISO 3166-2 codes such as 'US' or 'US-CA'`);if(n!==void 0&&!(Number.isInteger(n)&&n>=0))throw new Error(`[consentlayer] googleConsentMode waitForUpdate must be a whole number of milliseconds, received ${n}`);let a=n===void 0?{}:{wait_for_update:n},c=!1,o;return i=>{if(typeof window>"u")return;re();let u=window.gtag;if(!c){c=!0,u("consent","default",{...ke(null),...a});for(let{region:y,...v}of t)u("consent","default",{...ke(v),...a,region:y});r&&u("set","url_passthrough",!0),d&&u("set","ads_data_redaction",!0)}let p=ke(i);(i||o)&&JSON.stringify(p)!==o&&(u("consent","update",p),o=JSON.stringify(p))}}function Q(e){(T("BuiltInConsentMode")??R("BuiltInConsentMode",Se()))(e)}L();function Fe(e={}){let t=Se(e);return{id:"google-consent-mode",observe(n){R("GoogleConsentMode",!0),t(n)}}}L();function de(e,t=!1){if(typeof e=="boolean")return e;if(typeof e=="string"){let n=e.toLowerCase();if(["granted","allow","accepted","yes","true"].includes(n))return!0;if(["denied","reject","refused","no","false"].includes(n))return!1}return t}async function Ve(e,t,n){t&&(n&&!e.Shopify?.customerPrivacy&&await x(Yt()),e.Shopify?.loadFeatures&&await new Promise(r=>{e.Shopify?.loadFeatures?.([{name:"consent-tracking-api",version:"0.1"}],()=>r())}))}function Ke(e={}){let t=e.document??(typeof document<"u"?document:void 0),n=e.window??(typeof window<"u"?window:void 0),r=!!e.headlessStorefront?.storefrontAccessToken;return{id:"shopify-customer-privacy",async bootstrap(){if(!n||!t||e.canBootstrap&&!e.canBootstrap())return null;await Ve(n,e.loadFeature??!0,r);let d=n.Shopify?.customerPrivacy?.currentVisitorConsent?.();return!d||!Object.values(d).some(c=>typeof c=="string"&&c.length>0)?null:{preferences:de(d.preferences),analytics:de(d.analytics),marketing:de(d.marketing),...d.sale_of_data?{sale_of_data:de(d.sale_of_data)}:{}}},async apply(d){if(!n)return;await Ve(n,e.loadFeature??!0,r);let a={preferences:d.preferences,analytics:d.analytics,marketing:d.marketing,...typeof d.sale_of_data=="boolean"?{sale_of_data:d.sale_of_data}:{},...r?{headlessStorefront:!0,...e.headlessStorefront}:{}},c=n.Shopify?.customerPrivacy?.setTrackingConsent;c&&await new Promise(o=>c(a,o))},subscribe(d){if(!t)return()=>{};let a=c=>{let o=c.detail,i={marketing:!!o?.marketingAllowed,analytics:!!o?.analyticsAllowed,preferences:!!o?.preferencesAllowed,...typeof o?.saleOfDataAllowed=="boolean"?{sale_of_data:o.saleOfDataAllowed}:{}};d(i)};return t.addEventListener("visitorConsentCollected",a),()=>t.removeEventListener("visitorConsentCollected",a)}}}function Yt(){return"https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.1/consent-tracking-api.js"}var en={preferences:[1],analytics:[1,8],marketing:[1,2,3,4,7]};function ze(e,t){let n,r=!1,d=()=>e("removeEventListener",2,()=>{},n);return e("addEventListener",2,(a,c)=>{c&&a&&(n=a.listenerId),!r&&t(c&&a?a:null)&&(r=!0),r&&n!==void 0&&d()}),()=>{r=!0,n!==void 0&&d()}}function We(e={}){let t=e.window??(typeof window<"u"?window:void 0),n={...en,...e.purposes},r=e.timeout??5e3;if(!(r>=0&&Number.isFinite(r)))throw new Error(`[consentlayer] tcf timeout must be a non-negative number, received ${r}`);let d=a=>Object.fromEntries(Object.entries(n).map(([c,o])=>[c,o.length>0&&o.every(i=>a.purpose?.consents?.[i]===!0)]));return{id:"tcf",authoritative:!0,bootstrap(){let a=t?.__tcfapi;return a?new Promise((c,o)=>{let i=setTimeout(()=>{u(),o(new Error(`[consentlayer] The TCF CMP did not answer within ${r} ms`))},r),u=ze(a,p=>(clearTimeout(i),c(p?.gdprApplies===!0?d(p):null),!0))}):null},subscribe(a){let c=t?.__tcfapi;if(c)return ze(c,o=>{o?.gdprApplies===!0&&a(d(o))})}}}Z();var tn=["button",'[role="button"]',"a",'input[type="submit"]','input[type="button"]'],nn=[25,50,75,100],on=[5,15,30,60,120];function Je(e={}){let{clicks:t,scroll:n,timeOnPage:r,pageViews:d,only:a}=e,c=[t,n,r,d].some(u=>u!=null&&u!==!1),o=u=>u==null?!c:u!==!1,i=u=>typeof u=="object"?u:{};return({track:u,signal:p})=>{let y=(S,g)=>{u(S,g,{only:a,requireAnalyticsConsent:!0})},v=0,h=new AbortController;if(p.addEventListener("abort",()=>h.abort()),o(t)){let{mode:S="all",attribute:g="data-track",selectors:C=tn}=i(t),E=S==="attribute"?`[${g}]`:C.join(", "),A=O=>{let f=E?O.target?.closest(E):null;f instanceof HTMLElement&&y(F().autoTrackingEvents.uiClick,{ui_target:f.getAttribute(g)||f.getAttribute("aria-label")||"unknown",ui_element:f.tagName.toLowerCase(),ui_id:f.id||void 0,path:window.location.pathname,session_id:v})};window.addEventListener("click",A,{signal:p})}return()=>{h.abort(),h=new AbortController;let S=h.signal,g=++v;if(o(d)&&y(F().autoTrackingEvents.pageSessionStart,{session_id:g}),o(n)){let C=(i(n).thresholds??nn).filter(O=>Number.isFinite(O)&&O>0&&O<=100).sort((O,f)=>O-f),E=new Set,A=()=>{let O=document.documentElement,f=O.scrollHeight-window.innerHeight;if(f<=0)return;let _=Math.round(Math.min(1,(window.scrollY||O.scrollTop)/f)*100);for(let P of C)_<(P===100?95:P)||E.has(P)||(E.add(P),y(F().autoTrackingEvents.scrollDepth,{depth:P,session_id:g}));E.size===C.length&&window.removeEventListener("scroll",A)};window.addEventListener("scroll",A,{passive:!0,signal:S})}if(o(r))for(let C of i(r).intervals??on){if(!Number.isFinite(C)||C<=0)continue;let E=window.setTimeout(()=>y(F().autoTrackingEvents.timeOnPage,{seconds:C,session_id:g}),C*1e3);S.addEventListener("abort",()=>window.clearTimeout(E))}}}}Z();var rn=/^G-[A-Z0-9]{4,16}$/,an=/^\d{8,20}$/,sn=/^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/,dn=/^\+?[1-9]\d{6,14}$/;function cn(e){return typeof e=="string"&&rn.test(e)}function Xe(e){if(!cn(e))throw new Error(`[consentlayer] Invalid GA4 measurement ID: expected format "G-XXXXXXXX", received ${_e(e)}.`);return e}function ln(e){return typeof e=="string"&&an.test(e)}function Ze(e){if(!ln(e))throw new Error(`[consentlayer] Invalid Meta Pixel ID: expected 8-20 digit numeric string, received ${_e(e)}.`);return e}function un(e){if(typeof e!="string"||e.length===0)return!1;if(e.startsWith("/"))return!e.startsWith("//");try{return new URL(e).protocol==="https:"}catch{return!1}}function B(e,t){if(!un(e))throw new Error(`[consentlayer] ${t} must be an HTTPS URL or a relative path starting with "/", received ${_e(e)}.`);return e}function Qe(e){return typeof e=="string"&&sn.test(e)}function Ye(e){return typeof e=="string"&&dn.test(e)}function et(e,t=["preferences","analytics","marketing"]){let n=e;if(!(typeof n=="object"&&n!==null&&t.every(d=>typeof n[d]=="boolean")&&(n.sale_of_data===void 0||typeof n.sale_of_data=="boolean")))throw new TypeError(`[consentlayer] consent must have boolean ${t.slice(0,-1).join(", ")} and ${t.at(-1)}, received ${JSON.stringify(e)??"undefined"}.`)}function _e(e){return e===null?"null":e===void 0?"undefined":typeof e=="string"?e.length>32?`string(length=${e.length})`:`"${e}"`:typeof e}function H(){return typeof window<"u"&&typeof document<"u"}var Ie=["preferences","analytics","marketing"];function tt(e,t=Ie){return e?{...Object.fromEntries(t.map(n=>[n,!!e[n]])),...typeof e.sale_of_data=="boolean"?{sale_of_data:e.sale_of_data}:{}}:null}function nt(e,t){return JSON.stringify(e)===JSON.stringify(t)}function Ee(e,t){return t==="none"?!0:!t||!e?!1:typeof t=="function"?t(e):!!e[t]}function z(e){let t={};if(e.email){let r=e.email.trim().toLowerCase();Qe(r)&&(t.email=r)}if(e.phone){let r=e.phone.replace(/[\s\-().]/g,"");Ye(r)&&(t.phone=r)}let n=e.userId??e.external_id;return n&&(t.userId=String(n)),t}function Pe(){try{return globalThis.crypto?.randomUUID?.()??Math.random().toString(36).slice(2)}catch{return Math.random().toString(36).slice(2)}}function D(e){let t=location.hostname.split(".").map((n,r,d)=>d.slice(r).join("."));for(let n of document.cookie.split(";")){let r=n.split("=")[0]?.trim();if(!(!r||!e(r)))for(let d of["",...t.map(a=>`; domain=${a}`)])document.cookie=`${r}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/${d}`}}function Ae(){return H()?{url:window.location.href,path:window.location.pathname+window.location.search,title:document.title}:{}}function ot(e){let t={};for(let[n,r]of Object.entries(e))r==null?t[n]=null:typeof r=="string"||typeof r=="number"||typeof r=="boolean"?t[n]=r:r instanceof Date&&(t[n]=r.toISOString());return t}function rt(e,t={}){let n=t.document??(typeof document<"u"?document:void 0),r=t.window??(typeof window<"u"?window:void 0);if(r)for(let d of[t.globalKey??[]].flat())r[d]=e;if(n)for(let d of[t.eventName??[]].flat())n.dispatchEvent(new CustomEvent(d,{detail:e}))}var fn=["consent","events","providers","errors"];function ce(e){if(!e)return()=>{};let t=e===!0?{}:e,n=fn.some(r=>t[r]);return(r,d,a,...c)=>{(t[r]??!n)&&(d&&t.only&&!t.only.includes(d)||(t.logger?t.logger({topic:r,provider:d,message:a,data:c}):console.debug("[consentlayer]",a,...c)))}}function Te(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}function it(e){return{read(){return Y(e,t=>pn(Te(dt(t,e))),null)},write(t){Y(e,n=>t?n.setItem(e.key,JSON.stringify(t)):n.removeItem(e.key),void 0)},subscribe(t){let n=e.window??(H()?window:void 0);if(!n)return()=>{};let r=d=>{d.key===e.key&&t()};return n.addEventListener("storage",r),()=>n.removeEventListener("storage",r)},clear(){Y(e,t=>t.removeItem(e.key),void 0)}}}function at(e){return{read(){return Y(e,t=>z(Te(dt(t,e))??{}),{})},write(t){Y(e,n=>n.setItem(e.key,JSON.stringify(z(t))),void 0)},clear(){Y(e,t=>{for(let n of[e.key,...e.legacyKeys??he(e.key)])t.removeItem(n)},void 0)}}}function st(e={}){let t=z(e);return{read(){return t},write(n){t=z(n)},clear(){t={}}}}function pn(e){return!e||typeof e!="object"?null:"consent"in e&&typeof e.consent=="object"?e:{consent:e}}function dt(e,{key:t,legacyKeys:n=he(t)}){let r=e.getItem(t);if(r!==null)return r;for(let d of n){let a=e.getItem(d);if(a!==null)return e.setItem(t,a),e.removeItem(d),a}return null}function Y(e,t,n){try{let r=e.storage??(H()?window.localStorage:void 0);return r?t(r):n}catch{return n}}var gn=new Set(["setup","consent","load","teardown"]),mn={setup:"providers",consent:"providers",load:"providers",teardown:"providers",page:"events",track:"events",identify:"events",group:"events",reset:"events",error:"errors"},ct=["pointerdown","keydown","scroll","touchstart"];function yn(e,t){return H()?new Promise(n=>{if(typeof e=="number")window.setTimeout(n,e);else if(e==="idle")typeof window.requestIdleCallback=="function"?window.requestIdleCallback(()=>n(),{timeout:5e3}):window.setTimeout(n,1);else{let r=()=>{for(let d of ct)window.removeEventListener(d,r);n()};for(let d of ct)window.addEventListener(d,r,{once:!0,passive:!0,signal:t})}}):Promise.resolve()}function lt(e={}){if(e.autoTracking!==void 0&&typeof e.autoTracking!="function")throw new Error("[consentlayer] autoTracking must be autoTracking() from consentlayer/auto-tracking");let t=ce(e.debug),n=new Set,r=new Map,d=e.identityStorage??st(),a=e.consent??e.consentEngine?.getConsent()??null,c=d.read(),o=c.userId?{userId:c.userId}:{},i=c.email||c.phone?c:void 0,u=()=>{!i||!a||(a.marketing&&o.userId===i.userId&&(o={...i,...o}),i=void 0)};u();let p=[],y=!1,v=!1,h=!1,S=!1,g=new AbortController,C=Promise.resolve(),E,A,O=()=>({booted:y,consent:a,activeProviders:[...r.values()].filter(s=>s.active).map(s=>s.plugin.id)}),f=O(),_=()=>{f=O()},P=()=>{_(),n.forEach(s=>s(f))},k=()=>typeof e.enabled=="function"?e.enabled():typeof e.enabled=="boolean"?e.enabled:!0,q=s=>{t("errors",s.providerId,`[${s.scope}] ${s.message}`,s.cause);try{e.onError?.(s)}catch(l){t("errors",void 0,"onError handler threw",l)}},I=new WeakSet,G=(s,l,m)=>{s.length<100?s.push(l):I.has(s)||(I.add(s),q({scope:"queue-full",providerId:m,message:`100 calls are already waiting ${m?`for ${m} to load`:"for boot"}; later ones are dropped`}))},Ht=s=>l=>q({...l,providerId:l.providerId??s}),ee=e.server?.endpoint?B(e.server.endpoint,"server.endpoint"):void 0,me=e.server?.consentEndpoint?B(e.server.consentEndpoint,"server.consentEndpoint"):void 0,Oe=!1,Ft=()=>{!me||Oe||(Oe=!0,fetch(me,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({consent:a,restored:!0})}).then(s=>{if(!s.ok)throw new Error(`HTTP ${s.status}`)}).catch(s=>q({scope:"server-forward",message:`Restoring the consent cookie at ${me} failed`,cause:s})))},Vt=s=>{if(!ee||!(a?.analytics||a?.marketing))return;let l=JSON.stringify({...s,consent:a,identity:V()}),m=w=>q({scope:"server-forward",message:`Sending ${s.name} to ${ee} failed`,cause:w});if(typeof fetch!="function"){navigator.sendBeacon(ee,new Blob([l],{type:"application/json"}))||m(void 0);return}fetch(ee,{method:"POST",keepalive:!0,headers:{"content-type":"application/json"},body:l}).then(w=>{if(!w.ok)throw new Error(`HTTP ${w.status}`);w.headers.get("consentlayer-forwarding")==="off"&&(ee=void 0),w.headers.get("consentlayer-consent")==="missing"&&Ft()}).catch(m)},V=()=>a?.marketing?o:o.userId?{userId:o.userId}:{},Re=()=>{let s=V();Object.keys(s).length&&(a?.analytics||a?.marketing)?d.write(s):d.clear?.()},Kt=s=>({consent:a,identity:V(),debug:!!e.debug,log:(l,...m)=>t("providers",s,l,...m),emitError:Ht(s)}),$=async(s,l,m,...w)=>{if(S)return!1;let{plugin:b}=s;if(s.backlog&&!gn.has(l))return G(s.backlog,()=>$(s,l,m,...w),b.id),!!b[l];b[l]&&t(mn[l],b.id,`${b.id}.${l}`,...w);try{await m(b,Kt(b.id))}catch(M){q({scope:l==="reset"||l==="group"?"provider-identify":`provider-${l}`,providerId:b.id,message:`${b.id}.${l} failed`,cause:M})}return!!b[l]},je=s=>{let l=r.get(s.id);if(l)return l.plugin!==s&&q({scope:"provider-setup",providerId:s.id,message:`Another provider already uses the id "${s.id}"; this one is ignored`}),l;let m={plugin:s,setup:!1,loaded:!1,active:!1};return r.set(s.id,m),m},se=async s=>{s.active&&(s.active=!1,await $(s,"teardown",(l,m)=>l.teardown?.(m)))},qe=async s=>{s.setup||(s.setup=!0,await $(s,"setup",(l,m)=>l.setup?.(m)))},zt=async s=>{if(!y||!k())return se(s);let{plugin:l}=s,m=Ee(a,l.requiredConsent);if(await qe(s),await $(s,"consent",(w,b)=>w.consent?.(b)),!s.loaded&&(m||l.loadBeforeConsent)&&(s.loaded=!0,l.defer?Wt(s,l.defer):await $(s,"load",(w,b)=>w.load?.(b))),!m)return se(s);s.active||(s.active=!0,Object.keys(V()).length&&!h&&await $(s,"identify",(w,b)=>w.identify?.(V(),{},b)))},Wt=(s,l)=>{s.backlog=[],yn(l,g.signal).then(()=>{C=C.then(async()=>{let m=s.backlog??[];if(s.backlog=void 0,!s.active&&!s.plugin.loadBeforeConsent){s.loaded=!1;return}await $(s,"load",(w,b)=>w.load?.(b));for(let w of m)s.active&&await w()})})},Jt=async()=>{let s=a;for(let l of r.values())await zt(l);if(e.autoTracking&&!A&&y&&s?.analytics&&H()){A=()=>{};try{A=e.autoTracking({track:ne.track,signal:g.signal}),A()}catch(l){q({scope:"auto-tracking",message:"Auto-tracking failed to start",cause:l})}}P()},ye=async()=>{C=C.then(Jt),await C},we=s=>s==="captureError"?"errors":"events",te=async(s,l,m,w)=>{if(!S){if(!k())return t(we(s),void 0,`${s} dropped: enabled is false`);if(!v){t(we(s),void 0,`${s} held until boot`),G(p,()=>$e(s,l,m,w));return}await $e(s,l,m,w)}},$e=async(s,l,m,w)=>{if(S)return;let b=w?.();b&&Vt(b);let M=0;for(let N of r.values())N.active&&Ee(a,N.plugin.requiredConsent)&&(l&&!l.includes(N.plugin.id)||await m(N)&&(M+=1));M||t(we(s),void 0,`${s} reached no provider`)},Le=(s,l)=>te("identify",l,m=>$(m,"identify",(w,b)=>w.identify?.(V(),s,b),s));e.consentEngine&&(E=e.consentEngine.subscribe(({consent:s})=>{ne.updateConsent(s)}));for(let s of e.providers??[]){let l=je(s);H()&&k()&&qe(l)}let Me=e.errors!==!1,Ne=new WeakSet,Ue=s=>{ne.captureError(s.error??s.message,{source:"global",level:"fatal"})},De=s=>{ne.captureError(s.reason,{source:"global"})},Ge=Me&&H()&&!(typeof e.errors=="object"&&e.errors.globalHandlers===!1),ne={async boot(){if(!(S||y)){y=!0,t("providers",void 0,"boot"),Ge&&(window.addEventListener("error",Ue),window.addEventListener("unhandledrejection",De)),await ye();for(let s=p.shift();s;s=p.shift())await s();v=!0,h=!1}},registerProvider(s){let l=je(s);return y?ye():P(),()=>{r.has(s.id)&&(se(l),r.delete(s.id),P())}},async updateConsent(s){let l=!!a?.marketing,m=!!(o.email||o.phone),w=[...r.values()].filter(b=>b.active).map(b=>b.plugin.id);if(a=s,s||(i=void 0),u(),s&&!s.marketing&&(o=o.userId?{userId:o.userId}:{}),Re(),await ye(),!(!m||l===!!s?.marketing))if(l)for(let b of r.values())b.active?await $(b,"identify",(M,N)=>M.identify?.(V(),{},N)):b.setup&&await $(b,"reset",(M,N)=>M.reset?.(N));else w.length&&await Le({},w)},getConsent(){return a},async page(s={},{only:l,server:m}={}){let w={...Ae(),...s,id:Pe()};await te("page",l,b=>$(b,"page",(M,N)=>M.page?.(w,N),w),()=>m===!1?void 0:{id:w.id,name:"page_view",url:w.url,only:m?void 0:l})},async track(s,l,m={}){let w={id:m.eventId??Pe(),name:s,params:l??{},options:m},b=()=>!(m.requireAnalyticsConsent&&!a?.analytics)&&!(m.requireMarketingConsent&&!a?.marketing);await te(s,m.only,async M=>b()&&await $(M,"track",(N,Xt)=>b()?N.track?.(w,Xt):void 0,s,w.params),()=>b()?{id:w.id,name:s,params:w.params,url:Ae().url,only:m.only,providers:m.providers}:void 0)},async identify(s,l={}){s&&s!==o.userId&&(o={}),o={...o,...z({userId:s,email:l.email,phone:l.phone})},Re(),v||(h=!0),await Le(Object.fromEntries(Object.entries(l).filter(([m])=>m!=="email"&&m!=="phone")))},async reset(){o={},i=void 0,d.clear?.();for(let s of r.values())s.setup&&await $(s,"reset",(l,m)=>l.reset?.(m))},async group(s,l={}){await te("group",void 0,m=>$(m,"group",(w,b)=>w.group?.(s,l,b),s,l))},async captureError(s,l={}){if(!Me)return;if(typeof s=="object"&&s!==null){if(Ne.has(s))return;Ne.add(s)}let m={source:"manual",...l};await te("captureError",void 0,w=>$(w,"error",(b,M)=>b.error?.(s,m,M),s))},newPageSession(){try{A?.()}catch(s){q({scope:"auto-tracking",message:"Auto-tracking failed to start a page session",cause:s})}},getSnapshot(){return f},subscribe(s){return n.add(s),()=>n.delete(s)},destroy(){for(let s of r.values())se(s);S=!0,g.abort(),E?.(),Ge&&(window.removeEventListener("error",Ue),window.removeEventListener("unhandledrejection",De)),r.clear(),n.clear()}};return ne}function ut(e={}){let t=ce(e.debug),n=[...Ie,...e.categories??[]],r=f=>tt(f,n),d=r(e.initialConsent),a=new Set,c=new Set,o=e.adapters??[],i=e.storage,u=!1,p,y=e.policyVersion?.trim()||void 0,{maxAgeDays:v}=e;if(v!==void 0&&!(v>0&&Number.isFinite(v)))throw new Error(`[consentlayer] consent.maxAgeDays must be a positive number, received ${v}`);let h=f=>f?.split(".")[0],S=f=>y!==void 0&&h(f.policyVersion)!==h(y)||v!==void 0&&!(typeof f.updatedAt=="number"&&Date.now()-f.updatedAt<=v*864e5),g=!1,C=0,E=()=>{let f={consent:d};a.forEach(_=>_(f))},A=async(f,_,{persist:P,applyAdapters:k,excludeAdapter:q})=>{u||!f||nt(d,f)&&!(P&&g)||(d=f,C++,P&&(g=!1,i?.write({consent:f,updatedAt:Date.now(),policyVersion:y})),rt(f,e.broadcast),t("consent",void 0,"consent updated",_,f),E(),k&&await Promise.all(o.filter(I=>I.apply&&I!==q).map(async I=>{try{await I.apply?.(f)}catch(G){e.onError?.({scope:"consent-adapter",providerId:I.id,message:`Consent adapter "${I.id}" failed to apply consent`,cause:G})}})))};i?.subscribe&&c.add(i.subscribe(()=>{let f=i.read(),_=r(f?.consent);_&&!S(f)&&(g=!1,A(_,"storage",{persist:!1,applyAdapters:!1}))}));for(let f of o){if(!f.observe)continue;let _=P=>{try{f.observe?.(P)}catch(k){e.onError?.({scope:"consent-adapter",providerId:f.id,message:`Consent adapter "${f.id}" failed to observe consent`,cause:k})}};_(d),a.add(({consent:P})=>_(P))}for(let f of o){if(!f.subscribe)continue;let _=f.subscribe(P=>{A(r({...d,...P}),"adapter",{persist:!0,applyAdapters:!0,excludeAdapter:f})});typeof _=="function"&&c.add(_)}let O=async()=>{let f=i?.read()??null,_=r(f?.consent);g=_!==null&&S(f),g&&t("consent",void 0,"stored consent is stale",f);let P=C,k=async I=>{try{return r(await I.bootstrap?.())}catch(G){return e.onError?.({scope:"consent-adapter",providerId:I.id,message:`Consent adapter "${I.id}" failed to read consent`,cause:G}),null}},q=[...o.filter(I=>I.authoritative),void 0,...o.filter(I=>!I.authoritative)];for(let I of q){if(I&&!I.bootstrap)continue;let G=I?await k(I):_&&(!g||e.onStale==="keep")?_:null;if(C!==P)return d;if(G)return await A(G,"bootstrap",{persist:I!==void 0,applyAdapters:!1,excludeAdapter:I}),d}return E(),d};return{categories:n,gpc:e.gpc!==!1&&typeof navigator<"u"&&navigator.globalPrivacyControl===!0,bootstrap(){return p??=O(),p},getConsent(){return d},isStale(){return g},async setConsent(f,_="imperative"){et(f,n),await A(r(f),_,{persist:!0,applyAdapters:!0})},subscribe(f){return a.add(f),()=>a.delete(f)},destroy(){u=!0,c.forEach(f=>f()),c.clear(),a.clear()}}}Z();var ie;function ft(e={}){let{consent:t,categories:n,names:r,...d}=e;He(r);let a=e.server?.consentEndpoint?B(e.server.consentEndpoint,"server.consentEndpoint"):void 0,c={id:"consent-endpoint",async apply(y){let v=await fetch(a,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({consent:y})});if(!v.ok)throw new Error(`HTTP ${v.status}`)}},o=ut({storage:it({key:F().consentStorageKey}),broadcast:{eventName:oe(y=>y.consentEventName),globalKey:oe(y=>y.consentGlobalKey)},...t,adapters:[...t?.adapters??[],...a?[c]:[]],categories:n,debug:e.debug,onError:e.onError}),i=lt({identityStorage:at({key:F().identityStorageKey}),...d,consentEngine:o}),u={boot:i.boot,registerProvider:i.registerProvider,page:i.page,track:i.track,identify:i.identify,reset:i.reset,group:i.group,captureError:i.captureError,newPageSession:i.newPageSession,getSnapshot:i.getSnapshot,subscribe:i.subscribe,consent:{categories:o.categories,gpc:o.gpc,bootstrap:o.bootstrap,getConsent:o.getConsent,isStale:o.isStale,setConsent:o.setConsent,subscribe:o.subscribe,async update(y){await o.bootstrap();let v=Object.fromEntries(o.categories.map(h=>[h,!1]));await o.setConsent({...v,...o.getConsent(),...y})}},destroy(){i.destroy(),o.destroy(),ie?.analytics===u&&(ie=void 0)}},p=JSON.stringify(r??{});return ie&&ie.names!==p&&console.warn("[consentlayer] createAnalytics() was called again with different names. Storage keys, globals and events are per page, so the last names win: create one instance per page."),ie={analytics:u,names:p},u}Z();function wn(e,t){let n=t?.mode??"immediate";if(n==="manual")return()=>{};if(n==="immediate"||typeof window>"u")return e.boot(),()=>{};if("requestIdleCallback"in window){let d=window.requestIdleCallback(()=>{e.boot()},{timeout:t?.timeoutMs??3e3});return()=>window.cancelIdleCallback?.(d)}let r=globalThis.setTimeout(()=>{e.boot()},t?.timeoutMs??1500);return()=>globalThis.clearTimeout(r)}function pt(e,{boot:t,autoShowBanner:n=!0,openConsentGlobalKey:r}={}){let d=e.consent,a=g=>Object.fromEntries(d.categories.map(C=>[C,typeof g=="function"?g(C):g])),c={ready:!1,error:null,bannerVisible:!1,dialogVisible:!1,categories:d.categories,gpc:d.gpc,prefs:a(!1)},o=new Set,i=g=>{c={...c,...g},o.forEach(C=>C())},u=null,p,y,v={routeKey:null,providers:new Set,forwarded:!1},h=()=>{let g=e.getSnapshot();if(!g.booted||u===null)return;v.routeKey!==u&&(v={routeKey:u,providers:new Set,forwarded:!1});let C=g.activeProviders.filter(A=>!v.providers.has(A)),E=!v.forwarded&&!!(g.consent?.analytics||g.consent?.marketing);!C.length&&!E||(C.forEach(A=>v.providers.add(A)),E&&(v.forwarded=!0),e.page(y,{only:C,server:E}))},S=async g=>{await d.setConsent(g),i({bannerVisible:!1,dialogVisible:!1})};return{getSnapshot:()=>c,subscribe(g){return o.add(g),()=>o.delete(g)},start(){let g=!1;d.bootstrap().then(k=>{g||i({...k&&{prefs:a(q=>k[q])},bannerVisible:k&&!d.isStale()?!1:n})}).catch(k=>{g||i({error:String(k),bannerVisible:n})}).finally(()=>{g||i({ready:!0})});let C=wn(e,t),E=k=>{k&&i({prefs:a(q=>k[q])})};E(d.getConsent());let A=d.subscribe(({consent:k})=>E(k)),O=e.subscribe(h);h();let f=typeof window>"u"?{}:window,_=()=>i({dialogVisible:!0}),P=r?[r]:oe(k=>k.openConsentGlobalKey);for(let k of P)f[k]=_;return()=>{g=!0;for(let k of P)f[k]===_&&delete f[k];C(),A(),O()}},setRoute(g,C){if(u=g,y=C,h(),g===null||p===g)return;let E=p!=null;p=g,E&&e.newPageSession()},actions:{setPrefs:g=>i({prefs:g}),showBanner:()=>i({bannerVisible:!0}),hideBanner:()=>i({bannerVisible:!1}),openDialog:()=>i({dialogVisible:!0}),closeDialog:()=>i({dialogVisible:!1}),acceptAll:()=>S(a(g=>!(d.gpc&&g==="marketing"))),rejectNonEssential:()=>S(a(!1)),savePreferences:()=>S(a(g=>c.prefs[g]))}}}L();var W=(...e)=>(window._uxa=window._uxa??[]).push(e),gt=(e=location.pathname)=>e.split(/[?#]/)[0];function mt(e){let t=e.tagId?.trim();if(!t)return j("contentsquare","tagId");let n;return{id:"contentsquare",requiredConsent:"analytics",consent(r){typeof window<"u"&&r.consent?.analytics&&D(d=>d==="_cs_optout")},load(){typeof window>"u"||T("ContentsquareInitialized")||(window._uxa=window._uxa??[],n=gt(),x(`https://t.contentsquare.net/uxa/${t}.js`).catch(()=>{}),R("ContentsquareInitialized",!0))},page(r){let d=gt(r.path);if(d===n){n=void 0;return}n=void 0,W("trackPageview",d)},track(r){if(r.name!=="purchase"){W("trackPageEvent",r.name);return}let{transaction_id:d,value:a,currency:c}=r.params;W("ec:transaction:create",{id:d,revenue:a,currency:c}),W("ec:transaction:send")},identify(r){r.userId&&W("identify",r.userId)},reset(){W("resetIdentity")},teardown(r){typeof window>"u"||r.consent?.analytics||!T("ContentsquareInitialized")||W("optout")}}}L();var bn={lead:"generate_lead"};function vn(e){return bn[e]??e.replace(/[^A-Za-z0-9_]/g,"_")}function yt(e){let t={};return e.email&&(t.email=e.email),e.phone&&(t.phone_number=e.phone.startsWith("+")?e.phone:`+${e.phone}`),t}function wt(e){if(!e.measurementId?.trim())return j("ga4","measurementId");let t=Xe(e.measurementId.trim()),n=e.consentMode==="advanced",r=e.serverContainerUrl&&B(e.serverContainerUrl,"ga4 serverContainerUrl"),d=!1,a=(...i)=>window.gtag?.(...i),c=()=>{let i=R("Ga4Configured",T("Ga4Configured")??{});i[t]||(a("config",t,{send_page_view:!1,...r&&{server_container_url:r}}),i[t]=!0)},o=i=>{a("set",{user_id:i.userId??null}),a("set","user_data",yt(i))};return{id:"ga4",requiredConsent:n?"none":"analytics",loadBeforeConsent:n||(e.loadBeforeConsent??!1),setup(){typeof window>"u"||(d=!T("GoogleConsentMode"),d?Q(null):re(),a("js",new Date),n&&c())},consent({consent:i,identity:u}){typeof window>"u"||(d&&Q(i),i&&!i.analytics&&D(p=>p==="_ga"||p==="_gid"||p.startsWith("_ga_")),n?o(i?.analytics?u:{}):i?.analytics&&c())},load({emitError:i}){typeof window>"u"||x(`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(t)}`).catch(()=>i({scope:"provider-script-load",message:`Failed to load GA4 gtag.js for measurement ID ${t}`}))},page(i){typeof window>"u"||a("event","page_view",{page_location:i.url??window.location.href,page_path:i.path??window.location.pathname,page_title:i.title??document.title})},track(i){typeof window>"u"||a("event",vn(i.name),{...i.params,...i.options.providers?.ga4})},identify(i,u,{consent:p}){typeof window>"u"||n&&!p?.analytics||(i.userId&&a("set",{user_id:i.userId}),a("set","user_data",yt(i)))},reset(){typeof window>"u"||o({})}}}L();var hn=/^GTM-[A-Z0-9]{4,12}$/;function bt(e){if(!e.containerId?.trim())return j("gtm","containerId");let t=e.containerId.trim();if(!hn.test(t))throw new Error(`[consentlayer] Invalid GTM container ID: expected format "GTM-XXXXXXX", received "${t}".`);let n=e.serverContainerUrl?B(e.serverContainerUrl,"gtm serverContainerUrl").replace(/\/$/,""):"https://www.googletagmanager.com",r=!1,d=null,a=null,c=i=>window.dataLayer?.push(i),o=i=>{(i??null)!==d&&(d=i??null,c({event:"consentlayer_identify",user_id:d}))};return{id:"gtm",requiredConsent:e.requiredConsent??"none",setup(){typeof window>"u"||(r=!T("GoogleConsentMode"),r?Q(null):re())},consent({consent:i,identity:u}){typeof window>"u"||(r&&Q(i),i&&JSON.stringify(i)!==JSON.stringify(a)&&(a=i,c({event:"consentlayer_consent",consent:{...i}})),o(i?.analytics?u.userId:void 0))},load({emitError:i}){if(typeof window>"u")return;let u=R("GtmLoaded",T("GtmLoaded")??{});u[t]||(u[t]=!0,c({"gtm.start":Date.now(),event:"gtm.js"}),x(`${n}/gtm.js?id=${encodeURIComponent(t)}`).catch(()=>i({scope:"provider-script-load",message:`Failed to load Google Tag Manager container ${t}`})))},page(i){typeof window>"u"||c({event:"page_view",page_location:i.url??window.location.href,page_path:i.path??window.location.pathname,page_title:i.title??document.title})},track(i){typeof window>"u"||c({...i.params,...i.options.providers?.gtm,event:i.name})},identify(i,u,{consent:p}){typeof window>"u"||!p?.analytics||o(i.userId)},reset(){typeof window>"u"||o(void 0)}}}L();function Cn(){D(e=>e.startsWith("_hj"));for(let e of[localStorage,sessionStorage])for(let t of Object.keys(e))/^_?hj/.test(t)&&e.removeItem(t)}function kn(e){typeof window>"u"||T("HotjarInitialized")||(window.hj=window.hj??((...t)=>{window.hj.q=window.hj.q??[],window.hj.q.push(t)}),window._hjSettings={hjid:e.siteId,hjsv:e.version},x(`https://static.hotjar.com/c/hotjar-${e.siteId}.js?sv=${e.version}`).catch(()=>{}),R("HotjarInitialized",!0))}var vt=e=>typeof e=="number"?e:/^\d+$/.test(e)?Number(e):Number.NaN;function ht(e){let t=typeof e.siteId=="string"?e.siteId.trim():e.siteId,n=typeof e.version=="string"?e.version.trim():e.version;if(t===void 0||t==="")return j("hotjar","siteId");if(n===void 0||n==="")return j("hotjar","version");let r=vt(t),d=vt(n);if(!Number.isSafeInteger(r)||r<=0||!Number.isSafeInteger(d)||d<=0)throw new Error(`[consentlayer] Invalid Hotjar siteId or version: expected positive integers, received ${JSON.stringify(e.siteId)} and ${JSON.stringify(e.version)}.`);return{id:"hotjar",requiredConsent:"analytics",load(){kn({siteId:r,version:d})},track(a){window.hj?.("event",a.name)},identify(a,c){let o=a.userId&&a.email?{...c,email:a.email}:c;window.hj?.("identify",a.userId??null,o)},teardown(a){if(!(typeof window>"u"||a.consent?.analytics))try{Cn()}finally{e.reloadOnRevoke&&location.reload()}},reset(){window.hj?.("identify",null,{})}}}var Ct={page_view:"PageView",view_item:"ViewContent",add_to_cart:"AddToCart",add_to_wishlist:"AddToWishlist",begin_checkout:"InitiateCheckout",add_payment_info:"AddPaymentInfo",purchase:"Purchase",sign_up:"CompleteRegistration",lead:"Lead",search:"Search",contact:"Contact",trial_started:"StartTrial",subscription_started:"Subscribe",customize_product:"CustomizeProduct",schedule:"Schedule",submit_application:"SubmitApplication",find_location:"FindLocation",donate:"Donate"},Sn=new Set([...Object.values(Ct),"PageView"]);function kt(e){let t=Ct[e.name]??(Sn.has(e.name)?e.name:void 0),{items:n,search_term:r,...d}=e.params,a={...d};if(Array.isArray(n)&&n.length){let c=o=>o.item_variant??o.item_id;a.content_ids=n.map(c),a.contents=n.map(o=>({id:c(o),quantity:o.quantity??1,item_price:o.price})),a.content_type="product",a.num_items=n.reduce((o,i)=>o+(i.quantity??1),0)}return r!==void 0&&(a.search_string=r),{method:t?"track":"trackCustom",name:t??e.name,params:{...a,...e.options.providers?.meta}}}function St(e){let t={};return e.email&&(t.em=e.email),e.phone&&(t.ph=e.phone.replace(/\D/g,"")),e.userId&&(t.external_id=e.userId),t}L();var _t=e=>e==="_fbp"||e==="_fbc";function It(e){if(!e.pixelId?.trim())return j("meta","pixelId");let t=Ze(e.pixelId.trim()),n=e.locale??"en_US",r=()=>typeof window<"u"&&typeof window.fbq=="function"&&T("MetaPixelInitialized")===!0,d=!1,a=!1;return{id:"meta",requiredConsent:"marketing",loadBeforeConsent:e.loadBeforeConsent??!1,load(c){if(typeof window>"u"||T("MetaPixelInitialized"))return;let o=document.createElement("script");o.setAttribute("data-consentlayer","meta-pixel-bootstrap"),o.text=`!function(f,b,e,v,n){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
2
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
3
+ n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];}(window);
4
+ fbq('consent', ${c.consent?.marketing?"'grant'":"'revoke'"});
5
+ fbq('init', ${JSON.stringify(t)}, ${JSON.stringify(St(c.identity)).replace(/</g,"\\u003c")});`,document.head.appendChild(o),o.remove(),d=!!(c.identity.email||c.identity.phone),x(`https://connect.facebook.net/${encodeURIComponent(n)}/fbevents.js`).catch(()=>c.emitError({scope:"provider-script-load",message:"Failed to load Meta Pixel (fbevents.js)"})),R("MetaPixelInitialized",!0)},consent(c){typeof window<"u"&&c.consent&&!c.consent.marketing&&D(_t),r()&&(d&&!c.consent?.marketing&&(a=!0),window.fbq?.("consent",c.consent?.marketing&&!a?"grant":"revoke"))},teardown(c){typeof window>"u"||c.consent?.marketing||D(_t)},page(c,o){!r()||a||!o.consent?.marketing||window.fbq?.("track","PageView",{},{eventID:c.id})},track(c,o){if(!r()||a||!o.consent?.marketing)return;let{method:i,name:u,params:p}=kt(c);window.fbq?.(i,u,p,{eventID:c.id})}}}L();function Rt(e){let t=e.apiKey?.trim();if(!t)return j("posthog","apiKey");let n=e.cookieless??!0,r,d,a=()=>!!d?.consent?.analytics,c=async o=>{if(!a()){o.has_opted_out_capturing()||o.opt_out_capturing();return}o.has_opted_in_capturing()||o.opt_in_capturing();let i=d?.identity.userId;i&&o.identify(i),e.recording&&(await Promise.resolve().then(()=>(Tt(),At)),o.startSessionRecording())};return{id:"posthog",requiredConsent:n?"none":"analytics",defer:e.defer,async consent(o){d=o,r&&await c(await r)},async load(o){d??=o,r=Promise.resolve().then(()=>(Ot(),xt)).then(({default:i})=>(i.init(t,{api_host:e.apiHost??"https://us.i.posthog.com",ui_host:e.uiHost,cookieless_mode:n?"on_reject":void 0,opt_out_capturing_by_default:!0,opt_out_persistence_by_default:!0,autocapture:e.autocapture??!1,capture_pageview:!1,capture_pageleave:!1,capture_exceptions:!1,capture_heatmaps:!1,capture_dead_clicks:!1,disable_session_recording:!0,disable_surveys:!0,advanced_disable_flags:!e.recording,advanced_disable_feature_flags:!0,disable_external_dependency_loading:!0}),i)),await c(await r)},async page(o){(await r)?.capture("$pageview",{$current_url:o.url,title:o.title})},async track(o){(await r)?.capture(o.name,{...o.params,...o.options.providers?.posthog})},async identify(o,i,u){d=u;let p=await r;!p||!a()||!o.userId||p.identify(o.userId,o.email?{...i,email:o.email}:i)},async group(o,i){let u=await r;u&&a()&&u.group(e.groupType??"company",o,i)},async reset(o){d=o;let i=await r;i&&(i.reset(),await c(i))},error:e.errors===!1?void 0:async(o,i)=>{(await r)?.captureException(o,{level:i.level,...i.tags,...i.extra})}}}L();function jt(e){let t=e.dsn?.trim();if(!t)return j("sentry","dsn");let n=e.replay===!0?{}:e.replay,r=e.tracing===!0?{}:e.tracing,d,a,c,o=!1,i=()=>!!a?.consent?.analytics,u=async p=>{let y=a?.identity.userId;p.setUser(i()&&y?{id:y,email:a?.identity.email}:null),n&&(i()?c?c.startBuffering():p.addIntegration(c=(await Promise.resolve().then(()=>(pe(),fe))).replayIntegration()):await c?.stop()),r&&i()&&!o&&(o=!0,p.addIntegration((await Promise.resolve().then(()=>(pe(),fe))).browserTracingIntegration()))};return{id:"sentry",requiredConsent:"none",defer:e.defer,async consent(p){a=p,d&&await u(await d)},async load(p){a??=p,d=Promise.resolve().then(()=>(pe(),fe)).then(y=>(y.init({dsn:t,environment:e.environment,release:e.release,tunnel:e.tunnel,dataCollection:{userInfo:!1,cookies:!1,httpHeaders:!1,httpBodies:[],urlQueryParams:!1},integrations:v=>v.filter(h=>h.name!=="GlobalHandlers"),tracesSampleRate:r?r.sampleRate??1:void 0,replaysSessionSampleRate:n?n.sessionSampleRate??.1:void 0,replaysOnErrorSampleRate:n?n.onErrorSampleRate??1:void 0,beforeSendTransaction:v=>i()?v:null}),y)),await u(await d)},async identify(p,y,v){a=v;let h=await d;h&&await u(h)},async reset(p){a=p,(await d)?.setUser(null)},async error(p,y){(await d)?.captureException(p,{level:y.level,tags:{...y.tags,source:y.source},extra:y.extra})}}}L();var An={view_item:"ViewContent",add_to_cart:"AddToCart",add_to_wishlist:"AddToWishlist",begin_checkout:"InitiateCheckout",add_payment_info:"AddPaymentInfo",purchase:"Purchase",sign_up:"CompleteRegistration",lead:"Lead",search:"Search",contact:"Contact",trial_started:"StartTrial",subscription_started:"Subscribe",customize_product:"CustomizeProduct",schedule:"Schedule",submit_application:"SubmitApplication",find_location:"FindLocation"};function qt(e){let{items:t,search_term:n,transaction_id:r,...d}=e.params,a={...d};if(Array.isArray(t)&&t.length){let c=o=>o.item_variant??o.item_id;a.content_ids=t.map(c),a.contents=t.map(o=>({content_id:c(o),content_name:o.item_name,content_category:o.item_category,brand:o.item_brand,price:o.price,quantity:o.quantity??1})),a.content_type="product",a.num_items=t.reduce((o,i)=>o+(i.quantity??1),0)}return n!==void 0&&(a.search_string=n),r!==void 0&&(a.order_id=r),{name:An[e.name]??e.name,params:{...a,...e.options.providers?.tiktok}}}function $t(e){let t={};return e.email&&(t.email=e.email.trim().toLowerCase()),e.phone&&(t.phone_number=`+${e.phone.replace(/\D/g,"")}`),e.userId&&(t.external_id=e.userId),t}var Lt=e=>e==="_ttp"||e==="ttclid"||e.startsWith("ttcsid");function Mt(e){let t=e.pixelId?.trim();if(!t)return j("tiktok","pixelId");let n=()=>typeof window<"u"&&window.ttq!==void 0&&T("TikTokPixelInitialized")===!0,r=!1,d=!1;return{id:"tiktok",requiredConsent:"marketing",loadBeforeConsent:e.loadBeforeConsent??!1,load(a){if(typeof window>"u"||T("TikTokPixelInitialized"))return;let c=document.createElement("script");c.setAttribute("data-consentlayer","tiktok-pixel-bootstrap"),c.text=`!function (w, d, t) {
6
+ w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e},ttq.load=function(e,n){var i="https://analytics.tiktok.com/i18n/pixel/events.js";ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{}};
7
+ ttq.${a.consent?.marketing?"grantConsent":"holdConsent"}();
8
+ ttq.load(${JSON.stringify(t).replace(/</g,"\\u003c")});
9
+ }(window, document, 'ttq');`,document.head.appendChild(c),c.remove(),x(`https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=${encodeURIComponent(t)}&lib=ttq`).catch(()=>a.emitError({scope:"provider-script-load",message:"Failed to load TikTok Pixel (events.js)"})),R("TikTokPixelInitialized",!0)},consent(a){typeof window<"u"&&a.consent&&!a.consent.marketing&&D(Lt),n()&&(r&&!a.consent?.marketing&&(d=!0),a.consent?.marketing&&!d?window.ttq?.grantConsent():window.ttq?.revokeConsent())},teardown(a){typeof window>"u"||a.consent?.marketing||D(Lt)},identify(a,c,o){if(!n()||d||!o.consent?.marketing)return;let i=$t(a);Object.keys(i).length&&(window.ttq?.identify(i),r||=!!(i.email||i.phone_number))},page(a,c){!n()||d||!c.consent?.marketing||window.ttq?.page()},track(a,c){if(!n()||d||!c.consent?.marketing)return;let{name:o,params:i}=qt(a);window.ttq?.track(o,i,{event_id:a.id})}}}function Nt(e){return{id:"vercel",requiredConsent:"none",track(t){e.trackEvent(t.name,ot(t.params))}}}ue();var Ut={ga4:wt,gtm:bt,meta:It,tiktok:Mt,contentsquare:mt,hotjar:ht,posthog:Rt,sentry:jt,vercel:e=>Nt({trackEvent:(t,n)=>window.va?.("event",{name:t,data:n}),...e})},xe={googleConsentMode:Fe,shopify:Ke,tcf:We},Dt={ga4:["ga4","measurementId"],gtm:["gtm","containerId"],metaPixel:["meta","pixelId"],tiktokPixel:["tiktok","pixelId"],contentsquareTag:["contentsquare","tagId"],hotjarSite:["hotjar","siteId"],hotjarVersion:["hotjar","version"],posthogKey:["posthog","apiKey"],posthogHost:["posthog","apiHost"],posthogRecording:["posthog","recording",!0],sentryDsn:["sentry","dsn"],sentryEnvironment:["sentry","environment"],sentryReplay:["sentry","replay",!0],sentryTracing:["sentry","tracing",!0],vercel:["vercel"]},ae=e=>e!=="false";function Gt(e,t){let n={...e},r={},d={};for(let[c,o]of Object.entries(e?.providers??{}))r[c]={...o};for(let[c,o]of Object.entries(e?.adapters??{}))d[c]={...o};let a=t instanceof HTMLScriptElement?t.dataset:{};for(let[c,o]of Object.entries(a))if(o!==void 0){if(c==="autoTracking")n.autoTracking=ae(o);else if(c==="debug")n.debug=ae(o);else if(xe[c])ae(o)?d[c]??={}:delete d[c];else if(Dt[c]){let[i,u,p]=Dt[c];!u&&!ae(o)?delete r[i]:r[i]??={},u&&(r[i][u]=p?ae(o):o)}}return n.providers=r,Object.keys(d).length?n.adapters=d:delete n.adapters,n}function Bt(e){let{providers:t={},adapters:n={},boot:r,autoShowBanner:d,openConsentGlobalKey:a,autoTracking:c,...o}=e,i=[],u=[...o.consent?.adapters??[]];for(let[h,S]of Object.entries(t))Ut[h]?i.push(Ut[h](S)):console.warn(`[consentlayer] Unknown provider "${h}".`);for(let[h,S]of Object.entries(n))xe[h]?u.push(xe[h](S)):console.warn(`[consentlayer] Unknown adapter "${h}".`);Pt(t.posthog?.apiHost);let p=ft({...o,providers:i,consent:{...o.consent,adapters:u},autoTracking:c?Je(c===!0?void 0:c):void 0}),y=pt(p,{boot:r,autoShowBanner:d,openConsentGlobalKey:a});y.start();let v=()=>y.setRoute(location.pathname+location.search);for(let h of["pushState","replaceState"]){let S=history[h];history[h]=function(...g){S.apply(this,g),v()}}return addEventListener("popstate",v),v(),{...p,controller:y}}var ge=window.ConsentLayer;(!ge||!("controller"in ge))&&(window.ConsentLayer={...Bt(Gt(ge,document.currentScript)),banner:ge?.banner},dispatchEvent(new Event("consentlayer:ready")));})();
@@ -0,0 +1,44 @@
1
+ import { r as AnalyticsManagerOptions, s as ConsentEngineOptions, m as Analytics } from './types-BV_AFZKQ.js';
2
+
3
+ /** Event names used by auto-tracking. */
4
+ type AutoTrackingEventNames = {
5
+ pageSessionStart: string;
6
+ scrollDepth: string;
7
+ timeOnPage: string;
8
+ uiClick: string;
9
+ };
10
+ /** Storage keys, globals and DOM events in use. */
11
+ type Names = {
12
+ prefix: string;
13
+ legacy: boolean;
14
+ consentStorageKey: string;
15
+ identityStorageKey: string;
16
+ consentEventName: string;
17
+ consentGlobalKey: string;
18
+ openConsentGlobalKey: string;
19
+ autoTrackingEvents: AutoTrackingEventNames;
20
+ };
21
+ /** Overrides for `createAnalytics({ names })`; the rest derives from `prefix`. */
22
+ type NamesInput = Partial<Omit<Names, 'autoTrackingEvents'>> & {
23
+ autoTrackingEvents?: Partial<AutoTrackingEventNames>;
24
+ };
25
+ /** The names in use, after `createAnalytics({ names })`. */
26
+ declare function getNames(): Names;
27
+ /** Window flags providers use to avoid loading a script twice. */
28
+ declare function getFlag<T>(name: string): T | undefined;
29
+ /** Sets a `window.__<prefix><name>` flag, so custom plugins can mark one-time setup. */
30
+ declare function setFlag<T>(name: string, value: T): T;
31
+
32
+ /** Options for `createAnalytics`. */
33
+ type AnalyticsOptions = Omit<AnalyticsManagerOptions, 'consent' | 'consentEngine'> & {
34
+ /** Storage, CMP integrations (e.g. Shopify Customer Privacy) and broadcast. Defaults to localStorage. */
35
+ consent?: Omit<ConsentEngineOptions, 'debug' | 'categories' | 'onError'>;
36
+ /** Your own categories, declared in `ConsentCategories`. Stored, broadcast and sent to the server like the built-in ones. */
37
+ categories?: ConsentEngineOptions['categories'];
38
+ /** Renames storage keys, globals and DOM events. */
39
+ names?: NamesInput;
40
+ };
41
+ /** Creates the analytics instance. Nothing loads until `boot()` (which `<AnalyticsProvider>` calls) and then only what consent allows. */
42
+ declare function createAnalytics(options?: AnalyticsOptions): Analytics;
43
+
44
+ export { type AnalyticsOptions as A, type Names as N, type AutoTrackingEventNames as a, type NamesInput as b, createAnalytics as c, getNames as d, getFlag as g, setFlag as s };
@@ -0,0 +1,41 @@
1
+ import { S as StandardEvents, E as EcommerceItem } from './types-BV_AFZKQ.js';
2
+
3
+ type MoneyLike = {
4
+ amount: number | string;
5
+ currencyCode: string;
6
+ };
7
+ /** A product or cart line, in the shape most storefront APIs return. */
8
+ type ProductRef = {
9
+ id: string;
10
+ variantId?: string;
11
+ title?: string;
12
+ vendor?: string;
13
+ category?: string | null;
14
+ price?: MoneyLike;
15
+ quantity?: number;
16
+ };
17
+ /** A cart: its lines and optional subtotal. */
18
+ type CartRef = {
19
+ subtotal?: MoneyLike;
20
+ lines: ProductRef[];
21
+ };
22
+ /** A completed order. */
23
+ type OrderRef = {
24
+ orderId: string;
25
+ value: number;
26
+ currency: string;
27
+ tax?: number;
28
+ shipping?: number;
29
+ coupon?: string | null;
30
+ lines: ProductRef[];
31
+ };
32
+ /** Converts a product to a GA4-style item. */
33
+ declare function toItem(product: ProductRef): EcommerceItem;
34
+ /** Params for `view_item`, `add_to_cart`, `remove_from_cart`, `add_to_wishlist`. */
35
+ declare function productParams(product: ProductRef): StandardEvents['view_item'];
36
+ /** Params for `begin_checkout`, `add_payment_info`, `add_shipping_info`. */
37
+ declare function cartParams(cart: CartRef): StandardEvents['begin_checkout'];
38
+ /** Params for `purchase`. */
39
+ declare function orderParams(order: OrderRef): StandardEvents['purchase'];
40
+
41
+ export { type CartRef, type OrderRef, type ProductRef, cartParams, orderParams, productParams, toItem };
@@ -0,0 +1,43 @@
1
+ // src/ecommerce.ts
2
+ function toItem(product) {
3
+ return {
4
+ item_id: product.id,
5
+ item_name: product.title,
6
+ item_variant: product.variantId,
7
+ item_brand: product.vendor,
8
+ item_category: product.category ?? void 0,
9
+ price: product.price ? Number(product.price.amount) : void 0,
10
+ quantity: product.quantity ?? 1
11
+ };
12
+ }
13
+ function productParams(product) {
14
+ const item = toItem(product);
15
+ return {
16
+ value: item.price === void 0 ? void 0 : item.price * (item.quantity ?? 1),
17
+ currency: product.price?.currencyCode,
18
+ items: [item]
19
+ };
20
+ }
21
+ function cartParams(cart) {
22
+ const items = cart.lines.map(toItem);
23
+ return {
24
+ value: cart.subtotal ? Number(cart.subtotal.amount) : items.reduce((sum, item) => sum + (item.price ?? 0) * (item.quantity ?? 1), 0),
25
+ currency: cart.subtotal?.currencyCode ?? cart.lines[0]?.price?.currencyCode,
26
+ items
27
+ };
28
+ }
29
+ function orderParams(order) {
30
+ return {
31
+ transaction_id: order.orderId,
32
+ value: order.value,
33
+ currency: order.currency,
34
+ tax: order.tax,
35
+ shipping: order.shipping,
36
+ coupon: order.coupon ?? void 0,
37
+ items: order.lines.map(toItem)
38
+ };
39
+ }
40
+
41
+ export { cartParams, orderParams, productParams, toItem };
42
+ //# sourceMappingURL=ecommerce.js.map
43
+ //# sourceMappingURL=ecommerce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ecommerce.ts"],"names":[],"mappings":";AAoCO,SAAS,OAAO,OAAA,EAAoC;AACzD,EAAA,OAAO;AAAA,IACL,SAAS,OAAA,CAAQ,EAAA;AAAA,IACjB,WAAW,OAAA,CAAQ,KAAA;AAAA,IACnB,cAAc,OAAA,CAAQ,SAAA;AAAA,IACtB,YAAY,OAAA,CAAQ,MAAA;AAAA,IACpB,aAAA,EAAe,QAAQ,QAAA,IAAY,MAAA;AAAA,IACnC,OAAO,OAAA,CAAQ,KAAA,GAAQ,OAAO,OAAA,CAAQ,KAAA,CAAM,MAAM,CAAA,GAAI,MAAA;AAAA,IACtD,QAAA,EAAU,QAAQ,QAAA,IAAY;AAAA,GAChC;AACF;AAGO,SAAS,cAAc,OAAA,EAAkD;AAC9E,EAAA,MAAM,IAAA,GAAO,OAAO,OAAO,CAAA;AAC3B,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,KAAK,KAAA,KAAU,MAAA,GAAY,SAAY,IAAA,CAAK,KAAA,IAAS,KAAK,QAAA,IAAY,CAAA,CAAA;AAAA,IAC7E,QAAA,EAAU,QAAQ,KAAA,EAAO,YAAA;AAAA,IACzB,KAAA,EAAO,CAAC,IAAI;AAAA,GACd;AACF;AAGO,SAAS,WAAW,IAAA,EAAiD;AAC1E,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AACnC,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,KAAK,QAAA,GACR,MAAA,CAAO,KAAK,QAAA,CAAS,MAAM,IAC3B,KAAA,CAAM,MAAA,CAAO,CAAC,GAAA,EAAK,IAAA,KAAS,OAAO,IAAA,CAAK,KAAA,IAAS,MAAM,IAAA,CAAK,QAAA,IAAY,IAAI,CAAC,CAAA;AAAA,IACjF,QAAA,EAAU,KAAK,QAAA,EAAU,YAAA,IAAgB,KAAK,KAAA,CAAM,CAAC,GAAG,KAAA,EAAO,YAAA;AAAA,IAC/D;AAAA,GACF;AACF;AAGO,SAAS,YAAY,KAAA,EAA6C;AACvE,EAAA,OAAO;AAAA,IACL,gBAAgB,KAAA,CAAM,OAAA;AAAA,IACtB,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,UAAU,KAAA,CAAM,QAAA;AAAA,IAChB,KAAK,KAAA,CAAM,GAAA;AAAA,IACX,UAAU,KAAA,CAAM,QAAA;AAAA,IAChB,MAAA,EAAQ,MAAM,MAAA,IAAU,MAAA;AAAA,IACxB,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,MAAM;AAAA,GAC/B;AACF","file":"ecommerce.js","sourcesContent":["import type { EcommerceItem, StandardEvents } from './core/types'\n\ntype MoneyLike = {\n amount: number | string\n currencyCode: string\n}\n\n/** A product or cart line, in the shape most storefront APIs return. */\nexport type ProductRef = {\n id: string\n variantId?: string\n title?: string\n vendor?: string\n category?: string | null\n price?: MoneyLike\n quantity?: number\n}\n\n/** A cart: its lines and optional subtotal. */\nexport type CartRef = {\n subtotal?: MoneyLike\n lines: ProductRef[]\n}\n\n/** A completed order. */\nexport type OrderRef = {\n orderId: string\n value: number\n currency: string\n tax?: number\n shipping?: number\n coupon?: string | null\n lines: ProductRef[]\n}\n\n/** Converts a product to a GA4-style item. */\nexport function toItem(product: ProductRef): EcommerceItem {\n return {\n item_id: product.id,\n item_name: product.title,\n item_variant: product.variantId,\n item_brand: product.vendor,\n item_category: product.category ?? undefined,\n price: product.price ? Number(product.price.amount) : undefined,\n quantity: product.quantity ?? 1,\n }\n}\n\n/** Params for `view_item`, `add_to_cart`, `remove_from_cart`, `add_to_wishlist`. */\nexport function productParams(product: ProductRef): StandardEvents['view_item'] {\n const item = toItem(product)\n return {\n value: item.price === undefined ? undefined : item.price * (item.quantity ?? 1),\n currency: product.price?.currencyCode,\n items: [item],\n }\n}\n\n/** Params for `begin_checkout`, `add_payment_info`, `add_shipping_info`. */\nexport function cartParams(cart: CartRef): StandardEvents['begin_checkout'] {\n const items = cart.lines.map(toItem)\n return {\n value: cart.subtotal\n ? Number(cart.subtotal.amount)\n : items.reduce((sum, item) => sum + (item.price ?? 0) * (item.quantity ?? 1), 0),\n currency: cart.subtotal?.currencyCode ?? cart.lines[0]?.price?.currencyCode,\n items,\n }\n}\n\n/** Params for `purchase`. */\nexport function orderParams(order: OrderRef): StandardEvents['purchase'] {\n return {\n transaction_id: order.orderId,\n value: order.value,\n currency: order.currency,\n tax: order.tax,\n shipping: order.shipping,\n coupon: order.coupon ?? undefined,\n items: order.lines.map(toItem),\n }\n}\n"]}
@@ -0,0 +1,58 @@
1
+ export { A as AnalyticsOptions, a as AutoTrackingEventNames, N as Names, b as NamesInput, c as createAnalytics, g as getFlag, d as getNames, s as setFlag } from './create-analytics-Bzvm1UpE.js';
2
+ export { c as ConsentController, a as ConsentControllerActions, b as ConsentControllerOptions, C as ConsentControllerState, d as createConsentController } from './consent-controller-DyHPNfyT.js';
3
+ import { f as AnalyticsPlugin, t as ConsentStorageAdapter, I as IdentityStorageAdapter, p as ConsentState, U as UserIdentity } from './types-BV_AFZKQ.js';
4
+ export { m as Analytics, u as AnalyticsError, v as AnalyticsErrorHandler, w as AnalyticsErrorScope, h as AnalyticsEventPayload, x as AnalyticsManagerStateSnapshot, b as AutoTrackingClickConfig, c as AutoTrackingClickMode, A as AutoTrackingConfig, d as AutoTrackingScrollConfig, e as AutoTrackingTimeConfig, q as ConsentApi, y as ConsentBroadcastConfig, z as ConsentCategories, k as ConsentCategory, B as ConsentChangeSource, D as ConsentEngineSnapshot, C as ConsentIntegrationAdapter, F as DebugEntry, G as DebugOptions, H as DebugTopic, E as EcommerceItem, l as ErrorContext, J as EventParams, o as LazyBootConfig, K as LazyBootMode, L as LoadTiming, g as PageEvent, n as PageViewPayload, P as PluginContext, j as ProviderConsentRequirement, M as ServerEvent, S as StandardEvents, T as TrackEventOptions, i as UserTraits } from './types-BV_AFZKQ.js';
5
+
6
+ /** Types a plugin; the manager runs its hooks. */
7
+ declare function definePlugin<T extends AnalyticsPlugin>(plugin: T): T;
8
+ /** Appends `<script async src>` once per `src`. Resolves on load, rejects on error. */
9
+ declare function loadScript(src: string, attributes?: Record<string, string>): Promise<void>;
10
+
11
+ type EnvConfigInput = Record<string, string | undefined>;
12
+ /**
13
+ * Reads the documented `NEXT_PUBLIC_*` and server env vars into one typed object.
14
+ * @deprecated Pass `process.env` values to the providers directly; an unset one turns its provider off.
15
+ */
16
+ declare function createEnvConfig(env: EnvConfigInput): {
17
+ runtimeEnabled: boolean;
18
+ debug: boolean;
19
+ ga4: {
20
+ measurementId: string | undefined;
21
+ };
22
+ hotjar: {
23
+ siteId: number | undefined;
24
+ version: number | undefined;
25
+ };
26
+ meta: {
27
+ pixelId: string | undefined;
28
+ noscriptEnabled: boolean;
29
+ };
30
+ shopify: {
31
+ storeId: string | undefined;
32
+ storefrontDomain: string | undefined;
33
+ storefrontAccessToken: string | undefined;
34
+ };
35
+ server: {
36
+ metaToken: string | undefined;
37
+ facebookTestEventCode: string | undefined;
38
+ ga4ApiSecret: string | undefined;
39
+ };
40
+ };
41
+
42
+ type LocalStorageAdapterOptions = {
43
+ key: string;
44
+ /** Keys to move an existing value from. Defaults to the legacy `acm_*` key when `key` is the configured one. */
45
+ legacyKeys?: string[];
46
+ storage?: Storage;
47
+ window?: Window;
48
+ };
49
+ /** Consent in localStorage, synced across tabs. Never throws when storage is blocked or full. */
50
+ declare function createLocalStorageConsentStorage(options: LocalStorageAdapterOptions): ConsentStorageAdapter;
51
+ /** Visitor identity in localStorage. Never throws when storage is blocked or full. */
52
+ declare function createLocalStorageIdentityStorage(options: LocalStorageAdapterOptions): IdentityStorageAdapter;
53
+ /** Consent kept in memory only, e.g. for tests or when you store it yourself. */
54
+ declare function createMemoryConsentStorage(initial?: ConsentState | null): ConsentStorageAdapter;
55
+ /** Identity kept in memory only. */
56
+ declare function createMemoryIdentityStorage(initial?: UserIdentity): IdentityStorageAdapter;
57
+
58
+ export { AnalyticsPlugin, ConsentState, ConsentStorageAdapter, type EnvConfigInput, IdentityStorageAdapter, UserIdentity, createEnvConfig, createLocalStorageConsentStorage, createLocalStorageIdentityStorage, createMemoryConsentStorage, createMemoryIdentityStorage, definePlugin, loadScript };
package/dist/index.js ADDED
@@ -0,0 +1,42 @@
1
+ export { createAnalytics, createConsentController } from './chunk-FDJMIJFV.js';
2
+ export { createLocalStorageConsentStorage, createLocalStorageIdentityStorage, createMemoryConsentStorage, createMemoryIdentityStorage } from './chunk-LEAQJXJU.js';
3
+ export { definePlugin, loadScript } from './chunk-7XLGT6U3.js';
4
+ export { getFlag, getNames, setFlag } from './chunk-R6I7OYQB.js';
5
+
6
+ // src/core/presets.ts
7
+ function createEnvConfig(env) {
8
+ const toNumber = (value) => {
9
+ if (!value) return void 0;
10
+ const parsed = Number(value);
11
+ return Number.isFinite(parsed) ? parsed : void 0;
12
+ };
13
+ return {
14
+ runtimeEnabled: env.NODE_ENV === "production" || env.NEXT_PUBLIC_ENABLE_ANALYTICS === "true",
15
+ debug: env.NEXT_PUBLIC_ANALYTICS_DEBUG === "true",
16
+ ga4: {
17
+ measurementId: env.NEXT_PUBLIC_GA4_MEASUREMENT_ID
18
+ },
19
+ hotjar: {
20
+ siteId: toNumber(env.NEXT_PUBLIC_HOTJAR_SITE_ID),
21
+ version: toNumber(env.NEXT_PUBLIC_HOTJAR_VERSION)
22
+ },
23
+ meta: {
24
+ pixelId: env.NEXT_PUBLIC_FACEBOOK_PIXEL_ID,
25
+ noscriptEnabled: env.NEXT_PUBLIC_FACEBOOK_PIXEL_NOSCRIPT === "true"
26
+ },
27
+ shopify: {
28
+ storeId: env.NEXT_PUBLIC_SHOPIFY_STORE_ID,
29
+ storefrontDomain: env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN,
30
+ storefrontAccessToken: env.NEXT_PUBLIC_SHOPIFY_PUBLIC_ACCESS_TOKEN
31
+ },
32
+ server: {
33
+ metaToken: env.META_TOKEN,
34
+ facebookTestEventCode: env.FACEBOOK_TEST_EVENT_CODE,
35
+ ga4ApiSecret: env.GA4_API_SECRET
36
+ }
37
+ };
38
+ }
39
+
40
+ export { createEnvConfig };
41
+ //# sourceMappingURL=index.js.map
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/presets.ts"],"names":[],"mappings":";;;;;;AAMO,SAAS,gBAAgB,GAAA,EAAqB;AACnD,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,KAA8B;AAC9C,IAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,IAAA,MAAM,MAAA,GAAS,OAAO,KAAK,CAAA;AAC3B,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,GAAI,MAAA,GAAS,MAAA;AAAA,EAC5C,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,cAAA,EAAgB,GAAA,CAAI,QAAA,KAAa,YAAA,IAAgB,IAAI,4BAAA,KAAiC,MAAA;AAAA,IACtF,KAAA,EAAO,IAAI,2BAAA,KAAgC,MAAA;AAAA,IAC3C,GAAA,EAAK;AAAA,MACH,eAAe,GAAA,CAAI;AAAA,KACrB;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,MAAA,EAAQ,QAAA,CAAS,GAAA,CAAI,0BAA0B,CAAA;AAAA,MAC/C,OAAA,EAAS,QAAA,CAAS,GAAA,CAAI,0BAA0B;AAAA,KAClD;AAAA,IACA,IAAA,EAAM;AAAA,MACJ,SAAS,GAAA,CAAI,6BAAA;AAAA,MACb,eAAA,EAAiB,IAAI,mCAAA,KAAwC;AAAA,KAC/D;AAAA,IACA,OAAA,EAAS;AAAA,MACP,SAAS,GAAA,CAAI,4BAAA;AAAA,MACb,kBAAkB,GAAA,CAAI,gCAAA;AAAA,MACtB,uBAAuB,GAAA,CAAI;AAAA,KAC7B;AAAA,IACA,MAAA,EAAQ;AAAA,MACN,WAAW,GAAA,CAAI,UAAA;AAAA,MACf,uBAAuB,GAAA,CAAI,wBAAA;AAAA,MAC3B,cAAc,GAAA,CAAI;AAAA;AACpB,GACF;AACF","file":"index.js","sourcesContent":["export type EnvConfigInput = Record<string, string | undefined>\n\n/**\n * Reads the documented `NEXT_PUBLIC_*` and server env vars into one typed object.\n * @deprecated Pass `process.env` values to the providers directly; an unset one turns its provider off.\n */\nexport function createEnvConfig(env: EnvConfigInput) {\n const toNumber = (value: string | undefined) => {\n if (!value) return undefined\n const parsed = Number(value)\n return Number.isFinite(parsed) ? parsed : undefined\n }\n\n return {\n runtimeEnabled: env.NODE_ENV === 'production' || env.NEXT_PUBLIC_ENABLE_ANALYTICS === 'true',\n debug: env.NEXT_PUBLIC_ANALYTICS_DEBUG === 'true',\n ga4: {\n measurementId: env.NEXT_PUBLIC_GA4_MEASUREMENT_ID,\n },\n hotjar: {\n siteId: toNumber(env.NEXT_PUBLIC_HOTJAR_SITE_ID),\n version: toNumber(env.NEXT_PUBLIC_HOTJAR_VERSION),\n },\n meta: {\n pixelId: env.NEXT_PUBLIC_FACEBOOK_PIXEL_ID,\n noscriptEnabled: env.NEXT_PUBLIC_FACEBOOK_PIXEL_NOSCRIPT === 'true',\n },\n shopify: {\n storeId: env.NEXT_PUBLIC_SHOPIFY_STORE_ID,\n storefrontDomain: env.NEXT_PUBLIC_SHOPIFY_STORE_DOMAIN,\n storefrontAccessToken: env.NEXT_PUBLIC_SHOPIFY_PUBLIC_ACCESS_TOKEN,\n },\n server: {\n metaToken: env.META_TOKEN,\n facebookTestEventCode: env.FACEBOOK_TEST_EVENT_CODE,\n ga4ApiSecret: env.GA4_API_SECRET,\n },\n }\n}\n"]}
package/dist/next.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { A as AnalyticsProviderProps } from './analytics-provider-07mxUgIK.js';
3
+ import 'react';
4
+ import './types-BV_AFZKQ.js';
5
+ import './consent-controller-DyHPNfyT.js';
6
+
7
+ /** Props for `<AnalyticsProvider>` from `consentlayer/next`: the route comes from the Next.js router. */
8
+ type NextAnalyticsProviderProps = Omit<AnalyticsProviderProps, 'routeKey'>;
9
+ /**
10
+ * `<AnalyticsProvider>` for the Next.js App Router and Pages Router: sends a
11
+ * page view on every navigation, query changes included. Only its route
12
+ * listener suspends, so your pages still render on the server.
13
+ */
14
+ declare function AnalyticsProvider({ children, ...props }: NextAnalyticsProviderProps): react_jsx_runtime.JSX.Element;
15
+
16
+ export { AnalyticsProvider, type NextAnalyticsProviderProps };
package/dist/next.js ADDED
@@ -0,0 +1,27 @@
1
+ 'use client';import { AnalyticsProvider } from './chunk-UAIZU5WD.js';
2
+ import { useRouter } from 'next/compat/router.js';
3
+ import { usePathname, useSearchParams } from 'next/navigation.js';
4
+ import { useState, Suspense, useEffect } from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ function RouteKey({ onChange }) {
8
+ const pagesRouter = useRouter();
9
+ const pathname = usePathname();
10
+ const searchParams = useSearchParams();
11
+ const routeKey = pathname === null || pagesRouter?.isReady === false ? null : `${pathname}?${searchParams?.toString() ?? ""}`;
12
+ useEffect(() => {
13
+ if (routeKey !== null) onChange(routeKey);
14
+ }, [onChange, routeKey]);
15
+ return null;
16
+ }
17
+ function AnalyticsProvider2({ children, ...props }) {
18
+ const [routeKey, setRouteKey] = useState(null);
19
+ return /* @__PURE__ */ jsxs(AnalyticsProvider, { ...props, routeKey, children: [
20
+ /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(RouteKey, { onChange: setRouteKey }) }),
21
+ children
22
+ ] });
23
+ }
24
+
25
+ export { AnalyticsProvider2 as AnalyticsProvider };
26
+ //# sourceMappingURL=next.js.map
27
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/next.tsx"],"names":["AnalyticsProvider"],"mappings":";;;;;;AAQA,SAAS,QAAA,CAAS,EAAE,QAAA,EAAS,EAA6C;AACxE,EAAA,MAAM,cAAc,SAAA,EAAU;AAC9B,EAAA,MAAM,WAA0B,WAAA,EAAY;AAC5C,EAAA,MAAM,eAAuC,eAAA,EAAgB;AAC7D,EAAA,MAAM,QAAA,GACJ,QAAA,KAAa,IAAA,IAAQ,WAAA,EAAa,OAAA,KAAY,KAAA,GAAQ,IAAA,GAAO,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,YAAA,EAAc,QAAA,MAAc,EAAE,CAAA,CAAA;AAC5G,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,QAAA,KAAa,IAAA,EAAM,QAAA,CAAS,QAAQ,CAAA;AAAA,EAC1C,CAAA,EAAG,CAAC,QAAA,EAAU,QAAQ,CAAC,CAAA;AACvB,EAAA,OAAO,IAAA;AACT;AAOO,SAASA,kBAAAA,CAAkB,EAAE,QAAA,EAAU,GAAG,OAAM,EAA+B;AACpF,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAwB,IAAI,CAAA;AAC5D,EAAA,uBACE,IAAA,CAAC,iBAAA,EAAA,EAAuB,GAAG,KAAA,EAAO,QAAA,EAChC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,YAAS,QAAA,EAAU,IAAA,EAClB,8BAAC,QAAA,EAAA,EAAS,QAAA,EAAU,aAAa,CAAA,EACnC,CAAA;AAAA,IACC;AAAA,GAAA,EACH,CAAA;AAEJ","file":"next.js","sourcesContent":["import { useRouter } from 'next/compat/router.js'\nimport { usePathname, useSearchParams } from 'next/navigation.js'\nimport { Suspense, useEffect, useState } from 'react'\nimport { AnalyticsProvider as BaseAnalyticsProvider, type AnalyticsProviderProps } from './react/analytics-provider'\n\n/** Props for `<AnalyticsProvider>` from `consentlayer/next`: the route comes from the Next.js router. */\nexport type NextAnalyticsProviderProps = Omit<AnalyticsProviderProps, 'routeKey'>\n\nfunction RouteKey({ onChange }: { onChange: (routeKey: string) => void }) {\n const pagesRouter = useRouter()\n const pathname: string | null = usePathname()\n const searchParams: URLSearchParams | null = useSearchParams()\n const routeKey =\n pathname === null || pagesRouter?.isReady === false ? null : `${pathname}?${searchParams?.toString() ?? ''}`\n useEffect(() => {\n if (routeKey !== null) onChange(routeKey)\n }, [onChange, routeKey])\n return null\n}\n\n/**\n * `<AnalyticsProvider>` for the Next.js App Router and Pages Router: sends a\n * page view on every navigation, query changes included. Only its route\n * listener suspends, so your pages still render on the server.\n */\nexport function AnalyticsProvider({ children, ...props }: NextAnalyticsProviderProps) {\n const [routeKey, setRouteKey] = useState<string | null>(null)\n return (\n <BaseAnalyticsProvider {...props} routeKey={routeKey}>\n <Suspense fallback={null}>\n <RouteKey onChange={setRouteKey} />\n </Suspense>\n {children}\n </BaseAnalyticsProvider>\n )\n}\n"]}