@cloudparse/up-miniapps-sdk 0.6.8 → 0.7.3

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.
package/dist/index.cjs CHANGED
@@ -65,6 +65,7 @@ __export(src_exports, {
65
65
  useMapControls: () => useMapControls,
66
66
  useMockLocation: () => useMockLocation,
67
67
  useRoute: () => useRoute,
68
+ useTapAction: () => useTapAction,
68
69
  useTrimmedRoute: () => useTrimmedRoute,
69
70
  useUserLocation: () => useUserLocation
70
71
  });
@@ -137,6 +138,59 @@ function isRunningInsideNativeShell() {
137
138
  // src/bridge.ts
138
139
  var BridgeTimeoutError = class extends Error {
139
140
  };
141
+ var MOCK_ACHIEVEMENTS = [
142
+ {
143
+ completed: true,
144
+ description: "Complete your first navigation journey.",
145
+ playerActionCount: 1,
146
+ priority: 1,
147
+ slug: "first-journey",
148
+ title: "First Steps",
149
+ totalActionCount: 1,
150
+ upReward: 20,
151
+ xpReward: 40
152
+ },
153
+ {
154
+ completed: false,
155
+ description: "Discover 5 points of interest around Annecy.",
156
+ playerActionCount: 3,
157
+ priority: 2,
158
+ slug: "explore-5-pois",
159
+ title: "Explorer",
160
+ totalActionCount: 5,
161
+ upReward: 50,
162
+ xpReward: 100
163
+ },
164
+ {
165
+ completed: false,
166
+ description: "Scan 10 QR codes at partner venues.",
167
+ playerActionCount: 4,
168
+ priority: 3,
169
+ slug: "scan-10-qrcodes",
170
+ title: "Code Breaker",
171
+ totalActionCount: 10,
172
+ upReward: 80,
173
+ xpReward: 150
174
+ }
175
+ ];
176
+ function mockAchievement(slug) {
177
+ const found = MOCK_ACHIEVEMENTS.find((a) => a.slug === slug);
178
+ if (found) return found;
179
+ return {
180
+ completed: false,
181
+ description: "Mocked achievement (no native shell attached).",
182
+ playerActionCount: 0,
183
+ priority: 1,
184
+ slug: slug || "unknown-achievement",
185
+ title: slug || "Unknown Achievement",
186
+ totalActionCount: 1,
187
+ upReward: 0,
188
+ xpReward: 0
189
+ };
190
+ }
191
+ function mockAchievements() {
192
+ return MOCK_ACHIEVEMENTS;
193
+ }
140
194
  var Bridge = class {
141
195
  callbacks = /* @__PURE__ */ new Map();
142
196
  eventListeners = /* @__PURE__ */ new Map();
@@ -287,6 +341,12 @@ var Bridge = class {
287
341
  return this.mockSaveImage(
288
342
  payload
289
343
  );
344
+ case "GET_ACHIEVEMENT":
345
+ return Promise.resolve(
346
+ mockAchievement(payload?.slug)
347
+ );
348
+ case "GET_ACHIEVEMENTS":
349
+ return Promise.resolve(mockAchievements());
290
350
  default:
291
351
  console.warn(
292
352
  `[Bridge] Mock mode active: Unhandled message type ${type}`
@@ -475,412 +535,27 @@ SheetDescription.displayName = SheetPrimitive.Description.displayName;
475
535
  // src/components/Map/components/MapDrawer.tsx
476
536
  var import_react2 = require("react");
477
537
  var import_jsx_runtime3 = require("react/jsx-runtime");
478
- var resolveHeightToPixels = (height, containerHeight) => {
479
- if (typeof height === "number") {
480
- return height;
481
- }
482
- if (height.endsWith("%")) {
483
- return parseFloat(height) / 100 * containerHeight;
484
- }
485
- return parseFloat(height);
486
- };
487
- var CONTENT_EDGE_PULL_THRESHOLD_PX = 24;
488
- var HANDLE_BAR_HEIGHT_PX = 32;
489
- var HANDLE_TAP_CLICK_SUPPRESSION_MS = 400;
490
538
  var MapDrawer = (0, import_react2.forwardRef)(
491
539
  ({
492
540
  menuItems,
493
541
  state,
494
542
  onChangeState,
495
- side,
496
- etaBarHeight = 0,
497
- etaData,
498
- touchStartY,
499
- setTouchStartY,
500
- currentTouchY,
501
- setCurrentTouchY,
502
- isDragging,
503
- clampedDragOffset,
504
- drawerPeekHeight,
505
- drawerFullHeight,
506
- drawerAutoMaxHeight,
507
- containerHeight,
508
543
  menuContent,
509
- enableTouchDrag = false,
510
- handleVisible = true,
511
- onAutoContentHeightChange,
512
544
  showScrollToTopButton = true,
513
- scrollToTopThreshold = 300,
514
- safeAreaInsets = { bottom: 0, left: 0, right: 0, top: 0 }
545
+ scrollToTopThreshold = 300
515
546
  }, ref) => {
516
547
  const scrollContainerRef = (0, import_react2.useRef)(null);
517
- const containerRef = (0, import_react2.useRef)(null);
518
- const handleBarRef = (0, import_react2.useRef)(null);
519
- const contentAreaRef = (0, import_react2.useRef)(null);
520
548
  (0, import_react2.useImperativeHandle)(
521
549
  ref,
522
550
  () => scrollContainerRef.current
523
551
  );
524
- const handleHandleClick = () => {
525
- if (side === "left") {
526
- onChangeState(state === "closed" ? "full" : "closed");
527
- } else {
528
- if (state === "closed") {
529
- onChangeState("peek");
530
- } else if (state === "peek") {
531
- onChangeState("full");
532
- } else if (state === "auto") {
533
- onChangeState("closed");
534
- } else {
535
- onChangeState("peek");
536
- }
537
- }
538
- };
539
- const handleHandleClickRef = (0, import_react2.useRef)(handleHandleClick);
540
- handleHandleClickRef.current = handleHandleClick;
541
- const [autoContentPx, setAutoContentPx] = (0, import_react2.useState)(0);
542
- (0, import_react2.useEffect)(() => {
543
- if (state !== "auto") return;
544
- const scrollEl = scrollContainerRef.current;
545
- const contentAreaEl = contentAreaRef.current;
546
- if (!scrollEl || !contentAreaEl) return;
547
- const handleHeight = handleVisible ? handleBarRef.current?.offsetHeight ?? 0 : 0;
548
- const contentEl = scrollEl.firstElementChild;
549
- const measure = () => {
550
- const contentAreaStyle = window.getComputedStyle(contentAreaEl);
551
- const verticalPadding = parseFloat(contentAreaStyle.paddingTop || "0") + parseFloat(contentAreaStyle.paddingBottom || "0");
552
- const contentHeight = contentEl?.scrollHeight ?? scrollEl.scrollHeight;
553
- const px = handleHeight + verticalPadding + contentHeight;
554
- setAutoContentPx(px);
555
- onAutoContentHeightChange?.(px);
556
- };
557
- measure();
558
- const ro = new ResizeObserver(measure);
559
- ro.observe(contentEl ?? scrollEl);
560
- return () => ro.disconnect();
561
- }, [state, handleVisible, onAutoContentHeightChange]);
562
552
  const [showScrollTop, setShowScrollTop] = (0, import_react2.useState)(false);
563
553
  const handleScroll = (e) => {
564
554
  const scrollTop = e.currentTarget.scrollTop;
565
555
  setShowScrollTop(state !== "closed" && scrollTop > scrollToTopThreshold);
566
556
  };
567
- (0, import_react2.useEffect)(() => {
568
- if (state === "closed") {
569
- setShowScrollTop(false);
570
- } else {
571
- const scrollTop = scrollContainerRef.current?.scrollTop || 0;
572
- setShowScrollTop(scrollTop > scrollToTopThreshold);
573
- }
574
- }, [state, scrollToTopThreshold]);
575
- const isDraggingSheet = (0, import_react2.useRef)(false);
576
- const hasDeterminedDirection = (0, import_react2.useRef)(false);
577
- const isTouchOnContent = (0, import_react2.useRef)(false);
578
- const isTouchOnHandle = (0, import_react2.useRef)(false);
579
- const suppressNextClickRef = (0, import_react2.useRef)(false);
580
- const contentAtTopSinceY = (0, import_react2.useRef)(null);
581
- const contentAtBottomSinceY = (0, import_react2.useRef)(null);
582
- const dragStartYRef = (0, import_react2.useRef)(null);
583
- const dragBaseHeightPxRef = (0, import_react2.useRef)(0);
584
- const stateRef = (0, import_react2.useRef)(state);
585
- const touchStartYRef = (0, import_react2.useRef)(touchStartY);
586
- const currentTouchYRef = (0, import_react2.useRef)(currentTouchY);
587
- (0, import_react2.useEffect)(() => {
588
- stateRef.current = state;
589
- }, [state]);
590
- (0, import_react2.useEffect)(() => {
591
- touchStartYRef.current = touchStartY;
592
- }, [touchStartY]);
593
- (0, import_react2.useEffect)(() => {
594
- currentTouchYRef.current = currentTouchY;
595
- }, [currentTouchY]);
596
- (0, import_react2.useEffect)(() => {
597
- const container = containerRef.current;
598
- if (!container || side !== "bottom" || !enableTouchDrag) return;
599
- const handleNativeTouchStart = (e) => {
600
- const clientY = e.targetTouches[0].clientY;
601
- setTouchStartY(clientY);
602
- setCurrentTouchY(clientY);
603
- isDraggingSheet.current = false;
604
- hasDeterminedDirection.current = false;
605
- contentAtTopSinceY.current = null;
606
- contentAtBottomSinceY.current = null;
607
- dragStartYRef.current = null;
608
- const target = e.target;
609
- isTouchOnContent.current = scrollContainerRef.current ? scrollContainerRef.current.contains(target) : false;
610
- isTouchOnHandle.current = handleBarRef.current ? handleBarRef.current.contains(target) : false;
611
- };
612
- const handleNativeTouchMove = (e) => {
613
- const startY = touchStartYRef.current;
614
- if (startY === null) return;
615
- const currentY = e.targetTouches[0].clientY;
616
- const deltaY = startY - currentY;
617
- const scrollTop = scrollContainerRef.current ? scrollContainerRef.current.scrollTop : 0;
618
- const clientHeight = scrollContainerRef.current ? scrollContainerRef.current.clientHeight : 0;
619
- const scrollHeight = scrollContainerRef.current ? scrollContainerRef.current.scrollHeight : 0;
620
- const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1;
621
- const currentState = stateRef.current;
622
- const containerHForHeights = containerHeight || container.parentElement?.getBoundingClientRect().height || window.innerHeight;
623
- const fullPxNow = resolveHeightToPixels(
624
- drawerFullHeight || "85%",
625
- containerHForHeights
626
- );
627
- const peekPxNow = resolveHeightToPixels(
628
- drawerPeekHeight || "15%",
629
- containerHForHeights
630
- );
631
- const closedPxNow = (handleVisible ? HANDLE_BAR_HEIGHT_PX : 0) + (currentState === "closed" ? safeAreaInsets.bottom : 0);
632
- const autoMaxPxNow = resolveHeightToPixels(
633
- drawerAutoMaxHeight || "100%",
634
- containerHForHeights
635
- );
636
- const autoPxNow = Math.min(autoMaxPxNow, autoContentPx);
637
- const baselineHeightPxForState = (s) => {
638
- if (s === "full") return fullPxNow;
639
- if (s === "peek") return peekPxNow;
640
- if (s === "auto") return autoPxNow;
641
- return closedPxNow;
642
- };
643
- const commitDrag = () => {
644
- isDraggingSheet.current = true;
645
- dragStartYRef.current = currentY;
646
- dragBaseHeightPxRef.current = baselineHeightPxForState(currentState);
647
- };
648
- if (scrollTop <= 0) {
649
- if (contentAtTopSinceY.current === null) {
650
- contentAtTopSinceY.current = currentY;
651
- }
652
- } else {
653
- contentAtTopSinceY.current = null;
654
- }
655
- if (isAtBottom) {
656
- if (contentAtBottomSinceY.current === null) {
657
- contentAtBottomSinceY.current = currentY;
658
- }
659
- } else {
660
- contentAtBottomSinceY.current = null;
661
- }
662
- const pullPastTop = contentAtTopSinceY.current !== null ? currentY - contentAtTopSinceY.current : 0;
663
- const pullPastBottom = contentAtBottomSinceY.current !== null ? contentAtBottomSinceY.current - currentY : 0;
664
- if (!hasDeterminedDirection.current) {
665
- if (!isTouchOnContent.current) {
666
- if (Math.abs(deltaY) < CONTENT_EDGE_PULL_THRESHOLD_PX) {
667
- return;
668
- }
669
- commitDrag();
670
- hasDeterminedDirection.current = true;
671
- } else if (currentState !== "full") {
672
- if (deltaY > 0 && isAtBottom && pullPastBottom >= CONTENT_EDGE_PULL_THRESHOLD_PX) {
673
- commitDrag();
674
- hasDeterminedDirection.current = true;
675
- } else if (deltaY < 0 && scrollTop <= 0 && pullPastTop >= CONTENT_EDGE_PULL_THRESHOLD_PX) {
676
- commitDrag();
677
- hasDeterminedDirection.current = true;
678
- } else if (deltaY > 0 && isAtBottom || deltaY < 0 && scrollTop <= 0) {
679
- return;
680
- } else {
681
- isDraggingSheet.current = false;
682
- hasDeterminedDirection.current = true;
683
- }
684
- } else {
685
- if (deltaY < 0 && scrollTop <= 0 && pullPastTop >= CONTENT_EDGE_PULL_THRESHOLD_PX) {
686
- commitDrag();
687
- hasDeterminedDirection.current = true;
688
- } else if (deltaY < 0 && scrollTop <= 0) {
689
- return;
690
- } else {
691
- isDraggingSheet.current = false;
692
- hasDeterminedDirection.current = true;
693
- }
694
- }
695
- } else if (!isDraggingSheet.current && isTouchOnContent.current) {
696
- if (deltaY < 0 && scrollTop <= 0 && pullPastTop >= CONTENT_EDGE_PULL_THRESHOLD_PX) {
697
- commitDrag();
698
- return;
699
- }
700
- if (deltaY > 0 && isAtBottom && currentState !== "full" && pullPastBottom >= CONTENT_EDGE_PULL_THRESHOLD_PX) {
701
- commitDrag();
702
- return;
703
- }
704
- }
705
- if (isDraggingSheet.current) {
706
- if (e.cancelable) {
707
- e.preventDefault();
708
- }
709
- const parentContainer = container.parentElement;
710
- if (parentContainer) {
711
- const dragOffset = currentY - (dragStartYRef.current ?? currentY);
712
- let localClamped = dragOffset;
713
- if (currentState === "full") {
714
- localClamped = Math.max(
715
- 0,
716
- Math.min(fullPxNow - closedPxNow, dragOffset)
717
- );
718
- } else if (currentState === "peek") {
719
- localClamped = Math.max(
720
- -(fullPxNow - peekPxNow),
721
- Math.min(peekPxNow - closedPxNow, dragOffset)
722
- );
723
- } else if (currentState === "closed") {
724
- localClamped = Math.min(
725
- 0,
726
- Math.max(-(fullPxNow - closedPxNow), dragOffset)
727
- );
728
- } else if (currentState === "auto") {
729
- localClamped = Math.max(0, dragOffset);
730
- }
731
- parentContainer.style.setProperty(
732
- "--drag-offset",
733
- `${localClamped}px`
734
- );
735
- }
736
- }
737
- };
738
- const handleNativeTouchEnd = (e) => {
739
- const startY = touchStartYRef.current;
740
- const currentY = currentTouchYRef.current;
741
- const parentContainer = container.parentElement;
742
- if (startY === null || currentY === null) {
743
- if (parentContainer) {
744
- parentContainer.style.setProperty("--drag-offset", "0px");
745
- }
746
- return;
747
- }
748
- if (!isDraggingSheet.current) {
749
- if (isTouchOnHandle.current) {
750
- handleHandleClickRef.current();
751
- suppressNextClickRef.current = true;
752
- setTimeout(() => {
753
- suppressNextClickRef.current = false;
754
- }, HANDLE_TAP_CLICK_SUPPRESSION_MS);
755
- }
756
- setTouchStartY(null);
757
- setCurrentTouchY(null);
758
- if (parentContainer) {
759
- parentContainer.style.setProperty("--drag-offset", "0px");
760
- }
761
- return;
762
- }
763
- const touchEndY = e.changedTouches[0].clientY;
764
- const dragStartY = dragStartYRef.current ?? startY;
765
- const dragDistance = Math.abs(touchEndY - dragStartY);
766
- if (dragDistance < 10) {
767
- setTouchStartY(null);
768
- setCurrentTouchY(null);
769
- if (parentContainer) {
770
- parentContainer.style.setProperty("--drag-offset", "0px");
771
- }
772
- return;
773
- }
774
- const containerH2 = containerHeight || (parentContainer ? parentContainer.getBoundingClientRect().height : window.innerHeight);
775
- const fullPx2 = resolveHeightToPixels(
776
- drawerFullHeight || "85%",
777
- containerH2
778
- );
779
- const peekPx2 = resolveHeightToPixels(
780
- drawerPeekHeight || "15%",
781
- containerH2
782
- );
783
- const currentState = stateRef.current;
784
- const closedPx = (handleVisible ? HANDLE_BAR_HEIGHT_PX : 0) + (currentState === "closed" ? safeAreaInsets.bottom : 0);
785
- const dragDelta = touchEndY - dragStartY;
786
- const drawerHeightFromBottom = dragBaseHeightPxRef.current - dragDelta;
787
- const distToClosed = Math.abs(drawerHeightFromBottom - closedPx);
788
- let targetState2;
789
- if (currentState === "auto") {
790
- const autoMaxPx2 = resolveHeightToPixels(
791
- drawerAutoMaxHeight || "100%",
792
- containerH2
793
- );
794
- const autoPx2 = Math.min(autoMaxPx2, autoContentPx);
795
- const distToAuto = Math.abs(drawerHeightFromBottom - autoPx2);
796
- targetState2 = distToAuto <= distToClosed ? "auto" : "closed";
797
- } else {
798
- const distToFull = Math.abs(drawerHeightFromBottom - fullPx2);
799
- const distToPeek = Math.abs(drawerHeightFromBottom - peekPx2);
800
- const minDist = Math.min(distToFull, distToPeek, distToClosed);
801
- if (minDist === distToFull) {
802
- targetState2 = "full";
803
- } else if (minDist === distToPeek) {
804
- targetState2 = "peek";
805
- } else {
806
- targetState2 = "closed";
807
- }
808
- }
809
- setTouchStartY(null);
810
- setCurrentTouchY(null);
811
- onChangeState(targetState2);
812
- requestAnimationFrame(() => {
813
- if (parentContainer) {
814
- parentContainer.style.setProperty("--drag-offset", "0px");
815
- }
816
- });
817
- };
818
- const handleNativeClickCapture = (e) => {
819
- if (!suppressNextClickRef.current) return;
820
- suppressNextClickRef.current = false;
821
- e.preventDefault();
822
- e.stopPropagation();
823
- };
824
- container.addEventListener("touchstart", handleNativeTouchStart, {
825
- passive: true
826
- });
827
- container.addEventListener("touchmove", handleNativeTouchMove, {
828
- passive: false
829
- });
830
- container.addEventListener("touchend", handleNativeTouchEnd, {
831
- passive: true
832
- });
833
- container.addEventListener("click", handleNativeClickCapture, {
834
- capture: true
835
- });
836
- return () => {
837
- container.removeEventListener("touchstart", handleNativeTouchStart);
838
- container.removeEventListener("touchmove", handleNativeTouchMove);
839
- container.removeEventListener("touchend", handleNativeTouchEnd);
840
- container.removeEventListener("click", handleNativeClickCapture, {
841
- capture: true
842
- });
843
- };
844
- }, [
845
- side,
846
- enableTouchDrag,
847
- containerHeight,
848
- drawerFullHeight,
849
- drawerPeekHeight,
850
- drawerAutoMaxHeight,
851
- safeAreaInsets,
852
- onChangeState,
853
- setTouchStartY,
854
- setCurrentTouchY,
855
- autoContentPx,
856
- handleVisible
857
- ]);
858
- const isBackdropActive = state === "full" || state === "auto";
557
+ const isBackdropActive = state !== "closed";
859
558
  const backdropStyles = isBackdropActive ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none";
860
- const containerH = containerHeight || window.innerHeight;
861
- const fullPx = resolveHeightToPixels(drawerFullHeight || "85%", containerH);
862
- const peekPx = resolveHeightToPixels(drawerPeekHeight || "15%", containerH);
863
- const autoMaxPx = resolveHeightToPixels(
864
- drawerAutoMaxHeight || "100%",
865
- containerH
866
- );
867
- const shiftPx = fullPx - peekPx;
868
- const autoPx = Math.min(autoMaxPx, autoContentPx);
869
- const autoShiftPx = Math.max(fullPx - autoPx, 0);
870
- const getBottomDrawerTransform = () => {
871
- if (state === "full") {
872
- return "translateY(var(--drag-offset, 0px))";
873
- }
874
- if (state === "peek") {
875
- return `translateY(calc(${shiftPx}px + var(--drag-offset, 0px)))`;
876
- }
877
- if (state === "auto") {
878
- return `translateY(calc(${autoShiftPx}px + var(--drag-offset, 0px)))`;
879
- }
880
- const closedVisibleHeight = handleVisible ? HANDLE_BAR_HEIGHT_PX : 0;
881
- const closedShiftPx = fullPx - closedVisibleHeight;
882
- return `translateY(calc(${closedShiftPx}px + var(--drag-offset, 0px)))`;
883
- };
884
559
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
885
560
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
886
561
  .no-scrollbar {
@@ -898,233 +573,113 @@ var MapDrawer = (0, import_react2.forwardRef)(
898
573
  onClick: () => onChangeState("closed")
899
574
  }
900
575
  ),
901
- side === "left" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
902
- state === "closed" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
903
- Button,
904
- {
905
- className: "absolute top-4 left-4 z-40 w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer hover:bg-zinc-900 hover:text-white p-0!",
906
- onClick: () => onChangeState("full"),
907
- variant: "ghost",
908
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
909
- "svg",
910
- {
911
- fill: "none",
912
- height: "24",
913
- stroke: "currentColor",
914
- strokeLinecap: "round",
915
- strokeLinejoin: "round",
916
- strokeWidth: "2",
917
- viewBox: "0 0 24 24",
918
- width: "24",
919
- xmlns: "http://www.w3.org/2000/svg",
920
- children: [
921
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "12", y2: "12" }),
922
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "6", y2: "6" }),
923
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "18", y2: "18" })
924
- ]
925
- }
926
- )
927
- }
928
- ),
929
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
930
- Sheet,
931
- {
932
- onOpenChange: (open) => onChangeState(open ? "full" : "closed"),
933
- open: state !== "closed",
934
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
935
- SheetContent,
936
- {
937
- className: "w-80 bg-zinc-950/85 backdrop-blur-md border-r border-y border-white/10 rounded-r-2xl shadow-2xl p-4 text-white flex flex-col h-full overflow-hidden",
938
- portal: false,
939
- side: "left",
940
- children: [
941
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SheetHeader, { className: "pb-3 border-b border-white/10 mb-2 text-left", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SheetTitle, { className: "text-sm font-bold tracking-wider text-zinc-400 uppercase", children: "Menu" }) }),
942
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
943
- "div",
944
- {
945
- className: "flex-1 overflow-y-auto no-scrollbar pr-2",
946
- onScroll: handleScroll,
947
- ref: scrollContainerRef,
948
- children: menuContent ? menuContent : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col gap-1.5", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
949
- Button,
950
- {
951
- className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 justify-start hover:bg-white/5 hover:text-white active:bg-white/10 text-white ${item.disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : ""}`,
952
- disabled: item.disabled,
953
- onClick: () => {
954
- if (!item.disabled) {
955
- item.onPress();
956
- onChangeState("closed");
957
- }
958
- },
959
- variant: "ghost",
960
- children: [
961
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
962
- item.icon,
963
- item.badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "absolute -top-1 -right-1 bg-cyan-500 text-black text-[9px] font-extrabold min-w-[15px] h-3.5 rounded-full flex items-center justify-center px-1 border border-zinc-950 shadow", children: item.badge })
964
- ] }),
965
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: item.label })
966
- ]
967
- },
968
- item.id
969
- )) })
970
- }
971
- ),
972
- showScrollToTopButton && showScrollTop && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
973
- Button,
974
- {
975
- className: "absolute bottom-6 right-6 z-50 flex items-center justify-center w-10 h-10 rounded-full bg-cyan-500 hover:bg-cyan-400 active:scale-95 text-black hover:text-black shadow-lg shadow-cyan-500/25 transition-all duration-200 cursor-pointer p-0!",
976
- onClick: () => {
977
- scrollContainerRef.current?.scrollTo({
978
- behavior: "smooth",
979
- top: 0
980
- });
981
- },
982
- variant: "ghost",
983
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
984
- "svg",
985
- {
986
- fill: "none",
987
- height: "20",
988
- stroke: "currentColor",
989
- strokeLinecap: "round",
990
- strokeLinejoin: "round",
991
- strokeWidth: "2.5",
992
- viewBox: "0 0 24 24",
993
- width: "20",
994
- xmlns: "http://www.w3.org/2000/svg",
995
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "18 15 12 9 6 15" })
996
- }
997
- )
998
- }
999
- )
1000
- ]
1001
- }
1002
- )
1003
- }
1004
- )
1005
- ] }) : (
1006
- /* Bottom Sheet Panel - Hardware accelerated translateY transitions */
1007
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1008
- "div",
1009
- {
1010
- className: `absolute w-full bg-zinc-950/85 backdrop-blur-md border border-white/10 rounded-t-2xl shadow-2xl flex flex-col z-40 select-none ${isDragging ? "transition-none" : "transition-transform duration-300 ease-out"}`,
1011
- ref: containerRef,
1012
- style: {
1013
- bottom: "0px",
1014
- // Box height must stay exactly fullPx for "closed"/"peek"/
1015
- // "full" — every other transform calc in this component
1016
- // assumes the box IS fullPx tall. Only "auto" grows it (up to
1017
- // autoMaxPx) when content needs more room than fullPx offers;
1018
- // getBottomDrawerTransform()'s auto branch is derived to match
1019
- // (shift = max(fullPx - autoPx, 0), so a taller box needs zero
1020
- // extra shift to fully reveal itself).
1021
- height: `${state === "auto" ? Math.max(fullPx, autoPx) : fullPx}px`,
1022
- marginBottom: state === "closed" ? `${safeAreaInsets.bottom}px` : "0px",
1023
- transform: getBottomDrawerTransform(),
1024
- // `height` is animated too (not just transform/margin-bottom):
1025
- // entering/leaving "auto" with content taller than fullPx
1026
- // changes the box's actual CSS height, and without this it
1027
- // would snap instantly while transform eases in over 300ms —
1028
- // a visible pop of content before the slide animation catches
1029
- // up.
1030
- transition: isDragging ? "none" : "transform 300ms ease-out, height 300ms ease-out, margin-bottom 250ms ease-in-out"
1031
- },
1032
- children: [
1033
- handleVisible && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1034
- "div",
1035
- {
1036
- className: "w-full h-8 flex flex-col items-center justify-center cursor-pointer hover:bg-white/5 rounded-t-2xl transition-colors border-b border-white/5",
1037
- onClick: () => {
1038
- if (suppressNextClickRef.current) return;
1039
- handleHandleClick();
1040
- },
1041
- ref: handleBarRef,
1042
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-12 h-1 bg-white/25 rounded-full" })
1043
- }
1044
- ),
1045
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1046
- "div",
1047
- {
1048
- className: "flex-1 flex flex-col overflow-hidden px-4 pb-4 pt-2 transition-[margin-top] duration-250 ease-in-out relative",
1049
- ref: contentAreaRef,
1050
- style: {
1051
- marginTop: state === "closed" ? `${safeAreaInsets.bottom}px` : "0px"
1052
- },
1053
- children: [
1054
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1055
- "div",
1056
- {
1057
- className: "flex-1 overflow-y-auto no-scrollbar",
1058
- onScroll: handleScroll,
1059
- ref: scrollContainerRef,
1060
- style: {
1061
- paddingBottom: state === "peek" ? `${shiftPx}px` : "0px"
1062
- },
1063
- children: menuContent ? menuContent : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col gap-1", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1064
- Button,
1065
- {
1066
- className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 justify-start hover:bg-white/5 hover:text-white active:bg-white/10 text-white ${item.disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : ""}`,
1067
- disabled: item.disabled,
1068
- onClick: () => {
1069
- if (!item.disabled) {
1070
- item.onPress();
1071
- onChangeState("closed");
1072
- }
1073
- },
1074
- variant: "ghost",
1075
- children: [
1076
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
1077
- item.icon,
1078
- item.badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "absolute -top-1 -right-1 bg-cyan-500 text-black text-[9px] font-extrabold min-w-[15px] h-3.5 rounded-full flex items-center justify-center px-1 border border-zinc-950 shadow", children: item.badge })
1079
- ] }),
1080
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-medium tracking-wide", children: item.label })
1081
- ]
1082
- },
1083
- item.id
1084
- )) })
1085
- }
1086
- ),
1087
- showScrollToTopButton && showScrollTop && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
576
+ state === "closed" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
577
+ Button,
578
+ {
579
+ className: "absolute top-4 left-4 z-40 w-12 h-12 rounded-full bg-zinc-950/80 backdrop-blur-md border border-white/10 shadow-lg flex items-center justify-center text-white active:scale-95 transition-all cursor-pointer hover:bg-zinc-900 hover:text-white p-0!",
580
+ onClick: () => onChangeState("full"),
581
+ variant: "ghost",
582
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
583
+ "svg",
584
+ {
585
+ fill: "none",
586
+ height: "24",
587
+ stroke: "currentColor",
588
+ strokeLinecap: "round",
589
+ strokeLinejoin: "round",
590
+ strokeWidth: "2",
591
+ viewBox: "0 0 24 24",
592
+ width: "24",
593
+ xmlns: "http://www.w3.org/2000/svg",
594
+ children: [
595
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "12", y2: "12" }),
596
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "6", y2: "6" }),
597
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "18", y2: "18" })
598
+ ]
599
+ }
600
+ )
601
+ }
602
+ ),
603
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
604
+ Sheet,
605
+ {
606
+ onOpenChange: (open) => onChangeState(open ? "full" : "closed"),
607
+ open: state !== "closed",
608
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
609
+ SheetContent,
610
+ {
611
+ className: "w-80 bg-zinc-950/85 backdrop-blur-md border-r border-y border-white/10 rounded-r-2xl shadow-2xl p-4 text-white flex flex-col h-full overflow-hidden",
612
+ portal: false,
613
+ side: "left",
614
+ children: [
615
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SheetHeader, { className: "pb-3 border-b border-white/10 mb-2 text-left", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SheetTitle, { className: "text-sm font-bold tracking-wider text-zinc-400 uppercase", children: "Menu" }) }),
616
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
617
+ "div",
618
+ {
619
+ className: "flex-1 overflow-y-auto no-scrollbar pr-2",
620
+ onScroll: handleScroll,
621
+ ref: scrollContainerRef,
622
+ children: menuContent ? menuContent : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex flex-col gap-1.5", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1088
623
  Button,
1089
624
  {
1090
- className: "absolute right-6 z-50 flex items-center justify-center w-10 h-10 rounded-full bg-cyan-500 hover:bg-cyan-400 active:scale-95 text-black hover:text-black shadow-lg shadow-cyan-500/25 transition-all duration-200 cursor-pointer p-0!",
625
+ className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 justify-start hover:bg-white/5 hover:text-white active:bg-white/10 text-white ${item.disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : ""}`,
626
+ disabled: item.disabled,
1091
627
  onClick: () => {
1092
- scrollContainerRef.current?.scrollTo({
1093
- behavior: "smooth",
1094
- top: 0
1095
- });
1096
- },
1097
- style: {
1098
- bottom: state === "peek" ? `calc(${24 + shiftPx}px + var(--drag-offset, 0px))` : `calc(24px + var(--drag-offset, 0px))`
628
+ if (!item.disabled) {
629
+ item.onPress();
630
+ onChangeState("closed");
631
+ }
1099
632
  },
1100
633
  variant: "ghost",
1101
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1102
- "svg",
1103
- {
1104
- fill: "none",
1105
- height: "20",
1106
- stroke: "currentColor",
1107
- strokeLinecap: "round",
1108
- strokeLinejoin: "round",
1109
- strokeWidth: "2.5",
1110
- viewBox: "0 0 24 24",
1111
- width: "20",
1112
- xmlns: "http://www.w3.org/2000/svg",
1113
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "18 15 12 9 6 15" })
1114
- }
1115
- )
634
+ children: [
635
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
636
+ item.icon,
637
+ item.badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "absolute -top-1 -right-1 bg-cyan-500 text-black text-[9px] font-extrabold min-w-[15px] h-3.5 rounded-full flex items-center justify-center px-1 border border-zinc-950 shadow", children: item.badge })
638
+ ] }),
639
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: item.label })
640
+ ]
641
+ },
642
+ item.id
643
+ )) })
644
+ }
645
+ ),
646
+ showScrollToTopButton && showScrollTop && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
647
+ Button,
648
+ {
649
+ className: "absolute bottom-6 right-6 z-50 flex items-center justify-center w-10 h-10 rounded-full bg-cyan-500 hover:bg-cyan-400 active:scale-95 text-black hover:text-black shadow-lg shadow-cyan-500/25 transition-all duration-200 cursor-pointer p-0!",
650
+ onClick: () => {
651
+ scrollContainerRef.current?.scrollTo({
652
+ behavior: "smooth",
653
+ top: 0
654
+ });
655
+ },
656
+ variant: "ghost",
657
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
658
+ "svg",
659
+ {
660
+ fill: "none",
661
+ height: "20",
662
+ stroke: "currentColor",
663
+ strokeLinecap: "round",
664
+ strokeLinejoin: "round",
665
+ strokeWidth: "2.5",
666
+ viewBox: "0 0 24 24",
667
+ width: "20",
668
+ xmlns: "http://www.w3.org/2000/svg",
669
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "18 15 12 9 6 15" })
1116
670
  }
1117
671
  )
1118
- ]
1119
- }
1120
- )
1121
- ]
1122
- }
1123
- )
672
+ }
673
+ )
674
+ ]
675
+ }
676
+ )
677
+ }
1124
678
  )
1125
679
  ] });
1126
680
  }
1127
681
  );
682
+ MapDrawer.displayName = "MapDrawer";
1128
683
 
1129
684
  // src/components/ui/card.tsx
1130
685
  var React3 = __toESM(require("react"), 1);
@@ -1575,33 +1130,333 @@ var MapRightControls = ({
1575
1130
  );
1576
1131
  };
1577
1132
 
1578
- // src/components/Map/MapContext.tsx
1579
- var import_react3 = require("react");
1133
+ // src/components/Map/components/MobileBottomDrawer.tsx
1134
+ var import_react3 = require("motion/react");
1135
+ var import_react4 = require("react");
1136
+ var import_react_modal_sheet = require("react-modal-sheet");
1580
1137
  var import_jsx_runtime7 = require("react/jsx-runtime");
1581
- var MapControlsContext = (0, import_react3.createContext)(
1138
+ var resolveHeightToPixels = (height, containerHeight) => {
1139
+ if (typeof height === "number") {
1140
+ return height;
1141
+ }
1142
+ if (height.endsWith("%")) {
1143
+ return parseFloat(height) / 100 * containerHeight;
1144
+ }
1145
+ return parseFloat(height);
1146
+ };
1147
+ var HANDLE_HEIGHT_PX = 32;
1148
+ var SHEET_TWEEN_CONFIG = {
1149
+ duration: 0.4,
1150
+ ease: [0.32, 0.72, 0, 1]
1151
+ };
1152
+ var SHEET_DRAG_VELOCITY_THRESHOLD = 1700;
1153
+ var MobileBottomDrawer = (0, import_react4.forwardRef)(
1154
+ ({
1155
+ menuItems,
1156
+ state,
1157
+ onChangeState,
1158
+ drawerPeekHeight,
1159
+ drawerFullHeight,
1160
+ drawerAutoMaxHeight,
1161
+ containerHeight,
1162
+ menuContent,
1163
+ enableTouchDrag = true,
1164
+ handleVisible = true,
1165
+ onAutoContentHeightChange,
1166
+ showScrollToTopButton = true,
1167
+ scrollToTopThreshold = 300,
1168
+ safeAreaInsets = { bottom: 0, left: 0, right: 0, top: 0 }
1169
+ }, ref) => {
1170
+ const scrollRef = (0, import_react4.useRef)(null);
1171
+ (0, import_react4.useImperativeHandle)(ref, () => scrollRef.current);
1172
+ const headerRef = (0, import_react4.useRef)(null);
1173
+ const contentWrapperRef = (0, import_react4.useRef)(null);
1174
+ const [viewportHeight, setViewportHeight] = (0, import_react4.useState)(
1175
+ () => containerHeight ?? (typeof window !== "undefined" ? window.innerHeight : 800)
1176
+ );
1177
+ (0, import_react4.useEffect)(() => {
1178
+ if (containerHeight) {
1179
+ setViewportHeight(containerHeight);
1180
+ return;
1181
+ }
1182
+ if (typeof window === "undefined") return;
1183
+ const update = () => setViewportHeight(window.innerHeight);
1184
+ update();
1185
+ window.addEventListener("resize", update);
1186
+ return () => window.removeEventListener("resize", update);
1187
+ }, [containerHeight]);
1188
+ const [autoContentPx, setAutoContentPx] = (0, import_react4.useState)(0);
1189
+ (0, import_react4.useEffect)(() => {
1190
+ const contentEl = contentWrapperRef.current;
1191
+ if (!contentEl) return;
1192
+ const measure = () => {
1193
+ const headerHeight = handleVisible ? headerRef.current?.offsetHeight ?? 0 : 0;
1194
+ const px = headerHeight + contentEl.scrollHeight;
1195
+ setAutoContentPx(px);
1196
+ onAutoContentHeightChange?.(px);
1197
+ };
1198
+ measure();
1199
+ const ro = new ResizeObserver(measure);
1200
+ ro.observe(contentEl);
1201
+ return () => ro.disconnect();
1202
+ }, [handleVisible, onAutoContentHeightChange]);
1203
+ const closedPx = (handleVisible ? HANDLE_HEIGHT_PX : 0) + safeAreaInsets.bottom;
1204
+ const peekPx = resolveHeightToPixels(
1205
+ drawerPeekHeight ?? "15%",
1206
+ viewportHeight
1207
+ );
1208
+ const autoMaxPx = resolveHeightToPixels(
1209
+ drawerAutoMaxHeight ?? "100%",
1210
+ viewportHeight
1211
+ );
1212
+ const autoPx = Math.min(autoMaxPx, Math.max(autoContentPx, closedPx + 1));
1213
+ const { snapPoints, snapLabels, backdropOutput } = (0, import_react4.useMemo)(() => {
1214
+ const normalize = (raw) => raw > 0 && raw <= 1 ? raw * viewportHeight : raw;
1215
+ const unsorted = [
1216
+ { label: "closed", raw: 0 },
1217
+ { label: "closed", raw: closedPx },
1218
+ { label: "peek", raw: peekPx },
1219
+ { label: "auto", raw: autoPx },
1220
+ { label: "full", raw: 1 }
1221
+ ];
1222
+ const entries = unsorted.sort(
1223
+ (a, b) => normalize(a.raw) - normalize(b.raw)
1224
+ );
1225
+ const deduped = [];
1226
+ for (const entry of entries) {
1227
+ const prev = deduped[deduped.length - 1];
1228
+ if (prev && Math.abs(normalize(prev.raw) - normalize(entry.raw)) < 0.5) {
1229
+ deduped[deduped.length - 1] = entry;
1230
+ continue;
1231
+ }
1232
+ deduped.push(entry);
1233
+ }
1234
+ return {
1235
+ backdropOutput: deduped.map(
1236
+ (d) => d.label === "full" || d.label === "auto" ? 1 : 0
1237
+ ),
1238
+ snapLabels: deduped.map((d) => d.label),
1239
+ snapPoints: deduped.map((d) => d.raw)
1240
+ };
1241
+ }, [closedPx, peekPx, autoPx, viewportHeight]);
1242
+ const currentIndex = Math.max(0, snapLabels.lastIndexOf(state));
1243
+ const sheetRef = (0, import_react4.useRef)(null);
1244
+ (0, import_react4.useEffect)(() => {
1245
+ let cancelled = false;
1246
+ let attempts = 0;
1247
+ const trySnap = () => {
1248
+ if (cancelled) return;
1249
+ const ref2 = sheetRef.current;
1250
+ if (ref2 && ref2.snapPoints.length > 0) {
1251
+ ref2.snapTo(currentIndex);
1252
+ return;
1253
+ }
1254
+ attempts += 1;
1255
+ if (attempts > 60) return;
1256
+ requestAnimationFrame(trySnap);
1257
+ };
1258
+ trySnap();
1259
+ return () => {
1260
+ cancelled = true;
1261
+ };
1262
+ }, [currentIndex]);
1263
+ const handleSnap = (0, import_react4.useCallback)(
1264
+ (index) => {
1265
+ const label = snapLabels[index] ?? "closed";
1266
+ if (label !== state) onChangeState(label);
1267
+ },
1268
+ [snapLabels, state, onChangeState]
1269
+ );
1270
+ const handleHandleClick = () => {
1271
+ if (state === "closed") {
1272
+ onChangeState("peek");
1273
+ } else if (state === "peek") {
1274
+ onChangeState("full");
1275
+ } else if (state === "auto") {
1276
+ onChangeState("closed");
1277
+ } else {
1278
+ onChangeState("peek");
1279
+ }
1280
+ };
1281
+ const [showScrollTop, setShowScrollTop] = (0, import_react4.useState)(false);
1282
+ (0, import_react4.useEffect)(() => {
1283
+ const el = scrollRef.current;
1284
+ if (!el) return;
1285
+ const onScroll = () => {
1286
+ setShowScrollTop(
1287
+ state !== "closed" && el.scrollTop > scrollToTopThreshold
1288
+ );
1289
+ };
1290
+ el.addEventListener("scroll", onScroll);
1291
+ return () => el.removeEventListener("scroll", onScroll);
1292
+ }, [state, scrollToTopThreshold]);
1293
+ (0, import_react4.useEffect)(() => {
1294
+ if (state === "closed") setShowScrollTop(false);
1295
+ }, [state]);
1296
+ const dragDisabled = !enableTouchDrag;
1297
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1298
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
1299
+ .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
1300
+ .no-scrollbar::-webkit-scrollbar { display: none; }
1301
+ ` }),
1302
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1303
+ import_react_modal_sheet.Sheet,
1304
+ {
1305
+ disableDismiss: true,
1306
+ disableDrag: dragDisabled,
1307
+ dragVelocityThreshold: SHEET_DRAG_VELOCITY_THRESHOLD,
1308
+ initialSnap: currentIndex,
1309
+ isOpen: true,
1310
+ onClose: () => onChangeState("closed"),
1311
+ onSnap: handleSnap,
1312
+ ref: sheetRef,
1313
+ snapPoints,
1314
+ tweenConfig: SHEET_TWEEN_CONFIG,
1315
+ children: [
1316
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1317
+ import_react_modal_sheet.Sheet.Container,
1318
+ {
1319
+ className: "!bg-zinc-950/85 !backdrop-blur-md !border !border-white/10 !border-b-0 !rounded-t-2xl !shadow-2xl ",
1320
+ style: { paddingBottom: safeAreaInsets.bottom },
1321
+ children: [
1322
+ handleVisible && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1323
+ import_react_modal_sheet.Sheet.Header,
1324
+ {
1325
+ className: "!bg-transparent cursor-pointer hover:!bg-white/5 transition-colors",
1326
+ onClick: handleHandleClick,
1327
+ ref: headerRef
1328
+ }
1329
+ ),
1330
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1331
+ import_react_modal_sheet.Sheet.Content,
1332
+ {
1333
+ className: "!bg-transparent",
1334
+ disableDrag: (info) => dragDisabled || info.scrollPosition === "middle",
1335
+ disableScroll: (info) => !dragDisabled && info.currentSnap !== snapPoints.length - 1,
1336
+ scrollClassName: "no-scrollbar",
1337
+ scrollRef,
1338
+ children: [
1339
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "px-4 pb-4 pt-2 relative", ref: contentWrapperRef, children: menuContent ? menuContent : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex flex-col gap-1", children: menuItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1340
+ Button,
1341
+ {
1342
+ className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 justify-start hover:bg-white/5 hover:text-white active:bg-white/10 text-white ${item.disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : ""}`,
1343
+ disabled: item.disabled,
1344
+ onClick: () => {
1345
+ if (!item.disabled) {
1346
+ item.onPress();
1347
+ onChangeState("closed");
1348
+ }
1349
+ },
1350
+ variant: "ghost",
1351
+ children: [
1352
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
1353
+ item.icon,
1354
+ item.badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "absolute -top-1 -right-1 bg-cyan-500 text-black text-[9px] font-extrabold min-w-[15px] h-3.5 rounded-full flex items-center justify-center px-1 border border-zinc-950 shadow", children: item.badge })
1355
+ ] }),
1356
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm font-medium tracking-wide", children: item.label })
1357
+ ]
1358
+ },
1359
+ item.id
1360
+ )) }) }),
1361
+ showScrollToTopButton && showScrollTop && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1362
+ Button,
1363
+ {
1364
+ className: "absolute bottom-4 right-6 z-50 flex items-center justify-center w-10 h-10 rounded-full bg-cyan-500 hover:bg-cyan-400 active:scale-95 text-black hover:text-black shadow-lg shadow-cyan-500/25 transition-all duration-200 cursor-pointer p-0!",
1365
+ onClick: () => {
1366
+ scrollRef.current?.scrollTo({ behavior: "smooth", top: 0 });
1367
+ },
1368
+ variant: "ghost",
1369
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1370
+ "svg",
1371
+ {
1372
+ fill: "none",
1373
+ height: "20",
1374
+ stroke: "currentColor",
1375
+ strokeLinecap: "round",
1376
+ strokeLinejoin: "round",
1377
+ strokeWidth: "2.5",
1378
+ viewBox: "0 0 24 24",
1379
+ width: "20",
1380
+ xmlns: "http://www.w3.org/2000/svg",
1381
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("polyline", { points: "18 15 12 9 6 15" })
1382
+ }
1383
+ )
1384
+ }
1385
+ )
1386
+ ]
1387
+ }
1388
+ )
1389
+ ]
1390
+ }
1391
+ ),
1392
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1393
+ DrawerBackdrop,
1394
+ {
1395
+ active: state === "full" || state === "auto",
1396
+ onTap: () => onChangeState("closed"),
1397
+ output: backdropOutput
1398
+ }
1399
+ )
1400
+ ]
1401
+ }
1402
+ )
1403
+ ] });
1404
+ }
1405
+ );
1406
+ MobileBottomDrawer.displayName = "MobileBottomDrawer";
1407
+ function DrawerBackdrop({
1408
+ active,
1409
+ output,
1410
+ onTap
1411
+ }) {
1412
+ const { y, snapPoints } = import_react_modal_sheet.Sheet.useContext();
1413
+ const opacity = (0, import_react3.useTransform)(y, (value) => {
1414
+ if (snapPoints.length === 0 || output.length !== snapPoints.length) {
1415
+ return 0;
1416
+ }
1417
+ const mix = (0, import_react3.interpolate)(
1418
+ snapPoints.map((point) => point.snapValueY),
1419
+ output
1420
+ );
1421
+ return mix(value) * 0.45;
1422
+ });
1423
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1424
+ import_react_modal_sheet.Sheet.Backdrop,
1425
+ {
1426
+ className: "!bg-black !backdrop-blur-[1px]",
1427
+ onTap: active ? onTap : void 0,
1428
+ style: { opacity }
1429
+ }
1430
+ );
1431
+ }
1432
+
1433
+ // src/components/Map/MapContext.tsx
1434
+ var import_react5 = require("react");
1435
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1436
+ var MapControlsContext = (0, import_react5.createContext)(
1582
1437
  null
1583
1438
  );
1584
1439
  var SDKMapProvider = ({
1585
1440
  children
1586
1441
  }) => {
1587
- const [isFollowing, setIsFollowing] = (0, import_react3.useState)(true);
1588
- const [bearing, setBearingState] = (0, import_react3.useState)(0);
1589
- const [pitch, setPitchState] = (0, import_react3.useState)(0);
1590
- const [drawerState, setDrawerStateInternal] = (0, import_react3.useState)("closed");
1591
- const drawerContentRef = (0, import_react3.useRef)(null);
1592
- const setDrawerState = (0, import_react3.useCallback)((val) => {
1442
+ const [isFollowing, setIsFollowing] = (0, import_react5.useState)(true);
1443
+ const [bearing, setBearingState] = (0, import_react5.useState)(0);
1444
+ const [pitch, setPitchState] = (0, import_react5.useState)(0);
1445
+ const [drawerState, setDrawerStateInternal] = (0, import_react5.useState)("closed");
1446
+ const drawerContentRef = (0, import_react5.useRef)(null);
1447
+ const setDrawerState = (0, import_react5.useCallback)((val) => {
1593
1448
  setDrawerStateInternal(val);
1594
1449
  }, []);
1595
- const [drawerHandleVisible, setDrawerHandleVisibleState] = (0, import_react3.useState)(true);
1596
- const setDrawerHandleVisible = (0, import_react3.useCallback)((val) => {
1450
+ const [drawerHandleVisible, setDrawerHandleVisibleState] = (0, import_react5.useState)(true);
1451
+ const setDrawerHandleVisible = (0, import_react5.useCallback)((val) => {
1597
1452
  setDrawerHandleVisibleState((prev) => prev === val ? prev : val);
1598
1453
  }, []);
1599
- const [hasControls, setHasControlsState] = (0, import_react3.useState)(false);
1600
- const setHasControls = (0, import_react3.useCallback)((val) => {
1454
+ const [hasControls, setHasControlsState] = (0, import_react5.useState)(false);
1455
+ const setHasControls = (0, import_react5.useCallback)((val) => {
1601
1456
  setHasControlsState((prev) => prev === val ? prev : val);
1602
1457
  }, []);
1603
- const [etaData, setEtaDataState] = (0, import_react3.useState)(void 0);
1604
- const setEtaData = (0, import_react3.useCallback)((newData) => {
1458
+ const [etaData, setEtaDataState] = (0, import_react5.useState)(void 0);
1459
+ const setEtaData = (0, import_react5.useCallback)((newData) => {
1605
1460
  setEtaDataState((prev) => {
1606
1461
  if (!prev && !newData) return prev;
1607
1462
  if (!prev || !newData) return newData;
@@ -1611,29 +1466,29 @@ var SDKMapProvider = ({
1611
1466
  return newData;
1612
1467
  });
1613
1468
  }, []);
1614
- const [insets, setInsetsState] = (0, import_react3.useState)({
1469
+ const [insets, setInsetsState] = (0, import_react5.useState)({
1615
1470
  bottom: 0,
1616
1471
  left: 0,
1617
1472
  right: 0,
1618
1473
  top: 0
1619
1474
  });
1620
- const setInsets = (0, import_react3.useCallback)((newInsets) => {
1475
+ const setInsets = (0, import_react5.useCallback)((newInsets) => {
1621
1476
  setInsetsState((prev) => ({ ...prev, ...newInsets }));
1622
1477
  }, []);
1623
- const centerCallbackRef = (0, import_react3.useRef)(null);
1624
- const resetBearingCallbackRef = (0, import_react3.useRef)(null);
1625
- const flyToCallbackRef = (0, import_react3.useRef)(null);
1626
- const centerOnUser = (0, import_react3.useCallback)((params) => {
1478
+ const centerCallbackRef = (0, import_react5.useRef)(null);
1479
+ const resetBearingCallbackRef = (0, import_react5.useRef)(null);
1480
+ const flyToCallbackRef = (0, import_react5.useRef)(null);
1481
+ const centerOnUser = (0, import_react5.useCallback)((params) => {
1627
1482
  if (centerCallbackRef.current) {
1628
1483
  centerCallbackRef.current(params);
1629
1484
  }
1630
1485
  }, []);
1631
- const resetBearing = (0, import_react3.useCallback)((params) => {
1486
+ const resetBearing = (0, import_react5.useCallback)((params) => {
1632
1487
  if (resetBearingCallbackRef.current) {
1633
1488
  resetBearingCallbackRef.current(params);
1634
1489
  }
1635
1490
  }, []);
1636
- const flyTo = (0, import_react3.useCallback)(
1491
+ const flyTo = (0, import_react5.useCallback)(
1637
1492
  (coords, params) => {
1638
1493
  if (flyToCallbackRef.current) {
1639
1494
  flyToCallbackRef.current(coords, params);
@@ -1641,31 +1496,31 @@ var SDKMapProvider = ({
1641
1496
  },
1642
1497
  []
1643
1498
  );
1644
- const _registerCenterCallback = (0, import_react3.useCallback)(
1499
+ const _registerCenterCallback = (0, import_react5.useCallback)(
1645
1500
  (cb) => {
1646
1501
  centerCallbackRef.current = cb;
1647
1502
  },
1648
1503
  []
1649
1504
  );
1650
- const _registerResetBearingCallback = (0, import_react3.useCallback)(
1505
+ const _registerResetBearingCallback = (0, import_react5.useCallback)(
1651
1506
  (cb) => {
1652
1507
  resetBearingCallbackRef.current = cb;
1653
1508
  },
1654
1509
  []
1655
1510
  );
1656
- const _registerFlyToCallback = (0, import_react3.useCallback)(
1511
+ const _registerFlyToCallback = (0, import_react5.useCallback)(
1657
1512
  (cb) => {
1658
1513
  flyToCallbackRef.current = cb;
1659
1514
  },
1660
1515
  []
1661
1516
  );
1662
- const setBearing = (0, import_react3.useCallback)((b) => {
1517
+ const setBearing = (0, import_react5.useCallback)((b) => {
1663
1518
  setBearingState(b);
1664
1519
  }, []);
1665
- const setPitch = (0, import_react3.useCallback)((p) => {
1520
+ const setPitch = (0, import_react5.useCallback)((p) => {
1666
1521
  setPitchState(p);
1667
1522
  }, []);
1668
- const contextValue = (0, import_react3.useMemo)(
1523
+ const contextValue = (0, import_react5.useMemo)(
1669
1524
  () => ({
1670
1525
  _registerCenterCallback,
1671
1526
  _registerFlyToCallback,
@@ -1715,10 +1570,10 @@ var SDKMapProvider = ({
1715
1570
  setInsets
1716
1571
  ]
1717
1572
  );
1718
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MapControlsContext.Provider, { value: contextValue, children });
1573
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MapControlsContext.Provider, { value: contextValue, children });
1719
1574
  };
1720
1575
  var useMapControls = () => {
1721
- const context = (0, import_react3.useContext)(MapControlsContext);
1576
+ const context = (0, import_react5.useContext)(MapControlsContext);
1722
1577
  if (!context) {
1723
1578
  throw new Error("useMapControls must be used within a MapControlsProvider");
1724
1579
  }
@@ -1726,8 +1581,8 @@ var useMapControls = () => {
1726
1581
  };
1727
1582
 
1728
1583
  // src/components/Map/components/MapControls.tsx
1729
- var import_react4 = require("react");
1730
- var import_jsx_runtime8 = require("react/jsx-runtime");
1584
+ var import_react6 = require("react");
1585
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1731
1586
  var resolveHeightToPixels2 = (height, containerHeight) => {
1732
1587
  if (typeof height === "number") {
1733
1588
  return height;
@@ -1763,9 +1618,9 @@ var MapControls = ({
1763
1618
  controlsBottomOffset = 0,
1764
1619
  isInternal = false
1765
1620
  }) => {
1766
- const mapContext = (0, import_react4.useContext)(MapControlsContext);
1621
+ const mapContext = (0, import_react6.useContext)(MapControlsContext);
1767
1622
  const contextRef = mapContext?.drawerContentRef;
1768
- const mergedRef = (0, import_react4.useCallback)(
1623
+ const mergedRef = (0, import_react6.useCallback)(
1769
1624
  (node) => {
1770
1625
  if (drawerContentRef) {
1771
1626
  if (typeof drawerContentRef === "function") {
@@ -1780,11 +1635,11 @@ var MapControls = ({
1780
1635
  },
1781
1636
  [drawerContentRef, contextRef]
1782
1637
  );
1783
- const [localDrawerState, setLocalDrawerState] = (0, import_react4.useState)(
1638
+ const [localDrawerState, setLocalDrawerState] = (0, import_react6.useState)(
1784
1639
  defaultState ?? "closed"
1785
1640
  );
1786
1641
  const drawerState = mapContext ? mapContext.drawerState : localDrawerState;
1787
- const setDrawerState = (0, import_react4.useCallback)(
1642
+ const setDrawerState = (0, import_react6.useCallback)(
1788
1643
  (state) => {
1789
1644
  if (mapContext) {
1790
1645
  mapContext.setDrawerState(state);
@@ -1794,15 +1649,15 @@ var MapControls = ({
1794
1649
  },
1795
1650
  [mapContext]
1796
1651
  );
1797
- (0, import_react4.useEffect)(() => {
1652
+ (0, import_react6.useEffect)(() => {
1798
1653
  if (defaultState && mapContext) {
1799
1654
  mapContext.setDrawerState(defaultState);
1800
1655
  }
1801
1656
  }, []);
1802
- const [side, setSide] = (0, import_react4.useState)("left");
1803
- const containerRef = (0, import_react4.useRef)(null);
1804
- const [mapHeight, setMapHeight] = (0, import_react4.useState)(600);
1805
- (0, import_react4.useEffect)(() => {
1657
+ const [side, setSide] = (0, import_react6.useState)("left");
1658
+ const containerRef = (0, import_react6.useRef)(null);
1659
+ const [mapHeight, setMapHeight] = (0, import_react6.useState)(600);
1660
+ (0, import_react6.useEffect)(() => {
1806
1661
  const parent = containerRef.current?.parentElement;
1807
1662
  if (!parent) return;
1808
1663
  const updateHeight = () => {
@@ -1816,7 +1671,7 @@ var MapControls = ({
1816
1671
  };
1817
1672
  }, []);
1818
1673
  const setHasControls = mapContext?.setHasControls;
1819
- (0, import_react4.useEffect)(() => {
1674
+ (0, import_react6.useEffect)(() => {
1820
1675
  if (setHasControls && !isInternal) {
1821
1676
  setHasControls(true);
1822
1677
  return () => setHasControls(false);
@@ -1840,10 +1695,8 @@ var MapControls = ({
1840
1695
  };
1841
1696
  const mapPitch = mapContext ? mapContext.pitch : 0;
1842
1697
  const resolvedEtaData = etaData !== void 0 ? etaData : mapContext?.etaData;
1843
- const [touchStartY, setTouchStartY] = (0, import_react4.useState)(null);
1844
- const [currentTouchY, setCurrentTouchY] = (0, import_react4.useState)(null);
1845
- const [autoContentPx, setAutoContentPx] = (0, import_react4.useState)(0);
1846
- (0, import_react4.useEffect)(() => {
1698
+ const [autoContentPx, setAutoContentPx] = (0, import_react6.useState)(0);
1699
+ (0, import_react6.useEffect)(() => {
1847
1700
  if (typeof window === "undefined") return;
1848
1701
  const checkLayout = () => {
1849
1702
  if (drawerSide) {
@@ -1860,8 +1713,8 @@ var MapControls = ({
1860
1713
  window.addEventListener("resize", checkLayout);
1861
1714
  return () => window.removeEventListener("resize", checkLayout);
1862
1715
  }, [drawerSide]);
1863
- const isDragging = touchStartY !== null && currentTouchY !== null;
1864
- const dragOffset = isDragging ? currentTouchY - touchStartY : 0;
1716
+ const isDragging = false;
1717
+ const clampedDragOffset = 0;
1865
1718
  const fullPx = resolveHeightToPixels2(drawerFullHeight || "85%", mapHeight);
1866
1719
  const peekPx = resolveHeightToPixels2(drawerPeekHeight || "15%", mapHeight);
1867
1720
  const autoMaxPx = resolveHeightToPixels2(
@@ -1871,22 +1724,6 @@ var MapControls = ({
1871
1724
  const autoPx = Math.min(autoMaxPx, autoContentPx);
1872
1725
  const bottomInset = mapContext?.insets.bottom || 0;
1873
1726
  const handleVisible = mapContext ? mapContext.drawerHandleVisible : true;
1874
- const closedPx = (handleVisible ? 32 : 0) + (drawerState === "closed" ? bottomInset : 0);
1875
- let clampedDragOffset = dragOffset;
1876
- if (drawerState === "full") {
1877
- clampedDragOffset = Math.max(0, Math.min(fullPx - closedPx, dragOffset));
1878
- } else if (drawerState === "peek") {
1879
- clampedDragOffset = Math.max(
1880
- -(fullPx - peekPx),
1881
- // up to full
1882
- Math.min(peekPx - closedPx, dragOffset)
1883
- // down to closed
1884
- );
1885
- } else if (drawerState === "closed") {
1886
- clampedDragOffset = Math.min(0, Math.max(-(fullPx - closedPx), dragOffset));
1887
- } else if (drawerState === "auto") {
1888
- clampedDragOffset = Math.max(0, dragOffset);
1889
- }
1890
1727
  let baseHeight = handleVisible ? 32 : 0;
1891
1728
  if (drawerState === "peek") {
1892
1729
  baseHeight = peekPx;
@@ -1895,7 +1732,7 @@ var MapControls = ({
1895
1732
  } else if (drawerState === "auto") {
1896
1733
  baseHeight = autoPx;
1897
1734
  }
1898
- const currentDrawerHeight = baseHeight - clampedDragOffset;
1735
+ const currentDrawerHeight = baseHeight;
1899
1736
  const startFadeHeight = peekPx + 20;
1900
1737
  const endFadeHeight = peekPx + (fullPx - peekPx) * 0.35;
1901
1738
  let etaOpacity = 1;
@@ -1915,22 +1752,17 @@ var MapControls = ({
1915
1752
  etaOpacity = drawerState === "full" ? 0 : 1;
1916
1753
  etaBottomStyle = `calc(1rem + ${bottomInset}px)`;
1917
1754
  }
1918
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1919
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: containerRef, style: { display: "none" } }),
1920
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1921
- MapDrawer,
1755
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1756
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, style: { display: "none" } }),
1757
+ side === "bottom" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1758
+ MobileBottomDrawer,
1922
1759
  {
1923
- clampedDragOffset,
1924
1760
  containerHeight: mapHeight,
1925
- currentTouchY,
1926
1761
  drawerAutoMaxHeight,
1927
1762
  drawerFullHeight,
1928
1763
  drawerPeekHeight,
1929
1764
  enableTouchDrag,
1930
- etaBarHeight,
1931
- etaData: resolvedEtaData,
1932
1765
  handleVisible,
1933
- isDragging,
1934
1766
  menuContent: children || menuContent,
1935
1767
  menuItems,
1936
1768
  onAutoContentHeightChange: setAutoContentPx,
@@ -1938,15 +1770,22 @@ var MapControls = ({
1938
1770
  ref: mergedRef,
1939
1771
  safeAreaInsets: mapContext?.insets,
1940
1772
  scrollToTopThreshold,
1941
- setCurrentTouchY,
1942
- setTouchStartY,
1943
1773
  showScrollToTopButton,
1944
- side,
1945
- state: drawerState,
1946
- touchStartY
1774
+ state: drawerState
1775
+ }
1776
+ ) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1777
+ MapDrawer,
1778
+ {
1779
+ menuContent: children || menuContent,
1780
+ menuItems,
1781
+ onChangeState: setDrawerState,
1782
+ ref: mergedRef,
1783
+ scrollToTopThreshold,
1784
+ showScrollToTopButton,
1785
+ state: drawerState
1947
1786
  }
1948
1787
  ),
1949
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1788
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1950
1789
  MapRightControls,
1951
1790
  {
1952
1791
  bottomOffset: controlsBottomOffset,
@@ -1969,7 +1808,7 @@ var MapControls = ({
1969
1808
  side
1970
1809
  }
1971
1810
  ),
1972
- resolvedEtaData && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1811
+ resolvedEtaData && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1973
1812
  MapEtaPanel,
1974
1813
  {
1975
1814
  etaData: resolvedEtaData,
@@ -1987,10 +1826,10 @@ var MapControls = ({
1987
1826
  };
1988
1827
 
1989
1828
  // src/components/Map/components/MapMenu.tsx
1990
- var import_react5 = require("react");
1991
- var import_jsx_runtime9 = require("react/jsx-runtime");
1829
+ var import_react7 = require("react");
1830
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1992
1831
  var MapMenu = ({ children }) => {
1993
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-col gap-1.5", children });
1832
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-col gap-1.5", children });
1994
1833
  };
1995
1834
  var MapMenuItem = ({
1996
1835
  id,
@@ -2001,7 +1840,7 @@ var MapMenuItem = ({
2001
1840
  disabled = false,
2002
1841
  children
2003
1842
  }) => {
2004
- const context = (0, import_react5.useContext)(MapControlsContext);
1843
+ const context = (0, import_react7.useContext)(MapControlsContext);
2005
1844
  const handleClick = (e) => {
2006
1845
  if (disabled) return;
2007
1846
  if (onPress) onPress();
@@ -2009,7 +1848,7 @@ var MapMenuItem = ({
2009
1848
  context.setDrawerState("closed");
2010
1849
  }
2011
1850
  };
2012
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1851
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2013
1852
  "button",
2014
1853
  {
2015
1854
  className: `flex items-center gap-3 w-full py-3 px-3.5 rounded-xl text-left cursor-pointer transition-all duration-150 ${disabled ? "opacity-45 cursor-not-allowed pointer-events-none" : "hover:bg-white/5 active:bg-white/10 text-white"}`,
@@ -2017,12 +1856,12 @@ var MapMenuItem = ({
2017
1856
  onClick: handleClick,
2018
1857
  type: "button",
2019
1858
  children: [
2020
- icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
1859
+ icon && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "relative flex items-center justify-center w-8 h-8 rounded-lg bg-white/5 text-zinc-300", children: [
2021
1860
  icon,
2022
- badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "absolute -top-1 -right-1 bg-cyan-500 text-black text-[9px] font-extrabold min-w-[15px] h-3.5 rounded-full flex items-center justify-center px-1 border border-zinc-950 shadow", children: badge })
1861
+ badge !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "absolute -top-1 -right-1 bg-cyan-500 text-black text-[9px] font-extrabold min-w-[15px] h-3.5 rounded-full flex items-center justify-center px-1 border border-zinc-950 shadow", children: badge })
2023
1862
  ] }),
2024
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex-1 flex flex-col justify-center", children: [
2025
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: label }),
1863
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1 flex flex-col justify-center", children: [
1864
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: label }),
2026
1865
  children
2027
1866
  ] })
2028
1867
  ]
@@ -2036,7 +1875,7 @@ var MapMenuTitle = ({
2036
1875
  showDivider = true,
2037
1876
  className = ""
2038
1877
  }) => {
2039
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1878
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2040
1879
  "div",
2041
1880
  {
2042
1881
  className: `flex items-center justify-between pb-3 first:mt-0 px-3.5 ${className} ${showDivider ? "border-b border-white/10 mb-2 mt-4" : ""}`,
@@ -2048,14 +1887,14 @@ MapMenuTitle.displayName = "MapMenuTitle";
2048
1887
  var MapMenuDivider = ({
2049
1888
  className = ""
2050
1889
  }) => {
2051
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `h-[1px] bg-white/10 my-3 mx-3.5 ${className}` });
1890
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `h-[1px] bg-white/10 my-3 mx-3.5 ${className}` });
2052
1891
  };
2053
1892
  MapMenuDivider.displayName = "MapMenuDivider";
2054
1893
  var MapMenuFooter = ({
2055
1894
  children,
2056
1895
  className = ""
2057
1896
  }) => {
2058
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1897
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2059
1898
  "div",
2060
1899
  {
2061
1900
  className: `mt-auto pt-4 border-t border-white/10 px-3.5 text-xs text-zinc-500 font-medium ${className}`,
@@ -2083,7 +1922,7 @@ var GlobalEvent = /* @__PURE__ */ ((GlobalEvent2) => {
2083
1922
  })(GlobalEvent || {});
2084
1923
 
2085
1924
  // src/components/Map/hooks/useUserLocation.ts
2086
- var import_react6 = require("react");
1925
+ var import_react8 = require("react");
2087
1926
  var LERP_FACTOR = 0.12;
2088
1927
  var EMPTY_STATE = {
2089
1928
  accuracy: null,
@@ -2204,8 +2043,8 @@ function stopSharedStream() {
2204
2043
  currentInterpolated = { coords: null, heading: null };
2205
2044
  }
2206
2045
  var useUserLocation = () => {
2207
- const [locationState, setLocationState] = (0, import_react6.useState)(getSnapshot);
2208
- (0, import_react6.useEffect)(() => {
2046
+ const [locationState, setLocationState] = (0, import_react8.useState)(getSnapshot);
2047
+ (0, import_react8.useEffect)(() => {
2209
2048
  refCount++;
2210
2049
  if (refCount === 1) {
2211
2050
  startSharedStream();
@@ -2225,7 +2064,7 @@ var useUserLocation = () => {
2225
2064
  };
2226
2065
 
2227
2066
  // src/components/Map/hooks/useLiveRouting.ts
2228
- var import_react7 = require("react");
2067
+ var import_react9 = require("react");
2229
2068
  var useLiveRouting = ({
2230
2069
  origin: manualOrigin,
2231
2070
  destination,
@@ -2234,19 +2073,19 @@ var useLiveRouting = ({
2234
2073
  enabled = true,
2235
2074
  initialMode = "preview"
2236
2075
  }) => {
2237
- const [route, setRoute] = (0, import_react7.useState)(null);
2238
- const [totalDistance, setTotalDistance] = (0, import_react7.useState)(null);
2239
- const [isCalculating, setIsCalculating] = (0, import_react7.useState)(false);
2240
- const [error, setError] = (0, import_react7.useState)(null);
2241
- const [mode, setMode] = (0, import_react7.useState)(initialMode);
2076
+ const [route, setRoute] = (0, import_react9.useState)(null);
2077
+ const [totalDistance, setTotalDistance] = (0, import_react9.useState)(null);
2078
+ const [isCalculating, setIsCalculating] = (0, import_react9.useState)(false);
2079
+ const [error, setError] = (0, import_react9.useState)(null);
2080
+ const [mode, setMode] = (0, import_react9.useState)(initialMode);
2242
2081
  const userLocationState = useUserLocation();
2243
2082
  const calculationOrigin = manualOrigin || userLocationState.coords;
2244
2083
  const trackingLocation = userLocationState.coords || manualOrigin;
2245
- const lastCalcOrigin = (0, import_react7.useRef)(null);
2246
- const lastCalcDest = (0, import_react7.useRef)(null);
2247
- const isRequestInProgress = (0, import_react7.useRef)(false);
2248
- const lastResetDestKey = (0, import_react7.useRef)(null);
2249
- const getDistance = (0, import_react7.useCallback)(
2084
+ const lastCalcOrigin = (0, import_react9.useRef)(null);
2085
+ const lastCalcDest = (0, import_react9.useRef)(null);
2086
+ const isRequestInProgress = (0, import_react9.useRef)(false);
2087
+ const lastResetDestKey = (0, import_react9.useRef)(null);
2088
+ const getDistance = (0, import_react9.useCallback)(
2250
2089
  (p1, p2) => {
2251
2090
  const R = 6371e3;
2252
2091
  const \u03C61 = p1[1] * Math.PI / 180;
@@ -2259,7 +2098,7 @@ var useLiveRouting = ({
2259
2098
  },
2260
2099
  []
2261
2100
  );
2262
- const currentDistanceMeters = (0, import_react7.useMemo)(() => {
2101
+ const currentDistanceMeters = (0, import_react9.useMemo)(() => {
2263
2102
  if (!trackingLocation || !route || route.geometry.coordinates.length < 2) {
2264
2103
  if (trackingLocation && destination) {
2265
2104
  return getDistance(trackingLocation, destination);
@@ -2286,7 +2125,7 @@ var useLiveRouting = ({
2286
2125
  }
2287
2126
  return dist;
2288
2127
  }, [trackingLocation, route, destination, getDistance]);
2289
- const calculate = (0, import_react7.useCallback)(
2128
+ const calculate = (0, import_react9.useCallback)(
2290
2129
  async (origin, dest, isNewDest) => {
2291
2130
  if (isRequestInProgress.current) return;
2292
2131
  isRequestInProgress.current = true;
@@ -2321,12 +2160,12 @@ var useLiveRouting = ({
2321
2160
  },
2322
2161
  [profile, getDistance]
2323
2162
  );
2324
- (0, import_react7.useEffect)(() => {
2163
+ (0, import_react9.useEffect)(() => {
2325
2164
  if (initialMode === "navigation") {
2326
2165
  setMode("navigation");
2327
2166
  }
2328
2167
  }, [initialMode]);
2329
- (0, import_react7.useEffect)(() => {
2168
+ (0, import_react9.useEffect)(() => {
2330
2169
  if (!enabled || !destination || !calculationOrigin) {
2331
2170
  if (!enabled || !destination) {
2332
2171
  setRoute(null);
@@ -2377,10 +2216,10 @@ var useLiveRouting = ({
2377
2216
  };
2378
2217
  };
2379
2218
  var useRoute = (origin, destination, profile = "driving") => {
2380
- const [route, setRoute] = (0, import_react7.useState)(null);
2381
- const [isCalculating, setIsCalculating] = (0, import_react7.useState)(false);
2382
- const [error, setError] = (0, import_react7.useState)(null);
2383
- (0, import_react7.useEffect)(() => {
2219
+ const [route, setRoute] = (0, import_react9.useState)(null);
2220
+ const [isCalculating, setIsCalculating] = (0, import_react9.useState)(false);
2221
+ const [error, setError] = (0, import_react9.useState)(null);
2222
+ (0, import_react9.useEffect)(() => {
2384
2223
  if (!origin || !destination) {
2385
2224
  setRoute(null);
2386
2225
  return;
@@ -2407,12 +2246,12 @@ var useRoute = (origin, destination, profile = "driving") => {
2407
2246
  };
2408
2247
 
2409
2248
  // src/components/Map/hooks/useJourney.ts
2410
- var import_react8 = require("react");
2249
+ var import_react10 = require("react");
2411
2250
  var useJourney = (options = {}) => {
2412
2251
  const { navigation, onAbort, onModeChange } = options;
2413
- const [progNav, setProgNav] = (0, import_react8.useState)(null);
2414
- const [isAborted, setIsAborted] = (0, import_react8.useState)(false);
2415
- (0, import_react8.useEffect)(() => {
2252
+ const [progNav, setProgNav] = (0, import_react10.useState)(null);
2253
+ const [isAborted, setIsAborted] = (0, import_react10.useState)(false);
2254
+ (0, import_react10.useEffect)(() => {
2416
2255
  const unsubCreate = sdk.on("SDK_NAVIGATION_CREATE", (payload) => {
2417
2256
  setIsAborted(false);
2418
2257
  setProgNav(payload);
@@ -2440,17 +2279,17 @@ var useJourney = (options = {}) => {
2440
2279
  profile: effectiveOptions?.profile || "driving",
2441
2280
  recalculateThreshold: effectiveOptions?.recalculateThreshold || 50
2442
2281
  });
2443
- const prevDest = (0, import_react8.useRef)(null);
2282
+ const prevDest = (0, import_react10.useRef)(null);
2444
2283
  const currentDest = effectiveOptions?.destination;
2445
- (0, import_react8.useEffect)(() => {
2284
+ (0, import_react10.useEffect)(() => {
2446
2285
  if (currentDest && (!prevDest.current || prevDest.current[0] !== currentDest[0] || prevDest.current[1] !== currentDest[1])) {
2447
2286
  setIsAborted(false);
2448
2287
  }
2449
2288
  prevDest.current = currentDest;
2450
2289
  }, [currentDest]);
2451
- const onModeChangeRef = (0, import_react8.useRef)(onModeChange);
2290
+ const onModeChangeRef = (0, import_react10.useRef)(onModeChange);
2452
2291
  onModeChangeRef.current = onModeChange;
2453
- (0, import_react8.useEffect)(() => {
2292
+ (0, import_react10.useEffect)(() => {
2454
2293
  onModeChangeRef.current?.(internalNav.mode);
2455
2294
  }, [internalNav.mode]);
2456
2295
  const isActive = !isAborted && !!effectiveOptions?.destination;
@@ -2472,13 +2311,13 @@ var useJourney = (options = {}) => {
2472
2311
  (totalDistanceMeters - remainingMeters) / totalDistanceMeters * 100
2473
2312
  )
2474
2313
  ) : 0;
2475
- const cancel = (0, import_react8.useCallback)(() => {
2314
+ const cancel = (0, import_react10.useCallback)(() => {
2476
2315
  setIsAborted(true);
2477
2316
  setProgNav(null);
2478
2317
  sdk.navigation.abort();
2479
2318
  if (onAbort) onAbort();
2480
2319
  }, [onAbort]);
2481
- const start = (0, import_react8.useCallback)(() => {
2320
+ const start = (0, import_react10.useCallback)(() => {
2482
2321
  sdk.navigation.start();
2483
2322
  internalNav.start();
2484
2323
  }, [internalNav.start]);
@@ -2500,9 +2339,9 @@ var useJourney = (options = {}) => {
2500
2339
  };
2501
2340
 
2502
2341
  // src/components/Map/hooks/useTrimmedRoute.ts
2503
- var import_react9 = require("react");
2342
+ var import_react11 = require("react");
2504
2343
  var useTrimmedRoute = (route, userLocation) => {
2505
- return (0, import_react9.useMemo)(() => {
2344
+ return (0, import_react11.useMemo)(() => {
2506
2345
  if (!route || !userLocation || route.coordinates.length < 2) return route;
2507
2346
  const coords = route.coordinates;
2508
2347
  let minDistance = Infinity;
@@ -2527,7 +2366,7 @@ var useTrimmedRoute = (route, userLocation) => {
2527
2366
 
2528
2367
  // src/components/Map/layers/RouteLayer.tsx
2529
2368
  var import_react_maplibre = require("@vis.gl/react-maplibre");
2530
- var import_jsx_runtime10 = require("react/jsx-runtime");
2369
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2531
2370
  var RouteLayer = ({
2532
2371
  geometry,
2533
2372
  color = "#3b82f6",
@@ -2540,8 +2379,8 @@ var RouteLayer = ({
2540
2379
  properties: {},
2541
2380
  type: "Feature"
2542
2381
  };
2543
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_maplibre.Source, { data, id: "sdk-route-source", type: "geojson", children: [
2544
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2382
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_maplibre.Source, { data, id: "sdk-route-source", type: "geojson", children: [
2383
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2545
2384
  import_react_maplibre.Layer,
2546
2385
  {
2547
2386
  id: "sdk-route-layer-casing",
@@ -2554,7 +2393,7 @@ var RouteLayer = ({
2554
2393
  type: "line"
2555
2394
  }
2556
2395
  ),
2557
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2396
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2558
2397
  import_react_maplibre.Layer,
2559
2398
  {
2560
2399
  id: "sdk-route-layer",
@@ -2597,8 +2436,8 @@ var buildGeoCircle = (center, radiusMeters, points = 64) => {
2597
2436
 
2598
2437
  // src/components/Map/layers/MockRadiusLayer.tsx
2599
2438
  var import_react_maplibre2 = require("@vis.gl/react-maplibre");
2600
- var import_react10 = require("react");
2601
- var import_jsx_runtime11 = require("react/jsx-runtime");
2439
+ var import_react12 = require("react");
2440
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2602
2441
  var MockRadiusLayer = ({
2603
2442
  center,
2604
2443
  radiusMeters,
@@ -2611,12 +2450,12 @@ var MockRadiusLayer = ({
2611
2450
  // pastel palette with no neon accents at all).
2612
2451
  color = "#e2e8f0"
2613
2452
  }) => {
2614
- const data = (0, import_react10.useMemo)(
2453
+ const data = (0, import_react12.useMemo)(
2615
2454
  () => buildGeoCircle(center, radiusMeters),
2616
2455
  [center, radiusMeters]
2617
2456
  );
2618
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_maplibre2.Source, { data, id: "sdk-mock-radius-source", type: "geojson", children: [
2619
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2457
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_maplibre2.Source, { data, id: "sdk-mock-radius-source", type: "geojson", children: [
2458
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2620
2459
  import_react_maplibre2.Layer,
2621
2460
  {
2622
2461
  id: "sdk-mock-radius-fill",
@@ -2627,7 +2466,7 @@ var MockRadiusLayer = ({
2627
2466
  type: "fill"
2628
2467
  }
2629
2468
  ),
2630
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2469
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2631
2470
  import_react_maplibre2.Layer,
2632
2471
  {
2633
2472
  id: "sdk-mock-radius-outline",
@@ -2644,8 +2483,8 @@ var MockRadiusLayer = ({
2644
2483
 
2645
2484
  // src/components/Map/layers/POILayers.tsx
2646
2485
  var import_react_maplibre3 = require("@vis.gl/react-maplibre");
2647
- var import_react11 = require("react");
2648
- var import_jsx_runtime12 = require("react/jsx-runtime");
2486
+ var import_react13 = require("react");
2487
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2649
2488
  function createEmojiIcon(emoji, size = 64) {
2650
2489
  const canvas = document.createElement("canvas");
2651
2490
  canvas.width = size;
@@ -2658,13 +2497,13 @@ function createEmojiIcon(emoji, size = 64) {
2658
2497
  return ctx.getImageData(0, 0, size, size);
2659
2498
  }
2660
2499
  var POILayers = ({ pois }) => {
2661
- const [loadedImages, setLoadedImages] = (0, import_react11.useState)(0);
2500
+ const [loadedImages, setLoadedImages] = (0, import_react13.useState)(0);
2662
2501
  const { current: map } = (0, import_react_maplibre3.useMap)();
2663
- const glPois = (0, import_react11.useMemo)(
2502
+ const glPois = (0, import_react13.useMemo)(
2664
2503
  () => pois.filter((p) => !p.displayMode || p.displayMode === "gl"),
2665
2504
  [pois]
2666
2505
  );
2667
- (0, import_react11.useEffect)(() => {
2506
+ (0, import_react13.useEffect)(() => {
2668
2507
  if (!map) return;
2669
2508
  const glMap = map.getMap();
2670
2509
  const defaults = [
@@ -2704,7 +2543,7 @@ var POILayers = ({ pois }) => {
2704
2543
  setLoadedImages((prev) => prev + updates);
2705
2544
  }
2706
2545
  }, [map, glPois]);
2707
- const geojson = (0, import_react11.useMemo)(
2546
+ const geojson = (0, import_react13.useMemo)(
2708
2547
  () => ({
2709
2548
  features: glPois.map((poi) => ({
2710
2549
  geometry: {
@@ -2722,7 +2561,7 @@ var POILayers = ({ pois }) => {
2722
2561
  }),
2723
2562
  [glPois]
2724
2563
  );
2725
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_maplibre3.Source, { data: geojson, id: "sdk-pois", type: "geojson", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2564
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_maplibre3.Source, { data: geojson, id: "sdk-pois", type: "geojson", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2726
2565
  import_react_maplibre3.Layer,
2727
2566
  {
2728
2567
  id: "sdk-poi-layer",
@@ -2759,11 +2598,11 @@ var POILayers = ({ pois }) => {
2759
2598
 
2760
2599
  // src/components/Map/layers/POIMarkers.tsx
2761
2600
  var import_react_maplibre4 = require("@vis.gl/react-maplibre");
2762
- var import_jsx_runtime13 = require("react/jsx-runtime");
2601
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2763
2602
  var POIMarkers = ({ pois, onClick }) => {
2764
2603
  const markerPois = pois.filter((p) => p.displayMode === "marker");
2765
2604
  if (markerPois.length === 0) return null;
2766
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: markerPois.map((poi) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2605
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: markerPois.map((poi) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2767
2606
  import_react_maplibre4.Marker,
2768
2607
  {
2769
2608
  anchor: "bottom",
@@ -2773,7 +2612,7 @@ var POIMarkers = ({ pois, onClick }) => {
2773
2612
  e.originalEvent.stopPropagation();
2774
2613
  if (onClick) onClick(poi);
2775
2614
  },
2776
- children: poi.markerComponent ? poi.markerComponent : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2615
+ children: poi.markerComponent ? poi.markerComponent : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2777
2616
  "div",
2778
2617
  {
2779
2618
  style: {
@@ -2782,7 +2621,7 @@ var POIMarkers = ({ pois, onClick }) => {
2782
2621
  transform: "transition-transform duration-200 hover:scale-110"
2783
2622
  },
2784
2623
  children: [
2785
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2624
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2786
2625
  "div",
2787
2626
  {
2788
2627
  style: {
@@ -2795,7 +2634,7 @@ var POIMarkers = ({ pois, onClick }) => {
2795
2634
  justifyContent: "center",
2796
2635
  width: "32px"
2797
2636
  },
2798
- children: poi.emoji ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: "16px" }, children: poi.emoji }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2637
+ children: poi.emoji ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { fontSize: "16px" }, children: poi.emoji }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2799
2638
  "div",
2800
2639
  {
2801
2640
  style: {
@@ -2808,7 +2647,7 @@ var POIMarkers = ({ pois, onClick }) => {
2808
2647
  )
2809
2648
  }
2810
2649
  ),
2811
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2650
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2812
2651
  "div",
2813
2652
  {
2814
2653
  style: {
@@ -2831,19 +2670,19 @@ var POIMarkers = ({ pois, onClick }) => {
2831
2670
 
2832
2671
  // src/components/Map/layers/UserLocationLayer.tsx
2833
2672
  var import_react_maplibre5 = require("@vis.gl/react-maplibre");
2834
- var import_jsx_runtime14 = require("react/jsx-runtime");
2673
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2835
2674
  var UserLocationLayer = ({
2836
2675
  forcedLocation,
2837
2676
  heading
2838
2677
  }) => {
2839
2678
  if (!forcedLocation) return null;
2840
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2679
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2841
2680
  import_react_maplibre5.Marker,
2842
2681
  {
2843
2682
  anchor: "center",
2844
2683
  latitude: forcedLocation[1],
2845
2684
  longitude: forcedLocation[0],
2846
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2685
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2847
2686
  "div",
2848
2687
  {
2849
2688
  style: {
@@ -2853,7 +2692,7 @@ var UserLocationLayer = ({
2853
2692
  position: "relative"
2854
2693
  },
2855
2694
  children: [
2856
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2695
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2857
2696
  "div",
2858
2697
  {
2859
2698
  style: {
@@ -2866,7 +2705,7 @@ var UserLocationLayer = ({
2866
2705
  }
2867
2706
  }
2868
2707
  ),
2869
- heading !== void 0 && heading !== null && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2708
+ heading !== void 0 && heading !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2870
2709
  "div",
2871
2710
  {
2872
2711
  style: {
@@ -2876,13 +2715,13 @@ var UserLocationLayer = ({
2876
2715
  width: "60px",
2877
2716
  zIndex: 0
2878
2717
  },
2879
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2718
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2880
2719
  "svg",
2881
2720
  {
2882
2721
  style: { height: "100%", width: "100%" },
2883
2722
  viewBox: "0 0 100 100",
2884
2723
  children: [
2885
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2724
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2886
2725
  "radialGradient",
2887
2726
  {
2888
2727
  cx: "50%",
@@ -2892,7 +2731,7 @@ var UserLocationLayer = ({
2892
2731
  id: "grad1",
2893
2732
  r: "50%",
2894
2733
  children: [
2895
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2734
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2896
2735
  "stop",
2897
2736
  {
2898
2737
  offset: "0%",
@@ -2902,7 +2741,7 @@ var UserLocationLayer = ({
2902
2741
  }
2903
2742
  }
2904
2743
  ),
2905
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2744
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2906
2745
  "stop",
2907
2746
  {
2908
2747
  offset: "100%",
@@ -2915,7 +2754,7 @@ var UserLocationLayer = ({
2915
2754
  ]
2916
2755
  }
2917
2756
  ) }),
2918
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2757
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2919
2758
  "path",
2920
2759
  {
2921
2760
  d: "M 50 50 L 35 0 A 50 50 0 0 1 65 0 Z",
@@ -2927,7 +2766,7 @@ var UserLocationLayer = ({
2927
2766
  )
2928
2767
  }
2929
2768
  ),
2930
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2769
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2931
2770
  "div",
2932
2771
  {
2933
2772
  style: {
@@ -2941,7 +2780,7 @@ var UserLocationLayer = ({
2941
2780
  width: "20px",
2942
2781
  zIndex: 1
2943
2782
  },
2944
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2783
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2945
2784
  "div",
2946
2785
  {
2947
2786
  style: {
@@ -2955,7 +2794,7 @@ var UserLocationLayer = ({
2955
2794
  )
2956
2795
  }
2957
2796
  ),
2958
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("style", { children: `@keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 70% { transform: scale(1.5); opacity: 0; } 100% { transform: scale(0.95); opacity: 0; } }` })
2797
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("style", { children: `@keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 70% { transform: scale(1.5); opacity: 0; } 100% { transform: scale(0.95); opacity: 0; } }` })
2959
2798
  ]
2960
2799
  }
2961
2800
  )
@@ -2965,9 +2804,9 @@ var UserLocationLayer = ({
2965
2804
 
2966
2805
  // src/components/Map/Map.tsx
2967
2806
  var import_react_maplibre6 = require("@vis.gl/react-maplibre");
2968
- var import_react12 = __toESM(require("react"), 1);
2807
+ var import_react14 = __toESM(require("react"), 1);
2969
2808
  var import_maplibre_gl = require("maplibre-gl/dist/maplibre-gl.css");
2970
- var import_jsx_runtime15 = require("react/jsx-runtime");
2809
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2971
2810
  var MapInternal = ({
2972
2811
  initialViewState = {
2973
2812
  latitude: 45.90583599233422,
@@ -3005,9 +2844,9 @@ var MapInternal = ({
3005
2844
  controlProps = {},
3006
2845
  enableTouchDrag = false
3007
2846
  }) => {
3008
- const mapControls = (0, import_react12.useContext)(MapControlsContext);
3009
- const mockLocation = (0, import_react12.useContext)(MockLocationContext);
3010
- const mapRef = (0, import_react12.useRef)(null);
2847
+ const mapControls = (0, import_react14.useContext)(MapControlsContext);
2848
+ const mockLocation = (0, import_react14.useContext)(MockLocationContext);
2849
+ const mapRef = (0, import_react14.useRef)(null);
3011
2850
  const userLocationState = useUserLocation();
3012
2851
  const journey = useJourney({
3013
2852
  navigation,
@@ -3025,24 +2864,24 @@ var MapInternal = ({
3025
2864
  const showNavigationUI = hasIntegratedNav ? externalShowNavigationUI !== false && navigation?.showUI !== false : externalShowNavigationUI;
3026
2865
  const mode = navigationData?.mode || "preview";
3027
2866
  const resolvedInitialFollow = mapControls ? mapControls.isFollowing : initialFollowUser;
3028
- const isFollowingRef = (0, import_react12.useRef)(resolvedInitialFollow);
3029
- const isFlyingRef = (0, import_react12.useRef)(false);
3030
- const flyingGenerationRef = (0, import_react12.useRef)(0);
3031
- const lockFlying = (0, import_react12.useCallback)(() => {
2867
+ const isFollowingRef = (0, import_react14.useRef)(resolvedInitialFollow);
2868
+ const isFlyingRef = (0, import_react14.useRef)(false);
2869
+ const flyingGenerationRef = (0, import_react14.useRef)(0);
2870
+ const lockFlying = (0, import_react14.useCallback)(() => {
3032
2871
  isFlyingRef.current = true;
3033
2872
  return ++flyingGenerationRef.current;
3034
2873
  }, []);
3035
- const releaseFlyingIfCurrent = (0, import_react12.useCallback)((flightId) => {
2874
+ const releaseFlyingIfCurrent = (0, import_react14.useCallback)((flightId) => {
3036
2875
  if (flyingGenerationRef.current === flightId) {
3037
2876
  isFlyingRef.current = false;
3038
2877
  }
3039
2878
  }, []);
3040
- const [localIsFollowingUI, setLocalIsFollowingUI] = (0, import_react12.useState)(
2879
+ const [localIsFollowingUI, setLocalIsFollowingUI] = (0, import_react14.useState)(
3041
2880
  resolvedInitialFollow
3042
2881
  );
3043
2882
  const isFollowingUI = mapControls ? mapControls.isFollowing : localIsFollowingUI;
3044
2883
  const setIsFollowingCtx = mapControls?.setIsFollowing;
3045
- const setFollowMode = (0, import_react12.useCallback)(
2884
+ const setFollowMode = (0, import_react14.useCallback)(
3046
2885
  (follow) => {
3047
2886
  isFollowingRef.current = follow;
3048
2887
  setLocalIsFollowingUI(follow);
@@ -3052,7 +2891,7 @@ var MapInternal = ({
3052
2891
  },
3053
2892
  [setIsFollowingCtx]
3054
2893
  );
3055
- (0, import_react12.useEffect)(() => {
2894
+ (0, import_react14.useEffect)(() => {
3056
2895
  if (mapControls && mapControls.isFollowing !== isFollowingRef.current) {
3057
2896
  isFollowingRef.current = mapControls.isFollowing;
3058
2897
  }
@@ -3061,8 +2900,8 @@ var MapInternal = ({
3061
2900
  if (pois.length > 0 && !mergedInteractiveLayerIds.includes("sdk-poi-layer")) {
3062
2901
  mergedInteractiveLayerIds.push("sdk-poi-layer");
3063
2902
  }
3064
- const prevInitialFollow = (0, import_react12.useRef)(initialFollowUser);
3065
- (0, import_react12.useEffect)(() => {
2903
+ const prevInitialFollow = (0, import_react14.useRef)(initialFollowUser);
2904
+ (0, import_react14.useEffect)(() => {
3066
2905
  if (initialFollowUser !== prevInitialFollow.current) {
3067
2906
  setFollowMode(initialFollowUser);
3068
2907
  prevInitialFollow.current = initialFollowUser;
@@ -3086,9 +2925,9 @@ var MapInternal = ({
3086
2925
  lockFlying,
3087
2926
  releaseFlyingIfCurrent
3088
2927
  ]);
3089
- const lastAutoLockedRouteRef = (0, import_react12.useRef)(null);
3090
- const lastModeRef = (0, import_react12.useRef)(null);
3091
- (0, import_react12.useEffect)(() => {
2928
+ const lastAutoLockedRouteRef = (0, import_react14.useRef)(null);
2929
+ const lastModeRef = (0, import_react14.useRef)(null);
2930
+ (0, import_react14.useEffect)(() => {
3092
2931
  if (!route || !mapRef.current) {
3093
2932
  if (!route) lastAutoLockedRouteRef.current = null;
3094
2933
  return;
@@ -3144,7 +2983,7 @@ var MapInternal = ({
3144
2983
  lockFlying,
3145
2984
  releaseFlyingIfCurrent
3146
2985
  ]);
3147
- (0, import_react12.useEffect)(() => {
2986
+ (0, import_react14.useEffect)(() => {
3148
2987
  if (isFollowingRef.current && !isFlyingRef.current && userLocationState.coords && mapRef.current) {
3149
2988
  mapRef.current.easeTo({
3150
2989
  center: userLocationState.coords,
@@ -3188,23 +3027,23 @@ var MapInternal = ({
3188
3027
  progress: progressValue
3189
3028
  } : void 0;
3190
3029
  const setEtaDataCtx = mapControls?.setEtaData;
3191
- (0, import_react12.useEffect)(() => {
3030
+ (0, import_react14.useEffect)(() => {
3192
3031
  if (setEtaDataCtx) {
3193
3032
  setEtaDataCtx(showEtaData);
3194
3033
  }
3195
3034
  }, [showEtaData, setEtaDataCtx]);
3196
3035
  const setDrawerStateCtx = mapControls?.setDrawerState;
3197
- (0, import_react12.useEffect)(() => {
3036
+ (0, import_react14.useEffect)(() => {
3198
3037
  if (setDrawerStateCtx && propDrawerState !== void 0) {
3199
3038
  setDrawerStateCtx(propDrawerState);
3200
3039
  }
3201
3040
  }, [propDrawerState, setDrawerStateCtx]);
3202
3041
  const resolvedMenuItems = menuItems ?? [];
3203
- const { mapLibreChildren, menuContentFromChildren } = (0, import_react12.useMemo)(() => {
3042
+ const { mapLibreChildren, menuContentFromChildren } = (0, import_react14.useMemo)(() => {
3204
3043
  const mapLibreChildren2 = [];
3205
3044
  const extractedMenuItems = [];
3206
- import_react12.default.Children.forEach(children, (child) => {
3207
- if (import_react12.default.isValidElement(child)) {
3045
+ import_react14.default.Children.forEach(children, (child) => {
3046
+ if (import_react14.default.isValidElement(child)) {
3208
3047
  const type = child.type;
3209
3048
  const displayName = type?.displayName || type?.name;
3210
3049
  const isMenu = type === MapMenu || displayName === "MapMenu";
@@ -3215,7 +3054,7 @@ var MapInternal = ({
3215
3054
  "MapMenuFooter"
3216
3055
  ].includes(displayName);
3217
3056
  if (isMenu) {
3218
- import_react12.default.Children.forEach(
3057
+ import_react14.default.Children.forEach(
3219
3058
  child.props.children,
3220
3059
  (nestedChild) => {
3221
3060
  if (nestedChild) {
@@ -3232,7 +3071,7 @@ var MapInternal = ({
3232
3071
  mapLibreChildren2.push(child);
3233
3072
  }
3234
3073
  });
3235
- const menuContentFromChildren2 = extractedMenuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MapMenu, { children: extractedMenuItems }) : null;
3074
+ const menuContentFromChildren2 = extractedMenuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MapMenu, { children: extractedMenuItems }) : null;
3236
3075
  return { mapLibreChildren: mapLibreChildren2, menuContentFromChildren: menuContentFromChildren2 };
3237
3076
  }, [children]);
3238
3077
  const handleMapClick = (e) => {
@@ -3260,7 +3099,7 @@ var MapInternal = ({
3260
3099
  }
3261
3100
  if (onClick) onClick(e);
3262
3101
  };
3263
- const handleCenterOnUser = (0, import_react12.useCallback)(
3102
+ const handleCenterOnUser = (0, import_react14.useCallback)(
3264
3103
  (payload) => {
3265
3104
  if (userLocationState.coords && mapRef.current) {
3266
3105
  setFollowMode(true);
@@ -3285,7 +3124,7 @@ var MapInternal = ({
3285
3124
  releaseFlyingIfCurrent
3286
3125
  ]
3287
3126
  );
3288
- const handleFlyTo = (0, import_react12.useCallback)(
3127
+ const handleFlyTo = (0, import_react14.useCallback)(
3289
3128
  (coords, params) => {
3290
3129
  const map = mapRef.current;
3291
3130
  if (!map) return;
@@ -3305,7 +3144,7 @@ var MapInternal = ({
3305
3144
  },
3306
3145
  [setFollowMode, lockFlying, releaseFlyingIfCurrent]
3307
3146
  );
3308
- const handleResetBearing = (0, import_react12.useCallback)((params) => {
3147
+ const handleResetBearing = (0, import_react14.useCallback)((params) => {
3309
3148
  if (mapRef.current) {
3310
3149
  mapRef.current.easeTo({
3311
3150
  bearing: 0,
@@ -3315,14 +3154,14 @@ var MapInternal = ({
3315
3154
  });
3316
3155
  }
3317
3156
  }, []);
3318
- (0, import_react12.useEffect)(() => {
3157
+ (0, import_react14.useEffect)(() => {
3319
3158
  if (mapControls) {
3320
3159
  mapControls._registerCenterCallback(handleCenterOnUser);
3321
3160
  mapControls._registerResetBearingCallback(handleResetBearing);
3322
3161
  mapControls._registerFlyToCallback(handleFlyTo);
3323
3162
  }
3324
3163
  }, [mapControls, handleCenterOnUser, handleResetBearing, handleFlyTo]);
3325
- const handleMove = (0, import_react12.useCallback)(() => {
3164
+ const handleMove = (0, import_react14.useCallback)(() => {
3326
3165
  if (mapRef.current && mapControls) {
3327
3166
  mapControls.setBearing(mapRef.current.getBearing());
3328
3167
  mapControls.setPitch(mapRef.current.getPitch());
@@ -3337,13 +3176,13 @@ var MapInternal = ({
3337
3176
  }
3338
3177
  }
3339
3178
  };
3340
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3179
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3341
3180
  "div",
3342
3181
  {
3343
3182
  className: `w-full h-full overflow-hidden relative ${mockLocation?.isPlacingLocation ? "cursor-crosshair" : ""} ${className}`,
3344
3183
  style,
3345
3184
  children: [
3346
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3185
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3347
3186
  import_react_maplibre6.Map,
3348
3187
  {
3349
3188
  attributionControl: false,
@@ -3373,30 +3212,30 @@ var MapInternal = ({
3373
3212
  showUserLocation && userLocationState.coords && (renderUserLocation ? renderUserLocation({
3374
3213
  coords: userLocationState.coords,
3375
3214
  heading: userLocationState.heading
3376
- }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3215
+ }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3377
3216
  UserLocationLayer,
3378
3217
  {
3379
3218
  forcedLocation: userLocationState.coords,
3380
3219
  heading: userLocationState.heading
3381
3220
  }
3382
3221
  )),
3383
- mockLocation && mockLocation.radiusMeters > 0 && userLocationState.coords && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3222
+ mockLocation && mockLocation.radiusMeters > 0 && userLocationState.coords && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3384
3223
  MockRadiusLayer,
3385
3224
  {
3386
3225
  center: userLocationState.coords,
3387
3226
  radiusMeters: mockLocation.radiusMeters
3388
3227
  }
3389
3228
  ),
3390
- displayRoute && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RouteLayer, { geometry: displayRoute }),
3391
- pois.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
3392
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(POILayers, { pois }),
3393
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(POIMarkers, { onClick: onPoiClick, pois })
3229
+ displayRoute && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RouteLayer, { geometry: displayRoute }),
3230
+ pois.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3231
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(POILayers, { pois }),
3232
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(POIMarkers, { onClick: onPoiClick, pois })
3394
3233
  ] }),
3395
3234
  mapLibreChildren
3396
3235
  ]
3397
3236
  }
3398
3237
  ),
3399
- showControls && mapControls && !mapControls.hasControls && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3238
+ showControls && mapControls && !mapControls.hasControls && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3400
3239
  MapControls,
3401
3240
  {
3402
3241
  drawerContentRef,
@@ -3416,18 +3255,18 @@ var MapInternal = ({
3416
3255
  var SDKMapProviderWrapper = ({
3417
3256
  children
3418
3257
  }) => {
3419
- const context = (0, import_react12.useContext)(MapControlsContext);
3258
+ const context = (0, import_react14.useContext)(MapControlsContext);
3420
3259
  if (context) {
3421
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children });
3260
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children });
3422
3261
  }
3423
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SDKMapProvider, { children });
3262
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SDKMapProvider, { children });
3424
3263
  };
3425
3264
  var Map2 = (props) => {
3426
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SDKMapProviderWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_maplibre6.MapProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MapInternal, { ...props }) }) });
3265
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SDKMapProviderWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_maplibre6.MapProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MapInternal, { ...props }) }) });
3427
3266
  };
3428
3267
 
3429
3268
  // src/components/MapWrapper.tsx
3430
- var import_react13 = __toESM(require("react"), 1);
3269
+ var import_react15 = __toESM(require("react"), 1);
3431
3270
  var import_client = require("react-dom/client");
3432
3271
  function renderMap(containerId, props = {}) {
3433
3272
  const container = document.getElementById(containerId);
@@ -3435,7 +3274,7 @@ function renderMap(containerId, props = {}) {
3435
3274
  throw new Error(`Container with id "${containerId}" not found.`);
3436
3275
  }
3437
3276
  const root = (0, import_client.createRoot)(container);
3438
- root.render(import_react13.default.createElement(Map2, props));
3277
+ root.render(import_react15.default.createElement(Map2, props));
3439
3278
  return root;
3440
3279
  }
3441
3280
 
@@ -3792,7 +3631,7 @@ var RoutingService = {
3792
3631
  };
3793
3632
 
3794
3633
  // package.json
3795
- var version = "0.6.8";
3634
+ var version = "0.7.3";
3796
3635
 
3797
3636
  // src/sdk.ts
3798
3637
  function deepFreeze(obj) {
@@ -4027,7 +3866,7 @@ var MiniAppSDK = class {
4027
3866
  }
4028
3867
  });
4029
3868
  /**
4030
- * Fidelity & Rewards program integration.
3869
+ * Fidelity & Points program integration.
4031
3870
  */
4032
3871
  fidelity = Object.freeze({
4033
3872
  /** Returns current fidelity balance. */
@@ -4138,6 +3977,8 @@ var MiniAppSDK = class {
4138
3977
  );
4139
3978
  this.initialize = this.initialize.bind(this);
4140
3979
  this.getEnv = this.getEnv.bind(this);
3980
+ this.achievement = this.achievement.bind(this);
3981
+ this.achievements = this.achievements.bind(this);
4141
3982
  this.on = this.on.bind(this);
4142
3983
  this.off = this.off.bind(this);
4143
3984
  }
@@ -4178,6 +4019,23 @@ var MiniAppSDK = class {
4178
4019
  getEnv() {
4179
4020
  return lastKnownEnv;
4180
4021
  }
4022
+ /**
4023
+ * Fetches a single Achievement's current progress by slug — read-only, for
4024
+ * rendering things like a progress bar. Progress is reported server-side
4025
+ * by the mini-app's own backend calling the Hub's M2M endpoint directly;
4026
+ * there is no corresponding "report progress" method on this SDK.
4027
+ * @param slug Unique slug identifying the Achievement.
4028
+ */
4029
+ achievement(slug) {
4030
+ return this.bridge.send("GET_ACHIEVEMENT", { slug });
4031
+ }
4032
+ /**
4033
+ * Fetches every Achievement (with current progress) visible to this
4034
+ * mini-app — read-only, same boundary as {@link MiniAppSDK.achievement}.
4035
+ */
4036
+ achievements() {
4037
+ return this.bridge.send("GET_ACHIEVEMENTS");
4038
+ }
4181
4039
  /**
4182
4040
  * Registers a callback for a specific event from the native shell.
4183
4041
  * @param event The name of the event to listen for.
@@ -4199,8 +4057,43 @@ var MiniAppSDK = class {
4199
4057
  var sdk = deepFreeze(new MiniAppSDK());
4200
4058
 
4201
4059
  // src/components/BridgeMocker.tsx
4202
- var import_react14 = require("react");
4203
- var import_jsx_runtime16 = require("react/jsx-runtime");
4060
+ var import_react16 = require("react");
4061
+ var import_jsx_runtime17 = require("react/jsx-runtime");
4062
+ var MOCK_ACHIEVEMENTS2 = [
4063
+ {
4064
+ completed: true,
4065
+ description: "Complete your first navigation journey.",
4066
+ playerActionCount: 1,
4067
+ priority: 1,
4068
+ slug: "first-journey",
4069
+ title: "First Steps",
4070
+ totalActionCount: 1,
4071
+ upReward: 20,
4072
+ xpReward: 40
4073
+ },
4074
+ {
4075
+ completed: false,
4076
+ description: "Discover 5 points of interest around Annecy.",
4077
+ playerActionCount: 3,
4078
+ priority: 2,
4079
+ slug: "explore-5-pois",
4080
+ title: "Explorer",
4081
+ totalActionCount: 5,
4082
+ upReward: 50,
4083
+ xpReward: 100
4084
+ },
4085
+ {
4086
+ completed: false,
4087
+ description: "Scan 10 QR codes at partner venues.",
4088
+ playerActionCount: 4,
4089
+ priority: 3,
4090
+ slug: "scan-10-qrcodes",
4091
+ title: "Code Breaker",
4092
+ totalActionCount: 10,
4093
+ upReward: 80,
4094
+ xpReward: 150
4095
+ }
4096
+ ];
4204
4097
  var AVATAR_MOUTH_VARIANTS = [
4205
4098
  "variant03",
4206
4099
  "variant07",
@@ -4287,19 +4180,19 @@ var BridgeMocker = ({
4287
4180
  mockJWTToken,
4288
4181
  children
4289
4182
  }) => {
4290
- const [autoMove, setAutoMove] = (0, import_react14.useState)(isMoving);
4291
- const [location, setLocation] = (0, import_react14.useState)(initialLocation);
4292
- const [heading, setHeading] = (0, import_react14.useState)(0);
4293
- const [speedMultiplier, setSpeedMultiplier] = (0, import_react14.useState)(simulationSpeed);
4294
- const [isReady, setIsReady] = (0, import_react14.useState)(false);
4295
- const [isMinimized, setIsMinimized] = (0, import_react14.useState)(true);
4296
- const [radiusMeters, setRadiusMeters] = (0, import_react14.useState)(0);
4297
- const [radiusUnit, setRadiusUnit] = (0, import_react14.useState)("m");
4298
- const [isPlacingLocation, setIsPlacingLocation] = (0, import_react14.useState)(false);
4299
- const streamIntervalRef = (0, import_react14.useRef)(null);
4300
- const pathIndexRef = (0, import_react14.useRef)(0);
4301
- const activeConfigRef = (0, import_react14.useRef)(null);
4302
- const stateRef = (0, import_react14.useRef)({
4183
+ const [autoMove, setAutoMove] = (0, import_react16.useState)(isMoving);
4184
+ const [location, setLocation] = (0, import_react16.useState)(initialLocation);
4185
+ const [heading, setHeading] = (0, import_react16.useState)(0);
4186
+ const [speedMultiplier, setSpeedMultiplier] = (0, import_react16.useState)(simulationSpeed);
4187
+ const [isReady, setIsReady] = (0, import_react16.useState)(false);
4188
+ const [isMinimized, setIsMinimized] = (0, import_react16.useState)(true);
4189
+ const [radiusMeters, setRadiusMeters] = (0, import_react16.useState)(0);
4190
+ const [radiusUnit, setRadiusUnit] = (0, import_react16.useState)("m");
4191
+ const [isPlacingLocation, setIsPlacingLocation] = (0, import_react16.useState)(false);
4192
+ const streamIntervalRef = (0, import_react16.useRef)(null);
4193
+ const pathIndexRef = (0, import_react16.useRef)(0);
4194
+ const activeConfigRef = (0, import_react16.useRef)(null);
4195
+ const stateRef = (0, import_react16.useRef)({
4303
4196
  autoMove,
4304
4197
  heading,
4305
4198
  location,
@@ -4311,7 +4204,7 @@ var BridgeMocker = ({
4311
4204
  simulationPath,
4312
4205
  speedMultiplier
4313
4206
  });
4314
- const pushLocationUpdateFor = (0, import_react14.useCallback)(
4207
+ const pushLocationUpdateFor = (0, import_react16.useCallback)(
4315
4208
  (coords, headingDeg) => {
4316
4209
  const currentState = stateRef.current;
4317
4210
  const payload = {
@@ -4343,11 +4236,11 @@ var BridgeMocker = ({
4343
4236
  },
4344
4237
  []
4345
4238
  );
4346
- const pushLocationUpdate = (0, import_react14.useCallback)(() => {
4239
+ const pushLocationUpdate = (0, import_react16.useCallback)(() => {
4347
4240
  const currentState = stateRef.current;
4348
4241
  pushLocationUpdateFor(currentState.location, currentState.heading);
4349
4242
  }, [pushLocationUpdateFor]);
4350
- const placeLocation = (0, import_react14.useCallback)(
4243
+ const placeLocation = (0, import_react16.useCallback)(
4351
4244
  (coords) => {
4352
4245
  setLocation(coords);
4353
4246
  setIsPlacingLocation(false);
@@ -4355,7 +4248,7 @@ var BridgeMocker = ({
4355
4248
  },
4356
4249
  [pushLocationUpdateFor]
4357
4250
  );
4358
- (0, import_react14.useEffect)(() => {
4251
+ (0, import_react16.useEffect)(() => {
4359
4252
  stateRef.current = {
4360
4253
  autoMove,
4361
4254
  heading,
@@ -4376,19 +4269,19 @@ var BridgeMocker = ({
4376
4269
  speedMultiplier,
4377
4270
  mockJWTToken
4378
4271
  ]);
4379
- (0, import_react14.useEffect)(() => {
4272
+ (0, import_react16.useEffect)(() => {
4380
4273
  setAutoMove(isMoving);
4381
4274
  }, [isMoving]);
4382
- (0, import_react14.useEffect)(() => {
4275
+ (0, import_react16.useEffect)(() => {
4383
4276
  setSpeedMultiplier(simulationSpeed);
4384
4277
  }, [simulationSpeed]);
4385
- (0, import_react14.useEffect)(() => {
4278
+ (0, import_react16.useEffect)(() => {
4386
4279
  if (simulationPath && simulationPath.length > 0) {
4387
4280
  pathIndexRef.current = 0;
4388
4281
  setLocation(simulationPath[0]);
4389
4282
  }
4390
4283
  }, [simulationPath]);
4391
- (0, import_react14.useEffect)(() => {
4284
+ (0, import_react16.useEffect)(() => {
4392
4285
  if (streamIntervalRef.current && activeConfigRef.current) {
4393
4286
  sdk.bridge.send(
4394
4287
  "START_LOCATION_STREAM",
@@ -4396,7 +4289,7 @@ var BridgeMocker = ({
4396
4289
  );
4397
4290
  }
4398
4291
  }, [speedMultiplier]);
4399
- (0, import_react14.useEffect)(() => {
4292
+ (0, import_react16.useEffect)(() => {
4400
4293
  const bridge = sdk.bridge;
4401
4294
  const originalSend = bridge.send.bind(bridge);
4402
4295
  const stopStream = () => {
@@ -4557,6 +4450,25 @@ var BridgeMocker = ({
4557
4450
  if (type === "GET_FIDELITY_BALANCE") {
4558
4451
  return Promise.resolve({ balance: 1337, currency: "FPoints" });
4559
4452
  }
4453
+ if (type === "GET_ACHIEVEMENTS") {
4454
+ return Promise.resolve(MOCK_ACHIEVEMENTS2);
4455
+ }
4456
+ if (type === "GET_ACHIEVEMENT") {
4457
+ const slug = payload?.slug;
4458
+ return Promise.resolve(
4459
+ MOCK_ACHIEVEMENTS2.find((a) => a.slug === slug) ?? {
4460
+ completed: false,
4461
+ description: "Mocked achievement (no native shell attached).",
4462
+ playerActionCount: 0,
4463
+ priority: 1,
4464
+ slug: slug || "unknown-achievement",
4465
+ title: slug || "Unknown Achievement",
4466
+ totalActionCount: 1,
4467
+ upReward: 0,
4468
+ xpReward: 0
4469
+ }
4470
+ );
4471
+ }
4560
4472
  if (type === "PAYMENT_REQUEST") {
4561
4473
  return Promise.resolve({
4562
4474
  success: true,
@@ -4575,7 +4487,7 @@ var BridgeMocker = ({
4575
4487
  };
4576
4488
  }, [appId]);
4577
4489
  const radiusInMeters = radiusUnit === "km" ? radiusMeters * 1e3 : radiusMeters;
4578
- const mockLocationContextValue = (0, import_react14.useMemo)(
4490
+ const mockLocationContextValue = (0, import_react16.useMemo)(
4579
4491
  () => ({
4580
4492
  isPlacingLocation,
4581
4493
  placeLocation,
@@ -4584,9 +4496,9 @@ var BridgeMocker = ({
4584
4496
  [isPlacingLocation, placeLocation, radiusInMeters]
4585
4497
  );
4586
4498
  if (!isReady) return null;
4587
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "relative w-full h-full", children: [
4588
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "w-full h-full", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MockLocationContext.Provider, { value: mockLocationContextValue, children }) }),
4589
- isMinimized ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4499
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative w-full h-full", children: [
4500
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "w-full h-full", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MockLocationContext.Provider, { value: mockLocationContextValue, children }) }),
4501
+ isMinimized ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4590
4502
  Button,
4591
4503
  {
4592
4504
  className: "fixed bottom-4 right-4 w-8 h-8 rounded-full bg-slate-900/60 backdrop-blur-sm border border-slate-700/50 flex items-center justify-center text-slate-400 hover:text-blue-400 hover:bg-slate-900/80 z-[9999] transition-all shadow-lg group p-0!",
@@ -4594,7 +4506,7 @@ var BridgeMocker = ({
4594
4506
  title: "Open Simulation Controls",
4595
4507
  type: "button",
4596
4508
  variant: "ghost",
4597
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
4509
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4598
4510
  "svg",
4599
4511
  {
4600
4512
  className: "group-hover:scale-110 transition-transform",
@@ -4608,34 +4520,34 @@ var BridgeMocker = ({
4608
4520
  width: "14",
4609
4521
  xmlns: "http://www.w3.org/2000/svg",
4610
4522
  children: [
4611
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M21 4H3" }),
4612
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M10 8H3" }),
4613
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M21 12H3" }),
4614
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M10 16H3" }),
4615
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M21 20H3" }),
4616
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "14", cy: "8", r: "2" }),
4617
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "14", cy: "16", r: "2" })
4523
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M21 4H3" }),
4524
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M10 8H3" }),
4525
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M21 12H3" }),
4526
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M10 16H3" }),
4527
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M21 20H3" }),
4528
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "14", cy: "8", r: "2" }),
4529
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "14", cy: "16", r: "2" })
4618
4530
  ]
4619
4531
  }
4620
4532
  )
4621
4533
  }
4622
- ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
4534
+ ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4623
4535
  "div",
4624
4536
  {
4625
4537
  className: "fixed bottom-4 right-4 bg-slate-900 text-slate-300 font-mono text-xs rounded-xl shadow-2xl border border-slate-700 pointer-events-auto flex flex-col w-80 overflow-hidden animate-in slide-in-from-right duration-300",
4626
4538
  style: { zIndex: 9998 },
4627
4539
  children: [
4628
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
4540
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4629
4541
  "div",
4630
4542
  {
4631
4543
  className: "flex justify-between items-center p-3 border-b border-slate-800 cursor-pointer bg-slate-800/50 hover:bg-slate-800 transition-colors",
4632
4544
  onClick: () => setIsMinimized(true),
4633
4545
  children: [
4634
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "font-bold text-slate-100 flex items-center gap-2", children: [
4635
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-lg", children: "\u{1F6E0}\uFE0F" }),
4546
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "font-bold text-slate-100 flex items-center gap-2", children: [
4547
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-lg", children: "\u{1F6E0}\uFE0F" }),
4636
4548
  " Simulation Controls"
4637
4549
  ] }),
4638
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4550
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4639
4551
  Button,
4640
4552
  {
4641
4553
  className: "text-slate-500 hover:text-white p-0 h-auto hover:bg-transparent cursor-pointer",
@@ -4647,10 +4559,10 @@ var BridgeMocker = ({
4647
4559
  ]
4648
4560
  }
4649
4561
  ),
4650
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "p-4 flex flex-col gap-3", children: [
4651
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex justify-between items-center", children: [
4652
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer", children: [
4653
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4562
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "p-4 flex flex-col gap-3", children: [
4563
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex justify-between items-center", children: [
4564
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer", children: [
4565
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4654
4566
  "input",
4655
4567
  {
4656
4568
  checked: autoMove,
@@ -4659,20 +4571,20 @@ var BridgeMocker = ({
4659
4571
  type: "checkbox"
4660
4572
  }
4661
4573
  ),
4662
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "text-slate-200 font-bold", children: [
4574
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "text-slate-200 font-bold", children: [
4663
4575
  "Auto-Move ",
4664
4576
  simulationPath ? "(Path)" : "(Random)"
4665
4577
  ] })
4666
4578
  ] }),
4667
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2", children: [
4668
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[10px] text-slate-500", children: "Speed:" }),
4669
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4579
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", children: [
4580
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500", children: "Speed:" }),
4581
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4670
4582
  "select",
4671
4583
  {
4672
4584
  className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5 text-white focus:outline-none focus:border-blue-500 text-[10px]",
4673
4585
  onChange: (e) => setSpeedMultiplier(Number(e.target.value)),
4674
4586
  value: speedMultiplier,
4675
- children: [1, 2, 5, 10, 50, 100, 250].map((s) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("option", { value: s, children: [
4587
+ children: [1, 2, 5, 10, 50, 100, 250].map((s) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("option", { value: s, children: [
4676
4588
  s,
4677
4589
  "x"
4678
4590
  ] }, s))
@@ -4680,10 +4592,10 @@ var BridgeMocker = ({
4680
4592
  )
4681
4593
  ] })
4682
4594
  ] }),
4683
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
4684
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
4685
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lng" }),
4686
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4595
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
4596
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-1", children: [
4597
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lng" }),
4598
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4687
4599
  "input",
4688
4600
  {
4689
4601
  className: "bg-slate-800 border border-slate-700 rounded px-2 py-1 text-white focus:outline-none focus:border-blue-500",
@@ -4698,9 +4610,9 @@ var BridgeMocker = ({
4698
4610
  }
4699
4611
  )
4700
4612
  ] }),
4701
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
4702
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lat" }),
4703
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4613
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-1", children: [
4614
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lat" }),
4615
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4704
4616
  "input",
4705
4617
  {
4706
4618
  className: "bg-slate-800 border border-slate-700 rounded px-2 py-1 text-white focus:outline-none focus:border-blue-500",
@@ -4715,9 +4627,9 @@ var BridgeMocker = ({
4715
4627
  }
4716
4628
  )
4717
4629
  ] }),
4718
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1 col-span-2", children: [
4719
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[10px] text-slate-500", children: "Heading (Degrees)" }),
4720
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4630
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-1 col-span-2", children: [
4631
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500", children: "Heading (Degrees)" }),
4632
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4721
4633
  "input",
4722
4634
  {
4723
4635
  className: "w-full accent-blue-500",
@@ -4731,13 +4643,13 @@ var BridgeMocker = ({
4731
4643
  value: heading
4732
4644
  }
4733
4645
  ),
4734
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "text-right text-slate-400", children: [
4646
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "text-right text-slate-400", children: [
4735
4647
  heading,
4736
4648
  "\xB0"
4737
4649
  ] })
4738
4650
  ] })
4739
4651
  ] }),
4740
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4652
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4741
4653
  Button,
4742
4654
  {
4743
4655
  className: `w-full rounded px-2 py-1.5 text-[10px] font-bold border cursor-pointer ${isPlacingLocation ? "bg-blue-500/20 border-blue-500 text-blue-300" : "bg-slate-800 border-slate-700 text-slate-200 hover:bg-slate-700"}`,
@@ -4747,11 +4659,11 @@ var BridgeMocker = ({
4747
4659
  children: isPlacingLocation ? "\u{1F4CD} Click the map to drop location\u2026" : "\u{1F4CD} Drop location on map"
4748
4660
  }
4749
4661
  ),
4750
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1 border-t border-slate-800 pt-3", children: [
4751
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex justify-between items-center", children: [
4752
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-[10px] text-slate-500", children: "Scan Radius" }),
4753
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-1", children: [
4754
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4662
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-1 border-t border-slate-800 pt-3", children: [
4663
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex justify-between items-center", children: [
4664
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500", children: "Scan Radius" }),
4665
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-1", children: [
4666
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4755
4667
  "input",
4756
4668
  {
4757
4669
  className: "w-16 bg-slate-800 border border-slate-700 rounded px-1.5 py-0.5 text-white text-[10px] focus:outline-none focus:border-blue-500",
@@ -4761,21 +4673,21 @@ var BridgeMocker = ({
4761
4673
  value: radiusMeters
4762
4674
  }
4763
4675
  ),
4764
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
4676
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4765
4677
  "select",
4766
4678
  {
4767
4679
  className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5 text-white text-[10px] focus:outline-none focus:border-blue-500",
4768
4680
  onChange: (e) => setRadiusUnit(e.target.value),
4769
4681
  value: radiusUnit,
4770
4682
  children: [
4771
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "m", children: "m" }),
4772
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "km", children: "km" })
4683
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "m", children: "m" }),
4684
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "km", children: "km" })
4773
4685
  ]
4774
4686
  }
4775
4687
  )
4776
4688
  ] })
4777
4689
  ] }),
4778
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4690
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4779
4691
  "input",
4780
4692
  {
4781
4693
  className: "w-full accent-blue-500",
@@ -4787,7 +4699,7 @@ var BridgeMocker = ({
4787
4699
  value: radiusMeters
4788
4700
  }
4789
4701
  ),
4790
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "text-right text-slate-400", children: radiusMeters === 0 ? "hidden" : `${radiusMeters}${radiusUnit} radius around user` })
4702
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "text-right text-slate-400", children: radiusMeters === 0 ? "hidden" : `${radiusMeters}${radiusUnit} radius around user` })
4791
4703
  ] })
4792
4704
  ] })
4793
4705
  ]
@@ -4797,20 +4709,20 @@ var BridgeMocker = ({
4797
4709
  };
4798
4710
 
4799
4711
  // src/components/DebugConsole.tsx
4800
- var import_react15 = require("react");
4801
- var import_jsx_runtime17 = require("react/jsx-runtime");
4712
+ var import_react17 = require("react");
4713
+ var import_jsx_runtime18 = require("react/jsx-runtime");
4802
4714
  var DebugConsole = ({
4803
4715
  isOpen: initialOpen = false,
4804
4716
  onClose
4805
4717
  }) => {
4806
- const [showConsole, setShowConsole] = (0, import_react15.useState)(initialOpen);
4807
- const [logs, setLogs] = (0, import_react15.useState)([]);
4808
- const scrollRef = (0, import_react15.useRef)(null);
4809
- (0, import_react15.useEffect)(() => {
4718
+ const [showConsole, setShowConsole] = (0, import_react17.useState)(initialOpen);
4719
+ const [logs, setLogs] = (0, import_react17.useState)([]);
4720
+ const scrollRef = (0, import_react17.useRef)(null);
4721
+ (0, import_react17.useEffect)(() => {
4810
4722
  setShowConsole(initialOpen);
4811
4723
  }, [initialOpen]);
4812
4724
  const clearLogs = () => setLogs([]);
4813
- const addLog = (0, import_react15.useCallback)((label, data) => {
4725
+ const addLog = (0, import_react17.useCallback)((label, data) => {
4814
4726
  if (label.includes("LOCATION_STREAM_UPDATE" /* LOCATION_STREAM_UPDATE */)) return;
4815
4727
  const entry = {
4816
4728
  content: typeof data === "string" ? data : JSON.stringify(data, null, 2),
@@ -4820,7 +4732,7 @@ var DebugConsole = ({
4820
4732
  };
4821
4733
  setLogs((prev) => [entry, ...prev].slice(0, 100));
4822
4734
  }, []);
4823
- (0, import_react15.useEffect)(() => {
4735
+ (0, import_react17.useEffect)(() => {
4824
4736
  if (typeof window === "undefined") return;
4825
4737
  const bridge = sdk.bridge;
4826
4738
  const originalSend = bridge.send.bind(bridge);
@@ -4842,7 +4754,7 @@ var DebugConsole = ({
4842
4754
  };
4843
4755
  }, [addLog]);
4844
4756
  if (!showConsole) {
4845
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4757
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4846
4758
  Button,
4847
4759
  {
4848
4760
  className: "fixed bottom-4 left-4 w-8 h-8 rounded-full bg-slate-900/60 backdrop-blur-sm border border-slate-700/50 flex items-center justify-center text-slate-400 hover:text-emerald-400 hover:bg-slate-900/80 transition-all z-[9998] shadow-lg group p-0!",
@@ -4850,7 +4762,7 @@ var DebugConsole = ({
4850
4762
  title: "Open Debug Console",
4851
4763
  type: "button",
4852
4764
  variant: "ghost",
4853
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4765
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4854
4766
  "svg",
4855
4767
  {
4856
4768
  className: "group-hover:scale-110 transition-transform",
@@ -4864,31 +4776,31 @@ var DebugConsole = ({
4864
4776
  width: "14",
4865
4777
  xmlns: "http://www.w3.org/2000/svg",
4866
4778
  children: [
4867
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "m8 2 1.88 1.88" }),
4868
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M14.12 3.88 16 2" }),
4869
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" }),
4870
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6" }),
4871
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M12 20v-9" }),
4872
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5" }),
4873
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M6 13H2" }),
4874
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4" }),
4875
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4" }),
4876
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M22 13h-4" }),
4877
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4" })
4779
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "m8 2 1.88 1.88" }),
4780
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M14.12 3.88 16 2" }),
4781
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" }),
4782
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6" }),
4783
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M12 20v-9" }),
4784
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5" }),
4785
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M6 13H2" }),
4786
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4" }),
4787
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4" }),
4788
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M22 13h-4" }),
4789
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4" })
4878
4790
  ]
4879
4791
  }
4880
4792
  )
4881
4793
  }
4882
4794
  );
4883
4795
  }
4884
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "fixed inset-x-0 bottom-0 w-full bg-[#0a080f] border-t border-slate-800 z-[9998] p-4 shadow-2xl flex flex-col animate-in slide-in-from-bottom duration-300", children: [
4885
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
4886
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-slate-400 flex items-center gap-2", children: [
4887
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
4796
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fixed inset-x-0 bottom-0 w-full bg-[#0a080f] border-t border-slate-800 z-[9998] p-4 shadow-2xl flex flex-col animate-in slide-in-from-bottom duration-300", children: [
4797
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
4798
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-slate-400 flex items-center gap-2", children: [
4799
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
4888
4800
  "UP SDK Debug Console"
4889
4801
  ] }),
4890
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex gap-4", children: [
4891
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4802
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex gap-4", children: [
4803
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4892
4804
  Button,
4893
4805
  {
4894
4806
  className: "text-[10px] text-slate-500 font-bold uppercase hover:text-slate-300 hover:bg-transparent transition-colors p-0 h-auto cursor-pointer",
@@ -4898,7 +4810,7 @@ var DebugConsole = ({
4898
4810
  children: "Clear"
4899
4811
  }
4900
4812
  ),
4901
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4813
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4902
4814
  Button,
4903
4815
  {
4904
4816
  className: "text-[10px] text-pink-500 font-bold uppercase hover:text-pink-400 hover:bg-transparent transition-colors p-0 h-auto cursor-pointer",
@@ -4913,21 +4825,21 @@ var DebugConsole = ({
4913
4825
  )
4914
4826
  ] })
4915
4827
  ] }),
4916
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4828
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4917
4829
  "div",
4918
4830
  {
4919
4831
  className: "bg-black/80 rounded-xl p-3 font-mono text-[10px] text-emerald-400 min-h-[120px] max-h-[240px] overflow-y-auto border border-slate-900 custom-scrollbar",
4920
4832
  ref: scrollRef,
4921
- children: logs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "text-slate-600 italic text-center py-8", children: "No logs yet. Interacting with the SDK will show events here." }) : logs.map((log) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4833
+ children: logs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "text-slate-600 italic text-center py-8", children: "No logs yet. Interacting with the SDK will show events here." }) : logs.map((log) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4922
4834
  "div",
4923
4835
  {
4924
4836
  className: "mb-3 pb-3 border-b border-slate-900/50 last:border-0 last:mb-0 last:pb-0",
4925
4837
  children: [
4926
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex gap-2 text-slate-500 mb-1 items-center", children: [
4927
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[8px]", children: log.time }),
4928
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "font-bold text-white uppercase text-[8px] bg-slate-800 px-1.5 py-0.5 rounded leading-none", children: log.label })
4838
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex gap-2 text-slate-500 mb-1 items-center", children: [
4839
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-[8px]", children: log.time }),
4840
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "font-bold text-white uppercase text-[8px] bg-slate-800 px-1.5 py-0.5 rounded leading-none", children: log.label })
4929
4841
  ] }),
4930
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("pre", { className: "whitespace-pre-wrap break-all opacity-90", children: log.content })
4842
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("pre", { className: "whitespace-pre-wrap break-all opacity-90", children: log.content })
4931
4843
  ]
4932
4844
  },
4933
4845
  log.id
@@ -4938,8 +4850,8 @@ var DebugConsole = ({
4938
4850
  };
4939
4851
 
4940
4852
  // src/components/PullToRefresh.tsx
4941
- var import_react16 = require("react");
4942
- var import_jsx_runtime18 = require("react/jsx-runtime");
4853
+ var import_react18 = require("react");
4854
+ var import_jsx_runtime19 = require("react/jsx-runtime");
4943
4855
  var DEFAULT_PULL_THRESHOLD = 64;
4944
4856
  var DEFAULT_MAX_PULL = 96;
4945
4857
  var RESISTANCE = 0.5;
@@ -4950,7 +4862,7 @@ function DefaultIndicator({
4950
4862
  progress,
4951
4863
  isRefreshing
4952
4864
  }) {
4953
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4865
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4954
4866
  "div",
4955
4867
  {
4956
4868
  style: {
@@ -4965,7 +4877,7 @@ function DefaultIndicator({
4965
4877
  width: 28
4966
4878
  },
4967
4879
  children: [
4968
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4880
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4969
4881
  "svg",
4970
4882
  {
4971
4883
  height: 14,
@@ -4977,8 +4889,8 @@ function DefaultIndicator({
4977
4889
  viewBox: "0 0 24 24",
4978
4890
  width: 14,
4979
4891
  children: [
4980
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("title", { children: "Refreshing" }),
4981
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4892
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("title", { children: "Refreshing" }),
4893
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4982
4894
  "path",
4983
4895
  {
4984
4896
  d: "M21 12a9 9 0 1 1-2.64-6.36",
@@ -4991,7 +4903,7 @@ function DefaultIndicator({
4991
4903
  ]
4992
4904
  }
4993
4905
  ),
4994
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("style", { children: "@keyframes up-sdk-ptr-spin { to { transform: rotate(360deg); } }" })
4906
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("style", { children: "@keyframes up-sdk-ptr-spin { to { transform: rotate(360deg); } }" })
4995
4907
  ]
4996
4908
  }
4997
4909
  );
@@ -5005,27 +4917,46 @@ var PullToRefresh = ({
5005
4917
  maxPull = DEFAULT_MAX_PULL,
5006
4918
  renderIndicator
5007
4919
  }) => {
5008
- const containerRef = (0, import_react16.useRef)(null);
5009
- const startYRef = (0, import_react16.useRef)(null);
5010
- const lastYRef = (0, import_react16.useRef)(0);
5011
- const lastMoveTimeRef = (0, import_react16.useRef)(0);
5012
- const velocityRef = (0, import_react16.useRef)(0);
5013
- const pointerIdRef = (0, import_react16.useRef)(null);
5014
- const isPullingRef = (0, import_react16.useRef)(false);
5015
- const pullDistanceRef = (0, import_react16.useRef)(0);
5016
- const flingRafRef = (0, import_react16.useRef)(null);
5017
- const [pullDistance, setPullDistance] = (0, import_react16.useState)(0);
5018
- const [isRefreshing, setIsRefreshing] = (0, import_react16.useState)(false);
5019
- const [isTracking, setIsTracking] = (0, import_react16.useState)(false);
5020
- const disabledRef = (0, import_react16.useRef)(disabled);
4920
+ const containerRef = (0, import_react18.useRef)(null);
4921
+ const startYRef = (0, import_react18.useRef)(null);
4922
+ const lastYRef = (0, import_react18.useRef)(0);
4923
+ const lastMoveTimeRef = (0, import_react18.useRef)(0);
4924
+ const velocityRef = (0, import_react18.useRef)(0);
4925
+ const pointerIdRef = (0, import_react18.useRef)(null);
4926
+ const isPullingRef = (0, import_react18.useRef)(false);
4927
+ const pullDistanceRef = (0, import_react18.useRef)(0);
4928
+ const flingRafRef = (0, import_react18.useRef)(null);
4929
+ const [pullDistance, setPullDistance] = (0, import_react18.useState)(0);
4930
+ const [isRefreshing, setIsRefreshing] = (0, import_react18.useState)(false);
4931
+ const [isTracking, setIsTracking] = (0, import_react18.useState)(false);
4932
+ const disabledRef = (0, import_react18.useRef)(disabled);
5021
4933
  disabledRef.current = disabled;
5022
- const onRefreshRef = (0, import_react16.useRef)(onRefresh);
4934
+ const onRefreshRef = (0, import_react18.useRef)(onRefresh);
5023
4935
  onRefreshRef.current = onRefresh;
5024
- const pullThresholdRef = (0, import_react16.useRef)(pullThreshold);
4936
+ const pullThresholdRef = (0, import_react18.useRef)(pullThreshold);
5025
4937
  pullThresholdRef.current = pullThreshold;
5026
- const maxPullRef = (0, import_react16.useRef)(maxPull);
4938
+ const maxPullRef = (0, import_react18.useRef)(maxPull);
5027
4939
  maxPullRef.current = maxPull;
5028
- (0, import_react16.useEffect)(() => {
4940
+ (0, import_react18.useEffect)(() => {
4941
+ const el = containerRef.current;
4942
+ if (!el || typeof window === "undefined") return;
4943
+ const checkScrollChain = () => {
4944
+ const noInternalOverflow = el.scrollHeight <= el.clientHeight;
4945
+ const tallerThanViewport = el.clientHeight > window.innerHeight;
4946
+ if (noInternalOverflow && tallerThanViewport) {
4947
+ console.warn(
4948
+ "[PullToRefresh] This container is taller than the viewport but has no internal scroll (scrollHeight <= clientHeight). Because this component disables native touch scrolling entirely (touch-action: none), scrolling is now completely broken here. This almost always means either: (1) an ancestor's flex-1 item is missing `min-h-0` (a flex item defaults to min-height:auto and refuses to shrink below its content size), or (2) an ancestor uses `min-h-screen`/`min-h-full` (a floor, not a ceiling) instead of `h-full`/`h-screen`/`h-dvh`. See the vault skill js/pull-to-refresh-scroll-chain.md for the fix pattern."
4949
+ );
4950
+ }
4951
+ };
4952
+ const raf = requestAnimationFrame(checkScrollChain);
4953
+ window.addEventListener("resize", checkScrollChain);
4954
+ return () => {
4955
+ cancelAnimationFrame(raf);
4956
+ window.removeEventListener("resize", checkScrollChain);
4957
+ };
4958
+ }, []);
4959
+ (0, import_react18.useEffect)(() => {
5029
4960
  const el = containerRef.current;
5030
4961
  if (!el) return;
5031
4962
  const updatePullDistance = (value) => {
@@ -5156,7 +5087,7 @@ var PullToRefresh = ({
5156
5087
  const indicatorHeight = isRefreshing ? pullThreshold : pullDistance;
5157
5088
  const progress = Math.min(indicatorHeight / pullThreshold, 1);
5158
5089
  const isSettling = pullDistance === 0 && !isRefreshing && !isTracking;
5159
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
5090
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
5160
5091
  "div",
5161
5092
  {
5162
5093
  className: `up-sdk-pull-to-refresh ${className}`,
@@ -5167,8 +5098,8 @@ var PullToRefresh = ({
5167
5098
  touchAction: "none"
5168
5099
  },
5169
5100
  children: [
5170
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("style", { children: ".up-sdk-pull-to-refresh::-webkit-scrollbar { display: none; } .up-sdk-pull-to-refresh { scrollbar-width: none; -ms-overflow-style: none; }" }),
5171
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5101
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("style", { children: ".up-sdk-pull-to-refresh::-webkit-scrollbar { display: none; } .up-sdk-pull-to-refresh { scrollbar-width: none; -ms-overflow-style: none; }" }),
5102
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5172
5103
  "div",
5173
5104
  {
5174
5105
  style: {
@@ -5181,7 +5112,7 @@ var PullToRefresh = ({
5181
5112
  userSelect: "none",
5182
5113
  width: "100%"
5183
5114
  },
5184
- children: renderIndicator ? renderIndicator({ isRefreshing, progress }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DefaultIndicator, { isRefreshing, progress })
5115
+ children: renderIndicator ? renderIndicator({ isRefreshing, progress }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DefaultIndicator, { isRefreshing, progress })
5185
5116
  }
5186
5117
  ),
5187
5118
  children
@@ -5192,16 +5123,16 @@ var PullToRefresh = ({
5192
5123
 
5193
5124
  // src/components/QRScanner.tsx
5194
5125
  var import_jsqr2 = __toESM(require("jsqr"), 1);
5195
- var import_react17 = require("react");
5196
- var import_jsx_runtime19 = require("react/jsx-runtime");
5126
+ var import_react19 = require("react");
5127
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5197
5128
  function QRScanner({ onScan, onError, className = "" }) {
5198
- const videoRef = (0, import_react17.useRef)(null);
5199
- const canvasRef = (0, import_react17.useRef)(null);
5200
- const streamRef = (0, import_react17.useRef)(null);
5201
- const tickRequestRef = (0, import_react17.useRef)(null);
5202
- const hasScannedRef = (0, import_react17.useRef)(false);
5203
- const [isReady, setIsReady] = (0, import_react17.useState)(false);
5204
- (0, import_react17.useEffect)(() => {
5129
+ const videoRef = (0, import_react19.useRef)(null);
5130
+ const canvasRef = (0, import_react19.useRef)(null);
5131
+ const streamRef = (0, import_react19.useRef)(null);
5132
+ const tickRequestRef = (0, import_react19.useRef)(null);
5133
+ const hasScannedRef = (0, import_react19.useRef)(false);
5134
+ const [isReady, setIsReady] = (0, import_react19.useState)(false);
5135
+ (0, import_react19.useEffect)(() => {
5205
5136
  let cancelled = false;
5206
5137
  hasScannedRef.current = false;
5207
5138
  const cleanup = () => {
@@ -5284,7 +5215,7 @@ function QRScanner({ onScan, onError, className = "" }) {
5284
5215
  cleanup();
5285
5216
  };
5286
5217
  }, []);
5287
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
5218
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5288
5219
  "div",
5289
5220
  {
5290
5221
  className,
@@ -5296,7 +5227,7 @@ function QRScanner({ onScan, onError, className = "" }) {
5296
5227
  position: "relative"
5297
5228
  },
5298
5229
  children: [
5299
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5230
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5300
5231
  "video",
5301
5232
  {
5302
5233
  playsInline: true,
@@ -5304,8 +5235,8 @@ function QRScanner({ onScan, onError, className = "" }) {
5304
5235
  style: { height: "100%", objectFit: "cover", width: "100%" }
5305
5236
  }
5306
5237
  ),
5307
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
5308
- isReady && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5238
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
5239
+ isReady && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5309
5240
  "div",
5310
5241
  {
5311
5242
  style: {
@@ -5326,30 +5257,30 @@ function QRScanner({ onScan, onError, className = "" }) {
5326
5257
  }
5327
5258
 
5328
5259
  // src/components/SDKProvider.tsx
5329
- var import_react18 = require("react");
5330
- var import_jsx_runtime20 = require("react/jsx-runtime");
5331
- var SDKContext = (0, import_react18.createContext)({ isMocked: false });
5332
- var useIsMocked = () => (0, import_react18.useContext)(SDKContext).isMocked;
5260
+ var import_react20 = require("react");
5261
+ var import_jsx_runtime21 = require("react/jsx-runtime");
5262
+ var SDKContext = (0, import_react20.createContext)({ isMocked: false });
5263
+ var useIsMocked = () => (0, import_react20.useContext)(SDKContext).isMocked;
5333
5264
  var SDKProvider = ({
5334
5265
  children,
5335
5266
  debug = false,
5336
5267
  ...mockerProps
5337
5268
  }) => {
5338
5269
  const isMocked = typeof window !== "undefined" && !(window.__UP_REACT_NATIVE_APP__ === true || !!window.ReactNativeWebView);
5339
- const value = (0, import_react18.useMemo)(() => ({ isMocked }), [isMocked]);
5340
- const content = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
5270
+ const value = (0, import_react20.useMemo)(() => ({ isMocked }), [isMocked]);
5271
+ const content = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5341
5272
  children,
5342
- (debug || isMocked) && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DebugConsole, {})
5273
+ (debug || isMocked) && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DebugConsole, {})
5343
5274
  ] });
5344
5275
  if (isMocked) {
5345
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SDKContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BridgeMocker, { ...mockerProps, children: content }) });
5276
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SDKContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BridgeMocker, { ...mockerProps, children: content }) });
5346
5277
  }
5347
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SDKContext.Provider, { value, children: content });
5278
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SDKContext.Provider, { value, children: content });
5348
5279
  };
5349
5280
 
5350
5281
  // src/components/SwipeCarousel.tsx
5351
- var import_react19 = require("react");
5352
- var import_jsx_runtime21 = require("react/jsx-runtime");
5282
+ var import_react21 = require("react");
5283
+ var import_jsx_runtime22 = require("react/jsx-runtime");
5353
5284
  var DIRECTION_LOCK_THRESHOLD_PX = 8;
5354
5285
  var SWIPE_DISTANCE_THRESHOLD_PX = 40;
5355
5286
  var SWIPE_VELOCITY_THRESHOLD = 0.4;
@@ -5376,28 +5307,28 @@ var SwipeCarousel = ({
5376
5307
  overscan = DEFAULT_OVERSCAN,
5377
5308
  visibleOverscan = DEFAULT_VISIBLE_OVERSCAN
5378
5309
  }) => {
5379
- const containerRef = (0, import_react19.useRef)(null);
5380
- const [containerWidth, setContainerWidth] = (0, import_react19.useState)(0);
5381
- const [dragX, setDragX] = (0, import_react19.useState)(0);
5382
- const [dragY, setDragY] = (0, import_react19.useState)(0);
5383
- const [isDraggingX, setIsDraggingX] = (0, import_react19.useState)(false);
5384
- const [isDraggingY, setIsDraggingY] = (0, import_react19.useState)(false);
5385
- const touchStateRef = (0, import_react19.useRef)(null);
5386
- const [internalIndex, setInternalIndex] = (0, import_react19.useState)(
5310
+ const containerRef = (0, import_react21.useRef)(null);
5311
+ const [containerWidth, setContainerWidth] = (0, import_react21.useState)(0);
5312
+ const [dragX, setDragX] = (0, import_react21.useState)(0);
5313
+ const [dragY, setDragY] = (0, import_react21.useState)(0);
5314
+ const [isDraggingX, setIsDraggingX] = (0, import_react21.useState)(false);
5315
+ const [isDraggingY, setIsDraggingY] = (0, import_react21.useState)(false);
5316
+ const touchStateRef = (0, import_react21.useRef)(null);
5317
+ const [internalIndex, setInternalIndex] = (0, import_react21.useState)(
5387
5318
  () => Math.max(
5388
5319
  0,
5389
5320
  items.findIndex((item) => item.id === activeId)
5390
5321
  )
5391
5322
  );
5392
- const prevActiveIdRef = (0, import_react19.useRef)(activeId);
5393
- const [timingWaiting, setTimingWaiting] = (0, import_react19.useState)(true);
5394
- (0, import_react19.useEffect)(() => {
5323
+ const prevActiveIdRef = (0, import_react21.useRef)(activeId);
5324
+ const [timingWaiting, setTimingWaiting] = (0, import_react21.useState)(true);
5325
+ (0, import_react21.useEffect)(() => {
5395
5326
  const timer = setTimeout(() => {
5396
5327
  setTimingWaiting(false);
5397
5328
  }, 1e3);
5398
5329
  return () => clearTimeout(timer);
5399
5330
  }, []);
5400
- (0, import_react19.useEffect)(() => {
5331
+ (0, import_react21.useEffect)(() => {
5401
5332
  if (activeId !== prevActiveIdRef.current) {
5402
5333
  const idx = items.findIndex((item) => item.id === activeId);
5403
5334
  if (idx !== -1) setInternalIndex(idx);
@@ -5408,7 +5339,7 @@ var SwipeCarousel = ({
5408
5339
  Math.max(internalIndex, 0),
5409
5340
  Math.max(items.length - 1, 0)
5410
5341
  );
5411
- (0, import_react19.useLayoutEffect)(() => {
5342
+ (0, import_react21.useLayoutEffect)(() => {
5412
5343
  const el = containerRef.current;
5413
5344
  if (!el) return;
5414
5345
  const update = () => setContainerWidth(el.clientWidth);
@@ -5526,7 +5457,7 @@ var SwipeCarousel = ({
5526
5457
  };
5527
5458
  const windowStart = Math.max(0, activeIndex - overscan);
5528
5459
  const windowEnd = Math.min(items.length - 1, activeIndex + overscan);
5529
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5460
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5530
5461
  "div",
5531
5462
  {
5532
5463
  className: `relative overflow-hidden touch-pan-y ${className ?? ""}`,
@@ -5535,7 +5466,7 @@ var SwipeCarousel = ({
5535
5466
  onTouchMove: handleTouchMove,
5536
5467
  onTouchStart: handleTouchStart,
5537
5468
  ref: containerRef,
5538
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5469
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5539
5470
  "div",
5540
5471
  {
5541
5472
  className: "relative h-full",
@@ -5550,7 +5481,7 @@ var SwipeCarousel = ({
5550
5481
  const verticalOffset = isActive ? dragY : 0;
5551
5482
  const distance = Math.abs(index - activeIndex);
5552
5483
  const isVisible = distance <= visibleOverscan;
5553
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5484
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5554
5485
  "div",
5555
5486
  {
5556
5487
  className: `absolute top-0 left-0 h-full shrink-0 ${itemClassName ?? ""} ${item.className ?? ""}`,
@@ -5578,6 +5509,40 @@ var SwipeCarousel = ({
5578
5509
  );
5579
5510
  };
5580
5511
 
5512
+ // src/hooks/useTapAction.ts
5513
+ var import_react22 = require("react");
5514
+ var TAP_MOVE_TOLERANCE_PX = 10;
5515
+ var CLICK_SUPPRESS_WINDOW_MS = 500;
5516
+ var useTapAction = (action) => {
5517
+ const startRef = (0, import_react22.useRef)(null);
5518
+ const handledByTouchRef = (0, import_react22.useRef)(false);
5519
+ const onTouchStart = (e) => {
5520
+ const touch = e.targetTouches[0];
5521
+ startRef.current = touch ? { x: touch.clientX, y: touch.clientY } : null;
5522
+ };
5523
+ const onTouchEnd = (e) => {
5524
+ const start = startRef.current;
5525
+ const touch = e.changedTouches[0];
5526
+ startRef.current = null;
5527
+ if (!start || !touch) return;
5528
+ const moved = Math.hypot(touch.clientX - start.x, touch.clientY - start.y);
5529
+ if (moved > TAP_MOVE_TOLERANCE_PX) return;
5530
+ handledByTouchRef.current = true;
5531
+ setTimeout(() => {
5532
+ handledByTouchRef.current = false;
5533
+ }, CLICK_SUPPRESS_WINDOW_MS);
5534
+ action();
5535
+ };
5536
+ const onClick = () => {
5537
+ if (handledByTouchRef.current) {
5538
+ handledByTouchRef.current = false;
5539
+ return;
5540
+ }
5541
+ action();
5542
+ };
5543
+ return { onClick, onTouchEnd, onTouchStart };
5544
+ };
5545
+
5581
5546
  // src/host/routingHandler.ts
5582
5547
  async function handleRouteRequest(req, config) {
5583
5548
  return RoutingService.fetchRoute(req, config);
@@ -5911,6 +5876,7 @@ var src_default = sdk;
5911
5876
  useMapControls,
5912
5877
  useMockLocation,
5913
5878
  useRoute,
5879
+ useTapAction,
5914
5880
  useTrimmedRoute,
5915
5881
  useUserLocation
5916
5882
  });