{
  "version": 3,
  "sources": ["../src/controller.ts", "../src/gutter.ts", "../src/html.ts"],
  "sourcesContent": ["/* ---------------------------------------------------------------\n * AUTO-GENERATED \u2014 DO NOT EDIT\n *\n * Source: plugins/shared/src/controller.ts\n * Run `node plugins/sync-types.mjs` to regenerate.\n * --------------------------------------------------------------- */\n\n/**\n * Sidemark \u2014 MrsfController: overlay gutter architecture.\n *\n * The controller is the runtime engine for interactive MRSF rendering.\n * It reads comment data from the DOM (embedded `<script type=\"application/mrsf+json\">`)\n * or constructor options, creates gutter overlay columns, positions\n * badges/buttons at the correct vertical offsets, and handles all\n * user interactions (tooltips, selection, action buttons).\n *\n * Usage:\n *   import { MrsfController } from \"@mrsf/plugin-shared/controller\";\n *\n *   const ctrl = new MrsfController(document.querySelector(\".my-content\")!, {\n *     interactive: true,\n *     gutterPosition: \"left\",\n *   });\n *   // ctrl.destroy() to clean up\n *\n * Events dispatched on document:\n *   - mrsf:resolve   { commentId, line, ... }\n *   - mrsf:unresolve { commentId, line, ... }\n *   - mrsf:reply     { commentId, line, ... }\n *   - mrsf:edit      { commentId, line, ... }\n *   - mrsf:delete    { commentId, line, ... }\n *   - mrsf:navigate  { commentId, line, ... }\n *   - mrsf:add       { commentId: null, line, selectionText?, ... }\n *   - mrsf:submit    { action, commentId, text?, line?, ... }\n */\n\nimport type { CommentThread, SlimComment } from \"./types.js\";\nimport type { MrsfGutterRenderers } from \"./gutter.js\";\nimport {\n  resolveMrsfGutterAddButtonPresentation,\n  resolveMrsfGutterBadgePresentation,\n} from \"./gutter.js\";\nimport { renderThreadHtml, escapeHtml } from \"./html.js\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type MrsfAction = \"resolve\" | \"unresolve\" | \"reply\" | \"edit\" | \"delete\" | \"navigate\" | \"add\";\n\nexport interface MrsfActionDetail {\n  commentId: string | null;\n  line: number | null;\n  action: MrsfAction;\n  selectionText?: string | null;\n  start_line?: number | null;\n  end_line?: number | null;\n  start_column?: number | null;\n  end_column?: number | null;\n}\n\nexport interface MrsfSubmitDetail {\n  action: \"add\" | \"edit\" | \"reply\" | \"resolve\" | \"unresolve\" | \"delete\";\n  commentId: string | null;\n  text: string;\n  type?: string | null;\n  severity?: \"low\" | \"medium\" | \"high\" | null;\n  line?: number | null;\n  end_line?: number | null;\n  start_column?: number | null;\n  end_column?: number | null;\n  selection_text?: string | null;\n}\n\nexport interface MrsfControllerOptions {\n  /** Show gutter on left or right side. Default: \"right\". */\n  gutterPosition?: \"left\" | \"right\";\n  /** Enable interactive actions (add, resolve, reply, etc.). Default: false. */\n  interactive?: boolean;\n  /** Comment data passed directly (overrides embedded script). */\n  comments?: CommentThread[];\n  /**\n   * Render inline text highlights for comments that have `selected_text`.\n   * Wraps matching text in `<mark>` elements with hover tooltips.\n   * Default: true.\n   */\n  inlineHighlights?: boolean;\n  gutterRenderers?: MrsfGutterRenderers;\n}\n\n// \u2500\u2500 MrsfController \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport class MrsfController {\n  private container: HTMLElement;\n  private opts: Required<MrsfControllerOptions>;\n  private threads: Map<number, CommentThread[]> = new Map();\n  private gutterLeft: HTMLDivElement | null = null;\n  private gutterRight: HTMLDivElement | null = null;\n  private activeTooltip: HTMLElement | null = null;\n  private floatingAddButton: HTMLButtonElement | null = null;\n  private overlayEl: HTMLDivElement | null = null;\n  private lastSelectionText: string | null = null;\n  private resizeObserver: ResizeObserver | null = null;\n  private mutationObserver: MutationObserver | null = null;\n  private styleInjected = false;\n  private inlineMarks: HTMLElement[] = [];\n  private inlineTooltipEl: HTMLElement | null = null;\n  private orphanedSection: HTMLDivElement | null = null;\n  private refreshQueued = false;\n\n  private handleResizeBound = this.positionGutterItems.bind(this);\n  private handleMutationBound = this.handleMutations.bind(this);\n  private handleClickBound = this.handleClick.bind(this);\n  private handleSelectionBound = this.handleSelectionChange.bind(this);\n\n  constructor(container: HTMLElement, options: MrsfControllerOptions = {}) {\n    this.container = container;\n    this.opts = {\n      gutterPosition: options.gutterPosition ?? \"right\",\n      interactive: options.interactive ?? false,\n      comments: options.comments ?? [],\n      inlineHighlights: options.inlineHighlights ?? true,\n      gutterRenderers: options.gutterRenderers ?? {},\n    };\n\n    this.loadCommentData();\n    this.setupOverlayStructure();\n    this.renderGutterItems();\n    this.positionGutterItems();\n    this.renderInlineHighlights();\n    this.renderOrphanedSection();\n\n    controllerRegistry.add(this);\n\n    // Listeners\n    this.resizeObserver = new ResizeObserver(this.handleResizeBound);\n    this.resizeObserver.observe(this.container);\n    if (typeof MutationObserver !== \"undefined\") {\n      this.mutationObserver = new MutationObserver(this.handleMutationBound);\n      this.mutationObserver.observe(this.container, {\n        childList: true,\n        subtree: true,\n        characterData: true,\n      });\n    }\n    document.addEventListener(\"click\", this.handleClickBound);\n    if (this.opts.interactive) {\n      document.addEventListener(\"selectionchange\", this.handleSelectionBound);\n    }\n  }\n\n  /** Remove all controller DOM and listeners. */\n  destroy(): void {\n    this.resizeObserver?.disconnect();\n    this.mutationObserver?.disconnect();\n    controllerRegistry.delete(this);\n    document.removeEventListener(\"click\", this.handleClickBound);\n    document.removeEventListener(\"selectionchange\", this.handleSelectionBound);\n    this.removeInlineHighlights();\n    this.orphanedSection?.remove();\n    this.gutterLeft?.remove();\n    this.gutterRight?.remove();\n    this.floatingAddButton?.remove();\n    this.closeOverlay();\n    this.container.classList.remove(\"mrsf-overlay-root\");\n  }\n\n  /** Recalculate gutter positions after async layout changes such as Mermaid renders. */\n  refresh(): void {\n    this.positionGutterItems();\n  }\n\n  // \u2500\u2500 Data loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  private loadCommentData(): void {\n    // Priority: constructor options > embedded script\n    if (this.opts.comments.length > 0) {\n      this.buildThreadMap(this.opts.comments);\n      return;\n    }\n\n    const script = this.container.querySelector('script[type=\"application/mrsf+json\"]');\n    if (!script?.textContent) return;\n\n    try {\n      const data = JSON.parse(script.textContent) as { threads?: CommentThread[] };\n      if (data.threads) {\n        this.buildThreadMap(data.threads);\n      }\n    } catch {\n      // silently ignore malformed data\n    }\n  }\n\n  private buildThreadMap(threads: CommentThread[]): void {\n    this.threads.clear();\n    for (const t of threads) {\n      const line = t.comment.line;\n      if (line == null) continue;\n      const arr = this.threads.get(line) ?? [];\n      arr.push(t);\n      this.threads.set(line, arr);\n    }\n  }\n\n  private findCommentById(commentId: string | null): SlimComment | null {\n    if (!commentId) return null;\n\n    for (const threadList of this.threads.values()) {\n      for (const thread of threadList) {\n        if (thread.comment.id === commentId) {\n          return thread.comment;\n        }\n        const reply = thread.replies.find((item) => item.id === commentId);\n        if (reply) {\n          return reply;\n        }\n      }\n    }\n\n    return null;\n  }\n\n  private orderThreadsForDisplay(threads: CommentThread[]): CommentThread[] {\n    return [...threads].sort((left, right) => {\n      if (left.comment.resolved === right.comment.resolved) return 0;\n      return left.comment.resolved ? 1 : -1;\n    });\n  }\n\n  // \u2500\u2500 Overlay structure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  private setupOverlayStructure(): void {\n    this.container.classList.add(\"mrsf-overlay-root\");\n\n    const pos = this.opts.gutterPosition;\n    if (pos === \"left\") {\n      this.gutterLeft = this.createGutter(\"mrsf-gutter-left\");\n    } else {\n      this.gutterRight = this.createGutter(\"mrsf-gutter-right\");\n    }\n  }\n\n  private createGutter(cls: string): HTMLDivElement {\n    const gutter = document.createElement(\"div\");\n    gutter.className = `mrsf-gutter ${cls}`;\n    this.container.appendChild(gutter);\n    return gutter;\n  }\n\n  // \u2500\u2500 Gutter rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  /** Build badge/add-button elements for each line in the gutter(s). */\n  private renderGutterItems(): void {\n    const lines = this.collectLines();\n    const displayMap = this.collectThreadDisplayMap(lines);\n    const gutter = this.primaryGutter();\n    if (!gutter) return;\n\n    for (const line of lines) {\n      const threads = displayMap.get(line);\n      if (threads && threads.length > 0) {\n        const item = this.createBadgeItem(line, threads);\n        gutter.appendChild(item);\n      } else if (this.opts.interactive) {\n        const item = this.createAddItem(line);\n        gutter.appendChild(item);\n      }\n    }\n  }\n\n  private primaryGutter(): HTMLDivElement | null {\n    return this.gutterLeft ?? this.gutterRight;\n  }\n\n  private shouldExpandRange(el: HTMLElement): boolean {\n    return el.tagName === \"BLOCKQUOTE\" || el.tagName === \"PRE\";\n  }\n\n  private addVisibleLinesForElement(el: HTMLElement, seen: Set<number>): void {\n    const line = parseInt(el.dataset.mrsfLine ?? \"\", 10);\n    const startLine = parseInt(el.dataset.mrsfStartLine ?? \"\", 10);\n    const endLine = parseInt(el.dataset.mrsfEndLine ?? \"\", 10);\n\n    if (el.tagName === \"PRE\" && !isNaN(startLine) && !isNaN(endLine) && endLine > startLine) {\n      const visibleStart = startLine + 1;\n      const visibleEnd = endLine - 1;\n      for (let currentLine = visibleStart; currentLine <= visibleEnd; currentLine++) {\n        seen.add(currentLine);\n      }\n      return;\n    }\n\n    if (!isNaN(line)) {\n      seen.add(line);\n    }\n\n    if (\n      this.shouldExpandRange(el) &&\n      !isNaN(startLine) &&\n      !isNaN(endLine) &&\n      endLine > startLine\n    ) {\n      for (let currentLine = startLine; currentLine <= endLine; currentLine++) {\n        seen.add(currentLine);\n      }\n    }\n  }\n\n  /** Collect all unique line numbers from data-mrsf-line elements, expanding multi-line ranges. */\n  private collectLines(): number[] {\n    const els = this.container.querySelectorAll<HTMLElement>(\"[data-mrsf-line]\");\n    const seen = new Set<number>();\n    for (const el of els) {\n      if (el.tagName === \"SCRIPT\") continue;\n      this.addVisibleLinesForElement(el, seen);\n    }\n\n    return [...seen].sort((a, b) => a - b);\n  }\n\n  private resolveThreadDisplayLine(thread: CommentThread, availableLines: Set<number>): number | null {\n    const startLine = thread.comment.line;\n    if (startLine == null) return null;\n\n    const endLine = thread.comment.end_line != null && thread.comment.end_line >= startLine\n      ? thread.comment.end_line\n      : startLine;\n\n    for (let currentLine = startLine; currentLine <= endLine; currentLine++) {\n      if (availableLines.has(currentLine)) {\n        return currentLine;\n      }\n    }\n\n    return null;\n  }\n\n  private collectThreadDisplayMap(lines: number[]): Map<number, CommentThread[]> {\n    const availableLines = new Set(lines);\n    const displayMap = new Map<number, CommentThread[]>();\n\n    for (const threads of this.threads.values()) {\n      for (const thread of threads) {\n        const displayLine = this.resolveThreadDisplayLine(thread, availableLines);\n        if (displayLine == null) continue;\n\n        const existing = displayMap.get(displayLine) ?? [];\n        existing.push(thread);\n        displayMap.set(displayLine, existing);\n      }\n    }\n\n    return displayMap;\n  }\n\n  private createBadgeItem(line: number, threads: CommentThread[]): HTMLDivElement {\n    const item = document.createElement(\"div\");\n    item.className = \"mrsf-gutter-item\";\n    item.dataset.mrsfGutterLine = String(line);\n\n    const displayThreads = this.orderThreadsForDisplay(threads);\n\n    const total = threads.reduce((n, t) => n + 1 + t.replies.length, 0);\n    const allResolved = threads.every((t) => t.comment.resolved);\n    const highestSeverity = threads.reduce<string | null>((sev, t) => {\n      if (t.comment.severity === \"high\" || sev === \"high\") return \"high\";\n      if (t.comment.severity === \"medium\" || sev === \"medium\") return \"medium\";\n      if (t.comment.severity === \"low\" || sev === \"low\") return \"low\";\n      return sev;\n    }, null);\n\n    const classes = [\"mrsf-badge\"];\n    if (allResolved) classes.push(\"mrsf-badge-resolved\");\n    if (highestSeverity === \"high\" || highestSeverity === \"medium\") {\n      classes.push(`mrsf-badge-severity-${highestSeverity}`);\n    }\n\n    const presentation = resolveMrsfGutterBadgePresentation(\n      {\n        line,\n        commentCount: total,\n        threadCount: threads.length,\n        resolvedState: allResolved ? \"resolved\" : threads.some((thread) => thread.comment.resolved) ? \"mixed\" : \"open\",\n        highestSeverity,\n        isActive: this.activeTooltip?.parentElement === item,\n      },\n      this.opts.gutterRenderers.badge,\n    );\n    const badge = document.createElement(\"span\");\n    badge.className = classes.join(\" \");\n    if (presentation.className) {\n      badge.classList.add(...presentation.className.split(/\\s+/).filter(Boolean));\n    }\n    badge.dataset.mrsfLine = String(line);\n    badge.dataset.mrsfAction = \"navigate\";\n    badge.dataset.mrsfCommentId = displayThreads[0].comment.id;\n    badge.tabIndex = 0;\n    badge.textContent = presentation.label;\n    badge.title = presentation.title;\n    badge.setAttribute(\"aria-label\", presentation.ariaLabel);\n    for (const [name, value] of Object.entries(presentation.attributes ?? {})) {\n      badge.setAttribute(name, value);\n    }\n    badge.addEventListener(\"click\", (e) => {\n      e.stopPropagation();\n      this.toggleTooltip(item, line, displayThreads);\n    });\n\n    item.appendChild(badge);\n\n    return item;\n  }\n\n  private createAddItem(line: number): HTMLDivElement {\n    const item = document.createElement(\"div\");\n    item.className = \"mrsf-gutter-item\";\n    item.dataset.mrsfGutterLine = String(line);\n\n    const addBtn = this.createAddButton(line);\n    item.appendChild(addBtn);\n    return item;\n  }\n\n  private createAddButton(line: number): HTMLButtonElement {\n    const presentation = resolveMrsfGutterAddButtonPresentation(\n      {\n        line,\n        isActive: false,\n      },\n      this.opts.gutterRenderers.addButton,\n    );\n    const btn = document.createElement(\"button\");\n    btn.className = \"mrsf-gutter-add\";\n    if (presentation.className) {\n      btn.classList.add(...presentation.className.split(/\\s+/).filter(Boolean));\n    }\n    btn.type = \"button\";\n    btn.dataset.mrsfAction = \"add\";\n    btn.dataset.mrsfLine = String(line);\n    btn.dataset.mrsfStartLine = String(line);\n    btn.dataset.mrsfEndLine = String(line);\n    btn.title = presentation.title;\n    btn.setAttribute(\"aria-label\", presentation.ariaLabel);\n    btn.textContent = presentation.label;\n    for (const [name, value] of Object.entries(presentation.attributes ?? {})) {\n      btn.setAttribute(name, value);\n    }\n    return btn;\n  }\n\n  // \u2500\u2500 Positioning \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  /** Measure [data-mrsf-line] elements and set gutter item Y offsets. */\n  positionGutterItems(): void {\n    const containerRect = this.container.getBoundingClientRect();\n\n    const gutters = [this.gutterLeft, this.gutterRight].filter(Boolean) as HTMLDivElement[];\n    for (const gutter of gutters) {\n      const items = gutter.querySelectorAll<HTMLDivElement>(\".mrsf-gutter-item\");\n      const positioned: Array<{ item: HTMLDivElement; target: HTMLElement; kind: \"badge\" | \"add\" }> = [];\n      for (const item of items) {\n        const line = parseInt(item.dataset.mrsfGutterLine!, 10);\n        // For expanded multi-line elements, find the rendered content element whose line data contains this line.\n        let target = this.findDirectElementForLine(line);\n        if (!target) {\n          target = this.findElementForLine(line);\n        }\n        if (!target) {\n          item.style.display = \"none\";\n          continue;\n        }\n        const top = this.calculateItemTop(target, line, containerRect);\n        item.style.top = `${top}px`;\n        item.style.display = \"\";\n        positioned.push({\n          item,\n          target,\n          kind: item.querySelector(\".mrsf-badge\") ? \"badge\" : \"add\",\n        });\n      }\n\n      this.suppressAddItemsThatShareBadgeTargets(positioned);\n    }\n  }\n\n  private suppressAddItemsThatShareBadgeTargets(\n    positioned: Array<{ item: HTMLDivElement; target: HTMLElement; kind: \"badge\" | \"add\" }>,\n  ): void {\n    const badgeTargets = new Set(\n      positioned\n        .filter((entry) => entry.kind === \"badge\")\n        .map((entry) => entry.target),\n    );\n\n    for (const entry of positioned) {\n      if (entry.kind === \"add\" && badgeTargets.has(entry.target)) {\n        entry.item.style.display = \"none\";\n      }\n    }\n  }\n\n  private handleMutations(records: MutationRecord[]): void {\n    if (!records.some((record) => this.isExternalContentMutation(record))) {\n      return;\n    }\n    this.queueRefresh();\n  }\n\n  private isExternalContentMutation(record: MutationRecord): boolean {\n    const target = record.target instanceof Node ? record.target : null;\n    if (target && this.isControllerOwnedNode(target)) {\n      return false;\n    }\n\n    for (const node of [...record.addedNodes, ...record.removedNodes]) {\n      if (!this.isControllerOwnedNode(node)) {\n        return true;\n      }\n    }\n\n    return record.type === \"characterData\";\n  }\n\n  private isControllerOwnedNode(node: Node): boolean {\n    if (!(node instanceof Element)) {\n      return false;\n    }\n    return Boolean(\n      node.closest(\".mrsf-gutter\") ||\n      node.closest(\".mrsf-orphaned-section\") ||\n      node.closest(\"script[type=\\\"application/mrsf+json\\\"]\"),\n    );\n  }\n\n  private queueRefresh(): void {\n    if (this.refreshQueued) return;\n    this.refreshQueued = true;\n    queueMicrotask(() => {\n      this.refreshQueued = false;\n      this.refresh();\n    });\n  }\n\n  private findDirectElementForLine(line: number): HTMLElement | null {\n    const els = this.container.querySelectorAll<HTMLElement>(`[data-mrsf-line=\"${line}\"]`);\n    for (const el of els) {\n      if (el.tagName === \"SCRIPT\") continue;\n      if (el.closest(\".mrsf-gutter\")) continue;\n      if (el.classList.contains(\"mrsf-gutter-item\")) continue;\n      return el;\n    }\n    return null;\n  }\n\n  private calculateItemTop(target: HTMLElement, line: number, containerRect: DOMRect): number {\n    const targetRect = target.getBoundingClientRect();\n    const rangeTop = targetRect.top - containerRect.top + this.container.scrollTop;\n\n    if (target.tagName !== \"PRE\") {\n      return rangeTop;\n    }\n\n    const startLine = parseInt(target.dataset.mrsfStartLine ?? \"\", 10);\n    const endLine = parseInt(target.dataset.mrsfEndLine ?? \"\", 10);\n    const visibleStart = startLine + 1;\n    const visibleEnd = endLine - 1;\n    const visibleLineCount = visibleEnd - visibleStart + 1;\n\n    if (\n      isNaN(startLine) ||\n      isNaN(endLine) ||\n      visibleLineCount <= 0 ||\n      line < visibleStart ||\n      line > visibleEnd\n    ) {\n      return rangeTop;\n    }\n\n    const styles = window.getComputedStyle(target);\n    const paddingTop = parseFloat(styles.paddingTop) || 0;\n    const paddingBottom = parseFloat(styles.paddingBottom) || 0;\n    const contentHeight = Math.max(targetRect.height - paddingTop - paddingBottom, 0);\n\n    let lineHeight = parseFloat(styles.lineHeight);\n    if (!Number.isFinite(lineHeight) || lineHeight <= 0) {\n      lineHeight = visibleLineCount > 0 ? contentHeight / visibleLineCount : 0;\n    }\n\n    return rangeTop + paddingTop + (line - visibleStart) * lineHeight;\n  }\n\n  /**\n   * Find the element whose start-line/end-line range contains the given line.\n   * Used for positioning gutter items on expanded multi-line elements.\n   */\n  private findElementForLine(line: number): HTMLElement | null {\n    const els = this.container.querySelectorAll<HTMLElement>(\"[data-mrsf-start-line][data-mrsf-end-line]\");\n    for (const el of els) {\n      if (el.tagName === \"SCRIPT\") continue;\n      const start = parseInt(el.dataset.mrsfStartLine!, 10);\n      const end = parseInt(el.dataset.mrsfEndLine!, 10);\n      if (!isNaN(start) && !isNaN(end) && line >= start && line <= end) {\n        return el;\n      }\n    }\n    return null;\n  }\n\n  // \u2500\u2500 Orphaned comments section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  /**\n   * Render orphaned comments (whose line doesn't match any DOM element)\n   * in a dedicated section at the bottom of the container.\n   */\n  private renderOrphanedSection(): void {\n    const lines = this.collectLines();\n    const lineSet = new Set(lines);\n    const orphanedThreads: CommentThread[] = [];\n\n    for (const threads of this.threads.values()) {\n      for (const thread of threads) {\n        if (this.resolveThreadDisplayLine(thread, lineSet) == null) {\n          orphanedThreads.push(thread);\n        }\n      }\n    }\n\n    if (orphanedThreads.length === 0) return;\n\n    const section = document.createElement(\"div\");\n    section.className = \"mrsf-orphaned-section\";\n\n    const heading = document.createElement(\"div\");\n    heading.className = \"mrsf-orphaned-heading\";\n    heading.textContent = `Orphaned Comments (${orphanedThreads.length})`;\n    section.appendChild(heading);\n\n    const interactive = this.opts.interactive;\n    for (const thread of this.orderThreadsForDisplay(orphanedThreads)) {\n      const wrapper = document.createElement(\"div\");\n      wrapper.className = interactive\n        ? \"mrsf-orphaned-thread mrsf-interactive\"\n        : \"mrsf-orphaned-thread\";\n      wrapper.innerHTML = renderThreadHtml(thread, interactive);\n      section.appendChild(wrapper);\n    }\n\n    this.container.appendChild(section);\n    this.orphanedSection = section;\n  }\n\n  // \u2500\u2500 Inline text highlights \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  /**\n   * For comments with `selected_text`, find the matching text in the DOM\n   * and wrap it in a `<mark class=\"mrsf-inline-highlight\">` element with\n   * hover/click behaviour to show the comment tooltip.\n   */\n  private renderInlineHighlights(): void {\n    if (!this.opts.inlineHighlights) return;\n\n    const lineSet = new Set(this.collectLines());\n\n    for (const threads of this.threads.values()) {\n      for (const thread of threads) {\n        const comment = thread.comment;\n        if (!comment.selected_text) continue;\n\n        const displayLine = this.resolveThreadDisplayLine(thread, lineSet);\n        if (displayLine == null) continue;\n\n        const el = this.container.querySelector<HTMLElement>(\n          `[data-mrsf-line=\"${displayLine}\"]:not(script):not(.mrsf-gutter):not(.mrsf-gutter-item)`,\n        );\n        if (!el) continue;\n\n        this.wrapSelectedText(el, comment.selected_text, thread, displayLine);\n      }\n    }\n  }\n\n  /**\n   * Strip common inline markdown syntax so `selected_text` from source\n   * can be matched against rendered text content.\n   */\n  private static stripInlineMarkdown(text: string): string {\n    let s = text;\n    // Backtick code spans: `code` \u2192 code\n    s = s.replace(/`([^`]+)`/g, \"$1\");\n    // Bold: **text** or __text__\n    s = s.replace(/\\*\\*(.+?)\\*\\*/g, \"$1\");\n    s = s.replace(/__(.+?)__/g, \"$1\");\n    // Italic: *text* or _text_\n    s = s.replace(/\\*(.+?)\\*/g, \"$1\");\n    s = s.replace(/_(.+?)_/g, \"$1\");\n    // Strikethrough: ~~text~~\n    s = s.replace(/~~(.+?)~~/g, \"$1\");\n    return s;\n  }\n\n  /**\n   * Walk text nodes inside `root` to find `text`, then wrap the matching\n   * range in a `<mark>` element. Falls back to markdown-stripped matching.\n   */\n  private wrapSelectedText(\n    root: HTMLElement,\n    selectedText: string,\n    thread: CommentThread,\n    displayLine: number,\n  ): void {\n    const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n    let accumulated = \"\";\n    const textNodes: { node: Text; start: number; end: number }[] = [];\n\n    let node: Text | null;\n    while ((node = walker.nextNode() as Text | null)) {\n      const start = accumulated.length;\n      accumulated += node.textContent || \"\";\n      textNodes.push({ node, start, end: accumulated.length });\n    }\n\n    // Try exact match first, then stripped markdown\n    let matchStart = accumulated.indexOf(selectedText);\n    let matchLen = selectedText.length;\n    if (matchStart === -1) {\n      const stripped = MrsfController.stripInlineMarkdown(selectedText);\n      if (stripped !== selectedText) {\n        matchStart = accumulated.indexOf(stripped);\n        matchLen = stripped.length;\n      }\n    }\n    if (matchStart === -1) return;\n\n    const matchEnd = matchStart + matchLen;\n\n    // Build a Range spanning the matched text nodes\n    const range = document.createRange();\n    let startSet = false;\n\n    for (const tn of textNodes) {\n      if (!startSet && tn.end > matchStart) {\n        range.setStart(tn.node, matchStart - tn.start);\n        startSet = true;\n      }\n      if (startSet && tn.end >= matchEnd) {\n        range.setEnd(tn.node, matchEnd - tn.start);\n        break;\n      }\n    }\n\n    if (!startSet) return;\n\n    const mark = document.createElement(\"mark\");\n    mark.className = \"mrsf-inline-highlight\";\n    mark.dataset.mrsfCommentId = thread.comment.id;\n    mark.dataset.mrsfLine = String(displayLine);\n\n    try {\n      range.surroundContents(mark);\n    } catch {\n      // Range crosses element boundaries \u2014 extract and re-insert\n      const fragment = range.extractContents();\n      mark.appendChild(fragment);\n      range.insertNode(mark);\n    }\n\n    this.inlineMarks.push(mark);\n\n    // Hover shows tooltip inline\n    mark.addEventListener(\"mouseenter\", () => {\n      this.showInlineTooltip(mark, thread);\n    });\n    mark.addEventListener(\"mouseleave\", (e) => {\n      // Don't hide if moving into the tooltip itself\n      const related = (e as MouseEvent).relatedTarget as HTMLElement | null;\n      if (related && this.inlineTooltipEl?.contains(related)) return;\n      this.scheduleHideInlineTooltip();\n    });\n\n    // Click toggles tooltip (for touch / accessibility)\n    mark.addEventListener(\"click\", (e) => {\n      e.stopPropagation();\n      if (this.inlineTooltipEl && this.inlineTooltipEl.dataset.mrsfForMark === thread.comment.id) {\n        this.hideInlineTooltip();\n      } else {\n        this.showInlineTooltip(mark, thread);\n      }\n    });\n  }\n\n  private showInlineTooltip(mark: HTMLElement, thread: CommentThread): void {\n    this.hideInlineTooltip();\n\n    const tooltip = document.createElement(\"div\");\n    tooltip.className = this.opts.interactive\n      ? \"mrsf-inline-tooltip mrsf-interactive mrsf-tooltip-visible\"\n      : \"mrsf-inline-tooltip mrsf-tooltip-visible\";\n    tooltip.dataset.mrsfForMark = thread.comment.id;\n    tooltip.innerHTML = renderThreadHtml(thread, this.opts.interactive);\n    this.applyThemeVariables(tooltip);\n\n    // Let user mouse into tooltip without it disappearing\n    tooltip.addEventListener(\"mouseenter\", () => {\n      this.cancelHideInlineTooltip();\n    });\n    tooltip.addEventListener(\"mouseleave\", () => {\n      this.hideInlineTooltip();\n    });\n\n    // Append to body with fixed positioning to avoid clipping\n    document.body.appendChild(tooltip);\n    this.inlineTooltipEl = tooltip;\n\n    // Position relative to the mark element\n    const rect = mark.getBoundingClientRect();\n    const margin = 4;\n    const tooltipH = tooltip.offsetHeight;\n\n    // Prefer below; flip above if not enough space at bottom\n    if (rect.bottom + margin + tooltipH > window.innerHeight) {\n      tooltip.style.top = `${rect.top - tooltipH - margin}px`;\n    } else {\n      tooltip.style.top = `${rect.bottom + margin}px`;\n    }\n    tooltip.style.left = `${Math.max(0, rect.left)}px`;\n  }\n\n  private applyThemeVariables(el: HTMLElement): void {\n    const styles = window.getComputedStyle(this.container);\n    const themeVars = [\n      \"--mrsf-accent\",\n      \"--mrsf-badge-bg\",\n      \"--mrsf-badge-fg\",\n      \"--mrsf-badge-resolved-bg\",\n      \"--mrsf-add-bg\",\n      \"--mrsf-add-fg\",\n      \"--mrsf-add-border\",\n      \"--mrsf-tooltip-bg\",\n      \"--mrsf-tooltip-fg\",\n      \"--mrsf-tooltip-border\",\n      \"--mrsf-highlight-bg\",\n      \"--mrsf-highlight-border\",\n      \"--mrsf-severity-high\",\n      \"--mrsf-severity-medium\",\n      \"--mrsf-severity-low\",\n      \"--mrsf-font-family\",\n    ];\n\n    for (const name of themeVars) {\n      const value = styles.getPropertyValue(name).trim();\n      if (value) {\n        el.style.setProperty(name, value);\n      }\n    }\n  }\n\n  private hideInlineTimeout: ReturnType<typeof setTimeout> | null = null;\n\n  private scheduleHideInlineTooltip(): void {\n    this.hideInlineTimeout = setTimeout(() => this.hideInlineTooltip(), 120);\n  }\n\n  private cancelHideInlineTooltip(): void {\n    if (this.hideInlineTimeout) {\n      clearTimeout(this.hideInlineTimeout);\n      this.hideInlineTimeout = null;\n    }\n  }\n\n  private hideInlineTooltip(): void {\n    this.cancelHideInlineTooltip();\n    if (this.inlineTooltipEl) {\n      this.inlineTooltipEl.remove();\n      this.inlineTooltipEl = null;\n    }\n  }\n\n  /** Remove all inline marks, unwrapping their contents back to text. */\n  private removeInlineHighlights(): void {\n    this.hideInlineTooltip();\n    for (const mark of this.inlineMarks) {\n      const parent = mark.parentNode;\n      if (!parent) continue;\n      while (mark.firstChild) {\n        parent.insertBefore(mark.firstChild, mark);\n      }\n      parent.removeChild(mark);\n    }\n    this.inlineMarks = [];\n  }\n\n  // \u2500\u2500 Tooltip \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  private toggleTooltip(anchor: HTMLElement, line: number, threads: CommentThread[]): void {\n    // If already visible on this anchor, hide it\n    if (this.activeTooltip && this.activeTooltip.parentElement === anchor) {\n      this.hideTooltip();\n      return;\n    }\n    this.hideTooltip();\n    this.showTooltip(anchor, line, threads);\n  }\n\n  private showTooltip(anchor: HTMLElement, line: number, threads: CommentThread[]): void {\n    const tooltip = document.createElement(\"div\");\n    const interactive = this.opts.interactive;\n    tooltip.className = interactive\n      ? \"mrsf-tooltip mrsf-interactive mrsf-tooltip-visible\"\n      : \"mrsf-tooltip mrsf-tooltip-visible\";\n    tooltip.dataset.mrsfLine = String(line);\n\n    let html = \"\";\n    for (const thread of this.orderThreadsForDisplay(threads)) {\n      html += renderThreadHtml(thread, interactive);\n    }\n    if (interactive) {\n      html += `<div class=\"mrsf-tooltip-actions\"><button class=\"mrsf-action-btn\" data-mrsf-action=\"add\" data-mrsf-line=\"${line}\" data-mrsf-start-line=\"${line}\" data-mrsf-end-line=\"${line}\">Add comment</button></div>`;\n    }\n    tooltip.innerHTML = html;\n\n    anchor.appendChild(tooltip);\n    this.activeTooltip = tooltip;\n  }\n\n  private hideTooltip(): void {\n    if (this.activeTooltip) {\n      this.activeTooltip.remove();\n      this.activeTooltip = null;\n    }\n  }\n\n  // \u2500\u2500 Click handling \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  private handleClick(e: Event): void {\n    const target = (e.target as HTMLElement).closest<HTMLElement>(\"[data-mrsf-action]\");\n\n    // Close tooltip when clicking outside\n    if (!target && this.activeTooltip) {\n      const tooltipClick = (e.target as HTMLElement).closest(\".mrsf-tooltip\");\n      if (!tooltipClick) {\n        this.hideTooltip();\n      }\n      return;\n    }\n    if (!target) return;\n\n    const action = target.dataset.mrsfAction as MrsfAction | undefined;\n    if (!action) return;\n\n    const commentId = target.dataset.mrsfCommentId ?? null;\n    const lineStr = target.dataset.mrsfLine;\n    const line = lineStr ? parseInt(lineStr, 10) : null;\n    const selectionText = target.dataset.mrsfSelection ?? this.lastSelectionText ?? null;\n\n    const startLineStr = target.dataset.mrsfStartLine;\n    const endLineStr = target.dataset.mrsfEndLine;\n    const startColStr = target.dataset.mrsfStartColumn;\n    const endColStr = target.dataset.mrsfEndColumn;\n    const startLine = startLineStr ? parseInt(startLineStr, 10) : (line ?? null);\n    const endLine = endLineStr ? parseInt(endLineStr, 10) : (line ?? null);\n    const startColumn = startColStr ? parseInt(startColStr, 10) : null;\n    const endColumn = endColStr ? parseInt(endColStr, 10) : null;\n\n    e.preventDefault();\n    e.stopPropagation();\n\n    const detail: MrsfActionDetail = {\n      commentId,\n      line,\n      action,\n      selectionText,\n      start_line: startLine,\n      end_line: endLine,\n      start_column: startColumn,\n      end_column: endColumn,\n    };\n\n    if (action === \"add\" || action === \"edit\" || action === \"reply\") {\n      if (action === \"add\") {\n        this.hideFloatingAddButton();\n      }\n      this.openForm(action, detail);\n      return;\n    }\n\n    if (action === \"resolve\" || action === \"unresolve\" || action === \"delete\") {\n      this.openConfirm(action, detail);\n      return;\n    }\n\n    document.dispatchEvent(\n      new CustomEvent(`mrsf:${action}`, { detail, bubbles: true }),\n    );\n  }\n\n  // \u2500\u2500 Selection handling \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  private handleSelectionChange(): void {\n    const sel = document.getSelection();\n    if (!sel || sel.isCollapsed || sel.rangeCount === 0) {\n      this.hideFloatingAddButton();\n      return;\n    }\n\n    const text = sel.toString().trim();\n    if (!text) {\n      this.hideFloatingAddButton();\n      return;\n    }\n\n    const range = sel.getRangeAt(0);\n    if (!this.selectionBelongsToContainer(range)) {\n      this.hideFloatingAddButton();\n      return;\n    }\n\n    const rect = range.getBoundingClientRect();\n    if (!rect || (rect.width === 0 && rect.height === 0)) {\n      this.hideFloatingAddButton();\n      return;\n    }\n\n    const startAnchor = this.findSelectionAnchor(range.startContainer);\n    const endAnchor = this.findSelectionAnchor(range.endContainer);\n    if (!startAnchor || !endAnchor) {\n      this.hideFloatingAddButton();\n      return;\n    }\n\n    const startLineStr = startAnchor?.dataset.mrsfStartLine ?? startAnchor?.dataset.mrsfLine;\n    const endLineStr = endAnchor?.dataset.mrsfEndLine ?? endAnchor?.dataset.mrsfLine ?? startLineStr;\n    const startLine = startLineStr ? parseInt(startLineStr, 10) : null;\n    const endLine = endLineStr ? parseInt(endLineStr, 10) : startLine;\n\n    const startColumn = range.startContainer.nodeType === Node.TEXT_NODE\n      ? range.startOffset : null;\n    const endColumn = range.endContainer.nodeType === Node.TEXT_NODE\n      ? range.endOffset : null;\n\n    this.showFloatingAddButton(startLine, endLine, startColumn, endColumn, rect, text);\n  }\n\n  private selectionBelongsToContainer(range: Range): boolean {\n    return this.container.contains(range.commonAncestorContainer)\n      && this.container.contains(range.startContainer)\n      && this.container.contains(range.endContainer);\n  }\n\n  private findSelectionAnchor(node: Node): HTMLElement | null {\n    const element = node instanceof Element ? node : node.parentElement;\n    const anchor = element?.closest<HTMLElement>(\"[data-mrsf-line]\") ?? null;\n    return anchor && this.container.contains(anchor) ? anchor : null;\n  }\n\n  private ensureFloatingAddButton(): HTMLButtonElement {\n    if (this.floatingAddButton) return this.floatingAddButton;\n    const btn = document.createElement(\"button\");\n    btn.textContent = \"Add comment\";\n    btn.className = \"mrsf-add-inline-button\";\n    btn.dataset.mrsfAction = \"add\";\n    btn.style.display = \"none\";\n    btn.style.position = \"absolute\";\n    btn.style.zIndex = \"1200\";\n    this.container.appendChild(btn);\n    this.floatingAddButton = btn;\n    return btn;\n  }\n\n  private hideFloatingAddButton(): void {\n    if (!this.floatingAddButton) return;\n    this.floatingAddButton.style.display = \"none\";\n    this.floatingAddButton.dataset.mrsfLine = \"\";\n    this.floatingAddButton.dataset.mrsfStartLine = \"\";\n    this.floatingAddButton.dataset.mrsfEndLine = \"\";\n    this.lastSelectionText = null;\n  }\n\n  private showFloatingAddButton(\n    startLine: number | null,\n    endLine: number | null,\n    startColumn: number | null,\n    endColumn: number | null,\n    rect: DOMRect,\n    selectionText: string,\n  ): void {\n    const btn = this.ensureFloatingAddButton();\n    if (startLine != null) {\n      btn.dataset.mrsfLine = String(startLine);\n      btn.dataset.mrsfStartLine = String(startLine);\n      btn.dataset.mrsfEndLine = String(endLine ?? startLine);\n    } else {\n      delete btn.dataset.mrsfLine;\n      delete btn.dataset.mrsfStartLine;\n      delete btn.dataset.mrsfEndLine;\n    }\n    if (startColumn != null) {\n      btn.dataset.mrsfStartColumn = String(startColumn);\n    } else {\n      delete btn.dataset.mrsfStartColumn;\n    }\n    if (endColumn != null) {\n      btn.dataset.mrsfEndColumn = String(endColumn);\n    } else {\n      delete btn.dataset.mrsfEndColumn;\n    }\n    this.lastSelectionText = selectionText;\n\n    const margin = 6;\n    const containerRect = this.container.getBoundingClientRect();\n    btn.style.visibility = \"hidden\";\n    btn.style.display = \"block\";\n    const width = btn.offsetWidth || 0;\n    const height = btn.offsetHeight || 0;\n\n    const minTop = this.container.scrollTop;\n    const maxTop = Math.max(minTop, minTop + this.container.clientHeight - height);\n    const minLeft = this.container.scrollLeft;\n    const maxLeft = Math.max(minLeft, minLeft + this.container.clientWidth - width);\n\n    const preferredTop = rect.top - containerRect.top + this.container.scrollTop - height - margin;\n    const fallbackTop = rect.bottom - containerRect.top + this.container.scrollTop + margin;\n    const unclampedTop = preferredTop < minTop ? fallbackTop : preferredTop;\n    const unclampedLeft = rect.left - containerRect.left + this.container.scrollLeft;\n\n    const top = Math.min(Math.max(unclampedTop, minTop), maxTop);\n    const left = Math.min(Math.max(unclampedLeft, minLeft), maxLeft);\n\n    btn.style.top = `${top}px`;\n    btn.style.left = `${left}px`;\n    btn.style.visibility = \"visible\";\n  }\n\n  // \u2500\u2500 Dialog: form (add/edit/reply) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  private injectStyles(): void {\n    if (this.styleInjected) return;\n    const css = `\n.mrsf-overlay { position: fixed; inset: 0; background: var(--mrsf-dialog-backdrop, rgba(15, 23, 42, 0.28)); z-index: 2000; display: flex; align-items: center; justify-content: center; padding: 12px; }\n.mrsf-dialog { background: var(--mrsf-dialog-bg, var(--mrsf-tooltip-bg, #0f172a)); color: var(--mrsf-dialog-fg, var(--mrsf-tooltip-fg, #e5eefb)); border: 1px solid var(--mrsf-dialog-border, var(--mrsf-tooltip-border, rgba(148, 163, 184, 0.35))); border-radius: 10px; width: min(420px, calc(100vw - 24px)); box-shadow: 0 18px 48px rgba(15, 23, 42, 0.24); font-family: var(--mrsf-font-family, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif); font-size: 13px; overflow: hidden; }\n.mrsf-dialog header { padding: 10px 12px; font-weight: 600; line-height: 1.35; border-bottom: 1px solid var(--mrsf-dialog-border, var(--mrsf-tooltip-border, rgba(148, 163, 184, 0.35))); }\n.mrsf-dialog form { padding: 12px; display: flex; flex-direction: column; gap: 10px; }\n.mrsf-dialog-body { padding: 12px; line-height: 1.45; }\n.mrsf-field { display: flex; flex-direction: column; gap: 4px; }\n.mrsf-field label { font-size: 12px; color: var(--mrsf-dialog-muted, color-mix(in srgb, var(--mrsf-dialog-fg, var(--mrsf-tooltip-fg, #e5eefb)) 72%, transparent)); }\n.mrsf-field input, .mrsf-field select, .mrsf-field textarea, .mrsf-field pre { background: var(--mrsf-field-bg, color-mix(in srgb, var(--mrsf-dialog-bg, var(--mrsf-tooltip-bg, #0f172a)) 88%, white)); color: var(--mrsf-dialog-fg, var(--mrsf-tooltip-fg, #e5eefb)); border: 1px solid var(--mrsf-dialog-border, var(--mrsf-tooltip-border, rgba(148, 163, 184, 0.35))); border-radius: 6px; padding: 7px 9px; font-size: 12px; line-height: 1.45; }\n.mrsf-field textarea { min-height: 76px; resize: vertical; }\n.mrsf-field select { min-height: 34px; }\n.mrsf-field pre { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }\n.mrsf-field input:focus, .mrsf-field select:focus, .mrsf-field textarea:focus { outline: 2px solid color-mix(in srgb, var(--mrsf-accent, #2563eb) 38%, transparent); outline-offset: 1px; }\n.mrsf-actions-row { display: flex; justify-content: flex-end; gap: 8px; margin-top: 0; padding: 10px 12px 12px; border-top: 1px solid var(--mrsf-dialog-border, var(--mrsf-tooltip-border, rgba(148, 163, 184, 0.35))); }\n.mrsf-btn { padding: 5px 10px; border-radius: 999px; border: 1px solid var(--mrsf-dialog-border, var(--mrsf-tooltip-border, rgba(148, 163, 184, 0.35))); background: var(--mrsf-button-bg, color-mix(in srgb, var(--mrsf-dialog-bg, var(--mrsf-tooltip-bg, #0f172a)) 82%, white)); color: var(--mrsf-dialog-fg, var(--mrsf-tooltip-fg, #e5eefb)); cursor: pointer; font: inherit; line-height: 1.2; }\n.mrsf-btn-primary { background: var(--mrsf-button-primary-bg, var(--mrsf-accent, #2563eb)); border-color: var(--mrsf-button-primary-bg, var(--mrsf-accent, #2563eb)); color: #fff; }\n.mrsf-helper { font-size: 11px; color: var(--mrsf-dialog-muted, color-mix(in srgb, var(--mrsf-dialog-fg, var(--mrsf-tooltip-fg, #e5eefb)) 72%, transparent)); }\n`;\n    const style = document.createElement(\"style\");\n    style.textContent = css;\n    document.head.appendChild(style);\n    this.styleInjected = true;\n  }\n\n  private closeOverlay(): void {\n    if (this.overlayEl?.parentElement) {\n      this.overlayEl.parentElement.removeChild(this.overlayEl);\n    }\n    this.overlayEl = null;\n  }\n\n  private openForm(action: \"add\" | \"edit\" | \"reply\", detail: MrsfActionDetail): void {\n    if ((window as any).mrsfDisableBuiltinUi) return;\n    this.injectStyles();\n    this.closeOverlay();\n\n    const sourceComment = action === \"edit\" ? this.findCommentById(detail.commentId) : null;\n    const selText = detail.selectionText ?? sourceComment?.selected_text ?? \"\";\n    const line = detail.line ?? detail.start_line ?? sourceComment?.line ?? null;\n    const endLine = detail.end_line ?? detail.line ?? sourceComment?.end_line ?? sourceComment?.line ?? null;\n    const startCol = detail.start_column ?? sourceComment?.start_column ?? null;\n    const endCol = detail.end_column ?? sourceComment?.end_column ?? null;\n\n    const overlay = document.createElement(\"div\");\n    overlay.className = \"mrsf-overlay\";\n    this.applyThemeVariables(overlay);\n\n    const dialog = document.createElement(\"div\");\n    dialog.className = \"mrsf-dialog\";\n\n    const header = document.createElement(\"header\");\n    header.textContent =\n      action === \"add\" ? \"Add comment\" : action === \"edit\" ? \"Edit comment\" : \"Reply\";\n    dialog.appendChild(header);\n\n    const form = document.createElement(\"form\");\n\n    const field = (labelText: string, inputEl: HTMLElement, helper?: string) => {\n      const wrap = document.createElement(\"div\");\n      wrap.className = \"mrsf-field\";\n      const label = document.createElement(\"label\");\n      label.textContent = labelText;\n      wrap.appendChild(label);\n      wrap.appendChild(inputEl);\n      if (helper) {\n        const h = document.createElement(\"div\");\n        h.className = \"mrsf-helper\";\n        h.textContent = helper;\n        wrap.appendChild(h);\n      }\n      form.appendChild(wrap);\n    };\n\n    const textArea = document.createElement(\"textarea\");\n    textArea.name = \"text\";\n    textArea.required = true;\n    textArea.value = action === \"edit\" ? (sourceComment?.text ?? \"\") : \"\";\n    field(\"Comment text\", textArea);\n\n    const typeSelect = document.createElement(\"select\");\n    typeSelect.name = \"type\";\n    [\"\", \"suggestion\", \"issue\", \"question\", \"accuracy\", \"style\", \"clarity\"].forEach((t) => {\n      const opt = document.createElement(\"option\");\n      opt.value = t;\n      opt.textContent = t || \"(none)\";\n      typeSelect.appendChild(opt);\n    });\n    typeSelect.value = action === \"edit\" ? (sourceComment?.type ?? \"\") : \"\";\n    field(\"Type\", typeSelect, \"Optional\");\n\n    const severitySelect = document.createElement(\"select\");\n    severitySelect.name = \"severity\";\n    [\"\", \"low\", \"medium\", \"high\"].forEach((s) => {\n      const opt = document.createElement(\"option\");\n      opt.value = s;\n      opt.textContent = s || \"(none)\";\n      severitySelect.appendChild(opt);\n    });\n    severitySelect.value = action === \"edit\" ? (sourceComment?.severity ?? \"\") : \"\";\n    field(\"Severity\", severitySelect, \"Optional\");\n\n    if (selText) {\n      const pre = document.createElement(\"pre\");\n      pre.textContent = selText;\n      field(\"Selected text\", pre as unknown as HTMLElement, \"Captured automatically\");\n    }\n\n    const actions = document.createElement(\"div\");\n    actions.className = \"mrsf-actions-row\";\n\n    const cancelBtn = document.createElement(\"button\");\n    cancelBtn.type = \"button\";\n    cancelBtn.className = \"mrsf-btn\";\n    cancelBtn.textContent = \"Cancel\";\n    cancelBtn.addEventListener(\"click\", () => this.closeOverlay());\n    actions.appendChild(cancelBtn);\n\n    const submitBtn = document.createElement(\"button\");\n    submitBtn.type = \"submit\";\n    submitBtn.className = \"mrsf-btn mrsf-btn-primary\";\n    submitBtn.textContent = action === \"add\" ? \"Add\" : action === \"reply\" ? \"Reply\" : \"Save\";\n    actions.appendChild(submitBtn);\n\n    form.appendChild(actions);\n\n    form.addEventListener(\"submit\", (ev) => {\n      ev.preventDefault();\n      const detailOut: MrsfSubmitDetail = {\n        action,\n        commentId: detail.commentId,\n        text: textArea.value.trim(),\n        type: typeSelect.value || null,\n        severity: (severitySelect.value as MrsfSubmitDetail[\"severity\"]) || null,\n        line,\n        end_line: endLine,\n        start_column: startCol,\n        end_column: endCol,\n        selection_text: selText || null,\n      };\n      document.dispatchEvent(new CustomEvent(\"mrsf:submit\", { detail: detailOut, bubbles: true }));\n      this.closeOverlay();\n    });\n\n    dialog.appendChild(form);\n    overlay.appendChild(dialog);\n    overlay.addEventListener(\"click\", (e) => {\n      if (e.target === overlay) this.closeOverlay();\n    });\n\n    document.body.appendChild(overlay);\n    this.overlayEl = overlay;\n  }\n\n  // \u2500\u2500 Dialog: confirm (resolve / unresolve / delete) \u2500\u2500\u2500\u2500\u2500\u2500\n\n  private openConfirm(action: \"resolve\" | \"unresolve\" | \"delete\", detail: MrsfActionDetail): void {\n    if ((window as any).mrsfDisableBuiltinUi) return;\n    this.injectStyles();\n    this.closeOverlay();\n\n    const overlay = document.createElement(\"div\");\n    overlay.className = \"mrsf-overlay\";\n    this.applyThemeVariables(overlay);\n\n    const dialog = document.createElement(\"div\");\n    dialog.className = \"mrsf-dialog\";\n\n    const header = document.createElement(\"header\");\n    header.textContent = action === \"delete\" ? \"Delete comment\" : \"Change status\";\n    dialog.appendChild(header);\n\n    const body = document.createElement(\"div\");\n    body.className = \"mrsf-dialog-body\";\n    body.textContent =\n      action === \"delete\"\n        ? \"Delete this comment?\"\n        : action === \"resolve\"\n          ? \"Mark this comment as resolved?\"\n          : \"Mark this comment as unresolved?\";\n    dialog.appendChild(body);\n\n    const actions = document.createElement(\"div\");\n    actions.className = \"mrsf-actions-row\";\n\n    const cancelBtn = document.createElement(\"button\");\n    cancelBtn.type = \"button\";\n    cancelBtn.className = \"mrsf-btn\";\n    cancelBtn.textContent = \"Cancel\";\n    cancelBtn.addEventListener(\"click\", () => this.closeOverlay());\n    actions.appendChild(cancelBtn);\n\n    const confirmBtn = document.createElement(\"button\");\n    confirmBtn.type = \"button\";\n    confirmBtn.className = \"mrsf-btn mrsf-btn-primary\";\n    confirmBtn.textContent = action === \"delete\" ? \"Delete\" : \"Confirm\";\n    confirmBtn.addEventListener(\"click\", () => {\n      const detailOut: MrsfSubmitDetail = {\n        action,\n        commentId: detail.commentId,\n        text: \"\",\n        type: null,\n        severity: null,\n        line: detail.line,\n        end_line: detail.end_line ?? detail.line ?? null,\n        start_column: detail.start_column ?? null,\n        end_column: detail.end_column ?? null,\n        selection_text: detail.selectionText ?? null,\n      };\n      document.dispatchEvent(new CustomEvent(\"mrsf:submit\", { detail: detailOut, bubbles: true }));\n      this.closeOverlay();\n    });\n    actions.appendChild(confirmBtn);\n\n    dialog.appendChild(actions);\n\n    overlay.appendChild(dialog);\n    overlay.addEventListener(\"click\", (e) => {\n      if (e.target === overlay) this.closeOverlay();\n    });\n\n    document.body.appendChild(overlay);\n    this.overlayEl = overlay;\n  }\n}\n\n// \u2500\u2500 Auto-init convenience \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Scan for containers with [data-mrsf-controller] and auto-init.\n\nconst controllerRegistry = new Set<MrsfController>();\nlet autoInitDone = false;\n\nexport function refreshAll(): void {\n  for (const controller of controllerRegistry) {\n    controller.refresh();\n  }\n}\n\nexport function autoInit(): void {\n  if (autoInitDone) return;\n  autoInitDone = true;\n\n  const containers = document.querySelectorAll<HTMLElement>(\"[data-mrsf-controller]\");\n  for (const container of containers) {\n    const pos = container.dataset.mrsfGutterPosition as MrsfControllerOptions[\"gutterPosition\"] | undefined;\n    const interactive = container.dataset.mrsfInteractive === \"true\";\n    new MrsfController(container, { gutterPosition: pos ?? \"right\", interactive });\n  }\n}\n\n// Auto-init on DOMContentLoaded if in browser context\nif (typeof document !== \"undefined\") {\n  if (document.readyState === \"loading\") {\n    document.addEventListener(\"DOMContentLoaded\", autoInit);\n  } else {\n    autoInit();\n  }\n}\n", "/* ---------------------------------------------------------------\n * AUTO-GENERATED \u2014 DO NOT EDIT\n *\n * Source: plugins/shared/src/gutter.ts\n * Run `node plugins/sync-types.mjs` to regenerate.\n * --------------------------------------------------------------- */\n\nexport type MrsfResolvedState = \"open\" | \"resolved\" | \"mixed\";\n\nexport interface MrsfGutterBadgePresentation {\n  icon: string;\n  countText: string;\n  label: string;\n  title: string;\n  ariaLabel: string;\n  className?: string;\n  attributes?: Record<string, string>;\n}\n\nexport interface MrsfGutterBadgeContext {\n  line: number;\n  commentCount: number;\n  threadCount: number;\n  resolvedState: MrsfResolvedState;\n  highestSeverity: string | null;\n  isActive: boolean;\n}\n\nexport interface MrsfGutterBadgeRenderContext extends MrsfGutterBadgeContext {\n  defaultPresentation: MrsfGutterBadgePresentation;\n}\n\nexport interface MrsfGutterAddButtonPresentation {\n  label: string;\n  title: string;\n  ariaLabel: string;\n  className?: string;\n  attributes?: Record<string, string>;\n}\n\nexport interface MrsfGutterAddButtonContext {\n  line: number;\n  isActive: boolean;\n}\n\nexport interface MrsfGutterAddButtonRenderContext extends MrsfGutterAddButtonContext {\n  defaultPresentation: MrsfGutterAddButtonPresentation;\n}\n\nexport interface MrsfGutterRenderers {\n  badge?: (\n    context: MrsfGutterBadgeRenderContext,\n  ) => Partial<MrsfGutterBadgePresentation> | null | undefined;\n  addButton?: (\n    context: MrsfGutterAddButtonRenderContext,\n  ) => Partial<MrsfGutterAddButtonPresentation> | null | undefined;\n}\n\nexport interface MrsfBadgeSource {\n  commentCount: number;\n  threadCount: number;\n  resolvedState: MrsfResolvedState;\n}\n\nexport function formatMrsfCount(count: number, max = 9): string {\n  return count > max ? `${max}+` : String(count);\n}\n\nexport function createMrsfGutterBadgePresentation(\n  context: MrsfGutterBadgeContext,\n): MrsfGutterBadgePresentation {\n  const icon = context.resolvedState === \"resolved\" ? \"\u2713\" : \"\uD83D\uDCAC\";\n  const countText = formatMrsfCount(context.commentCount);\n  const label = `${icon} ${countText}`;\n  const threadSummary = context.threadCount === 1 ? \"1 thread\" : `${context.threadCount} threads`;\n  const commentSummary = context.commentCount === 1 ? \"1 comment\" : `${context.commentCount} comments`;\n\n  return {\n    icon,\n    countText,\n    label,\n    title: `${threadSummary}, ${commentSummary}`,\n    ariaLabel: `${label} on line ${context.line}`,\n  };\n}\n\nexport function createMrsfGutterAddButtonPresentation(\n  _context: MrsfGutterAddButtonContext,\n): MrsfGutterAddButtonPresentation {\n  return {\n    label: \"Add\",\n    title: \"Add comment thread\",\n    ariaLabel: \"Add comment thread\",\n  };\n}\n\nexport function resolveMrsfGutterBadgePresentation(\n  context: MrsfGutterBadgeContext,\n  renderer?: MrsfGutterRenderers[\"badge\"],\n): MrsfGutterBadgePresentation {\n  const defaultPresentation = createMrsfGutterBadgePresentation(context);\n  const override = renderer?.({\n    ...context,\n    defaultPresentation,\n  });\n\n  return {\n    ...defaultPresentation,\n    ...override,\n    attributes: {\n      ...(defaultPresentation.attributes ?? {}),\n      ...(override?.attributes ?? {}),\n    },\n  };\n}\n\nexport function resolveMrsfGutterAddButtonPresentation(\n  context: MrsfGutterAddButtonContext,\n  renderer?: MrsfGutterRenderers[\"addButton\"],\n): MrsfGutterAddButtonPresentation {\n  const defaultPresentation = createMrsfGutterAddButtonPresentation(context);\n  const override = renderer?.({\n    ...context,\n    defaultPresentation,\n  });\n\n  return {\n    ...defaultPresentation,\n    ...override,\n    attributes: {\n      ...(defaultPresentation.attributes ?? {}),\n      ...(override?.attributes ?? {}),\n    },\n  };\n}", "/* ---------------------------------------------------------------\n * AUTO-GENERATED \u2014 DO NOT EDIT\n *\n * Source: plugins/shared/src/html.ts\n * Run `node plugins/sync-types.mjs` to regenerate.\n * --------------------------------------------------------------- */\n\n/**\n * Shared HTML rendering helpers for MRSF rendering plugins.\n *\n * These produce the HTML strings used in tooltips, badges, and comment\n * rendering. Both the markdown-it and rehype plugins use these functions\n * to ensure identical visual output.\n */\n\nimport type { CommentThread, SlimComment } from \"./types.js\";\n\nexport function escapeHtml(str: string): string {\n  return str\n    .replace(/&/g, \"&amp;\")\n    .replace(/</g, \"&lt;\")\n    .replace(/>/g, \"&gt;\")\n    .replace(/\"/g, \"&quot;\");\n}\n\nexport function formatTime(iso: string | null): string {\n  if (!iso) return \"\";\n  try {\n    const d = new Date(iso);\n    return d.toLocaleDateString(undefined, {\n      year: \"numeric\",\n      month: \"short\",\n      day: \"numeric\",\n    });\n  } catch {\n    return \"\";\n  }\n}\n\nexport function renderCommentHtml(\n  comment: SlimComment,\n  isReply: boolean,\n  interactive: boolean,\n): string {\n  const resolvedClass = comment.resolved ? \" mrsf-resolved\" : \"\";\n  const replyClass = isReply ? \" mrsf-reply\" : \"\";\n  let html = `<div class=\"mrsf-comment${resolvedClass}${replyClass}\" data-mrsf-comment-id=\"${escapeHtml(comment.id)}\">`;\n\n  // Header\n  html += `<div class=\"mrsf-comment-header\">`;\n  html += `<span class=\"mrsf-author\">${escapeHtml(comment.author)}</span>`;\n  if (comment.timestamp) {\n    html += `<span class=\"mrsf-date\">${escapeHtml(formatTime(comment.timestamp))}</span>`;\n  }\n  if (comment.severity) {\n    html += `<span class=\"mrsf-severity mrsf-severity-${escapeHtml(comment.severity)}\">${escapeHtml(comment.severity)}</span>`;\n  }\n  if (comment.type) {\n    html += `<span class=\"mrsf-type\">${escapeHtml(comment.type)}</span>`;\n  }\n  if (comment.resolved) {\n    html += `<span class=\"mrsf-resolved-badge\">\u2713 resolved</span>`;\n  }\n  html += `</div>`;\n\n  // Selected text quote (collapsible)\n  if (comment.selected_text) {\n    html += `<details class=\"mrsf-selected-text\"><summary class=\"mrsf-selected-text-summary\">${escapeHtml(comment.selected_text)}</summary><div class=\"mrsf-selected-text-full\">${escapeHtml(comment.selected_text)}</div></details>`;\n  }\n\n  // Body\n  html += `<div class=\"mrsf-comment-body\">${escapeHtml(comment.text)}</div>`;\n\n  // Action buttons (interactive mode)\n  if (interactive) {\n    const line = comment.line != null ? String(comment.line) : \"\";\n    html += `<div class=\"mrsf-actions\">`;\n    if (comment.resolved) {\n      html += `<button class=\"mrsf-action-btn\" data-mrsf-action=\"unresolve\" data-mrsf-comment-id=\"${escapeHtml(comment.id)}\" data-mrsf-line=\"${line}\">Unresolve</button>`;\n    } else {\n      html += `<button class=\"mrsf-action-btn\" data-mrsf-action=\"resolve\" data-mrsf-comment-id=\"${escapeHtml(comment.id)}\" data-mrsf-line=\"${line}\">Resolve</button>`;\n    }\n    html += `<button class=\"mrsf-action-btn\" data-mrsf-action=\"reply\" data-mrsf-comment-id=\"${escapeHtml(comment.id)}\" data-mrsf-line=\"${line}\">Reply</button>`;\n    html += `<button class=\"mrsf-action-btn\" data-mrsf-action=\"edit\" data-mrsf-comment-id=\"${escapeHtml(comment.id)}\" data-mrsf-line=\"${line}\">Edit</button>`;\n    html += `<button class=\"mrsf-action-btn mrsf-action-danger\" data-mrsf-action=\"delete\" data-mrsf-comment-id=\"${escapeHtml(comment.id)}\" data-mrsf-line=\"${line}\">Delete</button>`;\n    html += `</div>`;\n  }\n\n  html += `</div>`;\n  return html;\n}\n\nexport function renderThreadHtml(thread: CommentThread, interactive: boolean): string {\n  let html = `<div class=\"mrsf-thread\">`;\n  html += renderCommentHtml(thread.comment, false, interactive);\n  if (thread.replies.length > 0) {\n    html += `<div class=\"mrsf-replies\">`;\n    for (const reply of thread.replies) {\n      html += renderCommentHtml(reply, true, interactive);\n    }\n    html += `</div>`;\n  }\n  html += `</div>`;\n  return html;\n}\n"],
  "mappings": "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",
  "names": []
}
