@loafmarkets/ui 0.1.412 → 0.1.414

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.mjs CHANGED
@@ -2550,6 +2550,66 @@ function MobileDepthRow({
2550
2550
  }
2551
2551
  );
2552
2552
  }
2553
+ var isHlsManifest = (url) => /\.m3u8(\?|$)/i.test(url);
2554
+ var HLS_MIME = "application/vnd.apple.mpegurl";
2555
+ var MANIFEST_FAILURES = /* @__PURE__ */ new Set(["manifestLoadError", "manifestLoadTimeOut", "manifestParsingError"]);
2556
+ var HlsVideo = React5.forwardRef(
2557
+ ({ src, capLevelToPlayerSize = true, onError, ...videoProps }, ref) => {
2558
+ const videoRef = React5.useRef(null);
2559
+ React5.useImperativeHandle(ref, () => videoRef.current, []);
2560
+ const primary = typeof src === "string" ? src : src.src;
2561
+ const fallbackSrc = typeof src === "string" ? void 0 : src.fallbackSrc;
2562
+ const [failedSrc, setFailedSrc] = React5.useState(null);
2563
+ const usingFallback = fallbackSrc != null && failedSrc === primary;
2564
+ const activeSrc = usingFallback ? fallbackSrc : primary;
2565
+ const failPrimary = React5.useCallback(() => {
2566
+ if (fallbackSrc == null) return;
2567
+ setFailedSrc(primary);
2568
+ }, [fallbackSrc, primary]);
2569
+ React5.useEffect(() => {
2570
+ const video = videoRef.current;
2571
+ if (!video || !activeSrc) return;
2572
+ if (!isHlsManifest(activeSrc) || video.canPlayType(HLS_MIME)) {
2573
+ video.src = activeSrc;
2574
+ return;
2575
+ }
2576
+ let hls = null;
2577
+ let cancelled = false;
2578
+ void import('hls.js').then(({ default: Hls }) => {
2579
+ if (cancelled) return;
2580
+ if (!Hls.isSupported()) {
2581
+ video.src = activeSrc;
2582
+ return;
2583
+ }
2584
+ const instance = new Hls({
2585
+ capLevelToPlayerSize,
2586
+ startLevel: -1,
2587
+ enableWorker: true,
2588
+ startFragPrefetch: true
2589
+ });
2590
+ hls = instance;
2591
+ instance.on(Hls.Events.ERROR, (_evt, data) => {
2592
+ if (data?.fatal && MANIFEST_FAILURES.has(String(data.details))) failPrimary();
2593
+ });
2594
+ instance.loadSource(activeSrc);
2595
+ instance.attachMedia(video);
2596
+ });
2597
+ return () => {
2598
+ cancelled = true;
2599
+ hls?.destroy();
2600
+ };
2601
+ }, [activeSrc, capLevelToPlayerSize, failPrimary]);
2602
+ const handleError = React5.useCallback(
2603
+ (e) => {
2604
+ if (!usingFallback) failPrimary();
2605
+ onError?.(e);
2606
+ },
2607
+ [usingFallback, failPrimary, onError]
2608
+ );
2609
+ return /* @__PURE__ */ jsx("video", { ref: videoRef, onError: handleError, ...videoProps });
2610
+ }
2611
+ );
2612
+ HlsVideo.displayName = "HlsVideo";
2553
2613
  var PropertyTour = React5.forwardRef(
2554
2614
  ({
2555
2615
  className,
@@ -2564,11 +2624,6 @@ var PropertyTour = React5.forwardRef(
2564
2624
  ...props
2565
2625
  }, ref) => {
2566
2626
  const videoRef = React5.useRef(null);
2567
- React5.useEffect(() => {
2568
- if (videoRef.current && src) {
2569
- videoRef.current.load();
2570
- }
2571
- }, [src]);
2572
2627
  React5.useEffect(() => {
2573
2628
  const video = videoRef.current;
2574
2629
  if (!video) return;
@@ -2633,10 +2688,11 @@ var PropertyTour = React5.forwardRef(
2633
2688
  display: none !important;
2634
2689
  }
2635
2690
  ` }),
2636
- /* @__PURE__ */ jsxs(
2637
- "video",
2691
+ /* @__PURE__ */ jsx(
2692
+ HlsVideo,
2638
2693
  {
2639
2694
  ref: videoRef,
2695
+ src,
2640
2696
  className: "loaf-muted-video absolute inset-0 h-full w-full object-cover object-center",
2641
2697
  controls,
2642
2698
  controlsList: "nodownload noplaybackrate",
@@ -2650,10 +2706,7 @@ var PropertyTour = React5.forwardRef(
2650
2706
  muted,
2651
2707
  playsInline,
2652
2708
  poster,
2653
- children: [
2654
- /* @__PURE__ */ jsx("source", { src }),
2655
- "Your browser does not support the video tag."
2656
- ]
2709
+ children: "Your browser does not support the video tag."
2657
2710
  }
2658
2711
  )
2659
2712
  ] }) })
@@ -9772,8 +9825,9 @@ function GalleryMapSection({
9772
9825
  isMobile ? /* @__PURE__ */ jsx(StackedGallery, { images, onPhotoClick }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9773
9826
  /* @__PURE__ */ jsxs(Carousel, { children: [
9774
9827
  showVideo && videoUrl && /* @__PURE__ */ jsx(VideoOverlay, { children: /* @__PURE__ */ jsx(
9775
- "video",
9828
+ HlsVideo,
9776
9829
  {
9830
+ src: videoUrl,
9777
9831
  autoPlay: true,
9778
9832
  loop: true,
9779
9833
  playsInline: true,
@@ -9782,8 +9836,7 @@ function GalleryMapSection({
9782
9836
  onVolumeChange: (e) => {
9783
9837
  if (!e.currentTarget.muted) e.currentTarget.muted = true;
9784
9838
  },
9785
- style: { width: "100%", height: "100%", objectFit: "cover", borderRadius: 8 },
9786
- children: /* @__PURE__ */ jsx("source", { src: videoUrl, type: "video/mp4" })
9839
+ style: { width: "100%", height: "100%", objectFit: "cover", borderRadius: 8 }
9787
9840
  }
9788
9841
  ) }),
9789
9842
  /* @__PURE__ */ jsx(Track, { style: { transform: `translateX(-${carouselIndex * 100}%)` }, children: images.map((img, idx) => /* @__PURE__ */ jsxs(Slide, { onClick: () => onPhotoClick?.(idx), children: [
@@ -9899,7 +9952,7 @@ function GalleryMapSection({
9899
9952
  showFullVideo && videoUrl && /* @__PURE__ */ jsxs(FullVideoOverlay, { onClick: () => setShowFullVideo(false), children: [
9900
9953
  /* @__PURE__ */ jsx(FullVideoClose, { onClick: () => setShowFullVideo(false), "aria-label": "Close video", children: "\u2715" }),
9901
9954
  /* @__PURE__ */ jsx(
9902
- "video",
9955
+ HlsVideo,
9903
9956
  {
9904
9957
  src: videoUrl,
9905
9958
  autoPlay: true,
@@ -15097,6 +15150,9 @@ var STATUS_COLOR2 = {
15097
15150
  CLOSED: "#848e9c",
15098
15151
  CANCELLED: "#f6465d"
15099
15152
  };
15153
+ var STUCK_SETTLING_MS = 7e3;
15154
+ var SETTLING_MESSAGE = "Trade settling on-chain";
15155
+ var STUCK_SETTLING_MESSAGE = "Attention: Trade taking longer than usual to settle on chain. Please wait up to 10 seconds before trading. This is reflected in your locked balance.";
15100
15156
  var settlingSpin = keyframes`
15101
15157
  to { transform: rotate(360deg); }
15102
15158
  `;
@@ -15110,41 +15166,55 @@ var SettlingSpinner = styled10.span`
15110
15166
  animation: ${settlingSpin} 0.7s linear infinite;
15111
15167
  flex-shrink: 0;
15112
15168
  `;
15169
+ var StuckSettlingGlyph = styled10.span`
15170
+ display: inline-block;
15171
+ font-size: 11px;
15172
+ line-height: 1;
15173
+ flex-shrink: 0;
15174
+ `;
15113
15175
  var SettlingTip = styled10.span`
15114
15176
  position: relative;
15115
15177
  display: inline-flex;
15116
15178
  align-items: center;
15117
15179
  cursor: help;
15118
- &::after {
15119
- content: 'Trade settling on-chain';
15120
- position: absolute;
15121
- left: 50%;
15122
- bottom: calc(100% + 8px);
15123
- transform: translateX(-50%) translateY(3px);
15124
- padding: 6px 8px;
15125
- background: rgba(20, 22, 28, 0.97);
15126
- border: 1px solid rgba(255, 255, 255, 0.1);
15127
- border-radius: 6px;
15128
- color: rgba(255, 255, 255, 0.78);
15129
- font-size: 0.66rem;
15130
- font-weight: 400;
15131
- line-height: 1.3;
15132
- letter-spacing: normal;
15133
- text-transform: none;
15134
- white-space: nowrap;
15135
- box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
15136
- opacity: 0;
15137
- visibility: hidden;
15138
- transition: opacity 0.15s ease, transform 0.15s ease;
15139
- pointer-events: none;
15140
- z-index: 2000;
15141
- }
15142
- &:hover::after {
15180
+ `;
15181
+ var SettlingTipBubble = styled10.span`
15182
+ position: absolute;
15183
+ bottom: calc(100% + 8px);
15184
+ /* Stuck copy is a paragraph, so it anchors to the icon's left edge instead of
15185
+ centring centred it would hang off the left of the row. */
15186
+ left: ${(p) => p.$stuck ? "0" : "50%"};
15187
+ transform: ${(p) => p.$stuck ? "translateX(0)" : "translateX(-50%)"} translateY(3px);
15188
+ width: ${(p) => p.$stuck ? "224px" : "auto"};
15189
+ white-space: ${(p) => p.$stuck ? "normal" : "nowrap"};
15190
+ padding: 6px 8px;
15191
+ background: rgba(20, 22, 28, 0.97);
15192
+ border: 1px solid rgba(255, 255, 255, 0.1);
15193
+ border-radius: 6px;
15194
+ color: rgba(255, 255, 255, 0.78);
15195
+ font-size: 0.66rem;
15196
+ font-weight: 400;
15197
+ line-height: 1.35;
15198
+ letter-spacing: normal;
15199
+ text-transform: none;
15200
+ text-align: left;
15201
+ box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
15202
+ opacity: 0;
15203
+ visibility: hidden;
15204
+ transition: opacity 0.15s ease, transform 0.15s ease;
15205
+ pointer-events: none;
15206
+ z-index: 2000;
15207
+
15208
+ ${SettlingTip}:hover & {
15143
15209
  opacity: 1;
15144
15210
  visibility: visible;
15145
- transform: translateX(-50%) translateY(0);
15211
+ transform: ${(p) => p.$stuck ? "translateX(0)" : "translateX(-50%)"} translateY(0);
15146
15212
  }
15147
15213
  `;
15214
+ var SettlingIndicator = ({ stuck, style }) => /* @__PURE__ */ jsxs(SettlingTip, { role: "img", "aria-label": stuck ? "Settlement delayed" : SETTLING_MESSAGE, style, children: [
15215
+ stuck ? /* @__PURE__ */ jsx(StuckSettlingGlyph, { "aria-hidden": "true", children: "\u26A0\uFE0F" }) : /* @__PURE__ */ jsx(SettlingSpinner, { "aria-hidden": "true" }),
15216
+ /* @__PURE__ */ jsx(SettlingTipBubble, { $stuck: stuck, children: stuck ? STUCK_SETTLING_MESSAGE : SETTLING_MESSAGE })
15217
+ ] });
15148
15218
  var ACTIVITY_PAGE_SIZE_DEFAULT = 8;
15149
15219
  var formatCurrency4 = (value, opts) => {
15150
15220
  const min = opts?.minimumFractionDigits ?? 2;
@@ -15152,14 +15222,21 @@ var formatCurrency4 = (value, opts) => {
15152
15222
  return `$${value.toLocaleString("en-US", { minimumFractionDigits: min, maximumFractionDigits: max })}`;
15153
15223
  };
15154
15224
  var formatNumber2 = (value, maximumFractionDigits = 2) => value.toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits });
15225
+ var toMillis = (unix) => {
15226
+ if (unix > 1e18) return Math.floor(unix / 1e6);
15227
+ if (unix > 1e14) return Math.floor(unix / 1e3);
15228
+ if (unix > 1e12) return unix;
15229
+ return unix * 1e3;
15230
+ };
15231
+ var SETTLED_TRADE_STATUSES = ["SETTLED", "CONFIRMED", "FILLED", "ALLOCATED"];
15232
+ var FAILED_TRADE_STATUSES = ["SETTLEMENT_FAILED", "REJECTED", "CANCELLED", "CANCELED"];
15233
+ var tradeIsSettling = (status) => {
15234
+ const s = status?.toUpperCase();
15235
+ return !!s && !SETTLED_TRADE_STATUSES.includes(s) && !FAILED_TRADE_STATUSES.includes(s);
15236
+ };
15155
15237
  var formatTimestamp = (unix) => {
15156
15238
  if (!unix) return "\u2014";
15157
- let sec;
15158
- if (unix > 1e18) sec = Math.floor(unix / 1e9);
15159
- else if (unix > 1e14) sec = Math.floor(unix / 1e6);
15160
- else if (unix > 1e12) sec = Math.floor(unix / 1e3);
15161
- else sec = unix;
15162
- return new Date(sec * 1e3).toLocaleString("en-AU", {
15239
+ return new Date(toMillis(unix)).toLocaleString("en-AU", {
15163
15240
  day: "2-digit",
15164
15241
  month: "short",
15165
15242
  hour: "2-digit",
@@ -15223,6 +15300,40 @@ function PortfolioActivityPanel({
15223
15300
  const [closeAllOpen, setCloseAllOpen] = useState(false);
15224
15301
  const [closeAllType, setCloseAllType] = useState("market");
15225
15302
  const [closingAll, setClosingAll] = useState(false);
15303
+ const settlingPositionIds = positions.filter((p) => p.settling).map((p) => p.propertyId);
15304
+ const settlingKey = settlingPositionIds.join(",");
15305
+ const settlingTradeStartByProperty = /* @__PURE__ */ new Map();
15306
+ const settlingTradeDeadlines = [];
15307
+ for (const trade of tradeHistory) {
15308
+ if (!tradeIsSettling(trade.status)) continue;
15309
+ const startedAt = toMillis(trade.executedAt);
15310
+ settlingTradeDeadlines.push(startedAt + STUCK_SETTLING_MS);
15311
+ const earliest = settlingTradeStartByProperty.get(trade.propertyId);
15312
+ if (earliest === void 0 || startedAt < earliest) settlingTradeStartByProperty.set(trade.propertyId, startedAt);
15313
+ }
15314
+ const tradeDeadlineKey = settlingTradeDeadlines.join(",");
15315
+ const settlingSinceRef = useRef(/* @__PURE__ */ new Map());
15316
+ const [now, setNow] = useState(() => Date.now());
15317
+ useEffect(() => {
15318
+ const since = settlingSinceRef.current;
15319
+ const seenAt = Date.now();
15320
+ for (const id of settlingPositionIds) if (!since.has(id)) since.set(id, seenAt);
15321
+ for (const id of [...since.keys()]) if (!settlingPositionIds.includes(id)) since.delete(id);
15322
+ setNow(seenAt);
15323
+ }, [settlingKey]);
15324
+ const positionSettlingStart = (propertyId) => settlingTradeStartByProperty.get(propertyId) ?? settlingSinceRef.current.get(propertyId) ?? now;
15325
+ useEffect(() => {
15326
+ const pending = [
15327
+ ...settlingPositionIds.map((id) => positionSettlingStart(id) + STUCK_SETTLING_MS),
15328
+ ...settlingTradeDeadlines
15329
+ ].filter((deadline) => deadline > now);
15330
+ if (pending.length === 0) return;
15331
+ const delay = Math.min(Math.min(...pending) - now + 50, 2147483647);
15332
+ const timer = setTimeout(() => setNow(Date.now()), delay);
15333
+ return () => clearTimeout(timer);
15334
+ }, [settlingKey, tradeDeadlineKey, now]);
15335
+ const isPositionStuck = (pos) => !!pos.settling && now - positionSettlingStart(pos.propertyId) >= STUCK_SETTLING_MS;
15336
+ const isTradeStuck = (trade) => now - toMillis(trade.executedAt) >= STUCK_SETTLING_MS;
15226
15337
  const hasPositionActions = !!(onClosePosition || onSharePosition || onCloseAllPositions);
15227
15338
  const [posSortKey, setPosSortKey] = useState("asset");
15228
15339
  const [posSortAsc, setPosSortAsc] = useState(true);
@@ -15477,7 +15588,7 @@ function PortfolioActivityPanel({
15477
15588
  /* @__PURE__ */ jsx(CCellLabel, { children: "Asset" }),
15478
15589
  /* @__PURE__ */ jsxs(CAssetName, { children: [
15479
15590
  pos.tokenName,
15480
- pos.settling && /* @__PURE__ */ jsx(SettlingTip, { style: { marginLeft: 6 }, children: /* @__PURE__ */ jsx(SettlingSpinner, {}) })
15591
+ pos.settling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: isPositionStuck(pos), style: { marginLeft: 6 } })
15481
15592
  ] })
15482
15593
  ] }),
15483
15594
  /* @__PURE__ */ jsxs(CUnitsCell, { children: [
@@ -15569,7 +15680,7 @@ function PortfolioActivityPanel({
15569
15680
  return /* @__PURE__ */ jsxs(PositionsRow, { $hasClose: hasPositionActions, children: [
15570
15681
  /* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
15571
15682
  /* @__PURE__ */ jsx(HoldingsPropertyLink, { onClick: () => onPositionClick?.(pos.tokenName, pos.isIpoAllocation), children: pos.tokenName }),
15572
- pos.settling && /* @__PURE__ */ jsx(SettlingTip, { children: /* @__PURE__ */ jsx(SettlingSpinner, {}) })
15683
+ pos.settling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: isPositionStuck(pos) })
15573
15684
  ] }) }),
15574
15685
  /* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsxs("span", { style: { color: "#fff", fontSize: "0.8rem" }, children: [
15575
15686
  formatNumber2(pos.totalQuantity),
@@ -15950,7 +16061,8 @@ function PortfolioActivityPanel({
15950
16061
  const s = trade.status?.toUpperCase();
15951
16062
  const isSettled = s === "SETTLED" || s === "CONFIRMED" || s === "FILLED" || s === "ALLOCATED";
15952
16063
  const isFailed = s === "SETTLEMENT_FAILED" || s === "REJECTED" || s === "CANCELLED" || s === "CANCELED";
15953
- const isSettling = !isSettled && !isFailed && !!trade.status;
16064
+ const isSettling = tradeIsSettling(trade.status);
16065
+ const stuckSettling = isSettling && isTradeStuck(trade);
15954
16066
  const settlementLabel = isSettled ? "Settled" : isFailed ? "Settlement Failed" : isSettling ? prettyLabel(trade.status) : "\u2014";
15955
16067
  const settlementMeta = isSettled ? { color: "#0ecb81", bg: "rgba(14,203,129,0.1)" } : isFailed ? { color: "#f6465d", bg: "rgba(246,70,93,0.12)" } : isSettling ? { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" } : null;
15956
16068
  const sideColor = sideLabel(trade.side) === "Buy" ? "#0ecb81" : "#f6465d";
@@ -15993,7 +16105,10 @@ function PortfolioActivityPanel({
15993
16105
  ] }),
15994
16106
  /* @__PURE__ */ jsxs(CDetailItem, { children: [
15995
16107
  /* @__PURE__ */ jsx(CDLabel, { children: "Settlement" }),
15996
- /* @__PURE__ */ jsx(CDValue, { children: settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : "\u2014" })
16108
+ /* @__PURE__ */ jsxs(CDValue, { children: [
16109
+ settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : "\u2014",
16110
+ stuckSettling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: true, style: { marginLeft: 6 } })
16111
+ ] })
15997
16112
  ] }),
15998
16113
  /* @__PURE__ */ jsxs(CDetailItem, { children: [
15999
16114
  /* @__PURE__ */ jsx(CDLabel, { children: "Date" }),
@@ -16018,7 +16133,8 @@ function PortfolioActivityPanel({
16018
16133
  const s = trade.status?.toUpperCase();
16019
16134
  const isSettled = s === "SETTLED" || s === "CONFIRMED" || s === "FILLED" || s === "ALLOCATED";
16020
16135
  const isFailed = s === "SETTLEMENT_FAILED" || s === "REJECTED" || s === "CANCELLED" || s === "CANCELED";
16021
- const isSettling = !isSettled && !isFailed && !!trade.status;
16136
+ const isSettling = tradeIsSettling(trade.status);
16137
+ const stuckSettling = isSettling && isTradeStuck(trade);
16022
16138
  const settlementLabel = isSettled ? "Settled" : isFailed ? "Settlement Failed" : isSettling ? prettyLabel(trade.status) : "\u2014";
16023
16139
  const settlementMeta = isSettled ? { color: "#0ecb81", bg: "rgba(14,203,129,0.1)" } : isFailed ? { color: "#f6465d", bg: "rgba(246,70,93,0.12)" } : isSettling ? { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" } : null;
16024
16140
  const sideColor = sideLabel(trade.side) === "Buy" ? "#0ecb81" : "#f6465d";
@@ -16035,7 +16151,10 @@ function PortfolioActivityPanel({
16035
16151
  ] }) }),
16036
16152
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { children: formatCurrency4(trade.price) }) }),
16037
16153
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { children: formatCurrency4(trade.price * trade.quantity) }) }),
16038
- /* @__PURE__ */ jsx(GridCell, { children: settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : /* @__PURE__ */ jsx(CellText, { $muted: true, children: "\u2014" }) }),
16154
+ /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
16155
+ settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : /* @__PURE__ */ jsx(CellText, { $muted: true, children: "\u2014" }),
16156
+ stuckSettling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: true })
16157
+ ] }) }),
16039
16158
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: formatTimestamp(trade.executedAt) }) }),
16040
16159
  /* @__PURE__ */ jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
16041
16160
  /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
@@ -19563,8 +19682,9 @@ function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subt
19563
19682
  }
19564
19683
  ),
19565
19684
  showVideo && videoUrl ? /* @__PURE__ */ jsx(GalleryVideoWrap, { children: /* @__PURE__ */ jsx(
19566
- "video",
19685
+ HlsVideo,
19567
19686
  {
19687
+ src: videoUrl,
19568
19688
  autoPlay: true,
19569
19689
  loop: true,
19570
19690
  playsInline: true,
@@ -19573,8 +19693,7 @@ function GalleryContent({ galleryImages, startIndex, startWithVideo, title, subt
19573
19693
  onVolumeChange: (e) => {
19574
19694
  if (!e.currentTarget.muted) e.currentTarget.muted = true;
19575
19695
  },
19576
- style: { objectFit: "contain", borderRadius: 12, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" },
19577
- children: /* @__PURE__ */ jsx("source", { src: videoUrl, type: "video/mp4" })
19696
+ style: { objectFit: "contain", borderRadius: 12, boxShadow: "0 30px 80px rgba(0,0,0,0.55)" }
19578
19697
  }
19579
19698
  ) }) : galleryImages.map((image, idx) => /* @__PURE__ */ jsx(MainImage, { src: image.src, alt: image.alt, $visible: idx === currentIndex }, image.alt)),
19580
19699
  galleryImages[currentIndex]?.hotspots?.map((hotspot) => /* @__PURE__ */ jsx(
@@ -20584,6 +20703,6 @@ var SparklineChart = React5__default.memo(function SparklineChart2({ data, width
20584
20703
  );
20585
20704
  });
20586
20705
 
20587
- export { AssetSelectorBar, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ContactPopup, Header, HousePositionSlider, HousePositionSliderMobile, LoafLiquidityBadge, LoafLiquidityLogo, LoginPopup, MobileTradeNav, OfferingProgressCard, OnboardingGuide, Orderbook, owner_booking_default as OwnerBooking, PaymentPopup, PortfolioActivityPanel, PortfolioSummary, PriceChart, PropertyBuy, PropertyCompareBar, PropertyDocuments, PropertyHeroHeader, PropertyHistory, PropertyInspectionTimes, PropertyMediaRow, PropertyNewsUpdates, PropertyOffers, PropertyOverview, PropertyPhotoGallery, PropertySubheader, PropertyTour, PropertyValuation, SiteFooter, Skeleton, SlideDigit, SparklineChart, ToastProvider, TradeConfirmationModal, TradingSlider, YourOrders, badgeVariants, buttonVariants, extractSparkline, hasPendingActivity, useAdaptivePolling, useToast };
20706
+ export { AssetSelectorBar, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ContactPopup, Header, HlsVideo, HousePositionSlider, HousePositionSliderMobile, LoafLiquidityBadge, LoafLiquidityLogo, LoginPopup, MobileTradeNav, OfferingProgressCard, OnboardingGuide, Orderbook, owner_booking_default as OwnerBooking, PaymentPopup, PortfolioActivityPanel, PortfolioSummary, PriceChart, PropertyBuy, PropertyCompareBar, PropertyDocuments, PropertyHeroHeader, PropertyHistory, PropertyInspectionTimes, PropertyMediaRow, PropertyNewsUpdates, PropertyOffers, PropertyOverview, PropertyPhotoGallery, PropertySubheader, PropertyTour, PropertyValuation, SiteFooter, Skeleton, SlideDigit, SparklineChart, ToastProvider, TradeConfirmationModal, TradingSlider, YourOrders, badgeVariants, buttonVariants, extractSparkline, hasPendingActivity, useAdaptivePolling, useToast };
20588
20707
  //# sourceMappingURL=index.mjs.map
20589
20708
  //# sourceMappingURL=index.mjs.map