{"version":3,"file":"pack-lanes.cjs","sources":["../../../../components/data-view/utils/pack-lanes.tsx"],"sourcesContent":["import { EMPTY_BUCKET_KEY, orderBucketKeys } from './order-bucket-keys';\nimport { orderByX } from './order-by-x';\n\nexport interface PackLaneItem {\n  /** Left edge in px (time-scale space). */\n  x: number;\n  /** Rendered width in px. */\n  width: number;\n}\n\nexport interface PackLanesResult {\n  /** Lane index per input item, in the input's original order. */\n  lanes: number[];\n  laneCount: number;\n}\n\n/**\n * Horizontal gap between cards sharing a lane. Not the vertical gap between\n * lanes — that's the `laneGap` prop (default 16) applied in timeline.tsx.\n */\nconst DEFAULT_CARD_GAP_PX = 8;\n\n/**\n * Below this, scanning `laneEnds` linearly beats the sweep's typed-array\n * setup — the scan is only quadratic once both the item count and the lane\n * count are large.\n */\nconst SWEEP_MIN_ITEMS = 64;\n\n/**\n * Greedy interval scheduling. Items are visited in ascending `x` order and\n * each is dropped into the first lane whose last occupant ends at least\n * `gapPx` before the item starts; a new lane is opened when none fits.\n * Produces the dense \"packed\" layout of the timeline design — many\n * non-overlapping cards share a lane.\n *\n * Two implementations, identical output: a direct scan for small inputs, and\n * an O(n) sweep once the input is large enough for the scan's O(items × lanes)\n * to bite (10k mutually overlapping cards is ~10^7 comparisons).\n */\nexport function packLanes(\n  items: PackLaneItem[],\n  gapPx: number = DEFAULT_CARD_GAP_PX\n): PackLanesResult {\n  const order = orderByX(items);\n  return items.length < SWEEP_MIN_ITEMS\n    ? packByScan(items, gapPx, order)\n    : packBySweep(items, gapPx, order);\n}\n\n/** An item plus the sort-value lane bucket it belongs to. `null` = no value. */\nexport interface PackSortValueLaneItem extends PackLaneItem {\n  laneKey: string | null;\n}\n\n/**\n * Lane per distinct `laneKey`, packed by time within each: rows sharing a value\n * share a lane, and a value only takes extra (sub-)lanes when two of its own\n * cards overlap in time. Backs `lanePacking=\"one-per-sort-value\"`.\n *\n * Buckets come out in first-seen order, with the no-value bucket last. Lane\n * order is therefore the caller's row order — the timeline hands over the sorted\n * row model, so lanes follow the active sort and nothing else. That's\n * deliberately *not* `groupData`'s rule, which ranks sections by the field's\n * declared `groupOrder`: a field that is both grouped and sorted can order its\n * sections and its lanes differently, and the sort is what the mode promises.\n * Only the no-value-bucket-last half is shared (see `orderBucketKeys`).\n *\n * Within a bucket the greedy first-fit of `packLanes` decides sub-lanes, so a\n * value with no overlapping cards occupies exactly one lane.\n */\nexport function packLanesBySortValue(\n  items: PackSortValueLaneItem[],\n  gapPx: number = DEFAULT_CARD_GAP_PX\n): PackLanesResult {\n  if (items.length === 0) return { lanes: [], laneCount: 0 };\n  const lanes = new Array<number>(items.length).fill(0);\n\n  // Indices per bucket, in input order — Map insertion order is the first-seen\n  // (caller-sorted) order `orderBucketKeys` preserves.\n  const buckets = new Map<string, number[]>();\n  for (let index = 0; index < items.length; index++) {\n    const key = items[index].laneKey ?? EMPTY_BUCKET_KEY;\n    let bucket = buckets.get(key);\n    if (!bucket) {\n      bucket = [];\n      buckets.set(key, bucket);\n    }\n    bucket.push(index);\n  }\n\n  let laneCount = 0;\n  for (const key of orderBucketKeys([...buckets.keys()])) {\n    const bucket = buckets.get(key) as number[];\n    // A bucket of one can't collide with itself, so skip the pack — `orderByX`\n    // is a sort plus two typed arrays, and a high-cardinality sort field (which\n    // the Ordering control lets a user pick at runtime) makes that most buckets.\n    if (bucket.length === 1) {\n      lanes[bucket[0]] = laneCount++;\n      continue;\n    }\n    // Packing runs on the bucket alone, so lanes are bucket-relative and shift\n    // up by the lanes every earlier bucket already claimed.\n    const packed = packLanes(\n      bucket.map(index => ({ x: items[index].x, width: items[index].width })),\n      gapPx\n    );\n    for (let i = 0; i < bucket.length; i++) {\n      lanes[bucket[i]] = laneCount + packed.lanes[i];\n    }\n    laneCount += packed.laneCount;\n  }\n\n  return { lanes, laneCount };\n}\n\n/** First-fit by scanning every lane end — O(items × lanes). */\nfunction packByScan(\n  items: PackLaneItem[],\n  gapPx: number,\n  order: Int32Array\n): PackLanesResult {\n  const laneEnds: number[] = [];\n  const lanes = new Array<number>(items.length).fill(0);\n  for (const index of order) {\n    const item = items[index];\n    let lane = laneEnds.findIndex(end => end + gapPx <= item.x);\n    if (lane === -1) {\n      lane = laneEnds.length;\n      laneEnds.push(0);\n    }\n    laneEnds[lane] = item.x + item.width;\n    lanes[index] = lane;\n  }\n  return { lanes, laneCount: laneEnds.length };\n}\n\n/**\n * First-fit as a left-to-right sweep — same assignment as `packByScan`, in\n * O(n) rather than O(items × lanes).\n *\n * Two structures replace the linear `findIndex`:\n *\n * - A **free-lane bitmap** (words plus a summary word per 32 words) answers\n *   \"smallest free lane\" in a couple of `Math.clz32` calls. Smallest-free-id\n *   is exactly what first-fit picks, so lane assignment is unchanged.\n * - A **bucket queue** releases lanes as the sweep passes them. Lanes are\n *   filed under the column their occupant frees up in; because the sweep\n *   advances monotonically in x, columns strictly behind the current one\n *   release wholesale, and only the current column needs an exact per-lane\n *   check. That is Dial's monotone priority queue: O(1) amortized per\n *   insert/extract, versus O(log lanes) for a heap.\n */\nfunction packBySweep(\n  items: PackLaneItem[],\n  gapPx: number,\n  order: Int32Array\n): PackLanesResult {\n  const n = items.length;\n  const lanes = new Array<number>(n).fill(0);\n\n  // Column space spans starts *and* release times, so a lane always files\n  // into a real column.\n  let minX = Infinity;\n  let maxRelease = -Infinity;\n  for (let i = 0; i < n; i++) {\n    const item = items[i];\n    if (item.x < minX) minX = item.x;\n    const release = item.x + item.width + gapPx;\n    if (release > maxRelease) maxRelease = release;\n  }\n  // Degenerate extents (every card at one x, non-finite geometry) collapse to\n  // a single column: the exact per-lane check still runs, it just runs on the\n  // whole queue.\n  const span = maxRelease - minX;\n  const colCount = span > 0 ? n : 1;\n  const colScale = span > 0 ? colCount / span : 0;\n  const colOf = (value: number) => {\n    const col = Math.floor((value - minX) * colScale);\n    // Negated rather than `col < 0` so a NaN files into column 0 as well.\n    // Unguarded it returns NaN, and a NaN index on a typed array reads\n    // undefined and writes nothing — the lane would be filed into no column at\n    // all and never released, leaking it for the rest of the sweep.\n    if (!(col >= 0)) return 0;\n    return col >= colCount ? colCount - 1 : col;\n  };\n\n  // Release queue: an intrusive singly-linked list per column. A lane is in at\n  // most one column at a time, so `releaseNext` needs one slot per lane and\n  // lanes never exceed items.\n  const releaseHead = new Int32Array(colCount).fill(-1);\n  const releaseNext = new Int32Array(n).fill(-1);\n  /** Time (px) at which each lane's occupant frees it — end + gap. */\n  const laneRelease = new Float64Array(n);\n\n  // Free-lane bitmap. `summary` bit s.w is set when word w of block s has any\n  // free lane, so the search skips 1024 lanes at a time.\n  const wordCount = (n + 31) >> 5;\n  const words = new Uint32Array(wordCount);\n  const summary = new Uint32Array((wordCount + 31) >> 5);\n\n  /**\n   * How many lanes the bitmap currently holds. The summary walk below is\n   * O(lanes / 1024) and returns -1 when nothing is free, so a saturated sweep\n   * pays that walk once per item to learn the same thing every time: 50k cards\n   * on a single date is ~2.45M iterations of pure no. Counting the free lanes\n   * turns the empty case into a comparison.\n   */\n  let freeLanes = 0;\n\n  const markFree = (lane: number) => {\n    const word = lane >> 5;\n    words[word] |= 1 << (lane & 31);\n    summary[word >> 5] |= 1 << (word & 31);\n    freeLanes++;\n  };\n\n  /** Lowest set bit's index. Undefined for 0 — callers guard. */\n  const lowestBit = (bits: number) => 31 - Math.clz32(bits & -bits);\n\n  const takeSmallestFree = () => {\n    if (freeLanes === 0) return -1;\n    for (let block = 0; block < summary.length; block++) {\n      while (summary[block] !== 0) {\n        const blockBits = summary[block];\n        const wordOffset = lowestBit(blockBits);\n        const word = (block << 5) + wordOffset;\n        const bits = words[word];\n        if (bits === 0) {\n          // Word emptied without its summary bit clearing — can't happen\n          // below, but clearing here keeps the loop finite regardless.\n          summary[block] = blockBits & ~(1 << wordOffset);\n          continue;\n        }\n        const bitOffset = lowestBit(bits);\n        words[word] = bits & ~(1 << bitOffset);\n        if (words[word] === 0) summary[block] = blockBits & ~(1 << wordOffset);\n        freeLanes--;\n        return (word << 5) + bitOffset;\n      }\n    }\n    return -1;\n  };\n\n  let laneCount = 0;\n  // Every column before this one has been drained.\n  let drainedCol = 0;\n\n  for (let k = 0; k < n; k++) {\n    const index = order[k];\n    const item = items[index];\n    const x = item.x;\n    const col = colOf(x);\n\n    // Columns strictly behind the sweep release unconditionally: their release\n    // times all fall below the current column's left edge, which is <= x.\n    while (drainedCol < col) {\n      let lane = releaseHead[drainedCol];\n      while (lane !== -1) {\n        const next = releaseNext[lane];\n        releaseNext[lane] = -1;\n        markFree(lane);\n        lane = next;\n      }\n      releaseHead[drainedCol] = -1;\n      drainedCol++;\n    }\n\n    // The current column straddles x, so its lanes need the exact test. Ones\n    // that aren't free yet are relinked for the next item in this column.\n    let pending = releaseHead[col];\n    let stillBusy = -1;\n    while (pending !== -1) {\n      const next = releaseNext[pending];\n      if (laneRelease[pending] <= x) {\n        releaseNext[pending] = -1;\n        markFree(pending);\n      } else {\n        releaseNext[pending] = stillBusy;\n        stillBusy = pending;\n      }\n      pending = next;\n    }\n    releaseHead[col] = stillBusy;\n\n    let lane = takeSmallestFree();\n    if (lane === -1) lane = laneCount++;\n    lanes[index] = lane;\n\n    const release = x + item.width + gapPx;\n    laneRelease[lane] = release;\n    // Release is at or after x, so this never files into a drained column.\n    const releaseCol = colOf(release);\n    releaseNext[lane] = releaseHead[releaseCol];\n    releaseHead[releaseCol] = lane;\n  }\n\n  return { lanes, laneCount };\n}\n"],"names":["orderByX","EMPTY_BUCKET_KEY","orderBucketKeys"],"mappings":"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"}