{"version":3,"file":"index.mjs","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/vue/ListItem.tsx","../../src/src/vue/utils.ts","../../src/src/vue/Virtualizer.tsx","../../src/src/vue/VList.tsx","../../src/src/vue/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 once = <V>(fn: () => V): (() => V) => {\n  let called: undefined | boolean;\n  let cache: V;\n\n  return () => {\n    if (!called) {\n      called = true;\n      cache = fn();\n    }\n    return cache;\n  };\n};\n","import { ItemSize, type InternalCacheSnapshot, type ItemsRange } from \"./types\";\nimport { clamp, floor, max, min, sort } from \"./utils\";\n\ntype Writeable<T> = {\n  -readonly [key in keyof T]: T[key] extends object ? Writeable<T[key]> : 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: ItemSize;\n  // offsets\n  readonly _computedOffsetIndex: number;\n  readonly _offsets: number[];\n};\n\n// TODO: this can be filled with precomputed size\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  if (size === UNCACHED) {\n    return typeof cache._defaultItemSize === 'function' ? cache._defaultItemSize(index) : cache._defaultItemSize;\n  }\n  return 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 computeOffset = (\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 * @internal\n */\nexport const computeTotalSize = (cache: Cache): number => {\n  if (!cache._length) return 0;\n  return (\n    computeOffset(cache, cache._length - 1) +\n    getItemSize(cache, cache._length - 1)\n  );\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    const itemOffset = computeOffset(cache, mid);\n    if (itemOffset <= offset) {\n      if (itemOffset + getItemSize(cache, mid) > 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  scrollOffset: number,\n  viewportSize: 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 (computeOffset(cache, prevStartIndex) <= scrollOffset) {\n    // search forward\n    // start <= end, prevStartIndex <= start\n    const end = findIndex(cache, scrollOffset + viewportSize, prevStartIndex);\n    return [findIndex(cache, scrollOffset, prevStartIndex, end), end];\n  } else {\n    // search backward\n    // start <= end, start <= prevStartIndex\n    const start = findIndex(cache, scrollOffset, undefined, prevStartIndex);\n    return [start, findIndex(cache, scrollOffset + viewportSize, 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  if (typeof cache._defaultItemSize === 'function') {\n    const length = max(startIndex - measuredCountBeforeStart, 0);\n    return Array.from({ length })\n      .map((_, ix) => ix + measuredCountBeforeStart)\n      .reduce((acc, i) => acc + (cache._defaultItemSize as Exclude<ItemSize, number>)(i), 0)\n  }\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: ItemSize,\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),\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 currentLength = cache._length;\n  const diff = length - currentLength;\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    if (typeof cache._defaultItemSize === 'function') {\n      return Array.from({ length: diff })\n        .map((_, ix) => isShift ? ix : ix + currentLength)\n        .reduce((acc, i) => acc + (cache._defaultItemSize as Exclude<ItemSize, number>)(i), 0)\n    }\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, ix) => {\n        if (removed !== UNCACHED) return acc - removed;\n        if (typeof cache._defaultItemSize === 'function') return acc - cache._defaultItemSize(isShift ? ix : diff + ix);\n        return acc - cache._defaultItemSize;\n      },\n      0\n    );\n  }\n};\n","import { once } from \"./utils\";\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  return /iP(hone|od|ad)/.test(navigator.userAgent);\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  computeTotalSize,\n  computeOffset as computeStartOffset,\n  UNCACHED,\n  setItemSize,\n  estimateDefaultItemSize,\n  updateCacheLength,\n  computeRange,\n  takeCacheSnapshot,\n  findIndex,\n} from \"./cache\";\nimport { isIOSWebKit } from \"./environment\";\nimport type {\n  CacheSnapshot,\n  InternalCacheSnapshot,\n  ItemResize,\n  ItemSize,\n  ItemsRange,\n} from \"./types\";\nimport { abs, max, min, NULL } from \"./utils\";\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\n/**\n * @internal\n */\nexport const isInitialMeasurementDone = (store: VirtualStore): boolean => {\n  return !!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  $getStateVersion(): StateVersion;\n  $getCacheSnapshot(): CacheSnapshot;\n  $getRange(): 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  _hasUnmeasuredItemsInFrozenRange(): boolean;\n};\n\n/**\n * @internal\n */\nexport const createVirtualStore = (\n  elementsCount: number,\n  itemSize: ItemSize = 40,\n  overscan: number = 4,\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 = isSSR\n    ? [0, max(ssrCount - 1, 0)]\n    : NULL;\n  let _prevRange: ItemsRange = [0, 0];\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 = (offset: number) => {\n    return computeRange(cache, offset, viewportSize, _prevRange[0]);\n  };\n  const getTotalSize = (): number => computeTotalSize(cache);\n  const getItemOffset = (index: number): number => {\n    return computeStartOffset(cache, index) - pendingJump;\n  };\n  const getItemSize = (index: number): number => {\n    return _getItemSize(cache, index);\n  };\n\n  const applyJump = (j: number) => {\n    if (j) {\n      // In iOS WebKit browsers, updating scroll position will stop scrolling so it have to be deferred during scrolling.\n      if (isIOSWebKit() && _scrollDirection !== SCROLL_IDLE) {\n        pendingJump += j;\n      } else {\n        jump += j;\n      }\n    }\n  };\n\n  return {\n    $getStateVersion: () => stateVersion,\n    $getCacheSnapshot: () => {\n      return takeCacheSnapshot(cache) as unknown as CacheSnapshot;\n    },\n    $getRange: () => {\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        [startIndex, endIndex] = _prevRange = getRange(\n          max(0, getVisibleOffset())\n        );\n        if (_frozenRange) {\n          startIndex = min(startIndex, _frozenRange[0]);\n          endIndex = max(endIndex, _frozenRange[1]);\n        }\n      }\n\n      if (_scrollDirection !== SCROLL_DOWN) {\n        startIndex -= max(0, overscan);\n      }\n      if (_scrollDirection !== SCROLL_UP) {\n        endIndex += max(0, overscan);\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: (index) => cache._sizes[index] === UNCACHED,\n    _hasUnmeasuredItemsInFrozenRange: () => {\n      if (!_frozenRange) return false;\n      return cache._sizes\n        .slice(\n          max(0, _frozenRange[0] - 1),\n          min(cache._length - 1, _frozenRange[1] + 1) + 1\n        )\n        .includes(UNCACHED);\n    },\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 [\n        _flushedJump,\n        // Use absolute position not to exceed scrollable bounds\n        _scrollMode === SCROLL_BY_SHIFT ||\n          // https://github.com/inokawa/virtua/discussions/475\n          getRelativeScrollOffset() + viewportSize >= getTotalSize(),\n      ];\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          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            _frozenRange = NULL;\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]) => cache._sizes[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\n                  ? // https://github.com/inokawa/virtua/issues/380\n                    // https://github.com/inokawa/virtua/issues/590\n                    !isSSR && index < _frozenRange[0]\n                  : // Otherwise we should maintain visible position\n                    getItemOffset(index) +\n                      // https://github.com/inokawa/virtua/issues/385\n                      (_scrollDirection === SCROLL_IDLE &&\n                      _scrollMode === SCROLL_BY_NATIVE\n                        ? getItemSize(index)\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            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);\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\";\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  isInitialMeasurementDone,\n} from \"./store\";\nimport { type ScrollToIndexOpts } from \"./types\";\nimport { clamp, microtask, NULL } from \"./utils\";\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\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 cancelScroll: (() => void) | undefined;\n  const scrollOffsetKey = isHorizontal ? \"scrollLeft\" : \"scrollTop\";\n  const overflowKey = isHorizontal ? \"overflowX\" : \"overflowY\";\n\n  // The given offset will be clamped by browser\n  // https://drafts.csswg.org/cssom-view/#dom-element-scrolltop\n  const scheduleImperativeScroll = async (\n    getTargetOffset: () => number,\n    smooth?: boolean\n  ) => {\n    if (!viewportElement) {\n      // Wait for element assign. The element may be undefined if scrollRef prop is used and scroll is scheduled on mount.\n      microtask(() => scheduleImperativeScroll(getTargetOffset, smooth));\n      return;\n    }\n\n    if (cancelScroll) {\n      // Cancel waiting scrollTo\n      cancelScroll();\n    }\n\n    const waitForMeasurement = (): [Promise<void>, () => 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      let queue: (() => void) | undefined;\n      return [\n        new Promise<void>((resolve, reject) => {\n          queue = resolve;\n          cancelScroll = reject;\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 (isInitialMeasurementDone(store)) {\n            // Reject when items around scroll destination completely measured\n            timeout(reject, 150);\n          }\n        }),\n        store.$subscribe(UPDATE_SIZE_EVENT, () => {\n          queue && queue();\n        }),\n      ];\n    };\n\n    if (smooth && isSmoothScrollSupported()) {\n      while (true) {\n        store.$update(ACTION_BEFORE_MANUAL_SMOOTH_SCROLL, getTargetOffset());\n\n        if (!store._hasUnmeasuredItemsInFrozenRange()) {\n          break;\n        }\n\n        const [promise, unsubscribe] = waitForMeasurement();\n\n        try {\n          await promise;\n        } catch (e) {\n          // canceled\n          return;\n        } finally {\n          unsubscribe();\n        }\n      }\n\n      viewportElement.scrollTo({\n        [isHorizontal ? \"left\" : \"top\"]: normalizeOffset(\n          getTargetOffset(),\n          isHorizontal\n        ),\n        behavior: \"smooth\",\n      });\n    } else {\n      while (true) {\n        const [promise, unsubscribe] = waitForMeasurement();\n\n        try {\n          viewportElement[scrollOffsetKey] = normalizeOffset(\n            getTargetOffset(),\n            isHorizontal\n          );\n          store.$update(ACTION_MANUAL_SCROLL);\n\n          await promise;\n        } catch (e) {\n          // canceled or finished\n          return;\n        } finally {\n          unsubscribe();\n        }\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          if (shift) {\n            viewport[scrollOffsetKey] = store.$getScrollOffset() + jump;\n            // https://github.com/inokawa/virtua/issues/357\n            cancelScroll && cancelScroll();\n          } else {\n            viewport[scrollOffsetKey] += jump;\n          }\n        }\n      );\n    },\n    $dispose() {\n      scrollObserver && scrollObserver._dispose();\n    },\n    $scrollTo(offset) {\n      scheduleImperativeScroll(() => offset);\n    },\n    $scrollBy(offset) {\n      offset += store.$getScrollOffset();\n      scheduleImperativeScroll(() => 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      scheduleImperativeScroll(() => {\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 cancelScroll: (() => void) | undefined;\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  const scheduleImperativeScroll = async (\n    getTargetOffset: () => number,\n    smooth?: boolean\n  ) => {\n    if (!containerElement) {\n      // Wait for element assign\n      microtask(() => scheduleImperativeScroll(getTargetOffset, smooth));\n      return;\n    }\n\n    if (cancelScroll) {\n      cancelScroll();\n    }\n\n    const waitForMeasurement = (): [Promise<void>, () => void] => {\n      let queue: (() => void) | undefined;\n      return [\n        new Promise<void>((resolve, reject) => {\n          queue = resolve;\n          cancelScroll = reject;\n\n          if (isInitialMeasurementDone(store)) {\n            timeout(reject, 150);\n          }\n        }),\n        store.$subscribe(UPDATE_SIZE_EVENT, () => {\n          queue && queue();\n        }),\n      ];\n    };\n\n    const window = getCurrentWindow(getCurrentDocument(containerElement));\n\n    if (smooth && isSmoothScrollSupported()) {\n      while (true) {\n        store.$update(ACTION_BEFORE_MANUAL_SMOOTH_SCROLL, getTargetOffset());\n\n        if (!store._hasUnmeasuredItemsInFrozenRange()) {\n          break;\n        }\n\n        const [promise, unsubscribe] = waitForMeasurement();\n\n        try {\n          await promise;\n        } catch (e) {\n          return;\n        } finally {\n          unsubscribe();\n        }\n      }\n\n      window.scroll({\n        [isHorizontal ? \"left\" : \"top\"]: normalizeOffset(\n          getTargetOffset(),\n          isHorizontal\n        ),\n        behavior: \"smooth\",\n      });\n    } else {\n      while (true) {\n        const [promise, unsubscribe] = waitForMeasurement();\n\n        try {\n          window.scroll({\n            [isHorizontal ? \"left\" : \"top\"]: normalizeOffset(\n              getTargetOffset(),\n              isHorizontal\n            ),\n          });\n          store.$update(ACTION_MANUAL_SCROLL);\n\n          await promise;\n        } catch (e) {\n          return;\n        } finally {\n          unsubscribe();\n        }\n      }\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      const documentBody = document.body;\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            window.scroll({\n              [isHorizontal ? \"left\" : \"top\"]: store.$getScrollOffset() + jump,\n            });\n          } else {\n            window.scrollBy(isHorizontal ? jump : 0, isHorizontal ? 0 : jump);\n          }\n        },\n        () =>\n          calcOffsetToViewport(container, documentBody, window, isHorizontal)\n      );\n    },\n    $dispose() {\n      scrollObserver && scrollObserver._dispose();\n      containerElement = undefined;\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      scheduleImperativeScroll(() => {\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  vStore: VirtualStore,\n  hStore: VirtualStore\n): GridScroller => {\n  const vScroller = createScroller(vStore, false);\n  const hScroller = createScroller(hStore, 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\";\nimport {\n  ACTION_ITEM_RESIZE,\n  ACTION_VIEWPORT_RESIZE,\n  type VirtualStore,\n} from \"./store\";\nimport { type ItemResize } from \"./types\";\nimport { max, NULL } from \"./utils\";\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      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  vStore: VirtualStore,\n  hStore: VirtualStore\n) => {\n  let viewportElement: HTMLElement | undefined;\n\n  const heightKey = \"height\";\n  const widthKey = \"width\";\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 { 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        vStore.$update(ACTION_VIEWPORT_RESIZE, contentRect[heightKey]);\n        hStore.$update(ACTION_VIEWPORT_RESIZE, contentRect[widthKey]);\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          const size: CellSize = [\n            contentRect[heightKey],\n            contentRect[widthKey],\n          ];\n          let rowResized: boolean | undefined;\n          let colResized: boolean | undefined;\n          if (!prevSize) {\n            rowResized = colResized = true;\n          } else {\n            if (prevSize[0] !== size[0]) {\n              rowResized = true;\n            }\n            if (prevSize[1] !== size[1]) {\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, size);\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      vStore.$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      hStore.$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    $dispose: resizeObserver._dispose,\n  };\n};\n\n/**\n * @internal\n */\nexport type GridResizer = ReturnType<typeof createGridResizer>;\n","/** @jsxImportSource vue */\nimport {\n  ref,\n  defineComponent,\n  watch,\n  StyleValue,\n  PropType,\n  VNode,\n  NativeElements,\n  computed,\n  Ref,\n} from \"vue\";\nimport {\n  ItemResizeObserver,\n  isRTLDocument,\n  StateVersion,\n  VirtualStore,\n} from \"../core\";\nimport { ItemProps } from \"./utils\";\n\n/**\n * @internal\n */\nexport const ListItem = /*#__PURE__*/ defineComponent({\n  props: {\n    _stateVersion: {\n      type: Object as PropType<Ref<StateVersion>>,\n      required: true,\n    },\n    _store: { type: Object as PropType<VirtualStore>, required: true },\n    _children: { type: Object as PropType<VNode>, required: true },\n    _resizer: {\n      type: Function as PropType<ItemResizeObserver>,\n      required: true,\n    },\n    _index: { type: Number, required: true },\n    _isHorizontal: { type: Boolean },\n    _isSSR: { type: Boolean },\n    _as: { type: String as PropType<keyof NativeElements>, required: true },\n    _itemProps: Object as PropType<ReturnType<ItemProps>>,\n  },\n  setup(props) {\n    const elementRef = ref<HTMLDivElement>();\n\n    const offset = computed(\n      () =>\n        props._stateVersion.value && props._store.$getItemOffset(props._index)\n    );\n    const hide = computed(\n      () =>\n        props._stateVersion.value &&\n        props._store.$isUnmeasuredItem(props._index)\n    );\n\n    // The index may be changed if elements are inserted to or removed from the start of props.children\n    watch(\n      () => elementRef.value && props._index,\n      (_, __, onCleanup) => {\n        onCleanup(props._resizer(elementRef.value!, props._index));\n      },\n      {\n        flush: \"post\",\n      }\n    );\n\n    return () => {\n      const {\n        _children: children,\n        _isHorizontal: isHorizontal,\n        _isSSR: isSSR,\n        _as: Element,\n      } = props;\n      const isHide = hide.value;\n\n      const { style: styleProp, ...rest } = props._itemProps ?? {};\n\n      const style: StyleValue = {\n        position: isHide && isSSR ? undefined : \"absolute\",\n        [isHorizontal ? \"height\" : \"width\"]: \"100%\",\n        [isHorizontal ? \"top\" : \"left\"]: \"0px\",\n        [isHorizontal ? (isRTLDocument() ? \"right\" : \"left\") : \"top\"]:\n          offset.value + \"px\",\n        visibility: !isHide || isSSR ? \"visible\" : \"hidden\",\n        ...styleProp,\n      };\n      if (isHorizontal) {\n        style.display = \"flex\";\n      }\n\n      return (\n        <Element ref={elementRef} style={style} {...rest}>\n          {children}\n        </Element>\n      );\n    };\n  },\n});\n","import { CSSProperties, VNode } from \"vue\";\nimport { ItemsRange } from \"../core\";\n\n/**\n * @internal\n */\nexport const getKey = (e: VNode, i: number): Exclude<VNode[\"key\"], null> => {\n  const key = e.key;\n  return key != null ? key : \"_\" + i;\n};\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\nexport type ItemProps = (payload: {\n  item: any;\n  index: number;\n}) => { [key: string]: any; style?: CSSProperties; class?: string } | undefined;\n","/** @jsxImportSource vue */\nimport {\n  ref,\n  onMounted,\n  defineComponent,\n  onUnmounted,\n  VNode,\n  watch,\n  ComponentOptionsMixin,\n  SlotsType,\n  ComponentOptionsWithObjectProps,\n  ComponentObjectPropsOptions,\n  PropType,\n  NativeElements,\n  computed,\n} from \"vue\";\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  microtask,\n  sort,\n} from \"../core\";\nimport { ListItem } from \"./ListItem\";\nimport { getKey, isSameRange, ItemProps } from \"./utils\";\n\nexport interface VirtualizerHandle {\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\nconst props = {\n  /**\n   * The data items rendered by this component.\n   */\n  data: { type: Array, required: true },\n  /**\n   * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.\n   * @defaultValue 4\n   */\n  overscan: Number,\n  /**\n   * Item size hint for unmeasured items. 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   * If you put an element before virtualizer, you have to define its height with this prop.\n   */\n  startMargin: { type: Number, default: 0 },\n  /**\n   * A prop for SSR. If set, the specified amount of items will be mounted in the initial rendering regardless of the container size until hydrated.\n   */\n  ssrCount: Number,\n  /**\n   * Reference to the scrollable element. The default will get the direct parent element of virtualizer.\n   */\n  scrollRef: Object as PropType<HTMLElement>,\n  /**\n   * Component or element type for container element.\n   * @defaultValue \"div\"\n   */\n  as: { type: String as PropType<keyof NativeElements>, default: \"div\" },\n  /**\n   * Component or element type for item element.\n   * @defaultValue \"div\"\n   */\n  item: { type: String as PropType<keyof NativeElements>, default: \"div\" },\n  /**\n   * A function that provides properties/attributes for item element\n   *\n   * **This prop will be merged into `item` prop in the future**\n   */\n  itemProps: Function as PropType<ItemProps>,\n  /**\n   * List of indexes that should be always mounted, even when off screen.\n   */\n  keepMounted: Array as PropType<number[]>,\n} satisfies ComponentObjectPropsOptions;\n\nexport const Virtualizer = /*#__PURE__*/ defineComponent({\n  props: props,\n  emits: [\"scroll\", \"scrollEnd\"],\n  setup(props, { emit, expose, slots }) {\n    let isSSR = !!props.ssrCount;\n\n    const isHorizontal = props.horizontal;\n    const containerRef = ref<HTMLDivElement>();\n    const store = createVirtualStore(\n      props.data.length,\n      props.itemSize,\n      props.overscan,\n      props.ssrCount,\n      undefined,\n      !props.itemSize\n    );\n    const resizer = createResizer(store, isHorizontal);\n    const scroller = createScroller(store, isHorizontal);\n\n    const stateVersion = ref(store.$getStateVersion());\n    const unsubscribeStore = store.$subscribe(UPDATE_VIRTUAL_STATE, () => {\n      stateVersion.value = store.$getStateVersion();\n    });\n\n    const unsubscribeOnScroll = store.$subscribe(UPDATE_SCROLL_EVENT, () => {\n      emit(\"scroll\", store.$getScrollOffset());\n    });\n    const unsubscribeOnScrollEnd = store.$subscribe(\n      UPDATE_SCROLL_END_EVENT,\n      () => {\n        emit(\"scrollEnd\");\n      }\n    );\n\n    const range = computed<ItemsRange>((prev) => {\n      stateVersion.value;\n      const next = store.$getRange();\n      if (prev && isSameRange(prev, next)) {\n        return prev;\n      }\n      return next;\n    });\n    const isScrolling = computed(\n      () => stateVersion.value && store.$isScrolling()\n    );\n    const totalSize = computed(\n      () => stateVersion.value && store.$getTotalSize()\n    );\n\n    onMounted(() => {\n      isSSR = false;\n\n      microtask(() => {\n        const assignScrollableElement = (e: HTMLElement) => {\n          resizer.$observeRoot(e);\n          scroller.$observe(e);\n        };\n        if (props.scrollRef) {\n          // parent's ref doesn't exist when onMounted is called\n          assignScrollableElement(props.scrollRef!);\n        } else {\n          assignScrollableElement(containerRef.value!.parentElement!);\n        }\n      });\n    });\n    onUnmounted(() => {\n      unsubscribeStore();\n      unsubscribeOnScroll();\n      unsubscribeOnScrollEnd();\n      resizer.$dispose();\n      scroller.$dispose();\n    });\n\n    watch(\n      () => props.data.length,\n      (count) => {\n        store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);\n      }\n    );\n    watch(\n      () => props.startMargin,\n      (value) => {\n        store.$update(ACTION_START_OFFSET_CHANGE, value);\n      },\n      { immediate: true }\n    );\n\n    watch(\n      [stateVersion],\n      () => {\n        scroller.$fixScrollJump();\n      },\n      { flush: \"post\" }\n    );\n\n    expose({\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    } satisfies VirtualizerHandle);\n\n    return () => {\n      const Element = props.as;\n      const ItemElement = props.item;\n\n      const [startIndex, endIndex] = range.value;\n      const total = totalSize.value;\n\n      const items: VNode[] = [];\n\n      function getListItem(i: number) {\n        const e = slots.default({ item: props.data![i]!, index: i })[0]!;\n        return (\n          <ListItem\n            key={getKey(e, i)}\n            _stateVersion={stateVersion}\n            _store={store}\n            _resizer={resizer.$observeItem}\n            _index={i}\n            _children={e}\n            _isHorizontal={isHorizontal}\n            _isSSR={isSSR}\n            _as={ItemElement}\n            _itemProps={props.itemProps?.({ item: props.data![i]!, index: i })}\n          />\n        );\n      }\n      for (let i = startIndex, j = endIndex; i <= j; i++) {\n        items.push(getListItem(i));\n      }\n\n      if (props.keepMounted) {\n        const startItems: VNode[] = [];\n        const endItems: VNode[] = [];\n        sort(props.keepMounted).forEach((index) => {\n          if (index < startIndex) {\n            startItems.push(getListItem(index));\n          }\n          if (index > endIndex) {\n            endItems.push(getListItem(index));\n          }\n        });\n\n        items.unshift(...startItems);\n        items.push(...endItems);\n      }\n\n      return (\n        <Element\n          ref={containerRef}\n          style={{\n            // contain: \"content\",\n            overflowAnchor: \"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            visibility: \"hidden\", // TODO replace with other optimization methods\n            width: isHorizontal ? total + \"px\" : \"100%\",\n            height: isHorizontal ? \"100%\" : total + \"px\",\n            pointerEvents: isScrolling.value ? \"none\" : undefined,\n          }}\n        >\n          {items}\n        </Element>\n      );\n    };\n  },\n} as ComponentOptionsWithObjectProps<\n  typeof props,\n  VirtualizerHandle,\n  {},\n  {},\n  {},\n  ComponentOptionsMixin,\n  ComponentOptionsMixin,\n  {\n    /**\n     * Callback invoked whenever scroll offset changes.\n     * @param offset Current scrollTop, or scrollLeft if horizontal: true.\n     */\n    scroll: (offset: number) => void;\n    /**\n     * Callback invoked when scrolling stops.\n     */\n    scrollEnd: () => void;\n  },\n  string,\n  {},\n  string,\n  SlotsType<{ default: (arg: { item: any; index: number }) => VNode[] }>\n>);\n","/** @jsxImportSource vue */\nimport {\n  defineComponent,\n  ComponentOptionsMixin,\n  SlotsType,\n  ComponentOptionsWithObjectProps,\n  ComponentObjectPropsOptions,\n  ref,\n  VNode,\n  PropType,\n} from \"vue\";\nimport { Virtualizer, VirtualizerHandle } from \"./Virtualizer\";\nimport { ItemProps } from \"./utils\";\n\ninterface VListHandle extends VirtualizerHandle {}\n\nconst props = {\n  /**\n   * The data items rendered by this component.\n   */\n  data: { type: Array, required: true },\n  /**\n   * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.\n   * @defaultValue 4\n   */\n  overscan: Number,\n  /**\n   * Item size hint for unmeasured items. 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   * A prop for SSR. If set, the specified amount of items will be mounted in the initial rendering regardless of the container size until hydrated.\n   */\n  ssrCount: Number,\n  /**\n   * A function that provides properties/attributes for item element\n   *\n   * **This prop will be merged into `item` prop in the future**\n   */\n  itemProps: Function as PropType<ItemProps>,\n  /**\n   * List of indexes that should be always mounted, even when off screen.\n   */\n  keepMounted: Array as PropType<number[]>,\n} satisfies ComponentObjectPropsOptions;\n\nexport const VList = /*#__PURE__*/ defineComponent({\n  props: props,\n  emits: [\"scroll\", \"scrollEnd\"],\n  setup(props, { emit, expose, slots }) {\n    const horizontal = props.horizontal;\n\n    const onScroll = (offset: number) => {\n      emit(\"scroll\", offset);\n    };\n    const onScrollEnd = () => {\n      emit(\"scrollEnd\");\n    };\n\n    const handle = ref<InstanceType<typeof Virtualizer>>();\n\n    expose({\n      get scrollOffset() {\n        return handle.value!.scrollOffset;\n      },\n      get scrollSize() {\n        return handle.value!.scrollSize;\n      },\n      get viewportSize() {\n        return handle.value!.viewportSize;\n      },\n      findStartIndex: (...args) => handle.value!.findStartIndex(...args),\n      findEndIndex: (...args) => handle.value!.findEndIndex(...args),\n      getItemOffset: (...args) => handle.value!.getItemOffset(...args),\n      getItemSize: (...args) => handle.value!.getItemSize(...args),\n      scrollToIndex: (...args) => handle.value!.scrollToIndex(...args),\n      scrollTo: (...args) => handle.value!.scrollTo(...args),\n      scrollBy: (...args) => handle.value!.scrollBy(...args),\n    } satisfies VListHandle);\n\n    return () => {\n      return (\n        <div\n          style={{\n            display: horizontal ? \"inline-block\" : \"block\",\n            [horizontal ? \"overflowX\" : \"overflowY\"]: \"auto\",\n            contain: \"strict\",\n            width: \"100%\",\n            height: \"100%\",\n          }}\n        >\n          <Virtualizer\n            ref={handle}\n            data={props.data}\n            overscan={props.overscan}\n            itemSize={props.itemSize}\n            itemProps={props.itemProps}\n            shift={props.shift}\n            ssrCount={props.ssrCount}\n            horizontal={horizontal}\n            keepMounted={props.keepMounted}\n            onScroll={onScroll}\n            onScrollEnd={onScrollEnd}\n          >\n            {slots}\n          </Virtualizer>\n        </div>\n      );\n    };\n  },\n} as ComponentOptionsWithObjectProps<\n  typeof props,\n  VListHandle,\n  {},\n  {},\n  {},\n  ComponentOptionsMixin,\n  ComponentOptionsMixin,\n  {\n    /**\n     * Callback invoked whenever scroll offset changes.\n     * @param offset Current scrollTop, or scrollLeft if horizontal: true.\n     */\n    scroll: (offset: number) => void;\n    /**\n     * Callback invoked when scrolling stops.\n     */\n    scrollEnd: () => void;\n  },\n  string,\n  {},\n  string,\n  SlotsType<{ default: (arg: { item: any; index: number }) => VNode[] }>\n>);\n","/** @jsxImportSource vue */\nimport {\n  ref,\n  onMounted,\n  defineComponent,\n  onUnmounted,\n  VNode,\n  watch,\n  ComponentOptionsMixin,\n  SlotsType,\n  ComponentOptionsWithObjectProps,\n  ComponentObjectPropsOptions,\n  PropType,\n  NativeElements,\n  computed,\n} from \"vue\";\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} from \"../core\";\nimport { ListItem } from \"./ListItem\";\nimport { getKey, isSameRange } from \"./utils\";\n\nexport interface WindowVirtualizerHandle {\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\nconst props = {\n  /**\n   * The data items rendered by this component.\n   */\n  data: { type: Array, required: true },\n  /**\n   * Number of items to render above/below the visible bounds of the list. You can increase to avoid showing blank items in fast scrolling.\n   * @defaultValue 4\n   */\n  overscan: Number,\n  /**\n   * Item size hint for unmeasured items. 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   * Component or element type for container element.\n   * @defaultValue \"div\"\n   */\n  as: { type: String as PropType<keyof NativeElements>, default: \"div\" },\n  /**\n   * Component or element type for item element.\n   * @defaultValue \"div\"\n   */\n  item: { type: String as PropType<keyof NativeElements>, default: \"div\" },\n} satisfies ComponentObjectPropsOptions;\n\nexport const WindowVirtualizer = /*#__PURE__*/ defineComponent({\n  props,\n  emits: [\"scroll\", \"scrollEnd\"],\n  setup(props, { emit, slots, expose }) {\n    const isHorizontal = props.horizontal;\n    const containerRef = ref<HTMLDivElement>();\n    const store = createVirtualStore(\n      props.data.length,\n      props.itemSize,\n      props.overscan,\n      undefined,\n      undefined,\n      !props.itemSize\n    );\n    const resizer = createWindowResizer(store, isHorizontal);\n    const scroller = createWindowScroller(store, isHorizontal);\n\n    const stateVersion = ref(store.$getStateVersion());\n    const unsubscribeStore = store.$subscribe(UPDATE_VIRTUAL_STATE, () => {\n      stateVersion.value = store.$getStateVersion();\n    });\n\n    const unsubscribeOnScroll = store.$subscribe(UPDATE_SCROLL_EVENT, () => {\n      // https://github.com/inokawa/virtua/discussions/580\n      emit(\"scroll\");\n    });\n    const unsubscribeOnScrollEnd = store.$subscribe(\n      UPDATE_SCROLL_END_EVENT,\n      () => {\n        emit(\"scrollEnd\");\n      }\n    );\n\n    const range = computed<ItemsRange>((prev) => {\n      stateVersion.value;\n      const next = store.$getRange();\n      if (prev && isSameRange(prev, next)) {\n        return prev;\n      }\n      return next;\n    });\n    const isScrolling = computed(\n      () => stateVersion.value && store.$isScrolling()\n    );\n    const totalSize = computed(\n      () => stateVersion.value && store.$getTotalSize()\n    );\n\n    onMounted(() => {\n      const el = containerRef.value;\n      if (!el) return;\n      resizer.$observeRoot(el);\n      scroller.$observe(el);\n    });\n    onUnmounted(() => {\n      unsubscribeStore();\n      unsubscribeOnScroll();\n      unsubscribeOnScrollEnd();\n      resizer.$dispose();\n      scroller.$dispose();\n    });\n\n    watch(\n      () => props.data.length,\n      (count) => {\n        store.$update(ACTION_ITEMS_LENGTH_CHANGE, [count, props.shift]);\n      }\n    );\n\n    watch(\n      [stateVersion],\n      () => {\n        scroller.$fixScrollJump();\n      },\n      { flush: \"post\" }\n    );\n\n    expose({\n      findStartIndex: store.$findStartIndex,\n      findEndIndex: store.$findEndIndex,\n      scrollToIndex: scroller.$scrollToIndex,\n    } satisfies WindowVirtualizerHandle);\n\n    return () => {\n      const Element = props.as;\n      const ItemElement = props.item;\n\n      const [startIndex, endIndex] = range.value;\n      const total = totalSize.value;\n\n      const items: VNode[] = [];\n      for (let i = startIndex, j = endIndex; i <= j; i++) {\n        const e = slots.default({ item: props.data![i]!, index: i })[0]!;\n        items.push(\n          <ListItem\n            key={getKey(e, i)}\n            _stateVersion={stateVersion}\n            _store={store}\n            _resizer={resizer.$observeItem}\n            _index={i}\n            _children={e}\n            _isHorizontal={isHorizontal}\n            _as={ItemElement}\n          />\n        );\n      }\n\n      return (\n        <Element\n          ref={containerRef}\n          style={{\n            // contain: \"content\",\n            overflowAnchor: \"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            visibility: \"hidden\", // TODO replace with other optimization methods\n            width: isHorizontal ? total + \"px\" : \"100%\",\n            height: isHorizontal ? \"100%\" : total + \"px\",\n            pointerEvents: isScrolling.value ? \"none\" : undefined,\n          }}\n        >\n          {items}\n        </Element>\n      );\n    };\n  },\n} as ComponentOptionsWithObjectProps<\n  typeof props,\n  void,\n  {},\n  {},\n  {},\n  ComponentOptionsMixin,\n  ComponentOptionsMixin,\n  {\n    /**\n     * Callback invoked whenever scroll offset changes.\n     */\n    scroll: () => void;\n    /**\n     * Callback invoked when scrolling stops.\n     */\n    scrollEnd: () => void;\n  },\n  string,\n  {},\n  string,\n  SlotsType<{ default: (arg: { item: any; index: number }) => VNode[] }>\n>);\n"],"names":["NULL","min","max","abs","floor","Math","clamp","value","minValue","maxValue","sort","arr","a","b","microtask","queueMicrotask","fn","Promise","resolve","then","once","called","cache","UNCACHED","fill","array","length","prepend","key","i","getItemSize","index","size","_sizes","_defaultItemSize","setItemSize","isInitialMeasurement","_computedOffsetIndex","computeOffset","_length","_offsets","top","findIndex","offset","low","high","mid","itemOffset","updateCacheLength","isShift","currentLength","diff","Array","from","map","_","ix","reduce","acc","splice","removed","isBrowser","window","getDocumentElement","document","documentElement","getCurrentDocument","node","ownerDocument","getCurrentWindow","doc","defaultView","isRTLDocument","getComputedStyle","direction","isIOSWebKit","test","navigator","userAgent","isSmoothScrollSupported","style","isInitialMeasurementDone","store","$getViewportSize","createVirtualStore","elementsCount","itemSize","overscan","ssrCount","cacheSnapshot","shouldAutoEstimateItemSize","isSSR","stateVersion","viewportSize","startSpacerSize","scrollOffset","jump","pendingJump","_flushedJump","_scrollDirection","_scrollMode","_frozenRange","_prevRange","_totalMeasuredSize","initCache","subscribers","Set","getRelativeScrollOffset","getVisibleOffset","getRange","computeRange","prevStartIndex","end","start","undefined","getTotalSize","computeTotalSize","getItemOffset","computeStartOffset","_getItemSize","applyJump","j","$getStateVersion","$getCacheSnapshot","slice","takeCacheSnapshot","$getRange","startIndex","endIndex","$findStartIndex","$findEndIndex","$isUnmeasuredItem","_hasUnmeasuredItemsInFrozenRange","includes","$getItemOffset","$getItemSize","$getItemsLength","$getScrollOffset","$isScrolling","$getStartSpacerSize","$getTotalSize","_flushJump","$subscribe","target","cb","sub","add","delete","$update","type","payload","shouldFlushPendingJump","shouldSync","mutated","flushedJump","delta","distance","relativeOffset","updated","filter","prevSize","estimateDefaultItemSize","measuredCountBeforeStart","measuredSizes","forEach","s","push","sorted","len","median","prevDefaultItemSize","UPDATE_VIRTUAL_STATE","timeout","setTimeout","normalizeOffset","isHorizontal","createScrollObserver","viewport","getScrollOffset","updateScrollOffset","getStartOffset","now","Date","lastScrollTime","wheeling","touching","justTouchEnded","stillMomentumScrolling","onScrollEnd","debounce","id","cancel","clearTimeout","debouncedFn","_cancel","onScroll","onWheel","e","ctrlKey","timeDelta","deltaX","deltaY","onTouchStart","onTouchEnd","addEventListener","passive","_dispose","removeEventListener","_fixScrollJump","shift","createResizeObserver","ro","_observe","observe","_unobserve","unobserve","disconnect","ListItem","defineComponent","props","_stateVersion","Object","required","_store","_children","_resizer","Function","_index","Number","_isHorizontal","Boolean","_isSSR","_as","String","_itemProps","setup","elementRef","ref","computed","hide","watch","__","onCleanup","flush","children","Element","isHide","styleProp","rest","_a","position","visibility","display","_createVNode","_mergeProps","_isVNode","prototype","toString","call","default","getKey","isSameRange","prev","next","Virtualizer","data","horizontal","startMargin","scrollRef","as","item","itemProps","keepMounted","emits","emit","expose","slots","containerRef","resizer","createResizer","viewportElement","sizeKey","mountedIndexes","WeakMap","resizeObserver","entries","resizes","contentRect","offsetParent","get","$observeRoot","$observeItem","el","set","$dispose","scroller","createScroller","scrollObserver","cancelScroll","scrollOffsetKey","overflowKey","scheduleImperativeScroll","async","getTargetOffset","smooth","waitForMeasurement","queue","reject","promise","unsubscribe","scrollTo","behavior","$observe","isMomentumScrolling","$scrollTo","$scrollBy","$scrollToIndex","align","$fixScrollJump","unsubscribeStore","unsubscribeOnScroll","unsubscribeOnScrollEnd","range","isScrolling","totalSize","onMounted","assignScrollableElement","parentElement","onUnmounted","count","immediate","scrollSize","getScrollSize","findStartIndex","findEndIndex","scrollToIndex","scrollBy","ItemElement","total","items","getListItem","W","X","U","D","Y","G","K","Z","ee","startItems","endItems","unshift","overflowAnchor","flex","width","height","pointerEvents","VList","handle","args","contain","WindowVirtualizer","createWindowResizer","windowSizeKey","cleanupOnWindowResize","container","onWindowResize","createWindowScroller","containerElement","calcOffsetToViewport","offsetKey","offsetSum","innerWidth","offsetWidth","parent","scroll","documentBody","body","html","getScrollbarSize","clientWidth","clientHeight"],"mappings":"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"}