@appfunnel-dev/sdk 2.0.0-canary.3 → 2.0.0-canary.5

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 (53) hide show
  1. package/dist/{chunk-AKO6XKXP.js → chunk-AXXG3ODP.js} +10 -3
  2. package/dist/chunk-AXXG3ODP.js.map +1 -0
  3. package/dist/{chunk-M6U3FNRW.js → chunk-CFFMZYPE.js} +3 -3
  4. package/dist/{chunk-M6U3FNRW.js.map → chunk-CFFMZYPE.js.map} +1 -1
  5. package/dist/chunk-EMMSS5I5.cjs +37 -0
  6. package/dist/chunk-EMMSS5I5.cjs.map +1 -0
  7. package/dist/chunk-G3PMV62Z.js +33 -0
  8. package/dist/chunk-G3PMV62Z.js.map +1 -0
  9. package/dist/{chunk-JSRKA375.cjs → chunk-G44BUG6G.cjs} +10 -3
  10. package/dist/chunk-G44BUG6G.cjs.map +1 -0
  11. package/dist/{chunk-LJYLGLFS.cjs → chunk-QMAZGLGV.cjs} +2 -35
  12. package/dist/chunk-QMAZGLGV.cjs.map +1 -0
  13. package/dist/{chunk-YY375F2B.js → chunk-TNLRQPVY.js} +3 -33
  14. package/dist/chunk-TNLRQPVY.js.map +1 -0
  15. package/dist/{chunk-CY4VBSMX.cjs → chunk-VAOR77NW.cjs} +7 -7
  16. package/dist/{chunk-CY4VBSMX.cjs.map → chunk-VAOR77NW.cjs.map} +1 -1
  17. package/dist/chunk-WYUDL4FI.cjs +8 -0
  18. package/dist/chunk-WYUDL4FI.cjs.map +1 -0
  19. package/dist/chunk-ZZJG4EYL.js +6 -0
  20. package/dist/chunk-ZZJG4EYL.js.map +1 -0
  21. package/dist/driver-paddle.cjs +23 -22
  22. package/dist/driver-paddle.cjs.map +1 -1
  23. package/dist/driver-paddle.js +3 -2
  24. package/dist/driver-paddle.js.map +1 -1
  25. package/dist/driver-stripe.cjs +37 -36
  26. package/dist/driver-stripe.cjs.map +1 -1
  27. package/dist/driver-stripe.js +3 -2
  28. package/dist/driver-stripe.js.map +1 -1
  29. package/dist/index.cjs +541 -91
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +151 -75
  32. package/dist/index.d.ts +151 -75
  33. package/dist/index.js +484 -34
  34. package/dist/index.js.map +1 -1
  35. package/dist/{manifest-Cr2y1op6.d.cts → manifest-Dl7faaKe.d.cts} +34 -0
  36. package/dist/{manifest-Cr2y1op6.d.ts → manifest-Dl7faaKe.d.ts} +34 -0
  37. package/dist/manifest-entry.cjs +45 -30
  38. package/dist/manifest-entry.cjs.map +1 -1
  39. package/dist/manifest-entry.d.cts +1 -1
  40. package/dist/manifest-entry.d.ts +1 -1
  41. package/dist/manifest-entry.js +10 -3
  42. package/dist/manifest-entry.js.map +1 -1
  43. package/dist/protocol.cjs +13 -0
  44. package/dist/protocol.cjs.map +1 -0
  45. package/dist/protocol.d.cts +182 -0
  46. package/dist/protocol.d.ts +182 -0
  47. package/dist/protocol.js +4 -0
  48. package/dist/protocol.js.map +1 -0
  49. package/package.json +14 -2
  50. package/dist/chunk-AKO6XKXP.js.map +0 -1
  51. package/dist/chunk-JSRKA375.cjs.map +0 -1
  52. package/dist/chunk-LJYLGLFS.cjs.map +0 -1
  53. package/dist/chunk-YY375F2B.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkJSRKA375_cjs = require('./chunk-JSRKA375.cjs');
4
- var chunkLJYLGLFS_cjs = require('./chunk-LJYLGLFS.cjs');
3
+ var chunkG44BUG6G_cjs = require('./chunk-G44BUG6G.cjs');
4
+ var chunkWYUDL4FI_cjs = require('./chunk-WYUDL4FI.cjs');
5
+ var chunkQMAZGLGV_cjs = require('./chunk-QMAZGLGV.cjs');
6
+ require('./chunk-EMMSS5I5.cjs');
5
7
  var React = require('react');
6
8
  var ReactDOM = require('react-dom');
7
9
  var jsxRuntime = require('react/jsx-runtime');
@@ -385,7 +387,27 @@ function createBus(accessors, now2 = () => Date.now()) {
385
387
  }
386
388
  }
387
389
  };
388
- return { on, off, events, emit, ...accessors };
390
+ let nav = null;
391
+ let warnedNoNav = false;
392
+ const currentNav = () => {
393
+ if (!nav && !warnedNoNav) {
394
+ warnedNoNav = true;
395
+ console.warn("[appfunnel] window.appfunnel navigation called before the funnel flow mounted \u2014 ignored");
396
+ }
397
+ return nav;
398
+ };
399
+ const registerNavigation = (n) => {
400
+ nav = n;
401
+ warnedNoNav = false;
402
+ return () => {
403
+ if (nav === n) nav = null;
404
+ };
405
+ };
406
+ const goTo = (pageKey) => currentNav()?.goTo(pageKey) ?? false;
407
+ const goNext = () => currentNav()?.goNext();
408
+ const goPrevious = () => currentNav()?.goPrevious();
409
+ const navigation = () => nav?.snapshot() ?? null;
410
+ return { on, off, events, emit, registerNavigation, goTo, goNext, goPrevious, navigation, ...accessors };
389
411
  }
390
412
  function withBus(tracker, bus) {
391
413
  return {
@@ -407,7 +429,19 @@ function withBus(tracker, bus) {
407
429
  function attachBus(bus) {
408
430
  if (typeof window === "undefined") return () => {
409
431
  };
410
- const { on, off, getVariable, getVariables, getCurrentPageId, getCustomerId, getVisitorId } = bus;
432
+ const {
433
+ on,
434
+ off,
435
+ getVariable,
436
+ getVariables,
437
+ getCurrentPageId,
438
+ getCustomerId,
439
+ getVisitorId,
440
+ goTo,
441
+ goNext,
442
+ goPrevious,
443
+ navigation
444
+ } = bus;
411
445
  const api = {
412
446
  on,
413
447
  off,
@@ -416,6 +450,11 @@ function attachBus(bus) {
416
450
  getCurrentPageId,
417
451
  getCustomerId,
418
452
  getVisitorId,
453
+ // Flow control (bound closures over the bus's live nav registration).
454
+ goTo,
455
+ goNext,
456
+ goPrevious,
457
+ navigation,
419
458
  get events() {
420
459
  return bus.events;
421
460
  }
@@ -452,9 +491,9 @@ function LocaleProvider({
452
491
  override,
453
492
  children
454
493
  }) {
455
- const [locale, setLocale] = React.useState(() => chunkJSRKA375_cjs.resolveLocale(config, detected, override));
494
+ const [locale, setLocale] = React.useState(() => chunkG44BUG6G_cjs.resolveLocale(config, detected, override));
456
495
  React.useEffect(() => {
457
- setLocale(chunkJSRKA375_cjs.resolveLocale(config, detected, override));
496
+ setLocale(chunkG44BUG6G_cjs.resolveLocale(config, detected, override));
458
497
  }, [config, detected, override]);
459
498
  const value = React.useMemo(
460
499
  () => ({ locale, setLocale, config, catalog }),
@@ -526,7 +565,7 @@ function useTranslation() {
526
565
  fmt,
527
566
  locale,
528
567
  setLocale,
529
- dir: chunkJSRKA375_cjs.isRtl(locale) ? "rtl" : "ltr",
568
+ dir: chunkG44BUG6G_cjs.isRtl(locale) ? "rtl" : "ltr",
530
569
  locales: config?.supported ?? [locale]
531
570
  };
532
571
  }
@@ -547,16 +586,112 @@ function useProduct(id) {
547
586
  const catalog = useCatalog();
548
587
  const locale = useActiveLocale();
549
588
  const resolved = id ? catalog.get(id) : void 0;
550
- return React.useMemo(() => resolved ? chunkJSRKA375_cjs.formatProduct(resolved, locale) : void 0, [resolved, locale]);
589
+ return React.useMemo(() => resolved ? chunkG44BUG6G_cjs.formatProduct(resolved, locale) : void 0, [resolved, locale]);
551
590
  }
552
591
  function useProducts() {
553
592
  const catalog = useCatalog();
554
593
  const locale = useActiveLocale();
555
594
  return React.useMemo(
556
- () => Array.from(catalog.values()).map((r) => chunkJSRKA375_cjs.formatProduct(r, locale)),
595
+ () => Array.from(catalog.values()).map((r) => chunkG44BUG6G_cjs.formatProduct(r, locale)),
557
596
  [catalog, locale]
558
597
  );
559
598
  }
599
+
600
+ // src/flow/screenshot.ts
601
+ var MIME = { png: "image/png", jpeg: "image/jpeg", webp: "image/webp" };
602
+ var ScreenshotError = class extends Error {
603
+ constructor(code, message) {
604
+ super(message);
605
+ this.code = code;
606
+ }
607
+ };
608
+ function resolveTarget(t) {
609
+ if (!t || t.kind === "page") return document.getElementById("root") ?? document.body;
610
+ if (t.kind === "viewport") return document.body;
611
+ return document.querySelector(t.selector);
612
+ }
613
+ var delay = (ms) => new Promise((r) => setTimeout(r, ms));
614
+ function hideAll(selectors) {
615
+ const touched = [];
616
+ for (const sel of selectors) {
617
+ document.querySelectorAll(sel).forEach((el) => {
618
+ touched.push([el, el.style.visibility]);
619
+ el.style.visibility = "hidden";
620
+ });
621
+ }
622
+ return () => touched.forEach(([el, v]) => el.style.visibility = v);
623
+ }
624
+ async function scrollThrough(el) {
625
+ const prev = el.scrollTop;
626
+ const step = el.clientHeight || window.innerHeight;
627
+ for (let y = 0; y < el.scrollHeight; y += step) {
628
+ el.scrollTop = y;
629
+ await delay(16);
630
+ }
631
+ el.scrollTop = prev;
632
+ await delay(16);
633
+ }
634
+ function blobToDataURL(blob) {
635
+ return new Promise((resolve, reject) => {
636
+ const fr = new FileReader();
637
+ fr.onload = () => resolve(String(fr.result));
638
+ fr.onerror = () => reject(fr.error);
639
+ fr.readAsDataURL(blob);
640
+ });
641
+ }
642
+ async function captureScreenshot(params = {}) {
643
+ const el = resolveTarget(params.target);
644
+ if (!el) throw new ScreenshotError("bad_params", "screenshot target not found");
645
+ const restore = params.hideSelectors?.length ? hideAll(params.hideSelectors) : null;
646
+ const scale = Math.min(params.scale ?? 2, params.maxScale ?? 3);
647
+ const format = params.format ?? "png";
648
+ const timeout = params.timeout ?? 1e4;
649
+ try {
650
+ if (params.waitForFonts !== false && document.fonts?.ready) {
651
+ await Promise.race([document.fonts.ready, delay(timeout)]);
652
+ }
653
+ if (params.triggerLazyLoad) await scrollThrough(el);
654
+ if (params.waitForImages !== false) {
655
+ await Promise.all(
656
+ Array.from(el.querySelectorAll("img")).map(
657
+ (img) => typeof img.decode === "function" ? img.decode().catch(() => {
658
+ }) : Promise.resolve()
659
+ )
660
+ );
661
+ }
662
+ const { domToBlob } = await import('modern-screenshot');
663
+ let blob;
664
+ try {
665
+ blob = await domToBlob(el, {
666
+ type: MIME[format],
667
+ quality: params.quality ?? 0.92,
668
+ scale,
669
+ width: params.width,
670
+ height: params.height,
671
+ // `null` = transparent (png/webp); only fall back to white when the caller omitted it. `??`
672
+ // would wrongly collapse an explicit `null` to white.
673
+ backgroundColor: params.backgroundColor === void 0 ? "#ffffff" : params.backgroundColor,
674
+ timeout
675
+ });
676
+ } catch (e) {
677
+ throw new ScreenshotError("failed", `capture failed (an image/font may be served without CORS '*'): ${String(e?.message || e)}`);
678
+ }
679
+ const result = {
680
+ mime: MIME[format],
681
+ width: Math.round((params.width ?? el.clientWidth) * scale),
682
+ height: Math.round((params.height ?? el.scrollHeight) * scale),
683
+ scale,
684
+ bytesApprox: blob.size
685
+ };
686
+ if ((params.encoding ?? "blob") === "dataURL") result.dataURL = await blobToDataURL(blob);
687
+ else result.blob = blob;
688
+ return result;
689
+ } finally {
690
+ restore?.();
691
+ }
692
+ }
693
+
694
+ // src/flow/flow.tsx
560
695
  var NavContext = React.createContext(null);
561
696
  var ExperimentContext = React.createContext({});
562
697
  function useExperiment(id) {
@@ -609,6 +744,7 @@ function usePageExitTimer(tracker, currentKey) {
609
744
  function FunnelView({
610
745
  pages,
611
746
  initialKey,
747
+ trustInitialKey = false,
612
748
  layout,
613
749
  fallback,
614
750
  prefetch: prefetchMode = "auto",
@@ -634,10 +770,10 @@ function FunnelView({
634
770
  [pages]
635
771
  );
636
772
  const seedRef = React.useRef(null);
637
- if (seedRef.current === null) seedRef.current = chunkJSRKA375_cjs.bucketingSeed(funnel.context);
773
+ if (seedRef.current === null) seedRef.current = chunkG44BUG6G_cjs.bucketingSeed(funnel.context);
638
774
  const seed = seedRef.current;
639
775
  const experiments = React.useMemo(
640
- () => chunkJSRKA375_cjs.resolveExperiments(pages, funnel.experiments, seed),
776
+ () => chunkG44BUG6G_cjs.resolveExperiments(pages, funnel.experiments, seed),
641
777
  [pages, funnel.experiments, seed]
642
778
  );
643
779
  const toSlot = React.useCallback((k) => experiments.slotOf[k] ?? k, [experiments]);
@@ -656,8 +792,9 @@ function FunnelView({
656
792
  if (!initialKey || initialKey === start) return start ? [start] : [];
657
793
  const target = toSlot(initialKey);
658
794
  const page2 = flowPages.find((p) => p.key === target);
659
- const guard = chunkJSRKA375_cjs.entryGuard(page2?.meta);
660
- const ok = page2 && (!guard || chunkJSRKA375_cjs.evaluateGate(guard, funnel.snapshot()));
795
+ if (trustInitialKey) return page2 ? [target] : start ? [start] : [];
796
+ const guard = chunkG44BUG6G_cjs.entryGuard(page2?.meta);
797
+ const ok = page2 && (!guard || chunkG44BUG6G_cjs.evaluateGate(guard, funnel.snapshot()));
661
798
  const first = ok ? target : start;
662
799
  return first ? [first] : [];
663
800
  });
@@ -665,7 +802,7 @@ function FunnelView({
665
802
  const index = history.length - 1;
666
803
  const startKey = history[0];
667
804
  const total = React.useMemo(
668
- () => chunkJSRKA375_cjs.expectedPathLength(flow, startKey, funnel.snapshot()),
805
+ () => chunkG44BUG6G_cjs.expectedPathLength(flow, startKey, funnel.snapshot()),
669
806
  // currentKey in deps: re-trace as each step's answers settle the branch.
670
807
  [flow, startKey, currentKey, funnel]
671
808
  );
@@ -700,7 +837,7 @@ function FunnelView({
700
837
  usePageExitTimer(tracker, currentKey);
701
838
  const [isNavigating, startNav] = React.useTransition();
702
839
  const next = React.useCallback(() => {
703
- const target = chunkJSRKA375_cjs.nextPage(flow, currentKey, funnel.snapshot());
840
+ const target = chunkG44BUG6G_cjs.nextPage(flow, currentKey, funnel.snapshot());
704
841
  const resolved = target ? toSlot(target) : target;
705
842
  if (resolved) startNav(() => setHistory((h) => [...h, resolved]));
706
843
  }, [flow, currentKey, funnel, toSlot]);
@@ -724,7 +861,7 @@ function FunnelView({
724
861
  [loaders, toRenderKey]
725
862
  );
726
863
  const nextCandidates = React.useMemo(
727
- () => [...new Set(chunkJSRKA375_cjs.outgoingKeys(flow, currentKey).map(toRenderKey))],
864
+ () => [...new Set(chunkG44BUG6G_cjs.outgoingKeys(flow, currentKey).map(toRenderKey))],
728
865
  [flow, currentKey, toRenderKey]
729
866
  );
730
867
  React.useEffect(() => {
@@ -741,6 +878,44 @@ function FunnelView({
741
878
  canGoBack: history.length > 1,
742
879
  isNavigating
743
880
  };
881
+ const bus = useBusInternal();
882
+ const navRef = React.useRef(value);
883
+ navRef.current = value;
884
+ React.useEffect(() => {
885
+ if (!bus) return;
886
+ const control = {
887
+ goTo: (key) => {
888
+ if (!components.has(toRenderKey(key))) return false;
889
+ navRef.current.go(key);
890
+ return true;
891
+ },
892
+ goNext: () => navRef.current.next(),
893
+ goPrevious: () => navRef.current.back(),
894
+ snapshot: () => {
895
+ const v = navRef.current;
896
+ return {
897
+ key: v.page.key,
898
+ index: v.page.index,
899
+ total: v.page.total,
900
+ progressPercentage: v.page.progressPercentage,
901
+ canGoBack: v.canGoBack,
902
+ nextCandidates: v.nextCandidates
903
+ };
904
+ }
905
+ };
906
+ return bus.registerNavigation(control);
907
+ }, [bus]);
908
+ React.useEffect(() => {
909
+ const v = navRef.current;
910
+ bus?.emit("navigation", {
911
+ key: v.page.key,
912
+ index: v.page.index,
913
+ total: v.page.total,
914
+ progressPercentage: v.page.progressPercentage,
915
+ canGoBack: v.canGoBack,
916
+ nextCandidates: v.nextCandidates
917
+ });
918
+ }, [bus, currentKey]);
744
919
  const renderKey = toRenderKey(currentKey);
745
920
  const Current = components.get(renderKey);
746
921
  const pageEl = React.createElement(React.Suspense, { fallback: fallback ?? null }, Current ? React.createElement(Current) : null);
@@ -756,6 +931,81 @@ function useNavigation() {
756
931
  if (!ctx) throw new Error("useNavigation must be used inside <FunnelView>");
757
932
  return ctx;
758
933
  }
934
+ var EMBED_CAPABILITIES = {
935
+ methods: ["nav.snapshot", "nav.goTo", "nav.goNext", "nav.goPrevious", "screenshot"],
936
+ events: ["navigation"]
937
+ };
938
+ function EmbedBridge() {
939
+ const bus = useBusInternal();
940
+ React.useEffect(() => {
941
+ if (!bus || typeof window === "undefined" || window.parent === window) return;
942
+ const parent = window.parent;
943
+ let disposed = false;
944
+ const send = (msg) => {
945
+ try {
946
+ parent.postMessage({ af: chunkWYUDL4FI_cjs.AF_PROTOCOL, source: "af-preview", ...msg }, "*");
947
+ } catch {
948
+ }
949
+ };
950
+ const hello = () => send({ kind: "hello", role: "funnel", protocol: chunkWYUDL4FI_cjs.AF_PROTOCOL, capabilities: EMBED_CAPABILITIES });
951
+ const sendSnapshot = () => {
952
+ const s = bus.navigation();
953
+ if (s) send({ kind: "event", event: "navigation", data: s });
954
+ };
955
+ async function invoke(method, params) {
956
+ switch (method) {
957
+ case "nav.snapshot":
958
+ return bus.navigation();
959
+ case "nav.goTo": {
960
+ const key = params?.key;
961
+ if (typeof key !== "string" || !bus.goTo(key)) throw { code: "bad_params", message: `unknown page key: ${String(key)}` };
962
+ return void 0;
963
+ }
964
+ case "nav.goNext":
965
+ bus.goNext();
966
+ return void 0;
967
+ case "nav.goPrevious":
968
+ bus.goPrevious();
969
+ return void 0;
970
+ case "screenshot":
971
+ return await captureScreenshot(params ?? {});
972
+ default:
973
+ throw { code: "unknown_method", message: `unknown method: ${method}` };
974
+ }
975
+ }
976
+ async function onMsg(e) {
977
+ if (e.source !== parent) return;
978
+ const d = e.data;
979
+ if (!d || typeof d !== "object" || d.af !== chunkWYUDL4FI_cjs.AF_PROTOCOL || d.source !== "af-host") return;
980
+ if (d.kind === "hello") {
981
+ hello();
982
+ sendSnapshot();
983
+ return;
984
+ }
985
+ if (d.kind !== "request" || typeof d.id !== "string") return;
986
+ try {
987
+ const result = await invoke(d.method, d.params);
988
+ if (!disposed) send({ kind: "response", id: d.id, ok: true, result });
989
+ } catch (err) {
990
+ const e2 = err;
991
+ const error = e2 && typeof e2.code === "string" ? { code: e2.code, message: String(e2.message ?? e2.code) } : { code: "failed", message: String(e2?.message ?? err) };
992
+ if (!disposed) send({ kind: "response", id: d.id, ok: false, error });
993
+ }
994
+ }
995
+ window.addEventListener("message", onMsg);
996
+ const offNav = bus.on("navigation", (data) => {
997
+ if (!disposed) send({ kind: "event", event: "navigation", data });
998
+ });
999
+ hello();
1000
+ sendSnapshot();
1001
+ return () => {
1002
+ disposed = true;
1003
+ offNav();
1004
+ window.removeEventListener("message", onMsg);
1005
+ };
1006
+ }, [bus]);
1007
+ return null;
1008
+ }
759
1009
  function usePage() {
760
1010
  return useNavigation().page;
761
1011
  }
@@ -1072,7 +1322,7 @@ function Modal(props) {
1072
1322
  // src/commerce/checkout.tsx
1073
1323
  function createMockDriver(provider = "stripe", options = {}) {
1074
1324
  const success = options.result ?? { ok: true, amountMinor: 0, currency: "USD" };
1075
- const offError = typeof options.failOffSession === "object" ? options.failOffSession : chunkLJYLGLFS_cjs.checkoutError("authentication_required", "off-session charge declined (mock)");
1325
+ const offError = typeof options.failOffSession === "object" ? options.failOffSession : chunkQMAZGLGV_cjs.checkoutError("authentication_required", "off-session charge declined (mock)");
1076
1326
  return {
1077
1327
  provider,
1078
1328
  start: (req) => {
@@ -1087,7 +1337,7 @@ function createMockDriver(provider = "stripe", options = {}) {
1087
1337
  onClick: () => {
1088
1338
  cb.onStart?.();
1089
1339
  if (success.ok) cb.onSuccess(success);
1090
- else cb.onError(success.error ?? chunkLJYLGLFS_cjs.checkoutError("processing_error", "failed (mock)"));
1340
+ else cb.onError(success.error ?? chunkQMAZGLGV_cjs.checkoutError("processing_error", "failed (mock)"));
1091
1341
  }
1092
1342
  },
1093
1343
  `Pay (mock ${req.surface})`
@@ -1125,12 +1375,25 @@ var FALLBACK_DRIVER = createMockDriver();
1125
1375
  function useCheckout(opts = {}) {
1126
1376
  const driver = useDriver();
1127
1377
  const tracker = useTrackerRef();
1378
+ const catalog = useCatalog();
1128
1379
  const nav = useNavigation();
1129
1380
  const [status, setStatus] = React.useState("idle");
1130
1381
  const [error, setError] = React.useState(null);
1131
1382
  const intent = opts.intent ?? "purchase";
1132
1383
  const kind = opts.kind;
1133
1384
  const advance = opts.advanceOnSuccess ?? true;
1385
+ const productFacts = React.useCallback(
1386
+ (product) => {
1387
+ const resolved = product ? catalog.get(product) : void 0;
1388
+ return {
1389
+ productId: resolved?.catalogKey ?? product,
1390
+ amount: resolved ? resolved.priceMinor / 100 : void 0,
1391
+ currency: resolved?.currency,
1392
+ isSubscription: resolved ? resolved.period !== "one-time" : kind === "subscription" || kind === "upgrade"
1393
+ };
1394
+ },
1395
+ [catalog, kind]
1396
+ );
1134
1397
  const recovering = React.useRef(false);
1135
1398
  const failRef = React.useRef(() => {
1136
1399
  });
@@ -1138,18 +1401,24 @@ function useCheckout(opts = {}) {
1138
1401
  async () => ({ ok: false })
1139
1402
  );
1140
1403
  const succeed = React.useCallback(
1141
- (result) => {
1404
+ (result, product) => {
1142
1405
  setStatus("success");
1406
+ const { productId, isSubscription } = productFacts(product);
1407
+ const amount = result.amountMinor != null ? result.amountMinor / 100 : void 0;
1143
1408
  tracker.track("purchase.complete", {
1144
- amount: result.amountMinor != null ? result.amountMinor / 100 : void 0,
1409
+ amount,
1145
1410
  currency: result.currency,
1411
+ productId,
1146
1412
  eventId: result.eventId
1147
1413
  // server-minted (browser↔CAPI dedup); undefined if none
1148
1414
  });
1415
+ if (isSubscription) {
1416
+ tracker.track("subscription.created", { amount, currency: result.currency, productId, eventId: result.eventId });
1417
+ }
1149
1418
  opts.onSuccess?.(result);
1150
1419
  if (advance) nav.next();
1151
1420
  },
1152
- [tracker, nav, advance, opts]
1421
+ [tracker, nav, advance, opts, productFacts]
1153
1422
  );
1154
1423
  const succeedRef = React.useRef(succeed);
1155
1424
  succeedRef.current = succeed;
@@ -1157,12 +1426,19 @@ function useCheckout(opts = {}) {
1157
1426
  (product, surface) => {
1158
1427
  setStatus("loading");
1159
1428
  setError(null);
1160
- tracker.track("checkout.start", { productId: product, surface });
1429
+ const { productId, amount, currency } = productFacts(product);
1430
+ tracker.track("checkout.start", { productId, amount, currency, surface, eventId: newEventId() });
1161
1431
  },
1162
- [tracker]
1432
+ [tracker, productFacts]
1433
+ );
1434
+ const paymentAdded = React.useCallback(
1435
+ (product) => {
1436
+ const { productId, amount, currency } = productFacts(product);
1437
+ tracker.track("checkout.payment_added", { productId, amount, currency, eventId: newEventId() });
1438
+ },
1439
+ [tracker, productFacts]
1163
1440
  );
1164
- const paymentAdded = React.useCallback(() => tracker.track("checkout.payment_added", {}), [tracker]);
1165
- const hostInSheet = (surface) => surface === "sheet" || chunkLJYLGLFS_cjs.isInlineSurface(surface) && !!chunkLJYLGLFS_cjs.PROVIDER_PROFILES[driver.provider]?.surfaces.sheet;
1441
+ const hostInSheet = (surface) => surface === "sheet" || chunkQMAZGLGV_cjs.isInlineSurface(surface) && !!chunkQMAZGLGV_cjs.PROVIDER_PROFILES[driver.provider]?.surfaces.sheet;
1166
1442
  const startRecovery = (product, surface) => {
1167
1443
  recovering.current = true;
1168
1444
  if (hostInSheet(surface)) {
@@ -1172,9 +1448,9 @@ function useCheckout(opts = {}) {
1172
1448
  surface: "sheet",
1173
1449
  intent,
1174
1450
  kind,
1175
- onSuccess: (r) => succeedRef.current(r),
1451
+ onSuccess: (r) => succeedRef.current(r, product),
1176
1452
  onError: (e) => failRef.current(e, product),
1177
- onPaymentAdded: () => paymentAdded()
1453
+ onPaymentAdded: () => paymentAdded(product)
1178
1454
  });
1179
1455
  } else {
1180
1456
  void attemptRef.current(product, surface);
@@ -1213,7 +1489,7 @@ function useCheckout(opts = {}) {
1213
1489
  recovering.current = true;
1214
1490
  if (!surface) {
1215
1491
  if (intent === "upsell") void attemptRef.current(product);
1216
- else startRecovery(product, chunkLJYLGLFS_cjs.PROVIDER_PROFILES[driver.provider]?.surfaces.sheet ? "sheet" : "popup");
1492
+ else startRecovery(product, chunkQMAZGLGV_cjs.PROVIDER_PROFILES[driver.provider]?.surfaces.sheet ? "sheet" : "popup");
1217
1493
  return;
1218
1494
  }
1219
1495
  startRecovery(product, surface);
@@ -1228,11 +1504,11 @@ function useCheckout(opts = {}) {
1228
1504
  begin(product, surface);
1229
1505
  try {
1230
1506
  const result = await driver.start({ product, intent, surface, kind });
1231
- if (result.ok) succeedRef.current(result);
1232
- else failRef.current(result.error ?? chunkLJYLGLFS_cjs.checkoutError("unknown", "Checkout failed"), product);
1507
+ if (result.ok) succeedRef.current(result, product);
1508
+ else failRef.current(result.error ?? chunkQMAZGLGV_cjs.checkoutError("unknown", "Checkout failed"), product);
1233
1509
  return result;
1234
1510
  } catch (e) {
1235
- const err = chunkLJYLGLFS_cjs.checkoutError("processing_error", e instanceof Error ? e.message : "Checkout failed");
1511
+ const err = chunkQMAZGLGV_cjs.checkoutError("processing_error", e instanceof Error ? e.message : "Checkout failed");
1236
1512
  failRef.current(err, product);
1237
1513
  return { ok: false, error: err };
1238
1514
  }
@@ -1247,9 +1523,9 @@ function useCheckout(opts = {}) {
1247
1523
  recovering.current = false;
1248
1524
  begin(product, surface);
1249
1525
  },
1250
- onSuccess: (result) => succeedRef.current(result),
1526
+ onSuccess: (result) => succeedRef.current(result, product),
1251
1527
  onError: (err) => failRef.current(err, product),
1252
- onPaymentAdded: () => paymentAdded()
1528
+ onPaymentAdded: () => paymentAdded(product)
1253
1529
  }),
1254
1530
  [begin, paymentAdded]
1255
1531
  );
@@ -1271,7 +1547,7 @@ var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, on
1271
1547
  if (!hostable) {
1272
1548
  resolved.current = true;
1273
1549
  onErrorRef.current(
1274
- chunkLJYLGLFS_cjs.checkoutError("processing_error", "This checkout driver has no inline surface to host in the sheet")
1550
+ chunkQMAZGLGV_cjs.checkoutError("processing_error", "This checkout driver has no inline surface to host in the sheet")
1275
1551
  );
1276
1552
  void modal.hide();
1277
1553
  modal.remove();
@@ -1279,7 +1555,7 @@ var CheckoutSheet = defineModal(({ product, surface, intent, kind, onSuccess, on
1279
1555
  }
1280
1556
  return () => {
1281
1557
  if (!resolved.current) {
1282
- onErrorRef.current(chunkLJYLGLFS_cjs.checkoutError("canceled", "Checkout was dismissed before completing"));
1558
+ onErrorRef.current(chunkQMAZGLGV_cjs.checkoutError("canceled", "Checkout was dismissed before completing"));
1283
1559
  }
1284
1560
  };
1285
1561
  }, []);
@@ -1324,7 +1600,7 @@ function Checkout({
1324
1600
  const driver = useDriver();
1325
1601
  const checkout = useCheckout(options);
1326
1602
  const intent = options.intent ?? "purchase";
1327
- if (chunkLJYLGLFS_cjs.isInlineSurface(surface)) {
1603
+ if (chunkQMAZGLGV_cjs.isInlineSurface(surface)) {
1328
1604
  return driver.renderInline ? React.createElement(
1329
1605
  "div",
1330
1606
  { key: product, className },
@@ -1386,7 +1662,7 @@ function CheckoutResume(options = {}) {
1386
1662
  window.history.replaceState(window.history.state, "", url.toString());
1387
1663
  cb.onSuccess(result);
1388
1664
  } else {
1389
- cb.onError(result.error ?? chunkLJYLGLFS_cjs.checkoutError("unknown", "The checkout could not be verified"));
1665
+ cb.onError(result.error ?? chunkQMAZGLGV_cjs.checkoutError("unknown", "The checkout could not be verified"));
1390
1666
  }
1391
1667
  });
1392
1668
  }, []);
@@ -2547,6 +2823,7 @@ var FunnelCtx = React.createContext(null);
2547
2823
  function FunnelProvider({
2548
2824
  config,
2549
2825
  sessionValues,
2826
+ deferSessionValues = false,
2550
2827
  tracker,
2551
2828
  context: contextOpts,
2552
2829
  products,
@@ -2562,7 +2839,12 @@ function FunnelProvider({
2562
2839
  const [value] = React.useState(() => {
2563
2840
  const s = store ?? createFunnelStore(
2564
2841
  { responses: config?.responses, data: config?.data },
2565
- sessionValues
2842
+ // FLASH-FREE HYDRATION: with deferSessionValues the initial render is seeded with
2843
+ // DEFAULTS ONLY, so the client's first render is byte-identical to the build-time
2844
+ // DEFAULT-state prerender it hydrates against (clean match). The visitor's saved
2845
+ // answers arrive as a post-hydration setMany below. Without the flag, sessionValues
2846
+ // seed the store at construction (SSR + non-prerendered paths).
2847
+ deferSessionValues ? void 0 : sessionValues
2566
2848
  );
2567
2849
  const ctx = buildContext({
2568
2850
  funnelId: config?.id,
@@ -2580,7 +2862,7 @@ function FunnelProvider({
2580
2862
  const value2 = s.get("user.email");
2581
2863
  return typeof value2 === "string" && /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(value2) ? value2 : void 0;
2582
2864
  };
2583
- const catalog = chunkJSRKA375_cjs.buildCatalog(products ?? []);
2865
+ const catalog = chunkG44BUG6G_cjs.buildCatalog(products ?? []);
2584
2866
  return {
2585
2867
  funnel: createFunnel(s, ctx, busTracker, experiments ?? []),
2586
2868
  store: s,
@@ -2594,6 +2876,12 @@ function FunnelProvider({
2594
2876
  };
2595
2877
  });
2596
2878
  React.useEffect(() => attachBus(value.bus), [value.bus]);
2879
+ React.useEffect(() => {
2880
+ if (!deferSessionValues || !sessionValues) return;
2881
+ const updates = {};
2882
+ for (const [key, v] of Object.entries(sessionValues)) if (v !== void 0) updates[key] = v;
2883
+ if (Object.keys(updates).length > 0) value.store.setMany(updates);
2884
+ }, []);
2597
2885
  React.useEffect(() => {
2598
2886
  value.tracker.setAcquisition?.(buildAcquisition(value.context));
2599
2887
  }, [value]);
@@ -2629,6 +2917,9 @@ function useFunnelCtx() {
2629
2917
  function useFunnel() {
2630
2918
  return useFunnelCtx().funnel;
2631
2919
  }
2920
+ function useBusInternal() {
2921
+ return React.useContext(FunnelCtx)?.bus ?? null;
2922
+ }
2632
2923
  function useStoreKey(store, key) {
2633
2924
  const subscribe = React.useCallback(
2634
2925
  (cb) => store.subscribe(cb, { keys: [key] }),
@@ -2692,6 +2983,152 @@ function useContextValue(path) {
2692
2983
  );
2693
2984
  }
2694
2985
 
2986
+ // src/tracking/snapshotPersistence.ts
2987
+ function createSnapshotPersistence(opts) {
2988
+ const baseDelay = opts.baseDelayMs ?? 1e3;
2989
+ const maxDelay = opts.maxDelayMs ?? 3e4;
2990
+ const setT = opts.timers?.setTimeout ?? ((fn, ms) => setTimeout(fn, ms));
2991
+ const clearT = opts.timers?.clearTimeout ?? ((h) => clearTimeout(h));
2992
+ const rand = opts.random ?? Math.random;
2993
+ let pending = null;
2994
+ let seq = 0;
2995
+ let pendingSeq = 0;
2996
+ let inFlight = false;
2997
+ let attempt = 0;
2998
+ let retryTimer = null;
2999
+ let disposed = false;
3000
+ let fatalSeq = -1;
3001
+ const clearRetry = () => {
3002
+ if (retryTimer !== null) {
3003
+ clearT(retryTimer);
3004
+ retryTimer = null;
3005
+ }
3006
+ };
3007
+ const buildBody = (snapshot, s) => JSON.stringify({ sessionId: opts.getSessionId(), userData: snapshot, seq: s });
3008
+ const trySend = () => {
3009
+ if (disposed || inFlight || pending === null) return;
3010
+ if (retryTimer !== null) return;
3011
+ const sessionId = opts.getSessionId();
3012
+ if (!sessionId) return;
3013
+ if (typeof navigator !== "undefined" && navigator.onLine === false) return;
3014
+ if (pendingSeq === fatalSeq) return;
3015
+ const snapshot = pending;
3016
+ const sentSeq = pendingSeq;
3017
+ const body = buildBody(snapshot, sentSeq);
3018
+ inFlight = true;
3019
+ void fetch(opts.url, {
3020
+ method: "POST",
3021
+ headers: { "content-type": "application/json" },
3022
+ body,
3023
+ keepalive: true
3024
+ }).then((res) => {
3025
+ inFlight = false;
3026
+ if (disposed) return;
3027
+ if (res.ok) {
3028
+ attempt = 0;
3029
+ if (pendingSeq === sentSeq) pending = null;
3030
+ else trySend();
3031
+ return;
3032
+ }
3033
+ if (res.status >= 400 && res.status < 500) {
3034
+ if (process.env.NODE_ENV !== "production") {
3035
+ console.warn(
3036
+ `[appfunnel] snapshot persist rejected ${res.status} (dropping snapshot; check session/payload)`
3037
+ );
3038
+ }
3039
+ fatalSeq = sentSeq;
3040
+ if (pendingSeq === sentSeq) pending = null;
3041
+ else trySend();
3042
+ return;
3043
+ }
3044
+ scheduleRetry();
3045
+ }).catch(() => {
3046
+ inFlight = false;
3047
+ if (disposed) return;
3048
+ scheduleRetry();
3049
+ });
3050
+ };
3051
+ const scheduleRetry = () => {
3052
+ if (disposed || pending === null) return;
3053
+ const exp = Math.min(maxDelay, baseDelay * 2 ** attempt);
3054
+ const delay2 = Math.round(exp * (0.5 + rand() * 0.5));
3055
+ attempt++;
3056
+ clearRetry();
3057
+ retryTimer = setT(() => {
3058
+ retryTimer = null;
3059
+ trySend();
3060
+ }, delay2);
3061
+ };
3062
+ const push = (snapshot) => {
3063
+ if (disposed) return;
3064
+ pending = snapshot;
3065
+ pendingSeq = ++seq;
3066
+ if (fatalSeq !== -1 && pendingSeq !== fatalSeq) fatalSeq = -1;
3067
+ if (retryTimer === null) trySend();
3068
+ };
3069
+ const flushBeacon = () => {
3070
+ if (disposed || pending === null) return;
3071
+ const sessionId = opts.getSessionId();
3072
+ if (!sessionId) return;
3073
+ const body = buildBody(pending, pendingSeq);
3074
+ let delivered = false;
3075
+ if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function") {
3076
+ try {
3077
+ delivered = navigator.sendBeacon(
3078
+ opts.url,
3079
+ new Blob([body], { type: "application/json" })
3080
+ );
3081
+ } catch {
3082
+ delivered = false;
3083
+ }
3084
+ }
3085
+ if (!delivered) {
3086
+ try {
3087
+ void fetch(opts.url, {
3088
+ method: "POST",
3089
+ headers: { "content-type": "application/json" },
3090
+ body,
3091
+ keepalive: true
3092
+ }).catch(() => {
3093
+ });
3094
+ delivered = true;
3095
+ } catch {
3096
+ delivered = false;
3097
+ }
3098
+ }
3099
+ if (delivered) pending = null;
3100
+ };
3101
+ const onHidden = () => {
3102
+ if (typeof document !== "undefined" && document.visibilityState === "hidden") {
3103
+ flushBeacon();
3104
+ }
3105
+ };
3106
+ const onPageHide = () => flushBeacon();
3107
+ const onOnline = () => trySend();
3108
+ if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
3109
+ try {
3110
+ document.addEventListener("visibilitychange", onHidden);
3111
+ window.addEventListener("pagehide", onPageHide);
3112
+ window.addEventListener("online", onOnline);
3113
+ } catch {
3114
+ }
3115
+ }
3116
+ const dispose = () => {
3117
+ disposed = true;
3118
+ clearRetry();
3119
+ pending = null;
3120
+ if (typeof window !== "undefined" && typeof window.removeEventListener === "function") {
3121
+ try {
3122
+ document.removeEventListener("visibilitychange", onHidden);
3123
+ window.removeEventListener("pagehide", onPageHide);
3124
+ window.removeEventListener("online", onOnline);
3125
+ } catch {
3126
+ }
3127
+ }
3128
+ };
3129
+ return { push, flushBeacon, dispose };
3130
+ }
3131
+
2695
3132
  // src/tracking/platformTracker.ts
2696
3133
  function validClickIds(acq) {
2697
3134
  return Object.entries(acq.clickIds ?? {}).filter(
@@ -2797,32 +3234,35 @@ function createPlatformTracker(cfg) {
2797
3234
  }
2798
3235
  };
2799
3236
  const VARS_DEBOUNCE_MS = 800;
3237
+ const dataUrl = `${base}/campaign/${encodeURIComponent(cfg.campaignId)}/event/session/data`;
2800
3238
  let pendingVars = null;
2801
3239
  let varsTimer = null;
3240
+ const persistence = createSnapshotPersistence({
3241
+ url: dataUrl,
3242
+ getSessionId: () => sessionId
3243
+ });
2802
3244
  const flushVars = () => {
2803
3245
  if (varsTimer) {
2804
3246
  clearTimeout(varsTimer);
2805
3247
  varsTimer = null;
2806
3248
  }
2807
3249
  if (!pendingVars) return;
2808
- const doPost = () => {
2809
- if (!pendingVars || !sessionId) return;
2810
- const userData = pendingVars;
2811
- pendingVars = null;
2812
- void fetch(`${base}/campaign/${encodeURIComponent(cfg.campaignId)}/event/session/data`, {
2813
- method: "POST",
2814
- headers: { "content-type": "application/json" },
2815
- body: JSON.stringify({ sessionId, userData }),
2816
- keepalive: true
2817
- }).catch((e) => {
2818
- if (process.env.NODE_ENV !== "production") console.warn("[appfunnel] variable persist failed:", e);
2819
- });
2820
- };
2821
- if (sessionId) doPost();
2822
- else chain = chain.then(doPost);
3250
+ const snapshot = pendingVars;
3251
+ pendingVars = null;
3252
+ persistence.push(snapshot);
3253
+ if (!sessionId) chain = chain.then(() => {
3254
+ persistence.push(snapshot);
3255
+ });
3256
+ };
3257
+ const drainOnExit = () => {
3258
+ if (pendingVars) {
3259
+ flushVars();
3260
+ persistence.flushBeacon();
3261
+ }
2823
3262
  };
2824
3263
  try {
2825
- window.addEventListener("pagehide", flushVars);
3264
+ window.addEventListener("visibilitychange", drainOnExit);
3265
+ window.addEventListener("pagehide", drainOnExit);
2826
3266
  } catch {
2827
3267
  }
2828
3268
  if (cfg.experiment?.id && cfg.experiment.variant) {
@@ -2865,6 +3305,7 @@ function createFunnelTree({
2865
3305
  }) {
2866
3306
  return function tree(opts) {
2867
3307
  const mode = opts.mode ?? "live";
3308
+ const embedEnabled = opts.embed ?? false;
2868
3309
  const tracker = opts.tracking ? createPlatformTracker({
2869
3310
  ...opts.tracking,
2870
3311
  visitorId: opts.visitorId,
@@ -2886,6 +3327,7 @@ function createFunnelTree({
2886
3327
  React.Fragment,
2887
3328
  null,
2888
3329
  React.createElement(CheckoutResume, null),
3330
+ embedEnabled ? React.createElement(EmbedBridge, null) : null,
2889
3331
  layout ? React.createElement(layout, null, children) : children
2890
3332
  );
2891
3333
  };
@@ -2899,6 +3341,7 @@ function createFunnelTree({
2899
3341
  tracker,
2900
3342
  checkout,
2901
3343
  sessionValues: opts.sessionValues,
3344
+ deferSessionValues: opts.deferSessionValues,
2902
3345
  experiments: opts.experiments,
2903
3346
  context: {
2904
3347
  mode,
@@ -2910,6 +3353,13 @@ function createFunnelTree({
2910
3353
  pages,
2911
3354
  layout: layoutWithResume,
2912
3355
  initialKey: opts.initialKey,
3356
+ // FLASH-FREE HYDRATION (Option B, FIX 1): trust the SERVER-resolved initialKey instead of
3357
+ // re-running the entry guard. The CLIENT sets this via deferSessionValues (its deferred
3358
+ // snapshot is empty, so re-running the guard would bounce a qualified deep-link and
3359
+ // mismatch the markup). The build-time PRERENDER sets `trustInitialKey` explicitly so a
3360
+ // guarded page prerenders its OWN default-state markup (the renderer picks target-vs-bounce
3361
+ // at serve time). Live SSR fallback leaves both off → the guard runs against real values.
3362
+ trustInitialKey: opts.trustInitialKey ?? opts.deferSessionValues,
2913
3363
  prefetch: "off"
2914
3364
  // renderer background-modulepreloads all chunks
2915
3365
  })
@@ -3058,147 +3508,147 @@ function Script({
3058
3508
 
3059
3509
  Object.defineProperty(exports, "assignVariant", {
3060
3510
  enumerable: true,
3061
- get: function () { return chunkJSRKA375_cjs.assignVariant; }
3511
+ get: function () { return chunkG44BUG6G_cjs.assignVariant; }
3062
3512
  });
3063
3513
  Object.defineProperty(exports, "bucketingSeed", {
3064
3514
  enumerable: true,
3065
- get: function () { return chunkJSRKA375_cjs.bucketingSeed; }
3515
+ get: function () { return chunkG44BUG6G_cjs.bucketingSeed; }
3066
3516
  });
3067
3517
  Object.defineProperty(exports, "buildCatalog", {
3068
3518
  enumerable: true,
3069
- get: function () { return chunkJSRKA375_cjs.buildCatalog; }
3519
+ get: function () { return chunkG44BUG6G_cjs.buildCatalog; }
3070
3520
  });
3071
3521
  Object.defineProperty(exports, "compileManifest", {
3072
3522
  enumerable: true,
3073
- get: function () { return chunkJSRKA375_cjs.compileManifest; }
3523
+ get: function () { return chunkG44BUG6G_cjs.compileManifest; }
3074
3524
  });
3075
3525
  Object.defineProperty(exports, "currencyExponent", {
3076
3526
  enumerable: true,
3077
- get: function () { return chunkJSRKA375_cjs.currencyExponent; }
3527
+ get: function () { return chunkG44BUG6G_cjs.currencyExponent; }
3078
3528
  });
3079
3529
  Object.defineProperty(exports, "defineFunnel", {
3080
3530
  enumerable: true,
3081
- get: function () { return chunkJSRKA375_cjs.defineFunnel; }
3531
+ get: function () { return chunkG44BUG6G_cjs.defineFunnel; }
3082
3532
  });
3083
3533
  Object.defineProperty(exports, "definePage", {
3084
3534
  enumerable: true,
3085
- get: function () { return chunkJSRKA375_cjs.definePage; }
3535
+ get: function () { return chunkG44BUG6G_cjs.definePage; }
3086
3536
  });
3087
3537
  Object.defineProperty(exports, "entryGuard", {
3088
3538
  enumerable: true,
3089
- get: function () { return chunkJSRKA375_cjs.entryGuard; }
3539
+ get: function () { return chunkG44BUG6G_cjs.entryGuard; }
3090
3540
  });
3091
3541
  Object.defineProperty(exports, "evaluateCondition", {
3092
3542
  enumerable: true,
3093
- get: function () { return chunkJSRKA375_cjs.evaluateCondition; }
3543
+ get: function () { return chunkG44BUG6G_cjs.evaluateCondition; }
3094
3544
  });
3095
3545
  Object.defineProperty(exports, "evaluateGate", {
3096
3546
  enumerable: true,
3097
- get: function () { return chunkJSRKA375_cjs.evaluateGate; }
3547
+ get: function () { return chunkG44BUG6G_cjs.evaluateGate; }
3098
3548
  });
3099
3549
  Object.defineProperty(exports, "expectedPathLength", {
3100
3550
  enumerable: true,
3101
- get: function () { return chunkJSRKA375_cjs.expectedPathLength; }
3551
+ get: function () { return chunkG44BUG6G_cjs.expectedPathLength; }
3102
3552
  });
3103
3553
  Object.defineProperty(exports, "fnv1a", {
3104
3554
  enumerable: true,
3105
- get: function () { return chunkJSRKA375_cjs.fnv1a; }
3555
+ get: function () { return chunkG44BUG6G_cjs.fnv1a; }
3106
3556
  });
3107
3557
  Object.defineProperty(exports, "formatMoney", {
3108
3558
  enumerable: true,
3109
- get: function () { return chunkJSRKA375_cjs.formatMoney; }
3559
+ get: function () { return chunkG44BUG6G_cjs.formatMoney; }
3110
3560
  });
3111
3561
  Object.defineProperty(exports, "formatProduct", {
3112
3562
  enumerable: true,
3113
- get: function () { return chunkJSRKA375_cjs.formatProduct; }
3563
+ get: function () { return chunkG44BUG6G_cjs.formatProduct; }
3114
3564
  });
3115
3565
  Object.defineProperty(exports, "hashToUnit", {
3116
3566
  enumerable: true,
3117
- get: function () { return chunkJSRKA375_cjs.hashToUnit; }
3567
+ get: function () { return chunkG44BUG6G_cjs.hashToUnit; }
3118
3568
  });
3119
3569
  Object.defineProperty(exports, "isRtl", {
3120
3570
  enumerable: true,
3121
- get: function () { return chunkJSRKA375_cjs.isRtl; }
3571
+ get: function () { return chunkG44BUG6G_cjs.isRtl; }
3122
3572
  });
3123
3573
  Object.defineProperty(exports, "isVariantKey", {
3124
3574
  enumerable: true,
3125
- get: function () { return chunkJSRKA375_cjs.isVariantKey; }
3575
+ get: function () { return chunkG44BUG6G_cjs.isVariantKey; }
3126
3576
  });
3127
3577
  Object.defineProperty(exports, "nextPage", {
3128
3578
  enumerable: true,
3129
- get: function () { return chunkJSRKA375_cjs.nextPage; }
3579
+ get: function () { return chunkG44BUG6G_cjs.nextPage; }
3130
3580
  });
3131
3581
  Object.defineProperty(exports, "outgoingKeys", {
3132
3582
  enumerable: true,
3133
- get: function () { return chunkJSRKA375_cjs.outgoingKeys; }
3583
+ get: function () { return chunkG44BUG6G_cjs.outgoingKeys; }
3134
3584
  });
3135
3585
  Object.defineProperty(exports, "pageMeta", {
3136
3586
  enumerable: true,
3137
- get: function () { return chunkJSRKA375_cjs.pageMeta; }
3587
+ get: function () { return chunkG44BUG6G_cjs.pageMeta; }
3138
3588
  });
3139
3589
  Object.defineProperty(exports, "parseSlotKey", {
3140
3590
  enumerable: true,
3141
- get: function () { return chunkJSRKA375_cjs.parseSlotKey; }
3591
+ get: function () { return chunkG44BUG6G_cjs.parseSlotKey; }
3142
3592
  });
3143
3593
  Object.defineProperty(exports, "pickByWeight", {
3144
3594
  enumerable: true,
3145
- get: function () { return chunkJSRKA375_cjs.pickByWeight; }
3595
+ get: function () { return chunkG44BUG6G_cjs.pickByWeight; }
3146
3596
  });
3147
3597
  Object.defineProperty(exports, "resolveExperiments", {
3148
3598
  enumerable: true,
3149
- get: function () { return chunkJSRKA375_cjs.resolveExperiments; }
3599
+ get: function () { return chunkG44BUG6G_cjs.resolveExperiments; }
3150
3600
  });
3151
3601
  Object.defineProperty(exports, "resolveLocale", {
3152
3602
  enumerable: true,
3153
- get: function () { return chunkJSRKA375_cjs.resolveLocale; }
3603
+ get: function () { return chunkG44BUG6G_cjs.resolveLocale; }
3154
3604
  });
3155
3605
  Object.defineProperty(exports, "resolveProduct", {
3156
3606
  enumerable: true,
3157
- get: function () { return chunkJSRKA375_cjs.resolveProduct; }
3607
+ get: function () { return chunkG44BUG6G_cjs.resolveProduct; }
3158
3608
  });
3159
3609
  Object.defineProperty(exports, "resolveRoute", {
3160
3610
  enumerable: true,
3161
- get: function () { return chunkJSRKA375_cjs.resolveRoute; }
3611
+ get: function () { return chunkG44BUG6G_cjs.resolveRoute; }
3162
3612
  });
3163
3613
  Object.defineProperty(exports, "validateExperiments", {
3164
3614
  enumerable: true,
3165
- get: function () { return chunkJSRKA375_cjs.validateExperiments; }
3615
+ get: function () { return chunkG44BUG6G_cjs.validateExperiments; }
3166
3616
  });
3167
3617
  Object.defineProperty(exports, "INLINE_SURFACES", {
3168
3618
  enumerable: true,
3169
- get: function () { return chunkLJYLGLFS_cjs.INLINE_SURFACES; }
3619
+ get: function () { return chunkQMAZGLGV_cjs.INLINE_SURFACES; }
3170
3620
  });
3171
3621
  Object.defineProperty(exports, "PROVIDER_PROFILES", {
3172
3622
  enumerable: true,
3173
- get: function () { return chunkLJYLGLFS_cjs.PROVIDER_PROFILES; }
3623
+ get: function () { return chunkQMAZGLGV_cjs.PROVIDER_PROFILES; }
3174
3624
  });
3175
3625
  Object.defineProperty(exports, "checkoutError", {
3176
3626
  enumerable: true,
3177
- get: function () { return chunkLJYLGLFS_cjs.checkoutError; }
3627
+ get: function () { return chunkQMAZGLGV_cjs.checkoutError; }
3178
3628
  });
3179
3629
  Object.defineProperty(exports, "isInlineSurface", {
3180
3630
  enumerable: true,
3181
- get: function () { return chunkLJYLGLFS_cjs.isInlineSurface; }
3631
+ get: function () { return chunkQMAZGLGV_cjs.isInlineSurface; }
3182
3632
  });
3183
3633
  Object.defineProperty(exports, "isMerchantOfRecord", {
3184
3634
  enumerable: true,
3185
- get: function () { return chunkLJYLGLFS_cjs.isMerchantOfRecord; }
3635
+ get: function () { return chunkQMAZGLGV_cjs.isMerchantOfRecord; }
3186
3636
  });
3187
3637
  Object.defineProperty(exports, "isOrchestrator", {
3188
3638
  enumerable: true,
3189
- get: function () { return chunkLJYLGLFS_cjs.isOrchestrator; }
3639
+ get: function () { return chunkQMAZGLGV_cjs.isOrchestrator; }
3190
3640
  });
3191
3641
  Object.defineProperty(exports, "surfacesFor", {
3192
3642
  enumerable: true,
3193
- get: function () { return chunkLJYLGLFS_cjs.surfacesFor; }
3643
+ get: function () { return chunkQMAZGLGV_cjs.surfacesFor; }
3194
3644
  });
3195
3645
  Object.defineProperty(exports, "validateCheckout", {
3196
3646
  enumerable: true,
3197
- get: function () { return chunkLJYLGLFS_cjs.validateCheckout; }
3647
+ get: function () { return chunkQMAZGLGV_cjs.validateCheckout; }
3198
3648
  });
3199
3649
  Object.defineProperty(exports, "validateUpsell", {
3200
3650
  enumerable: true,
3201
- get: function () { return chunkLJYLGLFS_cjs.validateUpsell; }
3651
+ get: function () { return chunkQMAZGLGV_cjs.validateUpsell; }
3202
3652
  });
3203
3653
  exports.AssetsContext = AssetsContext;
3204
3654
  exports.AssetsProvider = AssetsProvider;