@tabula-md/tabula 0.2.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.
Files changed (122) hide show
  1. package/README.md +106 -0
  2. package/dist/activeDocumentRuntime.d.ts +50 -0
  3. package/dist/activeDocumentRuntime.d.ts.map +1 -0
  4. package/dist/collabCollaborators.d.ts +16 -0
  5. package/dist/collabCollaborators.d.ts.map +1 -0
  6. package/dist/collabConnectionModel.d.ts +11 -0
  7. package/dist/collabConnectionModel.d.ts.map +1 -0
  8. package/dist/collabSessionState.d.ts +24 -0
  9. package/dist/collabSessionState.d.ts.map +1 -0
  10. package/dist/collaboration.d.ts +8 -0
  11. package/dist/collaboration.d.ts.map +1 -0
  12. package/dist/collaboration.js +78 -0
  13. package/dist/collaboration.js.map +1 -0
  14. package/dist/collaborationPresence.d.ts +7 -0
  15. package/dist/collaborationPresence.d.ts.map +1 -0
  16. package/dist/collaborationTypes.d.ts +27 -0
  17. package/dist/collaborationTypes.d.ts.map +1 -0
  18. package/dist/commentRuntimeModel.d.ts +53 -0
  19. package/dist/commentRuntimeModel.d.ts.map +1 -0
  20. package/dist/data/base64Url.d.ts +3 -0
  21. package/dist/data/base64Url.d.ts.map +1 -0
  22. package/dist/data/encode.d.ts +20 -0
  23. package/dist/data/encode.d.ts.map +1 -0
  24. package/dist/data/encode.js +61 -0
  25. package/dist/data/encode.js.map +1 -0
  26. package/dist/data/encryption.d.ts +20 -0
  27. package/dist/data/encryption.d.ts.map +1 -0
  28. package/dist/data/encryption.js +13 -0
  29. package/dist/data/encryption.js.map +1 -0
  30. package/dist/data/json.d.ts +18 -0
  31. package/dist/data/json.d.ts.map +1 -0
  32. package/dist/data/json.js +18 -0
  33. package/dist/data/json.js.map +1 -0
  34. package/dist/data/restore.d.ts +3 -0
  35. package/dist/data/restore.d.ts.map +1 -0
  36. package/dist/data/restore.js +6 -0
  37. package/dist/data/restore.js.map +1 -0
  38. package/dist/documentBuffer.d.ts +68 -0
  39. package/dist/documentBuffer.d.ts.map +1 -0
  40. package/dist/documentControlsModel.d.ts +58 -0
  41. package/dist/documentControlsModel.d.ts.map +1 -0
  42. package/dist/documentMetrics.d.ts +2 -0
  43. package/dist/documentMetrics.d.ts.map +1 -0
  44. package/dist/documentPrimitives.d.ts +9 -0
  45. package/dist/documentPrimitives.d.ts.map +1 -0
  46. package/dist/documentSurfaceModel.d.ts +44 -0
  47. package/dist/documentSurfaceModel.d.ts.map +1 -0
  48. package/dist/encryption-B0xRVvlF.js +82 -0
  49. package/dist/encryption-B0xRVvlF.js.map +1 -0
  50. package/dist/index.d.ts +85 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +2474 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/jsonShareLinkModel.d.ts +36 -0
  55. package/dist/jsonShareLinkModel.d.ts.map +1 -0
  56. package/dist/lineSurfaceModel.d.ts +73 -0
  57. package/dist/lineSurfaceModel.d.ts.map +1 -0
  58. package/dist/markdown/editing.d.ts +12 -0
  59. package/dist/markdown/editing.d.ts.map +1 -0
  60. package/dist/markdown/links.d.ts +23 -0
  61. package/dist/markdown/links.d.ts.map +1 -0
  62. package/dist/markdown/tasks.d.ts +22 -0
  63. package/dist/markdown/tasks.d.ts.map +1 -0
  64. package/dist/markdown.d.ts +25 -0
  65. package/dist/markdown.d.ts.map +1 -0
  66. package/dist/markdownEditing.d.ts +2 -0
  67. package/dist/markdownEditing.d.ts.map +1 -0
  68. package/dist/markdownFormatting.d.ts +11 -0
  69. package/dist/markdownFormatting.d.ts.map +1 -0
  70. package/dist/previewBlockModel.d.ts +66 -0
  71. package/dist/previewBlockModel.d.ts.map +1 -0
  72. package/dist/productPerformancePolicy.d.ts +14 -0
  73. package/dist/productPerformancePolicy.d.ts.map +1 -0
  74. package/dist/rightPanelCommentViewModel.d.ts +39 -0
  75. package/dist/rightPanelCommentViewModel.d.ts.map +1 -0
  76. package/dist/room/envelope.d.ts +27 -0
  77. package/dist/room/envelope.d.ts.map +1 -0
  78. package/dist/room/envelope.js +38 -0
  79. package/dist/room/envelope.js.map +1 -0
  80. package/dist/roomBinaryProtocol.d.ts +43 -0
  81. package/dist/roomBinaryProtocol.d.ts.map +1 -0
  82. package/dist/roomCollaboration.d.ts +39 -0
  83. package/dist/roomCollaboration.d.ts.map +1 -0
  84. package/dist/roomProtocol.d.ts +11 -0
  85. package/dist/roomProtocol.d.ts.map +1 -0
  86. package/dist/roomShareLinkModel.d.ts +20 -0
  87. package/dist/roomShareLinkModel.d.ts.map +1 -0
  88. package/dist/shareLinkViewModel.d.ts +8 -0
  89. package/dist/shareLinkViewModel.d.ts.map +1 -0
  90. package/dist/shareSnapshotPayload-CsTw9sRq.js +209 -0
  91. package/dist/shareSnapshotPayload-CsTw9sRq.js.map +1 -0
  92. package/dist/shareSnapshotPayload.d.ts +75 -0
  93. package/dist/shareSnapshotPayload.d.ts.map +1 -0
  94. package/dist/shareViewModel.d.ts +33 -0
  95. package/dist/shareViewModel.d.ts.map +1 -0
  96. package/dist/sourceScrollTransfer.d.ts +54 -0
  97. package/dist/sourceScrollTransfer.d.ts.map +1 -0
  98. package/dist/statusBarViewModel.d.ts +13 -0
  99. package/dist/statusBarViewModel.d.ts.map +1 -0
  100. package/dist/textPatches.d.ts +16 -0
  101. package/dist/textPatches.d.ts.map +1 -0
  102. package/dist/workspaceFileRuntimeModel.d.ts +11 -0
  103. package/dist/workspaceFileRuntimeModel.d.ts.map +1 -0
  104. package/dist/workspaceIoModel.d.ts +37 -0
  105. package/dist/workspaceIoModel.d.ts.map +1 -0
  106. package/dist/workspaceModel.d.ts +112 -0
  107. package/dist/workspaceModel.d.ts.map +1 -0
  108. package/dist/workspaceRoomCheckpoint.d.ts +46 -0
  109. package/dist/workspaceRoomCheckpoint.d.ts.map +1 -0
  110. package/dist/workspaceRoomCrdt.d.ts +55 -0
  111. package/dist/workspaceRoomCrdt.d.ts.map +1 -0
  112. package/dist/workspaceRoomModel-CO-5ZOpS.js +78 -0
  113. package/dist/workspaceRoomModel-CO-5ZOpS.js.map +1 -0
  114. package/dist/workspaceRoomModel.d.ts +69 -0
  115. package/dist/workspaceRoomModel.d.ts.map +1 -0
  116. package/dist/workspaceRoomSync-B3niC7cn.js +758 -0
  117. package/dist/workspaceRoomSync-B3niC7cn.js.map +1 -0
  118. package/dist/workspaceRoomSync.d.ts +98 -0
  119. package/dist/workspaceRoomSync.d.ts.map +1 -0
  120. package/dist/workspaceViewModel.d.ts +13 -0
  121. package/dist/workspaceViewModel.d.ts.map +1 -0
  122. package/package.json +82 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/documentPrimitives.ts","../src/markdown.ts","../src/documentMetrics.ts","../src/textPatches.ts","../src/previewBlockModel.ts","../src/activeDocumentRuntime.ts","../src/collabConnectionModel.ts","../src/collabCollaborators.ts","../src/collabSessionState.ts","../src/collaborationPresence.ts","../src/lineSurfaceModel.ts","../src/commentRuntimeModel.ts","../src/documentControlsModel.ts","../src/documentSurfaceModel.ts","../src/documentBuffer.ts","../src/jsonShareLinkModel.ts","../src/sourceScrollTransfer.ts","../src/productPerformancePolicy.ts","../src/markdown/editing.ts","../src/markdown/links.ts","../src/markdown/tasks.ts","../src/markdownFormatting.ts","../src/rightPanelCommentViewModel.ts","../src/roomShareLinkModel.ts","../src/shareLinkViewModel.ts","../src/shareViewModel.ts","../src/statusBarViewModel.ts","../src/workspaceFileRuntimeModel.ts","../src/workspaceModel.ts","../src/workspaceIoModel.ts","../src/workspaceViewModel.ts"],"sourcesContent":["export const READING_WIDTHS = [\"narrow\", \"standard\", \"wide\"] as const;\nexport const FILE_VIEW_MODES = [\"edit\", \"split\", \"preview\"] as const;\n\nexport type ReadingWidth = (typeof READING_WIDTHS)[number];\nexport type FileViewMode = (typeof FILE_VIEW_MODES)[number];\n\nexport const DEFAULT_SPLIT_EDITOR_RATIO = 0.5;\nexport const MIN_SPLIT_EDITOR_RATIO = 0.28;\nexport const MAX_SPLIT_EDITOR_RATIO = 0.72;\n\nexport const clampSplitEditorRatio = (value: unknown) => {\n const numericValue =\n typeof value === \"number\" && Number.isFinite(value)\n ? value\n : DEFAULT_SPLIT_EDITOR_RATIO;\n\n return Math.min(\n MAX_SPLIT_EDITOR_RATIO,\n Math.max(MIN_SPLIT_EDITOR_RATIO, numericValue),\n );\n};\n","import { isMap, isScalar, parseDocument } from \"yaml\";\n\nexport type ParsedFrontmatter = {\n attributes: Array<{ key: string; value: string }>;\n body: string;\n};\n\nexport type PreviewBody = {\n body: string;\n sourceLineOffset: number;\n};\n\nexport type MarkdownHeading = {\n depth: number;\n text: string;\n lineIndex: number;\n sourceLineIndex: number;\n};\n\nconst frontmatterOpeningDelimiterPattern = /^---\\s*$/;\nconst frontmatterClosingDelimiterPattern = /^(?:---|\\.\\.\\.)\\s*$/;\n\nconst getLineBreakLength = (text: string, lineBreakIndex: number) =>\n text.startsWith(\"\\r\\n\", lineBreakIndex) ? 2 : 1;\n\nconst formatYamlMetadataValue = (value: unknown): string => {\n if (value === null || typeof value === \"undefined\") {\n return \"\";\n }\n\n if (Array.isArray(value)) {\n return value.map(formatYamlMetadataValue).join(\", \");\n }\n\n if (typeof value === \"object\") {\n return Object.entries(value)\n .map(([key, nestedValue]) => `${key}: ${formatYamlMetadataValue(nestedValue)}`)\n .join(\"\\n\");\n }\n\n return String(value).replace(/\\n$/, \"\");\n};\n\nconst getFrontmatterBlock = (markdown: string) => {\n const firstLineBreakIndex = markdown.search(/\\r?\\n/);\n if (firstLineBreakIndex === -1) {\n return null;\n }\n\n const firstLine = markdown.slice(0, firstLineBreakIndex);\n if (!frontmatterOpeningDelimiterPattern.test(firstLine)) {\n return null;\n }\n\n const rawStart = firstLineBreakIndex + getLineBreakLength(markdown, firstLineBreakIndex);\n let cursor = rawStart;\n\n while (cursor < markdown.length) {\n const nextLineBreakIndex = markdown.indexOf(\"\\n\", cursor);\n const lineEnd =\n nextLineBreakIndex === -1\n ? markdown.length\n : markdown[nextLineBreakIndex - 1] === \"\\r\"\n ? nextLineBreakIndex - 1\n : nextLineBreakIndex;\n const line = markdown.slice(cursor, lineEnd);\n\n if (frontmatterClosingDelimiterPattern.test(line)) {\n const bodyStart = nextLineBreakIndex === -1 ? markdown.length : nextLineBreakIndex + 1;\n return {\n rawFrontmatter: markdown.slice(rawStart, cursor).replace(/\\r?\\n$/, \"\"),\n body: markdown.slice(bodyStart),\n };\n }\n\n if (nextLineBreakIndex === -1) {\n break;\n }\n cursor = nextLineBreakIndex + 1;\n }\n\n return null;\n};\n\nexport const getPreviewBody = (body: string): PreviewBody => ({ body, sourceLineOffset: 0 });\n\nexport const parseFrontmatter = (markdown: string): ParsedFrontmatter => {\n const frontmatterBlock = getFrontmatterBlock(markdown);\n if (!frontmatterBlock) {\n return { attributes: [], body: markdown };\n }\n\n const document = parseDocument(frontmatterBlock.rawFrontmatter, { prettyErrors: false });\n if (document.errors.length > 0 || !isMap(document.contents)) {\n return { attributes: [], body: markdown };\n }\n\n const attributes: ParsedFrontmatter[\"attributes\"] = [];\n for (const item of document.contents.items) {\n if (!isScalar(item.key)) {\n return { attributes: [], body: markdown };\n }\n\n const key = formatYamlMetadataValue(item.key.value).trim();\n if (!key) {\n return { attributes: [], body: markdown };\n }\n\n attributes.push({\n key,\n value: formatYamlMetadataValue(item.value?.toJSON()),\n });\n }\n\n return attributes.length > 0 ? { attributes, body: frontmatterBlock.body } : { attributes: [], body: markdown };\n};\n\nexport const getMarkdownDocumentTitle = (markdown: string) => {\n const parsed = parseFrontmatter(markdown);\n const metadataTitle = parsed.attributes\n .find((attribute) => attribute.key.toLowerCase() === \"title\")\n ?.value.trim();\n\n if (metadataTitle) {\n return metadataTitle;\n }\n\n const headingTitle = parsed.body.match(/^#{1,2}\\s+(.+?)\\s*#*\\s*$/m)?.[1]?.trim();\n return headingTitle || \"\";\n};\n\nexport const getOutlineHeadings = (previewBody: PreviewBody): MarkdownHeading[] =>\n previewBody.body\n .split(\"\\n\")\n .map((line, lineIndex) => {\n const match = line.match(/^(#{1,3})\\s+(.+)$/);\n if (!match) {\n return null;\n }\n\n return {\n depth: match[1].length,\n text: match[2].replace(/\\s+#+\\s*$/, \"\").trim(),\n lineIndex,\n sourceLineIndex: lineIndex + previewBody.sourceLineOffset,\n };\n })\n .filter((heading): heading is MarkdownHeading => Boolean(heading?.text));\n\nexport const getOutlineHeadingsFromMarkdown = (markdown: string): MarkdownHeading[] => {\n const headings: MarkdownHeading[] = [];\n let lineIndex = 0;\n let lineStart = 0;\n\n while (lineStart <= markdown.length) {\n const lineBreakIndex = markdown.indexOf(\"\\n\", lineStart);\n const lineEnd =\n lineBreakIndex === -1\n ? markdown.length\n : markdown[lineBreakIndex - 1] === \"\\r\"\n ? lineBreakIndex - 1\n : lineBreakIndex;\n const line = markdown.slice(lineStart, lineEnd);\n const match = line.match(/^(#{1,3})\\s+(.+)$/);\n\n if (match) {\n const text = match[2].replace(/\\s+#+\\s*$/, \"\").trim();\n if (text) {\n headings.push({\n depth: match[1].length,\n text,\n lineIndex,\n sourceLineIndex: lineIndex,\n });\n }\n }\n\n if (lineBreakIndex === -1) {\n break;\n }\n\n lineIndex += 1;\n lineStart = lineBreakIndex + 1;\n }\n\n return headings;\n};\n\nexport const getLineStartOffset = (markdown: string, targetLineIndex: number) => {\n const lines = markdown.split(\"\\n\");\n let offset = 0;\n\n for (let index = 0; index < targetLineIndex; index += 1) {\n offset += (lines[index]?.length ?? 0) + 1;\n }\n\n return offset;\n};\n\nexport const getLineNumberForOffset = (content: string, offset: number) => content.slice(0, offset).split(\"\\n\").length;\n","export const getMarkdownWordCount = (text: string) =>\n text.trim() ? text.trim().split(/\\s+/).length : 0;\n","export type TextPatch = {\n from: number;\n to: number;\n insert: string;\n};\n\nexport type TextChange = {\n docLength?: number;\n lineCount?: number;\n patches: TextPatch[];\n};\n\nconst comparePatchesDescending = (first: TextPatch, second: TextPatch) =>\n second.from - first.from || second.to - first.to;\n\nconst comparePatchesAscending = (first: TextPatch, second: TextPatch) =>\n first.from - second.from || first.to - second.to;\n\nexport const diffTextPatch = (oldText: string, nextText: string): TextPatch => {\n let start = 0;\n while (\n start < oldText.length &&\n start < nextText.length &&\n oldText[start] === nextText[start]\n ) {\n start += 1;\n }\n\n let oldEnd = oldText.length;\n let nextEnd = nextText.length;\n while (\n oldEnd > start &&\n nextEnd > start &&\n oldText[oldEnd - 1] === nextText[nextEnd - 1]\n ) {\n oldEnd -= 1;\n nextEnd -= 1;\n }\n\n return {\n from: start,\n to: oldEnd,\n insert: nextText.slice(start, nextEnd),\n };\n};\n\nexport const normalizeTextPatches = (patches: readonly TextPatch[]) =>\n [...patches].sort(comparePatchesAscending);\n\nexport const areTextPatchesApplicable = (text: string, patches: readonly TextPatch[]) => {\n let previousTo = 0;\n\n for (const patch of normalizeTextPatches(patches)) {\n if (\n !Number.isInteger(patch.from) ||\n !Number.isInteger(patch.to) ||\n patch.from < 0 ||\n patch.to < patch.from ||\n patch.to > text.length ||\n patch.from < previousTo\n ) {\n return false;\n }\n\n previousTo = patch.to;\n }\n\n return true;\n};\n\nexport const applyTextPatches = (text: string, patches: readonly TextPatch[]) => {\n if (!areTextPatchesApplicable(text, patches)) {\n return null;\n }\n\n return [...patches]\n .sort(comparePatchesDescending)\n .reduce(\n (currentText, patch) =>\n `${currentText.slice(0, patch.from)}${patch.insert}${currentText.slice(patch.to)}`,\n text,\n );\n};\n\nexport const getTextPatchesForChange = (\n oldText: string,\n nextText: string,\n preferredPatches?: readonly TextPatch[],\n) => {\n if (preferredPatches?.length) {\n const patchedText = applyTextPatches(oldText, preferredPatches);\n if (patchedText === nextText) {\n return normalizeTextPatches(preferredPatches);\n }\n }\n\n const fallbackPatch = diffTextPatch(oldText, nextText);\n return fallbackPatch.from === fallbackPatch.to && fallbackPatch.insert === \"\" ? [] : [fallbackPatch];\n};\n","import { applyTextPatches, normalizeTextPatches, type TextPatch } from \"./textPatches\";\n\nexport const LARGE_DOCUMENT_CHAR_THRESHOLD = 64_000;\nexport const LARGE_DOCUMENT_LINE_THRESHOLD = 800;\nexport const LARGE_DOCUMENT_WORD_THRESHOLD = 8_000;\nexport const LARGE_DOCUMENT_LONG_LINE_THRESHOLD = 8_000;\nexport const LARGE_DOCUMENT_TABLE_RUN_THRESHOLD = 120;\nexport const LIVE_PREVIEW_CHAR_THRESHOLD = 24_000;\nexport const HEAVY_PREVIEW_TABLE_RUN_THRESHOLD = 16;\nexport const HEAVY_PREVIEW_FENCE_LINE_THRESHOLD = 80;\nexport const HEAVY_PREVIEW_FENCE_CHAR_THRESHOLD = 12_000;\n\nexport type PreviewBlockKind =\n | \"blank\"\n | \"blockquote\"\n | \"fence\"\n | \"heading\"\n | \"html\"\n | \"list\"\n | \"paragraph\"\n | \"table\"\n | \"thematic\";\n\nexport type PreviewBlock = {\n id: string;\n kind: PreviewBlockKind;\n text: string;\n headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n startLine: number;\n endLine: number;\n startOffset: number;\n endOffset: number;\n estimatedTop: number;\n estimatedHeight: number;\n};\n\nexport type PreviewBlockIndex = {\n blocks: PreviewBlock[];\n lineCount: number;\n totalEstimatedHeight: number;\n};\n\nexport type PreviewBlockMeasurements = Readonly<Record<string, number>>;\n\nexport type PreviewWindow = {\n blocks: PreviewBlock[];\n endIndex: number;\n startIndex: number;\n};\n\nexport type PreviewRenderableAnchor = {\n endLine: number;\n rendered: boolean;\n sourceElement?: boolean;\n startLine: number;\n};\n\nexport type PreviewScrollMapAnchor = {\n align: \"end\" | \"preserve-offset\";\n lineNumber: number;\n lineOffsetRatio?: number;\n};\n\nexport type PreviewScrollMapOptions = {\n edgePadding?: number;\n viewportHeight: number;\n};\n\ntype MarkdownLine = {\n text: string;\n startOffset: number;\n endOffset: number;\n};\n\nconst DEFAULT_LINE_HEIGHT = 27;\nconst BLOCK_GAP_HEIGHT = 10;\nconst CODE_LINE_HEIGHT = 24;\nconst HEADING_ESTIMATED_HEIGHT_BY_LEVEL = {\n 1: 49,\n 2: 43,\n 3: 38,\n 4: 33,\n 5: 29,\n 6: 27,\n} as const;\nconst PREVIEW_PARAGRAPH_LINE_CHUNK_SIZE = 40;\nconst PREVIEW_PARAGRAPH_CHAR_CHUNK_SIZE = 4_000;\nconst PREVIEW_PARAGRAPH_ESTIMATED_CHARS_PER_LINE = 92;\n// Measurements are partial while scrolling, so small count-based pads prevent visible gaps from estimate drift.\nconst PREVIEW_WINDOW_MAX_LEADING_OVERSCAN = 240;\nconst PREVIEW_WINDOW_LEADING_BLOCK_PADDING = 0;\nconst PREVIEW_WINDOW_TRAILING_BLOCK_PADDING = 1;\nconst PREVIEW_WINDOW_END_LEADING_BLOCK_PADDING = 4;\nconst PREVIEW_WINDOW_END_TRAILING_BLOCK_PADDING = 4;\nconst PREVIEW_WINDOW_END_SCROLL_RATIO = 0.8;\nconst OPTIMISTIC_INDEX_MAX_CHANGED_LINES = 80;\nconst OPTIMISTIC_INDEX_CONTEXT_BLOCK_COUNT = 1;\n\nconst fenceLinePattern = /^ {0,3}(`{3,}|~{3,})/;\nconst headingLinePattern = /^ {0,3}#{1,6}\\s+\\S/;\nconst thematicLinePattern = /^ {0,3}(?:-{3,}|\\*{3,}|_{3,})\\s*$/;\nconst blockquoteLinePattern = /^ {0,3}>/;\nconst listLinePattern = /^ {0,3}(?:[-+*]|\\d{1,9}[.)])\\s+/;\nconst indentedContinuationPattern = /^(?: {2,}|\\t)\\S/;\nconst tableSeparatorPattern = /^ {0,3}\\|?\\s*:?-{1,}:?\\s*(?:\\|\\s*:?-{1,}:?\\s*)+\\|?\\s*$/;\nconst htmlLinePattern = /^ {0,3}<\\/?[A-Za-z][A-Za-z0-9-]*(?:\\s|>|\\/>)/;\nconst displayMathLinePattern = /^ {0,3}\\$\\$\\s*$/;\nconst heavyFenceLanguagePattern = /^(?:mermaid|mmd|math|tex|latex|katex)$/i;\nconst frontmatterFencePattern = /^---\\s*$/;\nconst yamlKeyLinePattern = /^[A-Za-z0-9_-]+:\\s*/;\nconst footnoteDefinitionLinePattern = /^ {0,3}\\[\\^[^\\]\\n]+]:/;\nconst footnoteReferencePattern = /\\[\\^[^\\]\\n]+]/;\nconst referenceDefinitionLinePattern = /^ {0,3}\\[(?!\\^)([^\\]\\n]+)]:\\s+\\S/;\nconst referenceLinkPattern = /\\[[^\\]\\n]+]\\[[^\\]\\n]*]/;\nconst definitionListLinePattern = /^ {0,3}:\\s+\\S/;\n\nexport const getMarkdownLineCount = (markdown: string) => {\n if (markdown.length === 0) {\n return 1;\n }\n\n let lineCount = 1;\n for (let index = 0; index < markdown.length; index += 1) {\n if (markdown.charCodeAt(index) === 10) {\n lineCount += 1;\n }\n }\n return lineCount;\n};\n\nexport const hasLongMarkdownLine = (\n markdown: string,\n threshold = LARGE_DOCUMENT_LONG_LINE_THRESHOLD,\n) => {\n let currentLineLength = 0;\n\n for (let index = 0; index < markdown.length; index += 1) {\n const characterCode = markdown.charCodeAt(index);\n if (characterCode === 10) {\n if (currentLineLength >= threshold) {\n return true;\n }\n currentLineLength = 0;\n continue;\n }\n\n if (characterCode !== 13) {\n currentLineLength += 1;\n }\n }\n\n return currentLineLength >= threshold;\n};\n\nexport const hasLargeMarkdownWordCount = (markdown: string) => {\n let wordCount = 0;\n let inWord = false;\n\n for (let index = 0; index < markdown.length; index += 1) {\n const character = markdown.charCodeAt(index);\n const isWhitespace =\n character === 32 ||\n character === 9 ||\n character === 10 ||\n character === 13 ||\n character === 12 ||\n character === 11;\n\n if (isWhitespace) {\n inWord = false;\n continue;\n }\n\n if (!inWord) {\n wordCount += 1;\n if (wordCount >= LARGE_DOCUMENT_WORD_THRESHOLD) {\n return true;\n }\n inWord = true;\n }\n }\n\n return false;\n};\n\nexport const hasLargeMarkdownDocumentShape = (markdown: string) => {\n let currentLineLength = 0;\n let currentTableRun = 0;\n let lineHasTableDelimiter = false;\n\n const finishLine = () => {\n if (currentLineLength >= LARGE_DOCUMENT_LONG_LINE_THRESHOLD) {\n return true;\n }\n\n currentTableRun = lineHasTableDelimiter ? currentTableRun + 1 : 0;\n if (currentTableRun >= LARGE_DOCUMENT_TABLE_RUN_THRESHOLD) {\n return true;\n }\n\n currentLineLength = 0;\n lineHasTableDelimiter = false;\n return false;\n };\n\n for (let index = 0; index < markdown.length; index += 1) {\n const characterCode = markdown.charCodeAt(index);\n if (characterCode === 10) {\n if (finishLine()) {\n return true;\n }\n continue;\n }\n\n if (characterCode !== 13) {\n currentLineLength += 1;\n }\n if (characterCode === 124) {\n lineHasTableDelimiter = true;\n }\n }\n\n return finishLine();\n};\n\nexport const isLargeMarkdownDocument = (markdown: string) =>\n markdown.length >= LARGE_DOCUMENT_CHAR_THRESHOLD ||\n getMarkdownLineCount(markdown) >= LARGE_DOCUMENT_LINE_THRESHOLD ||\n hasLargeMarkdownWordCount(markdown) ||\n hasLargeMarkdownDocumentShape(markdown);\n\nexport const hasHeavyMarkdownPreviewShape = (markdown: string) => {\n const lines = markdown.split(/\\r?\\n/);\n let tableRun = 0;\n let inFence = false;\n let fenceChar = \"\";\n let fenceLength = 0;\n let fenceLanguage = \"\";\n let fenceLineCount = 0;\n let fenceCharCount = 0;\n let inDisplayMath = false;\n\n const finishFence = () => {\n const isHeavyFence =\n heavyFenceLanguagePattern.test(fenceLanguage) ||\n fenceLineCount >= HEAVY_PREVIEW_FENCE_LINE_THRESHOLD ||\n fenceCharCount >= HEAVY_PREVIEW_FENCE_CHAR_THRESHOLD;\n fenceLanguage = \"\";\n fenceLineCount = 0;\n fenceCharCount = 0;\n return isHeavyFence;\n };\n\n for (const line of lines) {\n const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})\\s*([A-Za-z0-9_-]+)?/);\n if (fenceMatch) {\n const marker = fenceMatch[1];\n if (!inFence) {\n inFence = true;\n fenceChar = marker[0];\n fenceLength = marker.length;\n fenceLanguage = fenceMatch[2]?.toLowerCase() ?? \"\";\n fenceLineCount = 0;\n fenceCharCount = 0;\n if (heavyFenceLanguagePattern.test(fenceLanguage)) {\n return true;\n }\n continue;\n }\n\n if (marker[0] === fenceChar && marker.length >= fenceLength) {\n inFence = false;\n if (finishFence()) {\n return true;\n }\n continue;\n }\n }\n\n if (inFence) {\n fenceLineCount += 1;\n fenceCharCount += line.length;\n if (\n fenceLineCount >= HEAVY_PREVIEW_FENCE_LINE_THRESHOLD ||\n fenceCharCount >= HEAVY_PREVIEW_FENCE_CHAR_THRESHOLD\n ) {\n return true;\n }\n continue;\n }\n\n if (displayMathLinePattern.test(line)) {\n inDisplayMath = !inDisplayMath;\n return true;\n }\n\n if (inDisplayMath) {\n return true;\n }\n\n if (htmlLinePattern.test(line)) {\n return true;\n }\n\n tableRun = line.includes(\"|\") ? tableRun + 1 : 0;\n if (tableRun >= HEAVY_PREVIEW_TABLE_RUN_THRESHOLD) {\n return true;\n }\n }\n\n return inFence ? finishFence() : false;\n};\n\nexport const hasGlobalMarkdownSyntax = (markdown: string) => {\n const lines = markdown.split(/\\r?\\n/);\n let inFence = false;\n let fenceChar = \"\";\n let fenceLength = 0;\n\n if (\n lines.length >= 3 &&\n frontmatterFencePattern.test(lines[0] ?? \"\") &&\n lines.slice(1, Math.min(lines.length, 40)).some((line) => yamlKeyLinePattern.test(line)) &&\n lines.slice(1).some((line) => frontmatterFencePattern.test(line))\n ) {\n return true;\n }\n\n for (const line of lines) {\n const fenceMatch = line.match(/^ {0,3}(`{3,}|~{3,})/);\n if (fenceMatch) {\n const marker = fenceMatch[1];\n if (!inFence) {\n inFence = true;\n fenceChar = marker[0];\n fenceLength = marker.length;\n continue;\n }\n\n if (marker[0] === fenceChar && marker.length >= fenceLength) {\n inFence = false;\n continue;\n }\n }\n\n if (inFence) {\n continue;\n }\n\n if (\n footnoteDefinitionLinePattern.test(line) ||\n footnoteReferencePattern.test(line) ||\n referenceDefinitionLinePattern.test(line) ||\n referenceLinkPattern.test(line) ||\n definitionListLinePattern.test(line)\n ) {\n return true;\n }\n }\n\n return false;\n};\n\nexport const shouldUseImmediateMarkdownPreview = (markdown: string) =>\n markdown.length <= LIVE_PREVIEW_CHAR_THRESHOLD &&\n !isLargeMarkdownDocument(markdown) &&\n !hasHeavyMarkdownPreviewShape(markdown);\n\nconst splitMarkdownLines = (markdown: string): MarkdownLine[] => {\n if (markdown.length === 0) {\n return [{ text: \"\", startOffset: 0, endOffset: 0 }];\n }\n\n const lines: MarkdownLine[] = [];\n let startOffset = 0;\n while (startOffset <= markdown.length) {\n const lineBreakIndex = markdown.indexOf(\"\\n\", startOffset);\n const rawEndOffset = lineBreakIndex === -1 ? markdown.length : lineBreakIndex;\n const endOffset =\n rawEndOffset > startOffset && markdown.charCodeAt(rawEndOffset - 1) === 13\n ? rawEndOffset - 1\n : rawEndOffset;\n lines.push({\n text: markdown.slice(startOffset, endOffset),\n startOffset,\n endOffset,\n });\n\n if (lineBreakIndex === -1) {\n break;\n }\n\n startOffset = lineBreakIndex + 1;\n }\n\n return lines;\n};\n\nconst isBlankLine = (line: MarkdownLine) => line.text.trim().length === 0;\n\nconst startsStructuralBlock = (line: MarkdownLine, nextLine?: MarkdownLine) =>\n isBlankLine(line) ||\n fenceLinePattern.test(line.text) ||\n headingLinePattern.test(line.text) ||\n thematicLinePattern.test(line.text) ||\n blockquoteLinePattern.test(line.text) ||\n listLinePattern.test(line.text) ||\n htmlLinePattern.test(line.text) ||\n isTableStart(line, nextLine);\n\nconst isTableStart = (line: MarkdownLine, nextLine?: MarkdownLine) =>\n Boolean(nextLine && line.text.includes(\"|\") && tableSeparatorPattern.test(nextLine.text));\n\nconst getHeadingLevel = (text: string): 1 | 2 | 3 | 4 | 5 | 6 | undefined => {\n const match = text.match(/^ {0,3}(#{1,6})\\s+\\S/);\n const level = match?.[1]?.length;\n return level === 1 || level === 2 || level === 3 || level === 4 || level === 5 || level === 6\n ? level\n : undefined;\n};\n\nconst estimateBlockHeight = (kind: PreviewBlockKind, lineCount: number, text = \"\") => {\n if (kind === \"blank\") {\n return 0;\n }\n\n if (kind === \"fence\") {\n return Math.max(54, lineCount * CODE_LINE_HEIGHT + 34);\n }\n\n if (kind === \"heading\") {\n return HEADING_ESTIMATED_HEIGHT_BY_LEVEL[getHeadingLevel(text) ?? 3];\n }\n\n if (kind === \"table\") {\n return Math.max(52, lineCount * DEFAULT_LINE_HEIGHT + 20);\n }\n\n return Math.max(DEFAULT_LINE_HEIGHT, lineCount * DEFAULT_LINE_HEIGHT) + BLOCK_GAP_HEIGHT;\n};\n\nconst createBlock = (\n lines: MarkdownLine[],\n startIndex: number,\n endIndex: number,\n kind: PreviewBlockKind,\n estimatedTop: number,\n): PreviewBlock => {\n const startLine = startIndex + 1;\n const endLine = endIndex + 1;\n const startOffset = lines[startIndex]?.startOffset ?? 0;\n const endOffset = lines[endIndex]?.endOffset ?? startOffset;\n const text = lines\n .slice(startIndex, endIndex + 1)\n .map((line) => line.text)\n .join(\"\\n\");\n const headingLevel = kind === \"heading\" ? getHeadingLevel(text) : undefined;\n const estimatedHeight = estimateBlockHeight(kind, endLine - startLine + 1, text);\n\n return {\n id: `${startLine}:${endLine}:${startOffset}`,\n kind,\n text,\n ...(headingLevel ? { headingLevel } : {}),\n startLine,\n endLine,\n startOffset,\n endOffset,\n estimatedTop,\n estimatedHeight,\n };\n};\n\nconst findParagraphTextChunkEnd = (text: string, startOffset: number) => {\n const preferredEnd = Math.min(text.length, startOffset + PREVIEW_PARAGRAPH_CHAR_CHUNK_SIZE);\n if (preferredEnd >= text.length) {\n return text.length;\n }\n\n const searchEnd = Math.min(text.length, preferredEnd + 600);\n for (let index = preferredEnd; index < searchEnd; index += 1) {\n const character = text.charCodeAt(index);\n if (character === 32 || character === 9) {\n return index + 1;\n }\n }\n\n return preferredEnd;\n};\n\nconst createParagraphTextChunkBlock = (\n line: MarkdownLine,\n lineIndex: number,\n chunkStart: number,\n chunkEnd: number,\n estimatedTop: number,\n): PreviewBlock => {\n const startLine = lineIndex + 1;\n const startOffset = line.startOffset + chunkStart;\n const endOffset = line.startOffset + chunkEnd;\n const text = line.text.slice(chunkStart, chunkEnd);\n const estimatedLineCount = Math.max(1, Math.ceil(text.length / PREVIEW_PARAGRAPH_ESTIMATED_CHARS_PER_LINE));\n const estimatedHeight = estimateBlockHeight(\"paragraph\", estimatedLineCount, text);\n\n return {\n id: `${startLine}:${startLine}:${startOffset}:${endOffset}`,\n kind: \"paragraph\",\n text,\n startLine,\n endLine: startLine,\n startOffset,\n endOffset,\n estimatedTop,\n estimatedHeight,\n };\n};\n\nconst createParagraphBlocks = (\n lines: MarkdownLine[],\n startIndex: number,\n endIndex: number,\n estimatedTop: number,\n): { blocks: PreviewBlock[]; estimatedTop: number } => {\n const blocks: PreviewBlock[] = [];\n\n if (startIndex === endIndex && lines[startIndex].text.length > PREVIEW_PARAGRAPH_CHAR_CHUNK_SIZE) {\n const line = lines[startIndex];\n let chunkStart = 0;\n let nextEstimatedTop = estimatedTop;\n while (chunkStart < line.text.length) {\n const chunkEnd = findParagraphTextChunkEnd(line.text, chunkStart);\n const block = createParagraphTextChunkBlock(line, startIndex, chunkStart, chunkEnd, nextEstimatedTop);\n blocks.push(block);\n nextEstimatedTop += block.estimatedHeight;\n chunkStart = chunkEnd;\n }\n return { blocks, estimatedTop: nextEstimatedTop };\n }\n\n let chunkStartIndex = startIndex;\n let nextEstimatedTop = estimatedTop;\n while (chunkStartIndex <= endIndex) {\n const chunkEndIndex = Math.min(endIndex, chunkStartIndex + PREVIEW_PARAGRAPH_LINE_CHUNK_SIZE - 1);\n const block = createBlock(lines, chunkStartIndex, chunkEndIndex, \"paragraph\", nextEstimatedTop);\n blocks.push(block);\n nextEstimatedTop += block.estimatedHeight;\n chunkStartIndex = chunkEndIndex + 1;\n }\n\n return { blocks, estimatedTop: nextEstimatedTop };\n};\n\nconst findFenceEnd = (lines: MarkdownLine[], startIndex: number) => {\n const openingMatch = lines[startIndex]?.text.match(fenceLinePattern);\n if (!openingMatch) {\n return startIndex;\n }\n\n const marker = openingMatch[1];\n for (let index = startIndex + 1; index < lines.length; index += 1) {\n const closingMatch = lines[index].text.match(fenceLinePattern);\n if (closingMatch && closingMatch[1][0] === marker[0] && closingMatch[1].length >= marker.length) {\n return index;\n }\n }\n\n return lines.length - 1;\n};\n\nconst getHtmlBlockOpeningTagName = (line: string) => {\n const match = line.match(/^ {0,3}<([A-Za-z][A-Za-z0-9-]*)(?:\\s|>|\\/>)/);\n if (!match || line.trimStart().startsWith(\"</\")) {\n return null;\n }\n\n const tagName = match[1];\n const closingPattern = new RegExp(`</${tagName}>`, \"i\");\n if (closingPattern.test(line) || /\\/>\\s*$/.test(line)) {\n return null;\n }\n\n return tagName;\n};\n\nconst findPairedHtmlEnd = (lines: MarkdownLine[], startIndex: number) => {\n const tagName = getHtmlBlockOpeningTagName(lines[startIndex]?.text ?? \"\");\n if (!tagName) {\n return null;\n }\n\n const openingPattern = new RegExp(`^ {0,3}<${tagName}(?:\\\\s|>|/>)`, \"i\");\n const closingPattern = new RegExp(`</${tagName}>`, \"i\");\n let depth = 0;\n\n for (let index = startIndex; index < lines.length; index += 1) {\n const text = lines[index].text;\n if (openingPattern.test(text) && !/\\/>\\s*$/.test(text) && !closingPattern.test(text)) {\n depth += 1;\n }\n\n if (closingPattern.test(text)) {\n depth -= 1;\n if (depth <= 0) {\n return index;\n }\n }\n }\n\n return null;\n};\n\nconst findHtmlEnd = (lines: MarkdownLine[], startIndex: number) => {\n const pairedHtmlEnd = findPairedHtmlEnd(lines, startIndex);\n if (pairedHtmlEnd !== null) {\n return pairedHtmlEnd;\n }\n\n for (let index = startIndex + 1; index < lines.length; index += 1) {\n if (isBlankLine(lines[index])) {\n return index - 1;\n }\n }\n return lines.length - 1;\n};\n\nconst findListEnd = (lines: MarkdownLine[], startIndex: number) => {\n let sawBlank = false;\n for (let index = startIndex + 1; index < lines.length; index += 1) {\n const line = lines[index];\n if (isBlankLine(line)) {\n sawBlank = true;\n continue;\n }\n if (listLinePattern.test(line.text) || indentedContinuationPattern.test(line.text)) {\n sawBlank = false;\n continue;\n }\n return sawBlank ? index - 2 : index - 1;\n }\n return lines.length - 1;\n};\n\nconst findBlockquoteEnd = (lines: MarkdownLine[], startIndex: number) => {\n for (let index = startIndex + 1; index < lines.length; index += 1) {\n if (isBlankLine(lines[index])) {\n return index - 1;\n }\n if (!blockquoteLinePattern.test(lines[index].text)) {\n return index - 1;\n }\n }\n return lines.length - 1;\n};\n\nconst findTableEnd = (lines: MarkdownLine[], startIndex: number) => {\n for (let index = startIndex + 2; index < lines.length; index += 1) {\n if (!lines[index].text.includes(\"|\") || isBlankLine(lines[index])) {\n return index - 1;\n }\n }\n return lines.length - 1;\n};\n\nconst findParagraphEnd = (lines: MarkdownLine[], startIndex: number) => {\n for (let index = startIndex + 1; index < lines.length; index += 1) {\n if (startsStructuralBlock(lines[index], lines[index + 1])) {\n return index - 1;\n }\n }\n return lines.length - 1;\n};\n\nconst resolveBlockRange = (lines: MarkdownLine[], startIndex: number) => {\n const line = lines[startIndex];\n const nextLine = lines[startIndex + 1];\n\n if (isBlankLine(line)) {\n let endIndex = startIndex;\n while (endIndex + 1 < lines.length && isBlankLine(lines[endIndex + 1])) {\n endIndex += 1;\n }\n return { endIndex, kind: \"blank\" as const };\n }\n\n if (fenceLinePattern.test(line.text)) {\n return { endIndex: findFenceEnd(lines, startIndex), kind: \"fence\" as const };\n }\n\n if (isTableStart(line, nextLine)) {\n return { endIndex: findTableEnd(lines, startIndex), kind: \"table\" as const };\n }\n\n if (headingLinePattern.test(line.text)) {\n return { endIndex: startIndex, kind: \"heading\" as const };\n }\n\n if (thematicLinePattern.test(line.text)) {\n return { endIndex: startIndex, kind: \"thematic\" as const };\n }\n\n if (blockquoteLinePattern.test(line.text)) {\n return { endIndex: findBlockquoteEnd(lines, startIndex), kind: \"blockquote\" as const };\n }\n\n if (listLinePattern.test(line.text)) {\n return { endIndex: findListEnd(lines, startIndex), kind: \"list\" as const };\n }\n\n if (htmlLinePattern.test(line.text)) {\n return { endIndex: findHtmlEnd(lines, startIndex), kind: \"html\" as const };\n }\n\n return { endIndex: findParagraphEnd(lines, startIndex), kind: \"paragraph\" as const };\n};\n\nexport const createPreviewBlockIndex = (markdown: string): PreviewBlockIndex => {\n const lines = splitMarkdownLines(markdown);\n const blocks: PreviewBlock[] = [];\n let lineIndex = 0;\n let estimatedTop = 0;\n\n while (lineIndex < lines.length) {\n const { endIndex, kind } = resolveBlockRange(lines, lineIndex);\n const safeEndIndex = Math.max(lineIndex, Math.min(endIndex, lines.length - 1));\n if (kind === \"paragraph\") {\n const paragraphBlocks = createParagraphBlocks(lines, lineIndex, safeEndIndex, estimatedTop);\n blocks.push(...paragraphBlocks.blocks);\n estimatedTop = paragraphBlocks.estimatedTop;\n lineIndex = safeEndIndex + 1;\n continue;\n }\n\n const block = createBlock(lines, lineIndex, safeEndIndex, kind, estimatedTop);\n blocks.push(block);\n estimatedTop += block.estimatedHeight;\n lineIndex = safeEndIndex + 1;\n }\n\n return {\n blocks,\n lineCount: lines.length,\n totalEstimatedHeight: estimatedTop,\n };\n};\n\ntype TextChangeRange = {\n nextEndOffset: number;\n nextStartOffset: number;\n previousEndOffset: number;\n previousStartOffset: number;\n};\n\nconst getTextChangeRange = (previousMarkdown: string, nextMarkdown: string): TextChangeRange | null => {\n if (previousMarkdown === nextMarkdown) {\n return null;\n }\n\n const sharedLength = Math.min(previousMarkdown.length, nextMarkdown.length);\n let startOffset = 0;\n while (\n startOffset < sharedLength &&\n previousMarkdown.charCodeAt(startOffset) === nextMarkdown.charCodeAt(startOffset)\n ) {\n startOffset += 1;\n }\n\n let suffixLength = 0;\n const maxSuffixLength = sharedLength - startOffset;\n while (\n suffixLength < maxSuffixLength &&\n previousMarkdown.charCodeAt(previousMarkdown.length - suffixLength - 1) ===\n nextMarkdown.charCodeAt(nextMarkdown.length - suffixLength - 1)\n ) {\n suffixLength += 1;\n }\n\n return {\n nextEndOffset: nextMarkdown.length - suffixLength,\n nextStartOffset: startOffset,\n previousEndOffset: previousMarkdown.length - suffixLength,\n previousStartOffset: startOffset,\n };\n};\n\nconst getTextChangeRangeFromPatches = (\n previousMarkdown: string,\n nextMarkdown: string,\n patches: readonly TextPatch[],\n): TextChangeRange | null | undefined => {\n if (patches.length === 0) {\n return previousMarkdown === nextMarkdown ? null : undefined;\n }\n\n const normalizedPatches = normalizeTextPatches(patches);\n if (applyTextPatches(previousMarkdown, normalizedPatches) !== nextMarkdown) {\n return undefined;\n }\n\n let previousStartOffset = Number.POSITIVE_INFINITY;\n let previousEndOffset = 0;\n let nextStartOffset = Number.POSITIVE_INFINITY;\n let nextEndOffset = 0;\n let offsetDelta = 0;\n\n for (const patch of normalizedPatches) {\n const nextPatchStartOffset = patch.from + offsetDelta;\n const nextPatchEndOffset = nextPatchStartOffset + patch.insert.length;\n previousStartOffset = Math.min(previousStartOffset, patch.from);\n previousEndOffset = Math.max(previousEndOffset, patch.to);\n nextStartOffset = Math.min(nextStartOffset, nextPatchStartOffset);\n nextEndOffset = Math.max(nextEndOffset, nextPatchEndOffset);\n offsetDelta += patch.insert.length - (patch.to - patch.from);\n }\n\n return {\n nextEndOffset,\n nextStartOffset,\n previousEndOffset,\n previousStartOffset,\n };\n};\n\nconst getLineNumberForMarkdownOffset = (lines: readonly MarkdownLine[], offset: number) => {\n if (lines.length === 0) {\n return 1;\n }\n\n const clampedOffset = Math.max(0, offset);\n for (let index = 0; index < lines.length; index += 1) {\n const nextLineStartOffset = lines[index + 1]?.startOffset;\n if (typeof nextLineStartOffset !== \"number\" || clampedOffset < nextLineStartOffset) {\n return index + 1;\n }\n }\n\n return lines.length;\n};\n\nconst getChangedLineSpan = (\n lines: readonly MarkdownLine[],\n startOffset: number,\n endOffset: number,\n) => {\n const startLine = getLineNumberForMarkdownOffset(lines, startOffset);\n const endLine = getLineNumberForMarkdownOffset(lines, Math.max(startOffset, endOffset - 1));\n return {\n endLine: Math.max(startLine, endLine),\n startLine,\n };\n};\n\nconst isOptimisticStructuralLine = (\n line: MarkdownLine | undefined,\n nextLine?: MarkdownLine,\n) => {\n if (!line) {\n return true;\n }\n\n return (\n fenceLinePattern.test(line.text) ||\n thematicLinePattern.test(line.text) ||\n blockquoteLinePattern.test(line.text) ||\n listLinePattern.test(line.text) ||\n tableSeparatorPattern.test(line.text) ||\n isTableStart(line, nextLine) ||\n htmlLinePattern.test(line.text) ||\n displayMathLinePattern.test(line.text) ||\n frontmatterFencePattern.test(line.text)\n );\n};\n\nconst isUnsafeOptimisticChangedLine = (\n lines: readonly MarkdownLine[],\n lineIndex: number,\n options: { blankIsUnsafe: boolean },\n) => {\n const line = lines[lineIndex];\n if (!line) {\n return true;\n }\n\n if (isBlankLine(line)) {\n return (\n options.blankIsUnsafe &&\n (\n isOptimisticStructuralLine(lines[lineIndex - 1], line) ||\n isOptimisticStructuralLine(lines[lineIndex + 1], lines[lineIndex + 2])\n )\n );\n }\n\n return isOptimisticStructuralLine(line, lines[lineIndex + 1]);\n};\n\nconst hasUnsafeOptimisticChangedLines = (\n lines: readonly MarkdownLine[],\n span: { endLine: number; startLine: number },\n options: { blankIsUnsafe?: boolean } = {},\n) => {\n const startIndex = Math.max(0, span.startLine - 1);\n const endIndex = Math.min(lines.length - 1, span.endLine - 1);\n const blankIsUnsafe = options.blankIsUnsafe ?? true;\n\n for (let index = startIndex; index <= endIndex; index += 1) {\n if (isUnsafeOptimisticChangedLine(lines, index, { blankIsUnsafe })) {\n return true;\n }\n }\n\n return false;\n};\n\nconst findFirstPreviewBlockIndexAtLine = (blocks: readonly PreviewBlock[], lineNumber: number) =>\n blocks.findIndex((block) => block.endLine >= lineNumber);\n\nconst findLastPreviewBlockIndexAtLine = (blocks: readonly PreviewBlock[], lineNumber: number) => {\n for (let index = blocks.length - 1; index >= 0; index -= 1) {\n if (blocks[index].startLine <= lineNumber) {\n return index;\n }\n }\n return -1;\n};\n\nconst getLineStartOffsetFromLines = (lines: readonly MarkdownLine[], lineNumber: number) =>\n lines[Math.max(0, Math.min(lines.length - 1, lineNumber - 1))]?.startOffset ?? 0;\n\nconst getLineEndOffsetFromLines = (lines: readonly MarkdownLine[], lineNumber: number) =>\n lines[Math.max(0, Math.min(lines.length - 1, lineNumber - 1))]?.endOffset ?? 0;\n\nconst rekeyPreviewBlock = (\n block: PreviewBlock,\n startLine: number,\n endLine: number,\n startOffset: number,\n endOffset: number,\n) => {\n const hasExplicitEndOffset = block.id.split(\":\").length >= 4;\n return hasExplicitEndOffset\n ? `${startLine}:${endLine}:${startOffset}:${endOffset}`\n : `${startLine}:${endLine}:${startOffset}`;\n};\n\nconst rebasePreviewBlock = (\n block: PreviewBlock,\n options: {\n lineOffset: number;\n offsetBase: number;\n },\n): PreviewBlock => {\n const startLine = block.startLine + options.lineOffset;\n const endLine = block.endLine + options.lineOffset;\n const startOffset = block.startOffset + options.offsetBase;\n const endOffset = block.endOffset + options.offsetBase;\n\n return {\n ...block,\n id: rekeyPreviewBlock(block, startLine, endLine, startOffset, endOffset),\n startLine,\n endLine,\n startOffset,\n endOffset,\n };\n};\n\nconst shiftPreviewBlock = (\n block: PreviewBlock,\n options: {\n charDelta: number;\n lineDelta: number;\n },\n): PreviewBlock => {\n if (options.charDelta === 0 && options.lineDelta === 0) {\n return block;\n }\n\n const startLine = block.startLine + options.lineDelta;\n const endLine = block.endLine + options.lineDelta;\n const startOffset = block.startOffset + options.charDelta;\n const endOffset = block.endOffset + options.charDelta;\n\n return {\n ...block,\n id: rekeyPreviewBlock(block, startLine, endLine, startOffset, endOffset),\n startLine,\n endLine,\n startOffset,\n endOffset,\n };\n};\n\nconst reflowPreviewBlockTops = (blocks: readonly PreviewBlock[]) => {\n let estimatedTop = 0;\n return blocks.map((block) => {\n const nextBlock = block.estimatedTop === estimatedTop ? block : { ...block, estimatedTop };\n estimatedTop += nextBlock.estimatedHeight;\n return nextBlock;\n });\n};\n\nconst createOptimisticPreviewBlockIndexForChangeRange = (\n previousIndex: PreviewBlockIndex,\n previousMarkdown: string,\n nextMarkdown: string,\n changeRange: TextChangeRange | null,\n): PreviewBlockIndex | null => {\n if (!changeRange) {\n return previousIndex;\n }\n if (previousIndex.blocks.length === 0) {\n return null;\n }\n\n const previousLines = splitMarkdownLines(previousMarkdown);\n const nextLines = splitMarkdownLines(nextMarkdown);\n const previousChangedLineSpan = getChangedLineSpan(\n previousLines,\n changeRange.previousStartOffset,\n changeRange.previousEndOffset,\n );\n const nextChangedLineSpan = getChangedLineSpan(\n nextLines,\n changeRange.nextStartOffset,\n changeRange.nextEndOffset,\n );\n const changedLineCount = Math.max(\n previousChangedLineSpan.endLine - previousChangedLineSpan.startLine + 1,\n nextChangedLineSpan.endLine - nextChangedLineSpan.startLine + 1,\n );\n if (changedLineCount > OPTIMISTIC_INDEX_MAX_CHANGED_LINES) {\n return null;\n }\n if (\n hasUnsafeOptimisticChangedLines(previousLines, previousChangedLineSpan) ||\n hasUnsafeOptimisticChangedLines(nextLines, nextChangedLineSpan, { blankIsUnsafe: false })\n ) {\n return null;\n }\n\n const firstChangedBlockIndex = findFirstPreviewBlockIndexAtLine(\n previousIndex.blocks,\n previousChangedLineSpan.startLine,\n );\n const lastChangedBlockIndex = findLastPreviewBlockIndexAtLine(\n previousIndex.blocks,\n previousChangedLineSpan.endLine,\n );\n if (firstChangedBlockIndex === -1 || lastChangedBlockIndex === -1) {\n return null;\n }\n\n const replaceStartBlockIndex = Math.max(\n 0,\n firstChangedBlockIndex - OPTIMISTIC_INDEX_CONTEXT_BLOCK_COUNT,\n );\n const replaceEndBlockIndex = Math.min(\n previousIndex.blocks.length - 1,\n lastChangedBlockIndex + OPTIMISTIC_INDEX_CONTEXT_BLOCK_COUNT,\n );\n const replaceStartBlock = previousIndex.blocks[replaceStartBlockIndex];\n const replaceEndBlock = previousIndex.blocks[replaceEndBlockIndex];\n const lineDelta = nextLines.length - previousLines.length;\n const charDelta = nextMarkdown.length - previousMarkdown.length;\n const nextReplaceStartLine = Math.max(1, Math.min(nextLines.length, replaceStartBlock.startLine));\n const nextReplaceEndLine = Math.max(\n nextReplaceStartLine,\n Math.min(nextLines.length, replaceEndBlock.endLine + lineDelta),\n );\n const sliceStartOffset = getLineStartOffsetFromLines(nextLines, nextReplaceStartLine);\n const sliceEndOffset = getLineEndOffsetFromLines(nextLines, nextReplaceEndLine);\n const replacementIndex = createPreviewBlockIndex(nextMarkdown.slice(sliceStartOffset, sliceEndOffset));\n const replacementBlocks = replacementIndex.blocks.map((block) =>\n rebasePreviewBlock(block, {\n lineOffset: nextReplaceStartLine - 1,\n offsetBase: sliceStartOffset,\n }),\n );\n const suffixBlocks = previousIndex.blocks\n .slice(replaceEndBlockIndex + 1)\n .map((block) => shiftPreviewBlock(block, { charDelta, lineDelta }));\n const blocks = reflowPreviewBlockTops([\n ...previousIndex.blocks.slice(0, replaceStartBlockIndex),\n ...replacementBlocks,\n ...suffixBlocks,\n ]);\n const totalEstimatedHeight = blocks.reduce((total, block) => total + block.estimatedHeight, 0);\n\n return {\n blocks,\n lineCount: nextLines.length,\n totalEstimatedHeight,\n };\n};\n\nexport const createOptimisticPreviewBlockIndex = (\n previousIndex: PreviewBlockIndex,\n previousMarkdown: string,\n nextMarkdown: string,\n): PreviewBlockIndex | null =>\n createOptimisticPreviewBlockIndexForChangeRange(\n previousIndex,\n previousMarkdown,\n nextMarkdown,\n getTextChangeRange(previousMarkdown, nextMarkdown),\n );\n\nexport const createOptimisticPreviewBlockIndexFromPatches = (\n previousIndex: PreviewBlockIndex,\n previousMarkdown: string,\n nextMarkdown: string,\n patches: readonly TextPatch[],\n): PreviewBlockIndex | null => {\n const changeRange = getTextChangeRangeFromPatches(previousMarkdown, nextMarkdown, patches);\n return changeRange === undefined\n ? null\n : createOptimisticPreviewBlockIndexForChangeRange(\n previousIndex,\n previousMarkdown,\n nextMarkdown,\n changeRange,\n );\n};\n\nexport const applyPreviewBlockMeasurements = (\n index: PreviewBlockIndex,\n measurements: PreviewBlockMeasurements,\n): PreviewBlockIndex => {\n let estimatedTop = 0;\n const blocks = index.blocks.map((block) => {\n const measuredHeight = measurements[block.id];\n const estimatedHeight =\n Number.isFinite(measuredHeight) && measuredHeight >= 0\n ? measuredHeight\n : block.estimatedHeight;\n const measuredBlock =\n block.estimatedTop === estimatedTop && block.estimatedHeight === estimatedHeight\n ? block\n : {\n ...block,\n estimatedTop,\n estimatedHeight,\n };\n estimatedTop += estimatedHeight;\n return measuredBlock;\n });\n\n return {\n ...index,\n blocks,\n totalEstimatedHeight: estimatedTop,\n };\n};\n\nexport const choosePreviewRenderableAnchor = <TAnchor extends PreviewRenderableAnchor>(\n anchors: readonly TAnchor[],\n sourceLineNumber: number,\n): TAnchor | null => {\n const targetLine = Math.max(1, Math.floor(sourceLineNumber));\n const measuredAnchors = anchors\n .filter((anchor) => Number.isFinite(anchor.startLine) && Number.isFinite(anchor.endLine))\n .map((anchor) => ({\n ...anchor,\n endLine: Math.max(anchor.startLine, anchor.endLine),\n startLine: anchor.startLine,\n }));\n const targetLineHasUnrenderedAnchor = measuredAnchors.some(\n (anchor) => anchor.startLine <= targetLine && anchor.endLine >= targetLine && !anchor.rendered,\n );\n const renderableAnchors = measuredAnchors.filter((anchor) => anchor.rendered);\n\n if (renderableAnchors.length === 0) {\n return null;\n }\n\n const scoreAnchor = (anchor: TAnchor) => {\n const containsTarget = anchor.startLine <= targetLine && anchor.endLine >= targetLine;\n const sourceElementScore = anchor.sourceElement ? 0 : 1;\n\n if (containsTarget) {\n return [0, sourceElementScore, Math.abs(anchor.startLine - targetLine)];\n }\n\n if (anchor.endLine < targetLine) {\n return [\n targetLineHasUnrenderedAnchor ? 2 : 1,\n targetLine - anchor.endLine,\n sourceElementScore,\n ];\n }\n\n return [\n targetLineHasUnrenderedAnchor ? 1 : 2,\n anchor.startLine - targetLine,\n sourceElementScore,\n ];\n };\n\n return [...renderableAnchors].sort((first, second) => {\n const firstScore = scoreAnchor(first);\n const secondScore = scoreAnchor(second);\n for (let index = 0; index < firstScore.length; index += 1) {\n const difference = firstScore[index] - secondScore[index];\n if (difference !== 0) {\n return difference;\n }\n }\n\n return first.startLine - second.startLine;\n })[0] ?? null;\n};\n\nconst isPreviewBlockRenderableForScrollMap = (block: PreviewBlock) =>\n block.kind !== \"blank\" && block.estimatedHeight > 0;\n\nconst clampPreviewScrollTop = (scrollTop: number, totalHeight: number, viewportHeight: number) =>\n Math.max(0, Math.min(Math.max(0, totalHeight - viewportHeight), scrollTop));\n\nexport const getPreviewScrollTopForSourceLine = (\n index: PreviewBlockIndex,\n anchor: PreviewScrollMapAnchor,\n options: PreviewScrollMapOptions,\n) => {\n const viewportHeight = Math.max(1, options.viewportHeight);\n const edgePadding = options.edgePadding ?? 32;\n\n if (anchor.align === \"end\") {\n return clampPreviewScrollTop(index.totalEstimatedHeight, index.totalEstimatedHeight, viewportHeight);\n }\n\n const targetLine = Math.max(1, Math.floor(anchor.lineNumber));\n const lineOffsetRatio = Math.max(0, Math.min(1, anchor.lineOffsetRatio ?? 0));\n const sourceBlock = mapPreviewLineToBlock(index, targetLine);\n const renderableBlocks = index.blocks.filter(isPreviewBlockRenderableForScrollMap);\n if (renderableBlocks.length === 0) {\n return 0;\n }\n\n if (sourceBlock && isPreviewBlockRenderableForScrollMap(sourceBlock)) {\n const blockLineCount = Math.max(1, sourceBlock.endLine - sourceBlock.startLine + 1);\n const blockLineOffset = Math.max(\n 0,\n Math.min(blockLineCount, targetLine - sourceBlock.startLine + lineOffsetRatio),\n );\n const blockRatio = blockLineOffset / blockLineCount;\n return clampPreviewScrollTop(\n sourceBlock.estimatedTop + sourceBlock.estimatedHeight * blockRatio - edgePadding,\n index.totalEstimatedHeight,\n viewportHeight,\n );\n }\n\n const fallbackBlock = choosePreviewRenderableAnchor(\n index.blocks.map((block) => ({\n ...block,\n rendered: isPreviewBlockRenderableForScrollMap(block),\n })),\n targetLine,\n );\n if (!fallbackBlock) {\n return 0;\n }\n\n const fallbackTop =\n fallbackBlock.endLine < targetLine\n ? fallbackBlock.estimatedTop + fallbackBlock.estimatedHeight\n : fallbackBlock.estimatedTop;\n return clampPreviewScrollTop(fallbackTop - edgePadding, index.totalEstimatedHeight, viewportHeight);\n};\n\nexport const getPreviewWindow = (\n index: PreviewBlockIndex,\n scrollTop: number,\n viewportHeight: number,\n overscan = 1_200,\n): PreviewWindow => {\n if (index.blocks.length === 0) {\n return {\n blocks: [],\n startIndex: 0,\n endIndex: 0,\n };\n }\n\n const leadingOverscan = Math.min(overscan, PREVIEW_WINDOW_MAX_LEADING_OVERSCAN);\n const trailingOverscan = overscan + (overscan - leadingOverscan);\n const windowTop = Math.max(0, scrollTop - leadingOverscan);\n const windowBottom = Math.max(windowTop, scrollTop + viewportHeight + trailingOverscan);\n const firstVisibleIndex = index.blocks.findIndex(\n (block) => block.estimatedTop + block.estimatedHeight >= windowTop,\n );\n const startIndex = firstVisibleIndex === -1 ? index.blocks.length - 1 : Math.max(0, firstVisibleIndex);\n let endIndex = startIndex;\n\n while (\n endIndex < index.blocks.length &&\n index.blocks[endIndex].estimatedTop <= windowBottom\n ) {\n endIndex += 1;\n }\n\n const scrollRatio =\n index.totalEstimatedHeight <= 0 ? 0 : Math.max(0, Math.min(1, scrollTop / index.totalEstimatedHeight));\n const leadingBlockPadding =\n scrollRatio >= PREVIEW_WINDOW_END_SCROLL_RATIO\n ? PREVIEW_WINDOW_END_LEADING_BLOCK_PADDING\n : PREVIEW_WINDOW_LEADING_BLOCK_PADDING;\n const trailingBlockPadding =\n scrollRatio >= PREVIEW_WINDOW_END_SCROLL_RATIO\n ? PREVIEW_WINDOW_END_TRAILING_BLOCK_PADDING\n : PREVIEW_WINDOW_TRAILING_BLOCK_PADDING;\n const paddedStartIndex = Math.max(0, startIndex - leadingBlockPadding);\n const paddedEndIndex = Math.min(index.blocks.length, endIndex + trailingBlockPadding);\n\n return {\n blocks: index.blocks.slice(paddedStartIndex, paddedEndIndex),\n startIndex: paddedStartIndex,\n endIndex: paddedEndIndex,\n };\n};\n\nexport const mapPreviewLineToBlock = (index: PreviewBlockIndex, lineNumber: number) =>\n index.blocks.find((block) => block.startLine <= lineNumber && block.endLine >= lineNumber) ?? null;\n","import {\n clampSplitEditorRatio,\n DEFAULT_SPLIT_EDITOR_RATIO,\n type FileViewMode,\n type ReadingWidth,\n} from \"./documentPrimitives\";\nimport {\n getLineStartOffset,\n getOutlineHeadingsFromMarkdown,\n getPreviewBody,\n parseFrontmatter,\n type MarkdownHeading,\n type ParsedFrontmatter,\n type PreviewBody,\n} from \"./markdown\";\nimport { getMarkdownWordCount } from \"./documentMetrics\";\nimport { isLargeMarkdownDocument } from \"./previewBlockModel\";\n\nexport type DocumentBookmark = {\n id: string;\n position: number;\n createdAt: string;\n};\n\nexport type ActiveDocumentFile = {\n title: string;\n text: string;\n viewMode: FileViewMode;\n readingWidth: ReadingWidth;\n splitRatio?: number;\n lineWrapping: boolean;\n lineNumbers: boolean;\n bookmarks?: DocumentBookmark[];\n};\n\nexport type ActiveDocumentRuntime = {\n bookmarks: DocumentBookmark[];\n canCopy: boolean;\n canFormat: boolean;\n hasFile: boolean;\n lineNumbers: boolean;\n lineWrapping: boolean;\n outlineHeadings: MarkdownHeading[];\n parsedMarkdown: ParsedFrontmatter;\n previewBodyStartOffset: number;\n readingWidth: ReadingWidth;\n renderedPreview: PreviewBody;\n largeDocumentMode: boolean;\n splitRatio: number;\n text: string;\n title: string;\n viewMode: FileViewMode;\n wordCount: number;\n};\n\nexport type ActiveDocumentEditorRuntime = Omit<\n ActiveDocumentRuntime,\n \"outlineHeadings\" | \"parsedMarkdown\" | \"previewBodyStartOffset\" | \"renderedPreview\"\n>;\n\nexport type ActiveDocumentPreviewRuntime = Pick<\n ActiveDocumentRuntime,\n \"outlineHeadings\" | \"parsedMarkdown\" | \"previewBodyStartOffset\" | \"renderedPreview\"\n>;\n\nexport type ActiveDocumentPreviewBodyRuntime = Pick<\n ActiveDocumentRuntime,\n \"previewBodyStartOffset\" | \"renderedPreview\"\n>;\n\nexport type ActiveDocumentPreviewMetadataRuntime = Pick<\n ActiveDocumentRuntime,\n \"outlineHeadings\" | \"parsedMarkdown\"\n>;\n\nexport type ActiveDocumentRuntimeOptions = {\n text?: string;\n wordCount?: number;\n};\n\nconst EMPTY_PARSED_MARKDOWN: ParsedFrontmatter = {\n attributes: [],\n body: \"\",\n};\n\nconst EMPTY_PREVIEW_BODY: PreviewBody = {\n body: \"\",\n sourceLineOffset: 0,\n};\n\nconst EMPTY_PREVIEW_BODY_RUNTIME: ActiveDocumentPreviewBodyRuntime = {\n previewBodyStartOffset: 0,\n renderedPreview: EMPTY_PREVIEW_BODY,\n};\n\nconst EMPTY_PREVIEW_METADATA_RUNTIME: ActiveDocumentPreviewMetadataRuntime = {\n outlineHeadings: [],\n parsedMarkdown: EMPTY_PARSED_MARKDOWN,\n};\n\nexport const createActiveDocumentEditorRuntime = (\n activeFile?: ActiveDocumentFile,\n options: ActiveDocumentRuntimeOptions = {},\n): ActiveDocumentEditorRuntime => {\n const text = options.text ?? activeFile?.text ?? \"\";\n const viewMode = activeFile?.viewMode ?? \"edit\";\n const readingWidth = activeFile?.readingWidth ?? \"wide\";\n const splitRatio = clampSplitEditorRatio(activeFile?.splitRatio ?? DEFAULT_SPLIT_EDITOR_RATIO);\n const lineWrapping = activeFile?.lineWrapping ?? true;\n const lineNumbers = activeFile?.lineNumbers ?? true;\n const bookmarks = activeFile?.bookmarks ?? [];\n const title = activeFile?.title ?? \"No file open\";\n const wordCount = options.wordCount ?? getMarkdownWordCount(text);\n const hasFile = Boolean(activeFile);\n const largeDocumentMode = isLargeMarkdownDocument(text);\n\n return {\n bookmarks,\n canCopy: text.trim().length > 0,\n canFormat: hasFile && viewMode !== \"preview\",\n hasFile,\n largeDocumentMode,\n lineNumbers,\n lineWrapping,\n readingWidth,\n splitRatio,\n text,\n title,\n viewMode,\n wordCount,\n };\n};\n\nexport const createActiveDocumentPreviewRuntime = (\n activeFile?: Pick<ActiveDocumentFile, \"text\">,\n options: Pick<ActiveDocumentRuntimeOptions, \"text\"> = {},\n): ActiveDocumentPreviewRuntime => {\n if (!activeFile) {\n return {\n ...EMPTY_PREVIEW_BODY_RUNTIME,\n ...EMPTY_PREVIEW_METADATA_RUNTIME,\n };\n }\n\n const text = options.text ?? activeFile.text;\n const parsedMarkdown = parseFrontmatter(text);\n const renderedPreview = getPreviewBody(parsedMarkdown.body);\n const parsedBodyStartOffset = text.indexOf(parsedMarkdown.body);\n const previewBodyStartOffset =\n (parsedBodyStartOffset === -1 ? 0 : parsedBodyStartOffset) +\n getLineStartOffset(parsedMarkdown.body, renderedPreview.sourceLineOffset);\n const outlineHeadings = getOutlineHeadingsFromMarkdown(parsedMarkdown.body);\n\n return {\n outlineHeadings,\n parsedMarkdown,\n previewBodyStartOffset,\n renderedPreview,\n };\n};\n\nexport const createActiveDocumentPreviewBodyRuntime = (\n activeFile?: Pick<ActiveDocumentFile, \"text\">,\n options: Pick<ActiveDocumentRuntimeOptions, \"text\"> = {},\n): ActiveDocumentPreviewBodyRuntime => {\n if (!activeFile) {\n return EMPTY_PREVIEW_BODY_RUNTIME;\n }\n\n const text = options.text ?? activeFile.text;\n const parsedMarkdown = parseFrontmatter(text);\n const renderedPreview = getPreviewBody(parsedMarkdown.body);\n const parsedBodyStartOffset = text.indexOf(parsedMarkdown.body);\n const previewBodyStartOffset =\n (parsedBodyStartOffset === -1 ? 0 : parsedBodyStartOffset) +\n getLineStartOffset(parsedMarkdown.body, renderedPreview.sourceLineOffset);\n\n return {\n previewBodyStartOffset,\n renderedPreview,\n };\n};\n\nexport const createActiveDocumentPreviewMetadataRuntime = (\n activeFile?: Pick<ActiveDocumentFile, \"text\">,\n options: Pick<ActiveDocumentRuntimeOptions, \"text\"> = {},\n): ActiveDocumentPreviewMetadataRuntime => {\n if (!activeFile) {\n return EMPTY_PREVIEW_METADATA_RUNTIME;\n }\n\n const text = options.text ?? activeFile.text;\n const parsedMarkdown = parseFrontmatter(text);\n const outlineHeadings = getOutlineHeadingsFromMarkdown(parsedMarkdown.body);\n\n return {\n outlineHeadings,\n parsedMarkdown,\n };\n};\n\nexport const createActiveDocumentRuntime = (\n activeFile?: ActiveDocumentFile,\n options: ActiveDocumentRuntimeOptions = {},\n): ActiveDocumentRuntime => ({\n ...createActiveDocumentEditorRuntime(activeFile, options),\n ...createActiveDocumentPreviewRuntime(activeFile, options),\n});\n","import type { CollaborationCollaborator } from \"./collaborationTypes\";\nimport type { EncryptedEnvelope } from \"./roomProtocol\";\n\nexport type RoomServerMetadata = {\n roomId: string;\n activeConnections: number;\n updatedAt?: string | null;\n};\n\nexport const createRoomApiUrl = (baseUrl: string, roomId: string, suffix = \"\") =>\n `${baseUrl}/v1/rooms/${encodeURIComponent(roomId)}${suffix}`;\n\nexport const isEncryptedEnvelope = (value: unknown): value is EncryptedEnvelope => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return false;\n }\n\n const envelope = value as Partial<EncryptedEnvelope>;\n return (\n envelope.v === 1 &&\n typeof envelope.roomId === \"string\" &&\n envelope.kind === \"room-event\" &&\n typeof envelope.version === \"number\" &&\n typeof envelope.iv === \"string\" &&\n typeof envelope.ciphertext === \"string\" &&\n typeof envelope.createdAt === \"string\"\n );\n};\n\nexport const sortCollaborators = (collaborators: Iterable<CollaborationCollaborator>) =>\n [...collaborators].sort((first, second) => first.name.localeCompare(second.name));\n","import { sortCollaborators } from \"./collabConnectionModel\";\nimport type { CollaborationCollaborator } from \"./collaborationTypes\";\nimport { normalizeTextPatches, type TextPatch } from \"./textPatches\";\n\nexport type CollaboratorRegistry = {\n upsert(collaborator: CollaborationCollaborator, selfId: string): boolean;\n prune(peerIds: Iterable<string>): boolean;\n remapSelections(patches: readonly TextPatch[], docLength: number): boolean;\n clear(): boolean;\n list(): CollaborationCollaborator[];\n};\n\nconst clampPosition = (position: number, docLength: number) => Math.max(0, Math.min(position, docLength));\n\nconst selectionsAreEqual = (\n first?: CollaborationCollaborator[\"selection\"],\n second?: CollaborationCollaborator[\"selection\"],\n) =>\n first === second ||\n (Boolean(first) &&\n Boolean(second) &&\n first?.documentId === second?.documentId &&\n first?.from === second?.from &&\n first?.to === second?.to);\n\nconst capabilityListsAreEqual = (\n first?: readonly string[],\n second?: readonly string[],\n) =>\n first === second ||\n (Boolean(first) &&\n Boolean(second) &&\n first?.length === second?.length &&\n first?.every((capability, index) => capability === second?.[index]));\n\nconst collaboratorsAreEqual = (\n first: CollaborationCollaborator,\n second: CollaborationCollaborator,\n) =>\n first.id === second.id &&\n first.name === second.name &&\n first.color === second.color &&\n first.activeDocumentId === second.activeDocumentId &&\n first.kind === second.kind &&\n first.client === second.client &&\n first.joinedAt === second.joinedAt &&\n capabilityListsAreEqual(first.capabilities, second.capabilities) &&\n first.roomId === second.roomId &&\n first.fileTitle === second.fileTitle &&\n selectionsAreEqual(first.selection, second.selection);\n\nexport const mapCollaborationPositionThroughTextPatches = (\n position: number,\n patches: readonly TextPatch[],\n docLength: number,\n assoc: -1 | 1 = -1,\n) => {\n let delta = 0;\n for (const patch of normalizeTextPatches(patches)) {\n const insertedLength = patch.insert.length;\n const deletedLength = patch.to - patch.from;\n\n if (position < patch.from) {\n break;\n }\n\n if (position > patch.to) {\n delta += insertedLength - deletedLength;\n continue;\n }\n\n if (position === patch.from && deletedLength === 0) {\n return clampPosition(position + delta + (assoc > 0 ? insertedLength : 0), docLength);\n }\n\n return clampPosition(patch.from + delta + (assoc > 0 ? insertedLength : 0), docLength);\n }\n\n return clampPosition(position + delta, docLength);\n};\n\nexport const mapCollaborationSelectionThroughTextPatches = (\n selection: NonNullable<CollaborationCollaborator[\"selection\"]>,\n patches: readonly TextPatch[],\n docLength: number,\n) => {\n if (selection.from === selection.to) {\n const position = mapCollaborationPositionThroughTextPatches(selection.to, patches, docLength, -1);\n return { from: position, to: position };\n }\n\n return {\n from: mapCollaborationPositionThroughTextPatches(selection.from, patches, docLength, -1),\n to: mapCollaborationPositionThroughTextPatches(selection.to, patches, docLength, 1),\n };\n};\n\nexport const createCollaboratorRegistry = (): CollaboratorRegistry => {\n const collaborators = new Map<string, CollaborationCollaborator>();\n\n return {\n upsert(collaborator, selfId) {\n if (collaborator.id === selfId) {\n return false;\n }\n\n const currentCollaborator = collaborators.get(collaborator.id);\n if (currentCollaborator && collaboratorsAreEqual(currentCollaborator, collaborator)) {\n return false;\n }\n\n collaborators.set(collaborator.id, collaborator);\n return true;\n },\n prune(peerIds) {\n const nextPeerIds = new Set(peerIds);\n let changed = false;\n for (const collaboratorId of collaborators.keys()) {\n if (!nextPeerIds.has(collaboratorId)) {\n collaborators.delete(collaboratorId);\n changed = true;\n }\n }\n return changed;\n },\n remapSelections(patches, docLength) {\n if (patches.length === 0) {\n return false;\n }\n\n let changed = false;\n for (const [collaboratorId, collaborator] of collaborators) {\n if (!collaborator.selection) {\n continue;\n }\n\n const selection = mapCollaborationSelectionThroughTextPatches(collaborator.selection, patches, docLength);\n if (\n selection.from === collaborator.selection.from &&\n selection.to === collaborator.selection.to\n ) {\n continue;\n }\n\n collaborators.set(collaboratorId, {\n ...collaborator,\n selection,\n });\n changed = true;\n }\n\n return changed;\n },\n clear() {\n const changed = collaborators.size > 0;\n collaborators.clear();\n return changed;\n },\n list() {\n return sortCollaborators(collaborators.values());\n },\n };\n};\n","export type CollabOfflineReason = \"disconnect\" | \"connect-error\";\nexport type CollabOfflineStatus = \"reconnecting\" | \"disconnected\" | \"failed\";\n\nexport type CollabJoinResult =\n | {\n reconnected: true;\n message: string;\n }\n | {\n reconnected: false;\n };\n\nexport type CollabOfflineResult =\n | {\n status: CollabOfflineStatus;\n notify: true;\n message: string;\n }\n | {\n status: CollabOfflineStatus;\n notify: false;\n };\n\nexport type CollabSessionState = {\n markJoinBlocked(): void;\n markJoined(): CollabJoinResult;\n markOffline(reason: CollabOfflineReason): CollabOfflineResult;\n isBlocked(): boolean;\n};\n\nexport const createCollabSessionState = (): CollabSessionState => {\n let hasConnectedOnce = false;\n let collaborationBlocked = false;\n let serverOfflineNotified = false;\n\n return {\n markJoinBlocked() {\n collaborationBlocked = true;\n },\n markJoined() {\n const reconnected = hasConnectedOnce;\n hasConnectedOnce = true;\n serverOfflineNotified = false;\n\n return reconnected\n ? {\n reconnected: true,\n message: \"Connection restored and room state was resynced.\",\n }\n : {\n reconnected: false,\n };\n },\n markOffline(reason) {\n const status: CollabOfflineStatus =\n reason === \"disconnect\"\n ? hasConnectedOnce\n ? \"reconnecting\"\n : \"disconnected\"\n : hasConnectedOnce\n ? \"reconnecting\"\n : \"failed\";\n\n if (collaborationBlocked) {\n return { status: \"failed\", notify: false };\n }\n\n if (serverOfflineNotified) {\n return { status, notify: false };\n }\n\n if (reason === \"disconnect\" && !hasConnectedOnce) {\n return { status, notify: false };\n }\n\n serverOfflineNotified = true;\n return {\n status,\n notify: true,\n message:\n reason === \"disconnect\"\n ? \"The collaboration server disconnected. Local edits will sync when it reconnects.\"\n : \"The collaboration server is not reachable. Local edits stay in this browser.\",\n };\n },\n isBlocked() {\n return collaborationBlocked;\n },\n };\n};\n","import type {\n CollaborationCollaborator,\n CollaborationLiveSelection,\n} from \"./collaborationTypes\";\n\nconst clampOffset = (text: string, offset: number) => Math.max(0, Math.min(offset, text.length));\n\nexport const getLineNumberForPresenceOffset = (text: string, offset: number) => {\n const targetOffset = clampOffset(text, offset);\n let lineNumber = 1;\n\n for (let index = 0; index < targetOffset; index += 1) {\n if (text.charCodeAt(index) === 10) {\n lineNumber += 1;\n }\n }\n\n return lineNumber;\n};\n\nexport const getLineNumberForPresenceSelection = (text: string, selection?: CollaborationLiveSelection) => {\n if (!selection) {\n return null;\n }\n\n const metadataLineNumber = selection.lineNumber ?? selection.toLineNumber;\n if (typeof metadataLineNumber === \"number\" && Number.isInteger(metadataLineNumber) && metadataLineNumber > 0) {\n return metadataLineNumber;\n }\n\n return getLineNumberForPresenceOffset(text, selection.to);\n};\n\nexport const isCollaboratorInFile = (\n collaborator: CollaborationCollaborator,\n currentFileTitle?: string,\n currentRoomId?: string,\n currentDocumentId?: string,\n) => {\n const collaboratorDocumentId = collaborator.activeDocumentId ?? collaborator.selection?.documentId;\n if (currentDocumentId || collaboratorDocumentId) {\n return Boolean(currentDocumentId && collaboratorDocumentId === currentDocumentId);\n }\n\n if (currentRoomId && collaborator.roomId) {\n return collaborator.roomId === currentRoomId;\n }\n\n return !currentFileTitle || !collaborator.fileTitle || collaborator.fileTitle === currentFileTitle;\n};\n\nexport const getCollaboratorPresenceDetail = (\n collaborator: CollaborationCollaborator,\n text: string,\n currentFileTitle?: string,\n currentRoomId?: string,\n currentDocumentId?: string,\n) => {\n const collaboratorDocumentId = collaborator.activeDocumentId ?? collaborator.selection?.documentId;\n if (!collaboratorDocumentId && !collaborator.fileTitle) {\n return collaborator.kind === \"agent\" ? \"Agent in workspace\" : \"In workspace\";\n }\n\n if (!isCollaboratorInFile(collaborator, currentFileTitle, currentRoomId, currentDocumentId)) {\n return `${collaborator.kind === \"agent\" ? \"Agent viewing\" : \"Viewing\"} ${collaborator.fileTitle}`;\n }\n\n const lineNumber = getLineNumberForPresenceSelection(text, collaborator.selection);\n const prefix = collaborator.kind === \"agent\" ? \"Agent\" : \"\";\n const detail = lineNumber ? `Line ${lineNumber}` : \"In this file\";\n return prefix ? `${prefix} - ${detail}` : detail;\n};\n\nexport const getCollaboratorPresenceLabel = (collaborator: CollaborationCollaborator, text = \"\") => {\n const lineNumber = getLineNumberForPresenceSelection(text, collaborator.selection);\n const segments = [collaborator.name];\n\n if (collaborator.kind === \"agent\") {\n segments.push(\"agent\");\n }\n\n if (collaborator.fileTitle) {\n segments.push(collaborator.fileTitle);\n }\n\n if (lineNumber) {\n segments.push(`line ${lineNumber}`);\n }\n\n return segments.join(\" - \");\n};\n","// Shared line surface contract:\n// - source lines are 1-based lines backed by [start, end] document offsets; empty lines keep start === end and remain addressable.\n// - visual rows are measured rectangles normalized by source run and wrapped row order; one source line may become many visual rows.\n// - annotation rows consume source-line semantics first, then use DOM measurement only to place gutters and overlays.\nexport type LineSurfaceRectKind = \"text\" | \"empty-line\";\n\nexport type LineSurfaceRect = {\n kind: LineSurfaceRectKind;\n left: number;\n top: number;\n width: number;\n height: number;\n runIndex: number;\n};\n\nexport type LineSurfaceVisualRow<TRectangle extends LineSurfaceRect = LineSurfaceRect> = {\n runIndex: number;\n rowIndex: number;\n left: number;\n right: number;\n top: number;\n bottom: number;\n rectangles: TRectangle[];\n};\n\nexport type LineSurfaceSourceLine = {\n number: number;\n start: number;\n end: number;\n};\n\nexport type LineSurfaceSourceRange = {\n start: number;\n end: number;\n};\n\nexport type LineSurfaceAnnotation = {\n lineNumber: number;\n start: number;\n end: number;\n hasBookmark: boolean;\n hasComment: boolean;\n hasActiveComment?: boolean;\n};\n\nexport type LineSurfaceSourceBlock = {\n startLine: number;\n endLine: number;\n top: number;\n bottom: number;\n};\n\nexport type LineSurfaceRow<TAnnotation extends LineSurfaceAnnotation = LineSurfaceAnnotation> = TAnnotation & {\n top: number;\n height: number;\n};\n\nexport type LineSurfaceVisualRowOptions = {\n rowTolerance?: number;\n};\n\nexport type LineSurfaceAnnotationRowOptions = {\n fallbackHeight?: number;\n fallbackGap?: number;\n minRowHeight?: number;\n};\n\nconst defaultVisualRowOptions = {\n rowTolerance: 1,\n} satisfies Required<LineSurfaceVisualRowOptions>;\n\nconst defaultAnnotationRowOptions = {\n fallbackGap: 6,\n fallbackHeight: 24,\n minRowHeight: 20,\n} satisfies Required<LineSurfaceAnnotationRowOptions>;\n\nexport const getLineSurfaceRectRight = (rectangle: Pick<LineSurfaceRect, \"left\" | \"width\">) =>\n rectangle.left + rectangle.width;\n\nexport const getLineSurfaceRectBottom = (rectangle: Pick<LineSurfaceRect, \"top\" | \"height\">) =>\n rectangle.top + rectangle.height;\n\nconst clampSourcePosition = (position: number, docLength: number) =>\n Math.max(0, Math.min(position, Math.max(0, docLength)));\n\nconst normalizeSourceRange = (range: LineSurfaceSourceRange, docLength: number): LineSurfaceSourceRange => {\n const start = clampSourcePosition(Math.min(range.start, range.end), docLength);\n const end = clampSourcePosition(Math.max(range.start, range.end), docLength);\n return { start, end };\n};\n\nconst groupRectsByRun = <TRectangle extends LineSurfaceRect>(rectangles: TRectangle[]) => {\n const rectanglesByRun = new Map<number, TRectangle[]>();\n rectangles.forEach((rectangle) => {\n const runRectangles = rectanglesByRun.get(rectangle.runIndex);\n if (runRectangles) {\n runRectangles.push(rectangle);\n return;\n }\n\n rectanglesByRun.set(rectangle.runIndex, [rectangle]);\n });\n\n return rectanglesByRun;\n};\n\nexport const buildLineSurfaceVisualRows = <TRectangle extends LineSurfaceRect>(\n rectangles: TRectangle[],\n optionOverrides: LineSurfaceVisualRowOptions = {},\n) => {\n const options = { ...defaultVisualRowOptions, ...optionOverrides };\n const rows: LineSurfaceVisualRow<TRectangle>[] = [];\n\n groupRectsByRun(rectangles).forEach((runRectangles) => {\n const sortedRectangles = [...runRectangles].sort((first, second) => first.top - second.top || first.left - second.left);\n const rowGroups: { top: number; rectangles: TRectangle[] }[] = [];\n\n sortedRectangles.forEach((rectangle) => {\n const currentGroup = rowGroups[rowGroups.length - 1];\n if (!currentGroup || Math.abs(rectangle.top - currentGroup.top) > options.rowTolerance) {\n rowGroups.push({ top: rectangle.top, rectangles: [rectangle] });\n return;\n }\n\n currentGroup.rectangles.push(rectangle);\n currentGroup.top = Math.min(currentGroup.top, rectangle.top);\n });\n\n rowGroups.forEach((rowGroup, rowIndex) => {\n const top = rowGroup.top;\n const rawBottom = Math.max(...rowGroup.rectangles.map(getLineSurfaceRectBottom));\n const nextTop = rowGroups[rowIndex + 1]?.top;\n const bottom = typeof nextTop === \"number\" && nextTop > top ? nextTop : rawBottom;\n\n rows.push({\n runIndex: rowGroup.rectangles[0]?.runIndex ?? 0,\n rowIndex,\n left: Math.min(...rowGroup.rectangles.map((rectangle) => rectangle.left)),\n right: Math.max(...rowGroup.rectangles.map(getLineSurfaceRectRight)),\n top,\n bottom: top + Math.max(1, bottom - top),\n rectangles: rowGroup.rectangles,\n });\n });\n });\n\n return rows.sort((first, second) => first.runIndex - second.runIndex || first.rowIndex - second.rowIndex);\n};\n\nexport const lineSurfaceRowsAreAdjacent = (\n firstRow: Pick<LineSurfaceVisualRow, \"runIndex\" | \"rowIndex\"> | undefined,\n secondRow: Pick<LineSurfaceVisualRow, \"runIndex\" | \"rowIndex\"> | undefined,\n) => Boolean(firstRow && secondRow && firstRow.runIndex === secondRow.runIndex && firstRow.rowIndex + 1 === secondRow.rowIndex);\n\nexport const positionInSourceLine = (position: number, lineStart: number, lineEnd: number) =>\n lineStart === lineEnd ? position === lineStart : position >= lineStart && position <= lineEnd;\n\nexport const sourceRangeIntersectsLine = (\n range: LineSurfaceSourceRange,\n line: Pick<LineSurfaceSourceLine, \"start\" | \"end\">,\n) => {\n const start = Math.min(range.start, range.end);\n const end = Math.max(range.start, range.end);\n\n if (line.start === line.end) {\n return start <= line.start && end >= line.start;\n }\n\n if (start === end) {\n return positionInSourceLine(start, line.start, line.end);\n }\n\n return end > line.start && start < line.end;\n};\n\nexport const getLineNumberForSourcePosition = ({\n docLength,\n position,\n resolveLineAt,\n}: {\n docLength: number;\n position: number;\n resolveLineAt: (position: number) => Pick<LineSurfaceSourceLine, \"number\">;\n}) => resolveLineAt(clampSourcePosition(position, docLength)).number;\n\nexport const getLineNumbersForSourceRanges = ({\n docLength,\n ranges,\n resolveLineAt,\n}: {\n docLength: number;\n ranges: LineSurfaceSourceRange[];\n resolveLineAt: (position: number) => Pick<LineSurfaceSourceLine, \"number\">;\n}) => {\n const lineNumbers = new Set<number>();\n\n ranges.forEach((range) => {\n const normalizedRange = normalizeSourceRange(range, docLength);\n const startLine = resolveLineAt(normalizedRange.start).number;\n const endLine =\n normalizedRange.end > normalizedRange.start\n ? resolveLineAt(Math.max(normalizedRange.start, normalizedRange.end - 1)).number\n : startLine;\n\n for (let lineNumber = startLine; lineNumber <= endLine; lineNumber += 1) {\n lineNumbers.add(lineNumber);\n }\n });\n\n return lineNumbers;\n};\n\nexport const getLineSurfaceAnnotationsSignature = (annotations: LineSurfaceAnnotation[]) =>\n annotations\n .map((annotation) =>\n [\n annotation.lineNumber,\n annotation.start,\n annotation.end,\n annotation.hasBookmark ? 1 : 0,\n annotation.hasComment ? 1 : 0,\n annotation.hasActiveComment ? 1 : 0,\n ].join(\":\"),\n )\n .join(\"|\");\n\nexport const areLineSurfaceRowsEqual = <TRow extends LineSurfaceRow>(firstRows: TRow[], secondRows: TRow[]) =>\n firstRows.length === secondRows.length &&\n firstRows.every((firstRow, index) => {\n const secondRow = secondRows[index];\n return (\n firstRow.lineNumber === secondRow.lineNumber &&\n firstRow.start === secondRow.start &&\n firstRow.end === secondRow.end &&\n firstRow.hasBookmark === secondRow.hasBookmark &&\n firstRow.hasComment === secondRow.hasComment &&\n firstRow.hasActiveComment === secondRow.hasActiveComment &&\n Math.abs(firstRow.top - secondRow.top) < 0.5 &&\n Math.abs(firstRow.height - secondRow.height) < 0.5\n );\n });\n\nconst getFallbackLineTop = (\n lineNumber: number,\n sourceBlocks: LineSurfaceSourceBlock[],\n options: Required<LineSurfaceAnnotationRowOptions>,\n) => {\n const previousBlock = [...sourceBlocks].reverse().find((block) => block.endLine < lineNumber);\n const nextBlock = sourceBlocks.find((block) => block.startLine > lineNumber);\n if (previousBlock && nextBlock) {\n return previousBlock.bottom + Math.max(0, nextBlock.top - previousBlock.bottom) / 2 - options.fallbackHeight / 2;\n }\n\n if (previousBlock) {\n return previousBlock.bottom + options.fallbackGap;\n }\n\n if (nextBlock) {\n return Math.max(0, nextBlock.top - options.fallbackHeight - options.fallbackGap);\n }\n\n return 0;\n};\n\nexport const buildLineSurfaceAnnotationRows = <TAnnotation extends LineSurfaceAnnotation>(\n annotations: TAnnotation[],\n sourceBlocks: LineSurfaceSourceBlock[],\n optionOverrides: LineSurfaceAnnotationRowOptions = {},\n): LineSurfaceRow<TAnnotation>[] => {\n const options = { ...defaultAnnotationRowOptions, ...optionOverrides };\n\n return annotations\n .map((annotation) => {\n const matchingBlock = sourceBlocks.find(\n (block) => block.startLine <= annotation.lineNumber && block.endLine >= annotation.lineNumber,\n );\n\n if (!matchingBlock) {\n return {\n ...annotation,\n top: getFallbackLineTop(annotation.lineNumber, sourceBlocks, options),\n height: options.fallbackHeight,\n };\n }\n\n const sourceLineCount = Math.max(1, matchingBlock.endLine - matchingBlock.startLine + 1);\n const sourceLineHeight = Math.max(options.minRowHeight, (matchingBlock.bottom - matchingBlock.top) / sourceLineCount);\n return {\n ...annotation,\n top: matchingBlock.top + (annotation.lineNumber - matchingBlock.startLine) * sourceLineHeight,\n height: sourceLineHeight,\n };\n })\n .filter((row, index, rows) => rows.findIndex((candidate) => candidate.lineNumber === row.lineNumber) === index);\n};\n","import {\n positionInSourceLine,\n sourceRangeIntersectsLine,\n type LineSurfaceSourceRange,\n} from \"./lineSurfaceModel\";\n\nexport type CommentRuntimeAnchor = {\n id: string;\n start: number;\n end: number;\n};\n\nexport type CommentRuntimeBookmark = {\n id: string;\n position: number;\n createdAt: string;\n};\n\nexport type PreviewCommentAnchor = {\n id: string;\n start: number;\n end: number;\n};\n\nexport type PreviewLineAnnotation = {\n lineNumber: number;\n start: number;\n end: number;\n hasBookmark: boolean;\n hasComment: boolean;\n hasActiveComment: boolean;\n};\n\nexport const isPositionInLineRange = (\n position: number,\n lineStart: number,\n lineEnd: number,\n) => positionInSourceLine(position, lineStart, lineEnd);\n\nexport const toggleLineBookmarkInList = <\n TBookmark extends CommentRuntimeBookmark = CommentRuntimeBookmark,\n>({\n bookmarks,\n createId,\n lineStart,\n lineEnd,\n nowIso,\n}: {\n bookmarks: TBookmark[];\n createId: () => string;\n lineStart: number;\n lineEnd: number;\n nowIso: string;\n}): CommentRuntimeBookmark[] => {\n const existingBookmark = bookmarks.find((bookmark) =>\n isPositionInLineRange(bookmark.position, lineStart, lineEnd),\n );\n\n if (existingBookmark) {\n return bookmarks.filter((bookmark) => bookmark.id !== existingBookmark.id);\n }\n\n return [\n ...bookmarks,\n {\n id: createId(),\n position: lineStart,\n createdAt: nowIso,\n },\n ];\n};\n\nexport const getPreviewCommentAnchors = <\n TAnchor extends CommentRuntimeAnchor = CommentRuntimeAnchor,\n>({\n commentAnchors,\n previewBody,\n previewBodyStartOffset,\n}: {\n commentAnchors: TAnchor[];\n previewBody: string;\n previewBodyStartOffset: number;\n}): PreviewCommentAnchor[] =>\n commentAnchors\n .map((anchor) => ({\n id: anchor.id,\n start: anchor.start - previewBodyStartOffset,\n end: anchor.end - previewBodyStartOffset,\n }))\n .filter((anchor) => anchor.end > 0 && anchor.start < previewBody.length)\n .map((anchor) => ({\n ...anchor,\n start: Math.max(0, anchor.start),\n end: Math.min(previewBody.length, anchor.end),\n }))\n .filter((anchor) => anchor.end > anchor.start);\n\nexport const getPreviewLineAnnotations = <\n TBookmark extends Pick<CommentRuntimeBookmark, \"position\"> = CommentRuntimeBookmark,\n TAnchor extends CommentRuntimeAnchor = CommentRuntimeAnchor,\n>({\n body,\n bodyStartOffset,\n bookmarks,\n commentAnchors,\n activeCommentId,\n includeEmptyLines = true,\n}: {\n body: string;\n bodyStartOffset: number;\n bookmarks: TBookmark[];\n commentAnchors: TAnchor[];\n activeCommentId?: string | null;\n includeEmptyLines?: boolean;\n}): PreviewLineAnnotation[] => {\n const lines = body.split(\"\\n\");\n let bodyOffset = 0;\n\n return lines.flatMap((line, index) => {\n const start = bodyStartOffset + bodyOffset;\n const end = start + line.length;\n const sourceLine = { start, end };\n const hasBookmark = bookmarks.some((bookmark) =>\n positionInSourceLine(bookmark.position, start, end),\n );\n const lineComments = commentAnchors.filter((anchor) =>\n sourceRangeIntersectsLine(anchor, sourceLine),\n );\n bodyOffset += line.length + 1;\n\n if (!includeEmptyLines && !hasBookmark && lineComments.length === 0) {\n return [];\n }\n\n return [{\n lineNumber: index + 1,\n start,\n end,\n hasBookmark,\n hasComment: lineComments.length > 0,\n hasActiveComment: lineComments.some(\n (anchor) => anchor.id === activeCommentId,\n ),\n }];\n });\n};\n\nexport const getItemsInSourceLineRange = <TItem>({\n items,\n lineStart,\n lineEnd,\n resolveRange,\n}: {\n items: TItem[];\n lineStart: number;\n lineEnd: number;\n resolveRange: (item: TItem) => LineSurfaceSourceRange | null | undefined;\n}) =>\n items.filter((item) => {\n const range = resolveRange(item);\n return Boolean(\n range &&\n sourceRangeIntersectsLine(range, {\n start: lineStart,\n end: lineEnd,\n }),\n );\n });\n\nexport const formatCommentDate = (isoDate: string, now = Date.now()) => {\n const date = new Date(isoDate);\n if (Number.isNaN(date.getTime())) {\n return \"\";\n }\n\n const elapsedSeconds = Math.max(0, Math.floor((now - date.getTime()) / 1000));\n if (elapsedSeconds < 45) {\n return \"just now\";\n }\n\n const elapsedMinutes = Math.floor(elapsedSeconds / 60);\n if (elapsedMinutes < 60) {\n return `${elapsedMinutes} ${elapsedMinutes === 1 ? \"minute\" : \"minutes\"} ago`;\n }\n\n const elapsedHours = Math.floor(elapsedMinutes / 60);\n if (elapsedHours < 24) {\n return `${elapsedHours} ${elapsedHours === 1 ? \"hour\" : \"hours\"} ago`;\n }\n\n const elapsedDays = Math.floor(elapsedHours / 24);\n if (elapsedDays < 7) {\n return `${elapsedDays} ${elapsedDays === 1 ? \"day\" : \"days\"} ago`;\n }\n\n return new Intl.DateTimeFormat(undefined, {\n month: \"short\",\n day: \"numeric\",\n }).format(date);\n};\n","import {\n READING_WIDTHS,\n type FileViewMode,\n type ReadingWidth,\n} from \"./documentPrimitives\";\n\nexport type DocumentControlsCopy = {\n documentControlsLabel: string;\n edit: string;\n editorControls: string;\n fillWidth: string;\n focusWidth: string;\n layoutControls: string;\n lineNumbers: string;\n lineWrapping: string;\n preview: string;\n search: string;\n split: string;\n standardWidth: string;\n syncScrolling: string;\n textWidth: string;\n viewControls: string;\n};\n\nexport type DocumentViewModeIcon = \"edit\" | \"preview\" | \"split\";\n\nexport type DocumentViewModeOption = {\n active: boolean;\n icon: DocumentViewModeIcon;\n label: string;\n viewMode: FileViewMode;\n};\n\nexport type DocumentToggleControl = {\n active: boolean;\n label: string;\n};\n\nexport type DocumentReadingWidthOption = {\n active: boolean;\n label: string;\n readingWidth: ReadingWidth;\n};\n\nexport type DocumentControlsModel = {\n controlsLabel: string;\n documentControlsLabel: string;\n lineNumbers: DocumentToggleControl;\n lineWrapping: DocumentToggleControl;\n readingWidthLabel: string;\n readingWidthOptions: DocumentReadingWidthOption[];\n searchLabel: string;\n showEditorToggles: boolean;\n showSplitToggles: boolean;\n syncScrolling: DocumentToggleControl;\n viewModeLabel: string;\n viewModeOptions: DocumentViewModeOption[];\n};\n\nexport type DocumentControlsModelInput = {\n activeLineNumbers: boolean;\n activeLineWrapping: boolean;\n activeReadingWidth: ReadingWidth;\n activeSyncScrolling: boolean;\n activeViewMode: FileViewMode;\n copy: DocumentControlsCopy;\n};\n\nconst getControlsLabel = (\n activeViewMode: FileViewMode,\n copy: DocumentControlsCopy,\n) => {\n if (activeViewMode === \"preview\") {\n return copy.viewControls;\n }\n\n if (activeViewMode === \"split\") {\n return copy.layoutControls;\n }\n\n return copy.editorControls;\n};\n\nconst getViewModeOptions = (\n activeViewMode: FileViewMode,\n copy: DocumentControlsCopy,\n): DocumentViewModeOption[] => [\n { active: activeViewMode === \"edit\", icon: \"edit\", label: copy.edit, viewMode: \"edit\" },\n { active: activeViewMode === \"split\", icon: \"split\", label: copy.split, viewMode: \"split\" },\n { active: activeViewMode === \"preview\", icon: \"preview\", label: copy.preview, viewMode: \"preview\" },\n];\n\nexport const buildDocumentControlsModel = ({\n activeLineNumbers,\n activeLineWrapping,\n activeReadingWidth,\n activeSyncScrolling,\n activeViewMode,\n copy,\n}: DocumentControlsModelInput): DocumentControlsModel => {\n const readingWidthLabels: Record<ReadingWidth, string> = {\n narrow: copy.focusWidth,\n standard: copy.standardWidth,\n wide: copy.fillWidth,\n };\n\n return {\n controlsLabel: getControlsLabel(activeViewMode, copy),\n documentControlsLabel: copy.documentControlsLabel,\n lineNumbers: {\n active: activeLineNumbers,\n label: copy.lineNumbers,\n },\n lineWrapping: {\n active: activeLineWrapping,\n label: copy.lineWrapping,\n },\n readingWidthLabel: copy.textWidth,\n readingWidthOptions: READING_WIDTHS.map((readingWidth) => ({\n active: readingWidth === activeReadingWidth,\n label: readingWidthLabels[readingWidth],\n readingWidth,\n })),\n searchLabel: copy.search,\n showEditorToggles: activeViewMode !== \"preview\",\n showSplitToggles: activeViewMode === \"split\",\n syncScrolling: {\n active: activeSyncScrolling,\n label: copy.syncScrolling,\n },\n viewModeLabel: `${copy.documentControlsLabel}: ${copy.edit}, ${copy.split}, ${copy.preview}`,\n viewModeOptions: getViewModeOptions(activeViewMode, copy),\n };\n};\n","import type { FileViewMode, ReadingWidth } from \"./documentPrimitives\";\n\nconst classNames = (...parts: Array<string | false | undefined>) =>\n parts.filter(Boolean).join(\" \");\n\nexport type DocumentSurfaceDocumentState = {\n canCopy: boolean;\n canFormat: boolean;\n hasFile: boolean;\n lineNumbers: boolean;\n lineWrapping: boolean;\n readingWidth: ReadingWidth;\n title: string;\n viewMode: FileViewMode;\n wordCount: number;\n};\n\nexport type DocumentSurfaceState = {\n document: DocumentSurfaceDocumentState;\n hasSelectionActionPosition: boolean;\n searchOpen: boolean;\n selectedCharacterCount: number;\n shareOpen: boolean;\n splitDividerDragging: boolean;\n};\n\nexport const buildDocumentSurface = ({\n document,\n hasSelectionActionPosition,\n searchOpen,\n selectedCharacterCount,\n shareOpen,\n splitDividerDragging,\n}: DocumentSurfaceState) => {\n const documentModeClassName = `view-${document.viewMode} reading-${document.readingWidth}`;\n const lineNumbersClassName = document.lineNumbers\n ? \"line-numbers-on\"\n : \"line-numbers-off\";\n const lineWrappingClassName = document.lineWrapping\n ? \"line-wrapping-on\"\n : \"line-wrapping-off\";\n\n return {\n centerWorkbenchClassName: classNames(\n \"center-workbench\",\n document.hasFile ? `has-file ${documentModeClassName}` : \"empty\",\n document.hasFile && lineNumbersClassName,\n document.hasFile && lineWrappingClassName,\n ),\n documentControls: {\n activeLineNumbers: document.lineNumbers,\n activeLineWrapping: document.lineWrapping,\n activeReadingWidth: document.readingWidth,\n activeViewMode: document.viewMode,\n },\n documentToolbarClassName: classNames(\n \"document-toolbar-row\",\n document.viewMode,\n `reading-${document.readingWidth}`,\n document.canFormat && \"with-formatting\",\n ),\n editorSurfaceClassName: classNames(\n \"editor-surface\",\n lineNumbersClassName,\n lineWrappingClassName,\n selectedCharacterCount > 0 && \"has-text-selection\",\n ),\n fileShellClassName: classNames(\n \"file-shell\",\n document.hasFile ? documentModeClassName : \"empty\",\n document.hasFile && \"comments-enabled\",\n document.hasFile && lineNumbersClassName,\n document.hasFile && lineWrappingClassName,\n document.canFormat && \"with-format-toolbar\",\n searchOpen && \"with-search-row\",\n shareOpen && \"share-modal-open\",\n ),\n formattingToolbarClassName: classNames(\n document.viewMode,\n `reading-${document.readingWidth}`,\n ),\n showFormattingToolbar: document.canFormat,\n showSelectionCommentPopover: Boolean(\n document.hasFile &&\n selectedCharacterCount > 0 &&\n hasSelectionActionPosition,\n ),\n showSplitResizeHandle: document.viewMode === \"split\" && !shareOpen,\n statusBar: {\n activeFileTitle: document.title,\n activeViewMode: document.viewMode,\n wordCount: document.wordCount,\n },\n workspaceClassName: classNames(\n \"workspace\",\n document.viewMode,\n `reading-${document.readingWidth}`,\n splitDividerDragging && \"split-resizing\",\n ),\n };\n};\n\nexport type DocumentSurfaceModel = ReturnType<typeof buildDocumentSurface>;\n","import { applyTextPatches, type TextPatch } from \"./textPatches\";\n\nexport type PendingDocumentBufferCommit = {\n fileId: string;\n text?: string;\n};\n\nexport type DocumentBufferTextReader = () => string | null | undefined;\n\nexport type DocumentBufferTextState = {\n committedText: string;\n fileId: string;\n pending: boolean;\n pendingTextAvailable: boolean;\n visibleText: string;\n};\n\nexport type EditorDocumentRuntimeSnapshot = {\n committedText: string;\n dirty: boolean;\n fileId: string;\n pendingCommit: boolean;\n pendingTextAvailable: boolean;\n revision: number;\n text: string;\n};\n\nexport type EditorDocumentRuntimeFlushResult = {\n fileId: string;\n revision: number;\n text: string;\n};\n\nexport type EditorDocumentRuntime = {\n applyPatch(patches: readonly TextPatch[]): boolean;\n flush(): EditorDocumentRuntimeFlushResult | null;\n getSnapshot(): EditorDocumentRuntimeSnapshot;\n getText(): string;\n getVisibleText(): string;\n replaceAll(text: string): void;\n setPendingCommit(input: { readText?: DocumentBufferTextReader; text?: string }): void;\n syncCommitted(input: { fileId: string; revision?: number; text: string }): void;\n};\n\nexport const createPendingDocumentBufferCommit = (\n fileId: string,\n text?: string,\n): PendingDocumentBufferCommit => (\n text === undefined\n ? { fileId }\n : { fileId, text }\n);\n\nexport const resolvePendingDocumentBufferText = (\n pendingCommit: PendingDocumentBufferCommit,\n fallbackText: string,\n readPendingText?: DocumentBufferTextReader,\n) => {\n if (typeof pendingCommit.text === \"string\") {\n return pendingCommit.text;\n }\n\n const readText = readPendingText?.();\n return typeof readText === \"string\" ? readText : fallbackText;\n};\n\nexport const getDocumentBufferVisibleText = ({\n committedText,\n fileId,\n pendingCommit,\n readPendingText,\n}: {\n committedText: string;\n fileId: string;\n pendingCommit?: PendingDocumentBufferCommit | null;\n readPendingText?: DocumentBufferTextReader;\n}) => {\n if (pendingCommit?.fileId !== fileId) {\n return committedText;\n }\n\n return resolvePendingDocumentBufferText(pendingCommit, committedText, readPendingText);\n};\n\nexport const createDocumentBufferTextState = ({\n committedText,\n fileId,\n pendingCommit,\n readPendingText,\n}: {\n committedText: string;\n fileId: string;\n pendingCommit?: PendingDocumentBufferCommit | null;\n readPendingText?: DocumentBufferTextReader;\n}): DocumentBufferTextState => {\n const pending = pendingCommit?.fileId === fileId;\n const visibleText = pending\n ? resolvePendingDocumentBufferText(pendingCommit, committedText, readPendingText)\n : committedText;\n\n return {\n committedText,\n fileId,\n pending,\n pendingTextAvailable: pending && typeof pendingCommit.text === \"string\",\n visibleText,\n };\n};\n\nexport const shouldCancelPendingDocumentBufferCommit = (\n pendingCommit: PendingDocumentBufferCommit | null,\n activeDocument: { id: string; text: string } | undefined,\n) =>\n Boolean(\n activeDocument &&\n pendingCommit &&\n pendingCommit.fileId === activeDocument.id &&\n pendingCommit.text !== undefined &&\n activeDocument.text !== pendingCommit.text,\n );\n\nexport const createEditorDocumentRuntime = ({\n fileId: initialFileId,\n revision: initialRevision = 0,\n text: initialText,\n}: {\n fileId: string;\n revision?: number;\n text: string;\n}): EditorDocumentRuntime => {\n let committedText = initialText;\n let dirty = false;\n let fileId = initialFileId;\n let pendingCommit = false;\n let pendingReader: DocumentBufferTextReader | undefined;\n let pendingTextAvailable = false;\n let revision = initialRevision;\n let text = initialText;\n\n const replaceAll = (nextText: string) => {\n pendingReader = undefined;\n pendingCommit = true;\n pendingTextAvailable = true;\n if (nextText !== text) {\n text = nextText;\n revision += 1;\n }\n dirty = text !== committedText;\n };\n\n const getSnapshot = (): EditorDocumentRuntimeSnapshot => ({\n committedText,\n dirty,\n fileId,\n pendingCommit,\n pendingTextAvailable,\n revision,\n text,\n });\n\n const getVisibleText = () => {\n if (pendingReader) {\n const readText = pendingReader();\n if (typeof readText === \"string\") {\n return readText;\n }\n }\n\n return text;\n };\n\n return {\n applyPatch(patches) {\n const nextText = applyTextPatches(text, patches);\n if (typeof nextText !== \"string\") {\n return false;\n }\n\n replaceAll(nextText);\n return true;\n },\n\n flush() {\n if (pendingReader) {\n const readText = pendingReader();\n if (typeof readText === \"string\" && readText !== text) {\n text = readText;\n if (!dirty) {\n revision += 1;\n }\n }\n }\n\n pendingReader = undefined;\n pendingCommit = false;\n pendingTextAvailable = true;\n\n if (!dirty && text === committedText) {\n return null;\n }\n\n committedText = text;\n dirty = false;\n return { fileId, revision, text };\n },\n\n getSnapshot,\n getText: () => text,\n getVisibleText,\n replaceAll,\n\n setPendingCommit(input) {\n pendingCommit = true;\n pendingReader = input.readText;\n pendingTextAvailable = typeof input.text === \"string\";\n if (typeof input.text === \"string\") {\n replaceAll(input.text);\n return;\n }\n\n dirty = true;\n revision += 1;\n },\n\n syncCommitted(input) {\n fileId = input.fileId;\n committedText = input.text;\n text = input.text;\n dirty = false;\n pendingCommit = false;\n pendingReader = undefined;\n pendingTextAvailable = true;\n revision = input.revision ?? revision;\n },\n };\n};\n","export type JsonShareRoute = {\n snapshotId: string;\n key: string;\n};\n\nexport type JsonShareImportRoute =\n | {\n status: \"valid\";\n route: JsonShareRoute;\n routeKey: string;\n }\n | {\n status: \"invalid\";\n errorMessage: string;\n routeKey: string;\n };\n\nexport type JsonShareCreateResponse = {\n id: string;\n data: string;\n expiresAt?: string;\n};\n\nexport type JsonShareLocation = {\n hash: string;\n pathname: string;\n};\n\nexport const JSON_SHARE_KEY_BYTES = 32;\nexport const JSON_SHARE_ID_PATTERN = /^[A-Za-z0-9_-]+$/;\nexport const JSON_SHARE_API_PREFIX = \"/api/v2/\";\nexport const JSON_SHARE_POST_PATH = \"/api/v2/post/\";\n\nexport const trimTrailingSlash = (value: string) => value.replace(/\\/+$/, \"\");\n\nexport const createJsonShareUrl = (origin: string, snapshotId: string, key: string) =>\n `${origin}/#json=${snapshotId},${key}`;\n\nexport const parseJsonShareFromHash = (hash: string): JsonShareRoute | null => {\n const fragment = hash.replace(/^#/, \"\").trim();\n if (!fragment.startsWith(\"json=\")) {\n return null;\n }\n\n const jsonValue = fragment.slice(\"json=\".length);\n const [snapshotId, key, extra] = jsonValue.split(\",\");\n if (\n extra !== undefined ||\n jsonValue.includes(\"&\") ||\n !snapshotId ||\n !JSON_SHARE_ID_PATTERN.test(snapshotId) ||\n !key ||\n !JSON_SHARE_ID_PATTERN.test(key)\n ) {\n return null;\n }\n\n try {\n return decodeBase64Url(key).byteLength === JSON_SHARE_KEY_BYTES ? { snapshotId, key } : null;\n } catch {\n return null;\n }\n};\n\nexport const getJsonShareRoute = (location: JsonShareLocation): JsonShareRoute | null => {\n if (location.pathname !== \"/\") {\n return null;\n }\n return parseJsonShareFromHash(location.hash);\n};\n\nexport const getJsonShareImportRoute = (location: JsonShareLocation): JsonShareImportRoute | null => {\n if (location.pathname !== \"/\") {\n return null;\n }\n\n const fragment = location.hash.replace(/^#/, \"\").trim();\n if (!fragment.startsWith(\"json=\")) {\n return null;\n }\n\n const route = parseJsonShareFromHash(location.hash);\n if (route) {\n return {\n status: \"valid\",\n route,\n routeKey: `${route.snapshotId}:${route.key}`,\n };\n }\n\n const jsonValue = fragment.slice(\"json=\".length);\n const [snapshotId, key, extra] = jsonValue.split(\",\");\n const routeKey = `invalid:${jsonValue}`;\n if (!snapshotId || extra !== undefined || jsonValue.includes(\"&\") || !JSON_SHARE_ID_PATTERN.test(snapshotId)) {\n return {\n status: \"invalid\",\n routeKey,\n errorMessage: \"This export link is invalid.\",\n };\n }\n\n if (!key) {\n return {\n status: \"invalid\",\n routeKey,\n errorMessage: \"This export link is missing its client-only key.\",\n };\n }\n\n return {\n status: \"invalid\",\n routeKey,\n errorMessage: \"This export link has an invalid client-only key.\",\n };\n};\n\nexport const formatJsonShareUrlPreview = (url: string) => {\n try {\n const parsed = new URL(url);\n const [prefix] = parsed.hash.split(\",\");\n return `${parsed.host}/${prefix}...`;\n } catch {\n return url;\n }\n};\n\nexport const validateJsonShareCreateResponse = (\n value: unknown,\n serviceUrl: string,\n): JsonShareCreateResponse => {\n if (!isRecord(value)) {\n throw new Error(\"Share link failed: invalid service response\");\n }\n const id = requireNonEmptyString(value.id, \"id\");\n if (!JSON_SHARE_ID_PATTERN.test(id)) {\n throw new Error(\"Share link failed: invalid service response id\");\n }\n const data = requireNonEmptyString(value.data, \"data\");\n const expectedData = `${trimTrailingSlash(serviceUrl)}${JSON_SHARE_API_PREFIX}${id}`;\n if (data !== expectedData) {\n throw new Error(\"Share link failed: invalid service response data\");\n }\n const expiresAt = optionalIsoDateString(value.expiresAt, \"expiresAt\");\n return {\n id,\n data,\n ...(expiresAt ? { expiresAt } : {}),\n };\n};\n\nexport { decodeBase64Url, encodeBase64Url };\n\nconst requireString = (value: unknown, fieldName: string) => {\n if (typeof value !== \"string\") {\n throw new Error(`Share link failed: missing ${fieldName}`);\n }\n return value;\n};\n\nconst requireNonEmptyString = (value: unknown, fieldName: string) => {\n const text = requireString(value, fieldName);\n if (!text) {\n throw new Error(`Share link failed: missing ${fieldName}`);\n }\n return text;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst optionalIsoDateString = (value: unknown, fieldName: string) => {\n if (value === undefined) {\n return undefined;\n }\n const text = requireNonEmptyString(value, fieldName);\n if (!Number.isFinite(Date.parse(text))) {\n throw new Error(`Share link failed: invalid service response ${fieldName}`);\n }\n return text;\n};\nimport { decodeBase64Url, encodeBase64Url } from \"./data/base64Url\";\n","import {\n getMarkdownLineCount,\n type PreviewBlock,\n type PreviewBlockIndex,\n type PreviewBlockKind,\n type PreviewBlockMeasurements,\n} from \"./previewBlockModel\";\n\nexport type EditorScrollPosition = {\n atDocumentEnd: boolean;\n lineNumber: number;\n lineOffsetRatio: number;\n};\n\nexport type PreviewScrollTarget = {\n clamped: boolean;\n scrollTop: number;\n sourceLineNumber: number;\n sourceProgress: number;\n};\n\nexport type SourceScrollSegmentKind = PreviewBlockKind | \"document-end\" | \"frontmatter\";\n\nexport type SourceScrollSegment = {\n blockId?: string;\n id: string;\n kind: SourceScrollSegmentKind;\n measured: boolean;\n previewHeight: number;\n previewTop: number;\n renderable: boolean;\n sourceEndLine: number;\n sourceStartLine: number;\n};\n\nexport type SourceScrollMap = {\n lineCount: number;\n segments: SourceScrollSegment[];\n totalPreviewHeight: number;\n};\n\nexport type SourceScrollPosition = {\n atDocumentEnd: boolean;\n lineNumber: number;\n lineOffsetRatio: number;\n segmentId: string | null;\n segmentProgress: number;\n sourceProgress: number;\n};\n\nexport type BuildSourceScrollSegmentsMetadata = {\n frontmatterEstimatedHeight?: number;\n frontmatterLineCount?: number;\n frontmatterMeasuredHeight?: number;\n sourceLineCount?: number;\n sourceLineOffset?: number;\n};\n\nexport type SourceScrollTransferViewport = {\n edgePadding?: number;\n viewportHeight: number;\n};\n\nconst DEFAULT_FRONTMATTER_ESTIMATED_HEIGHT = 96;\nconst DEFAULT_EDGE_PADDING = 32;\n\nconst clamp = (value: number, minimum: number, maximum: number) =>\n Math.max(minimum, Math.min(maximum, value));\n\nconst normalizeLineNumber = (lineNumber: number, lineCount: number) =>\n clamp(Number.isFinite(lineNumber) ? Math.floor(lineNumber) : 1, 1, Math.max(1, lineCount));\n\nconst normalizeRatio = (ratio: number) =>\n clamp(Number.isFinite(ratio) ? ratio : 0, 0, 1);\n\nconst normalizeHeight = (height: number | undefined, fallback = 0) => {\n const normalizedHeight = height ?? fallback;\n return Number.isFinite(normalizedHeight) ? Math.max(0, normalizedHeight) : Math.max(0, fallback);\n};\n\nconst isPreviewBlockRenderableForTransfer = (block: PreviewBlock, previewHeight: number) =>\n block.kind !== \"blank\" && previewHeight > 0;\n\nconst clampPreviewScrollTop = (scrollTop: number, totalHeight: number, viewportHeight: number) => {\n const scrollableDistance = Math.max(0, totalHeight - Math.max(1, viewportHeight));\n const clampedScrollTop = clamp(scrollTop, 0, scrollableDistance);\n return {\n clamped: Math.abs(clampedScrollTop - scrollTop) > 0.5,\n scrollTop: clampedScrollTop,\n };\n};\n\nconst getSourceProgress = (lineNumber: number, lineOffsetRatio: number, lineCount: number) => {\n if (lineCount <= 1) {\n return lineOffsetRatio >= 1 ? 1 : 0;\n }\n\n return clamp((lineNumber - 1 + lineOffsetRatio) / lineCount, 0, 1);\n};\n\nconst findSegmentForLine = (\n segments: readonly SourceScrollSegment[],\n lineNumber: number,\n) =>\n segments.find(\n (segment) => segment.sourceStartLine <= lineNumber && segment.sourceEndLine >= lineNumber,\n ) ?? null;\n\nconst findSegmentById = (\n segments: readonly SourceScrollSegment[],\n segmentId: string | null,\n) => (segmentId ? segments.find((segment) => segment.id === segmentId) ?? null : null);\n\nconst getSegmentProgress = (\n segment: SourceScrollSegment,\n lineNumber: number,\n lineOffsetRatio: number,\n) => {\n const lineSpan = Math.max(1, segment.sourceEndLine - segment.sourceStartLine + 1);\n const lineOffset = clamp(lineNumber - segment.sourceStartLine + lineOffsetRatio, 0, lineSpan);\n return clamp(lineOffset / lineSpan, 0, 1);\n};\n\nconst getRenderableSegments = (segments: readonly SourceScrollSegment[]) =>\n segments.filter((segment) => segment.renderable && segment.previewHeight > 0);\n\nconst getNearestRenderableBoundary = (\n segments: readonly SourceScrollSegment[],\n sourceSegment: SourceScrollSegment | null,\n lineNumber: number,\n) => {\n const renderableSegments = getRenderableSegments(segments);\n if (renderableSegments.length === 0) {\n return 0;\n }\n\n if (!sourceSegment) {\n const nearestSegment = [...renderableSegments].sort((first, second) => {\n const firstDistance =\n lineNumber < first.sourceStartLine\n ? first.sourceStartLine - lineNumber\n : lineNumber - first.sourceEndLine;\n const secondDistance =\n lineNumber < second.sourceStartLine\n ? second.sourceStartLine - lineNumber\n : lineNumber - second.sourceEndLine;\n return firstDistance - secondDistance || first.sourceStartLine - second.sourceStartLine;\n })[0];\n return nearestSegment?.previewTop ?? 0;\n }\n\n const nextSegment = renderableSegments.find(\n (segment) => segment.sourceStartLine > sourceSegment.sourceEndLine,\n );\n if (nextSegment) {\n return nextSegment.previewTop;\n }\n\n for (let index = renderableSegments.length - 1; index >= 0; index -= 1) {\n const previousSegment = renderableSegments[index];\n if (previousSegment.sourceEndLine < sourceSegment.sourceStartLine) {\n return previousSegment.previewTop + previousSegment.previewHeight;\n }\n }\n\n return renderableSegments[0]?.previewTop ?? 0;\n};\n\nexport const buildSourceScrollSegments = (\n markdown: string,\n previewBlockIndex: PreviewBlockIndex,\n metadata: BuildSourceScrollSegmentsMetadata = {},\n): SourceScrollMap => {\n const sourceLineOffset = Math.max(0, Math.floor(metadata.sourceLineOffset ?? 0));\n const frontmatterLineCount = Math.max(\n 0,\n Math.floor(metadata.frontmatterLineCount ?? sourceLineOffset),\n );\n const frontmatterHeight = normalizeHeight(\n metadata.frontmatterMeasuredHeight,\n frontmatterLineCount > 0 ? metadata.frontmatterEstimatedHeight ?? DEFAULT_FRONTMATTER_ESTIMATED_HEIGHT : 0,\n );\n const bodyLineCount = getMarkdownLineCount(markdown);\n const lineCount = Math.max(\n 1,\n Math.floor(metadata.sourceLineCount ?? sourceLineOffset + bodyLineCount),\n frontmatterLineCount,\n ...previewBlockIndex.blocks.map((block) => block.endLine + sourceLineOffset),\n );\n\n let previewTop = 0;\n const segments: SourceScrollSegment[] = [];\n\n if (frontmatterLineCount > 0) {\n segments.push({\n id: \"frontmatter\",\n kind: \"frontmatter\",\n measured: typeof metadata.frontmatterMeasuredHeight === \"number\",\n previewHeight: frontmatterHeight,\n previewTop,\n renderable: frontmatterHeight > 0,\n sourceEndLine: frontmatterLineCount,\n sourceStartLine: 1,\n });\n previewTop += frontmatterHeight;\n }\n\n for (const block of previewBlockIndex.blocks) {\n const previewHeight = normalizeHeight(block.estimatedHeight);\n segments.push({\n blockId: block.id,\n id: `block:${block.id}`,\n kind: block.kind,\n measured: false,\n previewHeight,\n previewTop,\n renderable: isPreviewBlockRenderableForTransfer(block, previewHeight),\n sourceEndLine: Math.max(1, block.endLine + sourceLineOffset),\n sourceStartLine: Math.max(1, block.startLine + sourceLineOffset),\n });\n previewTop += previewHeight;\n }\n\n segments.push({\n id: \"document-end\",\n kind: \"document-end\",\n measured: true,\n previewHeight: 0,\n previewTop,\n renderable: false,\n sourceEndLine: lineCount,\n sourceStartLine: lineCount,\n });\n\n return {\n lineCount,\n segments,\n totalPreviewHeight: previewTop,\n };\n};\n\nexport const resolveSourcePosition = (\n editorPosition: EditorScrollPosition,\n sourceScrollMap: SourceScrollMap,\n): SourceScrollPosition => {\n const lineCount = Math.max(1, sourceScrollMap.lineCount);\n const lineNumber = editorPosition.atDocumentEnd\n ? lineCount\n : normalizeLineNumber(editorPosition.lineNumber, lineCount);\n const lineOffsetRatio = editorPosition.atDocumentEnd ? 1 : normalizeRatio(editorPosition.lineOffsetRatio);\n const segment = editorPosition.atDocumentEnd\n ? sourceScrollMap.segments.at(-1) ?? null\n : findSegmentForLine(sourceScrollMap.segments, lineNumber);\n const segmentProgress = segment ? getSegmentProgress(segment, lineNumber, lineOffsetRatio) : 0;\n const sourceProgress = editorPosition.atDocumentEnd\n ? 1\n : getSourceProgress(lineNumber, lineOffsetRatio, lineCount);\n\n return {\n atDocumentEnd: editorPosition.atDocumentEnd,\n lineNumber,\n lineOffsetRatio,\n segmentId: segment?.id ?? null,\n segmentProgress,\n sourceProgress,\n };\n};\n\nexport const getPreviewScrollTopForSourcePosition = (\n sourceScrollMap: SourceScrollMap,\n sourcePosition: SourceScrollPosition,\n viewport: SourceScrollTransferViewport,\n): PreviewScrollTarget => {\n const viewportHeight = Math.max(1, viewport.viewportHeight);\n const edgePadding = viewport.edgePadding ?? DEFAULT_EDGE_PADDING;\n const sourceLineNumber = normalizeLineNumber(sourcePosition.lineNumber, sourceScrollMap.lineCount);\n\n if (sourcePosition.atDocumentEnd) {\n const target = clampPreviewScrollTop(\n sourceScrollMap.totalPreviewHeight,\n sourceScrollMap.totalPreviewHeight,\n viewportHeight,\n );\n return {\n ...target,\n sourceLineNumber,\n sourceProgress: 1,\n };\n }\n\n const sourceSegment = findSegmentById(sourceScrollMap.segments, sourcePosition.segmentId);\n const rawScrollTop =\n sourceSegment && sourceSegment.renderable && sourceSegment.previewHeight > 0\n ? sourceSegment.previewTop + sourceSegment.previewHeight * sourcePosition.segmentProgress - edgePadding\n : getNearestRenderableBoundary(sourceScrollMap.segments, sourceSegment, sourceLineNumber) - edgePadding;\n const target = clampPreviewScrollTop(rawScrollTop, sourceScrollMap.totalPreviewHeight, viewportHeight);\n\n return {\n ...target,\n sourceLineNumber,\n sourceProgress: sourcePosition.sourceProgress,\n };\n};\n\nexport const getPreviewScrollTargetForEditorPosition = (\n markdown: string,\n previewBlockIndex: PreviewBlockIndex,\n editorPosition: EditorScrollPosition,\n viewport: SourceScrollTransferViewport,\n metadata: BuildSourceScrollSegmentsMetadata = {},\n) => {\n const sourceScrollMap = buildSourceScrollSegments(markdown, previewBlockIndex, metadata);\n const sourcePosition = resolveSourcePosition(editorPosition, sourceScrollMap);\n return getPreviewScrollTopForSourcePosition(sourceScrollMap, sourcePosition, viewport);\n};\n\nexport const applyPreviewSegmentMeasurements = (\n sourceScrollMap: SourceScrollMap,\n measurements: PreviewBlockMeasurements,\n): SourceScrollMap => {\n let previewTop = 0;\n const segments = sourceScrollMap.segments.map((segment) => {\n const measuredHeight =\n segment.blockId !== undefined ? measurements[segment.blockId] : measurements[segment.id];\n const previewHeight = normalizeHeight(measuredHeight, segment.previewHeight);\n const measuredSegment: SourceScrollSegment = {\n ...segment,\n measured: segment.measured || typeof measuredHeight === \"number\",\n previewHeight,\n previewTop,\n renderable: segment.kind !== \"blank\" && segment.kind !== \"document-end\" && previewHeight > 0,\n };\n previewTop += previewHeight;\n return measuredSegment;\n });\n\n return {\n ...sourceScrollMap,\n segments,\n totalPreviewHeight: previewTop,\n };\n};\n","export const TABULA_PRODUCT_SUPPORT_TARGETS = {\n betaMarkdownBytes: 150_000,\n launchMarkdownBytes: 1_000_000,\n collaborationMinPeople: 2,\n collaborationMaxPeople: 5,\n collaborationSoakDurationMs: 30 * 60 * 1000,\n} as const;\n\nexport const TABULA_LARGE_DOCUMENT_UX_POLICY = {\n editorResponsivenessFirst: true,\n splitViewPriority: \"editor-responsiveness\",\n previewRefresh: \"idle-only\",\n showTransientPreviewStatus: false,\n} as const;\n","export type MarkdownRangeSelection = {\n from: number;\n to: number;\n};\n\nexport type MarkdownRangeEdit = {\n from: number;\n to: number;\n insert: string;\n selection: MarkdownRangeSelection;\n};\n\nconst orderedMarkerPattern = /^(\\s*)(\\d+)(\\.\\s+)/;\nconst listMarkerPattern = /^(\\s*)(?:[-*+]\\s+\\[[ xX]\\]\\s+|[-*+]\\s+|\\d+\\.\\s+)/;\n\nconst getSelectedLineRange = (text: string, selection: MarkdownRangeSelection) => {\n const safeFrom = Math.max(0, Math.min(Math.min(selection.from, selection.to), text.length));\n const safeTo = Math.max(0, Math.min(Math.max(selection.from, selection.to), text.length));\n const lineStart = text.lastIndexOf(\"\\n\", Math.max(0, safeFrom - 1)) + 1;\n const selectedEnd = safeTo > safeFrom && text[safeTo - 1] === \"\\n\" ? safeTo - 1 : safeTo;\n const nextLineBreak = text.indexOf(\"\\n\", selectedEnd);\n const lineEnd = nextLineBreak === -1 ? text.length : nextLineBreak;\n\n return {\n from: lineStart,\n to: lineEnd,\n selectionFrom: safeFrom,\n selectionTo: safeTo,\n lines: text.slice(lineStart, lineEnd).split(\"\\n\"),\n };\n};\n\nconst getListLineIndentChange = (line: string, direction: \"indent\" | \"outdent\") => {\n const listMatch = line.match(listMarkerPattern);\n if (!listMatch) {\n return line;\n }\n\n if (direction === \"indent\") {\n return ` ${line}`;\n }\n\n const indent = listMatch[1];\n const removeCount = Math.min(2, indent.length);\n if (removeCount === 0) {\n return line;\n }\n\n return line.slice(removeCount);\n};\n\nconst getCommonPrefixLength = (left: string, right: string) => {\n let index = 0;\n while (index < left.length && index < right.length && left[index] === right[index]) {\n index += 1;\n }\n return index;\n};\n\nconst getCommonSuffixLength = (left: string, right: string, prefixLength: number) => {\n let length = 0;\n while (\n length + prefixLength < left.length &&\n length + prefixLength < right.length &&\n left[left.length - length - 1] === right[right.length - length - 1]\n ) {\n length += 1;\n }\n return length;\n};\n\nconst mapColumnThroughLineReplacement = (column: number, originalLine: string, nextLine: string) => {\n if (originalLine === nextLine) {\n return column;\n }\n\n const prefixLength = getCommonPrefixLength(originalLine, nextLine);\n const suffixLength = getCommonSuffixLength(originalLine, nextLine, prefixLength);\n const originalChangeEnd = originalLine.length - suffixLength;\n const nextChangeEnd = nextLine.length - suffixLength;\n\n if (column === prefixLength && originalChangeEnd === prefixLength && nextChangeEnd > prefixLength) {\n return nextChangeEnd;\n }\n\n if (column <= prefixLength) {\n return column;\n }\n\n if (column >= originalChangeEnd) {\n return Math.max(prefixLength, column + nextLine.length - originalLine.length);\n }\n\n return nextChangeEnd;\n};\n\nconst mapOffsetThroughLineReplacements = (\n offset: number,\n rangeStart: number,\n originalLines: string[],\n nextLines: string[],\n) => {\n let originalLineStart = 0;\n let nextLineStart = 0;\n\n for (let index = 0; index < originalLines.length; index += 1) {\n const originalLine = originalLines[index] ?? \"\";\n const nextLine = nextLines[index] ?? \"\";\n const originalLineEnd = originalLineStart + originalLine.length;\n\n if (offset <= rangeStart + originalLineEnd) {\n const column = Math.max(0, offset - rangeStart - originalLineStart);\n return rangeStart + nextLineStart + mapColumnThroughLineReplacement(column, originalLine, nextLine);\n }\n\n originalLineStart += originalLine.length + 1;\n nextLineStart += nextLine.length + 1;\n }\n\n return rangeStart + nextLines.join(\"\\n\").length;\n};\n\nconst renumberOrderedListRuns = (lines: string[]) => {\n const countersByIndent = new Map<string, number>();\n\n return lines.map((line) => {\n const orderedMatch = line.match(orderedMarkerPattern);\n if (!orderedMatch) {\n if (line.trim().length > 0) {\n countersByIndent.clear();\n }\n return line;\n }\n\n const indent = orderedMatch[1];\n const previousNumber = countersByIndent.get(indent);\n const nextNumber = previousNumber === undefined ? Number(orderedMatch[2]) : previousNumber + 1;\n countersByIndent.set(indent, nextNumber);\n\n for (const key of countersByIndent.keys()) {\n if (key.length > indent.length) {\n countersByIndent.delete(key);\n }\n }\n\n return `${indent}${nextNumber}${orderedMatch[3]}${line.slice(orderedMatch[0].length)}`;\n });\n};\n\nexport const getMarkdownIndentEdit = (\n text: string,\n selection: MarkdownRangeSelection,\n direction: \"indent\" | \"outdent\",\n): MarkdownRangeEdit | null => {\n const range = getSelectedLineRange(text, selection);\n const transformedLines = range.lines.map((line) => getListLineIndentChange(line, direction));\n const nextLines = renumberOrderedListRuns(transformedLines);\n const changed = nextLines.some((line, index) => line !== range.lines[index]);\n\n if (!changed) {\n return null;\n }\n\n const insert = nextLines.join(\"\\n\");\n return {\n from: range.from,\n to: range.to,\n insert,\n selection: {\n from: mapOffsetThroughLineReplacements(range.selectionFrom, range.from, range.lines, nextLines),\n to: mapOffsetThroughLineReplacements(range.selectionTo, range.from, range.lines, nextLines),\n },\n };\n};\n","import type { TextPatch } from \"../textPatches\";\n\nexport type MarkdownLink = {\n from: number;\n to: number;\n text: string;\n url: string;\n urlFrom: number;\n urlTo: number;\n isImage: boolean;\n isSafe: boolean;\n};\n\nexport type MarkdownLinkUrlEdit = {\n patch: TextPatch;\n selection: {\n from: number;\n to: number;\n };\n};\n\nconst markdownLinkPattern = /(!?)\\[([^\\]\\n]*(?:\\\\.[^\\]\\n]*)*)\\]\\(([^)\\s]+)\\)/g;\nconst safeMarkdownLinkUrlPattern = /^(?:https?:\\/\\/|mailto:|\\/(?!\\/)|#|\\.\\.?\\/)/i;\n\nexport const isSafeMarkdownLinkUrl = (url: string) => safeMarkdownLinkUrlPattern.test(url.trim());\n\nexport const getMarkdownLinks = (text: string): MarkdownLink[] =>\n Array.from(text.matchAll(markdownLinkPattern)).map((match) => {\n const fullMatch = match[0];\n const from = match.index ?? 0;\n const textStart = from + match[1].length + 1;\n const textEnd = textStart + match[2].length;\n const urlFrom = textEnd + 2;\n const url = match[3];\n const urlTo = urlFrom + url.length;\n\n return {\n from,\n to: from + fullMatch.length,\n text: match[2],\n url,\n urlFrom,\n urlTo,\n isImage: match[1] === \"!\",\n isSafe: isSafeMarkdownLinkUrl(url),\n };\n });\n\nexport const getMarkdownLinkAtOffset = (text: string, offset: number): MarkdownLink | null => {\n const safeOffset = Math.max(0, Math.min(offset, text.length));\n return (\n getMarkdownLinks(text).find(\n (link) => !link.isImage && safeOffset >= link.from && safeOffset <= link.to,\n ) ?? null\n );\n};\n\nexport const updateMarkdownLinkUrl = (\n text: string,\n linkFrom: number,\n nextUrl: string,\n): MarkdownLinkUrlEdit | null => {\n const link = getMarkdownLinks(text).find((candidate) => candidate.from === linkFrom && !candidate.isImage);\n if (!link || link.url === nextUrl) {\n return null;\n }\n\n return {\n patch: {\n from: link.urlFrom,\n to: link.urlTo,\n insert: nextUrl,\n },\n selection: {\n from: link.urlFrom,\n to: link.urlFrom + nextUrl.length,\n },\n };\n};\n","import type { TextPatch } from \"../textPatches\";\n\nexport type MarkdownTaskMarker = {\n lineStart: number;\n lineEnd: number;\n markerStart: number;\n markerEnd: number;\n stateStart: number;\n stateEnd: number;\n checked: boolean;\n};\n\nexport type MarkdownTaskToggleEdit = {\n patch: TextPatch;\n selection: {\n from: number;\n to: number;\n };\n};\n\nconst taskMarkerPattern = /^(\\s*[-*+]\\s+\\[)([ xX])(\\]\\s+)/;\n\nconst getLineRanges = (text: string) => {\n const ranges: Array<{ start: number; end: number; text: string }> = [];\n let start = 0;\n\n while (start <= text.length) {\n const lineBreak = text.indexOf(\"\\n\", start);\n const end = lineBreak === -1 ? text.length : lineBreak;\n ranges.push({ start, end, text: text.slice(start, end) });\n if (lineBreak === -1) {\n break;\n }\n start = lineBreak + 1;\n }\n\n return ranges;\n};\n\nexport const getMarkdownTaskMarkers = (text: string): MarkdownTaskMarker[] =>\n getLineRanges(text)\n .map((line) => {\n const match = line.text.match(taskMarkerPattern);\n if (!match) {\n return null;\n }\n\n const stateStart = line.start + match[1].length;\n return {\n lineStart: line.start,\n lineEnd: line.end,\n markerStart: line.start + match[1].length - 1,\n markerEnd: line.start + match[0].length,\n stateStart,\n stateEnd: stateStart + 1,\n checked: match[2].toLowerCase() === \"x\",\n };\n })\n .filter((marker): marker is MarkdownTaskMarker => marker !== null);\n\nexport const getMarkdownTaskAtOffset = (text: string, offset: number): MarkdownTaskMarker | null => {\n const safeOffset = Math.max(0, Math.min(offset, text.length));\n return (\n getMarkdownTaskMarkers(text).find(\n (marker) => safeOffset >= marker.markerStart && safeOffset <= marker.markerEnd,\n ) ?? null\n );\n};\n\nexport const toggleMarkdownTaskAtOffset = (text: string, offset: number): MarkdownTaskToggleEdit | null => {\n const task = getMarkdownTaskAtOffset(text, offset);\n if (!task) {\n return null;\n }\n\n const insert = task.checked ? \" \" : \"x\";\n return {\n patch: {\n from: task.stateStart,\n to: task.stateEnd,\n insert,\n },\n selection: {\n from: task.stateStart,\n to: task.stateStart + insert.length,\n },\n };\n};\n\nexport const toggleMarkdownTaskOnLine = (text: string, lineStart: number): MarkdownTaskToggleEdit | null => {\n const safeLineStart = Math.max(0, Math.min(lineStart, text.length));\n const task = getMarkdownTaskMarkers(text).find((marker) => marker.lineStart === safeLineStart);\n if (!task) {\n return null;\n }\n\n const insert = task.checked ? \" \" : \"x\";\n return {\n patch: {\n from: task.stateStart,\n to: task.stateEnd,\n insert,\n },\n selection: {\n from: task.stateStart,\n to: task.stateStart + insert.length,\n },\n };\n};\n","export type MarkdownFormatCommand =\n | \"bold\"\n | \"italic\"\n | \"strikethrough\"\n | \"inline-code\"\n | \"link\"\n | \"image\"\n | \"quote\"\n | \"heading-1\"\n | \"heading-2\"\n | \"heading-3\"\n | \"bullet-list\"\n | \"numbered-list\"\n | \"check-list\"\n | \"horizontal-rule\"\n | \"code-block\"\n | \"table\"\n | \"frontmatter\"\n | \"footnote\"\n | \"clear-formatting\";\n\nexport type MarkdownFormatSelection = {\n from: number;\n to: number;\n};\n\nexport type MarkdownFormatResult = {\n text: string;\n selection: MarkdownFormatSelection;\n};\n\ntype InlineWrapOptions = {\n prefix: string;\n suffix?: string;\n placeholder: string;\n};\n\nconst clampOffset = (offset: number, textLength: number) => Math.max(0, Math.min(offset, textLength));\n\nconst normalizeSelection = (text: string, selection: MarkdownFormatSelection): MarkdownFormatSelection => {\n const from = clampOffset(Math.min(selection.from, selection.to), text.length);\n const to = clampOffset(Math.max(selection.from, selection.to), text.length);\n return { from, to };\n};\n\nconst replaceTextRange = (\n text: string,\n from: number,\n to: number,\n insertion: string,\n selectionFrom: number,\n selectionTo: number,\n): MarkdownFormatResult => ({\n text: `${text.slice(0, from)}${insertion}${text.slice(to)}`,\n selection: {\n from: selectionFrom,\n to: selectionTo,\n },\n});\n\nconst wrapInlineSelection = (\n text: string,\n selection: MarkdownFormatSelection,\n { prefix, suffix = prefix, placeholder }: InlineWrapOptions,\n) => {\n const { from, to } = normalizeSelection(text, selection);\n const selectedText = text.slice(from, to);\n\n if (!selectedText) {\n const insertion = `${prefix}${placeholder}${suffix}`;\n const selectionFrom = from + prefix.length;\n return replaceTextRange(text, from, to, insertion, selectionFrom, selectionFrom + placeholder.length);\n }\n\n const outerFrom = from - prefix.length;\n const outerTo = to + suffix.length;\n const hasOuterWrap =\n outerFrom >= 0 && text.slice(outerFrom, from) === prefix && text.slice(to, outerTo) === suffix;\n if (hasOuterWrap) {\n return replaceTextRange(text, outerFrom, outerTo, selectedText, outerFrom, outerFrom + selectedText.length);\n }\n\n const hasSelectedWrap = selectedText.startsWith(prefix) && selectedText.endsWith(suffix);\n if (hasSelectedWrap && selectedText.length >= prefix.length + suffix.length) {\n const innerText = selectedText.slice(prefix.length, selectedText.length - suffix.length);\n return replaceTextRange(text, from, to, innerText, from, from + innerText.length);\n }\n\n const insertion = `${prefix}${selectedText}${suffix}`;\n const selectionFrom = from + prefix.length;\n return replaceTextRange(text, from, to, insertion, selectionFrom, selectionFrom + selectedText.length);\n};\n\nconst insertLink = (text: string, selection: MarkdownFormatSelection) => {\n const { from, to } = normalizeSelection(text, selection);\n const selectedText = text.slice(from, to) || \"link\";\n const insertion = `[${selectedText}](url)`;\n const urlFrom = from + selectedText.length + 3;\n return replaceTextRange(text, from, to, insertion, urlFrom, urlFrom + 3);\n};\n\nconst insertImage = (text: string, selection: MarkdownFormatSelection) => {\n const { from, to } = normalizeSelection(text, selection);\n const selectedText = text.slice(from, to) || \"image alt\";\n const insertion = `![${selectedText}](image-url)`;\n const urlFrom = from + selectedText.length + 4;\n return replaceTextRange(text, from, to, insertion, urlFrom, urlFrom + \"image-url\".length);\n};\n\nconst getSelectedLineRange = (text: string, selection: MarkdownFormatSelection) => {\n const { from, to } = normalizeSelection(text, selection);\n const lineStart = text.lastIndexOf(\"\\n\", Math.max(0, from - 1)) + 1;\n const selectedEnd = to > from && text[to - 1] === \"\\n\" ? to - 1 : to;\n const nextLineBreak = text.indexOf(\"\\n\", selectedEnd);\n const lineEnd = nextLineBreak === -1 ? text.length : nextLineBreak;\n\n return {\n from: lineStart,\n to: lineEnd,\n lines: text.slice(lineStart, lineEnd).split(\"\\n\"),\n };\n};\n\nconst replaceSelectedLines = (\n text: string,\n selection: MarkdownFormatSelection,\n transformLines: (lines: string[]) => string[],\n) => {\n const range = getSelectedLineRange(text, selection);\n const insertion = transformLines(range.lines).join(\"\\n\");\n return replaceTextRange(text, range.from, range.to, insertion, range.from, range.from + insertion.length);\n};\n\nconst replaceEmptySelectedLine = (\n text: string,\n selection: MarkdownFormatSelection,\n insertion: string,\n placeholderFrom: number,\n placeholderLength: number,\n) => {\n const normalizedSelection = normalizeSelection(text, selection);\n const range = getSelectedLineRange(text, selection);\n if (\n normalizedSelection.from !== normalizedSelection.to ||\n range.lines.length !== 1 ||\n range.lines[0] !== \"\"\n ) {\n return null;\n }\n\n const selectionFrom = range.from + placeholderFrom;\n return replaceTextRange(text, range.from, range.to, insertion, selectionFrom, selectionFrom + placeholderLength);\n};\n\nconst stripListMarker = (line: string) => {\n const match = line.match(/^(\\s*)(?:- \\[[ xX]\\]\\s+|\\d+\\.\\s+|[-*+]\\s+)?(.*)$/);\n if (!match) {\n return { indent: \"\", content: line };\n }\n\n return {\n indent: match[1],\n content: match[2],\n };\n};\n\nconst isNonEmptyLine = (line: string) => line.trim().length > 0;\n\nconst applyHeading = (text: string, selection: MarkdownFormatSelection, depth: 1 | 2 | 3) =>\n replaceEmptySelectedLine(\n text,\n selection,\n `${\"#\".repeat(depth)} Heading`,\n depth + 1,\n \"Heading\".length,\n ) ??\n replaceSelectedLines(text, selection, (lines) => {\n const marker = \"#\".repeat(depth);\n const nonEmptyLines = lines.filter(isNonEmptyLine);\n const shouldRemove =\n nonEmptyLines.length > 0 &&\n nonEmptyLines.every((line) => new RegExp(`^#{${depth}}\\\\s+`).test(line.trimStart()));\n\n return lines.map((line) => {\n if (!isNonEmptyLine(line)) {\n return line;\n }\n\n const indent = line.match(/^\\s*/)?.[0] ?? \"\";\n const content = line.trimStart().replace(/^#{1,6}\\s+/, \"\");\n return shouldRemove ? `${indent}${content}` : `${indent}${marker} ${content}`;\n });\n });\n\nconst applyQuote = (text: string, selection: MarkdownFormatSelection) =>\n replaceEmptySelectedLine(text, selection, \"> quote\", 2, \"quote\".length) ??\n replaceSelectedLines(text, selection, (lines) => {\n const shouldRemove = lines.some(isNonEmptyLine) && lines.filter(isNonEmptyLine).every((line) => /^>\\s?/.test(line));\n return lines.map((line) => (shouldRemove ? line.replace(/^>\\s?/, \"\") : `> ${line}`));\n });\n\nconst applyBulletList = (text: string, selection: MarkdownFormatSelection) =>\n replaceEmptySelectedLine(text, selection, \"- item\", 2, \"item\".length) ??\n replaceSelectedLines(text, selection, (lines) => {\n const nonEmptyLines = lines.filter(isNonEmptyLine);\n const shouldRemove = nonEmptyLines.length > 0 && nonEmptyLines.every((line) => /^\\s*[-*+]\\s+/.test(line));\n return lines.map((line) => {\n if (!isNonEmptyLine(line)) {\n return line;\n }\n\n const { indent, content } = stripListMarker(line);\n return shouldRemove ? `${indent}${content}` : `${indent}- ${content}`;\n });\n });\n\nconst applyNumberedList = (text: string, selection: MarkdownFormatSelection) =>\n replaceEmptySelectedLine(text, selection, \"1. item\", 3, \"item\".length) ??\n replaceSelectedLines(text, selection, (lines) => {\n const nonEmptyLines = lines.filter(isNonEmptyLine);\n const shouldRemove = nonEmptyLines.length > 0 && nonEmptyLines.every((line) => /^\\s*\\d+\\.\\s+/.test(line));\n let number = 1;\n\n return lines.map((line) => {\n if (!isNonEmptyLine(line)) {\n return line;\n }\n\n const { indent, content } = stripListMarker(line);\n if (shouldRemove) {\n return `${indent}${content}`;\n }\n\n const nextLine = `${indent}${number}. ${content}`;\n number += 1;\n return nextLine;\n });\n });\n\nconst applyCheckList = (text: string, selection: MarkdownFormatSelection) =>\n replaceEmptySelectedLine(text, selection, \"- [ ] item\", 6, \"item\".length) ??\n replaceSelectedLines(text, selection, (lines) => {\n const nonEmptyLines = lines.filter(isNonEmptyLine);\n const shouldRemove =\n nonEmptyLines.length > 0 && nonEmptyLines.every((line) => /^\\s*- \\[[ xX]\\]\\s+/.test(line));\n\n return lines.map((line) => {\n if (!isNonEmptyLine(line)) {\n return line;\n }\n\n const { indent, content } = stripListMarker(line);\n return shouldRemove ? `${indent}${content}` : `${indent}- [ ] ${content}`;\n });\n });\n\nconst isHorizontalRuleLine = (line: string) => /^\\s*(?:---|\\*\\*\\*|___)\\s*$/.test(line);\n\nconst applyHorizontalRule = (text: string, selection: MarkdownFormatSelection) => {\n const normalizedSelection = normalizeSelection(text, selection);\n const range = getSelectedLineRange(text, normalizedSelection);\n const nonEmptyLines = range.lines.filter(isNonEmptyLine);\n\n if (nonEmptyLines.length > 0 && nonEmptyLines.every(isHorizontalRuleLine)) {\n return replaceTextRange(text, range.from, range.to, \"\", range.from, range.from);\n }\n\n if (\n normalizedSelection.from === normalizedSelection.to &&\n range.lines.length === 1 &&\n range.lines[0].trim().length === 0\n ) {\n return replaceTextRange(text, range.from, range.to, \"---\", range.from + 3, range.from + 3);\n }\n\n const insertAt = range.to;\n const before = text.slice(0, insertAt);\n const after = text.slice(insertAt);\n const leadingBreak = before.length === 0 ? \"\" : before.endsWith(\"\\n\\n\") ? \"\" : before.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n const trailingBreak = after.length === 0 ? \"\" : after.startsWith(\"\\n\\n\") ? \"\" : after.startsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n const insertion = `${leadingBreak}---${trailingBreak}`;\n const selectionOffset = insertAt + leadingBreak.length + 3;\n\n return replaceTextRange(text, insertAt, insertAt, insertion, selectionOffset, selectionOffset);\n};\n\nconst applyCodeBlock = (text: string, selection: MarkdownFormatSelection) => {\n const { from, to } = normalizeSelection(text, selection);\n const selectedText = text.slice(from, to);\n const selectedFenceMatch = selectedText.match(/^```[^\\n]*\\n([\\s\\S]*?)\\n```$/);\n\n if (selectedFenceMatch) {\n const innerText = selectedFenceMatch[1];\n return replaceTextRange(text, from, to, innerText, from, from + innerText.length);\n }\n\n const codeText = selectedText || \"code\";\n const languagePlaceholder = \"language\";\n const insertion = `\\`\\`\\`${languagePlaceholder}\\n${codeText}\\n\\`\\`\\``;\n const selectionFrom = from + 3;\n return replaceTextRange(\n text,\n from,\n to,\n insertion,\n selectionFrom,\n selectionFrom + languagePlaceholder.length,\n );\n};\n\nconst insertBlockAtSelection = (\n text: string,\n selection: MarkdownFormatSelection,\n block: string,\n selectionOffset: number,\n selectionLength: number,\n) => {\n const { from, to } = normalizeSelection(text, selection);\n const before = text.slice(0, from);\n const after = text.slice(to);\n const leadingBreak = before.length === 0 ? \"\" : before.endsWith(\"\\n\\n\") ? \"\" : before.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n const trailingBreak = after.length === 0 ? \"\" : after.startsWith(\"\\n\\n\") ? \"\" : after.startsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n const insertion = `${leadingBreak}${block}${trailingBreak}`;\n const selectionFrom = from + leadingBreak.length + selectionOffset;\n return replaceTextRange(\n text,\n from,\n to,\n insertion,\n selectionFrom,\n selectionFrom + selectionLength,\n );\n};\n\nconst insertTable = (text: string, selection: MarkdownFormatSelection) =>\n insertBlockAtSelection(\n text,\n selection,\n \"| Column 1 | Column 2 |\\n| --- | --- |\\n| Value 1 | Value 2 |\",\n 2,\n \"Column 1\".length,\n );\n\nconst insertFrontmatter = (text: string, selection: MarkdownFormatSelection) => {\n const { from, to } = normalizeSelection(text, selection);\n const insertion = \"---\\ntitle: Untitled\\n---\\n\\n\";\n const selectionFrom = \"title: \".length + 4;\n if (from === 0 && to === 0) {\n return replaceTextRange(text, 0, 0, insertion, selectionFrom, selectionFrom + \"Untitled\".length);\n }\n\n return insertBlockAtSelection(text, selection, \"---\\ntitle: Untitled\\n---\", \"title: \".length + 4, \"Untitled\".length);\n};\n\nconst insertFootnote = (text: string, selection: MarkdownFormatSelection) => {\n const { from, to } = normalizeSelection(text, selection);\n const selectedText = text.slice(from, to) || \"note\";\n const insertion = `[^1]\\n\\n[^1]: ${selectedText}`;\n const selectionFrom = from + insertion.length - selectedText.length;\n return replaceTextRange(text, from, to, insertion, selectionFrom, selectionFrom + selectedText.length);\n};\n\nconst clearInlineFormatting = (value: string) =>\n value\n .replace(/\\*\\*([^*\\n]+)\\*\\*/g, \"$1\")\n .replace(/__([^_\\n]+)__/g, \"$1\")\n .replace(/~~([^~\\n]+)~~/g, \"$1\")\n .replace(/`([^`\\n]+)`/g, \"$1\")\n .replace(/!\\[([^\\]\\n]*)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/\\[([^\\]\\n]+)\\]\\([^)]+\\)/g, \"$1\")\n .replace(/(^|[^*])\\*([^*\\n]+)\\*(?!\\*)/g, \"$1$2\")\n .replace(/(^|[^_])_([^_\\n]+)_(?!_)/g, \"$1$2\");\n\nconst clearLineFormatting = (line: string) => {\n const withoutBlockMarker = line\n .replace(/^(\\s*)#{1,6}\\s+/, \"$1\")\n .replace(/^(\\s*)>\\s?/, \"$1\")\n .replace(/^(\\s*)(?:- \\[[ xX]\\]\\s+|\\d+\\.\\s+|[-*+]\\s+)/, \"$1\");\n return clearInlineFormatting(withoutBlockMarker);\n};\n\nconst clearFormatting = (text: string, selection: MarkdownFormatSelection) => {\n const { from, to } = normalizeSelection(text, selection);\n if (from === to) {\n return { text, selection: { from, to } };\n }\n\n const selectedText = text.slice(from, to);\n const cleanedText = selectedText\n .split(\"\\n\")\n .map(clearLineFormatting)\n .join(\"\\n\");\n return replaceTextRange(text, from, to, cleanedText, from, from + cleanedText.length);\n};\n\nexport const applyMarkdownFormat = (\n text: string,\n selection: MarkdownFormatSelection,\n command: MarkdownFormatCommand,\n): MarkdownFormatResult => {\n switch (command) {\n case \"bold\":\n return wrapInlineSelection(text, selection, { prefix: \"**\", placeholder: \"bold text\" });\n case \"italic\":\n return wrapInlineSelection(text, selection, { prefix: \"_\", placeholder: \"italic text\" });\n case \"strikethrough\":\n return wrapInlineSelection(text, selection, { prefix: \"~~\", placeholder: \"struck text\" });\n case \"inline-code\":\n return wrapInlineSelection(text, selection, { prefix: \"`\", placeholder: \"code\" });\n case \"link\":\n return insertLink(text, selection);\n case \"image\":\n return insertImage(text, selection);\n case \"quote\":\n return applyQuote(text, selection);\n case \"heading-1\":\n return applyHeading(text, selection, 1);\n case \"heading-2\":\n return applyHeading(text, selection, 2);\n case \"heading-3\":\n return applyHeading(text, selection, 3);\n case \"bullet-list\":\n return applyBulletList(text, selection);\n case \"numbered-list\":\n return applyNumberedList(text, selection);\n case \"check-list\":\n return applyCheckList(text, selection);\n case \"horizontal-rule\":\n return applyHorizontalRule(text, selection);\n case \"code-block\":\n return applyCodeBlock(text, selection);\n case \"table\":\n return insertTable(text, selection);\n case \"frontmatter\":\n return insertFrontmatter(text, selection);\n case \"footnote\":\n return insertFootnote(text, selection);\n case \"clear-formatting\":\n return clearFormatting(text, selection);\n }\n};\n","export type CommentScope = \"current\" | \"all\";\n\nexport type RightPanelCommentFile = {\n id: string;\n title: string;\n};\n\nexport type RightPanelComment = {\n id: string;\n createdAt: string;\n resolved?: boolean;\n replies?: {\n id?: string;\n body?: string;\n createdAt: string;\n }[];\n};\n\nexport type RightPanelCommentGroup<\n TFile extends RightPanelCommentFile = RightPanelCommentFile,\n TComment extends RightPanelComment = RightPanelComment,\n> = {\n file: TFile;\n comments: TComment[];\n};\n\ntype RightPanelCommentGroups<\n TFile extends RightPanelCommentFile,\n TComment extends RightPanelComment,\n> = {\n openCommentGroups: RightPanelCommentGroup<TFile, TComment>[];\n resolvedCommentGroups: RightPanelCommentGroup<TFile, TComment>[];\n};\n\ntype RightPanelCommentScopeModelArgs<\n TFile extends RightPanelCommentFile,\n TComment extends RightPanelComment,\n> = {\n activeFileId: string;\n openCommentGroups: RightPanelCommentGroup<TFile, TComment>[];\n resolvedCommentGroups: RightPanelCommentGroup<TFile, TComment>[];\n commentScope: CommentScope;\n};\n\nexport const stripMarkdownExtension = (title: string) => title.replace(/\\.md$/i, \"\");\n\nconst getFileComments = <TComment extends RightPanelComment>(\n commentsByFileId: Record<string, TComment[]>,\n fileId: string,\n) =>\n commentsByFileId[fileId] ?? [];\n\nconst getCommentActivityTime = (comment: RightPanelComment) => {\n const replyTimes = (comment.replies ?? []).map((reply) => Date.parse(reply.createdAt)).filter(Number.isFinite);\n return Math.max(Date.parse(comment.createdAt) || 0, ...replyTimes);\n};\n\nconst getGroupActivityTime = (group: RightPanelCommentGroup) =>\n Math.max(0, ...group.comments.map((comment) => getCommentActivityTime(comment)));\n\nconst sortCommentGroupsByActivity = <\n TFile extends RightPanelCommentFile,\n TComment extends RightPanelComment,\n>(\n groups: RightPanelCommentGroup<TFile, TComment>[],\n) =>\n groups\n .map((group) => ({\n ...group,\n comments: [...group.comments].sort((first, second) => getCommentActivityTime(second) - getCommentActivityTime(first)),\n }))\n .sort((first, second) => getGroupActivityTime(second) - getGroupActivityTime(first));\n\nexport const getRightPanelCommentGroups = <\n TFile extends RightPanelCommentFile,\n TComment extends RightPanelComment,\n>(\n files: TFile[],\n commentsByFileId: Record<string, TComment[]>,\n): RightPanelCommentGroups<TFile, TComment> => {\n const openCommentGroups = files\n .map((file) => ({\n file,\n comments: getFileComments(commentsByFileId, file.id).filter((comment) => !comment.resolved),\n }))\n .filter((group) => group.comments.length > 0);\n const resolvedCommentGroups = files\n .map((file) => ({\n file,\n comments: getFileComments(commentsByFileId, file.id).filter((comment) => comment.resolved),\n }))\n .filter((group) => group.comments.length > 0);\n\n return {\n openCommentGroups,\n resolvedCommentGroups,\n };\n};\n\nexport const getRightPanelCommentScopeModel = <\n TFile extends RightPanelCommentFile,\n TComment extends RightPanelComment,\n>({\n activeFileId,\n openCommentGroups,\n resolvedCommentGroups,\n commentScope,\n}: RightPanelCommentScopeModelArgs<TFile, TComment>) => {\n const activeOpenCommentGroup = openCommentGroups.find((group) => group.file.id === activeFileId);\n const activeResolvedCommentGroup = resolvedCommentGroups.find((group) => group.file.id === activeFileId);\n const scopedOpenCommentGroups =\n commentScope === \"current\"\n ? activeOpenCommentGroup\n ? [activeOpenCommentGroup]\n : []\n : sortCommentGroupsByActivity(openCommentGroups);\n const scopedResolvedCommentGroups =\n commentScope === \"current\"\n ? activeResolvedCommentGroup\n ? [activeResolvedCommentGroup]\n : []\n : sortCommentGroupsByActivity(resolvedCommentGroups);\n return {\n scopedOpenCommentGroups,\n scopedResolvedCommentGroups,\n hasAnyComments: scopedOpenCommentGroups.length > 0 || scopedResolvedCommentGroups.length > 0,\n hideSingleActiveFileHeader: commentScope === \"current\",\n };\n};\n","import { decodeBase64Url } from \"./jsonShareLinkModel\";\n\nexport type RoomRouteLocation = {\n hash: string;\n origin: string;\n pathname: string;\n};\n\nexport type RoomSession = {\n roomId: string;\n roomKey: string;\n shareUrl: string;\n};\n\nexport type ParsedRoomLocation = RoomSession;\n\nexport const ROOM_ID_BYTES = 16;\nexport const ROOM_KEY_BYTES = 32;\nexport const ROOM_KEY_PATTERN = /^[A-Za-z0-9_-]+$/;\n\nexport const parseRoomFromHash = (hash: string): Pick<RoomSession, \"roomId\" | \"roomKey\"> | null => {\n const fragment = hash.replace(/^#/, \"\").trim();\n if (!fragment.startsWith(\"room=\")) {\n return null;\n }\n\n const roomValue = fragment.slice(\"room=\".length);\n const [roomId, roomKey, extra] = roomValue.split(\",\");\n if (\n extra !== undefined ||\n roomValue.includes(\"&\") ||\n !roomId ||\n !ROOM_KEY_PATTERN.test(roomId) ||\n !roomKey ||\n !ROOM_KEY_PATTERN.test(roomKey)\n ) {\n return null;\n }\n\n try {\n return decodeBase64Url(roomKey).byteLength === ROOM_KEY_BYTES ? { roomId, roomKey } : null;\n } catch {\n return null;\n }\n};\n\nexport const parseRoomKeyFromHash = (hash: string) => {\n const roomKey = parseRoomFromHash(hash)?.roomKey;\n if (!roomKey || !ROOM_KEY_PATTERN.test(roomKey)) {\n return null;\n }\n\n try {\n return decodeBase64Url(roomKey).byteLength === ROOM_KEY_BYTES ? roomKey : null;\n } catch {\n return null;\n }\n};\n\nexport const createRoomShareUrl = (origin: string, roomId: string, roomKey: string) =>\n `${origin}/#room=${roomId},${roomKey}`;\n\nexport const parseRoomLocation = (location: RoomRouteLocation): ParsedRoomLocation | null => {\n if (location.pathname !== \"/\") {\n return null;\n }\n\n const parsedRoom = parseRoomFromHash(location.hash);\n if (!parsedRoom) {\n return null;\n }\n\n return {\n roomId: parsedRoom.roomId,\n roomKey: parsedRoom.roomKey,\n shareUrl: createRoomShareUrl(location.origin, parsedRoom.roomId, parsedRoom.roomKey),\n };\n};\n\nexport const parseRoomShareUrl = (shareUrl: string): ParsedRoomLocation | null => {\n try {\n return parseRoomLocation(new URL(shareUrl));\n } catch {\n return null;\n }\n};\n","import { parseRoomShareUrl } from \"./roomShareLinkModel\";\n\nconst UNAVAILABLE_ROOM_LINK_LABEL = \"Invite link unavailable\";\n\nconst compactRoomId = (roomId: string) => (roomId.length > 12 ? `${roomId.slice(0, 8)}...` : roomId);\n\nexport type RoomShareLinkView = {\n canCopy: boolean;\n display: string;\n title: string;\n url?: string;\n};\n\nexport const getRoomShareLinkView = (shareUrl?: string, expectedRoomId?: string): RoomShareLinkView => {\n const parsedRoom = shareUrl ? parseRoomShareUrl(shareUrl) : null;\n\n if (!parsedRoom || (expectedRoomId && parsedRoom.roomId !== expectedRoomId)) {\n return {\n canCopy: false,\n display: UNAVAILABLE_ROOM_LINK_LABEL,\n title: shareUrl ?? UNAVAILABLE_ROOM_LINK_LABEL,\n };\n }\n\n const parsedUrl = new URL(parsedRoom.shareUrl);\n\n return {\n canCopy: true,\n display: `${parsedUrl.origin}/#room=${compactRoomId(parsedRoom.roomId)},...`,\n title: parsedRoom.shareUrl,\n url: parsedRoom.shareUrl,\n };\n};\n","import {\n getRoomShareLinkView,\n type RoomShareLinkView,\n} from \"./shareLinkViewModel\";\n\nexport type ShareViewLabels = {\n exportToLink: string;\n exporting: string;\n};\n\nexport type ShareViewModel = {\n live: {\n status: \"active\" | \"blocked\" | \"ready\";\n canStart: boolean;\n disabledReason: string;\n link: RoomShareLinkView;\n };\n shareable: {\n status: \"blocked\" | \"exported\" | \"exporting\" | \"ready\";\n canExport: boolean;\n disabledReason: string;\n hasLink: boolean;\n primaryLabel: string;\n };\n};\n\nexport const buildShareViewModel = ({\n canStartSession,\n isLive,\n labels,\n jsonShareCanExport,\n jsonShareDisabledReason,\n jsonShareExporting,\n jsonShareUrl,\n roomId,\n shareUrl,\n startSessionUnavailableReason,\n}: {\n canStartSession: boolean;\n isLive: boolean;\n labels: ShareViewLabels;\n jsonShareCanExport: boolean;\n jsonShareDisabledReason: string;\n jsonShareExporting: boolean;\n jsonShareUrl?: string;\n roomId?: string;\n shareUrl?: string;\n startSessionUnavailableReason: string;\n}): ShareViewModel => {\n const shareableHasLink = Boolean(jsonShareUrl);\n const shareableBlocked = Boolean(jsonShareDisabledReason);\n\n return {\n live: {\n status: isLive ? \"active\" : canStartSession ? \"ready\" : \"blocked\",\n canStart: canStartSession,\n disabledReason: startSessionUnavailableReason,\n link: getRoomShareLinkView(shareUrl, roomId),\n },\n shareable: {\n status: jsonShareExporting\n ? \"exporting\"\n : shareableBlocked\n ? \"blocked\"\n : shareableHasLink\n ? \"exported\"\n : \"ready\",\n canExport: jsonShareCanExport,\n disabledReason: jsonShareDisabledReason,\n hasLink: shareableHasLink,\n primaryLabel: jsonShareExporting\n ? labels.exporting\n : labels.exportToLink,\n },\n };\n};\n","export type StatusBarSaveState = {\n label: string;\n tone: \"saved\" | \"attention\";\n visible: boolean;\n};\n\nexport const getStatusBarSaveState = ({\n isLive,\n roomAttentionLabels = [\n \"Reconnecting\",\n \"Disconnected\",\n \"Connection failed\",\n \"Room offline\",\n \"Changes aren’t backed up\",\n ],\n roomOfflineLabel = \"Room offline\",\n savedLocallyLabel = \"Saved locally\",\n statusLabel,\n}: {\n isLive: boolean;\n roomAttentionLabels?: readonly string[];\n roomOfflineLabel?: string;\n savedLocallyLabel?: string;\n statusLabel: string;\n}): StatusBarSaveState => {\n if (!isLive) {\n return { label: savedLocallyLabel, tone: \"saved\", visible: true };\n }\n\n if (roomAttentionLabels.includes(statusLabel)) {\n return { label: statusLabel, tone: \"attention\", visible: true };\n }\n\n if (statusLabel === roomOfflineLabel) {\n return { label: roomOfflineLabel, tone: \"attention\", visible: true };\n }\n\n return { label: statusLabel, tone: \"saved\", visible: false };\n};\n","export type WorkspaceFileTitleLike = {\n title: string;\n};\n\nexport type WorkspaceFileIdentity = {\n id: string;\n};\n\nexport function removeRecordKey<TValue>(\n record: Record<string, TValue>,\n key: string,\n) {\n if (!(key in record)) {\n return record;\n }\n\n const { [key]: _removed, ...nextRecord } = record;\n return nextRecord;\n}\n\nexport function restoreFileToList<TFile extends WorkspaceFileIdentity>(\n files: TFile[],\n restoredFile: TFile,\n restoredIndex: number,\n) {\n if (files.some((file) => file.id === restoredFile.id)) {\n return files;\n }\n\n const nextFiles = [...files];\n nextFiles.splice(Math.min(Math.max(0, restoredIndex), nextFiles.length), 0, restoredFile);\n return nextFiles;\n}\n\nexport function restoreOpenFileId(\n openFileIds: string[],\n restoredFileId: string,\n previousOpenFileIds: string[],\n) {\n if (\n !previousOpenFileIds.includes(restoredFileId) ||\n openFileIds.includes(restoredFileId)\n ) {\n return openFileIds;\n }\n\n const previousOpenIndex = previousOpenFileIds.indexOf(restoredFileId);\n const nextOpenFileIds = [...openFileIds];\n nextOpenFileIds.splice(\n Math.min(previousOpenIndex, nextOpenFileIds.length),\n 0,\n restoredFileId,\n );\n return nextOpenFileIds;\n}\n\nexport const normalizeWorkspaceFileTitleForLookup = (\n file: WorkspaceFileTitleLike,\n) => file.title.trim().toLowerCase().replace(/\\.md$/, \"\");\n","import {\n clampSplitEditorRatio,\n type FileViewMode,\n type ReadingWidth,\n} from \"./documentPrimitives\";\n\nexport type WorkspaceModelFile = {\n id: string;\n title: string;\n text: string;\n viewMode: FileViewMode;\n readingWidth: ReadingWidth;\n splitRatio?: number;\n lineWrapping: boolean;\n lineNumbers: boolean;\n};\n\nexport type WorkspaceModelState<TFile extends WorkspaceModelFile = WorkspaceModelFile> = {\n files: TFile[];\n openFileIds: string[];\n activeFileId: string;\n};\n\nexport type CloseFileResult<TFile extends WorkspaceModelFile = WorkspaceModelFile> = {\n closedActiveFile: boolean;\n nextActiveFile?: TFile;\n};\n\nexport type RenameFileResult =\n | {\n ok: true;\n title: string;\n }\n | {\n ok: false;\n reason: \"empty\" | \"duplicate\";\n title: string;\n message: string;\n };\n\ntype WorkspaceValueUpdater<T> = T | ((currentValue: T) => T);\n\nexport type WorkspaceModelAction<TFile extends WorkspaceModelFile = WorkspaceModelFile> =\n | { type: \"replaceWorkspace\"; state: WorkspaceModelState<TFile> }\n | { type: \"replaceFiles\"; update: WorkspaceValueUpdater<TFile[]> }\n | { type: \"replaceOpenFileIds\"; update: WorkspaceValueUpdater<string[]> }\n | { type: \"setActiveFileId\"; fileId: string }\n | { type: \"selectFile\"; fileId: string }\n | { type: \"addFile\"; file: TFile; insertAfterFileId?: string }\n | { type: \"renameFile\"; fileId: string; title: string }\n | { type: \"closeFile\"; fileId: string }\n | { type: \"deleteFile\"; fileId: string }\n | { type: \"reorderOpenFile\"; sourceFileId: string; targetFileId: string }\n | { type: \"setActiveFileText\"; text: string }\n | { type: \"setActiveFileViewMode\"; viewMode: FileViewMode }\n | { type: \"setActiveFileReadingWidth\"; readingWidth: ReadingWidth }\n | { type: \"setActiveFileLineWrapping\"; lineWrapping: boolean }\n | { type: \"setActiveFileLineNumbers\"; lineNumbers: boolean }\n | { type: \"setActiveFileSplitRatio\"; splitRatio: number };\n\nconst updateWorkspaceFileFields = <TFile extends WorkspaceModelFile>(\n file: TFile,\n fields: Partial<WorkspaceModelFile>,\n): TFile => ({\n ...file,\n ...fields,\n});\n\nconst applyValueUpdater = <T>(value: T, update: WorkspaceValueUpdater<T>) =>\n typeof update === \"function\" ? (update as (currentValue: T) => T)(value) : update;\n\nconst uniqueKnownFileIds = (fileIds: string[], knownFileIds: Set<string>) => {\n const nextFileIds: string[] = [];\n\n for (const fileId of fileIds) {\n if (!knownFileIds.has(fileId) || nextFileIds.includes(fileId)) {\n continue;\n }\n\n nextFileIds.push(fileId);\n }\n\n return nextFileIds;\n};\n\nexport const createWorkspaceModelState = <TFile extends WorkspaceModelFile>({\n files,\n openFileIds,\n activeFileId,\n}: WorkspaceModelState<TFile>): WorkspaceModelState<TFile> => {\n const knownFileIds = new Set(files.map((file) => file.id));\n const nextOpenFileIds = uniqueKnownFileIds(openFileIds, knownFileIds);\n const hasActiveFile = Boolean(activeFileId && knownFileIds.has(activeFileId));\n const nextActiveFileId = hasActiveFile ? activeFileId : (nextOpenFileIds[0] ?? \"\");\n\n if (nextActiveFileId && !nextOpenFileIds.includes(nextActiveFileId)) {\n nextOpenFileIds.push(nextActiveFileId);\n }\n\n return {\n files,\n openFileIds: nextOpenFileIds,\n activeFileId: nextActiveFileId,\n };\n};\n\nexport const getOpenWorkspaceFiles = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n) =>\n state.openFileIds\n .map((fileId) => state.files.find((file) => file.id === fileId))\n .filter((file): file is TFile => Boolean(file));\n\nexport const getActiveWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n) =>\n getOpenWorkspaceFiles(state).find((file) => file.id === state.activeFileId);\n\nexport const normalizeWorkspaceFileTitle = (title: string) => {\n const trimmedTitle = title\n .trim()\n .split(\"\\0\")\n .join(\" \")\n .replace(/[/\\\\]/g, \" \")\n .replace(/\\s+/g, \" \");\n if (!trimmedTitle || trimmedTitle === \".\" || trimmedTitle === \"..\") {\n return \"Untitled.md\";\n }\n\n return /\\.[A-Za-z0-9]+$/.test(trimmedTitle) ? trimmedTitle : `${trimmedTitle}.md`;\n};\n\nexport const getAvailableWorkspaceFileTitle = <TFile extends WorkspaceModelFile>(\n files: TFile[],\n baseTitle: string,\n) => {\n const normalizedTitle = normalizeWorkspaceFileTitle(baseTitle);\n const existingTitles = new Set(files.map((file) => file.title.toLowerCase()));\n if (!existingTitles.has(normalizedTitle.toLowerCase())) {\n return normalizedTitle;\n }\n\n const extensionMatch = normalizedTitle.match(/(\\.[A-Za-z0-9]+)$/);\n const extension = extensionMatch?.[1] ?? \"\";\n const titleWithoutExtension = extension ? normalizedTitle.slice(0, -extension.length) : normalizedTitle;\n let index = 2;\n let candidateTitle = `${titleWithoutExtension} ${index}${extension}`;\n\n while (existingTitles.has(candidateTitle.toLowerCase())) {\n index += 1;\n candidateTitle = `${titleWithoutExtension} ${index}${extension}`;\n }\n\n return candidateTitle;\n};\n\nexport const renameWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n fileId: string,\n nextRawTitle: string,\n): { state: WorkspaceModelState<TFile>; result: RenameFileResult } => {\n const trimmedTitle = nextRawTitle.trim().replace(/\\s+/g, \" \");\n if (!trimmedTitle) {\n return {\n state,\n result: {\n ok: false,\n reason: \"empty\",\n title: \"\",\n message: \"File name cannot be empty.\",\n },\n };\n }\n\n const nextTitle = normalizeWorkspaceFileTitle(trimmedTitle);\n const duplicateFile = state.files.find(\n (file) => file.id !== fileId && file.title.toLowerCase() === nextTitle.toLowerCase(),\n );\n\n if (duplicateFile) {\n return {\n state,\n result: {\n ok: false,\n reason: \"duplicate\",\n title: nextTitle,\n message: \"File name already exists.\",\n },\n };\n }\n\n return {\n state: {\n ...state,\n files: state.files.map((file) =>\n file.id === fileId ? updateWorkspaceFileFields(file, { title: nextTitle }) : file,\n ),\n },\n result: { ok: true, title: nextTitle },\n };\n};\n\nexport const selectWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n fileId: string,\n): WorkspaceModelState<TFile> => {\n if (!state.files.some((file) => file.id === fileId)) {\n return state;\n }\n\n return {\n ...state,\n activeFileId: fileId,\n openFileIds: state.openFileIds.includes(fileId) ? state.openFileIds : [...state.openFileIds, fileId],\n };\n};\n\nexport const setWorkspaceActiveFileId = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n fileId: string,\n): WorkspaceModelState<TFile> => {\n if (!fileId) {\n return {\n ...state,\n activeFileId: \"\",\n };\n }\n\n return selectWorkspaceFile(state, fileId);\n};\n\nexport const addWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n file: TFile,\n options: { insertAfterFileId?: string } = {},\n): WorkspaceModelState<TFile> => {\n const files = [...state.files];\n const insertAfterIndex = options.insertAfterFileId\n ? files.findIndex((candidateFile) => candidateFile.id === options.insertAfterFileId)\n : -1;\n\n if (insertAfterIndex === -1) {\n files.push(file);\n } else {\n files.splice(insertAfterIndex + 1, 0, file);\n }\n\n return {\n files,\n openFileIds: state.openFileIds.includes(file.id) ? state.openFileIds : [...state.openFileIds, file.id],\n activeFileId: file.id,\n };\n};\n\nexport const closeWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n fileId: string,\n): { state: WorkspaceModelState<TFile>; result: CloseFileResult<TFile> } | undefined => {\n const closingIndex = state.openFileIds.findIndex((openFileId) => openFileId === fileId);\n if (closingIndex === -1) {\n return undefined;\n }\n\n const remainingOpenFileIds = state.openFileIds.filter((openFileId) => openFileId !== fileId);\n const closedActiveFile = fileId === state.activeFileId;\n const nextActiveFileId = closedActiveFile\n ? (remainingOpenFileIds[closingIndex] ?? remainingOpenFileIds[closingIndex - 1] ?? remainingOpenFileIds[0] ?? \"\")\n : state.activeFileId;\n const nextActiveFile = closedActiveFile\n ? state.files.find((file) => file.id === nextActiveFileId)\n : state.files.find((file) => file.id === state.activeFileId);\n\n return {\n state: {\n ...state,\n openFileIds: remainingOpenFileIds,\n activeFileId: closedActiveFile ? (nextActiveFile?.id ?? \"\") : state.activeFileId,\n },\n result: { closedActiveFile, nextActiveFile },\n };\n};\n\nexport const deleteWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n fileId: string,\n): { state: WorkspaceModelState<TFile>; result: CloseFileResult<TFile> } | undefined => {\n const deletingFile = state.files.find((file) => file.id === fileId);\n if (!deletingFile) {\n return undefined;\n }\n\n const deletedOpenIndex = state.openFileIds.findIndex((openFileId) => openFileId === fileId);\n const remainingOpenFileIds = state.openFileIds.filter((openFileId) => openFileId !== fileId);\n const deletedActiveFile = fileId === state.activeFileId;\n const nextActiveFileId = deletedActiveFile\n ? (remainingOpenFileIds[deletedOpenIndex] ?? remainingOpenFileIds[deletedOpenIndex - 1] ?? remainingOpenFileIds[0] ?? \"\")\n : state.activeFileId;\n const nextFiles = state.files.filter((file) => file.id !== fileId);\n const nextActiveFile = deletedActiveFile ? nextFiles.find((file) => file.id === nextActiveFileId) : getActiveWorkspaceFile(state);\n\n return {\n state: {\n files: nextFiles,\n openFileIds: remainingOpenFileIds,\n activeFileId: deletedActiveFile ? (nextActiveFile?.id ?? \"\") : state.activeFileId,\n },\n result: { closedActiveFile: deletedActiveFile, nextActiveFile },\n };\n};\n\nexport const reorderOpenWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n sourceFileId: string,\n targetFileId: string,\n): WorkspaceModelState<TFile> => {\n if (sourceFileId === targetFileId) {\n return state;\n }\n\n const sourceIndex = state.openFileIds.indexOf(sourceFileId);\n const targetIndex = state.openFileIds.indexOf(targetFileId);\n\n if (sourceIndex === -1 || targetIndex === -1) {\n return state;\n }\n\n const openFileIds = [...state.openFileIds];\n const [movedFileId] = openFileIds.splice(sourceIndex, 1);\n openFileIds.splice(targetIndex, 0, movedFileId);\n\n return {\n ...state,\n openFileIds,\n };\n};\n\nexport const selectAdjacentWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n direction: -1 | 1,\n): { state: WorkspaceModelState<TFile>; file?: TFile } => {\n const openFiles = getOpenWorkspaceFiles(state);\n if (openFiles.length < 2) {\n return { state };\n }\n\n const currentIndex = Math.max(\n 0,\n openFiles.findIndex((file) => file.id === state.activeFileId),\n );\n const nextIndex = (currentIndex + direction + openFiles.length) % openFiles.length;\n const nextFile = openFiles[nextIndex];\n\n return {\n state: {\n ...state,\n activeFileId: nextFile.id,\n },\n file: nextFile,\n };\n};\n\nconst updateWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n fileId: string,\n updateFile: (file: TFile) => TFile,\n): WorkspaceModelState<TFile> => {\n if (!state.files.some((file) => file.id === fileId)) {\n return state;\n }\n\n return {\n ...state,\n files: state.files.map((file) => (file.id === fileId ? updateFile(file) : file)),\n };\n};\n\nconst updateActiveWorkspaceFile = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n updateFile: (file: TFile) => TFile,\n): WorkspaceModelState<TFile> => {\n if (!state.activeFileId) {\n return state;\n }\n\n return updateWorkspaceFile(state, state.activeFileId, updateFile);\n};\n\nexport const workspaceReducer = <TFile extends WorkspaceModelFile>(\n state: WorkspaceModelState<TFile>,\n action: WorkspaceModelAction<TFile>,\n): WorkspaceModelState<TFile> => {\n switch (action.type) {\n case \"replaceWorkspace\":\n return createWorkspaceModelState(action.state);\n case \"replaceFiles\":\n return createWorkspaceModelState({\n ...state,\n files: applyValueUpdater(state.files, action.update),\n });\n case \"replaceOpenFileIds\": {\n const knownFileIds = new Set(state.files.map((file) => file.id));\n const openFileIds = uniqueKnownFileIds(applyValueUpdater(state.openFileIds, action.update), knownFileIds);\n const nextOpenFileIds =\n state.activeFileId && knownFileIds.has(state.activeFileId) && !openFileIds.includes(state.activeFileId)\n ? [...openFileIds, state.activeFileId]\n : openFileIds;\n\n return {\n ...state,\n openFileIds: nextOpenFileIds,\n activeFileId: state.activeFileId && nextOpenFileIds.includes(state.activeFileId) ? state.activeFileId : (nextOpenFileIds[0] ?? \"\"),\n };\n }\n case \"setActiveFileId\":\n return setWorkspaceActiveFileId(state, action.fileId);\n case \"selectFile\":\n return selectWorkspaceFile(state, action.fileId);\n case \"addFile\":\n return addWorkspaceFile(state, action.file, { insertAfterFileId: action.insertAfterFileId });\n case \"renameFile\":\n return renameWorkspaceFile(state, action.fileId, action.title).state;\n case \"closeFile\":\n return closeWorkspaceFile(state, action.fileId)?.state ?? state;\n case \"deleteFile\":\n return deleteWorkspaceFile(state, action.fileId)?.state ?? state;\n case \"reorderOpenFile\":\n return reorderOpenWorkspaceFile(state, action.sourceFileId, action.targetFileId);\n case \"setActiveFileText\":\n return updateActiveWorkspaceFile(state, (file) =>\n updateWorkspaceFileFields(file, { text: action.text }),\n );\n case \"setActiveFileViewMode\":\n return updateActiveWorkspaceFile(state, (file) =>\n updateWorkspaceFileFields(file, { viewMode: action.viewMode }),\n );\n case \"setActiveFileReadingWidth\":\n return updateActiveWorkspaceFile(state, (file) =>\n updateWorkspaceFileFields(file, { readingWidth: action.readingWidth }),\n );\n case \"setActiveFileLineWrapping\":\n return updateActiveWorkspaceFile(state, (file) =>\n updateWorkspaceFileFields(file, { lineWrapping: action.lineWrapping }),\n );\n case \"setActiveFileLineNumbers\":\n return updateActiveWorkspaceFile(state, (file) =>\n updateWorkspaceFileFields(file, { lineNumbers: action.lineNumbers }),\n );\n case \"setActiveFileSplitRatio\":\n return updateActiveWorkspaceFile(state, (file) =>\n updateWorkspaceFileFields(file, {\n splitRatio: clampSplitEditorRatio(action.splitRatio),\n }),\n );\n default:\n return state;\n }\n};\n","import { type FileViewMode, type ReadingWidth } from \"./documentPrimitives\";\nimport { normalizeWorkspaceFileTitle } from \"./workspaceModel\";\n\nexport type WorkspaceFilePreferenceDefaults<\n TViewMode extends string = FileViewMode,\n TReadingWidth extends string = ReadingWidth,\n> = {\n newFileViewMode: TViewMode;\n readingWidth: TReadingWidth;\n lineWrapping: boolean;\n lineNumbers: boolean;\n};\n\nexport type WorkspaceIoPreferenceOverrides<\n TViewMode extends string = FileViewMode,\n TReadingWidth extends string = ReadingWidth,\n> = {\n viewMode: TViewMode;\n readingWidth: TReadingWidth;\n lineWrapping: boolean;\n lineNumbers: boolean;\n};\n\nexport type TextFileDownloadDraft = {\n fileName: string;\n content: string;\n type: string;\n};\n\nexport type WorkspaceIoFile = {\n title: string;\n text: string;\n};\n\nexport type WorkspaceImportFileDescriptor = {\n name: string;\n type: string;\n};\n\nexport type ImportedWorkspaceFileDraft<\n TViewMode extends string = FileViewMode,\n TReadingWidth extends string = ReadingWidth,\n> = {\n title: string;\n text: string;\n viewMode: TViewMode;\n overrides: WorkspaceIoPreferenceOverrides<TViewMode, TReadingWidth>;\n};\n\nexport function getNewFilePreferenceOverrides<\n TViewMode extends string,\n TReadingWidth extends string,\n>(\n preferences: WorkspaceFilePreferenceDefaults<TViewMode, TReadingWidth>,\n): WorkspaceIoPreferenceOverrides<TViewMode, TReadingWidth> {\n return {\n viewMode: preferences.newFileViewMode,\n readingWidth: preferences.readingWidth,\n lineWrapping: preferences.lineWrapping,\n lineNumbers: preferences.lineNumbers,\n };\n}\n\nexport const isSupportedImportFileDescriptor = (file: WorkspaceImportFileDescriptor) => {\n const fileName = file.name.toLowerCase();\n return (\n fileName.endsWith(\".md\") ||\n fileName.endsWith(\".markdown\") ||\n file.type === \"text/markdown\" ||\n file.type === \"text/plain\"\n );\n};\n\nexport const createCurrentFileDownloadDraft = (\n file: WorkspaceIoFile,\n): TextFileDownloadDraft => ({\n fileName: file.title,\n content: file.text,\n type: \"text/markdown;charset=utf-8\",\n});\n\nexport const createImportedWorkspaceFileDraft = <\n TViewMode extends string,\n TReadingWidth extends string,\n>(\n fileName: string,\n text: string,\n preferences: WorkspaceFilePreferenceDefaults<TViewMode, TReadingWidth>,\n): ImportedWorkspaceFileDraft<TViewMode, TReadingWidth> => ({\n title: normalizeWorkspaceFileTitle(fileName || \"Imported.md\"),\n text,\n viewMode: preferences.newFileViewMode,\n overrides: getNewFilePreferenceOverrides(preferences),\n});\n","import { parseFrontmatter } from \"./markdown\";\n\nexport type WorkspaceConnectionStatus =\n | \"idle\"\n | \"connecting\"\n | \"connected\"\n | \"reconnecting\"\n | \"disconnected\"\n | \"failed\";\n\nexport type WorkspaceViewFile = {\n id: string;\n title: string;\n text: string;\n};\n\nexport const getWorkspaceStatusLabel = (status: WorkspaceConnectionStatus) =>\n ({\n idle: \"Local draft\",\n connecting: \"Connecting\",\n connected: \"Live session\",\n reconnecting: \"Reconnecting\",\n disconnected: \"Disconnected\",\n failed: \"Connection failed\",\n })[status];\n\nexport const getActiveWorkspaceStatus = ({\n isLive,\n connectionStatus,\n}: {\n isLive: boolean;\n connectionStatus: WorkspaceConnectionStatus;\n}) => (isLive ? connectionStatus : \"idle\");\n\nexport const getWorkspaceFileSearchText = (file: WorkspaceViewFile) => {\n const metadata = parseFrontmatter(file.text);\n const title = metadata.attributes.find((attribute) => attribute.key.toLowerCase() === \"title\")?.value ?? \"\";\n return `${file.title} ${title}`;\n};\n"],"names":["READING_WIDTHS","FILE_VIEW_MODES","DEFAULT_SPLIT_EDITOR_RATIO","MIN_SPLIT_EDITOR_RATIO","MAX_SPLIT_EDITOR_RATIO","clampSplitEditorRatio","value","numericValue","frontmatterOpeningDelimiterPattern","frontmatterClosingDelimiterPattern","getLineBreakLength","text","lineBreakIndex","formatYamlMetadataValue","key","nestedValue","getFrontmatterBlock","markdown","firstLineBreakIndex","firstLine","rawStart","cursor","nextLineBreakIndex","lineEnd","line","bodyStart","getPreviewBody","body","parseFrontmatter","frontmatterBlock","document","parseDocument","isMap","attributes","item","isScalar","_a","getMarkdownDocumentTitle","parsed","metadataTitle","attribute","_c","_b","getOutlineHeadings","previewBody","lineIndex","match","heading","getOutlineHeadingsFromMarkdown","headings","lineStart","getLineStartOffset","targetLineIndex","lines","offset","index","getLineNumberForOffset","content","getMarkdownWordCount","comparePatchesDescending","first","second","comparePatchesAscending","diffTextPatch","oldText","nextText","start","oldEnd","nextEnd","normalizeTextPatches","patches","areTextPatchesApplicable","previousTo","patch","applyTextPatches","currentText","getTextPatchesForChange","preferredPatches","fallbackPatch","LARGE_DOCUMENT_CHAR_THRESHOLD","LARGE_DOCUMENT_LINE_THRESHOLD","LARGE_DOCUMENT_WORD_THRESHOLD","LARGE_DOCUMENT_LONG_LINE_THRESHOLD","LARGE_DOCUMENT_TABLE_RUN_THRESHOLD","LIVE_PREVIEW_CHAR_THRESHOLD","HEAVY_PREVIEW_TABLE_RUN_THRESHOLD","HEAVY_PREVIEW_FENCE_LINE_THRESHOLD","HEAVY_PREVIEW_FENCE_CHAR_THRESHOLD","DEFAULT_LINE_HEIGHT","BLOCK_GAP_HEIGHT","CODE_LINE_HEIGHT","HEADING_ESTIMATED_HEIGHT_BY_LEVEL","PREVIEW_PARAGRAPH_LINE_CHUNK_SIZE","PREVIEW_PARAGRAPH_CHAR_CHUNK_SIZE","PREVIEW_PARAGRAPH_ESTIMATED_CHARS_PER_LINE","PREVIEW_WINDOW_MAX_LEADING_OVERSCAN","PREVIEW_WINDOW_LEADING_BLOCK_PADDING","PREVIEW_WINDOW_TRAILING_BLOCK_PADDING","PREVIEW_WINDOW_END_LEADING_BLOCK_PADDING","PREVIEW_WINDOW_END_TRAILING_BLOCK_PADDING","PREVIEW_WINDOW_END_SCROLL_RATIO","OPTIMISTIC_INDEX_MAX_CHANGED_LINES","OPTIMISTIC_INDEX_CONTEXT_BLOCK_COUNT","fenceLinePattern","headingLinePattern","thematicLinePattern","blockquoteLinePattern","listLinePattern","indentedContinuationPattern","tableSeparatorPattern","htmlLinePattern","displayMathLinePattern","heavyFenceLanguagePattern","frontmatterFencePattern","yamlKeyLinePattern","footnoteDefinitionLinePattern","footnoteReferencePattern","referenceDefinitionLinePattern","referenceLinkPattern","definitionListLinePattern","getMarkdownLineCount","lineCount","hasLongMarkdownLine","threshold","currentLineLength","characterCode","hasLargeMarkdownWordCount","wordCount","inWord","character","hasLargeMarkdownDocumentShape","currentTableRun","lineHasTableDelimiter","finishLine","isLargeMarkdownDocument","hasHeavyMarkdownPreviewShape","tableRun","inFence","fenceChar","fenceLength","fenceLanguage","fenceLineCount","fenceCharCount","inDisplayMath","finishFence","isHeavyFence","fenceMatch","marker","hasGlobalMarkdownSyntax","shouldUseImmediateMarkdownPreview","splitMarkdownLines","startOffset","rawEndOffset","endOffset","isBlankLine","startsStructuralBlock","nextLine","isTableStart","getHeadingLevel","level","estimateBlockHeight","kind","createBlock","startIndex","endIndex","estimatedTop","startLine","endLine","headingLevel","estimatedHeight","findParagraphTextChunkEnd","preferredEnd","searchEnd","createParagraphTextChunkBlock","chunkStart","chunkEnd","estimatedLineCount","createParagraphBlocks","blocks","nextEstimatedTop","block","chunkStartIndex","chunkEndIndex","findFenceEnd","openingMatch","closingMatch","getHtmlBlockOpeningTagName","tagName","findPairedHtmlEnd","openingPattern","closingPattern","depth","findHtmlEnd","pairedHtmlEnd","findListEnd","sawBlank","findBlockquoteEnd","findTableEnd","findParagraphEnd","resolveBlockRange","createPreviewBlockIndex","safeEndIndex","paragraphBlocks","getTextChangeRange","previousMarkdown","nextMarkdown","sharedLength","suffixLength","maxSuffixLength","getTextChangeRangeFromPatches","normalizedPatches","previousStartOffset","previousEndOffset","nextStartOffset","nextEndOffset","offsetDelta","nextPatchStartOffset","nextPatchEndOffset","getLineNumberForMarkdownOffset","clampedOffset","nextLineStartOffset","getChangedLineSpan","isOptimisticStructuralLine","isUnsafeOptimisticChangedLine","options","hasUnsafeOptimisticChangedLines","span","blankIsUnsafe","findFirstPreviewBlockIndexAtLine","lineNumber","findLastPreviewBlockIndexAtLine","getLineStartOffsetFromLines","getLineEndOffsetFromLines","rekeyPreviewBlock","rebasePreviewBlock","shiftPreviewBlock","reflowPreviewBlockTops","nextBlock","createOptimisticPreviewBlockIndexForChangeRange","previousIndex","changeRange","previousLines","nextLines","previousChangedLineSpan","nextChangedLineSpan","firstChangedBlockIndex","lastChangedBlockIndex","replaceStartBlockIndex","replaceEndBlockIndex","replaceStartBlock","replaceEndBlock","lineDelta","charDelta","nextReplaceStartLine","nextReplaceEndLine","sliceStartOffset","sliceEndOffset","replacementBlocks","suffixBlocks","totalEstimatedHeight","total","createOptimisticPreviewBlockIndex","createOptimisticPreviewBlockIndexFromPatches","applyPreviewBlockMeasurements","measurements","measuredHeight","measuredBlock","choosePreviewRenderableAnchor","anchors","sourceLineNumber","targetLine","measuredAnchors","anchor","targetLineHasUnrenderedAnchor","renderableAnchors","scoreAnchor","containsTarget","sourceElementScore","firstScore","secondScore","difference","isPreviewBlockRenderableForScrollMap","clampPreviewScrollTop","scrollTop","totalHeight","viewportHeight","getPreviewScrollTopForSourceLine","edgePadding","lineOffsetRatio","sourceBlock","mapPreviewLineToBlock","blockLineCount","blockRatio","fallbackBlock","fallbackTop","getPreviewWindow","overscan","leadingOverscan","trailingOverscan","windowTop","windowBottom","firstVisibleIndex","scrollRatio","leadingBlockPadding","trailingBlockPadding","paddedStartIndex","paddedEndIndex","EMPTY_PARSED_MARKDOWN","EMPTY_PREVIEW_BODY","EMPTY_PREVIEW_BODY_RUNTIME","EMPTY_PREVIEW_METADATA_RUNTIME","createActiveDocumentEditorRuntime","activeFile","viewMode","readingWidth","splitRatio","lineWrapping","lineNumbers","bookmarks","title","hasFile","largeDocumentMode","createActiveDocumentPreviewRuntime","parsedMarkdown","renderedPreview","parsedBodyStartOffset","previewBodyStartOffset","createActiveDocumentPreviewBodyRuntime","createActiveDocumentPreviewMetadataRuntime","createActiveDocumentRuntime","createRoomApiUrl","baseUrl","roomId","suffix","isEncryptedEnvelope","envelope","sortCollaborators","collaborators","clampPosition","position","docLength","selectionsAreEqual","capabilityListsAreEqual","capability","collaboratorsAreEqual","mapCollaborationPositionThroughTextPatches","assoc","delta","insertedLength","deletedLength","mapCollaborationSelectionThroughTextPatches","selection","createCollaboratorRegistry","collaborator","selfId","currentCollaborator","peerIds","nextPeerIds","changed","collaboratorId","createCollabSessionState","hasConnectedOnce","collaborationBlocked","serverOfflineNotified","reconnected","reason","status","clampOffset","getLineNumberForPresenceOffset","targetOffset","getLineNumberForPresenceSelection","metadataLineNumber","isCollaboratorInFile","currentFileTitle","currentRoomId","currentDocumentId","collaboratorDocumentId","getCollaboratorPresenceDetail","prefix","detail","getCollaboratorPresenceLabel","segments","defaultVisualRowOptions","defaultAnnotationRowOptions","getLineSurfaceRectRight","rectangle","getLineSurfaceRectBottom","clampSourcePosition","normalizeSourceRange","range","end","groupRectsByRun","rectangles","rectanglesByRun","runRectangles","buildLineSurfaceVisualRows","optionOverrides","rows","sortedRectangles","rowGroups","currentGroup","rowGroup","rowIndex","top","rawBottom","nextTop","bottom","lineSurfaceRowsAreAdjacent","firstRow","secondRow","positionInSourceLine","sourceRangeIntersectsLine","getLineNumberForSourcePosition","resolveLineAt","getLineNumbersForSourceRanges","ranges","normalizedRange","getLineSurfaceAnnotationsSignature","annotations","annotation","areLineSurfaceRowsEqual","firstRows","secondRows","getFallbackLineTop","sourceBlocks","previousBlock","buildLineSurfaceAnnotationRows","matchingBlock","sourceLineCount","sourceLineHeight","row","candidate","isPositionInLineRange","toggleLineBookmarkInList","createId","nowIso","existingBookmark","bookmark","getPreviewCommentAnchors","commentAnchors","getPreviewLineAnnotations","bodyStartOffset","activeCommentId","includeEmptyLines","bodyOffset","sourceLine","hasBookmark","lineComments","getItemsInSourceLineRange","items","resolveRange","formatCommentDate","isoDate","now","date","elapsedSeconds","elapsedMinutes","elapsedHours","elapsedDays","getControlsLabel","activeViewMode","copy","getViewModeOptions","buildDocumentControlsModel","activeLineNumbers","activeLineWrapping","activeReadingWidth","activeSyncScrolling","readingWidthLabels","classNames","parts","buildDocumentSurface","hasSelectionActionPosition","searchOpen","selectedCharacterCount","shareOpen","splitDividerDragging","documentModeClassName","lineNumbersClassName","lineWrappingClassName","createPendingDocumentBufferCommit","fileId","resolvePendingDocumentBufferText","pendingCommit","fallbackText","readPendingText","readText","getDocumentBufferVisibleText","committedText","createDocumentBufferTextState","pending","visibleText","shouldCancelPendingDocumentBufferCommit","activeDocument","createEditorDocumentRuntime","initialFileId","initialRevision","initialText","dirty","pendingReader","pendingTextAvailable","revision","replaceAll","input","JSON_SHARE_KEY_BYTES","JSON_SHARE_ID_PATTERN","JSON_SHARE_API_PREFIX","JSON_SHARE_POST_PATH","trimTrailingSlash","createJsonShareUrl","origin","snapshotId","parseJsonShareFromHash","hash","fragment","jsonValue","extra","decodeBase64Url","getJsonShareRoute","location","getJsonShareImportRoute","route","routeKey","formatJsonShareUrlPreview","url","validateJsonShareCreateResponse","serviceUrl","isRecord","id","requireNonEmptyString","data","expectedData","expiresAt","optionalIsoDateString","requireString","fieldName","DEFAULT_FRONTMATTER_ESTIMATED_HEIGHT","DEFAULT_EDGE_PADDING","clamp","minimum","maximum","normalizeLineNumber","normalizeRatio","ratio","normalizeHeight","height","fallback","normalizedHeight","isPreviewBlockRenderableForTransfer","previewHeight","scrollableDistance","clampedScrollTop","getSourceProgress","findSegmentForLine","segment","findSegmentById","segmentId","getSegmentProgress","lineSpan","lineOffset","getRenderableSegments","getNearestRenderableBoundary","sourceSegment","renderableSegments","nearestSegment","firstDistance","secondDistance","nextSegment","previousSegment","buildSourceScrollSegments","previewBlockIndex","metadata","sourceLineOffset","frontmatterLineCount","frontmatterHeight","bodyLineCount","previewTop","resolveSourcePosition","editorPosition","sourceScrollMap","segmentProgress","sourceProgress","getPreviewScrollTopForSourcePosition","sourcePosition","viewport","rawScrollTop","getPreviewScrollTargetForEditorPosition","applyPreviewSegmentMeasurements","measuredSegment","TABULA_PRODUCT_SUPPORT_TARGETS","TABULA_LARGE_DOCUMENT_UX_POLICY","orderedMarkerPattern","listMarkerPattern","getSelectedLineRange","safeFrom","safeTo","selectedEnd","nextLineBreak","getListLineIndentChange","direction","listMatch","indent","removeCount","getCommonPrefixLength","left","right","getCommonSuffixLength","prefixLength","length","mapColumnThroughLineReplacement","column","originalLine","originalChangeEnd","nextChangeEnd","mapOffsetThroughLineReplacements","rangeStart","originalLines","originalLineStart","nextLineStart","originalLineEnd","renumberOrderedListRuns","countersByIndent","orderedMatch","previousNumber","nextNumber","getMarkdownIndentEdit","transformedLines","insert","markdownLinkPattern","safeMarkdownLinkUrlPattern","isSafeMarkdownLinkUrl","getMarkdownLinks","fullMatch","from","urlFrom","urlTo","getMarkdownLinkAtOffset","safeOffset","link","updateMarkdownLinkUrl","linkFrom","nextUrl","taskMarkerPattern","getLineRanges","lineBreak","getMarkdownTaskMarkers","stateStart","getMarkdownTaskAtOffset","toggleMarkdownTaskAtOffset","task","toggleMarkdownTaskOnLine","safeLineStart","textLength","normalizeSelection","to","replaceTextRange","insertion","selectionFrom","selectionTo","wrapInlineSelection","placeholder","selectedText","outerFrom","outerTo","innerText","insertLink","insertImage","replaceSelectedLines","transformLines","replaceEmptySelectedLine","placeholderFrom","placeholderLength","normalizedSelection","stripListMarker","isNonEmptyLine","applyHeading","nonEmptyLines","shouldRemove","applyQuote","applyBulletList","applyNumberedList","number","applyCheckList","isHorizontalRuleLine","applyHorizontalRule","insertAt","before","after","leadingBreak","trailingBreak","selectionOffset","applyCodeBlock","selectedFenceMatch","codeText","languagePlaceholder","insertBlockAtSelection","selectionLength","insertTable","insertFrontmatter","insertFootnote","clearInlineFormatting","clearLineFormatting","withoutBlockMarker","clearFormatting","cleanedText","applyMarkdownFormat","command","stripMarkdownExtension","getFileComments","commentsByFileId","getCommentActivityTime","comment","replyTimes","reply","getGroupActivityTime","group","sortCommentGroupsByActivity","groups","getRightPanelCommentGroups","files","openCommentGroups","file","resolvedCommentGroups","getRightPanelCommentScopeModel","activeFileId","commentScope","activeOpenCommentGroup","activeResolvedCommentGroup","scopedOpenCommentGroups","scopedResolvedCommentGroups","ROOM_ID_BYTES","ROOM_KEY_BYTES","ROOM_KEY_PATTERN","parseRoomFromHash","roomValue","roomKey","parseRoomKeyFromHash","createRoomShareUrl","parseRoomLocation","parsedRoom","parseRoomShareUrl","shareUrl","UNAVAILABLE_ROOM_LINK_LABEL","compactRoomId","getRoomShareLinkView","expectedRoomId","buildShareViewModel","canStartSession","isLive","labels","jsonShareCanExport","jsonShareDisabledReason","jsonShareExporting","jsonShareUrl","startSessionUnavailableReason","shareableHasLink","shareableBlocked","getStatusBarSaveState","roomAttentionLabels","roomOfflineLabel","savedLocallyLabel","statusLabel","removeRecordKey","record","_removed","nextRecord","restoreFileToList","restoredFile","restoredIndex","nextFiles","restoreOpenFileId","openFileIds","restoredFileId","previousOpenFileIds","previousOpenIndex","nextOpenFileIds","normalizeWorkspaceFileTitleForLookup","updateWorkspaceFileFields","fields","applyValueUpdater","update","uniqueKnownFileIds","fileIds","knownFileIds","nextFileIds","createWorkspaceModelState","nextActiveFileId","getOpenWorkspaceFiles","state","getActiveWorkspaceFile","normalizeWorkspaceFileTitle","trimmedTitle","getAvailableWorkspaceFileTitle","baseTitle","normalizedTitle","existingTitles","extensionMatch","extension","titleWithoutExtension","candidateTitle","renameWorkspaceFile","nextRawTitle","nextTitle","selectWorkspaceFile","setWorkspaceActiveFileId","addWorkspaceFile","insertAfterIndex","candidateFile","closeWorkspaceFile","closingIndex","openFileId","remainingOpenFileIds","closedActiveFile","nextActiveFile","deleteWorkspaceFile","deletedOpenIndex","deletedActiveFile","reorderOpenWorkspaceFile","sourceFileId","targetFileId","sourceIndex","targetIndex","movedFileId","selectAdjacentWorkspaceFile","openFiles","nextIndex","nextFile","updateWorkspaceFile","updateFile","updateActiveWorkspaceFile","workspaceReducer","action","getNewFilePreferenceOverrides","preferences","isSupportedImportFileDescriptor","fileName","createCurrentFileDownloadDraft","createImportedWorkspaceFileDraft","getWorkspaceStatusLabel","getActiveWorkspaceStatus","connectionStatus","getWorkspaceFileSearchText"],"mappings":"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"}