@taskctrl/canvas-timeline 0.8.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/canvas-timeline.cjs.js +1 -1
- package/dist/canvas-timeline.cjs.js.map +1 -1
- package/dist/canvas-timeline.es.js +1005 -980
- package/dist/canvas-timeline.es.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/interaction/InteractionHandler.d.ts +2 -2
- package/dist/interaction/interactionInfo.d.ts +3 -2
- package/dist/interaction/snapResolve.d.ts +41 -0
- package/dist/interaction/snapUtils.d.ts +1 -1
- package/dist/types.d.ts +36 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-timeline.cjs.js","sources":["../src/types.ts","../src/core/ViewState.ts","../src/core/IntervalTree.ts","../src/core/LayoutEngine.ts","../src/core/HierarchyEngine.ts","../src/canvas/defaultSummaryRenderer.ts","../src/core/HitTest.ts","../src/canvas/CanvasManager.ts","../node_modules/dayjs/plugin/utc.js","../node_modules/dayjs/plugin/timezone.js","../src/utils/timezone.ts","../src/canvas/GridLayer.ts","../src/canvas/DrawHelpers.ts","../src/canvas/ItemsLayer.ts","../src/canvas/OverlayLayer.ts","../src/interaction/ZoomHandler.ts","../src/interaction/InteractionHandler.ts","../src/interaction/snapUtils.ts","../src/interaction/interactionInfo.ts","../node_modules/dayjs/plugin/isoWeek.js","../src/dom/Sidebar.tsx","../src/dom/TodayMarker.tsx","../src/dom/CustomMarker.tsx","../src/CanvasTimeline.tsx","../src/dom/TimelineHeaders.tsx","../node_modules/dayjs/plugin/weekOfYear.js","../src/dom/DateHeader.tsx","../src/dom/SidebarHeader.tsx","../src/dom/CustomHeader.tsx"],"sourcesContent":["import type React from 'react'\n\nexport interface Group {\n id: number | string\n title: string\n type?: string\n hierarchy?: string\n root?: boolean\n [key: string]: unknown\n}\n\nexport interface Item {\n id: number\n group: number | string\n start_time: number\n end_time: number\n parentId?: number\n type?: string\n /** Per-item override of the timeline-wide `canResize` prop. When set, this\n * wins for this item; when omitted, the global `canResize` applies. */\n canResize?: false | 'left' | 'right' | 'both'\n /** Per-item override of the timeline-wide `canMove` prop. When set, this\n * wins for this item; when omitted, the global `canMove` applies. */\n canMove?: boolean\n [key: string]: unknown\n}\n\nexport interface ItemBounds {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface ItemState {\n selected: boolean\n hovered: boolean\n dragging: boolean\n filtered: boolean\n}\n\nexport interface DrawHelpers {\n roundRect(x: number, y: number, w: number, h: number, radius?: number): void\n fillText(text: string, x: number, y: number, maxWidth?: number): void\n gradient(x: number, w: number, color1: string, color2: string): CanvasGradient\n leftBar(color: string, width?: number): void\n icon(type: 'check' | 'danger-red' | 'danger-yellow', x: number, y: number, size?: number): void\n badge(text: string, x: number, y: number, bgColor: string): void\n}\n\nexport type CanvasItemRenderer = (\n ctx: CanvasRenderingContext2D,\n item: Item,\n bounds: ItemBounds,\n state: ItemState,\n helpers: DrawHelpers,\n) => void\n\nexport type CanvasGroupItemRenderer = CanvasItemRenderer\n\nexport interface DayStyle {\n backgroundColor?: string\n borderColor?: string\n opacity?: number\n}\n\nexport interface RowStyle {\n backgroundColor?: string\n borderBottomColor?: string\n}\n\nexport interface Dependency {\n fromItemId: number\n toItemId: number\n type?: 'finish-to-start' | 'start-to-start' | 'finish-to-finish'\n color?: string\n}\n\nexport interface TimeRangeHighlight {\n start: number\n end: number\n color: string\n label?: string\n opacity?: number\n}\n\nexport interface TimelineTheme {\n primary: string\n trainColors: Record<string, string>\n status: { red: string; yellow: string; green: string }\n grid: { line: string; rowAlt: string; weekend: string }\n item: { radius: number; text: string; selectedRing: string }\n marker: { today: string; milestone: string; cursor: string }\n sidebar: { bg: string; border: string; text: string }\n header: { bg: string; border: string; text: string }\n}\n\nexport const DEFAULT_THEME: TimelineTheme = {\n primary: '#269bf7',\n trainColors: {},\n status: { red: '#EF5350', yellow: '#FBBF24', green: '#31c48d' },\n grid: { line: '#E5E5E5', rowAlt: '#F7F7F7', weekend: 'rgba(0,0,0,0.03)' },\n item: { radius: 3, text: '#374151', selectedRing: '#a3a3a3' },\n marker: { today: '#FD7171', milestone: '#3B82F6', cursor: '#269bf7' },\n sidebar: { bg: '#F9FAFB', border: '#E5E7EB', text: '#6c737f' },\n header: { bg: '#F9FAFB', border: '#E5E7EB', text: '#6c737f' },\n}\n\nexport interface MarkerConfig {\n date: number\n color: string\n width: number\n label?: string\n}\n\n/** Live state of an in-progress drag/resize, emitted via `onInteractionUpdate`.\n * All times are the snapped values that will commit on drop (item-edge snap +\n * grid snap, plus hierarchy resize constraints) — i.e. where the item will\n * actually land, matching the snap guide. The consumer-supplied\n * `moveResizeValidator` is NOT applied here (it may run per frame). */\nexport interface InteractionInfo {\n itemId: number\n mode: 'move' | 'resize-left' | 'resize-right'\n /** Set for resize interactions; which edge is being dragged. */\n edge?: 'left' | 'right'\n /** The headline time to display: the new start for `move`/`resize-left`, the\n * new end for `resize-right`. */\n time: number\n /** The item's snapped start time during this interaction. */\n startTime: number\n /** The item's snapped end time during this interaction. */\n endTime: number\n /** Pointer position in viewport coordinates (clientX/clientY), for\n * positioning a `position: fixed` tooltip without further math. */\n pointerX: number\n pointerY: number\n}\n\nexport interface CanvasTimelineProps {\n groups: Group[]\n items: Item[]\n defaultTimeStart: number\n defaultTimeEnd: number\n visibleTimeStart?: number\n visibleTimeEnd?: number\n sidebarWidth: number\n lineHeight: number\n itemHeightRatio: number\n stackItems: boolean\n buffer?: number\n canMove: boolean\n canResize: false | 'left' | 'right' | 'both'\n canChangeGroup: boolean\n dragSnap: number\n minZoom: number\n maxZoom: number\n theme?: Partial<TimelineTheme>\n dayStyle?: (date: Date) => DayStyle | null\n rowStyle?: (group: Group) => RowStyle | null\n showCursorLine?: boolean\n itemRenderer: CanvasItemRenderer\n groupRenderer?: CanvasGroupItemRenderer\n summaryRenderer?: CanvasItemRenderer\n sidebarGroupRenderer: (group: Group) => React.ReactNode\n rightSidebarWidth?: number\n rightSidebarGroupRenderer?: (group: Group) => React.ReactNode\n dependencies?: Dependency[]\n highlights?: TimeRangeHighlight[]\n onItemClick?: (itemId: number, e: PointerEvent) => void\n onItemDoubleClick?: (itemId: number, e: PointerEvent) => void\n onItemContextMenu?: (itemId: number, e: PointerEvent) => void\n onItemMove?: (itemId: number, newStartTime: number, newGroupId: string | number, childMoves?: { itemId: number; newStart: number }[]) => void\n onItemResize?: (itemId: number, newTime: number, edge: 'left' | 'right') => void\n /** Validate and optionally constrain move/resize. Return the (possibly modified) time. */\n moveResizeValidator?: (action: 'move' | 'resize', itemId: number, time: number, edge?: 'left' | 'right') => number\n onItemHover?: (itemId: number | null, e: PointerEvent) => void\n /** Fires once per animation frame during an active drag/resize, then once with\n * `null` when it ends. Intended for a live \"current time\" tooltip. This is a\n * hot path: do NOT call setState here — mutate a ref'd DOM node's text/transform\n * directly so neither the library nor your app re-renders per frame. */\n onInteractionUpdate?: (info: InteractionInfo | null) => void\n onCanvasDoubleClick?: (groupId: number, time: number) => void\n onCanvasContextMenu?: (groupId: number, time: number, e: PointerEvent) => void\n onTimeChange?: (start: number, end: number) => void\n onZoom?: (start: number, end: number) => void\n selected?: number[]\n /** Called when the timeline is ready, providing the capture API */\n onReady?: (api: CanvasTimelineRef) => void\n /** Dev-only: show a version + build-time badge in the top-left corner.\n * Wire to your app's dev flag, e.g. `devBadge={import.meta.env.DEV}`. */\n /** Maximum visible height for the timeline body. Accepts a number (px) or\n * a CSS string like `'calc(100vh - 98px)'`. When set, the canvas and sidebar\n * are clipped and internally scrollable via wheel, drag, or touch. */\n maxHeight?: number | string\n /** IANA timezone string (e.g. \"America/New_York\", \"UTC\").\n * When set, grid lines, headers, and day styling render in this timezone.\n * Defaults to the browser's local timezone. */\n timezone?: string\n devBadge?: boolean\n children?: React.ReactNode\n}\n\nexport interface CaptureOptions {\n timeStart: number\n timeEnd: number\n scale: number\n sidebarWidth: number\n}\n\nexport interface CanvasTimelineRef {\n captureToCanvas(options: CaptureOptions): HTMLCanvasElement\n}\n","export interface ViewStateConfig {\n visibleTimeStart: number\n visibleTimeEnd: number\n canvasWidth: number\n canvasHeight: number\n sidebarWidth: number\n lineHeight: number\n groupCount: number\n buffer: number\n scrollTop: number\n groupHeights?: number[]\n}\n\nexport class ViewState {\n visibleTimeStart: number\n visibleTimeEnd: number\n canvasWidth: number\n canvasHeight: number\n sidebarWidth: number\n lineHeight: number\n groupCount: number\n buffer: number\n scrollTop: number\n groupHeights: number[] | null\n\n private visibleDuration: number\n private pixelsPerMs: number\n // Cumulative top-edge offsets per group: length = groupCount + 1,\n // groupYOffsets[i] = sum of heights[0..i-1]; groupYOffsets[groupCount] = total.\n private groupYOffsets: number[]\n\n constructor(config: ViewStateConfig) {\n this.visibleTimeStart = config.visibleTimeStart\n this.visibleTimeEnd = config.visibleTimeEnd\n this.canvasWidth = config.canvasWidth\n this.canvasHeight = config.canvasHeight\n this.sidebarWidth = config.sidebarWidth\n this.lineHeight = config.lineHeight\n this.groupCount = config.groupCount\n this.buffer = config.buffer\n this.scrollTop = config.scrollTop\n this.groupHeights = config.groupHeights ?? null\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n this.groupYOffsets = []\n this.recomputeGroupYOffsets()\n }\n\n update(params: Partial<ViewStateConfig>): void {\n if (params.visibleTimeStart !== undefined) this.visibleTimeStart = params.visibleTimeStart\n if (params.visibleTimeEnd !== undefined) this.visibleTimeEnd = params.visibleTimeEnd\n if (params.canvasWidth !== undefined) this.canvasWidth = params.canvasWidth\n if (params.canvasHeight !== undefined) this.canvasHeight = params.canvasHeight\n if (params.sidebarWidth !== undefined) this.sidebarWidth = params.sidebarWidth\n if (params.lineHeight !== undefined) this.lineHeight = params.lineHeight\n if (params.groupCount !== undefined) this.groupCount = params.groupCount\n if (params.buffer !== undefined) this.buffer = params.buffer\n if (params.scrollTop !== undefined) this.scrollTop = params.scrollTop\n if (params.groupHeights !== undefined) this.groupHeights = params.groupHeights ?? null\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n this.recomputeGroupYOffsets()\n }\n\n private recomputeGroupYOffsets(): void {\n const offsets = new Array<number>(this.groupCount + 1)\n offsets[0] = 0\n for (let i = 0; i < this.groupCount; i++) {\n const h = this.groupHeights?.[i] ?? this.lineHeight\n offsets[i + 1] = offsets[i] + h\n }\n this.groupYOffsets = offsets\n }\n\n timeToX(time: number): number {\n return (time - this.visibleTimeStart) * this.pixelsPerMs\n }\n\n xToTime(x: number): number {\n return this.visibleTimeStart + x / this.pixelsPerMs\n }\n\n yToGroupIndex(y: number): number {\n if (this.groupCount === 0) return 0\n const target = y + this.scrollTop\n if (target <= 0) return 0\n if (target >= this.groupYOffsets[this.groupCount]) return this.groupCount - 1\n // Binary search: smallest i where groupYOffsets[i + 1] > target.\n let lo = 0\n let hi = this.groupCount - 1\n while (lo < hi) {\n const mid = (lo + hi) >>> 1\n if (this.groupYOffsets[mid + 1] > target) hi = mid\n else lo = mid + 1\n }\n return lo\n }\n\n groupIndexToY(index: number): number {\n if (index < 0) return -this.scrollTop\n if (index >= this.groupCount) {\n return (this.groupYOffsets[this.groupCount] ?? 0) - this.scrollTop\n }\n return this.groupYOffsets[index] - this.scrollTop\n }\n\n groupIndexToHeight(index: number): number {\n if (index < 0 || index >= this.groupCount) return this.lineHeight\n return this.groupHeights?.[index] ?? this.lineHeight\n }\n\n getBufferBounds(): { bufferStart: number; bufferEnd: number } {\n const extend = this.visibleDuration * 1.5\n return {\n bufferStart: this.visibleTimeStart - extend,\n bufferEnd: this.visibleTimeEnd + extend,\n }\n }\n\n getVisibleGroupRange(): { firstVisible: number; lastVisible: number } {\n if (this.groupCount === 0) return { firstVisible: 0, lastVisible: -1 }\n const firstVisible = this.yToGroupIndex(0)\n const lastVisible = this.yToGroupIndex(this.canvasHeight)\n return { firstVisible, lastVisible }\n }\n\n isScrollInBuffer(scrollXOffset: number): boolean {\n const bufferPixels = this.visibleDuration * 1.5 * this.pixelsPerMs\n return Math.abs(scrollXOffset) < bufferPixels\n }\n\n getTotalHeight(): number {\n return this.groupYOffsets[this.groupCount] ?? 0\n }\n}\n","interface TreeNode<T> {\n center: number\n left: TreeNode<T> | null\n right: TreeNode<T> | null\n overlapping: Array<{ item: T; start: number; end: number }>\n}\n\nexport class IntervalTree<T> {\n private root: TreeNode<T> | null = null\n\n buildFromItems(\n items: T[],\n getStart: (item: T) => number,\n getEnd: (item: T) => number,\n ): void {\n const intervals = items.map((item) => ({\n item,\n start: getStart(item),\n end: getEnd(item),\n }))\n this.root = this.buildNode(intervals)\n }\n\n private buildNode(\n intervals: Array<{ item: T; start: number; end: number }>,\n ): TreeNode<T> | null {\n if (intervals.length === 0) return null\n\n let min = Infinity\n let max = -Infinity\n for (const iv of intervals) {\n if (iv.start < min) min = iv.start\n if (iv.end > max) max = iv.end\n }\n const center = (min + max) / 2\n\n const leftIntervals: Array<{ item: T; start: number; end: number }> = []\n const rightIntervals: Array<{ item: T; start: number; end: number }> = []\n const overlapping: Array<{ item: T; start: number; end: number }> = []\n\n for (const iv of intervals) {\n if (iv.end < center) {\n leftIntervals.push(iv)\n } else if (iv.start > center) {\n rightIntervals.push(iv)\n } else {\n overlapping.push(iv)\n }\n }\n\n return {\n center,\n left: this.buildNode(leftIntervals),\n right: this.buildNode(rightIntervals),\n overlapping,\n }\n }\n\n query(start: number, end: number): T[] {\n const results: T[] = []\n this.queryNode(this.root, start, end, results)\n return results\n }\n\n private queryNode(\n node: TreeNode<T> | null,\n start: number,\n end: number,\n results: T[],\n ): void {\n if (node === null) return\n\n for (const iv of node.overlapping) {\n if (iv.start <= end && iv.end >= start) {\n results.push(iv.item)\n }\n }\n\n if (start <= node.center && node.left !== null) {\n this.queryNode(node.left, start, end, results)\n }\n\n if (end >= node.center && node.right !== null) {\n this.queryNode(node.right, start, end, results)\n }\n }\n}\n","import type { Item } from '../types'\nimport type { HierarchyEngine } from './HierarchyEngine'\n\nexport interface ItemLayout {\n stackLevel: number\n itemHeight: number\n}\n\nexport class LayoutEngine {\n private readonly lineHeight: number\n private readonly itemHeightRatio: number\n private layoutCache: Map<number, ItemLayout> = new Map()\n private groupMaxStack: Map<string | number, number> = new Map()\n\n constructor(lineHeight: number, itemHeightRatio: number) {\n this.lineHeight = lineHeight\n this.itemHeightRatio = itemHeightRatio\n }\n\n computeLayout(items: Item[], stackItems: boolean, hierarchy?: HierarchyEngine): Map<number, ItemLayout> {\n this.layoutCache = new Map()\n this.groupMaxStack = new Map()\n\n const itemHeight = this.lineHeight * this.itemHeightRatio\n const summaryHeight = itemHeight * 0.6\n\n if (!stackItems) {\n for (const item of items) {\n const isSummary = hierarchy?.isParent(item.id) ?? false\n this.layoutCache.set(item.id, { stackLevel: 0, itemHeight: isSummary ? summaryHeight : itemHeight })\n this.groupMaxStack.set(item.group, 0)\n }\n return this.layoutCache\n }\n\n // Group items by group id\n const byGroup = new Map<string | number, Item[]>()\n for (const item of items) {\n let arr = byGroup.get(item.group)\n if (!arr) {\n arr = []\n byGroup.set(item.group, arr)\n }\n arr.push(item)\n }\n\n for (const [groupId, groupItems] of byGroup) {\n if (hierarchy) {\n this.computeHierarchyLayout(groupItems, hierarchy, itemHeight, summaryHeight, groupId)\n } else {\n this.computeFlatLayout(groupItems, itemHeight, groupId)\n }\n }\n\n return this.layoutCache\n }\n\n private computeFlatLayout(groupItems: Item[], itemHeight: number, groupId: string | number): void {\n groupItems.sort((a, b) => {\n const d = a.start_time - b.start_time\n if (d !== 0) return d\n return (b.end_time - b.start_time) - (a.end_time - a.start_time)\n })\n\n const levelEnds: number[] = []\n let maxLevel = 0\n\n for (const item of groupItems) {\n let level = -1\n for (let i = 0; i < levelEnds.length; i++) {\n if (levelEnds[i] <= item.start_time) {\n level = i\n break\n }\n }\n\n if (level === -1) {\n level = levelEnds.length\n levelEnds.push(item.end_time)\n } else {\n levelEnds[level] = item.end_time\n }\n\n if (level > maxLevel) maxLevel = level\n\n this.layoutCache.set(item.id, { stackLevel: level, itemHeight })\n }\n\n this.groupMaxStack.set(groupId, maxLevel)\n }\n\n private computeHierarchyLayout(\n groupItems: Item[],\n hierarchy: HierarchyEngine,\n itemHeight: number,\n summaryHeight: number,\n groupId: string | number,\n ): void {\n // Separate leaf items from parents\n const leaves: Item[] = []\n const parents: Item[] = []\n for (const item of groupItems) {\n if (hierarchy.isParent(item.id)) {\n parents.push(item)\n } else {\n leaves.push(item)\n }\n }\n\n // Stack leaves first using sweep-line\n leaves.sort((a, b) => {\n const d = a.start_time - b.start_time\n if (d !== 0) return d\n return (b.end_time - b.start_time) - (a.end_time - a.start_time)\n })\n\n const levelEnds: number[] = []\n let maxLevel = 0\n\n for (const item of leaves) {\n let level = -1\n for (let i = 0; i < levelEnds.length; i++) {\n if (levelEnds[i] <= item.start_time) {\n level = i\n break\n }\n }\n\n if (level === -1) {\n level = levelEnds.length\n levelEnds.push(item.end_time)\n } else {\n levelEnds[level] = item.end_time\n }\n\n if (level > maxLevel) maxLevel = level\n\n this.layoutCache.set(item.id, { stackLevel: level, itemHeight })\n }\n\n // Stack parents above leaves, sorted by nesting depth\n // Deepest parents first (closest to children), shallowest last (on top)\n parents.sort((a, b) => hierarchy.getNestingDepth(b.id) - hierarchy.getNestingDepth(a.id))\n\n let nextLevel = leaves.length > 0 ? maxLevel + 1 : 0\n for (const parent of parents) {\n this.layoutCache.set(parent.id, { stackLevel: nextLevel, itemHeight: summaryHeight })\n if (nextLevel > maxLevel) maxLevel = nextLevel\n nextLevel++\n }\n\n this.groupMaxStack.set(groupId, maxLevel)\n }\n\n getLayout(itemId: number): ItemLayout | undefined {\n return this.layoutCache.get(itemId)\n }\n\n getGroupHeight(groupId: string | number): number {\n const maxStack = this.groupMaxStack.get(groupId) ?? 0\n return (maxStack + 1) * this.lineHeight\n }\n}\n","interface HierarchyItem {\n id: number\n start_time: number\n end_time: number\n parentId?: number\n}\n\nexport class HierarchyEngine {\n private parentToChildren: Map<number, number[]> = new Map()\n private childToParent: Map<number, number> = new Map()\n private itemMap: Map<number, HierarchyItem> = new Map()\n private depthCache: Map<number, number> = new Map()\n\n rebuild(items: HierarchyItem[]): void {\n this.parentToChildren = new Map()\n this.childToParent = new Map()\n this.itemMap = new Map()\n this.depthCache = new Map()\n\n for (const item of items) {\n this.itemMap.set(item.id, item)\n }\n\n for (const item of items) {\n if (item.parentId !== undefined && this.itemMap.has(item.parentId)) {\n this.childToParent.set(item.id, item.parentId)\n let children = this.parentToChildren.get(item.parentId)\n if (!children) {\n children = []\n this.parentToChildren.set(item.parentId, children)\n }\n children.push(item.id)\n }\n }\n\n // Detect and break cycles\n for (const id of this.childToParent.keys()) {\n const visited = new Set<number>()\n let current: number | undefined = id\n while (current !== undefined) {\n if (visited.has(current)) {\n const parentId = this.childToParent.get(id)!\n this.childToParent.delete(id)\n const siblings = this.parentToChildren.get(parentId)\n if (siblings) {\n const idx = siblings.indexOf(id)\n if (idx !== -1) siblings.splice(idx, 1)\n if (siblings.length === 0) this.parentToChildren.delete(parentId)\n }\n break\n }\n visited.add(current)\n current = this.childToParent.get(current)\n }\n }\n }\n\n isParent(itemId: number): boolean {\n const children = this.parentToChildren.get(itemId)\n return children !== undefined && children.length > 0\n }\n\n getParent(itemId: number): number | undefined {\n return this.childToParent.get(itemId)\n }\n\n getChildren(itemId: number): number[] {\n return this.parentToChildren.get(itemId) ?? []\n }\n\n getDescendants(itemId: number): number[] {\n const result: number[] = []\n const stack = [...this.getChildren(itemId)]\n while (stack.length > 0) {\n const id = stack.pop()!\n result.push(id)\n const children = this.parentToChildren.get(id)\n if (children) stack.push(...children)\n }\n return result\n }\n\n getEffectiveSpan(itemId: number): { start: number; end: number } {\n const item = this.itemMap.get(itemId)\n if (!item) return { start: 0, end: 0 }\n\n let start = item.start_time\n let end = item.end_time\n\n const descendants = this.getDescendants(itemId)\n for (const descId of descendants) {\n const desc = this.itemMap.get(descId)\n if (!desc) continue\n if (desc.start_time < start) start = desc.start_time\n if (desc.end_time > end) end = desc.end_time\n }\n\n return { start, end }\n }\n\n getNestingDepth(itemId: number): number {\n const cached = this.depthCache.get(itemId)\n if (cached !== undefined) return cached\n\n let depth = 0\n let current = this.childToParent.get(itemId)\n while (current !== undefined) {\n depth++\n current = this.childToParent.get(current)\n }\n this.depthCache.set(itemId, depth)\n return depth\n }\n\n getMoveDelta(itemId: number, newStart: number): { itemId: number; newStart: number }[] {\n const item = this.itemMap.get(itemId)\n if (!item) return []\n\n const delta = newStart - item.start_time\n const descendants = this.getDescendants(itemId)\n return descendants.map(descId => {\n const desc = this.itemMap.get(descId)!\n return { itemId: descId, newStart: desc.start_time + delta }\n })\n }\n\n getResizeConstraint(itemId: number, edge: 'left' | 'right'): { min: number; max: number } {\n const children = this.getDescendants(itemId)\n if (children.length === 0) {\n return edge === 'left'\n ? { min: -Infinity, max: Infinity }\n : { min: -Infinity, max: Infinity }\n }\n\n if (edge === 'left') {\n let minChildStart = Infinity\n for (const childId of children) {\n const child = this.itemMap.get(childId)\n if (child && child.start_time < minChildStart) {\n minChildStart = child.start_time\n }\n }\n return { min: -Infinity, max: minChildStart }\n } else {\n let maxChildEnd = -Infinity\n for (const childId of children) {\n const child = this.itemMap.get(childId)\n if (child && child.end_time > maxChildEnd) {\n maxChildEnd = child.end_time\n }\n }\n return { min: maxChildEnd, max: Infinity }\n }\n }\n}\n","import type { Item, ItemBounds, ItemState, DrawHelpers, TimelineTheme } from '../types'\n\nexport function defaultSummaryRenderer(\n ctx: CanvasRenderingContext2D,\n item: Item,\n bounds: ItemBounds,\n state: ItemState,\n _helpers: DrawHelpers,\n theme: TimelineTheme,\n): void {\n const { x, y, width, height } = bounds\n const color = theme.primary\n\n // Semi-transparent fill\n ctx.globalAlpha = 0.15\n ctx.fillStyle = color\n ctx.fillRect(x, y, width, height)\n ctx.globalAlpha = 1\n\n // Border\n ctx.strokeStyle = color\n ctx.lineWidth = 1.5\n ctx.strokeRect(x, y, width, height)\n\n // Diamond marker at start edge\n const diamondSize = Math.min(height * 0.5, 6)\n const midY = y + height / 2\n\n ctx.fillStyle = color\n // Left diamond\n ctx.beginPath()\n ctx.moveTo(x, midY)\n ctx.lineTo(x + diamondSize, midY - diamondSize)\n ctx.lineTo(x + diamondSize * 2, midY)\n ctx.lineTo(x + diamondSize, midY + diamondSize)\n ctx.closePath()\n ctx.fill()\n\n // Right diamond\n ctx.beginPath()\n ctx.moveTo(x + width, midY)\n ctx.lineTo(x + width - diamondSize, midY - diamondSize)\n ctx.lineTo(x + width - diamondSize * 2, midY)\n ctx.lineTo(x + width - diamondSize, midY + diamondSize)\n ctx.closePath()\n ctx.fill()\n\n // Title text centered\n const title = (item as { title?: string }).title\n if (title && width > 30) {\n ctx.fillStyle = theme.item.text\n ctx.font = '500 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n ctx.textBaseline = 'middle'\n const textWidth = ctx.measureText(title).width\n const maxTextWidth = width - diamondSize * 4 - 4\n if (maxTextWidth > 20) {\n const displayText = textWidth > maxTextWidth\n ? title.slice(0, Math.floor(title.length * maxTextWidth / textWidth)) + '...'\n : title\n ctx.fillText(displayText, x + width / 2 - Math.min(textWidth, maxTextWidth) / 2, midY)\n }\n }\n\n // Selected ring\n if (state.selected) {\n ctx.strokeStyle = theme.item.selectedRing\n ctx.lineWidth = 2\n ctx.strokeRect(x - 1, y - 1, width + 2, height + 2)\n }\n}\n","import type { Item, Group } from '../types'\nimport type { ViewState } from './ViewState'\nimport type { IntervalTree } from './IntervalTree'\nimport type { LayoutEngine } from './LayoutEngine'\n\nexport function hitTest(\n canvasX: number,\n canvasY: number,\n view: ViewState,\n tree: IntervalTree<Item>,\n layout: LayoutEngine,\n groups: Group[],\n): Item | null {\n const time = view.xToTime(canvasX)\n\n const groupIndexMap = new Map<string | number, number>()\n for (let i = 0; i < groups.length; i++) {\n groupIndexMap.set(groups[i].id, i)\n }\n\n const candidates = tree.query(time, time)\n\n let topItem: Item | null = null\n let topY = -Infinity\n\n for (const item of candidates) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n\n const itemLayout = layout.getLayout(item.id)\n if (!itemLayout) continue\n\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n\n if (canvasX < x || canvasX > x + width) continue\n\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n const height = itemLayout.itemHeight\n\n if (canvasY < y || canvasY > y + height) continue\n\n if (y > topY) {\n topY = y\n topItem = item\n }\n }\n\n return topItem\n}\n\nexport function hitTestGroup(\n canvasY: number,\n view: ViewState,\n groups: Group[],\n): Group | null {\n const groupIndex = view.yToGroupIndex(canvasY)\n return groups[groupIndex] ?? null\n}\n\nexport function detectEdge(\n canvasX: number,\n item: Item,\n view: ViewState,\n threshold: number = 6,\n): 'left' | 'right' | 'body' {\n const leftX = view.timeToX(item.start_time)\n const rightX = view.timeToX(item.end_time)\n if (canvasX - leftX <= threshold) return 'left'\n if (rightX - canvasX <= threshold) return 'right'\n return 'body'\n}\n\n/**\n * Resolve the effective `canResize` for an item: a per-item `item.canResize`\n * wins when present, otherwise the timeline-wide `globalCanResize` applies.\n * Uses `??` (not `||`) so an explicit per-item `false` disables resize rather\n * than falling through to the global value.\n */\nexport function resolveCanResize(\n item: Item,\n globalCanResize: false | 'left' | 'right' | 'both',\n): false | 'left' | 'right' | 'both' {\n return item.canResize ?? globalCanResize\n}\n\n/**\n * Resolve the effective `canMove` for an item: a per-item `item.canMove` wins\n * when present, otherwise the timeline-wide `globalCanMove` applies. Uses `??`\n * (not `||`) so an explicit per-item `false` disables moving rather than\n * falling through to the global value.\n */\nexport function resolveCanMove(item: Item, globalCanMove: boolean): boolean {\n return item.canMove ?? globalCanMove\n}\n\n/**\n * Decide which interaction (if any) a pointer-down at `edge` should start for\n * `item`, given the timeline-wide `canResize`/`canMove` props. Returns `null`\n * when nothing is permitted — the caller then starts no interaction (no ghost)\n * and shows no affordance (default cursor). Centralising this keeps the cursor\n * and the interaction decision in lockstep.\n *\n * An item explicitly resize-locked per-item (`item.canResize === false`) has\n * inert edges: grabbing an edge returns `null` rather than falling through to a\n * move, so a user trying to resize a locked item sees no UI. This is scoped to\n * the *explicit* per-item override — an item inheriting a global `canResize:\n * false` (field undefined) keeps the move-only behaviour where the whole item,\n * edges included, is draggable.\n */\nexport function resolveInteractionMode(\n item: Item,\n edge: 'left' | 'right' | 'body',\n globalCanResize: false | 'left' | 'right' | 'both',\n globalCanMove: boolean,\n): 'move' | 'resize-left' | 'resize-right' | null {\n const cr = resolveCanResize(item, globalCanResize)\n if (edge === 'left' && (cr === 'left' || cr === 'both')) return 'resize-left'\n if (edge === 'right' && (cr === 'right' || cr === 'both')) return 'resize-right'\n if (item.canResize === false && edge !== 'body') return null\n if (resolveCanMove(item, globalCanMove)) return 'move'\n return null\n}\n","/**\n * Resize the canvas buffer only when dimensions actually change.\n * Setting canvas.width/height is destructive (clears buffer + resets state),\n * so we avoid it unless necessary.\n */\nexport function setupCanvas(\n canvas: HTMLCanvasElement,\n width: number,\n height: number,\n): CanvasRenderingContext2D {\n const dpr = window.devicePixelRatio || 1\n const targetW = Math.round(width * dpr)\n const targetH = Math.round(height * dpr)\n\n if (canvas.width !== targetW || canvas.height !== targetH) {\n canvas.width = targetW\n canvas.height = targetH\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n }\n\n const ctx = canvas.getContext('2d')!\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n return ctx\n}\n\nexport function clearCanvas(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement): void {\n const dpr = window.devicePixelRatio || 1\n ctx.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr)\n}\n\nexport type LayerName = 'grid' | 'items' | 'overlay'\n\nexport interface DirtyFlags {\n grid: boolean\n items: boolean\n overlay: boolean\n}\n\nexport class RenderScheduler {\n private dirty: DirtyFlags = { grid: false, items: false, overlay: false }\n private rafId: number | null = null\n private drawCallback: (flags: DirtyFlags) => void\n\n constructor(drawCallback: (flags: DirtyFlags) => void) {\n this.drawCallback = drawCallback\n }\n\n markDirty(layer: LayerName): void {\n this.dirty[layer] = true\n this.schedule()\n }\n\n markAllDirty(): void {\n this.dirty.grid = true\n this.dirty.items = true\n this.dirty.overlay = true\n this.schedule()\n }\n\n dispose(): void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n private schedule(): void {\n if (this.rafId !== null) return\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n const flags = { ...this.dirty }\n this.dirty.grid = false\n this.dirty.items = false\n this.dirty.overlay = false\n this.drawCallback(flags)\n })\n }\n}\n","!function(t,i){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=i():\"function\"==typeof define&&define.amd?define(i):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).dayjs_plugin_utc=i()}(this,(function(){\"use strict\";var t=\"minute\",i=/[+-]\\d\\d(?::?\\d\\d)?/g,e=/([+-]|\\d\\d)/g;return function(s,f,n){var u=f.prototype;n.utc=function(t){var i={date:t,utc:!0,args:arguments};return new f(i)},u.utc=function(i){var e=n(this.toDate(),{locale:this.$L,utc:!0});return i?e.add(this.utcOffset(),t):e},u.local=function(){return n(this.toDate(),{locale:this.$L,utc:!1})};var r=u.parse;u.parse=function(t){t.utc&&(this.$u=!0),this.$utils().u(t.$offset)||(this.$offset=t.$offset),r.call(this,t)};var o=u.init;u.init=function(){if(this.$u){var t=this.$d;this.$y=t.getUTCFullYear(),this.$M=t.getUTCMonth(),this.$D=t.getUTCDate(),this.$W=t.getUTCDay(),this.$H=t.getUTCHours(),this.$m=t.getUTCMinutes(),this.$s=t.getUTCSeconds(),this.$ms=t.getUTCMilliseconds()}else o.call(this)};var a=u.utcOffset;u.utcOffset=function(s,f){var n=this.$utils().u;if(n(s))return this.$u?0:n(this.$offset)?a.call(this):this.$offset;if(\"string\"==typeof s&&(s=function(t){void 0===t&&(t=\"\");var s=t.match(i);if(!s)return null;var f=(\"\"+s[0]).match(e)||[\"-\",0,0],n=f[0],u=60*+f[1]+ +f[2];return 0===u?0:\"+\"===n?u:-u}(s),null===s))return this;var u=Math.abs(s)<=16?60*s:s;if(0===u)return this.utc(f);var r=this.clone();if(f)return r.$offset=u,r.$u=!1,r;var o=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();return(r=this.local().add(u+o,t)).$offset=u,r.$x.$localOffset=o,r};var h=u.format;u.format=function(t){var i=t||(this.$u?\"YYYY-MM-DDTHH:mm:ss[Z]\":\"\");return h.call(this,i)},u.valueOf=function(){var t=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*t},u.isUTC=function(){return!!this.$u},u.toISOString=function(){return this.toDate().toISOString()},u.toString=function(){return this.toDate().toUTCString()};var l=u.toDate;u.toDate=function(t){return\"s\"===t&&this.$offset?n(this.format(\"YYYY-MM-DD HH:mm:ss:SSS\")).toDate():l.call(this)};var c=u.diff;u.diff=function(t,i,e){if(t&&this.$u===t.$u)return c.call(this,t,i,e);var s=this.local(),f=n(t).local();return c.call(s,f,i,e)}}}));","!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).dayjs_plugin_timezone=e()}(this,(function(){\"use strict\";var t={year:0,month:1,day:2,hour:3,minute:4,second:5},e={};return function(n,i,o){var r,a=function(t,n,i){void 0===i&&(i={});var o=new Date(t),r=function(t,n){void 0===n&&(n={});var i=n.timeZoneName||\"short\",o=t+\"|\"+i,r=e[o];return r||(r=new Intl.DateTimeFormat(\"en-US\",{hour12:!1,timeZone:t,year:\"numeric\",month:\"2-digit\",day:\"2-digit\",hour:\"2-digit\",minute:\"2-digit\",second:\"2-digit\",timeZoneName:i}),e[o]=r),r}(n,i);return r.formatToParts(o)},u=function(e,n){for(var i=a(e,n),r=[],u=0;u<i.length;u+=1){var f=i[u],s=f.type,m=f.value,c=t[s];c>=0&&(r[c]=parseInt(m,10))}var d=r[3],l=24===d?0:d,h=r[0]+\"-\"+r[1]+\"-\"+r[2]+\" \"+l+\":\"+r[4]+\":\"+r[5]+\":000\",v=+e;return(o.utc(h).valueOf()-(v-=v%1e3))/6e4},f=i.prototype;f.tz=function(t,e){void 0===t&&(t=r);var n,i=this.utcOffset(),a=this.toDate(),u=a.toLocaleString(\"en-US\",{timeZone:t}),f=Math.round((a-new Date(u))/1e3/60),s=15*-Math.round(a.getTimezoneOffset()/15)-f;if(!Number(s))n=this.utcOffset(0,e);else if(n=o(u,{locale:this.$L}).$set(\"millisecond\",this.$ms).utcOffset(s,!0),e){var m=n.utcOffset();n=n.add(i-m,\"minute\")}return n.$x.$timezone=t,n},f.offsetName=function(t){var e=this.$x.$timezone||o.tz.guess(),n=a(this.valueOf(),e,{timeZoneName:t}).find((function(t){return\"timezonename\"===t.type.toLowerCase()}));return n&&n.value};var s=f.startOf;f.startOf=function(t,e){if(!this.$x||!this.$x.$timezone)return s.call(this,t,e);var n=o(this.format(\"YYYY-MM-DD HH:mm:ss:SSS\"),{locale:this.$L});return s.call(n,t,e).tz(this.$x.$timezone,!0)},o.tz=function(t,e,n){var i=n&&e,a=n||e||r,f=u(+o(),a);if(\"string\"!=typeof t)return o(t).tz(a);var s=function(t,e,n){var i=t-60*e*1e3,o=u(i,n);if(e===o)return[i,e];var r=u(i-=60*(o-e)*1e3,n);return o===r?[i,o]:[t-60*Math.min(o,r)*1e3,Math.max(o,r)]}(o.utc(t,i).valueOf(),f,a),m=s[0],c=s[1],d=o(m).utcOffset(c);return d.$x.$timezone=a,d},o.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},o.tz.setDefault=function(t){r=t}}}));","import dayjs from 'dayjs'\nimport utc from 'dayjs/plugin/utc'\nimport tz from 'dayjs/plugin/timezone'\n\ndayjs.extend(utc)\ndayjs.extend(tz)\n\nexport function toDayjs(ts: number, timezone?: string): dayjs.Dayjs {\n return timezone ? dayjs(ts).tz(timezone) : dayjs(ts)\n}\n","import { toDayjs } from '../utils/timezone'\nimport type { Group, TimelineTheme, DayStyle, RowStyle, TimeRangeHighlight } from '../types'\nimport type { ViewState } from '../core/ViewState'\n\nexport class GridLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n groups: Group[],\n theme: TimelineTheme,\n dayStyle?: (date: Date) => DayStyle | null,\n rowStyle?: (group: Group) => RowStyle | null,\n highlights?: TimeRangeHighlight[],\n timezone?: string,\n ): void {\n const { firstVisible, lastVisible } = view.getVisibleGroupRange()\n\n // Draw row backgrounds\n for (let i = firstVisible; i <= lastVisible; i++) {\n const y = view.groupIndexToY(i)\n const rowHeight = view.groupIndexToHeight(i)\n const group = groups[i]\n if (!group) continue\n\n let bgColor: string\n const customRow = rowStyle?.(group)\n if (customRow?.backgroundColor) {\n bgColor = customRow.backgroundColor\n } else {\n bgColor = i % 2 === 0 ? '#FFFFFF' : theme.grid.rowAlt\n }\n\n ctx.fillStyle = bgColor\n ctx.fillRect(0, y, view.canvasWidth, rowHeight)\n\n // Row separator\n ctx.strokeStyle = customRow?.borderBottomColor ?? theme.grid.line\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + rowHeight)\n ctx.lineTo(view.canvasWidth, y + rowHeight)\n ctx.stroke()\n }\n\n // Draw time range highlight backgrounds (under grid lines)\n if (highlights && highlights.length > 0) {\n for (const h of highlights) {\n const x1 = view.timeToX(h.start)\n const x2 = view.timeToX(h.end)\n if (x2 < 0 || x1 > view.canvasWidth) continue\n\n const x = Math.max(0, x1)\n const w = Math.min(view.canvasWidth, x2) - x\n\n const opacity = h.opacity ?? 0.12\n const r = parseInt(h.color.slice(1, 3), 16)\n const g = parseInt(h.color.slice(3, 5), 16)\n const b = parseInt(h.color.slice(5, 7), 16)\n ctx.fillStyle = `rgb(${Math.round(r * opacity + 255 * (1 - opacity))},${Math.round(g * opacity + 255 * (1 - opacity))},${Math.round(b * opacity + 255 * (1 - opacity))})`\n ctx.fillRect(x, 0, w, view.canvasHeight)\n }\n }\n\n // Draw day columns, backgrounds, and vertical grid lines\n const visibleStart = view.visibleTimeStart\n const visibleEnd = view.visibleTimeEnd\n const visibleDuration = visibleEnd - visibleStart\n const dayMs = 86400000\n const dayPixelWidth = (dayMs / visibleDuration) * view.canvasWidth\n\n // Determine grid line interval based on zoom level\n let stepUnit: 'day' | 'week' | 'month' = 'day'\n if (dayPixelWidth < 2) stepUnit = 'month'\n else if (dayPixelWidth < 8) stepUnit = 'week'\n\n // Draw day backgrounds (dayStyle + weekends) — batch consecutive same-style days\n if (dayStyle || true) { // always draw weekends\n let current = toDayjs(visibleStart, timezone).startOf('day')\n const end = toDayjs(visibleEnd, timezone).endOf('day')\n\n // Batch: track current fill color and start x\n let batchColor: string | null = null\n let batchOpacity = 1\n let batchStartX = 0\n const customBorderLines: { x: number; color: string }[] = []\n\n const flushBatch = (endX: number) => {\n if (batchColor !== null) {\n ctx.fillStyle = batchColor\n if (batchOpacity !== 1) ctx.globalAlpha = batchOpacity\n ctx.fillRect(batchStartX, 0, endX - batchStartX, view.canvasHeight)\n if (batchOpacity !== 1) ctx.globalAlpha = 1\n batchColor = null\n batchOpacity = 1\n }\n }\n\n while (current.isBefore(end)) {\n const x = view.timeToX(current.valueOf())\n\n const date = current.toDate()\n const custom = dayStyle?.(date)\n let color: string | null = null\n let opacity = 1\n\n if (custom?.backgroundColor) {\n color = custom.backgroundColor\n opacity = custom.opacity ?? 1\n } else {\n const dow = current.day()\n if (dow === 0 || dow === 6) {\n color = theme.grid.weekend\n }\n }\n\n // Collect custom border colors for later drawing\n if (custom?.borderColor) {\n customBorderLines.push({ x, color: custom.borderColor })\n }\n\n // Batch consecutive same-color fills\n if (color === batchColor && opacity === batchOpacity) {\n // extend batch\n } else {\n flushBatch(x)\n if (color !== null) {\n batchColor = color\n batchOpacity = opacity\n batchStartX = x\n }\n }\n\n current = current.add(1, 'day')\n }\n // Flush remaining batch\n if (batchColor !== null) {\n flushBatch(view.timeToX(current.valueOf()))\n }\n\n // Draw custom border lines from dayStyle\n for (const line of customBorderLines) {\n ctx.strokeStyle = line.color\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(line.x, 0)\n ctx.lineTo(line.x, view.canvasHeight)\n ctx.stroke()\n }\n }\n\n // Draw vertical grid lines at appropriate interval\n let current = toDayjs(visibleStart, timezone).startOf(stepUnit)\n const end = toDayjs(visibleEnd, timezone).add(1, stepUnit)\n\n ctx.strokeStyle = theme.grid.line\n ctx.lineWidth = 0.5\n ctx.beginPath()\n while (current.isBefore(end)) {\n const x = view.timeToX(current.valueOf())\n ctx.moveTo(x, 0)\n ctx.lineTo(x, view.canvasHeight)\n current = current.add(1, stepUnit)\n }\n ctx.stroke()\n\n // Draw time range highlight edge lines and labels (after grid lines so they render on top)\n if (highlights && highlights.length > 0) {\n for (const h of highlights) {\n const x1 = view.timeToX(h.start)\n const x2 = view.timeToX(h.end)\n if (x2 < 0 || x1 > view.canvasWidth) continue\n\n // Edge lines\n ctx.strokeStyle = h.color\n ctx.globalAlpha = 0.4\n ctx.lineWidth = 1\n ctx.beginPath()\n if (x1 >= 0 && x1 <= view.canvasWidth) {\n ctx.moveTo(x1, 0)\n ctx.lineTo(x1, view.canvasHeight)\n }\n if (x2 >= 0 && x2 <= view.canvasWidth) {\n ctx.moveTo(x2, 0)\n ctx.lineTo(x2, view.canvasHeight)\n }\n ctx.stroke()\n ctx.globalAlpha = 1\n\n // Label badge\n if (h.label) {\n const x = Math.max(0, x1)\n const w = Math.min(view.canvasWidth, x2) - x\n\n ctx.save()\n ctx.font = '600 10px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n const textWidth = ctx.measureText(h.label).width\n const padding = 6\n const badgeWidth = textWidth + padding * 2\n const badgeHeight = 18\n const badgeX = x + (w - badgeWidth) / 2\n const badgeY = 4\n\n ctx.fillStyle = h.color\n ctx.globalAlpha = 0.9\n ctx.beginPath()\n ctx.roundRect(badgeX, badgeY, badgeWidth, badgeHeight, 3)\n ctx.fill()\n\n ctx.globalAlpha = 1\n ctx.fillStyle = '#FFFFFF'\n ctx.textBaseline = 'middle'\n ctx.fillText(h.label, badgeX + padding, badgeY + badgeHeight / 2)\n ctx.restore()\n }\n }\n }\n }\n}\n","import type { DrawHelpers, ItemBounds } from '../types'\n\nconst ITEM_FONT = '500 12px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n\n/**\n * Creates a DrawHelpers object bound to the given canvas context and optional item bounds.\n * These helpers are passed to every itemRenderer call to simplify common canvas operations.\n */\nexport function createDrawHelpers(\n ctx: CanvasRenderingContext2D,\n bounds?: ItemBounds,\n): DrawHelpers {\n return {\n /**\n * Draws a filled rounded rectangle.\n * Default corner radius is 3px.\n */\n roundRect(x: number, y: number, w: number, h: number, radius = 3): void {\n ctx.beginPath()\n ctx.roundRect(x, y, w, h, radius)\n ctx.fill()\n },\n\n /**\n * Draws text at (x, y) using the standard item font.\n * If maxWidth is provided and the text is too wide, binary-search truncates it\n * and appends '...' so it fits within maxWidth.\n */\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n ctx.font = ITEM_FONT\n\n if (maxWidth !== undefined && ctx.measureText(text).width > maxWidth) {\n // Binary-search for the longest prefix that fits with '...' appended\n let lo = 0\n let hi = text.length\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n const candidate = text.slice(0, mid) + '...'\n if (ctx.measureText(candidate).width <= maxWidth) {\n lo = mid\n } else {\n hi = mid - 1\n }\n }\n ctx.fillText(text.slice(0, lo) + '...', x, y)\n } else {\n ctx.fillText(text, x, y)\n }\n },\n\n /**\n * Creates a 50/50 linear gradient from color1 (0%–50%) to color2 (50%–100%)\n * spanning the given x position and width.\n */\n gradient(x: number, w: number, color1: string, color2: string): CanvasGradient {\n const grad = ctx.createLinearGradient(x, 0, x + w, 0)\n grad.addColorStop(0, color1)\n grad.addColorStop(0.5, color1)\n grad.addColorStop(0.5, color2)\n grad.addColorStop(1, color2)\n return grad\n },\n\n /**\n * Draws a vertical colored bar on the left edge of the item bounds.\n * Does nothing if no bounds were provided.\n */\n leftBar(color: string, width = 3): void {\n if (!bounds) return\n ctx.save()\n ctx.fillStyle = color\n ctx.fillRect(bounds.x, bounds.y, width, bounds.height)\n ctx.restore()\n },\n\n /**\n * Draws a vector icon centered at (x, y).\n * Supported types: 'check', 'danger-red', 'danger-yellow'.\n * Default size is 14px.\n */\n icon(type: 'check' | 'danger-red' | 'danger-yellow', x: number, y: number, size = 14): void {\n ctx.save()\n const half = size / 2\n\n if (type === 'check') {\n // Green circle with white checkmark\n ctx.fillStyle = '#31c48d'\n ctx.beginPath()\n ctx.arc(x + half, y + half, half, 0, Math.PI * 2)\n ctx.fill()\n\n // Draw checkmark path\n ctx.strokeStyle = '#ffffff'\n ctx.lineWidth = size * 0.12\n ctx.beginPath()\n const cx = x + half\n const cy = y + half\n ctx.moveTo(cx - half * 0.45, cy)\n ctx.lineTo(cx - half * 0.1, cy + half * 0.42)\n ctx.lineTo(cx + half * 0.45, cy - half * 0.35)\n ctx.stroke()\n } else if (type === 'danger-red' || type === 'danger-yellow') {\n const fillColor = type === 'danger-red' ? '#EF5350' : '#FBBF24'\n\n // Triangle background\n ctx.fillStyle = fillColor\n ctx.beginPath()\n ctx.moveTo(x + half, y) // top-center\n ctx.lineTo(x + size, y + size) // bottom-right\n ctx.lineTo(x, y + size) // bottom-left\n ctx.closePath()\n ctx.fill()\n\n // Exclamation mark stem\n ctx.fillStyle = '#ffffff'\n const stemW = size * 0.12\n const stemX = x + half - stemW / 2\n ctx.fillRect(stemX, y + size * 0.35, stemW, size * 0.35)\n\n // Exclamation mark dot\n ctx.beginPath()\n ctx.arc(x + half, y + size * 0.82, stemW * 0.7, 0, Math.PI * 2)\n ctx.fill()\n }\n\n ctx.restore()\n },\n\n /**\n * Draws a pill-shaped badge with centered white text on a colored background.\n */\n badge(text: string, x: number, y: number, bgColor: string): void {\n ctx.save()\n\n // Measure text to size the pill\n ctx.font = ITEM_FONT\n const textMetrics = ctx.measureText(text)\n const textWidth = textMetrics.width\n const paddingH = 8\n const paddingV = 3\n const pillHeight = 12 + paddingV * 2\n const pillWidth = textWidth + paddingH * 2\n const radius = pillHeight / 2\n\n // Draw pill background\n ctx.fillStyle = bgColor\n ctx.beginPath()\n ctx.roundRect(x, y, pillWidth, pillHeight, radius)\n ctx.fill()\n\n // Draw centered white text\n ctx.fillStyle = '#ffffff'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(text, x + pillWidth / 2, y + pillHeight / 2)\n\n ctx.restore()\n },\n }\n}\n","import type {\n Item, Group, TimelineTheme, CanvasItemRenderer, CanvasGroupItemRenderer,\n Dependency, ItemBounds, ItemState,\n} from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { IntervalTree } from '../core/IntervalTree'\nimport type { LayoutEngine } from '../core/LayoutEngine'\nimport type { HierarchyEngine } from '../core/HierarchyEngine'\nimport { createDrawHelpers } from './DrawHelpers'\n\nexport class ItemsLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n groups: Group[],\n items: Item[],\n tree: IntervalTree<Item>,\n layout: LayoutEngine,\n itemRenderer: CanvasItemRenderer,\n groupRenderer: CanvasGroupItemRenderer | undefined,\n theme: TimelineTheme,\n selected: number[],\n hoveredItemId: number | undefined,\n dependencies?: Dependency[],\n summaryRenderer?: CanvasItemRenderer,\n hierarchy?: HierarchyEngine,\n ): void {\n // Query only visible time range + small padding (not the full 4x buffer)\n const padding = (view.visibleTimeEnd - view.visibleTimeStart) * 0.1\n const queryStart = view.visibleTimeStart - padding\n const queryEnd = view.visibleTimeEnd + padding\n const visibleItems = tree.query(queryStart, queryEnd)\n\n const groupIndexMap = new Map<string | number, number>()\n for (let i = 0; i < groups.length; i++) {\n groupIndexMap.set(groups[i].id, i)\n }\n\n const selectedSet = new Set(selected)\n const itemBoundsMap = new Map<number, ItemBounds>()\n\n // Vertical culling bounds\n const yMin = -view.lineHeight\n const yMax = view.canvasHeight + view.lineHeight\n\n for (const item of visibleItems) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n\n const itemLayout = layout.getLayout(item.id)\n if (!itemLayout) continue\n\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n\n // Skip items that are entirely off-screen vertically\n const height = itemLayout.itemHeight\n if (y + height < yMin || y > yMax) continue\n\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n\n const bounds: ItemBounds = { x, y, width, height }\n itemBoundsMap.set(item.id, bounds)\n\n const state: ItemState = {\n selected: selectedSet.has(item.id),\n hovered: hoveredItemId === item.id,\n dragging: false,\n filtered: item.filtered !== false,\n }\n\n ctx.save()\n const helpers = createDrawHelpers(ctx, bounds)\n let renderer: CanvasItemRenderer\n if (summaryRenderer && hierarchy?.isParent(item.id)) {\n renderer = summaryRenderer\n } else if (groupRenderer && (item.type === 'control_area_group' || item.type === 'construction_train')) {\n renderer = groupRenderer\n } else {\n renderer = itemRenderer\n }\n renderer(ctx, item, bounds, state, helpers)\n ctx.restore()\n }\n\n if (dependencies && dependencies.length > 0) {\n // Build a full item map for dependency endpoint lookup (off-screen items too)\n const depItemIds = new Set<number>()\n for (const dep of dependencies) {\n if (!itemBoundsMap.has(dep.fromItemId)) depItemIds.add(dep.fromItemId)\n if (!itemBoundsMap.has(dep.toItemId)) depItemIds.add(dep.toItemId)\n }\n if (depItemIds.size > 0) {\n const itemMap = new Map<number, Item>()\n for (const item of items) {\n if (depItemIds.has(item.id)) itemMap.set(item.id, item)\n }\n for (const [id, item] of itemMap) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n const itemLayout = layout.getLayout(id)\n if (!itemLayout) continue\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n itemBoundsMap.set(id, { x, y, width, height: itemLayout.itemHeight })\n }\n }\n this.drawDependencies(ctx, dependencies, itemBoundsMap, hoveredItemId, theme)\n }\n }\n\n private drawDependencies(\n ctx: CanvasRenderingContext2D,\n dependencies: Dependency[],\n boundsMap: Map<number, ItemBounds>,\n hoveredItemId: number | undefined,\n theme: TimelineTheme,\n ): void {\n for (const dep of dependencies) {\n const fromBounds = boundsMap.get(dep.fromItemId)\n const toBounds = boundsMap.get(dep.toItemId)\n if (!fromBounds || !toBounds) continue\n\n const isHighlighted = hoveredItemId === dep.fromItemId || hoveredItemId === dep.toItemId\n\n ctx.strokeStyle = isHighlighted ? theme.primary : (dep.color ?? '#94A3B8')\n ctx.lineWidth = isHighlighted ? 2 : 1.5\n ctx.setLineDash([])\n\n const startX = fromBounds.x + fromBounds.width\n const startY = fromBounds.y + fromBounds.height / 2\n const endX = toBounds.x\n const endY = toBounds.y + toBounds.height / 2\n\n const dx = Math.abs(endX - startX)\n const cpOffset = Math.max(dx * 0.4, 30)\n\n ctx.beginPath()\n ctx.moveTo(startX, startY)\n ctx.bezierCurveTo(startX + cpOffset, startY, endX - cpOffset, endY, endX, endY)\n ctx.stroke()\n\n // Arrowhead\n const arrowSize = 6\n ctx.fillStyle = ctx.strokeStyle\n ctx.beginPath()\n ctx.moveTo(endX, endY)\n ctx.lineTo(endX - arrowSize, endY - arrowSize / 2)\n ctx.lineTo(endX - arrowSize, endY + arrowSize / 2)\n ctx.closePath()\n ctx.fill()\n }\n }\n}\n","import type { TimelineTheme, MarkerConfig, ItemBounds, Item, CanvasItemRenderer } from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { InteractionMode } from '../interaction/InteractionHandler'\nimport { createDrawHelpers } from './DrawHelpers'\n\nexport interface InteractionRenderState {\n item: Item\n mode: InteractionMode\n bounds: ItemBounds\n renderer: CanvasItemRenderer\n targetGroupY?: number\n groupChanged?: boolean\n}\n\nexport interface OverlayDrawOptions {\n cursorX: number | null\n snapX?: number | null\n markers?: MarkerConfig[]\n\n interaction?: InteractionRenderState | null\n}\n\nexport class OverlayLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n theme: TimelineTheme,\n options: OverlayDrawOptions,\n ): void {\n const { cursorX, snapX, markers, interaction } = options\n\n // Draw markers\n if (markers) {\n for (const marker of markers) {\n const x = view.timeToX(marker.date)\n\n ctx.fillStyle = marker.color\n ctx.fillRect(x - marker.width / 2, 0, marker.width, view.canvasHeight)\n\n if (marker.label) {\n ctx.save()\n ctx.font = '500 10px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n const textWidth = ctx.measureText(marker.label).width\n const padding = 8\n const maxBadgeWidth = 200\n const badgeWidth = Math.min(textWidth + padding * 2, maxBadgeWidth)\n const badgeHeight = 20\n const badgeX = x - badgeWidth / 2\n const badgeY = 4\n\n ctx.fillStyle = marker.color\n ctx.beginPath()\n ctx.roundRect(badgeX, badgeY, badgeWidth, badgeHeight, 3)\n ctx.fill()\n\n ctx.fillStyle = '#FFFFFF'\n ctx.textBaseline = 'middle'\n const maxTextWidth = maxBadgeWidth - padding * 2\n const displayText = textWidth > maxTextWidth\n ? marker.label.slice(0, Math.floor(marker.label.length * maxTextWidth / textWidth)) + '…'\n : marker.label\n ctx.fillText(displayText, badgeX + padding, badgeY + badgeHeight / 2)\n ctx.restore()\n }\n }\n }\n\n // Draw cursor line\n if (cursorX !== null && cursorX !== undefined) {\n ctx.strokeStyle = theme.marker.cursor\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(cursorX, 0)\n ctx.lineTo(cursorX, view.canvasHeight)\n ctx.stroke()\n }\n\n // Draw snap guide line\n if (snapX !== null && snapX !== undefined) {\n ctx.strokeStyle = theme.primary\n ctx.lineWidth = 1\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(snapX, 0)\n ctx.lineTo(snapX, view.canvasHeight)\n ctx.stroke()\n ctx.setLineDash([])\n }\n\n // Draw interaction ghost (move, resize-left, resize-right)\n if (interaction) {\n // Group highlight band when moving to a different group\n if (interaction.groupChanged && interaction.targetGroupY !== undefined) {\n ctx.fillStyle = 'rgba(59, 130, 246, 0.08)'\n ctx.fillRect(0, interaction.targetGroupY, view.canvasWidth, view.lineHeight)\n }\n\n ctx.save()\n ctx.globalAlpha = 0.5\n const helpers = createDrawHelpers(ctx, interaction.bounds)\n interaction.renderer(\n ctx, interaction.item, interaction.bounds,\n { selected: false, hovered: false, dragging: true, filtered: true },\n helpers,\n )\n ctx.restore()\n }\n }\n}\n","const MAX_DELTA = 120\n\n/**\n * Normalize wheel delta across browsers/platforms.\n * deltaMode 0 = pixels, 1 = lines (×15), 2 = pages (×800).\n * Clamp to ±120 to prevent erratic jumps.\n */\nfunction normalizeDelta(e: WheelEvent): number {\n let delta = e.deltaY || e.deltaX\n if (e.deltaMode === 1) delta *= 15\n else if (e.deltaMode === 2) delta *= 800\n return Math.max(-MAX_DELTA, Math.min(MAX_DELTA, delta))\n}\n\nexport class ZoomHandler {\n private onZoom: (newStart: number, newEnd: number) => void\n private visibleTimeStart: number\n private visibleTimeEnd: number\n private minZoom: number\n private maxZoom: number\n\n constructor(\n onZoom: (newStart: number, newEnd: number) => void,\n visibleTimeStart: number,\n visibleTimeEnd: number,\n minZoom: number,\n maxZoom: number,\n ) {\n this.onZoom = onZoom\n this.visibleTimeStart = visibleTimeStart\n this.visibleTimeEnd = visibleTimeEnd\n this.minZoom = minZoom\n this.maxZoom = maxZoom\n }\n\n updateBounds(start: number, end: number): void {\n this.visibleTimeStart = start\n this.visibleTimeEnd = end\n }\n\n handleWheelZoom(e: WheelEvent, cursorRatio: number): void {\n const delta = normalizeDelta(e)\n // Speed: ctrlKey (trackpad pinch) = 10, metaKey = 3, altKey = 1\n const speed = e.ctrlKey ? 10 : e.metaKey ? 3 : 1\n\n // Reciprocal formula for symmetric zoom-in / zoom-out\n const scale = delta > 0\n ? 1.0 + (speed * delta) / 500\n : 1.0 / (1.0 + (speed * -delta) / 500)\n\n const currentDuration = this.visibleTimeEnd - this.visibleTimeStart\n let newDuration = Math.round(currentDuration * scale)\n newDuration = Math.max(this.minZoom, Math.min(this.maxZoom, newDuration))\n\n const newStart = Math.round(this.visibleTimeStart + (currentDuration - newDuration) * cursorRatio)\n const newEnd = newStart + newDuration\n\n this.onZoom(newStart, newEnd)\n }\n}\n","import type { Item } from '../types'\n\nconst ACTIVATION_THRESHOLD = 4\n\nexport type InteractionMode = 'move' | 'resize-left' | 'resize-right'\n\nexport interface InteractionState {\n item: Item\n mode: InteractionMode\n startX: number\n startY: number\n currentX: number\n currentY: number\n deltaX: number\n originalGroup: string | number\n currentGroup: string | number\n}\n\nexport class InteractionHandler {\n private state: InteractionState | null = null\n private dragSnap: number\n private activated = false\n\n constructor(dragSnap: number) {\n this.dragSnap = dragSnap\n }\n\n startInteraction(item: Item, mode: InteractionMode, x: number, y: number): void {\n this.state = {\n item, mode, startX: x, startY: y, currentX: x, currentY: y,\n deltaX: 0, originalGroup: item.group, currentGroup: item.group,\n }\n this.activated = false\n }\n\n update(x: number, y: number): void {\n if (!this.state) return\n this.state.currentX = x\n this.state.currentY = y\n this.state.deltaX = x - this.state.startX\n if (!this.activated && Math.abs(this.state.deltaX) >= ACTIVATION_THRESHOLD) {\n this.activated = true\n }\n }\n\n setCurrentGroup(groupId: string | number): void {\n if (this.state) this.state.currentGroup = groupId\n }\n\n endMove(pixelsPerMs: number): { newStartTime: number; newGroupId: string | number } | null {\n if (!this.state) return null\n const deltaMs = this.state.deltaX / pixelsPerMs\n const newStartTime = this.state.item.start_time + deltaMs\n const snapped = Math.round(newStartTime / this.dragSnap) * this.dragSnap\n const newGroupId = this.state.currentGroup\n this.state = null\n this.activated = false\n return { newStartTime: snapped, newGroupId }\n }\n\n endResize(pixelsPerMs: number): { newTime: number; edge: 'left' | 'right' } | null {\n if (!this.state) return null\n const deltaMs = this.state.deltaX / pixelsPerMs\n const edge = this.state.mode === 'resize-left' ? 'left' as const : 'right' as const\n const baseTime = edge === 'left' ? this.state.item.start_time : this.state.item.end_time\n const newTime = baseTime + deltaMs\n const snapped = Math.round(newTime / this.dragSnap) * this.dragSnap\n this.state = null\n this.activated = false\n return { newTime: snapped, edge }\n }\n\n cancel(): void {\n this.state = null\n this.activated = false\n }\n\n getState(): InteractionState | null {\n return this.state\n }\n\n getMode(): InteractionMode | null {\n return this.state?.mode ?? null\n }\n\n isActive(): boolean {\n return this.state !== null && this.activated\n }\n\n isPending(): boolean {\n return this.state !== null\n }\n}\n","interface SnapItem {\n id: number\n start_time: number\n end_time: number\n}\n\n/**\n * Collect start and end X positions from all items except the dragged item.\n */\nexport function collectItemEdges(\n items: SnapItem[],\n excludeItemId: number,\n timeToX: (time: number) => number,\n): number[] {\n const edges: number[] = []\n for (const item of items) {\n if (item.id === excludeItemId) continue\n edges.push(timeToX(item.start_time))\n edges.push(timeToX(item.end_time))\n }\n return edges\n}\n\n/**\n * Find the best snap target from a list of edge X positions.\n * Returns the snapped X position if an edge is within threshold, or null to fall back to time-grid snap.\n */\nexport function findSnapTarget(\n currentX: number,\n edgeXPositions: number[],\n thresholdPx: number,\n _pixelsPerMs: number,\n _dragSnap: number,\n): number | null {\n if (edgeXPositions.length === 0) return null\n\n let closestX = edgeXPositions[0]\n let closestDist = Math.abs(currentX - closestX)\n\n for (let i = 1; i < edgeXPositions.length; i++) {\n const dist = Math.abs(currentX - edgeXPositions[i])\n if (dist < closestDist) {\n closestDist = dist\n closestX = edgeXPositions[i]\n }\n }\n\n if (closestDist <= thresholdPx) {\n return closestX\n }\n\n return null\n}\n","import type { Item, InteractionInfo } from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { IntervalTree } from '../core/IntervalTree'\nimport type { HierarchyEngine } from '../core/HierarchyEngine'\nimport type { InteractionState } from './InteractionHandler'\nimport { findSnapTarget, collectItemEdges } from './snapUtils'\n\n/** The subset of props the snap helpers need. */\nexport interface SnapDeps {\n canvasWidth: number\n dragSnap: number\n intervalTree: IntervalTree<Item>\n hierarchyEngine: HierarchyEngine\n}\n\n/** Snapped new start time for a move, matching the pointer-up commit path:\n * item-edge snap (start edge first, then end edge) with grid snap as fallback. */\nexport function snappedMoveStart(state: InteractionState, vs: ViewState, p: SnapDeps): number {\n const pixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = state.deltaX / pixelsPerMs\n const rawStart = state.item.start_time + deltaMs\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, state.item.id, (t) => vs.timeToX(t))\n const startSnap = findSnapTarget(vs.timeToX(rawStart), otherEdges, 8, pixelsPerMs, p.dragSnap)\n if (startSnap !== null) return vs.xToTime(startSnap)\n const endSnap = findSnapTarget(vs.timeToX(state.item.end_time + deltaMs), otherEdges, 8, pixelsPerMs, p.dragSnap)\n if (endSnap !== null) return vs.xToTime(endSnap) - (state.item.end_time - state.item.start_time)\n return Math.round(rawStart / p.dragSnap) * p.dragSnap\n}\n\n/** Snapped edge time for a resize, matching the pointer-up commit path: item-edge\n * snap with grid-snap fallback, then hierarchy resize constraints. */\nexport function snappedResizeEdge(state: InteractionState, vs: ViewState, p: SnapDeps): { edge: 'left' | 'right'; time: number } {\n const pixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = state.deltaX / pixelsPerMs\n const edge = state.mode === 'resize-left' ? 'left' as const : 'right' as const\n const rawEdgeTime = (edge === 'left' ? state.item.start_time : state.item.end_time) + deltaMs\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, state.item.id, (t) => vs.timeToX(t))\n const snap = findSnapTarget(vs.timeToX(rawEdgeTime), otherEdges, 8, pixelsPerMs, p.dragSnap)\n let time = snap !== null ? vs.xToTime(snap) : Math.round(rawEdgeTime / p.dragSnap) * p.dragSnap\n const constraint = p.hierarchyEngine.getResizeConstraint(state.item.id, edge)\n if (edge === 'left' && time > constraint.max) time = constraint.max\n else if (edge === 'right' && time < constraint.min) time = constraint.min\n return { edge, time }\n}\n\n/** Build the public InteractionInfo payload for the current drag/resize state. */\nexport function buildInteractionInfo(\n state: InteractionState,\n vs: ViewState,\n p: SnapDeps,\n pointer: { x: number; y: number },\n): InteractionInfo {\n if (state.mode === 'move') {\n const startTime = snappedMoveStart(state, vs, p)\n const duration = state.item.end_time - state.item.start_time\n return { itemId: state.item.id, mode: 'move', time: startTime, startTime, endTime: startTime + duration, pointerX: pointer.x, pointerY: pointer.y }\n }\n const { edge, time } = snappedResizeEdge(state, vs, p)\n const startTime = edge === 'left' ? time : state.item.start_time\n const endTime = edge === 'right' ? time : state.item.end_time\n return { itemId: state.item.id, mode: state.mode, edge, time, startTime, endTime, pointerX: pointer.x, pointerY: pointer.y }\n}\n","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_isoWeek=t()}(this,(function(){\"use strict\";var e=\"day\";return function(t,i,s){var a=function(t){return t.add(4-t.isoWeekday(),e)},d=i.prototype;d.isoWeekYear=function(){return a(this).year()},d.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),e);var i,d,n,o,r=a(this),u=(i=this.isoWeekYear(),d=this.$u,n=(d?s.utc:s)().year(i).startOf(\"year\"),o=4-n.isoWeekday(),n.isoWeekday()>4&&(o+=7),n.add(o,e));return r.diff(u,\"week\")+1},d.isoWeekday=function(e){return this.$utils().u(e)?this.day()||7:this.day(this.day()%7?e:e-7)};var n=d.startOf;d.startOf=function(e,t){var i=this.$utils(),s=!!i.u(t)||t;return\"isoweek\"===i.p(e)?s?this.date(this.date()-(this.isoWeekday()-1)).startOf(\"day\"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf(\"day\"):n.bind(this)(e,t)}}}));","import React, { useRef, useCallback, useEffect, useMemo } from 'react'\nimport type { Group, TimelineTheme } from '../types'\n\ninterface SidebarProps {\n groups: Group[]\n width: number\n lineHeight: number\n groupHeights?: number[]\n scrollTop: number\n canvasHeight: number\n theme: TimelineTheme\n groupRenderer: (group: Group) => React.ReactNode\n onScroll: (scrollTop: number) => void\n}\n\nconst OVERSCAN_PX = 200\n\nexport function Sidebar({\n groups, width, lineHeight, groupHeights, scrollTop, canvasHeight, theme, groupRenderer, onScroll,\n}: SidebarProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false)\n\n // Cumulative top-edge offsets per group: length = groups.length + 1.\n const offsets = useMemo(() => {\n const arr = new Array<number>(groups.length + 1)\n arr[0] = 0\n for (let i = 0; i < groups.length; i++) {\n arr[i + 1] = arr[i] + (groupHeights?.[i] ?? lineHeight)\n }\n return arr\n }, [groups.length, groupHeights, lineHeight])\n\n const totalHeight = offsets[groups.length] ?? 0\n const displayHeight = canvasHeight\n\n // Binary search for the group containing a given y; clamped to [0, groups.length - 1].\n const groupAtY = useCallback((y: number): number => {\n if (groups.length === 0) return 0\n if (y <= 0) return 0\n if (y >= totalHeight) return groups.length - 1\n let lo = 0\n let hi = groups.length - 1\n while (lo < hi) {\n const mid = (lo + hi) >>> 1\n if (offsets[mid + 1] > y) hi = mid\n else lo = mid + 1\n }\n return lo\n }, [groups.length, offsets, totalHeight])\n\n const firstVisible = groupAtY(scrollTop - OVERSCAN_PX)\n const lastVisible = groupAtY(scrollTop + canvasHeight + OVERSCAN_PX)\n\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n if (isScrollingRef.current) return\n onScroll(e.currentTarget.scrollTop)\n }, [onScroll])\n\n useEffect(() => {\n if (containerRef.current) {\n isScrollingRef.current = true\n containerRef.current.scrollTop = scrollTop\n requestAnimationFrame(() => { isScrollingRef.current = false })\n }\n }, [scrollTop])\n\n const visibleGroups = []\n for (let i = firstVisible; i <= lastVisible; i++) {\n const group = groups[i]\n if (!group) continue\n const top = offsets[i]\n const height = offsets[i + 1] - top\n visibleGroups.push(\n <div\n key={group.id}\n style={{\n position: 'absolute',\n top,\n height,\n width: '100%',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'stretch',\n borderBottom: `1px solid ${theme.grid?.line ?? '#E5E5E5'}`,\n boxSizing: 'border-box',\n }}\n >\n {groupRenderer(group)}\n </div>,\n )\n }\n\n return (\n <div\n ref={containerRef}\n onScroll={handleScroll}\n style={{\n width,\n height: displayHeight,\n overflowY: totalHeight > canvasHeight ? 'auto' : 'hidden',\n overflowX: 'hidden',\n position: 'relative',\n borderRight: `1px solid ${theme.sidebar.border}`,\n backgroundColor: theme.sidebar.bg,\n }}\n >\n <div style={{ height: totalHeight, position: 'relative' }}>{visibleGroups}</div>\n </div>\n )\n}\n","import type { MarkerConfig } from '../types'\n\ninterface TodayMarkerProps {\n color?: string\n width?: number\n label?: string\n /** Auto-update interval in ms. Default 10000 (10s). Set 0 to disable. */\n interval?: number\n}\n\nexport function TodayMarker(_props: TodayMarkerProps) { return null }\nTodayMarker.displayName = 'TodayMarker'\n\nexport function getTodayMarkerConfig(props: TodayMarkerProps): MarkerConfig {\n // Snap to current minute to avoid unnecessary redraws\n const now = Math.floor(Date.now() / 60000) * 60000\n return { date: now, color: props.color ?? '#FD7171', width: props.width ?? 6, label: props.label }\n}\n\nexport function getTodayMarkerInterval(props: TodayMarkerProps): number {\n return props.interval ?? 10000\n}\n","import type { MarkerConfig } from '../types'\n\ninterface CustomMarkerProps {\n date: number\n color?: string\n width?: number\n label?: string\n}\n\nexport function CustomMarker(_props: CustomMarkerProps) { return null }\nCustomMarker.displayName = 'CustomMarker'\n\nexport function getCustomMarkerConfig(props: CustomMarkerProps): MarkerConfig {\n return {\n date: props.date,\n color: props.color ?? '#3B82F6',\n width: props.width ?? 4,\n label: props.label,\n }\n}\n","import React, { useRef, useEffect, useState, useCallback, useMemo, useImperativeHandle, forwardRef } from 'react'\nimport { flushSync } from 'react-dom'\nimport type {\n CanvasTimelineProps,\n CanvasTimelineRef,\n MarkerConfig,\n TimelineTheme,\n Item,\n ItemBounds,\n ItemState,\n DrawHelpers,\n} from './types'\nimport { DEFAULT_THEME } from './types'\nimport { ViewState } from './core/ViewState'\nimport { IntervalTree } from './core/IntervalTree'\nimport { LayoutEngine } from './core/LayoutEngine'\nimport { HierarchyEngine } from './core/HierarchyEngine'\nimport { defaultSummaryRenderer } from './canvas/defaultSummaryRenderer'\nimport { hitTest, hitTestGroup } from './core/HitTest'\nimport { setupCanvas, clearCanvas, RenderScheduler } from './canvas/CanvasManager'\nimport { GridLayer } from './canvas/GridLayer'\nimport { ItemsLayer } from './canvas/ItemsLayer'\nimport { OverlayLayer } from './canvas/OverlayLayer'\nimport { ZoomHandler } from './interaction/ZoomHandler'\nimport { InteractionHandler } from './interaction/InteractionHandler'\nimport type { InteractionMode } from './interaction/InteractionHandler'\nimport { findSnapTarget, collectItemEdges } from './interaction/snapUtils'\nimport { snappedMoveStart, snappedResizeEdge, buildInteractionInfo } from './interaction/interactionInfo'\nimport { detectEdge, resolveInteractionMode } from './core/HitTest'\nimport dayjs from 'dayjs'\nimport isoWeek from 'dayjs/plugin/isoWeek'\nimport { toDayjs } from './utils/timezone'\nimport { Sidebar } from './dom/Sidebar'\nimport { getTodayMarkerConfig, getTodayMarkerInterval } from './dom/TodayMarker'\nimport { getCustomMarkerConfig } from './dom/CustomMarker'\n\ndayjs.extend(isoWeek)\n\nfunction mergeTheme(partial?: Partial<TimelineTheme>): TimelineTheme {\n if (!partial) return DEFAULT_THEME\n return {\n ...DEFAULT_THEME,\n ...partial,\n status: { ...DEFAULT_THEME.status, ...partial.status },\n grid: { ...DEFAULT_THEME.grid, ...partial.grid },\n item: { ...DEFAULT_THEME.item, ...partial.item },\n marker: { ...DEFAULT_THEME.marker, ...partial.marker },\n sidebar: { ...DEFAULT_THEME.sidebar, ...partial.sidebar },\n header: { ...DEFAULT_THEME.header, ...partial.header },\n }\n}\n\nconst HEADER_THROTTLE_MS = 32\n\nexport const CanvasTimeline = React.memo(forwardRef<CanvasTimelineRef, CanvasTimelineProps>(function CanvasTimeline(props, ref) {\n const {\n groups,\n items,\n defaultTimeStart,\n defaultTimeEnd,\n sidebarWidth,\n lineHeight,\n itemHeightRatio,\n stackItems,\n canMove,\n canChangeGroup,\n canResize,\n dragSnap,\n minZoom,\n maxZoom,\n theme: themePartial,\n dayStyle,\n rowStyle,\n showCursorLine,\n itemRenderer,\n groupRenderer,\n sidebarGroupRenderer,\n dependencies,\n highlights,\n onItemClick,\n onItemDoubleClick,\n onItemContextMenu,\n onItemMove,\n onItemResize,\n moveResizeValidator,\n onItemHover,\n onInteractionUpdate,\n onCanvasDoubleClick,\n onCanvasContextMenu,\n onTimeChange,\n onZoom,\n selected: selectedProp = [],\n rightSidebarWidth,\n rightSidebarGroupRenderer,\n onReady,\n maxHeight,\n timezone,\n devBadge,\n children,\n } = props\n\n const theme = useMemo(() => mergeTheme(themePartial), [themePartial])\n\n const getGroupIndex = useCallback((groupId: string | number, grps: typeof groups) => {\n for (let i = 0; i < grps.length; i++) {\n if (grps[i].id === groupId) return i\n }\n return 0\n }, [])\n\n const selectedKey = selectedProp.join(',')\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const selected = useMemo(() => selectedProp, [selectedKey])\n\n const gridCanvasRef = useRef<HTMLCanvasElement>(null)\n const itemsCanvasRef = useRef<HTMLCanvasElement>(null)\n const overlayCanvasRef = useRef<HTMLCanvasElement>(null)\n const interactionRef = useRef<HTMLDivElement>(null)\n const outerRef = useRef<HTMLDivElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const [containerWidth, setContainerWidth] = useState(800)\n const [measuredHeight, setMeasuredHeight] = useState<number | null>(null)\n\n useEffect(() => {\n const container = outerRef.current\n if (!container) return\n const obs = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) {\n setContainerWidth(entry.contentRect.width)\n }\n })\n obs.observe(container)\n return () => obs.disconnect()\n }, [])\n\n // Measure actual resolved height of the body container (handles CSS calc values)\n useEffect(() => {\n const el = containerRef.current\n if (!el || !maxHeight) return\n const obs = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setMeasuredHeight(entry.contentRect.height)\n })\n obs.observe(el)\n return () => obs.disconnect()\n }, [maxHeight])\n\n const canvasWidth = Math.max(0, containerWidth - sidebarWidth - (rightSidebarWidth ?? 0))\n\n // --- CORE DATA STRUCTURES ---\n const hierarchyEngine = useMemo(() => {\n const engine = new HierarchyEngine()\n engine.rebuild(items)\n return engine\n }, [items])\n\n const intervalTree = useMemo(() => {\n const tree = new IntervalTree<(typeof items)[0]>()\n tree.buildFromItems(\n items,\n (i) => hierarchyEngine.getEffectiveSpan(i.id).start,\n (i) => hierarchyEngine.getEffectiveSpan(i.id).end,\n )\n return tree\n }, [items, hierarchyEngine])\n\n const layoutEngine = useMemo(() => {\n const engine = new LayoutEngine(lineHeight, itemHeightRatio)\n engine.computeLayout(items, stackItems, hierarchyEngine)\n return engine\n }, [items, lineHeight, itemHeightRatio, stackItems, hierarchyEngine])\n\n const groupHeights = useMemo(\n () => groups.map((g) => layoutEngine.getGroupHeight(g.id)),\n [groups, layoutEngine],\n )\n const totalHeight = useMemo(\n () => groupHeights.reduce((a, b) => a + b, 0),\n [groupHeights],\n )\n const resolvedMaxHeight = typeof maxHeight === 'number' ? maxHeight : measuredHeight\n const canvasHeight = resolvedMaxHeight ? Math.min(totalHeight, resolvedMaxHeight) : totalHeight\n\n // --- MUTABLE VIEW STATE (hot path) ---\n const viewStateRef = useRef<ViewState>(\n new ViewState({\n visibleTimeStart: props.visibleTimeStart ?? defaultTimeStart,\n visibleTimeEnd: props.visibleTimeEnd ?? defaultTimeEnd,\n canvasWidth,\n canvasHeight,\n sidebarWidth,\n lineHeight,\n groupCount: groups.length,\n buffer: props.buffer ?? 3,\n scrollTop: 0,\n groupHeights,\n }),\n )\n\n const cursorXRef = useRef<number | null>(null)\n const hoveredItemIdRef = useRef<number | undefined>(undefined)\n // Viewport-space pointer position, for positioning the interaction tooltip.\n const pointerClientRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 })\n // Whether onInteractionUpdate was last fired with a non-null payload, so we\n // emit the terminating `null` exactly once when the drag/resize ends.\n const interactionActiveRef = useRef(false)\n\n // --- PAN STATE ---\n const panRef = useRef<{ startX: number; startY: number; lastX: number; lastY: number } | null>(null)\n const didPanRef = useRef(false)\n const PAN_THRESHOLD = 4\n\n // --- THROTTLED HEADER STATE ---\n const [headerTimeStart, setHeaderTimeStart] = useState(props.visibleTimeStart ?? defaultTimeStart)\n const [headerTimeEnd, setHeaderTimeEnd] = useState(props.visibleTimeEnd ?? defaultTimeEnd)\n const [sidebarScrollTop, setSidebarScrollTop] = useState(0)\n const headerTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const syncHeaderState = useCallback(() => {\n const vs = viewStateRef.current\n setHeaderTimeStart(vs.visibleTimeStart)\n setHeaderTimeEnd(vs.visibleTimeEnd)\n setSidebarScrollTop(vs.scrollTop)\n headerTimerRef.current = null\n }, [])\n\n const scheduleHeaderSync = useCallback(() => {\n if (headerTimerRef.current !== null) return\n headerTimerRef.current = setTimeout(syncHeaderState, HEADER_THROTTLE_MS)\n }, [syncHeaderState])\n\n useEffect(() => {\n return () => { if (headerTimerRef.current !== null) clearTimeout(headerTimerRef.current) }\n }, [])\n\n const resolvedSummaryRenderer = useMemo(() => {\n if (props.summaryRenderer) return props.summaryRenderer\n return (ctx: CanvasRenderingContext2D, item: Item, bounds: ItemBounds, state: ItemState, helpers: DrawHelpers) => {\n defaultSummaryRenderer(ctx, item, bounds, state, helpers, theme)\n }\n }, [props.summaryRenderer, theme])\n\n const gridLayer = useMemo(() => new GridLayer(), [])\n const itemsLayer = useMemo(() => new ItemsLayer(), [])\n const overlayLayer = useMemo(() => new OverlayLayer(), [])\n const interactionHandler = useMemo(() => new InteractionHandler(dragSnap), [dragSnap])\n\n // --- MARKERS ---\n const markerConfigs = useMemo(() => {\n const configs: MarkerConfig[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n configs.push(getTodayMarkerConfig(child.props as { color?: string; width?: number; label?: string }))\n } else if (displayName === 'CustomMarker') {\n configs.push(getCustomMarkerConfig(child.props as { date: number; color?: string; width?: number; label?: string }))\n }\n })\n return configs\n }, [children])\n const markersKey = useMemo(() => markerConfigs.map(m => `${m.date}|${m.color}|${m.width}|${m.label ?? ''}`).join(';'), [markerConfigs])\n const markersRef = useRef(markerConfigs)\n markersRef.current = markerConfigs\n\n // TodayMarker auto-update: refresh overlay on interval\n const todayMarkerInterval = useMemo(() => {\n let interval = 0\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n interval = getTodayMarkerInterval(child.props as { interval?: number })\n }\n })\n return interval\n }, [children])\n\n // --- PROPS REF ---\n const propsRef = useRef({\n groups, items, intervalTree, layoutEngine, itemRenderer, groupRenderer,\n theme, selected, dependencies, highlights, dayStyle, rowStyle, showCursorLine,\n canvasWidth, canvasHeight, lineHeight, itemHeightRatio,\n onTimeChange, onZoom, onItemHover, onItemClick, onItemDoubleClick,\n onItemContextMenu, onItemMove, onItemResize, onInteractionUpdate, onCanvasDoubleClick, onCanvasContextMenu,\n canMove, canResize, canChangeGroup, dragSnap, sidebarWidth, moveResizeValidator,\n summaryRenderer: resolvedSummaryRenderer, hierarchyEngine, timezone,\n })\n propsRef.current = {\n groups, items, intervalTree, layoutEngine, itemRenderer, groupRenderer,\n theme, selected, dependencies, highlights, dayStyle, rowStyle, showCursorLine,\n canvasWidth, canvasHeight, lineHeight, itemHeightRatio,\n onTimeChange, onZoom, onItemHover, onItemClick, onItemDoubleClick,\n onItemContextMenu, onItemMove, onItemResize, onInteractionUpdate, onCanvasDoubleClick, onCanvasContextMenu,\n canMove, canResize, canChangeGroup, dragSnap, sidebarWidth, moveResizeValidator,\n summaryRenderer: resolvedSummaryRenderer, hierarchyEngine, timezone,\n }\n\n // --- DRAW FUNCTIONS ---\n const drawGrid = useCallback(() => {\n const canvas = gridCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n gridLayer.draw(ctx, viewStateRef.current, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights, p.timezone)\n }, [gridLayer])\n\n const drawItems = useCallback(() => {\n const canvas = itemsCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n itemsLayer.draw(\n ctx, viewStateRef.current, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, hoveredItemIdRef.current, p.dependencies,\n p.summaryRenderer, p.hierarchyEngine,\n )\n }, [itemsLayer])\n\n const calculateSnapX = useCallback((item: (typeof items)[0], deltaX: number, mode: InteractionMode) => {\n const vs = viewStateRef.current\n const p = propsRef.current\n const pixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = deltaX / pixelsPerMs\n\n // Determine which edges of the dragged item to check\n const draggedEdgeXs: number[] = []\n if (mode === 'move') {\n draggedEdgeXs.push(vs.timeToX(item.start_time + deltaMs))\n draggedEdgeXs.push(vs.timeToX(item.end_time + deltaMs))\n } else if (mode === 'resize-left') {\n draggedEdgeXs.push(vs.timeToX(item.start_time + deltaMs))\n } else {\n draggedEdgeXs.push(vs.timeToX(item.end_time + deltaMs))\n }\n\n // Collect other items' edges\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, item.id, (t) => vs.timeToX(t))\n\n // Check each dragged edge against other items' edges\n for (const edgeX of draggedEdgeXs) {\n const snapX = findSnapTarget(edgeX, otherEdges, 8, pixelsPerMs, p.dragSnap)\n if (snapX !== null) return snapX\n }\n\n // Fall back to time grid snap — snap the edge being dragged, not the start\n const edgeTime = mode === 'resize-right'\n ? item.end_time + deltaMs\n : item.start_time + deltaMs\n const snapped = Math.round(edgeTime / p.dragSnap) * p.dragSnap\n return vs.timeToX(snapped)\n }, [])\n\n const drawOverlay = useCallback(() => {\n const canvas = overlayCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n\n const vs = viewStateRef.current\n const state = interactionHandler.getState()\n let interactionRender = null\n if (state) {\n const origX = vs.timeToX(state.item.start_time)\n const origWidth = vs.timeToX(state.item.end_time) - origX\n let x: number, width: number\n if (state.mode === 'resize-left') {\n x = origX + state.deltaX\n width = origWidth - state.deltaX\n } else if (state.mode === 'resize-right') {\n x = origX\n width = origWidth + state.deltaX\n } else {\n // move\n x = origX + state.deltaX\n width = origWidth\n }\n const groupIndex = getGroupIndex(state.currentGroup, p.groups)\n const targetGroupY = vs.groupIndexToY(groupIndex)\n const groupChanged = state.currentGroup !== state.originalGroup\n interactionRender = {\n item: state.item,\n mode: state.mode,\n bounds: { x, y: targetGroupY + (p.lineHeight - p.lineHeight * p.itemHeightRatio) / 2, width, height: p.lineHeight * p.itemHeightRatio },\n renderer: p.itemRenderer,\n targetGroupY,\n groupChanged,\n }\n }\n\n overlayLayer.draw(ctx, vs, p.theme, {\n cursorX: p.showCursorLine ? cursorXRef.current : null,\n snapX: state ? calculateSnapX(state.item, state.deltaX, state.mode) : null,\n markers: markersRef.current,\n interaction: interactionRender,\n })\n\n // Live drag/resize tooltip feed. Rides the rAF-coalesced overlay draw, so\n // this fires at most once per frame. Emits a terminating `null` once the\n // interaction clears (pointer-up also marks the overlay dirty).\n if (p.onInteractionUpdate) {\n if (state) {\n p.onInteractionUpdate(buildInteractionInfo(state, vs, p, pointerClientRef.current))\n interactionActiveRef.current = true\n } else if (interactionActiveRef.current) {\n interactionActiveRef.current = false\n p.onInteractionUpdate(null)\n }\n }\n }, [overlayLayer, interactionHandler, calculateSnapX, getGroupIndex])\n\n // --- RENDER SCHEDULER ---\n const schedulerRef = useRef<RenderScheduler | null>(null)\n if (!schedulerRef.current) {\n schedulerRef.current = new RenderScheduler((flags) => {\n if (flags.grid) drawGrid()\n if (flags.items) drawItems()\n if (flags.overlay) drawOverlay()\n })\n }\n const scheduler = schedulerRef.current\n\n useEffect(() => {\n return () => scheduler.dispose()\n }, [scheduler])\n\n // --- TODAY MARKER AUTO-UPDATE ---\n useEffect(() => {\n if (!todayMarkerInterval) return\n const timer = setInterval(() => {\n const configs: MarkerConfig[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n configs.push(getTodayMarkerConfig(child.props as { color?: string; width?: number; label?: string }))\n } else if (displayName === 'CustomMarker') {\n configs.push(getCustomMarkerConfig(child.props as { date: number; color?: string; width?: number; label?: string }))\n }\n })\n markersRef.current = configs\n scheduler.markDirty('overlay')\n }, todayMarkerInterval)\n return () => clearInterval(timer)\n }, [todayMarkerInterval, children, scheduler])\n\n // --- SYNC ON DIMENSION/DATA CHANGES ---\n useEffect(() => {\n viewStateRef.current.update({\n canvasWidth, canvasHeight, sidebarWidth, lineHeight,\n groupCount: groups.length, groupHeights,\n })\n scheduler.markAllDirty()\n }, [canvasWidth, canvasHeight, sidebarWidth, lineHeight, groups.length, groupHeights, scheduler])\n\n useEffect(() => {\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n }, [items, groups, selected, theme, dayStyle, rowStyle, intervalTree, layoutEngine, scheduler])\n\n const highlightsKey = useMemo(\n () => props.highlights?.map(h => `${h.start}|${h.end}|${h.color}|${h.label ?? ''}|${h.opacity ?? ''}`).join(';') ?? '',\n [props.highlights],\n )\n\n const prevHighlightsKey = useRef(highlightsKey)\n useEffect(() => {\n if (highlightsKey !== prevHighlightsKey.current) {\n prevHighlightsKey.current = highlightsKey\n scheduler.markDirty('grid')\n }\n }, [highlightsKey, scheduler])\n\n const prevMarkersKey = useRef(markersKey)\n useEffect(() => {\n if (markersKey !== prevMarkersKey.current) {\n prevMarkersKey.current = markersKey\n scheduler.markDirty('overlay')\n }\n }, [markersKey, scheduler])\n\n // --- CONTROLLED MODE ---\n const prevControlledStart = useRef(props.visibleTimeStart)\n const prevControlledEnd = useRef(props.visibleTimeEnd)\n if (props.visibleTimeStart !== undefined && props.visibleTimeStart !== prevControlledStart.current) {\n prevControlledStart.current = props.visibleTimeStart\n viewStateRef.current.update({ visibleTimeStart: props.visibleTimeStart })\n scheduler.markAllDirty()\n }\n if (props.visibleTimeEnd !== undefined && props.visibleTimeEnd !== prevControlledEnd.current) {\n prevControlledEnd.current = props.visibleTimeEnd\n viewStateRef.current.update({ visibleTimeEnd: props.visibleTimeEnd })\n scheduler.markAllDirty()\n }\n\n // --- THROTTLED PARENT CALLBACKS ---\n const callbackTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const scheduleCallbacks = useCallback((type: 'zoom' | 'scroll') => {\n if (callbackTimerRef.current !== null) return\n callbackTimerRef.current = setTimeout(() => {\n callbackTimerRef.current = null\n const vs = viewStateRef.current\n const p = propsRef.current\n if (type === 'zoom') {\n p.onZoom?.(vs.visibleTimeStart, vs.visibleTimeEnd)\n } else {\n p.onTimeChange?.(vs.visibleTimeStart, vs.visibleTimeEnd)\n }\n }, HEADER_THROTTLE_MS)\n }, [])\n\n useEffect(() => {\n return () => { if (callbackTimerRef.current !== null) clearTimeout(callbackTimerRef.current) }\n }, [])\n\n // --- ZOOM HANDLER ---\n const zoomHandlerRef = useRef<ZoomHandler | null>(null)\n const zoomHandler = useMemo(() => {\n return new ZoomHandler(\n (newStart, newEnd) => {\n viewStateRef.current.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n scheduleHeaderSync()\n scheduleCallbacks('zoom')\n },\n defaultTimeStart,\n defaultTimeEnd,\n minZoom,\n maxZoom,\n )\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n zoomHandlerRef.current = zoomHandler\n\n // --- WHEEL HANDLER ---\n const handleVerticalScroll = useCallback((deltaY: number) => {\n const vs = viewStateRef.current\n const totalHeight = vs.getTotalHeight()\n const maxScroll = Math.max(0, totalHeight - vs.canvasHeight)\n const newScrollTop = Math.max(0, Math.min(maxScroll, vs.scrollTop + deltaY))\n if (newScrollTop === vs.scrollTop) return\n vs.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }, [scheduler])\n\n const handleHorizontalScroll = useCallback((deltaX: number) => {\n const vs = viewStateRef.current\n const pixelsPerMs = vs.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = deltaX / pixelsPerMs\n const newStart = vs.visibleTimeStart + deltaMs\n const newEnd = vs.visibleTimeEnd + deltaMs\n vs.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n flushSync(() => syncHeaderState())\n propsRef.current.onTimeChange?.(newStart, newEnd)\n }, [scheduler, syncHeaderState])\n\n useEffect(() => {\n const el = interactionRef.current\n if (!el) return\n const handleWheel = (e: WheelEvent) => {\n if (e.ctrlKey || e.metaKey || e.altKey) {\n e.preventDefault()\n const rect = el.getBoundingClientRect()\n const cursorRatio = (e.clientX - rect.left) / rect.width\n zoomHandler.handleWheelZoom(e, cursorRatio)\n } else if (e.shiftKey) {\n e.preventDefault()\n // Some browsers (Chrome/Edge on macOS) pre-translate shift + external mouse wheel\n // into deltaX with deltaY=0; trackpads keep the raw deltaY. Use whichever is non-zero.\n handleHorizontalScroll(e.deltaY || e.deltaX)\n } else {\n const deltaX = e.deltaX\n if (deltaX !== 0 && Math.abs(deltaX) > Math.abs(e.deltaY)) {\n e.preventDefault()\n handleHorizontalScroll(deltaX)\n } else if (e.deltaY !== 0) {\n const hasInternalScroll = totalHeight > canvasHeight\n if (hasInternalScroll) e.preventDefault()\n handleVerticalScroll(e.deltaY)\n }\n }\n }\n el.addEventListener('wheel', handleWheel, { passive: false })\n return () => el.removeEventListener('wheel', handleWheel)\n }, [zoomHandler, handleVerticalScroll, handleHorizontalScroll, totalHeight, canvasHeight])\n\n // --- TOUCH PINCH-TO-ZOOM ---\n const touchRef = useRef<{ lastDistance: number | null; lastCenter: number | null }>({ lastDistance: null, lastCenter: null })\n\n useEffect(() => {\n const el = interactionRef.current\n if (!el) return\n\n const getDistance = (t1: Touch, t2: Touch) => Math.abs(t1.clientX - t2.clientX)\n const getCenter = (t1: Touch, t2: Touch, rect: DOMRect) => ((t1.clientX + t2.clientX) / 2) - rect.left\n\n const handleTouchStart = (e: TouchEvent) => {\n if (e.touches.length === 2) {\n e.preventDefault()\n touchRef.current.lastDistance = getDistance(e.touches[0], e.touches[1])\n touchRef.current.lastCenter = null\n }\n }\n\n const handleTouchMove = (e: TouchEvent) => {\n if (e.touches.length === 2 && touchRef.current.lastDistance !== null) {\n e.preventDefault()\n const newDistance = getDistance(e.touches[0], e.touches[1])\n const rect = el.getBoundingClientRect()\n const center = getCenter(e.touches[0], e.touches[1], rect)\n const cursorRatio = center / rect.width\n\n if (newDistance !== 0 && touchRef.current.lastDistance !== 0) {\n const scale = touchRef.current.lastDistance / newDistance\n const vs = viewStateRef.current\n const currentDuration = vs.visibleTimeEnd - vs.visibleTimeStart\n let newDuration = currentDuration * scale\n newDuration = Math.max(minZoom, Math.min(maxZoom, newDuration))\n\n const cursorTime = vs.visibleTimeStart + currentDuration * cursorRatio\n const newStart = cursorTime - newDuration * cursorRatio\n const newEnd = cursorTime + newDuration * (1 - cursorRatio)\n\n vs.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n scheduleHeaderSync()\n scheduleCallbacks('zoom')\n }\n touchRef.current.lastDistance = newDistance\n }\n }\n\n const handleTouchEnd = () => {\n touchRef.current.lastDistance = null\n touchRef.current.lastCenter = null\n }\n\n el.addEventListener('touchstart', handleTouchStart, { passive: false })\n el.addEventListener('touchmove', handleTouchMove, { passive: false })\n el.addEventListener('touchend', handleTouchEnd)\n return () => {\n el.removeEventListener('touchstart', handleTouchStart)\n el.removeEventListener('touchmove', handleTouchMove)\n el.removeEventListener('touchend', handleTouchEnd)\n }\n }, [scheduler, scheduleHeaderSync, scheduleCallbacks])\n\n // --- POINTER HANDLERS ---\n const handlePointerMove = useCallback((e: React.PointerEvent) => {\n const el = e.currentTarget as HTMLElement\n const rect = el.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n cursorXRef.current = x\n pointerClientRef.current = { x: e.clientX, y: e.clientY }\n\n // --- Pan mode (drag on empty canvas) ---\n if (panRef.current) {\n const dx = e.clientX - panRef.current.startX\n const dy = e.clientY - panRef.current.startY\n if (!didPanRef.current && (Math.abs(dx) >= PAN_THRESHOLD || Math.abs(dy) >= PAN_THRESHOLD)) {\n didPanRef.current = true\n el.style.cursor = 'grabbing'\n el.setPointerCapture(e.pointerId)\n }\n if (didPanRef.current) {\n const moveDeltaX = e.clientX - panRef.current.lastX\n const moveDeltaY = e.clientY - panRef.current.lastY\n panRef.current.lastX = e.clientX\n panRef.current.lastY = e.clientY\n if (Math.abs(moveDeltaX) > 0) handleHorizontalScroll(-moveDeltaX)\n if (Math.abs(moveDeltaY) > 0) handleVerticalScroll(-moveDeltaY)\n }\n return\n }\n\n if (interactionHandler.isPending()) {\n interactionHandler.update(x, y)\n if (interactionHandler.isActive()) {\n const state = interactionHandler.getState()\n if (state && state.mode === 'move' && propsRef.current.canChangeGroup) {\n const group = hitTestGroup(y, viewStateRef.current, propsRef.current.groups)\n if (group) interactionHandler.setCurrentGroup(group.id)\n }\n scheduler.markDirty('overlay')\n }\n return\n }\n\n if (propsRef.current.showCursorLine) scheduler.markDirty('overlay')\n\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n const newHoveredId = item?.id\n if (newHoveredId !== hoveredItemIdRef.current) {\n hoveredItemIdRef.current = newHoveredId\n scheduler.markDirty('items')\n p.onItemHover?.(newHoveredId ?? null, e.nativeEvent as unknown as PointerEvent)\n }\n\n // Cursor management — derived from the same decision the pointer-down uses,\n // so the affordance and the interaction can never disagree.\n if (item) {\n const edge = detectEdge(x, item, viewStateRef.current)\n const mode = resolveInteractionMode(item, edge, p.canResize, p.canMove)\n el.style.cursor =\n mode === 'resize-left' || mode === 'resize-right' ? 'col-resize'\n : mode === 'move' ? 'grab'\n : 'default'\n } else {\n el.style.cursor = 'default'\n }\n }, [interactionHandler, scheduler, handleHorizontalScroll, handleVerticalScroll])\n\n const handlePointerDown = useCallback((e: React.PointerEvent) => {\n const p = propsRef.current\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n\n if (!item) {\n // Start pan on empty canvas\n panRef.current = { startX: e.clientX, startY: e.clientY, lastX: e.clientX, lastY: e.clientY }\n didPanRef.current = false\n return\n }\n\n const edge = detectEdge(x, item, viewStateRef.current)\n const mode = resolveInteractionMode(item, edge, p.canResize, p.canMove)\n\n // No permitted interaction → start nothing (no ghost, no drag).\n if (mode) {\n interactionHandler.startInteraction(item, mode, x, y)\n }\n }, [interactionHandler])\n\n const handlePointerUp = useCallback((e: React.PointerEvent) => {\n const el = e.currentTarget as HTMLElement\n\n // --- End pan mode ---\n if (panRef.current) {\n const wasPanning = didPanRef.current\n panRef.current = null\n didPanRef.current = false\n el.style.cursor = 'default'\n if (wasPanning) return // suppress click after pan\n }\n\n if (interactionHandler.isActive()) {\n const state = interactionHandler.getState()\n const vs = viewStateRef.current\n const pixelsPerMs = vs.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n if (state) {\n const validator = propsRef.current.moveResizeValidator\n const p = propsRef.current\n if (state.mode === 'move') {\n // Snapped start matches the live tooltip; endMove only resets the\n // handler and yields the (possibly changed) group.\n const snappedStartTime = snappedMoveStart(state, vs, p)\n const result = interactionHandler.endMove(pixelsPerMs)\n if (result) {\n const validatedTime = validator ? validator('move', state.item.id, snappedStartTime) : snappedStartTime\n const childMoves = p.hierarchyEngine.getMoveDelta(state.item.id, validatedTime)\n p.onItemMove?.(state.item.id, validatedTime, result.newGroupId, childMoves.length > 0 ? childMoves : undefined)\n }\n } else {\n const { edge, time: constrainedTime } = snappedResizeEdge(state, vs, p)\n const result = interactionHandler.endResize(pixelsPerMs)\n if (result) {\n const validatedTime = validator ? validator('resize', state.item.id, constrainedTime, edge) : constrainedTime\n p.onItemResize?.(state.item.id, validatedTime, edge)\n }\n }\n }\n el.style.cursor = 'default'\n scheduler.markDirty('overlay')\n return\n }\n if (interactionHandler.isPending()) interactionHandler.cancel()\n const rect = el.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const item = hitTest(x, y, viewStateRef.current, propsRef.current.intervalTree, propsRef.current.layoutEngine, propsRef.current.groups)\n if (item) propsRef.current.onItemClick?.(item.id, e.nativeEvent as unknown as PointerEvent)\n }, [interactionHandler, scheduler])\n\n const handleDoubleClick = useCallback((e: React.MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (item) {\n p.onItemDoubleClick?.(item.id, e.nativeEvent as unknown as PointerEvent)\n } else {\n const group = hitTestGroup(y, viewStateRef.current, p.groups)\n const time = viewStateRef.current.xToTime(x)\n if (group) p.onCanvasDoubleClick?.(group.id as number, time)\n }\n }, [])\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n e.preventDefault()\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (item) {\n p.onItemContextMenu?.(item.id, e.nativeEvent as unknown as PointerEvent)\n } else {\n const group = hitTestGroup(y, viewStateRef.current, p.groups)\n const time = viewStateRef.current.xToTime(x)\n if (group) p.onCanvasContextMenu?.(group.id as number, time, e.nativeEvent as unknown as PointerEvent)\n }\n }, [])\n\n const handlePointerLeave = useCallback(() => {\n panRef.current = null\n didPanRef.current = false\n cursorXRef.current = null\n if (interactionRef.current) interactionRef.current.style.cursor = 'default'\n if (hoveredItemIdRef.current !== undefined) {\n hoveredItemIdRef.current = undefined\n scheduler.markDirty('items')\n propsRef.current.onItemHover?.(null, new PointerEvent('pointerleave'))\n }\n if (propsRef.current.showCursorLine) scheduler.markDirty('overlay')\n }, [scheduler])\n\n // --- HEADER CHILDREN ---\n const headerChildren = useMemo(() => {\n const headers: React.ReactNode[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TimelineHeaders') {\n const childProps = child.props as Record<string, unknown>\n headers.push(\n React.cloneElement(child as React.ReactElement<Record<string, unknown>>, {\n visibleTimeStart: childProps.visibleTimeStart ?? headerTimeStart,\n visibleTimeEnd: childProps.visibleTimeEnd ?? headerTimeEnd,\n canvasWidth: childProps.canvasWidth ?? canvasWidth,\n sidebarWidth: childProps.sidebarWidth ?? sidebarWidth,\n theme: childProps.theme ?? theme,\n timezone: childProps.timezone ?? timezone,\n onZoomToInterval: childProps.onZoomToInterval ?? ((start: number, end: number) => {\n viewStateRef.current.update({ visibleTimeStart: start, visibleTimeEnd: end })\n scheduler.markAllDirty()\n syncHeaderState()\n propsRef.current.onTimeChange?.(start, end)\n propsRef.current.onZoom?.(start, end)\n }),\n }),\n )\n }\n })\n return headers\n }, [children, headerTimeStart, headerTimeEnd, canvasWidth, sidebarWidth, theme, timezone, scheduler, syncHeaderState])\n\n // --- INITIAL DRAW ---\n const initialDrawDone = useRef(false)\n useEffect(() => {\n if (!initialDrawDone.current) {\n initialDrawDone.current = true\n scheduler.markAllDirty()\n }\n }, [scheduler])\n\n // --- IMPERATIVE HANDLE (print capture) ---\n useImperativeHandle(ref, () => ({\n captureToCanvas({ timeStart, timeEnd, scale, sidebarWidth: printSidebarWidth }) {\n const p = propsRef.current\n const headerRowHeight = 28\n const headerHeight = headerRowHeight * 3\n const printGroupHeights = p.groups.map((g) => p.layoutEngine.getGroupHeight(g.id))\n const printGroupOffsets: number[] = [0]\n for (let i = 0; i < printGroupHeights.length; i++) {\n printGroupOffsets.push(printGroupOffsets[i] + printGroupHeights[i])\n }\n const totalHeight = printGroupOffsets[printGroupHeights.length]\n\n // Preserve the current zoom level (pixels per ms) from the on-screen view\n const vs = viewStateRef.current\n const currentPixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const printDuration = timeEnd - timeStart\n const timelineWidth = Math.max(p.canvasWidth, Math.round(printDuration * currentPixelsPerMs))\n\n const compositeWidth = (printSidebarWidth + timelineWidth) * scale\n const compositeHeight = (headerHeight + totalHeight) * scale\n\n const canvas = document.createElement('canvas')\n canvas.width = compositeWidth\n canvas.height = compositeHeight\n const ctx = canvas.getContext('2d')!\n ctx.scale(scale, scale)\n\n // --- Draw sidebar ---\n for (let i = 0; i < p.groups.length; i++) {\n const group = p.groups[i]\n const rowHeight = printGroupHeights[i]\n const y = headerHeight + printGroupOffsets[i]\n\n // Row background from rowStyle\n if (p.rowStyle) {\n const style = p.rowStyle(group)\n if (style?.backgroundColor) {\n ctx.fillStyle = style.backgroundColor\n ctx.fillRect(0, y, printSidebarWidth, rowHeight)\n }\n }\n\n // Group title\n const groupType = group.type as string | undefined\n let fontWeight = '400'\n let indent = 8\n if (groupType === 'project') {\n fontWeight = '700'\n } else if (groupType === 'CAG') {\n fontWeight = '600'\n } else if (groupType === 'CA') {\n fontWeight = '400'\n indent = 24\n }\n\n ctx.fillStyle = '#111'\n ctx.font = `${fontWeight} 12px sans-serif`\n ctx.textBaseline = 'middle'\n ctx.fillText(group.title, indent, y + rowHeight / 2, printSidebarWidth - indent - 4)\n }\n\n // --- Draw headers ---\n const drawHeaderRow = (rowY: number, getLabel: (time: dayjs.Dayjs) => string, unit: dayjs.ManipulateType) => {\n ctx.fillStyle = p.theme.header?.bg ?? '#f5f5f5'\n ctx.fillRect(printSidebarWidth, rowY, timelineWidth, headerRowHeight)\n ctx.strokeStyle = p.theme.grid?.line ?? '#e0e0e0'\n ctx.lineWidth = 1\n ctx.strokeRect(printSidebarWidth, rowY, timelineWidth, headerRowHeight)\n\n let cursor = toDayjs(timeStart, p.timezone).startOf(unit)\n if (cursor.valueOf() < timeStart) cursor = cursor.add(1, unit)\n\n const pxPerMs = timelineWidth / (timeEnd - timeStart)\n\n while (cursor.valueOf() < timeEnd) {\n const nextCursor = cursor.add(1, unit)\n const x = printSidebarWidth + (cursor.valueOf() - timeStart) * pxPerMs\n const endX = printSidebarWidth + (Math.min(nextCursor.valueOf(), timeEnd) - timeStart) * pxPerMs\n const width = endX - x\n\n // Vertical divider\n ctx.beginPath()\n ctx.moveTo(x, rowY)\n ctx.lineTo(x, rowY + headerRowHeight)\n ctx.stroke()\n\n // Label\n ctx.fillStyle = '#333'\n ctx.font = '600 11px sans-serif'\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'center'\n ctx.fillText(getLabel(cursor), x + width / 2, rowY + headerRowHeight / 2, width - 4)\n\n cursor = nextCursor\n }\n ctx.textAlign = 'start' // reset\n }\n\n drawHeaderRow(0, (d) => d.format('YYYY'), 'year')\n drawHeaderRow(headerRowHeight, (d) => d.format('MM'), 'month')\n drawHeaderRow(headerRowHeight * 2, (d) => String(d.isoWeek()), 'week')\n\n // --- Draw timeline layers ---\n const printViewState = new ViewState({\n visibleTimeStart: timeStart,\n visibleTimeEnd: timeEnd,\n canvasWidth: timelineWidth,\n canvasHeight: totalHeight,\n sidebarWidth: 0,\n lineHeight: p.lineHeight,\n groupCount: p.groups.length,\n buffer: 1,\n scrollTop: 0,\n groupHeights: printGroupHeights,\n })\n\n // Offset context for timeline area\n ctx.save()\n ctx.translate(printSidebarWidth, headerHeight)\n\n // Clip to timeline area\n ctx.beginPath()\n ctx.rect(0, 0, timelineWidth, totalHeight)\n ctx.clip()\n\n gridLayer.draw(ctx, printViewState, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights, p.timezone)\n itemsLayer.draw(\n ctx, printViewState, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, undefined, p.dependencies,\n p.summaryRenderer, p.hierarchyEngine,\n )\n overlayLayer.draw(ctx, printViewState, p.theme, {\n cursorX: null,\n snapX: null,\n markers: markersRef.current,\n interaction: null,\n })\n\n ctx.restore()\n\n return canvas\n },\n }), [gridLayer, itemsLayer, overlayLayer])\n\n // --- ON READY CALLBACK ---\n useEffect(() => {\n const api: CanvasTimelineRef = {\n captureToCanvas({ timeStart, timeEnd, scale, sidebarWidth: printSidebarWidth }) {\n const p = propsRef.current\n const headerRowHeight = 28\n const headerHeight = headerRowHeight * 3\n const printGroupHeights = p.groups.map((g) => p.layoutEngine.getGroupHeight(g.id))\n const printGroupOffsets: number[] = [0]\n for (let i = 0; i < printGroupHeights.length; i++) {\n printGroupOffsets.push(printGroupOffsets[i] + printGroupHeights[i])\n }\n const totalHeight = printGroupOffsets[printGroupHeights.length]\n const vs = viewStateRef.current\n const currentPixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const printDuration = timeEnd - timeStart\n const timelineWidth = Math.max(p.canvasWidth, Math.round(printDuration * currentPixelsPerMs))\n const fullWidth = printSidebarWidth + timelineWidth\n const fullHeight = headerHeight + totalHeight\n\n const canvas = document.createElement('canvas')\n canvas.width = fullWidth * scale\n canvas.height = fullHeight * scale\n const ctx = canvas.getContext('2d')!\n ctx.scale(scale, scale)\n ctx.fillStyle = '#FFFFFF'\n ctx.fillRect(0, 0, fullWidth, fullHeight)\n\n // Sidebar\n ctx.save()\n ctx.beginPath()\n ctx.rect(0, 0, printSidebarWidth, fullHeight)\n ctx.clip()\n ctx.fillStyle = '#F9FAFB'\n ctx.fillRect(0, 0, printSidebarWidth, headerHeight)\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 1\n ctx.strokeRect(0, 0, printSidebarWidth, headerHeight)\n for (let i = 0; i < p.groups.length; i++) {\n const group = p.groups[i]\n const rowHeight = printGroupHeights[i]\n const y = headerHeight + printGroupOffsets[i]\n const rs = p.rowStyle?.(group)\n ctx.fillStyle = rs?.backgroundColor ?? (i % 2 === 0 ? '#FFFFFF' : '#F7F7F7')\n ctx.fillRect(0, y, printSidebarWidth, rowHeight)\n ctx.strokeStyle = '#E5E5E5'\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + rowHeight)\n ctx.lineTo(printSidebarWidth, y + rowHeight)\n ctx.stroke()\n const gt = (group.type as string) ?? ''\n let indent = 8, fw = '400', fs = 11\n if (gt === 'project') { fw = '700'; fs = 12 }\n else if (gt === 'control_area_group') { fw = '600' }\n else if (gt === 'control_area') { indent = 24 }\n ctx.fillStyle = '#374151'\n ctx.font = `${fw} ${fs}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif`\n ctx.textBaseline = 'middle'\n const title = typeof group.title === 'string' ? group.title : String(group.title)\n ctx.fillText(title, indent, y + rowHeight / 2, printSidebarWidth - indent - 8)\n }\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(printSidebarWidth, 0)\n ctx.lineTo(printSidebarWidth, fullHeight)\n ctx.stroke()\n ctx.restore()\n\n // Headers\n ctx.save()\n ctx.beginPath()\n ctx.rect(printSidebarWidth, 0, timelineWidth, headerHeight)\n ctx.clip()\n const duration = timeEnd - timeStart\n const units: Array<{ unit: 'year' | 'month' | 'week'; row: number }> = [\n { unit: 'year', row: 0 }, { unit: 'month', row: 1 }, { unit: 'week', row: 2 },\n ]\n for (const { unit, row } of units) {\n const hy = row * headerRowHeight\n ctx.fillStyle = '#F9FAFB'\n ctx.fillRect(printSidebarWidth, hy, timelineWidth, headerRowHeight)\n let cur = toDayjs(timeStart, p.timezone).startOf(unit)\n const endBound = toDayjs(timeEnd, p.timezone).add(1, unit)\n while (cur.isBefore(endBound)) {\n const next = cur.add(1, unit)\n const sx = printSidebarWidth + ((cur.valueOf() - timeStart) / duration) * timelineWidth\n const w = ((next.valueOf() - cur.valueOf()) / duration) * timelineWidth\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 0.5\n ctx.strokeRect(sx, hy, w, headerRowHeight)\n let label: string\n if (unit === 'year') label = cur.format('YYYY')\n else if (unit === 'month') label = cur.format('MM')\n else label = `${cur.week()}`\n ctx.fillStyle = '#6c737f'\n ctx.font = unit === 'year'\n ? '600 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n : '400 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'center'\n if (w > 20) ctx.fillText(label, sx + w / 2, hy + headerRowHeight / 2)\n cur = next\n }\n }\n ctx.textAlign = 'start'\n ctx.restore()\n\n // Timeline\n ctx.save()\n ctx.beginPath()\n ctx.rect(printSidebarWidth, headerHeight, timelineWidth, totalHeight)\n ctx.clip()\n ctx.translate(printSidebarWidth, headerHeight)\n const pv = new ViewState({\n visibleTimeStart: timeStart, visibleTimeEnd: timeEnd,\n canvasWidth: timelineWidth, canvasHeight: totalHeight,\n sidebarWidth: 0, lineHeight: p.lineHeight,\n groupCount: p.groups.length, buffer: 1, scrollTop: 0,\n groupHeights: printGroupHeights,\n })\n gridLayer.draw(ctx, pv, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights, p.timezone)\n itemsLayer.draw(ctx, pv, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, undefined, p.dependencies,\n p.summaryRenderer, p.hierarchyEngine)\n overlayLayer.draw(ctx, pv, p.theme, { cursorX: null, markers: markersRef.current })\n ctx.restore()\n\n return canvas\n },\n }\n onReady?.(api)\n }, [onReady, gridLayer, itemsLayer, overlayLayer])\n\n // --- RENDER ---\n const canvasContainerStyle: React.CSSProperties = {\n position: 'relative',\n width: canvasWidth,\n height: canvasHeight,\n overflow: 'hidden',\n cursor: 'default',\n }\n\n const canvasStyle: React.CSSProperties = { position: 'absolute', top: 0, left: 0 }\n\n return (\n <div ref={outerRef} style={{ display: 'flex', flexDirection: 'column', width: '100%', position: 'relative' }}>\n {(__LIB_DEV__ || devBadge) ? (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n zIndex: 9999,\n padding: '2px 6px',\n fontSize: 10,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n lineHeight: 1.4,\n color: '#fff',\n background: 'rgba(17, 24, 39, 0.78)',\n borderBottomRightRadius: 4,\n pointerEvents: 'none',\n userSelect: 'none',\n }}\n >\n v{__LIB_VERSION__} · {__LIB_BUILD__}\n </div>\n ) : null}\n {headerChildren}\n <div ref={containerRef} style={{ display: 'flex', overflow: 'hidden', maxHeight: maxHeight ?? undefined }}>\n <Sidebar\n groups={groups}\n width={sidebarWidth}\n lineHeight={lineHeight}\n groupHeights={groupHeights}\n scrollTop={sidebarScrollTop}\n canvasHeight={canvasHeight}\n theme={theme}\n groupRenderer={sidebarGroupRenderer}\n onScroll={(newScrollTop) => {\n viewStateRef.current.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }}\n />\n <div\n ref={interactionRef}\n style={canvasContainerStyle}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n onDoubleClick={handleDoubleClick}\n onContextMenu={handleContextMenu}\n onPointerLeave={handlePointerLeave}\n >\n <canvas ref={gridCanvasRef} style={{ ...canvasStyle, zIndex: 0 }} />\n <canvas ref={itemsCanvasRef} style={{ ...canvasStyle, zIndex: 1 }} />\n <canvas ref={overlayCanvasRef} style={{ ...canvasStyle, zIndex: 2 }} />\n </div>\n {rightSidebarWidth && rightSidebarGroupRenderer ? (\n <Sidebar\n groups={groups}\n width={rightSidebarWidth}\n lineHeight={lineHeight}\n groupHeights={groupHeights}\n scrollTop={sidebarScrollTop}\n canvasHeight={canvasHeight}\n theme={theme}\n groupRenderer={rightSidebarGroupRenderer}\n onScroll={(newScrollTop) => {\n viewStateRef.current.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }}\n />\n ) : null}\n </div>\n </div>\n )\n}))\n","import React from 'react'\nimport type { TimelineTheme } from '../types'\n\nexport interface TimelineHeadersProps {\n children: React.ReactNode\n theme?: TimelineTheme\n className?: string\n classNames?: string\n style?: React.CSSProperties\n visibleTimeStart?: number\n visibleTimeEnd?: number\n canvasWidth?: number\n sidebarWidth?: number\n onZoomToInterval?: (start: number, end: number) => void\n timezone?: string\n}\n\nexport function TimelineHeaders({ children, theme, className, classNames: _classNames, style, visibleTimeStart, visibleTimeEnd, canvasWidth, sidebarWidth = 0, onZoomToInterval, timezone }: TimelineHeadersProps) {\n const enhancedChildren = React.Children.map(children, (child) => {\n if (!React.isValidElement(child)) return child\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'DateHeader') {\n const childProps = child.props as Record<string, unknown>\n const enhanced = React.cloneElement(child as React.ReactElement<Record<string, unknown>>, {\n visibleTimeStart: childProps.visibleTimeStart ?? visibleTimeStart,\n visibleTimeEnd: childProps.visibleTimeEnd ?? visibleTimeEnd,\n canvasWidth: childProps.canvasWidth ?? canvasWidth,\n theme: childProps.theme ?? theme,\n onZoomToInterval: childProps.onIntervalClick ?? childProps.onZoomToInterval ?? onZoomToInterval,\n timezone: childProps.timezone ?? timezone,\n })\n return (\n <div style={{ display: 'flex' }}>\n <div style={{ width: sidebarWidth, flexShrink: 0 }} />\n <div style={{ flex: 1, overflow: 'hidden' }}>{enhanced}</div>\n </div>\n )\n }\n return child\n })\n\n return (\n <div className={className} style={{\n position: 'sticky', top: 0, zIndex: 20, display: 'flex', flexDirection: 'column',\n backgroundColor: theme?.header.bg ?? '#F9FAFB',\n borderTop: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n borderBottom: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n ...style,\n }}>\n {enhancedChildren}\n </div>\n )\n}\nTimelineHeaders.displayName = 'TimelineHeaders'\n","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_weekOfYear=t()}(this,(function(){\"use strict\";var e=\"week\",t=\"year\";return function(i,n,r){var f=n.prototype;f.week=function(i){if(void 0===i&&(i=null),null!==i)return this.add(7*(i-this.week()),\"day\");var n=this.$locale().yearStart||1;if(11===this.month()&&this.date()>25){var f=r(this).startOf(t).add(1,t).date(n),s=r(this).endOf(e);if(f.isBefore(s))return 1}var a=r(this).startOf(t).date(n).startOf(e).subtract(1,\"millisecond\"),o=this.diff(a,e,!0);return o<0?r(this).startOf(\"week\").week():Math.ceil(o)},f.weeks=function(e){return void 0===e&&(e=null),this.week(e)}}}));","import { useMemo, useCallback } from 'react'\nimport dayjs from 'dayjs'\nimport weekOfYear from 'dayjs/plugin/weekOfYear'\nimport type { TimelineTheme } from '../types'\nimport { toDayjs } from '../utils/timezone'\n\ndayjs.extend(weekOfYear)\n\nexport type DateUnit = 'year' | 'month' | 'week' | 'day' | 'hour'\n\n// Minimum cell width in pixels before the header auto-hides\nconst DEFAULT_MIN_CELL_WIDTH: Record<DateUnit, number> = {\n year: 30,\n month: 30,\n week: 20,\n day: 15,\n hour: 30,\n}\n\nexport interface DateHeaderProps {\n unit: DateUnit\n visibleTimeStart?: number\n visibleTimeEnd?: number\n canvasWidth?: number\n theme?: TimelineTheme\n height?: number\n className?: string\n labelFormat?: string | ((start: Date, end: Date, unit: DateUnit) => string)\n onIntervalClick?: (startTime: number, endTime: number) => void\n /** Minimum cell width in pixels. Header auto-hides when cells are narrower. Set to 0 to disable. */\n minCellWidth?: number\n // Called by TimelineHeaders to inject zoom behavior\n onZoomToInterval?: (start: number, end: number) => void\n timezone?: string\n}\n\nexport function DateHeader({\n unit,\n visibleTimeStart = 0,\n visibleTimeEnd = 0,\n canvasWidth = 0,\n theme,\n height = 28,\n className,\n labelFormat,\n onIntervalClick,\n minCellWidth,\n onZoomToInterval,\n timezone,\n}: DateHeaderProps) {\n const intervals = useMemo(() => {\n if (!visibleTimeStart || !visibleTimeEnd || !canvasWidth) return []\n\n const duration = visibleTimeEnd - visibleTimeStart\n\n // Check average cell width — auto-hide if too narrow\n const minWidth = minCellWidth ?? DEFAULT_MIN_CELL_WIDTH[unit]\n if (minWidth > 0) {\n const sampleStart = toDayjs(visibleTimeStart, timezone).startOf(unit)\n const sampleEnd = sampleStart.add(1, unit)\n const avgCellWidth = ((sampleEnd.valueOf() - sampleStart.valueOf()) / duration) * canvasWidth\n if (avgCellWidth < minWidth) return []\n }\n\n const result: Array<{ start: number; end: number; label: string; left: number; width: number }> = []\n // Add buffer: 1 extra unit before and after visible range\n let current = toDayjs(visibleTimeStart, timezone).startOf(unit).subtract(1, unit)\n const endBound = toDayjs(visibleTimeEnd, timezone).add(2, unit).valueOf()\n\n while (current.valueOf() < endBound) {\n const next = current.add(1, unit)\n const start = current.valueOf()\n const end = next.valueOf()\n const left = ((start - visibleTimeStart) / duration) * canvasWidth\n const width = ((end - start) / duration) * canvasWidth\n const label = formatLabel(current, next, unit, labelFormat, width)\n result.push({ start, end, label, left, width })\n current = next\n }\n return result\n }, [visibleTimeStart, visibleTimeEnd, canvasWidth, unit, labelFormat, minCellWidth, timezone])\n\n const handleClick = useCallback((start: number, end: number) => {\n if (onIntervalClick) {\n onIntervalClick(start, end)\n } else if (onZoomToInterval) {\n onZoomToInterval(start, end)\n }\n }, [onIntervalClick, onZoomToInterval])\n\n // Auto-hide: return nothing if no intervals (cells too narrow)\n if (intervals.length === 0) return null\n\n return (\n <div style={{ display: 'flex', position: 'relative', height, overflow: 'hidden' }}>\n {intervals.map((interval) => (\n <div\n key={interval.start}\n className={className}\n onClick={() => handleClick(interval.start, interval.end)}\n style={{\n position: 'absolute',\n left: interval.left,\n width: interval.width,\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRight: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n borderBottom: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n fontSize: 12,\n color: theme?.header.text ?? '#6c737f',\n backgroundColor: theme?.header.bg ?? '#F9FAFB',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n cursor: 'pointer',\n userSelect: 'none',\n padding: '0 4px',\n boxSizing: 'border-box',\n }}\n >\n <span>{interval.label}</span>\n </div>\n ))}\n </div>\n )\n}\nDateHeader.displayName = 'DateHeader'\n\nfunction formatLabel(\n start: dayjs.Dayjs,\n end: dayjs.Dayjs,\n unit: DateUnit,\n labelFormat: string | ((start: Date, end: Date, unit: DateUnit) => string) | undefined,\n _width: number,\n): string {\n if (typeof labelFormat === 'function') {\n return labelFormat(start.toDate(), end.toDate(), unit)\n }\n if (typeof labelFormat === 'string') {\n return start.format(labelFormat)\n }\n return formatDefault(start, unit)\n}\n\nfunction formatDefault(d: dayjs.Dayjs, unit: DateUnit): string {\n switch (unit) {\n case 'year': return d.format('YYYY')\n case 'month': return d.format('MM')\n case 'week': return `${d.week()}`\n case 'day': return d.format('D')\n case 'hour': return d.format('HH:mm')\n }\n}\n","import React from 'react'\n\ninterface SidebarHeaderProps {\n width: number\n children?: (props: { getRootProps: () => React.HTMLAttributes<HTMLDivElement> }) => React.ReactNode\n style?: React.CSSProperties\n}\n\nexport function SidebarHeader({ width, children, style }: SidebarHeaderProps) {\n const getRootProps = (): React.HTMLAttributes<HTMLDivElement> => ({ style: { width, ...style } })\n if (children) return <>{children({ getRootProps })}</>\n return <div style={{ width }} />\n}\nSidebarHeader.displayName = 'SidebarHeader'\n","import React from 'react'\ninterface CustomHeaderProps { children: React.ReactNode }\nexport function CustomHeader({ children }: CustomHeaderProps) { return <>{children}</> }\nCustomHeader.displayName = 'CustomHeader'\n"],"names":["DEFAULT_THEME","ViewState","config","params","offsets","i","h","_a","time","x","y","target","lo","hi","mid","index","extend","firstVisible","lastVisible","scrollXOffset","bufferPixels","IntervalTree","items","getStart","getEnd","intervals","item","min","max","iv","center","leftIntervals","rightIntervals","overlapping","start","end","results","node","LayoutEngine","lineHeight","itemHeightRatio","stackItems","hierarchy","itemHeight","summaryHeight","isSummary","byGroup","arr","groupId","groupItems","a","b","d","levelEnds","maxLevel","level","leaves","parents","nextLevel","parent","itemId","HierarchyEngine","children","id","visited","current","parentId","siblings","idx","result","stack","descendants","descId","desc","cached","depth","newStart","delta","edge","minChildStart","childId","child","maxChildEnd","defaultSummaryRenderer","ctx","bounds","state","_helpers","theme","width","height","color","diamondSize","midY","title","textWidth","maxTextWidth","displayText","hitTest","canvasX","canvasY","view","tree","layout","groups","groupIndexMap","candidates","topItem","topY","groupIndex","itemLayout","hitTestGroup","detectEdge","threshold","leftX","rightX","resolveCanResize","globalCanResize","resolveCanMove","globalCanMove","resolveInteractionMode","cr","setupCanvas","canvas","dpr","targetW","targetH","clearCanvas","RenderScheduler","drawCallback","layer","flags","module","this","e","s","f","n","u","t","r","o","l","c","m","v","dayjs","utc","tz","toDayjs","ts","timezone","GridLayer","dayStyle","rowStyle","highlights","rowHeight","group","bgColor","customRow","x1","x2","w","opacity","g","visibleStart","visibleEnd","dayPixelWidth","stepUnit","batchColor","batchOpacity","batchStartX","customBorderLines","flushBatch","endX","date","custom","dow","line","padding","badgeWidth","badgeHeight","badgeX","badgeY","ITEM_FONT","createDrawHelpers","radius","text","maxWidth","candidate","color1","color2","grad","type","size","half","cx","cy","fillColor","stemW","stemX","paddingH","pillHeight","pillWidth","ItemsLayer","itemRenderer","groupRenderer","selected","hoveredItemId","dependencies","summaryRenderer","queryStart","queryEnd","visibleItems","selectedSet","itemBoundsMap","yMin","yMax","helpers","renderer","depItemIds","dep","itemMap","boundsMap","fromBounds","toBounds","isHighlighted","startX","startY","endY","dx","cpOffset","arrowSize","OverlayLayer","options","cursorX","snapX","markers","interaction","marker","maxBadgeWidth","MAX_DELTA","normalizeDelta","ZoomHandler","onZoom","visibleTimeStart","visibleTimeEnd","minZoom","maxZoom","cursorRatio","speed","scale","currentDuration","newDuration","newEnd","ACTIVATION_THRESHOLD","InteractionHandler","dragSnap","mode","pixelsPerMs","deltaMs","newStartTime","snapped","newGroupId","newTime","collectItemEdges","excludeItemId","timeToX","edges","findSnapTarget","currentX","edgeXPositions","thresholdPx","_pixelsPerMs","_dragSnap","closestX","closestDist","dist","snappedMoveStart","vs","p","rawStart","otherEdges","startSnap","endSnap","snappedResizeEdge","rawEdgeTime","snap","constraint","buildInteractionInfo","pointer","startTime","duration","endTime","OVERSCAN_PX","Sidebar","groupHeights","scrollTop","canvasHeight","onScroll","containerRef","useRef","isScrollingRef","useMemo","totalHeight","displayHeight","groupAtY","useCallback","handleScroll","useEffect","visibleGroups","top","_jsx","TodayMarker","_props","getTodayMarkerConfig","props","getTodayMarkerInterval","CustomMarker","getCustomMarkerConfig","isoWeek","mergeTheme","partial","HEADER_THROTTLE_MS","CanvasTimeline","React","forwardRef","ref","defaultTimeStart","defaultTimeEnd","sidebarWidth","canMove","canChangeGroup","canResize","themePartial","showCursorLine","sidebarGroupRenderer","onItemClick","onItemDoubleClick","onItemContextMenu","onItemMove","onItemResize","moveResizeValidator","onItemHover","onInteractionUpdate","onCanvasDoubleClick","onCanvasContextMenu","onTimeChange","selectedProp","rightSidebarWidth","rightSidebarGroupRenderer","onReady","maxHeight","devBadge","getGroupIndex","grps","selectedKey","gridCanvasRef","itemsCanvasRef","overlayCanvasRef","interactionRef","outerRef","containerWidth","setContainerWidth","useState","measuredHeight","setMeasuredHeight","container","obs","entries","entry","el","canvasWidth","hierarchyEngine","engine","intervalTree","layoutEngine","resolvedMaxHeight","viewStateRef","cursorXRef","hoveredItemIdRef","pointerClientRef","interactionActiveRef","panRef","didPanRef","PAN_THRESHOLD","headerTimeStart","setHeaderTimeStart","headerTimeEnd","setHeaderTimeEnd","sidebarScrollTop","setSidebarScrollTop","headerTimerRef","syncHeaderState","scheduleHeaderSync","resolvedSummaryRenderer","gridLayer","itemsLayer","overlayLayer","interactionHandler","markerConfigs","configs","displayName","markersKey","markersRef","todayMarkerInterval","interval","propsRef","drawGrid","drawItems","calculateSnapX","deltaX","draggedEdgeXs","edgeX","edgeTime","drawOverlay","interactionRender","origX","origWidth","targetGroupY","groupChanged","schedulerRef","scheduler","timer","highlightsKey","prevHighlightsKey","prevMarkersKey","prevControlledStart","prevControlledEnd","callbackTimerRef","scheduleCallbacks","_b","zoomHandlerRef","zoomHandler","handleVerticalScroll","deltaY","maxScroll","newScrollTop","handleHorizontalScroll","flushSync","_c","handleWheel","rect","touchRef","getDistance","t1","t2","getCenter","handleTouchStart","handleTouchMove","newDistance","cursorTime","handleTouchEnd","handlePointerMove","dy","moveDeltaX","moveDeltaY","newHoveredId","handlePointerDown","handlePointerUp","wasPanning","validator","snappedStartTime","validatedTime","childMoves","constrainedTime","_d","handleDoubleClick","handleContextMenu","handlePointerLeave","headerChildren","headers","childProps","initialDrawDone","useImperativeHandle","timeStart","timeEnd","printSidebarWidth","headerRowHeight","headerHeight","printGroupHeights","printGroupOffsets","currentPixelsPerMs","printDuration","timelineWidth","compositeWidth","compositeHeight","style","groupType","fontWeight","indent","drawHeaderRow","rowY","getLabel","unit","cursor","pxPerMs","nextCursor","printViewState","api","fullWidth","fullHeight","rs","gt","fw","fs","units","row","hy","cur","endBound","next","sx","label","pv","canvasContainerStyle","canvasStyle","_jsxs","TimelineHeaders","className","_classNames","onZoomToInterval","enhancedChildren","enhanced","weekOfYear","DEFAULT_MIN_CELL_WIDTH","DateHeader","labelFormat","onIntervalClick","minCellWidth","minWidth","sampleStart","left","formatLabel","handleClick","_width","formatDefault","SidebarHeader","getRootProps","_Fragment","CustomHeader"],"mappings":"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","x_google_ignoreList":[8,9,19,25]}
|
|
1
|
+
{"version":3,"file":"canvas-timeline.cjs.js","sources":["../src/types.ts","../src/core/ViewState.ts","../src/core/IntervalTree.ts","../src/core/LayoutEngine.ts","../src/core/HierarchyEngine.ts","../src/canvas/defaultSummaryRenderer.ts","../src/core/HitTest.ts","../src/canvas/CanvasManager.ts","../node_modules/dayjs/plugin/utc.js","../node_modules/dayjs/plugin/timezone.js","../src/utils/timezone.ts","../src/canvas/GridLayer.ts","../src/canvas/DrawHelpers.ts","../src/canvas/ItemsLayer.ts","../src/canvas/OverlayLayer.ts","../src/interaction/ZoomHandler.ts","../src/interaction/snapResolve.ts","../src/interaction/InteractionHandler.ts","../src/interaction/snapUtils.ts","../src/interaction/interactionInfo.ts","../node_modules/dayjs/plugin/isoWeek.js","../src/dom/Sidebar.tsx","../src/dom/TodayMarker.tsx","../src/dom/CustomMarker.tsx","../src/CanvasTimeline.tsx","../src/dom/TimelineHeaders.tsx","../node_modules/dayjs/plugin/weekOfYear.js","../src/dom/DateHeader.tsx","../src/dom/SidebarHeader.tsx","../src/dom/CustomHeader.tsx"],"sourcesContent":["import type React from 'react'\n\nexport interface Group {\n id: number | string\n title: string\n type?: string\n hierarchy?: string\n root?: boolean\n [key: string]: unknown\n}\n\nexport interface Item {\n id: number\n group: number | string\n start_time: number\n end_time: number\n parentId?: number\n type?: string\n /** Per-item override of the timeline-wide `canResize` prop. When set, this\n * wins for this item; when omitted, the global `canResize` applies. */\n canResize?: false | 'left' | 'right' | 'both'\n /** Per-item override of the timeline-wide `canMove` prop. When set, this\n * wins for this item; when omitted, the global `canMove` applies. */\n canMove?: boolean\n [key: string]: unknown\n}\n\nexport interface ItemBounds {\n x: number\n y: number\n width: number\n height: number\n}\n\nexport interface ItemState {\n selected: boolean\n hovered: boolean\n dragging: boolean\n filtered: boolean\n}\n\nexport interface DrawHelpers {\n roundRect(x: number, y: number, w: number, h: number, radius?: number): void\n fillText(text: string, x: number, y: number, maxWidth?: number): void\n gradient(x: number, w: number, color1: string, color2: string): CanvasGradient\n leftBar(color: string, width?: number): void\n icon(type: 'check' | 'danger-red' | 'danger-yellow', x: number, y: number, size?: number): void\n badge(text: string, x: number, y: number, bgColor: string): void\n}\n\nexport type CanvasItemRenderer = (\n ctx: CanvasRenderingContext2D,\n item: Item,\n bounds: ItemBounds,\n state: ItemState,\n helpers: DrawHelpers,\n) => void\n\nexport type CanvasGroupItemRenderer = CanvasItemRenderer\n\nexport interface DayStyle {\n backgroundColor?: string\n borderColor?: string\n opacity?: number\n}\n\nexport interface RowStyle {\n backgroundColor?: string\n borderBottomColor?: string\n}\n\nexport interface Dependency {\n fromItemId: number\n toItemId: number\n type?: 'finish-to-start' | 'start-to-start' | 'finish-to-finish'\n color?: string\n}\n\nexport interface TimeRangeHighlight {\n start: number\n end: number\n color: string\n label?: string\n opacity?: number\n}\n\nexport interface TimelineTheme {\n primary: string\n trainColors: Record<string, string>\n status: { red: string; yellow: string; green: string }\n grid: { line: string; rowAlt: string; weekend: string }\n item: { radius: number; text: string; selectedRing: string }\n marker: { today: string; milestone: string; cursor: string }\n sidebar: { bg: string; border: string; text: string }\n header: { bg: string; border: string; text: string }\n}\n\nexport const DEFAULT_THEME: TimelineTheme = {\n primary: '#269bf7',\n trainColors: {},\n status: { red: '#EF5350', yellow: '#FBBF24', green: '#31c48d' },\n grid: { line: '#E5E5E5', rowAlt: '#F7F7F7', weekend: 'rgba(0,0,0,0.03)' },\n item: { radius: 3, text: '#374151', selectedRing: '#a3a3a3' },\n marker: { today: '#FD7171', milestone: '#3B82F6', cursor: '#269bf7' },\n sidebar: { bg: '#F9FAFB', border: '#E5E7EB', text: '#6c737f' },\n header: { bg: '#F9FAFB', border: '#E5E7EB', text: '#6c737f' },\n}\n\nexport interface MarkerConfig {\n date: number\n color: string\n width: number\n label?: string\n}\n\n/** Live state of an in-progress drag/resize, emitted via `onInteractionUpdate`.\n * All times are the snapped values that will commit on drop (item-edge snap +\n * grid snap, plus hierarchy resize constraints) — i.e. where the item will\n * actually land, matching the snap guide. The consumer-supplied\n * `moveResizeValidator` is NOT applied here (it may run per frame). */\nexport interface InteractionInfo {\n itemId: number\n mode: 'move' | 'resize-left' | 'resize-right'\n /** Set for resize interactions; which edge is being dragged. */\n edge?: 'left' | 'right'\n /** The headline time to display: the new start for `move`/`resize-left`, the\n * new end for `resize-right`. */\n time: number\n /** The item's snapped start time during this interaction. */\n startTime: number\n /** The item's snapped end time during this interaction. */\n endTime: number\n /** Pointer position in viewport coordinates (clientX/clientY), for\n * positioning a `position: fixed` tooltip without further math. */\n pointerX: number\n pointerY: number\n}\n\n/** Anchored snap grid: snap to `anchor + N * interval`. Returning this from a\n * {@link DragSnapFn} overrides the default tz-local-midnight anchoring — the\n * consumer is fully in charge of phase. */\nexport interface DragSnapAnchor {\n /** Snap interval in ms. Must be finite and `> 0`, else snapping is disabled\n * (falls back to no snap, one `console.warn` per session). */\n interval: number\n /** Absolute epoch ms. The snap grid is built as\n * `anchor + N * interval`. Because `interval` is exact ms, the grid does\n * NOT track wall-clock hour across DST — at the spring-forward boundary the\n * snapped position will drift one hour from local time and stay drifted\n * until the next anchor reset. Consumers that need wall-clock-stable\n * snapping should re-pick an anchor on the DST side they care about.\n * The timeline's `timezone` prop is ignored when an anchor is supplied. */\n anchor: number\n}\n\n/** What a {@link DragSnapFn} may return: a bare interval (ms) — tz-aware\n * default anchoring — or an explicit `{ interval, anchor }` grid. */\nexport type DragSnapResult = number | DragSnapAnchor\n\n/**\n * Per-drag snap resolver. Called on every pointer-move frame during a\n * drag/resize, so keep it cheap — the library does not memoize the result.\n *\n * @param item The item being dragged/resized.\n * @param edge `'left' | 'right'` during a resize; `undefined` during a move.\n * @returns Either a snap interval in ms (varies only the *interval*; phase stays\n * grid-aligned to multiples of it — tz-local midnight for day-or-larger\n * intervals when `timezone` is set), or a {@link DragSnapAnchor} `{ interval,\n * anchor }` to also control phase (tz is ignored in that case). A `0`, `NaN`,\n * or negative `interval` (or non-finite `anchor`) falls back to no snap.\n */\nexport type DragSnapFn = (item: Item, edge?: 'left' | 'right') => DragSnapResult\n\nexport interface CanvasTimelineProps {\n groups: Group[]\n items: Item[]\n defaultTimeStart: number\n defaultTimeEnd: number\n visibleTimeStart?: number\n visibleTimeEnd?: number\n sidebarWidth: number\n lineHeight: number\n itemHeightRatio: number\n stackItems: boolean\n buffer?: number\n canMove: boolean\n canResize: false | 'left' | 'right' | 'both'\n canChangeGroup: boolean\n /** Snap interval for drag/resize, in ms. A `number` snaps everything to that\n * interval; a {@link DragSnapFn} resolves the interval per item/edge. When\n * omitted, no snapping is applied. */\n dragSnap?: number | DragSnapFn\n minZoom: number\n maxZoom: number\n theme?: Partial<TimelineTheme>\n dayStyle?: (date: Date) => DayStyle | null\n rowStyle?: (group: Group) => RowStyle | null\n showCursorLine?: boolean\n itemRenderer: CanvasItemRenderer\n groupRenderer?: CanvasGroupItemRenderer\n summaryRenderer?: CanvasItemRenderer\n sidebarGroupRenderer: (group: Group) => React.ReactNode\n rightSidebarWidth?: number\n rightSidebarGroupRenderer?: (group: Group) => React.ReactNode\n dependencies?: Dependency[]\n highlights?: TimeRangeHighlight[]\n onItemClick?: (itemId: number, e: PointerEvent) => void\n onItemDoubleClick?: (itemId: number, e: PointerEvent) => void\n onItemContextMenu?: (itemId: number, e: PointerEvent) => void\n onItemMove?: (itemId: number, newStartTime: number, newGroupId: string | number, childMoves?: { itemId: number; newStart: number }[]) => void\n onItemResize?: (itemId: number, newTime: number, edge: 'left' | 'right') => void\n /** Validate and optionally constrain move/resize. Return the (possibly modified) time. */\n moveResizeValidator?: (action: 'move' | 'resize', itemId: number, time: number, edge?: 'left' | 'right') => number\n onItemHover?: (itemId: number | null, e: PointerEvent) => void\n /** Fires once per animation frame during an active drag/resize, then once with\n * `null` when it ends. Intended for a live \"current time\" tooltip. This is a\n * hot path: do NOT call setState here — mutate a ref'd DOM node's text/transform\n * directly so neither the library nor your app re-renders per frame. */\n onInteractionUpdate?: (info: InteractionInfo | null) => void\n onCanvasDoubleClick?: (groupId: number, time: number) => void\n onCanvasContextMenu?: (groupId: number, time: number, e: PointerEvent) => void\n onTimeChange?: (start: number, end: number) => void\n onZoom?: (start: number, end: number) => void\n selected?: number[]\n /** Called when the timeline is ready, providing the capture API */\n onReady?: (api: CanvasTimelineRef) => void\n /** Dev-only: show a version + build-time badge in the top-left corner.\n * Wire to your app's dev flag, e.g. `devBadge={import.meta.env.DEV}`. */\n /** Maximum visible height for the timeline body. Accepts a number (px) or\n * a CSS string like `'calc(100vh - 98px)'`. When set, the canvas and sidebar\n * are clipped and internally scrollable via wheel, drag, or touch. */\n maxHeight?: number | string\n /** IANA timezone string (e.g. \"America/New_York\", \"UTC\").\n * When set, grid lines, headers, and day styling render in this timezone.\n * Defaults to the browser's local timezone. */\n timezone?: string\n devBadge?: boolean\n children?: React.ReactNode\n}\n\nexport interface CaptureOptions {\n timeStart: number\n timeEnd: number\n scale: number\n sidebarWidth: number\n}\n\nexport interface CanvasTimelineRef {\n captureToCanvas(options: CaptureOptions): HTMLCanvasElement\n}\n","export interface ViewStateConfig {\n visibleTimeStart: number\n visibleTimeEnd: number\n canvasWidth: number\n canvasHeight: number\n sidebarWidth: number\n lineHeight: number\n groupCount: number\n buffer: number\n scrollTop: number\n groupHeights?: number[]\n}\n\nexport class ViewState {\n visibleTimeStart: number\n visibleTimeEnd: number\n canvasWidth: number\n canvasHeight: number\n sidebarWidth: number\n lineHeight: number\n groupCount: number\n buffer: number\n scrollTop: number\n groupHeights: number[] | null\n\n private visibleDuration: number\n private pixelsPerMs: number\n // Cumulative top-edge offsets per group: length = groupCount + 1,\n // groupYOffsets[i] = sum of heights[0..i-1]; groupYOffsets[groupCount] = total.\n private groupYOffsets: number[]\n\n constructor(config: ViewStateConfig) {\n this.visibleTimeStart = config.visibleTimeStart\n this.visibleTimeEnd = config.visibleTimeEnd\n this.canvasWidth = config.canvasWidth\n this.canvasHeight = config.canvasHeight\n this.sidebarWidth = config.sidebarWidth\n this.lineHeight = config.lineHeight\n this.groupCount = config.groupCount\n this.buffer = config.buffer\n this.scrollTop = config.scrollTop\n this.groupHeights = config.groupHeights ?? null\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n this.groupYOffsets = []\n this.recomputeGroupYOffsets()\n }\n\n update(params: Partial<ViewStateConfig>): void {\n if (params.visibleTimeStart !== undefined) this.visibleTimeStart = params.visibleTimeStart\n if (params.visibleTimeEnd !== undefined) this.visibleTimeEnd = params.visibleTimeEnd\n if (params.canvasWidth !== undefined) this.canvasWidth = params.canvasWidth\n if (params.canvasHeight !== undefined) this.canvasHeight = params.canvasHeight\n if (params.sidebarWidth !== undefined) this.sidebarWidth = params.sidebarWidth\n if (params.lineHeight !== undefined) this.lineHeight = params.lineHeight\n if (params.groupCount !== undefined) this.groupCount = params.groupCount\n if (params.buffer !== undefined) this.buffer = params.buffer\n if (params.scrollTop !== undefined) this.scrollTop = params.scrollTop\n if (params.groupHeights !== undefined) this.groupHeights = params.groupHeights ?? null\n\n this.visibleDuration = this.visibleTimeEnd - this.visibleTimeStart\n this.pixelsPerMs = this.canvasWidth / this.visibleDuration\n this.recomputeGroupYOffsets()\n }\n\n private recomputeGroupYOffsets(): void {\n const offsets = new Array<number>(this.groupCount + 1)\n offsets[0] = 0\n for (let i = 0; i < this.groupCount; i++) {\n const h = this.groupHeights?.[i] ?? this.lineHeight\n offsets[i + 1] = offsets[i] + h\n }\n this.groupYOffsets = offsets\n }\n\n timeToX(time: number): number {\n return (time - this.visibleTimeStart) * this.pixelsPerMs\n }\n\n xToTime(x: number): number {\n return this.visibleTimeStart + x / this.pixelsPerMs\n }\n\n yToGroupIndex(y: number): number {\n if (this.groupCount === 0) return 0\n const target = y + this.scrollTop\n if (target <= 0) return 0\n if (target >= this.groupYOffsets[this.groupCount]) return this.groupCount - 1\n // Binary search: smallest i where groupYOffsets[i + 1] > target.\n let lo = 0\n let hi = this.groupCount - 1\n while (lo < hi) {\n const mid = (lo + hi) >>> 1\n if (this.groupYOffsets[mid + 1] > target) hi = mid\n else lo = mid + 1\n }\n return lo\n }\n\n groupIndexToY(index: number): number {\n if (index < 0) return -this.scrollTop\n if (index >= this.groupCount) {\n return (this.groupYOffsets[this.groupCount] ?? 0) - this.scrollTop\n }\n return this.groupYOffsets[index] - this.scrollTop\n }\n\n groupIndexToHeight(index: number): number {\n if (index < 0 || index >= this.groupCount) return this.lineHeight\n return this.groupHeights?.[index] ?? this.lineHeight\n }\n\n getBufferBounds(): { bufferStart: number; bufferEnd: number } {\n const extend = this.visibleDuration * 1.5\n return {\n bufferStart: this.visibleTimeStart - extend,\n bufferEnd: this.visibleTimeEnd + extend,\n }\n }\n\n getVisibleGroupRange(): { firstVisible: number; lastVisible: number } {\n if (this.groupCount === 0) return { firstVisible: 0, lastVisible: -1 }\n const firstVisible = this.yToGroupIndex(0)\n const lastVisible = this.yToGroupIndex(this.canvasHeight)\n return { firstVisible, lastVisible }\n }\n\n isScrollInBuffer(scrollXOffset: number): boolean {\n const bufferPixels = this.visibleDuration * 1.5 * this.pixelsPerMs\n return Math.abs(scrollXOffset) < bufferPixels\n }\n\n getTotalHeight(): number {\n return this.groupYOffsets[this.groupCount] ?? 0\n }\n}\n","interface TreeNode<T> {\n center: number\n left: TreeNode<T> | null\n right: TreeNode<T> | null\n overlapping: Array<{ item: T; start: number; end: number }>\n}\n\nexport class IntervalTree<T> {\n private root: TreeNode<T> | null = null\n\n buildFromItems(\n items: T[],\n getStart: (item: T) => number,\n getEnd: (item: T) => number,\n ): void {\n const intervals = items.map((item) => ({\n item,\n start: getStart(item),\n end: getEnd(item),\n }))\n this.root = this.buildNode(intervals)\n }\n\n private buildNode(\n intervals: Array<{ item: T; start: number; end: number }>,\n ): TreeNode<T> | null {\n if (intervals.length === 0) return null\n\n let min = Infinity\n let max = -Infinity\n for (const iv of intervals) {\n if (iv.start < min) min = iv.start\n if (iv.end > max) max = iv.end\n }\n const center = (min + max) / 2\n\n const leftIntervals: Array<{ item: T; start: number; end: number }> = []\n const rightIntervals: Array<{ item: T; start: number; end: number }> = []\n const overlapping: Array<{ item: T; start: number; end: number }> = []\n\n for (const iv of intervals) {\n if (iv.end < center) {\n leftIntervals.push(iv)\n } else if (iv.start > center) {\n rightIntervals.push(iv)\n } else {\n overlapping.push(iv)\n }\n }\n\n return {\n center,\n left: this.buildNode(leftIntervals),\n right: this.buildNode(rightIntervals),\n overlapping,\n }\n }\n\n query(start: number, end: number): T[] {\n const results: T[] = []\n this.queryNode(this.root, start, end, results)\n return results\n }\n\n private queryNode(\n node: TreeNode<T> | null,\n start: number,\n end: number,\n results: T[],\n ): void {\n if (node === null) return\n\n for (const iv of node.overlapping) {\n if (iv.start <= end && iv.end >= start) {\n results.push(iv.item)\n }\n }\n\n if (start <= node.center && node.left !== null) {\n this.queryNode(node.left, start, end, results)\n }\n\n if (end >= node.center && node.right !== null) {\n this.queryNode(node.right, start, end, results)\n }\n }\n}\n","import type { Item } from '../types'\nimport type { HierarchyEngine } from './HierarchyEngine'\n\nexport interface ItemLayout {\n stackLevel: number\n itemHeight: number\n}\n\nexport class LayoutEngine {\n private readonly lineHeight: number\n private readonly itemHeightRatio: number\n private layoutCache: Map<number, ItemLayout> = new Map()\n private groupMaxStack: Map<string | number, number> = new Map()\n\n constructor(lineHeight: number, itemHeightRatio: number) {\n this.lineHeight = lineHeight\n this.itemHeightRatio = itemHeightRatio\n }\n\n computeLayout(items: Item[], stackItems: boolean, hierarchy?: HierarchyEngine): Map<number, ItemLayout> {\n this.layoutCache = new Map()\n this.groupMaxStack = new Map()\n\n const itemHeight = this.lineHeight * this.itemHeightRatio\n const summaryHeight = itemHeight * 0.6\n\n if (!stackItems) {\n for (const item of items) {\n const isSummary = hierarchy?.isParent(item.id) ?? false\n this.layoutCache.set(item.id, { stackLevel: 0, itemHeight: isSummary ? summaryHeight : itemHeight })\n this.groupMaxStack.set(item.group, 0)\n }\n return this.layoutCache\n }\n\n // Group items by group id\n const byGroup = new Map<string | number, Item[]>()\n for (const item of items) {\n let arr = byGroup.get(item.group)\n if (!arr) {\n arr = []\n byGroup.set(item.group, arr)\n }\n arr.push(item)\n }\n\n for (const [groupId, groupItems] of byGroup) {\n if (hierarchy) {\n this.computeHierarchyLayout(groupItems, hierarchy, itemHeight, summaryHeight, groupId)\n } else {\n this.computeFlatLayout(groupItems, itemHeight, groupId)\n }\n }\n\n return this.layoutCache\n }\n\n private computeFlatLayout(groupItems: Item[], itemHeight: number, groupId: string | number): void {\n groupItems.sort((a, b) => {\n const d = a.start_time - b.start_time\n if (d !== 0) return d\n return (b.end_time - b.start_time) - (a.end_time - a.start_time)\n })\n\n const levelEnds: number[] = []\n let maxLevel = 0\n\n for (const item of groupItems) {\n let level = -1\n for (let i = 0; i < levelEnds.length; i++) {\n if (levelEnds[i] <= item.start_time) {\n level = i\n break\n }\n }\n\n if (level === -1) {\n level = levelEnds.length\n levelEnds.push(item.end_time)\n } else {\n levelEnds[level] = item.end_time\n }\n\n if (level > maxLevel) maxLevel = level\n\n this.layoutCache.set(item.id, { stackLevel: level, itemHeight })\n }\n\n this.groupMaxStack.set(groupId, maxLevel)\n }\n\n private computeHierarchyLayout(\n groupItems: Item[],\n hierarchy: HierarchyEngine,\n itemHeight: number,\n summaryHeight: number,\n groupId: string | number,\n ): void {\n // Separate leaf items from parents\n const leaves: Item[] = []\n const parents: Item[] = []\n for (const item of groupItems) {\n if (hierarchy.isParent(item.id)) {\n parents.push(item)\n } else {\n leaves.push(item)\n }\n }\n\n // Stack leaves first using sweep-line\n leaves.sort((a, b) => {\n const d = a.start_time - b.start_time\n if (d !== 0) return d\n return (b.end_time - b.start_time) - (a.end_time - a.start_time)\n })\n\n const levelEnds: number[] = []\n let maxLevel = 0\n\n for (const item of leaves) {\n let level = -1\n for (let i = 0; i < levelEnds.length; i++) {\n if (levelEnds[i] <= item.start_time) {\n level = i\n break\n }\n }\n\n if (level === -1) {\n level = levelEnds.length\n levelEnds.push(item.end_time)\n } else {\n levelEnds[level] = item.end_time\n }\n\n if (level > maxLevel) maxLevel = level\n\n this.layoutCache.set(item.id, { stackLevel: level, itemHeight })\n }\n\n // Stack parents above leaves, sorted by nesting depth\n // Deepest parents first (closest to children), shallowest last (on top)\n parents.sort((a, b) => hierarchy.getNestingDepth(b.id) - hierarchy.getNestingDepth(a.id))\n\n let nextLevel = leaves.length > 0 ? maxLevel + 1 : 0\n for (const parent of parents) {\n this.layoutCache.set(parent.id, { stackLevel: nextLevel, itemHeight: summaryHeight })\n if (nextLevel > maxLevel) maxLevel = nextLevel\n nextLevel++\n }\n\n this.groupMaxStack.set(groupId, maxLevel)\n }\n\n getLayout(itemId: number): ItemLayout | undefined {\n return this.layoutCache.get(itemId)\n }\n\n getGroupHeight(groupId: string | number): number {\n const maxStack = this.groupMaxStack.get(groupId) ?? 0\n return (maxStack + 1) * this.lineHeight\n }\n}\n","interface HierarchyItem {\n id: number\n start_time: number\n end_time: number\n parentId?: number\n}\n\nexport class HierarchyEngine {\n private parentToChildren: Map<number, number[]> = new Map()\n private childToParent: Map<number, number> = new Map()\n private itemMap: Map<number, HierarchyItem> = new Map()\n private depthCache: Map<number, number> = new Map()\n\n rebuild(items: HierarchyItem[]): void {\n this.parentToChildren = new Map()\n this.childToParent = new Map()\n this.itemMap = new Map()\n this.depthCache = new Map()\n\n for (const item of items) {\n this.itemMap.set(item.id, item)\n }\n\n for (const item of items) {\n if (item.parentId !== undefined && this.itemMap.has(item.parentId)) {\n this.childToParent.set(item.id, item.parentId)\n let children = this.parentToChildren.get(item.parentId)\n if (!children) {\n children = []\n this.parentToChildren.set(item.parentId, children)\n }\n children.push(item.id)\n }\n }\n\n // Detect and break cycles\n for (const id of this.childToParent.keys()) {\n const visited = new Set<number>()\n let current: number | undefined = id\n while (current !== undefined) {\n if (visited.has(current)) {\n const parentId = this.childToParent.get(id)!\n this.childToParent.delete(id)\n const siblings = this.parentToChildren.get(parentId)\n if (siblings) {\n const idx = siblings.indexOf(id)\n if (idx !== -1) siblings.splice(idx, 1)\n if (siblings.length === 0) this.parentToChildren.delete(parentId)\n }\n break\n }\n visited.add(current)\n current = this.childToParent.get(current)\n }\n }\n }\n\n isParent(itemId: number): boolean {\n const children = this.parentToChildren.get(itemId)\n return children !== undefined && children.length > 0\n }\n\n getParent(itemId: number): number | undefined {\n return this.childToParent.get(itemId)\n }\n\n getChildren(itemId: number): number[] {\n return this.parentToChildren.get(itemId) ?? []\n }\n\n getDescendants(itemId: number): number[] {\n const result: number[] = []\n const stack = [...this.getChildren(itemId)]\n while (stack.length > 0) {\n const id = stack.pop()!\n result.push(id)\n const children = this.parentToChildren.get(id)\n if (children) stack.push(...children)\n }\n return result\n }\n\n getEffectiveSpan(itemId: number): { start: number; end: number } {\n const item = this.itemMap.get(itemId)\n if (!item) return { start: 0, end: 0 }\n\n let start = item.start_time\n let end = item.end_time\n\n const descendants = this.getDescendants(itemId)\n for (const descId of descendants) {\n const desc = this.itemMap.get(descId)\n if (!desc) continue\n if (desc.start_time < start) start = desc.start_time\n if (desc.end_time > end) end = desc.end_time\n }\n\n return { start, end }\n }\n\n getNestingDepth(itemId: number): number {\n const cached = this.depthCache.get(itemId)\n if (cached !== undefined) return cached\n\n let depth = 0\n let current = this.childToParent.get(itemId)\n while (current !== undefined) {\n depth++\n current = this.childToParent.get(current)\n }\n this.depthCache.set(itemId, depth)\n return depth\n }\n\n getMoveDelta(itemId: number, newStart: number): { itemId: number; newStart: number }[] {\n const item = this.itemMap.get(itemId)\n if (!item) return []\n\n const delta = newStart - item.start_time\n const descendants = this.getDescendants(itemId)\n return descendants.map(descId => {\n const desc = this.itemMap.get(descId)!\n return { itemId: descId, newStart: desc.start_time + delta }\n })\n }\n\n getResizeConstraint(itemId: number, edge: 'left' | 'right'): { min: number; max: number } {\n const children = this.getDescendants(itemId)\n if (children.length === 0) {\n return edge === 'left'\n ? { min: -Infinity, max: Infinity }\n : { min: -Infinity, max: Infinity }\n }\n\n if (edge === 'left') {\n let minChildStart = Infinity\n for (const childId of children) {\n const child = this.itemMap.get(childId)\n if (child && child.start_time < minChildStart) {\n minChildStart = child.start_time\n }\n }\n return { min: -Infinity, max: minChildStart }\n } else {\n let maxChildEnd = -Infinity\n for (const childId of children) {\n const child = this.itemMap.get(childId)\n if (child && child.end_time > maxChildEnd) {\n maxChildEnd = child.end_time\n }\n }\n return { min: maxChildEnd, max: Infinity }\n }\n }\n}\n","import type { Item, ItemBounds, ItemState, DrawHelpers, TimelineTheme } from '../types'\n\nexport function defaultSummaryRenderer(\n ctx: CanvasRenderingContext2D,\n item: Item,\n bounds: ItemBounds,\n state: ItemState,\n _helpers: DrawHelpers,\n theme: TimelineTheme,\n): void {\n const { x, y, width, height } = bounds\n const color = theme.primary\n\n // Semi-transparent fill\n ctx.globalAlpha = 0.15\n ctx.fillStyle = color\n ctx.fillRect(x, y, width, height)\n ctx.globalAlpha = 1\n\n // Border\n ctx.strokeStyle = color\n ctx.lineWidth = 1.5\n ctx.strokeRect(x, y, width, height)\n\n // Diamond marker at start edge\n const diamondSize = Math.min(height * 0.5, 6)\n const midY = y + height / 2\n\n ctx.fillStyle = color\n // Left diamond\n ctx.beginPath()\n ctx.moveTo(x, midY)\n ctx.lineTo(x + diamondSize, midY - diamondSize)\n ctx.lineTo(x + diamondSize * 2, midY)\n ctx.lineTo(x + diamondSize, midY + diamondSize)\n ctx.closePath()\n ctx.fill()\n\n // Right diamond\n ctx.beginPath()\n ctx.moveTo(x + width, midY)\n ctx.lineTo(x + width - diamondSize, midY - diamondSize)\n ctx.lineTo(x + width - diamondSize * 2, midY)\n ctx.lineTo(x + width - diamondSize, midY + diamondSize)\n ctx.closePath()\n ctx.fill()\n\n // Title text centered\n const title = (item as { title?: string }).title\n if (title && width > 30) {\n ctx.fillStyle = theme.item.text\n ctx.font = '500 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n ctx.textBaseline = 'middle'\n const textWidth = ctx.measureText(title).width\n const maxTextWidth = width - diamondSize * 4 - 4\n if (maxTextWidth > 20) {\n const displayText = textWidth > maxTextWidth\n ? title.slice(0, Math.floor(title.length * maxTextWidth / textWidth)) + '...'\n : title\n ctx.fillText(displayText, x + width / 2 - Math.min(textWidth, maxTextWidth) / 2, midY)\n }\n }\n\n // Selected ring\n if (state.selected) {\n ctx.strokeStyle = theme.item.selectedRing\n ctx.lineWidth = 2\n ctx.strokeRect(x - 1, y - 1, width + 2, height + 2)\n }\n}\n","import type { Item, Group } from '../types'\nimport type { ViewState } from './ViewState'\nimport type { IntervalTree } from './IntervalTree'\nimport type { LayoutEngine } from './LayoutEngine'\n\nexport function hitTest(\n canvasX: number,\n canvasY: number,\n view: ViewState,\n tree: IntervalTree<Item>,\n layout: LayoutEngine,\n groups: Group[],\n): Item | null {\n const time = view.xToTime(canvasX)\n\n const groupIndexMap = new Map<string | number, number>()\n for (let i = 0; i < groups.length; i++) {\n groupIndexMap.set(groups[i].id, i)\n }\n\n const candidates = tree.query(time, time)\n\n let topItem: Item | null = null\n let topY = -Infinity\n\n for (const item of candidates) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n\n const itemLayout = layout.getLayout(item.id)\n if (!itemLayout) continue\n\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n\n if (canvasX < x || canvasX > x + width) continue\n\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n const height = itemLayout.itemHeight\n\n if (canvasY < y || canvasY > y + height) continue\n\n if (y > topY) {\n topY = y\n topItem = item\n }\n }\n\n return topItem\n}\n\nexport function hitTestGroup(\n canvasY: number,\n view: ViewState,\n groups: Group[],\n): Group | null {\n const groupIndex = view.yToGroupIndex(canvasY)\n return groups[groupIndex] ?? null\n}\n\nexport function detectEdge(\n canvasX: number,\n item: Item,\n view: ViewState,\n threshold: number = 6,\n): 'left' | 'right' | 'body' {\n const leftX = view.timeToX(item.start_time)\n const rightX = view.timeToX(item.end_time)\n if (canvasX - leftX <= threshold) return 'left'\n if (rightX - canvasX <= threshold) return 'right'\n return 'body'\n}\n\n/**\n * Resolve the effective `canResize` for an item: a per-item `item.canResize`\n * wins when present, otherwise the timeline-wide `globalCanResize` applies.\n * Uses `??` (not `||`) so an explicit per-item `false` disables resize rather\n * than falling through to the global value.\n */\nexport function resolveCanResize(\n item: Item,\n globalCanResize: false | 'left' | 'right' | 'both',\n): false | 'left' | 'right' | 'both' {\n return item.canResize ?? globalCanResize\n}\n\n/**\n * Resolve the effective `canMove` for an item: a per-item `item.canMove` wins\n * when present, otherwise the timeline-wide `globalCanMove` applies. Uses `??`\n * (not `||`) so an explicit per-item `false` disables moving rather than\n * falling through to the global value.\n */\nexport function resolveCanMove(item: Item, globalCanMove: boolean): boolean {\n return item.canMove ?? globalCanMove\n}\n\n/**\n * Decide which interaction (if any) a pointer-down at `edge` should start for\n * `item`, given the timeline-wide `canResize`/`canMove` props. Returns `null`\n * when nothing is permitted — the caller then starts no interaction (no ghost)\n * and shows no affordance (default cursor). Centralising this keeps the cursor\n * and the interaction decision in lockstep.\n *\n * An item explicitly resize-locked per-item (`item.canResize === false`) has\n * inert edges: grabbing an edge returns `null` rather than falling through to a\n * move, so a user trying to resize a locked item sees no UI. This is scoped to\n * the *explicit* per-item override — an item inheriting a global `canResize:\n * false` (field undefined) keeps the move-only behaviour where the whole item,\n * edges included, is draggable.\n */\nexport function resolveInteractionMode(\n item: Item,\n edge: 'left' | 'right' | 'body',\n globalCanResize: false | 'left' | 'right' | 'both',\n globalCanMove: boolean,\n): 'move' | 'resize-left' | 'resize-right' | null {\n const cr = resolveCanResize(item, globalCanResize)\n if (edge === 'left' && (cr === 'left' || cr === 'both')) return 'resize-left'\n if (edge === 'right' && (cr === 'right' || cr === 'both')) return 'resize-right'\n if (item.canResize === false && edge !== 'body') return null\n if (resolveCanMove(item, globalCanMove)) return 'move'\n return null\n}\n","/**\n * Resize the canvas buffer only when dimensions actually change.\n * Setting canvas.width/height is destructive (clears buffer + resets state),\n * so we avoid it unless necessary.\n */\nexport function setupCanvas(\n canvas: HTMLCanvasElement,\n width: number,\n height: number,\n): CanvasRenderingContext2D {\n const dpr = window.devicePixelRatio || 1\n const targetW = Math.round(width * dpr)\n const targetH = Math.round(height * dpr)\n\n if (canvas.width !== targetW || canvas.height !== targetH) {\n canvas.width = targetW\n canvas.height = targetH\n canvas.style.width = `${width}px`\n canvas.style.height = `${height}px`\n }\n\n const ctx = canvas.getContext('2d')!\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n return ctx\n}\n\nexport function clearCanvas(ctx: CanvasRenderingContext2D, canvas: HTMLCanvasElement): void {\n const dpr = window.devicePixelRatio || 1\n ctx.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr)\n}\n\nexport type LayerName = 'grid' | 'items' | 'overlay'\n\nexport interface DirtyFlags {\n grid: boolean\n items: boolean\n overlay: boolean\n}\n\nexport class RenderScheduler {\n private dirty: DirtyFlags = { grid: false, items: false, overlay: false }\n private rafId: number | null = null\n private drawCallback: (flags: DirtyFlags) => void\n\n constructor(drawCallback: (flags: DirtyFlags) => void) {\n this.drawCallback = drawCallback\n }\n\n markDirty(layer: LayerName): void {\n this.dirty[layer] = true\n this.schedule()\n }\n\n markAllDirty(): void {\n this.dirty.grid = true\n this.dirty.items = true\n this.dirty.overlay = true\n this.schedule()\n }\n\n dispose(): void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId)\n this.rafId = null\n }\n }\n\n private schedule(): void {\n if (this.rafId !== null) return\n this.rafId = requestAnimationFrame(() => {\n this.rafId = null\n const flags = { ...this.dirty }\n this.dirty.grid = false\n this.dirty.items = false\n this.dirty.overlay = false\n this.drawCallback(flags)\n })\n }\n}\n","!function(t,i){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=i():\"function\"==typeof define&&define.amd?define(i):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).dayjs_plugin_utc=i()}(this,(function(){\"use strict\";var t=\"minute\",i=/[+-]\\d\\d(?::?\\d\\d)?/g,e=/([+-]|\\d\\d)/g;return function(s,f,n){var u=f.prototype;n.utc=function(t){var i={date:t,utc:!0,args:arguments};return new f(i)},u.utc=function(i){var e=n(this.toDate(),{locale:this.$L,utc:!0});return i?e.add(this.utcOffset(),t):e},u.local=function(){return n(this.toDate(),{locale:this.$L,utc:!1})};var r=u.parse;u.parse=function(t){t.utc&&(this.$u=!0),this.$utils().u(t.$offset)||(this.$offset=t.$offset),r.call(this,t)};var o=u.init;u.init=function(){if(this.$u){var t=this.$d;this.$y=t.getUTCFullYear(),this.$M=t.getUTCMonth(),this.$D=t.getUTCDate(),this.$W=t.getUTCDay(),this.$H=t.getUTCHours(),this.$m=t.getUTCMinutes(),this.$s=t.getUTCSeconds(),this.$ms=t.getUTCMilliseconds()}else o.call(this)};var a=u.utcOffset;u.utcOffset=function(s,f){var n=this.$utils().u;if(n(s))return this.$u?0:n(this.$offset)?a.call(this):this.$offset;if(\"string\"==typeof s&&(s=function(t){void 0===t&&(t=\"\");var s=t.match(i);if(!s)return null;var f=(\"\"+s[0]).match(e)||[\"-\",0,0],n=f[0],u=60*+f[1]+ +f[2];return 0===u?0:\"+\"===n?u:-u}(s),null===s))return this;var u=Math.abs(s)<=16?60*s:s;if(0===u)return this.utc(f);var r=this.clone();if(f)return r.$offset=u,r.$u=!1,r;var o=this.$u?this.toDate().getTimezoneOffset():-1*this.utcOffset();return(r=this.local().add(u+o,t)).$offset=u,r.$x.$localOffset=o,r};var h=u.format;u.format=function(t){var i=t||(this.$u?\"YYYY-MM-DDTHH:mm:ss[Z]\":\"\");return h.call(this,i)},u.valueOf=function(){var t=this.$utils().u(this.$offset)?0:this.$offset+(this.$x.$localOffset||this.$d.getTimezoneOffset());return this.$d.valueOf()-6e4*t},u.isUTC=function(){return!!this.$u},u.toISOString=function(){return this.toDate().toISOString()},u.toString=function(){return this.toDate().toUTCString()};var l=u.toDate;u.toDate=function(t){return\"s\"===t&&this.$offset?n(this.format(\"YYYY-MM-DD HH:mm:ss:SSS\")).toDate():l.call(this)};var c=u.diff;u.diff=function(t,i,e){if(t&&this.$u===t.$u)return c.call(this,t,i,e);var s=this.local(),f=n(t).local();return c.call(s,f,i,e)}}}));","!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).dayjs_plugin_timezone=e()}(this,(function(){\"use strict\";var t={year:0,month:1,day:2,hour:3,minute:4,second:5},e={};return function(n,i,o){var r,a=function(t,n,i){void 0===i&&(i={});var o=new Date(t),r=function(t,n){void 0===n&&(n={});var i=n.timeZoneName||\"short\",o=t+\"|\"+i,r=e[o];return r||(r=new Intl.DateTimeFormat(\"en-US\",{hour12:!1,timeZone:t,year:\"numeric\",month:\"2-digit\",day:\"2-digit\",hour:\"2-digit\",minute:\"2-digit\",second:\"2-digit\",timeZoneName:i}),e[o]=r),r}(n,i);return r.formatToParts(o)},u=function(e,n){for(var i=a(e,n),r=[],u=0;u<i.length;u+=1){var f=i[u],s=f.type,m=f.value,c=t[s];c>=0&&(r[c]=parseInt(m,10))}var d=r[3],l=24===d?0:d,h=r[0]+\"-\"+r[1]+\"-\"+r[2]+\" \"+l+\":\"+r[4]+\":\"+r[5]+\":000\",v=+e;return(o.utc(h).valueOf()-(v-=v%1e3))/6e4},f=i.prototype;f.tz=function(t,e){void 0===t&&(t=r);var n,i=this.utcOffset(),a=this.toDate(),u=a.toLocaleString(\"en-US\",{timeZone:t}),f=Math.round((a-new Date(u))/1e3/60),s=15*-Math.round(a.getTimezoneOffset()/15)-f;if(!Number(s))n=this.utcOffset(0,e);else if(n=o(u,{locale:this.$L}).$set(\"millisecond\",this.$ms).utcOffset(s,!0),e){var m=n.utcOffset();n=n.add(i-m,\"minute\")}return n.$x.$timezone=t,n},f.offsetName=function(t){var e=this.$x.$timezone||o.tz.guess(),n=a(this.valueOf(),e,{timeZoneName:t}).find((function(t){return\"timezonename\"===t.type.toLowerCase()}));return n&&n.value};var s=f.startOf;f.startOf=function(t,e){if(!this.$x||!this.$x.$timezone)return s.call(this,t,e);var n=o(this.format(\"YYYY-MM-DD HH:mm:ss:SSS\"),{locale:this.$L});return s.call(n,t,e).tz(this.$x.$timezone,!0)},o.tz=function(t,e,n){var i=n&&e,a=n||e||r,f=u(+o(),a);if(\"string\"!=typeof t)return o(t).tz(a);var s=function(t,e,n){var i=t-60*e*1e3,o=u(i,n);if(e===o)return[i,e];var r=u(i-=60*(o-e)*1e3,n);return o===r?[i,o]:[t-60*Math.min(o,r)*1e3,Math.max(o,r)]}(o.utc(t,i).valueOf(),f,a),m=s[0],c=s[1],d=o(m).utcOffset(c);return d.$x.$timezone=a,d},o.tz.guess=function(){return Intl.DateTimeFormat().resolvedOptions().timeZone},o.tz.setDefault=function(t){r=t}}}));","import dayjs from 'dayjs'\nimport utc from 'dayjs/plugin/utc'\nimport tz from 'dayjs/plugin/timezone'\n\ndayjs.extend(utc)\ndayjs.extend(tz)\n\nexport function toDayjs(ts: number, timezone?: string): dayjs.Dayjs {\n return timezone ? dayjs(ts).tz(timezone) : dayjs(ts)\n}\n","import { toDayjs } from '../utils/timezone'\nimport type { Group, TimelineTheme, DayStyle, RowStyle, TimeRangeHighlight } from '../types'\nimport type { ViewState } from '../core/ViewState'\n\nexport class GridLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n groups: Group[],\n theme: TimelineTheme,\n dayStyle?: (date: Date) => DayStyle | null,\n rowStyle?: (group: Group) => RowStyle | null,\n highlights?: TimeRangeHighlight[],\n timezone?: string,\n ): void {\n const { firstVisible, lastVisible } = view.getVisibleGroupRange()\n\n // Draw row backgrounds\n for (let i = firstVisible; i <= lastVisible; i++) {\n const y = view.groupIndexToY(i)\n const rowHeight = view.groupIndexToHeight(i)\n const group = groups[i]\n if (!group) continue\n\n let bgColor: string\n const customRow = rowStyle?.(group)\n if (customRow?.backgroundColor) {\n bgColor = customRow.backgroundColor\n } else {\n bgColor = i % 2 === 0 ? '#FFFFFF' : theme.grid.rowAlt\n }\n\n ctx.fillStyle = bgColor\n ctx.fillRect(0, y, view.canvasWidth, rowHeight)\n\n // Row separator\n ctx.strokeStyle = customRow?.borderBottomColor ?? theme.grid.line\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + rowHeight)\n ctx.lineTo(view.canvasWidth, y + rowHeight)\n ctx.stroke()\n }\n\n // Draw time range highlight backgrounds (under grid lines)\n if (highlights && highlights.length > 0) {\n for (const h of highlights) {\n const x1 = view.timeToX(h.start)\n const x2 = view.timeToX(h.end)\n if (x2 < 0 || x1 > view.canvasWidth) continue\n\n const x = Math.max(0, x1)\n const w = Math.min(view.canvasWidth, x2) - x\n\n const opacity = h.opacity ?? 0.12\n const r = parseInt(h.color.slice(1, 3), 16)\n const g = parseInt(h.color.slice(3, 5), 16)\n const b = parseInt(h.color.slice(5, 7), 16)\n ctx.fillStyle = `rgb(${Math.round(r * opacity + 255 * (1 - opacity))},${Math.round(g * opacity + 255 * (1 - opacity))},${Math.round(b * opacity + 255 * (1 - opacity))})`\n ctx.fillRect(x, 0, w, view.canvasHeight)\n }\n }\n\n // Draw day columns, backgrounds, and vertical grid lines\n const visibleStart = view.visibleTimeStart\n const visibleEnd = view.visibleTimeEnd\n const visibleDuration = visibleEnd - visibleStart\n const dayMs = 86400000\n const dayPixelWidth = (dayMs / visibleDuration) * view.canvasWidth\n\n // Determine grid line interval based on zoom level\n let stepUnit: 'day' | 'week' | 'month' = 'day'\n if (dayPixelWidth < 2) stepUnit = 'month'\n else if (dayPixelWidth < 8) stepUnit = 'week'\n\n // Draw day backgrounds (dayStyle + weekends) — batch consecutive same-style days\n if (dayStyle || true) { // always draw weekends\n let current = toDayjs(visibleStart, timezone).startOf('day')\n const end = toDayjs(visibleEnd, timezone).endOf('day')\n\n // Batch: track current fill color and start x\n let batchColor: string | null = null\n let batchOpacity = 1\n let batchStartX = 0\n const customBorderLines: { x: number; color: string }[] = []\n\n const flushBatch = (endX: number) => {\n if (batchColor !== null) {\n ctx.fillStyle = batchColor\n if (batchOpacity !== 1) ctx.globalAlpha = batchOpacity\n ctx.fillRect(batchStartX, 0, endX - batchStartX, view.canvasHeight)\n if (batchOpacity !== 1) ctx.globalAlpha = 1\n batchColor = null\n batchOpacity = 1\n }\n }\n\n while (current.isBefore(end)) {\n const x = view.timeToX(current.valueOf())\n\n const date = current.toDate()\n const custom = dayStyle?.(date)\n let color: string | null = null\n let opacity = 1\n\n if (custom?.backgroundColor) {\n color = custom.backgroundColor\n opacity = custom.opacity ?? 1\n } else {\n const dow = current.day()\n if (dow === 0 || dow === 6) {\n color = theme.grid.weekend\n }\n }\n\n // Collect custom border colors for later drawing\n if (custom?.borderColor) {\n customBorderLines.push({ x, color: custom.borderColor })\n }\n\n // Batch consecutive same-color fills\n if (color === batchColor && opacity === batchOpacity) {\n // extend batch\n } else {\n flushBatch(x)\n if (color !== null) {\n batchColor = color\n batchOpacity = opacity\n batchStartX = x\n }\n }\n\n current = current.add(1, 'day')\n }\n // Flush remaining batch\n if (batchColor !== null) {\n flushBatch(view.timeToX(current.valueOf()))\n }\n\n // Draw custom border lines from dayStyle\n for (const line of customBorderLines) {\n ctx.strokeStyle = line.color\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(line.x, 0)\n ctx.lineTo(line.x, view.canvasHeight)\n ctx.stroke()\n }\n }\n\n // Draw vertical grid lines at appropriate interval\n let current = toDayjs(visibleStart, timezone).startOf(stepUnit)\n const end = toDayjs(visibleEnd, timezone).add(1, stepUnit)\n\n ctx.strokeStyle = theme.grid.line\n ctx.lineWidth = 0.5\n ctx.beginPath()\n while (current.isBefore(end)) {\n const x = view.timeToX(current.valueOf())\n ctx.moveTo(x, 0)\n ctx.lineTo(x, view.canvasHeight)\n current = current.add(1, stepUnit)\n }\n ctx.stroke()\n\n // Draw time range highlight edge lines and labels (after grid lines so they render on top)\n if (highlights && highlights.length > 0) {\n for (const h of highlights) {\n const x1 = view.timeToX(h.start)\n const x2 = view.timeToX(h.end)\n if (x2 < 0 || x1 > view.canvasWidth) continue\n\n // Edge lines\n ctx.strokeStyle = h.color\n ctx.globalAlpha = 0.4\n ctx.lineWidth = 1\n ctx.beginPath()\n if (x1 >= 0 && x1 <= view.canvasWidth) {\n ctx.moveTo(x1, 0)\n ctx.lineTo(x1, view.canvasHeight)\n }\n if (x2 >= 0 && x2 <= view.canvasWidth) {\n ctx.moveTo(x2, 0)\n ctx.lineTo(x2, view.canvasHeight)\n }\n ctx.stroke()\n ctx.globalAlpha = 1\n\n // Label badge\n if (h.label) {\n const x = Math.max(0, x1)\n const w = Math.min(view.canvasWidth, x2) - x\n\n ctx.save()\n ctx.font = '600 10px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n const textWidth = ctx.measureText(h.label).width\n const padding = 6\n const badgeWidth = textWidth + padding * 2\n const badgeHeight = 18\n const badgeX = x + (w - badgeWidth) / 2\n const badgeY = 4\n\n ctx.fillStyle = h.color\n ctx.globalAlpha = 0.9\n ctx.beginPath()\n ctx.roundRect(badgeX, badgeY, badgeWidth, badgeHeight, 3)\n ctx.fill()\n\n ctx.globalAlpha = 1\n ctx.fillStyle = '#FFFFFF'\n ctx.textBaseline = 'middle'\n ctx.fillText(h.label, badgeX + padding, badgeY + badgeHeight / 2)\n ctx.restore()\n }\n }\n }\n }\n}\n","import type { DrawHelpers, ItemBounds } from '../types'\n\nconst ITEM_FONT = '500 12px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n\n/**\n * Creates a DrawHelpers object bound to the given canvas context and optional item bounds.\n * These helpers are passed to every itemRenderer call to simplify common canvas operations.\n */\nexport function createDrawHelpers(\n ctx: CanvasRenderingContext2D,\n bounds?: ItemBounds,\n): DrawHelpers {\n return {\n /**\n * Draws a filled rounded rectangle.\n * Default corner radius is 3px.\n */\n roundRect(x: number, y: number, w: number, h: number, radius = 3): void {\n ctx.beginPath()\n ctx.roundRect(x, y, w, h, radius)\n ctx.fill()\n },\n\n /**\n * Draws text at (x, y) using the standard item font.\n * If maxWidth is provided and the text is too wide, binary-search truncates it\n * and appends '...' so it fits within maxWidth.\n */\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n ctx.font = ITEM_FONT\n\n if (maxWidth !== undefined && ctx.measureText(text).width > maxWidth) {\n // Binary-search for the longest prefix that fits with '...' appended\n let lo = 0\n let hi = text.length\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2)\n const candidate = text.slice(0, mid) + '...'\n if (ctx.measureText(candidate).width <= maxWidth) {\n lo = mid\n } else {\n hi = mid - 1\n }\n }\n ctx.fillText(text.slice(0, lo) + '...', x, y)\n } else {\n ctx.fillText(text, x, y)\n }\n },\n\n /**\n * Creates a 50/50 linear gradient from color1 (0%–50%) to color2 (50%–100%)\n * spanning the given x position and width.\n */\n gradient(x: number, w: number, color1: string, color2: string): CanvasGradient {\n const grad = ctx.createLinearGradient(x, 0, x + w, 0)\n grad.addColorStop(0, color1)\n grad.addColorStop(0.5, color1)\n grad.addColorStop(0.5, color2)\n grad.addColorStop(1, color2)\n return grad\n },\n\n /**\n * Draws a vertical colored bar on the left edge of the item bounds.\n * Does nothing if no bounds were provided.\n */\n leftBar(color: string, width = 3): void {\n if (!bounds) return\n ctx.save()\n ctx.fillStyle = color\n ctx.fillRect(bounds.x, bounds.y, width, bounds.height)\n ctx.restore()\n },\n\n /**\n * Draws a vector icon centered at (x, y).\n * Supported types: 'check', 'danger-red', 'danger-yellow'.\n * Default size is 14px.\n */\n icon(type: 'check' | 'danger-red' | 'danger-yellow', x: number, y: number, size = 14): void {\n ctx.save()\n const half = size / 2\n\n if (type === 'check') {\n // Green circle with white checkmark\n ctx.fillStyle = '#31c48d'\n ctx.beginPath()\n ctx.arc(x + half, y + half, half, 0, Math.PI * 2)\n ctx.fill()\n\n // Draw checkmark path\n ctx.strokeStyle = '#ffffff'\n ctx.lineWidth = size * 0.12\n ctx.beginPath()\n const cx = x + half\n const cy = y + half\n ctx.moveTo(cx - half * 0.45, cy)\n ctx.lineTo(cx - half * 0.1, cy + half * 0.42)\n ctx.lineTo(cx + half * 0.45, cy - half * 0.35)\n ctx.stroke()\n } else if (type === 'danger-red' || type === 'danger-yellow') {\n const fillColor = type === 'danger-red' ? '#EF5350' : '#FBBF24'\n\n // Triangle background\n ctx.fillStyle = fillColor\n ctx.beginPath()\n ctx.moveTo(x + half, y) // top-center\n ctx.lineTo(x + size, y + size) // bottom-right\n ctx.lineTo(x, y + size) // bottom-left\n ctx.closePath()\n ctx.fill()\n\n // Exclamation mark stem\n ctx.fillStyle = '#ffffff'\n const stemW = size * 0.12\n const stemX = x + half - stemW / 2\n ctx.fillRect(stemX, y + size * 0.35, stemW, size * 0.35)\n\n // Exclamation mark dot\n ctx.beginPath()\n ctx.arc(x + half, y + size * 0.82, stemW * 0.7, 0, Math.PI * 2)\n ctx.fill()\n }\n\n ctx.restore()\n },\n\n /**\n * Draws a pill-shaped badge with centered white text on a colored background.\n */\n badge(text: string, x: number, y: number, bgColor: string): void {\n ctx.save()\n\n // Measure text to size the pill\n ctx.font = ITEM_FONT\n const textMetrics = ctx.measureText(text)\n const textWidth = textMetrics.width\n const paddingH = 8\n const paddingV = 3\n const pillHeight = 12 + paddingV * 2\n const pillWidth = textWidth + paddingH * 2\n const radius = pillHeight / 2\n\n // Draw pill background\n ctx.fillStyle = bgColor\n ctx.beginPath()\n ctx.roundRect(x, y, pillWidth, pillHeight, radius)\n ctx.fill()\n\n // Draw centered white text\n ctx.fillStyle = '#ffffff'\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(text, x + pillWidth / 2, y + pillHeight / 2)\n\n ctx.restore()\n },\n }\n}\n","import type {\n Item, Group, TimelineTheme, CanvasItemRenderer, CanvasGroupItemRenderer,\n Dependency, ItemBounds, ItemState,\n} from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { IntervalTree } from '../core/IntervalTree'\nimport type { LayoutEngine } from '../core/LayoutEngine'\nimport type { HierarchyEngine } from '../core/HierarchyEngine'\nimport { createDrawHelpers } from './DrawHelpers'\n\nexport class ItemsLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n groups: Group[],\n items: Item[],\n tree: IntervalTree<Item>,\n layout: LayoutEngine,\n itemRenderer: CanvasItemRenderer,\n groupRenderer: CanvasGroupItemRenderer | undefined,\n theme: TimelineTheme,\n selected: number[],\n hoveredItemId: number | undefined,\n dependencies?: Dependency[],\n summaryRenderer?: CanvasItemRenderer,\n hierarchy?: HierarchyEngine,\n ): void {\n // Query only visible time range + small padding (not the full 4x buffer)\n const padding = (view.visibleTimeEnd - view.visibleTimeStart) * 0.1\n const queryStart = view.visibleTimeStart - padding\n const queryEnd = view.visibleTimeEnd + padding\n const visibleItems = tree.query(queryStart, queryEnd)\n\n const groupIndexMap = new Map<string | number, number>()\n for (let i = 0; i < groups.length; i++) {\n groupIndexMap.set(groups[i].id, i)\n }\n\n const selectedSet = new Set(selected)\n const itemBoundsMap = new Map<number, ItemBounds>()\n\n // Vertical culling bounds\n const yMin = -view.lineHeight\n const yMax = view.canvasHeight + view.lineHeight\n\n for (const item of visibleItems) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n\n const itemLayout = layout.getLayout(item.id)\n if (!itemLayout) continue\n\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n\n // Skip items that are entirely off-screen vertically\n const height = itemLayout.itemHeight\n if (y + height < yMin || y > yMax) continue\n\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n\n const bounds: ItemBounds = { x, y, width, height }\n itemBoundsMap.set(item.id, bounds)\n\n const state: ItemState = {\n selected: selectedSet.has(item.id),\n hovered: hoveredItemId === item.id,\n dragging: false,\n filtered: item.filtered !== false,\n }\n\n ctx.save()\n const helpers = createDrawHelpers(ctx, bounds)\n let renderer: CanvasItemRenderer\n if (summaryRenderer && hierarchy?.isParent(item.id)) {\n renderer = summaryRenderer\n } else if (groupRenderer && (item.type === 'control_area_group' || item.type === 'construction_train')) {\n renderer = groupRenderer\n } else {\n renderer = itemRenderer\n }\n renderer(ctx, item, bounds, state, helpers)\n ctx.restore()\n }\n\n if (dependencies && dependencies.length > 0) {\n // Build a full item map for dependency endpoint lookup (off-screen items too)\n const depItemIds = new Set<number>()\n for (const dep of dependencies) {\n if (!itemBoundsMap.has(dep.fromItemId)) depItemIds.add(dep.fromItemId)\n if (!itemBoundsMap.has(dep.toItemId)) depItemIds.add(dep.toItemId)\n }\n if (depItemIds.size > 0) {\n const itemMap = new Map<number, Item>()\n for (const item of items) {\n if (depItemIds.has(item.id)) itemMap.set(item.id, item)\n }\n for (const [id, item] of itemMap) {\n const groupIndex = groupIndexMap.get(item.group)\n if (groupIndex === undefined) continue\n const itemLayout = layout.getLayout(id)\n if (!itemLayout) continue\n const groupY = view.groupIndexToY(groupIndex)\n const y = groupY + itemLayout.stackLevel * view.lineHeight + (view.lineHeight - itemLayout.itemHeight) / 2\n const x = view.timeToX(item.start_time)\n const width = view.timeToX(item.end_time) - x\n itemBoundsMap.set(id, { x, y, width, height: itemLayout.itemHeight })\n }\n }\n this.drawDependencies(ctx, dependencies, itemBoundsMap, hoveredItemId, theme)\n }\n }\n\n private drawDependencies(\n ctx: CanvasRenderingContext2D,\n dependencies: Dependency[],\n boundsMap: Map<number, ItemBounds>,\n hoveredItemId: number | undefined,\n theme: TimelineTheme,\n ): void {\n for (const dep of dependencies) {\n const fromBounds = boundsMap.get(dep.fromItemId)\n const toBounds = boundsMap.get(dep.toItemId)\n if (!fromBounds || !toBounds) continue\n\n const isHighlighted = hoveredItemId === dep.fromItemId || hoveredItemId === dep.toItemId\n\n ctx.strokeStyle = isHighlighted ? theme.primary : (dep.color ?? '#94A3B8')\n ctx.lineWidth = isHighlighted ? 2 : 1.5\n ctx.setLineDash([])\n\n const startX = fromBounds.x + fromBounds.width\n const startY = fromBounds.y + fromBounds.height / 2\n const endX = toBounds.x\n const endY = toBounds.y + toBounds.height / 2\n\n const dx = Math.abs(endX - startX)\n const cpOffset = Math.max(dx * 0.4, 30)\n\n ctx.beginPath()\n ctx.moveTo(startX, startY)\n ctx.bezierCurveTo(startX + cpOffset, startY, endX - cpOffset, endY, endX, endY)\n ctx.stroke()\n\n // Arrowhead\n const arrowSize = 6\n ctx.fillStyle = ctx.strokeStyle\n ctx.beginPath()\n ctx.moveTo(endX, endY)\n ctx.lineTo(endX - arrowSize, endY - arrowSize / 2)\n ctx.lineTo(endX - arrowSize, endY + arrowSize / 2)\n ctx.closePath()\n ctx.fill()\n }\n }\n}\n","import type { TimelineTheme, MarkerConfig, ItemBounds, Item, CanvasItemRenderer } from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { InteractionMode } from '../interaction/InteractionHandler'\nimport { createDrawHelpers } from './DrawHelpers'\n\nexport interface InteractionRenderState {\n item: Item\n mode: InteractionMode\n bounds: ItemBounds\n renderer: CanvasItemRenderer\n targetGroupY?: number\n groupChanged?: boolean\n}\n\nexport interface OverlayDrawOptions {\n cursorX: number | null\n snapX?: number | null\n markers?: MarkerConfig[]\n\n interaction?: InteractionRenderState | null\n}\n\nexport class OverlayLayer {\n draw(\n ctx: CanvasRenderingContext2D,\n view: ViewState,\n theme: TimelineTheme,\n options: OverlayDrawOptions,\n ): void {\n const { cursorX, snapX, markers, interaction } = options\n\n // Draw markers\n if (markers) {\n for (const marker of markers) {\n const x = view.timeToX(marker.date)\n\n ctx.fillStyle = marker.color\n ctx.fillRect(x - marker.width / 2, 0, marker.width, view.canvasHeight)\n\n if (marker.label) {\n ctx.save()\n ctx.font = '500 10px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n const textWidth = ctx.measureText(marker.label).width\n const padding = 8\n const maxBadgeWidth = 200\n const badgeWidth = Math.min(textWidth + padding * 2, maxBadgeWidth)\n const badgeHeight = 20\n const badgeX = x - badgeWidth / 2\n const badgeY = 4\n\n ctx.fillStyle = marker.color\n ctx.beginPath()\n ctx.roundRect(badgeX, badgeY, badgeWidth, badgeHeight, 3)\n ctx.fill()\n\n ctx.fillStyle = '#FFFFFF'\n ctx.textBaseline = 'middle'\n const maxTextWidth = maxBadgeWidth - padding * 2\n const displayText = textWidth > maxTextWidth\n ? marker.label.slice(0, Math.floor(marker.label.length * maxTextWidth / textWidth)) + '…'\n : marker.label\n ctx.fillText(displayText, badgeX + padding, badgeY + badgeHeight / 2)\n ctx.restore()\n }\n }\n }\n\n // Draw cursor line\n if (cursorX !== null && cursorX !== undefined) {\n ctx.strokeStyle = theme.marker.cursor\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(cursorX, 0)\n ctx.lineTo(cursorX, view.canvasHeight)\n ctx.stroke()\n }\n\n // Draw snap guide line\n if (snapX !== null && snapX !== undefined) {\n ctx.strokeStyle = theme.primary\n ctx.lineWidth = 1\n ctx.setLineDash([4, 4])\n ctx.beginPath()\n ctx.moveTo(snapX, 0)\n ctx.lineTo(snapX, view.canvasHeight)\n ctx.stroke()\n ctx.setLineDash([])\n }\n\n // Draw interaction ghost (move, resize-left, resize-right)\n if (interaction) {\n // Group highlight band when moving to a different group\n if (interaction.groupChanged && interaction.targetGroupY !== undefined) {\n ctx.fillStyle = 'rgba(59, 130, 246, 0.08)'\n ctx.fillRect(0, interaction.targetGroupY, view.canvasWidth, view.lineHeight)\n }\n\n ctx.save()\n ctx.globalAlpha = 0.5\n const helpers = createDrawHelpers(ctx, interaction.bounds)\n interaction.renderer(\n ctx, interaction.item, interaction.bounds,\n { selected: false, hovered: false, dragging: true, filtered: true },\n helpers,\n )\n ctx.restore()\n }\n }\n}\n","const MAX_DELTA = 120\n\n/**\n * Normalize wheel delta across browsers/platforms.\n * deltaMode 0 = pixels, 1 = lines (×15), 2 = pages (×800).\n * Clamp to ±120 to prevent erratic jumps.\n */\nfunction normalizeDelta(e: WheelEvent): number {\n let delta = e.deltaY || e.deltaX\n if (e.deltaMode === 1) delta *= 15\n else if (e.deltaMode === 2) delta *= 800\n return Math.max(-MAX_DELTA, Math.min(MAX_DELTA, delta))\n}\n\nexport class ZoomHandler {\n private onZoom: (newStart: number, newEnd: number) => void\n private visibleTimeStart: number\n private visibleTimeEnd: number\n private minZoom: number\n private maxZoom: number\n\n constructor(\n onZoom: (newStart: number, newEnd: number) => void,\n visibleTimeStart: number,\n visibleTimeEnd: number,\n minZoom: number,\n maxZoom: number,\n ) {\n this.onZoom = onZoom\n this.visibleTimeStart = visibleTimeStart\n this.visibleTimeEnd = visibleTimeEnd\n this.minZoom = minZoom\n this.maxZoom = maxZoom\n }\n\n updateBounds(start: number, end: number): void {\n this.visibleTimeStart = start\n this.visibleTimeEnd = end\n }\n\n handleWheelZoom(e: WheelEvent, cursorRatio: number): void {\n const delta = normalizeDelta(e)\n // Speed: ctrlKey (trackpad pinch) = 10, metaKey = 3, altKey = 1\n const speed = e.ctrlKey ? 10 : e.metaKey ? 3 : 1\n\n // Reciprocal formula for symmetric zoom-in / zoom-out\n const scale = delta > 0\n ? 1.0 + (speed * delta) / 500\n : 1.0 / (1.0 + (speed * -delta) / 500)\n\n const currentDuration = this.visibleTimeEnd - this.visibleTimeStart\n let newDuration = Math.round(currentDuration * scale)\n newDuration = Math.max(this.minZoom, Math.min(this.maxZoom, newDuration))\n\n const newStart = Math.round(this.visibleTimeStart + (currentDuration - newDuration) * cursorRatio)\n const newEnd = newStart + newDuration\n\n this.onZoom(newStart, newEnd)\n }\n}\n","import dayjs from 'dayjs'\nimport type { Item, DragSnapFn, DragSnapResult } from '../types'\nimport { toDayjs } from '../utils/timezone'\n\nconst DAY_MS = 86_400_000\n\nlet warnedInvalidSnap = false\n\n/** Reset the once-per-session invalid-snap warning. Test-only. */\nexport function _resetSnapWarning(): void {\n warnedInvalidSnap = false\n}\n\nfunction warnInvalidSnap(detail: string): number {\n if (!warnedInvalidSnap) {\n warnedInvalidSnap = true\n // eslint-disable-next-line no-console\n console.warn(\n `[canvas-timeline] dragSnap function returned ${detail}; ` +\n 'falling back to no snap. This warning is shown once per session.',\n )\n }\n return 1\n}\n\n/**\n * Resolve a `dragSnap` prop to a concrete snap spec for the given item/edge.\n *\n * - `undefined` → `1` (no snap).\n * - `number` → returned as-is (preserves legacy behavior, including `0`).\n * - `DragSnapFn` → invoked with `(item, edge)`. `edge` is `'left' | 'right'`\n * during a resize and `undefined` during a move. It may return either a bare\n * interval (ms) — tz-aware default anchoring (see {@link gridSnap}) — or a\n * `{ interval, anchor }` spec to control phase explicitly. An invalid return\n * (`interval` that is `0`, `NaN`, or negative, or a non-finite `anchor`) falls\n * back to `1` (no snap) and warns once per session.\n *\n * Hot path: called on every pointer-move frame. Returns the consumer's object\n * by reference — no allocation or copying here.\n */\nexport function resolveDragSnap(\n dragSnap: number | DragSnapFn | undefined,\n item: Item,\n edge?: 'left' | 'right',\n): DragSnapResult {\n if (dragSnap === undefined) return 1\n if (typeof dragSnap !== 'function') return dragSnap\n const value = dragSnap(item, edge)\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || value <= 0) return warnInvalidSnap(`an invalid interval (${value})`)\n return value\n }\n if (!Number.isFinite(value.interval) || value.interval <= 0) {\n return warnInvalidSnap(`an invalid interval (${value.interval})`)\n }\n if (!Number.isFinite(value.anchor)) return warnInvalidSnap(`a non-finite anchor (${value.anchor})`)\n return value\n}\n\n/**\n * Snap `time` (epoch ms) to a snap grid.\n *\n * When `snap` is a `{ interval, anchor }` spec, the grid is `anchor + N *\n * interval` and the `timezone` is ignored — the consumer owns the phase (see\n * {@link DragSnapAnchor} for the DST caveat). This branch is pure arithmetic\n * (no dayjs), so it is the cheapest path.\n *\n * When `snap` is a bare `number` interval:\n * - For day-or-larger intervals with a `timezone`, the grid is anchored to\n * tz-local midnight rather than the UTC epoch, so the snap lands on the same\n * day boundaries the grid/headers render (which are also tz-local). Day\n * boundaries in a tz with a non-zero UTC offset are not multiples of\n * 86_400_000 since the epoch, so a naive `Math.round(time / interval) *\n * interval` drifts by the offset. The snap is computed in local-calendar-day\n * space, so it stays correct across DST transitions (where a local day is 23\n * or 25 hours long).\n * - Sub-day intervals (1h, 15min, …) stay UTC-anchored: hours and quarter-hours\n * line up between UTC and any whole- or fractional-hour offset, so no\n * translation is needed.\n */\nexport function gridSnap(time: number, snap: DragSnapResult, timezone?: string): number {\n if (typeof snap !== 'number') {\n const { interval, anchor } = snap\n if (!Number.isFinite(interval) || interval <= 0) return time\n if (!Number.isFinite(anchor)) return time\n return Math.round((time - anchor) / interval) * interval + anchor\n }\n const interval = snap\n if (timezone && interval % DAY_MS === 0) {\n const days = interval / DAY_MS\n const local = toDayjs(time, timezone)\n const startOfDay = local.startOf('day')\n // Local day length varies (23/24/25h on DST days); use it to place `time`\n // as a fraction within its own local day.\n const dayLenMs = startOfDay.add(1, 'day').valueOf() - startOfDay.valueOf()\n const fraction = (time - startOfDay.valueOf()) / dayLenMs\n // DST-free integer index of the local calendar date.\n const dayIndex = Math.round(dayjs.utc(local.format('YYYY-MM-DD')).valueOf() / DAY_MS)\n const snappedIndex = Math.round((dayIndex + fraction) / days) * days\n const snappedDate = dayjs.utc(snappedIndex * DAY_MS).format('YYYY-MM-DD')\n return dayjs.tz(snappedDate, timezone).valueOf()\n }\n return Math.round(time / interval) * interval\n}\n","import type { Item, DragSnapFn } from '../types'\nimport { resolveDragSnap, gridSnap } from './snapResolve'\n\nconst ACTIVATION_THRESHOLD = 4\n\nexport type InteractionMode = 'move' | 'resize-left' | 'resize-right'\n\nexport interface InteractionState {\n item: Item\n mode: InteractionMode\n startX: number\n startY: number\n currentX: number\n currentY: number\n deltaX: number\n originalGroup: string | number\n currentGroup: string | number\n}\n\nexport class InteractionHandler {\n private state: InteractionState | null = null\n private dragSnap: number | DragSnapFn | undefined\n private activated = false\n\n constructor(dragSnap: number | DragSnapFn | undefined) {\n this.dragSnap = dragSnap\n }\n\n startInteraction(item: Item, mode: InteractionMode, x: number, y: number): void {\n this.state = {\n item, mode, startX: x, startY: y, currentX: x, currentY: y,\n deltaX: 0, originalGroup: item.group, currentGroup: item.group,\n }\n this.activated = false\n }\n\n update(x: number, y: number): void {\n if (!this.state) return\n this.state.currentX = x\n this.state.currentY = y\n this.state.deltaX = x - this.state.startX\n if (!this.activated && Math.abs(this.state.deltaX) >= ACTIVATION_THRESHOLD) {\n this.activated = true\n }\n }\n\n setCurrentGroup(groupId: string | number): void {\n if (this.state) this.state.currentGroup = groupId\n }\n\n endMove(pixelsPerMs: number): { newStartTime: number; newGroupId: string | number } | null {\n if (!this.state) return null\n const deltaMs = this.state.deltaX / pixelsPerMs\n const newStartTime = this.state.item.start_time + deltaMs\n const snapped = gridSnap(newStartTime, resolveDragSnap(this.dragSnap, this.state.item))\n const newGroupId = this.state.currentGroup\n this.state = null\n this.activated = false\n return { newStartTime: snapped, newGroupId }\n }\n\n endResize(pixelsPerMs: number): { newTime: number; edge: 'left' | 'right' } | null {\n if (!this.state) return null\n const deltaMs = this.state.deltaX / pixelsPerMs\n const edge = this.state.mode === 'resize-left' ? 'left' as const : 'right' as const\n const baseTime = edge === 'left' ? this.state.item.start_time : this.state.item.end_time\n const newTime = baseTime + deltaMs\n const snapped = gridSnap(newTime, resolveDragSnap(this.dragSnap, this.state.item, edge))\n this.state = null\n this.activated = false\n return { newTime: snapped, edge }\n }\n\n cancel(): void {\n this.state = null\n this.activated = false\n }\n\n getState(): InteractionState | null {\n return this.state\n }\n\n getMode(): InteractionMode | null {\n return this.state?.mode ?? null\n }\n\n isActive(): boolean {\n return this.state !== null && this.activated\n }\n\n isPending(): boolean {\n return this.state !== null\n }\n}\n","interface SnapItem {\n id: number\n start_time: number\n end_time: number\n}\n\n/**\n * Collect start and end X positions from all items except the dragged item.\n */\nexport function collectItemEdges(\n items: SnapItem[],\n excludeItemId: number,\n timeToX: (time: number) => number,\n): number[] {\n const edges: number[] = []\n for (const item of items) {\n if (item.id === excludeItemId) continue\n edges.push(timeToX(item.start_time))\n edges.push(timeToX(item.end_time))\n }\n return edges\n}\n\n/**\n * Find the best snap target from a list of edge X positions.\n * Returns the snapped X position if an edge is within threshold, or null to fall back to time-grid snap.\n */\nexport function findSnapTarget(\n currentX: number,\n edgeXPositions: number[],\n thresholdPx: number,\n _pixelsPerMs: number,\n _dragSnap: import('../types').DragSnapResult,\n): number | null {\n if (edgeXPositions.length === 0) return null\n\n let closestX = edgeXPositions[0]\n let closestDist = Math.abs(currentX - closestX)\n\n for (let i = 1; i < edgeXPositions.length; i++) {\n const dist = Math.abs(currentX - edgeXPositions[i])\n if (dist < closestDist) {\n closestDist = dist\n closestX = edgeXPositions[i]\n }\n }\n\n if (closestDist <= thresholdPx) {\n return closestX\n }\n\n return null\n}\n","import type { Item, InteractionInfo, DragSnapFn } from '../types'\nimport type { ViewState } from '../core/ViewState'\nimport type { IntervalTree } from '../core/IntervalTree'\nimport type { HierarchyEngine } from '../core/HierarchyEngine'\nimport type { InteractionState } from './InteractionHandler'\nimport { findSnapTarget, collectItemEdges } from './snapUtils'\nimport { resolveDragSnap, gridSnap } from './snapResolve'\n\n/** The subset of props the snap helpers need. */\nexport interface SnapDeps {\n canvasWidth: number\n dragSnap?: number | DragSnapFn\n timezone?: string\n intervalTree: IntervalTree<Item>\n hierarchyEngine: HierarchyEngine\n}\n\n/** Snapped new start time for a move, matching the pointer-up commit path:\n * item-edge snap (start edge first, then end edge) with grid snap as fallback. */\nexport function snappedMoveStart(state: InteractionState, vs: ViewState, p: SnapDeps): number {\n const pixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = state.deltaX / pixelsPerMs\n const rawStart = state.item.start_time + deltaMs\n const snap = resolveDragSnap(p.dragSnap, state.item)\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, state.item.id, (t) => vs.timeToX(t))\n const startSnap = findSnapTarget(vs.timeToX(rawStart), otherEdges, 8, pixelsPerMs, snap)\n if (startSnap !== null) return vs.xToTime(startSnap)\n const endSnap = findSnapTarget(vs.timeToX(state.item.end_time + deltaMs), otherEdges, 8, pixelsPerMs, snap)\n if (endSnap !== null) return vs.xToTime(endSnap) - (state.item.end_time - state.item.start_time)\n return gridSnap(rawStart, snap, p.timezone)\n}\n\n/** Snapped edge time for a resize, matching the pointer-up commit path: item-edge\n * snap with grid-snap fallback, then hierarchy resize constraints. */\nexport function snappedResizeEdge(state: InteractionState, vs: ViewState, p: SnapDeps): { edge: 'left' | 'right'; time: number } {\n const pixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = state.deltaX / pixelsPerMs\n const edge = state.mode === 'resize-left' ? 'left' as const : 'right' as const\n const rawEdgeTime = (edge === 'left' ? state.item.start_time : state.item.end_time) + deltaMs\n const snap = resolveDragSnap(p.dragSnap, state.item, edge)\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, state.item.id, (t) => vs.timeToX(t))\n const edgeSnapX = findSnapTarget(vs.timeToX(rawEdgeTime), otherEdges, 8, pixelsPerMs, snap)\n let time = edgeSnapX !== null ? vs.xToTime(edgeSnapX) : gridSnap(rawEdgeTime, snap, p.timezone)\n const constraint = p.hierarchyEngine.getResizeConstraint(state.item.id, edge)\n if (edge === 'left' && time > constraint.max) time = constraint.max\n else if (edge === 'right' && time < constraint.min) time = constraint.min\n return { edge, time }\n}\n\n/** Build the public InteractionInfo payload for the current drag/resize state. */\nexport function buildInteractionInfo(\n state: InteractionState,\n vs: ViewState,\n p: SnapDeps,\n pointer: { x: number; y: number },\n): InteractionInfo {\n if (state.mode === 'move') {\n const startTime = snappedMoveStart(state, vs, p)\n const duration = state.item.end_time - state.item.start_time\n return { itemId: state.item.id, mode: 'move', time: startTime, startTime, endTime: startTime + duration, pointerX: pointer.x, pointerY: pointer.y }\n }\n const { edge, time } = snappedResizeEdge(state, vs, p)\n const startTime = edge === 'left' ? time : state.item.start_time\n const endTime = edge === 'right' ? time : state.item.end_time\n return { itemId: state.item.id, mode: state.mode, edge, time, startTime, endTime, pointerX: pointer.x, pointerY: pointer.y }\n}\n","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_isoWeek=t()}(this,(function(){\"use strict\";var e=\"day\";return function(t,i,s){var a=function(t){return t.add(4-t.isoWeekday(),e)},d=i.prototype;d.isoWeekYear=function(){return a(this).year()},d.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),e);var i,d,n,o,r=a(this),u=(i=this.isoWeekYear(),d=this.$u,n=(d?s.utc:s)().year(i).startOf(\"year\"),o=4-n.isoWeekday(),n.isoWeekday()>4&&(o+=7),n.add(o,e));return r.diff(u,\"week\")+1},d.isoWeekday=function(e){return this.$utils().u(e)?this.day()||7:this.day(this.day()%7?e:e-7)};var n=d.startOf;d.startOf=function(e,t){var i=this.$utils(),s=!!i.u(t)||t;return\"isoweek\"===i.p(e)?s?this.date(this.date()-(this.isoWeekday()-1)).startOf(\"day\"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf(\"day\"):n.bind(this)(e,t)}}}));","import React, { useRef, useCallback, useEffect, useMemo } from 'react'\nimport type { Group, TimelineTheme } from '../types'\n\ninterface SidebarProps {\n groups: Group[]\n width: number\n lineHeight: number\n groupHeights?: number[]\n scrollTop: number\n canvasHeight: number\n theme: TimelineTheme\n groupRenderer: (group: Group) => React.ReactNode\n onScroll: (scrollTop: number) => void\n}\n\nconst OVERSCAN_PX = 200\n\nexport function Sidebar({\n groups, width, lineHeight, groupHeights, scrollTop, canvasHeight, theme, groupRenderer, onScroll,\n}: SidebarProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n const isScrollingRef = useRef(false)\n\n // Cumulative top-edge offsets per group: length = groups.length + 1.\n const offsets = useMemo(() => {\n const arr = new Array<number>(groups.length + 1)\n arr[0] = 0\n for (let i = 0; i < groups.length; i++) {\n arr[i + 1] = arr[i] + (groupHeights?.[i] ?? lineHeight)\n }\n return arr\n }, [groups.length, groupHeights, lineHeight])\n\n const totalHeight = offsets[groups.length] ?? 0\n const displayHeight = canvasHeight\n\n // Binary search for the group containing a given y; clamped to [0, groups.length - 1].\n const groupAtY = useCallback((y: number): number => {\n if (groups.length === 0) return 0\n if (y <= 0) return 0\n if (y >= totalHeight) return groups.length - 1\n let lo = 0\n let hi = groups.length - 1\n while (lo < hi) {\n const mid = (lo + hi) >>> 1\n if (offsets[mid + 1] > y) hi = mid\n else lo = mid + 1\n }\n return lo\n }, [groups.length, offsets, totalHeight])\n\n const firstVisible = groupAtY(scrollTop - OVERSCAN_PX)\n const lastVisible = groupAtY(scrollTop + canvasHeight + OVERSCAN_PX)\n\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n if (isScrollingRef.current) return\n onScroll(e.currentTarget.scrollTop)\n }, [onScroll])\n\n useEffect(() => {\n if (containerRef.current) {\n isScrollingRef.current = true\n containerRef.current.scrollTop = scrollTop\n requestAnimationFrame(() => { isScrollingRef.current = false })\n }\n }, [scrollTop])\n\n const visibleGroups = []\n for (let i = firstVisible; i <= lastVisible; i++) {\n const group = groups[i]\n if (!group) continue\n const top = offsets[i]\n const height = offsets[i + 1] - top\n visibleGroups.push(\n <div\n key={group.id}\n style={{\n position: 'absolute',\n top,\n height,\n width: '100%',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'stretch',\n borderBottom: `1px solid ${theme.grid?.line ?? '#E5E5E5'}`,\n boxSizing: 'border-box',\n }}\n >\n {groupRenderer(group)}\n </div>,\n )\n }\n\n return (\n <div\n ref={containerRef}\n onScroll={handleScroll}\n style={{\n width,\n height: displayHeight,\n overflowY: totalHeight > canvasHeight ? 'auto' : 'hidden',\n overflowX: 'hidden',\n position: 'relative',\n borderRight: `1px solid ${theme.sidebar.border}`,\n backgroundColor: theme.sidebar.bg,\n }}\n >\n <div style={{ height: totalHeight, position: 'relative' }}>{visibleGroups}</div>\n </div>\n )\n}\n","import type { MarkerConfig } from '../types'\n\ninterface TodayMarkerProps {\n color?: string\n width?: number\n label?: string\n /** Auto-update interval in ms. Default 10000 (10s). Set 0 to disable. */\n interval?: number\n}\n\nexport function TodayMarker(_props: TodayMarkerProps) { return null }\nTodayMarker.displayName = 'TodayMarker'\n\nexport function getTodayMarkerConfig(props: TodayMarkerProps): MarkerConfig {\n // Snap to current minute to avoid unnecessary redraws\n const now = Math.floor(Date.now() / 60000) * 60000\n return { date: now, color: props.color ?? '#FD7171', width: props.width ?? 6, label: props.label }\n}\n\nexport function getTodayMarkerInterval(props: TodayMarkerProps): number {\n return props.interval ?? 10000\n}\n","import type { MarkerConfig } from '../types'\n\ninterface CustomMarkerProps {\n date: number\n color?: string\n width?: number\n label?: string\n}\n\nexport function CustomMarker(_props: CustomMarkerProps) { return null }\nCustomMarker.displayName = 'CustomMarker'\n\nexport function getCustomMarkerConfig(props: CustomMarkerProps): MarkerConfig {\n return {\n date: props.date,\n color: props.color ?? '#3B82F6',\n width: props.width ?? 4,\n label: props.label,\n }\n}\n","import React, { useRef, useEffect, useState, useCallback, useMemo, useImperativeHandle, forwardRef } from 'react'\nimport { flushSync } from 'react-dom'\nimport type {\n CanvasTimelineProps,\n CanvasTimelineRef,\n MarkerConfig,\n TimelineTheme,\n Item,\n ItemBounds,\n ItemState,\n DrawHelpers,\n} from './types'\nimport { DEFAULT_THEME } from './types'\nimport { ViewState } from './core/ViewState'\nimport { IntervalTree } from './core/IntervalTree'\nimport { LayoutEngine } from './core/LayoutEngine'\nimport { HierarchyEngine } from './core/HierarchyEngine'\nimport { defaultSummaryRenderer } from './canvas/defaultSummaryRenderer'\nimport { hitTest, hitTestGroup } from './core/HitTest'\nimport { setupCanvas, clearCanvas, RenderScheduler } from './canvas/CanvasManager'\nimport { GridLayer } from './canvas/GridLayer'\nimport { ItemsLayer } from './canvas/ItemsLayer'\nimport { OverlayLayer } from './canvas/OverlayLayer'\nimport { ZoomHandler } from './interaction/ZoomHandler'\nimport { InteractionHandler } from './interaction/InteractionHandler'\nimport type { InteractionMode } from './interaction/InteractionHandler'\nimport { findSnapTarget, collectItemEdges } from './interaction/snapUtils'\nimport { resolveDragSnap, gridSnap } from './interaction/snapResolve'\nimport { snappedMoveStart, snappedResizeEdge, buildInteractionInfo } from './interaction/interactionInfo'\nimport { detectEdge, resolveInteractionMode } from './core/HitTest'\nimport dayjs from 'dayjs'\nimport isoWeek from 'dayjs/plugin/isoWeek'\nimport { toDayjs } from './utils/timezone'\nimport { Sidebar } from './dom/Sidebar'\nimport { getTodayMarkerConfig, getTodayMarkerInterval } from './dom/TodayMarker'\nimport { getCustomMarkerConfig } from './dom/CustomMarker'\n\ndayjs.extend(isoWeek)\n\nfunction mergeTheme(partial?: Partial<TimelineTheme>): TimelineTheme {\n if (!partial) return DEFAULT_THEME\n return {\n ...DEFAULT_THEME,\n ...partial,\n status: { ...DEFAULT_THEME.status, ...partial.status },\n grid: { ...DEFAULT_THEME.grid, ...partial.grid },\n item: { ...DEFAULT_THEME.item, ...partial.item },\n marker: { ...DEFAULT_THEME.marker, ...partial.marker },\n sidebar: { ...DEFAULT_THEME.sidebar, ...partial.sidebar },\n header: { ...DEFAULT_THEME.header, ...partial.header },\n }\n}\n\nconst HEADER_THROTTLE_MS = 32\n\nexport const CanvasTimeline = React.memo(forwardRef<CanvasTimelineRef, CanvasTimelineProps>(function CanvasTimeline(props, ref) {\n const {\n groups,\n items,\n defaultTimeStart,\n defaultTimeEnd,\n sidebarWidth,\n lineHeight,\n itemHeightRatio,\n stackItems,\n canMove,\n canChangeGroup,\n canResize,\n dragSnap,\n minZoom,\n maxZoom,\n theme: themePartial,\n dayStyle,\n rowStyle,\n showCursorLine,\n itemRenderer,\n groupRenderer,\n sidebarGroupRenderer,\n dependencies,\n highlights,\n onItemClick,\n onItemDoubleClick,\n onItemContextMenu,\n onItemMove,\n onItemResize,\n moveResizeValidator,\n onItemHover,\n onInteractionUpdate,\n onCanvasDoubleClick,\n onCanvasContextMenu,\n onTimeChange,\n onZoom,\n selected: selectedProp = [],\n rightSidebarWidth,\n rightSidebarGroupRenderer,\n onReady,\n maxHeight,\n timezone,\n devBadge,\n children,\n } = props\n\n const theme = useMemo(() => mergeTheme(themePartial), [themePartial])\n\n const getGroupIndex = useCallback((groupId: string | number, grps: typeof groups) => {\n for (let i = 0; i < grps.length; i++) {\n if (grps[i].id === groupId) return i\n }\n return 0\n }, [])\n\n const selectedKey = selectedProp.join(',')\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const selected = useMemo(() => selectedProp, [selectedKey])\n\n const gridCanvasRef = useRef<HTMLCanvasElement>(null)\n const itemsCanvasRef = useRef<HTMLCanvasElement>(null)\n const overlayCanvasRef = useRef<HTMLCanvasElement>(null)\n const interactionRef = useRef<HTMLDivElement>(null)\n const outerRef = useRef<HTMLDivElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const [containerWidth, setContainerWidth] = useState(800)\n const [measuredHeight, setMeasuredHeight] = useState<number | null>(null)\n\n useEffect(() => {\n const container = outerRef.current\n if (!container) return\n const obs = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) {\n setContainerWidth(entry.contentRect.width)\n }\n })\n obs.observe(container)\n return () => obs.disconnect()\n }, [])\n\n // Measure actual resolved height of the body container (handles CSS calc values)\n useEffect(() => {\n const el = containerRef.current\n if (!el || !maxHeight) return\n const obs = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setMeasuredHeight(entry.contentRect.height)\n })\n obs.observe(el)\n return () => obs.disconnect()\n }, [maxHeight])\n\n const canvasWidth = Math.max(0, containerWidth - sidebarWidth - (rightSidebarWidth ?? 0))\n\n // --- CORE DATA STRUCTURES ---\n const hierarchyEngine = useMemo(() => {\n const engine = new HierarchyEngine()\n engine.rebuild(items)\n return engine\n }, [items])\n\n const intervalTree = useMemo(() => {\n const tree = new IntervalTree<(typeof items)[0]>()\n tree.buildFromItems(\n items,\n (i) => hierarchyEngine.getEffectiveSpan(i.id).start,\n (i) => hierarchyEngine.getEffectiveSpan(i.id).end,\n )\n return tree\n }, [items, hierarchyEngine])\n\n const layoutEngine = useMemo(() => {\n const engine = new LayoutEngine(lineHeight, itemHeightRatio)\n engine.computeLayout(items, stackItems, hierarchyEngine)\n return engine\n }, [items, lineHeight, itemHeightRatio, stackItems, hierarchyEngine])\n\n const groupHeights = useMemo(\n () => groups.map((g) => layoutEngine.getGroupHeight(g.id)),\n [groups, layoutEngine],\n )\n const totalHeight = useMemo(\n () => groupHeights.reduce((a, b) => a + b, 0),\n [groupHeights],\n )\n const resolvedMaxHeight = typeof maxHeight === 'number' ? maxHeight : measuredHeight\n const canvasHeight = resolvedMaxHeight ? Math.min(totalHeight, resolvedMaxHeight) : totalHeight\n\n // --- MUTABLE VIEW STATE (hot path) ---\n const viewStateRef = useRef<ViewState>(\n new ViewState({\n visibleTimeStart: props.visibleTimeStart ?? defaultTimeStart,\n visibleTimeEnd: props.visibleTimeEnd ?? defaultTimeEnd,\n canvasWidth,\n canvasHeight,\n sidebarWidth,\n lineHeight,\n groupCount: groups.length,\n buffer: props.buffer ?? 3,\n scrollTop: 0,\n groupHeights,\n }),\n )\n\n const cursorXRef = useRef<number | null>(null)\n const hoveredItemIdRef = useRef<number | undefined>(undefined)\n // Viewport-space pointer position, for positioning the interaction tooltip.\n const pointerClientRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 })\n // Whether onInteractionUpdate was last fired with a non-null payload, so we\n // emit the terminating `null` exactly once when the drag/resize ends.\n const interactionActiveRef = useRef(false)\n\n // --- PAN STATE ---\n const panRef = useRef<{ startX: number; startY: number; lastX: number; lastY: number } | null>(null)\n const didPanRef = useRef(false)\n const PAN_THRESHOLD = 4\n\n // --- THROTTLED HEADER STATE ---\n const [headerTimeStart, setHeaderTimeStart] = useState(props.visibleTimeStart ?? defaultTimeStart)\n const [headerTimeEnd, setHeaderTimeEnd] = useState(props.visibleTimeEnd ?? defaultTimeEnd)\n const [sidebarScrollTop, setSidebarScrollTop] = useState(0)\n const headerTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const syncHeaderState = useCallback(() => {\n const vs = viewStateRef.current\n setHeaderTimeStart(vs.visibleTimeStart)\n setHeaderTimeEnd(vs.visibleTimeEnd)\n setSidebarScrollTop(vs.scrollTop)\n headerTimerRef.current = null\n }, [])\n\n const scheduleHeaderSync = useCallback(() => {\n if (headerTimerRef.current !== null) return\n headerTimerRef.current = setTimeout(syncHeaderState, HEADER_THROTTLE_MS)\n }, [syncHeaderState])\n\n useEffect(() => {\n return () => { if (headerTimerRef.current !== null) clearTimeout(headerTimerRef.current) }\n }, [])\n\n const resolvedSummaryRenderer = useMemo(() => {\n if (props.summaryRenderer) return props.summaryRenderer\n return (ctx: CanvasRenderingContext2D, item: Item, bounds: ItemBounds, state: ItemState, helpers: DrawHelpers) => {\n defaultSummaryRenderer(ctx, item, bounds, state, helpers, theme)\n }\n }, [props.summaryRenderer, theme])\n\n const gridLayer = useMemo(() => new GridLayer(), [])\n const itemsLayer = useMemo(() => new ItemsLayer(), [])\n const overlayLayer = useMemo(() => new OverlayLayer(), [])\n const interactionHandler = useMemo(() => new InteractionHandler(dragSnap), [dragSnap])\n\n // --- MARKERS ---\n const markerConfigs = useMemo(() => {\n const configs: MarkerConfig[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n configs.push(getTodayMarkerConfig(child.props as { color?: string; width?: number; label?: string }))\n } else if (displayName === 'CustomMarker') {\n configs.push(getCustomMarkerConfig(child.props as { date: number; color?: string; width?: number; label?: string }))\n }\n })\n return configs\n }, [children])\n const markersKey = useMemo(() => markerConfigs.map(m => `${m.date}|${m.color}|${m.width}|${m.label ?? ''}`).join(';'), [markerConfigs])\n const markersRef = useRef(markerConfigs)\n markersRef.current = markerConfigs\n\n // TodayMarker auto-update: refresh overlay on interval\n const todayMarkerInterval = useMemo(() => {\n let interval = 0\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n interval = getTodayMarkerInterval(child.props as { interval?: number })\n }\n })\n return interval\n }, [children])\n\n // --- PROPS REF ---\n const propsRef = useRef({\n groups, items, intervalTree, layoutEngine, itemRenderer, groupRenderer,\n theme, selected, dependencies, highlights, dayStyle, rowStyle, showCursorLine,\n canvasWidth, canvasHeight, lineHeight, itemHeightRatio,\n onTimeChange, onZoom, onItemHover, onItemClick, onItemDoubleClick,\n onItemContextMenu, onItemMove, onItemResize, onInteractionUpdate, onCanvasDoubleClick, onCanvasContextMenu,\n canMove, canResize, canChangeGroup, dragSnap, sidebarWidth, moveResizeValidator,\n summaryRenderer: resolvedSummaryRenderer, hierarchyEngine, timezone,\n })\n propsRef.current = {\n groups, items, intervalTree, layoutEngine, itemRenderer, groupRenderer,\n theme, selected, dependencies, highlights, dayStyle, rowStyle, showCursorLine,\n canvasWidth, canvasHeight, lineHeight, itemHeightRatio,\n onTimeChange, onZoom, onItemHover, onItemClick, onItemDoubleClick,\n onItemContextMenu, onItemMove, onItemResize, onInteractionUpdate, onCanvasDoubleClick, onCanvasContextMenu,\n canMove, canResize, canChangeGroup, dragSnap, sidebarWidth, moveResizeValidator,\n summaryRenderer: resolvedSummaryRenderer, hierarchyEngine, timezone,\n }\n\n // --- DRAW FUNCTIONS ---\n const drawGrid = useCallback(() => {\n const canvas = gridCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n gridLayer.draw(ctx, viewStateRef.current, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights, p.timezone)\n }, [gridLayer])\n\n const drawItems = useCallback(() => {\n const canvas = itemsCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n itemsLayer.draw(\n ctx, viewStateRef.current, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, hoveredItemIdRef.current, p.dependencies,\n p.summaryRenderer, p.hierarchyEngine,\n )\n }, [itemsLayer])\n\n const calculateSnapX = useCallback((item: (typeof items)[0], deltaX: number, mode: InteractionMode) => {\n const vs = viewStateRef.current\n const p = propsRef.current\n const pixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = deltaX / pixelsPerMs\n const edge = mode === 'resize-left' ? 'left' : mode === 'resize-right' ? 'right' : undefined\n const snap = resolveDragSnap(p.dragSnap, item, edge)\n\n // Determine which edges of the dragged item to check\n const draggedEdgeXs: number[] = []\n if (mode === 'move') {\n draggedEdgeXs.push(vs.timeToX(item.start_time + deltaMs))\n draggedEdgeXs.push(vs.timeToX(item.end_time + deltaMs))\n } else if (mode === 'resize-left') {\n draggedEdgeXs.push(vs.timeToX(item.start_time + deltaMs))\n } else {\n draggedEdgeXs.push(vs.timeToX(item.end_time + deltaMs))\n }\n\n // Collect other items' edges\n const padding = (vs.visibleTimeEnd - vs.visibleTimeStart) * 0.1\n const visibleItems = p.intervalTree.query(vs.visibleTimeStart - padding, vs.visibleTimeEnd + padding)\n const otherEdges = collectItemEdges(visibleItems, item.id, (t) => vs.timeToX(t))\n\n // Check each dragged edge against other items' edges\n for (const edgeX of draggedEdgeXs) {\n const snapX = findSnapTarget(edgeX, otherEdges, 8, pixelsPerMs, snap)\n if (snapX !== null) return snapX\n }\n\n // Fall back to time grid snap — snap the edge being dragged, not the start\n const edgeTime = mode === 'resize-right'\n ? item.end_time + deltaMs\n : item.start_time + deltaMs\n const snapped = gridSnap(edgeTime, snap, p.timezone)\n return vs.timeToX(snapped)\n }, [])\n\n const drawOverlay = useCallback(() => {\n const canvas = overlayCanvasRef.current\n if (!canvas) return\n const p = propsRef.current\n const ctx = setupCanvas(canvas, p.canvasWidth, p.canvasHeight)\n clearCanvas(ctx, canvas)\n\n const vs = viewStateRef.current\n const state = interactionHandler.getState()\n let interactionRender = null\n if (state) {\n const origX = vs.timeToX(state.item.start_time)\n const origWidth = vs.timeToX(state.item.end_time) - origX\n let x: number, width: number\n if (state.mode === 'resize-left') {\n x = origX + state.deltaX\n width = origWidth - state.deltaX\n } else if (state.mode === 'resize-right') {\n x = origX\n width = origWidth + state.deltaX\n } else {\n // move\n x = origX + state.deltaX\n width = origWidth\n }\n const groupIndex = getGroupIndex(state.currentGroup, p.groups)\n const targetGroupY = vs.groupIndexToY(groupIndex)\n const groupChanged = state.currentGroup !== state.originalGroup\n interactionRender = {\n item: state.item,\n mode: state.mode,\n bounds: { x, y: targetGroupY + (p.lineHeight - p.lineHeight * p.itemHeightRatio) / 2, width, height: p.lineHeight * p.itemHeightRatio },\n renderer: p.itemRenderer,\n targetGroupY,\n groupChanged,\n }\n }\n\n overlayLayer.draw(ctx, vs, p.theme, {\n cursorX: p.showCursorLine ? cursorXRef.current : null,\n snapX: state ? calculateSnapX(state.item, state.deltaX, state.mode) : null,\n markers: markersRef.current,\n interaction: interactionRender,\n })\n\n // Live drag/resize tooltip feed. Rides the rAF-coalesced overlay draw, so\n // this fires at most once per frame. Emits a terminating `null` once the\n // interaction clears (pointer-up also marks the overlay dirty).\n if (p.onInteractionUpdate) {\n if (state) {\n p.onInteractionUpdate(buildInteractionInfo(state, vs, p, pointerClientRef.current))\n interactionActiveRef.current = true\n } else if (interactionActiveRef.current) {\n interactionActiveRef.current = false\n p.onInteractionUpdate(null)\n }\n }\n }, [overlayLayer, interactionHandler, calculateSnapX, getGroupIndex])\n\n // --- RENDER SCHEDULER ---\n const schedulerRef = useRef<RenderScheduler | null>(null)\n if (!schedulerRef.current) {\n schedulerRef.current = new RenderScheduler((flags) => {\n if (flags.grid) drawGrid()\n if (flags.items) drawItems()\n if (flags.overlay) drawOverlay()\n })\n }\n const scheduler = schedulerRef.current\n\n useEffect(() => {\n return () => scheduler.dispose()\n }, [scheduler])\n\n // --- TODAY MARKER AUTO-UPDATE ---\n useEffect(() => {\n if (!todayMarkerInterval) return\n const timer = setInterval(() => {\n const configs: MarkerConfig[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TodayMarker') {\n configs.push(getTodayMarkerConfig(child.props as { color?: string; width?: number; label?: string }))\n } else if (displayName === 'CustomMarker') {\n configs.push(getCustomMarkerConfig(child.props as { date: number; color?: string; width?: number; label?: string }))\n }\n })\n markersRef.current = configs\n scheduler.markDirty('overlay')\n }, todayMarkerInterval)\n return () => clearInterval(timer)\n }, [todayMarkerInterval, children, scheduler])\n\n // --- SYNC ON DIMENSION/DATA CHANGES ---\n useEffect(() => {\n viewStateRef.current.update({\n canvasWidth, canvasHeight, sidebarWidth, lineHeight,\n groupCount: groups.length, groupHeights,\n })\n scheduler.markAllDirty()\n }, [canvasWidth, canvasHeight, sidebarWidth, lineHeight, groups.length, groupHeights, scheduler])\n\n useEffect(() => {\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n }, [items, groups, selected, theme, dayStyle, rowStyle, intervalTree, layoutEngine, scheduler])\n\n const highlightsKey = useMemo(\n () => props.highlights?.map(h => `${h.start}|${h.end}|${h.color}|${h.label ?? ''}|${h.opacity ?? ''}`).join(';') ?? '',\n [props.highlights],\n )\n\n const prevHighlightsKey = useRef(highlightsKey)\n useEffect(() => {\n if (highlightsKey !== prevHighlightsKey.current) {\n prevHighlightsKey.current = highlightsKey\n scheduler.markDirty('grid')\n }\n }, [highlightsKey, scheduler])\n\n const prevMarkersKey = useRef(markersKey)\n useEffect(() => {\n if (markersKey !== prevMarkersKey.current) {\n prevMarkersKey.current = markersKey\n scheduler.markDirty('overlay')\n }\n }, [markersKey, scheduler])\n\n // --- CONTROLLED MODE ---\n const prevControlledStart = useRef(props.visibleTimeStart)\n const prevControlledEnd = useRef(props.visibleTimeEnd)\n if (props.visibleTimeStart !== undefined && props.visibleTimeStart !== prevControlledStart.current) {\n prevControlledStart.current = props.visibleTimeStart\n viewStateRef.current.update({ visibleTimeStart: props.visibleTimeStart })\n scheduler.markAllDirty()\n }\n if (props.visibleTimeEnd !== undefined && props.visibleTimeEnd !== prevControlledEnd.current) {\n prevControlledEnd.current = props.visibleTimeEnd\n viewStateRef.current.update({ visibleTimeEnd: props.visibleTimeEnd })\n scheduler.markAllDirty()\n }\n\n // --- THROTTLED PARENT CALLBACKS ---\n const callbackTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const scheduleCallbacks = useCallback((type: 'zoom' | 'scroll') => {\n if (callbackTimerRef.current !== null) return\n callbackTimerRef.current = setTimeout(() => {\n callbackTimerRef.current = null\n const vs = viewStateRef.current\n const p = propsRef.current\n if (type === 'zoom') {\n p.onZoom?.(vs.visibleTimeStart, vs.visibleTimeEnd)\n } else {\n p.onTimeChange?.(vs.visibleTimeStart, vs.visibleTimeEnd)\n }\n }, HEADER_THROTTLE_MS)\n }, [])\n\n useEffect(() => {\n return () => { if (callbackTimerRef.current !== null) clearTimeout(callbackTimerRef.current) }\n }, [])\n\n // --- ZOOM HANDLER ---\n const zoomHandlerRef = useRef<ZoomHandler | null>(null)\n const zoomHandler = useMemo(() => {\n return new ZoomHandler(\n (newStart, newEnd) => {\n viewStateRef.current.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n scheduleHeaderSync()\n scheduleCallbacks('zoom')\n },\n defaultTimeStart,\n defaultTimeEnd,\n minZoom,\n maxZoom,\n )\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n zoomHandlerRef.current = zoomHandler\n\n // --- WHEEL HANDLER ---\n const handleVerticalScroll = useCallback((deltaY: number) => {\n const vs = viewStateRef.current\n const totalHeight = vs.getTotalHeight()\n const maxScroll = Math.max(0, totalHeight - vs.canvasHeight)\n const newScrollTop = Math.max(0, Math.min(maxScroll, vs.scrollTop + deltaY))\n if (newScrollTop === vs.scrollTop) return\n vs.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }, [scheduler])\n\n const handleHorizontalScroll = useCallback((deltaX: number) => {\n const vs = viewStateRef.current\n const pixelsPerMs = vs.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const deltaMs = deltaX / pixelsPerMs\n const newStart = vs.visibleTimeStart + deltaMs\n const newEnd = vs.visibleTimeEnd + deltaMs\n vs.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n flushSync(() => syncHeaderState())\n propsRef.current.onTimeChange?.(newStart, newEnd)\n }, [scheduler, syncHeaderState])\n\n useEffect(() => {\n const el = interactionRef.current\n if (!el) return\n const handleWheel = (e: WheelEvent) => {\n if (e.ctrlKey || e.metaKey || e.altKey) {\n e.preventDefault()\n const rect = el.getBoundingClientRect()\n const cursorRatio = (e.clientX - rect.left) / rect.width\n zoomHandler.handleWheelZoom(e, cursorRatio)\n } else if (e.shiftKey) {\n e.preventDefault()\n // Some browsers (Chrome/Edge on macOS) pre-translate shift + external mouse wheel\n // into deltaX with deltaY=0; trackpads keep the raw deltaY. Use whichever is non-zero.\n handleHorizontalScroll(e.deltaY || e.deltaX)\n } else {\n const deltaX = e.deltaX\n if (deltaX !== 0 && Math.abs(deltaX) > Math.abs(e.deltaY)) {\n e.preventDefault()\n handleHorizontalScroll(deltaX)\n } else if (e.deltaY !== 0) {\n const hasInternalScroll = totalHeight > canvasHeight\n if (hasInternalScroll) e.preventDefault()\n handleVerticalScroll(e.deltaY)\n }\n }\n }\n el.addEventListener('wheel', handleWheel, { passive: false })\n return () => el.removeEventListener('wheel', handleWheel)\n }, [zoomHandler, handleVerticalScroll, handleHorizontalScroll, totalHeight, canvasHeight])\n\n // --- TOUCH PINCH-TO-ZOOM ---\n const touchRef = useRef<{ lastDistance: number | null; lastCenter: number | null }>({ lastDistance: null, lastCenter: null })\n\n useEffect(() => {\n const el = interactionRef.current\n if (!el) return\n\n const getDistance = (t1: Touch, t2: Touch) => Math.abs(t1.clientX - t2.clientX)\n const getCenter = (t1: Touch, t2: Touch, rect: DOMRect) => ((t1.clientX + t2.clientX) / 2) - rect.left\n\n const handleTouchStart = (e: TouchEvent) => {\n if (e.touches.length === 2) {\n e.preventDefault()\n touchRef.current.lastDistance = getDistance(e.touches[0], e.touches[1])\n touchRef.current.lastCenter = null\n }\n }\n\n const handleTouchMove = (e: TouchEvent) => {\n if (e.touches.length === 2 && touchRef.current.lastDistance !== null) {\n e.preventDefault()\n const newDistance = getDistance(e.touches[0], e.touches[1])\n const rect = el.getBoundingClientRect()\n const center = getCenter(e.touches[0], e.touches[1], rect)\n const cursorRatio = center / rect.width\n\n if (newDistance !== 0 && touchRef.current.lastDistance !== 0) {\n const scale = touchRef.current.lastDistance / newDistance\n const vs = viewStateRef.current\n const currentDuration = vs.visibleTimeEnd - vs.visibleTimeStart\n let newDuration = currentDuration * scale\n newDuration = Math.max(minZoom, Math.min(maxZoom, newDuration))\n\n const cursorTime = vs.visibleTimeStart + currentDuration * cursorRatio\n const newStart = cursorTime - newDuration * cursorRatio\n const newEnd = cursorTime + newDuration * (1 - cursorRatio)\n\n vs.update({ visibleTimeStart: newStart, visibleTimeEnd: newEnd })\n zoomHandlerRef.current?.updateBounds(newStart, newEnd)\n scheduler.markAllDirty()\n scheduleHeaderSync()\n scheduleCallbacks('zoom')\n }\n touchRef.current.lastDistance = newDistance\n }\n }\n\n const handleTouchEnd = () => {\n touchRef.current.lastDistance = null\n touchRef.current.lastCenter = null\n }\n\n el.addEventListener('touchstart', handleTouchStart, { passive: false })\n el.addEventListener('touchmove', handleTouchMove, { passive: false })\n el.addEventListener('touchend', handleTouchEnd)\n return () => {\n el.removeEventListener('touchstart', handleTouchStart)\n el.removeEventListener('touchmove', handleTouchMove)\n el.removeEventListener('touchend', handleTouchEnd)\n }\n }, [scheduler, scheduleHeaderSync, scheduleCallbacks])\n\n // --- POINTER HANDLERS ---\n const handlePointerMove = useCallback((e: React.PointerEvent) => {\n const el = e.currentTarget as HTMLElement\n const rect = el.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n cursorXRef.current = x\n pointerClientRef.current = { x: e.clientX, y: e.clientY }\n\n // --- Pan mode (drag on empty canvas) ---\n if (panRef.current) {\n const dx = e.clientX - panRef.current.startX\n const dy = e.clientY - panRef.current.startY\n if (!didPanRef.current && (Math.abs(dx) >= PAN_THRESHOLD || Math.abs(dy) >= PAN_THRESHOLD)) {\n didPanRef.current = true\n el.style.cursor = 'grabbing'\n el.setPointerCapture(e.pointerId)\n }\n if (didPanRef.current) {\n const moveDeltaX = e.clientX - panRef.current.lastX\n const moveDeltaY = e.clientY - panRef.current.lastY\n panRef.current.lastX = e.clientX\n panRef.current.lastY = e.clientY\n if (Math.abs(moveDeltaX) > 0) handleHorizontalScroll(-moveDeltaX)\n if (Math.abs(moveDeltaY) > 0) handleVerticalScroll(-moveDeltaY)\n }\n return\n }\n\n if (interactionHandler.isPending()) {\n interactionHandler.update(x, y)\n if (interactionHandler.isActive()) {\n const state = interactionHandler.getState()\n if (state && state.mode === 'move' && propsRef.current.canChangeGroup) {\n const group = hitTestGroup(y, viewStateRef.current, propsRef.current.groups)\n if (group) interactionHandler.setCurrentGroup(group.id)\n }\n scheduler.markDirty('overlay')\n }\n return\n }\n\n if (propsRef.current.showCursorLine) scheduler.markDirty('overlay')\n\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n const newHoveredId = item?.id\n if (newHoveredId !== hoveredItemIdRef.current) {\n hoveredItemIdRef.current = newHoveredId\n scheduler.markDirty('items')\n p.onItemHover?.(newHoveredId ?? null, e.nativeEvent as unknown as PointerEvent)\n }\n\n // Cursor management — derived from the same decision the pointer-down uses,\n // so the affordance and the interaction can never disagree.\n if (item) {\n const edge = detectEdge(x, item, viewStateRef.current)\n const mode = resolveInteractionMode(item, edge, p.canResize, p.canMove)\n el.style.cursor =\n mode === 'resize-left' || mode === 'resize-right' ? 'col-resize'\n : mode === 'move' ? 'grab'\n : 'default'\n } else {\n el.style.cursor = 'default'\n }\n }, [interactionHandler, scheduler, handleHorizontalScroll, handleVerticalScroll])\n\n const handlePointerDown = useCallback((e: React.PointerEvent) => {\n const p = propsRef.current\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n\n if (!item) {\n // Start pan on empty canvas\n panRef.current = { startX: e.clientX, startY: e.clientY, lastX: e.clientX, lastY: e.clientY }\n didPanRef.current = false\n return\n }\n\n const edge = detectEdge(x, item, viewStateRef.current)\n const mode = resolveInteractionMode(item, edge, p.canResize, p.canMove)\n\n // No permitted interaction → start nothing (no ghost, no drag).\n if (mode) {\n interactionHandler.startInteraction(item, mode, x, y)\n }\n }, [interactionHandler])\n\n const handlePointerUp = useCallback((e: React.PointerEvent) => {\n const el = e.currentTarget as HTMLElement\n\n // --- End pan mode ---\n if (panRef.current) {\n const wasPanning = didPanRef.current\n panRef.current = null\n didPanRef.current = false\n el.style.cursor = 'default'\n if (wasPanning) return // suppress click after pan\n }\n\n if (interactionHandler.isActive()) {\n const state = interactionHandler.getState()\n const vs = viewStateRef.current\n const pixelsPerMs = vs.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n if (state) {\n const validator = propsRef.current.moveResizeValidator\n const p = propsRef.current\n if (state.mode === 'move') {\n // Snapped start matches the live tooltip; endMove only resets the\n // handler and yields the (possibly changed) group.\n const snappedStartTime = snappedMoveStart(state, vs, p)\n const result = interactionHandler.endMove(pixelsPerMs)\n if (result) {\n const validatedTime = validator ? validator('move', state.item.id, snappedStartTime) : snappedStartTime\n const childMoves = p.hierarchyEngine.getMoveDelta(state.item.id, validatedTime)\n p.onItemMove?.(state.item.id, validatedTime, result.newGroupId, childMoves.length > 0 ? childMoves : undefined)\n }\n } else {\n const { edge, time: constrainedTime } = snappedResizeEdge(state, vs, p)\n const result = interactionHandler.endResize(pixelsPerMs)\n if (result) {\n const validatedTime = validator ? validator('resize', state.item.id, constrainedTime, edge) : constrainedTime\n p.onItemResize?.(state.item.id, validatedTime, edge)\n }\n }\n }\n el.style.cursor = 'default'\n scheduler.markDirty('overlay')\n return\n }\n if (interactionHandler.isPending()) interactionHandler.cancel()\n const rect = el.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const item = hitTest(x, y, viewStateRef.current, propsRef.current.intervalTree, propsRef.current.layoutEngine, propsRef.current.groups)\n if (item) propsRef.current.onItemClick?.(item.id, e.nativeEvent as unknown as PointerEvent)\n }, [interactionHandler, scheduler])\n\n const handleDoubleClick = useCallback((e: React.MouseEvent) => {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (item) {\n p.onItemDoubleClick?.(item.id, e.nativeEvent as unknown as PointerEvent)\n } else {\n const group = hitTestGroup(y, viewStateRef.current, p.groups)\n const time = viewStateRef.current.xToTime(x)\n if (group) p.onCanvasDoubleClick?.(group.id as number, time)\n }\n }, [])\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n e.preventDefault()\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const p = propsRef.current\n const item = hitTest(x, y, viewStateRef.current, p.intervalTree, p.layoutEngine, p.groups)\n if (item) {\n p.onItemContextMenu?.(item.id, e.nativeEvent as unknown as PointerEvent)\n } else {\n const group = hitTestGroup(y, viewStateRef.current, p.groups)\n const time = viewStateRef.current.xToTime(x)\n if (group) p.onCanvasContextMenu?.(group.id as number, time, e.nativeEvent as unknown as PointerEvent)\n }\n }, [])\n\n const handlePointerLeave = useCallback(() => {\n panRef.current = null\n didPanRef.current = false\n cursorXRef.current = null\n if (interactionRef.current) interactionRef.current.style.cursor = 'default'\n if (hoveredItemIdRef.current !== undefined) {\n hoveredItemIdRef.current = undefined\n scheduler.markDirty('items')\n propsRef.current.onItemHover?.(null, new PointerEvent('pointerleave'))\n }\n if (propsRef.current.showCursorLine) scheduler.markDirty('overlay')\n }, [scheduler])\n\n // --- HEADER CHILDREN ---\n const headerChildren = useMemo(() => {\n const headers: React.ReactNode[] = []\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) return\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'TimelineHeaders') {\n const childProps = child.props as Record<string, unknown>\n headers.push(\n React.cloneElement(child as React.ReactElement<Record<string, unknown>>, {\n visibleTimeStart: childProps.visibleTimeStart ?? headerTimeStart,\n visibleTimeEnd: childProps.visibleTimeEnd ?? headerTimeEnd,\n canvasWidth: childProps.canvasWidth ?? canvasWidth,\n sidebarWidth: childProps.sidebarWidth ?? sidebarWidth,\n theme: childProps.theme ?? theme,\n timezone: childProps.timezone ?? timezone,\n onZoomToInterval: childProps.onZoomToInterval ?? ((start: number, end: number) => {\n viewStateRef.current.update({ visibleTimeStart: start, visibleTimeEnd: end })\n scheduler.markAllDirty()\n syncHeaderState()\n propsRef.current.onTimeChange?.(start, end)\n propsRef.current.onZoom?.(start, end)\n }),\n }),\n )\n }\n })\n return headers\n }, [children, headerTimeStart, headerTimeEnd, canvasWidth, sidebarWidth, theme, timezone, scheduler, syncHeaderState])\n\n // --- INITIAL DRAW ---\n const initialDrawDone = useRef(false)\n useEffect(() => {\n if (!initialDrawDone.current) {\n initialDrawDone.current = true\n scheduler.markAllDirty()\n }\n }, [scheduler])\n\n // --- IMPERATIVE HANDLE (print capture) ---\n useImperativeHandle(ref, () => ({\n captureToCanvas({ timeStart, timeEnd, scale, sidebarWidth: printSidebarWidth }) {\n const p = propsRef.current\n const headerRowHeight = 28\n const headerHeight = headerRowHeight * 3\n const printGroupHeights = p.groups.map((g) => p.layoutEngine.getGroupHeight(g.id))\n const printGroupOffsets: number[] = [0]\n for (let i = 0; i < printGroupHeights.length; i++) {\n printGroupOffsets.push(printGroupOffsets[i] + printGroupHeights[i])\n }\n const totalHeight = printGroupOffsets[printGroupHeights.length]\n\n // Preserve the current zoom level (pixels per ms) from the on-screen view\n const vs = viewStateRef.current\n const currentPixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const printDuration = timeEnd - timeStart\n const timelineWidth = Math.max(p.canvasWidth, Math.round(printDuration * currentPixelsPerMs))\n\n const compositeWidth = (printSidebarWidth + timelineWidth) * scale\n const compositeHeight = (headerHeight + totalHeight) * scale\n\n const canvas = document.createElement('canvas')\n canvas.width = compositeWidth\n canvas.height = compositeHeight\n const ctx = canvas.getContext('2d')!\n ctx.scale(scale, scale)\n\n // --- Draw sidebar ---\n for (let i = 0; i < p.groups.length; i++) {\n const group = p.groups[i]\n const rowHeight = printGroupHeights[i]\n const y = headerHeight + printGroupOffsets[i]\n\n // Row background from rowStyle\n if (p.rowStyle) {\n const style = p.rowStyle(group)\n if (style?.backgroundColor) {\n ctx.fillStyle = style.backgroundColor\n ctx.fillRect(0, y, printSidebarWidth, rowHeight)\n }\n }\n\n // Group title\n const groupType = group.type as string | undefined\n let fontWeight = '400'\n let indent = 8\n if (groupType === 'project') {\n fontWeight = '700'\n } else if (groupType === 'CAG') {\n fontWeight = '600'\n } else if (groupType === 'CA') {\n fontWeight = '400'\n indent = 24\n }\n\n ctx.fillStyle = '#111'\n ctx.font = `${fontWeight} 12px sans-serif`\n ctx.textBaseline = 'middle'\n ctx.fillText(group.title, indent, y + rowHeight / 2, printSidebarWidth - indent - 4)\n }\n\n // --- Draw headers ---\n const drawHeaderRow = (rowY: number, getLabel: (time: dayjs.Dayjs) => string, unit: dayjs.ManipulateType) => {\n ctx.fillStyle = p.theme.header?.bg ?? '#f5f5f5'\n ctx.fillRect(printSidebarWidth, rowY, timelineWidth, headerRowHeight)\n ctx.strokeStyle = p.theme.grid?.line ?? '#e0e0e0'\n ctx.lineWidth = 1\n ctx.strokeRect(printSidebarWidth, rowY, timelineWidth, headerRowHeight)\n\n let cursor = toDayjs(timeStart, p.timezone).startOf(unit)\n if (cursor.valueOf() < timeStart) cursor = cursor.add(1, unit)\n\n const pxPerMs = timelineWidth / (timeEnd - timeStart)\n\n while (cursor.valueOf() < timeEnd) {\n const nextCursor = cursor.add(1, unit)\n const x = printSidebarWidth + (cursor.valueOf() - timeStart) * pxPerMs\n const endX = printSidebarWidth + (Math.min(nextCursor.valueOf(), timeEnd) - timeStart) * pxPerMs\n const width = endX - x\n\n // Vertical divider\n ctx.beginPath()\n ctx.moveTo(x, rowY)\n ctx.lineTo(x, rowY + headerRowHeight)\n ctx.stroke()\n\n // Label\n ctx.fillStyle = '#333'\n ctx.font = '600 11px sans-serif'\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'center'\n ctx.fillText(getLabel(cursor), x + width / 2, rowY + headerRowHeight / 2, width - 4)\n\n cursor = nextCursor\n }\n ctx.textAlign = 'start' // reset\n }\n\n drawHeaderRow(0, (d) => d.format('YYYY'), 'year')\n drawHeaderRow(headerRowHeight, (d) => d.format('MM'), 'month')\n drawHeaderRow(headerRowHeight * 2, (d) => String(d.isoWeek()), 'week')\n\n // --- Draw timeline layers ---\n const printViewState = new ViewState({\n visibleTimeStart: timeStart,\n visibleTimeEnd: timeEnd,\n canvasWidth: timelineWidth,\n canvasHeight: totalHeight,\n sidebarWidth: 0,\n lineHeight: p.lineHeight,\n groupCount: p.groups.length,\n buffer: 1,\n scrollTop: 0,\n groupHeights: printGroupHeights,\n })\n\n // Offset context for timeline area\n ctx.save()\n ctx.translate(printSidebarWidth, headerHeight)\n\n // Clip to timeline area\n ctx.beginPath()\n ctx.rect(0, 0, timelineWidth, totalHeight)\n ctx.clip()\n\n gridLayer.draw(ctx, printViewState, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights, p.timezone)\n itemsLayer.draw(\n ctx, printViewState, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, undefined, p.dependencies,\n p.summaryRenderer, p.hierarchyEngine,\n )\n overlayLayer.draw(ctx, printViewState, p.theme, {\n cursorX: null,\n snapX: null,\n markers: markersRef.current,\n interaction: null,\n })\n\n ctx.restore()\n\n return canvas\n },\n }), [gridLayer, itemsLayer, overlayLayer])\n\n // --- ON READY CALLBACK ---\n useEffect(() => {\n const api: CanvasTimelineRef = {\n captureToCanvas({ timeStart, timeEnd, scale, sidebarWidth: printSidebarWidth }) {\n const p = propsRef.current\n const headerRowHeight = 28\n const headerHeight = headerRowHeight * 3\n const printGroupHeights = p.groups.map((g) => p.layoutEngine.getGroupHeight(g.id))\n const printGroupOffsets: number[] = [0]\n for (let i = 0; i < printGroupHeights.length; i++) {\n printGroupOffsets.push(printGroupOffsets[i] + printGroupHeights[i])\n }\n const totalHeight = printGroupOffsets[printGroupHeights.length]\n const vs = viewStateRef.current\n const currentPixelsPerMs = p.canvasWidth / (vs.visibleTimeEnd - vs.visibleTimeStart)\n const printDuration = timeEnd - timeStart\n const timelineWidth = Math.max(p.canvasWidth, Math.round(printDuration * currentPixelsPerMs))\n const fullWidth = printSidebarWidth + timelineWidth\n const fullHeight = headerHeight + totalHeight\n\n const canvas = document.createElement('canvas')\n canvas.width = fullWidth * scale\n canvas.height = fullHeight * scale\n const ctx = canvas.getContext('2d')!\n ctx.scale(scale, scale)\n ctx.fillStyle = '#FFFFFF'\n ctx.fillRect(0, 0, fullWidth, fullHeight)\n\n // Sidebar\n ctx.save()\n ctx.beginPath()\n ctx.rect(0, 0, printSidebarWidth, fullHeight)\n ctx.clip()\n ctx.fillStyle = '#F9FAFB'\n ctx.fillRect(0, 0, printSidebarWidth, headerHeight)\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 1\n ctx.strokeRect(0, 0, printSidebarWidth, headerHeight)\n for (let i = 0; i < p.groups.length; i++) {\n const group = p.groups[i]\n const rowHeight = printGroupHeights[i]\n const y = headerHeight + printGroupOffsets[i]\n const rs = p.rowStyle?.(group)\n ctx.fillStyle = rs?.backgroundColor ?? (i % 2 === 0 ? '#FFFFFF' : '#F7F7F7')\n ctx.fillRect(0, y, printSidebarWidth, rowHeight)\n ctx.strokeStyle = '#E5E5E5'\n ctx.lineWidth = 0.5\n ctx.beginPath()\n ctx.moveTo(0, y + rowHeight)\n ctx.lineTo(printSidebarWidth, y + rowHeight)\n ctx.stroke()\n const gt = (group.type as string) ?? ''\n let indent = 8, fw = '400', fs = 11\n if (gt === 'project') { fw = '700'; fs = 12 }\n else if (gt === 'control_area_group') { fw = '600' }\n else if (gt === 'control_area') { indent = 24 }\n ctx.fillStyle = '#374151'\n ctx.font = `${fw} ${fs}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif`\n ctx.textBaseline = 'middle'\n const title = typeof group.title === 'string' ? group.title : String(group.title)\n ctx.fillText(title, indent, y + rowHeight / 2, printSidebarWidth - indent - 8)\n }\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 1\n ctx.beginPath()\n ctx.moveTo(printSidebarWidth, 0)\n ctx.lineTo(printSidebarWidth, fullHeight)\n ctx.stroke()\n ctx.restore()\n\n // Headers\n ctx.save()\n ctx.beginPath()\n ctx.rect(printSidebarWidth, 0, timelineWidth, headerHeight)\n ctx.clip()\n const duration = timeEnd - timeStart\n const units: Array<{ unit: 'year' | 'month' | 'week'; row: number }> = [\n { unit: 'year', row: 0 }, { unit: 'month', row: 1 }, { unit: 'week', row: 2 },\n ]\n for (const { unit, row } of units) {\n const hy = row * headerRowHeight\n ctx.fillStyle = '#F9FAFB'\n ctx.fillRect(printSidebarWidth, hy, timelineWidth, headerRowHeight)\n let cur = toDayjs(timeStart, p.timezone).startOf(unit)\n const endBound = toDayjs(timeEnd, p.timezone).add(1, unit)\n while (cur.isBefore(endBound)) {\n const next = cur.add(1, unit)\n const sx = printSidebarWidth + ((cur.valueOf() - timeStart) / duration) * timelineWidth\n const w = ((next.valueOf() - cur.valueOf()) / duration) * timelineWidth\n ctx.strokeStyle = '#E5E7EB'\n ctx.lineWidth = 0.5\n ctx.strokeRect(sx, hy, w, headerRowHeight)\n let label: string\n if (unit === 'year') label = cur.format('YYYY')\n else if (unit === 'month') label = cur.format('MM')\n else label = `${cur.week()}`\n ctx.fillStyle = '#6c737f'\n ctx.font = unit === 'year'\n ? '600 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n : '400 11px -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n ctx.textBaseline = 'middle'\n ctx.textAlign = 'center'\n if (w > 20) ctx.fillText(label, sx + w / 2, hy + headerRowHeight / 2)\n cur = next\n }\n }\n ctx.textAlign = 'start'\n ctx.restore()\n\n // Timeline\n ctx.save()\n ctx.beginPath()\n ctx.rect(printSidebarWidth, headerHeight, timelineWidth, totalHeight)\n ctx.clip()\n ctx.translate(printSidebarWidth, headerHeight)\n const pv = new ViewState({\n visibleTimeStart: timeStart, visibleTimeEnd: timeEnd,\n canvasWidth: timelineWidth, canvasHeight: totalHeight,\n sidebarWidth: 0, lineHeight: p.lineHeight,\n groupCount: p.groups.length, buffer: 1, scrollTop: 0,\n groupHeights: printGroupHeights,\n })\n gridLayer.draw(ctx, pv, p.groups, p.theme, p.dayStyle, p.rowStyle, p.highlights, p.timezone)\n itemsLayer.draw(ctx, pv, p.groups, p.items, p.intervalTree, p.layoutEngine,\n p.itemRenderer, p.groupRenderer, p.theme, p.selected, undefined, p.dependencies,\n p.summaryRenderer, p.hierarchyEngine)\n overlayLayer.draw(ctx, pv, p.theme, { cursorX: null, markers: markersRef.current })\n ctx.restore()\n\n return canvas\n },\n }\n onReady?.(api)\n }, [onReady, gridLayer, itemsLayer, overlayLayer])\n\n // --- RENDER ---\n const canvasContainerStyle: React.CSSProperties = {\n position: 'relative',\n width: canvasWidth,\n height: canvasHeight,\n overflow: 'hidden',\n cursor: 'default',\n }\n\n const canvasStyle: React.CSSProperties = { position: 'absolute', top: 0, left: 0 }\n\n return (\n <div ref={outerRef} style={{ display: 'flex', flexDirection: 'column', width: '100%', position: 'relative' }}>\n {(__LIB_DEV__ || devBadge) ? (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n zIndex: 9999,\n padding: '2px 6px',\n fontSize: 10,\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n lineHeight: 1.4,\n color: '#fff',\n background: 'rgba(17, 24, 39, 0.78)',\n borderBottomRightRadius: 4,\n pointerEvents: 'none',\n userSelect: 'none',\n }}\n >\n v{__LIB_VERSION__} · {__LIB_BUILD__}\n </div>\n ) : null}\n {headerChildren}\n <div ref={containerRef} style={{ display: 'flex', overflow: 'hidden', maxHeight: maxHeight ?? undefined }}>\n <Sidebar\n groups={groups}\n width={sidebarWidth}\n lineHeight={lineHeight}\n groupHeights={groupHeights}\n scrollTop={sidebarScrollTop}\n canvasHeight={canvasHeight}\n theme={theme}\n groupRenderer={sidebarGroupRenderer}\n onScroll={(newScrollTop) => {\n viewStateRef.current.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }}\n />\n <div\n ref={interactionRef}\n style={canvasContainerStyle}\n onPointerMove={handlePointerMove}\n onPointerDown={handlePointerDown}\n onPointerUp={handlePointerUp}\n onDoubleClick={handleDoubleClick}\n onContextMenu={handleContextMenu}\n onPointerLeave={handlePointerLeave}\n >\n <canvas ref={gridCanvasRef} style={{ ...canvasStyle, zIndex: 0 }} />\n <canvas ref={itemsCanvasRef} style={{ ...canvasStyle, zIndex: 1 }} />\n <canvas ref={overlayCanvasRef} style={{ ...canvasStyle, zIndex: 2 }} />\n </div>\n {rightSidebarWidth && rightSidebarGroupRenderer ? (\n <Sidebar\n groups={groups}\n width={rightSidebarWidth}\n lineHeight={lineHeight}\n groupHeights={groupHeights}\n scrollTop={sidebarScrollTop}\n canvasHeight={canvasHeight}\n theme={theme}\n groupRenderer={rightSidebarGroupRenderer}\n onScroll={(newScrollTop) => {\n viewStateRef.current.update({ scrollTop: newScrollTop })\n scheduler.markDirty('grid')\n scheduler.markDirty('items')\n scheduler.markDirty('overlay')\n setSidebarScrollTop(newScrollTop)\n }}\n />\n ) : null}\n </div>\n </div>\n )\n}))\n","import React from 'react'\nimport type { TimelineTheme } from '../types'\n\nexport interface TimelineHeadersProps {\n children: React.ReactNode\n theme?: TimelineTheme\n className?: string\n classNames?: string\n style?: React.CSSProperties\n visibleTimeStart?: number\n visibleTimeEnd?: number\n canvasWidth?: number\n sidebarWidth?: number\n onZoomToInterval?: (start: number, end: number) => void\n timezone?: string\n}\n\nexport function TimelineHeaders({ children, theme, className, classNames: _classNames, style, visibleTimeStart, visibleTimeEnd, canvasWidth, sidebarWidth = 0, onZoomToInterval, timezone }: TimelineHeadersProps) {\n const enhancedChildren = React.Children.map(children, (child) => {\n if (!React.isValidElement(child)) return child\n const displayName = (child.type as { displayName?: string })?.displayName\n if (displayName === 'DateHeader') {\n const childProps = child.props as Record<string, unknown>\n const enhanced = React.cloneElement(child as React.ReactElement<Record<string, unknown>>, {\n visibleTimeStart: childProps.visibleTimeStart ?? visibleTimeStart,\n visibleTimeEnd: childProps.visibleTimeEnd ?? visibleTimeEnd,\n canvasWidth: childProps.canvasWidth ?? canvasWidth,\n theme: childProps.theme ?? theme,\n onZoomToInterval: childProps.onIntervalClick ?? childProps.onZoomToInterval ?? onZoomToInterval,\n timezone: childProps.timezone ?? timezone,\n })\n return (\n <div style={{ display: 'flex' }}>\n <div style={{ width: sidebarWidth, flexShrink: 0 }} />\n <div style={{ flex: 1, overflow: 'hidden' }}>{enhanced}</div>\n </div>\n )\n }\n return child\n })\n\n return (\n <div className={className} style={{\n position: 'sticky', top: 0, zIndex: 20, display: 'flex', flexDirection: 'column',\n backgroundColor: theme?.header.bg ?? '#F9FAFB',\n borderTop: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n borderBottom: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n ...style,\n }}>\n {enhancedChildren}\n </div>\n )\n}\nTimelineHeaders.displayName = 'TimelineHeaders'\n","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_weekOfYear=t()}(this,(function(){\"use strict\";var e=\"week\",t=\"year\";return function(i,n,r){var f=n.prototype;f.week=function(i){if(void 0===i&&(i=null),null!==i)return this.add(7*(i-this.week()),\"day\");var n=this.$locale().yearStart||1;if(11===this.month()&&this.date()>25){var f=r(this).startOf(t).add(1,t).date(n),s=r(this).endOf(e);if(f.isBefore(s))return 1}var a=r(this).startOf(t).date(n).startOf(e).subtract(1,\"millisecond\"),o=this.diff(a,e,!0);return o<0?r(this).startOf(\"week\").week():Math.ceil(o)},f.weeks=function(e){return void 0===e&&(e=null),this.week(e)}}}));","import { useMemo, useCallback } from 'react'\nimport dayjs from 'dayjs'\nimport weekOfYear from 'dayjs/plugin/weekOfYear'\nimport type { TimelineTheme } from '../types'\nimport { toDayjs } from '../utils/timezone'\n\ndayjs.extend(weekOfYear)\n\nexport type DateUnit = 'year' | 'month' | 'week' | 'day' | 'hour'\n\n// Minimum cell width in pixels before the header auto-hides\nconst DEFAULT_MIN_CELL_WIDTH: Record<DateUnit, number> = {\n year: 30,\n month: 30,\n week: 20,\n day: 15,\n hour: 30,\n}\n\nexport interface DateHeaderProps {\n unit: DateUnit\n visibleTimeStart?: number\n visibleTimeEnd?: number\n canvasWidth?: number\n theme?: TimelineTheme\n height?: number\n className?: string\n labelFormat?: string | ((start: Date, end: Date, unit: DateUnit) => string)\n onIntervalClick?: (startTime: number, endTime: number) => void\n /** Minimum cell width in pixels. Header auto-hides when cells are narrower. Set to 0 to disable. */\n minCellWidth?: number\n // Called by TimelineHeaders to inject zoom behavior\n onZoomToInterval?: (start: number, end: number) => void\n timezone?: string\n}\n\nexport function DateHeader({\n unit,\n visibleTimeStart = 0,\n visibleTimeEnd = 0,\n canvasWidth = 0,\n theme,\n height = 28,\n className,\n labelFormat,\n onIntervalClick,\n minCellWidth,\n onZoomToInterval,\n timezone,\n}: DateHeaderProps) {\n const intervals = useMemo(() => {\n if (!visibleTimeStart || !visibleTimeEnd || !canvasWidth) return []\n\n const duration = visibleTimeEnd - visibleTimeStart\n\n // Check average cell width — auto-hide if too narrow\n const minWidth = minCellWidth ?? DEFAULT_MIN_CELL_WIDTH[unit]\n if (minWidth > 0) {\n const sampleStart = toDayjs(visibleTimeStart, timezone).startOf(unit)\n const sampleEnd = sampleStart.add(1, unit)\n const avgCellWidth = ((sampleEnd.valueOf() - sampleStart.valueOf()) / duration) * canvasWidth\n if (avgCellWidth < minWidth) return []\n }\n\n const result: Array<{ start: number; end: number; label: string; left: number; width: number }> = []\n // Add buffer: 1 extra unit before and after visible range\n let current = toDayjs(visibleTimeStart, timezone).startOf(unit).subtract(1, unit)\n const endBound = toDayjs(visibleTimeEnd, timezone).add(2, unit).valueOf()\n\n while (current.valueOf() < endBound) {\n const next = current.add(1, unit)\n const start = current.valueOf()\n const end = next.valueOf()\n const left = ((start - visibleTimeStart) / duration) * canvasWidth\n const width = ((end - start) / duration) * canvasWidth\n const label = formatLabel(current, next, unit, labelFormat, width)\n result.push({ start, end, label, left, width })\n current = next\n }\n return result\n }, [visibleTimeStart, visibleTimeEnd, canvasWidth, unit, labelFormat, minCellWidth, timezone])\n\n const handleClick = useCallback((start: number, end: number) => {\n if (onIntervalClick) {\n onIntervalClick(start, end)\n } else if (onZoomToInterval) {\n onZoomToInterval(start, end)\n }\n }, [onIntervalClick, onZoomToInterval])\n\n // Auto-hide: return nothing if no intervals (cells too narrow)\n if (intervals.length === 0) return null\n\n return (\n <div style={{ display: 'flex', position: 'relative', height, overflow: 'hidden' }}>\n {intervals.map((interval) => (\n <div\n key={interval.start}\n className={className}\n onClick={() => handleClick(interval.start, interval.end)}\n style={{\n position: 'absolute',\n left: interval.left,\n width: interval.width,\n height: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRight: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n borderBottom: `1px solid ${theme?.header.border ?? '#E5E7EB'}`,\n fontSize: 12,\n color: theme?.header.text ?? '#6c737f',\n backgroundColor: theme?.header.bg ?? '#F9FAFB',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n cursor: 'pointer',\n userSelect: 'none',\n padding: '0 4px',\n boxSizing: 'border-box',\n }}\n >\n <span>{interval.label}</span>\n </div>\n ))}\n </div>\n )\n}\nDateHeader.displayName = 'DateHeader'\n\nfunction formatLabel(\n start: dayjs.Dayjs,\n end: dayjs.Dayjs,\n unit: DateUnit,\n labelFormat: string | ((start: Date, end: Date, unit: DateUnit) => string) | undefined,\n _width: number,\n): string {\n if (typeof labelFormat === 'function') {\n return labelFormat(start.toDate(), end.toDate(), unit)\n }\n if (typeof labelFormat === 'string') {\n return start.format(labelFormat)\n }\n return formatDefault(start, unit)\n}\n\nfunction formatDefault(d: dayjs.Dayjs, unit: DateUnit): string {\n switch (unit) {\n case 'year': return d.format('YYYY')\n case 'month': return d.format('MM')\n case 'week': return `${d.week()}`\n case 'day': return d.format('D')\n case 'hour': return d.format('HH:mm')\n }\n}\n","import React from 'react'\n\ninterface SidebarHeaderProps {\n width: number\n children?: (props: { getRootProps: () => React.HTMLAttributes<HTMLDivElement> }) => React.ReactNode\n style?: React.CSSProperties\n}\n\nexport function SidebarHeader({ width, children, style }: SidebarHeaderProps) {\n const getRootProps = (): React.HTMLAttributes<HTMLDivElement> => ({ style: { width, ...style } })\n if (children) return <>{children({ getRootProps })}</>\n return <div style={{ width }} />\n}\nSidebarHeader.displayName = 'SidebarHeader'\n","import React from 'react'\ninterface CustomHeaderProps { children: React.ReactNode }\nexport function CustomHeader({ children }: CustomHeaderProps) { return <>{children}</> }\nCustomHeader.displayName = 'CustomHeader'\n"],"names":["DEFAULT_THEME","ViewState","config","params","offsets","i","h","_a","time","x","y","target","lo","hi","mid","index","extend","firstVisible","lastVisible","scrollXOffset","bufferPixels","IntervalTree","items","getStart","getEnd","intervals","item","min","max","iv","center","leftIntervals","rightIntervals","overlapping","start","end","results","node","LayoutEngine","lineHeight","itemHeightRatio","stackItems","hierarchy","itemHeight","summaryHeight","isSummary","byGroup","arr","groupId","groupItems","a","b","d","levelEnds","maxLevel","level","leaves","parents","nextLevel","parent","itemId","HierarchyEngine","children","id","visited","current","parentId","siblings","idx","result","stack","descendants","descId","desc","cached","depth","newStart","delta","edge","minChildStart","childId","child","maxChildEnd","defaultSummaryRenderer","ctx","bounds","state","_helpers","theme","width","height","color","diamondSize","midY","title","textWidth","maxTextWidth","displayText","hitTest","canvasX","canvasY","view","tree","layout","groups","groupIndexMap","candidates","topItem","topY","groupIndex","itemLayout","hitTestGroup","detectEdge","threshold","leftX","rightX","resolveCanResize","globalCanResize","resolveCanMove","globalCanMove","resolveInteractionMode","cr","setupCanvas","canvas","dpr","targetW","targetH","clearCanvas","RenderScheduler","drawCallback","layer","flags","t","module","this","e","s","f","n","u","r","o","l","c","m","v","dayjs","utc","tz","toDayjs","ts","timezone","GridLayer","dayStyle","rowStyle","highlights","rowHeight","group","bgColor","customRow","x1","x2","w","opacity","g","visibleStart","visibleEnd","dayPixelWidth","stepUnit","batchColor","batchOpacity","batchStartX","customBorderLines","flushBatch","endX","date","custom","dow","line","padding","badgeWidth","badgeHeight","badgeX","badgeY","ITEM_FONT","createDrawHelpers","radius","text","maxWidth","candidate","color1","color2","grad","type","size","half","cx","cy","fillColor","stemW","stemX","paddingH","pillHeight","pillWidth","ItemsLayer","itemRenderer","groupRenderer","selected","hoveredItemId","dependencies","summaryRenderer","queryStart","queryEnd","visibleItems","selectedSet","itemBoundsMap","yMin","yMax","helpers","renderer","depItemIds","dep","itemMap","boundsMap","fromBounds","toBounds","isHighlighted","startX","startY","endY","dx","cpOffset","arrowSize","OverlayLayer","options","cursorX","snapX","markers","interaction","marker","maxBadgeWidth","MAX_DELTA","normalizeDelta","ZoomHandler","onZoom","visibleTimeStart","visibleTimeEnd","minZoom","maxZoom","cursorRatio","speed","scale","currentDuration","newDuration","newEnd","DAY_MS","warnedInvalidSnap","warnInvalidSnap","detail","resolveDragSnap","dragSnap","value","gridSnap","snap","interval","anchor","days","local","startOfDay","dayLenMs","fraction","dayIndex","snappedIndex","snappedDate","ACTIVATION_THRESHOLD","InteractionHandler","mode","pixelsPerMs","deltaMs","newStartTime","snapped","newGroupId","newTime","collectItemEdges","excludeItemId","timeToX","edges","findSnapTarget","currentX","edgeXPositions","thresholdPx","_pixelsPerMs","_dragSnap","closestX","closestDist","dist","snappedMoveStart","vs","p","rawStart","otherEdges","startSnap","endSnap","snappedResizeEdge","rawEdgeTime","edgeSnapX","constraint","buildInteractionInfo","pointer","startTime","duration","endTime","OVERSCAN_PX","Sidebar","groupHeights","scrollTop","canvasHeight","onScroll","containerRef","useRef","isScrollingRef","useMemo","totalHeight","displayHeight","groupAtY","useCallback","handleScroll","useEffect","visibleGroups","top","_jsx","TodayMarker","_props","getTodayMarkerConfig","props","getTodayMarkerInterval","CustomMarker","getCustomMarkerConfig","isoWeek","mergeTheme","partial","HEADER_THROTTLE_MS","CanvasTimeline","React","forwardRef","ref","defaultTimeStart","defaultTimeEnd","sidebarWidth","canMove","canChangeGroup","canResize","themePartial","showCursorLine","sidebarGroupRenderer","onItemClick","onItemDoubleClick","onItemContextMenu","onItemMove","onItemResize","moveResizeValidator","onItemHover","onInteractionUpdate","onCanvasDoubleClick","onCanvasContextMenu","onTimeChange","selectedProp","rightSidebarWidth","rightSidebarGroupRenderer","onReady","maxHeight","devBadge","getGroupIndex","grps","selectedKey","gridCanvasRef","itemsCanvasRef","overlayCanvasRef","interactionRef","outerRef","containerWidth","setContainerWidth","useState","measuredHeight","setMeasuredHeight","container","obs","entries","entry","el","canvasWidth","hierarchyEngine","engine","intervalTree","layoutEngine","resolvedMaxHeight","viewStateRef","cursorXRef","hoveredItemIdRef","pointerClientRef","interactionActiveRef","panRef","didPanRef","PAN_THRESHOLD","headerTimeStart","setHeaderTimeStart","headerTimeEnd","setHeaderTimeEnd","sidebarScrollTop","setSidebarScrollTop","headerTimerRef","syncHeaderState","scheduleHeaderSync","resolvedSummaryRenderer","gridLayer","itemsLayer","overlayLayer","interactionHandler","markerConfigs","configs","displayName","markersKey","markersRef","todayMarkerInterval","propsRef","drawGrid","drawItems","calculateSnapX","deltaX","draggedEdgeXs","edgeX","edgeTime","drawOverlay","interactionRender","origX","origWidth","targetGroupY","groupChanged","schedulerRef","scheduler","timer","highlightsKey","prevHighlightsKey","prevMarkersKey","prevControlledStart","prevControlledEnd","callbackTimerRef","scheduleCallbacks","_b","zoomHandlerRef","zoomHandler","handleVerticalScroll","deltaY","maxScroll","newScrollTop","handleHorizontalScroll","flushSync","_c","handleWheel","rect","touchRef","getDistance","t1","t2","getCenter","handleTouchStart","handleTouchMove","newDistance","cursorTime","handleTouchEnd","handlePointerMove","dy","moveDeltaX","moveDeltaY","newHoveredId","handlePointerDown","handlePointerUp","wasPanning","validator","snappedStartTime","validatedTime","childMoves","constrainedTime","_d","handleDoubleClick","handleContextMenu","handlePointerLeave","headerChildren","headers","childProps","initialDrawDone","useImperativeHandle","timeStart","timeEnd","printSidebarWidth","headerRowHeight","headerHeight","printGroupHeights","printGroupOffsets","currentPixelsPerMs","printDuration","timelineWidth","compositeWidth","compositeHeight","style","groupType","fontWeight","indent","drawHeaderRow","rowY","getLabel","unit","cursor","pxPerMs","nextCursor","printViewState","api","fullWidth","fullHeight","rs","gt","fw","fs","units","row","hy","cur","endBound","next","sx","label","pv","canvasContainerStyle","canvasStyle","_jsxs","TimelineHeaders","className","_classNames","onZoomToInterval","enhancedChildren","enhanced","weekOfYear","DEFAULT_MIN_CELL_WIDTH","DateHeader","labelFormat","onIntervalClick","minCellWidth","minWidth","sampleStart","left","formatLabel","handleClick","_width","formatDefault","SidebarHeader","getRootProps","_Fragment","CustomHeader"],"mappings":"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","x_google_ignoreList":[8,9,20,26]}
|