@aiquants/virtualscroll 1.1.0 → 1.3.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/README.md CHANGED
@@ -95,6 +95,7 @@ function App() {
95
95
  | `initialScrollIndex` | `number` | ❌ | Initial scroll index |
96
96
  | `initialScrollOffset` | `number` | ❌ | Initial scroll offset |
97
97
  | `tapScrollCircleOptions` | `ScrollBarTapCircleOptions` | ❌ | Customization for the auxiliary tap scroll circle |
98
+ | `renderThumbOverlay` | `(props: ScrollBarThumbOverlayRenderProps) => ReactNode` | ❌ | Render prop to anchor custom UI near the scrollbar thumb |
98
99
  | `inertiaOptions` | `ScrollPaneInertiaOptions` | ❌ | Physics tuning for drag inertia |
99
100
 
100
101
  ### VirtualScrollHandle Methods
@@ -114,11 +115,21 @@ function App() {
114
115
  ### With Ref and Scroll Control
115
116
 
116
117
  ```tsx
117
- import { VirtualScroll, VirtualScrollHandle } from '@aiquants/virtualscroll'
118
- import { useRef } from 'react'
118
+ import { ScrollBarThumbOverlayRenderProps, VirtualScroll, VirtualScrollHandle } from '@aiquants/virtualscroll'
119
+ import { useCallback, useRef, useState } from 'react'
120
+
121
+ const items = Array.from({ length: 100000 }, (_, index) => ({
122
+ id: index,
123
+ text: `Item ${index}`,
124
+ height: (index % 20) * 2 + 30,
125
+ }))
126
+
127
+ const getItem = (index: number) => items[index]
128
+ const getItemHeight = (index: number) => items[index].height
119
129
 
120
130
  function AdvancedExample() {
121
131
  const virtualScrollRef = useRef<VirtualScrollHandle>(null)
132
+ const [visibleStartIndex, setVisibleStartIndex] = useState(0)
122
133
 
123
134
  const scrollToTop = () => {
124
135
  virtualScrollRef.current?.scrollTo(0)
@@ -128,6 +139,40 @@ function AdvancedExample() {
128
139
  virtualScrollRef.current?.scrollToIndex(index)
129
140
  }
130
141
 
142
+ const handleRangeChange = useCallback((
143
+ _renderingStartIndex: number,
144
+ _renderingEndIndex: number,
145
+ visibleStart: number,
146
+ _visibleEndIndex: number,
147
+ _scrollPosition: number,
148
+ _totalHeight: number,
149
+ ) => {
150
+ setVisibleStartIndex(visibleStart)
151
+ }, [])
152
+
153
+ const renderThumbOverlay = useCallback((props: ScrollBarThumbOverlayRenderProps) => {
154
+ if (!(props.isDragging || props.isTapScrollActive)) {
155
+ return null
156
+ }
157
+ const activeItem = items[visibleStartIndex]
158
+ const label = activeItem ? activeItem.text : `Item ${visibleStartIndex}`
159
+
160
+ return (
161
+ <div
162
+ className="pointer-events-none absolute flex items-center"
163
+ style={
164
+ props.orientation === 'vertical'
165
+ ? { top: props.thumbCenter, left: -14, transform: 'translate(-100%, -50%)' }
166
+ : { left: props.thumbCenter, top: -14, transform: 'translate(-50%, -100%)' }
167
+ }
168
+ >
169
+ <div className="rounded-full border border-slate-200 bg-white px-2 py-1 text-xs font-medium text-slate-700 shadow-md">
170
+ {label}
171
+ </div>
172
+ </div>
173
+ )
174
+ }, [visibleStartIndex])
175
+
131
176
  return (
132
177
  <div>
133
178
  <div>
@@ -136,13 +181,12 @@ function AdvancedExample() {
136
181
  </div>
137
182
  <VirtualScroll
138
183
  ref={virtualScrollRef}
139
- itemCount={100000}
184
+ itemCount={items.length}
140
185
  getItem={getItem}
141
186
  getItemHeight={getItemHeight}
142
187
  viewportSize={400}
143
- onRangeChange={(start, end) => {
144
- console.log(`Visible range: ${start} - ${end}`)
145
- }}
188
+ onRangeChange={handleRangeChange}
189
+ renderThumbOverlay={renderThumbOverlay}
146
190
  >
147
191
  {(item, index) => <ItemComponent item={item} index={index} />}
148
192
  </VirtualScroll>
@@ -182,6 +226,7 @@ The auxiliary tap scroll circle can replace the native scrollbar for large datas
182
226
 
183
227
  - **Adaptive speed scaling** automatically ramps up to a `120×` multiplier as `itemCount` grows (trillions supported).
184
228
  - **Manual overrides** let you clamp or extend speed via `maxSpeedMultiplier` when you need deterministic behavior.
229
+ - **Exponential capping** enables distance-sensitive ceilings with `maxSpeedCurve`, blending gentle near-threshold drag with high-speed travel at extended distances. Use `easedOffset` to slightly raise the entry-level speed without changing the ceiling.
185
230
  - **Full layout control** (`size`, `offsetX`, `offsetY`) keeps the circle accessible on both desktop and touch devices.
186
231
  - **Visibility tuning** exposes an `opacity` knob so you can match subdued or high-contrast UI themes.
187
232
 
@@ -203,6 +248,11 @@ export function UltraFastExample() {
203
248
  viewportSize={480}
204
249
  tapScrollCircleOptions={{
205
250
  maxSpeedMultiplier: 80, // Optional: override adaptive speed when needed
251
+ maxSpeedCurve: {
252
+ exponentialSteepness: 6,
253
+ exponentialScale: 80,
254
+ easedOffset: 0.1,
255
+ },
206
256
  offsetX: -96,
207
257
  opacity: 0.85,
208
258
  }}
package/dist/index.cjs CHANGED
@@ -1,2 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const E=require("react/jsx-runtime"),n=require("react"),be=require("tailwind-merge"),Ne={active:!1,offsetX:0,offsetY:0,distance:0,direction:0},Oe=6,et=({dragState:a,normalizedDistance:e})=>{const t=1+e*.18,s=.16+e*.24,r=.38+e*.28,i=a.active?"80ms ease-out":"220ms ease";return E.jsxs(E.Fragment,{children:[E.jsx("div",{className:"absolute inset-0 rounded-full",style:{background:"linear-gradient(140deg, rgba(255,255,255,0.62), rgba(72,72,72,0.48))",boxShadow:`0 0 0 1px rgba(255,255,255,0.28), 0 10px 22px rgba(0,0,0,${s})`,transform:`scale(${t})`,transition:`${i}, ${a.active?"80ms":"260ms"} box-shadow ease`}}),E.jsx("div",{className:"absolute inset-[18%] rounded-full",style:{background:"linear-gradient(140deg, rgba(255,255,255,0.72), rgba(28,28,28,0.58))",boxShadow:"inset 0 4px 10px rgba(0,0,0,0.24), inset 0 0 2px rgba(255,255,255,0.55)",opacity:r,transition:a.active?"120ms opacity ease-out":"220ms opacity ease"}})]})},Xe=n.forwardRef(({onDragChange:a,className:e,maxVisualDistance:t=160,size:s=40,style:r,opacity:i=1,renderVisual:c},l)=>{const[m,d]=n.useState(Ne),f=n.useRef(null),g=n.useRef({x:0,y:0}),A=n.useRef(null),V=n.useCallback(p=>{d(p),a(p)},[a]),H=n.useCallback((p,D,h=!1)=>{const{x:k,y:x}=g.current,N=p-k,L=D-x,F=Math.abs(L),R=F<Oe?0:L<0?-1:1;V({active:h||F>=Oe,offsetX:N,offsetY:L,distance:F,direction:R})},[V]),Q=n.useCallback(p=>{if(p===null)return;const D=A.current;D?.hasPointerCapture(p)&&D.releasePointerCapture(p)},[]),T=n.useCallback((p=!1)=>{p&&Q(f.current),f.current=null,V(Ne)},[V,Q]),oe=n.useCallback(p=>{p.preventDefault(),p.stopPropagation();const D=A.current??p.currentTarget,{left:h,top:k,width:x,height:N}=D.getBoundingClientRect();g.current={x:h+x/2,y:k+N/2},f.current=p.pointerId,D.setPointerCapture(p.pointerId),H(p.clientX,p.clientY,!0)},[H]),ae=n.useCallback(p=>{f.current===p.pointerId&&(p.preventDefault(),H(p.clientX,p.clientY))},[H]),G=n.useCallback(p=>{f.current===p.pointerId&&(p.preventDefault(),p.stopPropagation(),T(!0))},[T]);n.useImperativeHandle(l,()=>({reset:()=>{T(!0)},getElement:()=>A.current}),[T]);const _=Math.min(Math.max(i,0),1),$=s/64,O=Math.min(m.distance,t)/t,b=m.direction*O*10*$,P=c??et,S={dragState:m,normalizedDistance:O,sizeScale:$,size:s,opacity:_},j={...r,width:s,height:s,transform:`translateY(${b}px)`};return j.opacity=_,E.jsx("div",{ref:A,className:be.twMerge("relative flex touch-none select-none items-center justify-center","transition-transform duration-100 ease-out",e),style:j,onPointerDown:oe,onPointerMove:ae,onPointerUp:G,onPointerCancel:G,role:"presentation",children:P(S)})});Xe.displayName="TapScrollCircle";const U=(a,e,t)=>Math.min(t,Math.max(e,a)),Ye=(a,e,t)=>{const s="touches"in a.nativeEvent,r=s?a.nativeEvent.touches[0]:a.nativeEvent,i=l=>{s&&l.cancelable&&l.preventDefault();const m="touches"in l?l.touches[0]:l;e({deltaX:m.clientX-r.clientX,deltaY:m.clientY-r.clientY})},c=()=>{s?(document.removeEventListener("touchmove",i),document.removeEventListener("touchend",c)):(document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",c)),t?.()};s?(document.addEventListener("touchmove",i,{passive:!1}),document.addEventListener("touchend",c)):(document.addEventListener("mousemove",i),document.addEventListener("mouseup",c))},Ce="virtualscroll:tap-scroll-cancel",ze=20,tt=250,st=60,nt=20,rt=20,ot=220,je={active:!1,offsetX:0,offsetY:0,distance:0,direction:0},Re=2.2,at=8,it=120,fe={enabled:!0,size:40,offsetX:-80,offsetY:0,className:void 0,maxVisualDistance:ot,opacity:1,renderVisual:void 0},lt=a=>{if(!a||a<=0)return Re;const e=Math.max(1,a),t=Math.log10(e),s=Re+t*at;return U(s,Re,it)},Ue=({contentSize:a,viewportSize:e,scrollPosition:t,onScroll:s,enableThumbDrag:r=!0,enableTrackClick:i=!0,enableArrowButtons:c=!0,horizontal:l=!1,scrollBarWidth:m=12,className:d,ariaControls:f,tapScrollCircleOptions:g,itemCount:A})=>{const[V,H]=n.useState(!1),[Q,T]=n.useState(!1),[oe,ae]=n.useState(!1),G=n.useRef(null),_=n.useRef(t),$=n.useRef(null),O=n.useRef(null),b=n.useRef(je),P=n.useRef(null),S=n.useRef(null),j=n.useRef(null),p=n.useMemo(()=>{const o=g?.maxSpeedMultiplier,v=typeof o=="number"?o:lt(A);return{enabled:g?.enabled??fe.enabled,size:g?.size??fe.size,offsetX:g?.offsetX??fe.offsetX,offsetY:g?.offsetY??fe.offsetY,className:g?.className??fe.className,maxVisualDistance:g?.maxVisualDistance??fe.maxVisualDistance,maxSpeedMultiplier:v,opacity:U(g?.opacity??fe.opacity,0,1),renderVisual:g?.renderVisual??fe.renderVisual}},[A,g]),{enabled:D,size:h,offsetX:k,offsetY:x,className:N,maxVisualDistance:L,maxSpeedMultiplier:F,opacity:R,renderVisual:w}=p,M=l?"width":"height",y=l?"height":"width",I=l?"left":"top",C=l?"clientX":"clientY",q=(o,v)=>l?o:v,ne=o=>o[C],K=l?["Scroll left","Scroll right"]:["Scroll up","Scroll down"],W=l?["◀","▶"]:["▲","▼"],te=l?"flex flex-row items-stretch":"flex flex-col items-stretch",B=Math.max(L,1),ce=e/a,Y=m,u=Math.max(e-Y*2,0),Z=ce*u,J=Math.min(Math.max(ze,Z||0),u||ze),z=a-e,re=Math.max(u-J,0),he=z<=0||re<=0?0:t/z*re,ue=a>e,Ae=ue&&c;n.useEffect(()=>{_.current=t},[t]),n.useEffect(()=>{r||T(!1)},[r]),n.useEffect(()=>{const o=G.current;if(!o)return;const v=l?"scaleY(1.06)":"scaleX(1.06)",X=l?"scaleY(1.12)":"scaleX(1.12)";if(!r){o.style.removeProperty("transform"),o.style.backgroundColor="#7F7F7F",o.style.removeProperty("transition");return}if(V){o.style.transform=X,o.style.backgroundColor="#4F4F4F",o.style.transition="transform 60ms ease-out";return}o.style.transition="transform 80ms ease-out",Q?(o.style.transform=v,o.style.backgroundColor="#5F5F5F"):(o.style.removeProperty("transform"),o.style.backgroundColor="#7F7F7F")},[r,l,V,Q]);const ve=n.useCallback(()=>{$.current!==null&&(window.clearInterval($.current),$.current=null),O.current!==null&&(window.clearTimeout(O.current),O.current=null)},[]),ie=n.useCallback(()=>{S.current!==null&&(window.cancelAnimationFrame(S.current),S.current=null),j.current=null},[]),le=n.useCallback(()=>{b.current={...je},ae(!1),P.current?.reset(),ie()},[ie]),Te=n.useCallback(o=>{const v=b.current;if(!v.active||v.direction===0){ie();return}if(!ue||z<=0){ie();return}const X=j.current??o,ee=Math.max((o-X)/1e3,0);if(j.current=o,ee<=0){S.current=window.requestAnimationFrame(Te);return}const Me=(Math.min(v.distance,B)/B)**1.1,pe=Math.max(e*.2,40),Ee=Math.max(e*F,1200),Ve=pe+(Ee-pe)*Me,ge=_.current,Pe=U(ge+v.direction*Ve*ee,0,z);if(Pe===ge){ie();return}_.current=Pe,s?.(Pe,ge),S.current=window.requestAnimationFrame(Te)},[B,z,s,ue,ie,F,e]),_e=n.useCallback(()=>{S.current===null&&(j.current=null,S.current=window.requestAnimationFrame(Te))},[Te]);n.useEffect(()=>()=>{ve(),ie()},[ve,ie]);const Ge=n.useCallback(o=>{b.current=o,ae(o.active),o.active&&o.direction!==0?_e():ie()},[_e,ie]);n.useEffect(()=>{D||le()},[le,D]),n.useEffect(()=>{const o=v=>{const ee=v.detail?.paneId;ee&&f&&ee!==f||le()};return window.addEventListener(Ce,o),()=>{window.removeEventListener(Ce,o)}},[f,le]),n.useEffect(()=>{if(!D)return;const o=v=>{if(!b.current.active)return;const X=v.target;if(!(X instanceof Node)){le();return}P.current?.getElement()?.contains(X)||le()};return document.addEventListener("pointerdown",o,!0),()=>{document.removeEventListener("pointerdown",o,!0)}},[le,D]);const Se=o=>{if(!ue||re<=0||z<=0)return 0;const v=U(o,0,re);return U(v/re*z,0,z)},Ie=o=>{if(!ue||z<=0)return;const v=Math.max(Math.round(e/rt),nt),X=_.current,ee=U(X+o*v,0,z);ee!==X&&(_.current=ee,s?.(ee,X))},ye=()=>{ve()},ke=o=>v=>{Ae&&(v.preventDefault(),v.stopPropagation(),le(),ve(),Ie(o),O.current=window.setTimeout(()=>{$.current=window.setInterval(()=>{Ie(o)},st)},tt))},Ze=o=>v=>{c&&(v.key==="Enter"||v.key===" "||v.key==="Spacebar")&&(v.preventDefault(),Ie(o))},Le=o=>{if(!ue)return;if(!r){o.preventDefault(),o.stopPropagation();return}if("button"in o&&o.button!==0||o.ctrlKey)return;o.stopPropagation(),le();const v=he;H(!0),T(!0),Ye(o,({deltaX:X,deltaY:ee})=>{const me=q(X,ee);s?.(Se(v+me),he)},()=>{H(!1),G.current&&!G.current.matches(":hover")&&T(!1)})},Fe=o=>{if(!ue)return;if(!i){o.preventDefault(),o.stopPropagation();return}if("button"in o&&o.button!==0||o.ctrlKey)return;const X="touches"in o.nativeEvent?o.nativeEvent.touches[0]:o.nativeEvent,ee=ne(X),me=o.currentTarget.getBoundingClientRect(),Me=ee-(l?me.left:me.top);le();const pe=Me-J/2;s?.(Se(pe),he),Ye(o,({deltaX:Ee,deltaY:Ve})=>{const ge=q(Ee,Ve);s?.(Se(pe+ge),he)})},Je=n.useMemo(()=>U((oe?1:.8)*R,0,1),[oe,R]),Qe=n.useMemo(()=>{const v=`calc(50% - ${h/2}px + ${x}px)`;return{left:k,top:v}},[k,x,h]),De=(o,v,X)=>E.jsx("button",{type:"button",className:"flex items-center justify-center text-[#313131] text-xs transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-[#60a5fa] focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-50",style:{[M]:Y,[y]:m,backgroundColor:"#E0E0E0"},"aria-label":v,onMouseDown:ke(o),onTouchStart:ke(o),onMouseUp:ye,onMouseLeave:ye,onTouchEnd:ye,onTouchCancel:ye,onKeyDown:Ze(o),"aria-disabled":!c,disabled:!Ae,children:E.jsx("span",{"aria-hidden":"true",children:X})});return E.jsxs("div",{className:be.twMerge("group relative cursor-default select-none",te,d),style:{[M]:e,[y]:m,backgroundColor:"white",userSelect:"none",position:"relative"},role:"scrollbar",tabIndex:-1,"aria-controls":f,"aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":z,"aria-orientation":l?"horizontal":"vertical",children:[!l&&ue&&D&&E.jsx(Xe,{ref:P,className:be.twMerge("pointer-events-auto absolute transition-opacity duration-150",N),size:h,maxVisualDistance:B,style:Qe,opacity:Je,renderVisual:w,onDragChange:Ge}),De(-1,K[0],W[0]),E.jsx("div",{className:"relative flex-1",style:{backgroundColor:"#F5F5F5",borderRadius:m/2},onMouseDown:Fe,onTouchStart:Fe,"aria-disabled":!i,children:ue&&E.jsx("div",{className:"group absolute",style:{[M]:J,[I]:he,...l?{top:0,bottom:0}:{left:0,right:0}},onMouseDown:Le,onTouchStart:Le,role:"slider","aria-orientation":l?"horizontal":"vertical","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":z,"aria-disabled":!r,tabIndex:r?0:-1,children:E.jsx("div",{ref:G,className:be.twMerge("absolute",l?`inset-x-0 inset-y-[1.5px] group-hover:inset-y-[-0.5px] ${V?"-inset-y-0.5":"group-active:-inset-y-0.5"}`:`inset-x-[1.5px] inset-y-0 group-hover:inset-x-[-0.5px] ${V?"-inset-x-0.5":"group-active:-inset-x-0.5"}`),style:{backgroundColor:"#7F7F7F",borderRadius:m-1,cursor:r?"pointer":"default",...l?{left:0,right:0,top:1.5,bottom:1.5}:{top:0,bottom:0,left:1.5,right:1.5}},onMouseEnter:()=>{r&&T(!0)},onMouseLeave:()=>{r&&T(!1)}})})}),De(1,K[1],W[1])]})},se={debug(a,...e){typeof window<"u"&&window.localStorage?.getItem("debug")==="true"&&console.debug(`[VirtualScroll] ${a}`,...e)},warn(a,...e){console.warn(`[VirtualScroll] ${a}`,...e)},error(a,...e){console.error(`[VirtualScroll] ${a}`,...e)}},xe={maxVelocity:6,minVelocity:.02,deceleration:.0025,velocitySampleWindow:90,startVelocityThreshold:.04},we=(a,e,t)=>{for(const[s,r,i]of e)t==="add"?a.addEventListener(s,r,i):a.removeEventListener(s,r,i)},qe=n.forwardRef(({children:a,contentSize:e,viewportSize:t,scrollBarWidth:s=12,enableThumbDrag:r=!0,enableTrackClick:i=!0,enableArrowButtons:c=!0,enablePointerDrag:l=!0,onScroll:m,className:d,style:f,background:g,tapScrollCircleOptions:A,inertiaOptions:V,itemCount:H},Q)=>{const T=n.useRef(0),[oe,ae]=n.useReducer(h=>h+1,0),G=n.useRef(null),_=n.useRef(null),$=n.useRef({frame:null,velocity:0,lastTimestamp:null}),O=n.useMemo(()=>({maxVelocity:V?.maxVelocity??xe.maxVelocity,minVelocity:V?.minVelocity??xe.minVelocity,deceleration:V?.deceleration??xe.deceleration,velocitySampleWindow:V?.velocitySampleWindow??xe.velocitySampleWindow,startVelocityThreshold:V?.startVelocityThreshold??xe.startVelocityThreshold}),[V]);se.debug("[ScrollPane] ScrollPane rendered",{contentSize:e,viewportSize:t,scrollBarWidth:s,className:d,style:f,tapScrollCircleOptions:A,inertiaOptions:V,enablePointerDrag:l});const b=n.useRef({contentSize:e,viewportSize:t}),P=n.useMemo(()=>e>t,[e,t]),S=n.useCallback(h=>{const{contentSize:k,viewportSize:x}=b.current,N=k>x,L=T.current;if(se.debug("[ScrollPane] scrollTo called",{newPosition:h,contentSize:k,viewportSize:x,currentIsScrollable:N,prevPosition:L}),!N){T.current!==0&&(T.current=0,m?.(0,L));return}const F=typeof h=="function"?h(T.current):h,R=U(F,0,k-x);T.current!==R&&(T.current=R,m?.(R,L))},[m]),j=n.useCallback(()=>{const h=$.current;h.frame!==null&&cancelAnimationFrame(h.frame),h.frame=null,h.velocity=0,h.lastTimestamp=null},[]),p=n.useCallback(h=>{if(!P)return;const{maxVelocity:k,minVelocity:x,deceleration:N,startVelocityThreshold:L}=O,F=U(h,-k,k);if(Math.abs(F)<L)return;j(),$.current.velocity=F,$.current.lastTimestamp=null;const R=w=>{const M=$.current;if(M.lastTimestamp===null){M.lastTimestamp=w,M.frame=requestAnimationFrame(R);return}const y=w-M.lastTimestamp;if(M.lastTimestamp=w,y<=0){M.frame=requestAnimationFrame(R);return}const I=M.velocity;let C=I;const q=N*y;I>0?C=Math.max(0,I-q):I<0&&(C=Math.min(0,I+q));const K=(I+C)/2*y,W=T.current;K!==0&&S(Z=>Z+K);const te=T.current,{contentSize:B,viewportSize:ce}=b.current,Y=Math.max(B-ce,0);M.velocity=C;const u=te===W||te<=0&&C<=0||te>=Y&&C>=0;if(Math.abs(C)<x||u){j();return}M.frame=requestAnimationFrame(R)};$.current.frame=requestAnimationFrame(R)},[P,O,S,j]);n.useLayoutEffect(()=>{b.current={contentSize:e,viewportSize:t}},[e,t]),n.useLayoutEffect(()=>{if(P){se.debug("[ScrollPane] Adjusting scroll position due to content or viewport size change",{contentSize:e,viewportSize:t,scrollPosition:T.current});const h=U(e-t,0,e);T.current>h&&S(h)}else S(0)},[P,S,e,t]),n.useEffect(()=>{const h=x=>{if(!P)return;x.preventDefault(),j();let N=x.deltaY;x.deltaMode===1?N*=16:x.deltaMode===2&&(N*=t),se.debug("[ScrollPane] wheel event",{deltaY:N,scrollPosition:T.current}),S(L=>L+N)},k=G.current;return k&&k.addEventListener("wheel",h,{passive:!1}),()=>{k&&k.removeEventListener("wheel",h)}},[P,S,j,t]),n.useImperativeHandle(Q,()=>({scrollTo:S,getScrollPosition:()=>T.current,getContentSize:()=>e,getViewportSize:()=>t}),[S,e,t]);const D=n.useId();return n.useEffect(()=>{const h=_.current;if(!h)return;if(!l){j();return}const k=6;let x=null,N=0,L=0,F=!1,R=!1,w=null,M=[];const y=()=>{x=null,N=0,L=0,F=!1,M=[]},I=u=>{const Z=performance.now();M.push({clientY:u,time:Z}),M=M.filter(J=>Z-J.time<=O.velocitySampleWindow)},C=u=>u instanceof HTMLElement&&u.closest("[data-scrollpane-ignore-drag='true']")!==null,q=u=>{R&&(u.preventDefault(),u.stopPropagation(),R=!1)},ne=u=>{F||(F=!0,R=!0,h.hasPointerCapture(u.pointerId)||h.setPointerCapture(u.pointerId),I(u.clientY))},K=u=>{if(x!==u.pointerId||!F&&(Math.abs(u.clientY-N)<k||(ne(u),!F)))return;I(u.clientY);const Z=u.clientY-N,J=L-Z;S(J),u.cancelable&&u.preventDefault()},W=u=>{if(x!==u.pointerId)return;F&&R&&u.cancelable&&(u.preventDefault(),u.stopPropagation()),h.hasPointerCapture(u.pointerId)&&h.releasePointerCapture(u.pointerId);let Z=0;if(F&&M.length>=2){const J=M[M.length-1],z=M.find(re=>J.time-re.time<=O.velocitySampleWindow)??M[0];if(J&&z&&J.time!==z.time){const re=J.clientY-z.clientY,he=J.time-z.time;Z=-(re/he)}}y(),w!==null&&window.clearTimeout(w),R&&(w=window.setTimeout(()=>{R=!1,w=null},0)),Math.abs(Z)>=O.startVelocityThreshold&&p(Z)},te=u=>{P&&(u.button!==0&&u.pointerType==="mouse"||u.ctrlKey||u.metaKey||u.altKey||C(u.target)||(window.dispatchEvent(new CustomEvent(Ce,{detail:{paneId:D}})),j(),x=u.pointerId,N=u.clientY,L=T.current,F=!1,R=!1,M=[]))},B=u=>{x===u.pointerId&&(R=!1,h.hasPointerCapture(u.pointerId)&&h.releasePointerCapture(u.pointerId),w!==null&&(window.clearTimeout(w),w=null),y())},ce=[["click",q,!0],["pointerdown",te,{passive:!1}],["pointermove",K,{passive:!1}],["pointerup",W,void 0],["pointercancel",B,void 0]],Y=[["pointermove",K,{passive:!1}],["pointerup",W,void 0],["pointercancel",B,void 0]];return we(h,ce,"add"),we(window,Y,"add"),()=>{we(h,ce,"remove"),we(window,Y,"remove"),x!==null&&h.hasPointerCapture(x)&&h.releasePointerCapture(x),w!==null&&window.clearTimeout(w),j()}},[l,D,P,O,S,p,j]),E.jsxs("div",{ref:G,className:be.twMerge("flex",d),style:f,children:[E.jsxs("div",{ref:_,className:"relative h-full flex-1 overflow-hidden",style:{height:t,...l?{touchAction:"none"}:{}},id:D,children:[g,a(T.current)]}),P&&E.jsx(Ue,{contentSize:e,viewportSize:t,scrollPosition:T.current,onScroll:S,enableThumbDrag:r,enableTrackClick:i,enableArrowButtons:c,scrollBarWidth:s,ariaControls:D,tapScrollCircleOptions:A,itemCount:H})]})}),He=(a,e,t)=>Math.min(Math.max(a,e),t),ct=({dragState:a,normalizedDistance:e,sizeScale:t,size:s})=>{const r=Math.max(s/2,1),i=1+e*.65,c=Math.max(.65,1-e*.25),l=a.direction*e*26*t,m=.8+e*.18,d=3*t,f=6*t,g=22*t,A=Math.abs(l)+f,V=l>0?d:-Math.abs(l)-d,H=Math.max(2.5,3*t),Q=He(a.offsetX,-r,r),T=He(a.offsetY,-r,r),oe=r*.35,ae=Q/r*oe,G=T/r*oe,_=ae*.45,$=G*.45,O=Math.max(g*.38,6),b=.65+e*.2,P=a.active;return E.jsxs(E.Fragment,{children:[E.jsx("div",{className:"absolute inset-0 rounded-full border border-white/40 bg-linear-to-br from-[#1d4ed8]/60 via-[#60a5fa]/55 to-[#bfdbfe]/40 shadow-md",style:{transform:`scale(${c}, ${i})`,transition:P?"40ms transform ease-out":"200ms ease transform"}}),E.jsx("div",{className:"absolute top-1/2 left-1/2 rounded-full border border-white/50 bg-white/85",style:{width:g,height:g,transform:`translate(calc(-50% + ${ae}px), calc(-50% + ${G}px)) scale(${c}, ${m*i})`,transition:P?"70ms transform ease-out":"200ms ease transform"}}),E.jsx("div",{className:"absolute top-1/2 left-1/2 rounded-full bg-white/80",style:{width:O,height:O,transform:`translate(calc(-50% + ${_}px), calc(-50% + ${$}px)) scale(${c}, ${i})`,opacity:b,boxShadow:"0 0 8px rgba(255,255,255,0.45)",transition:P?"120ms opacity 150ms, 120ms transform ease-out ease-out":"220ms ease transform, 240ms opacity ease"}}),E.jsx("div",{className:"absolute top-1/2 left-1/2 rounded-full bg-white/50",style:{width:H,height:A,transform:`translate(-50%, ${V}px)`,opacity:e,transition:P?"40ms height, 60ms opacity ease-out ease-out":"200ms ease height, 120ms ease opacity"}})]})};class Ke{tree;deltas;size;baseValue;valueFn;total;constructor(e,t,s){this.reset(e,t,s)}reset(e,t,s){if(this.size=e,this.tree=new Map,this.deltas=new Map,this.total=void 0,typeof t=="function"){if(this.valueFn=t,this.size>0){const i=s?.sampleRange??{from:0,to:Math.min(99,this.size-1)},{mode:c,materializedValues:l}=this._calculateMode(i.from,i.to);if(this.baseValue=c,s?.materialize)for(let m=0;m<l.length;m++){const d=l[m],f=i.from+m;if(f>=this.size)break;const g=d-this.baseValue;this.deltas.set(f,g),this._updateTree(f,g)}}else this.baseValue=0;this.total=this.getTotal()}else this.valueFn=void 0,this.baseValue=t,this.total=this.baseValue*this.size}setValueFn(e){typeof e=="function"?this.valueFn=e:(this.valueFn=void 0,this.baseValue=e)}_calculateMode(e,t){if(!this.valueFn)return{mode:0,materializedValues:[]};const s=[];for(let d=e;d<=t&&!(d>=this.size);d++)s.push(this.valueFn(d));const r=[...s];if(s.length===0)return{mode:0,materializedValues:[]};s.sort((d,f)=>d-f);const i=Math.floor(s.length/2);let c;s.length%2===0?c=Math.floor((s[i-1]+s[i])/2):c=s[i];const l=new Map;let m=0;for(const d of s){const f=(l.get(d)??0)+1;l.set(d,f),f>m&&(m=f)}if(m>1){const d=[];for(const[g,A]of l.entries())A===m&&d.push(g);const f=d.reduce((g,A)=>g+A,0);c=Math.floor(f/d.length)}return{mode:c,materializedValues:r}}update(e,t){return this.updates([{index:e,value:t}])}updates(e){const t=this._buildDeltaUpdates(e);return t.length>0?this.updateDeltas(t):this.total}updateDelta(e,t){return this.updateDeltas([{index:e,change:t}])}updateDeltas(e){for(const{index:t,change:s}of e){if(t<0||t>=this.size)throw new Error(`Index ${t} out of bounds`);const r=this.deltas.get(t)??0;this.deltas.set(t,r+s),this._updateTree(t,s)}return this.total}_updateTree(e,t){if(t===0)return;let s=e+1;for(;s<=this.size;)this.tree.set(s,(this.tree.get(s)??0)+t),s+=s&-s;this.total!==void 0&&(this.total+=t)}_buildDeltaUpdates(e){const t=[];for(const{index:s,value:r}of e){if(s<0||s>=this.size)throw new Error(`Index ${s} out of bounds`);if(r<0)throw new Error("Value cannot be negative.");const i=this.deltas.has(s)?(this.deltas.get(s)??0)+this.baseValue:this.baseValue,c=r-i;c!==0&&t.push({index:s,change:c})}return t}_materialize(e,t=!0){if(this.valueFn){const s=this.deltas.get(e)??0,i=this.valueFn(e)-this.baseValue;if(i!==s&&(this.deltas.set(e,i),t)){const c=i-s;this._updateTree(e,c)}}}_materializeRanges(e,t,s=!1){if(!(e?.materialize&&this.valueFn))return;const r=e.ranges;if(r&&r.length>0){for(const l of r){const m=l.from,d=Math.min(l.to,this.size-1);for(let f=m;f<=d;f++)this._materialize(f)}if(t===void 0)return;if(s){this._materialize(t);return}const i=r[0].from,c=r[r.length-1].to;t>=i&&t<=c&&this._materialize(t);return}t!==void 0&&this._materialize(t)}_findIndex(e,t={},s){if(this.size===0)return{index:-1,total:this.total??0,cumulative:void 0,currentValue:void 0,safeIndex:void 0};let r=0,i=this.size-1,c=-1,l,m=this.total;for(;r<=i;){const d=Math.floor((r+i)/2);l=this.prefixSum(d,t),m=l.total,(s?l.cumulative>=e:l.cumulative<=e)?(c=d,s?i=d-1:r=d+1):s?r=d+1:i=d-1}return{index:c,total:m,cumulative:l?.cumulative,currentValue:l?.currentValue,safeIndex:l?.safeIndex}}prefixSum(e,t){if(e<0)return{cumulative:0,total:this.total,currentValue:0,safeIndex:0};const s=U(e,0,this.size-1),r=t?.materializeOption;this._materializeRanges(r,s,!0);let i=0,c=s+1;for(;c>0;){const m=this.tree.get(c)??0;i+=m,c-=c&-c}const l=r?.materialize?this.get(s):(this.deltas.get(s)||0)+this.baseValue;return{cumulative:i+this.baseValue*(s+1),total:this.total,currentValue:l,safeIndex:s}}get(e,t){if(e<0||e>=this.size)throw new Error("Index out of bounds");const s=t?.materializeOption;return this._materializeRanges(s,e),(this.deltas.get(e)??0)+this.baseValue}getTotal(e){const t=e?.materializeOption;if(this._materializeRanges(t),this.total===void 0)if(this.size===0)this.total=0;else{let s=this.baseValue*this.size;for(const i of this.deltas.values())s+=i;this.total=s;const r=this.prefixSum(this.getSize()-1);console.assert(r.cumulative===r.total,"Inconsistent Fenwick Tree state")}return this.total}rebuildTree(e){if(e?.materialize&&this.valueFn){const r=this.valueFn;this.reset(this.size,i=>r(i),{materialize:!0});return}const t=new Map;let s=this.baseValue*this.size;for(const[r,i]of this.deltas.entries()){if(s+=i,i===0)continue;let c=r+1;for(;c<=this.size;)t.set(c,(t.get(c)??0)+i),c+=c&-c}this.tree=t,this.total=s}calculateAccumulatedError(){if(this.total===void 0)return 0;let e=this.baseValue*this.size;for(const t of this.deltas.values())e+=t;return this.total-e}changeSize(e){const t=this.size;if(e===t)return;if(e<t)for(const r of this.deltas.keys())r>=e&&this.deltas.delete(r);this.size=e,this.rebuildTree();const s=this.prefixSum(this.getSize()-1);console.assert(s.cumulative===s.total,"Inconsistent Fenwick Tree state")}getSize(){return this.size}findIndexAtOrAfter(e,t){return this._findIndex(e,t??{},!0)}findIndexAtOrBefore(e,t){return this._findIndex(e,t??{},!1)}}const We=(a,e,t)=>{const s=Math.max(0,a),r=n.useRef(null),i=n.useMemo(()=>new Ke(s,e,t),[s,e,t]);return Object.is(r.current,i)||console.warn("[useFenwickMapTree] instance changed"),r.current=i,i};class ut{key;value;prev=null;next=null;constructor(e,t){this.key=e,this.value=t}}class $e{head=null;tail=null;addToTail(e){this.tail?(this.tail.next=e,e.prev=this.tail,this.tail=e):this.head=this.tail=e}remove(e){e.prev?e.prev.next=e.next:this.head=e.next,e.next?e.next.prev=e.prev:this.tail=e.prev,e.prev=null,e.next=null}removeHead(){const e=this.head;return e&&this.remove(e),e}moveToTail(e){this.remove(e),this.addToTail(e)}}function Be(a){const e=n.useRef(new Map),t=n.useRef(new $e);n.useEffect(()=>{for(;e.current.size>a;){const d=t.current.removeHead();if(d)e.current.delete(d.key);else break}},[a]);const s=n.useCallback(d=>{const f=e.current.get(d);if(f)return t.current.moveToTail(f),f.value},[]),r=n.useCallback((d,f)=>{if(a<=0)return;let g=e.current.get(d);if(g)g.value=f,t.current.moveToTail(g);else{if(e.current.size>=a){const A=t.current.removeHead();A&&e.current.delete(A.key)}g=new ut(d,f),e.current.set(d,g),t.current.addToTail(g)}},[a]),i=n.useCallback(d=>e.current.has(d),[]),c=n.useCallback(()=>{e.current.clear(),t.current=new $e},[]),[l,m]=n.useState(()=>({get:s,set:r,has:i,clear:c}));return n.useEffect(()=>m({get:s,set:r,has:i,clear:c}),[s,r,i,c]),l}const dt=1e4,ft=()=>{const{get:a,set:e,has:t,clear:s}=Be(dt);return{get:a,set:e,has:t,clear:s}},de=(a,e)=>e<=0?0:U(a,0,e-1),ht=(a,e,t,s,r,i)=>{if(s===0)return{renderingStartIndex:0,renderingEndIndex:0,visibleStartIndex:0,visibleEndIndex:0};const{index:c,cumulative:l,currentValue:m}=i.findIndexAtOrAfter(a,{materializeOption:{materialize:!1}}),d=c===-1?0:c,f=c!==-1&&(l??0)<a+(m??0)?d+1:d,g=de(f,s),A=de(g-t,s);let V=0,H=g;for(;H<s&&V<e;)V+=r(H),H++;const Q=de(H-1,s),T=de(Q+t,s);return{renderingStartIndex:A,renderingEndIndex:T,visibleStartIndex:g,visibleEndIndex:Q}};function mt({itemCount:a,getItem:e,getItemHeight:t,viewportSize:s,overscanCount:r=5,className:i,onScroll:c,onRangeChange:l,children:m,background:d,initialScrollIndex:f,initialScrollOffset:g,tapScrollCircleOptions:A,scrollBarWidth:V,enableThumbDrag:H,enableTrackClick:Q,enableArrowButtons:T,enablePointerDrag:oe,inertiaOptions:ae},G){const _=n.useRef(null),$=n.useRef(!1);n.useEffect(()=>($.current=!0,()=>{$.current=!1}),[]);const O=n.useRef({size:a,valueOrFn:t,options:{sampleRange:{from:0,to:100}}}),b=We(O.current.size,O.current.valueOrFn,O.current.options),[P]=n.useState(()=>{let y=0,I=0;if(typeof f=="number"){const C=U(f,0,a-1),q=U(C-r*2,0,a-1),ne=U(C+r*2,0,a-1),K=f>0?{materializeOption:{materialize:!0,ranges:[{from:q,to:ne}]}}:void 0,{cumulative:W,total:te,currentValue:B}=b.prefixSum(f,K);y=W-B,I=te??b.getTotal()}else typeof g=="number"&&(y=g),I=b.getTotal();return{position:y,total:I}}),[S,j]=n.useState(P.position),[p,D]=n.useState(P.total),[h,k]=n.useState(P.position),[x,N]=n.useState(a);n.useLayoutEffect(()=>{b.setValueFn(t),x!==a&&(b.changeSize(a),N(a));const y=b.getTotal();p!==y&&D(y)},[b,x,a,p,t]),n.useLayoutEffect(()=>{h!==null&&_.current&&(se.debug("[VirtualScroll] Scrolling to position:",h),_.current.scrollTo(h),k(null))},[h]);const L=n.useCallback(y=>{if(!_.current)return;const I=de(y,x),C=de(I-r*2,x),q=de(I+r*2,x),{cumulative:ne,total:K,currentValue:W}=b.prefixSum(I,{materializeOption:{materialize:!0,ranges:[{from:C,to:q}]}});se.debug("[VirtualScroll] Scrolling to index:",I,"Offset:",ne,"Total height:",K,"Current value:",W,"safeIndexFrom:",C,"safeIndexTo:",q),K&&(D(K),k(ne-W),se.debug("[VirtualScroll] Setting scroll position to:",ne-W))},[b,r,x]),F=n.useCallback(y=>{if(!_.current)return;const I=b.getTotal(),C=U(Math.floor(y),0,I),q=b.findIndexAtOrAfter(C,{materializeOption:{materialize:!1}}).index;L(q)},[b,L]),R=n.useCallback((y,I)=>{se.debug("[VirtualScroll] Scroll position changed:",y),j(y);const C=b.getTotal();c?.(y,C)},[b,c]),w=n.useMemo(()=>{const y=ht(S,s,r,x,t,b);return se.debug("[VirtualScroll] Calculated rendering range:",{...y,scrollPosition:S,renderingContentSize:b.getTotal(),overscanCount:r,viewportSize:s}),y},[S,s,r,x,t,b]);n.useEffect(()=>{const y=_.current?.getScrollPosition()??0;se.debug("[VirtualScroll] Range change effect triggered",{renderingStartIndex:w.renderingStartIndex,renderingEndIndex:w.renderingEndIndex,visibleStartIndex:w.visibleStartIndex,visibleEndIndex:w.visibleEndIndex,scrollPosition:S,contentSize:p,scrollPaneScrollPosition:y}),l?.(w.renderingStartIndex,w.renderingEndIndex,w.visibleStartIndex,w.visibleEndIndex,S,p)},[w.renderingStartIndex,w.renderingEndIndex,w.visibleStartIndex,w.visibleEndIndex,l,S,p]);const M=n.useCallback(y=>{const{renderingStartIndex:I,renderingEndIndex:C}=w;if(se.debug("[VirtualScroll] Rendering visible items",{currentScrollPosition:y,renderingStartIndex:I,renderingEndIndex:C,fenwickSize:x,viewportSize:s}),x===0)return E.jsx("div",{className:"absolute w-full",style:{top:0},children:E.jsx("div",{className:"text-center text-gray-500",children:"No items"})});const q=de(I,x),{cumulative:ne,currentValue:K}=b.prefixSum(q,{materializeOption:{materialize:!1}}),W=ne-K,te=[],B=[];for(let Y=I;Y<=C;Y++){const u=t(Y);te.push({item:e(Y),height:u,index:Y}),b.get(Y)!==u&&B.push({index:Y,value:u})}B.length>0&&Promise.resolve().then(()=>{const Y=b.updates(B);Y&&(D(Y),se.debug("[VirtualScroll] Updated heights for items",B,"New total height:",Y))});const ce=p<s?0:W-y;return se.debug("[VirtualScroll] Rendering items",{visibleItems:te,containerTop:ce}),E.jsx("div",{className:"absolute w-full",style:{top:ce},children:te.map(({item:Y,index:u})=>{const Z=de(u,x),{cumulative:J,currentValue:z}=b.prefixSum(Z,{materializeOption:{materialize:!1}}),re=J-z;return E.jsx("div",{"data-index":u,style:{position:"absolute",top:re-W,width:"100%"},children:m(Y,u)},u)})})},[e,m,p,s,w,b,x,t]);return n.useImperativeHandle(G,()=>({getScrollPosition:()=>_.current?.getScrollPosition()??-1,getContentSize:()=>_.current?.getContentSize()??-1,getViewportSize:()=>_.current?.getViewportSize()??-1,scrollTo:F,scrollToIndex:L,getFenwickTreeTotalHeight:()=>b.getTotal(),getFenwickSize:()=>b.getSize()}),[F,L,b]),E.jsx(qe,{ref:_,contentSize:p,viewportSize:s,className:i,onScroll:R,background:d,tapScrollCircleOptions:A,inertiaOptions:ae,itemCount:a,scrollBarWidth:V,enableThumbDrag:H,enableTrackClick:Q,enableArrowButtons:T,enablePointerDrag:oe,children:M})}const pt=n.forwardRef(mt);exports.FenwickMapTree=Ke;exports.ScrollBar=Ue;exports.ScrollPane=qe;exports.VirtualScroll=pt;exports.minmax=U;exports.tapScrollCircleSampleVisual=ct;exports.useFenwickMapTree=We;exports.useHeightCache=ft;exports.useLruCache=Be;
2
- //# sourceMappingURL=index.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const L=require("react/jsx-runtime"),n=require("react"),Ue=require("tailwind-merge"),ct={active:!1,offsetX:0,offsetY:0,distance:0,direction:0},ot=6,_t=8,Ft=({dragState:s,normalizedDistance:e})=>{const t=1+e*.18,r=.16+e*.24,o=.38+e*.28,l=s.active?"80ms ease-out":"220ms ease";return L.jsxs(L.Fragment,{children:[L.jsx("div",{className:"absolute inset-0 rounded-full",style:{background:"linear-gradient(140deg, rgba(255,255,255,0.62), rgba(72,72,72,0.48))",boxShadow:`0 0 0 1px rgba(255,255,255,0.28), 0 10px 22px rgba(0,0,0,${r})`,transform:`scale(${t})`,transition:`${l}, ${s.active?"80ms":"260ms"} box-shadow ease`}}),L.jsx("div",{className:"aqvs:tap-scroll-circle-inner absolute rounded-full",style:{background:"linear-gradient(140deg, rgba(255,255,255,0.72), rgba(28,28,28,0.58))",boxShadow:"inset 0 4px 10px rgba(0,0,0,0.24), inset 0 0 2px rgba(255,255,255,0.55)",opacity:o,transition:s.active?"120ms opacity ease-out":"220ms opacity ease"}})]})},gt=n.forwardRef(({onDragChange:s,className:e,maxVisualDistance:t=160,size:r=40,style:o,opacity:l=1,renderVisual:f},p)=>{const[c,u]=n.useState(ct),d=n.useRef(null),g=n.useRef({x:0,y:0}),C=n.useRef(null),T=n.useRef(0),F=n.useCallback(R=>{u(R),s(R)},[s]),V=n.useCallback((R,S,W=!1)=>{const{x:te,y:ve}=g.current,ne=R-te,U=S-ve,ae=Math.abs(U),ue=ae<ot?0:U<0?-1:1,y=T.current;let P=ue;const M=ot+_t;ue===0?y!==0&&ae<M?P=y:(P=0,W||(T.current=0)):ue!==y&&y!==0&&ae<M?P=y:T.current=ue,F({active:W||ae>=ot,offsetX:ne,offsetY:U,distance:ae,direction:P})},[F]),J=n.useCallback(R=>{if(R===null)return;const S=C.current;S?.hasPointerCapture(R)&&S.releasePointerCapture(R)},[]),O=n.useCallback((R=!1)=>{R&&J(d.current),d.current=null,T.current=0,F(ct)},[F,J]),ce=n.useCallback(R=>{R.preventDefault(),R.stopPropagation();const S=C.current??R.currentTarget,{left:W,top:te,width:ve,height:ne}=S.getBoundingClientRect();g.current={x:W+ve/2,y:te+ne/2},d.current=R.pointerId,S.setPointerCapture(R.pointerId),V(R.clientX,R.clientY,!0)},[V]),E=n.useCallback(R=>{d.current===R.pointerId&&(R.preventDefault(),V(R.clientX,R.clientY))},[V]),k=n.useCallback(R=>{d.current===R.pointerId&&(R.preventDefault(),R.stopPropagation(),O(!0))},[O]);n.useImperativeHandle(p,()=>({reset:()=>{O(!0)},getElement:()=>C.current}),[O]);const z=Math.min(Math.max(l,0),1),N=r/64,w=Math.min(c.distance,t)/t,H=c.direction*w*10*N,j=f??Ft,_={dragState:c,normalizedDistance:w,sizeScale:N,size:r,opacity:z},x={...o,width:r,height:r,transform:`translateY(${H}px)`};return x.opacity=z,L.jsx("div",{ref:C,"data-testid":"virtual-scroll-tap-circle",className:Ue.twMerge("relative flex touch-none select-none items-center justify-center","transition-transform duration-100 ease-out",e),style:x,tabIndex:-1,onPointerDown:ce,onPointerMove:E,onPointerUp:k,onPointerCancel:k,role:"presentation",children:j(_)})});gt.displayName="TapScrollCircle";const le=(s,e,t)=>Math.min(t,Math.max(e,s)),at="virtualscroll:tap-scroll-cancel",ut=20,Nt=250,Lt=60,Ot=20,Yt=20,zt=240,ft={active:!1,offsetX:0,offsetY:0,distance:0,direction:0},it=2.2,Ht=8,Xt=120,jt=1/60,Fe={enabled:!0,size:40,offsetX:-80,offsetY:0,className:void 0,maxVisualDistance:zt,minSpeedMultiplier:.2,opacity:.9,renderVisual:void 0,maxSpeedCurve:void 0},qt=s=>s?{mainSizeKey:"width",crossSizeKey:"height",positionKey:"left",selectDelta:(e,t)=>e,getPointerCoordinate:({clientX:e})=>e,arrowLabels:["Scroll left","Scroll right"],arrowIcons:["◀","▶"],directionClass:"flex flex-row items-stretch",orientation:"horizontal"}:{mainSizeKey:"height",crossSizeKey:"width",positionKey:"top",selectDelta:(e,t)=>t,getPointerCoordinate:({clientY:e})=>e,arrowLabels:["Scroll up","Scroll down"],arrowIcons:["▲","▼"],directionClass:"flex flex-col items-stretch",orientation:"vertical"},Ut=(s,e)=>{const t=s?.maxSpeedMultiplier,r=typeof t=="number"?t:Wt(e);return{enabled:s?.enabled??Fe.enabled,size:s?.size??Fe.size,offsetX:s?.offsetX??Fe.offsetX,offsetY:s?.offsetY??Fe.offsetY,className:s?.className??Fe.className,maxVisualDistance:s?.maxVisualDistance??Fe.maxVisualDistance,maxSpeedMultiplier:r,minSpeedMultiplier:Math.max(s?.minSpeedMultiplier??Fe.minSpeedMultiplier,0),opacity:le(s?.opacity??Fe.opacity,0,1),renderVisual:s?.renderVisual??Fe.renderVisual,maxSpeedCurve:s?.maxSpeedCurve??Fe.maxSpeedCurve}},Bt=({isDragging:s,isThumbHovered:e,enableThumbDrag:t})=>n.useMemo(()=>t?s?"dragging":e?"hover":"idle":"disabled",[t,s,e]),$t=({canUseArrowButtons:s,enableArrowButtons:e,resetTapScroll:t,scrollByStep:r})=>{const o=n.useRef(null),l=n.useRef(null),f=n.useCallback(()=>{o.current!==null&&(window.clearInterval(o.current),o.current=null),l.current!==null&&(window.clearTimeout(l.current),l.current=null)},[]),p=n.useCallback(()=>{f()},[f]),c=n.useCallback(d=>g=>{s&&(g.preventDefault(),g.stopPropagation(),t(),f(),r(d),l.current=window.setTimeout(()=>{o.current=window.setInterval(()=>{r(d)},Lt)},Nt))},[s,f,t,r]),u=n.useCallback(d=>g=>{e&&(g.key==="Enter"||g.key===" "||g.key==="Spacebar")&&(g.preventDefault(),r(d))},[e,r]);return n.useEffect(()=>()=>{f()},[f]),{handleArrowPointerDown:c,handleArrowPointerUp:p,handleArrowKeyDown:u}},Wt=s=>{if(!s||s<=0)return it;const e=Math.max(1,s),t=Math.log10(e),r=it+t*Ht;return le(r,it,Xt)},xt=({contentSize:s,viewportSize:e,scrollPosition:t,onScroll:r,enableThumbDrag:o=!0,enableTrackClick:l=!0,enableArrowButtons:f=!0,horizontal:p=!1,scrollBarWidth:c=12,className:u,ariaControls:d,tapScrollCircleOptions:g,itemCount:C,renderThumbOverlay:T})=>{const[F,V]=n.useState(!1),[J,O]=n.useState(!1),[ce,E]=n.useState(!1),k=n.useRef(null),z=n.useRef({pointerId:null,startThumbPosition:0,startClientX:0,startClientY:0}),N=n.useRef({pointerId:null,startThumbPosition:0,startClientX:0,startClientY:0}),w=n.useRef(t),H=n.useRef(ft),j=n.useRef(null),_=n.useRef(null),x=n.useRef(null),R=n.useMemo(()=>Ut(g,C),[C,g]),S=n.useMemo(()=>qt(p),[p]),{enabled:W,size:te,offsetX:ve,offsetY:ne,className:U,maxVisualDistance:ae,maxSpeedMultiplier:ue,minSpeedMultiplier:y,opacity:P,renderVisual:M,maxSpeedCurve:re}=R,B=n.useRef({viewportSize:e,maxScrollPosition:Math.max(s-e,0),scrollBarVisible:s>e,effectiveTapMaxDistance:Math.max(ae,1),tapCircleMaxSpeedMultiplier:ue,tapCircleMinSpeedMultiplier:y,tapCircleMaxSpeedCurve:re,tapScrollCircleOptions:g}),{mainSizeKey:K,crossSizeKey:fe,positionKey:Q,selectDelta:se,getPointerCoordinate:ee,arrowLabels:me,arrowIcons:de,directionClass:he,orientation:Te}=S,ye=Math.max(ae,1),Ee=e/s,m=c,h=Math.max(e-m*2,0),pe=Ee*h,G=Math.min(Math.max(ut,pe||0),h||ut),Y=s-e,Re=Math.max(h-G,0),ge=Y<=0||Re<=0?0:t/Y*Re,we=ge+G/2,xe=s>e,Ae=xe&&f;B.current={viewportSize:e,maxScrollPosition:Y,scrollBarVisible:xe,effectiveTapMaxDistance:ye,tapCircleMaxSpeedMultiplier:ue,tapCircleMinSpeedMultiplier:y,tapCircleMaxSpeedCurve:re,tapScrollCircleOptions:g},n.useEffect(()=>{w.current=t},[t]),n.useEffect(()=>{o||O(!1)},[o]);const Ye=Bt({isDragging:F,isThumbHovered:J,enableThumbDrag:o}),Ce=n.useCallback((i,b)=>{const A=B.current,Z=b??w.current;if(r){const De=r(i,Z);if(typeof De=="number"&&Number.isFinite(De))return w.current=De,De}const be=typeof i=="function"?i(Z):i,Ie=Math.max(A.maxScrollPosition,0),Ve=A.scrollBarVisible?le(be,0,Ie):0;return w.current=Ve,Ve},[r]),_e=n.useCallback(i=>{const b=B.current,A=w.current;if(!b.scrollBarVisible||b.maxScrollPosition<=0){const De=Ce(0,A),rt=De-A;return{nextPosition:De,actualDelta:rt,reachedBoundary:!0}}if(i===0)return{nextPosition:A,actualDelta:0,reachedBoundary:!1};const be=Ce(De=>le(De+i,0,b.maxScrollPosition),A),Ie=be-A,Ve=Ie===0||i<0&&be<=0||i>0&&be>=b.maxScrollPosition;return{nextPosition:be,actualDelta:Ie,reachedBoundary:Ve}},[Ce]),oe=n.useCallback(()=>{_.current!==null&&(window.cancelAnimationFrame(_.current),_.current=null),x.current=null},[]),Se=n.useCallback(()=>{H.current={...ft},E(!1),j.current?.reset(),oe()},[oe]),He=n.useCallback(i=>{const b=H.current,A=B.current;if(!b.active||b.direction===0){oe();return}if(!A.scrollBarVisible||A.maxScrollPosition<=0){oe();return}const Z=x.current??i,be=Math.max((i-Z)/1e3,0),Ie=Math.min(be,jt);if(x.current=i,Ie<=0){_.current=window.requestAnimationFrame(He);return}const Ve=Math.min(b.distance,A.effectiveTapMaxDistance)/A.effectiveTapMaxDistance,De=Ve**1.1,rt=typeof A.tapScrollCircleOptions?.maxSpeedMultiplier=="number",Be=Math.max(A.viewportSize*A.tapCircleMinSpeedMultiplier,40),St=rt?Be:1200;let st=Math.max(A.viewportSize*A.tapCircleMaxSpeedMultiplier,St);const Ze=A.tapCircleMaxSpeedCurve;if(Ze){const Je=Math.max(Ze.exponentialSteepness,0),At=Math.max(Ze.exponentialScale??A.tapCircleMaxSpeedMultiplier,0),kt=Je===0?Ve:Math.expm1(Je*Ve),lt=Je===0?1:Math.expm1(Je)||1,Vt=lt===0?Ve:Math.min(Math.max(kt/lt,0),1),Dt=A.viewportSize*At*Vt;st=Math.min(st,Math.max(Dt,Be))}const Pt=Math.max(st,Be),Mt=Math.max(Ze?.easedOffset??0,0),vt=Math.min(1,De+Mt),Rt=Be+(Pt-Be)*vt,wt=b.direction*Rt*Ie,{actualDelta:yt,reachedBoundary:Et}=_e(wt);if(Et||yt===0){oe();return}_.current=window.requestAnimationFrame(He)},[_e,oe]),Ke=n.useCallback(()=>{_.current===null&&(x.current=null,_.current=window.requestAnimationFrame(He))},[He]);n.useEffect(()=>()=>{oe()},[oe]);const tt=n.useCallback(i=>{H.current=i,E(i.active),i.active&&i.direction!==0?Ke():oe()},[Ke,oe]);n.useEffect(()=>{W||Se()},[Se,W]),n.useEffect(()=>{const i=b=>{const Z=b.detail?.paneId;Z&&d&&Z!==d||Se()};return window.addEventListener(at,i),()=>{window.removeEventListener(at,i)}},[d,Se]),n.useEffect(()=>{if(!W)return;const i=b=>{if(!H.current.active)return;const A=b.target;if(!(A instanceof Node)){Se();return}j.current?.getElement()?.contains(A)||Se()};return document.addEventListener("pointerdown",i,!0),()=>{document.removeEventListener("pointerdown",i,!0)}},[Se,W]);const a=i=>{if(!xe||Re<=0||Y<=0)return 0;const b=le(i,0,Re);return le(b/Re*Y,0,Y)},I=i=>{const b=Math.max(Math.round(e/Yt),Ot);_e(i*b)},{handleArrowPointerDown:v,handleArrowPointerUp:D,handleArrowKeyDown:q}=$t({canUseArrowButtons:Ae,enableArrowButtons:f,resetTapScroll:Se,scrollByStep:I}),$=i=>{if(!xe)return;if(!o){i.preventDefault(),i.stopPropagation();return}if(i.pointerType==="mouse"&&i.button!==0||i.ctrlKey)return;Se();const b=i.currentTarget;b.setPointerCapture&&b.setPointerCapture(i.pointerId),z.current={pointerId:i.pointerId,startThumbPosition:ge,startClientX:i.clientX,startClientY:i.clientY},V(!0),O(!0),i.preventDefault(),i.stopPropagation()},Pe=i=>{const b=z.current;if(b.pointerId!==i.pointerId)return;const A=i.clientX-b.startClientX,Z=i.clientY-b.startClientY,be=se(A,Z),Ie=a(b.startThumbPosition+be);Ce(Ie),i.cancelable&&i.preventDefault()},Ne=i=>{if(z.current.pointerId!==i.pointerId)return;const b=i.currentTarget;b.hasPointerCapture(i.pointerId)&&b.releasePointerCapture(i.pointerId),z.current={pointerId:null,startThumbPosition:0,startClientX:0,startClientY:0},V(!1),k.current&&!k.current.matches(":hover")&&O(!1),i.preventDefault(),i.stopPropagation()},ke=i=>{if(z.current.pointerId!==i.pointerId)return;const b=i.currentTarget;b.hasPointerCapture(i.pointerId)&&b.releasePointerCapture(i.pointerId),z.current={pointerId:null,startThumbPosition:0,startClientX:0,startClientY:0},V(!1),k.current&&!k.current.matches(":hover")&&O(!1)},Le=i=>{if(!xe)return;if(!l){i.preventDefault(),i.stopPropagation();return}if(i.pointerType==="mouse"&&i.button!==0||i.ctrlKey)return;const b=i.currentTarget,A=b.getBoundingClientRect(),be=ee(i)-(p?A.left:A.top);Se();const Ie=be-G/2,Ve=a(Ie);Ce(Ve),b.setPointerCapture&&b.setPointerCapture(i.pointerId),N.current={pointerId:i.pointerId,startThumbPosition:Ie,startClientX:i.clientX,startClientY:i.clientY},i.preventDefault(),i.stopPropagation()},Xe=i=>{const b=N.current;if(b.pointerId!==i.pointerId)return;const A=i.clientX-b.startClientX,Z=i.clientY-b.startClientY,be=se(A,Z),Ie=a(b.startThumbPosition+be);Ce(Ie),i.cancelable&&i.preventDefault()},Oe=i=>{if(N.current.pointerId!==i.pointerId)return;const b=i.currentTarget;b.hasPointerCapture(i.pointerId)&&b.releasePointerCapture(i.pointerId),N.current={pointerId:null,startThumbPosition:0,startClientX:0,startClientY:0},i.preventDefault(),i.stopPropagation()},je=i=>{if(N.current.pointerId!==i.pointerId)return;const b=i.currentTarget;b.hasPointerCapture(i.pointerId)&&b.releasePointerCapture(i.pointerId),N.current={pointerId:null,startThumbPosition:0,startClientX:0,startClientY:0}},X=n.useMemo(()=>le((ce?1:.8)*P,0,1),[ce,P]),qe=n.useMemo(()=>{const b=`calc(50% - ${te/2}px + ${ne}px)`;return{left:ve,top:b}},[ve,ne,te]),nt=(i,b,A)=>L.jsx("button",{type:"button",tabIndex:-1,className:"aqvs:scrollbar-arrow-button flex items-center justify-center text-xs transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-50",style:{[K]:m,[fe]:c},"aria-label":b,onMouseDown:v(i),onTouchStart:v(i),onMouseUp:D,onMouseLeave:D,onTouchEnd:D,onTouchCancel:D,onKeyDown:q(i),"aria-disabled":!f,disabled:!Ae,children:L.jsx("span",{"aria-hidden":"true",children:A})}),Ge=T&&xe?{orientation:Te,scrollPosition:t,maxScrollPosition:Y,contentSize:s,viewportSize:e,thumbSize:G,thumbPosition:ge,thumbCenter:we,trackSize:h,isDragging:F,isTapScrollActive:ce}:null;return L.jsxs("div",{className:Ue.twMerge("group relative cursor-default select-none",he,u),style:{[K]:e,[fe]:c,backgroundColor:"white",userSelect:"none",position:"relative",touchAction:"none"},role:"scrollbar",tabIndex:-1,"aria-controls":d,"aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":Y,"aria-orientation":p?"horizontal":"vertical",children:[!p&&xe&&W&&L.jsx(gt,{ref:j,className:Ue.twMerge("pointer-events-auto absolute transition-opacity duration-150",U),size:te,maxVisualDistance:ye,style:qe,opacity:X,renderVisual:M,onDragChange:tt}),nt(-1,me[0],de[0]),L.jsxs("div",{className:"aqvs:scrollbar-track relative flex-1",style:{borderRadius:c/2,touchAction:"none"},onPointerDown:Le,onPointerMove:Xe,onPointerUp:Oe,onPointerCancel:je,"aria-disabled":!l,children:[Ge&&L.jsx("div",{className:"pointer-events-none absolute inset-0","aria-hidden":!0,children:T?.(Ge)}),xe&&L.jsx("div",{className:"group absolute",style:{[K]:G,[Q]:ge,...p?{top:0,bottom:0}:{left:0,right:0},touchAction:"none"},onPointerDown:$,onPointerMove:Pe,onPointerUp:Ne,onPointerCancel:ke,role:"slider","aria-orientation":p?"horizontal":"vertical","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":Y,"aria-disabled":!o,tabIndex:-1,children:L.jsx("div",{ref:k,className:Ue.twMerge("aqvs:scrollbar-thumb absolute",p?"aqvs:scrollbar-thumb-horizontal":"aqvs:scrollbar-thumb-vertical"),"data-thumb-state":Ye,style:{borderRadius:c-1,cursor:o?"pointer":"default"},onMouseEnter:()=>{o&&O(!0)},onMouseLeave:()=>{o&&O(!1)}})})]}),nt(1,me[1],de[1])]})},Me={debug(s,...e){typeof window<"u"&&window.localStorage?.getItem("debug")==="true"&&console.debug(`[VirtualScroll] ${s}`,...e)},warn(s,...e){console.warn(`[VirtualScroll] ${s}`,...e)},error(s,...e){console.error(`[VirtualScroll] ${s}`,...e)}},$e={maxVelocity:6,minVelocity:.02,deceleration:.0025,velocitySampleWindow:90,startVelocityThreshold:.04},Qe=(s,e,t)=>{for(const[r,o,l]of e)t==="add"?s.addEventListener(r,o,l):s.removeEventListener(r,o,l)},bt=n.forwardRef(({children:s,contentSize:e,viewportSize:t,scrollBarWidth:r=12,enableThumbDrag:o=!0,enableTrackClick:l=!0,enableArrowButtons:f=!0,enablePointerDrag:p=!0,onScroll:c,className:u,style:d,background:g,tapScrollCircleOptions:C,inertiaOptions:T,itemCount:F,renderThumbOverlay:V,wheelSpeedMultiplier:J=1,contentInsets:O},ce)=>{const E=n.useRef(0),k=n.useRef(null),z=n.useRef(null),N=n.useRef({frame:null,velocity:0,lastTimestamp:null}),w=n.useMemo(()=>({maxVelocity:T?.maxVelocity??$e.maxVelocity,minVelocity:T?.minVelocity??$e.minVelocity,deceleration:T?.deceleration??$e.deceleration,velocitySampleWindow:T?.velocitySampleWindow??$e.velocitySampleWindow,startVelocityThreshold:T?.startVelocityThreshold??$e.startVelocityThreshold}),[T]),H=n.useMemo(()=>({top:Math.max(0,O?.top??0),bottom:Math.max(0,O?.bottom??0)}),[O]);Me.debug("[ScrollPane] ScrollPane rendered",{contentSize:e,viewportSize:t,scrollBarWidth:r,className:u,style:d,tapScrollCircleOptions:C,inertiaOptions:T,enablePointerDrag:p,contentInsets:H});const j=n.useRef({contentSize:e,viewportSize:t}),_=n.useMemo(()=>e>t,[e,t]),x=n.useCallback(P=>{const{contentSize:M,viewportSize:re}=j.current,B=M>re,K=E.current;if(Me.debug("[ScrollPane] scrollTo called",{newPosition:P,contentSize:M,viewportSize:re,currentIsScrollable:B,prevPosition:K}),!B)return E.current!==0&&(E.current=0,c?.(0,K)),E.current;const fe=typeof P=="function"?P(E.current):P,Q=Math.max(M-re,0),se=le(fe,0,Q);return E.current!==se&&(E.current=se,c?.(se,K)),E.current},[c]),R=n.useCallback(()=>{const P=N.current;P.frame!==null&&cancelAnimationFrame(P.frame),P.frame=null,P.velocity=0,P.lastTimestamp=null},[]),S=n.useRef(R);n.useEffect(()=>{S.current=R},[R]);const W=n.useCallback(P=>{if(!_)return;const{maxVelocity:M,minVelocity:re,deceleration:B,startVelocityThreshold:K}=w,fe=le(P,-M,M);if(Math.abs(fe)<K)return;R(),N.current.velocity=fe,N.current.lastTimestamp=null;const Q=se=>{const ee=N.current;if(ee.lastTimestamp===null){ee.lastTimestamp=se,ee.frame=requestAnimationFrame(Q);return}const me=se-ee.lastTimestamp;if(ee.lastTimestamp=se,me<=0){ee.frame=requestAnimationFrame(Q);return}const de=ee.velocity;let he=de;const Te=B*me;de>0?he=Math.max(0,de-Te):de<0&&(he=Math.min(0,de+Te));const Ee=(de+he)/2*me,m=E.current;Ee!==0&&x(ge=>ge+Ee);const h=E.current,{contentSize:pe,viewportSize:G}=j.current,Y=Math.max(pe-G,0);ee.velocity=he;const Re=h===m||h<=0&&he<=0||h>=Y&&he>=0;if(Math.abs(he)<re||Re){R();return}ee.frame=requestAnimationFrame(Q)};N.current.frame=requestAnimationFrame(Q)},[_,w,x,R]),te=n.useRef(W);n.useEffect(()=>{te.current=W},[W]),n.useLayoutEffect(()=>{j.current={contentSize:e,viewportSize:t}},[e,t]),n.useLayoutEffect(()=>{if(_){Me.debug("[ScrollPane] Adjusting scroll position due to content or viewport size change",{contentSize:e,viewportSize:t,scrollPosition:E.current});const P=le(e-t,0,e);E.current>P&&x(P)}else x(0)},[_,x,e,t]),n.useEffect(()=>{const P=re=>{if(!_)return;re.preventDefault(),R();let B=re.deltaY;re.deltaMode===1?B*=16:re.deltaMode===2&&(B*=t),J!==1&&(B*=J),Me.debug("[ScrollPane] wheel event",{deltaY:B,scrollPosition:E.current,wheelSpeedMultiplier:J}),x(K=>K+B)},M=k.current;return M&&M.addEventListener("wheel",P,{passive:!1}),()=>{M&&M.removeEventListener("wheel",P)}},[_,x,R,t,J]),n.useImperativeHandle(ce,()=>({scrollTo:x,getScrollPosition:()=>E.current,getContentSize:()=>e,getViewportSize:()=>t}),[x,e,t]);const ve=n.useRef(x);n.useEffect(()=>{ve.current=x},[x]);const ne=n.useId(),U=n.useRef({pointerId:null,startClientY:0,startScroll:0,isDragging:!1,shouldCancelNextClick:!1,clickResetTimer:null,velocitySamples:[]}),ae=n.useRef(p);n.useEffect(()=>{ae.current=p},[p]);const ue=n.useRef(_);n.useEffect(()=>{ue.current=_},[_]);const y=n.useRef(w);return n.useEffect(()=>{y.current=w},[w]),n.useEffect(()=>{if(p)return;const P=z.current,M=U.current;M.pointerId!==null&&P&&P.hasPointerCapture(M.pointerId)&&P.releasePointerCapture(M.pointerId),M.clickResetTimer!==null&&(window.clearTimeout(M.clickResetTimer),M.clickResetTimer=null),M.pointerId=null,M.startClientY=0,M.startScroll=0,M.isDragging=!1,M.shouldCancelNextClick=!1,M.velocitySamples=[]},[p]),n.useEffect(()=>{const P=z.current;if(!P)return;const M=6,re=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now(),B=()=>{const m=U.current;m.pointerId=null,m.startClientY=0,m.startScroll=0,m.isDragging=!1,m.velocitySamples=[]},K=()=>{const m=U.current;m.clickResetTimer!==null&&(window.clearTimeout(m.clickResetTimer),m.clickResetTimer=null)},fe=m=>{const h=U.current,pe=re();h.velocitySamples.push({clientY:m,time:pe});const G=y.current.velocitySampleWindow;h.velocitySamples=h.velocitySamples.filter(Y=>pe-Y.time<=G)},Q=m=>m instanceof HTMLElement&&m.closest("[data-scrollpane-ignore-drag='true']")!==null,se=m=>{const h=U.current;h.shouldCancelNextClick&&(m.preventDefault(),m.stopPropagation(),h.shouldCancelNextClick=!1)},ee=m=>{const h=U.current;h.isDragging||(h.isDragging=!0,h.shouldCancelNextClick=!0,P.hasPointerCapture(m.pointerId)||P.setPointerCapture(m.pointerId),fe(m.clientY))},me=m=>{const h=U.current;if(h.pointerId!==m.pointerId||!(ae.current&&ue.current)||!h.isDragging&&(Math.abs(m.clientY-h.startClientY)<M||(ee(m),!h.isDragging)))return;fe(m.clientY);const pe=m.clientY-h.startClientY,G=h.startScroll-pe;ve.current(G),m.cancelable&&m.preventDefault()},de=m=>{const h=U.current;if(h.pointerId!==m.pointerId)return;h.isDragging&&h.shouldCancelNextClick&&m.cancelable&&(m.preventDefault(),m.stopPropagation()),P.hasPointerCapture(m.pointerId)&&P.releasePointerCapture(m.pointerId);let pe=0;if(h.isDragging&&h.velocitySamples.length>=2){const Y=h.velocitySamples,Re=y.current.velocitySampleWindow,ge=Y[Y.length-1],we=Y.find(xe=>ge.time-xe.time<=Re)??Y[0];if(ge&&we&&ge.time!==we.time){const xe=ge.clientY-we.clientY,Ae=ge.time-we.time;pe=-(xe/Ae)}}K(),h.shouldCancelNextClick&&(h.clickResetTimer=window.setTimeout(()=>{const Y=U.current;Y.shouldCancelNextClick=!1,Y.clickResetTimer=null},0));const G=y.current.startVelocityThreshold;B(),Math.abs(pe)>=G&&te.current?.(pe)},he=m=>{if(!(ae.current&&ue.current)||m.button!==0&&m.pointerType==="mouse"||m.ctrlKey||m.metaKey||m.altKey||Q(m.target))return;window.dispatchEvent(new CustomEvent(at,{detail:{paneId:ne}})),S.current?.();const h=U.current;K(),h.pointerId=m.pointerId,h.startClientY=m.clientY,h.startScroll=E.current,h.isDragging=!1,h.shouldCancelNextClick=!1,h.velocitySamples=[]},Te=m=>{const h=U.current;h.pointerId===m.pointerId&&(h.shouldCancelNextClick=!1,P.hasPointerCapture(m.pointerId)&&P.releasePointerCapture(m.pointerId),K(),B())},ye=[["click",se,!0],["pointerdown",he,{passive:!1}],["pointermove",me,{passive:!1}],["pointerup",de,void 0],["pointercancel",Te,void 0]],Ee=[["pointermove",me,{passive:!1}],["pointerup",de,void 0],["pointercancel",Te,void 0]];return Qe(P,ye,"add"),Qe(window,Ee,"add"),()=>{Qe(P,ye,"remove"),Qe(window,Ee,"remove");const m=U.current;m.pointerId!==null&&P.hasPointerCapture(m.pointerId)&&P.releasePointerCapture(m.pointerId),K(),B()}},[ne]),L.jsxs("div",{ref:k,className:Ue.twMerge("flex",u),style:d,children:[L.jsxs("div",{ref:z,className:Ue.twMerge("relative h-full flex-1 overflow-hidden"),style:{height:t,paddingTop:H.top,paddingBottom:H.bottom,...p?{touchAction:"none"}:{}},id:ne,children:[g,s(E.current)]}),_&&L.jsx(xt,{contentSize:e,viewportSize:t,scrollPosition:E.current,onScroll:x,enableThumbDrag:o,enableTrackClick:l,enableArrowButtons:f,scrollBarWidth:r,ariaControls:ne,tapScrollCircleOptions:C,itemCount:F,renderThumbOverlay:V})]})}),dt=(s,e,t)=>Math.min(Math.max(s,e),t),Kt=({dragState:s,normalizedDistance:e,sizeScale:t,size:r})=>{const o=Math.max(r/2,1),l=1+e*.65,f=Math.max(.65,1-e*.25),p=s.direction*e*26*t,c=.8+e*.18,u=3*t,d=6*t,g=22*t,C=Math.abs(p)+d,T=p>0?u:-Math.abs(p)-u,F=Math.max(2.5,3*t),V=dt(s.offsetX,-o,o),J=dt(s.offsetY,-o,o),O=o*.35,ce=V/o*O,E=J/o*O,k=ce*.45,z=E*.45,N=Math.max(g*.38,6),w=.65+e*.2,H=s.active;return L.jsxs(L.Fragment,{children:[L.jsx("div",{className:"aqvs:tap-scroll-circle-gradient absolute inset-0 rounded-full border border-white/40 shadow-md",style:{transform:`scale(${f}, ${l})`,transition:H?"40ms transform ease-out":"200ms ease transform"}}),L.jsx("div",{className:"absolute top-1/2 left-1/2 rounded-full border border-white/50 bg-white/85",style:{width:g,height:g,transform:`translate(calc(-50% + ${ce}px), calc(-50% + ${E}px)) scale(${f}, ${c*l})`,transition:H?"70ms transform ease-out":"200ms ease transform"}}),L.jsx("div",{className:"absolute top-1/2 left-1/2 rounded-full bg-white/80",style:{width:N,height:N,transform:`translate(calc(-50% + ${k}px), calc(-50% + ${z}px)) scale(${f}, ${l})`,opacity:w,boxShadow:"0 0 8px rgba(255,255,255,0.45)",transition:H?"120ms opacity 150ms, 120ms transform ease-out ease-out":"220ms ease transform, 240ms opacity ease"}}),L.jsx("div",{className:"absolute top-1/2 left-1/2 rounded-full bg-white/50",style:{width:F,height:C,transform:`translate(-50%, ${T}px)`,opacity:e,transition:H?"40ms height, 60ms opacity ease-out ease-out":"200ms ease height, 120ms ease opacity"}})]})},Gt=s=>{if(!Number.isFinite(s))return 0n;const e=Math.trunc(s);return e<=0?0n:BigInt(e)},et=s=>{if(s<=0||!Number.isFinite(s))return 0;const e=Math.trunc(s),t=BigInt(e)&-BigInt(e);return Number(t)};class It{tree;deltas;size;baseValue;valueFn;total;constructor(e,t,r){this.reset(e,t,r)}reset(e,t,r){if(this.size=e,this.tree=new Map,this.deltas=new Map,this.total=void 0,typeof t=="function"){if(this.valueFn=t,this.size>0){const l=r?.sampleRange??{from:0,to:Math.min(99,this.size-1)},{mode:f,materializedValues:p}=this._calculateMode(l.from,l.to);if(this.baseValue=f,r?.materialize)for(let c=0;c<p.length;c++){const u=p[c],d=l.from+c;if(d>=this.size)break;const g=u-this.baseValue;this.deltas.set(d,g),this._updateTree(d,g)}}else this.baseValue=0;this.total=this.getTotal()}else this.valueFn=void 0,this.baseValue=t,this.total=this.baseValue*this.size}setValueFn(e){typeof e=="function"?this.valueFn=e:(this.valueFn=void 0,this.baseValue=e)}_calculateMode(e,t){if(!this.valueFn)return{mode:0,materializedValues:[]};const r=[];for(let u=e;u<=t&&!(u>=this.size);u++)r.push(this.valueFn(u));const o=[...r];if(r.length===0)return{mode:0,materializedValues:[]};r.sort((u,d)=>u-d);const l=Math.floor(r.length/2);let f;r.length%2===0?f=Math.floor((r[l-1]+r[l])/2):f=r[l];const p=new Map;let c=0;for(const u of r){const d=(p.get(u)??0)+1;p.set(u,d),d>c&&(c=d)}if(c>1){const u=[];for(const[g,C]of p.entries())C===c&&u.push(g);const d=u.reduce((g,C)=>g+C,0);f=Math.floor(d/u.length)}return{mode:f,materializedValues:o}}update(e,t){return this.updates([{index:e,value:t}])}updates(e){const t=this._buildDeltaUpdates(e);return t.length>0?this.updateDeltas(t):this.total}updateDelta(e,t){return this.updateDeltas([{index:e,change:t}])}updateDeltas(e){for(const{index:t,change:r}of e){if(t<0||t>=this.size)throw new Error(`Index ${t} out of bounds`);const o=this.deltas.get(t)??0;this.deltas.set(t,o+r),this._updateTree(t,r)}return this.total}_updateTree(e,t){if(t===0)return;let r=e+1;for(;r<=this.size;){this.tree.set(r,(this.tree.get(r)??0)+t);const o=et(r);if(o===0)break;r+=o}this.total!==void 0&&(this.total+=t)}_buildDeltaUpdates(e){const t=[];for(const{index:r,value:o}of e){if(r<0||r>=this.size)throw new Error(`Index ${r} out of bounds`);if(o<0)throw new Error("Value cannot be negative.");const l=this.deltas.has(r)?(this.deltas.get(r)??0)+this.baseValue:this.baseValue,f=o-l;f!==0&&t.push({index:r,change:f})}return t}_computeTreeTotal(){if(this.size<=0)return 0;let e=0,t=this.size;for(;t>0;){e+=this.tree.get(t)??0;const r=et(t);if(r===0)break;t-=r}return e+this.baseValue*this.size}_materialize(e,t=!0){if(this.valueFn){const r=this.deltas.get(e)??0,l=this.valueFn(e)-this.baseValue;if(l!==r&&(this.deltas.set(e,l),t)){const f=l-r;this._updateTree(e,f)}}}_materializeRanges(e,t,r=!1){if(!(e?.materialize&&this.valueFn))return;const o=e.ranges;if(o&&o.length>0){for(const p of o){const c=p.from,u=Math.min(p.to,this.size-1);for(let d=c;d<=u;d++)this._materialize(d)}if(t===void 0)return;if(r){this._materialize(t);return}const l=o[0].from,f=o[o.length-1].to;t>=l&&t<=f&&this._materialize(t);return}t!==void 0&&this._materialize(t)}_findIndex(e,t={},r){if(this.size>=Number.MAX_SAFE_INTEGER)return this._findIndexLarge(e,t,r);if(this.size===0)return{index:-1,total:this.total??0,cumulative:void 0,currentValue:void 0,safeIndex:void 0};let o=0,l=this.size-1,f=-1,p,c=this.total;for(;o<=l;){const u=Math.floor((o+l)/2);p=this.prefixSum(u,t),c=p.total,(r?p.cumulative>=e:p.cumulative<=e)?(f=u,r?l=u-1:o=u+1):r?o=u+1:l=u-1}return{index:f,total:c,cumulative:p?.cumulative,currentValue:p?.currentValue,safeIndex:p?.safeIndex}}_findIndexLarge(e,t,r){if(this.size===0)return{index:-1,total:this.total??0,cumulative:void 0,currentValue:void 0,safeIndex:void 0};const o=Gt(this.size);if(o===0n)return{index:-1,total:this.total??0,cumulative:void 0,currentValue:void 0,safeIndex:void 0};let l=0n,f=o-1n,p,c,u,d=this.total;for(;l<=f;){const T=l+f>>1n,F=Number(T),V=this.prefixSum(F,t);if(u=V,d=V.total,r?V.cumulative>=e:V.cumulative<=e)if(p=T,c=V,r){if(T===0n)break;f=T-1n}else l=T+1n;else if(r)l=T+1n;else{if(T===0n)break;f=T-1n}}const g=c??u;return{index:p!==void 0?Number(p):-1,total:d,cumulative:g?.cumulative,currentValue:g?.currentValue,safeIndex:g?.safeIndex}}prefixSum(e,t){if(e<0)return{cumulative:0,total:this.total,currentValue:0,safeIndex:0};const r=le(e,0,this.size-1),o=t?.materializeOption;this._materializeRanges(o,r,!0);let l=0,f=r+1;for(;f>0;){const c=this.tree.get(f)??0;l+=c;const u=et(f);if(u===0)break;f-=u}const p=o?.materialize?this.get(r):(this.deltas.get(r)||0)+this.baseValue;return{cumulative:l+this.baseValue*(r+1),total:this.total,currentValue:p,safeIndex:r}}get(e,t){if(e<0||e>=this.size)throw new Error("Index out of bounds");const r=t?.materializeOption;return this._materializeRanges(r,e),(this.deltas.get(e)??0)+this.baseValue}getTotal(e){const t=e?.materializeOption;if(this._materializeRanges(t),this.total===void 0)if(this.size===0)this.total=0;else{this.total=this._computeTreeTotal();const r=this.prefixSum(this.getSize()-1);console.assert(r.cumulative===r.total,"Inconsistent Fenwick Tree state")}return this.total}rebuildTree(e){if(e?.materialize&&this.valueFn){const r=this.valueFn;this.reset(this.size,o=>r(o),{materialize:!0});return}const t=new Map;for(const[r,o]of this.deltas.entries()){if(o===0)continue;let l=r+1;for(;l<=this.size;){t.set(l,(t.get(l)??0)+o);const f=et(l);if(f===0)break;l+=f}}this.tree=t,this.total=this._computeTreeTotal()}calculateAccumulatedError(){if(this.total===void 0)return 0;let e=this.baseValue*this.size;for(const t of this.deltas.values())e+=t;return this.total-e}changeSize(e){const t=this.size;if(e===t)return;if(e<t)for(const o of this.deltas.keys())o>=e&&this.deltas.delete(o);this.size=e,this.rebuildTree();const r=this.prefixSum(this.getSize()-1);console.assert(r.cumulative===r.total,"Inconsistent Fenwick Tree state")}getSize(){return this.size}findIndexAtOrAfter(e,t){return this._findIndex(e,t??{},!0)}findIndexAtOrBefore(e,t){return this._findIndex(e,t??{},!1)}}const Tt=(s,e,t)=>{const r=Math.max(0,s),o=n.useRef(null),l=n.useMemo(()=>new It(r,e,t),[r,e,t]);return Object.is(o.current,l)||console.warn("[useFenwickMapTree] instance changed"),o.current=l,l};class Zt{key;value;prev=null;next=null;constructor(e,t){this.key=e,this.value=t}}class pt{head=null;tail=null;addToTail(e){this.tail?(this.tail.next=e,e.prev=this.tail,this.tail=e):this.head=this.tail=e}remove(e){e.prev?e.prev.next=e.next:this.head=e.next,e.next?e.next.prev=e.prev:this.tail=e.prev,e.prev=null,e.next=null}removeHead(){const e=this.head;return e&&this.remove(e),e}moveToTail(e){this.remove(e),this.addToTail(e)}}function Ct(s){const e=n.useRef(new Map),t=n.useRef(new pt);n.useEffect(()=>{for(;e.current.size>s;){const d=t.current.removeHead();if(d)e.current.delete(d.key);else break}},[s]);const r=n.useCallback(d=>{const g=e.current.get(d);if(g)return t.current.moveToTail(g),g.value},[]),o=n.useCallback((d,g)=>{if(s<=0)return;let C=e.current.get(d);if(C)C.value=g,t.current.moveToTail(C);else{if(e.current.size>=s){const T=t.current.removeHead();T&&e.current.delete(T.key)}C=new Zt(d,g),e.current.set(d,C),t.current.addToTail(C)}},[s]),l=n.useCallback(d=>e.current.has(d),[]),f=n.useCallback(d=>{const g=e.current.get(d);g&&(t.current.remove(g),e.current.delete(d))},[]),p=n.useCallback(()=>{e.current.clear(),t.current=new pt},[]),[c,u]=n.useState(()=>({get:r,set:o,has:l,remove:f,clear:p}));return n.useEffect(()=>u({get:r,set:o,has:l,remove:f,clear:p}),[r,o,l,f,p]),c}const Jt=1e4,Qt=()=>{const{get:s,set:e,has:t,clear:r}=Ct(Jt);return{get:s,set:e,has:t,clear:r}},ie=(s,e)=>e<=0?0:le(s,0,e-1),en=s=>({top:Math.max(0,s?.top??0),bottom:Math.max(0,s?.bottom??0)}),ze=(s,e)=>s<=e?0:s-e,We=(s,e)=>s<=0?e:s+e,mt=s=>{if(!Number.isFinite(s))return 0n;const e=Math.trunc(s);return e<=0?0n:BigInt(e)},tn=(s,e,t,r,o,l,f,p)=>{const c=mt(r);if(c===0n)return{renderingStartIndex:0,renderingEndIndex:0,visibleStartIndex:0,visibleEndIndex:0};const u=k=>k<0n?0n:k>=c?c-1n:k,d={materializeOption:{materialize:!1}},{index:g}=l.findIndexAtOrAfter(s,d);let C;g===-1?C=c-1n:(C=mt(g),C>=c&&(C=c-1n)),s<=0&&(C=0n),p&&s>=f&&(C=c-1n);const T=k=>{let z=0,N=k,w=k,H=0n;for(;N<c&&z<e;){const j=Number(N),_=o(j);if(z+=_,w=N,N+=1n,H+=1n,!Number.isFinite(_)||_<=0)break}return H===0n&&(w=k),{height:z,end:w}};let{height:F,end:V}=T(C);if(F<e&&C>0n){let k=C,z=F;for(;k>0n&&z<e;){k-=1n;const w=Number(k),H=o(w);if(z+=H,!Number.isFinite(H)||H<=0)break}C=u(k);const N=T(C);F=N.height,V=N.end}const J=u(C),O=u(V),ce=u(J-BigInt(Math.max(0,t))),E=u(O+BigInt(Math.max(0,t)));return{renderingStartIndex:ie(Number(ce),r),renderingEndIndex:ie(Number(E),r),visibleStartIndex:ie(Number(J),r),visibleEndIndex:ie(Number(O),r)}},nn=(s,e,t,r,o,l)=>{if(r===0)return{renderingStartIndex:0,renderingEndIndex:0,visibleStartIndex:0,visibleEndIndex:0};const f=l.getTotal(),p=Number.isFinite(f),c=p?Math.min(s,f):s;if(r>Number.MAX_SAFE_INTEGER)return tn(c,e,t,r,o,l,f,p);const{index:u,cumulative:d,currentValue:g}=l.findIndexAtOrAfter(c,{materializeOption:{materialize:!1}}),C=u===-1?e<=0||(d??0)<c+(g??0)?r-1:0:u;let T=ie(C,r),F=0,V=T;for(;V<r&&F<e;)F+=o(V),V++;if(F<e&&T>0){let E=F,k=T-1;for(;k>=0&&E<e;)E+=o(k),k--;for(T=ie(k+1,r),F=0,V=T;V<r&&F<e;)F+=o(V),V++}const J=ie(T-t,r),O=ie(Math.max(V-1,T),r),ce=ie(O+t,r);return{renderingStartIndex:J,renderingEndIndex:ce,visibleStartIndex:T,visibleEndIndex:O}},rn=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now(),ht=(s,e,t)=>{const r=Math.max(0,e??0),o=n.useRef({lastInvokeAt:0,rafId:null,pendingPayload:null,loopActive:!1,normalizedThrottle:r}),l=n.useCallback(()=>{const c=o.current;c.rafId!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(c.rafId),c.rafId=null,c.loopActive=!1},[]),f=n.useCallback(c=>{const u=o.current;u.rafId=null;const d=typeof c=="number"?c:rn(),g=u.normalizedThrottle,C=u.pendingPayload,T=s.current;if(C!==null&&T){const F=d-u.lastInvokeAt;(g===0||u.lastInvokeAt===0||F>=g)&&(u.pendingPayload=null,u.lastInvokeAt=d,t(T,C))}if(u.pendingPayload!==null){typeof requestAnimationFrame=="function"?u.rafId=requestAnimationFrame(f):u.loopActive=!1;return}u.loopActive=!1},[s,t]),p=n.useCallback(()=>{const c=o.current;if(!c.loopActive){if(c.loopActive=!0,typeof requestAnimationFrame=="function"){c.rafId=requestAnimationFrame(f);return}c.loopActive=!1}},[f]);return n.useEffect(()=>()=>{l(),o.current.pendingPayload=null},[l]),n.useEffect(()=>{l();const c=o.current;c.lastInvokeAt=0,c.pendingPayload=null,c.normalizedThrottle=r},[r,l]),n.useCallback(c=>{const u=o.current;u.pendingPayload=c,p()},[p])},sn=({itemCount:s,getItem:e,getItemHeight:t,viewportSize:r,overscanCount:o=15,className:l,onScroll:f,onRangeChange:p,children:c,background:u,initialScrollIndex:d,initialScrollOffset:g,tapScrollCircleOptions:C,scrollBarWidth:T,enableThumbDrag:F,enableTrackClick:V,enableArrowButtons:J,enablePointerDrag:O,inertiaOptions:ce,callbackThrottleMs:E=5,renderThumbOverlay:k,wheelSpeedMultiplier:z,contentInsets:N,enableKeyboardNavigation:w=!0},H)=>{const j=n.useRef(null),_=n.useRef(!1),x=n.useMemo(()=>en(N),[N]),R=n.useRef({size:s,valueOrFn:t,options:{sampleRange:{from:0,to:100}}}),S=Tt(R.current.size,R.current.valueOrFn,R.current.options),[W]=n.useState(()=>{let a=x.top,I=0;if(typeof d=="number"){const v=le(d,0,s-1),D=le(v-o*2,0,s-1),q=le(v+o*2,0,s-1),$=d>0?{materializeOption:{materialize:!0,ranges:[{from:D,to:q}]}}:void 0,{cumulative:Pe,total:Ne,currentValue:ke}=S.prefixSum(d,$),Le=Math.max(Pe-ke,0);a=We(Le,x.top),I=Ne??S.getTotal()}else typeof g=="number"&&(a=We(Math.max(g,0),x.top)),I=S.getTotal();return{position:a,total:I}}),[te,ve]=n.useState(W.position),[ne,U]=n.useState(W.total),[ae,ue]=n.useState(W.position),[y,P]=n.useState(s),M=n.useRef(W.position),re=n.useRef(x.top),B=n.useRef(f??void 0),K=n.useRef(p??void 0),fe=n.useRef(new Map),Q=n.useRef(null),se=n.useRef(null);n.useEffect(()=>{B.current=f??void 0,K.current=p??void 0},[p,f]);const ee=n.useCallback(a=>{if(w&&a&&typeof a.focus=="function")try{a.focus({preventScroll:!0})}catch{a.focus()}},[w]),me=ht(B,E,(a,{position:I,totalHeight:v})=>{a(I,v)}),de=ht(K,E,(a,{renderingStartIndex:I,renderingEndIndex:v,visibleStartIndex:D,visibleEndIndex:q,scrollPosition:$,totalHeight:Pe})=>{a(I,v,D,q,$,Pe)});n.useEffect(()=>(_.current=!0,()=>{_.current=!1}),[]),n.useEffect(()=>{w||(fe.current.clear(),Q.current=null,se.current=null)},[w]);const he=.01,Te=n.useRef({rafId:null,loopActive:!1,idleFrames:0,lastRenderedPosition:W.position}),ye=n.useCallback(()=>{const a=Te.current;a.rafId!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(a.rafId),a.rafId=null,a.loopActive=!1,a.idleFrames=0},[]);n.useEffect(()=>()=>{ye()},[ye]);const Ee=n.useCallback(()=>{const a=Te.current;a.rafId=null;const I=M.current,v=ze(I,x.top),D=S.getTotal();if(ve($=>Math.abs($-I)<he?$:I),me({position:v,totalHeight:D}),Math.abs(a.lastRenderedPosition-I)>=he?(a.lastRenderedPosition=I,a.idleFrames=0):a.idleFrames+=1,a.idleFrames>=2){ye();return}if(typeof requestAnimationFrame=="function"){a.rafId=requestAnimationFrame(Ee);return}a.loopActive=!1},[S,x.top,me,ye]),m=n.useCallback(()=>{const a=Te.current;if(a.idleFrames=0,!a.loopActive){if(a.loopActive=!0,typeof requestAnimationFrame=="function"){a.rafId=requestAnimationFrame(Ee);return}a.loopActive=!1}},[Ee]),h=n.useCallback((a,I)=>{const v=I?.immediate??!1,D=ze(a,x.top);if(M.current=a,v){Te.current.lastRenderedPosition=a,Te.current.idleFrames=0,ve(a),me({position:D,totalHeight:S.getTotal()});return}m()},[m,S,x.top,me]),pe=n.useRef(!1);n.useEffect(()=>{if(!pe.current)if(pe.current=!0,typeof g=="number"){const a=We(Math.max(g,0),x.top),I=Math.abs(a-M.current)>.5;h(a,{immediate:!0}),I&&ue(a)}else h(M.current,{immediate:!0})},[g,x.top,h]),n.useLayoutEffect(()=>{S.setValueFn(t),y!==s&&(S.changeSize(s),P(s));const a=S.getTotal();ne!==a&&U(a)},[S,y,s,ne,t]),n.useLayoutEffect(()=>{ae!==null&&j.current&&(Me.debug("[VirtualScroll] Scrolling to position:",ae),j.current.scrollTo(ae),ue(null))},[ae]),n.useEffect(()=>{const a=re.current;if(a===x.top)return;const I=ze(M.current,a),v=We(I,x.top);re.current=x.top,M.current=v,ue(v),h(v,{immediate:!0})},[x.top,h]);const G=n.useCallback(a=>{if(!j.current)return;const I=ie(a,y),v=ie(I-o*2,y),D=ie(I+o*2,y),{cumulative:q,total:$,currentValue:Pe}=S.prefixSum(I,{materializeOption:{materialize:!0,ranges:[{from:v,to:D}]}});if(Me.debug("[VirtualScroll] Scrolling to index:",I,"Offset:",q,"Total height:",$,"Current value:",Pe,"safeIndexFrom:",v,"safeIndexTo:",D),!$)return;const Ne=Math.max(q-Pe,0),ke=We(Ne,x.top);U($),ue(ke),Me.debug("[VirtualScroll] Setting scroll position to:",ke)},[S,o,y,x.top]),Y=n.useCallback(a=>{if(!j.current)return;const I=S.getTotal(),v=le(Math.floor(a),0,I),D=S.findIndexAtOrAfter(v,{materializeOption:{materialize:!1}}).index;G(D)},[S,G]),Re=n.useCallback(a=>{const I=ze(M.current,x.top),v=typeof a=="function"?a(I):a;Y(v);const D=j.current?.getScrollPosition(),q=typeof D=="number"?D:M.current;return h(q),q},[x.top,Y,h]),ge=n.useCallback((a,I)=>{Me.debug("[VirtualScroll] Scroll position changed:",a),h(a)},[h]),we=n.useMemo(()=>ze(te,x.top),[x.top,te]),xe=n.useMemo(()=>{const a=nn(we,r,o,y,t,S);return Me.debug("[VirtualScroll] Calculated rendering range:",{...a,scrollPosition:we,renderingContentSize:S.getTotal(),overscanCount:o,viewportSize:r}),a},[we,r,o,y,t,S]),{renderingStartIndex:Ae,renderingEndIndex:Ye,visibleStartIndex:Ce,visibleEndIndex:_e}=xe,oe=n.useCallback((a,I)=>{if(!w||y===0)return;const v=ie(a,y);if(!(I?.ensureVisible??!0)){const je=fe.current.get(v);je&&(Q.current=null,se.current=v,ee(je));return}const q=S.prefixSum(v,{materializeOption:{materialize:!1}}),$=q.currentValue,Pe=Math.max(q.cumulative-$,0),Ne=Pe+$,ke=ze(M.current,x.top),Le=ke+r;if(Pe<ke||Ne>Le){Q.current=v,G(v);return}const Oe=fe.current.get(v);if(Oe){Q.current=null,se.current=v,ee(Oe);return}Q.current=v},[w,y,S,x.top,G,ee,r]),Se=n.useCallback((a,I)=>{if(!w||a.defaultPrevented||a.altKey||a.metaKey||a.ctrlKey)return;const v=a.target;if(v){const D=v.tagName;if(D==="INPUT"||D==="TEXTAREA"||D==="SELECT"||v.isContentEditable)return}if(a.key==="ArrowDown"){I<y-1&&(a.preventDefault(),oe(I+1));return}if(a.key==="ArrowUp"){I>0&&(a.preventDefault(),oe(I-1));return}if(a.key==="PageDown"){if(I<y-1){a.preventDefault();const D=Math.max(_e-Ce+1,1),q=Math.max(D,1),$=ie(Math.min(I+q,y-1),y);oe($)}return}if(a.key==="PageUp"&&I>0){a.preventDefault();const D=Math.max(_e-Ce+1,1),q=Math.max(D,1),$=ie(I-q,y);oe($)}},[w,y,oe,_e,Ce]),He=n.useCallback(a=>{if(!w)return;const I=ie(a,y);Q.current=null,se.current=I},[w,y]);n.useEffect(()=>{const a=j.current?.getScrollPosition()??0,I=M.current,v=ze(I,x.top);Me.debug("[VirtualScroll] Range change effect triggered",{renderingStartIndex:Ae,renderingEndIndex:Ye,visibleStartIndex:Ce,visibleEndIndex:_e,scrollPositionState:te,paneScrollPosition:I,logicalScrollPosition:v,contentSize:ne,scrollPaneScrollPosition:a}),de({renderingStartIndex:Ae,renderingEndIndex:Ye,visibleStartIndex:Ce,visibleEndIndex:_e,scrollPosition:v,totalHeight:ne})},[ne,Ye,Ae,x.top,de,te,_e,Ce]);const Ke=n.useCallback(a=>{const I=(E??0)>0,v=Math.abs(a-te),D=I&&v>.5?te:a,q=ze(D,x.top);if(Me.debug("[VirtualScroll] Rendering visible items",{currentScrollPosition:a,effectiveScrollPosition:q,renderingStartIndex:Ae,renderingEndIndex:Ye,fenwickSize:y,viewportSize:r,callbackThrottleMs:E,diff:v,rawEffectiveScrollPosition:D}),y===0)return L.jsx("div",{className:"absolute w-full",style:{top:0},children:L.jsx("div",{className:"text-center text-gray-500",children:"No items"})});const $=ie(Ae,y),Pe=ie(Ye,y),{cumulative:Ne,currentValue:ke}=S.prefixSum($,{materializeOption:{materialize:!1}}),Le=Ne-ke,Xe=[],Oe=[];for(let X=$;X<=Pe;X++){const qe=t(X);S.get(X)!==qe&&Xe.push({index:X,value:qe});const{cumulative:Ge,currentValue:i}=S.prefixSum(X,{materializeOption:{materialize:!1}}),b=Ge-i,A=Z=>{if(!Z){fe.current.delete(X);return}w&&(fe.current.set(X,Z),Q.current===X&&(Q.current=null,se.current=X,ee(Z)))};Oe.push(L.jsx("div",{ref:A,"data-index":X,"data-virtualscroll-item":"true",style:{position:"absolute",top:b-Le+x.top,width:"100%"},tabIndex:w?-1:void 0,onKeyDownCapture:w?Z=>Se(Z,X):void 0,onFocusCapture:w?()=>He(X):void 0,children:c(e(X),X)},X))}Xe.length>0&&Promise.resolve().then(()=>{if(!_.current)return;const X=S.updates(Xe);if(!_.current||typeof X!="number")return;U(X),Me.debug("[VirtualScroll] Updated heights for items",Xe,"New total height:",X);const qe=j.current?.getScrollPosition()??M.current;qe===M.current||!_.current||h(qe)});const je=Le-q;if(x.bottom>0){const X=S.getTotal()+x.top-Le;Oe.push(L.jsx("div",{style:{position:"absolute",top:X,height:x.bottom,width:"100%"}},"virtualscroll-bottom-inset"))}return Me.debug("[VirtualScroll] Rendering items",{nodeCount:Oe.length,containerTop:je,logicalScrollPosition:we,resolvedInsets:x,effectiveScrollPosition:q}),L.jsx("div",{className:"absolute w-full",style:{top:je},children:Oe})},[E,c,w,S,y,e,t,He,Se,we,Ye,Ae,x,te,ee,h,r]);n.useImperativeHandle(H,()=>({getScrollPosition:()=>j.current?.getScrollPosition()??-1,getContentSize:()=>j.current?.getContentSize()??-1,getViewportSize:()=>j.current?.getViewportSize()??-1,scrollTo:Re,scrollToIndex:G,getFenwickTreeTotalHeight:()=>S.getTotal(),getFenwickSize:()=>S.getSize(),focusItemAtIndex:oe}),[Re,G,S,oe]);const tt=ne+x.top+x.bottom;return L.jsx(bt,{ref:j,contentSize:tt,viewportSize:r,className:l,onScroll:ge,background:u,tapScrollCircleOptions:C,inertiaOptions:ce,itemCount:s,scrollBarWidth:T,enableThumbDrag:F,enableTrackClick:V,enableArrowButtons:J,enablePointerDrag:O,renderThumbOverlay:k,wheelSpeedMultiplier:z,contentInsets:x,children:Ke})},on=n.forwardRef(sn);exports.FenwickMapTree=It;exports.ScrollBar=xt;exports.ScrollPane=bt;exports.VirtualScroll=on;exports.minmax=le;exports.tapScrollCircleSampleVisual=Kt;exports.useFenwickMapTree=Tt;exports.useHeightCache=Qt;exports.useLruCache=Ct;