{"version":3,"file":"index.cjs","sources":["../../src/src/core/utils.ts","../../src/src/core/cache.ts","../../src/src/core/environment.ts","../../src/src/core/store.ts","../../src/src/core/scroller.ts","../../src/src/core/resizer.ts","../../src/src/solid/ListItem.tsx","../../src/src/solid/utils.ts","../../src/src/solid/Virtualizer.tsx","../../src/src/solid/VList.tsx","../../src/src/solid/WindowVirtualizer.tsx"],"sourcesContent":["/** @internal */\nexport const NULL = null;\n\n/** @internal */\nexport const { min, max, abs, floor } = Math;\n\n/**\n * @internal\n */\nexport const clamp = (\n  value: number,\n  minValue: number,\n  maxValue: number\n): number => min(maxValue, max(minValue, value));\n\n/**\n * @internal\n */\nexport const sort = <T extends number>(arr: readonly T[]): T[] => {\n  return [...arr].sort((a, b) => a - b);\n};\n\n/**\n * @internal\n */\nexport const microtask: (fn: () => void) => void =\n  typeof queueMicrotask === \"function\"\n    ? queueMicrotask\n    : (fn) => {\n        Promise.resolve().then(fn);\n      };\n\n/**\n * @internal\n */\nexport const createPromise = <T = void>(): [Promise<T>, (arg: T) => void] => {\n  let resolve: ((arg: T) => void) | undefined;\n  const promise = new Promise<T>((res) => {\n    resolve = res;\n  });\n  return [promise, resolve!];\n};\n\n/**\n * @internal\n */\nexport const once = <T>(fn: () => T): (() => T) => {\n  let cache: T;\n\n  return () => {\n    if (fn) {\n      cache = fn();\n      fn = undefined!;\n    }\n    return cache;\n  };\n};\n","import { type InternalCacheSnapshot, type ItemsRange } from \"./types.js\";\nimport { clamp, floor, max, min, sort } from \"./utils.js\";\n\ntype Writeable<T> = {\n  -readonly [key in keyof T]: Writeable<T[key]>;\n};\n\n/** @internal */\nexport const UNCACHED = -1;\n\n/**\n * @internal\n */\nexport type Cache = {\n  readonly _length: number;\n  // sizes\n  readonly _sizes: number[];\n  readonly _defaultItemSize: number;\n  // offsets\n  readonly _computedOffsetIndex: number;\n  readonly _offsets: number[];\n};\n\nconst fill = (array: number[], length: number, prepend?: boolean): number[] => {\n  const key = prepend ? \"unshift\" : \"push\";\n  for (let i = 0; i < length; i++) {\n    array[key](UNCACHED);\n  }\n  return array;\n};\n\n/**\n * @internal\n */\nexport const getItemSize = (cache: Cache, index: number): number => {\n  const size = cache._sizes[index]!;\n  return size === UNCACHED ? cache._defaultItemSize : size;\n};\n\n/**\n * @internal\n */\nexport const setItemSize = (\n  cache: Writeable<Cache>,\n  index: number,\n  size: number\n): boolean => {\n  const isInitialMeasurement = cache._sizes[index] === UNCACHED;\n  cache._sizes[index] = size;\n  // mark as dirty\n  cache._computedOffsetIndex = min(index, cache._computedOffsetIndex);\n  return isInitialMeasurement;\n};\n\n/**\n * @internal\n */\nexport const getItemOffset = (\n  cache: Writeable<Cache>,\n  index: number\n): number => {\n  if (!cache._length) return 0;\n  if (cache._computedOffsetIndex >= index) {\n    return cache._offsets[index]!;\n  }\n\n  if (cache._computedOffsetIndex < 0) {\n    // first offset must be 0 to avoid returning NaN, which can cause infinite rerender.\n    // https://github.com/inokawa/virtua/pull/160\n    cache._offsets[0] = 0;\n    cache._computedOffsetIndex = 0;\n  }\n  let i = cache._computedOffsetIndex;\n  let top = cache._offsets[i]!;\n  while (i < index) {\n    top += getItemSize(cache, i);\n    cache._offsets[++i] = top;\n  }\n  // mark as measured\n  cache._computedOffsetIndex = index;\n  return top;\n};\n\n/**\n * Finds the index of an item in the cache whose computed offset is closest to the specified offset.\n *\n * @internal\n */\nexport const findIndex = (\n  cache: Cache,\n  offset: number,\n  low: number = 0,\n  high: number = cache._length - 1\n): number => {\n  // Find with binary search\n  while (low <= high) {\n    const mid = floor((low + high) / 2);\n    if (getItemOffset(cache, mid) <= offset) {\n      if (getItemOffset(cache, mid + 1) > offset) {\n        return mid;\n      }\n      low = mid + 1;\n    } else {\n      high = mid - 1;\n    }\n  }\n  return clamp(low, 0, cache._length - 1);\n};\n\n/**\n * @internal\n */\nexport const computeRange = (\n  cache: Cache,\n  startOffset: number,\n  endOffset: number,\n  prevStartIndex: number\n): ItemsRange => {\n  // Clamp because prevStartIndex may exceed the limit when children decreased a lot after scrolling\n  prevStartIndex = min(prevStartIndex, cache._length - 1);\n\n  if (getItemOffset(cache, prevStartIndex) <= startOffset) {\n    // search forward\n    // start <= end, prevStartIndex <= start\n    const end = findIndex(cache, endOffset, prevStartIndex);\n    return [findIndex(cache, startOffset, prevStartIndex, end), end];\n  } else {\n    // search backward\n    // start <= end, start <= prevStartIndex\n    const start = findIndex(cache, startOffset, undefined, prevStartIndex);\n    return [start, findIndex(cache, endOffset, start)];\n  }\n};\n\n/**\n * @internal\n */\nexport const estimateDefaultItemSize = (\n  cache: Writeable<Cache>,\n  startIndex: number\n): number => {\n  let measuredCountBeforeStart = 0;\n  // This function will be called after measurement so measured size array must be longer than 0\n  const measuredSizes: number[] = [];\n  cache._sizes.forEach((s, i) => {\n    if (s !== UNCACHED) {\n      measuredSizes.push(s);\n      if (i < startIndex) {\n        measuredCountBeforeStart++;\n      }\n    }\n  });\n\n  // Discard cache for now\n  cache._computedOffsetIndex = -1;\n\n  // Calculate median\n  const sorted = sort(measuredSizes);\n  const len = sorted.length;\n  const mid = (len / 2) | 0;\n  const median =\n    len % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n\n  const prevDefaultItemSize = cache._defaultItemSize;\n\n  // Calculate diff of unmeasured items before start\n  return (\n    ((cache._defaultItemSize = median) - prevDefaultItemSize) *\n    max(startIndex - measuredCountBeforeStart, 0)\n  );\n};\n\n/**\n * @internal\n */\nexport const initCache = (\n  length: number,\n  itemSize: number,\n  snapshot?: InternalCacheSnapshot\n): Cache => {\n  return {\n    _defaultItemSize: snapshot ? snapshot[1] : itemSize,\n    _sizes:\n      snapshot && snapshot[0]\n        ? // https://github.com/inokawa/virtua/issues/441\n          fill(\n            snapshot[0].slice(0, min(length, snapshot[0].length)),\n            max(0, length - snapshot[0].length)\n          )\n        : fill([], length),\n    _length: length,\n    _computedOffsetIndex: -1,\n    _offsets: fill([], length + 1),\n  };\n};\n\n/**\n * @internal\n */\nexport const takeCacheSnapshot = (cache: Cache): InternalCacheSnapshot => {\n  return [cache._sizes.slice(), cache._defaultItemSize];\n};\n\n/**\n * @internal\n */\nexport const updateCacheLength = (\n  cache: Writeable<Cache>,\n  length: number,\n  isShift?: boolean\n): number => {\n  const diff = length - cache._length;\n\n  cache._computedOffsetIndex = isShift\n    ? // Discard cache for now\n      -1\n    : min(length - 1, cache._computedOffsetIndex);\n  cache._length = length;\n\n  if (diff > 0) {\n    // Added\n    fill(cache._offsets, diff);\n    fill(cache._sizes, diff, isShift);\n    return cache._defaultItemSize * diff;\n  } else {\n    // Removed\n    cache._offsets.splice(diff);\n    return (\n      isShift ? cache._sizes.splice(0, -diff) : cache._sizes.splice(diff)\n    ).reduce(\n      (acc, removed) =>\n        acc - (removed === UNCACHED ? cache._defaultItemSize : removed),\n      0\n    );\n  }\n};\n","import { once } from \"./utils.js\";\n\n/**\n * @internal\n */\nexport const isBrowser = typeof window !== \"undefined\";\n\nconst getDocumentElement = () => document.documentElement;\n\n/**\n * @internal\n */\nexport const getCurrentDocument = (node: HTMLElement): Document =>\n  node.ownerDocument;\n\n/**\n * @internal\n */\nexport const getCurrentWindow = (doc: Document) => doc.defaultView!;\n\n/**\n * @internal\n */\nexport const isRTLDocument = /*#__PURE__*/ once((): boolean => {\n  // TODO support SSR in rtl\n  return isBrowser\n    ? getComputedStyle(getDocumentElement()).direction === \"rtl\"\n    : false;\n});\n\n/**\n * Currently, all browsers on iOS/iPadOS are WebKit, including WebView.\n * @internal\n */\nexport const isIOSWebKit = /*#__PURE__*/ once((): boolean => {\n  if (/iP(hone|od|ad)/.test(navigator.userAgent)) {\n    return true;\n  }\n  // Modern iPad detection (iPadOS 13+)\n  // iPadOS 13+ reports the same userAgent/platform information as macOS, to enable desktop sites.\n  // So we treat devices that have macOS like information but with touch support as iPadOS.\n  // https://stackoverflow.com/questions/57776001/how-to-detect-ipad-pro-as-ipad-using-javascript\n  return navigator.platform === \"MacIntel\" && navigator.maxTouchPoints > 0;\n});\n\n/**\n * @internal\n */\nexport const isSmoothScrollSupported = /*#__PURE__*/ once((): boolean => {\n  return \"scrollBehavior\" in getDocumentElement().style;\n});\n","import {\n  initCache,\n  getItemSize as _getItemSize,\n  getItemOffset as _getItemOffset,\n  UNCACHED,\n  setItemSize,\n  estimateDefaultItemSize,\n  updateCacheLength,\n  computeRange,\n  takeCacheSnapshot,\n  findIndex,\n} from \"./cache.js\";\nimport { isIOSWebKit } from \"./environment.js\";\nimport type {\n  CacheSnapshot,\n  InternalCacheSnapshot,\n  ItemResize,\n  ItemsRange,\n} from \"./types.js\";\nimport { abs, max, min, NULL } from \"./utils.js\";\n\nconst MAX_INT_32 = 0x7fffffff;\n\nconst SCROLL_IDLE = 0;\nconst SCROLL_DOWN = 1;\nconst SCROLL_UP = 2;\ntype ScrollDirection =\n  | typeof SCROLL_IDLE\n  | typeof SCROLL_DOWN\n  | typeof SCROLL_UP;\n\nconst SCROLL_BY_NATIVE = 0;\nconst SCROLL_BY_MANUAL_SCROLL = 1;\nconst SCROLL_BY_SHIFT = 2;\ntype ScrollMode =\n  | typeof SCROLL_BY_NATIVE\n  | typeof SCROLL_BY_MANUAL_SCROLL\n  | typeof SCROLL_BY_SHIFT;\n\n/** @internal */\nexport const ACTION_SCROLL = 1;\n/** @internal */\nexport const ACTION_SCROLL_END = 2;\n/** @internal */\nexport const ACTION_ITEM_RESIZE = 3;\n/** @internal */\nexport const ACTION_VIEWPORT_RESIZE = 4;\n/** @internal */\nexport const ACTION_ITEMS_LENGTH_CHANGE = 5;\n/** @internal */\nexport const ACTION_START_OFFSET_CHANGE = 6;\n/** @internal */\nexport const ACTION_MANUAL_SCROLL = 7;\n/** @internal */\nexport const ACTION_BEFORE_MANUAL_SMOOTH_SCROLL = 8;\n\ntype Actions =\n  | [type: typeof ACTION_SCROLL, offset: number]\n  | [type: typeof ACTION_SCROLL_END, dummy?: void]\n  | [type: typeof ACTION_ITEM_RESIZE, entries: ItemResize[]]\n  | [type: typeof ACTION_VIEWPORT_RESIZE, size: number]\n  | [\n      type: typeof ACTION_ITEMS_LENGTH_CHANGE,\n      arg: [length: number, isShift?: boolean | undefined]\n    ]\n  | [type: typeof ACTION_START_OFFSET_CHANGE, offset: number]\n  | [type: typeof ACTION_MANUAL_SCROLL, dummy?: void]\n  | [type: typeof ACTION_BEFORE_MANUAL_SMOOTH_SCROLL, offset: number];\n\n/** @internal */\nexport const UPDATE_VIRTUAL_STATE = 0b0001;\n/** @internal */\nexport const UPDATE_SIZE_EVENT = 0b0010;\n/** @internal */\nexport const UPDATE_SCROLL_EVENT = 0b0100;\n/** @internal */\nexport const UPDATE_SCROLL_END_EVENT = 0b1000;\n\n/**\n * @internal\n */\nexport const getScrollSize = (store: VirtualStore): number => {\n  return max(store.$getTotalSize(), store.$getViewportSize());\n};\n\ntype Subscriber = (sync?: boolean) => void;\n\n/** @internal */\nexport type StateVersion =\n  number & {} /* hack for typescript to pretend as not falsy */;\n\n/**\n * @internal\n */\nexport type VirtualStore = {\n  $dispose(): void;\n  $getStateVersion(): StateVersion;\n  $getCacheSnapshot(): CacheSnapshot;\n  $getRange(bufferSize?: number): ItemsRange;\n  $findStartIndex(): number;\n  $findEndIndex(): number;\n  $isUnmeasuredItem(index: number): boolean;\n  $getItemOffset(index: number): number;\n  $getItemSize(index: number): number;\n  $getItemsLength(): number;\n  $getScrollOffset(): number;\n  $isScrolling(): boolean;\n  $getViewportSize(): number;\n  $getStartSpacerSize(): number;\n  $getTotalSize(): number;\n  _flushJump(): [number, boolean];\n  $subscribe(target: number, cb: Subscriber): () => void;\n  $update(...action: Actions): void;\n};\n\n/**\n * @internal\n */\nexport const createVirtualStore = (\n  elementsCount: number,\n  itemSize: number = 40,\n  ssrCount: number = 0,\n  cacheSnapshot?: CacheSnapshot | undefined,\n  shouldAutoEstimateItemSize: boolean = false\n): VirtualStore => {\n  let isSSR = !!ssrCount;\n  let stateVersion: StateVersion = 1;\n  let viewportSize = 0;\n  let startSpacerSize = 0;\n  let scrollOffset = 0;\n  let jump = 0;\n  let pendingJump = 0;\n  let _flushedJump = 0;\n  let _scrollDirection: ScrollDirection = SCROLL_IDLE;\n  let _scrollMode: ScrollMode = SCROLL_BY_NATIVE;\n  let _frozenRange: ItemsRange | null = NULL;\n  let _prevRange: ItemsRange = [0, isSSR ? max(ssrCount - 1, 0) : -1];\n  let _totalMeasuredSize = 0;\n\n  const cache = initCache(\n    elementsCount,\n    itemSize,\n    cacheSnapshot as unknown as InternalCacheSnapshot | undefined\n  );\n  const subscribers = new Set<[number, Subscriber]>();\n  const getRelativeScrollOffset = () => scrollOffset - startSpacerSize;\n  const getVisibleOffset = () => getRelativeScrollOffset() + pendingJump + jump;\n  const getRange = (startOffset: number, endOffset: number) => {\n    return computeRange(cache, startOffset, endOffset, _prevRange[0]);\n  };\n  const getTotalSize = (): number => _getItemOffset(cache, cache._length);\n  const getItemOffset = (index: number): number => {\n    return _getItemOffset(cache, index) - pendingJump;\n  };\n  const getItemSize = (index: number): number => {\n    return _getItemSize(cache, index);\n  };\n  const isSizeEqual = (index: number, value: number = UNCACHED): boolean => {\n    return cache._sizes[index] === value;\n  };\n\n  const applyJump = (j: number) => {\n    if (j) {\n      if (\n        // In iOS WebKit browsers, updating scroll position will stop scrolling so it have to be deferred during scrolling.\n        (isIOSWebKit() && _scrollDirection !== SCROLL_IDLE) ||\n        // Before imperative smooth scrolling, we measure all items which may be visible during scrolling.\n        // However, especially in Firefox, there are rare cases where items resize while scrolling, which can stop smooth scrolling.\n        (_frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL)\n      ) {\n        pendingJump += j;\n      } else {\n        jump += j;\n      }\n    }\n  };\n\n  return {\n    $dispose: () => {\n      subscribers.clear();\n    },\n    $getStateVersion: () => stateVersion,\n    $getCacheSnapshot: () => {\n      return takeCacheSnapshot(cache) as unknown as CacheSnapshot;\n    },\n    $getRange: (bufferSize = 200) => {\n      if (!viewportSize || isSSR) {\n        // Empty viewportSize means the first render.\n        // We return range for SSR here, or return [0, -1] to render nothing, until the scroll offset and viewport size are determined.\n        // https://github.com/inokawa/virtua/issues/415\n        return _prevRange;\n      }\n      let startIndex: number;\n      let endIndex: number;\n      if (_flushedJump) {\n        // Return previous range for consistent render until next scroll event comes in.\n        // And it must be clamped. https://github.com/inokawa/virtua/issues/597\n        [startIndex, endIndex] = _prevRange;\n      } else {\n        let startOffset = max(0, getVisibleOffset());\n        let endOffset = startOffset + viewportSize;\n\n        // For faster initial render pass, returns without buffer if measurement seems to be in progress.\n        if (!shouldAutoEstimateItemSize) {\n          bufferSize = max(0, bufferSize);\n\n          if (_scrollDirection !== SCROLL_DOWN) {\n            startOffset -= bufferSize;\n          }\n          if (_scrollDirection !== SCROLL_UP) {\n            endOffset += bufferSize;\n          }\n        }\n\n        [startIndex, endIndex] = _prevRange = getRange(\n          max(0, startOffset),\n          max(0, endOffset)\n        );\n        if (_frozenRange) {\n          startIndex = min(startIndex, _frozenRange[0]);\n          endIndex = max(endIndex, _frozenRange[1]);\n        }\n      }\n\n      return [max(startIndex, 0), min(endIndex, cache._length - 1)];\n    },\n    $findStartIndex: () => findIndex(cache, getVisibleOffset()),\n    $findEndIndex: () => findIndex(cache, getVisibleOffset() + viewportSize),\n    $isUnmeasuredItem: isSizeEqual,\n    $getItemOffset: getItemOffset,\n    $getItemSize: getItemSize,\n    $getItemsLength: () => cache._length,\n    $getScrollOffset: () => scrollOffset,\n    $isScrolling: () => _scrollDirection !== SCROLL_IDLE,\n    $getViewportSize: () => viewportSize,\n    $getStartSpacerSize: () => startSpacerSize,\n    $getTotalSize: getTotalSize,\n    _flushJump: () => {\n      _flushedJump = jump;\n      jump = 0;\n      return [_flushedJump, _scrollMode === SCROLL_BY_SHIFT];\n    },\n    $subscribe: (target, cb) => {\n      const sub: [number, Subscriber] = [target, cb];\n      subscribers.add(sub);\n      return () => {\n        subscribers.delete(sub);\n      };\n    },\n    $update: (type, payload): void => {\n      let shouldFlushPendingJump: boolean | undefined;\n      let shouldSync: boolean | undefined;\n      let mutated = 0;\n\n      switch (type) {\n        case ACTION_SCROLL: {\n          if (payload === scrollOffset && _scrollMode === SCROLL_BY_NATIVE) {\n            // Ignore scroll events from different direction\n            break;\n          }\n\n          const flushedJump = _flushedJump;\n          _flushedJump = 0;\n\n          const delta = payload - scrollOffset;\n          const distance = abs(delta);\n\n          // Scroll event after jump compensation is not reliable because it may result in the opposite direction.\n          // The delta of artificial scroll may not be equal with the jump because it may be batched with other scrolls.\n          // And at least in latest Chrome/Firefox/Safari in 2023, setting value to scrollTop/scrollLeft can lose subpixel because its integer (sometimes float probably depending on dpr).\n          const isJustJumped = flushedJump && distance < abs(flushedJump) + 1;\n\n          // Scroll events are dispatched enough so it's ok to skip some of them.\n          if (\n            !isJustJumped &&\n            // Ignore until manual scrolling\n            _scrollMode === SCROLL_BY_NATIVE\n          ) {\n            _scrollDirection = delta < 0 ? SCROLL_UP : SCROLL_DOWN;\n          }\n\n          // TODO This will cause glitch in reverse infinite scrolling. Disable this until better solution is found.\n          // if (\n          //   pendingJump &&\n          //   ((_scrollDirection === SCROLL_UP &&\n          //     payload - max(pendingJump, 0) <= 0) ||\n          //     (_scrollDirection === SCROLL_DOWN &&\n          //       payload - min(pendingJump, 0) >= getScrollOffsetMax()))\n          // ) {\n          //   // Flush if almost reached to start or end\n          //   shouldFlushPendingJump = true;\n          // }\n\n          if (isSSR) {\n            isSSR = false;\n          }\n\n          scrollOffset = payload;\n          mutated = UPDATE_SCROLL_EVENT;\n\n          // Skip if offset is not changed\n          // Scroll offset may exceed min or max especially in Safari's elastic scrolling.\n          const relativeOffset = getRelativeScrollOffset();\n          if (\n            relativeOffset >= -viewportSize &&\n            relativeOffset <= getTotalSize()\n          ) {\n            mutated += UPDATE_VIRTUAL_STATE;\n\n            // Update synchronously if scrolled a lot\n            shouldSync = distance > viewportSize;\n          }\n          break;\n        }\n        case ACTION_SCROLL_END: {\n          mutated = UPDATE_SCROLL_END_EVENT;\n          if (_scrollDirection !== SCROLL_IDLE) {\n            shouldFlushPendingJump = true;\n            mutated += UPDATE_VIRTUAL_STATE;\n          }\n          _scrollDirection = SCROLL_IDLE;\n          _scrollMode = SCROLL_BY_NATIVE;\n          _frozenRange = NULL;\n          break;\n        }\n        case ACTION_ITEM_RESIZE: {\n          const updated = payload.filter(\n            ([index, size]) => !isSizeEqual(index, size)\n          );\n\n          // Skip if all items are cached and not updated\n          if (!updated.length) {\n            break;\n          }\n\n          // Calculate jump by resize to minimize junks in appearance\n          applyJump(\n            updated.reduce((acc, [index, size]) => {\n              if (\n                // Keep distance from end during shifting\n                _scrollMode === SCROLL_BY_SHIFT ||\n                (_frozenRange && _scrollMode === SCROLL_BY_MANUAL_SCROLL\n                  ? // https://github.com/inokawa/virtua/issues/380\n                    // https://github.com/inokawa/virtua/issues/758\n                    index < _frozenRange[0]\n                  : // Otherwise we should maintain visible position\n                    getItemOffset(\n                      index +\n                        // https://github.com/inokawa/virtua/issues/385\n                        (_scrollDirection === SCROLL_IDLE &&\n                        _scrollMode === SCROLL_BY_NATIVE\n                          ? 1\n                          : 0)\n                    ) < getRelativeScrollOffset())\n              ) {\n                acc += size - getItemSize(index);\n              }\n              return acc;\n            }, 0)\n          );\n\n          // Update item sizes\n          for (const [index, size] of updated) {\n            const prevSize = getItemSize(index);\n            const isInitialMeasurement = setItemSize(cache, index, size);\n\n            if (shouldAutoEstimateItemSize) {\n              _totalMeasuredSize += isInitialMeasurement\n                ? size\n                : size - prevSize;\n            }\n          }\n\n          // Estimate initial item size from measured sizes\n          if (\n            shouldAutoEstimateItemSize &&\n            viewportSize &&\n            // If the total size is lower than the viewport, the item may be a empty state\n            _totalMeasuredSize > viewportSize\n          ) {\n            applyJump(\n              estimateDefaultItemSize(\n                cache,\n                findIndex(cache, getVisibleOffset())\n              )\n            );\n            shouldAutoEstimateItemSize = false;\n          }\n\n          mutated = UPDATE_VIRTUAL_STATE + UPDATE_SIZE_EVENT;\n\n          // Synchronous update is necessary in current design to minimize visible glitch in concurrent rendering.\n          // However this seems to be the main cause of the errors from ResizeObserver.\n          // https://github.com/inokawa/virtua/issues/470\n          //\n          // And in React, synchronous update with flushSync after asynchronous update will overtake the asynchronous one.\n          // If items resize happens just after scroll, race condition can occur depending on implementation.\n          shouldSync = true;\n          break;\n        }\n        case ACTION_VIEWPORT_RESIZE: {\n          if (viewportSize !== payload) {\n            if (!viewportSize) {\n              shouldSync = true;\n            }\n            viewportSize = payload;\n            mutated = UPDATE_VIRTUAL_STATE + UPDATE_SIZE_EVENT;\n          }\n          break;\n        }\n        case ACTION_ITEMS_LENGTH_CHANGE: {\n          if (payload[1]) {\n            applyJump(updateCacheLength(cache, payload[0], true));\n            _scrollMode = SCROLL_BY_SHIFT;\n            mutated = UPDATE_VIRTUAL_STATE;\n          } else {\n            updateCacheLength(cache, payload[0]);\n            // https://github.com/inokawa/virtua/issues/552\n            // https://github.com/inokawa/virtua/issues/557\n            mutated = UPDATE_VIRTUAL_STATE;\n          }\n          break;\n        }\n        case ACTION_START_OFFSET_CHANGE: {\n          startSpacerSize = payload;\n          break;\n        }\n        case ACTION_MANUAL_SCROLL: {\n          _scrollMode = SCROLL_BY_MANUAL_SCROLL;\n          break;\n        }\n        case ACTION_BEFORE_MANUAL_SMOOTH_SCROLL: {\n          _frozenRange = getRange(payload, payload + viewportSize);\n          mutated = UPDATE_VIRTUAL_STATE;\n          break;\n        }\n      }\n\n      if (mutated) {\n        stateVersion = (stateVersion & MAX_INT_32) + 1;\n\n        if (shouldFlushPendingJump && pendingJump) {\n          jump += pendingJump;\n          pendingJump = 0;\n        }\n\n        subscribers.forEach(([target, cb]) => {\n          // Early return to skip React's computation\n          if (!(mutated & target)) {\n            return;\n          }\n          // https://github.com/facebook/react/issues/25191\n          // https://github.com/facebook/react/blob/a5fc797db14c6e05d4d5c4dbb22a0dd70d41f5d5/packages/react-reconciler/src/ReactFiberWorkLoop.js#L1443-L1447\n          cb(shouldSync);\n        });\n      }\n    },\n  };\n};\n","import {\n  getCurrentDocument,\n  getCurrentWindow,\n  isIOSWebKit,\n  isRTLDocument,\n  isSmoothScrollSupported,\n} from \"./environment.js\";\nimport {\n  ACTION_SCROLL,\n  type VirtualStore,\n  ACTION_SCROLL_END,\n  UPDATE_SIZE_EVENT,\n  ACTION_MANUAL_SCROLL,\n  ACTION_BEFORE_MANUAL_SMOOTH_SCROLL,\n  ACTION_START_OFFSET_CHANGE,\n} from \"./store.js\";\nimport { type ScrollToIndexOpts } from \"./types.js\";\nimport { clamp, createPromise, microtask, NULL } from \"./utils.js\";\n\nconst timeout = setTimeout;\n\nconst debounce = <T extends () => void>(fn: T, ms: number) => {\n  let id: ReturnType<typeof setTimeout> | undefined | null;\n\n  const cancel = () => {\n    if (id != NULL) {\n      clearTimeout(id);\n    }\n  };\n  const debouncedFn = () => {\n    cancel();\n    id = timeout(() => {\n      id = NULL;\n      fn();\n    }, ms);\n  };\n  debouncedFn._cancel = cancel;\n  return debouncedFn;\n};\n\n/**\n * scrollLeft is negative value in rtl direction.\n *\n * left  right\n * 0     100    spec compliant (ltr)\n * -100  0      spec compliant (rtl)\n * https://github.com/othree/jquery.rtl-scroll-type\n */\nconst normalizeOffset = (offset: number, isHorizontal: boolean): number => {\n  if (isHorizontal && isRTLDocument()) {\n    return -offset;\n  } else {\n    return offset;\n  }\n};\n\nconst createScrollObserver = (\n  store: VirtualStore,\n  viewport: HTMLElement | Window,\n  isHorizontal: boolean,\n  getScrollOffset: () => number,\n  updateScrollOffset: (\n    value: number,\n    shift: boolean,\n    isMomentumScrolling: boolean\n  ) => void,\n  getStartOffset?: () => number\n) => {\n  const now = Date.now;\n\n  let lastScrollTime = 0;\n  let wheeling = false;\n  let touching = false;\n  let justTouchEnded = false;\n  let stillMomentumScrolling = false;\n\n  const onScrollEnd = debounce(() => {\n    if (wheeling || touching) {\n      wheeling = false;\n\n      // Wait while wheeling or touching\n      onScrollEnd();\n      return;\n    }\n\n    justTouchEnded = false;\n\n    store.$update(ACTION_SCROLL_END);\n  }, 150);\n\n  const onScroll = () => {\n    lastScrollTime = now();\n\n    if (justTouchEnded) {\n      stillMomentumScrolling = true;\n    }\n\n    if (getStartOffset) {\n      store.$update(ACTION_START_OFFSET_CHANGE, getStartOffset());\n    }\n    store.$update(ACTION_SCROLL, getScrollOffset());\n\n    onScrollEnd();\n  };\n\n  // Infer scroll state also from wheel events\n  // Sometimes scroll events do not fire when frame dropped even if the visual have been already scrolled\n  const onWheel = ((e: WheelEvent) => {\n    if (\n      wheeling ||\n      // Scroll start should be detected with scroll event\n      !store.$isScrolling() ||\n      // Probably a pinch-to-zoom gesture\n      e.ctrlKey\n    ) {\n      return;\n    }\n\n    const timeDelta = now() - lastScrollTime;\n    if (\n      // Check if wheel event occurs some time after scrolling\n      150 > timeDelta &&\n      50 < timeDelta &&\n      // Get delta before checking deltaMode for firefox behavior\n      // https://github.com/w3c/uievents/issues/181#issuecomment-392648065\n      // https://bugzilla.mozilla.org/show_bug.cgi?id=1392460#c34\n      (isHorizontal ? e.deltaX : e.deltaY)\n    ) {\n      wheeling = true;\n    }\n  }) as (e: Event) => void; // FIXME type error. why only here?\n\n  const onTouchStart = () => {\n    touching = true;\n    justTouchEnded = stillMomentumScrolling = false;\n  };\n  const onTouchEnd = () => {\n    touching = false;\n    if (isIOSWebKit()) {\n      justTouchEnded = true;\n    }\n  };\n\n  viewport.addEventListener(\"scroll\", onScroll);\n  viewport.addEventListener(\"wheel\", onWheel, { passive: true });\n  viewport.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n  viewport.addEventListener(\"touchend\", onTouchEnd, { passive: true });\n\n  return {\n    _dispose: () => {\n      viewport.removeEventListener(\"scroll\", onScroll);\n      viewport.removeEventListener(\"wheel\", onWheel);\n      viewport.removeEventListener(\"touchstart\", onTouchStart);\n      viewport.removeEventListener(\"touchend\", onTouchEnd);\n      onScrollEnd._cancel();\n    },\n    _fixScrollJump: () => {\n      const [jump, shift] = store._flushJump();\n      if (!jump) return;\n      updateScrollOffset(\n        normalizeOffset(jump, isHorizontal),\n        shift,\n        stillMomentumScrolling\n      );\n      stillMomentumScrolling = false;\n\n      if (shift && store.$getViewportSize() > store.$getTotalSize()) {\n        // In this case applying jump may not cause scroll.\n        // Current logic expects scroll event occurs after applying jump so we dispatch it manually.\n        store.$update(ACTION_SCROLL, getScrollOffset());\n      }\n    },\n  };\n};\n\ntype ScrollObserver = ReturnType<typeof createScrollObserver>;\n\ntype ScrollScheduler = [\n  scroll: (getTargetOffset: () => number, smooth?: boolean) => Promise<void>,\n  cancel: () => void\n];\n\nconst createScrollScheduler = (\n  store: VirtualStore,\n  initialized: () => Promise<boolean>,\n  scroll: (offset: number, smooth?: boolean) => void\n): ScrollScheduler => {\n  let cancelScroll: (() => void) | undefined;\n\n  // The given offset will be clamped by browser\n  // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop\n  return [\n    async (getTargetOffset, smooth) => {\n      // Wait for element assign. The element may be undefined if scrollRef prop is used and scroll is scheduled on mount.\n      // https://github.com/inokawa/virtua/pull/733\n      // https://github.com/inokawa/virtua/pull/750\n      if (!(await initialized())) {\n        return;\n      }\n\n      if (cancelScroll) {\n        // Cancel waiting scrollTo\n        cancelScroll();\n      }\n\n      const waitForMeasurement = (): [Promise<boolean>, () => void] => {\n        // Wait for the scroll destination items to be measured.\n        // The measurement will be done asynchronously and the timing is not predictable so we use promise.\n        const [promise, resolve] = createPromise<boolean>();\n        cancelScroll = () => {\n          resolve(false);\n        };\n\n        // Resize event may not happen when the window/tab is not visible, or during browser back in Safari.\n        // We have to wait for the initial measurement to avoid failing imperative scroll on mount.\n        // https://github.com/inokawa/virtua/issues/450\n        if (store.$getViewportSize()) {\n          // Cancel when items around scroll destination completely measured\n          timeout(cancelScroll, 150);\n        }\n        return [\n          promise,\n          store.$subscribe(UPDATE_SIZE_EVENT, () => {\n            resolve(true);\n          }),\n        ];\n      };\n\n      if (smooth && isSmoothScrollSupported()) {\n        store.$update(ACTION_BEFORE_MANUAL_SMOOTH_SCROLL, getTargetOffset());\n\n        // https://github.com/inokawa/virtua/issues/590\n        microtask(async () => {\n          while (true) {\n            let done = true;\n            for (let [i, end] = store.$getRange(); i <= end; i++) {\n              if (store.$isUnmeasuredItem(i)) {\n                done = false;\n                break;\n              }\n            }\n            if (done) {\n              break;\n            }\n            const [promise, unsubscribe] = waitForMeasurement();\n\n            try {\n              if (!(await promise)) {\n                // canceled\n                return;\n              }\n            } finally {\n              unsubscribe();\n            }\n          }\n\n          store.$update(ACTION_MANUAL_SCROLL);\n          scroll(getTargetOffset(), smooth);\n        });\n      } else {\n        while (true) {\n          const [promise, unsubscribe] = waitForMeasurement();\n\n          try {\n            store.$update(ACTION_MANUAL_SCROLL);\n            scroll(getTargetOffset());\n\n            if (!(await promise)) {\n              // canceled or finished\n              return;\n            }\n          } finally {\n            unsubscribe();\n          }\n        }\n      }\n    },\n    () => {\n      cancelScroll && cancelScroll();\n    },\n  ];\n};\n\n/**\n * @internal\n */\nexport type Scroller = {\n  $observe: (viewportElement: HTMLElement) => void;\n  $dispose(): void;\n  $scrollTo: (offset: number) => void;\n  $scrollBy: (offset: number) => void;\n  $scrollToIndex: (index: number, opts?: ScrollToIndexOpts) => void;\n  $fixScrollJump: () => void;\n};\n\n/**\n * @internal\n */\nexport const createScroller = (\n  store: VirtualStore,\n  isHorizontal: boolean\n): Scroller => {\n  let viewportElement: HTMLElement | undefined;\n  let scrollObserver: ScrollObserver | undefined;\n  let initialized = createPromise<boolean>();\n  const scrollOffsetKey = isHorizontal ? \"scrollLeft\" : \"scrollTop\";\n  const overflowKey = isHorizontal ? \"overflowX\" : \"overflowY\";\n\n  const [scheduleScroll, cancelScroll] = createScrollScheduler(\n    store,\n    () => initialized[0],\n    (offset, smooth) => {\n      offset = normalizeOffset(offset, isHorizontal);\n\n      if (smooth) {\n        viewportElement!.scrollTo({\n          [isHorizontal ? \"left\" : \"top\"]: offset,\n          behavior: \"smooth\",\n        });\n      } else {\n        viewportElement![scrollOffsetKey] = offset;\n      }\n    }\n  );\n\n  return {\n    $observe(viewport) {\n      viewportElement = viewport;\n\n      scrollObserver = createScrollObserver(\n        store,\n        viewport,\n        isHorizontal,\n        () => normalizeOffset(viewport[scrollOffsetKey], isHorizontal),\n        (jump, shift, isMomentumScrolling) => {\n          // If we update scroll position while touching on iOS, the position will be reverted.\n          // However iOS WebKit fires touch events only once at the beginning of momentum scrolling.\n          // That means we have no reliable way to confirm still touched or not if user touches more than once during momentum scrolling...\n          // This is a hack for the suspectable situations, inspired by https://github.com/prud/ios-overflow-scroll-to-top\n          if (isMomentumScrolling) {\n            const style = viewport.style;\n            const prev = style[overflowKey];\n            style[overflowKey] = \"hidden\";\n            timeout(() => {\n              style[overflowKey] = prev;\n            });\n          }\n\n          // Use absolute position not to exceed scrollable bounds\n          // https://github.com/inokawa/virtua/discussions/475\n          viewport[scrollOffsetKey] = store.$getScrollOffset() + jump;\n          if (shift) {\n            // https://github.com/inokawa/virtua/issues/357\n            cancelScroll();\n          }\n        }\n      );\n\n      initialized[1](true);\n    },\n    $dispose() {\n      scrollObserver && scrollObserver._dispose();\n      initialized[1](false);\n      // https://github.com/inokawa/virtua/pull/765\n      initialized = createPromise();\n    },\n    $scrollTo(offset) {\n      scheduleScroll(() => offset);\n    },\n    $scrollBy(offset) {\n      offset += store.$getScrollOffset();\n      scheduleScroll(() => offset);\n    },\n    $scrollToIndex(index, { align, smooth, offset = 0 } = {}) {\n      index = clamp(index, 0, store.$getItemsLength() - 1);\n\n      if (align === \"nearest\") {\n        const itemOffset = store.$getItemOffset(index);\n        const scrollOffset = store.$getScrollOffset();\n\n        if (itemOffset < scrollOffset) {\n          align = \"start\";\n        } else if (\n          itemOffset + store.$getItemSize(index) >\n          scrollOffset + store.$getViewportSize()\n        ) {\n          align = \"end\";\n        } else {\n          // already completely visible\n          return;\n        }\n      }\n\n      scheduleScroll(() => {\n        return (\n          offset +\n          store.$getStartSpacerSize() +\n          store.$getItemOffset(index) +\n          (align === \"end\"\n            ? store.$getItemSize(index) - store.$getViewportSize()\n            : align === \"center\"\n            ? (store.$getItemSize(index) - store.$getViewportSize()) / 2\n            : 0)\n        );\n      }, smooth);\n    },\n    $fixScrollJump: () => {\n      scrollObserver && scrollObserver._fixScrollJump();\n    },\n  };\n};\n\n/**\n * @internal\n */\nexport type WindowScroller = {\n  $observe(containerElement: HTMLElement): void;\n  $dispose(): void;\n  $scrollToIndex: (index: number, opts?: ScrollToIndexOpts) => void;\n  $fixScrollJump: () => void;\n};\n\n/**\n * @internal\n */\nexport const createWindowScroller = (\n  store: VirtualStore,\n  isHorizontal: boolean\n): WindowScroller => {\n  let containerElement: HTMLElement | undefined;\n  let scrollObserver: ScrollObserver | undefined;\n  let initialized = createPromise<boolean>();\n  const scrollToKey = isHorizontal ? \"left\" : \"top\";\n\n  const [scheduleScroll] = createScrollScheduler(\n    store,\n    () => initialized[0],\n    (offset, smooth) => {\n      offset = normalizeOffset(offset, isHorizontal);\n\n      const window = getCurrentWindow(getCurrentDocument(containerElement!));\n\n      if (smooth) {\n        window.scroll({\n          [scrollToKey]: offset,\n          behavior: \"smooth\",\n        });\n      } else {\n        window.scroll({\n          [scrollToKey]: offset,\n        });\n      }\n    }\n  );\n\n  const calcOffsetToViewport = (\n    node: HTMLElement,\n    viewport: HTMLElement,\n    window: Window,\n    isHorizontal: boolean,\n    offset: number = 0\n  ): number => {\n    // TODO calc offset only when it changes (maybe impossible)\n    const offsetKey = isHorizontal ? \"offsetLeft\" : \"offsetTop\";\n    const offsetSum =\n      offset +\n      (isHorizontal && isRTLDocument()\n        ? window.innerWidth - node[offsetKey] - node.offsetWidth\n        : node[offsetKey]);\n\n    const parent = node.offsetParent;\n    if (node === viewport || !parent) {\n      return offsetSum;\n    }\n\n    return calcOffsetToViewport(\n      parent as HTMLElement,\n      viewport,\n      window,\n      isHorizontal,\n      offsetSum\n    );\n  };\n\n  return {\n    $observe(container) {\n      containerElement = container;\n      const scrollOffsetKey = isHorizontal ? \"scrollX\" : \"scrollY\";\n\n      const document = getCurrentDocument(container);\n      const window = getCurrentWindow(document);\n\n      scrollObserver = createScrollObserver(\n        store,\n        window,\n        isHorizontal,\n        () => normalizeOffset(window[scrollOffsetKey], isHorizontal),\n        (jump, shift) => {\n          // TODO support case two window scrollers exist in the same view\n          if (shift) {\n            // Use absolute position not to exceed scrollable bounds\n            window.scroll({\n              [scrollToKey]: store.$getScrollOffset() + jump,\n            });\n          } else {\n            // Use window.scrollBy here, which causes less layout shift for some reason.\n            window.scrollBy({\n              [scrollToKey]: jump,\n            });\n          }\n        },\n        () =>\n          calcOffsetToViewport(container, document.body, window, isHorizontal)\n      );\n\n      initialized[1](true);\n    },\n    $dispose() {\n      scrollObserver && scrollObserver._dispose();\n      containerElement = undefined;\n      initialized[1](false);\n      // https://github.com/inokawa/virtua/pull/765\n      initialized = createPromise();\n    },\n    $fixScrollJump: () => {\n      scrollObserver && scrollObserver._fixScrollJump();\n    },\n    $scrollToIndex(index, { align, smooth, offset = 0 } = {}) {\n      if (!containerElement) return;\n\n      index = clamp(index, 0, store.$getItemsLength() - 1);\n\n      if (align === \"nearest\") {\n        const itemOffset = store.$getItemOffset(index);\n        const scrollOffset = store.$getScrollOffset();\n\n        if (itemOffset < scrollOffset) {\n          align = \"start\";\n        } else if (\n          itemOffset + store.$getItemSize(index) >\n          scrollOffset + store.$getViewportSize()\n        ) {\n          align = \"end\";\n        } else {\n          return;\n        }\n      }\n\n      const document = getCurrentDocument(containerElement);\n      const window = getCurrentWindow(document);\n      const html = document.documentElement;\n      const getScrollbarSize = () =>\n        store.$getViewportSize() -\n        (isHorizontal ? html.clientWidth : html.clientHeight);\n\n      scheduleScroll(() => {\n        return (\n          offset +\n          // Calculate target scroll position including container's offset from document\n          calcOffsetToViewport(\n            containerElement!,\n            document.body,\n            window,\n            isHorizontal\n          ) +\n          // store._getStartSpacerSize() +\n          store.$getItemOffset(index) +\n          (align === \"end\"\n            ? store.$getItemSize(index) -\n              (store.$getViewportSize() - getScrollbarSize())\n            : align === \"center\"\n            ? (store.$getItemSize(index) -\n                (store.$getViewportSize() - getScrollbarSize())) /\n              2\n            : 0)\n        );\n      }, smooth);\n    },\n  };\n};\n\n/**\n * @internal\n */\nexport type GridScroller = {\n  $observe: (viewportElement: HTMLElement) => void;\n  $dispose(): void;\n  $scrollTo: (offsetX: number, offsetY: number) => void;\n  $scrollBy: (offsetX: number, offsetY: number) => void;\n  $scrollToIndex: (indexX: number, indexY: number) => void;\n  $fixScrollJump: () => void;\n};\n\n/**\n * @internal\n */\nexport const createGridScroller = (\n  rowStore: VirtualStore,\n  colStore: VirtualStore\n): GridScroller => {\n  const vScroller = createScroller(rowStore, false);\n  const hScroller = createScroller(colStore, true);\n  return {\n    $observe(viewportElement) {\n      vScroller.$observe(viewportElement);\n      hScroller.$observe(viewportElement);\n    },\n    $dispose() {\n      vScroller.$dispose();\n      hScroller.$dispose();\n    },\n    $scrollTo(offsetX, offsetY) {\n      vScroller.$scrollTo(offsetY);\n      hScroller.$scrollTo(offsetX);\n    },\n    $scrollBy(offsetX, offsetY) {\n      vScroller.$scrollBy(offsetY);\n      hScroller.$scrollBy(offsetX);\n    },\n    $scrollToIndex(indexX, indexY) {\n      vScroller.$scrollToIndex(indexY);\n      hScroller.$scrollToIndex(indexX);\n    },\n    $fixScrollJump() {\n      vScroller.$fixScrollJump();\n      hScroller.$fixScrollJump();\n    },\n  };\n};\n","import { getCurrentDocument, getCurrentWindow } from \"./environment.js\";\nimport {\n  ACTION_ITEM_RESIZE,\n  ACTION_VIEWPORT_RESIZE,\n  type VirtualStore,\n} from \"./store.js\";\nimport { type ItemResize } from \"./types.js\";\nimport { max, microtask, NULL } from \"./utils.js\";\n\nconst createResizeObserver = (cb: ResizeObserverCallback) => {\n  let ro: ResizeObserver | undefined;\n\n  return {\n    _observe(e: HTMLElement) {\n      // Initialize ResizeObserver lazily for SSR\n      // https://www.w3.org/TR/resize-observer/#intro\n      (\n        ro ||\n        // https://bugs.chromium.org/p/chromium/issues/detail?id=1491739\n        (ro = new (getCurrentWindow(getCurrentDocument(e)).ResizeObserver)(cb))\n      ).observe(e);\n    },\n    _unobserve(e: HTMLElement) {\n      ro!.unobserve(e);\n    },\n    _dispose() {\n      ro && ro.disconnect();\n    },\n  };\n};\n\n/**\n * @internal\n */\nexport type ItemResizeObserver = (el: HTMLElement, i: number) => () => void;\n\ninterface ListResizer {\n  $observeRoot(viewportElement: HTMLElement): void;\n  $observeItem: ItemResizeObserver;\n  $dispose(): void;\n}\n\n/**\n * @internal\n */\nexport const createResizer = (\n  store: VirtualStore,\n  isHorizontal: boolean\n): ListResizer => {\n  let viewportElement: HTMLElement | undefined;\n  const sizeKey = isHorizontal ? \"width\" : \"height\";\n  const mountedIndexes = new WeakMap<Element, number>();\n\n  const resizeObserver = createResizeObserver((entries) => {\n    const resizes: ItemResize[] = [];\n    for (const { target, contentRect } of entries) {\n      // Skip zero-sized rects that may be observed under `display: none` style\n      if (!(target as HTMLElement).offsetParent) continue;\n\n      if (target === viewportElement) {\n        store.$update(ACTION_VIEWPORT_RESIZE, contentRect[sizeKey]);\n      } else {\n        const index = mountedIndexes.get(target);\n        if (index != NULL) {\n          resizes.push([index, contentRect[sizeKey]]);\n        }\n      }\n    }\n\n    if (resizes.length) {\n      store.$update(ACTION_ITEM_RESIZE, resizes);\n    }\n  });\n\n  return {\n    $observeRoot(viewport: HTMLElement) {\n      resizeObserver._observe((viewportElement = viewport));\n    },\n    $observeItem: (el: HTMLElement, i: number) => {\n      mountedIndexes.set(el, i);\n      resizeObserver._observe(el);\n      return () => {\n        mountedIndexes.delete(el);\n        resizeObserver._unobserve(el);\n      };\n    },\n    $dispose: resizeObserver._dispose,\n  };\n};\n\ninterface WindowListResizer {\n  $observeRoot(container: HTMLElement): void;\n  $observeItem: ItemResizeObserver;\n  $dispose(): void;\n}\n\n/**\n * @internal\n */\nexport const createWindowResizer = (\n  store: VirtualStore,\n  isHorizontal: boolean\n): WindowListResizer => {\n  const sizeKey = isHorizontal ? \"width\" : \"height\";\n  const windowSizeKey = isHorizontal ? \"innerWidth\" : \"innerHeight\";\n  const mountedIndexes = new WeakMap<Element, number>();\n\n  const resizeObserver = createResizeObserver((entries) => {\n    const resizes: ItemResize[] = [];\n    for (const { target, contentRect } of entries) {\n      // Skip zero-sized rects that may be observed under `display: none` style\n      if (!(target as HTMLElement).offsetParent) continue;\n\n      const index = mountedIndexes.get(target);\n      if (index != NULL) {\n        resizes.push([index, contentRect[sizeKey]]);\n      }\n    }\n\n    if (resizes.length) {\n      store.$update(ACTION_ITEM_RESIZE, resizes);\n    }\n  });\n\n  let cleanupOnWindowResize: (() => void) | undefined;\n\n  return {\n    $observeRoot(container) {\n      const window = getCurrentWindow(getCurrentDocument(container));\n      const onWindowResize = () => {\n        store.$update(ACTION_VIEWPORT_RESIZE, window[windowSizeKey]);\n      };\n      window.addEventListener(\"resize\", onWindowResize);\n\n      // https://github.com/inokawa/virtua/issues/792\n      microtask(onWindowResize);\n\n      cleanupOnWindowResize = () => {\n        window.removeEventListener(\"resize\", onWindowResize);\n      };\n    },\n    $observeItem: (el: HTMLElement, i: number) => {\n      mountedIndexes.set(el, i);\n      resizeObserver._observe(el);\n      return () => {\n        mountedIndexes.delete(el);\n        resizeObserver._unobserve(el);\n      };\n    },\n    $dispose() {\n      cleanupOnWindowResize && cleanupOnWindowResize();\n      resizeObserver._dispose();\n    },\n  };\n};\n\n/**\n * @internal\n */\nexport const createGridResizer = (\n  rowStore: VirtualStore,\n  colStore: VirtualStore\n) => {\n  let viewportElement: HTMLElement | undefined;\n\n  const mountedIndexes = new WeakMap<\n    Element,\n    [rowIndex: number, colIndex: number]\n  >();\n\n  type CellSize = [height: number, width: number];\n  const maybeCachedRowIndexes = new Set<number>();\n  const maybeCachedColIndexes = new Set<number>();\n  const sizeCache = new Map<string, CellSize>();\n  const getKey = (rowIndex: number, colIndex: number): string =>\n    `${rowIndex}-${colIndex}`;\n\n  const resizeObserver = createResizeObserver((entries) => {\n    const resizedRows = new Set<number>();\n    const resizedCols = new Set<number>();\n    for (const {\n      target,\n      contentRect: { width, height },\n    } of entries) {\n      // Skip zero-sized rects that may be observed under `display: none` style\n      if (!(target as HTMLElement).offsetParent) continue;\n\n      if (target === viewportElement) {\n        rowStore.$update(ACTION_VIEWPORT_RESIZE, height);\n        colStore.$update(ACTION_VIEWPORT_RESIZE, width);\n      } else {\n        const cell = mountedIndexes.get(target);\n        if (cell) {\n          const [rowIndex, colIndex] = cell;\n          const key = getKey(rowIndex, colIndex);\n          const prevSize = sizeCache.get(key);\n          let rowResized: boolean | undefined;\n          let colResized: boolean | undefined;\n          if (!prevSize) {\n            rowResized = colResized = true;\n          } else {\n            if (prevSize[0] !== height) {\n              rowResized = true;\n            }\n            if (prevSize[1] !== width) {\n              colResized = true;\n            }\n          }\n          if (rowResized) {\n            resizedRows.add(rowIndex);\n          }\n          if (colResized) {\n            resizedCols.add(colIndex);\n          }\n          if (rowResized || colResized) {\n            sizeCache.set(key, [height, width]);\n          }\n        }\n      }\n    }\n\n    if (resizedRows.size) {\n      const heightResizes: ItemResize[] = [];\n      resizedRows.forEach((rowIndex) => {\n        let maxHeight = 0;\n        maybeCachedColIndexes.forEach((colIndex) => {\n          const size = sizeCache.get(getKey(rowIndex, colIndex));\n          if (size) {\n            maxHeight = max(maxHeight, size[0]);\n          }\n        });\n        if (maxHeight) {\n          heightResizes.push([rowIndex, maxHeight]);\n        }\n      });\n      rowStore.$update(ACTION_ITEM_RESIZE, heightResizes);\n    }\n    if (resizedCols.size) {\n      const widthResizes: ItemResize[] = [];\n      resizedCols.forEach((colIndex) => {\n        let maxWidth = 0;\n        maybeCachedRowIndexes.forEach((rowIndex) => {\n          const size = sizeCache.get(getKey(rowIndex, colIndex));\n          if (size) {\n            maxWidth = max(maxWidth, size[1]);\n          }\n        });\n        if (maxWidth) {\n          widthResizes.push([colIndex, maxWidth]);\n        }\n      });\n      colStore.$update(ACTION_ITEM_RESIZE, widthResizes);\n    }\n  });\n\n  return {\n    $observeRoot(viewport: HTMLElement) {\n      resizeObserver._observe((viewportElement = viewport));\n    },\n    $observeItem(el: HTMLElement, rowIndex: number, colIndex: number) {\n      mountedIndexes.set(el, [rowIndex, colIndex]);\n      maybeCachedRowIndexes.add(rowIndex);\n      maybeCachedColIndexes.add(colIndex);\n      resizeObserver._observe(el);\n      return () => {\n        mountedIndexes.delete(el);\n        resizeObserver._unobserve(el);\n      };\n    },\n    $resizeCols(cols: ItemResize[]) {\n      for (const [c] of cols) {\n        for (let r = 0; r < rowStore.$getItemsLength(); r++) {\n          sizeCache.delete(getKey(r, c));\n        }\n      }\n      colStore.$update(ACTION_ITEM_RESIZE, cols);\n    },\n    $resizeRows(rows: ItemResize[]) {\n      for (const [r] of rows) {\n        for (let c = 0; c < colStore.$getItemsLength(); c++) {\n          sizeCache.delete(getKey(r, c));\n        }\n      }\n      rowStore.$update(ACTION_ITEM_RESIZE, rows);\n    },\n    $dispose: resizeObserver._dispose,\n  };\n};\n\n/**\n * @internal\n */\nexport type GridResizer = ReturnType<typeof createGridResizer>;\n","/**\n * @jsxImportSource solid-js\n */\nimport { ItemResizeObserver, isRTLDocument } from \"../core/index.js\";\nimport {\n  Component,\n  JSX,\n  createEffect,\n  createMemo,\n  mergeProps,\n  onCleanup,\n  type ValidComponent,\n} from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\n\ninterface ListItemProps {\n  _children: JSX.Element;\n  _resizer: ItemResizeObserver;\n  _index: number;\n  _offset: number;\n  _hide: boolean;\n  _isHorizontal: boolean;\n  _as?: ValidComponent;\n}\n\n/**\n * @internal\n */\nexport const ListItem: Component<ListItemProps> = (props) => {\n  let elementRef: HTMLDivElement | undefined;\n  props = mergeProps<[Partial<ListItemProps>, ListItemProps]>(\n    { _as: \"div\" },\n    props\n  );\n\n  // The index may be changed if elements are inserted to or removed from the start of props.children\n  createEffect(() => {\n    if (!elementRef) return;\n    onCleanup(props._resizer(elementRef, props._index));\n  });\n\n  const style = createMemo(() => {\n    const isHorizontal = props._isHorizontal;\n    const style: JSX.CSSProperties = {\n      contain: \"layout style\",\n      position: \"absolute\",\n      [isHorizontal ? \"height\" : \"width\"]: \"100%\",\n      [isHorizontal ? \"top\" : \"left\"]: \"0px\",\n      [isHorizontal ? (isRTLDocument() ? \"right\" : \"left\") : \"top\"]:\n        props._offset + \"px\",\n      visibility: props._hide ? \"hidden\" : \"visible\",\n    };\n    if (isHorizontal) {\n      style.display = \"inline-flex\";\n    }\n    return style;\n  });\n\n  return (\n    <Dynamic\n      component={props._as}\n      index={props._index}\n      ref={elementRef}\n      style={style()}\n    >\n      {props._children}\n    </Dynamic>\n  );\n};\n","import { ItemsRange } from \"../core/index.js\";\n\n/**\n * @internal\n */\nexport const isSameRange = (prev: ItemsRange, next: ItemsRange): boolean => {\n  return prev[0] === next[0] && prev[1] === next[1];\n};\n","/**\n * @jsxImportSource solid-js\n */\nimport {\n  onMount,\n  onCleanup,\n  createEffect,\n  createSignal,\n  createMemo,\n  JSX,\n  on,\n  createComputed,\n  type ValidComponent,\n  mergeProps,\n  For,\n  Accessor,\n  untrack,\n} from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport {\n  UPDATE_SCROLL_EVENT,\n  UPDATE_SCROLL_END_EVENT,\n  UPDATE_VIRTUAL_STATE,\n  createVirtualStore,\n  ACTION_ITEMS_LENGTH_CHANGE,\n  getScrollSize,\n  ACTION_START_OFFSET_CHANGE,\n  createResizer,\n  createScroller,\n  ItemsRange,\n  ScrollToIndexOpts,\n  CacheSnapshot,\n  sort,\n} from \"../core/index.js\";\nimport { ListItem } from \"./ListItem.js\";\nimport { isSameRange } from \"./utils.js\";\n\n/**\n * Methods of {@link Virtualizer}.\n */\nexport interface VirtualizerHandle {\n  /**\n   * Get current {@link CacheSnapshot}.\n   */\n  readonly cache: CacheSnapshot;\n  /**\n   * Get current scrollTop, or scrollLeft if horizontal: true.\n   */\n  readonly scrollOffset: number;\n  /**\n   * Get current scrollHeight, or scrollWidth if horizontal: true.\n   */\n  readonly scrollSize: number;\n  /**\n   * Get current offsetHeight, or offsetWidth if horizontal: true.\n   */\n  readonly viewportSize: number;\n  /**\n   * Find the start index of visible range of items.\n   */\n  findStartIndex: () => number;\n  /**\n   * Find the end index of visible range of items.\n   */\n  findEndIndex: () => number;\n  /**\n   * Get item offset from start.\n   * @param index index of item\n   */\n  getItemOffset(index: number): number;\n  /**\n   * Get item size.\n   * @param index index of item\n   */\n  getItemSize(index: number): number;\n  /**\n   * Scroll to the item specified by index.\n   * @param index index of item\n   * @param opts options\n   */\n  scrollToIndex(index: number, opts?: ScrollToIndexOpts): void;\n  /**\n   * Scroll to the given offset.\n   * @param offset offset from start\n   */\n  scrollTo(offset: number): void;\n  /**\n   * Scroll by the given offset.\n   * @param offset offset from current position\n   */\n  scrollBy(offset: number): void;\n}\n\n/**\n * Props of {@link Virtualizer}.\n */\nexport interface VirtualizerProps<T> {\n  /**\n   * Get reference to {@link VirtualizerHandle}.\n   */\n  ref?: (handle?: VirtualizerHandle) => void;\n  /**\n   * The data items rendered by this component.\n   */\n  data: readonly T[];\n  /**\n   * The elements renderer function.\n   */\n  children: (data: T, index: Accessor<number>) => JSX.Element;\n  /**\n   * Extra item space in pixels to render before/after the viewport. The minimum value is 0. Lower value will give better performance but you can increase to avoid showing blank items in fast scrolling.\n   * @defaultValue 200\n   */\n  bufferSize?: number;\n  /**\n   * Component or element type for container element.\n   * @defaultValue \"div\"\n   */\n  as?: ValidComponent;\n  /**\n   * Component or element type for item element.\n   * @defaultValue \"div\"\n   */\n  item?: ValidComponent;\n  /**\n   * Reference to the scrollable element. The default will get the direct parent element of virtualizer.\n   */\n  scrollRef?: HTMLElement;\n  /**\n   * Item size hint for unmeasured items in pixels. It will help to reduce scroll jump when items are measured if used properly.\n   *\n   * - If not set, initial item sizes will be automatically estimated from measured sizes. This is recommended for most cases.\n   * - If set, you can opt out estimation and use the value as initial item size.\n   */\n  itemSize?: number;\n  /**\n   * While true is set, scroll position will be maintained from the end not usual start when items are added to/removed from start. It's recommended to set false if you add to/remove from mid/end of the list because it can cause unexpected behavior. This prop is useful for reverse infinite scrolling.\n   */\n  shift?: boolean;\n  /**\n   * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.\n   */\n  horizontal?: boolean;\n  /**\n   * List of indexes that should be always mounted, even when off screen.\n   */\n  keepMounted?: readonly number[];\n  /**\n   * You can restore cache by passing a {@link CacheSnapshot} on mount. This is useful when you want to restore scroll position after navigation. The snapshot can be obtained from {@link VirtualizerHandle.cache}.\n   *\n   * **The length of items should be the same as when you take the snapshot, otherwise restoration may not work as expected.**\n   */\n  cache?: CacheSnapshot;\n  /**\n   * The offset to the scrollable parent before virtualizer in pixels. If you put an element before virtualizer, you have to set its height to this prop.\n   */\n  startMargin?: number;\n  /**\n   * Callback invoked whenever scroll offset changes.\n   * @param offset Current scrollTop, or scrollLeft if horizontal: true.\n   */\n  onScroll?: (offset: number) => void;\n  /**\n   * Callback invoked when scrolling stops.\n   */\n  onScrollEnd?: () => void;\n}\n\n/**\n * Customizable list virtualizer for advanced usage. See {@link VirtualizerProps} and {@link VirtualizerHandle}.\n */\nexport const Virtualizer = <T,>(props: VirtualizerProps<T>): JSX.Element => {\n  let containerRef: HTMLDivElement | undefined;\n  const { itemSize, horizontal = false, cache } = props;\n  props = mergeProps<[Partial<VirtualizerProps<T>>, VirtualizerProps<T>]>(\n    { as: \"div\" },\n    props\n  );\n\n  const store = createVirtualStore(\n    props.data.length,\n    itemSize,\n    undefined,\n    cache,\n    !itemSize\n  );\n  const resizer = createResizer(store, horizontal);\n  const scroller = createScroller(store, horizontal);\n\n  const [stateVersion, setRerender] = createSignal(store.$getStateVersion());\n\n  store.$subscribe(UPDATE_VIRTUAL_STATE, () => {\n    setRerender(store.$getStateVersion());\n  });\n  store.$subscribe(UPDATE_SCROLL_EVENT, () => {\n    props.onScroll?.(store.$getScrollOffset());\n  });\n  store.$subscribe(UPDATE_SCROLL_END_EVENT, () => {\n    props.onScrollEnd?.();\n  });\n\n  const range = createMemo<ItemsRange>((prev) => {\n    stateVersion();\n    const next = store.$getRange(props.bufferSize);\n    if (prev && isSameRange(prev, next)) {\n      return prev;\n    }\n    return next;\n  });\n  const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());\n  const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());\n\n  onMount(() => {\n    if (props.ref) {\n      props.ref({\n        get cache() {\n          return store.$getCacheSnapshot();\n        },\n        get scrollOffset() {\n          return store.$getScrollOffset();\n        },\n        get scrollSize() {\n          return getScrollSize(store);\n        },\n        get viewportSize() {\n          return store.$getViewportSize();\n        },\n        findStartIndex: store.$findStartIndex,\n        findEndIndex: store.$findEndIndex,\n        getItemOffset: store.$getItemOffset,\n        getItemSize: store.$getItemSize,\n        scrollToIndex: scroller.$scrollToIndex,\n        scrollTo: scroller.$scrollTo,\n        scrollBy: scroller.$scrollBy,\n      });\n    }\n\n    const scrollable = props.scrollRef || containerRef!.parentElement!;\n    resizer.$observeRoot(scrollable);\n    scroller.$observe(scrollable);\n\n    onCleanup(() => {\n      if (props.ref) {\n        props.ref();\n      }\n\n      store.$dispose();\n      resizer.$dispose();\n      scroller.$dispose();\n    });\n  });\n\n  createComputed(\n    on(\n      () => props.startMargin || 0,\n      (value) => {\n        if (value !== store.$getStartSpacerSize()) {\n          store.$update(ACTION_START_OFFSET_CHANGE, value);\n        }\n      }\n    )\n  );\n\n  createEffect(\n    on(stateVersion, () => {\n      scroller.$fixScrollJump();\n    })\n  );\n\n  const dataSlice = createMemo(() => {\n    const count = props.data.length;\n    untrack(() => {\n      if (count !== store.$getItemsLength()) {\n        store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);\n      }\n    });\n    const items: T[] = [];\n    const indexes: number[] = [];\n\n    if (props.keepMounted) {\n      const mounted = new Set(props.keepMounted);\n      for (let [i, j] = range(); i <= j; i++) {\n        mounted.add(i);\n      }\n      sort([...mounted]).forEach((index) => {\n        items.push(props.data[index]!);\n        indexes.push(index);\n      });\n    } else {\n      for (let [i, j] = range(); i <= j; i++) {\n        items.push(props.data[i]!);\n        indexes.push(i);\n      }\n    }\n\n    return { _items: items, _indexes: indexes };\n  });\n\n  const renderItem = (data: T, index: Accessor<number>) => {\n    const offset = createMemo(() => {\n      stateVersion();\n      return store.$getItemOffset(index());\n    });\n    const hide = createMemo(() => {\n      stateVersion();\n      return store.$isUnmeasuredItem(index());\n    });\n    const children = createMemo(() => {\n      return untrack(() => props.children(data, index));\n    });\n\n    return (\n      <ListItem\n        _as={props.item}\n        _index={index()}\n        _resizer={resizer.$observeItem}\n        _offset={offset()}\n        _hide={hide()}\n        _children={children()}\n        _isHorizontal={horizontal}\n      />\n    );\n  };\n\n  return (\n    <Dynamic\n      component={props.as}\n      ref={containerRef}\n      style={{\n        contain: \"size style\", // https://github.com/inokawa/virtua/pull/775 https://github.com/inokawa/virtua/issues/800\n        \"overflow-anchor\": \"none\", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer\n        flex: \"none\", // flex style can break layout\n        position: \"relative\",\n        width: horizontal ? totalSize() + \"px\" : \"100%\",\n        height: horizontal ? \"100%\" : totalSize() + \"px\",\n        \"pointer-events\": isScrolling() ? \"none\" : undefined,\n      }}\n    >\n      <For each={dataSlice()._items}>\n        {(data, index) => {\n          const itemIndex = createMemo(() => dataSlice()._indexes[index()]!);\n          // eslint-disable-next-line solid/reactivity\n          return renderItem(data, itemIndex);\n        }}\n      </For>\n    </Dynamic>\n  );\n};\n","/**\n * @jsxImportSource solid-js\n */\nimport { JSX, splitProps } from \"solid-js\";\nimport { ViewportComponentAttributes } from \"./types.js\";\nimport {\n  Virtualizer,\n  VirtualizerHandle,\n  VirtualizerProps,\n} from \"./Virtualizer.js\";\n\n/**\n * Methods of {@link VList}.\n */\nexport interface VListHandle extends VirtualizerHandle {}\n\n/**\n * Props of {@link VList}.\n */\nexport interface VListProps<T>\n  extends Pick<\n      VirtualizerProps<T>,\n      | \"ref\"\n      | \"data\"\n      | \"children\"\n      | \"bufferSize\"\n      | \"itemSize\"\n      | \"shift\"\n      | \"horizontal\"\n      | \"cache\"\n      | \"item\"\n      | \"onScroll\"\n      | \"onScrollEnd\"\n      | \"keepMounted\"\n    >,\n    ViewportComponentAttributes {}\n\n/**\n * Virtualized list component. See {@link VListProps} and {@link VListHandle}.\n */\nexport const VList = <T,>(props: VListProps<T>): JSX.Element => {\n  const [local, others] = splitProps(props, [\n    \"ref\",\n    \"data\",\n    \"children\",\n    \"bufferSize\",\n    \"itemSize\",\n    \"shift\",\n    \"horizontal\",\n    \"keepMounted\",\n    \"cache\",\n    \"item\",\n    \"onScroll\",\n    \"onScrollEnd\",\n    \"style\",\n  ]);\n\n  return (\n    <div\n      {...others}\n      style={{\n        display: local.horizontal ? \"inline-block\" : \"block\",\n        [local.horizontal ? \"overflow-x\" : \"overflow-y\"]: \"auto\",\n        contain: \"strict\",\n        width: \"100%\",\n        height: \"100%\",\n        ...local.style,\n      }}\n    >\n      <Virtualizer\n        ref={local.ref}\n        data={local.data}\n        bufferSize={local.bufferSize}\n        itemSize={local.itemSize}\n        shift={local.shift}\n        horizontal={local.horizontal}\n        keepMounted={local.keepMounted}\n        cache={local.cache}\n        item={local.item}\n        onScroll={local.onScroll}\n        onScrollEnd={local.onScrollEnd}\n      >\n        {local.children}\n      </Virtualizer>\n    </div>\n  );\n};\n","/**\n * @jsxImportSource solid-js\n */\nimport {\n  onMount,\n  onCleanup,\n  createEffect,\n  createSignal,\n  createMemo,\n  JSX,\n  Accessor,\n  on,\n  For,\n  untrack,\n} from \"solid-js\";\nimport {\n  UPDATE_SCROLL_END_EVENT,\n  UPDATE_VIRTUAL_STATE,\n  createVirtualStore,\n  ACTION_ITEMS_LENGTH_CHANGE,\n  UPDATE_SCROLL_EVENT,\n  createWindowResizer,\n  createWindowScroller,\n  ItemsRange,\n  ScrollToIndexOpts,\n  CacheSnapshot,\n} from \"../core/index.js\";\nimport { ListItem } from \"./ListItem.js\";\nimport { isSameRange } from \"./utils.js\";\n\n/**\n * Methods of {@link WindowVirtualizer}.\n */\nexport interface WindowVirtualizerHandle {\n  /**\n   * Get current {@link CacheSnapshot}.\n   */\n  readonly cache: CacheSnapshot;\n  /**\n   * Find the start index of visible range of items.\n   */\n  findStartIndex: () => number;\n  /**\n   * Find the end index of visible range of items.\n   */\n  findEndIndex: () => number;\n  /**\n   * Scroll to the item specified by index.\n   * @param index index of item\n   * @param opts options\n   */\n  scrollToIndex(index: number, opts?: ScrollToIndexOpts): void;\n}\n\n/**\n * Props of {@link WindowVirtualizer}.\n */\nexport interface WindowVirtualizerProps<T> {\n  /**\n   * Get reference to {@link WindowVirtualizerHandle}.\n   */\n  ref?: (handle?: WindowVirtualizerHandle) => void;\n  /**\n   * The data items rendered by this component.\n   */\n  data: readonly T[];\n  /**\n   * The elements renderer function.\n   */\n  children: (data: T, index: Accessor<number>) => JSX.Element;\n  /**\n   * Extra item space in pixels to render before/after the viewport. The minimum value is 0. Lower value will give better performance but you can increase to avoid showing blank items in fast scrolling.\n   * @defaultValue 200\n   */\n  bufferSize?: number;\n  /**\n   * Item size hint for unmeasured items in pixels. It will help to reduce scroll jump when items are measured if used properly.\n   *\n   * - If not set, initial item sizes will be automatically estimated from measured sizes. This is recommended for most cases.\n   * - If set, you can opt out estimation and use the value as initial item size.\n   */\n  itemSize?: number;\n  /**\n   * While true is set, scroll position will be maintained from the end not usual start when items are added to/removed from start. It's recommended to set false if you add to/remove from mid/end of the list because it can cause unexpected behavior. This prop is useful for reverse infinite scrolling.\n   */\n  shift?: boolean;\n  /**\n   * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list.\n   */\n  horizontal?: boolean;\n  /**\n   * You can restore cache by passing a {@link CacheSnapshot} on mount. This is useful when you want to restore scroll position after navigation. The snapshot can be obtained from {@link WindowVirtualizerHandle.cache}.\n   *\n   * **The length of items should be the same as when you take the snapshot, otherwise restoration may not work as expected.**\n   */\n  cache?: CacheSnapshot;\n  /**\n   * Callback invoked whenever scroll offset changes.\n   */\n  onScroll?: () => void;\n  /**\n   * Callback invoked when scrolling stops.\n   */\n  onScrollEnd?: () => void;\n}\n\n/**\n * {@link Virtualizer} controlled by the window scrolling. See {@link WindowVirtualizerProps} and {@link WindowVirtualizerHandle}.\n */\nexport const WindowVirtualizer = <T,>(\n  props: WindowVirtualizerProps<T>\n): JSX.Element => {\n  let containerRef: HTMLDivElement | undefined;\n\n  const {\n    ref: _ref,\n    data: _data,\n    children: _children,\n    itemSize,\n    shift: _shift,\n    horizontal = false,\n    cache,\n    onScrollEnd: _onScrollEnd,\n  } = props;\n\n  const store = createVirtualStore(\n    props.data.length,\n    itemSize,\n    undefined,\n    cache,\n    !itemSize\n  );\n  const resizer = createWindowResizer(store, horizontal);\n  const scroller = createWindowScroller(store, horizontal);\n\n  const [stateVersion, setRerender] = createSignal(store.$getStateVersion());\n\n  store.$subscribe(UPDATE_VIRTUAL_STATE, () => {\n    setRerender(store.$getStateVersion());\n  });\n  store.$subscribe(UPDATE_SCROLL_EVENT, () => {\n    // https://github.com/inokawa/virtua/discussions/580\n    props.onScroll?.();\n  });\n  store.$subscribe(UPDATE_SCROLL_END_EVENT, () => {\n    props.onScrollEnd?.();\n  });\n\n  const range = createMemo<ItemsRange>((prev) => {\n    stateVersion();\n    const next = store.$getRange(props.bufferSize);\n    if (prev && isSameRange(prev, next)) {\n      return prev;\n    }\n    return next;\n  });\n  const isScrolling = createMemo(() => stateVersion() && store.$isScrolling());\n  const totalSize = createMemo(() => stateVersion() && store.$getTotalSize());\n\n  onMount(() => {\n    if (props.ref) {\n      props.ref({\n        get cache() {\n          return store.$getCacheSnapshot();\n        },\n        findStartIndex: store.$findStartIndex,\n        findEndIndex: store.$findEndIndex,\n        scrollToIndex: scroller.$scrollToIndex,\n      });\n    }\n\n    resizer.$observeRoot(containerRef!);\n    scroller.$observe(containerRef!);\n\n    onCleanup(() => {\n      if (props.ref) {\n        props.ref();\n      }\n\n      store.$dispose();\n      resizer.$dispose();\n      scroller.$dispose();\n    });\n  });\n\n  createEffect(\n    on(stateVersion, () => {\n      scroller.$fixScrollJump();\n    })\n  );\n\n  const dataSlice = createMemo<T[]>(() => {\n    const count = props.data.length;\n    untrack(() => {\n      if (count !== store.$getItemsLength()) {\n        store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);\n      }\n    });\n    const items: T[] = [];\n    for (let [i, j] = range(); i <= j; i++) {\n      items.push(props.data[i]!);\n    }\n    return items;\n  });\n\n  return (\n    <div\n      ref={containerRef}\n      style={{\n        contain: \"size style\", // https://github.com/inokawa/virtua/pull/775 https://github.com/inokawa/virtua/issues/800\n        \"overflow-anchor\": \"none\", // opt out browser's scroll anchoring because it will conflict to scroll anchoring of virtualizer\n        flex: \"none\", // flex style can break layout\n        position: \"relative\",\n        width: horizontal ? totalSize() + \"px\" : \"100%\",\n        height: horizontal ? \"100%\" : totalSize() + \"px\",\n        \"pointer-events\": isScrolling() ? \"none\" : undefined,\n      }}\n    >\n      <For each={dataSlice()}>\n        {(data, index) => {\n          const itemIndex = createMemo(() => range()[0] + index());\n          const offset = createMemo(() => {\n            stateVersion();\n            return store.$getItemOffset(itemIndex());\n          });\n          const hide = createMemo(() => {\n            stateVersion();\n            return store.$isUnmeasuredItem(itemIndex());\n          });\n          const children = createMemo(() => {\n            return untrack(() => props.children(data, itemIndex));\n          });\n\n          return (\n            <ListItem\n              _index={itemIndex()}\n              _resizer={resizer.$observeItem}\n              _offset={offset()}\n              _hide={hide()}\n              _children={children()}\n              _isHorizontal={horizontal}\n            />\n          );\n        }}\n      </For>\n    </div>\n  );\n};\n"],"names":["NULL","min","max","abs","floor","Math","clamp","value","minValue","maxValue","sort","arr","a","b","microtask","queueMicrotask","fn","Promise","resolve","then","createPromise","res","once","cache","undefined","fill","array","length","prepend","key","i","getItemSize","index","size","_sizes","_defaultItemSize","setItemSize","isInitialMeasurement","_computedOffsetIndex","getItemOffset","_length","_offsets","top","findIndex","offset","low","high","mid","updateCacheLength","isShift","diff","splice","reduce","acc","removed","isBrowser","window","getDocumentElement","document","documentElement","getCurrentDocument","node","ownerDocument","getCurrentWindow","doc","defaultView","isRTLDocument","getComputedStyle","direction","isIOSWebKit","test","navigator","userAgent","platform","maxTouchPoints","isSmoothScrollSupported","style","createVirtualStore","elementsCount","itemSize","ssrCount","cacheSnapshot","shouldAutoEstimateItemSize","isSSR","stateVersion","viewportSize","startSpacerSize","scrollOffset","jump","pendingJump","_flushedJump","_scrollDirection","_scrollMode","_frozenRange","_prevRange","_totalMeasuredSize","snapshot","slice","initCache","subscribers","Set","getRelativeScrollOffset","getVisibleOffset","getRange","startOffset","endOffset","prevStartIndex","end","start","computeRange","getTotalSize","_getItemOffset","_getItemSize","isSizeEqual","UNCACHED","applyJump","j","$dispose","clear","$getStateVersion","$getCacheSnapshot","takeCacheSnapshot","$getRange","bufferSize","startIndex","endIndex","$findStartIndex","$findEndIndex","$isUnmeasuredItem","$getItemOffset","$getItemSize","$getItemsLength","$getScrollOffset","$isScrolling","$getViewportSize","$getStartSpacerSize","$getTotalSize","_flushJump","$subscribe","target","cb","sub","add","delete","$update","type","payload","shouldFlushPendingJump","shouldSync","mutated","flushedJump","delta","distance","relativeOffset","updated","filter","prevSize","measuredCountBeforeStart","measuredSizes","forEach","s","push","sorted","len","median","prevDefaultItemSize","estimateDefaultItemSize","UPDATE_VIRTUAL_STATE","timeout","setTimeout","normalizeOffset","isHorizontal","createScrollObserver","store","viewport","getScrollOffset","updateScrollOffset","getStartOffset","now","Date","lastScrollTime","wheeling","touching","justTouchEnded","stillMomentumScrolling","onScrollEnd","id","cancel","clearTimeout","debouncedFn","_cancel","debounce","onScroll","onWheel","e","ctrlKey","timeDelta","deltaX","deltaY","onTouchStart","onTouchEnd","addEventListener","passive","_dispose","removeEventListener","_fixScrollJump","shift","createScrollScheduler","initialized","scroll","cancelScroll","async","getTargetOffset","smooth","waitForMeasurement","promise","done","unsubscribe","createResizeObserver","ro","_observe","observe","_unobserve","unobserve","disconnect","ListItem","props","elementRef","mergeProps","_as","createEffect","onCleanup","_resizer","_index","createMemo","_isHorizontal","contain","position","_offset","visibility","_hide","display","_$createComponent","Dynamic","component","ref","r$","children","_children","isSameRange","prev","next","Virtualizer","containerRef","horizontal","as","data","resizer","viewportElement","sizeKey","mountedIndexes","WeakMap","resizeObserver","entries","resizes","contentRect","offsetParent","get","$observeRoot","$observeItem","el","set","createResizer","scroller","scrollObserver","scrollOffsetKey","overflowKey","scheduleScroll","scrollTo","behavior","$observe","isMomentumScrolling","$scrollTo","$scrollBy","$scrollToIndex","align","itemOffset","$fixScrollJump","createScroller","setRerender","createSignal","_a","call","range","isScrolling","totalSize","onMount","scrollSize","getScrollSize","findStartIndex","findEndIndex","scrollToIndex","scrollBy","scrollable","scrollRef","parentElement","createComputed","on","startMargin","dataSlice","count","untrack","items","indexes","keepMounted","mounted","_items","_indexes","flex","width","height","For","each","renderItem","hide","item","local","others","splitProps","_el$","_tmpl$","_$spread","_$mergeProps","_$insert","_ref$","_ref","_data","_shift","_onScrollEnd","windowSizeKey","cleanupOnWindowResize","container","onWindowResize","createWindowResizer","containerElement","scrollToKey","calcOffsetToViewport","offsetKey","offsetSum","innerWidth","offsetWidth","parent","body","html","getScrollbarSize","clientWidth","clientHeight","createWindowScroller","_$use","_$setStyleProperty","itemIndex","_$effect","_p$","_v$","_v$2","_v$3","t"],"mappings":"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"}