{"version":3,"file":"timelineClipModel.mjs","names":[],"sources":["../../../src/hooks/clips/timelineClipModel.ts"],"sourcesContent":["import type {\n  Clip,\n  TimelineReadonly,\n  TimelineClipEntry,\n  TimelineClipGroup,\n  Track,\n} from '@techsquidtv/canvas-timeline-core';\n\nexport type { TimelineClipEntry } from '@techsquidtv/canvas-timeline-core';\n\n/**\n * Selected clip and track state derived from the current timeline snapshot.\n *\n * @template TrackKind - App-defined track kind.\n */\nexport interface TimelineSelectionState<TrackKind = string> {\n  /** Currently selected clip, or null when no clip is selected. */\n  selectedClip: TimelineReadonly<Clip> | null;\n  /** ID of the currently selected clip, or null when no clip is selected. */\n  selectedClipId: string | null;\n  /** ID of the track containing the selected clip, or null when no clip is selected. */\n  selectedClipTrackId: string | null;\n  /** All selected clips in track order. */\n  selectedClips: TimelineReadonly<Clip>[];\n  /** IDs of all selected clips in track order. */\n  selectedClipIds: string[];\n  /** Selected group when the primary selected clip belongs to one. */\n  selectedGroup: TimelineReadonly<TimelineClipGroup> | null;\n  /** Selected group id when the primary selected clip belongs to one. */\n  selectedGroupId: string | null;\n  /** Whether any clip or track is selected. */\n  hasSelection: boolean;\n  /** Currently selected track, or null when no track row is selected. */\n  selectedTrack: TimelineReadonly<Track<TrackKind>> | null;\n  /** ID of the currently selected track, or null when no track row is selected. */\n  selectedTrackId: string | null;\n}\n\n/**\n * Flattens timeline tracks into stable clip entries.\n *\n * @param tracks - Timeline tracks to flatten.\n * @template TrackKind - App-defined track kind values carried by returned\n * entries.\n * @returns Flattened clip entries in track order.\n */\nexport function flattenTimelineClips<TrackKind>(\n  tracks: readonly TimelineReadonly<Track<TrackKind>>[]\n): TimelineClipEntry<TrackKind>[] {\n  return tracks.flatMap((track, trackIndex) =>\n    track.clips.map((clip, clipIndex) => ({\n      clip,\n      track,\n      trackIndex,\n      clipIndex,\n    }))\n  );\n}\n\n/**\n * Derives selected clip and track metadata from timeline tracks.\n *\n * @param tracks - Timeline tracks to inspect.\n * @param clipGroups - Clip group state used to derive selected group metadata.\n * @template TrackKind - App-defined track kind values carried by selected track\n * state.\n * @returns Current selection metadata.\n */\nexport function deriveTimelineSelection<TrackKind>(\n  tracks: readonly TimelineReadonly<Track<TrackKind>>[],\n  clipGroups: readonly TimelineReadonly<TimelineClipGroup>[] = []\n): TimelineSelectionState<TrackKind> {\n  let selectedClip: TimelineReadonly<Clip> | null = null;\n  let selectedClipTrackId: string | null = null;\n  let selectedTrack: TimelineReadonly<Track<TrackKind>> | null = null;\n  const selectedClips: TimelineReadonly<Clip>[] = [];\n  const clipGroupByClipId = new Map<string, TimelineReadonly<TimelineClipGroup>>();\n  for (const group of clipGroups) {\n    for (const clipId of group.clipIds) {\n      clipGroupByClipId.set(clipId, group);\n    }\n  }\n\n  for (const track of tracks) {\n    if (track.selected) {\n      selectedTrack = track;\n    }\n\n    for (const clip of track.clips) {\n      if (clip.selected) {\n        selectedClips.push(clip);\n      }\n      if (!selectedClip && clip.selected) {\n        selectedClip = clip;\n        selectedClipTrackId = track.id;\n      }\n    }\n  }\n  const selectedGroup =\n    selectedClip === null ? null : (clipGroupByClipId.get(selectedClip.id) ?? null);\n\n  return {\n    selectedClip,\n    selectedClipId: selectedClip?.id ?? null,\n    selectedClipTrackId,\n    selectedClips,\n    selectedClipIds: selectedClips.map((clip) => clip.id),\n    selectedGroup,\n    selectedGroupId: selectedGroup?.id ?? null,\n    selectedTrack,\n    selectedTrackId: selectedTrack?.id ?? null,\n    hasSelection: selectedClips.length > 0 || selectedTrack !== null,\n  };\n}\n"],"mappings":";;;;;;;;;AA8CA,SAAgB,qBACd,QACgC;CAChC,OAAO,OAAO,SAAS,OAAO,eAC5B,MAAM,MAAM,KAAK,MAAM,eAAe;EACpC;EACA;EACA;EACA;CACF,EAAE,CACJ;AACF;;;;;;;;;;AAWA,SAAgB,wBACd,QACA,aAA6D,CAAC,GAC3B;CACnC,IAAI,eAA8C;CAClD,IAAI,sBAAqC;CACzC,IAAI,gBAA2D;CAC/D,MAAM,gBAA0C,CAAC;CACjD,MAAM,oCAAoB,IAAI,IAAiD;CAC/E,KAAK,MAAM,SAAS,YAClB,KAAK,MAAM,UAAU,MAAM,SACzB,kBAAkB,IAAI,QAAQ,KAAK;CAIvC,KAAK,MAAM,SAAS,QAAQ;EAC1B,IAAI,MAAM,UACR,gBAAgB;EAGlB,KAAK,MAAM,QAAQ,MAAM,OAAO;GAC9B,IAAI,KAAK,UACP,cAAc,KAAK,IAAI;GAEzB,IAAI,CAAC,gBAAgB,KAAK,UAAU;IAClC,eAAe;IACf,sBAAsB,MAAM;GAC9B;EACF;CACF;CACA,MAAM,gBACJ,iBAAiB,OAAO,OAAQ,kBAAkB,IAAI,aAAa,EAAE,KAAK;CAE5E,OAAO;EACL;EACA,gBAAgB,cAAc,MAAM;EACpC;EACA;EACA,iBAAiB,cAAc,KAAK,SAAS,KAAK,EAAE;EACpD;EACA,iBAAiB,eAAe,MAAM;EACtC;EACA,iBAAiB,eAAe,MAAM;EACtC,cAAc,cAAc,SAAS,KAAK,kBAAkB;CAC9D;AACF"}