@gemx-dev/heatmap-react 3.5.92-dev.16 → 3.5.92-dev.19

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 (134) hide show
  1. package/dist/esm/components/VizDom/VizDomHeatmap.d.ts.map +1 -1
  2. package/dist/esm/components/VizDom/VizDomRenderer.d.ts +2 -1
  3. package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  4. package/dist/esm/hooks/common/index.d.ts +1 -1
  5. package/dist/esm/hooks/common/index.d.ts.map +1 -1
  6. package/dist/esm/hooks/common/useHeatmapViewportByDevice.d.ts +7 -0
  7. package/dist/esm/hooks/common/useHeatmapViewportByDevice.d.ts.map +1 -0
  8. package/dist/esm/hooks/view-context/useHeatmapVizContext.d.ts +2 -2
  9. package/dist/esm/hooks/view-context/useHeatmapVizContext.d.ts.map +1 -1
  10. package/dist/esm/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
  11. package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  12. package/dist/esm/hooks/viz-render/useHeatmapIframeProcessor.d.ts +6 -0
  13. package/dist/esm/hooks/viz-render/useHeatmapIframeProcessor.d.ts.map +1 -0
  14. package/dist/esm/hooks/viz-render/useHeatmapRenderByMode.d.ts +3 -2
  15. package/dist/esm/hooks/viz-render/useHeatmapRenderByMode.d.ts.map +1 -1
  16. package/dist/esm/hooks/viz-render/useHeatmapRenderDom.d.ts +5 -0
  17. package/dist/esm/hooks/viz-render/useHeatmapRenderDom.d.ts.map +1 -0
  18. package/dist/esm/hooks/viz-render/useReplayRender.d.ts +2 -2
  19. package/dist/esm/hooks/viz-render/useReplayRender.d.ts.map +1 -1
  20. package/dist/esm/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
  21. package/dist/esm/hooks/viz-scale/useScaleCalculation.d.ts +1 -2
  22. package/dist/esm/hooks/viz-scale/useScaleCalculation.d.ts.map +1 -1
  23. package/dist/esm/index.js +683 -187
  24. package/dist/esm/index.mjs +683 -187
  25. package/dist/esm/libs/visualizer/GXVisualizer.d.ts +7 -1
  26. package/dist/esm/libs/visualizer/GXVisualizer.d.ts.map +1 -1
  27. package/dist/esm/libs/visualizer/cache/config.d.ts +15 -0
  28. package/dist/esm/libs/visualizer/cache/config.d.ts.map +1 -0
  29. package/dist/esm/libs/visualizer/cache/index.d.ts +16 -0
  30. package/dist/esm/libs/visualizer/cache/index.d.ts.map +1 -0
  31. package/dist/esm/libs/visualizer/index.d.ts +1 -2
  32. package/dist/esm/libs/visualizer/index.d.ts.map +1 -1
  33. package/dist/esm/libs/visualizer/{AttentionMapRenderer.d.ts → renderers/AttentionMapRenderer.d.ts} +1 -1
  34. package/dist/esm/libs/visualizer/renderers/AttentionMapRenderer.d.ts.map +1 -0
  35. package/dist/esm/libs/visualizer/{ClickHeatmapRenderer.d.ts → renderers/ClickHeatmapRenderer.d.ts} +1 -1
  36. package/dist/esm/libs/visualizer/renderers/ClickHeatmapRenderer.d.ts.map +1 -0
  37. package/dist/esm/libs/visualizer/renderers/index.d.ts +3 -0
  38. package/dist/esm/libs/visualizer/renderers/index.d.ts.map +1 -0
  39. package/dist/esm/libs/visualizer/shadow-dom/extractor.d.ts +23 -0
  40. package/dist/esm/libs/visualizer/shadow-dom/extractor.d.ts.map +1 -0
  41. package/dist/esm/libs/visualizer/types/data.d.ts +72 -0
  42. package/dist/esm/libs/visualizer/types/data.d.ts.map +1 -0
  43. package/dist/esm/libs/visualizer/{types.d.ts → types/extend.d.ts} +7 -2
  44. package/dist/esm/libs/visualizer/types/extend.d.ts.map +1 -0
  45. package/dist/esm/libs/visualizer/types/index.d.ts +6 -0
  46. package/dist/esm/libs/visualizer/types/index.d.ts.map +1 -0
  47. package/dist/esm/libs/visualizer/types/layout.d.ts +69 -0
  48. package/dist/esm/libs/visualizer/types/layout.d.ts.map +1 -0
  49. package/dist/esm/libs/visualizer/types/visualize.d.ts +7 -0
  50. package/dist/esm/libs/visualizer/types/visualize.d.ts.map +1 -0
  51. package/dist/esm/stores/viz.d.ts +2 -2
  52. package/dist/esm/stores/viz.d.ts.map +1 -1
  53. package/dist/esm/types/heatmap-info.d.ts +1 -0
  54. package/dist/esm/types/heatmap-info.d.ts.map +1 -1
  55. package/dist/esm/types/heatmap.d.ts +4 -0
  56. package/dist/esm/types/heatmap.d.ts.map +1 -1
  57. package/dist/umd/components/VizDom/VizDomHeatmap.d.ts.map +1 -1
  58. package/dist/umd/components/VizDom/VizDomRenderer.d.ts +2 -1
  59. package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  60. package/dist/umd/hooks/common/index.d.ts +1 -1
  61. package/dist/umd/hooks/common/index.d.ts.map +1 -1
  62. package/dist/umd/hooks/common/useHeatmapViewportByDevice.d.ts +7 -0
  63. package/dist/umd/hooks/common/useHeatmapViewportByDevice.d.ts.map +1 -0
  64. package/dist/umd/hooks/view-context/useHeatmapVizContext.d.ts +2 -2
  65. package/dist/umd/hooks/view-context/useHeatmapVizContext.d.ts.map +1 -1
  66. package/dist/umd/hooks/viz-canvas/useClickmap.d.ts.map +1 -1
  67. package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  68. package/dist/umd/hooks/viz-render/useHeatmapIframeProcessor.d.ts +6 -0
  69. package/dist/umd/hooks/viz-render/useHeatmapIframeProcessor.d.ts.map +1 -0
  70. package/dist/umd/hooks/viz-render/useHeatmapRenderByMode.d.ts +3 -2
  71. package/dist/umd/hooks/viz-render/useHeatmapRenderByMode.d.ts.map +1 -1
  72. package/dist/umd/hooks/viz-render/useHeatmapRenderDom.d.ts +5 -0
  73. package/dist/umd/hooks/viz-render/useHeatmapRenderDom.d.ts.map +1 -0
  74. package/dist/umd/hooks/viz-render/useReplayRender.d.ts +2 -2
  75. package/dist/umd/hooks/viz-render/useReplayRender.d.ts.map +1 -1
  76. package/dist/umd/hooks/viz-scale/useHeatmapScale.d.ts.map +1 -1
  77. package/dist/umd/hooks/viz-scale/useScaleCalculation.d.ts +1 -2
  78. package/dist/umd/hooks/viz-scale/useScaleCalculation.d.ts.map +1 -1
  79. package/dist/umd/index.js +2 -2
  80. package/dist/umd/libs/visualizer/GXVisualizer.d.ts +7 -1
  81. package/dist/umd/libs/visualizer/GXVisualizer.d.ts.map +1 -1
  82. package/dist/umd/libs/visualizer/cache/config.d.ts +15 -0
  83. package/dist/umd/libs/visualizer/cache/config.d.ts.map +1 -0
  84. package/dist/umd/libs/visualizer/cache/index.d.ts +16 -0
  85. package/dist/umd/libs/visualizer/cache/index.d.ts.map +1 -0
  86. package/dist/umd/libs/visualizer/index.d.ts +1 -2
  87. package/dist/umd/libs/visualizer/index.d.ts.map +1 -1
  88. package/dist/umd/libs/visualizer/{AttentionMapRenderer.d.ts → renderers/AttentionMapRenderer.d.ts} +1 -1
  89. package/dist/umd/libs/visualizer/renderers/AttentionMapRenderer.d.ts.map +1 -0
  90. package/dist/umd/libs/visualizer/{ClickHeatmapRenderer.d.ts → renderers/ClickHeatmapRenderer.d.ts} +1 -1
  91. package/dist/umd/libs/visualizer/renderers/ClickHeatmapRenderer.d.ts.map +1 -0
  92. package/dist/umd/libs/visualizer/renderers/index.d.ts +3 -0
  93. package/dist/umd/libs/visualizer/renderers/index.d.ts.map +1 -0
  94. package/dist/umd/libs/visualizer/shadow-dom/extractor.d.ts +23 -0
  95. package/dist/umd/libs/visualizer/shadow-dom/extractor.d.ts.map +1 -0
  96. package/dist/umd/libs/visualizer/types/data.d.ts +72 -0
  97. package/dist/umd/libs/visualizer/types/data.d.ts.map +1 -0
  98. package/dist/umd/libs/visualizer/{types.d.ts → types/extend.d.ts} +7 -2
  99. package/dist/umd/libs/visualizer/types/extend.d.ts.map +1 -0
  100. package/dist/umd/libs/visualizer/types/index.d.ts +6 -0
  101. package/dist/umd/libs/visualizer/types/index.d.ts.map +1 -0
  102. package/dist/umd/libs/visualizer/types/layout.d.ts +69 -0
  103. package/dist/umd/libs/visualizer/types/layout.d.ts.map +1 -0
  104. package/dist/umd/libs/visualizer/types/visualize.d.ts +7 -0
  105. package/dist/umd/libs/visualizer/types/visualize.d.ts.map +1 -0
  106. package/dist/umd/stores/viz.d.ts +2 -2
  107. package/dist/umd/stores/viz.d.ts.map +1 -1
  108. package/dist/umd/types/heatmap-info.d.ts +1 -0
  109. package/dist/umd/types/heatmap-info.d.ts.map +1 -1
  110. package/dist/umd/types/heatmap.d.ts +4 -0
  111. package/dist/umd/types/heatmap.d.ts.map +1 -1
  112. package/package.json +4 -4
  113. package/dist/esm/hooks/common/useHeatmapWidthByDevice.d.ts +0 -2
  114. package/dist/esm/hooks/common/useHeatmapWidthByDevice.d.ts.map +0 -1
  115. package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts +0 -5
  116. package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts.map +0 -1
  117. package/dist/esm/hooks/viz-scale/useContentDimensions.d.ts +0 -9
  118. package/dist/esm/hooks/viz-scale/useContentDimensions.d.ts.map +0 -1
  119. package/dist/esm/libs/visualizer/AttentionMapRenderer.d.ts.map +0 -1
  120. package/dist/esm/libs/visualizer/ClickHeatmapRenderer.d.ts.map +0 -1
  121. package/dist/esm/libs/visualizer/ScrollHeatmapRenderer.d.ts +0 -17
  122. package/dist/esm/libs/visualizer/ScrollHeatmapRenderer.d.ts.map +0 -1
  123. package/dist/esm/libs/visualizer/types.d.ts.map +0 -1
  124. package/dist/umd/hooks/common/useHeatmapWidthByDevice.d.ts +0 -2
  125. package/dist/umd/hooks/common/useHeatmapWidthByDevice.d.ts.map +0 -1
  126. package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts +0 -5
  127. package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts.map +0 -1
  128. package/dist/umd/hooks/viz-scale/useContentDimensions.d.ts +0 -9
  129. package/dist/umd/hooks/viz-scale/useContentDimensions.d.ts.map +0 -1
  130. package/dist/umd/libs/visualizer/AttentionMapRenderer.d.ts.map +0 -1
  131. package/dist/umd/libs/visualizer/ClickHeatmapRenderer.d.ts.map +0 -1
  132. package/dist/umd/libs/visualizer/ScrollHeatmapRenderer.d.ts +0 -17
  133. package/dist/umd/libs/visualizer/ScrollHeatmapRenderer.d.ts.map +0 -1
  134. package/dist/umd/libs/visualizer/types.d.ts.map +0 -1
@@ -162,6 +162,11 @@ var EHeatmapType;
162
162
  EHeatmapType["Click"] = "click";
163
163
  EHeatmapType["Scroll"] = "scroll";
164
164
  })(EHeatmapType || (EHeatmapType = {}));
165
+ var EHeatmapMode;
166
+ (function (EHeatmapMode) {
167
+ EHeatmapMode["Heatmap"] = "heatmap";
168
+ EHeatmapMode["Replay"] = "replay";
169
+ })(EHeatmapMode || (EHeatmapMode = {}));
165
170
  var EClickType;
166
171
  (function (EClickType) {
167
172
  /** Return all clicks (default) */
@@ -198,7 +203,6 @@ var EScrollType;
198
203
  EScrollType["Attention"] = "ATTENTION";
199
204
  EScrollType["Revenue"] = "REVENUE";
200
205
  })(EScrollType || (EScrollType = {}));
201
- var EHeatmapMode;
202
206
  (function (EHeatmapMode) {
203
207
  EHeatmapMode["Single"] = "single";
204
208
  EHeatmapMode["Live"] = "live";
@@ -620,16 +624,16 @@ const useHeatmapSettingStore = create()(subscribeWithSelector((set) => {
620
624
 
621
625
  const useHeatmapVizStore = create()(subscribeWithSelector((set) => {
622
626
  return {
623
- isRenderedViz: new Map([[DEFAULT_VIEW_ID, false]]),
627
+ isDomLoaded: new Map([[DEFAULT_VIEW_ID, false]]),
624
628
  zoomRatio: new Map([[DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO.DEFAULT]]),
625
629
  minZoomRatio: new Map([[DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO.MIN]]),
626
630
  maxZoomRatio: new Map([[DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO.MAX]]),
627
631
  scale: new Map([[DEFAULT_VIEW_ID, 1]]),
628
632
  isScaledToFit: new Map([[DEFAULT_VIEW_ID, false]]),
629
- setIsRenderedViz: (isRenderedViz, viewId = DEFAULT_VIEW_ID) => set((prev) => {
630
- const newIsRenderedViz = new Map(prev.isRenderedViz);
631
- newIsRenderedViz.set(viewId, isRenderedViz);
632
- return { isRenderedViz: newIsRenderedViz };
633
+ setIsDomLoaded: (isDomLoaded, viewId = DEFAULT_VIEW_ID) => set((prev) => {
634
+ const newIsDomLoaded = new Map(prev.isDomLoaded);
635
+ newIsDomLoaded.set(viewId, isDomLoaded);
636
+ return { isDomLoaded: newIsDomLoaded };
633
637
  }),
634
638
  setZoomRatio: (zoomRatio, viewId = DEFAULT_VIEW_ID) => set((prev) => {
635
639
  const newZoomRatio = new Map(prev.zoomRatio);
@@ -657,18 +661,18 @@ const useHeatmapVizStore = create()(subscribeWithSelector((set) => {
657
661
  return { isScaledToFit: newIsScaledToFit };
658
662
  }),
659
663
  copyView: (fromViewId, toViewId) => set((prev) => {
660
- const newIsRenderedViz = new Map(prev.isRenderedViz);
664
+ const newIsDomLoaded = new Map(prev.isDomLoaded);
661
665
  const newZoomRatio = new Map(prev.zoomRatio);
662
666
  const newMinZoomRatio = new Map(prev.minZoomRatio);
663
667
  const newScale = new Map(prev.scale);
664
668
  const newIsScaledToFit = new Map(prev.isScaledToFit);
665
- newIsRenderedViz.set(toViewId, prev.isRenderedViz.get(fromViewId) ?? false);
669
+ newIsDomLoaded.set(toViewId, prev.isDomLoaded.get(fromViewId) ?? false);
666
670
  newZoomRatio.set(toViewId, prev.zoomRatio.get(fromViewId) ?? 100);
667
671
  newMinZoomRatio.set(toViewId, prev.minZoomRatio.get(fromViewId) ?? 10);
668
672
  newScale.set(toViewId, prev.scale.get(fromViewId) ?? 1);
669
673
  newIsScaledToFit.set(toViewId, prev.isScaledToFit.get(fromViewId) ?? false);
670
674
  return {
671
- isRenderedViz: newIsRenderedViz,
675
+ isDomLoaded: newIsDomLoaded,
672
676
  zoomRatio: newZoomRatio,
673
677
  minZoomRatio: newMinZoomRatio,
674
678
  scale: newScale,
@@ -676,18 +680,18 @@ const useHeatmapVizStore = create()(subscribeWithSelector((set) => {
676
680
  };
677
681
  }),
678
682
  clearView: (viewId) => set((prev) => {
679
- const newIsRenderedViz = new Map(prev.isRenderedViz);
683
+ const newIsDomLoaded = new Map(prev.isDomLoaded);
680
684
  const newZoomRatio = new Map(prev.zoomRatio);
681
685
  const newMinZoomRatio = new Map(prev.minZoomRatio);
682
686
  const newScale = new Map(prev.scale);
683
687
  const newIsScaledToFit = new Map(prev.isScaledToFit);
684
- newIsRenderedViz.delete(viewId);
688
+ newIsDomLoaded.delete(viewId);
685
689
  newZoomRatio.delete(viewId);
686
690
  newMinZoomRatio.delete(viewId);
687
691
  newScale.delete(viewId);
688
692
  newIsScaledToFit.delete(viewId);
689
693
  return {
690
- isRenderedViz: newIsRenderedViz,
694
+ isDomLoaded: newIsDomLoaded,
691
695
  zoomRatio: newZoomRatio,
692
696
  minZoomRatio: newMinZoomRatio,
693
697
  scale: newScale,
@@ -695,7 +699,7 @@ const useHeatmapVizStore = create()(subscribeWithSelector((set) => {
695
699
  };
696
700
  }),
697
701
  resetAll: () => set({
698
- isRenderedViz: new Map([[DEFAULT_VIEW_ID, false]]),
702
+ isDomLoaded: new Map([[DEFAULT_VIEW_ID, false]]),
699
703
  zoomRatio: new Map([[DEFAULT_VIEW_ID, 100]]),
700
704
  minZoomRatio: new Map([[DEFAULT_VIEW_ID, 10]]),
701
705
  scale: new Map([[DEFAULT_VIEW_ID, 1]]),
@@ -1415,7 +1419,7 @@ const useHeatmapSettingContext = createViewContextHook({
1415
1419
  const useHeatmapVizContext = createViewContextHook({
1416
1420
  useStore: useHeatmapVizStore,
1417
1421
  getState: (store, viewId) => ({
1418
- isRenderedViz: store.isRenderedViz.get(viewId) ?? false,
1422
+ isDomLoaded: store.isDomLoaded.get(viewId) ?? false,
1419
1423
  zoomRatio: store.zoomRatio.get(viewId) ?? DEFAULT_ZOOM_RATIO.DEFAULT,
1420
1424
  minZoomRatio: store.minZoomRatio.get(viewId) ?? DEFAULT_ZOOM_RATIO.MIN,
1421
1425
  maxZoomRatio: store.maxZoomRatio.get(viewId) ?? DEFAULT_ZOOM_RATIO.MAX,
@@ -1423,7 +1427,7 @@ const useHeatmapVizContext = createViewContextHook({
1423
1427
  isScaledToFit: store.isScaledToFit.get(viewId) ?? false,
1424
1428
  }),
1425
1429
  getActions: (store, viewId) => ({
1426
- setIsRenderedViz: (value) => store.setIsRenderedViz(value, viewId),
1430
+ setIsDomLoaded: (value) => store.setIsDomLoaded(value, viewId),
1427
1431
  setZoomRatio: (value) => store.setZoomRatio(value, viewId),
1428
1432
  setMinZoomRatio: (value) => store.setMinZoomRatio(value, viewId),
1429
1433
  setMaxZoomRatio: (value) => store.setMaxZoomRatio(value, viewId),
@@ -1525,10 +1529,11 @@ const useHeatmapCopyView = () => {
1525
1529
  };
1526
1530
  };
1527
1531
 
1528
- const useHeatmapWidthByDevice = () => {
1532
+ const useHeatmapViewportByDevice = () => {
1529
1533
  const deviceType = useHeatmapSettingContext((state) => state.deviceType);
1530
1534
  const width = useMemo(() => calcWidthByDeviceType(deviceType), [deviceType]);
1531
- return width;
1535
+ const height = useMemo(() => calcHeightByDeviceType(deviceType), [deviceType]);
1536
+ return { width, height };
1532
1537
  function calcWidthByDeviceType(deviceType) {
1533
1538
  if (!deviceType)
1534
1539
  return 1440;
@@ -1543,6 +1548,20 @@ const useHeatmapWidthByDevice = () => {
1543
1548
  return 375;
1544
1549
  }
1545
1550
  }
1551
+ function calcHeightByDeviceType(deviceType) {
1552
+ if (!deviceType)
1553
+ return 900;
1554
+ switch (deviceType) {
1555
+ case EDeviceType.DesktopLarge:
1556
+ return 1080; // 1920×1080
1557
+ case EDeviceType.Desktop:
1558
+ return 900; // 1440×900
1559
+ case EDeviceType.Tablet:
1560
+ return 1024; // 768×1024 (iPad portrait)
1561
+ case EDeviceType.Mobile:
1562
+ return 812; // 375×812 (iPhone X/11/12/13)
1563
+ }
1564
+ }
1546
1565
  };
1547
1566
 
1548
1567
  const useRegisterConfig = ({ shopId, isLoading, isLoadingCanvas, excludeClassNames, }) => {
@@ -1567,7 +1586,7 @@ const useRegisterConfig = ({ shopId, isLoading, isLoadingCanvas, excludeClassNam
1567
1586
  setIsRendering(true);
1568
1587
  setTimeout(() => {
1569
1588
  setIsRendering(false);
1570
- }, 100);
1589
+ }, 500);
1571
1590
  }, [mode, deviceType, sidebarWidth]); // eslint-disable-line react-hooks/exhaustive-deps
1572
1591
  useEffect(() => {
1573
1592
  setIsRendering(!!isLoading);
@@ -3504,18 +3523,20 @@ const useAreaClickmap = () => {
3504
3523
  const useClickmap = () => {
3505
3524
  const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
3506
3525
  const clickmap = useHeatmapDataContext((s) => s.clickmap);
3507
- const isRenderedViz = useHeatmapVizContext((s) => s.isRenderedViz);
3526
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
3508
3527
  const start = useCallback(() => {
3509
- if (!vizRef || !clickmap || clickmap.length === 0 || !isRenderedViz)
3528
+ if (!vizRef || !clickmap || clickmap.length === 0 || !isDomLoaded)
3510
3529
  return;
3511
3530
  try {
3512
- vizRef?.clearmap?.();
3513
- vizRef?.clickmap?.(clickmap);
3531
+ requestIdleCallback(() => {
3532
+ vizRef?.clearmap?.();
3533
+ vizRef?.clickmap?.(clickmap);
3534
+ }, { timeout: 300 });
3514
3535
  }
3515
3536
  catch (error) {
3516
3537
  console.error(`🚀 🐥 ~ useClickmap ~ error:`, error);
3517
3538
  }
3518
- }, [vizRef, clickmap, isRenderedViz]);
3539
+ }, [vizRef, clickmap, isDomLoaded]);
3519
3540
  return { start };
3520
3541
  };
3521
3542
 
@@ -3523,6 +3544,7 @@ const useScrollmap = () => {
3523
3544
  const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
3524
3545
  const scrollType = useHeatmapSettingContext((s) => s.scrollType);
3525
3546
  const scrollmap = useHeatmapDataContext((s) => s.scrollmap);
3547
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
3526
3548
  useMemo(() => {
3527
3549
  switch (scrollType) {
3528
3550
  case EScrollType.Depth:
@@ -3536,16 +3558,18 @@ const useScrollmap = () => {
3536
3558
  }
3537
3559
  }, [scrollmap, scrollType]);
3538
3560
  const start = useCallback(() => {
3539
- if (!vizRef || !scrollmap || scrollmap.length === 0)
3561
+ if (!vizRef || !scrollmap || scrollmap.length === 0 || !isDomLoaded)
3540
3562
  return;
3541
3563
  try {
3542
- vizRef?.clearmap?.();
3543
- vizRef?.scrollmap?.(scrollmap);
3564
+ requestIdleCallback(() => {
3565
+ vizRef?.clearmap?.();
3566
+ vizRef?.scrollmap?.(scrollmap);
3567
+ }, { timeout: 300 });
3544
3568
  }
3545
3569
  catch (error) {
3546
3570
  logger$4.error(`🚀 🐥 ~ useScrollmap ~ error:`, error);
3547
3571
  }
3548
- }, [vizRef, scrollmap]);
3572
+ }, [vizRef, scrollmap, isDomLoaded]);
3549
3573
  return { start };
3550
3574
  };
3551
3575
 
@@ -3709,7 +3733,7 @@ const useHeatmapEffects = ({ isVisible }) => {
3709
3733
  };
3710
3734
 
3711
3735
  const useHeatmapElementPosition = ({ iframeRef, wrapperRef, visualizer }) => {
3712
- const heatmapWidth = useHeatmapWidthByDevice();
3736
+ const viewport = useHeatmapViewportByDevice();
3713
3737
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
3714
3738
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
3715
3739
  const getRect = useCallback((element) => {
@@ -3737,17 +3761,17 @@ const useHeatmapElementPosition = ({ iframeRef, wrapperRef, visualizer }) => {
3737
3761
  const outOfBounds = adjustedTop < 0 ||
3738
3762
  adjustedTop > (iframeHeight || Infinity) ||
3739
3763
  layout.left < 0 ||
3740
- (typeof heatmapWidth === 'number' && layout.left > heatmapWidth);
3764
+ (typeof viewport.width === 'number' && layout.left > viewport.width);
3741
3765
  if (outOfBounds)
3742
3766
  return null;
3743
3767
  return {
3744
3768
  left: layout.left,
3745
3769
  top: adjustedTop,
3746
- width: Math.min(layout.width, heatmapWidth || layout.width),
3770
+ width: Math.min(layout.width, viewport.width || layout.width),
3747
3771
  height: layout.height,
3748
3772
  outOfBounds,
3749
3773
  };
3750
- }, [iframeRef, wrapperRef, visualizer, heatmapWidth, iframeHeight, widthScale]);
3774
+ }, [iframeRef, wrapperRef, visualizer, viewport, iframeHeight, widthScale]);
3751
3775
  return { getRect };
3752
3776
  };
3753
3777
 
@@ -4148,7 +4172,7 @@ function flush() {
4148
4172
  window.__gemxPerf = getReport();
4149
4173
  }
4150
4174
  // ── Global singleton export ───────────────────────────────────────────────────
4151
- const perf$1 = {
4175
+ const perf$2 = {
4152
4176
  startSession,
4153
4177
  endSession,
4154
4178
  mark: globalMark,
@@ -4941,7 +4965,7 @@ const YIELD_EVERY_RULES = 100;
4941
4965
  * Uses `scheduler.yield()` (Chrome 115+) when available; falls back to a
4942
4966
  * zero-timeout macrotask which is universally supported.
4943
4967
  */
4944
- function yieldToMain() {
4968
+ function yieldToMain$1() {
4945
4969
  if (typeof globalThis !== 'undefined' && 'scheduler' in globalThis) {
4946
4970
  return globalThis.scheduler.yield();
4947
4971
  }
@@ -5101,7 +5125,7 @@ async function processStylesheets(ctx) {
5101
5125
  rulesSinceYield++;
5102
5126
  if (rulesSinceYield >= YIELD_EVERY_RULES) {
5103
5127
  rulesSinceYield = 0;
5104
- await yieldToMain();
5128
+ await yieldToMain$1();
5105
5129
  }
5106
5130
  }
5107
5131
  }
@@ -5384,52 +5408,52 @@ function configure(debug) {
5384
5408
  }
5385
5409
  async function run$1(ctx, activeGlobal, shopFix) {
5386
5410
  // ── Phase 1: beforeProcess ────────────────────────────────────────────────
5387
- const t1 = perf$1.mark('phase1.beforeProcess');
5411
+ const t1 = perf$2.mark('phase1.beforeProcess');
5388
5412
  for (const fix of activeGlobal) {
5389
5413
  if (fix.beforeProcess) {
5390
5414
  logger.log(`[beforeProcess] ${fix.name}`);
5391
- const t = perf$1.mark(`phase1.${fix.name}.beforeProcess`);
5415
+ const t = perf$2.mark(`phase1.${fix.name}.beforeProcess`);
5392
5416
  await fix.beforeProcess(ctx);
5393
- perf$1.measure(`phase1.${fix.name}.beforeProcess`, t);
5417
+ perf$2.measure(`phase1.${fix.name}.beforeProcess`, t);
5394
5418
  }
5395
5419
  }
5396
5420
  if (shopFix?.beforeProcess) {
5397
5421
  logger.log('[beforeProcess] shop');
5398
- const t = perf$1.mark('phase1.shop.beforeProcess');
5422
+ const t = perf$2.mark('phase1.shop.beforeProcess');
5399
5423
  await shopFix.beforeProcess(ctx);
5400
- perf$1.measure('phase1.shop.beforeProcess', t);
5424
+ perf$2.measure('phase1.shop.beforeProcess', t);
5401
5425
  }
5402
- perf$1.measure('phase1.beforeProcess', t1);
5426
+ perf$2.measure('phase1.beforeProcess', t1);
5403
5427
  // ── Phase 2: process ──────────────────────────────────────────────────────
5404
- const t2 = perf$1.mark('phase2.process');
5428
+ const t2 = perf$2.mark('phase2.process');
5405
5429
  for (const fix of activeGlobal) {
5406
5430
  if (fix.process) {
5407
5431
  logger.log(`[process] ${fix.name}`);
5408
- const t = perf$1.mark(`phase2.${fix.name}.process`);
5432
+ const t = perf$2.mark(`phase2.${fix.name}.process`);
5409
5433
  await fix.process(ctx);
5410
- perf$1.measure(`phase2.${fix.name}.process`, t);
5434
+ perf$2.measure(`phase2.${fix.name}.process`, t);
5411
5435
  }
5412
5436
  }
5413
- perf$1.measure('phase2.process', t2);
5437
+ perf$2.measure('phase2.process', t2);
5414
5438
  // ── Phase 3: afterProcess ─────────────────────────────────────────────────
5415
- const t3 = perf$1.mark('phase3.afterProcess');
5439
+ const t3 = perf$2.mark('phase3.afterProcess');
5416
5440
  if (shopFix?.afterProcess) {
5417
5441
  logger.log('[afterProcess] shop');
5418
- const t = perf$1.mark('phase3.shop.afterProcess');
5442
+ const t = perf$2.mark('phase3.shop.afterProcess');
5419
5443
  await shopFix.afterProcess(ctx);
5420
- perf$1.measure('phase3.shop.afterProcess', t);
5444
+ perf$2.measure('phase3.shop.afterProcess', t);
5421
5445
  }
5422
5446
  for (const fix of activeGlobal) {
5423
5447
  if (fix.afterProcess) {
5424
5448
  logger.log(`[afterProcess] ${fix.name}`);
5425
- const t = perf$1.mark(`phase3.${fix.name}.afterProcess`);
5449
+ const t = perf$2.mark(`phase3.${fix.name}.afterProcess`);
5426
5450
  await fix.afterProcess(ctx);
5427
- perf$1.measure(`phase3.${fix.name}.afterProcess`, t);
5451
+ perf$2.measure(`phase3.${fix.name}.afterProcess`, t);
5428
5452
  }
5429
5453
  }
5430
- perf$1.measure('phase3.afterProcess', t3);
5454
+ perf$2.measure('phase3.afterProcess', t3);
5431
5455
  // ── Phase 4: getDimensions ────────────────────────────────────────────────
5432
- const t4 = perf$1.mark('phase4.getDimensions');
5456
+ const t4 = perf$2.mark('phase4.getDimensions');
5433
5457
  return new Promise((resolve) => {
5434
5458
  requestAnimationFrame(() => {
5435
5459
  let dimensions = null;
@@ -5454,7 +5478,7 @@ async function run$1(ctx, activeGlobal, shopFix) {
5454
5478
  dimensions = { height: getFinalHeight(ctx.doc, ctx.win), width: getFinalWidth(ctx.doc) };
5455
5479
  }
5456
5480
  logger.log('Final dimensions:', dimensions);
5457
- perf$1.measure('phase4.getDimensions', t4);
5481
+ perf$2.measure('phase4.getDimensions', t4);
5458
5482
  resolve(dimensions);
5459
5483
  });
5460
5484
  });
@@ -5582,14 +5606,14 @@ async function run(s) {
5582
5606
  const activeGlobal = getActiveFixes(ctx);
5583
5607
  if (activeGlobal.length > 0)
5584
5608
  s.logger.log(`Active global fixes: ${activeGlobal.map((f) => f.name).join(', ')}`);
5585
- const tRun = perf$1.mark('viewport.run');
5609
+ const tRun = perf$2.mark('viewport.run');
5586
5610
  try {
5587
5611
  const result = await run$1(ctx, activeGlobal, s.shopFix);
5588
- perf$1.measure('viewport.run', tRun);
5612
+ perf$2.measure('viewport.run', tRun);
5589
5613
  return result;
5590
5614
  }
5591
5615
  catch (err) {
5592
- perf$1.measure('viewport.run', tRun);
5616
+ perf$2.measure('viewport.run', tRun);
5593
5617
  s.logger.error('Critical error:', err);
5594
5618
  return { height: s.doc.body?.scrollHeight || 1000, width: s.doc.body?.scrollWidth || 1000 };
5595
5619
  }
@@ -5639,22 +5663,22 @@ async function process(s) {
5639
5663
  return;
5640
5664
  }
5641
5665
  const sessionId = `render-${Date.now()}`;
5642
- perf$1.startSession(sessionId);
5643
- const t0 = perf$1.mark('orchestrator.process');
5666
+ perf$2.startSession(sessionId);
5667
+ const t0 = perf$2.mark('orchestrator.process');
5644
5668
  try {
5645
5669
  s.logger.log('Processing viewport units...');
5646
5670
  s.viewportReplacer.start(s.iframe, s.config);
5647
5671
  s.navigationBlocker.start(s.iframe, { debug: s.config.debug });
5648
5672
  const result = await s.viewportReplacer.run();
5649
- perf$1.measure('orchestrator.process', t0);
5650
- perf$1.endSession();
5673
+ perf$2.measure('orchestrator.process', t0);
5674
+ perf$2.endSession();
5651
5675
  s.logger.log('Process completed:', result);
5652
5676
  s.config.onSuccess?.(result);
5653
5677
  dispatchDimensionsEvent(result);
5654
5678
  }
5655
5679
  catch (error) {
5656
- perf$1.measure('orchestrator.process', t0);
5657
- perf$1.endSession();
5680
+ perf$2.measure('orchestrator.process', t0);
5681
+ perf$2.endSession();
5658
5682
  s.logger.error('Failed to process:', error);
5659
5683
  s.config.onError?.(error);
5660
5684
  }
@@ -5805,13 +5829,13 @@ function useVizLiveRender() {
5805
5829
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
5806
5830
  const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
5807
5831
  const wrapperWidth = useHeatmapVizRectContext((s) => s.wrapperWidth);
5808
- const setIsRenderedViz = useHeatmapVizContext((s) => s.setIsRenderedViz);
5832
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
5809
5833
  const htmlContent = useHeatmapLiveContext((s) => s.htmlContent);
5810
5834
  const targetUrl = useHeatmapLiveContext((s) => s.targetUrl);
5811
5835
  const deviceType = useHeatmapSettingContext((s) => s.deviceType);
5812
5836
  const renderMode = useHeatmapLiveContext((s) => s.renderMode);
5813
5837
  const storefrontPassword = useHeatmapLiveContext((s) => s.storefrontPassword);
5814
- useHeatmapWidthByDevice();
5838
+ useHeatmapViewportByDevice();
5815
5839
  const { iframeRef, isReady } = useVizLiveIframeMsg();
5816
5840
  // Handle iframe rendering based on mode
5817
5841
  useEffect(() => {
@@ -5851,10 +5875,10 @@ function useVizLiveRender() {
5851
5875
  const hasContent = (renderMode === 'portal' && targetUrl) || (renderMode === 'inline' && htmlContent);
5852
5876
  if (!iframe || !hasContent)
5853
5877
  return;
5854
- setIsRenderedViz(true);
5878
+ setIsDomLoaded(true);
5855
5879
  startIframe$1(iframe, deviceType, { width: wrapperWidth, height: wrapperHeight }, (height) => {
5856
5880
  height && setIframeHeight(height);
5857
- setIsRenderedViz(true);
5881
+ setIsDomLoaded(true);
5858
5882
  });
5859
5883
  return () => { };
5860
5884
  }, [
@@ -5866,7 +5890,7 @@ function useVizLiveRender() {
5866
5890
  targetUrl,
5867
5891
  htmlContent,
5868
5892
  iframeRef,
5869
- setIsRenderedViz,
5893
+ setIsDomLoaded,
5870
5894
  setIframeHeight,
5871
5895
  ]);
5872
5896
  return {
@@ -5901,6 +5925,109 @@ function startIframe$1(iframe, deviceType = EDeviceType.Desktop, rect, onSuccess
5901
5925
  iframeHelper.enableNavigationBlocking();
5902
5926
  }
5903
5927
 
5928
+ const DEFAULT_CONFIG = {
5929
+ dbName: 'gx-viz-html-cache',
5930
+ maxEntries: 20,
5931
+ ttlMs: 24 * 60 * 60 * 1000, // 24 hours
5932
+ cacheVersion: 3.0,
5933
+ };
5934
+ let _config = { ...DEFAULT_CONFIG };
5935
+ function getHtmlCacheConfig() {
5936
+ return _config;
5937
+ }
5938
+ /** Build a full cache key that includes the cache version to handle invalidation. */
5939
+ function buildCacheKey(baseKey, shortCircuitStrategy) {
5940
+ return `v${_config.cacheVersion}:${baseKey}:${shortCircuitStrategy}`;
5941
+ }
5942
+
5943
+ const STORE_NAME = 'entries';
5944
+ const IDB_SCHEMA_VERSION = 1;
5945
+ function openDb() {
5946
+ const { dbName } = getHtmlCacheConfig();
5947
+ return new Promise((resolve, reject) => {
5948
+ const req = indexedDB.open(dbName, IDB_SCHEMA_VERSION);
5949
+ req.onupgradeneeded = () => {
5950
+ const db = req.result;
5951
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
5952
+ const store = db.createObjectStore(STORE_NAME, { keyPath: 'key' });
5953
+ store.createIndex('timestamp', 'timestamp');
5954
+ }
5955
+ };
5956
+ req.onsuccess = () => resolve(req.result);
5957
+ req.onerror = () => reject(req.error);
5958
+ });
5959
+ }
5960
+ async function evict(db) {
5961
+ const { maxEntries } = getHtmlCacheConfig();
5962
+ return new Promise((resolve) => {
5963
+ const tx = db.transaction(STORE_NAME, 'readwrite');
5964
+ const store = tx.objectStore(STORE_NAME);
5965
+ const countReq = store.count();
5966
+ countReq.onsuccess = () => {
5967
+ if (countReq.result <= maxEntries) {
5968
+ resolve();
5969
+ return;
5970
+ }
5971
+ const idx = store.index('timestamp');
5972
+ const cursorReq = idx.openCursor();
5973
+ let toDelete = countReq.result - maxEntries;
5974
+ cursorReq.onsuccess = () => {
5975
+ const cursor = cursorReq.result;
5976
+ if (cursor && toDelete > 0) {
5977
+ cursor.delete();
5978
+ toDelete--;
5979
+ cursor.continue();
5980
+ }
5981
+ else {
5982
+ resolve();
5983
+ }
5984
+ };
5985
+ cursorReq.onerror = () => resolve();
5986
+ };
5987
+ countReq.onerror = () => resolve();
5988
+ });
5989
+ }
5990
+ const htmlCache = {
5991
+ async get(key) {
5992
+ try {
5993
+ const { ttlMs } = getHtmlCacheConfig();
5994
+ const db = await openDb();
5995
+ return new Promise((resolve) => {
5996
+ const tx = db.transaction(STORE_NAME, 'readonly');
5997
+ const req = tx.objectStore(STORE_NAME).get(key);
5998
+ req.onsuccess = () => {
5999
+ const entry = req.result;
6000
+ if (!entry || Date.now() - entry.timestamp > ttlMs) {
6001
+ resolve(null);
6002
+ }
6003
+ else {
6004
+ resolve(entry);
6005
+ }
6006
+ };
6007
+ req.onerror = () => resolve(null);
6008
+ });
6009
+ }
6010
+ catch {
6011
+ return null;
6012
+ }
6013
+ },
6014
+ async set(entry) {
6015
+ try {
6016
+ const db = await openDb();
6017
+ await new Promise((resolve, reject) => {
6018
+ const tx = db.transaction(STORE_NAME, 'readwrite');
6019
+ tx.objectStore(STORE_NAME).put(entry);
6020
+ tx.oncomplete = () => resolve();
6021
+ tx.onerror = () => reject(tx.error);
6022
+ });
6023
+ await evict(db);
6024
+ }
6025
+ catch {
6026
+ // ignore cache write errors
6027
+ }
6028
+ },
6029
+ };
6030
+
5904
6031
  const CANVAS_ID = 'clarity-heatmap-canvas';
5905
6032
  const ATTENTION_HUES = [240, 210, 180, 150, 120, 90, 60, 30, 0];
5906
6033
  const CANVAS_MAX_HEIGHT = 65535;
@@ -6109,6 +6236,250 @@ class AttentionMapRenderer {
6109
6236
  };
6110
6237
  }
6111
6238
 
6239
+ var Event;
6240
+ (function (Event) {
6241
+ /* Data */
6242
+ Event[Event["Metric"] = 0] = "Metric";
6243
+ Event[Event["Dimension"] = 1] = "Dimension";
6244
+ Event[Event["Upload"] = 2] = "Upload";
6245
+ Event[Event["Upgrade"] = 3] = "Upgrade";
6246
+ Event[Event["Baseline"] = 4] = "Baseline";
6247
+ Event[Event["Discover"] = 5] = "Discover";
6248
+ Event[Event["Mutation"] = 6] = "Mutation";
6249
+ Event[Event["Region"] = 7] = "Region";
6250
+ Event[Event["Document"] = 8] = "Document";
6251
+ Event[Event["Click"] = 9] = "Click";
6252
+ Event[Event["Scroll"] = 10] = "Scroll";
6253
+ Event[Event["Resize"] = 11] = "Resize";
6254
+ Event[Event["MouseMove"] = 12] = "MouseMove";
6255
+ Event[Event["MouseDown"] = 13] = "MouseDown";
6256
+ Event[Event["MouseUp"] = 14] = "MouseUp";
6257
+ Event[Event["MouseWheel"] = 15] = "MouseWheel";
6258
+ Event[Event["DoubleClick"] = 16] = "DoubleClick";
6259
+ Event[Event["TouchStart"] = 17] = "TouchStart";
6260
+ Event[Event["TouchEnd"] = 18] = "TouchEnd";
6261
+ Event[Event["TouchMove"] = 19] = "TouchMove";
6262
+ Event[Event["TouchCancel"] = 20] = "TouchCancel";
6263
+ Event[Event["Selection"] = 21] = "Selection";
6264
+ Event[Event["Timeline"] = 22] = "Timeline";
6265
+ Event[Event["Page"] = 23] = "Page";
6266
+ Event[Event["Custom"] = 24] = "Custom";
6267
+ Event[Event["Ping"] = 25] = "Ping";
6268
+ Event[Event["Unload"] = 26] = "Unload";
6269
+ Event[Event["Input"] = 27] = "Input";
6270
+ Event[Event["Visibility"] = 28] = "Visibility";
6271
+ Event[Event["Navigation"] = 29] = "Navigation";
6272
+ /**
6273
+ * @deprecated No longer support Network Connection
6274
+ */
6275
+ Event[Event["Connection"] = 30] = "Connection";
6276
+ Event[Event["ScriptError"] = 31] = "ScriptError";
6277
+ /**
6278
+ * @deprecated No longer support Image Error
6279
+ */
6280
+ Event[Event["ImageError"] = 32] = "ImageError";
6281
+ Event[Event["Log"] = 33] = "Log";
6282
+ Event[Event["Variable"] = 34] = "Variable";
6283
+ Event[Event["Limit"] = 35] = "Limit";
6284
+ Event[Event["Summary"] = 36] = "Summary";
6285
+ /**
6286
+ * @deprecated No longer support Box event
6287
+ */
6288
+ Event[Event["Box"] = 37] = "Box";
6289
+ Event[Event["Clipboard"] = 38] = "Clipboard";
6290
+ Event[Event["Submit"] = 39] = "Submit";
6291
+ Event[Event["Extract"] = 40] = "Extract";
6292
+ Event[Event["Fraud"] = 41] = "Fraud";
6293
+ Event[Event["Change"] = 42] = "Change";
6294
+ Event[Event["Snapshot"] = 43] = "Snapshot";
6295
+ Event[Event["Animation"] = 44] = "Animation";
6296
+ Event[Event["StyleSheetAdoption"] = 45] = "StyleSheetAdoption";
6297
+ Event[Event["StyleSheetUpdate"] = 46] = "StyleSheetUpdate";
6298
+ Event[Event["Consent"] = 47] = "Consent";
6299
+ Event[Event["ContextMenu"] = 48] = "ContextMenu";
6300
+ // 49 is reserved for internal use
6301
+ Event[Event["Focus"] = 50] = "Focus";
6302
+ Event[Event["CustomElement"] = 51] = "CustomElement";
6303
+ Event[Event["Chat"] = 52] = "Chat";
6304
+ // Apps specific events
6305
+ Event[Event["WebViewDiscover"] = 100] = "WebViewDiscover";
6306
+ Event[Event["WebViewMutation"] = 101] = "WebViewMutation";
6307
+ Event[Event["MutationError"] = 102] = "MutationError";
6308
+ Event[Event["FragmentVisibility"] = 103] = "FragmentVisibility";
6309
+ Event[Event["Keystrokes"] = 104] = "Keystrokes";
6310
+ Event[Event["BackGesture"] = 105] = "BackGesture";
6311
+ Event[Event["WebViewStatus"] = 106] = "WebViewStatus";
6312
+ Event[Event["AppInstallReferrer"] = 107] = "AppInstallReferrer";
6313
+ // 200-300 reserved for internal use
6314
+ })(Event || (Event = {}));
6315
+
6316
+ var Constant;
6317
+ (function (Constant) {
6318
+ Constant["Empty"] = "";
6319
+ Constant["SvgPrefix"] = "svg:";
6320
+ Constant["DataPrefix"] = "data:";
6321
+ Constant["IFramePrefix"] = "iframe:";
6322
+ Constant["SvgNamespace"] = "http://www.w3.org/2000/svg";
6323
+ Constant["Id"] = "id";
6324
+ Constant["Class"] = "class";
6325
+ Constant["Style"] = "style";
6326
+ Constant["Href"] = "href";
6327
+ Constant["Src"] = "src";
6328
+ Constant["Srcset"] = "srcset";
6329
+ Constant["Hash"] = "#";
6330
+ Constant["Dot"] = ".";
6331
+ Constant["Separator"] = ">";
6332
+ Constant["Tilde"] = "~";
6333
+ Constant["Bang"] = "!";
6334
+ Constant["Period"] = ".";
6335
+ Constant["Comma"] = ",";
6336
+ Constant["DataAttribute"] = "data-";
6337
+ Constant["MaskData"] = "data-clarity-mask";
6338
+ Constant["UnmaskData"] = "data-clarity-unmask";
6339
+ Constant["RegionData"] = "data-clarity-region";
6340
+ Constant["GXDialogModal"] = "gx-dialog-modal";
6341
+ Constant["Type"] = "type";
6342
+ Constant["Submit"] = "submit";
6343
+ Constant["Name"] = "name";
6344
+ Constant["Base"] = "*B";
6345
+ Constant["SameOrigin"] = "*O";
6346
+ Constant["Object"] = "object";
6347
+ Constant["Function"] = "function";
6348
+ Constant["StyleTag"] = "STYLE";
6349
+ Constant["LinkTag"] = "LINK";
6350
+ Constant["InputTag"] = "INPUT";
6351
+ Constant["IFrameTag"] = "IFRAME";
6352
+ Constant["ImageTag"] = "IMG";
6353
+ Constant["TitleTag"] = "TITLE";
6354
+ Constant["BodyTag"] = "BODY";
6355
+ Constant["SvgTag"] = "svg:svg";
6356
+ Constant["BaseTag"] = "BASE";
6357
+ Constant["NativeCode"] = "[native code]";
6358
+ Constant["DocumentTag"] = "*D";
6359
+ Constant["ShadowDomTag"] = "*S";
6360
+ Constant["PolyfillShadowDomTag"] = "*P";
6361
+ Constant["TextTag"] = "*T";
6362
+ Constant["SuspendMutationTag"] = "*M";
6363
+ Constant["ChildList"] = "childList";
6364
+ Constant["Attributes"] = "attributes";
6365
+ Constant["CharacterData"] = "characterData";
6366
+ Constant["Throttle"] = "throttle";
6367
+ Constant["LoadEvent"] = "load";
6368
+ Constant["Pixel"] = "px";
6369
+ Constant["BorderBox"] = "border-box";
6370
+ Constant["Value"] = "value";
6371
+ Constant["MutationObserver"] = "MutationObserver";
6372
+ Constant["JsonLD"] = "application/ld+json";
6373
+ Constant["String"] = "string";
6374
+ Constant["Number"] = "number";
6375
+ Constant["Disable"] = "disable";
6376
+ Constant["HTML"] = "HTML";
6377
+ Constant["Property"] = "property";
6378
+ Constant["Content"] = "content";
6379
+ Constant["Generator"] = "generator";
6380
+ Constant["ogType"] = "og:type";
6381
+ Constant["ogTitle"] = "og:title";
6382
+ Constant["SvgStyle"] = "svg:style";
6383
+ Constant["StyleSheet"] = "stylesheet";
6384
+ })(Constant || (Constant = {}));
6385
+
6386
+ var ShortCircuitStrategy;
6387
+ (function (ShortCircuitStrategy) {
6388
+ ShortCircuitStrategy[ShortCircuitStrategy["None"] = 0] = "None";
6389
+ ShortCircuitStrategy[ShortCircuitStrategy["HashFirstTimestamp"] = 1] = "HashFirstTimestamp";
6390
+ ShortCircuitStrategy[ShortCircuitStrategy["HashFirstTimestampPlusBuffer"] = 2] = "HashFirstTimestampPlusBuffer";
6391
+ ShortCircuitStrategy[ShortCircuitStrategy["HashBeforeDeleted"] = 3] = "HashBeforeDeleted";
6392
+ })(ShortCircuitStrategy || (ShortCircuitStrategy = {}));
6393
+
6394
+ function isShadowDomNode(tag) {
6395
+ return tag === Constant.ShadowDomTag || tag === Constant.PolyfillShadowDomTag;
6396
+ }
6397
+ /** Scan the rendered DOM (including nested shadow roots) to collect tag names of shadow host elements. */
6398
+ function collectShadowHostTags(root, tags = new Set()) {
6399
+ root.querySelectorAll('*').forEach((el) => {
6400
+ if (el.shadowRoot) {
6401
+ tags.add(el.tagName);
6402
+ collectShadowHostTags(el.shadowRoot, tags);
6403
+ }
6404
+ });
6405
+ return tags;
6406
+ }
6407
+ /** Build a shadow subtree ID set from all DOM events.
6408
+ * Two-pass cascade to handle any event ordering:
6409
+ * Pass 1 — seed *S/*P node IDs.
6410
+ * Pass 2 — cascade: any node whose parent is in the set is also in the set (repeat until stable). */
6411
+ function buildShadowSubtreeIds(allDomEvents) {
6412
+ const subtreeIds = new Set();
6413
+ for (const e of allDomEvents) {
6414
+ const data = e.data;
6415
+ for (const node of data ?? []) {
6416
+ if (isShadowDomNode(node.tag))
6417
+ subtreeIds.add(node.id);
6418
+ }
6419
+ }
6420
+ let changed = true;
6421
+ while (changed) {
6422
+ changed = false;
6423
+ for (const e of allDomEvents) {
6424
+ const data = e.data;
6425
+ for (const node of data ?? []) {
6426
+ if (!subtreeIds.has(node.id) && subtreeIds.has(node.parent)) {
6427
+ subtreeIds.add(node.id);
6428
+ changed = true;
6429
+ }
6430
+ }
6431
+ }
6432
+ }
6433
+ return subtreeIds;
6434
+ }
6435
+ function filterShadowNodes(data, subtreeIds, shadowHostTags) {
6436
+ return (data?.filter((node) => {
6437
+ if (isShadowDomNode(node.tag))
6438
+ return true;
6439
+ if (shadowHostTags.has(node.tag ?? '') && subtreeIds.has(node.parent))
6440
+ return true;
6441
+ return subtreeIds.has(node.id);
6442
+ }) ?? []);
6443
+ }
6444
+ /** Extract shadow DOM nodes from merged.dom (initial Discover event, processed by setup()).
6445
+ * Returns a filtered copy of the dom event, or null if no shadow DOM present. */
6446
+ function extractSpecialDom(dom, events, shadowHostTags) {
6447
+ const mutationEvents = events.filter((e) => e.event === Event.Mutation);
6448
+ const subtreeIds = buildShadowSubtreeIds([dom, ...mutationEvents]);
6449
+ const shadowNodes = filterShadowNodes(dom.data, subtreeIds, shadowHostTags);
6450
+ return shadowNodes.length ? { ...dom, data: shadowNodes } : null;
6451
+ }
6452
+ /** Extract shadow DOM mutations + StyleSheet + CustomElement events from merged.events. */
6453
+ function extractSpecialEvents(events, dom, shadowHostTags) {
6454
+ const mutationEvents = events.filter((e) => e.event === Event.Mutation);
6455
+ const subtreeIds = buildShadowSubtreeIds([dom, ...mutationEvents]);
6456
+ const result = [];
6457
+ for (const e of events) {
6458
+ const ev = e.event;
6459
+ if (ev === Event.StyleSheetAdoption ||
6460
+ ev === Event.StyleSheetUpdate ||
6461
+ ev === Event.CustomElement) {
6462
+ result.push(e);
6463
+ continue;
6464
+ }
6465
+ if (ev === Event.Mutation) {
6466
+ const shadowNodes = filterShadowNodes(e.data, subtreeIds, shadowHostTags);
6467
+ if (shadowNodes.length)
6468
+ result.push({ ...e, data: shadowNodes });
6469
+ }
6470
+ }
6471
+ return result;
6472
+ }
6473
+
6474
+ const YIELD_INTERVAL_MS = 16;
6475
+ async function yieldToMain() {
6476
+ if ('scheduler' in globalThis && typeof globalThis.scheduler?.yield === 'function') {
6477
+ await globalThis.scheduler.yield();
6478
+ }
6479
+ else {
6480
+ await new Promise((resolve) => setTimeout(resolve, 0));
6481
+ }
6482
+ }
6112
6483
  class GXVisualizer extends Visualizer {
6113
6484
  attentionMap;
6114
6485
  originalClearmap;
@@ -6120,6 +6491,7 @@ class GXVisualizer extends Visualizer {
6120
6491
  this.originalClearmap = this.clearmap;
6121
6492
  this.clearmap = this.clearmapOverride;
6122
6493
  this.setup = this.setupOverride;
6494
+ this.html = this.htmlOverride;
6123
6495
  }
6124
6496
  setupOverride = async (target, options) => {
6125
6497
  this.attentionMap?.clear();
@@ -6131,6 +6503,99 @@ class GXVisualizer extends Visualizer {
6131
6503
  this.originalClearmap();
6132
6504
  this.attentionMap?.clear();
6133
6505
  };
6506
+ renderLoop = async (v, events, hash, useproxy, shortCircuitStrategy) => {
6507
+ let lastYield = performance.now();
6508
+ for (let i = 0; i < events.length; i++) {
6509
+ const now = performance.now();
6510
+ if (now - lastYield > YIELD_INTERVAL_MS) {
6511
+ await yieldToMain();
6512
+ lastYield = performance.now();
6513
+ }
6514
+ const entry = events[i];
6515
+ const entryEvent = entry.event;
6516
+ switch (entryEvent) {
6517
+ case Event.StyleSheetAdoption:
6518
+ case Event.StyleSheetUpdate:
6519
+ v.layout.styleChange(entry);
6520
+ break;
6521
+ case Event.CustomElement:
6522
+ v.layout.customElement(entry);
6523
+ break;
6524
+ case Event.Mutation: {
6525
+ const domEvent = entry;
6526
+ this.renderTime = domEvent.time;
6527
+ if (v.shortCircuitRendering(shortCircuitStrategy, domEvent, hash))
6528
+ return;
6529
+ v.layout.markup(domEvent, useproxy);
6530
+ break;
6531
+ }
6532
+ }
6533
+ }
6534
+ };
6535
+ htmlOverride = async (decoded, target, portalCanvasId, hash = '', useproxy, logerror, shortCircuitStrategy = ShortCircuitStrategy.None) => {
6536
+ if (decoded && decoded.length > 0 && target) {
6537
+ try {
6538
+ const v = this;
6539
+ const merged = v.mergeForHtml(decoded);
6540
+ await this.setup(target, { version: decoded[0].envelope.version, dom: merged.dom, useproxy, portalCanvasId });
6541
+ await this.renderLoop(v, merged.events, hash, useproxy, shortCircuitStrategy);
6542
+ }
6543
+ catch (e) {
6544
+ if (logerror)
6545
+ logerror(e);
6546
+ }
6547
+ }
6548
+ return this;
6549
+ };
6550
+ htmlCached = async (cacheKey, decoded, target, portalCanvasId, hash = '', useproxy, logerror, shortCircuitStrategy = 0) => {
6551
+ if (!decoded || decoded.length === 0 || !target)
6552
+ return this;
6553
+ const fullKey = buildCacheKey(cacheKey, 0);
6554
+ const cached = await htmlCache.get(fullKey);
6555
+ if (cached) {
6556
+ try {
6557
+ const v = this;
6558
+ await this.setup(target, { version: cached.version, useproxy, portalCanvasId });
6559
+ target.document.open();
6560
+ target.document.write(cached.html);
6561
+ target.document.close();
6562
+ v.layout.hydrate(target.document);
6563
+ // Replay shadow DOM from initial Discover event (was processed by setup() in full render)
6564
+ if (cached.specialDom) {
6565
+ v.layout.markup(cached.specialDom, useproxy);
6566
+ }
6567
+ // Replay shadow DOM mutations + StyleSheet + CustomElement
6568
+ await this.renderLoop(v, cached.specialEvents, '', useproxy, 0);
6569
+ return this;
6570
+ }
6571
+ catch (e) {
6572
+ if (logerror)
6573
+ logerror(e);
6574
+ }
6575
+ }
6576
+ try {
6577
+ const v = this;
6578
+ const merged = v.mergeForHtml(decoded);
6579
+ await this.setup(target, { version: decoded[0].envelope.version, dom: merged.dom, useproxy, portalCanvasId });
6580
+ await this.renderLoop(v, merged.events, hash, useproxy, shortCircuitStrategy);
6581
+ const shadowHostTags = collectShadowHostTags(target.document);
6582
+ const specialDom = extractSpecialDom(merged.dom, merged.events, shadowHostTags);
6583
+ const specialEvents = extractSpecialEvents(merged.events, merged.dom, shadowHostTags);
6584
+ void htmlCache.set({
6585
+ key: fullKey,
6586
+ html: target.document.documentElement.outerHTML,
6587
+ specialDom: specialDom,
6588
+ specialEvents,
6589
+ version: decoded[0].envelope.version,
6590
+ timestamp: Date.now(),
6591
+ });
6592
+ }
6593
+ catch (e) {
6594
+ if (logerror)
6595
+ logerror(e);
6596
+ }
6597
+ return this;
6598
+ };
6134
6599
  /**
6135
6600
  * Render attention/engagement map.
6136
6601
  * @param attentionData - Array of attention data points with start/end element hashes and time spent
@@ -6143,93 +6608,72 @@ class GXVisualizer extends Visualizer {
6143
6608
  };
6144
6609
  }
6145
6610
 
6146
- const perf = createPerfTimer('Render');
6147
- const useHeatmapRender = () => {
6148
- const viewId = useViewIdContext();
6149
- const data = useHeatmapDataContext((s) => s.data);
6611
+ const perf$1 = createPerfTimer('Render');
6612
+ const useHeatmapIframeProcessor = () => {
6150
6613
  const shopId = useHeatmapConfigStore((s) => s.shopId);
6151
- const excludeClassNames = useHeatmapConfigStore((s) => s.excludeClassNames);
6152
- const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
6153
- const setVizRef = useHeatmapVizRectContext((s) => s.setVizRef);
6154
- const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
6155
- const setIsRenderedViz = useHeatmapVizContext((s) => s.setIsRenderedViz);
6156
- const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
6157
- const contentWidth = useHeatmapWidthByDevice();
6158
6614
  const deviceType = useHeatmapSettingContext((s) => s.deviceType);
6159
- const iframeRef = useRef(null);
6615
+ const viewport = useHeatmapViewportByDevice();
6616
+ const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
6617
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
6160
6618
  const helperRef = useRef(null);
6161
- const abortRef = useRef(null);
6162
- const pendingDataRef = useRef(null);
6163
- const wrapperHeightRef = useRef(wrapperHeight);
6164
- wrapperHeightRef.current = wrapperHeight;
6165
- const contentWidthRef = useRef(contentWidth);
6166
- contentWidthRef.current = contentWidth;
6167
- const renderHeatmap = useCallback(async (payloads) => {
6168
- if (contentWidthRef.current === 0 || wrapperHeightRef.current === 0) {
6169
- pendingDataRef.current = payloads;
6619
+ const pendingRef = useRef(null);
6620
+ const reset = useCallback(() => {
6621
+ pendingRef.current = null;
6622
+ }, []);
6623
+ const run = useCallback((iframe, t0, abort) => {
6624
+ if (viewport.width === 0 || viewport.height === 0) {
6625
+ pendingRef.current = { iframe, t0, abort };
6170
6626
  return;
6171
6627
  }
6172
- pendingDataRef.current = null;
6173
- if (!payloads || payloads.length === 0)
6174
- return;
6175
- const iframe = iframeRef.current;
6176
- if (!iframe?.contentWindow)
6177
- return;
6178
- abortRef.current?.abort();
6179
- const abort = new AbortController();
6180
- abortRef.current = abort;
6181
- const t0 = perf.mark('renderHeatmap start');
6182
- const visualizer = vizRef ?? new GXVisualizer();
6183
- if (!vizRef)
6184
- setVizRef(visualizer);
6185
- visualizer.configure({ excludeClassNames });
6186
- setIsRenderedViz(false);
6187
- await perf.wrap('visualizer.html', () => visualizer.html(payloads, iframe.contentWindow, viewId));
6188
- if (abort.signal.aborted)
6189
- return;
6190
- const size = { width: contentWidthRef.current, height: wrapperHeightRef.current };
6191
6628
  startIframe({
6192
6629
  helperRef,
6193
6630
  iframe,
6194
6631
  shopId,
6195
6632
  deviceType,
6196
- size,
6633
+ size: viewport,
6197
6634
  t0,
6198
6635
  onSuccess: (height) => {
6199
6636
  if (abort.signal.aborted)
6200
6637
  return;
6201
6638
  if (height)
6202
6639
  setIframeHeight(height);
6203
- setIsRenderedViz(true);
6640
+ setIsDomLoaded(true);
6204
6641
  },
6205
6642
  });
6206
6643
  }, [deviceType]);
6644
+ // Retry when dims become available
6207
6645
  useEffect(() => {
6208
- if (!data || data.length === 0)
6646
+ if (viewport.width === 0 || viewport.height === 0)
6209
6647
  return;
6210
- const decoded = decodeArrayClarity(data);
6211
- renderHeatmap(decoded);
6212
- return () => { };
6213
- }, [data, renderHeatmap]);
6214
- // Retry pending render when dimensions become available
6215
- useEffect(() => {
6216
- if (contentWidth === 0 || wrapperHeight === 0)
6648
+ if (!pendingRef.current)
6217
6649
  return;
6218
- if (!pendingDataRef.current)
6650
+ const { iframe, t0, abort } = pendingRef.current;
6651
+ pendingRef.current = null;
6652
+ if (abort.signal.aborted)
6219
6653
  return;
6220
- const pending = pendingDataRef.current;
6221
- pendingDataRef.current = null;
6222
- renderHeatmap(pending);
6223
- }, [contentWidth, wrapperHeight, renderHeatmap]);
6654
+ startIframe({
6655
+ helperRef,
6656
+ iframe,
6657
+ shopId,
6658
+ deviceType,
6659
+ size: viewport,
6660
+ t0,
6661
+ onSuccess: (height) => {
6662
+ if (abort.signal.aborted)
6663
+ return;
6664
+ if (height)
6665
+ setIframeHeight(height);
6666
+ setIsDomLoaded(true);
6667
+ },
6668
+ });
6669
+ }, [viewport]); // eslint-disable-line react-hooks/exhaustive-deps
6224
6670
  useEffect(() => {
6225
6671
  return () => {
6226
- setVizRef(null);
6227
- abortRef.current?.abort();
6228
6672
  helperRef.current?.stop();
6229
6673
  helperRef.current = null;
6230
6674
  };
6231
- }, [setVizRef]);
6232
- return { iframeRef };
6675
+ }, []);
6676
+ return { run, reset };
6233
6677
  };
6234
6678
  // ── Helpers ───────────────────────────────────────────────────────────────────
6235
6679
  function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Desktop, size, t0, onSuccess, }) {
@@ -6238,7 +6682,7 @@ function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Deskt
6238
6682
  if (docHeight === 0)
6239
6683
  return;
6240
6684
  helperRef.current?.stop();
6241
- const tHelper = perf.mark('IframeHelper.start');
6685
+ const tHelper = perf$1.mark('IframeHelper.start');
6242
6686
  const helper = createIframeHelper();
6243
6687
  helperRef.current = helper;
6244
6688
  helper.start({
@@ -6249,17 +6693,81 @@ function startIframe({ helperRef, iframe, shopId, deviceType = EDeviceType.Deskt
6249
6693
  debug: true,
6250
6694
  shopId,
6251
6695
  onSuccess: (data) => {
6252
- perf.measure('IframeHelper processing', tHelper);
6253
- perf.measure('Total render', t0);
6696
+ perf$1.measure('IframeHelper processing', tHelper);
6697
+ perf$1.measure('Total render', t0);
6254
6698
  iframe.style.height = `${data.height}px`;
6255
6699
  onSuccess(data.height);
6256
6700
  },
6257
6701
  });
6258
6702
  }
6259
6703
 
6704
+ const EShortCircuitStrategy = {
6705
+ None: 0,
6706
+ HashFirstTimestamp: 1,
6707
+ HashFirstTimestampPlusBuffer: 2,
6708
+ HashBeforeDeleted: 3,
6709
+ };
6710
+ const perf = createPerfTimer('Render');
6711
+ const useHeatmapRenderDom = () => {
6712
+ const viewId = useViewIdContext();
6713
+ const data = useHeatmapDataContext((s) => s.data);
6714
+ const excludeClassNames = useHeatmapConfigStore((s) => s.excludeClassNames);
6715
+ const setVizRef = useHeatmapVizRectContext((s) => s.setVizRef);
6716
+ const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
6717
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
6718
+ const deviceType = useHeatmapSettingContext((s) => s.deviceType);
6719
+ const heatmapType = useHeatmapSettingContext((s) => s.heatmapType);
6720
+ const elementToShow = useHeatmapDataContext((s) => s.dataInfo?.elementToShow);
6721
+ const dataHash = useHeatmapDataContext((s) => s.dataHash);
6722
+ const iframeRef = useRef(null);
6723
+ const abortRef = useRef(null);
6724
+ const elementToShowRef = useRef(null);
6725
+ const dataHashRef = useRef(null);
6726
+ const heatmapTypeRef = useRef(heatmapType);
6727
+ elementToShowRef.current = elementToShow ?? null;
6728
+ dataHashRef.current = dataHash ?? null;
6729
+ heatmapTypeRef.current = heatmapType;
6730
+ const { run: runIframeSetup, reset: resetIframeSetup } = useHeatmapIframeProcessor();
6731
+ const renderHeatmap = useCallback(async (payloads) => {
6732
+ if (!payloads || payloads.length === 0)
6733
+ return;
6734
+ const iframe = iframeRef.current;
6735
+ const contentWindow = iframe?.contentWindow;
6736
+ if (!contentWindow)
6737
+ return;
6738
+ abortRef.current?.abort();
6739
+ const abort = new AbortController();
6740
+ abortRef.current = abort;
6741
+ resetIframeSetup();
6742
+ const t0 = perf.mark('renderHeatmap start');
6743
+ const visualizer = vizRef ?? new GXVisualizer();
6744
+ if (!vizRef)
6745
+ setVizRef(visualizer);
6746
+ visualizer.configure({ excludeClassNames });
6747
+ setIsDomLoaded(false);
6748
+ // Phase 1: render DOM — does not depend on contentWidth/wrapperHeight
6749
+ const hash = elementToShowRef.current ?? undefined;
6750
+ const cacheKey = dataHashRef.current;
6751
+ const strategy = hash ? EShortCircuitStrategy.HashFirstTimestampPlusBuffer : EShortCircuitStrategy.None;
6752
+ await perf.wrap('visualizer.html', () => cacheKey
6753
+ ? visualizer.htmlCached(cacheKey, payloads, contentWindow, viewId, hash, undefined, undefined, strategy)
6754
+ : visualizer.html(payloads, contentWindow, viewId, hash, undefined, undefined, strategy));
6755
+ if (abort.signal.aborted)
6756
+ return;
6757
+ // Phase 2: iframe setup — deferred to useIframeSetup (handles dims dependency)
6758
+ runIframeSetup(iframe, t0, abort);
6759
+ }, [deviceType]);
6760
+ useEffect(() => {
6761
+ if (!data || data.length === 0)
6762
+ return;
6763
+ renderHeatmap(decodeArrayClarity(data));
6764
+ }, [data, renderHeatmap]);
6765
+ return { iframeRef };
6766
+ };
6767
+
6260
6768
  const useReplayRender = () => {
6261
6769
  const data = useHeatmapDataContext((s) => s.data);
6262
- const setIsRenderedViz = useHeatmapVizContext((s) => s.setIsRenderedViz);
6770
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
6263
6771
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
6264
6772
  const visualizerRef = useRef(null);
6265
6773
  const iframeRef = useRef(null);
@@ -6279,7 +6787,7 @@ const useReplayRender = () => {
6279
6787
  version: envelope.version,
6280
6788
  onresize: (height) => {
6281
6789
  height && setIframeHeight(height);
6282
- setIsRenderedViz(true);
6790
+ setIsDomLoaded(true);
6283
6791
  },
6284
6792
  mobile,
6285
6793
  vNext: true,
@@ -6382,10 +6890,12 @@ const useReplayRender = () => {
6382
6890
  const useHeatmapRenderByMode = (mode) => {
6383
6891
  const heatmapResult = useMemo(() => {
6384
6892
  switch (mode) {
6385
- case 'heatmap':
6386
- return useHeatmapRender;
6387
- case 'replay':
6893
+ case EHeatmapMode.Heatmap:
6894
+ return useHeatmapRenderDom;
6895
+ case EHeatmapMode.Replay:
6388
6896
  return useReplayRender;
6897
+ default:
6898
+ return useHeatmapRenderDom;
6389
6899
  }
6390
6900
  }, [mode]);
6391
6901
  return heatmapResult();
@@ -6420,22 +6930,10 @@ const useContainerDimensions = (props) => {
6420
6930
  return { containerWidth, containerHeight };
6421
6931
  };
6422
6932
 
6423
- const useContentDimensions = ({ iframeRef }) => {
6424
- const contentWidth = useHeatmapWidthByDevice();
6425
- useEffect(() => {
6426
- if (!contentWidth)
6427
- return;
6428
- if (!iframeRef.current)
6429
- return;
6430
- // iframeRef.current.width = `${contentWidth}px`;
6431
- }, [contentWidth, iframeRef]);
6432
- return { contentWidth };
6433
- };
6434
-
6435
6933
  const useObserveIframeHeight = (props) => {
6436
6934
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
6437
6935
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
6438
- const isRenderedViz = useHeatmapVizContext((s) => s.isRenderedViz);
6936
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
6439
6937
  const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
6440
6938
  const { iframeRef } = props;
6441
6939
  const resizeObserverRef = useRef(null);
@@ -6496,7 +6994,7 @@ const useObserveIframeHeight = (props) => {
6496
6994
  }, [updateIframeHeight]);
6497
6995
  useEffect(() => {
6498
6996
  const iframe = iframeRef.current;
6499
- if (!iframe || !iframeHeight || !isRenderedViz)
6997
+ if (!iframe || !iframeHeight || !isDomLoaded)
6500
6998
  return;
6501
6999
  const setupObservers = () => {
6502
7000
  try {
@@ -6558,7 +7056,7 @@ const useObserveIframeHeight = (props) => {
6558
7056
  }
6559
7057
  iframe.removeEventListener('load', setupObservers);
6560
7058
  };
6561
- }, [iframeRef, iframeHeight, isRenderedViz]);
7059
+ }, [iframeRef, iframeHeight, isDomLoaded]);
6562
7060
  return {};
6563
7061
  };
6564
7062
 
@@ -6571,9 +7069,10 @@ const useScaleCalculation = (props) => {
6571
7069
  const setScale = useHeatmapVizContext((s) => s.setScale);
6572
7070
  const setIsScaledToFit = useHeatmapVizContext((s) => s.setIsScaledToFit);
6573
7071
  const setMinZoomRatio = useHeatmapVizContext((s) => s.setMinZoomRatio);
6574
- const { containerWidth, containerHeight, contentWidth, contentHeight } = props;
7072
+ const viewport = useHeatmapViewportByDevice();
7073
+ const { containerWidth, containerHeight, iframeHeight } = props;
6575
7074
  const calculateScaleResult = useCallback(() => {
6576
- if (containerWidth > 0 && contentWidth > 0 && containerHeight > 0 && contentHeight > 0) {
7075
+ if (containerWidth > 0 && viewport.width > 0 && containerHeight > 0 && iframeHeight > 0) {
6577
7076
  // 1. Calculate available dimensions
6578
7077
  const availableWidth = containerWidth - HEATMAP_CONFIG['padding'] * 2;
6579
7078
  const toolbarHeight = HEATMAP_CONFIG['heightToolbar'] || 0;
@@ -6581,12 +7080,12 @@ const useScaleCalculation = (props) => {
6581
7080
  const availableHeight = containerHeight - toolbarHeight - paddingTotal;
6582
7081
  // 2. Calculate widthScale (base scale to fit content width into container width)
6583
7082
  // This represents 100% zoom (fit to width)
6584
- const widthScale = Math.min(availableWidth / contentWidth, 1);
7083
+ const widthScale = Math.min(availableWidth / viewport.width, 1);
6585
7084
  // 3. Calculate minZoomRatio (zoom ratio to fit height)
6586
7085
  // At minZoomRatio, the content should fit entirely within the container height
6587
- // Formula: contentHeight * widthScale * (minZoomRatio / 100) = availableHeight
6588
- // => minZoomRatio = (availableHeight / (contentHeight * widthScale)) * 100
6589
- const calculatedMinZoomRatio = (availableHeight / (contentHeight * widthScale)) * 100;
7086
+ // Formula: iframeHeight * widthScale * (minZoomRatio / 100) = availableHeight
7087
+ // => minZoomRatio = (availableHeight / (iframeHeight * widthScale)) * 100
7088
+ const calculatedMinZoomRatio = (availableHeight / (iframeHeight * widthScale)) * 100;
6590
7089
  // Limit minZoomRatio: cannot exceed MAX_ZOOM_RATIO (100%)
6591
7090
  // and should have a reasonable minimum (e.g., 1%)
6592
7091
  const finalMinZoomRatio = Math.max(1, Math.min(calculatedMinZoomRatio, maxZoomRatio));
@@ -6605,7 +7104,7 @@ const useScaleCalculation = (props) => {
6605
7104
  setIsScaledToFit(isCurrentlyFitted);
6606
7105
  setMinZoomRatio(finalMinZoomRatio);
6607
7106
  }
6608
- }, [containerWidth, containerHeight, contentWidth, contentHeight, zoomRatio, maxZoomRatio]);
7107
+ }, [containerWidth, containerHeight, viewport.width, iframeHeight, zoomRatio, maxZoomRatio]);
6609
7108
  useEffect(() => {
6610
7109
  calculateScaleResult();
6611
7110
  }, [calculateScaleResult]);
@@ -6638,20 +7137,15 @@ const useHeatmapScale = (props) => {
6638
7137
  // 1. Observe container dimensions
6639
7138
  const { containerWidth, containerHeight } = useContainerDimensions({ wrapperRef });
6640
7139
  // 2. Get content dimensions from config
6641
- const { contentWidth } = useContentDimensions({ iframeRef });
7140
+ const viewport = useHeatmapViewportByDevice();
6642
7141
  // 3. Observe iframe height (now reacts to width changes)
6643
7142
  useObserveIframeHeight({ iframeRef });
6644
7143
  // 4. Calculate scale
6645
- const { widthScale } = useScaleCalculation({
6646
- containerWidth,
6647
- containerHeight,
6648
- contentWidth,
6649
- contentHeight: iframeHeight,
6650
- });
7144
+ const { widthScale } = useScaleCalculation({ containerWidth, containerHeight, iframeHeight });
6651
7145
  // 5. Setup scroll sync
6652
7146
  const { handleScroll } = useScrollSync({ widthScale, iframeRef });
6653
7147
  const scaledHeight = iframeHeight * widthScale;
6654
- const scaledWidth = contentWidth * widthScale;
7148
+ const scaledWidth = viewport.width * widthScale;
6655
7149
  return {
6656
7150
  scaledWidth,
6657
7151
  scaledHeight,
@@ -7690,11 +8184,11 @@ const AutoScrollHandler = ({ visualRef }) => {
7690
8184
  };
7691
8185
 
7692
8186
  const PortalAreaRenderer = ({ iframeRef, visualRef, shadowRoot, onAreaCreated, onAreaClick, }) => {
7693
- const isRenderedViz = useHeatmapVizContext((s) => s.isRenderedViz);
8187
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
7694
8188
  const iframeDocument = iframeRef.current?.contentDocument || undefined;
7695
8189
  const { shadowContainer, isReady } = useAreaRendererContainer(iframeDocument, shadowRoot);
7696
- useAreaRectSync({ iframeDocument, shadowRoot, enabled: isReady && isRenderedViz });
7697
- useAreaPositionsUpdater({ iframeRef, visualRef, enabled: isReady && isRenderedViz });
8190
+ useAreaRectSync({ iframeDocument, shadowRoot, enabled: isReady && isDomLoaded });
8191
+ useAreaPositionsUpdater({ iframeRef, visualRef, enabled: isReady && isDomLoaded });
7698
8192
  if (!shadowContainer || !isReady)
7699
8193
  return null;
7700
8194
  return (jsxs(Fragment$1, { children: [jsx(AutoScrollHandler, { visualRef: visualRef }), jsx(AreasPortal, { shadowContainer: shadowContainer, onAreaClick: onAreaClick }), jsx(AreaEditHighlightPortal, { shadowContainer: shadowContainer, iframeRef: iframeRef, customShadowRoot: shadowRoot, onAreaCreated: onAreaCreated })] }));
@@ -7703,7 +8197,7 @@ const PortalAreaRenderer = ({ iframeRef, visualRef, shadowRoot, onAreaCreated, o
7703
8197
  const VizAreaClick = ({ iframeRef, visualRef, shadowRoot, autoCreateTopN = 10, enableOverlapResolution = true, onAreaClick, }) => {
7704
8198
  const clickAreas = useHeatmapDataContext((s) => s.clickAreas);
7705
8199
  const resetView = useHeatmapAreaClickContext((s) => s.resetView);
7706
- const isRenderedViz = useHeatmapVizContext((s) => s.isRenderedViz);
8200
+ const isDomLoaded = useHeatmapVizContext((s) => s.isDomLoaded);
7707
8201
  useAreaTopAutoDetect({ autoCreateTopN, shadowRoot, disabled: !!clickAreas?.length });
7708
8202
  useAreaFilterVisible({ iframeRef, enableOverlapResolution });
7709
8203
  useAreaHydration({ shadowRoot });
@@ -7712,7 +8206,7 @@ const VizAreaClick = ({ iframeRef, visualRef, shadowRoot, autoCreateTopN = 10, e
7712
8206
  resetView();
7713
8207
  };
7714
8208
  }, []);
7715
- if (!iframeRef.current || !isRenderedViz)
8209
+ if (!iframeRef.current || !isDomLoaded)
7716
8210
  return null;
7717
8211
  return (jsx(Fragment, { children: jsx(PortalAreaRenderer, { iframeRef: iframeRef, visualRef: visualRef, shadowRoot: shadowRoot, onAreaClick: onAreaClick }) }));
7718
8212
  };
@@ -7843,7 +8337,7 @@ const useAnchorPosition = (calloutRef, props) => {
7843
8337
  const ElementMissing = ({ show = true, visualRef }) => {
7844
8338
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
7845
8339
  const missingElementRef = useRef(null);
7846
- const wrapperWidth = useHeatmapWidthByDevice();
8340
+ const viewport = useHeatmapViewportByDevice();
7847
8341
  const [scrollPosition, setScrollPosition] = useState({ scrollTop: 0, scrollLeft: 0 });
7848
8342
  useEffect(() => {
7849
8343
  const container = visualRef.current;
@@ -7873,7 +8367,7 @@ const ElementMissing = ({ show = true, visualRef }) => {
7873
8367
  const containerHeight = containerRect?.height ?? 0;
7874
8368
  const topPosition = scrollTop + (containerHeight + elementHeightCenter) / 2;
7875
8369
  const topPositionScaled = topPosition / widthScale;
7876
- const leftPosition = wrapperWidth / 2;
8370
+ const leftPosition = viewport.width / 2;
7877
8371
  return (jsxs(Fragment, { children: [jsx("div", { className: "missingElement-backdrop", style: {
7878
8372
  position: 'absolute',
7879
8373
  top: 0,
@@ -7998,7 +8492,7 @@ const ElementOverlayComponent = (props) => {
7998
8492
  const { type, element, onClick, elementId, hideOutline } = props;
7999
8493
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
8000
8494
  const viewportHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8001
- const viewportWidth = useHeatmapWidthByDevice();
8495
+ const viewport = useHeatmapViewportByDevice();
8002
8496
  const overlayStyle = useMemo(() => {
8003
8497
  const isInvalid = !element || (element.width === 0 && element.height === 0);
8004
8498
  if (isInvalid)
@@ -8015,7 +8509,7 @@ const ElementOverlayComponent = (props) => {
8015
8509
  const isHovered = type === 'hovered';
8016
8510
  const badgeWidthScale = isHovered ? 1 : widthScale;
8017
8511
  const showCallout = !!element?.mousePosition && !isHovered;
8018
- return (jsxs(Fragment$1, { children: [jsx("div", { onClick: onClick, className: `heatmapElement heatmapElement--${type} ${hideOutline ? 'heatmapElement--hide-outline' : ''}`, id: elementId, style: overlayStyle, children: showCallout && jsx(ElementCalloutOverlay, { ...props }) }), jsx(BackdropCanvas, { activeElement: overlayStyle, viewportWidth: viewportWidth, viewportHeight: viewportHeight, show: !isHovered }), jsx(RankBadge, { hash: element.hash, show: isHovered, index: element.rank, elementRect: element, widthScale: badgeWidthScale, clickOnElement: onClick })] }));
8512
+ return (jsxs(Fragment$1, { children: [jsx("div", { onClick: onClick, className: `heatmapElement heatmapElement--${type} ${hideOutline ? 'heatmapElement--hide-outline' : ''}`, id: elementId, style: overlayStyle, children: showCallout && jsx(ElementCalloutOverlay, { ...props }) }), jsx(BackdropCanvas, { activeElement: overlayStyle, viewportWidth: viewport.width, viewportHeight: viewportHeight, show: !isHovered }), jsx(RankBadge, { hash: element.hash, show: isHovered, index: element.rank, elementRect: element, widthScale: badgeWidthScale, clickOnElement: onClick })] }));
8019
8513
  };
8020
8514
  ElementOverlayComponent.displayName = 'ElementOverlay';
8021
8515
  const ElementOverlay = memo(ElementOverlayComponent);
@@ -8080,7 +8574,7 @@ const HeatmapElements = (props) => {
8080
8574
  };
8081
8575
 
8082
8576
  const VizElements = ({ iframeRef, visualRef, wrapperRef }) => {
8083
- const contentWidth = useHeatmapWidthByDevice();
8577
+ const viewport = useHeatmapViewportByDevice();
8084
8578
  const dataInfo = useHeatmapDataContext((s) => s.dataInfo);
8085
8579
  const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
8086
8580
  const visualizer = {
@@ -8094,7 +8588,7 @@ const VizElements = ({ iframeRef, visualRef, wrapperRef }) => {
8094
8588
  if (!iframeRef.current)
8095
8589
  return null;
8096
8590
  return (jsx(HeatmapElements, { visualizer: visualizer, visualRef: visualRef, iframeRef: iframeRef, wrapperRef: wrapperRef, heatmapInfo: dataInfo, isVisible: true, positionMode: DEFAULT_POSITION_MODE, isHideTopRank: true, iframeDimensions: {
8097
- width: contentWidth,
8591
+ width: viewport.width,
8098
8592
  position: 'absolute',
8099
8593
  top: 0,
8100
8594
  left: 0,
@@ -8358,7 +8852,7 @@ const VizLoadingCanvas = () => {
8358
8852
  const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHeight, onScroll, }) => {
8359
8853
  const isLoadingCanvas = useHeatmapSettingContext((state) => state.isLoadingCanvas);
8360
8854
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
8361
- const contentWidth = useHeatmapWidthByDevice();
8855
+ const viewport = useHeatmapViewportByDevice();
8362
8856
  const contentHeight = calcContentHeight();
8363
8857
  return (jsx("div", { ref: visualRef, className: "gx-hm-visual Polaris-Scrollable Polaris-Scrollable--vertical Polaris-Scrollable--scrollbarWidthThin Polaris-Scrollable--scrollbarGutterStable", onScroll: onScroll, style: {
8364
8858
  overflowX: 'hidden',
@@ -8380,7 +8874,7 @@ const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHe
8380
8874
  paddingBottom: HEATMAP_STYLE['viz']['paddingBottom'],
8381
8875
  background: HEATMAP_STYLE['viz']['background'],
8382
8876
  }, children: jsx("div", { className: "gx-hm-wrapper", ref: wrapperRef, style: {
8383
- width: contentWidth,
8877
+ width: viewport.width,
8384
8878
  height: iframeHeight,
8385
8879
  transform: `scale(${widthScale})`,
8386
8880
  transformOrigin: 'top center',
@@ -8393,14 +8887,14 @@ const WrapperVisual = ({ children, visualRef, wrapperRef, scaledHeight, iframeHe
8393
8887
  }
8394
8888
  };
8395
8889
 
8396
- const VizDomRenderer = ({ mode = 'heatmap' }) => {
8890
+ const VizDomRenderer = ({ mode }) => {
8397
8891
  const viewId = useViewIdContext();
8398
- const contentWidth = useHeatmapWidthByDevice();
8892
+ const viewport = useHeatmapViewportByDevice();
8399
8893
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8400
8894
  const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
8401
8895
  const wrapperRef = useRef(null);
8402
8896
  const visualRef = useRef(null);
8403
- const { iframeRef } = useHeatmapRenderByMode(mode);
8897
+ const { iframeRef } = useHeatmapRenderDom();
8404
8898
  const { scaledHeight, handleScroll } = useHeatmapScale({ wrapperRef, iframeRef, visualRef });
8405
8899
  useHeatmapCanvas();
8406
8900
  useRenderCount('VizDomRenderer');
@@ -8408,7 +8902,7 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
8408
8902
  const scrollTop = e.currentTarget.scrollTop;
8409
8903
  handleScroll(scrollTop);
8410
8904
  };
8411
- return (jsxs(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, onScroll: onScroll, iframeHeight: iframeHeight, children: [jsx(VizClickmap, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef }), jsx("iframe", { ...HEATMAP_IFRAME, id: `clarity-iframe-${viewId}`, ref: iframeRef, width: contentWidth, height: wrapperHeight }), jsx(VizLoadingCanvas, {}), jsx(VizScrollMap, { visualRef: visualRef, iframeRef: iframeRef, wrapperRef: wrapperRef })] }));
8905
+ return (jsxs(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, onScroll: onScroll, iframeHeight: iframeHeight, children: [jsx(VizClickmap, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef }), jsx("iframe", { ...HEATMAP_IFRAME, id: `clarity-iframe-${viewId}`, ref: iframeRef, width: viewport.width, height: wrapperHeight }), jsx(VizLoadingCanvas, {}), jsx(VizScrollMap, { visualRef: visualRef, iframeRef: iframeRef, wrapperRef: wrapperRef })] }));
8412
8906
  };
8413
8907
 
8414
8908
  const VizLoading = () => {
@@ -8425,8 +8919,9 @@ const VizLoading = () => {
8425
8919
  const VizDomHeatmap = () => {
8426
8920
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8427
8921
  const setIframeHeight = useHeatmapVizRectContext((s) => s.setIframeHeight);
8922
+ const setWrapperHeight = useHeatmapVizRectContext((s) => s.setWrapperHeight);
8428
8923
  const setVizRef = useHeatmapVizRectContext((s) => s.setVizRef);
8429
- const setIsRenderedViz = useHeatmapVizContext((s) => s.setIsRenderedViz);
8924
+ const setIsDomLoaded = useHeatmapVizContext((s) => s.setIsDomLoaded);
8430
8925
  const setSelectedElement = useHeatmapClickContext((s) => s.setSelectedElement);
8431
8926
  const setHoveredElement = useHeatmapHoverContext((s) => s.setHoveredElement);
8432
8927
  // const setSelectedArea = useHeatmapAreaClickContext((s) => s.setSelectedArea);
@@ -8436,7 +8931,8 @@ const VizDomHeatmap = () => {
8436
8931
  const cleanUp = () => {
8437
8932
  setVizRef(null);
8438
8933
  setIframeHeight(0);
8439
- setIsRenderedViz(false);
8934
+ setWrapperHeight(0);
8935
+ setIsDomLoaded(false);
8440
8936
  setSelectedElement(null);
8441
8937
  setHoveredElement(null);
8442
8938
  // setSelectedArea(null);
@@ -8445,13 +8941,13 @@ const VizDomHeatmap = () => {
8445
8941
  };
8446
8942
  useEffect(() => {
8447
8943
  return cleanUp;
8448
- }, []);
8449
- return (jsxs(VizContainer, { isActive: true, children: [jsx(VizDomRenderer, {}), iframeHeight === 0 && jsx(VizLoading, {})] }));
8944
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
8945
+ return (jsxs(VizContainer, { isActive: true, children: [jsx(VizDomRenderer, { mode: EHeatmapMode.Heatmap }), iframeHeight === 0 && jsx(VizLoading, {})] }));
8450
8946
  };
8451
8947
  VizDomHeatmap.displayName = 'VizDomHeatmap';
8452
8948
 
8453
8949
  const VizLiveRenderer = () => {
8454
- const contentWidth = useHeatmapWidthByDevice();
8950
+ const viewport = useHeatmapViewportByDevice();
8455
8951
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8456
8952
  const wrapperHeight = useHeatmapVizRectContext((s) => s.wrapperHeight);
8457
8953
  const visualRef = useRef(null);
@@ -8462,7 +8958,7 @@ const VizLiveRenderer = () => {
8462
8958
  const scrollTop = e.currentTarget.scrollTop;
8463
8959
  handleScroll(scrollTop);
8464
8960
  };
8465
- return (jsx(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, iframeHeight: iframeHeight, onScroll: onScroll, children: jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: contentWidth, height: wrapperHeight, scrolling: "no" }) }));
8961
+ return (jsx(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, iframeHeight: iframeHeight, onScroll: onScroll, children: jsx("iframe", { ref: iframeRef, ...HEATMAP_IFRAME, width: viewport.width, height: wrapperHeight, scrolling: "no" }) }));
8466
8962
  };
8467
8963
 
8468
8964
  const VizLiveHeatmap = () => {
@@ -8553,4 +9049,4 @@ const HeatmapLayout = ({ shopId, data, clickmap, clickAreas, scrollmap, attentio
8553
9049
  }
8554
9050
  };
8555
9051
 
8556
- export { BACKDROP_CONFIG, DEFAULT_SIDEBAR_WIDTH, DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO, EClickMode, EClickRankType, EClickType, EDeviceType, EHeatmapDataSource, EHeatmapMode, EHeatmapType, ELM_CALLOUT_CONFIG, EScrollType, GraphView, HEATMAP_CONFIG, HEATMAP_IFRAME, HEATMAP_STYLE, HeatmapLayout, ViewIdContext, Z_INDEX$1 as Z_INDEX, compareViewPerformance, convertViewportToIframeCoords, createStorePerformanceTracker, createViewContextHook, decodeArrayClarity, decodeClarity, downloadPerformanceReport, getCompareViewId, getMetricsByViewId, getPerformanceReportJSON, getScrollGradientColor, performanceLogger, printPerformanceSummary, scrollToElementIfNeeded, sendPerformanceReport, serializeAreas, trackStoreAction, useAreaCreation, useAreaEditMode, useAreaFilterVisible, useAreaHydration, useAreaInteraction, useAreaPositionsUpdater, useAreaRectSync, useAreaRendererContainer, useAreaTopAutoDetect, useClickedElement, useDebounceCallback, useElementCalloutVisible, useHeatmapAreaClickContext, useHeatmapCanvas, useHeatmapClickContext, useHeatmapCompareStore, useHeatmapConfigStore, useHeatmapCopyView, useHeatmapDataContext, useHeatmapEffects, useHeatmapElementPosition, useHeatmapHoverContext, useHeatmapLiveContext, useHeatmapRenderByMode, useHeatmapScale, useHeatmapScroll, useHeatmapScrollContext, useHeatmapSettingContext, useHeatmapVizContext, useHeatmapVizRectContext, useHeatmapWidthByDevice, useHoveredElement, useMeasureFunction, useRegisterConfig, useRegisterControl, useRegisterData, useRegisterHeatmap, useRenderCount, useScrollmapZones, useTrackHookCall, useViewIdContext, useVizLiveRender, useWhyDidYouUpdate, useWrapperRefHeight, useZonePositions, withPerformanceTracking };
9052
+ export { BACKDROP_CONFIG, DEFAULT_SIDEBAR_WIDTH, DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO, EClickMode, EClickRankType, EClickType, EDeviceType, EHeatmapDataSource, EHeatmapMode, EHeatmapType, ELM_CALLOUT_CONFIG, EScrollType, GraphView, HEATMAP_CONFIG, HEATMAP_IFRAME, HEATMAP_STYLE, HeatmapLayout, ViewIdContext, Z_INDEX$1 as Z_INDEX, compareViewPerformance, convertViewportToIframeCoords, createStorePerformanceTracker, createViewContextHook, decodeArrayClarity, decodeClarity, downloadPerformanceReport, getCompareViewId, getMetricsByViewId, getPerformanceReportJSON, getScrollGradientColor, performanceLogger, printPerformanceSummary, scrollToElementIfNeeded, sendPerformanceReport, serializeAreas, trackStoreAction, useAreaCreation, useAreaEditMode, useAreaFilterVisible, useAreaHydration, useAreaInteraction, useAreaPositionsUpdater, useAreaRectSync, useAreaRendererContainer, useAreaTopAutoDetect, useClickedElement, useDebounceCallback, useElementCalloutVisible, useHeatmapAreaClickContext, useHeatmapCanvas, useHeatmapClickContext, useHeatmapCompareStore, useHeatmapConfigStore, useHeatmapCopyView, useHeatmapDataContext, useHeatmapEffects, useHeatmapElementPosition, useHeatmapHoverContext, useHeatmapLiveContext, useHeatmapRenderByMode, useHeatmapScale, useHeatmapScroll, useHeatmapScrollContext, useHeatmapSettingContext, useHeatmapViewportByDevice, useHeatmapVizContext, useHeatmapVizRectContext, useHoveredElement, useMeasureFunction, useRegisterConfig, useRegisterControl, useRegisterData, useRegisterHeatmap, useRenderCount, useScrollmapZones, useTrackHookCall, useViewIdContext, useVizLiveRender, useWhyDidYouUpdate, useWrapperRefHeight, useZonePositions, withPerformanceTracking };