@cloudparse/up-miniapps-sdk 0.6.8 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,58 @@ function isRunningInsideNativeShell() {
137
138
  // src/bridge.ts
138
139
  var BridgeTimeoutError = class extends Error {
139
140
  };
141
+ var MOCK_ACHIEVEMENTS = [
142
+ {
143
+ completed: false,
144
+ description: "Discover 5 points of interest around Annecy.",
145
+ imageUrl: "https://api.dicebear.com/9.x/icons/svg?seed=explore",
146
+ playerActionCount: 3,
147
+ slug: "explore-5-pois",
148
+ title: "Explorer",
149
+ totalActionCount: 5,
150
+ upReward: 50,
151
+ xpReward: 100
152
+ },
153
+ {
154
+ completed: true,
155
+ description: "Complete your first navigation journey.",
156
+ imageUrl: "https://api.dicebear.com/9.x/icons/svg?seed=journey",
157
+ playerActionCount: 1,
158
+ slug: "first-journey",
159
+ title: "First Steps",
160
+ totalActionCount: 1,
161
+ upReward: 20,
162
+ xpReward: 40
163
+ },
164
+ {
165
+ completed: false,
166
+ description: "Scan 10 QR codes at partner venues.",
167
+ imageUrl: "https://api.dicebear.com/9.x/icons/svg?seed=scan",
168
+ playerActionCount: 4,
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
+ slug: slug || "unknown-achievement",
184
+ title: slug || "Unknown Achievement",
185
+ totalActionCount: 1,
186
+ upReward: 0,
187
+ xpReward: 0
188
+ };
189
+ }
190
+ function mockAchievements() {
191
+ return MOCK_ACHIEVEMENTS;
192
+ }
140
193
  var Bridge = class {
141
194
  callbacks = /* @__PURE__ */ new Map();
142
195
  eventListeners = /* @__PURE__ */ new Map();
@@ -287,6 +340,12 @@ var Bridge = class {
287
340
  return this.mockSaveImage(
288
341
  payload
289
342
  );
343
+ case "GET_ACHIEVEMENT":
344
+ return Promise.resolve(
345
+ mockAchievement(payload?.slug)
346
+ );
347
+ case "GET_ACHIEVEMENTS":
348
+ return Promise.resolve(mockAchievements());
290
349
  default:
291
350
  console.warn(
292
351
  `[Bridge] Mock mode active: Unhandled message type ${type}`
@@ -475,412 +534,27 @@ SheetDescription.displayName = SheetPrimitive.Description.displayName;
475
534
  // src/components/Map/components/MapDrawer.tsx
476
535
  var import_react2 = require("react");
477
536
  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
537
  var MapDrawer = (0, import_react2.forwardRef)(
491
538
  ({
492
539
  menuItems,
493
540
  state,
494
541
  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
542
  menuContent,
509
- enableTouchDrag = false,
510
- handleVisible = true,
511
- onAutoContentHeightChange,
512
543
  showScrollToTopButton = true,
513
- scrollToTopThreshold = 300,
514
- safeAreaInsets = { bottom: 0, left: 0, right: 0, top: 0 }
544
+ scrollToTopThreshold = 300
515
545
  }, ref) => {
516
546
  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
547
  (0, import_react2.useImperativeHandle)(
521
548
  ref,
522
549
  () => scrollContainerRef.current
523
550
  );
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
551
  const [showScrollTop, setShowScrollTop] = (0, import_react2.useState)(false);
563
552
  const handleScroll = (e) => {
564
553
  const scrollTop = e.currentTarget.scrollTop;
565
554
  setShowScrollTop(state !== "closed" && scrollTop > scrollToTopThreshold);
566
555
  };
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";
556
+ const isBackdropActive = state !== "closed";
859
557
  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
558
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
885
559
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
886
560
  .no-scrollbar {
@@ -898,233 +572,113 @@ var MapDrawer = (0, import_react2.forwardRef)(
898
572
  onClick: () => onChangeState("closed")
899
573
  }
900
574
  ),
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)(
575
+ state === "closed" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
576
+ Button,
577
+ {
578
+ 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!",
579
+ onClick: () => onChangeState("full"),
580
+ variant: "ghost",
581
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
582
+ "svg",
583
+ {
584
+ fill: "none",
585
+ height: "24",
586
+ stroke: "currentColor",
587
+ strokeLinecap: "round",
588
+ strokeLinejoin: "round",
589
+ strokeWidth: "2",
590
+ viewBox: "0 0 24 24",
591
+ width: "24",
592
+ xmlns: "http://www.w3.org/2000/svg",
593
+ children: [
594
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "12", y2: "12" }),
595
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "6", y2: "6" }),
596
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "4", x2: "20", y1: "18", y2: "18" })
597
+ ]
598
+ }
599
+ )
600
+ }
601
+ ),
602
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
603
+ Sheet,
604
+ {
605
+ onOpenChange: (open) => onChangeState(open ? "full" : "closed"),
606
+ open: state !== "closed",
607
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
608
+ SheetContent,
609
+ {
610
+ 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",
611
+ portal: false,
612
+ side: "left",
613
+ children: [
614
+ /* @__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" }) }),
615
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
616
+ "div",
617
+ {
618
+ className: "flex-1 overflow-y-auto no-scrollbar pr-2",
619
+ onScroll: handleScroll,
620
+ ref: scrollContainerRef,
621
+ 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
622
  Button,
1089
623
  {
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!",
624
+ 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" : ""}`,
625
+ disabled: item.disabled,
1091
626
  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))`
627
+ if (!item.disabled) {
628
+ item.onPress();
629
+ onChangeState("closed");
630
+ }
1099
631
  },
1100
632
  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
- )
633
+ children: [
634
+ /* @__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: [
635
+ item.icon,
636
+ 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 })
637
+ ] }),
638
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: item.label })
639
+ ]
640
+ },
641
+ item.id
642
+ )) })
643
+ }
644
+ ),
645
+ showScrollToTopButton && showScrollTop && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
646
+ Button,
647
+ {
648
+ 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!",
649
+ onClick: () => {
650
+ scrollContainerRef.current?.scrollTo({
651
+ behavior: "smooth",
652
+ top: 0
653
+ });
654
+ },
655
+ variant: "ghost",
656
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
657
+ "svg",
658
+ {
659
+ fill: "none",
660
+ height: "20",
661
+ stroke: "currentColor",
662
+ strokeLinecap: "round",
663
+ strokeLinejoin: "round",
664
+ strokeWidth: "2.5",
665
+ viewBox: "0 0 24 24",
666
+ width: "20",
667
+ xmlns: "http://www.w3.org/2000/svg",
668
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "18 15 12 9 6 15" })
1116
669
  }
1117
670
  )
1118
- ]
1119
- }
1120
- )
1121
- ]
1122
- }
1123
- )
671
+ }
672
+ )
673
+ ]
674
+ }
675
+ )
676
+ }
1124
677
  )
1125
678
  ] });
1126
679
  }
1127
680
  );
681
+ MapDrawer.displayName = "MapDrawer";
1128
682
 
1129
683
  // src/components/ui/card.tsx
1130
684
  var React3 = __toESM(require("react"), 1);
@@ -1575,33 +1129,333 @@ var MapRightControls = ({
1575
1129
  );
1576
1130
  };
1577
1131
 
1578
- // src/components/Map/MapContext.tsx
1579
- var import_react3 = require("react");
1132
+ // src/components/Map/components/MobileBottomDrawer.tsx
1133
+ var import_react3 = require("motion/react");
1134
+ var import_react4 = require("react");
1135
+ var import_react_modal_sheet = require("react-modal-sheet");
1580
1136
  var import_jsx_runtime7 = require("react/jsx-runtime");
1581
- var MapControlsContext = (0, import_react3.createContext)(
1137
+ var resolveHeightToPixels = (height, containerHeight) => {
1138
+ if (typeof height === "number") {
1139
+ return height;
1140
+ }
1141
+ if (height.endsWith("%")) {
1142
+ return parseFloat(height) / 100 * containerHeight;
1143
+ }
1144
+ return parseFloat(height);
1145
+ };
1146
+ var HANDLE_HEIGHT_PX = 32;
1147
+ var SHEET_TWEEN_CONFIG = {
1148
+ duration: 0.4,
1149
+ ease: [0.32, 0.72, 0, 1]
1150
+ };
1151
+ var SHEET_DRAG_VELOCITY_THRESHOLD = 1700;
1152
+ var MobileBottomDrawer = (0, import_react4.forwardRef)(
1153
+ ({
1154
+ menuItems,
1155
+ state,
1156
+ onChangeState,
1157
+ drawerPeekHeight,
1158
+ drawerFullHeight,
1159
+ drawerAutoMaxHeight,
1160
+ containerHeight,
1161
+ menuContent,
1162
+ enableTouchDrag = true,
1163
+ handleVisible = true,
1164
+ onAutoContentHeightChange,
1165
+ showScrollToTopButton = true,
1166
+ scrollToTopThreshold = 300,
1167
+ safeAreaInsets = { bottom: 0, left: 0, right: 0, top: 0 }
1168
+ }, ref) => {
1169
+ const scrollRef = (0, import_react4.useRef)(null);
1170
+ (0, import_react4.useImperativeHandle)(ref, () => scrollRef.current);
1171
+ const headerRef = (0, import_react4.useRef)(null);
1172
+ const contentWrapperRef = (0, import_react4.useRef)(null);
1173
+ const [viewportHeight, setViewportHeight] = (0, import_react4.useState)(
1174
+ () => containerHeight ?? (typeof window !== "undefined" ? window.innerHeight : 800)
1175
+ );
1176
+ (0, import_react4.useEffect)(() => {
1177
+ if (containerHeight) {
1178
+ setViewportHeight(containerHeight);
1179
+ return;
1180
+ }
1181
+ if (typeof window === "undefined") return;
1182
+ const update = () => setViewportHeight(window.innerHeight);
1183
+ update();
1184
+ window.addEventListener("resize", update);
1185
+ return () => window.removeEventListener("resize", update);
1186
+ }, [containerHeight]);
1187
+ const [autoContentPx, setAutoContentPx] = (0, import_react4.useState)(0);
1188
+ (0, import_react4.useEffect)(() => {
1189
+ const contentEl = contentWrapperRef.current;
1190
+ if (!contentEl) return;
1191
+ const measure = () => {
1192
+ const headerHeight = handleVisible ? headerRef.current?.offsetHeight ?? 0 : 0;
1193
+ const px = headerHeight + contentEl.scrollHeight;
1194
+ setAutoContentPx(px);
1195
+ onAutoContentHeightChange?.(px);
1196
+ };
1197
+ measure();
1198
+ const ro = new ResizeObserver(measure);
1199
+ ro.observe(contentEl);
1200
+ return () => ro.disconnect();
1201
+ }, [handleVisible, onAutoContentHeightChange]);
1202
+ const closedPx = (handleVisible ? HANDLE_HEIGHT_PX : 0) + safeAreaInsets.bottom;
1203
+ const peekPx = resolveHeightToPixels(
1204
+ drawerPeekHeight ?? "15%",
1205
+ viewportHeight
1206
+ );
1207
+ const autoMaxPx = resolveHeightToPixels(
1208
+ drawerAutoMaxHeight ?? "100%",
1209
+ viewportHeight
1210
+ );
1211
+ const autoPx = Math.min(autoMaxPx, Math.max(autoContentPx, closedPx + 1));
1212
+ const { snapPoints, snapLabels, backdropOutput } = (0, import_react4.useMemo)(() => {
1213
+ const normalize = (raw) => raw > 0 && raw <= 1 ? raw * viewportHeight : raw;
1214
+ const unsorted = [
1215
+ { label: "closed", raw: 0 },
1216
+ { label: "closed", raw: closedPx },
1217
+ { label: "peek", raw: peekPx },
1218
+ { label: "auto", raw: autoPx },
1219
+ { label: "full", raw: 1 }
1220
+ ];
1221
+ const entries = unsorted.sort(
1222
+ (a, b) => normalize(a.raw) - normalize(b.raw)
1223
+ );
1224
+ const deduped = [];
1225
+ for (const entry of entries) {
1226
+ const prev = deduped[deduped.length - 1];
1227
+ if (prev && Math.abs(normalize(prev.raw) - normalize(entry.raw)) < 0.5) {
1228
+ deduped[deduped.length - 1] = entry;
1229
+ continue;
1230
+ }
1231
+ deduped.push(entry);
1232
+ }
1233
+ return {
1234
+ backdropOutput: deduped.map(
1235
+ (d) => d.label === "full" || d.label === "auto" ? 1 : 0
1236
+ ),
1237
+ snapLabels: deduped.map((d) => d.label),
1238
+ snapPoints: deduped.map((d) => d.raw)
1239
+ };
1240
+ }, [closedPx, peekPx, autoPx, viewportHeight]);
1241
+ const currentIndex = Math.max(0, snapLabels.lastIndexOf(state));
1242
+ const sheetRef = (0, import_react4.useRef)(null);
1243
+ (0, import_react4.useEffect)(() => {
1244
+ let cancelled = false;
1245
+ let attempts = 0;
1246
+ const trySnap = () => {
1247
+ if (cancelled) return;
1248
+ const ref2 = sheetRef.current;
1249
+ if (ref2 && ref2.snapPoints.length > 0) {
1250
+ ref2.snapTo(currentIndex);
1251
+ return;
1252
+ }
1253
+ attempts += 1;
1254
+ if (attempts > 60) return;
1255
+ requestAnimationFrame(trySnap);
1256
+ };
1257
+ trySnap();
1258
+ return () => {
1259
+ cancelled = true;
1260
+ };
1261
+ }, [currentIndex]);
1262
+ const handleSnap = (0, import_react4.useCallback)(
1263
+ (index) => {
1264
+ const label = snapLabels[index] ?? "closed";
1265
+ if (label !== state) onChangeState(label);
1266
+ },
1267
+ [snapLabels, state, onChangeState]
1268
+ );
1269
+ const handleHandleClick = () => {
1270
+ if (state === "closed") {
1271
+ onChangeState("peek");
1272
+ } else if (state === "peek") {
1273
+ onChangeState("full");
1274
+ } else if (state === "auto") {
1275
+ onChangeState("closed");
1276
+ } else {
1277
+ onChangeState("peek");
1278
+ }
1279
+ };
1280
+ const [showScrollTop, setShowScrollTop] = (0, import_react4.useState)(false);
1281
+ (0, import_react4.useEffect)(() => {
1282
+ const el = scrollRef.current;
1283
+ if (!el) return;
1284
+ const onScroll = () => {
1285
+ setShowScrollTop(
1286
+ state !== "closed" && el.scrollTop > scrollToTopThreshold
1287
+ );
1288
+ };
1289
+ el.addEventListener("scroll", onScroll);
1290
+ return () => el.removeEventListener("scroll", onScroll);
1291
+ }, [state, scrollToTopThreshold]);
1292
+ (0, import_react4.useEffect)(() => {
1293
+ if (state === "closed") setShowScrollTop(false);
1294
+ }, [state]);
1295
+ const dragDisabled = !enableTouchDrag;
1296
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1297
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
1298
+ .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
1299
+ .no-scrollbar::-webkit-scrollbar { display: none; }
1300
+ ` }),
1301
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1302
+ import_react_modal_sheet.Sheet,
1303
+ {
1304
+ disableDismiss: true,
1305
+ disableDrag: dragDisabled,
1306
+ dragVelocityThreshold: SHEET_DRAG_VELOCITY_THRESHOLD,
1307
+ initialSnap: currentIndex,
1308
+ isOpen: true,
1309
+ onClose: () => onChangeState("closed"),
1310
+ onSnap: handleSnap,
1311
+ ref: sheetRef,
1312
+ snapPoints,
1313
+ tweenConfig: SHEET_TWEEN_CONFIG,
1314
+ children: [
1315
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1316
+ import_react_modal_sheet.Sheet.Container,
1317
+ {
1318
+ className: "!bg-zinc-950/85 !backdrop-blur-md !border !border-white/10 !border-b-0 !rounded-t-2xl !shadow-2xl ",
1319
+ style: { paddingBottom: safeAreaInsets.bottom },
1320
+ children: [
1321
+ handleVisible && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1322
+ import_react_modal_sheet.Sheet.Header,
1323
+ {
1324
+ className: "!bg-transparent cursor-pointer hover:!bg-white/5 transition-colors",
1325
+ onClick: handleHandleClick,
1326
+ ref: headerRef
1327
+ }
1328
+ ),
1329
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1330
+ import_react_modal_sheet.Sheet.Content,
1331
+ {
1332
+ className: "!bg-transparent",
1333
+ disableDrag: (info) => dragDisabled || info.scrollPosition === "middle",
1334
+ disableScroll: (info) => !dragDisabled && info.currentSnap !== snapPoints.length - 1,
1335
+ scrollClassName: "no-scrollbar",
1336
+ scrollRef,
1337
+ children: [
1338
+ /* @__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)(
1339
+ Button,
1340
+ {
1341
+ 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" : ""}`,
1342
+ disabled: item.disabled,
1343
+ onClick: () => {
1344
+ if (!item.disabled) {
1345
+ item.onPress();
1346
+ onChangeState("closed");
1347
+ }
1348
+ },
1349
+ variant: "ghost",
1350
+ children: [
1351
+ /* @__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: [
1352
+ item.icon,
1353
+ 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 })
1354
+ ] }),
1355
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm font-medium tracking-wide", children: item.label })
1356
+ ]
1357
+ },
1358
+ item.id
1359
+ )) }) }),
1360
+ showScrollToTopButton && showScrollTop && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1361
+ Button,
1362
+ {
1363
+ 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!",
1364
+ onClick: () => {
1365
+ scrollRef.current?.scrollTo({ behavior: "smooth", top: 0 });
1366
+ },
1367
+ variant: "ghost",
1368
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1369
+ "svg",
1370
+ {
1371
+ fill: "none",
1372
+ height: "20",
1373
+ stroke: "currentColor",
1374
+ strokeLinecap: "round",
1375
+ strokeLinejoin: "round",
1376
+ strokeWidth: "2.5",
1377
+ viewBox: "0 0 24 24",
1378
+ width: "20",
1379
+ xmlns: "http://www.w3.org/2000/svg",
1380
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("polyline", { points: "18 15 12 9 6 15" })
1381
+ }
1382
+ )
1383
+ }
1384
+ )
1385
+ ]
1386
+ }
1387
+ )
1388
+ ]
1389
+ }
1390
+ ),
1391
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1392
+ DrawerBackdrop,
1393
+ {
1394
+ active: state === "full" || state === "auto",
1395
+ onTap: () => onChangeState("closed"),
1396
+ output: backdropOutput
1397
+ }
1398
+ )
1399
+ ]
1400
+ }
1401
+ )
1402
+ ] });
1403
+ }
1404
+ );
1405
+ MobileBottomDrawer.displayName = "MobileBottomDrawer";
1406
+ function DrawerBackdrop({
1407
+ active,
1408
+ output,
1409
+ onTap
1410
+ }) {
1411
+ const { y, snapPoints } = import_react_modal_sheet.Sheet.useContext();
1412
+ const opacity = (0, import_react3.useTransform)(y, (value) => {
1413
+ if (snapPoints.length === 0 || output.length !== snapPoints.length) {
1414
+ return 0;
1415
+ }
1416
+ const mix = (0, import_react3.interpolate)(
1417
+ snapPoints.map((point) => point.snapValueY),
1418
+ output
1419
+ );
1420
+ return mix(value) * 0.45;
1421
+ });
1422
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1423
+ import_react_modal_sheet.Sheet.Backdrop,
1424
+ {
1425
+ className: "!bg-black !backdrop-blur-[1px]",
1426
+ onTap: active ? onTap : void 0,
1427
+ style: { opacity }
1428
+ }
1429
+ );
1430
+ }
1431
+
1432
+ // src/components/Map/MapContext.tsx
1433
+ var import_react5 = require("react");
1434
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1435
+ var MapControlsContext = (0, import_react5.createContext)(
1582
1436
  null
1583
1437
  );
1584
1438
  var SDKMapProvider = ({
1585
1439
  children
1586
1440
  }) => {
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) => {
1441
+ const [isFollowing, setIsFollowing] = (0, import_react5.useState)(true);
1442
+ const [bearing, setBearingState] = (0, import_react5.useState)(0);
1443
+ const [pitch, setPitchState] = (0, import_react5.useState)(0);
1444
+ const [drawerState, setDrawerStateInternal] = (0, import_react5.useState)("closed");
1445
+ const drawerContentRef = (0, import_react5.useRef)(null);
1446
+ const setDrawerState = (0, import_react5.useCallback)((val) => {
1593
1447
  setDrawerStateInternal(val);
1594
1448
  }, []);
1595
- const [drawerHandleVisible, setDrawerHandleVisibleState] = (0, import_react3.useState)(true);
1596
- const setDrawerHandleVisible = (0, import_react3.useCallback)((val) => {
1449
+ const [drawerHandleVisible, setDrawerHandleVisibleState] = (0, import_react5.useState)(true);
1450
+ const setDrawerHandleVisible = (0, import_react5.useCallback)((val) => {
1597
1451
  setDrawerHandleVisibleState((prev) => prev === val ? prev : val);
1598
1452
  }, []);
1599
- const [hasControls, setHasControlsState] = (0, import_react3.useState)(false);
1600
- const setHasControls = (0, import_react3.useCallback)((val) => {
1453
+ const [hasControls, setHasControlsState] = (0, import_react5.useState)(false);
1454
+ const setHasControls = (0, import_react5.useCallback)((val) => {
1601
1455
  setHasControlsState((prev) => prev === val ? prev : val);
1602
1456
  }, []);
1603
- const [etaData, setEtaDataState] = (0, import_react3.useState)(void 0);
1604
- const setEtaData = (0, import_react3.useCallback)((newData) => {
1457
+ const [etaData, setEtaDataState] = (0, import_react5.useState)(void 0);
1458
+ const setEtaData = (0, import_react5.useCallback)((newData) => {
1605
1459
  setEtaDataState((prev) => {
1606
1460
  if (!prev && !newData) return prev;
1607
1461
  if (!prev || !newData) return newData;
@@ -1611,29 +1465,29 @@ var SDKMapProvider = ({
1611
1465
  return newData;
1612
1466
  });
1613
1467
  }, []);
1614
- const [insets, setInsetsState] = (0, import_react3.useState)({
1468
+ const [insets, setInsetsState] = (0, import_react5.useState)({
1615
1469
  bottom: 0,
1616
1470
  left: 0,
1617
1471
  right: 0,
1618
1472
  top: 0
1619
1473
  });
1620
- const setInsets = (0, import_react3.useCallback)((newInsets) => {
1474
+ const setInsets = (0, import_react5.useCallback)((newInsets) => {
1621
1475
  setInsetsState((prev) => ({ ...prev, ...newInsets }));
1622
1476
  }, []);
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) => {
1477
+ const centerCallbackRef = (0, import_react5.useRef)(null);
1478
+ const resetBearingCallbackRef = (0, import_react5.useRef)(null);
1479
+ const flyToCallbackRef = (0, import_react5.useRef)(null);
1480
+ const centerOnUser = (0, import_react5.useCallback)((params) => {
1627
1481
  if (centerCallbackRef.current) {
1628
1482
  centerCallbackRef.current(params);
1629
1483
  }
1630
1484
  }, []);
1631
- const resetBearing = (0, import_react3.useCallback)((params) => {
1485
+ const resetBearing = (0, import_react5.useCallback)((params) => {
1632
1486
  if (resetBearingCallbackRef.current) {
1633
1487
  resetBearingCallbackRef.current(params);
1634
1488
  }
1635
1489
  }, []);
1636
- const flyTo = (0, import_react3.useCallback)(
1490
+ const flyTo = (0, import_react5.useCallback)(
1637
1491
  (coords, params) => {
1638
1492
  if (flyToCallbackRef.current) {
1639
1493
  flyToCallbackRef.current(coords, params);
@@ -1641,31 +1495,31 @@ var SDKMapProvider = ({
1641
1495
  },
1642
1496
  []
1643
1497
  );
1644
- const _registerCenterCallback = (0, import_react3.useCallback)(
1498
+ const _registerCenterCallback = (0, import_react5.useCallback)(
1645
1499
  (cb) => {
1646
1500
  centerCallbackRef.current = cb;
1647
1501
  },
1648
1502
  []
1649
1503
  );
1650
- const _registerResetBearingCallback = (0, import_react3.useCallback)(
1504
+ const _registerResetBearingCallback = (0, import_react5.useCallback)(
1651
1505
  (cb) => {
1652
1506
  resetBearingCallbackRef.current = cb;
1653
1507
  },
1654
1508
  []
1655
1509
  );
1656
- const _registerFlyToCallback = (0, import_react3.useCallback)(
1510
+ const _registerFlyToCallback = (0, import_react5.useCallback)(
1657
1511
  (cb) => {
1658
1512
  flyToCallbackRef.current = cb;
1659
1513
  },
1660
1514
  []
1661
1515
  );
1662
- const setBearing = (0, import_react3.useCallback)((b) => {
1516
+ const setBearing = (0, import_react5.useCallback)((b) => {
1663
1517
  setBearingState(b);
1664
1518
  }, []);
1665
- const setPitch = (0, import_react3.useCallback)((p) => {
1519
+ const setPitch = (0, import_react5.useCallback)((p) => {
1666
1520
  setPitchState(p);
1667
1521
  }, []);
1668
- const contextValue = (0, import_react3.useMemo)(
1522
+ const contextValue = (0, import_react5.useMemo)(
1669
1523
  () => ({
1670
1524
  _registerCenterCallback,
1671
1525
  _registerFlyToCallback,
@@ -1715,10 +1569,10 @@ var SDKMapProvider = ({
1715
1569
  setInsets
1716
1570
  ]
1717
1571
  );
1718
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MapControlsContext.Provider, { value: contextValue, children });
1572
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MapControlsContext.Provider, { value: contextValue, children });
1719
1573
  };
1720
1574
  var useMapControls = () => {
1721
- const context = (0, import_react3.useContext)(MapControlsContext);
1575
+ const context = (0, import_react5.useContext)(MapControlsContext);
1722
1576
  if (!context) {
1723
1577
  throw new Error("useMapControls must be used within a MapControlsProvider");
1724
1578
  }
@@ -1726,8 +1580,8 @@ var useMapControls = () => {
1726
1580
  };
1727
1581
 
1728
1582
  // src/components/Map/components/MapControls.tsx
1729
- var import_react4 = require("react");
1730
- var import_jsx_runtime8 = require("react/jsx-runtime");
1583
+ var import_react6 = require("react");
1584
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1731
1585
  var resolveHeightToPixels2 = (height, containerHeight) => {
1732
1586
  if (typeof height === "number") {
1733
1587
  return height;
@@ -1763,9 +1617,9 @@ var MapControls = ({
1763
1617
  controlsBottomOffset = 0,
1764
1618
  isInternal = false
1765
1619
  }) => {
1766
- const mapContext = (0, import_react4.useContext)(MapControlsContext);
1620
+ const mapContext = (0, import_react6.useContext)(MapControlsContext);
1767
1621
  const contextRef = mapContext?.drawerContentRef;
1768
- const mergedRef = (0, import_react4.useCallback)(
1622
+ const mergedRef = (0, import_react6.useCallback)(
1769
1623
  (node) => {
1770
1624
  if (drawerContentRef) {
1771
1625
  if (typeof drawerContentRef === "function") {
@@ -1780,11 +1634,11 @@ var MapControls = ({
1780
1634
  },
1781
1635
  [drawerContentRef, contextRef]
1782
1636
  );
1783
- const [localDrawerState, setLocalDrawerState] = (0, import_react4.useState)(
1637
+ const [localDrawerState, setLocalDrawerState] = (0, import_react6.useState)(
1784
1638
  defaultState ?? "closed"
1785
1639
  );
1786
1640
  const drawerState = mapContext ? mapContext.drawerState : localDrawerState;
1787
- const setDrawerState = (0, import_react4.useCallback)(
1641
+ const setDrawerState = (0, import_react6.useCallback)(
1788
1642
  (state) => {
1789
1643
  if (mapContext) {
1790
1644
  mapContext.setDrawerState(state);
@@ -1794,15 +1648,15 @@ var MapControls = ({
1794
1648
  },
1795
1649
  [mapContext]
1796
1650
  );
1797
- (0, import_react4.useEffect)(() => {
1651
+ (0, import_react6.useEffect)(() => {
1798
1652
  if (defaultState && mapContext) {
1799
1653
  mapContext.setDrawerState(defaultState);
1800
1654
  }
1801
1655
  }, []);
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)(() => {
1656
+ const [side, setSide] = (0, import_react6.useState)("left");
1657
+ const containerRef = (0, import_react6.useRef)(null);
1658
+ const [mapHeight, setMapHeight] = (0, import_react6.useState)(600);
1659
+ (0, import_react6.useEffect)(() => {
1806
1660
  const parent = containerRef.current?.parentElement;
1807
1661
  if (!parent) return;
1808
1662
  const updateHeight = () => {
@@ -1816,7 +1670,7 @@ var MapControls = ({
1816
1670
  };
1817
1671
  }, []);
1818
1672
  const setHasControls = mapContext?.setHasControls;
1819
- (0, import_react4.useEffect)(() => {
1673
+ (0, import_react6.useEffect)(() => {
1820
1674
  if (setHasControls && !isInternal) {
1821
1675
  setHasControls(true);
1822
1676
  return () => setHasControls(false);
@@ -1840,10 +1694,8 @@ var MapControls = ({
1840
1694
  };
1841
1695
  const mapPitch = mapContext ? mapContext.pitch : 0;
1842
1696
  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)(() => {
1697
+ const [autoContentPx, setAutoContentPx] = (0, import_react6.useState)(0);
1698
+ (0, import_react6.useEffect)(() => {
1847
1699
  if (typeof window === "undefined") return;
1848
1700
  const checkLayout = () => {
1849
1701
  if (drawerSide) {
@@ -1860,8 +1712,8 @@ var MapControls = ({
1860
1712
  window.addEventListener("resize", checkLayout);
1861
1713
  return () => window.removeEventListener("resize", checkLayout);
1862
1714
  }, [drawerSide]);
1863
- const isDragging = touchStartY !== null && currentTouchY !== null;
1864
- const dragOffset = isDragging ? currentTouchY - touchStartY : 0;
1715
+ const isDragging = false;
1716
+ const clampedDragOffset = 0;
1865
1717
  const fullPx = resolveHeightToPixels2(drawerFullHeight || "85%", mapHeight);
1866
1718
  const peekPx = resolveHeightToPixels2(drawerPeekHeight || "15%", mapHeight);
1867
1719
  const autoMaxPx = resolveHeightToPixels2(
@@ -1871,22 +1723,6 @@ var MapControls = ({
1871
1723
  const autoPx = Math.min(autoMaxPx, autoContentPx);
1872
1724
  const bottomInset = mapContext?.insets.bottom || 0;
1873
1725
  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
1726
  let baseHeight = handleVisible ? 32 : 0;
1891
1727
  if (drawerState === "peek") {
1892
1728
  baseHeight = peekPx;
@@ -1895,7 +1731,7 @@ var MapControls = ({
1895
1731
  } else if (drawerState === "auto") {
1896
1732
  baseHeight = autoPx;
1897
1733
  }
1898
- const currentDrawerHeight = baseHeight - clampedDragOffset;
1734
+ const currentDrawerHeight = baseHeight;
1899
1735
  const startFadeHeight = peekPx + 20;
1900
1736
  const endFadeHeight = peekPx + (fullPx - peekPx) * 0.35;
1901
1737
  let etaOpacity = 1;
@@ -1915,22 +1751,17 @@ var MapControls = ({
1915
1751
  etaOpacity = drawerState === "full" ? 0 : 1;
1916
1752
  etaBottomStyle = `calc(1rem + ${bottomInset}px)`;
1917
1753
  }
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,
1754
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1755
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: containerRef, style: { display: "none" } }),
1756
+ side === "bottom" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1757
+ MobileBottomDrawer,
1922
1758
  {
1923
- clampedDragOffset,
1924
1759
  containerHeight: mapHeight,
1925
- currentTouchY,
1926
1760
  drawerAutoMaxHeight,
1927
1761
  drawerFullHeight,
1928
1762
  drawerPeekHeight,
1929
1763
  enableTouchDrag,
1930
- etaBarHeight,
1931
- etaData: resolvedEtaData,
1932
1764
  handleVisible,
1933
- isDragging,
1934
1765
  menuContent: children || menuContent,
1935
1766
  menuItems,
1936
1767
  onAutoContentHeightChange: setAutoContentPx,
@@ -1938,15 +1769,22 @@ var MapControls = ({
1938
1769
  ref: mergedRef,
1939
1770
  safeAreaInsets: mapContext?.insets,
1940
1771
  scrollToTopThreshold,
1941
- setCurrentTouchY,
1942
- setTouchStartY,
1943
1772
  showScrollToTopButton,
1944
- side,
1945
- state: drawerState,
1946
- touchStartY
1773
+ state: drawerState
1774
+ }
1775
+ ) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1776
+ MapDrawer,
1777
+ {
1778
+ menuContent: children || menuContent,
1779
+ menuItems,
1780
+ onChangeState: setDrawerState,
1781
+ ref: mergedRef,
1782
+ scrollToTopThreshold,
1783
+ showScrollToTopButton,
1784
+ state: drawerState
1947
1785
  }
1948
1786
  ),
1949
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1787
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1950
1788
  MapRightControls,
1951
1789
  {
1952
1790
  bottomOffset: controlsBottomOffset,
@@ -1969,7 +1807,7 @@ var MapControls = ({
1969
1807
  side
1970
1808
  }
1971
1809
  ),
1972
- resolvedEtaData && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1810
+ resolvedEtaData && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1973
1811
  MapEtaPanel,
1974
1812
  {
1975
1813
  etaData: resolvedEtaData,
@@ -1987,10 +1825,10 @@ var MapControls = ({
1987
1825
  };
1988
1826
 
1989
1827
  // src/components/Map/components/MapMenu.tsx
1990
- var import_react5 = require("react");
1991
- var import_jsx_runtime9 = require("react/jsx-runtime");
1828
+ var import_react7 = require("react");
1829
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1992
1830
  var MapMenu = ({ children }) => {
1993
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-col gap-1.5", children });
1831
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex flex-col gap-1.5", children });
1994
1832
  };
1995
1833
  var MapMenuItem = ({
1996
1834
  id,
@@ -2001,7 +1839,7 @@ var MapMenuItem = ({
2001
1839
  disabled = false,
2002
1840
  children
2003
1841
  }) => {
2004
- const context = (0, import_react5.useContext)(MapControlsContext);
1842
+ const context = (0, import_react7.useContext)(MapControlsContext);
2005
1843
  const handleClick = (e) => {
2006
1844
  if (disabled) return;
2007
1845
  if (onPress) onPress();
@@ -2009,7 +1847,7 @@ var MapMenuItem = ({
2009
1847
  context.setDrawerState("closed");
2010
1848
  }
2011
1849
  };
2012
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1850
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2013
1851
  "button",
2014
1852
  {
2015
1853
  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 +1855,12 @@ var MapMenuItem = ({
2017
1855
  onClick: handleClick,
2018
1856
  type: "button",
2019
1857
  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: [
1858
+ 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
1859
  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 })
1860
+ 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
1861
  ] }),
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 }),
1862
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1 flex flex-col justify-center", children: [
1863
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-sm font-medium tracking-wide flex-1", children: label }),
2026
1864
  children
2027
1865
  ] })
2028
1866
  ]
@@ -2036,7 +1874,7 @@ var MapMenuTitle = ({
2036
1874
  showDivider = true,
2037
1875
  className = ""
2038
1876
  }) => {
2039
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1877
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2040
1878
  "div",
2041
1879
  {
2042
1880
  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 +1886,14 @@ MapMenuTitle.displayName = "MapMenuTitle";
2048
1886
  var MapMenuDivider = ({
2049
1887
  className = ""
2050
1888
  }) => {
2051
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `h-[1px] bg-white/10 my-3 mx-3.5 ${className}` });
1889
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `h-[1px] bg-white/10 my-3 mx-3.5 ${className}` });
2052
1890
  };
2053
1891
  MapMenuDivider.displayName = "MapMenuDivider";
2054
1892
  var MapMenuFooter = ({
2055
1893
  children,
2056
1894
  className = ""
2057
1895
  }) => {
2058
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1896
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2059
1897
  "div",
2060
1898
  {
2061
1899
  className: `mt-auto pt-4 border-t border-white/10 px-3.5 text-xs text-zinc-500 font-medium ${className}`,
@@ -2083,7 +1921,7 @@ var GlobalEvent = /* @__PURE__ */ ((GlobalEvent2) => {
2083
1921
  })(GlobalEvent || {});
2084
1922
 
2085
1923
  // src/components/Map/hooks/useUserLocation.ts
2086
- var import_react6 = require("react");
1924
+ var import_react8 = require("react");
2087
1925
  var LERP_FACTOR = 0.12;
2088
1926
  var EMPTY_STATE = {
2089
1927
  accuracy: null,
@@ -2204,8 +2042,8 @@ function stopSharedStream() {
2204
2042
  currentInterpolated = { coords: null, heading: null };
2205
2043
  }
2206
2044
  var useUserLocation = () => {
2207
- const [locationState, setLocationState] = (0, import_react6.useState)(getSnapshot);
2208
- (0, import_react6.useEffect)(() => {
2045
+ const [locationState, setLocationState] = (0, import_react8.useState)(getSnapshot);
2046
+ (0, import_react8.useEffect)(() => {
2209
2047
  refCount++;
2210
2048
  if (refCount === 1) {
2211
2049
  startSharedStream();
@@ -2225,7 +2063,7 @@ var useUserLocation = () => {
2225
2063
  };
2226
2064
 
2227
2065
  // src/components/Map/hooks/useLiveRouting.ts
2228
- var import_react7 = require("react");
2066
+ var import_react9 = require("react");
2229
2067
  var useLiveRouting = ({
2230
2068
  origin: manualOrigin,
2231
2069
  destination,
@@ -2234,19 +2072,19 @@ var useLiveRouting = ({
2234
2072
  enabled = true,
2235
2073
  initialMode = "preview"
2236
2074
  }) => {
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);
2075
+ const [route, setRoute] = (0, import_react9.useState)(null);
2076
+ const [totalDistance, setTotalDistance] = (0, import_react9.useState)(null);
2077
+ const [isCalculating, setIsCalculating] = (0, import_react9.useState)(false);
2078
+ const [error, setError] = (0, import_react9.useState)(null);
2079
+ const [mode, setMode] = (0, import_react9.useState)(initialMode);
2242
2080
  const userLocationState = useUserLocation();
2243
2081
  const calculationOrigin = manualOrigin || userLocationState.coords;
2244
2082
  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)(
2083
+ const lastCalcOrigin = (0, import_react9.useRef)(null);
2084
+ const lastCalcDest = (0, import_react9.useRef)(null);
2085
+ const isRequestInProgress = (0, import_react9.useRef)(false);
2086
+ const lastResetDestKey = (0, import_react9.useRef)(null);
2087
+ const getDistance = (0, import_react9.useCallback)(
2250
2088
  (p1, p2) => {
2251
2089
  const R = 6371e3;
2252
2090
  const \u03C61 = p1[1] * Math.PI / 180;
@@ -2259,7 +2097,7 @@ var useLiveRouting = ({
2259
2097
  },
2260
2098
  []
2261
2099
  );
2262
- const currentDistanceMeters = (0, import_react7.useMemo)(() => {
2100
+ const currentDistanceMeters = (0, import_react9.useMemo)(() => {
2263
2101
  if (!trackingLocation || !route || route.geometry.coordinates.length < 2) {
2264
2102
  if (trackingLocation && destination) {
2265
2103
  return getDistance(trackingLocation, destination);
@@ -2286,7 +2124,7 @@ var useLiveRouting = ({
2286
2124
  }
2287
2125
  return dist;
2288
2126
  }, [trackingLocation, route, destination, getDistance]);
2289
- const calculate = (0, import_react7.useCallback)(
2127
+ const calculate = (0, import_react9.useCallback)(
2290
2128
  async (origin, dest, isNewDest) => {
2291
2129
  if (isRequestInProgress.current) return;
2292
2130
  isRequestInProgress.current = true;
@@ -2321,12 +2159,12 @@ var useLiveRouting = ({
2321
2159
  },
2322
2160
  [profile, getDistance]
2323
2161
  );
2324
- (0, import_react7.useEffect)(() => {
2162
+ (0, import_react9.useEffect)(() => {
2325
2163
  if (initialMode === "navigation") {
2326
2164
  setMode("navigation");
2327
2165
  }
2328
2166
  }, [initialMode]);
2329
- (0, import_react7.useEffect)(() => {
2167
+ (0, import_react9.useEffect)(() => {
2330
2168
  if (!enabled || !destination || !calculationOrigin) {
2331
2169
  if (!enabled || !destination) {
2332
2170
  setRoute(null);
@@ -2377,10 +2215,10 @@ var useLiveRouting = ({
2377
2215
  };
2378
2216
  };
2379
2217
  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)(() => {
2218
+ const [route, setRoute] = (0, import_react9.useState)(null);
2219
+ const [isCalculating, setIsCalculating] = (0, import_react9.useState)(false);
2220
+ const [error, setError] = (0, import_react9.useState)(null);
2221
+ (0, import_react9.useEffect)(() => {
2384
2222
  if (!origin || !destination) {
2385
2223
  setRoute(null);
2386
2224
  return;
@@ -2407,12 +2245,12 @@ var useRoute = (origin, destination, profile = "driving") => {
2407
2245
  };
2408
2246
 
2409
2247
  // src/components/Map/hooks/useJourney.ts
2410
- var import_react8 = require("react");
2248
+ var import_react10 = require("react");
2411
2249
  var useJourney = (options = {}) => {
2412
2250
  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)(() => {
2251
+ const [progNav, setProgNav] = (0, import_react10.useState)(null);
2252
+ const [isAborted, setIsAborted] = (0, import_react10.useState)(false);
2253
+ (0, import_react10.useEffect)(() => {
2416
2254
  const unsubCreate = sdk.on("SDK_NAVIGATION_CREATE", (payload) => {
2417
2255
  setIsAborted(false);
2418
2256
  setProgNav(payload);
@@ -2440,17 +2278,17 @@ var useJourney = (options = {}) => {
2440
2278
  profile: effectiveOptions?.profile || "driving",
2441
2279
  recalculateThreshold: effectiveOptions?.recalculateThreshold || 50
2442
2280
  });
2443
- const prevDest = (0, import_react8.useRef)(null);
2281
+ const prevDest = (0, import_react10.useRef)(null);
2444
2282
  const currentDest = effectiveOptions?.destination;
2445
- (0, import_react8.useEffect)(() => {
2283
+ (0, import_react10.useEffect)(() => {
2446
2284
  if (currentDest && (!prevDest.current || prevDest.current[0] !== currentDest[0] || prevDest.current[1] !== currentDest[1])) {
2447
2285
  setIsAborted(false);
2448
2286
  }
2449
2287
  prevDest.current = currentDest;
2450
2288
  }, [currentDest]);
2451
- const onModeChangeRef = (0, import_react8.useRef)(onModeChange);
2289
+ const onModeChangeRef = (0, import_react10.useRef)(onModeChange);
2452
2290
  onModeChangeRef.current = onModeChange;
2453
- (0, import_react8.useEffect)(() => {
2291
+ (0, import_react10.useEffect)(() => {
2454
2292
  onModeChangeRef.current?.(internalNav.mode);
2455
2293
  }, [internalNav.mode]);
2456
2294
  const isActive = !isAborted && !!effectiveOptions?.destination;
@@ -2472,13 +2310,13 @@ var useJourney = (options = {}) => {
2472
2310
  (totalDistanceMeters - remainingMeters) / totalDistanceMeters * 100
2473
2311
  )
2474
2312
  ) : 0;
2475
- const cancel = (0, import_react8.useCallback)(() => {
2313
+ const cancel = (0, import_react10.useCallback)(() => {
2476
2314
  setIsAborted(true);
2477
2315
  setProgNav(null);
2478
2316
  sdk.navigation.abort();
2479
2317
  if (onAbort) onAbort();
2480
2318
  }, [onAbort]);
2481
- const start = (0, import_react8.useCallback)(() => {
2319
+ const start = (0, import_react10.useCallback)(() => {
2482
2320
  sdk.navigation.start();
2483
2321
  internalNav.start();
2484
2322
  }, [internalNav.start]);
@@ -2500,9 +2338,9 @@ var useJourney = (options = {}) => {
2500
2338
  };
2501
2339
 
2502
2340
  // src/components/Map/hooks/useTrimmedRoute.ts
2503
- var import_react9 = require("react");
2341
+ var import_react11 = require("react");
2504
2342
  var useTrimmedRoute = (route, userLocation) => {
2505
- return (0, import_react9.useMemo)(() => {
2343
+ return (0, import_react11.useMemo)(() => {
2506
2344
  if (!route || !userLocation || route.coordinates.length < 2) return route;
2507
2345
  const coords = route.coordinates;
2508
2346
  let minDistance = Infinity;
@@ -2527,7 +2365,7 @@ var useTrimmedRoute = (route, userLocation) => {
2527
2365
 
2528
2366
  // src/components/Map/layers/RouteLayer.tsx
2529
2367
  var import_react_maplibre = require("@vis.gl/react-maplibre");
2530
- var import_jsx_runtime10 = require("react/jsx-runtime");
2368
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2531
2369
  var RouteLayer = ({
2532
2370
  geometry,
2533
2371
  color = "#3b82f6",
@@ -2540,8 +2378,8 @@ var RouteLayer = ({
2540
2378
  properties: {},
2541
2379
  type: "Feature"
2542
2380
  };
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)(
2381
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_maplibre.Source, { data, id: "sdk-route-source", type: "geojson", children: [
2382
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2545
2383
  import_react_maplibre.Layer,
2546
2384
  {
2547
2385
  id: "sdk-route-layer-casing",
@@ -2554,7 +2392,7 @@ var RouteLayer = ({
2554
2392
  type: "line"
2555
2393
  }
2556
2394
  ),
2557
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2395
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2558
2396
  import_react_maplibre.Layer,
2559
2397
  {
2560
2398
  id: "sdk-route-layer",
@@ -2597,8 +2435,8 @@ var buildGeoCircle = (center, radiusMeters, points = 64) => {
2597
2435
 
2598
2436
  // src/components/Map/layers/MockRadiusLayer.tsx
2599
2437
  var import_react_maplibre2 = require("@vis.gl/react-maplibre");
2600
- var import_react10 = require("react");
2601
- var import_jsx_runtime11 = require("react/jsx-runtime");
2438
+ var import_react12 = require("react");
2439
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2602
2440
  var MockRadiusLayer = ({
2603
2441
  center,
2604
2442
  radiusMeters,
@@ -2611,12 +2449,12 @@ var MockRadiusLayer = ({
2611
2449
  // pastel palette with no neon accents at all).
2612
2450
  color = "#e2e8f0"
2613
2451
  }) => {
2614
- const data = (0, import_react10.useMemo)(
2452
+ const data = (0, import_react12.useMemo)(
2615
2453
  () => buildGeoCircle(center, radiusMeters),
2616
2454
  [center, radiusMeters]
2617
2455
  );
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)(
2456
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_maplibre2.Source, { data, id: "sdk-mock-radius-source", type: "geojson", children: [
2457
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2620
2458
  import_react_maplibre2.Layer,
2621
2459
  {
2622
2460
  id: "sdk-mock-radius-fill",
@@ -2627,7 +2465,7 @@ var MockRadiusLayer = ({
2627
2465
  type: "fill"
2628
2466
  }
2629
2467
  ),
2630
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2468
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2631
2469
  import_react_maplibre2.Layer,
2632
2470
  {
2633
2471
  id: "sdk-mock-radius-outline",
@@ -2644,8 +2482,8 @@ var MockRadiusLayer = ({
2644
2482
 
2645
2483
  // src/components/Map/layers/POILayers.tsx
2646
2484
  var import_react_maplibre3 = require("@vis.gl/react-maplibre");
2647
- var import_react11 = require("react");
2648
- var import_jsx_runtime12 = require("react/jsx-runtime");
2485
+ var import_react13 = require("react");
2486
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2649
2487
  function createEmojiIcon(emoji, size = 64) {
2650
2488
  const canvas = document.createElement("canvas");
2651
2489
  canvas.width = size;
@@ -2658,13 +2496,13 @@ function createEmojiIcon(emoji, size = 64) {
2658
2496
  return ctx.getImageData(0, 0, size, size);
2659
2497
  }
2660
2498
  var POILayers = ({ pois }) => {
2661
- const [loadedImages, setLoadedImages] = (0, import_react11.useState)(0);
2499
+ const [loadedImages, setLoadedImages] = (0, import_react13.useState)(0);
2662
2500
  const { current: map } = (0, import_react_maplibre3.useMap)();
2663
- const glPois = (0, import_react11.useMemo)(
2501
+ const glPois = (0, import_react13.useMemo)(
2664
2502
  () => pois.filter((p) => !p.displayMode || p.displayMode === "gl"),
2665
2503
  [pois]
2666
2504
  );
2667
- (0, import_react11.useEffect)(() => {
2505
+ (0, import_react13.useEffect)(() => {
2668
2506
  if (!map) return;
2669
2507
  const glMap = map.getMap();
2670
2508
  const defaults = [
@@ -2704,7 +2542,7 @@ var POILayers = ({ pois }) => {
2704
2542
  setLoadedImages((prev) => prev + updates);
2705
2543
  }
2706
2544
  }, [map, glPois]);
2707
- const geojson = (0, import_react11.useMemo)(
2545
+ const geojson = (0, import_react13.useMemo)(
2708
2546
  () => ({
2709
2547
  features: glPois.map((poi) => ({
2710
2548
  geometry: {
@@ -2722,7 +2560,7 @@ var POILayers = ({ pois }) => {
2722
2560
  }),
2723
2561
  [glPois]
2724
2562
  );
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)(
2563
+ 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
2564
  import_react_maplibre3.Layer,
2727
2565
  {
2728
2566
  id: "sdk-poi-layer",
@@ -2759,11 +2597,11 @@ var POILayers = ({ pois }) => {
2759
2597
 
2760
2598
  // src/components/Map/layers/POIMarkers.tsx
2761
2599
  var import_react_maplibre4 = require("@vis.gl/react-maplibre");
2762
- var import_jsx_runtime13 = require("react/jsx-runtime");
2600
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2763
2601
  var POIMarkers = ({ pois, onClick }) => {
2764
2602
  const markerPois = pois.filter((p) => p.displayMode === "marker");
2765
2603
  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)(
2604
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: markerPois.map((poi) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2767
2605
  import_react_maplibre4.Marker,
2768
2606
  {
2769
2607
  anchor: "bottom",
@@ -2773,7 +2611,7 @@ var POIMarkers = ({ pois, onClick }) => {
2773
2611
  e.originalEvent.stopPropagation();
2774
2612
  if (onClick) onClick(poi);
2775
2613
  },
2776
- children: poi.markerComponent ? poi.markerComponent : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2614
+ children: poi.markerComponent ? poi.markerComponent : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2777
2615
  "div",
2778
2616
  {
2779
2617
  style: {
@@ -2782,7 +2620,7 @@ var POIMarkers = ({ pois, onClick }) => {
2782
2620
  transform: "transition-transform duration-200 hover:scale-110"
2783
2621
  },
2784
2622
  children: [
2785
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2623
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2786
2624
  "div",
2787
2625
  {
2788
2626
  style: {
@@ -2795,7 +2633,7 @@ var POIMarkers = ({ pois, onClick }) => {
2795
2633
  justifyContent: "center",
2796
2634
  width: "32px"
2797
2635
  },
2798
- children: poi.emoji ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { fontSize: "16px" }, children: poi.emoji }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2636
+ children: poi.emoji ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { fontSize: "16px" }, children: poi.emoji }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2799
2637
  "div",
2800
2638
  {
2801
2639
  style: {
@@ -2808,7 +2646,7 @@ var POIMarkers = ({ pois, onClick }) => {
2808
2646
  )
2809
2647
  }
2810
2648
  ),
2811
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2649
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2812
2650
  "div",
2813
2651
  {
2814
2652
  style: {
@@ -2831,19 +2669,19 @@ var POIMarkers = ({ pois, onClick }) => {
2831
2669
 
2832
2670
  // src/components/Map/layers/UserLocationLayer.tsx
2833
2671
  var import_react_maplibre5 = require("@vis.gl/react-maplibre");
2834
- var import_jsx_runtime14 = require("react/jsx-runtime");
2672
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2835
2673
  var UserLocationLayer = ({
2836
2674
  forcedLocation,
2837
2675
  heading
2838
2676
  }) => {
2839
2677
  if (!forcedLocation) return null;
2840
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2678
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2841
2679
  import_react_maplibre5.Marker,
2842
2680
  {
2843
2681
  anchor: "center",
2844
2682
  latitude: forcedLocation[1],
2845
2683
  longitude: forcedLocation[0],
2846
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2684
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2847
2685
  "div",
2848
2686
  {
2849
2687
  style: {
@@ -2853,7 +2691,7 @@ var UserLocationLayer = ({
2853
2691
  position: "relative"
2854
2692
  },
2855
2693
  children: [
2856
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2694
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2857
2695
  "div",
2858
2696
  {
2859
2697
  style: {
@@ -2866,7 +2704,7 @@ var UserLocationLayer = ({
2866
2704
  }
2867
2705
  }
2868
2706
  ),
2869
- heading !== void 0 && heading !== null && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2707
+ heading !== void 0 && heading !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2870
2708
  "div",
2871
2709
  {
2872
2710
  style: {
@@ -2876,13 +2714,13 @@ var UserLocationLayer = ({
2876
2714
  width: "60px",
2877
2715
  zIndex: 0
2878
2716
  },
2879
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2717
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2880
2718
  "svg",
2881
2719
  {
2882
2720
  style: { height: "100%", width: "100%" },
2883
2721
  viewBox: "0 0 100 100",
2884
2722
  children: [
2885
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2723
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2886
2724
  "radialGradient",
2887
2725
  {
2888
2726
  cx: "50%",
@@ -2892,7 +2730,7 @@ var UserLocationLayer = ({
2892
2730
  id: "grad1",
2893
2731
  r: "50%",
2894
2732
  children: [
2895
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2733
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2896
2734
  "stop",
2897
2735
  {
2898
2736
  offset: "0%",
@@ -2902,7 +2740,7 @@ var UserLocationLayer = ({
2902
2740
  }
2903
2741
  }
2904
2742
  ),
2905
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2743
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2906
2744
  "stop",
2907
2745
  {
2908
2746
  offset: "100%",
@@ -2915,7 +2753,7 @@ var UserLocationLayer = ({
2915
2753
  ]
2916
2754
  }
2917
2755
  ) }),
2918
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2756
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2919
2757
  "path",
2920
2758
  {
2921
2759
  d: "M 50 50 L 35 0 A 50 50 0 0 1 65 0 Z",
@@ -2927,7 +2765,7 @@ var UserLocationLayer = ({
2927
2765
  )
2928
2766
  }
2929
2767
  ),
2930
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2768
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2931
2769
  "div",
2932
2770
  {
2933
2771
  style: {
@@ -2941,7 +2779,7 @@ var UserLocationLayer = ({
2941
2779
  width: "20px",
2942
2780
  zIndex: 1
2943
2781
  },
2944
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2782
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2945
2783
  "div",
2946
2784
  {
2947
2785
  style: {
@@ -2955,7 +2793,7 @@ var UserLocationLayer = ({
2955
2793
  )
2956
2794
  }
2957
2795
  ),
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; } }` })
2796
+ /* @__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
2797
  ]
2960
2798
  }
2961
2799
  )
@@ -2965,9 +2803,9 @@ var UserLocationLayer = ({
2965
2803
 
2966
2804
  // src/components/Map/Map.tsx
2967
2805
  var import_react_maplibre6 = require("@vis.gl/react-maplibre");
2968
- var import_react12 = __toESM(require("react"), 1);
2806
+ var import_react14 = __toESM(require("react"), 1);
2969
2807
  var import_maplibre_gl = require("maplibre-gl/dist/maplibre-gl.css");
2970
- var import_jsx_runtime15 = require("react/jsx-runtime");
2808
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2971
2809
  var MapInternal = ({
2972
2810
  initialViewState = {
2973
2811
  latitude: 45.90583599233422,
@@ -3005,9 +2843,9 @@ var MapInternal = ({
3005
2843
  controlProps = {},
3006
2844
  enableTouchDrag = false
3007
2845
  }) => {
3008
- const mapControls = (0, import_react12.useContext)(MapControlsContext);
3009
- const mockLocation = (0, import_react12.useContext)(MockLocationContext);
3010
- const mapRef = (0, import_react12.useRef)(null);
2846
+ const mapControls = (0, import_react14.useContext)(MapControlsContext);
2847
+ const mockLocation = (0, import_react14.useContext)(MockLocationContext);
2848
+ const mapRef = (0, import_react14.useRef)(null);
3011
2849
  const userLocationState = useUserLocation();
3012
2850
  const journey = useJourney({
3013
2851
  navigation,
@@ -3025,24 +2863,24 @@ var MapInternal = ({
3025
2863
  const showNavigationUI = hasIntegratedNav ? externalShowNavigationUI !== false && navigation?.showUI !== false : externalShowNavigationUI;
3026
2864
  const mode = navigationData?.mode || "preview";
3027
2865
  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)(() => {
2866
+ const isFollowingRef = (0, import_react14.useRef)(resolvedInitialFollow);
2867
+ const isFlyingRef = (0, import_react14.useRef)(false);
2868
+ const flyingGenerationRef = (0, import_react14.useRef)(0);
2869
+ const lockFlying = (0, import_react14.useCallback)(() => {
3032
2870
  isFlyingRef.current = true;
3033
2871
  return ++flyingGenerationRef.current;
3034
2872
  }, []);
3035
- const releaseFlyingIfCurrent = (0, import_react12.useCallback)((flightId) => {
2873
+ const releaseFlyingIfCurrent = (0, import_react14.useCallback)((flightId) => {
3036
2874
  if (flyingGenerationRef.current === flightId) {
3037
2875
  isFlyingRef.current = false;
3038
2876
  }
3039
2877
  }, []);
3040
- const [localIsFollowingUI, setLocalIsFollowingUI] = (0, import_react12.useState)(
2878
+ const [localIsFollowingUI, setLocalIsFollowingUI] = (0, import_react14.useState)(
3041
2879
  resolvedInitialFollow
3042
2880
  );
3043
2881
  const isFollowingUI = mapControls ? mapControls.isFollowing : localIsFollowingUI;
3044
2882
  const setIsFollowingCtx = mapControls?.setIsFollowing;
3045
- const setFollowMode = (0, import_react12.useCallback)(
2883
+ const setFollowMode = (0, import_react14.useCallback)(
3046
2884
  (follow) => {
3047
2885
  isFollowingRef.current = follow;
3048
2886
  setLocalIsFollowingUI(follow);
@@ -3052,7 +2890,7 @@ var MapInternal = ({
3052
2890
  },
3053
2891
  [setIsFollowingCtx]
3054
2892
  );
3055
- (0, import_react12.useEffect)(() => {
2893
+ (0, import_react14.useEffect)(() => {
3056
2894
  if (mapControls && mapControls.isFollowing !== isFollowingRef.current) {
3057
2895
  isFollowingRef.current = mapControls.isFollowing;
3058
2896
  }
@@ -3061,8 +2899,8 @@ var MapInternal = ({
3061
2899
  if (pois.length > 0 && !mergedInteractiveLayerIds.includes("sdk-poi-layer")) {
3062
2900
  mergedInteractiveLayerIds.push("sdk-poi-layer");
3063
2901
  }
3064
- const prevInitialFollow = (0, import_react12.useRef)(initialFollowUser);
3065
- (0, import_react12.useEffect)(() => {
2902
+ const prevInitialFollow = (0, import_react14.useRef)(initialFollowUser);
2903
+ (0, import_react14.useEffect)(() => {
3066
2904
  if (initialFollowUser !== prevInitialFollow.current) {
3067
2905
  setFollowMode(initialFollowUser);
3068
2906
  prevInitialFollow.current = initialFollowUser;
@@ -3086,9 +2924,9 @@ var MapInternal = ({
3086
2924
  lockFlying,
3087
2925
  releaseFlyingIfCurrent
3088
2926
  ]);
3089
- const lastAutoLockedRouteRef = (0, import_react12.useRef)(null);
3090
- const lastModeRef = (0, import_react12.useRef)(null);
3091
- (0, import_react12.useEffect)(() => {
2927
+ const lastAutoLockedRouteRef = (0, import_react14.useRef)(null);
2928
+ const lastModeRef = (0, import_react14.useRef)(null);
2929
+ (0, import_react14.useEffect)(() => {
3092
2930
  if (!route || !mapRef.current) {
3093
2931
  if (!route) lastAutoLockedRouteRef.current = null;
3094
2932
  return;
@@ -3144,7 +2982,7 @@ var MapInternal = ({
3144
2982
  lockFlying,
3145
2983
  releaseFlyingIfCurrent
3146
2984
  ]);
3147
- (0, import_react12.useEffect)(() => {
2985
+ (0, import_react14.useEffect)(() => {
3148
2986
  if (isFollowingRef.current && !isFlyingRef.current && userLocationState.coords && mapRef.current) {
3149
2987
  mapRef.current.easeTo({
3150
2988
  center: userLocationState.coords,
@@ -3188,23 +3026,23 @@ var MapInternal = ({
3188
3026
  progress: progressValue
3189
3027
  } : void 0;
3190
3028
  const setEtaDataCtx = mapControls?.setEtaData;
3191
- (0, import_react12.useEffect)(() => {
3029
+ (0, import_react14.useEffect)(() => {
3192
3030
  if (setEtaDataCtx) {
3193
3031
  setEtaDataCtx(showEtaData);
3194
3032
  }
3195
3033
  }, [showEtaData, setEtaDataCtx]);
3196
3034
  const setDrawerStateCtx = mapControls?.setDrawerState;
3197
- (0, import_react12.useEffect)(() => {
3035
+ (0, import_react14.useEffect)(() => {
3198
3036
  if (setDrawerStateCtx && propDrawerState !== void 0) {
3199
3037
  setDrawerStateCtx(propDrawerState);
3200
3038
  }
3201
3039
  }, [propDrawerState, setDrawerStateCtx]);
3202
3040
  const resolvedMenuItems = menuItems ?? [];
3203
- const { mapLibreChildren, menuContentFromChildren } = (0, import_react12.useMemo)(() => {
3041
+ const { mapLibreChildren, menuContentFromChildren } = (0, import_react14.useMemo)(() => {
3204
3042
  const mapLibreChildren2 = [];
3205
3043
  const extractedMenuItems = [];
3206
- import_react12.default.Children.forEach(children, (child) => {
3207
- if (import_react12.default.isValidElement(child)) {
3044
+ import_react14.default.Children.forEach(children, (child) => {
3045
+ if (import_react14.default.isValidElement(child)) {
3208
3046
  const type = child.type;
3209
3047
  const displayName = type?.displayName || type?.name;
3210
3048
  const isMenu = type === MapMenu || displayName === "MapMenu";
@@ -3215,7 +3053,7 @@ var MapInternal = ({
3215
3053
  "MapMenuFooter"
3216
3054
  ].includes(displayName);
3217
3055
  if (isMenu) {
3218
- import_react12.default.Children.forEach(
3056
+ import_react14.default.Children.forEach(
3219
3057
  child.props.children,
3220
3058
  (nestedChild) => {
3221
3059
  if (nestedChild) {
@@ -3232,7 +3070,7 @@ var MapInternal = ({
3232
3070
  mapLibreChildren2.push(child);
3233
3071
  }
3234
3072
  });
3235
- const menuContentFromChildren2 = extractedMenuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MapMenu, { children: extractedMenuItems }) : null;
3073
+ const menuContentFromChildren2 = extractedMenuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MapMenu, { children: extractedMenuItems }) : null;
3236
3074
  return { mapLibreChildren: mapLibreChildren2, menuContentFromChildren: menuContentFromChildren2 };
3237
3075
  }, [children]);
3238
3076
  const handleMapClick = (e) => {
@@ -3260,7 +3098,7 @@ var MapInternal = ({
3260
3098
  }
3261
3099
  if (onClick) onClick(e);
3262
3100
  };
3263
- const handleCenterOnUser = (0, import_react12.useCallback)(
3101
+ const handleCenterOnUser = (0, import_react14.useCallback)(
3264
3102
  (payload) => {
3265
3103
  if (userLocationState.coords && mapRef.current) {
3266
3104
  setFollowMode(true);
@@ -3285,7 +3123,7 @@ var MapInternal = ({
3285
3123
  releaseFlyingIfCurrent
3286
3124
  ]
3287
3125
  );
3288
- const handleFlyTo = (0, import_react12.useCallback)(
3126
+ const handleFlyTo = (0, import_react14.useCallback)(
3289
3127
  (coords, params) => {
3290
3128
  const map = mapRef.current;
3291
3129
  if (!map) return;
@@ -3305,7 +3143,7 @@ var MapInternal = ({
3305
3143
  },
3306
3144
  [setFollowMode, lockFlying, releaseFlyingIfCurrent]
3307
3145
  );
3308
- const handleResetBearing = (0, import_react12.useCallback)((params) => {
3146
+ const handleResetBearing = (0, import_react14.useCallback)((params) => {
3309
3147
  if (mapRef.current) {
3310
3148
  mapRef.current.easeTo({
3311
3149
  bearing: 0,
@@ -3315,14 +3153,14 @@ var MapInternal = ({
3315
3153
  });
3316
3154
  }
3317
3155
  }, []);
3318
- (0, import_react12.useEffect)(() => {
3156
+ (0, import_react14.useEffect)(() => {
3319
3157
  if (mapControls) {
3320
3158
  mapControls._registerCenterCallback(handleCenterOnUser);
3321
3159
  mapControls._registerResetBearingCallback(handleResetBearing);
3322
3160
  mapControls._registerFlyToCallback(handleFlyTo);
3323
3161
  }
3324
3162
  }, [mapControls, handleCenterOnUser, handleResetBearing, handleFlyTo]);
3325
- const handleMove = (0, import_react12.useCallback)(() => {
3163
+ const handleMove = (0, import_react14.useCallback)(() => {
3326
3164
  if (mapRef.current && mapControls) {
3327
3165
  mapControls.setBearing(mapRef.current.getBearing());
3328
3166
  mapControls.setPitch(mapRef.current.getPitch());
@@ -3337,13 +3175,13 @@ var MapInternal = ({
3337
3175
  }
3338
3176
  }
3339
3177
  };
3340
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3178
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3341
3179
  "div",
3342
3180
  {
3343
3181
  className: `w-full h-full overflow-hidden relative ${mockLocation?.isPlacingLocation ? "cursor-crosshair" : ""} ${className}`,
3344
3182
  style,
3345
3183
  children: [
3346
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3184
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3347
3185
  import_react_maplibre6.Map,
3348
3186
  {
3349
3187
  attributionControl: false,
@@ -3373,30 +3211,30 @@ var MapInternal = ({
3373
3211
  showUserLocation && userLocationState.coords && (renderUserLocation ? renderUserLocation({
3374
3212
  coords: userLocationState.coords,
3375
3213
  heading: userLocationState.heading
3376
- }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3214
+ }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3377
3215
  UserLocationLayer,
3378
3216
  {
3379
3217
  forcedLocation: userLocationState.coords,
3380
3218
  heading: userLocationState.heading
3381
3219
  }
3382
3220
  )),
3383
- mockLocation && mockLocation.radiusMeters > 0 && userLocationState.coords && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3221
+ mockLocation && mockLocation.radiusMeters > 0 && userLocationState.coords && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3384
3222
  MockRadiusLayer,
3385
3223
  {
3386
3224
  center: userLocationState.coords,
3387
3225
  radiusMeters: mockLocation.radiusMeters
3388
3226
  }
3389
3227
  ),
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 })
3228
+ displayRoute && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RouteLayer, { geometry: displayRoute }),
3229
+ pois.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3230
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(POILayers, { pois }),
3231
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(POIMarkers, { onClick: onPoiClick, pois })
3394
3232
  ] }),
3395
3233
  mapLibreChildren
3396
3234
  ]
3397
3235
  }
3398
3236
  ),
3399
- showControls && mapControls && !mapControls.hasControls && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3237
+ showControls && mapControls && !mapControls.hasControls && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3400
3238
  MapControls,
3401
3239
  {
3402
3240
  drawerContentRef,
@@ -3416,18 +3254,18 @@ var MapInternal = ({
3416
3254
  var SDKMapProviderWrapper = ({
3417
3255
  children
3418
3256
  }) => {
3419
- const context = (0, import_react12.useContext)(MapControlsContext);
3257
+ const context = (0, import_react14.useContext)(MapControlsContext);
3420
3258
  if (context) {
3421
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children });
3259
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children });
3422
3260
  }
3423
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SDKMapProvider, { children });
3261
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(SDKMapProvider, { children });
3424
3262
  };
3425
3263
  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 }) }) });
3264
+ 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
3265
  };
3428
3266
 
3429
3267
  // src/components/MapWrapper.tsx
3430
- var import_react13 = __toESM(require("react"), 1);
3268
+ var import_react15 = __toESM(require("react"), 1);
3431
3269
  var import_client = require("react-dom/client");
3432
3270
  function renderMap(containerId, props = {}) {
3433
3271
  const container = document.getElementById(containerId);
@@ -3435,7 +3273,7 @@ function renderMap(containerId, props = {}) {
3435
3273
  throw new Error(`Container with id "${containerId}" not found.`);
3436
3274
  }
3437
3275
  const root = (0, import_client.createRoot)(container);
3438
- root.render(import_react13.default.createElement(Map2, props));
3276
+ root.render(import_react15.default.createElement(Map2, props));
3439
3277
  return root;
3440
3278
  }
3441
3279
 
@@ -3792,7 +3630,7 @@ var RoutingService = {
3792
3630
  };
3793
3631
 
3794
3632
  // package.json
3795
- var version = "0.6.8";
3633
+ var version = "0.7.0";
3796
3634
 
3797
3635
  // src/sdk.ts
3798
3636
  function deepFreeze(obj) {
@@ -4138,6 +3976,8 @@ var MiniAppSDK = class {
4138
3976
  );
4139
3977
  this.initialize = this.initialize.bind(this);
4140
3978
  this.getEnv = this.getEnv.bind(this);
3979
+ this.achievement = this.achievement.bind(this);
3980
+ this.achievements = this.achievements.bind(this);
4141
3981
  this.on = this.on.bind(this);
4142
3982
  this.off = this.off.bind(this);
4143
3983
  }
@@ -4178,6 +4018,23 @@ var MiniAppSDK = class {
4178
4018
  getEnv() {
4179
4019
  return lastKnownEnv;
4180
4020
  }
4021
+ /**
4022
+ * Fetches a single Achievement's current progress by slug — read-only, for
4023
+ * rendering things like a progress bar. Progress is reported server-side
4024
+ * by the mini-app's own backend calling the Hub's M2M endpoint directly;
4025
+ * there is no corresponding "report progress" method on this SDK.
4026
+ * @param slug Unique slug identifying the Achievement.
4027
+ */
4028
+ achievement(slug) {
4029
+ return this.bridge.send("GET_ACHIEVEMENT", { slug });
4030
+ }
4031
+ /**
4032
+ * Fetches every Achievement (with current progress) visible to this
4033
+ * mini-app — read-only, same boundary as {@link MiniAppSDK.achievement}.
4034
+ */
4035
+ achievements() {
4036
+ return this.bridge.send("GET_ACHIEVEMENTS");
4037
+ }
4181
4038
  /**
4182
4039
  * Registers a callback for a specific event from the native shell.
4183
4040
  * @param event The name of the event to listen for.
@@ -4199,8 +4056,43 @@ var MiniAppSDK = class {
4199
4056
  var sdk = deepFreeze(new MiniAppSDK());
4200
4057
 
4201
4058
  // src/components/BridgeMocker.tsx
4202
- var import_react14 = require("react");
4203
- var import_jsx_runtime16 = require("react/jsx-runtime");
4059
+ var import_react16 = require("react");
4060
+ var import_jsx_runtime17 = require("react/jsx-runtime");
4061
+ var MOCK_ACHIEVEMENTS2 = [
4062
+ {
4063
+ completed: false,
4064
+ description: "Discover 5 points of interest around Annecy.",
4065
+ imageUrl: "https://api.dicebear.com/9.x/icons/svg?seed=explore",
4066
+ playerActionCount: 3,
4067
+ slug: "explore-5-pois",
4068
+ title: "Explorer",
4069
+ totalActionCount: 5,
4070
+ upReward: 50,
4071
+ xpReward: 100
4072
+ },
4073
+ {
4074
+ completed: true,
4075
+ description: "Complete your first navigation journey.",
4076
+ imageUrl: "https://api.dicebear.com/9.x/icons/svg?seed=journey",
4077
+ playerActionCount: 1,
4078
+ slug: "first-journey",
4079
+ title: "First Steps",
4080
+ totalActionCount: 1,
4081
+ upReward: 20,
4082
+ xpReward: 40
4083
+ },
4084
+ {
4085
+ completed: false,
4086
+ description: "Scan 10 QR codes at partner venues.",
4087
+ imageUrl: "https://api.dicebear.com/9.x/icons/svg?seed=scan",
4088
+ playerActionCount: 4,
4089
+ slug: "scan-10-qrcodes",
4090
+ title: "Code Breaker",
4091
+ totalActionCount: 10,
4092
+ upReward: 80,
4093
+ xpReward: 150
4094
+ }
4095
+ ];
4204
4096
  var AVATAR_MOUTH_VARIANTS = [
4205
4097
  "variant03",
4206
4098
  "variant07",
@@ -4287,19 +4179,19 @@ var BridgeMocker = ({
4287
4179
  mockJWTToken,
4288
4180
  children
4289
4181
  }) => {
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)({
4182
+ const [autoMove, setAutoMove] = (0, import_react16.useState)(isMoving);
4183
+ const [location, setLocation] = (0, import_react16.useState)(initialLocation);
4184
+ const [heading, setHeading] = (0, import_react16.useState)(0);
4185
+ const [speedMultiplier, setSpeedMultiplier] = (0, import_react16.useState)(simulationSpeed);
4186
+ const [isReady, setIsReady] = (0, import_react16.useState)(false);
4187
+ const [isMinimized, setIsMinimized] = (0, import_react16.useState)(true);
4188
+ const [radiusMeters, setRadiusMeters] = (0, import_react16.useState)(0);
4189
+ const [radiusUnit, setRadiusUnit] = (0, import_react16.useState)("m");
4190
+ const [isPlacingLocation, setIsPlacingLocation] = (0, import_react16.useState)(false);
4191
+ const streamIntervalRef = (0, import_react16.useRef)(null);
4192
+ const pathIndexRef = (0, import_react16.useRef)(0);
4193
+ const activeConfigRef = (0, import_react16.useRef)(null);
4194
+ const stateRef = (0, import_react16.useRef)({
4303
4195
  autoMove,
4304
4196
  heading,
4305
4197
  location,
@@ -4311,7 +4203,7 @@ var BridgeMocker = ({
4311
4203
  simulationPath,
4312
4204
  speedMultiplier
4313
4205
  });
4314
- const pushLocationUpdateFor = (0, import_react14.useCallback)(
4206
+ const pushLocationUpdateFor = (0, import_react16.useCallback)(
4315
4207
  (coords, headingDeg) => {
4316
4208
  const currentState = stateRef.current;
4317
4209
  const payload = {
@@ -4343,11 +4235,11 @@ var BridgeMocker = ({
4343
4235
  },
4344
4236
  []
4345
4237
  );
4346
- const pushLocationUpdate = (0, import_react14.useCallback)(() => {
4238
+ const pushLocationUpdate = (0, import_react16.useCallback)(() => {
4347
4239
  const currentState = stateRef.current;
4348
4240
  pushLocationUpdateFor(currentState.location, currentState.heading);
4349
4241
  }, [pushLocationUpdateFor]);
4350
- const placeLocation = (0, import_react14.useCallback)(
4242
+ const placeLocation = (0, import_react16.useCallback)(
4351
4243
  (coords) => {
4352
4244
  setLocation(coords);
4353
4245
  setIsPlacingLocation(false);
@@ -4355,7 +4247,7 @@ var BridgeMocker = ({
4355
4247
  },
4356
4248
  [pushLocationUpdateFor]
4357
4249
  );
4358
- (0, import_react14.useEffect)(() => {
4250
+ (0, import_react16.useEffect)(() => {
4359
4251
  stateRef.current = {
4360
4252
  autoMove,
4361
4253
  heading,
@@ -4376,19 +4268,19 @@ var BridgeMocker = ({
4376
4268
  speedMultiplier,
4377
4269
  mockJWTToken
4378
4270
  ]);
4379
- (0, import_react14.useEffect)(() => {
4271
+ (0, import_react16.useEffect)(() => {
4380
4272
  setAutoMove(isMoving);
4381
4273
  }, [isMoving]);
4382
- (0, import_react14.useEffect)(() => {
4274
+ (0, import_react16.useEffect)(() => {
4383
4275
  setSpeedMultiplier(simulationSpeed);
4384
4276
  }, [simulationSpeed]);
4385
- (0, import_react14.useEffect)(() => {
4277
+ (0, import_react16.useEffect)(() => {
4386
4278
  if (simulationPath && simulationPath.length > 0) {
4387
4279
  pathIndexRef.current = 0;
4388
4280
  setLocation(simulationPath[0]);
4389
4281
  }
4390
4282
  }, [simulationPath]);
4391
- (0, import_react14.useEffect)(() => {
4283
+ (0, import_react16.useEffect)(() => {
4392
4284
  if (streamIntervalRef.current && activeConfigRef.current) {
4393
4285
  sdk.bridge.send(
4394
4286
  "START_LOCATION_STREAM",
@@ -4396,7 +4288,7 @@ var BridgeMocker = ({
4396
4288
  );
4397
4289
  }
4398
4290
  }, [speedMultiplier]);
4399
- (0, import_react14.useEffect)(() => {
4291
+ (0, import_react16.useEffect)(() => {
4400
4292
  const bridge = sdk.bridge;
4401
4293
  const originalSend = bridge.send.bind(bridge);
4402
4294
  const stopStream = () => {
@@ -4557,6 +4449,24 @@ var BridgeMocker = ({
4557
4449
  if (type === "GET_FIDELITY_BALANCE") {
4558
4450
  return Promise.resolve({ balance: 1337, currency: "FPoints" });
4559
4451
  }
4452
+ if (type === "GET_ACHIEVEMENTS") {
4453
+ return Promise.resolve(MOCK_ACHIEVEMENTS2);
4454
+ }
4455
+ if (type === "GET_ACHIEVEMENT") {
4456
+ const slug = payload?.slug;
4457
+ return Promise.resolve(
4458
+ MOCK_ACHIEVEMENTS2.find((a) => a.slug === slug) ?? {
4459
+ completed: false,
4460
+ description: "Mocked achievement (no native shell attached).",
4461
+ playerActionCount: 0,
4462
+ slug: slug || "unknown-achievement",
4463
+ title: slug || "Unknown Achievement",
4464
+ totalActionCount: 1,
4465
+ upReward: 0,
4466
+ xpReward: 0
4467
+ }
4468
+ );
4469
+ }
4560
4470
  if (type === "PAYMENT_REQUEST") {
4561
4471
  return Promise.resolve({
4562
4472
  success: true,
@@ -4575,7 +4485,7 @@ var BridgeMocker = ({
4575
4485
  };
4576
4486
  }, [appId]);
4577
4487
  const radiusInMeters = radiusUnit === "km" ? radiusMeters * 1e3 : radiusMeters;
4578
- const mockLocationContextValue = (0, import_react14.useMemo)(
4488
+ const mockLocationContextValue = (0, import_react16.useMemo)(
4579
4489
  () => ({
4580
4490
  isPlacingLocation,
4581
4491
  placeLocation,
@@ -4584,9 +4494,9 @@ var BridgeMocker = ({
4584
4494
  [isPlacingLocation, placeLocation, radiusInMeters]
4585
4495
  );
4586
4496
  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)(
4497
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative w-full h-full", children: [
4498
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "w-full h-full", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MockLocationContext.Provider, { value: mockLocationContextValue, children }) }),
4499
+ isMinimized ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4590
4500
  Button,
4591
4501
  {
4592
4502
  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 +4504,7 @@ var BridgeMocker = ({
4594
4504
  title: "Open Simulation Controls",
4595
4505
  type: "button",
4596
4506
  variant: "ghost",
4597
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
4507
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4598
4508
  "svg",
4599
4509
  {
4600
4510
  className: "group-hover:scale-110 transition-transform",
@@ -4608,34 +4518,34 @@ var BridgeMocker = ({
4608
4518
  width: "14",
4609
4519
  xmlns: "http://www.w3.org/2000/svg",
4610
4520
  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" })
4521
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M21 4H3" }),
4522
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M10 8H3" }),
4523
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M21 12H3" }),
4524
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M10 16H3" }),
4525
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M21 20H3" }),
4526
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "14", cy: "8", r: "2" }),
4527
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "14", cy: "16", r: "2" })
4618
4528
  ]
4619
4529
  }
4620
4530
  )
4621
4531
  }
4622
- ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
4532
+ ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4623
4533
  "div",
4624
4534
  {
4625
4535
  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
4536
  style: { zIndex: 9998 },
4627
4537
  children: [
4628
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
4538
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4629
4539
  "div",
4630
4540
  {
4631
4541
  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
4542
  onClick: () => setIsMinimized(true),
4633
4543
  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" }),
4544
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "font-bold text-slate-100 flex items-center gap-2", children: [
4545
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-lg", children: "\u{1F6E0}\uFE0F" }),
4636
4546
  " Simulation Controls"
4637
4547
  ] }),
4638
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4548
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4639
4549
  Button,
4640
4550
  {
4641
4551
  className: "text-slate-500 hover:text-white p-0 h-auto hover:bg-transparent cursor-pointer",
@@ -4647,10 +4557,10 @@ var BridgeMocker = ({
4647
4557
  ]
4648
4558
  }
4649
4559
  ),
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)(
4560
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "p-4 flex flex-col gap-3", children: [
4561
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex justify-between items-center", children: [
4562
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer", children: [
4563
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4654
4564
  "input",
4655
4565
  {
4656
4566
  checked: autoMove,
@@ -4659,20 +4569,20 @@ var BridgeMocker = ({
4659
4569
  type: "checkbox"
4660
4570
  }
4661
4571
  ),
4662
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "text-slate-200 font-bold", children: [
4572
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "text-slate-200 font-bold", children: [
4663
4573
  "Auto-Move ",
4664
4574
  simulationPath ? "(Path)" : "(Random)"
4665
4575
  ] })
4666
4576
  ] }),
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)(
4577
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2", children: [
4578
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500", children: "Speed:" }),
4579
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4670
4580
  "select",
4671
4581
  {
4672
4582
  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
4583
  onChange: (e) => setSpeedMultiplier(Number(e.target.value)),
4674
4584
  value: speedMultiplier,
4675
- children: [1, 2, 5, 10, 50, 100, 250].map((s) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("option", { value: s, children: [
4585
+ children: [1, 2, 5, 10, 50, 100, 250].map((s) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("option", { value: s, children: [
4676
4586
  s,
4677
4587
  "x"
4678
4588
  ] }, s))
@@ -4680,10 +4590,10 @@ var BridgeMocker = ({
4680
4590
  )
4681
4591
  ] })
4682
4592
  ] }),
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)(
4593
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
4594
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-1", children: [
4595
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lng" }),
4596
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4687
4597
  "input",
4688
4598
  {
4689
4599
  className: "bg-slate-800 border border-slate-700 rounded px-2 py-1 text-white focus:outline-none focus:border-blue-500",
@@ -4698,9 +4608,9 @@ var BridgeMocker = ({
4698
4608
  }
4699
4609
  )
4700
4610
  ] }),
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)(
4611
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-1", children: [
4612
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500 text-left", children: "Lat" }),
4613
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4704
4614
  "input",
4705
4615
  {
4706
4616
  className: "bg-slate-800 border border-slate-700 rounded px-2 py-1 text-white focus:outline-none focus:border-blue-500",
@@ -4715,9 +4625,9 @@ var BridgeMocker = ({
4715
4625
  }
4716
4626
  )
4717
4627
  ] }),
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)(
4628
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-1 col-span-2", children: [
4629
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500", children: "Heading (Degrees)" }),
4630
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4721
4631
  "input",
4722
4632
  {
4723
4633
  className: "w-full accent-blue-500",
@@ -4731,13 +4641,13 @@ var BridgeMocker = ({
4731
4641
  value: heading
4732
4642
  }
4733
4643
  ),
4734
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "text-right text-slate-400", children: [
4644
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "text-right text-slate-400", children: [
4735
4645
  heading,
4736
4646
  "\xB0"
4737
4647
  ] })
4738
4648
  ] })
4739
4649
  ] }),
4740
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4650
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4741
4651
  Button,
4742
4652
  {
4743
4653
  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 +4657,11 @@ var BridgeMocker = ({
4747
4657
  children: isPlacingLocation ? "\u{1F4CD} Click the map to drop location\u2026" : "\u{1F4CD} Drop location on map"
4748
4658
  }
4749
4659
  ),
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)(
4660
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex flex-col gap-1 border-t border-slate-800 pt-3", children: [
4661
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex justify-between items-center", children: [
4662
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-[10px] text-slate-500", children: "Scan Radius" }),
4663
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-1", children: [
4664
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4755
4665
  "input",
4756
4666
  {
4757
4667
  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 +4671,21 @@ var BridgeMocker = ({
4761
4671
  value: radiusMeters
4762
4672
  }
4763
4673
  ),
4764
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
4674
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4765
4675
  "select",
4766
4676
  {
4767
4677
  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
4678
  onChange: (e) => setRadiusUnit(e.target.value),
4769
4679
  value: radiusUnit,
4770
4680
  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" })
4681
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "m", children: "m" }),
4682
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("option", { value: "km", children: "km" })
4773
4683
  ]
4774
4684
  }
4775
4685
  )
4776
4686
  ] })
4777
4687
  ] }),
4778
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4688
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4779
4689
  "input",
4780
4690
  {
4781
4691
  className: "w-full accent-blue-500",
@@ -4787,7 +4697,7 @@ var BridgeMocker = ({
4787
4697
  value: radiusMeters
4788
4698
  }
4789
4699
  ),
4790
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "text-right text-slate-400", children: radiusMeters === 0 ? "hidden" : `${radiusMeters}${radiusUnit} radius around user` })
4700
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "text-right text-slate-400", children: radiusMeters === 0 ? "hidden" : `${radiusMeters}${radiusUnit} radius around user` })
4791
4701
  ] })
4792
4702
  ] })
4793
4703
  ]
@@ -4797,20 +4707,20 @@ var BridgeMocker = ({
4797
4707
  };
4798
4708
 
4799
4709
  // src/components/DebugConsole.tsx
4800
- var import_react15 = require("react");
4801
- var import_jsx_runtime17 = require("react/jsx-runtime");
4710
+ var import_react17 = require("react");
4711
+ var import_jsx_runtime18 = require("react/jsx-runtime");
4802
4712
  var DebugConsole = ({
4803
4713
  isOpen: initialOpen = false,
4804
4714
  onClose
4805
4715
  }) => {
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)(() => {
4716
+ const [showConsole, setShowConsole] = (0, import_react17.useState)(initialOpen);
4717
+ const [logs, setLogs] = (0, import_react17.useState)([]);
4718
+ const scrollRef = (0, import_react17.useRef)(null);
4719
+ (0, import_react17.useEffect)(() => {
4810
4720
  setShowConsole(initialOpen);
4811
4721
  }, [initialOpen]);
4812
4722
  const clearLogs = () => setLogs([]);
4813
- const addLog = (0, import_react15.useCallback)((label, data) => {
4723
+ const addLog = (0, import_react17.useCallback)((label, data) => {
4814
4724
  if (label.includes("LOCATION_STREAM_UPDATE" /* LOCATION_STREAM_UPDATE */)) return;
4815
4725
  const entry = {
4816
4726
  content: typeof data === "string" ? data : JSON.stringify(data, null, 2),
@@ -4820,7 +4730,7 @@ var DebugConsole = ({
4820
4730
  };
4821
4731
  setLogs((prev) => [entry, ...prev].slice(0, 100));
4822
4732
  }, []);
4823
- (0, import_react15.useEffect)(() => {
4733
+ (0, import_react17.useEffect)(() => {
4824
4734
  if (typeof window === "undefined") return;
4825
4735
  const bridge = sdk.bridge;
4826
4736
  const originalSend = bridge.send.bind(bridge);
@@ -4842,7 +4752,7 @@ var DebugConsole = ({
4842
4752
  };
4843
4753
  }, [addLog]);
4844
4754
  if (!showConsole) {
4845
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4755
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4846
4756
  Button,
4847
4757
  {
4848
4758
  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 +4760,7 @@ var DebugConsole = ({
4850
4760
  title: "Open Debug Console",
4851
4761
  type: "button",
4852
4762
  variant: "ghost",
4853
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4763
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4854
4764
  "svg",
4855
4765
  {
4856
4766
  className: "group-hover:scale-110 transition-transform",
@@ -4864,31 +4774,31 @@ var DebugConsole = ({
4864
4774
  width: "14",
4865
4775
  xmlns: "http://www.w3.org/2000/svg",
4866
4776
  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" })
4777
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "m8 2 1.88 1.88" }),
4778
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M14.12 3.88 16 2" }),
4779
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M9 7.13v-1a3.003 3.003 0 1 1 6 0v1" }),
4780
+ /* @__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" }),
4781
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M12 20v-9" }),
4782
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M6.53 9C4.6 8.8 3 7.1 3 5" }),
4783
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M6 13H2" }),
4784
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M3 21c0-2.1 1.7-3.9 3.8-4" }),
4785
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M20.97 5c0 2.1-1.6 3.8-3.5 4" }),
4786
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M22 13h-4" }),
4787
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: "M17.2 17c2.1.1 3.8 1.9 3.8 4" })
4878
4788
  ]
4879
4789
  }
4880
4790
  )
4881
4791
  }
4882
4792
  );
4883
4793
  }
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" }),
4794
+ 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: [
4795
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
4796
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "text-[10px] font-bold uppercase tracking-widest text-slate-400 flex items-center gap-2", children: [
4797
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "w-2 h-2 rounded-full bg-emerald-500 animate-pulse" }),
4888
4798
  "UP SDK Debug Console"
4889
4799
  ] }),
4890
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex gap-4", children: [
4891
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4800
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex gap-4", children: [
4801
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4892
4802
  Button,
4893
4803
  {
4894
4804
  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 +4808,7 @@ var DebugConsole = ({
4898
4808
  children: "Clear"
4899
4809
  }
4900
4810
  ),
4901
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4811
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4902
4812
  Button,
4903
4813
  {
4904
4814
  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 +4823,21 @@ var DebugConsole = ({
4913
4823
  )
4914
4824
  ] })
4915
4825
  ] }),
4916
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4826
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4917
4827
  "div",
4918
4828
  {
4919
4829
  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
4830
  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)(
4831
+ 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
4832
  "div",
4923
4833
  {
4924
4834
  className: "mb-3 pb-3 border-b border-slate-900/50 last:border-0 last:mb-0 last:pb-0",
4925
4835
  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 })
4836
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex gap-2 text-slate-500 mb-1 items-center", children: [
4837
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-[8px]", children: log.time }),
4838
+ /* @__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
4839
  ] }),
4930
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("pre", { className: "whitespace-pre-wrap break-all opacity-90", children: log.content })
4840
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("pre", { className: "whitespace-pre-wrap break-all opacity-90", children: log.content })
4931
4841
  ]
4932
4842
  },
4933
4843
  log.id
@@ -4938,8 +4848,8 @@ var DebugConsole = ({
4938
4848
  };
4939
4849
 
4940
4850
  // src/components/PullToRefresh.tsx
4941
- var import_react16 = require("react");
4942
- var import_jsx_runtime18 = require("react/jsx-runtime");
4851
+ var import_react18 = require("react");
4852
+ var import_jsx_runtime19 = require("react/jsx-runtime");
4943
4853
  var DEFAULT_PULL_THRESHOLD = 64;
4944
4854
  var DEFAULT_MAX_PULL = 96;
4945
4855
  var RESISTANCE = 0.5;
@@ -4950,7 +4860,7 @@ function DefaultIndicator({
4950
4860
  progress,
4951
4861
  isRefreshing
4952
4862
  }) {
4953
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4863
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4954
4864
  "div",
4955
4865
  {
4956
4866
  style: {
@@ -4965,7 +4875,7 @@ function DefaultIndicator({
4965
4875
  width: 28
4966
4876
  },
4967
4877
  children: [
4968
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4878
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4969
4879
  "svg",
4970
4880
  {
4971
4881
  height: 14,
@@ -4977,8 +4887,8 @@ function DefaultIndicator({
4977
4887
  viewBox: "0 0 24 24",
4978
4888
  width: 14,
4979
4889
  children: [
4980
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("title", { children: "Refreshing" }),
4981
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4890
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("title", { children: "Refreshing" }),
4891
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4982
4892
  "path",
4983
4893
  {
4984
4894
  d: "M21 12a9 9 0 1 1-2.64-6.36",
@@ -4991,7 +4901,7 @@ function DefaultIndicator({
4991
4901
  ]
4992
4902
  }
4993
4903
  ),
4994
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("style", { children: "@keyframes up-sdk-ptr-spin { to { transform: rotate(360deg); } }" })
4904
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("style", { children: "@keyframes up-sdk-ptr-spin { to { transform: rotate(360deg); } }" })
4995
4905
  ]
4996
4906
  }
4997
4907
  );
@@ -5005,27 +4915,46 @@ var PullToRefresh = ({
5005
4915
  maxPull = DEFAULT_MAX_PULL,
5006
4916
  renderIndicator
5007
4917
  }) => {
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);
4918
+ const containerRef = (0, import_react18.useRef)(null);
4919
+ const startYRef = (0, import_react18.useRef)(null);
4920
+ const lastYRef = (0, import_react18.useRef)(0);
4921
+ const lastMoveTimeRef = (0, import_react18.useRef)(0);
4922
+ const velocityRef = (0, import_react18.useRef)(0);
4923
+ const pointerIdRef = (0, import_react18.useRef)(null);
4924
+ const isPullingRef = (0, import_react18.useRef)(false);
4925
+ const pullDistanceRef = (0, import_react18.useRef)(0);
4926
+ const flingRafRef = (0, import_react18.useRef)(null);
4927
+ const [pullDistance, setPullDistance] = (0, import_react18.useState)(0);
4928
+ const [isRefreshing, setIsRefreshing] = (0, import_react18.useState)(false);
4929
+ const [isTracking, setIsTracking] = (0, import_react18.useState)(false);
4930
+ const disabledRef = (0, import_react18.useRef)(disabled);
5021
4931
  disabledRef.current = disabled;
5022
- const onRefreshRef = (0, import_react16.useRef)(onRefresh);
4932
+ const onRefreshRef = (0, import_react18.useRef)(onRefresh);
5023
4933
  onRefreshRef.current = onRefresh;
5024
- const pullThresholdRef = (0, import_react16.useRef)(pullThreshold);
4934
+ const pullThresholdRef = (0, import_react18.useRef)(pullThreshold);
5025
4935
  pullThresholdRef.current = pullThreshold;
5026
- const maxPullRef = (0, import_react16.useRef)(maxPull);
4936
+ const maxPullRef = (0, import_react18.useRef)(maxPull);
5027
4937
  maxPullRef.current = maxPull;
5028
- (0, import_react16.useEffect)(() => {
4938
+ (0, import_react18.useEffect)(() => {
4939
+ const el = containerRef.current;
4940
+ if (!el || typeof window === "undefined") return;
4941
+ const checkScrollChain = () => {
4942
+ const noInternalOverflow = el.scrollHeight <= el.clientHeight;
4943
+ const tallerThanViewport = el.clientHeight > window.innerHeight;
4944
+ if (noInternalOverflow && tallerThanViewport) {
4945
+ console.warn(
4946
+ "[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."
4947
+ );
4948
+ }
4949
+ };
4950
+ const raf = requestAnimationFrame(checkScrollChain);
4951
+ window.addEventListener("resize", checkScrollChain);
4952
+ return () => {
4953
+ cancelAnimationFrame(raf);
4954
+ window.removeEventListener("resize", checkScrollChain);
4955
+ };
4956
+ }, []);
4957
+ (0, import_react18.useEffect)(() => {
5029
4958
  const el = containerRef.current;
5030
4959
  if (!el) return;
5031
4960
  const updatePullDistance = (value) => {
@@ -5156,7 +5085,7 @@ var PullToRefresh = ({
5156
5085
  const indicatorHeight = isRefreshing ? pullThreshold : pullDistance;
5157
5086
  const progress = Math.min(indicatorHeight / pullThreshold, 1);
5158
5087
  const isSettling = pullDistance === 0 && !isRefreshing && !isTracking;
5159
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
5088
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
5160
5089
  "div",
5161
5090
  {
5162
5091
  className: `up-sdk-pull-to-refresh ${className}`,
@@ -5167,8 +5096,8 @@ var PullToRefresh = ({
5167
5096
  touchAction: "none"
5168
5097
  },
5169
5098
  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)(
5099
+ /* @__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; }" }),
5100
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5172
5101
  "div",
5173
5102
  {
5174
5103
  style: {
@@ -5181,7 +5110,7 @@ var PullToRefresh = ({
5181
5110
  userSelect: "none",
5182
5111
  width: "100%"
5183
5112
  },
5184
- children: renderIndicator ? renderIndicator({ isRefreshing, progress }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DefaultIndicator, { isRefreshing, progress })
5113
+ children: renderIndicator ? renderIndicator({ isRefreshing, progress }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DefaultIndicator, { isRefreshing, progress })
5185
5114
  }
5186
5115
  ),
5187
5116
  children
@@ -5192,16 +5121,16 @@ var PullToRefresh = ({
5192
5121
 
5193
5122
  // src/components/QRScanner.tsx
5194
5123
  var import_jsqr2 = __toESM(require("jsqr"), 1);
5195
- var import_react17 = require("react");
5196
- var import_jsx_runtime19 = require("react/jsx-runtime");
5124
+ var import_react19 = require("react");
5125
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5197
5126
  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)(() => {
5127
+ const videoRef = (0, import_react19.useRef)(null);
5128
+ const canvasRef = (0, import_react19.useRef)(null);
5129
+ const streamRef = (0, import_react19.useRef)(null);
5130
+ const tickRequestRef = (0, import_react19.useRef)(null);
5131
+ const hasScannedRef = (0, import_react19.useRef)(false);
5132
+ const [isReady, setIsReady] = (0, import_react19.useState)(false);
5133
+ (0, import_react19.useEffect)(() => {
5205
5134
  let cancelled = false;
5206
5135
  hasScannedRef.current = false;
5207
5136
  const cleanup = () => {
@@ -5284,7 +5213,7 @@ function QRScanner({ onScan, onError, className = "" }) {
5284
5213
  cleanup();
5285
5214
  };
5286
5215
  }, []);
5287
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
5216
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
5288
5217
  "div",
5289
5218
  {
5290
5219
  className,
@@ -5296,7 +5225,7 @@ function QRScanner({ onScan, onError, className = "" }) {
5296
5225
  position: "relative"
5297
5226
  },
5298
5227
  children: [
5299
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5228
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5300
5229
  "video",
5301
5230
  {
5302
5231
  playsInline: true,
@@ -5304,8 +5233,8 @@ function QRScanner({ onScan, onError, className = "" }) {
5304
5233
  style: { height: "100%", objectFit: "cover", width: "100%" }
5305
5234
  }
5306
5235
  ),
5307
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
5308
- isReady && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5236
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
5237
+ isReady && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5309
5238
  "div",
5310
5239
  {
5311
5240
  style: {
@@ -5326,30 +5255,30 @@ function QRScanner({ onScan, onError, className = "" }) {
5326
5255
  }
5327
5256
 
5328
5257
  // 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;
5258
+ var import_react20 = require("react");
5259
+ var import_jsx_runtime21 = require("react/jsx-runtime");
5260
+ var SDKContext = (0, import_react20.createContext)({ isMocked: false });
5261
+ var useIsMocked = () => (0, import_react20.useContext)(SDKContext).isMocked;
5333
5262
  var SDKProvider = ({
5334
5263
  children,
5335
5264
  debug = false,
5336
5265
  ...mockerProps
5337
5266
  }) => {
5338
5267
  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: [
5268
+ const value = (0, import_react20.useMemo)(() => ({ isMocked }), [isMocked]);
5269
+ const content = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
5341
5270
  children,
5342
- (debug || isMocked) && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DebugConsole, {})
5271
+ (debug || isMocked) && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DebugConsole, {})
5343
5272
  ] });
5344
5273
  if (isMocked) {
5345
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SDKContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BridgeMocker, { ...mockerProps, children: content }) });
5274
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SDKContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BridgeMocker, { ...mockerProps, children: content }) });
5346
5275
  }
5347
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SDKContext.Provider, { value, children: content });
5276
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SDKContext.Provider, { value, children: content });
5348
5277
  };
5349
5278
 
5350
5279
  // src/components/SwipeCarousel.tsx
5351
- var import_react19 = require("react");
5352
- var import_jsx_runtime21 = require("react/jsx-runtime");
5280
+ var import_react21 = require("react");
5281
+ var import_jsx_runtime22 = require("react/jsx-runtime");
5353
5282
  var DIRECTION_LOCK_THRESHOLD_PX = 8;
5354
5283
  var SWIPE_DISTANCE_THRESHOLD_PX = 40;
5355
5284
  var SWIPE_VELOCITY_THRESHOLD = 0.4;
@@ -5376,28 +5305,28 @@ var SwipeCarousel = ({
5376
5305
  overscan = DEFAULT_OVERSCAN,
5377
5306
  visibleOverscan = DEFAULT_VISIBLE_OVERSCAN
5378
5307
  }) => {
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)(
5308
+ const containerRef = (0, import_react21.useRef)(null);
5309
+ const [containerWidth, setContainerWidth] = (0, import_react21.useState)(0);
5310
+ const [dragX, setDragX] = (0, import_react21.useState)(0);
5311
+ const [dragY, setDragY] = (0, import_react21.useState)(0);
5312
+ const [isDraggingX, setIsDraggingX] = (0, import_react21.useState)(false);
5313
+ const [isDraggingY, setIsDraggingY] = (0, import_react21.useState)(false);
5314
+ const touchStateRef = (0, import_react21.useRef)(null);
5315
+ const [internalIndex, setInternalIndex] = (0, import_react21.useState)(
5387
5316
  () => Math.max(
5388
5317
  0,
5389
5318
  items.findIndex((item) => item.id === activeId)
5390
5319
  )
5391
5320
  );
5392
- const prevActiveIdRef = (0, import_react19.useRef)(activeId);
5393
- const [timingWaiting, setTimingWaiting] = (0, import_react19.useState)(true);
5394
- (0, import_react19.useEffect)(() => {
5321
+ const prevActiveIdRef = (0, import_react21.useRef)(activeId);
5322
+ const [timingWaiting, setTimingWaiting] = (0, import_react21.useState)(true);
5323
+ (0, import_react21.useEffect)(() => {
5395
5324
  const timer = setTimeout(() => {
5396
5325
  setTimingWaiting(false);
5397
5326
  }, 1e3);
5398
5327
  return () => clearTimeout(timer);
5399
5328
  }, []);
5400
- (0, import_react19.useEffect)(() => {
5329
+ (0, import_react21.useEffect)(() => {
5401
5330
  if (activeId !== prevActiveIdRef.current) {
5402
5331
  const idx = items.findIndex((item) => item.id === activeId);
5403
5332
  if (idx !== -1) setInternalIndex(idx);
@@ -5408,7 +5337,7 @@ var SwipeCarousel = ({
5408
5337
  Math.max(internalIndex, 0),
5409
5338
  Math.max(items.length - 1, 0)
5410
5339
  );
5411
- (0, import_react19.useLayoutEffect)(() => {
5340
+ (0, import_react21.useLayoutEffect)(() => {
5412
5341
  const el = containerRef.current;
5413
5342
  if (!el) return;
5414
5343
  const update = () => setContainerWidth(el.clientWidth);
@@ -5526,7 +5455,7 @@ var SwipeCarousel = ({
5526
5455
  };
5527
5456
  const windowStart = Math.max(0, activeIndex - overscan);
5528
5457
  const windowEnd = Math.min(items.length - 1, activeIndex + overscan);
5529
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5458
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5530
5459
  "div",
5531
5460
  {
5532
5461
  className: `relative overflow-hidden touch-pan-y ${className ?? ""}`,
@@ -5535,7 +5464,7 @@ var SwipeCarousel = ({
5535
5464
  onTouchMove: handleTouchMove,
5536
5465
  onTouchStart: handleTouchStart,
5537
5466
  ref: containerRef,
5538
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5467
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5539
5468
  "div",
5540
5469
  {
5541
5470
  className: "relative h-full",
@@ -5550,7 +5479,7 @@ var SwipeCarousel = ({
5550
5479
  const verticalOffset = isActive ? dragY : 0;
5551
5480
  const distance = Math.abs(index - activeIndex);
5552
5481
  const isVisible = distance <= visibleOverscan;
5553
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5482
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5554
5483
  "div",
5555
5484
  {
5556
5485
  className: `absolute top-0 left-0 h-full shrink-0 ${itemClassName ?? ""} ${item.className ?? ""}`,
@@ -5578,6 +5507,40 @@ var SwipeCarousel = ({
5578
5507
  );
5579
5508
  };
5580
5509
 
5510
+ // src/hooks/useTapAction.ts
5511
+ var import_react22 = require("react");
5512
+ var TAP_MOVE_TOLERANCE_PX = 10;
5513
+ var CLICK_SUPPRESS_WINDOW_MS = 500;
5514
+ var useTapAction = (action) => {
5515
+ const startRef = (0, import_react22.useRef)(null);
5516
+ const handledByTouchRef = (0, import_react22.useRef)(false);
5517
+ const onTouchStart = (e) => {
5518
+ const touch = e.targetTouches[0];
5519
+ startRef.current = touch ? { x: touch.clientX, y: touch.clientY } : null;
5520
+ };
5521
+ const onTouchEnd = (e) => {
5522
+ const start = startRef.current;
5523
+ const touch = e.changedTouches[0];
5524
+ startRef.current = null;
5525
+ if (!start || !touch) return;
5526
+ const moved = Math.hypot(touch.clientX - start.x, touch.clientY - start.y);
5527
+ if (moved > TAP_MOVE_TOLERANCE_PX) return;
5528
+ handledByTouchRef.current = true;
5529
+ setTimeout(() => {
5530
+ handledByTouchRef.current = false;
5531
+ }, CLICK_SUPPRESS_WINDOW_MS);
5532
+ action();
5533
+ };
5534
+ const onClick = () => {
5535
+ if (handledByTouchRef.current) {
5536
+ handledByTouchRef.current = false;
5537
+ return;
5538
+ }
5539
+ action();
5540
+ };
5541
+ return { onClick, onTouchEnd, onTouchStart };
5542
+ };
5543
+
5581
5544
  // src/host/routingHandler.ts
5582
5545
  async function handleRouteRequest(req, config) {
5583
5546
  return RoutingService.fetchRoute(req, config);
@@ -5911,6 +5874,7 @@ var src_default = sdk;
5911
5874
  useMapControls,
5912
5875
  useMockLocation,
5913
5876
  useRoute,
5877
+ useTapAction,
5914
5878
  useTrimmedRoute,
5915
5879
  useUserLocation
5916
5880
  });