tldraw 3.15.0-next.f1dfcef63951 → 3.15.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 (162) hide show
  1. package/dist-cjs/index.d.ts +93 -92
  2. package/dist-cjs/index.js +32 -30
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawImage.js +5 -2
  5. package/dist-cjs/lib/TldrawImage.js.map +3 -3
  6. package/dist-cjs/lib/canvas/TldrawCropHandles.js +1 -1
  7. package/dist-cjs/lib/canvas/TldrawCropHandles.js.map +2 -2
  8. package/dist-cjs/lib/canvas/TldrawHandles.js +1 -1
  9. package/dist-cjs/lib/canvas/TldrawHandles.js.map +2 -2
  10. package/dist-cjs/lib/canvas/TldrawOverlays.js +1 -1
  11. package/dist-cjs/lib/canvas/TldrawOverlays.js.map +2 -2
  12. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +279 -271
  13. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  14. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +5 -5
  15. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/shapes/shared/PathBuilder.js +21 -3
  17. package/dist-cjs/lib/shapes/shared/PathBuilder.js.map +2 -2
  18. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -0
  19. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  20. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +1 -0
  21. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  22. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +5 -11
  23. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  24. package/dist-cjs/lib/styles.js.map +2 -2
  25. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +11 -1
  26. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
  27. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +1 -0
  28. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
  29. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +3 -4
  30. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
  31. package/dist-cjs/lib/ui/components/Spinner.js +2 -25
  32. package/dist-cjs/lib/ui/components/Spinner.js.map +2 -2
  33. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +2 -1
  34. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  35. package/dist-cjs/lib/ui/components/menu-items.js +16 -0
  36. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  37. package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButtonIcon.js.map +2 -2
  38. package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js +1 -1
  39. package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js.map +2 -2
  40. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +35 -1
  41. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
  42. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +5 -2
  43. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  44. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +1 -0
  45. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  46. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  47. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +0 -2
  48. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  49. package/dist-cjs/lib/ui/context/actions.js +28 -1
  50. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  51. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  52. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +24 -7
  53. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  54. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +2 -2
  55. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  56. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  57. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  58. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +4 -0
  59. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  60. package/dist-cjs/lib/ui/version.js +3 -3
  61. package/dist-cjs/lib/ui/version.js.map +1 -1
  62. package/dist-esm/index.d.mts +93 -92
  63. package/dist-esm/index.mjs +139 -133
  64. package/dist-esm/index.mjs.map +2 -2
  65. package/dist-esm/lib/TldrawImage.mjs +5 -2
  66. package/dist-esm/lib/TldrawImage.mjs.map +2 -2
  67. package/dist-esm/lib/canvas/TldrawCropHandles.mjs +1 -1
  68. package/dist-esm/lib/canvas/TldrawCropHandles.mjs.map +2 -2
  69. package/dist-esm/lib/canvas/TldrawHandles.mjs +1 -1
  70. package/dist-esm/lib/canvas/TldrawHandles.mjs.map +2 -2
  71. package/dist-esm/lib/canvas/TldrawOverlays.mjs +1 -1
  72. package/dist-esm/lib/canvas/TldrawOverlays.mjs.map +2 -2
  73. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +279 -271
  74. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  75. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +5 -5
  76. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  77. package/dist-esm/lib/shapes/shared/PathBuilder.mjs +22 -3
  78. package/dist-esm/lib/shapes/shared/PathBuilder.mjs.map +2 -2
  79. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -0
  80. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  81. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +1 -0
  82. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  83. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +5 -11
  84. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  85. package/dist-esm/lib/styles.mjs.map +2 -2
  86. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +11 -1
  87. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
  88. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs +2 -0
  89. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
  90. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +3 -4
  91. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
  92. package/dist-esm/lib/ui/components/Spinner.mjs +3 -26
  93. package/dist-esm/lib/ui/components/Spinner.mjs.map +2 -2
  94. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +2 -1
  95. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  96. package/dist-esm/lib/ui/components/menu-items.mjs +16 -0
  97. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  98. package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButtonIcon.mjs.map +2 -2
  99. package/dist-esm/lib/ui/components/primitives/TldrawUiDialog.mjs +1 -1
  100. package/dist-esm/lib/ui/components/primitives/TldrawUiDialog.mjs.map +2 -2
  101. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +36 -2
  102. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
  103. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +5 -2
  104. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  105. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +1 -0
  106. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  107. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  108. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +0 -2
  109. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  110. package/dist-esm/lib/ui/context/actions.mjs +28 -1
  111. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  112. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  113. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +24 -7
  114. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  115. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +2 -2
  116. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  117. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  118. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -0
  119. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  120. package/dist-esm/lib/ui/version.mjs +3 -3
  121. package/dist-esm/lib/ui/version.mjs.map +1 -1
  122. package/package.json +4 -3
  123. package/src/index.ts +165 -159
  124. package/src/lib/TldrawImage.tsx +6 -2
  125. package/src/lib/canvas/TldrawCropHandles.tsx +1 -1
  126. package/src/lib/canvas/TldrawHandles.tsx +5 -1
  127. package/src/lib/canvas/TldrawOverlays.tsx +1 -1
  128. package/src/lib/canvas/TldrawSelectionForeground.tsx +5 -1
  129. package/src/lib/shapes/frame/FrameShapeUtil.tsx +5 -7
  130. package/src/lib/shapes/shared/PathBuilder.test.tsx +1 -1
  131. package/src/lib/shapes/shared/PathBuilder.tsx +35 -1
  132. package/src/lib/shapes/shared/PlainTextLabel.tsx +1 -0
  133. package/src/lib/shapes/shared/RichTextLabel.tsx +1 -0
  134. package/src/lib/shapes/text/TextShapeUtil.tsx +5 -12
  135. package/src/lib/styles.tsx +3 -1
  136. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +8 -0
  137. package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +2 -0
  138. package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +3 -4
  139. package/src/lib/ui/components/Spinner.tsx +2 -24
  140. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +1 -0
  141. package/src/lib/ui/components/menu-items.tsx +17 -0
  142. package/src/lib/ui/components/primitives/Button/TldrawUiButtonIcon.tsx +2 -2
  143. package/src/lib/ui/components/primitives/TldrawUiDialog.tsx +1 -1
  144. package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +41 -3
  145. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +5 -1
  146. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +4 -0
  147. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +2 -2
  148. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +3 -4
  149. package/src/lib/ui/context/actions.tsx +30 -2
  150. package/src/lib/ui/context/events.tsx +2 -0
  151. package/src/lib/ui/hooks/useClipboardEvents.ts +31 -10
  152. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +3 -2
  153. package/src/lib/ui/hooks/useTools.tsx +2 -1
  154. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +4 -0
  155. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -0
  156. package/src/lib/ui/version.ts +3 -3
  157. package/src/lib/ui.css +8 -22
  158. package/src/test/Editor.test.tsx +68 -1
  159. package/src/test/commands/clipboard.test.ts +1 -1
  160. package/src/test/navigation.test.ts +254 -0
  161. package/tldraw.css +25 -26
  162. package/src/test/editor.test.ts +0 -77
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/PathBuilder.tsx"],
4
- "sourcesContent": ["import {\n\tapproximately,\n\tassert,\n\tassertExists,\n\tclamp,\n\tCubicBezier2d,\n\tEdge2d,\n\texhaustiveSwitchError,\n\tGeometry2d,\n\tGeometry2dFilters,\n\tGeometry2dOptions,\n\tgetPerfectDashProps,\n\tGroup2d,\n\tmodulate,\n\tPerfectDashTerminal,\n\trng,\n\ttoDomPrecision,\n\tVec,\n\tVecLike,\n\tVecModel,\n} from '@tldraw/editor'\nimport { ReactNode, SVGProps } from 'react'\n\n/** @public */\nexport interface BasePathBuilderOpts {\n\tstrokeWidth: number\n\tforceSolid?: boolean\n\tonlyFilled?: boolean\n\tprops?: SVGProps<SVGPathElement & SVGGElement>\n}\n\n/** @public */\nexport interface SolidPathBuilderOpts extends BasePathBuilderOpts {\n\tstyle: 'solid'\n}\n\n/** @public */\nexport interface DashedPathBuilderOpts extends BasePathBuilderOpts {\n\tstyle: 'dashed' | 'dotted'\n\tsnap?: number\n\tend?: PerfectDashTerminal\n\tstart?: PerfectDashTerminal\n\tlengthRatio?: number\n}\n\n/** @public */\nexport interface DrawPathBuilderDOpts {\n\tstrokeWidth: number\n\trandomSeed: string\n\toffset?: number\n\troundness?: number\n\tpasses?: number\n\tonlyFilled?: boolean\n}\n\n/** @public */\nexport interface DrawPathBuilderOpts extends BasePathBuilderOpts, DrawPathBuilderDOpts {\n\tstyle: 'draw'\n}\n\n/** @public */\nexport type PathBuilderOpts = SolidPathBuilderOpts | DashedPathBuilderOpts | DrawPathBuilderOpts\n\n/** @public */\nexport interface PathBuilderCommandOpts {\n\t/**\n\t * When converting to a draw-style line, how much offset from the original point should be\n\t * applied?\n\t */\n\toffset?: number\n\t/**\n\t * When converting to a draw-style line, how much roundness should be applied to the end of this\n\t * line?\n\t */\n\troundness?: number\n\t/**\n\t * When converting to a dash- or dot-style line, should the current segment be merged with the\n\t * previous segment when calculating the dash pattern? This is false by default, meaning each\n\t * command will start/end on a dash/dot boundary.\n\t */\n\tmergeWithPrevious?: boolean\n}\n\n/** @internal */\nexport interface PathBuilderCommandInfo {\n\ttangentStart: VecModel\n\ttangentEnd: VecModel\n\tlength: number\n}\n\n/** @internal */\nexport interface PathBuilderCommandBase {\n\topts?: PathBuilderCommandOpts\n\tx: number\n\ty: number\n\tisClose: boolean\n\t_info?: PathBuilderCommandInfo\n}\n\n/** @public */\nexport interface PathBuilderLineOpts extends PathBuilderCommandOpts {\n\tgeometry?: Omit<Geometry2dOptions, 'isClosed'> | false\n\tdashStart?: PerfectDashTerminal\n\tdashEnd?: PerfectDashTerminal\n}\n\n/** @internal */\nexport interface MoveToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'move'\n\tcloseIdx: number | null\n\topts?: PathBuilderLineOpts\n}\n\n/** @internal */\nexport interface LineToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'line'\n}\n\n/** @internal */\nexport interface CubicBezierToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'cubic'\n\tcp1: VecModel\n\tcp2: VecModel\n}\n\n/** @internal */\nexport type PathBuilderCommand =\n\t| MoveToPathBuilderCommand\n\t| LineToPathBuilderCommand\n\t| CubicBezierToPathBuilderCommand\n\n/** @public */\nexport interface PathBuilderToDOpts {\n\tstartIdx?: number\n\tendIdx?: number\n\tonlyFilled?: boolean\n}\n\n/** @public */\nexport class PathBuilder {\n\tstatic lineThroughPoints(\n\t\tpoints: VecLike[],\n\t\topts?: PathBuilderLineOpts & { endOffsets?: number }\n\t) {\n\t\tconst path = new PathBuilder()\n\t\tpath.moveTo(points[0].x, points[0].y, { ...opts, offset: opts?.endOffsets ?? opts?.offset })\n\t\tfor (let i = 1; i < points.length; i++) {\n\t\t\tconst isLast = i === points.length - 1\n\t\t\tpath.lineTo(points[i].x, points[i].y, isLast ? { offset: opts?.endOffsets } : undefined)\n\t\t}\n\t\treturn path\n\t}\n\n\tstatic cubicSplineThroughPoints(\n\t\tpoints: VecLike[],\n\t\topts?: PathBuilderLineOpts & { endOffsets?: number }\n\t) {\n\t\tconst path = new PathBuilder()\n\t\tconst len = points.length\n\t\tconst last = len - 2\n\t\tconst k = 1.25\n\n\t\tpath.moveTo(points[0].x, points[0].y, { ...opts, offset: opts?.endOffsets ?? opts?.offset })\n\n\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\tconst p0 = i === 0 ? points[0] : points[i - 1]\n\t\t\tconst p1 = points[i]\n\t\t\tconst p2 = points[i + 1]\n\t\t\tconst p3 = i === last ? p2 : points[i + 2]\n\n\t\t\tlet cp1x, cp1y, cp2x, cp2y\n\t\t\tif (i === 0) {\n\t\t\t\tcp1x = p0.x\n\t\t\t\tcp1y = p0.y\n\t\t\t} else {\n\t\t\t\tcp1x = p1.x + ((p2.x - p0.x) / 6) * k\n\t\t\t\tcp1y = p1.y + ((p2.y - p0.y) / 6) * k\n\t\t\t}\n\n\t\t\tlet pointOpts = undefined\n\t\t\tif (i === last) {\n\t\t\t\tcp2x = p2.x\n\t\t\t\tcp2y = p2.y\n\t\t\t\tpointOpts = { offset: opts?.endOffsets }\n\t\t\t} else {\n\t\t\t\tcp2x = p2.x - ((p3.x - p1.x) / 6) * k\n\t\t\t\tcp2y = p2.y - ((p3.y - p1.y) / 6) * k\n\t\t\t}\n\n\t\t\tpath.cubicBezierTo(p2.x, p2.y, cp1x, cp1y, cp2x, cp2y, pointOpts)\n\t\t}\n\n\t\treturn path\n\t}\n\n\tconstructor() {}\n\n\t/** @internal */\n\tcommands: PathBuilderCommand[] = []\n\n\tprivate lastMoveTo: MoveToPathBuilderCommand | null = null\n\tprivate assertHasMoveTo() {\n\t\tassert(this.lastMoveTo, 'Start an SVGPathBuilder with `.moveTo()`')\n\t\treturn this.lastMoveTo\n\t}\n\n\tmoveTo(x: number, y: number, opts?: PathBuilderLineOpts) {\n\t\tthis.lastMoveTo = { type: 'move', x, y, closeIdx: null, isClose: false, opts }\n\t\tthis.commands.push(this.lastMoveTo)\n\t\treturn this\n\t}\n\n\tlineTo(x: number, y: number, opts?: PathBuilderCommandOpts) {\n\t\tthis.assertHasMoveTo()\n\t\tthis.commands.push({ type: 'line', x, y, isClose: false, opts })\n\t\treturn this\n\t}\n\n\tcircularArcTo(\n\t\tradius: number,\n\t\tlargeArcFlag: boolean,\n\t\tsweepFlag: boolean,\n\t\tx2: number,\n\t\ty2: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\treturn this.arcTo(radius, radius, largeArcFlag, sweepFlag, 0, x2, y2, opts)\n\t}\n\n\tarcTo(\n\t\trx: number,\n\t\try: number,\n\t\tlargeArcFlag: boolean,\n\t\tsweepFlag: boolean,\n\t\txAxisRotationRadians: number,\n\t\tx2: number,\n\t\ty2: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\t// As arc flags make them very sensitive to offsets when we render them in draw mode, we\n\t\t// approximate arcs by converting them to up to 4 (1 per 90\u00B0 segment) cubic bezier curves.\n\t\t// This algorithm is a Claude special:\n\t\t// https://claude.ai/public/artifacts/5ea0bf18-4afb-4b3d-948d-31b8a77ef1e2\n\n\t\tthis.assertHasMoveTo()\n\n\t\tconst x1 = this.commands[this.commands.length - 1].x\n\t\tconst y1 = this.commands[this.commands.length - 1].y\n\n\t\t// If the endpoints are identical, don't add a command\n\t\tif (x1 === x2 && y1 === y2) {\n\t\t\treturn this\n\t\t}\n\n\t\t// If rx or ry is 0, return a straight line\n\t\tif (rx === 0 || ry === 0) {\n\t\t\treturn this.lineTo(x2, y2, opts)\n\t\t}\n\n\t\t// Convert angle from degrees to radians\n\t\tconst phi = xAxisRotationRadians\n\t\tconst sinPhi = Math.sin(phi)\n\t\tconst cosPhi = Math.cos(phi)\n\n\t\t// Ensure rx and ry are positive\n\t\tlet rx1 = Math.abs(rx)\n\t\tlet ry1 = Math.abs(ry)\n\n\t\t// Step 1: Compute (x1', y1') - transform from ellipse coordinate system to unit circle\n\t\tconst dx = (x1 - x2) / 2\n\t\tconst dy = (y1 - y2) / 2\n\t\tconst x1p = cosPhi * dx + sinPhi * dy\n\t\tconst y1p = -sinPhi * dx + cosPhi * dy\n\n\t\t// Correction of out-of-range radii\n\t\tconst lambda = (x1p * x1p) / (rx1 * rx1) + (y1p * y1p) / (ry1 * ry1)\n\t\tif (lambda > 1) {\n\t\t\tconst sqrtLambda = Math.sqrt(lambda)\n\t\t\trx1 *= sqrtLambda\n\t\t\try1 *= sqrtLambda\n\t\t}\n\n\t\t// Step 2: Compute (cx', cy') - center of ellipse in transformed system\n\t\tconst sign = largeArcFlag !== sweepFlag ? 1 : -1\n\n\t\tconst term = rx1 * rx1 * ry1 * ry1 - rx1 * rx1 * y1p * y1p - ry1 * ry1 * x1p * x1p\n\t\tconst numerator = rx1 * rx1 * y1p * y1p + ry1 * ry1 * x1p * x1p\n\n\t\tlet radicand = term / numerator\n\t\tradicand = radicand < 0 ? 0 : radicand\n\n\t\tconst coef = sign * Math.sqrt(radicand)\n\n\t\tconst cxp = coef * ((rx1 * y1p) / ry1)\n\t\tconst cyp = coef * (-(ry1 * x1p) / rx1)\n\n\t\t// Step 3: Compute (cx, cy) from (cx', cy') - transform back to original coordinate system\n\t\tconst cx = cosPhi * cxp - sinPhi * cyp + (x1 + x2) / 2\n\t\tconst cy = sinPhi * cxp + cosPhi * cyp + (y1 + y2) / 2\n\n\t\t// Step 4: Compute the start and end angles\n\t\tconst ux = (x1p - cxp) / rx1\n\t\tconst uy = (y1p - cyp) / ry1\n\t\tconst vx = (-x1p - cxp) / rx1\n\t\tconst vy = (-y1p - cyp) / ry1\n\n\t\tconst startAngle = Math.atan2(uy, ux)\n\t\tlet endAngle = Math.atan2(vy, vx)\n\n\t\t// Ensure correct sweep direction\n\t\tif (!sweepFlag && endAngle > startAngle) {\n\t\t\tendAngle -= 2 * Math.PI\n\t\t} else if (sweepFlag && endAngle < startAngle) {\n\t\t\tendAngle += 2 * Math.PI\n\t\t}\n\n\t\t// Calculate the sweep angle\n\t\tconst sweepAngle = endAngle - startAngle\n\n\t\t// Approximate the arc using cubic bezier curves\n\t\tconst numSegments = Math.min(4, Math.ceil(Math.abs(sweepAngle) / (Math.PI / 2)))\n\t\tconst anglePerSegment = sweepAngle / numSegments\n\n\t\t// Helper function to compute point on ellipse\n\t\tconst ellipsePoint = (angle: number) => {\n\t\t\treturn {\n\t\t\t\tx: cx + rx1 * Math.cos(angle) * cosPhi - ry1 * Math.sin(angle) * sinPhi,\n\t\t\t\ty: cy + rx1 * Math.cos(angle) * sinPhi + ry1 * Math.sin(angle) * cosPhi,\n\t\t\t}\n\t\t}\n\n\t\t// Helper function to compute derivative (tangent vector) at a point on the ellipse\n\t\tconst ellipseDerivative = (angle: number) => {\n\t\t\treturn {\n\t\t\t\tx: -rx1 * Math.sin(angle) * cosPhi - ry1 * Math.cos(angle) * sinPhi,\n\t\t\t\ty: -rx1 * Math.sin(angle) * sinPhi + ry1 * Math.cos(angle) * cosPhi,\n\t\t\t}\n\t\t}\n\n\t\t// Generate cubic bezier approximations\n\t\tfor (let i = 0; i < numSegments; i++) {\n\t\t\tconst theta1 = startAngle + i * anglePerSegment\n\t\t\tconst theta2 = startAngle + (i + 1) * anglePerSegment\n\t\t\tconst deltaTheta = theta2 - theta1\n\n\t\t\tconst start = ellipsePoint(theta1)\n\t\t\tconst end = ellipsePoint(theta2)\n\n\t\t\t// Get the derivative at the start and end points\n\t\t\tconst d1 = ellipseDerivative(theta1)\n\t\t\tconst d2 = ellipseDerivative(theta2)\n\n\t\t\t// Calculate the length of the tangent handles\n\t\t\t// This is a key factor for the accuracy of the approximation\n\t\t\t// For a 90\u00B0 arc, the handle length should be 4/3 * tan(\u03C0/8) * r\n\t\t\t// For smaller arcs, we scale this value by the angle ratio\n\t\t\tconst handleScale = (4 / 3) * Math.tan(deltaTheta / 4)\n\n\t\t\t// Create control points that are tangent to the ellipse at the endpoints\n\t\t\tconst cp1x = start.x + handleScale * d1.x\n\t\t\tconst cp1y = start.y + handleScale * d1.y\n\n\t\t\tconst cp2x = end.x - handleScale * d2.x\n\t\t\tconst cp2y = end.y - handleScale * d2.y\n\n\t\t\tconst bezierOpts = i === 0 ? opts : { ...opts, mergeWithPrevious: true }\n\t\t\tthis.cubicBezierTo(end.x, end.y, cp1x, cp1y, cp2x, cp2y, bezierOpts)\n\t\t}\n\n\t\treturn this\n\t}\n\n\tcubicBezierTo(\n\t\tx: number,\n\t\ty: number,\n\t\tcp1X: number,\n\t\tcp1Y: number,\n\t\tcp2X: number,\n\t\tcp2Y: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\tthis.assertHasMoveTo()\n\t\tthis.commands.push({\n\t\t\ttype: 'cubic',\n\t\t\tx,\n\t\t\ty,\n\t\t\tcp1: { x: cp1X, y: cp1Y },\n\t\t\tcp2: { x: cp2X, y: cp2Y },\n\t\t\tisClose: false,\n\t\t\topts,\n\t\t})\n\t\treturn this\n\t}\n\n\tclose() {\n\t\tconst lastMoveTo = this.assertHasMoveTo()\n\t\tconst lastCommand = this.commands[this.commands.length - 1]\n\n\t\tif (approximately(lastMoveTo.x, lastCommand.x) && approximately(lastMoveTo.y, lastCommand.y)) {\n\t\t\tlastCommand.isClose = true\n\t\t} else {\n\t\t\tthis.commands.push({\n\t\t\t\ttype: 'line',\n\t\t\t\tx: lastMoveTo.x,\n\t\t\t\ty: lastMoveTo.y,\n\t\t\t\tisClose: true,\n\t\t\t})\n\t\t}\n\n\t\tlastMoveTo.closeIdx = this.commands.length - 1\n\t\tthis.lastMoveTo = null\n\t\treturn this\n\t}\n\n\ttoD(opts: PathBuilderToDOpts = {}) {\n\t\tconst { startIdx = 0, endIdx = this.commands.length, onlyFilled = false } = opts\n\t\tconst parts = []\n\n\t\tlet isSkippingCurrentLine = false\n\n\t\tlet didAddMove = false\n\t\tlet didAddNaturalMove = false\n\n\t\tconst addMoveIfNeeded = (i: number) => {\n\t\t\tif (didAddMove || i === 0) return\n\t\t\tdidAddMove = true\n\t\t\tconst command = this.commands[i - 1]\n\t\t\tparts.push('M', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t}\n\n\t\tfor (let i = startIdx; i < endIdx; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tswitch (command.type) {\n\t\t\t\tcase 'move': {\n\t\t\t\t\tconst isFilled =\n\t\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\t\tif (onlyFilled && !isFilled) {\n\t\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\t\tdidAddMove = true\n\t\t\t\t\t\tdidAddNaturalMove = true\n\t\t\t\t\t\tparts.push('M', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'line':\n\t\t\t\t\tif (isSkippingCurrentLine) break\n\t\t\t\t\taddMoveIfNeeded(i)\n\t\t\t\t\tif (command.isClose && didAddNaturalMove) {\n\t\t\t\t\t\tparts.push('Z')\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparts.push('L', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic':\n\t\t\t\t\tif (isSkippingCurrentLine) break\n\t\t\t\t\taddMoveIfNeeded(i)\n\t\t\t\t\tparts.push(\n\t\t\t\t\t\t'C',\n\t\t\t\t\t\ttoDomPrecision(command.cp1.x),\n\t\t\t\t\t\ttoDomPrecision(command.cp1.y),\n\t\t\t\t\t\ttoDomPrecision(command.cp2.x),\n\t\t\t\t\t\ttoDomPrecision(command.cp2.y),\n\t\t\t\t\t\ttoDomPrecision(command.x),\n\t\t\t\t\t\ttoDomPrecision(command.y)\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t}\n\t\t}\n\t\treturn parts.join(' ')\n\t}\n\n\ttoSvg(opts: PathBuilderOpts) {\n\t\tif (opts.forceSolid) {\n\t\t\treturn this.toSolidSvg(opts)\n\t\t}\n\t\tswitch (opts.style) {\n\t\t\tcase 'solid':\n\t\t\t\treturn this.toSolidSvg(opts)\n\t\t\tcase 'dashed':\n\t\t\tcase 'dotted':\n\t\t\t\treturn this.toDashedSvg(opts)\n\t\t\tcase 'draw': {\n\t\t\t\tconst d = this.toDrawSvg(opts)\n\t\t\t\treturn d\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(opts, 'style')\n\t\t}\n\t}\n\n\ttoGeometry(): PathBuilderGeometry2d | Group2d {\n\t\tconst geometries = []\n\n\t\tlet current: null | {\n\t\t\tstartIdx: number\n\t\t\tmoveCommand: MoveToPathBuilderCommand\n\t\t\tisClosed: boolean\n\t\t\topts?: PathBuilderLineOpts\n\t\t} = null\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\n\t\t\tif (command.type === 'move') {\n\t\t\t\tif (current && current.opts?.geometry !== false) {\n\t\t\t\t\tgeometries.push(\n\t\t\t\t\t\tnew PathBuilderGeometry2d(this, current.startIdx, i, {\n\t\t\t\t\t\t\t...current.opts?.geometry,\n\t\t\t\t\t\t\tisFilled: current.opts?.geometry?.isFilled ?? false,\n\t\t\t\t\t\t\tisClosed: current.moveCommand.closeIdx !== null,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcurrent = { startIdx: i, moveCommand: command, opts: command.opts, isClosed: false }\n\t\t\t}\n\n\t\t\tif (command.isClose) {\n\t\t\t\tassert(current, 'No current move command')\n\t\t\t\tcurrent.isClosed = true\n\t\t\t}\n\t\t}\n\n\t\tif (current && current.opts?.geometry !== false) {\n\t\t\tgeometries.push(\n\t\t\t\tnew PathBuilderGeometry2d(this, current.startIdx, this.commands.length, {\n\t\t\t\t\t...current.opts?.geometry,\n\t\t\t\t\tisFilled: current.opts?.geometry?.isFilled ?? false,\n\t\t\t\t\tisClosed: current.moveCommand.closeIdx !== null,\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\tassert(geometries.length > 0)\n\t\tif (geometries.length === 1) return geometries[0]\n\t\treturn new Group2d({ children: geometries })\n\t}\n\n\tprivate toSolidSvg(opts: PathBuilderOpts) {\n\t\tconst { strokeWidth, props } = opts\n\n\t\treturn (\n\t\t\t<path strokeWidth={strokeWidth} d={this.toD({ onlyFilled: opts.onlyFilled })} {...props} />\n\t\t)\n\t}\n\n\tprivate toDashedSvg(opts: DashedPathBuilderOpts) {\n\t\tconst {\n\t\t\tstyle,\n\t\t\tstrokeWidth,\n\t\t\tsnap,\n\t\t\tlengthRatio,\n\t\t\tprops: { markerStart, markerEnd, ...props } = {},\n\t\t} = opts\n\n\t\tconst parts: ReactNode[] = []\n\n\t\tlet isCurrentPathClosed = false\n\t\tlet isSkippingCurrentLine = false\n\t\tlet currentLineOpts: PathBuilderLineOpts | undefined = undefined\n\n\t\tlet currentRun: {\n\t\t\tstartIdx: number\n\t\t\tendIdx: number\n\t\t\tisFirst: boolean\n\t\t\tisLast: boolean\n\t\t\tlength: number\n\t\t\tlineOpts: PathBuilderLineOpts | undefined\n\t\t\tpathIsClosed: boolean\n\t\t} | null = null\n\n\t\tconst addCurrentRun = () => {\n\t\t\tif (!currentRun) return\n\t\t\tconst { startIdx, endIdx, isFirst, isLast, length, lineOpts, pathIsClosed } = currentRun\n\t\t\tcurrentRun = null\n\n\t\t\tif (startIdx === endIdx && this.commands[startIdx].type === 'move') return\n\n\t\t\tconst start = lineOpts?.dashStart ?? opts.start\n\t\t\tconst end = lineOpts?.dashEnd ?? opts.end\n\t\t\tconst { strokeDasharray, strokeDashoffset } = getPerfectDashProps(length, strokeWidth, {\n\t\t\t\tstyle,\n\t\t\t\tsnap,\n\t\t\t\tlengthRatio,\n\t\t\t\tstart: isFirst ? (start ?? (pathIsClosed ? 'outset' : 'none')) : 'outset',\n\t\t\t\tend: isLast ? (end ?? (pathIsClosed ? 'outset' : 'none')) : 'outset',\n\t\t\t})\n\n\t\t\tconst d = this.toD({ startIdx, endIdx: endIdx + 1 })\n\t\t\tparts.push(\n\t\t\t\t<path\n\t\t\t\t\tkey={parts.length}\n\t\t\t\t\td={d}\n\t\t\t\t\tstrokeDasharray={strokeDasharray}\n\t\t\t\t\tstrokeDashoffset={strokeDashoffset}\n\t\t\t\t\tmarkerStart={isFirst ? markerStart : undefined}\n\t\t\t\t\tmarkerEnd={isLast ? markerEnd : undefined}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tconst lastCommand = this.commands[i - 1]\n\t\t\tif (command.type === 'move') {\n\t\t\t\tisCurrentPathClosed = command.closeIdx !== null\n\t\t\t\tconst isFilled =\n\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\tif (opts.onlyFilled && !isFilled) {\n\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t} else {\n\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\tcurrentLineOpts = command.opts\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (isSkippingCurrentLine) continue\n\n\t\t\tconst segmentLength = this.calculateSegmentLength(lastCommand, command)\n\t\t\tconst isFirst = lastCommand.type === 'move'\n\t\t\tconst isLast =\n\t\t\t\tcommand.isClose || i === this.commands.length - 1 || this.commands[i + 1]?.type === 'move'\n\n\t\t\tif (currentRun && command.opts?.mergeWithPrevious) {\n\t\t\t\tcurrentRun.length += segmentLength\n\t\t\t\tcurrentRun.endIdx = i\n\t\t\t\tcurrentRun.isLast = isLast\n\t\t\t} else {\n\t\t\t\taddCurrentRun()\n\t\t\t\tcurrentRun = {\n\t\t\t\t\tstartIdx: i,\n\t\t\t\t\tendIdx: i,\n\t\t\t\t\tisFirst,\n\t\t\t\t\tisLast,\n\t\t\t\t\tlength: segmentLength,\n\t\t\t\t\tlineOpts: currentLineOpts,\n\t\t\t\t\tpathIsClosed: isCurrentPathClosed,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\taddCurrentRun()\n\n\t\treturn (\n\t\t\t<g strokeWidth={strokeWidth} {...props}>\n\t\t\t\t{parts}\n\t\t\t</g>\n\t\t)\n\t}\n\n\tprivate toDrawSvg(opts: DrawPathBuilderOpts) {\n\t\treturn <path strokeWidth={opts.strokeWidth} d={this.toDrawD(opts)} {...opts.props} />\n\t}\n\n\ttoDrawD(opts: DrawPathBuilderDOpts) {\n\t\tconst {\n\t\t\tstrokeWidth,\n\t\t\trandomSeed,\n\t\t\toffset: defaultOffset = strokeWidth / 3,\n\t\t\troundness: defaultRoundness = strokeWidth * 2,\n\t\t\tpasses = 2,\n\t\t\tonlyFilled = false,\n\t\t} = opts\n\n\t\tconst parts = []\n\n\t\tconst commandInfo = this.getCommandInfo()\n\n\t\t// for each command, we draw the line for the command, plus the corner to the next command.\n\t\tconst drawCommands = []\n\t\tlet lastMoveCommandIdx = null\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tconst offset = command.opts?.offset ?? defaultOffset\n\t\t\tconst roundness = command.opts?.roundness ?? defaultRoundness\n\n\t\t\tif (command.type === 'move') {\n\t\t\t\tlastMoveCommandIdx = i\n\t\t\t}\n\n\t\t\tconst nextIdx = command.isClose\n\t\t\t\t? assertExists(lastMoveCommandIdx) + 1\n\t\t\t\t: !this.commands[i + 1] || this.commands[i + 1].type === 'move'\n\t\t\t\t\t? undefined\n\t\t\t\t\t: i + 1\n\n\t\t\tconst nextInfo =\n\t\t\t\tnextIdx !== undefined && this.commands[nextIdx] && this.commands[nextIdx]?.type !== 'move'\n\t\t\t\t\t? commandInfo[nextIdx]\n\t\t\t\t\t: undefined\n\n\t\t\tconst currentSupportsRoundness = commandsSupportingRoundness[command.type]\n\t\t\tconst nextSupportsRoundness =\n\t\t\t\tnextIdx !== undefined ? commandsSupportingRoundness[this.commands[nextIdx].type] : false\n\n\t\t\tconst currentInfo = commandInfo[i]\n\n\t\t\tconst tangentToPrev = currentInfo?.tangentEnd\n\t\t\tconst tangentToNext = nextInfo?.tangentStart\n\n\t\t\tconst roundnessClampedForAngle =\n\t\t\t\tcurrentSupportsRoundness &&\n\t\t\t\tnextSupportsRoundness &&\n\t\t\t\ttangentToPrev &&\n\t\t\t\ttangentToNext &&\n\t\t\t\tVec.Len2(tangentToPrev) > 0.01 &&\n\t\t\t\tVec.Len2(tangentToNext) > 0.01\n\t\t\t\t\t? modulate(\n\t\t\t\t\t\t\tMath.abs(Vec.AngleBetween(tangentToPrev, tangentToNext)),\n\t\t\t\t\t\t\t[Math.PI / 2, Math.PI],\n\t\t\t\t\t\t\t[roundness, 0],\n\t\t\t\t\t\t\ttrue\n\t\t\t\t\t\t)\n\t\t\t\t\t: 0\n\n\t\t\tconst shortestDistance = Math.min(\n\t\t\t\tcurrentInfo?.length ?? Infinity,\n\t\t\t\tnextInfo?.length ?? Infinity\n\t\t\t)\n\t\t\tconst offsetLimit = shortestDistance - roundnessClampedForAngle * 2\n\n\t\t\tconst offsetAmount = clamp(offset, 0, offsetLimit / 4)\n\n\t\t\tconst roundnessBeforeClampedForLength = Math.min(\n\t\t\t\troundnessClampedForAngle,\n\t\t\t\t(currentInfo?.length ?? Infinity) / 4\n\t\t\t)\n\t\t\tconst roundnessAfterClampedForLength = Math.min(\n\t\t\t\troundnessClampedForAngle,\n\t\t\t\t(nextInfo?.length ?? Infinity) / 4\n\t\t\t)\n\n\t\t\tconst drawCommand = {\n\t\t\t\tcommand,\n\t\t\t\toffsetAmount,\n\t\t\t\troundnessBefore: roundnessBeforeClampedForLength,\n\t\t\t\troundnessAfter: roundnessAfterClampedForLength,\n\t\t\t\ttangentToPrev: commandInfo[i]?.tangentEnd,\n\t\t\t\ttangentToNext: nextInfo?.tangentStart,\n\t\t\t\tmoveDidClose: false,\n\t\t\t}\n\n\t\t\tdrawCommands.push(drawCommand)\n\n\t\t\tif (command.isClose && lastMoveCommandIdx !== null) {\n\t\t\t\tconst lastMoveCommand = drawCommands[lastMoveCommandIdx]\n\t\t\t\tlastMoveCommand.moveDidClose = true\n\t\t\t\tlastMoveCommand.roundnessAfter = roundnessAfterClampedForLength\n\t\t\t} else if (command.type === 'move') {\n\t\t\t\tlastMoveCommandIdx = i\n\t\t\t}\n\t\t}\n\n\t\tfor (let pass = 0; pass < passes; pass++) {\n\t\t\tconst random = rng(randomSeed + pass)\n\n\t\t\tlet lastMoveToOffset = { x: 0, y: 0 }\n\t\t\tlet isSkippingCurrentLine = false\n\t\t\tfor (const {\n\t\t\t\tcommand,\n\t\t\t\toffsetAmount,\n\t\t\t\troundnessBefore,\n\t\t\t\troundnessAfter,\n\t\t\t\ttangentToNext,\n\t\t\t\ttangentToPrev,\n\t\t\t} of drawCommands) {\n\t\t\t\tconst offset = command.isClose\n\t\t\t\t\t? lastMoveToOffset\n\t\t\t\t\t: { x: random() * offsetAmount, y: random() * offsetAmount }\n\n\t\t\t\tif (command.type === 'move') {\n\t\t\t\t\tlastMoveToOffset = offset\n\t\t\t\t\tconst isFilled =\n\t\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\t\tif (onlyFilled && !isFilled) {\n\t\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (isSkippingCurrentLine) continue\n\n\t\t\t\tconst offsetPoint = Vec.Add(command, offset)\n\n\t\t\t\tconst endPoint =\n\t\t\t\t\ttangentToNext && roundnessAfter > 0\n\t\t\t\t\t\t? Vec.Mul(tangentToNext, -roundnessAfter).add(offsetPoint)\n\t\t\t\t\t\t: offsetPoint\n\n\t\t\t\tconst startPoint =\n\t\t\t\t\ttangentToPrev && roundnessBefore > 0\n\t\t\t\t\t\t? Vec.Mul(tangentToPrev, roundnessBefore).add(offsetPoint)\n\t\t\t\t\t\t: offsetPoint\n\n\t\t\t\tif (endPoint === offsetPoint || startPoint === offsetPoint) {\n\t\t\t\t\tswitch (command.type) {\n\t\t\t\t\t\tcase 'move':\n\t\t\t\t\t\t\tparts.push('M', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'line':\n\t\t\t\t\t\t\tparts.push('L', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'cubic': {\n\t\t\t\t\t\t\tconst offsetCp1 = Vec.Add(command.cp1, offset)\n\t\t\t\t\t\t\tconst offsetCp2 = Vec.Add(command.cp2, offset)\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'C',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (command.type) {\n\t\t\t\t\t\tcase 'move':\n\t\t\t\t\t\t\tparts.push('M', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'line':\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'L',\n\t\t\t\t\t\t\t\ttoDomPrecision(startPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(startPoint.y),\n\n\t\t\t\t\t\t\t\t'Q',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'cubic': {\n\t\t\t\t\t\t\tconst offsetCp1 = Vec.Add(command.cp1, offset)\n\t\t\t\t\t\t\tconst offsetCp2 = Vec.Add(command.cp2, offset)\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'C',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn parts.join(' ')\n\t}\n\n\tprivate calculateSegmentLength(lastPoint: VecLike, command: PathBuilderCommand) {\n\t\tswitch (command.type) {\n\t\t\tcase 'move':\n\t\t\t\treturn 0\n\t\t\tcase 'line':\n\t\t\t\treturn Vec.Dist(lastPoint, command)\n\t\t\tcase 'cubic':\n\t\t\t\treturn CubicBezier.length(\n\t\t\t\t\tlastPoint.x,\n\t\t\t\t\tlastPoint.y,\n\t\t\t\t\tcommand.cp1.x,\n\t\t\t\t\tcommand.cp1.y,\n\t\t\t\t\tcommand.cp2.x,\n\t\t\t\t\tcommand.cp2.y,\n\t\t\t\t\tcommand.x,\n\t\t\t\t\tcommand.y\n\t\t\t\t)\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t}\n\t}\n\n\t/** @internal */\n\tgetCommands(): readonly PathBuilderCommand[] {\n\t\treturn this.commands\n\t}\n\n\t/** @internal */\n\tgetCommandInfo() {\n\t\tconst commandInfo: Array<undefined | PathBuilderCommandInfo> = []\n\t\tfor (let i = 1; i < this.commands.length; i++) {\n\t\t\tconst previous = this.commands[i - 1]\n\t\t\tconst current = this.commands[i]\n\n\t\t\tif (current._info) {\n\t\t\t\tcommandInfo[i] = current._info\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (current.type === 'move') {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet tangentStart, tangentEnd\n\t\t\tswitch (current.type) {\n\t\t\t\tcase 'line':\n\t\t\t\t\ttangentStart = tangentEnd = Vec.Sub(previous, current).uni()\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic': {\n\t\t\t\t\ttangentStart = Vec.Sub(current.cp1, previous).uni()\n\t\t\t\t\ttangentEnd = Vec.Sub(current.cp2, current).uni()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(current, 'type')\n\t\t\t}\n\n\t\t\tcurrent._info = {\n\t\t\t\ttangentStart,\n\t\t\t\ttangentEnd,\n\t\t\t\tlength: this.calculateSegmentLength(previous, current),\n\t\t\t}\n\t\t\tcommandInfo[i] = current._info\n\t\t}\n\n\t\treturn commandInfo\n\t}\n}\n\nconst commandsSupportingRoundness = {\n\tline: true,\n\tmove: true,\n\tcubic: false,\n} as const satisfies Record<PathBuilderCommand['type'], boolean>\n\n/** @public */\nexport class PathBuilderGeometry2d extends Geometry2d {\n\tconstructor(\n\t\tprivate readonly path: PathBuilder,\n\t\tprivate readonly startIdx: number,\n\t\tprivate readonly endIdx: number,\n\t\toptions: Geometry2dOptions\n\t) {\n\t\tsuper(options)\n\t}\n\n\tprivate _segments: Geometry2d[] | null = null\n\tgetSegments() {\n\t\tif (this._segments) return this._segments\n\n\t\tthis._segments = []\n\t\tlet last = this.path.commands[this.startIdx]\n\t\tassert(last.type === 'move')\n\n\t\tfor (let i = this.startIdx + 1; i < this.endIdx; i++) {\n\t\t\tconst command = this.path.commands[i]\n\t\t\tassert(command.type !== 'move')\n\n\t\t\tswitch (command.type) {\n\t\t\t\tcase 'line':\n\t\t\t\t\tthis._segments.push(new Edge2d({ start: Vec.From(last), end: Vec.From(command) }))\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic': {\n\t\t\t\t\tthis._segments.push(\n\t\t\t\t\t\tnew CubicBezier2d({\n\t\t\t\t\t\t\tstart: Vec.From(last),\n\t\t\t\t\t\t\tcp1: Vec.From(command.cp1),\n\t\t\t\t\t\t\tcp2: Vec.From(command.cp2),\n\t\t\t\t\t\t\tend: Vec.From(command),\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t}\n\n\t\t\tlast = command\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getVertices(filters: Geometry2dFilters): Vec[] {\n\t\tconst vs = this.getSegments()\n\t\t\t.flatMap((s) => s.getVertices(filters))\n\t\t\t.filter((vertex, i, vertices) => {\n\t\t\t\tconst prev = vertices[i - 1]\n\t\t\t\tif (!prev) return true\n\t\t\t\treturn !Vec.Equals(prev, vertex)\n\t\t\t})\n\n\t\tif (this.isClosed) {\n\t\t\tconst last = vs[vs.length - 1]\n\t\t\tconst first = vs[0]\n\t\t\tif (!Vec.Equals(last, first)) {\n\t\t\t\tvs.push(first)\n\t\t\t}\n\t\t}\n\n\t\treturn vs\n\t}\n\n\toverride nearestPoint(point: VecLike, _filters?: Geometry2dFilters): Vec {\n\t\tlet nearest: Vec | null = null\n\t\tlet nearestDistance = Infinity\n\n\t\tfor (const segment of this.getSegments()) {\n\t\t\tconst candidate = segment.nearestPoint(point)\n\t\t\tconst distance = Vec.Dist2(point, candidate)\n\t\t\tif (distance < nearestDistance) {\n\t\t\t\tnearestDistance = distance\n\t\t\t\tnearest = candidate\n\t\t\t}\n\t\t}\n\n\t\tassert(nearest, 'No nearest point found')\n\t\treturn nearest\n\t}\n\n\toverride hitTestLineSegment(\n\t\tA: VecLike,\n\t\tB: VecLike,\n\t\tdistance = 0,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn super.hitTestLineSegment(A, B, distance, filters)\n\t}\n\toverride getSvgPathData(): string {\n\t\treturn this.path.toD({ startIdx: this.startIdx, endIdx: this.endIdx })\n\t}\n}\n\n/*!\n * Adapted from https://github.com/adobe-webplatform/Snap.svg/tree/master\n * Apache License: https://github.com/adobe-webplatform/Snap.svg/blob/master/LICENSE\n * https://github.com/adobe-webplatform/Snap.svg/blob/c8e483c9694517e24b282f8f59f985629f4994ce/dist/snap.svg.js#L5786\n */\nconst CubicBezier = {\n\tbase3(t: number, p1: number, p2: number, p3: number, p4: number) {\n\t\tconst t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4\n\t\tconst t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3\n\t\treturn t * t2 - 3 * p1 + 3 * p2\n\t},\n\t/**\n\t * Calculate the approximate length of a cubic bezier curve from (x1, y1) to (x4, y4) with\n\t * control points (x2, y2) and (x3, y3).\n\t */\n\tlength(\n\t\tx1: number,\n\t\ty1: number,\n\t\tx2: number,\n\t\ty2: number,\n\t\tx3: number,\n\t\ty3: number,\n\t\tx4: number,\n\t\ty4: number,\n\t\tz = 1\n\t) {\n\t\tz = z > 1 ? 1 : z < 0 ? 0 : z\n\t\tconst z2 = z / 2\n\t\tconst n = 12\n\n\t\tlet sum = 0\n\t\tsum = 0\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst ct = z2 * CubicBezier.Tvalues[i] + z2\n\t\t\tconst xbase = CubicBezier.base3(ct, x1, x2, x3, x4)\n\t\t\tconst ybase = CubicBezier.base3(ct, y1, y2, y3, y4)\n\t\t\tconst comb = xbase * xbase + ybase * ybase\n\t\t\tsum += CubicBezier.Cvalues[i] * Math.sqrt(comb)\n\t\t}\n\t\treturn z2 * sum\n\t},\n\tTvalues: [\n\t\t-0.1252, 0.1252, -0.3678, 0.3678, -0.5873, 0.5873, -0.7699, 0.7699, -0.9041, 0.9041, -0.9816,\n\t\t0.9816,\n\t],\n\tCvalues: [\n\t\t0.2491, 0.2491, 0.2335, 0.2335, 0.2032, 0.2032, 0.1601, 0.1601, 0.1069, 0.1069, 0.0472, 0.0472,\n\t],\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tapproximately,\n\tassert,\n\tassertExists,\n\tclamp,\n\tCubicBezier2d,\n\tEdge2d,\n\texhaustiveSwitchError,\n\tGeometry2d,\n\tGeometry2dFilters,\n\tGeometry2dOptions,\n\tgetPerfectDashProps,\n\tgetVerticesCountForArcLength,\n\tGroup2d,\n\tmodulate,\n\tPerfectDashTerminal,\n\trng,\n\ttoDomPrecision,\n\tVec,\n\tVecLike,\n\tVecModel,\n} from '@tldraw/editor'\nimport { ReactNode, SVGProps } from 'react'\n\n/** @public */\nexport interface BasePathBuilderOpts {\n\tstrokeWidth: number\n\tforceSolid?: boolean\n\tonlyFilled?: boolean\n\tprops?: SVGProps<SVGPathElement & SVGGElement>\n}\n\n/** @public */\nexport interface SolidPathBuilderOpts extends BasePathBuilderOpts {\n\tstyle: 'solid'\n}\n\n/** @public */\nexport interface DashedPathBuilderOpts extends BasePathBuilderOpts {\n\tstyle: 'dashed' | 'dotted'\n\tsnap?: number\n\tend?: PerfectDashTerminal\n\tstart?: PerfectDashTerminal\n\tlengthRatio?: number\n}\n\n/** @public */\nexport interface DrawPathBuilderDOpts {\n\tstrokeWidth: number\n\trandomSeed: string\n\toffset?: number\n\troundness?: number\n\tpasses?: number\n\tonlyFilled?: boolean\n}\n\n/** @public */\nexport interface DrawPathBuilderOpts extends BasePathBuilderOpts, DrawPathBuilderDOpts {\n\tstyle: 'draw'\n}\n\n/** @public */\nexport type PathBuilderOpts = SolidPathBuilderOpts | DashedPathBuilderOpts | DrawPathBuilderOpts\n\n/** @public */\nexport interface PathBuilderCommandOpts {\n\t/**\n\t * When converting to a draw-style line, how much offset from the original point should be\n\t * applied?\n\t */\n\toffset?: number\n\t/**\n\t * When converting to a draw-style line, how much roundness should be applied to the end of this\n\t * line?\n\t */\n\troundness?: number\n\t/**\n\t * When converting to a dash- or dot-style line, should the current segment be merged with the\n\t * previous segment when calculating the dash pattern? This is false by default, meaning each\n\t * command will start/end on a dash/dot boundary.\n\t */\n\tmergeWithPrevious?: boolean\n}\n\n/** @internal */\nexport interface PathBuilderCommandInfo {\n\ttangentStart: VecModel\n\ttangentEnd: VecModel\n\tlength: number\n}\n\n/** @internal */\nexport interface PathBuilderCommandBase {\n\topts?: PathBuilderCommandOpts\n\tx: number\n\ty: number\n\tisClose: boolean\n\t_info?: PathBuilderCommandInfo\n}\n\n/** @public */\nexport interface PathBuilderLineOpts extends PathBuilderCommandOpts {\n\tgeometry?: Omit<Geometry2dOptions, 'isClosed'> | false\n\tdashStart?: PerfectDashTerminal\n\tdashEnd?: PerfectDashTerminal\n}\n\n/** @internal */\nexport interface MoveToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'move'\n\tcloseIdx: number | null\n\topts?: PathBuilderLineOpts\n}\n\n/** @internal */\nexport interface LineToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'line'\n}\n\n/** @internal */\nexport interface CubicBezierToPathBuilderCommand extends PathBuilderCommandBase {\n\ttype: 'cubic'\n\tcp1: VecModel\n\tcp2: VecModel\n\tresolution?: number\n}\n\n/** @internal */\nexport type PathBuilderCommand =\n\t| MoveToPathBuilderCommand\n\t| LineToPathBuilderCommand\n\t| CubicBezierToPathBuilderCommand\n\n/** @public */\nexport interface PathBuilderToDOpts {\n\tstartIdx?: number\n\tendIdx?: number\n\tonlyFilled?: boolean\n}\n\n/** @public */\nexport class PathBuilder {\n\tstatic lineThroughPoints(\n\t\tpoints: VecLike[],\n\t\topts?: PathBuilderLineOpts & { endOffsets?: number }\n\t) {\n\t\tconst path = new PathBuilder()\n\t\tpath.moveTo(points[0].x, points[0].y, { ...opts, offset: opts?.endOffsets ?? opts?.offset })\n\t\tfor (let i = 1; i < points.length; i++) {\n\t\t\tconst isLast = i === points.length - 1\n\t\t\tpath.lineTo(points[i].x, points[i].y, isLast ? { offset: opts?.endOffsets } : undefined)\n\t\t}\n\t\treturn path\n\t}\n\n\tstatic cubicSplineThroughPoints(\n\t\tpoints: VecLike[],\n\t\topts?: PathBuilderLineOpts & { endOffsets?: number }\n\t) {\n\t\tconst path = new PathBuilder()\n\t\tconst len = points.length\n\t\tconst last = len - 2\n\t\tconst k = 1.25\n\n\t\tpath.moveTo(points[0].x, points[0].y, { ...opts, offset: opts?.endOffsets ?? opts?.offset })\n\n\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\tconst p0 = i === 0 ? points[0] : points[i - 1]\n\t\t\tconst p1 = points[i]\n\t\t\tconst p2 = points[i + 1]\n\t\t\tconst p3 = i === last ? p2 : points[i + 2]\n\n\t\t\tlet cp1x, cp1y, cp2x, cp2y\n\t\t\tif (i === 0) {\n\t\t\t\tcp1x = p0.x\n\t\t\t\tcp1y = p0.y\n\t\t\t} else {\n\t\t\t\tcp1x = p1.x + ((p2.x - p0.x) / 6) * k\n\t\t\t\tcp1y = p1.y + ((p2.y - p0.y) / 6) * k\n\t\t\t}\n\n\t\t\tlet pointOpts = undefined\n\t\t\tif (i === last) {\n\t\t\t\tcp2x = p2.x\n\t\t\t\tcp2y = p2.y\n\t\t\t\tpointOpts = { offset: opts?.endOffsets }\n\t\t\t} else {\n\t\t\t\tcp2x = p2.x - ((p3.x - p1.x) / 6) * k\n\t\t\t\tcp2y = p2.y - ((p3.y - p1.y) / 6) * k\n\t\t\t}\n\n\t\t\tpath.cubicBezierTo(p2.x, p2.y, cp1x, cp1y, cp2x, cp2y, pointOpts)\n\t\t}\n\n\t\treturn path\n\t}\n\n\tconstructor() {}\n\n\t/** @internal */\n\tcommands: PathBuilderCommand[] = []\n\n\tprivate lastMoveTo: MoveToPathBuilderCommand | null = null\n\tprivate assertHasMoveTo() {\n\t\tassert(this.lastMoveTo, 'Start an SVGPathBuilder with `.moveTo()`')\n\t\treturn this.lastMoveTo\n\t}\n\n\tmoveTo(x: number, y: number, opts?: PathBuilderLineOpts) {\n\t\tthis.lastMoveTo = { type: 'move', x, y, closeIdx: null, isClose: false, opts }\n\t\tthis.commands.push(this.lastMoveTo)\n\t\treturn this\n\t}\n\n\tlineTo(x: number, y: number, opts?: PathBuilderCommandOpts) {\n\t\tthis.assertHasMoveTo()\n\t\tthis.commands.push({ type: 'line', x, y, isClose: false, opts })\n\t\treturn this\n\t}\n\n\tcircularArcTo(\n\t\tradius: number,\n\t\tlargeArcFlag: boolean,\n\t\tsweepFlag: boolean,\n\t\tx2: number,\n\t\ty2: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\treturn this.arcTo(radius, radius, largeArcFlag, sweepFlag, 0, x2, y2, opts)\n\t}\n\n\tarcTo(\n\t\trx: number,\n\t\try: number,\n\t\tlargeArcFlag: boolean,\n\t\tsweepFlag: boolean,\n\t\txAxisRotationRadians: number,\n\t\tx2: number,\n\t\ty2: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\t// As arc flags make them very sensitive to offsets when we render them in draw mode, we\n\t\t// approximate arcs by converting them to up to 4 (1 per 90\u00B0 segment) cubic bezier curves.\n\t\t// This algorithm is a Claude special:\n\t\t// https://claude.ai/public/artifacts/5ea0bf18-4afb-4b3d-948d-31b8a77ef1e2\n\n\t\tthis.assertHasMoveTo()\n\n\t\tconst x1 = this.commands[this.commands.length - 1].x\n\t\tconst y1 = this.commands[this.commands.length - 1].y\n\n\t\t// If the endpoints are identical, don't add a command\n\t\tif (x1 === x2 && y1 === y2) {\n\t\t\treturn this\n\t\t}\n\n\t\t// If rx or ry is 0, return a straight line\n\t\tif (rx === 0 || ry === 0) {\n\t\t\treturn this.lineTo(x2, y2, opts)\n\t\t}\n\n\t\t// Convert angle from degrees to radians\n\t\tconst phi = xAxisRotationRadians\n\t\tconst sinPhi = Math.sin(phi)\n\t\tconst cosPhi = Math.cos(phi)\n\n\t\t// Ensure rx and ry are positive\n\t\tlet rx1 = Math.abs(rx)\n\t\tlet ry1 = Math.abs(ry)\n\n\t\t// Step 1: Compute (x1', y1') - transform from ellipse coordinate system to unit circle\n\t\tconst dx = (x1 - x2) / 2\n\t\tconst dy = (y1 - y2) / 2\n\t\tconst x1p = cosPhi * dx + sinPhi * dy\n\t\tconst y1p = -sinPhi * dx + cosPhi * dy\n\n\t\t// Correction of out-of-range radii\n\t\tconst lambda = (x1p * x1p) / (rx1 * rx1) + (y1p * y1p) / (ry1 * ry1)\n\t\tif (lambda > 1) {\n\t\t\tconst sqrtLambda = Math.sqrt(lambda)\n\t\t\trx1 *= sqrtLambda\n\t\t\try1 *= sqrtLambda\n\t\t}\n\n\t\t// Step 2: Compute (cx', cy') - center of ellipse in transformed system\n\t\tconst sign = largeArcFlag !== sweepFlag ? 1 : -1\n\n\t\tconst term = rx1 * rx1 * ry1 * ry1 - rx1 * rx1 * y1p * y1p - ry1 * ry1 * x1p * x1p\n\t\tconst numerator = rx1 * rx1 * y1p * y1p + ry1 * ry1 * x1p * x1p\n\n\t\tlet radicand = term / numerator\n\t\tradicand = radicand < 0 ? 0 : radicand\n\n\t\tconst coef = sign * Math.sqrt(radicand)\n\n\t\tconst cxp = coef * ((rx1 * y1p) / ry1)\n\t\tconst cyp = coef * (-(ry1 * x1p) / rx1)\n\n\t\t// Step 3: Compute (cx, cy) from (cx', cy') - transform back to original coordinate system\n\t\tconst cx = cosPhi * cxp - sinPhi * cyp + (x1 + x2) / 2\n\t\tconst cy = sinPhi * cxp + cosPhi * cyp + (y1 + y2) / 2\n\n\t\t// Step 4: Compute the start and end angles\n\t\tconst ux = (x1p - cxp) / rx1\n\t\tconst uy = (y1p - cyp) / ry1\n\t\tconst vx = (-x1p - cxp) / rx1\n\t\tconst vy = (-y1p - cyp) / ry1\n\n\t\tconst startAngle = Math.atan2(uy, ux)\n\t\tlet endAngle = Math.atan2(vy, vx)\n\n\t\t// Ensure correct sweep direction\n\t\tif (!sweepFlag && endAngle > startAngle) {\n\t\t\tendAngle -= 2 * Math.PI\n\t\t} else if (sweepFlag && endAngle < startAngle) {\n\t\t\tendAngle += 2 * Math.PI\n\t\t}\n\n\t\t// Calculate the sweep angle\n\t\tconst sweepAngle = endAngle - startAngle\n\n\t\t// Calculate the approximate arc length. General ellipse arc length is expensive - there's\n\t\t// no closed form solution, so we have to do iterative numerical approximation. As we only\n\t\t// use this to control the resolution of later approximations, let's cheat and just use the\n\t\t// circular arc length with the largest radius:\n\t\tconst approximateArcLength = Math.max(rx1, ry1) * Math.abs(sweepAngle)\n\n\t\t// Approximate the arc using cubic bezier curves\n\t\tconst numSegments = Math.min(4, Math.ceil(Math.abs(sweepAngle) / (Math.PI / 2)))\n\t\tconst resolutionPerSegment = Math.ceil(\n\t\t\tgetVerticesCountForArcLength(approximateArcLength) / numSegments\n\t\t)\n\t\tconst anglePerSegment = sweepAngle / numSegments\n\n\t\t// Helper function to compute point on ellipse\n\t\tconst ellipsePoint = (angle: number) => {\n\t\t\treturn {\n\t\t\t\tx: cx + rx1 * Math.cos(angle) * cosPhi - ry1 * Math.sin(angle) * sinPhi,\n\t\t\t\ty: cy + rx1 * Math.cos(angle) * sinPhi + ry1 * Math.sin(angle) * cosPhi,\n\t\t\t}\n\t\t}\n\n\t\t// Helper function to compute derivative (tangent vector) at a point on the ellipse\n\t\tconst ellipseDerivative = (angle: number) => {\n\t\t\treturn {\n\t\t\t\tx: -rx1 * Math.sin(angle) * cosPhi - ry1 * Math.cos(angle) * sinPhi,\n\t\t\t\ty: -rx1 * Math.sin(angle) * sinPhi + ry1 * Math.cos(angle) * cosPhi,\n\t\t\t}\n\t\t}\n\n\t\t// Generate cubic bezier approximations\n\t\tfor (let i = 0; i < numSegments; i++) {\n\t\t\tconst theta1 = startAngle + i * anglePerSegment\n\t\t\tconst theta2 = startAngle + (i + 1) * anglePerSegment\n\t\t\tconst deltaTheta = theta2 - theta1\n\n\t\t\tconst start = ellipsePoint(theta1)\n\t\t\tconst end = ellipsePoint(theta2)\n\n\t\t\t// Get the derivative at the start and end points\n\t\t\tconst d1 = ellipseDerivative(theta1)\n\t\t\tconst d2 = ellipseDerivative(theta2)\n\n\t\t\t// Calculate the length of the tangent handles\n\t\t\t// This is a key factor for the accuracy of the approximation\n\t\t\t// For a 90\u00B0 arc, the handle length should be 4/3 * tan(\u03C0/8) * r\n\t\t\t// For smaller arcs, we scale this value by the angle ratio\n\t\t\tconst handleScale = (4 / 3) * Math.tan(deltaTheta / 4)\n\n\t\t\t// Create control points that are tangent to the ellipse at the endpoints\n\t\t\tconst cp1x = start.x + handleScale * d1.x\n\t\t\tconst cp1y = start.y + handleScale * d1.y\n\n\t\t\tconst cp2x = end.x - handleScale * d2.x\n\t\t\tconst cp2y = end.y - handleScale * d2.y\n\n\t\t\tconst bezierOpts = i === 0 ? opts : { ...opts, mergeWithPrevious: true }\n\t\t\tthis.cubicBezierToWithResolution(\n\t\t\t\tend.x,\n\t\t\t\tend.y,\n\t\t\t\tcp1x,\n\t\t\t\tcp1y,\n\t\t\t\tcp2x,\n\t\t\t\tcp2y,\n\t\t\t\tbezierOpts,\n\t\t\t\tresolutionPerSegment\n\t\t\t)\n\t\t}\n\n\t\treturn this\n\t}\n\n\tcubicBezierTo(\n\t\tx: number,\n\t\ty: number,\n\t\tcp1X: number,\n\t\tcp1Y: number,\n\t\tcp2X: number,\n\t\tcp2Y: number,\n\t\topts?: PathBuilderCommandOpts\n\t) {\n\t\treturn this.cubicBezierToWithResolution(x, y, cp1X, cp1Y, cp2X, cp2Y, opts)\n\t}\n\tprivate cubicBezierToWithResolution(\n\t\tx: number,\n\t\ty: number,\n\t\tcp1X: number,\n\t\tcp1Y: number,\n\t\tcp2X: number,\n\t\tcp2Y: number,\n\t\topts?: PathBuilderCommandOpts,\n\t\tresolution?: number\n\t) {\n\t\tthis.assertHasMoveTo()\n\t\tthis.commands.push({\n\t\t\ttype: 'cubic',\n\t\t\tx,\n\t\t\ty,\n\t\t\tcp1: { x: cp1X, y: cp1Y },\n\t\t\tcp2: { x: cp2X, y: cp2Y },\n\t\t\tisClose: false,\n\t\t\topts,\n\t\t\tresolution,\n\t\t})\n\t\treturn this\n\t}\n\n\tclose() {\n\t\tconst lastMoveTo = this.assertHasMoveTo()\n\t\tconst lastCommand = this.commands[this.commands.length - 1]\n\n\t\tif (approximately(lastMoveTo.x, lastCommand.x) && approximately(lastMoveTo.y, lastCommand.y)) {\n\t\t\tlastCommand.isClose = true\n\t\t} else {\n\t\t\tthis.commands.push({\n\t\t\t\ttype: 'line',\n\t\t\t\tx: lastMoveTo.x,\n\t\t\t\ty: lastMoveTo.y,\n\t\t\t\tisClose: true,\n\t\t\t})\n\t\t}\n\n\t\tlastMoveTo.closeIdx = this.commands.length - 1\n\t\tthis.lastMoveTo = null\n\t\treturn this\n\t}\n\n\ttoD(opts: PathBuilderToDOpts = {}) {\n\t\tconst { startIdx = 0, endIdx = this.commands.length, onlyFilled = false } = opts\n\t\tconst parts = []\n\n\t\tlet isSkippingCurrentLine = false\n\n\t\tlet didAddMove = false\n\t\tlet didAddNaturalMove = false\n\n\t\tconst addMoveIfNeeded = (i: number) => {\n\t\t\tif (didAddMove || i === 0) return\n\t\t\tdidAddMove = true\n\t\t\tconst command = this.commands[i - 1]\n\t\t\tparts.push('M', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t}\n\n\t\tfor (let i = startIdx; i < endIdx; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tswitch (command.type) {\n\t\t\t\tcase 'move': {\n\t\t\t\t\tconst isFilled =\n\t\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\t\tif (onlyFilled && !isFilled) {\n\t\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\t\tdidAddMove = true\n\t\t\t\t\t\tdidAddNaturalMove = true\n\t\t\t\t\t\tparts.push('M', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'line':\n\t\t\t\t\tif (isSkippingCurrentLine) break\n\t\t\t\t\taddMoveIfNeeded(i)\n\t\t\t\t\tif (command.isClose && didAddNaturalMove) {\n\t\t\t\t\t\tparts.push('Z')\n\t\t\t\t\t} else {\n\t\t\t\t\t\tparts.push('L', toDomPrecision(command.x), toDomPrecision(command.y))\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic':\n\t\t\t\t\tif (isSkippingCurrentLine) break\n\t\t\t\t\taddMoveIfNeeded(i)\n\t\t\t\t\tparts.push(\n\t\t\t\t\t\t'C',\n\t\t\t\t\t\ttoDomPrecision(command.cp1.x),\n\t\t\t\t\t\ttoDomPrecision(command.cp1.y),\n\t\t\t\t\t\ttoDomPrecision(command.cp2.x),\n\t\t\t\t\t\ttoDomPrecision(command.cp2.y),\n\t\t\t\t\t\ttoDomPrecision(command.x),\n\t\t\t\t\t\ttoDomPrecision(command.y)\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t}\n\t\t}\n\t\treturn parts.join(' ')\n\t}\n\n\ttoSvg(opts: PathBuilderOpts) {\n\t\tif (opts.forceSolid) {\n\t\t\treturn this.toSolidSvg(opts)\n\t\t}\n\t\tswitch (opts.style) {\n\t\t\tcase 'solid':\n\t\t\t\treturn this.toSolidSvg(opts)\n\t\t\tcase 'dashed':\n\t\t\tcase 'dotted':\n\t\t\t\treturn this.toDashedSvg(opts)\n\t\t\tcase 'draw': {\n\t\t\t\tconst d = this.toDrawSvg(opts)\n\t\t\t\treturn d\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(opts, 'style')\n\t\t}\n\t}\n\n\ttoGeometry(): PathBuilderGeometry2d | Group2d {\n\t\tconst geometries = []\n\n\t\tlet current: null | {\n\t\t\tstartIdx: number\n\t\t\tmoveCommand: MoveToPathBuilderCommand\n\t\t\tisClosed: boolean\n\t\t\topts?: PathBuilderLineOpts\n\t\t} = null\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\n\t\t\tif (command.type === 'move') {\n\t\t\t\tif (current && current.opts?.geometry !== false) {\n\t\t\t\t\tgeometries.push(\n\t\t\t\t\t\tnew PathBuilderGeometry2d(this, current.startIdx, i, {\n\t\t\t\t\t\t\t...current.opts?.geometry,\n\t\t\t\t\t\t\tisFilled: current.opts?.geometry?.isFilled ?? false,\n\t\t\t\t\t\t\tisClosed: current.moveCommand.closeIdx !== null,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcurrent = { startIdx: i, moveCommand: command, opts: command.opts, isClosed: false }\n\t\t\t}\n\n\t\t\tif (command.isClose) {\n\t\t\t\tassert(current, 'No current move command')\n\t\t\t\tcurrent.isClosed = true\n\t\t\t}\n\t\t}\n\n\t\tif (current && current.opts?.geometry !== false) {\n\t\t\tgeometries.push(\n\t\t\t\tnew PathBuilderGeometry2d(this, current.startIdx, this.commands.length, {\n\t\t\t\t\t...current.opts?.geometry,\n\t\t\t\t\tisFilled: current.opts?.geometry?.isFilled ?? false,\n\t\t\t\t\tisClosed: current.moveCommand.closeIdx !== null,\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\n\t\tassert(geometries.length > 0)\n\t\tif (geometries.length === 1) return geometries[0]\n\t\treturn new Group2d({ children: geometries })\n\t}\n\n\tprivate toSolidSvg(opts: PathBuilderOpts) {\n\t\tconst { strokeWidth, props } = opts\n\n\t\treturn (\n\t\t\t<path strokeWidth={strokeWidth} d={this.toD({ onlyFilled: opts.onlyFilled })} {...props} />\n\t\t)\n\t}\n\n\tprivate toDashedSvg(opts: DashedPathBuilderOpts) {\n\t\tconst {\n\t\t\tstyle,\n\t\t\tstrokeWidth,\n\t\t\tsnap,\n\t\t\tlengthRatio,\n\t\t\tprops: { markerStart, markerEnd, ...props } = {},\n\t\t} = opts\n\n\t\tconst parts: ReactNode[] = []\n\n\t\tlet isCurrentPathClosed = false\n\t\tlet isSkippingCurrentLine = false\n\t\tlet currentLineOpts: PathBuilderLineOpts | undefined = undefined\n\n\t\tlet currentRun: {\n\t\t\tstartIdx: number\n\t\t\tendIdx: number\n\t\t\tisFirst: boolean\n\t\t\tisLast: boolean\n\t\t\tlength: number\n\t\t\tlineOpts: PathBuilderLineOpts | undefined\n\t\t\tpathIsClosed: boolean\n\t\t} | null = null\n\n\t\tconst addCurrentRun = () => {\n\t\t\tif (!currentRun) return\n\t\t\tconst { startIdx, endIdx, isFirst, isLast, length, lineOpts, pathIsClosed } = currentRun\n\t\t\tcurrentRun = null\n\n\t\t\tif (startIdx === endIdx && this.commands[startIdx].type === 'move') return\n\n\t\t\tconst start = lineOpts?.dashStart ?? opts.start\n\t\t\tconst end = lineOpts?.dashEnd ?? opts.end\n\t\t\tconst { strokeDasharray, strokeDashoffset } = getPerfectDashProps(length, strokeWidth, {\n\t\t\t\tstyle,\n\t\t\t\tsnap,\n\t\t\t\tlengthRatio,\n\t\t\t\tstart: isFirst ? (start ?? (pathIsClosed ? 'outset' : 'none')) : 'outset',\n\t\t\t\tend: isLast ? (end ?? (pathIsClosed ? 'outset' : 'none')) : 'outset',\n\t\t\t})\n\n\t\t\tconst d = this.toD({ startIdx, endIdx: endIdx + 1 })\n\t\t\tparts.push(\n\t\t\t\t<path\n\t\t\t\t\tkey={parts.length}\n\t\t\t\t\td={d}\n\t\t\t\t\tstrokeDasharray={strokeDasharray}\n\t\t\t\t\tstrokeDashoffset={strokeDashoffset}\n\t\t\t\t\tmarkerStart={isFirst ? markerStart : undefined}\n\t\t\t\t\tmarkerEnd={isLast ? markerEnd : undefined}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tconst lastCommand = this.commands[i - 1]\n\t\t\tif (command.type === 'move') {\n\t\t\t\tisCurrentPathClosed = command.closeIdx !== null\n\t\t\t\tconst isFilled =\n\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\tif (opts.onlyFilled && !isFilled) {\n\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t} else {\n\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\tcurrentLineOpts = command.opts\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (isSkippingCurrentLine) continue\n\n\t\t\tconst segmentLength = this.calculateSegmentLength(lastCommand, command)\n\t\t\tconst isFirst = lastCommand.type === 'move'\n\t\t\tconst isLast =\n\t\t\t\tcommand.isClose || i === this.commands.length - 1 || this.commands[i + 1]?.type === 'move'\n\n\t\t\tif (currentRun && command.opts?.mergeWithPrevious) {\n\t\t\t\tcurrentRun.length += segmentLength\n\t\t\t\tcurrentRun.endIdx = i\n\t\t\t\tcurrentRun.isLast = isLast\n\t\t\t} else {\n\t\t\t\taddCurrentRun()\n\t\t\t\tcurrentRun = {\n\t\t\t\t\tstartIdx: i,\n\t\t\t\t\tendIdx: i,\n\t\t\t\t\tisFirst,\n\t\t\t\t\tisLast,\n\t\t\t\t\tlength: segmentLength,\n\t\t\t\t\tlineOpts: currentLineOpts,\n\t\t\t\t\tpathIsClosed: isCurrentPathClosed,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\taddCurrentRun()\n\n\t\treturn (\n\t\t\t<g strokeWidth={strokeWidth} {...props}>\n\t\t\t\t{parts}\n\t\t\t</g>\n\t\t)\n\t}\n\n\tprivate toDrawSvg(opts: DrawPathBuilderOpts) {\n\t\treturn <path strokeWidth={opts.strokeWidth} d={this.toDrawD(opts)} {...opts.props} />\n\t}\n\n\ttoDrawD(opts: DrawPathBuilderDOpts) {\n\t\tconst {\n\t\t\tstrokeWidth,\n\t\t\trandomSeed,\n\t\t\toffset: defaultOffset = strokeWidth / 3,\n\t\t\troundness: defaultRoundness = strokeWidth * 2,\n\t\t\tpasses = 2,\n\t\t\tonlyFilled = false,\n\t\t} = opts\n\n\t\tconst parts = []\n\n\t\tconst commandInfo = this.getCommandInfo()\n\n\t\t// for each command, we draw the line for the command, plus the corner to the next command.\n\t\tconst drawCommands = []\n\t\tlet lastMoveCommandIdx = null\n\t\tfor (let i = 0; i < this.commands.length; i++) {\n\t\t\tconst command = this.commands[i]\n\t\t\tconst offset = command.opts?.offset ?? defaultOffset\n\t\t\tconst roundness = command.opts?.roundness ?? defaultRoundness\n\n\t\t\tif (command.type === 'move') {\n\t\t\t\tlastMoveCommandIdx = i\n\t\t\t}\n\n\t\t\tconst nextIdx = command.isClose\n\t\t\t\t? assertExists(lastMoveCommandIdx) + 1\n\t\t\t\t: !this.commands[i + 1] || this.commands[i + 1].type === 'move'\n\t\t\t\t\t? undefined\n\t\t\t\t\t: i + 1\n\n\t\t\tconst nextInfo =\n\t\t\t\tnextIdx !== undefined && this.commands[nextIdx] && this.commands[nextIdx]?.type !== 'move'\n\t\t\t\t\t? commandInfo[nextIdx]\n\t\t\t\t\t: undefined\n\n\t\t\tconst currentSupportsRoundness = commandsSupportingRoundness[command.type]\n\t\t\tconst nextSupportsRoundness =\n\t\t\t\tnextIdx !== undefined ? commandsSupportingRoundness[this.commands[nextIdx].type] : false\n\n\t\t\tconst currentInfo = commandInfo[i]\n\n\t\t\tconst tangentToPrev = currentInfo?.tangentEnd\n\t\t\tconst tangentToNext = nextInfo?.tangentStart\n\n\t\t\tconst roundnessClampedForAngle =\n\t\t\t\tcurrentSupportsRoundness &&\n\t\t\t\tnextSupportsRoundness &&\n\t\t\t\ttangentToPrev &&\n\t\t\t\ttangentToNext &&\n\t\t\t\tVec.Len2(tangentToPrev) > 0.01 &&\n\t\t\t\tVec.Len2(tangentToNext) > 0.01\n\t\t\t\t\t? modulate(\n\t\t\t\t\t\t\tMath.abs(Vec.AngleBetween(tangentToPrev, tangentToNext)),\n\t\t\t\t\t\t\t[Math.PI / 2, Math.PI],\n\t\t\t\t\t\t\t[roundness, 0],\n\t\t\t\t\t\t\ttrue\n\t\t\t\t\t\t)\n\t\t\t\t\t: 0\n\n\t\t\tconst shortestDistance = Math.min(\n\t\t\t\tcurrentInfo?.length ?? Infinity,\n\t\t\t\tnextInfo?.length ?? Infinity\n\t\t\t)\n\t\t\tconst offsetLimit = shortestDistance - roundnessClampedForAngle * 2\n\n\t\t\tconst offsetAmount = clamp(offset, 0, offsetLimit / 4)\n\n\t\t\tconst roundnessBeforeClampedForLength = Math.min(\n\t\t\t\troundnessClampedForAngle,\n\t\t\t\t(currentInfo?.length ?? Infinity) / 4\n\t\t\t)\n\t\t\tconst roundnessAfterClampedForLength = Math.min(\n\t\t\t\troundnessClampedForAngle,\n\t\t\t\t(nextInfo?.length ?? Infinity) / 4\n\t\t\t)\n\n\t\t\tconst drawCommand = {\n\t\t\t\tcommand,\n\t\t\t\toffsetAmount,\n\t\t\t\troundnessBefore: roundnessBeforeClampedForLength,\n\t\t\t\troundnessAfter: roundnessAfterClampedForLength,\n\t\t\t\ttangentToPrev: commandInfo[i]?.tangentEnd,\n\t\t\t\ttangentToNext: nextInfo?.tangentStart,\n\t\t\t\tmoveDidClose: false,\n\t\t\t}\n\n\t\t\tdrawCommands.push(drawCommand)\n\n\t\t\tif (command.isClose && lastMoveCommandIdx !== null) {\n\t\t\t\tconst lastMoveCommand = drawCommands[lastMoveCommandIdx]\n\t\t\t\tlastMoveCommand.moveDidClose = true\n\t\t\t\tlastMoveCommand.roundnessAfter = roundnessAfterClampedForLength\n\t\t\t} else if (command.type === 'move') {\n\t\t\t\tlastMoveCommandIdx = i\n\t\t\t}\n\t\t}\n\n\t\tfor (let pass = 0; pass < passes; pass++) {\n\t\t\tconst random = rng(randomSeed + pass)\n\n\t\t\tlet lastMoveToOffset = { x: 0, y: 0 }\n\t\t\tlet isSkippingCurrentLine = false\n\t\t\tfor (const {\n\t\t\t\tcommand,\n\t\t\t\toffsetAmount,\n\t\t\t\troundnessBefore,\n\t\t\t\troundnessAfter,\n\t\t\t\ttangentToNext,\n\t\t\t\ttangentToPrev,\n\t\t\t} of drawCommands) {\n\t\t\t\tconst offset = command.isClose\n\t\t\t\t\t? lastMoveToOffset\n\t\t\t\t\t: { x: random() * offsetAmount, y: random() * offsetAmount }\n\n\t\t\t\tif (command.type === 'move') {\n\t\t\t\t\tlastMoveToOffset = offset\n\t\t\t\t\tconst isFilled =\n\t\t\t\t\t\tcommand.opts?.geometry === false ? false : (command.opts?.geometry?.isFilled ?? false)\n\t\t\t\t\tif (onlyFilled && !isFilled) {\n\t\t\t\t\t\tisSkippingCurrentLine = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tisSkippingCurrentLine = false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (isSkippingCurrentLine) continue\n\n\t\t\t\tconst offsetPoint = Vec.Add(command, offset)\n\n\t\t\t\tconst endPoint =\n\t\t\t\t\ttangentToNext && roundnessAfter > 0\n\t\t\t\t\t\t? Vec.Mul(tangentToNext, -roundnessAfter).add(offsetPoint)\n\t\t\t\t\t\t: offsetPoint\n\n\t\t\t\tconst startPoint =\n\t\t\t\t\ttangentToPrev && roundnessBefore > 0\n\t\t\t\t\t\t? Vec.Mul(tangentToPrev, roundnessBefore).add(offsetPoint)\n\t\t\t\t\t\t: offsetPoint\n\n\t\t\t\tif (endPoint === offsetPoint || startPoint === offsetPoint) {\n\t\t\t\t\tswitch (command.type) {\n\t\t\t\t\t\tcase 'move':\n\t\t\t\t\t\t\tparts.push('M', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'line':\n\t\t\t\t\t\t\tparts.push('L', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'cubic': {\n\t\t\t\t\t\t\tconst offsetCp1 = Vec.Add(command.cp1, offset)\n\t\t\t\t\t\t\tconst offsetCp2 = Vec.Add(command.cp2, offset)\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'C',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (command.type) {\n\t\t\t\t\t\tcase 'move':\n\t\t\t\t\t\t\tparts.push('M', toDomPrecision(endPoint.x), toDomPrecision(endPoint.y))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'line':\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'L',\n\t\t\t\t\t\t\t\ttoDomPrecision(startPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(startPoint.y),\n\n\t\t\t\t\t\t\t\t'Q',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(endPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'cubic': {\n\t\t\t\t\t\t\tconst offsetCp1 = Vec.Add(command.cp1, offset)\n\t\t\t\t\t\t\tconst offsetCp2 = Vec.Add(command.cp2, offset)\n\t\t\t\t\t\t\tparts.push(\n\t\t\t\t\t\t\t\t'C',\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp1.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetCp2.y),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.x),\n\t\t\t\t\t\t\t\ttoDomPrecision(offsetPoint.y)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn parts.join(' ')\n\t}\n\n\tprivate calculateSegmentLength(lastPoint: VecLike, command: PathBuilderCommand) {\n\t\tswitch (command.type) {\n\t\t\tcase 'move':\n\t\t\t\treturn 0\n\t\t\tcase 'line':\n\t\t\t\treturn Vec.Dist(lastPoint, command)\n\t\t\tcase 'cubic':\n\t\t\t\treturn CubicBezier.length(\n\t\t\t\t\tlastPoint.x,\n\t\t\t\t\tlastPoint.y,\n\t\t\t\t\tcommand.cp1.x,\n\t\t\t\t\tcommand.cp1.y,\n\t\t\t\t\tcommand.cp2.x,\n\t\t\t\t\tcommand.cp2.y,\n\t\t\t\t\tcommand.x,\n\t\t\t\t\tcommand.y\n\t\t\t\t)\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t}\n\t}\n\n\t/** @internal */\n\tgetCommands(): readonly PathBuilderCommand[] {\n\t\treturn this.commands\n\t}\n\n\t/** @internal */\n\tgetCommandInfo() {\n\t\tconst commandInfo: Array<undefined | PathBuilderCommandInfo> = []\n\t\tfor (let i = 1; i < this.commands.length; i++) {\n\t\t\tconst previous = this.commands[i - 1]\n\t\t\tconst current = this.commands[i]\n\n\t\t\tif (current._info) {\n\t\t\t\tcommandInfo[i] = current._info\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (current.type === 'move') {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlet tangentStart, tangentEnd\n\t\t\tswitch (current.type) {\n\t\t\t\tcase 'line':\n\t\t\t\t\ttangentStart = tangentEnd = Vec.Sub(previous, current).uni()\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic': {\n\t\t\t\t\ttangentStart = Vec.Sub(current.cp1, previous).uni()\n\t\t\t\t\ttangentEnd = Vec.Sub(current.cp2, current).uni()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(current, 'type')\n\t\t\t}\n\n\t\t\tcurrent._info = {\n\t\t\t\ttangentStart,\n\t\t\t\ttangentEnd,\n\t\t\t\tlength: this.calculateSegmentLength(previous, current),\n\t\t\t}\n\t\t\tcommandInfo[i] = current._info\n\t\t}\n\n\t\treturn commandInfo\n\t}\n}\n\nconst commandsSupportingRoundness = {\n\tline: true,\n\tmove: true,\n\tcubic: false,\n} as const satisfies Record<PathBuilderCommand['type'], boolean>\n\n/** @public */\nexport class PathBuilderGeometry2d extends Geometry2d {\n\tconstructor(\n\t\tprivate readonly path: PathBuilder,\n\t\tprivate readonly startIdx: number,\n\t\tprivate readonly endIdx: number,\n\t\toptions: Geometry2dOptions\n\t) {\n\t\tsuper(options)\n\t}\n\n\tprivate _segments: Geometry2d[] | null = null\n\tgetSegments() {\n\t\tif (this._segments) return this._segments\n\n\t\tthis._segments = []\n\t\tlet last = this.path.commands[this.startIdx]\n\t\tassert(last.type === 'move')\n\n\t\tfor (let i = this.startIdx + 1; i < this.endIdx; i++) {\n\t\t\tconst command = this.path.commands[i]\n\t\t\tassert(command.type !== 'move')\n\n\t\t\tswitch (command.type) {\n\t\t\t\tcase 'line':\n\t\t\t\t\tthis._segments.push(new Edge2d({ start: Vec.From(last), end: Vec.From(command) }))\n\t\t\t\t\tbreak\n\t\t\t\tcase 'cubic': {\n\t\t\t\t\tthis._segments.push(\n\t\t\t\t\t\tnew CubicBezier2d({\n\t\t\t\t\t\t\tstart: Vec.From(last),\n\t\t\t\t\t\t\tcp1: Vec.From(command.cp1),\n\t\t\t\t\t\t\tcp2: Vec.From(command.cp2),\n\t\t\t\t\t\t\tend: Vec.From(command),\n\t\t\t\t\t\t\tresolution: command.resolution,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(command, 'type')\n\t\t\t}\n\n\t\t\tlast = command\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getVertices(filters: Geometry2dFilters): Vec[] {\n\t\tconst vs = this.getSegments()\n\t\t\t.flatMap((s) => s.getVertices(filters))\n\t\t\t.filter((vertex, i, vertices) => {\n\t\t\t\tconst prev = vertices[i - 1]\n\t\t\t\tif (!prev) return true\n\t\t\t\treturn !Vec.Equals(prev, vertex)\n\t\t\t})\n\n\t\tif (this.isClosed) {\n\t\t\tconst last = vs[vs.length - 1]\n\t\t\tconst first = vs[0]\n\t\t\tif (!Vec.Equals(last, first)) {\n\t\t\t\tvs.push(first)\n\t\t\t}\n\t\t}\n\n\t\treturn vs\n\t}\n\n\toverride nearestPoint(point: VecLike, _filters?: Geometry2dFilters): Vec {\n\t\tlet nearest: Vec | null = null\n\t\tlet nearestDistance = Infinity\n\n\t\tfor (const segment of this.getSegments()) {\n\t\t\tconst candidate = segment.nearestPoint(point)\n\t\t\tconst distance = Vec.Dist2(point, candidate)\n\t\t\tif (distance < nearestDistance) {\n\t\t\t\tnearestDistance = distance\n\t\t\t\tnearest = candidate\n\t\t\t}\n\t\t}\n\n\t\tassert(nearest, 'No nearest point found')\n\t\treturn nearest\n\t}\n\n\toverride hitTestLineSegment(\n\t\tA: VecLike,\n\t\tB: VecLike,\n\t\tdistance = 0,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn super.hitTestLineSegment(A, B, distance, filters)\n\t}\n\toverride getSvgPathData(): string {\n\t\treturn this.path.toD({ startIdx: this.startIdx, endIdx: this.endIdx })\n\t}\n}\n\n/*!\n * Adapted from https://github.com/adobe-webplatform/Snap.svg/tree/master\n * Apache License: https://github.com/adobe-webplatform/Snap.svg/blob/master/LICENSE\n * https://github.com/adobe-webplatform/Snap.svg/blob/c8e483c9694517e24b282f8f59f985629f4994ce/dist/snap.svg.js#L5786\n */\nconst CubicBezier = {\n\tbase3(t: number, p1: number, p2: number, p3: number, p4: number) {\n\t\tconst t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4\n\t\tconst t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3\n\t\treturn t * t2 - 3 * p1 + 3 * p2\n\t},\n\t/**\n\t * Calculate the approximate length of a cubic bezier curve from (x1, y1) to (x4, y4) with\n\t * control points (x2, y2) and (x3, y3).\n\t */\n\tlength(\n\t\tx1: number,\n\t\ty1: number,\n\t\tx2: number,\n\t\ty2: number,\n\t\tx3: number,\n\t\ty3: number,\n\t\tx4: number,\n\t\ty4: number,\n\t\tz = 1\n\t) {\n\t\tz = z > 1 ? 1 : z < 0 ? 0 : z\n\t\tconst z2 = z / 2\n\t\tconst n = 12\n\n\t\tlet sum = 0\n\t\tsum = 0\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst ct = z2 * CubicBezier.Tvalues[i] + z2\n\t\t\tconst xbase = CubicBezier.base3(ct, x1, x2, x3, x4)\n\t\t\tconst ybase = CubicBezier.base3(ct, y1, y2, y3, y4)\n\t\t\tconst comb = xbase * xbase + ybase * ybase\n\t\t\tsum += CubicBezier.Cvalues[i] * Math.sqrt(comb)\n\t\t}\n\t\treturn z2 * sum\n\t},\n\tTvalues: [\n\t\t-0.1252, 0.1252, -0.3678, 0.3678, -0.5873, 0.5873, -0.7699, 0.7699, -0.9041, 0.9041, -0.9816,\n\t\t0.9816,\n\t],\n\tCvalues: [\n\t\t0.2491, 0.2491, 0.2335, 0.2335, 0.2032, 0.2032, 0.1601, 0.1601, 0.1069, 0.1069, 0.0472, 0.0472,\n\t],\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -69,6 +69,7 @@ const PlainTextLabel = import_react.default.memo(function PlainTextLabel2({
69
69
  "div",
70
70
  {
71
71
  className: `${cssPrefix}-label tl-text-wrapper tl-plain-text-wrapper`,
72
+ "aria-hidden": !isEditing,
72
73
  "data-font": font,
73
74
  "data-align": align,
74
75
  "data-hastext": !isEmpty,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/PlainTextLabel.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tTLDefaultFillStyle,\n\tTLDefaultFontStyle,\n\tTLDefaultHorizontalAlignStyle,\n\tTLDefaultVerticalAlignStyle,\n\tTLShapeId,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { PlainTextArea } from '../text/PlainTextArea'\nimport { TextHelpers } from './TextHelpers'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditablePlainText } from './useEditablePlainText'\n\n/** @public */\nexport interface PlainTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: string\n\tfont: TLDefaultFontStyle\n\tfontSize: number\n\tlineHeight: number\n\tfill?: TLDefaultFillStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\n\twrap?: boolean\n\ttext?: string\n\tlabelColor: string\n\tbounds?: Box\n\tisSelected: boolean\n\tonKeyDown?(e: KeyboardEvent): void\n\tclassNamePrefix?: string\n\tstyle?: React.CSSProperties\n\ttextWidth?: number\n\ttextHeight?: number\n\tpadding?: number\n}\n\n/**\n * Renders a text label that can be used inside of shapes.\n * The component has the ability to be edited in place and furthermore\n * supports rich text editing.\n *\n * @public @react\n */\nexport const PlainTextLabel = React.memo(function PlainTextLabel({\n\tshapeId,\n\ttype,\n\ttext: plaintext,\n\tlabelColor,\n\tfont,\n\tfontSize,\n\tlineHeight,\n\talign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n}: PlainTextLabelProps) {\n\tconst { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =\n\t\tuseEditablePlainText(shapeId, type, plaintext)\n\n\tconst finalPlainText = TextHelpers.normalizeTextForDom(plaintext || '')\n\tconst hasText = finalPlainText.length > 0\n\n\tconst legacyAlign = isLegacyAlign(align)\n\n\tif (!isEditing && !hasText) {\n\t\treturn null\n\t}\n\n\t// TODO: probably combine tl-text and tl-arrow eventually\n\t// In case you're grepping for this, it breaks down as follows:\n\t// tl-text-label, tl-text-label__inner, tl-text-shape-label, tl-text\n\t// tl-arrow-label, tl-arrow-label__inner, tl-arrow\n\tconst cssPrefix = classNamePrefix || 'tl-text'\n\treturn (\n\t\t<div\n\t\t\tclassName={`${cssPrefix}-label tl-text-wrapper tl-plain-text-wrapper`}\n\t\t\tdata-font={font}\n\t\t\tdata-align={align}\n\t\t\tdata-hastext={!isEmpty}\n\t\t\tdata-isediting={isEditing}\n\t\t\tdata-is-ready-for-editing={isReadyForEditing}\n\t\t\tdata-textwrap={!!wrap}\n\t\t\tdata-isselected={isSelected}\n\t\t\tstyle={{\n\t\t\t\tjustifyContent: align === 'middle' || legacyAlign ? 'center' : align,\n\t\t\t\talignItems: verticalAlign === 'middle' ? 'center' : verticalAlign,\n\t\t\t\tpadding,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`${cssPrefix}-label__inner tl-text-content__wrapper`}\n\t\t\t\tstyle={{\n\t\t\t\t\tfontSize,\n\t\t\t\t\tlineHeight: lineHeight.toString(),\n\t\t\t\t\tminHeight: Math.floor(fontSize * lineHeight) + 'px',\n\t\t\t\t\tminWidth: Math.ceil(textWidth || 0),\n\t\t\t\t\tcolor: labelColor,\n\t\t\t\t\twidth: textWidth ? Math.ceil(textWidth) : undefined,\n\t\t\t\t\theight: textHeight ? Math.ceil(textHeight) : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={`${cssPrefix} tl-text tl-text-content`} dir=\"auto\">\n\t\t\t\t\t{finalPlainText.split('\\n').map((lineOfText, index) => (\n\t\t\t\t\t\t<div key={index} dir=\"auto\">\n\t\t\t\t\t\t\t{lineOfText}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t\t{(isReadyForEditing || isSelected) && (\n\t\t\t\t\t<PlainTextArea\n\t\t\t\t\t\t// Fudge the ref type because we're using forwardRef and it's not typed correctly.\n\t\t\t\t\t\tref={rInput as any}\n\t\t\t\t\t\ttext={plaintext}\n\t\t\t\t\t\tisEditing={isEditing}\n\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t{...editableTextRest}\n\t\t\t\t\t\thandleKeyDown={handleKeyDownCustom ?? editableTextRest.handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n\n/**\n * @deprecated Use `PlainTextLabel` instead.\n * @public\n */\nexport const TextLabel = PlainTextLabel\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiGG;AAzFH,mBAAkB;AAClB,2BAA8B;AAC9B,yBAA4B;AAC5B,yBAA8B;AAC9B,kCAAqC;AAgC9B,MAAM,iBAAiB,aAAAA,QAAM,KAAK,SAASC,gBAAe;AAAA,EAChE;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAwB;AACvB,QAAM,EAAE,QAAQ,SAAS,WAAW,mBAAmB,GAAG,iBAAiB,QAC1E,kDAAqB,SAAS,MAAM,SAAS;AAE9C,QAAM,iBAAiB,+BAAY,oBAAoB,aAAa,EAAE;AACtE,QAAM,UAAU,eAAe,SAAS;AAExC,QAAM,kBAAc,kCAAc,KAAK;AAEvC,MAAI,CAAC,aAAa,CAAC,SAAS;AAC3B,WAAO;AAAA,EACR;AAMA,QAAM,YAAY,mBAAmB;AACrC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,GAAG,SAAS;AAAA,MACvB,aAAW;AAAA,MACX,cAAY;AAAA,MACZ,gBAAc,CAAC;AAAA,MACf,kBAAgB;AAAA,MAChB,6BAA2B;AAAA,MAC3B,iBAAe,CAAC,CAAC;AAAA,MACjB,mBAAiB;AAAA,MACjB,OAAO;AAAA,QACN,gBAAgB,UAAU,YAAY,cAAc,WAAW;AAAA,QAC/D,YAAY,kBAAkB,WAAW,WAAW;AAAA,QACpD;AAAA,QACA,GAAG;AAAA,MACJ;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,GAAG,SAAS;AAAA,UACvB,OAAO;AAAA,YACN;AAAA,YACA,YAAY,WAAW,SAAS;AAAA,YAChC,WAAW,KAAK,MAAM,WAAW,UAAU,IAAI;AAAA,YAC/C,UAAU,KAAK,KAAK,aAAa,CAAC;AAAA,YAClC,OAAO;AAAA,YACP,OAAO,YAAY,KAAK,KAAK,SAAS,IAAI;AAAA,YAC1C,QAAQ,aAAa,KAAK,KAAK,UAAU,IAAI;AAAA,UAC9C;AAAA,UAEA;AAAA,wDAAC,SAAI,WAAW,GAAG,SAAS,4BAA4B,KAAI,QAC1D,yBAAe,MAAM,IAAI,EAAE,IAAI,CAAC,YAAY,UAC5C,4CAAC,SAAgB,KAAI,QACnB,wBADQ,KAEV,CACA,GACF;AAAA,aACE,qBAAqB,eACtB;AAAA,cAAC;AAAA;AAAA,gBAEA,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACC,GAAG;AAAA,gBACJ,eAAe,uBAAuB,iBAAiB;AAAA;AAAA,YACxD;AAAA;AAAA;AAAA,MAEF;AAAA;AAAA,EACD;AAEF,CAAC;AAMM,MAAM,YAAY;",
4
+ "sourcesContent": ["import {\n\tBox,\n\tTLDefaultFillStyle,\n\tTLDefaultFontStyle,\n\tTLDefaultHorizontalAlignStyle,\n\tTLDefaultVerticalAlignStyle,\n\tTLShapeId,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { PlainTextArea } from '../text/PlainTextArea'\nimport { TextHelpers } from './TextHelpers'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditablePlainText } from './useEditablePlainText'\n\n/** @public */\nexport interface PlainTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: string\n\tfont: TLDefaultFontStyle\n\tfontSize: number\n\tlineHeight: number\n\tfill?: TLDefaultFillStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\n\twrap?: boolean\n\ttext?: string\n\tlabelColor: string\n\tbounds?: Box\n\tisSelected: boolean\n\tonKeyDown?(e: KeyboardEvent): void\n\tclassNamePrefix?: string\n\tstyle?: React.CSSProperties\n\ttextWidth?: number\n\ttextHeight?: number\n\tpadding?: number\n}\n\n/**\n * Renders a text label that can be used inside of shapes.\n * The component has the ability to be edited in place and furthermore\n * supports rich text editing.\n *\n * @public @react\n */\nexport const PlainTextLabel = React.memo(function PlainTextLabel({\n\tshapeId,\n\ttype,\n\ttext: plaintext,\n\tlabelColor,\n\tfont,\n\tfontSize,\n\tlineHeight,\n\talign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n}: PlainTextLabelProps) {\n\tconst { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =\n\t\tuseEditablePlainText(shapeId, type, plaintext)\n\n\tconst finalPlainText = TextHelpers.normalizeTextForDom(plaintext || '')\n\tconst hasText = finalPlainText.length > 0\n\n\tconst legacyAlign = isLegacyAlign(align)\n\n\tif (!isEditing && !hasText) {\n\t\treturn null\n\t}\n\n\t// TODO: probably combine tl-text and tl-arrow eventually\n\t// In case you're grepping for this, it breaks down as follows:\n\t// tl-text-label, tl-text-label__inner, tl-text-shape-label, tl-text\n\t// tl-arrow-label, tl-arrow-label__inner, tl-arrow\n\tconst cssPrefix = classNamePrefix || 'tl-text'\n\treturn (\n\t\t<div\n\t\t\tclassName={`${cssPrefix}-label tl-text-wrapper tl-plain-text-wrapper`}\n\t\t\taria-hidden={!isEditing}\n\t\t\tdata-font={font}\n\t\t\tdata-align={align}\n\t\t\tdata-hastext={!isEmpty}\n\t\t\tdata-isediting={isEditing}\n\t\t\tdata-is-ready-for-editing={isReadyForEditing}\n\t\t\tdata-textwrap={!!wrap}\n\t\t\tdata-isselected={isSelected}\n\t\t\tstyle={{\n\t\t\t\tjustifyContent: align === 'middle' || legacyAlign ? 'center' : align,\n\t\t\t\talignItems: verticalAlign === 'middle' ? 'center' : verticalAlign,\n\t\t\t\tpadding,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`${cssPrefix}-label__inner tl-text-content__wrapper`}\n\t\t\t\tstyle={{\n\t\t\t\t\tfontSize,\n\t\t\t\t\tlineHeight: lineHeight.toString(),\n\t\t\t\t\tminHeight: Math.floor(fontSize * lineHeight) + 'px',\n\t\t\t\t\tminWidth: Math.ceil(textWidth || 0),\n\t\t\t\t\tcolor: labelColor,\n\t\t\t\t\twidth: textWidth ? Math.ceil(textWidth) : undefined,\n\t\t\t\t\theight: textHeight ? Math.ceil(textHeight) : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={`${cssPrefix} tl-text tl-text-content`} dir=\"auto\">\n\t\t\t\t\t{finalPlainText.split('\\n').map((lineOfText, index) => (\n\t\t\t\t\t\t<div key={index} dir=\"auto\">\n\t\t\t\t\t\t\t{lineOfText}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t\t{(isReadyForEditing || isSelected) && (\n\t\t\t\t\t<PlainTextArea\n\t\t\t\t\t\t// Fudge the ref type because we're using forwardRef and it's not typed correctly.\n\t\t\t\t\t\tref={rInput as any}\n\t\t\t\t\t\ttext={plaintext}\n\t\t\t\t\t\tisEditing={isEditing}\n\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t{...editableTextRest}\n\t\t\t\t\t\thandleKeyDown={handleKeyDownCustom ?? editableTextRest.handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n\n/**\n * @deprecated Use `PlainTextLabel` instead.\n * @public\n */\nexport const TextLabel = PlainTextLabel\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkGG;AA1FH,mBAAkB;AAClB,2BAA8B;AAC9B,yBAA4B;AAC5B,yBAA8B;AAC9B,kCAAqC;AAgC9B,MAAM,iBAAiB,aAAAA,QAAM,KAAK,SAASC,gBAAe;AAAA,EAChE;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAwB;AACvB,QAAM,EAAE,QAAQ,SAAS,WAAW,mBAAmB,GAAG,iBAAiB,QAC1E,kDAAqB,SAAS,MAAM,SAAS;AAE9C,QAAM,iBAAiB,+BAAY,oBAAoB,aAAa,EAAE;AACtE,QAAM,UAAU,eAAe,SAAS;AAExC,QAAM,kBAAc,kCAAc,KAAK;AAEvC,MAAI,CAAC,aAAa,CAAC,SAAS;AAC3B,WAAO;AAAA,EACR;AAMA,QAAM,YAAY,mBAAmB;AACrC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,GAAG,SAAS;AAAA,MACvB,eAAa,CAAC;AAAA,MACd,aAAW;AAAA,MACX,cAAY;AAAA,MACZ,gBAAc,CAAC;AAAA,MACf,kBAAgB;AAAA,MAChB,6BAA2B;AAAA,MAC3B,iBAAe,CAAC,CAAC;AAAA,MACjB,mBAAiB;AAAA,MACjB,OAAO;AAAA,QACN,gBAAgB,UAAU,YAAY,cAAc,WAAW;AAAA,QAC/D,YAAY,kBAAkB,WAAW,WAAW;AAAA,QACpD;AAAA,QACA,GAAG;AAAA,MACJ;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACA,WAAW,GAAG,SAAS;AAAA,UACvB,OAAO;AAAA,YACN;AAAA,YACA,YAAY,WAAW,SAAS;AAAA,YAChC,WAAW,KAAK,MAAM,WAAW,UAAU,IAAI;AAAA,YAC/C,UAAU,KAAK,KAAK,aAAa,CAAC;AAAA,YAClC,OAAO;AAAA,YACP,OAAO,YAAY,KAAK,KAAK,SAAS,IAAI;AAAA,YAC1C,QAAQ,aAAa,KAAK,KAAK,UAAU,IAAI;AAAA,UAC9C;AAAA,UAEA;AAAA,wDAAC,SAAI,WAAW,GAAG,SAAS,4BAA4B,KAAI,QAC1D,yBAAe,MAAM,IAAI,EAAE,IAAI,CAAC,YAAY,UAC5C,4CAAC,SAAgB,KAAI,QACnB,wBADQ,KAEV,CACA,GACF;AAAA,aACE,qBAAqB,eACtB;AAAA,cAAC;AAAA;AAAA,gBAEA,KAAK;AAAA,gBACL,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,gBACC,GAAG;AAAA,gBACJ,eAAe,uBAAuB,iBAAiB;AAAA;AAAA,YACxD;AAAA;AAAA;AAAA,MAEF;AAAA;AAAA,EACD;AAEF,CAAC;AAMM,MAAM,YAAY;",
6
6
  "names": ["React", "PlainTextLabel"]
7
7
  }
@@ -103,6 +103,7 @@ const RichTextLabel = import_react.default.memo(function RichTextLabel2({
103
103
  "div",
104
104
  {
105
105
  className: `${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`,
106
+ "aria-hidden": !isEditing,
106
107
  "data-font": font,
107
108
  "data-align": align,
108
109
  "data-hastext": !isEmpty,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/RichTextLabel.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tDefaultFontFamilies,\n\tTLDefaultFillStyle,\n\tTLDefaultFontStyle,\n\tTLDefaultHorizontalAlignStyle,\n\tTLDefaultVerticalAlignStyle,\n\tTLEventInfo,\n\tTLRichText,\n\tTLShapeId,\n\tpreventDefault,\n\tuseEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useMemo } from 'react'\nimport { renderHtmlFromRichText } from '../../utils/text/richText'\nimport { RichTextArea } from '../text/RichTextArea'\nimport { TEXT_PROPS } from './default-shape-constants'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditableRichText } from './useEditableRichText'\n\n/** @public */\nexport interface RichTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: string\n\tfont: TLDefaultFontStyle\n\tfontSize: number\n\tlineHeight: number\n\tfill?: TLDefaultFillStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\n\twrap?: boolean\n\trichText?: TLRichText\n\tlabelColor: string\n\tbounds?: Box\n\tisSelected: boolean\n\tonKeyDown?(e: KeyboardEvent): void\n\tclassNamePrefix?: string\n\tstyle?: React.CSSProperties\n\ttextWidth?: number\n\ttextHeight?: number\n\tpadding?: number\n\thasCustomTabBehavior?: boolean\n}\n\n/**\n * Renders a text label that can be used inside of shapes.\n * The component has the ability to be edited in place and furthermore\n * supports rich text editing.\n *\n * @public @react\n */\nexport const RichTextLabel = React.memo(function RichTextLabel({\n\tshapeId,\n\ttype,\n\trichText,\n\tlabelColor,\n\tfont,\n\tfontSize,\n\tlineHeight,\n\talign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n\thasCustomTabBehavior,\n}: RichTextLabelProps) {\n\tconst editor = useEditor()\n\tconst isDragging = React.useRef(false)\n\tconst { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =\n\t\tuseEditableRichText(shapeId, type, richText)\n\n\tconst html = useMemo(() => {\n\t\tif (richText) {\n\t\t\treturn renderHtmlFromRichText(editor, richText)\n\t\t}\n\t}, [editor, richText])\n\n\tconst selectToolActive = useValue(\n\t\t'isSelectToolActive',\n\t\t() => editor.getCurrentToolId() === 'select',\n\t\t[editor]\n\t)\n\n\tuseReactor(\n\t\t'isDragging',\n\t\t() => {\n\t\t\teditor.getInstanceState()\n\t\t\tisDragging.current = editor.inputs.isDragging\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst legacyAlign = isLegacyAlign(align)\n\n\tconst handlePointerDown = (e: React.MouseEvent<HTMLDivElement>) => {\n\t\tif (e.target instanceof HTMLElement && (e.target.tagName === 'A' || e.target.closest('a'))) {\n\t\t\t// This mousedown prevent default is to let dragging when over a link work.\n\t\t\tpreventDefault(e)\n\n\t\t\tif (!selectToolActive) return\n\t\t\tconst link = e.target.closest('a')?.getAttribute('href') ?? ''\n\t\t\t// We don't get the mouseup event later because we preventDefault\n\t\t\t// so we have to do it manually.\n\t\t\tconst handlePointerUp = (e: TLEventInfo) => {\n\t\t\t\tif (e.name !== 'pointer_up') return\n\n\t\t\t\tif (!isDragging.current) {\n\t\t\t\t\twindow.open(link, '_blank', 'noopener, noreferrer')\n\t\t\t\t}\n\t\t\t\teditor.off('event', handlePointerUp)\n\t\t\t}\n\t\t\teditor.on('event', handlePointerUp)\n\t\t}\n\t}\n\n\t// Should be guarded higher up so that this doesn't render... but repeated here. This should never be true.\n\tif (!isEditing && isEmpty) return null\n\n\t// TODO: probably combine tl-text and tl-arrow eventually\n\tconst cssPrefix = classNamePrefix || 'tl-text'\n\treturn (\n\t\t<div\n\t\t\tclassName={`${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`}\n\t\t\tdata-font={font}\n\t\t\tdata-align={align}\n\t\t\tdata-hastext={!isEmpty}\n\t\t\tdata-isediting={isEditing}\n\t\t\tdata-textwrap={!!wrap}\n\t\t\tdata-isselected={isSelected}\n\t\t\tstyle={{\n\t\t\t\tjustifyContent: align === 'middle' || legacyAlign ? 'center' : align,\n\t\t\t\talignItems: verticalAlign === 'middle' ? 'center' : verticalAlign,\n\t\t\t\tpadding,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`${cssPrefix}-label__inner tl-text-content__wrapper`}\n\t\t\t\tstyle={{\n\t\t\t\t\tfontSize,\n\t\t\t\t\tlineHeight: lineHeight.toString(),\n\t\t\t\t\tminHeight: Math.floor(fontSize * lineHeight) + 'px',\n\t\t\t\t\tminWidth: Math.ceil(textWidth || 0),\n\t\t\t\t\tcolor: labelColor,\n\t\t\t\t\twidth: textWidth ? Math.ceil(textWidth) : undefined,\n\t\t\t\t\theight: textHeight ? Math.ceil(textHeight) : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={`${cssPrefix} tl-text tl-text-content`} dir=\"auto\">\n\t\t\t\t\t{richText && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"tl-rich-text\"\n\t\t\t\t\t\t\tdata-is-select-tool-active={selectToolActive}\n\t\t\t\t\t\t\t// todo: see if I can abuse this\n\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: html || '' }}\n\t\t\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\t\t\tdata-is-ready-for-editing={isReadyForEditing}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{(isReadyForEditing || isSelected) && (\n\t\t\t\t\t<RichTextArea\n\t\t\t\t\t\t// Fudge the ref type because we're using forwardRef and it's not typed correctly.\n\t\t\t\t\t\tref={rInput as any}\n\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\tisEditing={isEditing}\n\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t{...editableTextRest}\n\t\t\t\t\t\thasCustomTabBehavior={hasCustomTabBehavior}\n\t\t\t\t\t\thandleKeyDown={handleKeyDownCustom ?? editableTextRest.handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n\n/** @public */\nexport interface RichTextSVGProps {\n\tbounds: Box\n\trichText: TLRichText\n\tfontSize: number\n\tfont: TLDefaultFontStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\n\twrap?: boolean\n\tlabelColor: string\n\tpadding: number\n\tshowTextOutline?: boolean\n}\n\n/**\n * Renders a rich text string as SVG given bounds and text properties.\n *\n * @public @react\n */\nexport function RichTextSVG({\n\tbounds,\n\trichText,\n\tfontSize,\n\tfont,\n\talign,\n\tverticalAlign,\n\twrap,\n\tlabelColor,\n\tpadding,\n\tshowTextOutline = true,\n}: RichTextSVGProps) {\n\tconst editor = useEditor()\n\tconst html = renderHtmlFromRichText(editor, richText)\n\tconst textAlign =\n\t\talign === 'middle'\n\t\t\t? ('center' as const)\n\t\t\t: align === 'start'\n\t\t\t\t? ('start' as const)\n\t\t\t\t: ('end' as const)\n\tconst justifyContent =\n\t\talign === 'middle'\n\t\t\t? ('center' as const)\n\t\t\t: align === 'start'\n\t\t\t\t? ('flex-start' as const)\n\t\t\t\t: ('flex-end' as const)\n\tconst alignItems =\n\t\tverticalAlign === 'middle' ? 'center' : verticalAlign === 'start' ? 'flex-start' : 'flex-end'\n\tconst wrapperStyle = {\n\t\tdisplay: 'flex',\n\t\tfontFamily: DefaultFontFamilies[font],\n\t\theight: `100%`,\n\t\tjustifyContent,\n\t\talignItems,\n\t\tpadding: `${padding}px`,\n\t}\n\tconst style = {\n\t\tfontSize: `${fontSize}px`,\n\t\twrap: wrap ? 'wrap' : 'nowrap',\n\t\tcolor: labelColor,\n\t\tlineHeight: TEXT_PROPS.lineHeight,\n\t\ttextAlign,\n\t\twidth: '100%',\n\t\twordWrap: 'break-word' as const,\n\t\toverflowWrap: 'break-word' as const,\n\t\twhiteSpace: 'pre-wrap',\n\t\ttextShadow: showTextOutline ? 'var(--tl-text-outline)' : 'none',\n\t}\n\n\treturn (\n\t\t<foreignObject\n\t\t\tx={bounds.minX}\n\t\t\ty={bounds.minY}\n\t\t\twidth={bounds.w}\n\t\t\theight={bounds.h}\n\t\t\tclassName=\"tl-export-embed-styles tl-rich-text tl-rich-text-svg\"\n\t\t>\n\t\t\t<div style={wrapperStyle}>\n\t\t\t\t<div dangerouslySetInnerHTML={{ __html: html }} style={style} />\n\t\t\t</div>\n\t\t</foreignObject>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBox,\n\tDefaultFontFamilies,\n\tTLDefaultFillStyle,\n\tTLDefaultFontStyle,\n\tTLDefaultHorizontalAlignStyle,\n\tTLDefaultVerticalAlignStyle,\n\tTLEventInfo,\n\tTLRichText,\n\tTLShapeId,\n\tpreventDefault,\n\tuseEditor,\n\tuseReactor,\n\tuseValue,\n} from '@tldraw/editor'\nimport React, { useMemo } from 'react'\nimport { renderHtmlFromRichText } from '../../utils/text/richText'\nimport { RichTextArea } from '../text/RichTextArea'\nimport { TEXT_PROPS } from './default-shape-constants'\nimport { isLegacyAlign } from './legacyProps'\nimport { useEditableRichText } from './useEditableRichText'\n\n/** @public */\nexport interface RichTextLabelProps {\n\tshapeId: TLShapeId\n\ttype: string\n\tfont: TLDefaultFontStyle\n\tfontSize: number\n\tlineHeight: number\n\tfill?: TLDefaultFillStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\n\twrap?: boolean\n\trichText?: TLRichText\n\tlabelColor: string\n\tbounds?: Box\n\tisSelected: boolean\n\tonKeyDown?(e: KeyboardEvent): void\n\tclassNamePrefix?: string\n\tstyle?: React.CSSProperties\n\ttextWidth?: number\n\ttextHeight?: number\n\tpadding?: number\n\thasCustomTabBehavior?: boolean\n}\n\n/**\n * Renders a text label that can be used inside of shapes.\n * The component has the ability to be edited in place and furthermore\n * supports rich text editing.\n *\n * @public @react\n */\nexport const RichTextLabel = React.memo(function RichTextLabel({\n\tshapeId,\n\ttype,\n\trichText,\n\tlabelColor,\n\tfont,\n\tfontSize,\n\tlineHeight,\n\talign,\n\tverticalAlign,\n\twrap,\n\tisSelected,\n\tpadding = 0,\n\tonKeyDown: handleKeyDownCustom,\n\tclassNamePrefix,\n\tstyle,\n\ttextWidth,\n\ttextHeight,\n\thasCustomTabBehavior,\n}: RichTextLabelProps) {\n\tconst editor = useEditor()\n\tconst isDragging = React.useRef(false)\n\tconst { rInput, isEmpty, isEditing, isReadyForEditing, ...editableTextRest } =\n\t\tuseEditableRichText(shapeId, type, richText)\n\n\tconst html = useMemo(() => {\n\t\tif (richText) {\n\t\t\treturn renderHtmlFromRichText(editor, richText)\n\t\t}\n\t}, [editor, richText])\n\n\tconst selectToolActive = useValue(\n\t\t'isSelectToolActive',\n\t\t() => editor.getCurrentToolId() === 'select',\n\t\t[editor]\n\t)\n\n\tuseReactor(\n\t\t'isDragging',\n\t\t() => {\n\t\t\teditor.getInstanceState()\n\t\t\tisDragging.current = editor.inputs.isDragging\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst legacyAlign = isLegacyAlign(align)\n\n\tconst handlePointerDown = (e: React.MouseEvent<HTMLDivElement>) => {\n\t\tif (e.target instanceof HTMLElement && (e.target.tagName === 'A' || e.target.closest('a'))) {\n\t\t\t// This mousedown prevent default is to let dragging when over a link work.\n\t\t\tpreventDefault(e)\n\n\t\t\tif (!selectToolActive) return\n\t\t\tconst link = e.target.closest('a')?.getAttribute('href') ?? ''\n\t\t\t// We don't get the mouseup event later because we preventDefault\n\t\t\t// so we have to do it manually.\n\t\t\tconst handlePointerUp = (e: TLEventInfo) => {\n\t\t\t\tif (e.name !== 'pointer_up') return\n\n\t\t\t\tif (!isDragging.current) {\n\t\t\t\t\twindow.open(link, '_blank', 'noopener, noreferrer')\n\t\t\t\t}\n\t\t\t\teditor.off('event', handlePointerUp)\n\t\t\t}\n\t\t\teditor.on('event', handlePointerUp)\n\t\t}\n\t}\n\n\t// Should be guarded higher up so that this doesn't render... but repeated here. This should never be true.\n\tif (!isEditing && isEmpty) return null\n\n\t// TODO: probably combine tl-text and tl-arrow eventually\n\tconst cssPrefix = classNamePrefix || 'tl-text'\n\treturn (\n\t\t<div\n\t\t\tclassName={`${cssPrefix}-label tl-text-wrapper tl-rich-text-wrapper`}\n\t\t\taria-hidden={!isEditing}\n\t\t\tdata-font={font}\n\t\t\tdata-align={align}\n\t\t\tdata-hastext={!isEmpty}\n\t\t\tdata-isediting={isEditing}\n\t\t\tdata-textwrap={!!wrap}\n\t\t\tdata-isselected={isSelected}\n\t\t\tstyle={{\n\t\t\t\tjustifyContent: align === 'middle' || legacyAlign ? 'center' : align,\n\t\t\t\talignItems: verticalAlign === 'middle' ? 'center' : verticalAlign,\n\t\t\t\tpadding,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName={`${cssPrefix}-label__inner tl-text-content__wrapper`}\n\t\t\t\tstyle={{\n\t\t\t\t\tfontSize,\n\t\t\t\t\tlineHeight: lineHeight.toString(),\n\t\t\t\t\tminHeight: Math.floor(fontSize * lineHeight) + 'px',\n\t\t\t\t\tminWidth: Math.ceil(textWidth || 0),\n\t\t\t\t\tcolor: labelColor,\n\t\t\t\t\twidth: textWidth ? Math.ceil(textWidth) : undefined,\n\t\t\t\t\theight: textHeight ? Math.ceil(textHeight) : undefined,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div className={`${cssPrefix} tl-text tl-text-content`} dir=\"auto\">\n\t\t\t\t\t{richText && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName=\"tl-rich-text\"\n\t\t\t\t\t\t\tdata-is-select-tool-active={selectToolActive}\n\t\t\t\t\t\t\t// todo: see if I can abuse this\n\t\t\t\t\t\t\tdangerouslySetInnerHTML={{ __html: html || '' }}\n\t\t\t\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\t\t\t\tdata-is-ready-for-editing={isReadyForEditing}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{(isReadyForEditing || isSelected) && (\n\t\t\t\t\t<RichTextArea\n\t\t\t\t\t\t// Fudge the ref type because we're using forwardRef and it's not typed correctly.\n\t\t\t\t\t\tref={rInput as any}\n\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\tisEditing={isEditing}\n\t\t\t\t\t\tshapeId={shapeId}\n\t\t\t\t\t\t{...editableTextRest}\n\t\t\t\t\t\thasCustomTabBehavior={hasCustomTabBehavior}\n\t\t\t\t\t\thandleKeyDown={handleKeyDownCustom ?? editableTextRest.handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n})\n\n/** @public */\nexport interface RichTextSVGProps {\n\tbounds: Box\n\trichText: TLRichText\n\tfontSize: number\n\tfont: TLDefaultFontStyle\n\talign: TLDefaultHorizontalAlignStyle\n\tverticalAlign: TLDefaultVerticalAlignStyle\n\twrap?: boolean\n\tlabelColor: string\n\tpadding: number\n\tshowTextOutline?: boolean\n}\n\n/**\n * Renders a rich text string as SVG given bounds and text properties.\n *\n * @public @react\n */\nexport function RichTextSVG({\n\tbounds,\n\trichText,\n\tfontSize,\n\tfont,\n\talign,\n\tverticalAlign,\n\twrap,\n\tlabelColor,\n\tpadding,\n\tshowTextOutline = true,\n}: RichTextSVGProps) {\n\tconst editor = useEditor()\n\tconst html = renderHtmlFromRichText(editor, richText)\n\tconst textAlign =\n\t\talign === 'middle'\n\t\t\t? ('center' as const)\n\t\t\t: align === 'start'\n\t\t\t\t? ('start' as const)\n\t\t\t\t: ('end' as const)\n\tconst justifyContent =\n\t\talign === 'middle'\n\t\t\t? ('center' as const)\n\t\t\t: align === 'start'\n\t\t\t\t? ('flex-start' as const)\n\t\t\t\t: ('flex-end' as const)\n\tconst alignItems =\n\t\tverticalAlign === 'middle' ? 'center' : verticalAlign === 'start' ? 'flex-start' : 'flex-end'\n\tconst wrapperStyle = {\n\t\tdisplay: 'flex',\n\t\tfontFamily: DefaultFontFamilies[font],\n\t\theight: `100%`,\n\t\tjustifyContent,\n\t\talignItems,\n\t\tpadding: `${padding}px`,\n\t}\n\tconst style = {\n\t\tfontSize: `${fontSize}px`,\n\t\twrap: wrap ? 'wrap' : 'nowrap',\n\t\tcolor: labelColor,\n\t\tlineHeight: TEXT_PROPS.lineHeight,\n\t\ttextAlign,\n\t\twidth: '100%',\n\t\twordWrap: 'break-word' as const,\n\t\toverflowWrap: 'break-word' as const,\n\t\twhiteSpace: 'pre-wrap',\n\t\ttextShadow: showTextOutline ? 'var(--tl-text-outline)' : 'none',\n\t}\n\n\treturn (\n\t\t<foreignObject\n\t\t\tx={bounds.minX}\n\t\t\ty={bounds.minY}\n\t\t\twidth={bounds.w}\n\t\t\theight={bounds.h}\n\t\t\tclassName=\"tl-export-embed-styles tl-rich-text tl-rich-text-svg\"\n\t\t>\n\t\t\t<div style={wrapperStyle}>\n\t\t\t\t<div dangerouslySetInnerHTML={{ __html: html }} style={style} />\n\t\t\t</div>\n\t\t</foreignObject>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["React", "RichTextLabel", "e"]
7
7
  }
@@ -245,25 +245,19 @@ class TextShapeUtil extends import_editor.ShapeUtil {
245
245
  // }
246
246
  }
247
247
  function getTextSize(editor, props) {
248
- const { font, richText, autoSize, size, w } = props;
249
- const minWidth = autoSize ? 16 : Math.max(16, w);
248
+ const { font, richText, size, w } = props;
249
+ const minWidth = 16;
250
250
  const fontSize = import_default_shape_constants.FONT_SIZES[size];
251
- const cw = autoSize ? null : (
252
- // `measureText` floors the number so we need to do the same here to avoid issues.
253
- Math.floor(Math.max(minWidth, w))
254
- );
251
+ const maybeFixedWidth = props.autoSize ? null : Math.max(minWidth, Math.floor(w));
255
252
  const html = (0, import_richText.renderHtmlFromRichTextForMeasurement)(editor, richText);
256
253
  const result = editor.textMeasure.measureHtml(html, {
257
254
  ...import_default_shape_constants.TEXT_PROPS,
258
255
  fontFamily: import_default_shape_constants.FONT_FAMILIES[font],
259
256
  fontSize,
260
- maxWidth: cw
257
+ maxWidth: maybeFixedWidth
261
258
  });
262
- if (autoSize) {
263
- result.w += 1;
264
- }
265
259
  return {
266
- width: Math.max(minWidth, result.w),
260
+ width: maybeFixedWidth ?? Math.max(minWidth, result.w + 1),
267
261
  height: Math.max(fontSize, result.h)
268
262
  };
269
263
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/text/TextShapeUtil.tsx"],
4
- "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBox,\n\tEditor,\n\tRectangle2d,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLGeometryOpts,\n\tTLResizeInfo,\n\tTLShapeId,\n\tTLTextShape,\n\tVec,\n\tcreateComputedCache,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tisEqual,\n\tresizeScaled,\n\ttextShapeMigrations,\n\ttextShapeProps,\n\ttoDomPrecision,\n\ttoRichText,\n\tuseEditor,\n} from '@tldraw/editor'\nimport { useCallback } from 'react'\nimport {\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport { FONT_FAMILIES, FONT_SIZES, TEXT_PROPS } from '../shared/default-shape-constants'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\nconst sizeCache = createComputedCache(\n\t'text size',\n\t(editor: Editor, shape: TLTextShape) => {\n\t\teditor.fonts.trackFontsForShape(shape)\n\t\treturn getTextSize(editor, shape.props)\n\t},\n\t{ areRecordsEqual: (a, b) => a.props === b.props }\n)\n/** @public */\nexport interface TextShapeOptions {\n\t/** How much addition padding should be added to the horizontal geometry of the shape when binding to an arrow? */\n\textraArrowHorizontalPadding: number\n}\n\n/** @public */\nexport class TextShapeUtil extends ShapeUtil<TLTextShape> {\n\tstatic override type = 'text' as const\n\tstatic override props = textShapeProps\n\tstatic override migrations = textShapeMigrations\n\n\toverride options: TextShapeOptions = {\n\t\textraArrowHorizontalPadding: 10,\n\t}\n\n\tgetDefaultProps(): TLTextShape['props'] {\n\t\treturn {\n\t\t\tcolor: 'black',\n\t\t\tsize: 'm',\n\t\t\tw: 8,\n\t\t\tfont: 'draw',\n\t\t\ttextAlign: 'start',\n\t\t\tautoSize: true,\n\t\t\tscale: 1,\n\t\t\trichText: toRichText(''),\n\t\t}\n\t}\n\n\tgetMinDimensions(shape: TLTextShape) {\n\t\treturn sizeCache.get(this.editor, shape.id)!\n\t}\n\n\tgetGeometry(shape: TLTextShape, opts: TLGeometryOpts) {\n\t\tconst { scale } = shape.props\n\t\tconst { width, height } = this.getMinDimensions(shape)!\n\t\tconst context = opts?.context ?? 'none'\n\t\treturn new Rectangle2d({\n\t\t\tx:\n\t\t\t\t(context === '@tldraw/arrow-without-arrowhead'\n\t\t\t\t\t? -this.options.extraArrowHorizontalPadding\n\t\t\t\t\t: 0) * scale,\n\t\t\twidth:\n\t\t\t\t(width +\n\t\t\t\t\t(context === '@tldraw/arrow-without-arrowhead'\n\t\t\t\t\t\t? this.options.extraArrowHorizontalPadding * 2\n\t\t\t\t\t\t: 0)) *\n\t\t\t\tscale,\n\t\t\theight: height * scale,\n\t\t\tisFilled: true,\n\t\t\tisLabel: true,\n\t\t})\n\t}\n\n\toverride getFontFaces(shape: TLTextShape) {\n\t\t// no need for an empty rich text check here\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\toverride getText(shape: TLTextShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride isAspectRatioLocked() {\n\t\treturn true\n\t} // WAIT NO THIS IS HARD CODED IN THE RESIZE HANDLER\n\n\tcomponent(shape: TLTextShape) {\n\t\tconst {\n\t\t\tid,\n\t\t\tprops: { font, size, richText, color, scale, textAlign },\n\t\t} = shape\n\n\t\tconst { width, height } = this.getMinDimensions(shape)\n\t\tconst isSelected = shape.id === this.editor.getOnlySelectedShapeId()\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst handleKeyDown = useTextShapeKeydownHandler(id)\n\n\t\treturn (\n\t\t\t<RichTextLabel\n\t\t\t\tshapeId={id}\n\t\t\t\tclassNamePrefix=\"tl-text-shape\"\n\t\t\t\ttype=\"text\"\n\t\t\t\tfont={font}\n\t\t\t\tfontSize={FONT_SIZES[size]}\n\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\talign={textAlign}\n\t\t\t\tverticalAlign=\"middle\"\n\t\t\t\trichText={richText}\n\t\t\t\tlabelColor={theme[color].solid}\n\t\t\t\tisSelected={isSelected}\n\t\t\t\ttextWidth={width}\n\t\t\t\ttextHeight={height}\n\t\t\t\tstyle={{\n\t\t\t\t\ttransform: `scale(${scale})`,\n\t\t\t\t\ttransformOrigin: 'top left',\n\t\t\t\t}}\n\t\t\t\twrap\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t/>\n\t\t)\n\t}\n\n\tindicator(shape: TLTextShape) {\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\t\tconst editor = useEditor()\n\t\tif (shape.props.autoSize && editor.getEditingShapeId() === shape.id) return null\n\t\treturn <rect width={toDomPrecision(bounds.width)} height={toDomPrecision(bounds.height)} />\n\t}\n\n\toverride toSvg(shape: TLTextShape, ctx: SvgExportContext) {\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\t\tconst width = bounds.width / (shape.props.scale ?? 1)\n\t\tconst height = bounds.height / (shape.props.scale ?? 1)\n\n\t\tconst theme = getDefaultColorTheme(ctx)\n\n\t\tconst exportBounds = new Box(0, 0, width, height)\n\t\treturn (\n\t\t\t<RichTextSVG\n\t\t\t\tfontSize={FONT_SIZES[shape.props.size]}\n\t\t\t\tfont={shape.props.font}\n\t\t\t\talign={shape.props.textAlign}\n\t\t\t\tverticalAlign=\"middle\"\n\t\t\t\trichText={shape.props.richText}\n\t\t\t\tlabelColor={theme[shape.props.color].solid}\n\t\t\t\tbounds={exportBounds}\n\t\t\t\tpadding={0}\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride onResize(shape: TLTextShape, info: TLResizeInfo<TLTextShape>) {\n\t\tconst { newPoint, initialBounds, initialShape, scaleX, handle } = info\n\n\t\tif (info.mode === 'scale_shape' || (handle !== 'right' && handle !== 'left')) {\n\t\t\treturn {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\t...resizeScaled(shape, info),\n\t\t\t}\n\t\t} else {\n\t\t\tconst nextWidth = Math.max(1, Math.abs(initialBounds.width * scaleX))\n\t\t\tconst { x, y } =\n\t\t\t\tscaleX < 0 ? Vec.Sub(newPoint, Vec.FromAngle(shape.rotation).mul(nextWidth)) : newPoint\n\n\t\t\treturn {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\tprops: {\n\t\t\t\t\tw: nextWidth / initialShape.props.scale,\n\t\t\t\t\tautoSize: false,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onEditEnd(shape: TLTextShape) {\n\t\t// todo: find a way to check if the rich text has any nodes that aren't empty spaces\n\t\tconst trimmedText = renderPlaintextFromRichText(this.editor, shape.props.richText).trimEnd()\n\n\t\tif (trimmedText.length === 0) {\n\t\t\tthis.editor.deleteShapes([shape.id])\n\t\t}\n\t}\n\n\toverride onBeforeUpdate(prev: TLTextShape, next: TLTextShape) {\n\t\tif (!next.props.autoSize) return\n\n\t\tconst styleDidChange =\n\t\t\tprev.props.size !== next.props.size ||\n\t\t\tprev.props.textAlign !== next.props.textAlign ||\n\t\t\tprev.props.font !== next.props.font ||\n\t\t\t(prev.props.scale !== 1 && next.props.scale === 1)\n\n\t\tconst textDidChange = !isEqual(prev.props.richText, next.props.richText)\n\n\t\t// Only update position if either changed\n\t\tif (!styleDidChange && !textDidChange) return\n\n\t\t// Might return a cached value for the bounds\n\t\tconst boundsA = this.getMinDimensions(prev)\n\n\t\t// Will always be a fresh call to getTextSize\n\t\tconst boundsB = getTextSize(this.editor, next.props)\n\n\t\tconst wA = boundsA.width * prev.props.scale\n\t\tconst hA = boundsA.height * prev.props.scale\n\t\tconst wB = boundsB.width * next.props.scale\n\t\tconst hB = boundsB.height * next.props.scale\n\n\t\tlet delta: Vec | undefined\n\n\t\tswitch (next.props.textAlign) {\n\t\t\tcase 'middle': {\n\t\t\t\tdelta = new Vec((wB - wA) / 2, textDidChange ? 0 : (hB - hA) / 2)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'end': {\n\t\t\t\tdelta = new Vec(wB - wA, textDidChange ? 0 : (hB - hA) / 2)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (textDidChange) break\n\t\t\t\tdelta = new Vec(0, (hB - hA) / 2)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif (delta) {\n\t\t\t// account for shape rotation when writing text:\n\t\t\tdelta.rot(next.rotation)\n\t\t\tconst { x, y } = next\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tx: x - delta.x,\n\t\t\t\ty: y - delta.y,\n\t\t\t\tprops: { ...next.props, w: wB },\n\t\t\t}\n\t\t} else {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: { ...next.props, w: wB },\n\t\t\t}\n\t\t}\n\t}\n\n\t// \ttodo: The edge doubleclicking feels like a mistake more often than\n\t// not, especially on multiline text. Removed June 16 2024\n\n\t// override onDoubleClickEdge = (shape: TLTextShape) => {\n\t// \t// If the shape has a fixed width, set it to autoSize.\n\t// \tif (!shape.props.autoSize) {\n\t// \t\treturn {\n\t// \t\t\tid: shape.id,\n\t// \t\t\ttype: shape.type,\n\t// \t\t\tprops: {\n\t// \t\t\t\tautoSize: true,\n\t// \t\t\t},\n\t// \t\t}\n\t// \t}\n\t// \t// If the shape is scaled, reset the scale to 1.\n\t// \tif (shape.props.scale !== 1) {\n\t// \t\treturn {\n\t// \t\t\tid: shape.id,\n\t// \t\t\ttype: shape.type,\n\t// \t\t\tprops: {\n\t// \t\t\t\tscale: 1,\n\t// \t\t\t},\n\t// \t\t}\n\t// \t}\n\t// }\n}\n\nfunction getTextSize(editor: Editor, props: TLTextShape['props']) {\n\tconst { font, richText, autoSize, size, w } = props\n\n\tconst minWidth = autoSize ? 16 : Math.max(16, w)\n\tconst fontSize = FONT_SIZES[size]\n\n\tconst cw = autoSize\n\t\t? null\n\t\t: // `measureText` floors the number so we need to do the same here to avoid issues.\n\t\t\tMath.floor(Math.max(minWidth, w))\n\n\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\tconst result = editor.textMeasure.measureHtml(html, {\n\t\t...TEXT_PROPS,\n\t\tfontFamily: FONT_FAMILIES[font],\n\t\tfontSize: fontSize,\n\t\tmaxWidth: cw,\n\t})\n\n\t// If we're autosizing the measureText will essentially `Math.floor`\n\t// the numbers so `19` rather than `19.3`, this means we must +1 to\n\t// whatever we get to avoid wrapping.\n\tif (autoSize) {\n\t\tresult.w += 1\n\t}\n\n\treturn {\n\t\twidth: Math.max(minWidth, result.w),\n\t\theight: Math.max(fontSize, result.h),\n\t}\n}\n\nfunction useTextShapeKeydownHandler(id: TLShapeId) {\n\tconst editor = useEditor()\n\n\treturn useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (editor.getEditingShapeId() !== id) return\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase 'Enter': {\n\t\t\t\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\t\t\t\teditor.complete()\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, id]\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBox,\n\tEditor,\n\tRectangle2d,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLGeometryOpts,\n\tTLResizeInfo,\n\tTLShapeId,\n\tTLTextShape,\n\tVec,\n\tcreateComputedCache,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tisEqual,\n\tresizeScaled,\n\ttextShapeMigrations,\n\ttextShapeProps,\n\ttoDomPrecision,\n\ttoRichText,\n\tuseEditor,\n} from '@tldraw/editor'\nimport { useCallback } from 'react'\nimport {\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport { FONT_FAMILIES, FONT_SIZES, TEXT_PROPS } from '../shared/default-shape-constants'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\nconst sizeCache = createComputedCache(\n\t'text size',\n\t(editor: Editor, shape: TLTextShape) => {\n\t\teditor.fonts.trackFontsForShape(shape)\n\t\treturn getTextSize(editor, shape.props)\n\t},\n\t{ areRecordsEqual: (a, b) => a.props === b.props }\n)\n/** @public */\nexport interface TextShapeOptions {\n\t/** How much addition padding should be added to the horizontal geometry of the shape when binding to an arrow? */\n\textraArrowHorizontalPadding: number\n}\n\n/** @public */\nexport class TextShapeUtil extends ShapeUtil<TLTextShape> {\n\tstatic override type = 'text' as const\n\tstatic override props = textShapeProps\n\tstatic override migrations = textShapeMigrations\n\n\toverride options: TextShapeOptions = {\n\t\textraArrowHorizontalPadding: 10,\n\t}\n\n\tgetDefaultProps(): TLTextShape['props'] {\n\t\treturn {\n\t\t\tcolor: 'black',\n\t\t\tsize: 'm',\n\t\t\tw: 8,\n\t\t\tfont: 'draw',\n\t\t\ttextAlign: 'start',\n\t\t\tautoSize: true,\n\t\t\tscale: 1,\n\t\t\trichText: toRichText(''),\n\t\t}\n\t}\n\n\tgetMinDimensions(shape: TLTextShape) {\n\t\treturn sizeCache.get(this.editor, shape.id)!\n\t}\n\n\tgetGeometry(shape: TLTextShape, opts: TLGeometryOpts) {\n\t\tconst { scale } = shape.props\n\t\tconst { width, height } = this.getMinDimensions(shape)!\n\t\tconst context = opts?.context ?? 'none'\n\t\treturn new Rectangle2d({\n\t\t\tx:\n\t\t\t\t(context === '@tldraw/arrow-without-arrowhead'\n\t\t\t\t\t? -this.options.extraArrowHorizontalPadding\n\t\t\t\t\t: 0) * scale,\n\t\t\twidth:\n\t\t\t\t(width +\n\t\t\t\t\t(context === '@tldraw/arrow-without-arrowhead'\n\t\t\t\t\t\t? this.options.extraArrowHorizontalPadding * 2\n\t\t\t\t\t\t: 0)) *\n\t\t\t\tscale,\n\t\t\theight: height * scale,\n\t\t\tisFilled: true,\n\t\t\tisLabel: true,\n\t\t})\n\t}\n\n\toverride getFontFaces(shape: TLTextShape) {\n\t\t// no need for an empty rich text check here\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\toverride getText(shape: TLTextShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride isAspectRatioLocked() {\n\t\treturn true\n\t} // WAIT NO THIS IS HARD CODED IN THE RESIZE HANDLER\n\n\tcomponent(shape: TLTextShape) {\n\t\tconst {\n\t\t\tid,\n\t\t\tprops: { font, size, richText, color, scale, textAlign },\n\t\t} = shape\n\n\t\tconst { width, height } = this.getMinDimensions(shape)\n\t\tconst isSelected = shape.id === this.editor.getOnlySelectedShapeId()\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst handleKeyDown = useTextShapeKeydownHandler(id)\n\n\t\treturn (\n\t\t\t<RichTextLabel\n\t\t\t\tshapeId={id}\n\t\t\t\tclassNamePrefix=\"tl-text-shape\"\n\t\t\t\ttype=\"text\"\n\t\t\t\tfont={font}\n\t\t\t\tfontSize={FONT_SIZES[size]}\n\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\talign={textAlign}\n\t\t\t\tverticalAlign=\"middle\"\n\t\t\t\trichText={richText}\n\t\t\t\tlabelColor={theme[color].solid}\n\t\t\t\tisSelected={isSelected}\n\t\t\t\ttextWidth={width}\n\t\t\t\ttextHeight={height}\n\t\t\t\tstyle={{\n\t\t\t\t\ttransform: `scale(${scale})`,\n\t\t\t\t\ttransformOrigin: 'top left',\n\t\t\t\t}}\n\t\t\t\twrap\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t/>\n\t\t)\n\t}\n\n\tindicator(shape: TLTextShape) {\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\t\tconst editor = useEditor()\n\t\tif (shape.props.autoSize && editor.getEditingShapeId() === shape.id) return null\n\t\treturn <rect width={toDomPrecision(bounds.width)} height={toDomPrecision(bounds.height)} />\n\t}\n\n\toverride toSvg(shape: TLTextShape, ctx: SvgExportContext) {\n\t\tconst bounds = this.editor.getShapeGeometry(shape).bounds\n\t\tconst width = bounds.width / (shape.props.scale ?? 1)\n\t\tconst height = bounds.height / (shape.props.scale ?? 1)\n\n\t\tconst theme = getDefaultColorTheme(ctx)\n\n\t\tconst exportBounds = new Box(0, 0, width, height)\n\t\treturn (\n\t\t\t<RichTextSVG\n\t\t\t\tfontSize={FONT_SIZES[shape.props.size]}\n\t\t\t\tfont={shape.props.font}\n\t\t\t\talign={shape.props.textAlign}\n\t\t\t\tverticalAlign=\"middle\"\n\t\t\t\trichText={shape.props.richText}\n\t\t\t\tlabelColor={theme[shape.props.color].solid}\n\t\t\t\tbounds={exportBounds}\n\t\t\t\tpadding={0}\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride onResize(shape: TLTextShape, info: TLResizeInfo<TLTextShape>) {\n\t\tconst { newPoint, initialBounds, initialShape, scaleX, handle } = info\n\n\t\tif (info.mode === 'scale_shape' || (handle !== 'right' && handle !== 'left')) {\n\t\t\treturn {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\t...resizeScaled(shape, info),\n\t\t\t}\n\t\t} else {\n\t\t\tconst nextWidth = Math.max(1, Math.abs(initialBounds.width * scaleX))\n\t\t\tconst { x, y } =\n\t\t\t\tscaleX < 0 ? Vec.Sub(newPoint, Vec.FromAngle(shape.rotation).mul(nextWidth)) : newPoint\n\n\t\t\treturn {\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\tprops: {\n\t\t\t\t\tw: nextWidth / initialShape.props.scale,\n\t\t\t\t\tautoSize: false,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onEditEnd(shape: TLTextShape) {\n\t\t// todo: find a way to check if the rich text has any nodes that aren't empty spaces\n\t\tconst trimmedText = renderPlaintextFromRichText(this.editor, shape.props.richText).trimEnd()\n\n\t\tif (trimmedText.length === 0) {\n\t\t\tthis.editor.deleteShapes([shape.id])\n\t\t}\n\t}\n\n\toverride onBeforeUpdate(prev: TLTextShape, next: TLTextShape) {\n\t\tif (!next.props.autoSize) return\n\n\t\tconst styleDidChange =\n\t\t\tprev.props.size !== next.props.size ||\n\t\t\tprev.props.textAlign !== next.props.textAlign ||\n\t\t\tprev.props.font !== next.props.font ||\n\t\t\t(prev.props.scale !== 1 && next.props.scale === 1)\n\n\t\tconst textDidChange = !isEqual(prev.props.richText, next.props.richText)\n\n\t\t// Only update position if either changed\n\t\tif (!styleDidChange && !textDidChange) return\n\n\t\t// Might return a cached value for the bounds\n\t\tconst boundsA = this.getMinDimensions(prev)\n\n\t\t// Will always be a fresh call to getTextSize\n\t\tconst boundsB = getTextSize(this.editor, next.props)\n\n\t\tconst wA = boundsA.width * prev.props.scale\n\t\tconst hA = boundsA.height * prev.props.scale\n\t\tconst wB = boundsB.width * next.props.scale\n\t\tconst hB = boundsB.height * next.props.scale\n\n\t\tlet delta: Vec | undefined\n\n\t\tswitch (next.props.textAlign) {\n\t\t\tcase 'middle': {\n\t\t\t\tdelta = new Vec((wB - wA) / 2, textDidChange ? 0 : (hB - hA) / 2)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'end': {\n\t\t\t\tdelta = new Vec(wB - wA, textDidChange ? 0 : (hB - hA) / 2)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (textDidChange) break\n\t\t\t\tdelta = new Vec(0, (hB - hA) / 2)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif (delta) {\n\t\t\t// account for shape rotation when writing text:\n\t\t\tdelta.rot(next.rotation)\n\t\t\tconst { x, y } = next\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tx: x - delta.x,\n\t\t\t\ty: y - delta.y,\n\t\t\t\tprops: { ...next.props, w: wB },\n\t\t\t}\n\t\t} else {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: { ...next.props, w: wB },\n\t\t\t}\n\t\t}\n\t}\n\n\t// \ttodo: The edge doubleclicking feels like a mistake more often than\n\t// not, especially on multiline text. Removed June 16 2024\n\n\t// override onDoubleClickEdge = (shape: TLTextShape) => {\n\t// \t// If the shape has a fixed width, set it to autoSize.\n\t// \tif (!shape.props.autoSize) {\n\t// \t\treturn {\n\t// \t\t\tid: shape.id,\n\t// \t\t\ttype: shape.type,\n\t// \t\t\tprops: {\n\t// \t\t\t\tautoSize: true,\n\t// \t\t\t},\n\t// \t\t}\n\t// \t}\n\t// \t// If the shape is scaled, reset the scale to 1.\n\t// \tif (shape.props.scale !== 1) {\n\t// \t\treturn {\n\t// \t\t\tid: shape.id,\n\t// \t\t\ttype: shape.type,\n\t// \t\t\tprops: {\n\t// \t\t\t\tscale: 1,\n\t// \t\t\t},\n\t// \t\t}\n\t// \t}\n\t// }\n}\n\nfunction getTextSize(editor: Editor, props: TLTextShape['props']) {\n\tconst { font, richText, size, w } = props\n\n\tconst minWidth = 16\n\tconst fontSize = FONT_SIZES[size]\n\n\tconst maybeFixedWidth = props.autoSize ? null : Math.max(minWidth, Math.floor(w))\n\n\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\tconst result = editor.textMeasure.measureHtml(html, {\n\t\t...TEXT_PROPS,\n\t\tfontFamily: FONT_FAMILIES[font],\n\t\tfontSize: fontSize,\n\t\tmaxWidth: maybeFixedWidth,\n\t})\n\n\t// If we're autosizing the measureText will essentially `Math.floor`\n\t// the numbers so `19` rather than `19.3`, this means we must +1 to\n\t// whatever we get to avoid wrapping.\n\treturn {\n\t\twidth: maybeFixedWidth ?? Math.max(minWidth, result.w + 1),\n\t\theight: Math.max(fontSize, result.h),\n\t}\n}\n\nfunction useTextShapeKeydownHandler(id: TLShapeId) {\n\tconst editor = useEditor()\n\n\treturn useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (editor.getEditingShapeId() !== id) return\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase 'Enter': {\n\t\t\t\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\t\t\t\teditor.complete()\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, id]\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/styles.tsx"],
4
- "sourcesContent": ["/** @public */\nexport type StyleValuesForUi<T> = readonly {\n\treadonly value: T\n\treadonly icon: string\n}[]\n\n// todo: default styles prop?\nexport const STYLES = {\n\tcolor: [\n\t\t{ value: 'black', icon: 'color' },\n\t\t{ value: 'grey', icon: 'color' },\n\t\t{ value: 'light-violet', icon: 'color' },\n\t\t{ value: 'violet', icon: 'color' },\n\t\t{ value: 'blue', icon: 'color' },\n\t\t{ value: 'light-blue', icon: 'color' },\n\t\t{ value: 'yellow', icon: 'color' },\n\t\t{ value: 'orange', icon: 'color' },\n\t\t{ value: 'green', icon: 'color' },\n\t\t{ value: 'light-green', icon: 'color' },\n\t\t{ value: 'light-red', icon: 'color' },\n\t\t{ value: 'red', icon: 'color' },\n\t],\n\tfill: [\n\t\t{ value: 'none', icon: 'fill-none' },\n\t\t{ value: 'semi', icon: 'fill-semi' },\n\t\t{ value: 'solid', icon: 'fill-solid' },\n\t\t{ value: 'pattern', icon: 'fill-pattern' },\n\t\t// { value: 'fill', icon: 'fill-fill' },\n\t],\n\tdash: [\n\t\t{ value: 'draw', icon: 'dash-draw' },\n\t\t{ value: 'dashed', icon: 'dash-dashed' },\n\t\t{ value: 'dotted', icon: 'dash-dotted' },\n\t\t{ value: 'solid', icon: 'dash-solid' },\n\t],\n\tsize: [\n\t\t{ value: 's', icon: 'size-small' },\n\t\t{ value: 'm', icon: 'size-medium' },\n\t\t{ value: 'l', icon: 'size-large' },\n\t\t{ value: 'xl', icon: 'size-extra-large' },\n\t],\n\tfont: [\n\t\t{ value: 'draw', icon: 'font-draw' },\n\t\t{ value: 'sans', icon: 'font-sans' },\n\t\t{ value: 'serif', icon: 'font-serif' },\n\t\t{ value: 'mono', icon: 'font-mono' },\n\t],\n\ttextAlign: [\n\t\t{ value: 'start', icon: 'text-align-left' },\n\t\t{ value: 'middle', icon: 'text-align-center' },\n\t\t{ value: 'end', icon: 'text-align-right' },\n\t],\n\thorizontalAlign: [\n\t\t{ value: 'start', icon: 'horizontal-align-start' },\n\t\t{ value: 'middle', icon: 'horizontal-align-middle' },\n\t\t{ value: 'end', icon: 'horizontal-align-end' },\n\t],\n\tverticalAlign: [\n\t\t{ value: 'start', icon: 'vertical-align-start' },\n\t\t{ value: 'middle', icon: 'vertical-align-middle' },\n\t\t{ value: 'end', icon: 'vertical-align-end' },\n\t],\n\tgeo: [\n\t\t{ value: 'rectangle', icon: 'geo-rectangle' },\n\t\t{ value: 'ellipse', icon: 'geo-ellipse' },\n\t\t{ value: 'triangle', icon: 'geo-triangle' },\n\t\t{ value: 'diamond', icon: 'geo-diamond' },\n\t\t{ value: 'star', icon: 'geo-star' },\n\t\t{ value: 'pentagon', icon: 'geo-pentagon' },\n\t\t{ value: 'hexagon', icon: 'geo-hexagon' },\n\t\t{ value: 'octagon', icon: 'geo-octagon' },\n\t\t{ value: 'rhombus', icon: 'geo-rhombus' },\n\t\t{ value: 'rhombus-2', icon: 'geo-rhombus-2' },\n\t\t{ value: 'oval', icon: 'geo-oval' },\n\t\t{ value: 'trapezoid', icon: 'geo-trapezoid' },\n\t\t{ value: 'arrow-left', icon: 'geo-arrow-left' },\n\t\t{ value: 'arrow-up', icon: 'geo-arrow-up' },\n\t\t{ value: 'arrow-down', icon: 'geo-arrow-down' },\n\t\t{ value: 'arrow-right', icon: 'geo-arrow-right' },\n\t\t{ value: 'cloud', icon: 'geo-cloud' },\n\t\t{ value: 'x-box', icon: 'geo-x-box' },\n\t\t{ value: 'check-box', icon: 'geo-check-box' },\n\t\t{ value: 'heart', icon: 'geo-heart' },\n\t],\n\tarrowKind: [\n\t\t{ value: 'arc', icon: 'arrow-arc' },\n\t\t{ value: 'elbow', icon: 'arrow-elbow' },\n\t],\n\tarrowheadStart: [\n\t\t{ value: 'none', icon: 'arrowhead-none' },\n\t\t{ value: 'arrow', icon: 'arrowhead-arrow' },\n\t\t{ value: 'triangle', icon: 'arrowhead-triangle' },\n\t\t{ value: 'square', icon: 'arrowhead-square' },\n\t\t{ value: 'dot', icon: 'arrowhead-dot' },\n\t\t{ value: 'diamond', icon: 'arrowhead-diamond' },\n\t\t{ value: 'inverted', icon: 'arrowhead-triangle-inverted' },\n\t\t{ value: 'bar', icon: 'arrowhead-bar' },\n\t],\n\tarrowheadEnd: [\n\t\t{ value: 'none', icon: 'arrowhead-none' },\n\t\t{ value: 'arrow', icon: 'arrowhead-arrow' },\n\t\t{ value: 'triangle', icon: 'arrowhead-triangle' },\n\t\t{ value: 'square', icon: 'arrowhead-square' },\n\t\t{ value: 'dot', icon: 'arrowhead-dot' },\n\t\t{ value: 'diamond', icon: 'arrowhead-diamond' },\n\t\t{ value: 'inverted', icon: 'arrowhead-triangle-inverted' },\n\t\t{ value: 'bar', icon: 'arrowhead-bar' },\n\t],\n\tspline: [\n\t\t{ value: 'line', icon: 'spline-line' },\n\t\t{ value: 'cubic', icon: 'spline-cubic' },\n\t],\n} as const satisfies Record<string, StyleValuesForUi<string>>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { TLUiIconJsx } from './ui/components/primitives/TldrawUiIcon'\n\n/** @public */\nexport type StyleValuesForUi<T> = readonly {\n\treadonly value: T\n\treadonly icon: string | TLUiIconJsx\n}[]\n\n// todo: default styles prop?\nexport const STYLES = {\n\tcolor: [\n\t\t{ value: 'black', icon: 'color' },\n\t\t{ value: 'grey', icon: 'color' },\n\t\t{ value: 'light-violet', icon: 'color' },\n\t\t{ value: 'violet', icon: 'color' },\n\t\t{ value: 'blue', icon: 'color' },\n\t\t{ value: 'light-blue', icon: 'color' },\n\t\t{ value: 'yellow', icon: 'color' },\n\t\t{ value: 'orange', icon: 'color' },\n\t\t{ value: 'green', icon: 'color' },\n\t\t{ value: 'light-green', icon: 'color' },\n\t\t{ value: 'light-red', icon: 'color' },\n\t\t{ value: 'red', icon: 'color' },\n\t],\n\tfill: [\n\t\t{ value: 'none', icon: 'fill-none' },\n\t\t{ value: 'semi', icon: 'fill-semi' },\n\t\t{ value: 'solid', icon: 'fill-solid' },\n\t\t{ value: 'pattern', icon: 'fill-pattern' },\n\t\t// { value: 'fill', icon: 'fill-fill' },\n\t],\n\tdash: [\n\t\t{ value: 'draw', icon: 'dash-draw' },\n\t\t{ value: 'dashed', icon: 'dash-dashed' },\n\t\t{ value: 'dotted', icon: 'dash-dotted' },\n\t\t{ value: 'solid', icon: 'dash-solid' },\n\t],\n\tsize: [\n\t\t{ value: 's', icon: 'size-small' },\n\t\t{ value: 'm', icon: 'size-medium' },\n\t\t{ value: 'l', icon: 'size-large' },\n\t\t{ value: 'xl', icon: 'size-extra-large' },\n\t],\n\tfont: [\n\t\t{ value: 'draw', icon: 'font-draw' },\n\t\t{ value: 'sans', icon: 'font-sans' },\n\t\t{ value: 'serif', icon: 'font-serif' },\n\t\t{ value: 'mono', icon: 'font-mono' },\n\t],\n\ttextAlign: [\n\t\t{ value: 'start', icon: 'text-align-left' },\n\t\t{ value: 'middle', icon: 'text-align-center' },\n\t\t{ value: 'end', icon: 'text-align-right' },\n\t],\n\thorizontalAlign: [\n\t\t{ value: 'start', icon: 'horizontal-align-start' },\n\t\t{ value: 'middle', icon: 'horizontal-align-middle' },\n\t\t{ value: 'end', icon: 'horizontal-align-end' },\n\t],\n\tverticalAlign: [\n\t\t{ value: 'start', icon: 'vertical-align-start' },\n\t\t{ value: 'middle', icon: 'vertical-align-middle' },\n\t\t{ value: 'end', icon: 'vertical-align-end' },\n\t],\n\tgeo: [\n\t\t{ value: 'rectangle', icon: 'geo-rectangle' },\n\t\t{ value: 'ellipse', icon: 'geo-ellipse' },\n\t\t{ value: 'triangle', icon: 'geo-triangle' },\n\t\t{ value: 'diamond', icon: 'geo-diamond' },\n\t\t{ value: 'star', icon: 'geo-star' },\n\t\t{ value: 'pentagon', icon: 'geo-pentagon' },\n\t\t{ value: 'hexagon', icon: 'geo-hexagon' },\n\t\t{ value: 'octagon', icon: 'geo-octagon' },\n\t\t{ value: 'rhombus', icon: 'geo-rhombus' },\n\t\t{ value: 'rhombus-2', icon: 'geo-rhombus-2' },\n\t\t{ value: 'oval', icon: 'geo-oval' },\n\t\t{ value: 'trapezoid', icon: 'geo-trapezoid' },\n\t\t{ value: 'arrow-left', icon: 'geo-arrow-left' },\n\t\t{ value: 'arrow-up', icon: 'geo-arrow-up' },\n\t\t{ value: 'arrow-down', icon: 'geo-arrow-down' },\n\t\t{ value: 'arrow-right', icon: 'geo-arrow-right' },\n\t\t{ value: 'cloud', icon: 'geo-cloud' },\n\t\t{ value: 'x-box', icon: 'geo-x-box' },\n\t\t{ value: 'check-box', icon: 'geo-check-box' },\n\t\t{ value: 'heart', icon: 'geo-heart' },\n\t],\n\tarrowKind: [\n\t\t{ value: 'arc', icon: 'arrow-arc' },\n\t\t{ value: 'elbow', icon: 'arrow-elbow' },\n\t],\n\tarrowheadStart: [\n\t\t{ value: 'none', icon: 'arrowhead-none' },\n\t\t{ value: 'arrow', icon: 'arrowhead-arrow' },\n\t\t{ value: 'triangle', icon: 'arrowhead-triangle' },\n\t\t{ value: 'square', icon: 'arrowhead-square' },\n\t\t{ value: 'dot', icon: 'arrowhead-dot' },\n\t\t{ value: 'diamond', icon: 'arrowhead-diamond' },\n\t\t{ value: 'inverted', icon: 'arrowhead-triangle-inverted' },\n\t\t{ value: 'bar', icon: 'arrowhead-bar' },\n\t],\n\tarrowheadEnd: [\n\t\t{ value: 'none', icon: 'arrowhead-none' },\n\t\t{ value: 'arrow', icon: 'arrowhead-arrow' },\n\t\t{ value: 'triangle', icon: 'arrowhead-triangle' },\n\t\t{ value: 'square', icon: 'arrowhead-square' },\n\t\t{ value: 'dot', icon: 'arrowhead-dot' },\n\t\t{ value: 'diamond', icon: 'arrowhead-diamond' },\n\t\t{ value: 'inverted', icon: 'arrowhead-triangle-inverted' },\n\t\t{ value: 'bar', icon: 'arrowhead-bar' },\n\t],\n\tspline: [\n\t\t{ value: 'line', icon: 'spline-line' },\n\t\t{ value: 'cubic', icon: 'spline-cubic' },\n\t],\n} as const satisfies Record<string, StyleValuesForUi<string>>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -269,7 +269,17 @@ function DefaultKeyboardShortcutsDialogContent() {
269
269
  ),
270
270
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiMenuActionItem.TldrawUiMenuActionItem, { actionId: "enlarge-shapes" }),
271
271
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiMenuActionItem.TldrawUiMenuActionItem, { actionId: "shrink-shapes" }),
272
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiMenuActionItem.TldrawUiMenuActionItem, { actionId: "a11y-repeat-shape-announce" })
272
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiMenuActionItem.TldrawUiMenuActionItem, { actionId: "a11y-repeat-shape-announce" }),
273
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
274
+ import_TldrawUiMenuItem.TldrawUiMenuItem,
275
+ {
276
+ id: "a11y-open-keyboard-shortcuts",
277
+ label: "a11y.open-keyboard-shortcuts",
278
+ kbd: "cmd+alt+/",
279
+ onSelect: () => {
280
+ }
281
+ }
282
+ )
273
283
  ] }),
274
284
  showCollaborationUi && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiMenuGroup.TldrawUiMenuGroup, { label: "shortcuts-dialog.collaboration", id: "collaboration", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiMenuActionItem.TldrawUiMenuActionItem, { actionId: "open-cursor-chat" }) })
275
285
  ] });