@tldraw/editor 4.6.0-next.5a871ec02ff3 → 4.6.0-next.6594d48ace27

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 (448) hide show
  1. package/dist-cjs/index.d.ts +1316 -285
  2. package/dist-cjs/index.js +31 -26
  3. package/dist-cjs/index.js.map +3 -3
  4. package/dist-cjs/lib/TldrawEditor.js +62 -14
  5. package/dist-cjs/lib/TldrawEditor.js.map +3 -3
  6. package/dist-cjs/lib/components/MenuClickCapture.js +99 -38
  7. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  8. package/dist-cjs/lib/components/default-components/CanvasOverlays.js +180 -0
  9. package/dist-cjs/lib/components/default-components/CanvasOverlays.js.map +7 -0
  10. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +33 -236
  11. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +3 -3
  12. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
  13. package/dist-cjs/lib/config/{createTLUser.js → createTLCurrentUser.js} +9 -9
  14. package/dist-cjs/lib/config/createTLCurrentUser.js.map +7 -0
  15. package/dist-cjs/lib/config/createTLStore.js +31 -1
  16. package/dist-cjs/lib/config/createTLStore.js.map +2 -2
  17. package/dist-cjs/lib/{components/default-components/DefaultShapeIndicatorErrorFallback.js → config/defaultAssets.js} +17 -9
  18. package/dist-cjs/lib/config/defaultAssets.js.map +7 -0
  19. package/dist-cjs/lib/config/defaultShapes.js.map +2 -2
  20. package/dist-cjs/lib/editor/Editor.js +921 -386
  21. package/dist-cjs/lib/editor/Editor.js.map +3 -3
  22. package/dist-cjs/lib/editor/assets/AssetUtil.js +67 -0
  23. package/dist-cjs/lib/editor/assets/AssetUtil.js.map +7 -0
  24. package/dist-cjs/lib/editor/bindings/BindingUtil.js +1 -0
  25. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +1 -1
  26. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +26 -64
  27. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  28. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +98 -0
  29. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +7 -0
  30. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +2 -1
  31. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +2 -2
  32. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +15 -53
  33. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +1 -1
  34. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +2 -0
  35. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
  36. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +2 -0
  37. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +1 -1
  38. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +83 -112
  39. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
  40. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js +80 -0
  41. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js.map +7 -0
  42. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js +466 -0
  43. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js.map +7 -0
  44. package/dist-cjs/lib/{components/default-components/DefaultHandles.js → editor/managers/PerformanceManager/perf-types.js} +3 -14
  45. package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js.map +7 -0
  46. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +1 -0
  47. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +1 -1
  48. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +22 -56
  49. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +2 -2
  50. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js +12 -52
  51. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
  52. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +21 -57
  53. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
  54. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +5 -4
  55. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +2 -2
  56. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +103 -30
  57. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
  58. package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js +107 -0
  59. package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js.map +7 -0
  60. package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +600 -0
  61. package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +7 -0
  62. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +17 -55
  63. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +1 -1
  64. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +65 -72
  65. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  66. package/dist-cjs/lib/editor/overlays/OverlayManager.js +154 -0
  67. package/dist-cjs/lib/editor/overlays/OverlayManager.js.map +7 -0
  68. package/dist-cjs/lib/editor/overlays/OverlayUtil.js +92 -0
  69. package/dist-cjs/lib/editor/overlays/OverlayUtil.js.map +7 -0
  70. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +161 -0
  71. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
  72. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +76 -0
  73. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +7 -0
  74. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +35 -20
  75. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  76. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +33 -3
  77. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  78. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js +6 -0
  79. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
  80. package/dist-cjs/lib/editor/tools/StateNode.js +15 -17
  81. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  82. package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
  83. package/dist-cjs/lib/editor/types/clipboard-types.js.map +1 -1
  84. package/dist-cjs/lib/editor/types/event-types.js.map +2 -2
  85. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  86. package/dist-cjs/lib/exports/ExportDelay.js +13 -53
  87. package/dist-cjs/lib/exports/ExportDelay.js.map +1 -1
  88. package/dist-cjs/lib/exports/FontEmbedder.js +14 -57
  89. package/dist-cjs/lib/exports/FontEmbedder.js.map +1 -1
  90. package/dist-cjs/lib/exports/StyleEmbedder.js +2 -1
  91. package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
  92. package/dist-cjs/lib/exports/fetchCache.js +1 -1
  93. package/dist-cjs/lib/exports/fetchCache.js.map +2 -2
  94. package/dist-cjs/lib/exports/getSvgJsx.js +14 -8
  95. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  96. package/dist-cjs/lib/globals/environment.js +18 -1
  97. package/dist-cjs/lib/globals/environment.js.map +2 -2
  98. package/dist-cjs/lib/hooks/EditorComponentsContext.js.map +2 -2
  99. package/dist-cjs/lib/hooks/useCanvasEvents.js +25 -4
  100. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  101. package/dist-cjs/lib/hooks/{useIsDarkMode.js → useColorMode.js} +14 -10
  102. package/dist-cjs/lib/hooks/useColorMode.js.map +7 -0
  103. package/dist-cjs/lib/hooks/useCursor.js +3 -7
  104. package/dist-cjs/lib/hooks/useCursor.js.map +2 -2
  105. package/dist-cjs/lib/hooks/useDarkMode.js +4 -4
  106. package/dist-cjs/lib/hooks/useDarkMode.js.map +2 -2
  107. package/dist-cjs/lib/hooks/useEditorComponents.js +0 -28
  108. package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
  109. package/dist-cjs/lib/hooks/useGestureEvents.js +171 -127
  110. package/dist-cjs/lib/hooks/useGestureEvents.js.map +3 -3
  111. package/dist-cjs/lib/hooks/useLocalStore.js.map +2 -2
  112. package/dist-cjs/lib/hooks/usePeerIds.js +1 -36
  113. package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
  114. package/dist-cjs/lib/hooks/useShapeCulling.js +2 -1
  115. package/dist-cjs/lib/hooks/useShapeCulling.js.map +2 -2
  116. package/dist-cjs/lib/options.js +4 -0
  117. package/dist-cjs/lib/options.js.map +2 -2
  118. package/dist-cjs/lib/primitives/Box.js +26 -26
  119. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  120. package/dist-cjs/lib/primitives/Vec.js +4 -1
  121. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  122. package/dist-cjs/lib/primitives/geometry/Arc2d.js +2 -2
  123. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  124. package/dist-cjs/lib/primitives/geometry/Circle2d.js +3 -2
  125. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  126. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js +1 -1
  127. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +1 -1
  128. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +4 -3
  129. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  130. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +12 -9
  131. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  132. package/dist-cjs/lib/primitives/geometry/Polyline2d.js +2 -2
  133. package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
  134. package/dist-cjs/lib/primitives/geometry/Stadium2d.js +2 -1
  135. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
  136. package/dist-cjs/lib/utils/EditorAtom.js +2 -0
  137. package/dist-cjs/lib/utils/EditorAtom.js.map +1 -1
  138. package/dist-cjs/lib/utils/SharedStylesMap.js +1 -1
  139. package/dist-cjs/lib/utils/SharedStylesMap.js.map +1 -1
  140. package/dist-cjs/lib/utils/getSvgPathFromPoints.js.map +2 -2
  141. package/dist-cjs/lib/utils/reparenting.js +2 -1
  142. package/dist-cjs/lib/utils/reparenting.js.map +2 -2
  143. package/dist-cjs/lib/utils/richText.js.map +2 -2
  144. package/dist-cjs/lib/utils/runtime.js +2 -1
  145. package/dist-cjs/lib/utils/runtime.js.map +2 -2
  146. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +8 -2
  147. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  148. package/dist-cjs/lib/utils/sync/hardReset.js +0 -8
  149. package/dist-cjs/lib/utils/sync/hardReset.js.map +2 -2
  150. package/dist-cjs/version.js +3 -3
  151. package/dist-cjs/version.js.map +1 -1
  152. package/dist-esm/index.d.mts +1316 -285
  153. package/dist-esm/index.mjs +44 -48
  154. package/dist-esm/index.mjs.map +2 -2
  155. package/dist-esm/lib/TldrawEditor.mjs +65 -14
  156. package/dist-esm/lib/TldrawEditor.mjs.map +3 -3
  157. package/dist-esm/lib/components/MenuClickCapture.mjs +100 -39
  158. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  159. package/dist-esm/lib/components/default-components/CanvasOverlays.mjs +160 -0
  160. package/dist-esm/lib/components/default-components/CanvasOverlays.mjs.map +7 -0
  161. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +34 -237
  162. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +3 -3
  163. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
  164. package/dist-esm/lib/config/{createTLUser.mjs → createTLCurrentUser.mjs} +6 -6
  165. package/dist-esm/lib/config/createTLCurrentUser.mjs.map +7 -0
  166. package/dist-esm/lib/config/createTLStore.mjs +37 -2
  167. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  168. package/dist-esm/lib/config/defaultAssets.mjs +16 -0
  169. package/dist-esm/lib/config/defaultAssets.mjs.map +7 -0
  170. package/dist-esm/lib/config/defaultShapes.mjs.map +2 -2
  171. package/dist-esm/lib/editor/Editor.mjs +924 -389
  172. package/dist-esm/lib/editor/Editor.mjs.map +3 -3
  173. package/dist-esm/lib/editor/assets/AssetUtil.mjs +47 -0
  174. package/dist-esm/lib/editor/assets/AssetUtil.mjs.map +7 -0
  175. package/dist-esm/lib/editor/bindings/BindingUtil.mjs +1 -0
  176. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +1 -1
  177. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +26 -64
  178. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  179. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +83 -0
  180. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +7 -0
  181. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +2 -1
  182. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +2 -2
  183. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +15 -53
  184. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +1 -1
  185. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +2 -0
  186. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
  187. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +2 -0
  188. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +1 -1
  189. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +83 -112
  190. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
  191. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs +60 -0
  192. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs.map +7 -0
  193. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs +438 -0
  194. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs.map +7 -0
  195. package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs +1 -0
  196. package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs.map +7 -0
  197. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +1 -0
  198. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +1 -1
  199. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +22 -56
  200. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
  201. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs +12 -52
  202. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
  203. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +21 -57
  204. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
  205. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +5 -4
  206. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +2 -2
  207. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +103 -30
  208. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
  209. package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs +89 -0
  210. package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs.map +7 -0
  211. package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +582 -0
  212. package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +7 -0
  213. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +17 -55
  214. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +1 -1
  215. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +65 -72
  216. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  217. package/dist-esm/lib/editor/overlays/OverlayManager.mjs +136 -0
  218. package/dist-esm/lib/editor/overlays/OverlayManager.mjs.map +7 -0
  219. package/dist-esm/lib/editor/overlays/OverlayUtil.mjs +72 -0
  220. package/dist-esm/lib/editor/overlays/OverlayUtil.mjs.map +7 -0
  221. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +141 -0
  222. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
  223. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +56 -0
  224. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +7 -0
  225. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +35 -20
  226. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  227. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +33 -3
  228. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  229. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs +6 -0
  230. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
  231. package/dist-esm/lib/editor/tools/StateNode.mjs +15 -17
  232. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  233. package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
  234. package/dist-esm/lib/editor/types/event-types.mjs.map +2 -2
  235. package/dist-esm/lib/exports/ExportDelay.mjs +13 -53
  236. package/dist-esm/lib/exports/ExportDelay.mjs.map +1 -1
  237. package/dist-esm/lib/exports/FontEmbedder.mjs +14 -57
  238. package/dist-esm/lib/exports/FontEmbedder.mjs.map +1 -1
  239. package/dist-esm/lib/exports/StyleEmbedder.mjs +2 -1
  240. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
  241. package/dist-esm/lib/exports/fetchCache.mjs +2 -2
  242. package/dist-esm/lib/exports/fetchCache.mjs.map +2 -2
  243. package/dist-esm/lib/exports/getSvgJsx.mjs +14 -11
  244. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  245. package/dist-esm/lib/globals/environment.mjs +18 -1
  246. package/dist-esm/lib/globals/environment.mjs.map +2 -2
  247. package/dist-esm/lib/hooks/EditorComponentsContext.mjs.map +2 -2
  248. package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -4
  249. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  250. package/dist-esm/lib/hooks/useColorMode.mjs +19 -0
  251. package/dist-esm/lib/hooks/useColorMode.mjs.map +7 -0
  252. package/dist-esm/lib/hooks/useCursor.mjs +3 -7
  253. package/dist-esm/lib/hooks/useCursor.mjs.map +2 -2
  254. package/dist-esm/lib/hooks/useDarkMode.mjs +4 -4
  255. package/dist-esm/lib/hooks/useDarkMode.mjs.map +2 -2
  256. package/dist-esm/lib/hooks/useEditorComponents.mjs +0 -28
  257. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  258. package/dist-esm/lib/hooks/useGestureEvents.mjs +171 -127
  259. package/dist-esm/lib/hooks/useGestureEvents.mjs.map +3 -3
  260. package/dist-esm/lib/hooks/useLocalStore.mjs.map +2 -2
  261. package/dist-esm/lib/hooks/usePeerIds.mjs +2 -40
  262. package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
  263. package/dist-esm/lib/hooks/useShapeCulling.mjs +2 -1
  264. package/dist-esm/lib/hooks/useShapeCulling.mjs.map +2 -2
  265. package/dist-esm/lib/options.mjs +4 -0
  266. package/dist-esm/lib/options.mjs.map +2 -2
  267. package/dist-esm/lib/primitives/Box.mjs +26 -26
  268. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  269. package/dist-esm/lib/primitives/Vec.mjs +4 -1
  270. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  271. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
  272. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  273. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +3 -2
  274. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  275. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs +1 -1
  276. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +1 -1
  277. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +4 -3
  278. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  279. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +12 -9
  280. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  281. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs +2 -2
  282. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
  283. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +2 -1
  284. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
  285. package/dist-esm/lib/utils/EditorAtom.mjs +2 -0
  286. package/dist-esm/lib/utils/EditorAtom.mjs.map +1 -1
  287. package/dist-esm/lib/utils/SharedStylesMap.mjs +1 -1
  288. package/dist-esm/lib/utils/SharedStylesMap.mjs.map +1 -1
  289. package/dist-esm/lib/utils/getSvgPathFromPoints.mjs.map +2 -2
  290. package/dist-esm/lib/utils/reparenting.mjs +2 -1
  291. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  292. package/dist-esm/lib/utils/richText.mjs.map +2 -2
  293. package/dist-esm/lib/utils/runtime.mjs +2 -1
  294. package/dist-esm/lib/utils/runtime.mjs.map +2 -2
  295. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +8 -2
  296. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  297. package/dist-esm/lib/utils/sync/hardReset.mjs +0 -8
  298. package/dist-esm/lib/utils/sync/hardReset.mjs.map +2 -2
  299. package/dist-esm/version.mjs +3 -3
  300. package/dist-esm/version.mjs.map +1 -1
  301. package/editor.css +16 -256
  302. package/package.json +7 -8
  303. package/src/index.ts +58 -52
  304. package/src/lib/TldrawEditor.tsx +108 -20
  305. package/src/lib/components/MenuClickCapture.tsx +129 -49
  306. package/src/lib/components/default-components/CanvasOverlays.tsx +208 -0
  307. package/src/lib/components/default-components/DefaultCanvas.tsx +38 -310
  308. package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -0
  309. package/src/lib/config/TLEditorSnapshot.test.ts +1 -1
  310. package/src/lib/config/{createTLUser.ts → createTLCurrentUser.ts} +9 -9
  311. package/src/lib/config/createTLStore.ts +58 -3
  312. package/src/lib/config/defaultAssets.ts +19 -0
  313. package/src/lib/config/defaultShapes.ts +1 -1
  314. package/src/lib/editor/Editor.test.ts +3 -1
  315. package/src/lib/editor/Editor.ts +610 -69
  316. package/src/lib/editor/assets/AssetUtil.ts +85 -0
  317. package/src/lib/editor/managers/ClickManager/ClickManager.ts +1 -1
  318. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +98 -0
  319. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +1 -1
  320. package/src/lib/editor/managers/FontManager/FontManager.test.ts +9 -2
  321. package/src/lib/editor/managers/FontManager/FontManager.ts +1 -67
  322. package/src/lib/editor/managers/InputsManager/InputsManager.ts +42 -30
  323. package/src/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.ts +82 -0
  324. package/src/lib/editor/managers/PerformanceManager/PerformanceManager.test.ts +522 -0
  325. package/src/lib/editor/managers/PerformanceManager/PerformanceManager.ts +583 -0
  326. package/src/lib/editor/managers/PerformanceManager/perf-types.ts +196 -0
  327. package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +1 -1
  328. package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +1 -1
  329. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +13 -2
  330. package/src/lib/editor/managers/SnapManager/SnapManager.ts +1 -1
  331. package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +5 -5
  332. package/src/lib/editor/managers/TextManager/TextManager.test.ts +18 -4
  333. package/src/lib/editor/managers/TextManager/TextManager.ts +140 -34
  334. package/src/lib/editor/managers/ThemeManager/ThemeManager.ts +116 -0
  335. package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +619 -0
  336. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +25 -31
  337. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +7 -5
  338. package/src/lib/editor/overlays/OverlayManager.ts +183 -0
  339. package/src/lib/editor/overlays/OverlayUtil.ts +143 -0
  340. package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +216 -0
  341. package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +123 -0
  342. package/src/lib/editor/shapes/ShapeUtil.ts +67 -30
  343. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +41 -4
  344. package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +7 -0
  345. package/src/lib/editor/tools/StateNode.ts +16 -18
  346. package/src/lib/editor/types/SvgExportContext.tsx +5 -0
  347. package/src/lib/editor/types/clipboard-types.ts +2 -1
  348. package/src/lib/editor/types/event-types.ts +2 -0
  349. package/src/lib/editor/types/external-content.ts +1 -0
  350. package/src/lib/exports/StyleEmbedder.ts +1 -1
  351. package/src/lib/exports/fetchCache.ts +2 -4
  352. package/src/lib/exports/getSvgJsx.test.ts +3 -1
  353. package/src/lib/exports/getSvgJsx.tsx +24 -17
  354. package/src/lib/globals/environment.ts +18 -0
  355. package/src/lib/hooks/EditorComponentsContext.tsx +0 -27
  356. package/src/lib/hooks/useCanvasEvents.ts +40 -3
  357. package/src/lib/hooks/{useIsDarkMode.ts → useColorMode.ts} +9 -5
  358. package/src/lib/hooks/useCursor.ts +3 -7
  359. package/src/lib/hooks/useDarkMode.ts +4 -4
  360. package/src/lib/hooks/useEditorComponents.tsx +1 -29
  361. package/src/lib/hooks/useGestureEvents.ts +240 -168
  362. package/src/lib/hooks/useLocalStore.ts +1 -1
  363. package/src/lib/hooks/usePeerIds.ts +6 -55
  364. package/src/lib/hooks/useShapeCulling.tsx +3 -1
  365. package/src/lib/options.ts +115 -0
  366. package/src/lib/primitives/Box.test.ts +30 -0
  367. package/src/lib/primitives/Box.ts +26 -26
  368. package/src/lib/primitives/Vec.ts +1 -1
  369. package/src/lib/primitives/geometry/Arc2d.ts +2 -2
  370. package/src/lib/primitives/geometry/Circle2d.ts +2 -2
  371. package/src/lib/primitives/geometry/CubicSpline2d.ts +1 -1
  372. package/src/lib/primitives/geometry/Ellipse2d.ts +3 -3
  373. package/src/lib/primitives/geometry/Geometry2d.test.ts +21 -0
  374. package/src/lib/primitives/geometry/Geometry2d.ts +10 -9
  375. package/src/lib/primitives/geometry/Polyline2d.ts +2 -2
  376. package/src/lib/primitives/geometry/Stadium2d.ts +1 -1
  377. package/src/lib/utils/SharedStylesMap.ts +1 -1
  378. package/src/lib/utils/getSvgPathFromPoints.ts +1 -1
  379. package/src/lib/utils/reparenting.ts +6 -2
  380. package/src/lib/utils/richText.ts +1 -1
  381. package/src/lib/utils/runtime.ts +3 -1
  382. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +1 -1
  383. package/src/lib/utils/sync/TLLocalSyncClient.ts +5 -1
  384. package/src/lib/utils/sync/hardReset.ts +0 -8
  385. package/src/version.ts +3 -3
  386. package/dist-cjs/lib/components/LiveCollaborators.js +0 -151
  387. package/dist-cjs/lib/components/LiveCollaborators.js.map +0 -7
  388. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +0 -227
  389. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +0 -7
  390. package/dist-cjs/lib/components/default-components/DefaultBrush.js +0 -38
  391. package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +0 -7
  392. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +0 -71
  393. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +0 -7
  394. package/dist-cjs/lib/components/default-components/DefaultHandle.js +0 -56
  395. package/dist-cjs/lib/components/default-components/DefaultHandle.js.map +0 -7
  396. package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +0 -7
  397. package/dist-cjs/lib/components/default-components/DefaultScribble.js +0 -51
  398. package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +0 -7
  399. package/dist-cjs/lib/components/default-components/DefaultSelectionForeground.js +0 -69
  400. package/dist-cjs/lib/components/default-components/DefaultSelectionForeground.js.map +0 -7
  401. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +0 -107
  402. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +0 -7
  403. package/dist-cjs/lib/components/default-components/DefaultShapeIndicatorErrorFallback.js.map +0 -7
  404. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +0 -101
  405. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +0 -7
  406. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +0 -170
  407. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +0 -7
  408. package/dist-cjs/lib/config/createTLUser.js.map +0 -7
  409. package/dist-cjs/lib/hooks/useIsDarkMode.js.map +0 -7
  410. package/dist-esm/lib/components/LiveCollaborators.mjs +0 -134
  411. package/dist-esm/lib/components/LiveCollaborators.mjs.map +0 -7
  412. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +0 -207
  413. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +0 -7
  414. package/dist-esm/lib/components/default-components/DefaultBrush.mjs +0 -18
  415. package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +0 -7
  416. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +0 -41
  417. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +0 -7
  418. package/dist-esm/lib/components/default-components/DefaultHandle.mjs +0 -26
  419. package/dist-esm/lib/components/default-components/DefaultHandle.mjs.map +0 -7
  420. package/dist-esm/lib/components/default-components/DefaultHandles.mjs +0 -8
  421. package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +0 -7
  422. package/dist-esm/lib/components/default-components/DefaultScribble.mjs +0 -21
  423. package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +0 -7
  424. package/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs +0 -39
  425. package/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs.map +0 -7
  426. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +0 -77
  427. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +0 -7
  428. package/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs +0 -8
  429. package/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs.map +0 -7
  430. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +0 -81
  431. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +0 -7
  432. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +0 -142
  433. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +0 -7
  434. package/dist-esm/lib/config/createTLUser.mjs.map +0 -7
  435. package/dist-esm/lib/hooks/useIsDarkMode.mjs +0 -15
  436. package/dist-esm/lib/hooks/useIsDarkMode.mjs.map +0 -7
  437. package/src/lib/components/LiveCollaborators.tsx +0 -174
  438. package/src/lib/components/default-components/CanvasShapeIndicators.tsx +0 -289
  439. package/src/lib/components/default-components/DefaultBrush.tsx +0 -35
  440. package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +0 -52
  441. package/src/lib/components/default-components/DefaultHandle.tsx +0 -42
  442. package/src/lib/components/default-components/DefaultHandles.tsx +0 -15
  443. package/src/lib/components/default-components/DefaultScribble.tsx +0 -31
  444. package/src/lib/components/default-components/DefaultSelectionForeground.tsx +0 -50
  445. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +0 -104
  446. package/src/lib/components/default-components/DefaultShapeIndicatorErrorFallback.tsx +0 -9
  447. package/src/lib/components/default-components/DefaultShapeIndicators.tsx +0 -116
  448. package/src/lib/components/default-components/DefaultSnapIndictor.tsx +0 -174
@@ -1,8 +1,8 @@
1
- import { Vec } from "../Vec.mjs";
2
1
  import { intersectLineSegmentCircle } from "../intersect.mjs";
3
2
  import { getArcMeasure, getPointInArcT, getPointOnCircle } from "../utils.mjs";
4
- import { Geometry2d } from "./Geometry2d.mjs";
3
+ import { Vec } from "../Vec.mjs";
5
4
  import { getVerticesCountForArcLength } from "./geometry-constants.mjs";
5
+ import { Geometry2d } from "./Geometry2d.mjs";
6
6
  class Arc2d extends Geometry2d {
7
7
  _center;
8
8
  _radius;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Arc2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Arc2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _start: Vec\n\tprivate _end: Vec\n\tprivate _largeArcFlag: number\n\tprivate _sweepFlag: number\n\tprivate _measure: number\n\tprivate _angleStart: number\n\tprivate _angleEnd: number\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tcenter: Vec\n\t\t\tstart: Vec\n\t\t\tend: Vec\n\t\t\tsweepFlag: number\n\t\t\tlargeArcFlag: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isFilled: false, isClosed: false })\n\t\tconst { center, sweepFlag, largeArcFlag, start, end } = config\n\t\tif (start.equals(end)) throw Error(`Arc must have different start and end points.`)\n\n\t\t// ensure that the start and end are clockwise\n\t\tthis._angleStart = Vec.Angle(center, start)\n\t\tthis._angleEnd = Vec.Angle(center, end)\n\t\tthis._radius = Vec.Dist(center, start)\n\t\tthis._measure = getArcMeasure(this._angleStart, this._angleEnd, sweepFlag, largeArcFlag)\n\n\t\tthis._start = start\n\t\tthis._end = end\n\n\t\tthis._sweepFlag = sweepFlag\n\t\tthis._largeArcFlag = largeArcFlag\n\t\tthis._center = center\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_measure: measure,\n\t\t\t_radius: radius,\n\t\t\t_angleEnd: angleEnd,\n\t\t\t_angleStart: angleStart,\n\t\t\t_start: A,\n\t\t\t_end: B,\n\t\t} = this\n\t\tconst t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))\n\t\tif (t <= 0) return A\n\t\tif (t >= 1) return B\n\n\t\t// Inlined: Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t\t// When t is in (0,1), the nearest point is the radial projection of point onto the arc.\n\t\t// Previously this also checked min-distance against A and B, but that's unnecessary when\n\t\t// t is already in range \u2014 the radial projection is always closer.\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst len = Math.sqrt(dx * dx + dy * dy)\n\t\tif (len === 0) return A\n\t\tconst scale = radius / len\n\t\treturn new Vec(_center.x + dx * scale, _center.y + dy * scale)\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_radius: radius,\n\t\t\t_measure: measure,\n\t\t\t_angleStart: angleStart,\n\t\t\t_angleEnd: angleEnd,\n\t\t} = this\n\t\tconst intersection = intersectLineSegmentCircle(A, B, _center, radius)\n\t\tif (intersection === null) return false\n\n\t\treturn intersection.some((p) => {\n\t\t\tconst result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p))\n\t\t\treturn result >= 0 && result <= 1\n\t\t})\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _measure: measure, length, _radius: radius, _angleStart: angleStart } = this\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(Math.abs(length)); i < n + 1; i++) {\n\t\t\tconst t = (i / n) * measure\n\t\t\tconst angle = angleStart + t\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst {\n\t\t\t_start: start,\n\t\t\t_end: end,\n\t\t\t_radius: radius,\n\t\t\t_largeArcFlag: largeArcFlag,\n\t\t\t_sweepFlag: sweepFlag,\n\t\t} = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.toFixed()}`\n\t}\n\n\toverride getLength() {\n\t\treturn Math.abs(this._measure * this._radius)\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { intersectLineSegmentCircle } from '../intersect'\nimport { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'\nimport { Vec, VecLike } from '../Vec'\nimport { getVerticesCountForArcLength } from './geometry-constants'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Arc2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _start: Vec\n\tprivate _end: Vec\n\tprivate _largeArcFlag: number\n\tprivate _sweepFlag: number\n\tprivate _measure: number\n\tprivate _angleStart: number\n\tprivate _angleEnd: number\n\n\tconstructor(\n\t\tconfig: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & {\n\t\t\tcenter: Vec\n\t\t\tstart: Vec\n\t\t\tend: Vec\n\t\t\tsweepFlag: number\n\t\t\tlargeArcFlag: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isFilled: false, isClosed: false })\n\t\tconst { center, sweepFlag, largeArcFlag, start, end } = config\n\t\tif (start.equals(end)) throw Error(`Arc must have different start and end points.`)\n\n\t\t// ensure that the start and end are clockwise\n\t\tthis._angleStart = Vec.Angle(center, start)\n\t\tthis._angleEnd = Vec.Angle(center, end)\n\t\tthis._radius = Vec.Dist(center, start)\n\t\tthis._measure = getArcMeasure(this._angleStart, this._angleEnd, sweepFlag, largeArcFlag)\n\n\t\tthis._start = start\n\t\tthis._end = end\n\n\t\tthis._sweepFlag = sweepFlag\n\t\tthis._largeArcFlag = largeArcFlag\n\t\tthis._center = center\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_measure: measure,\n\t\t\t_radius: radius,\n\t\t\t_angleEnd: angleEnd,\n\t\t\t_angleStart: angleStart,\n\t\t\t_start: A,\n\t\t\t_end: B,\n\t\t} = this\n\t\tconst t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))\n\t\tif (t <= 0) return A\n\t\tif (t >= 1) return B\n\n\t\t// Inlined: Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t\t// When t is in (0,1), the nearest point is the radial projection of point onto the arc.\n\t\t// Previously this also checked min-distance against A and B, but that's unnecessary when\n\t\t// t is already in range \u2014 the radial projection is always closer.\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst len = Math.sqrt(dx * dx + dy * dy)\n\t\tif (len === 0) return A\n\t\tconst scale = radius / len\n\t\treturn new Vec(_center.x + dx * scale, _center.y + dy * scale)\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst {\n\t\t\t_center,\n\t\t\t_radius: radius,\n\t\t\t_measure: measure,\n\t\t\t_angleStart: angleStart,\n\t\t\t_angleEnd: angleEnd,\n\t\t} = this\n\t\tconst intersection = intersectLineSegmentCircle(A, B, _center, radius)\n\t\tif (intersection === null) return false\n\n\t\treturn intersection.some((p) => {\n\t\t\tconst result = getPointInArcT(measure, angleStart, angleEnd, _center.angle(p))\n\t\t\treturn result >= 0 && result <= 1\n\t\t})\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _measure: measure, length, _radius: radius, _angleStart: angleStart } = this\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(Math.abs(length)); i < n + 1; i++) {\n\t\t\tconst t = (i / n) * measure\n\t\t\tconst angle = angleStart + t\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst {\n\t\t\t_start: start,\n\t\t\t_end: end,\n\t\t\t_radius: radius,\n\t\t\t_largeArcFlag: largeArcFlag,\n\t\t\t_sweepFlag: sweepFlag,\n\t\t} = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} A${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.toFixed()}`\n\t}\n\n\toverride getLength() {\n\t\treturn Math.abs(this._measure * this._radius)\n\t}\n}\n"],
5
+ "mappings": "AAAA,SAAS,kCAAkC;AAC3C,SAAS,eAAe,gBAAgB,wBAAwB;AAChE,SAAS,WAAoB;AAC7B,SAAS,oCAAoC;AAC7C,SAAS,kBAAqC;AAGvC,MAAM,cAAc,WAAW;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACC,QAOC;AACD,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,QAAQ,WAAW,cAAc,OAAO,IAAI,IAAI;AACxD,QAAI,MAAM,OAAO,GAAG,EAAG,OAAM,MAAM,+CAA+C;AAGlF,SAAK,cAAc,IAAI,MAAM,QAAQ,KAAK;AAC1C,SAAK,YAAY,IAAI,MAAM,QAAQ,GAAG;AACtC,SAAK,UAAU,IAAI,KAAK,QAAQ,KAAK;AACrC,SAAK,WAAW,cAAc,KAAK,aAAa,KAAK,WAAW,WAAW,YAAY;AAEvF,SAAK,SAAS;AACd,SAAK,OAAO;AAEZ,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,UAAU;AAAA,EAChB;AAAA,EAEA,aAAa,OAAqB;AACjC,UAAM;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,SAAS;AAAA,MACT,WAAW;AAAA,MACX,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,MAAM;AAAA,IACP,IAAI;AACJ,UAAM,IAAI,eAAe,SAAS,YAAY,UAAU,QAAQ,MAAM,KAAK,CAAC;AAC5E,QAAI,KAAK,EAAG,QAAO;AACnB,QAAI,KAAK,EAAG,QAAO;AAMnB,UAAM,KAAK,MAAM,IAAI,QAAQ;AAC7B,UAAM,KAAK,MAAM,IAAI,QAAQ;AAC7B,UAAM,MAAM,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AACvC,QAAI,QAAQ,EAAG,QAAO;AACtB,UAAM,QAAQ,SAAS;AACvB,WAAO,IAAI,IAAI,QAAQ,IAAI,KAAK,OAAO,QAAQ,IAAI,KAAK,KAAK;AAAA,EAC9D;AAAA,EAEA,mBAAmB,GAAY,GAAqB;AACnD,UAAM;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa;AAAA,MACb,WAAW;AAAA,IACZ,IAAI;AACJ,UAAM,eAAe,2BAA2B,GAAG,GAAG,SAAS,MAAM;AACrE,QAAI,iBAAiB,KAAM,QAAO;AAElC,WAAO,aAAa,KAAK,CAAC,MAAM;AAC/B,YAAM,SAAS,eAAe,SAAS,YAAY,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7E,aAAO,UAAU,KAAK,UAAU;AAAA,IACjC,CAAC;AAAA,EACF;AAAA,EAEA,cAAqB;AACpB,UAAM,EAAE,SAAS,UAAU,SAAS,QAAQ,SAAS,QAAQ,aAAa,WAAW,IAAI;AACzF,UAAM,WAAkB,CAAC;AACzB,aAAS,IAAI,GAAG,IAAI,6BAA6B,KAAK,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,GAAG,KAAK;AACnF,YAAM,IAAK,IAAI,IAAK;AACpB,YAAM,QAAQ,aAAa;AAC3B,eAAS,KAAK,iBAAiB,SAAS,QAAQ,KAAK,CAAC;AAAA,IACvD;AACA,WAAO;AAAA,EACR;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,eAAe;AAAA,MACf,YAAY;AAAA,IACb,IAAI;AACJ,WAAO,GAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,MAAM,IAAI,MAAM,MAAM,YAAY,IAAI,SAAS,IAAI,IAAI,QAAQ,CAAC;AAAA,EAClH;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,IAAI,KAAK,WAAW,KAAK,OAAO;AAAA,EAC7C;AACD;",
6
6
  "names": []
7
7
  }
@@ -1,9 +1,9 @@
1
1
  import { Box } from "../Box.mjs";
2
- import { Vec } from "../Vec.mjs";
3
2
  import { intersectLineSegmentCircle } from "../intersect.mjs";
4
3
  import { PI2, getPointOnCircle } from "../utils.mjs";
5
- import { Geometry2d } from "./Geometry2d.mjs";
4
+ import { Vec } from "../Vec.mjs";
6
5
  import { getVerticesCountForArcLength } from "./geometry-constants.mjs";
6
+ import { Geometry2d } from "./Geometry2d.mjs";
7
7
  class Circle2d extends Geometry2d {
8
8
  constructor(config) {
9
9
  super({ isClosed: true, ...config });
@@ -14,6 +14,7 @@ class Circle2d extends Geometry2d {
14
14
  this._center = new Vec(radius + x, radius + y);
15
15
  this._radius = radius;
16
16
  }
17
+ config;
17
18
  _center;
18
19
  _radius;
19
20
  _x;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Circle2d.ts"],
4
- "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { PI2, getPointOnCircle } from '../utils'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Circle2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _x: number\n\tprivate _y: number\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\tradius: number\n\t\t\tisFilled: boolean\n\t\t}\n\t) {\n\t\tsuper({ isClosed: true, ...config })\n\t\tconst { x = 0, y = 0, radius } = config\n\t\tthis._x = x\n\t\tthis._y = y\n\t\tthis._center = new Vec(radius + x, radius + y)\n\t\tthis._radius = radius\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this._x, this._y, this._radius * 2, this._radius * 2)\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _radius: radius } = this\n\t\tconst perimeter = PI2 * radius\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(perimeter); i < n; i++) {\n\t\t\tconst angle = (i / n) * PI2\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\t// Inlined: Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t\t// Computes direction from center to point, normalizes, scales by radius, offsets by center.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst len = Math.sqrt(dx * dx + dy * dy)\n\t\tif (len === 0) return new Vec(_center.x + radius, _center.y)\n\t\tconst scale = radius / len\n\t\treturn new Vec(_center.x + dx * scale, _center.y + dy * scale)\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\t// Inlined: Math.abs(Vec.Dist(point, _center) - radius)\n\t\t// Computes distance from point to center, then subtracts radius for edge distance.\n\t\t// Returns negative when inside a filled circle to indicate containment.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst dist = Math.sqrt(dx * dx + dy * dy)\n\t\tconst distToEdge = dist - radius\n\t\tif (distToEdge < 0 && (this.isFilled || hitInside)) {\n\t\t\treturn distToEdge\n\t\t}\n\t\treturn Math.abs(distToEdge)\n\t}\n\n\toverride hitTestPoint(point: VecLike, margin = 0, hitInside = false): boolean {\n\t\t// Equivalent to: dist = Vec.Dist(point, _center); return dist within [radius - margin, radius + margin]\n\t\t// Uses squared distances throughout to avoid any sqrt calls.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst dist2 = dx * dx + dy * dy\n\t\tif ((this.isFilled || hitInside) && dist2 <= radius * radius) {\n\t\t\treturn true\n\t\t}\n\t\tconst outerR = radius + margin\n\t\tif (dist2 > outerR * outerR) return false\n\t\tconst innerR = radius - margin\n\t\tif (innerR <= 0) return true\n\t\treturn dist2 >= innerR * innerR\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box } from '../Box'\nimport { intersectLineSegmentCircle } from '../intersect'\nimport { PI2, getPointOnCircle } from '../utils'\nimport { Vec, VecLike } from '../Vec'\nimport { getVerticesCountForArcLength } from './geometry-constants'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Circle2d extends Geometry2d {\n\tprivate _center: Vec\n\tprivate _radius: number\n\tprivate _x: number\n\tprivate _y: number\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\tx?: number\n\t\t\ty?: number\n\t\t\tradius: number\n\t\t\tisFilled: boolean\n\t\t}\n\t) {\n\t\tsuper({ isClosed: true, ...config })\n\t\tconst { x = 0, y = 0, radius } = config\n\t\tthis._x = x\n\t\tthis._y = y\n\t\tthis._center = new Vec(radius + x, radius + y)\n\t\tthis._radius = radius\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(this._x, this._y, this._radius * 2, this._radius * 2)\n\t}\n\n\tgetVertices(): Vec[] {\n\t\tconst { _center, _radius: radius } = this\n\t\tconst perimeter = PI2 * radius\n\t\tconst vertices: Vec[] = []\n\t\tfor (let i = 0, n = getVerticesCountForArcLength(perimeter); i < n; i++) {\n\t\t\tconst angle = (i / n) * PI2\n\t\t\tvertices.push(getPointOnCircle(_center, radius, angle))\n\t\t}\n\t\treturn vertices\n\t}\n\n\tnearestPoint(point: VecLike): Vec {\n\t\t// Inlined: Vec.Sub(point, _center).uni().mul(radius).add(_center)\n\t\t// Computes direction from center to point, normalizes, scales by radius, offsets by center.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst len = Math.sqrt(dx * dx + dy * dy)\n\t\tif (len === 0) return new Vec(_center.x + radius, _center.y)\n\t\tconst scale = radius / len\n\t\treturn new Vec(_center.x + dx * scale, _center.y + dy * scale)\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\t// Inlined: Math.abs(Vec.Dist(point, _center) - radius)\n\t\t// Computes distance from point to center, then subtracts radius for edge distance.\n\t\t// Returns negative when inside a filled circle to indicate containment.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst dist = Math.sqrt(dx * dx + dy * dy)\n\t\tconst distToEdge = dist - radius\n\t\tif (distToEdge < 0 && (this.isFilled || hitInside)) {\n\t\t\treturn distToEdge\n\t\t}\n\t\treturn Math.abs(distToEdge)\n\t}\n\n\toverride hitTestPoint(point: VecLike, margin = 0, hitInside = false): boolean {\n\t\t// Equivalent to: dist = Vec.Dist(point, _center); return dist within [radius - margin, radius + margin]\n\t\t// Uses squared distances throughout to avoid any sqrt calls.\n\t\tconst { _center, _radius: radius } = this\n\t\tconst dx = point.x - _center.x\n\t\tconst dy = point.y - _center.y\n\t\tconst dist2 = dx * dx + dy * dy\n\t\tif ((this.isFilled || hitInside) && dist2 <= radius * radius) {\n\t\t\treturn true\n\t\t}\n\t\tconst outerR = radius + margin\n\t\tif (dist2 > outerR * outerR) return false\n\t\tconst innerR = radius - margin\n\t\tif (innerR <= 0) return true\n\t\treturn dist2 >= innerR * innerR\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn intersectLineSegmentCircle(A, B, _center, radius + distance) !== null\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { _center, _radius: radius } = this\n\t\treturn `M${_center.x + radius},${_center.y} a${radius},${radius} 0 1,0 ${radius * 2},0a${radius},${radius} 0 1,0 -${radius * 2},0`\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -9,7 +9,7 @@ class CubicSpline2d extends Geometry2d {
9
9
  this._points = points;
10
10
  }
11
11
  _segments;
12
- // eslint-disable-next-line no-restricted-syntax
12
+ // eslint-disable-next-line tldraw/no-setter-getter
13
13
  get segments() {
14
14
  if (!this._segments) {
15
15
  this._segments = [];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/CubicSpline2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { CubicBezier2d } from './CubicBezier2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class CubicSpline2d extends Geometry2d {\n\tprivate _points: Vec[]\n\n\tconstructor(config: Omit<Geometry2dOptions, 'isClosed' | 'isFilled'> & { points: Vec[] }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { points } = config\n\n\t\tthis._points = points\n\t}\n\n\tprivate _segments?: CubicBezier2d[]\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget segments() {\n\t\tif (!this._segments) {\n\t\t\tthis._segments = []\n\t\t\tconst { _points: points } = this\n\n\t\t\tconst len = points.length\n\t\t\tconst last = len - 2\n\t\t\tconst k = 1.25\n\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst p0 = i === 0 ? points[0] : points[i - 1]\n\t\t\t\tconst p1 = points[i]\n\t\t\t\tconst p2 = points[i + 1]\n\t\t\t\tconst p3 = i === last ? p2 : points[i + 2]\n\t\t\t\tconst start = p1,\n\t\t\t\t\tcp1 =\n\t\t\t\t\t\ti === 0 ? p0 : new Vec(p1.x + ((p2.x - p0.x) / 6) * k, p1.y + ((p2.y - p0.y) / 6) * k),\n\t\t\t\t\tcp2 =\n\t\t\t\t\t\ti === last\n\t\t\t\t\t\t\t? p2\n\t\t\t\t\t\t\t: new Vec(p2.x - ((p3.x - p1.x) / 6) * k, p2.y - ((p3.y - p1.y) / 6) * k),\n\t\t\t\t\tend = p2\n\n\t\t\t\tthis._segments.push(new CubicBezier2d({ start, cp1, cp2, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getLength() {\n\t\treturn this.segments.reduce((acc, segment) => acc + segment.length, 0)\n\t}\n\n\tgetVertices() {\n\t\tconst vertices = this.segments.reduce((acc, segment) => {\n\t\t\treturn acc.concat(segment.vertices)\n\t\t}, [] as Vec[])\n\t\tvertices.push(this._points[this._points.length - 1])\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const segment of this.segments) {\n\t\t\tp = segment.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: VecLike, _hitInside = false): number {\n\t\tconst { segments } = this\n\t\tlet minDist = Infinity\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tconst d = segments[i].distanceToPoint(point)\n\t\t\tif (d < minDist) minDist = d\n\t\t}\n\t\treturn minDist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\treturn this.segments.some((segment) => segment.hitTestLineSegment(A, B))\n\t}\n\n\tgetSvgPathData() {\n\t\tlet d = this.segments.reduce((d, segment, i) => {\n\t\t\treturn d + segment.getSvgPathData(i === 0)\n\t\t}, '')\n\n\t\tif (this.isClosed) {\n\t\t\td += 'Z'\n\t\t}\n\n\t\treturn d\n\t}\n}\n"],
4
+ "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { CubicBezier2d } from './CubicBezier2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class CubicSpline2d extends Geometry2d {\n\tprivate _points: Vec[]\n\n\tconstructor(config: Omit<Geometry2dOptions, 'isClosed' | 'isFilled'> & { points: Vec[] }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { points } = config\n\n\t\tthis._points = points\n\t}\n\n\tprivate _segments?: CubicBezier2d[]\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget segments() {\n\t\tif (!this._segments) {\n\t\t\tthis._segments = []\n\t\t\tconst { _points: points } = this\n\n\t\t\tconst len = points.length\n\t\t\tconst last = len - 2\n\t\t\tconst k = 1.25\n\n\t\t\tfor (let i = 0; i < len - 1; i++) {\n\t\t\t\tconst p0 = i === 0 ? points[0] : points[i - 1]\n\t\t\t\tconst p1 = points[i]\n\t\t\t\tconst p2 = points[i + 1]\n\t\t\t\tconst p3 = i === last ? p2 : points[i + 2]\n\t\t\t\tconst start = p1,\n\t\t\t\t\tcp1 =\n\t\t\t\t\t\ti === 0 ? p0 : new Vec(p1.x + ((p2.x - p0.x) / 6) * k, p1.y + ((p2.y - p0.y) / 6) * k),\n\t\t\t\t\tcp2 =\n\t\t\t\t\t\ti === last\n\t\t\t\t\t\t\t? p2\n\t\t\t\t\t\t\t: new Vec(p2.x - ((p3.x - p1.x) / 6) * k, p2.y - ((p3.y - p1.y) / 6) * k),\n\t\t\t\t\tend = p2\n\n\t\t\t\tthis._segments.push(new CubicBezier2d({ start, cp1, cp2, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getLength() {\n\t\treturn this.segments.reduce((acc, segment) => acc + segment.length, 0)\n\t}\n\n\tgetVertices() {\n\t\tconst vertices = this.segments.reduce((acc, segment) => {\n\t\t\treturn acc.concat(segment.vertices)\n\t\t}, [] as Vec[])\n\t\tvertices.push(this._points[this._points.length - 1])\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const segment of this.segments) {\n\t\t\tp = segment.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: VecLike, _hitInside = false): number {\n\t\tconst { segments } = this\n\t\tlet minDist = Infinity\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tconst d = segments[i].distanceToPoint(point)\n\t\t\tif (d < minDist) minDist = d\n\t\t}\n\t\treturn minDist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\treturn this.segments.some((segment) => segment.hitTestLineSegment(A, B))\n\t}\n\n\tgetSvgPathData() {\n\t\tlet d = this.segments.reduce((d, segment, i) => {\n\t\t\treturn d + segment.getSvgPathData(i === 0)\n\t\t}, '')\n\n\t\tif (this.isClosed) {\n\t\t\td += 'Z'\n\t\t}\n\n\t\treturn d\n\t}\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["d"]
7
7
  }
@@ -1,9 +1,9 @@
1
1
  import { Box } from "../Box.mjs";
2
- import { Vec } from "../Vec.mjs";
3
2
  import { PI, PI2, clamp, perimeterOfEllipse, pointInPolygon } from "../utils.mjs";
3
+ import { Vec } from "../Vec.mjs";
4
4
  import { Edge2d } from "./Edge2d.mjs";
5
- import { Geometry2d } from "./Geometry2d.mjs";
6
5
  import { getVerticesCountForArcLength } from "./geometry-constants.mjs";
6
+ import { Geometry2d } from "./Geometry2d.mjs";
7
7
  class Ellipse2d extends Geometry2d {
8
8
  constructor(config) {
9
9
  super({ ...config, isClosed: true });
@@ -12,10 +12,11 @@ class Ellipse2d extends Geometry2d {
12
12
  this._w = width;
13
13
  this._h = height;
14
14
  }
15
+ config;
15
16
  _w;
16
17
  _h;
17
18
  _edges;
18
- // eslint-disable-next-line no-restricted-syntax
19
+ // eslint-disable-next-line tldraw/no-setter-getter
19
20
  get edges() {
20
21
  if (!this._edges) {
21
22
  const { vertices } = this;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Ellipse2d.ts"],
4
- "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { PI, PI2, clamp, perimeterOfEllipse, pointInPolygon } from '../utils'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\n\n/** @public */\nexport class Ellipse2d extends Geometry2d {\n\tprivate _w: number\n\tprivate _h: number\n\tprivate _edges?: Edge2d[]\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width, height } = config\n\t\tthis._w = width\n\t\tthis._h = height\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget edges() {\n\t\tif (!this._edges) {\n\t\t\tconst { vertices } = this\n\t\t\tthis._edges = []\n\t\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[(i + 1) % n]\n\t\t\t\tthis._edges.push(new Edge2d({ start, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._edges\n\t}\n\n\tgetVertices() {\n\t\t// Perimeter of the ellipse\n\t\tconst w = Math.max(1, this._w)\n\t\tconst h = Math.max(1, this._h)\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2)\n\t\tconst p = PI * (cx + cy) * (1 + (3 * q) / (10 + Math.sqrt(4 - 3 * q)))\n\t\t// Number of points\n\t\tconst len = getVerticesCountForArcLength(p)\n\t\t// Size of step\n\t\tconst step = PI2 / len\n\n\t\tconst a = Math.cos(step)\n\t\tconst b = Math.sin(step)\n\n\t\tlet sin = 0\n\t\tlet cos = 1\n\t\tlet ts = 0\n\t\tlet tc = 1\n\n\t\tconst vertices = Array(len)\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tvertices[i] = new Vec(clamp(cx + cx * cos, 0, w), clamp(cy + cy * sin, 0, h))\n\t\t\tts = b * cos + a * sin\n\t\t\ttc = a * cos - b * sin\n\t\t\tsin = ts\n\t\t\tcos = tc\n\t\t}\n\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.edges) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\tconst { edges } = this\n\t\tlet minDist = Infinity\n\t\tfor (let i = 0; i < edges.length; i++) {\n\t\t\tconst d = edges[i].distanceToPoint(point)\n\t\t\tif (d < minDist) minDist = d\n\t\t}\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn -minDist\n\t\t}\n\t\treturn minDist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\treturn this.edges.some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this._w, this._h)\n\t}\n\n\tgetLength(): number {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn perimeterOfEllipse(rx, ry)\n\t}\n\n\tgetSvgPathData(first = false) {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn `${first ? `M${cx - rx},${cy}` : ``} a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box } from '../Box'\nimport { PI, PI2, clamp, perimeterOfEllipse, pointInPolygon } from '../utils'\nimport { Vec, VecLike } from '../Vec'\nimport { Edge2d } from './Edge2d'\nimport { getVerticesCountForArcLength } from './geometry-constants'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Ellipse2d extends Geometry2d {\n\tprivate _w: number\n\tprivate _h: number\n\tprivate _edges?: Edge2d[]\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width, height } = config\n\t\tthis._w = width\n\t\tthis._h = height\n\t}\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget edges() {\n\t\tif (!this._edges) {\n\t\t\tconst { vertices } = this\n\t\t\tthis._edges = []\n\t\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[(i + 1) % n]\n\t\t\t\tthis._edges.push(new Edge2d({ start, end }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._edges\n\t}\n\n\tgetVertices() {\n\t\t// Perimeter of the ellipse\n\t\tconst w = Math.max(1, this._w)\n\t\tconst h = Math.max(1, this._h)\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst q = Math.pow(cx - cy, 2) / Math.pow(cx + cy, 2)\n\t\tconst p = PI * (cx + cy) * (1 + (3 * q) / (10 + Math.sqrt(4 - 3 * q)))\n\t\t// Number of points\n\t\tconst len = getVerticesCountForArcLength(p)\n\t\t// Size of step\n\t\tconst step = PI2 / len\n\n\t\tconst a = Math.cos(step)\n\t\tconst b = Math.sin(step)\n\n\t\tlet sin = 0\n\t\tlet cos = 1\n\t\tlet ts = 0\n\t\tlet tc = 1\n\n\t\tconst vertices = Array(len)\n\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tvertices[i] = new Vec(clamp(cx + cx * cos, 0, w), clamp(cy + cy * sin, 0, h))\n\t\t\tts = b * cos + a * sin\n\t\t\ttc = a * cos - b * sin\n\t\t\tsin = ts\n\t\t\tcos = tc\n\t\t}\n\n\t\treturn vertices\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number\n\t\tlet p: Vec\n\t\tfor (const edge of this.edges) {\n\t\t\tp = edge.nearestPoint(A)\n\t\t\td = Vec.Dist2(p, A)\n\t\t\tif (d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\tconst { edges } = this\n\t\tlet minDist = Infinity\n\t\tfor (let i = 0; i < edges.length; i++) {\n\t\t\tconst d = edges[i].distanceToPoint(point)\n\t\t\tif (d < minDist) minDist = d\n\t\t}\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn -minDist\n\t\t}\n\t\treturn minDist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\treturn this.edges.some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this._w, this._h)\n\t}\n\n\tgetLength(): number {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn perimeterOfEllipse(rx, ry)\n\t}\n\n\tgetSvgPathData(first = false) {\n\t\tconst { _w: w, _h: h } = this\n\t\tconst cx = w / 2\n\t\tconst cy = h / 2\n\t\tconst rx = Math.max(0, cx)\n\t\tconst ry = Math.max(0, cy)\n\t\treturn `${first ? `M${cx - rx},${cy}` : ``} a${rx},${ry},0,1,1,${rx * 2},0a${rx},${ry},0,1,1,-${rx * 2},0`\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,5 @@
1
1
  import { assert, invLerp } from "@tldraw/utils";
2
2
  import { Box } from "../Box.mjs";
3
- import { Mat } from "../Mat.mjs";
4
- import { Vec } from "../Vec.mjs";
5
3
  import {
6
4
  intersectCirclePolygon,
7
5
  intersectCirclePolyline,
@@ -12,7 +10,9 @@ import {
12
10
  polygonIntersectsPolyline,
13
11
  polygonsIntersect
14
12
  } from "../intersect.mjs";
13
+ import { Mat } from "../Mat.mjs";
15
14
  import { approximately, pointInPolygon } from "../utils.mjs";
15
+ import { Vec } from "../Vec.mjs";
16
16
  const Geometry2dFilters = {
17
17
  EXCLUDE_NON_STANDARD: {
18
18
  includeLabels: false,
@@ -122,6 +122,7 @@ class Geometry2d {
122
122
  const dist = Vec.Dist(curr, next);
123
123
  const newDistanceTraveled = distanceTraveled + dist;
124
124
  if (newDistanceTraveled >= distanceToTravel) {
125
+ if (dist === 0) return curr;
125
126
  const p = Vec.Lrp(
126
127
  curr,
127
128
  next,
@@ -161,7 +162,7 @@ class Geometry2d {
161
162
  }
162
163
  assert(closestSegment);
163
164
  const distanceAlongRoute = closestSegment.distanceToStart + Vec.Dist(closestSegment.start, closestSegment.nearestPoint);
164
- return distanceAlongRoute / length;
165
+ return length === 0 ? 0 : distanceAlongRoute / length;
165
166
  }
166
167
  isPointInBounds(point, margin = 0) {
167
168
  const { bounds } = this;
@@ -197,7 +198,7 @@ class Geometry2d {
197
198
  return new TransformedGeometry2d(this, transform, opts);
198
199
  }
199
200
  _vertices;
200
- // eslint-disable-next-line no-restricted-syntax
201
+ // eslint-disable-next-line tldraw/no-setter-getter
201
202
  get vertices() {
202
203
  if (!this._vertices) {
203
204
  this._vertices = this.getVertices(Geometry2dFilters.EXCLUDE_LABELS);
@@ -209,7 +210,7 @@ class Geometry2d {
209
210
  return this.vertices;
210
211
  }
211
212
  _boundsVertices;
212
- // eslint-disable-next-line no-restricted-syntax
213
+ // eslint-disable-next-line tldraw/no-setter-getter
213
214
  get boundsVertices() {
214
215
  if (!this._boundsVertices) {
215
216
  this._boundsVertices = this.getBoundsVertices();
@@ -220,19 +221,19 @@ class Geometry2d {
220
221
  return Box.FromPoints(this.boundsVertices);
221
222
  }
222
223
  _bounds;
223
- // eslint-disable-next-line no-restricted-syntax
224
+ // eslint-disable-next-line tldraw/no-setter-getter
224
225
  get bounds() {
225
226
  if (!this._bounds) {
226
227
  this._bounds = this.getBounds();
227
228
  }
228
229
  return this._bounds;
229
230
  }
230
- // eslint-disable-next-line no-restricted-syntax
231
+ // eslint-disable-next-line tldraw/no-setter-getter
231
232
  get center() {
232
233
  return this.bounds.center;
233
234
  }
234
235
  _area;
235
- // eslint-disable-next-line no-restricted-syntax
236
+ // eslint-disable-next-line tldraw/no-setter-getter
236
237
  get area() {
237
238
  if (!this._area) {
238
239
  this._area = this.getArea();
@@ -267,7 +268,7 @@ class Geometry2d {
267
268
  return path;
268
269
  }
269
270
  _length;
270
- // eslint-disable-next-line no-restricted-syntax
271
+ // eslint-disable-next-line tldraw/no-setter-getter
271
272
  get length() {
272
273
  if (this._length) return this._length;
273
274
  this._length = this.getLength(Geometry2dFilters.EXCLUDE_LABELS);
@@ -314,6 +315,8 @@ class TransformedGeometry2d extends Geometry2d {
314
315
  "non-uniform scaling is not yet supported"
315
316
  );
316
317
  }
318
+ geometry;
319
+ matrix;
317
320
  inverse;
318
321
  decomposed;
319
322
  getVertices(filters) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Geometry2d.ts"],
4
- "sourcesContent": ["import { assert, invLerp } from '@tldraw/utils'\nimport { Box } from '../Box'\nimport { Mat, MatModel } from '../Mat'\nimport { Vec, VecLike } from '../Vec'\nimport {\n\tintersectCirclePolygon,\n\tintersectCirclePolyline,\n\tintersectLineSegmentPolygon,\n\tintersectLineSegmentPolyline,\n\tintersectPolys,\n\tlinesIntersect,\n\tpolygonIntersectsPolyline,\n\tpolygonsIntersect,\n} from '../intersect'\nimport { approximately, pointInPolygon } from '../utils'\n\n/**\n * Filter geometry within a group.\n *\n * Filters are ignored when called directly on primitive geometries, but can be used to narrow down\n * the results of an operation on `Group2d` geometries.\n *\n * @public\n */\nexport interface Geometry2dFilters {\n\treadonly includeLabels?: boolean\n\treadonly includeInternal?: boolean\n}\n\n/** @public */\nexport const Geometry2dFilters: {\n\tEXCLUDE_NON_STANDARD: Geometry2dFilters\n\tINCLUDE_ALL: Geometry2dFilters\n\tEXCLUDE_LABELS: Geometry2dFilters\n\tEXCLUDE_INTERNAL: Geometry2dFilters\n} = {\n\tEXCLUDE_NON_STANDARD: {\n\t\tincludeLabels: false,\n\t\tincludeInternal: false,\n\t},\n\tINCLUDE_ALL: { includeLabels: true, includeInternal: true },\n\tEXCLUDE_LABELS: { includeLabels: false, includeInternal: true },\n\tEXCLUDE_INTERNAL: { includeLabels: true, includeInternal: false },\n}\n\n/** @public */\nexport interface TransformedGeometry2dOptions {\n\tisLabel?: boolean\n\tisEmptyLabel?: boolean\n\tisInternal?: boolean\n\tdebugColor?: string\n\tignore?: boolean\n\texcludeFromShapeBounds?: boolean\n}\n\n/** @public */\nexport interface Geometry2dOptions extends TransformedGeometry2dOptions {\n\tisFilled: boolean\n\tisClosed: boolean\n}\n\n/** @public */\nexport abstract class Geometry2d {\n\t// todo: consider making accessors for these too, so that they can be overridden in subclasses by geometries with more complex logic\n\tisFilled = false\n\tisClosed = true\n\tisLabel = false\n\tisEmptyLabel = false\n\tisInternal = false\n\texcludeFromShapeBounds = false\n\tdebugColor?: string\n\tignore?: boolean\n\n\tconstructor(opts: Geometry2dOptions) {\n\t\tconst {\n\t\t\tisLabel = false,\n\t\t\tisEmptyLabel = false,\n\t\t\tisInternal = false,\n\t\t\texcludeFromShapeBounds = false,\n\t\t} = opts\n\t\tthis.isFilled = opts.isFilled\n\t\tthis.isClosed = opts.isClosed\n\t\tthis.debugColor = opts.debugColor\n\t\tthis.ignore = opts.ignore\n\t\tthis.isLabel = isLabel\n\t\tthis.isEmptyLabel = isEmptyLabel\n\t\tthis.isInternal = isInternal\n\t\tthis.excludeFromShapeBounds = excludeFromShapeBounds\n\t}\n\n\tisExcludedByFilter(filters?: Geometry2dFilters) {\n\t\tif (!filters) return false\n\t\tif (this.isLabel && !filters.includeLabels) return true\n\t\tif (this.isInternal && !filters.includeInternal) return true\n\t\treturn false\n\t}\n\n\tabstract getVertices(filters: Geometry2dFilters): Vec[]\n\n\tabstract nearestPoint(point: VecLike, _filters?: Geometry2dFilters): Vec\n\n\thitTestPoint(point: VecLike, margin = 0, hitInside = false, _filters?: Geometry2dFilters) {\n\t\t// First check whether the point is inside\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn true\n\t\t}\n\t\t// Then check whether the distance is within the margin\n\t\treturn Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin\n\t}\n\n\tdistanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tVec.Dist(point, this.nearestPoint(point, filters)) *\n\t\t\t(this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)\n\t\t\t\t? -1\n\t\t\t\t: 1)\n\t\t)\n\t}\n\n\tdistanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\tif (Vec.Equals(A, B)) return this.distanceToPoint(A, false, filters)\n\t\tconst { vertices } = this\n\t\tif (vertices.length === 0) throw Error('nearest point not found')\n\t\tif (vertices.length === 1) return Vec.Dist(A, vertices[0])\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number, p: Vec, q: Vec\n\t\tconst nextLimit = this.isClosed ? vertices.length : vertices.length - 1\n\t\tfor (let i = 0; i < vertices.length; i++) {\n\t\t\tp = vertices[i]\n\t\t\tif (i < nextLimit) {\n\t\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\t\t\t\tif (linesIntersect(A, B, p, next)) return 0\n\t\t\t}\n\t\t\tq = Vec.NearestPointOnLineSegment(A, B, p, true)\n\t\t\td = Vec.Dist2(p, q)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = q\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\tdist = Math.sqrt(dist) // return the actual distance, not the squared distance\n\t\treturn this.isClosed && this.isFilled && pointInPolygon(nearest, this.vertices) ? -dist : dist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0, filters?: Geometry2dFilters): boolean {\n\t\treturn this.distanceToLineSegment(A, B, filters) <= distance\n\t}\n\n\tintersectLineSegment(A: VecLike, B: VecLike, _filters?: Geometry2dFilters): VecLike[] {\n\t\tconst intersections = this.isClosed\n\t\t\t? intersectLineSegmentPolygon(A, B, this.vertices)\n\t\t\t: intersectLineSegmentPolyline(A, B, this.vertices)\n\n\t\treturn intersections ?? []\n\t}\n\n\tintersectCircle(center: VecLike, radius: number, _filters?: Geometry2dFilters): VecLike[] {\n\t\tconst intersections = this.isClosed\n\t\t\t? intersectCirclePolygon(center, radius, this.vertices)\n\t\t\t: intersectCirclePolyline(center, radius, this.vertices)\n\n\t\treturn intersections ?? []\n\t}\n\n\tintersectPolygon(polygon: VecLike[], _filters?: Geometry2dFilters): VecLike[] {\n\t\treturn intersectPolys(polygon, this.vertices, true, this.isClosed)\n\t}\n\n\tintersectPolyline(polyline: VecLike[], _filters?: Geometry2dFilters): VecLike[] {\n\t\treturn intersectPolys(polyline, this.vertices, false, this.isClosed)\n\t}\n\n\t/**\n\t * Find a point along the edge of the geometry that is a fraction `t` along the entire way round.\n\t */\n\tinterpolateAlongEdge(t: number, _filters?: Geometry2dFilters): Vec {\n\t\tconst { vertices } = this\n\n\t\tif (vertices.length === 0) return new Vec(0, 0)\n\t\tif (vertices.length === 1) return vertices[0]\n\t\tif (t <= 0) return vertices[0]\n\n\t\tconst distanceToTravel = t * this.length\n\t\tlet distanceTraveled = 0\n\n\t\tfor (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\t\t\tconst dist = Vec.Dist(curr, next)\n\t\t\tconst newDistanceTraveled = distanceTraveled + dist\n\t\t\tif (newDistanceTraveled >= distanceToTravel) {\n\t\t\t\tconst p = Vec.Lrp(\n\t\t\t\t\tcurr,\n\t\t\t\t\tnext,\n\t\t\t\t\tinvLerp(distanceTraveled, newDistanceTraveled, distanceToTravel)\n\t\t\t\t)\n\t\t\t\treturn p\n\t\t\t}\n\t\t\tdistanceTraveled = newDistanceTraveled\n\t\t}\n\n\t\treturn this.isClosed ? vertices[0] : vertices[vertices.length - 1]\n\t}\n\n\t/**\n\t * Take `point`, find the closest point to it on the edge of the geometry, and return how far\n\t * along the edge it is as a fraction of the total length.\n\t */\n\tuninterpolateAlongEdge(point: VecLike, _filters?: Geometry2dFilters): number {\n\t\tconst { vertices, length } = this\n\t\tlet closestSegment = null\n\t\tlet closestDistance = Infinity\n\t\tlet distanceTraveled = 0\n\n\t\tif (vertices.length === 0 || vertices.length === 1) return 0\n\n\t\tfor (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\n\t\t\tconst nearestPoint = Vec.NearestPointOnLineSegment(curr, next, point, true)\n\t\t\tconst distance = Vec.Dist(nearestPoint, point)\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestSegment = {\n\t\t\t\t\tstart: curr,\n\t\t\t\t\tend: next,\n\t\t\t\t\tnearestPoint,\n\t\t\t\t\tdistanceToStart: distanceTraveled,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdistanceTraveled += Vec.Dist(curr, next)\n\t\t}\n\n\t\tassert(closestSegment)\n\n\t\tconst distanceAlongRoute =\n\t\t\tclosestSegment.distanceToStart + Vec.Dist(closestSegment.start, closestSegment.nearestPoint)\n\n\t\treturn distanceAlongRoute / length\n\t}\n\n\tisPointInBounds(point: VecLike, margin = 0) {\n\t\tconst { bounds } = this\n\t\treturn !(\n\t\t\tpoint.x < bounds.minX - margin ||\n\t\t\tpoint.y < bounds.minY - margin ||\n\t\t\tpoint.x > bounds.maxX + margin ||\n\t\t\tpoint.y > bounds.maxY + margin\n\t\t)\n\t}\n\n\toverlapsPolygon(_polygon: VecLike[]): boolean {\n\t\tconst polygon = _polygon.map((v) => Vec.From(v))\n\n\t\t// Otherwise, check if the geometry itself overlaps the polygon\n\t\tconst { vertices, center, isFilled, isEmptyLabel, isClosed } = this\n\n\t\t// We'll do things in order of cheapest to most expensive checks\n\n\t\t// Skip empty labels\n\t\tif (isEmptyLabel) return false\n\n\t\t// If any of the geometry's vertices are inside the polygon, it's inside\n\t\tif (vertices.some((v) => pointInPolygon(v, polygon))) {\n\t\t\treturn true\n\t\t}\n\n\t\t// If the geometry is filled and closed and its center is inside the polygon, it's inside\n\t\tif (isClosed) {\n\t\t\tif (isFilled) {\n\t\t\t\t// If closed and filled, check if the center is inside the polygon\n\t\t\t\tif (pointInPolygon(center, polygon)) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\n\t\t\t\t// ..then, slightly more expensive check, see the geometry covers the entire polygon but not its center\n\t\t\t\tif (polygon.every((v) => pointInPolygon(v, vertices))) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If any the geometry's vertices intersect the edge of the polygon, it's inside.\n\t\t\t// for example when a rotated rectangle is moved over the corner of a parent rectangle\n\t\t\t// If the geometry is closed, intersect as a polygon\n\t\t\tif (polygonsIntersect(polygon, vertices)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t} else {\n\t\t\t// If the geometry is not closed, intersect as a polyline\n\t\t\tif (polygonIntersectsPolyline(polygon, vertices)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\n\t\t// If none of the above checks passed, the geometry is outside the polygon\n\t\treturn false\n\t}\n\n\ttransform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {\n\t\treturn new TransformedGeometry2d(this, transform, opts)\n\t}\n\n\tprivate _vertices: Vec[] | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget vertices(): Vec[] {\n\t\tif (!this._vertices) {\n\t\t\tthis._vertices = this.getVertices(Geometry2dFilters.EXCLUDE_LABELS)\n\t\t}\n\n\t\treturn this._vertices\n\t}\n\n\tgetBoundsVertices(): Vec[] {\n\t\tif (this.excludeFromShapeBounds) return []\n\t\treturn this.vertices\n\t}\n\n\tprivate _boundsVertices: Vec[] | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget boundsVertices(): Vec[] {\n\t\tif (!this._boundsVertices) {\n\t\t\tthis._boundsVertices = this.getBoundsVertices()\n\t\t}\n\t\treturn this._boundsVertices\n\t}\n\n\tgetBounds() {\n\t\treturn Box.FromPoints(this.boundsVertices)\n\t}\n\n\tprivate _bounds: Box | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget bounds(): Box {\n\t\tif (!this._bounds) {\n\t\t\tthis._bounds = this.getBounds()\n\t\t}\n\t\treturn this._bounds\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget center() {\n\t\treturn this.bounds.center\n\t}\n\n\tprivate _area: number | undefined\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget area() {\n\t\tif (!this._area) {\n\t\t\tthis._area = this.getArea()\n\t\t}\n\t\treturn this._area\n\t}\n\n\tgetArea() {\n\t\tif (!this.isClosed) {\n\t\t\treturn 0\n\t\t}\n\t\tconst { vertices } = this\n\t\tlet area = 0\n\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % n]\n\t\t\tarea += curr.x * next.y - next.x * curr.y\n\t\t}\n\t\treturn area / 2\n\t}\n\n\ttoSimpleSvgPath() {\n\t\tlet path = ''\n\n\t\tconst { vertices } = this\n\t\tconst n = vertices.length\n\n\t\tif (n === 0) return path\n\n\t\tpath += `M${vertices[0].x},${vertices[0].y}`\n\n\t\tfor (let i = 1; i < n; i++) {\n\t\t\tpath += `L${vertices[i].x},${vertices[i].y}`\n\t\t}\n\n\t\tif (this.isClosed) {\n\t\t\tpath += 'Z'\n\t\t}\n\n\t\treturn path\n\t}\n\n\tprivate _length?: number\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tget length() {\n\t\tif (this._length) return this._length\n\t\tthis._length = this.getLength(Geometry2dFilters.EXCLUDE_LABELS)\n\t\treturn this._length\n\t}\n\n\tgetLength(_filters?: Geometry2dFilters) {\n\t\tconst vertices = this.getVertices(_filters ?? Geometry2dFilters.EXCLUDE_LABELS)\n\t\tif (vertices.length === 0) return 0\n\t\tlet prev = vertices[0]\n\t\tlet length = 0\n\t\tfor (let i = 1; i < vertices.length; i++) {\n\t\t\tconst next = vertices[i]\n\t\t\tlength += Vec.Dist(prev, next)\n\t\t\tprev = next\n\t\t}\n\t\tif (this.isClosed) {\n\t\t\tlength += Vec.Dist(vertices[vertices.length - 1], vertices[0])\n\t\t}\n\t\treturn length\n\t}\n\n\t/**\n\t * Called after a hit test succeeds. Return `true` to reject the hit and allow\n\t * shapes behind this one to be selected instead (e.g. transparent image pixels).\n\t */\n\tignoreHit(_point: VecLike): boolean {\n\t\treturn false\n\t}\n\n\tabstract getSvgPathData(first: boolean): string\n}\n\n// =================================================================================================\n// Because Geometry2d.transform depends on TransformedGeometry2d, we need to define it here instead\n// of in its own files. This prevents a circular import error.\n// =================================================================================================\n\n/** @public */\nexport class TransformedGeometry2d extends Geometry2d {\n\tprivate readonly inverse: MatModel\n\tprivate readonly decomposed\n\n\tconstructor(\n\t\tprivate readonly geometry: Geometry2d,\n\t\tprivate readonly matrix: MatModel,\n\t\topts?: TransformedGeometry2dOptions\n\t) {\n\t\tsuper(geometry)\n\t\tthis.inverse = Mat.Inverse(matrix)\n\t\tthis.decomposed = Mat.Decompose(matrix)\n\n\t\tif (opts) {\n\t\t\tif (opts.isLabel != null) this.isLabel = opts.isLabel\n\t\t\tif (opts.isInternal != null) this.isInternal = opts.isInternal\n\t\t\tif (opts.debugColor != null) this.debugColor = opts.debugColor\n\t\t\tif (opts.ignore != null) this.ignore = opts.ignore\n\t\t}\n\n\t\tassert(\n\t\t\tapproximately(this.decomposed.scaleX, this.decomposed.scaleY),\n\t\t\t'non-uniform scaling is not yet supported'\n\t\t)\n\t}\n\n\tgetVertices(filters: Geometry2dFilters): Vec[] {\n\t\treturn this.geometry.getVertices(filters).map((v) => Mat.applyToPoint(this.matrix, v))\n\t}\n\n\tgetBoundsVertices(): Vec[] {\n\t\treturn this.geometry.getBoundsVertices().map((v) => Mat.applyToPoint(this.matrix, v))\n\t}\n\n\tnearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec {\n\t\treturn Mat.applyToPoint(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.nearestPoint(Mat.applyToPoint(this.inverse, point), filters)\n\t\t)\n\t}\n\n\toverride hitTestPoint(\n\t\tpoint: VecLike,\n\t\tmargin = 0,\n\t\thitInside?: boolean,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn this.geometry.hitTestPoint(\n\t\t\tMat.applyToPoint(this.inverse, point),\n\t\t\tmargin / this.decomposed.scaleX,\n\t\t\thitInside,\n\t\t\tfilters\n\t\t)\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tthis.geometry.distanceToPoint(Mat.applyToPoint(this.inverse, point), hitInside, filters) *\n\t\t\tthis.decomposed.scaleX\n\t\t)\n\t}\n\n\toverride distanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tthis.geometry.distanceToLineSegment(\n\t\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\t\tfilters\n\t\t\t) * this.decomposed.scaleX\n\t\t)\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 this.geometry.hitTestLineSegment(\n\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\tdistance / this.decomposed.scaleX,\n\t\t\tfilters\n\t\t)\n\t}\n\n\toverride intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectLineSegment(\n\t\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\t\tfilters\n\t\t\t)\n\t\t)\n\t}\n\n\toverride intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters) {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectCircle(\n\t\t\t\tMat.applyToPoint(this.inverse, center),\n\t\t\t\tradius / this.decomposed.scaleX,\n\t\t\t\tfilters\n\t\t\t)\n\t\t)\n\t}\n\n\toverride intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters): VecLike[] {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectPolygon(Mat.applyToPoints(this.inverse, polygon), filters)\n\t\t)\n\t}\n\n\toverride intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters): VecLike[] {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectPolyline(Mat.applyToPoints(this.inverse, polyline), filters)\n\t\t)\n\t}\n\n\toverride ignoreHit(point: VecLike): boolean {\n\t\treturn this.geometry.ignoreHit(Mat.applyToPoint(this.inverse, point))\n\t}\n\n\toverride transform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {\n\t\treturn new TransformedGeometry2d(this.geometry, Mat.Multiply(transform, this.matrix), {\n\t\t\tisLabel: opts?.isLabel ?? this.isLabel,\n\t\t\tisInternal: opts?.isInternal ?? this.isInternal,\n\t\t\tdebugColor: opts?.debugColor ?? this.debugColor,\n\t\t\tignore: opts?.ignore ?? this.ignore,\n\t\t})\n\t}\n\n\tgetSvgPathData(): string {\n\t\tthrow new Error('Cannot get SVG path data for transformed geometry.')\n\t}\n}\n"],
5
- "mappings": "AAAA,SAAS,QAAQ,eAAe;AAChC,SAAS,WAAW;AACpB,SAAS,WAAqB;AAC9B,SAAS,WAAoB;AAC7B;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,eAAe,sBAAsB;AAgBvC,MAAM,oBAKT;AAAA,EACH,sBAAsB;AAAA,IACrB,eAAe;AAAA,IACf,iBAAiB;AAAA,EAClB;AAAA,EACA,aAAa,EAAE,eAAe,MAAM,iBAAiB,KAAK;AAAA,EAC1D,gBAAgB,EAAE,eAAe,OAAO,iBAAiB,KAAK;AAAA,EAC9D,kBAAkB,EAAE,eAAe,MAAM,iBAAiB,MAAM;AACjE;AAmBO,MAAe,WAAW;AAAA;AAAA,EAEhC,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA,EACf,aAAa;AAAA,EACb,yBAAyB;AAAA,EACzB;AAAA,EACA;AAAA,EAEA,YAAY,MAAyB;AACpC,UAAM;AAAA,MACL,UAAU;AAAA,MACV,eAAe;AAAA,MACf,aAAa;AAAA,MACb,yBAAyB;AAAA,IAC1B,IAAI;AACJ,SAAK,WAAW,KAAK;AACrB,SAAK,WAAW,KAAK;AACrB,SAAK,aAAa,KAAK;AACvB,SAAK,SAAS,KAAK;AACnB,SAAK,UAAU;AACf,SAAK,eAAe;AACpB,SAAK,aAAa;AAClB,SAAK,yBAAyB;AAAA,EAC/B;AAAA,EAEA,mBAAmB,SAA6B;AAC/C,QAAI,CAAC,QAAS,QAAO;AACrB,QAAI,KAAK,WAAW,CAAC,QAAQ,cAAe,QAAO;AACnD,QAAI,KAAK,cAAc,CAAC,QAAQ,gBAAiB,QAAO;AACxD,WAAO;AAAA,EACR;AAAA,EAMA,aAAa,OAAgB,SAAS,GAAG,YAAY,OAAO,UAA8B;AAEzF,QAAI,KAAK,aAAa,KAAK,YAAY,cAAc,eAAe,OAAO,KAAK,QAAQ,GAAG;AAC1F,aAAO;AAAA,IACR;AAEA,WAAO,IAAI,MAAM,OAAO,KAAK,aAAa,KAAK,CAAC,KAAK,SAAS;AAAA,EAC/D;AAAA,EAEA,gBAAgB,OAAgB,YAAY,OAAO,SAA6B;AAC/E,WACC,IAAI,KAAK,OAAO,KAAK,aAAa,OAAO,OAAO,CAAC,KAChD,KAAK,aAAa,KAAK,YAAY,cAAc,eAAe,OAAO,KAAK,QAAQ,IAClF,KACA;AAAA,EAEL;AAAA,EAEA,sBAAsB,GAAY,GAAY,SAA6B;AAC1E,QAAI,IAAI,OAAO,GAAG,CAAC,EAAG,QAAO,KAAK,gBAAgB,GAAG,OAAO,OAAO;AACnE,UAAM,EAAE,SAAS,IAAI;AACrB,QAAI,SAAS,WAAW,EAAG,OAAM,MAAM,yBAAyB;AAChE,QAAI,SAAS,WAAW,EAAG,QAAO,IAAI,KAAK,GAAG,SAAS,CAAC,CAAC;AACzD,QAAI;AACJ,QAAI,OAAO;AACX,QAAI,GAAW,GAAQ;AACvB,UAAM,YAAY,KAAK,WAAW,SAAS,SAAS,SAAS,SAAS;AACtE,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACzC,UAAI,SAAS,CAAC;AACd,UAAI,IAAI,WAAW;AAClB,cAAM,OAAO,UAAU,IAAI,KAAK,SAAS,MAAM;AAC/C,YAAI,eAAe,GAAG,GAAG,GAAG,IAAI,EAAG,QAAO;AAAA,MAC3C;AACA,UAAI,IAAI,0BAA0B,GAAG,GAAG,GAAG,IAAI;AAC/C,UAAI,IAAI,MAAM,GAAG,CAAC;AAClB,UAAI,IAAI,MAAM;AACb,eAAO;AACP,kBAAU;AAAA,MACX;AAAA,IACD;AACA,QAAI,CAAC,QAAS,OAAM,MAAM,yBAAyB;AACnD,WAAO,KAAK,KAAK,IAAI;AACrB,WAAO,KAAK,YAAY,KAAK,YAAY,eAAe,SAAS,KAAK,QAAQ,IAAI,CAAC,OAAO;AAAA,EAC3F;AAAA,EAEA,mBAAmB,GAAY,GAAY,WAAW,GAAG,SAAsC;AAC9F,WAAO,KAAK,sBAAsB,GAAG,GAAG,OAAO,KAAK;AAAA,EACrD;AAAA,EAEA,qBAAqB,GAAY,GAAY,UAAyC;AACrF,UAAM,gBAAgB,KAAK,WACxB,4BAA4B,GAAG,GAAG,KAAK,QAAQ,IAC/C,6BAA6B,GAAG,GAAG,KAAK,QAAQ;AAEnD,WAAO,iBAAiB,CAAC;AAAA,EAC1B;AAAA,EAEA,gBAAgB,QAAiB,QAAgB,UAAyC;AACzF,UAAM,gBAAgB,KAAK,WACxB,uBAAuB,QAAQ,QAAQ,KAAK,QAAQ,IACpD,wBAAwB,QAAQ,QAAQ,KAAK,QAAQ;AAExD,WAAO,iBAAiB,CAAC;AAAA,EAC1B;AAAA,EAEA,iBAAiB,SAAoB,UAAyC;AAC7E,WAAO,eAAe,SAAS,KAAK,UAAU,MAAM,KAAK,QAAQ;AAAA,EAClE;AAAA,EAEA,kBAAkB,UAAqB,UAAyC;AAC/E,WAAO,eAAe,UAAU,KAAK,UAAU,OAAO,KAAK,QAAQ;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB,GAAW,UAAmC;AAClE,UAAM,EAAE,SAAS,IAAI;AAErB,QAAI,SAAS,WAAW,EAAG,QAAO,IAAI,IAAI,GAAG,CAAC;AAC9C,QAAI,SAAS,WAAW,EAAG,QAAO,SAAS,CAAC;AAC5C,QAAI,KAAK,EAAG,QAAO,SAAS,CAAC;AAE7B,UAAM,mBAAmB,IAAI,KAAK;AAClC,QAAI,mBAAmB;AAEvB,aAAS,IAAI,GAAG,KAAK,KAAK,WAAW,SAAS,SAAS,SAAS,SAAS,IAAI,KAAK;AACjF,YAAM,OAAO,SAAS,CAAC;AACvB,YAAM,OAAO,UAAU,IAAI,KAAK,SAAS,MAAM;AAC/C,YAAM,OAAO,IAAI,KAAK,MAAM,IAAI;AAChC,YAAM,sBAAsB,mBAAmB;AAC/C,UAAI,uBAAuB,kBAAkB;AAC5C,cAAM,IAAI,IAAI;AAAA,UACb;AAAA,UACA;AAAA,UACA,QAAQ,kBAAkB,qBAAqB,gBAAgB;AAAA,QAChE;AACA,eAAO;AAAA,MACR;AACA,yBAAmB;AAAA,IACpB;AAEA,WAAO,KAAK,WAAW,SAAS,CAAC,IAAI,SAAS,SAAS,SAAS,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,uBAAuB,OAAgB,UAAsC;AAC5E,UAAM,EAAE,UAAU,OAAO,IAAI;AAC7B,QAAI,iBAAiB;AACrB,QAAI,kBAAkB;AACtB,QAAI,mBAAmB;AAEvB,QAAI,SAAS,WAAW,KAAK,SAAS,WAAW,EAAG,QAAO;AAE3D,aAAS,IAAI,GAAG,KAAK,KAAK,WAAW,SAAS,SAAS,SAAS,SAAS,IAAI,KAAK;AACjF,YAAM,OAAO,SAAS,CAAC;AACvB,YAAM,OAAO,UAAU,IAAI,KAAK,SAAS,MAAM;AAE/C,YAAM,eAAe,IAAI,0BAA0B,MAAM,MAAM,OAAO,IAAI;AAC1E,YAAM,WAAW,IAAI,KAAK,cAAc,KAAK;AAE7C,UAAI,WAAW,iBAAiB;AAC/B,0BAAkB;AAClB,yBAAiB;AAAA,UAChB,OAAO;AAAA,UACP,KAAK;AAAA,UACL;AAAA,UACA,iBAAiB;AAAA,QAClB;AAAA,MACD;AAEA,0BAAoB,IAAI,KAAK,MAAM,IAAI;AAAA,IACxC;AAEA,WAAO,cAAc;AAErB,UAAM,qBACL,eAAe,kBAAkB,IAAI,KAAK,eAAe,OAAO,eAAe,YAAY;AAE5F,WAAO,qBAAqB;AAAA,EAC7B;AAAA,EAEA,gBAAgB,OAAgB,SAAS,GAAG;AAC3C,UAAM,EAAE,OAAO,IAAI;AACnB,WAAO,EACN,MAAM,IAAI,OAAO,OAAO,UACxB,MAAM,IAAI,OAAO,OAAO,UACxB,MAAM,IAAI,OAAO,OAAO,UACxB,MAAM,IAAI,OAAO,OAAO;AAAA,EAE1B;AAAA,EAEA,gBAAgB,UAA8B;AAC7C,UAAM,UAAU,SAAS,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAG/C,UAAM,EAAE,UAAU,QAAQ,UAAU,cAAc,SAAS,IAAI;AAK/D,QAAI,aAAc,QAAO;AAGzB,QAAI,SAAS,KAAK,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG;AACrD,aAAO;AAAA,IACR;AAGA,QAAI,UAAU;AACb,UAAI,UAAU;AAEb,YAAI,eAAe,QAAQ,OAAO,GAAG;AACpC,iBAAO;AAAA,QACR;AAGA,YAAI,QAAQ,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,GAAG;AACtD,iBAAO;AAAA,QACR;AAAA,MACD;AAKA,UAAI,kBAAkB,SAAS,QAAQ,GAAG;AACzC,eAAO;AAAA,MACR;AAAA,IACD,OAAO;AAEN,UAAI,0BAA0B,SAAS,QAAQ,GAAG;AACjD,eAAO;AAAA,MACR;AAAA,IACD;AAGA,WAAO;AAAA,EACR;AAAA,EAEA,UAAU,WAAqB,MAAiD;AAC/E,WAAO,IAAI,sBAAsB,MAAM,WAAW,IAAI;AAAA,EACvD;AAAA,EAEQ;AAAA;AAAA,EAGR,IAAI,WAAkB;AACrB,QAAI,CAAC,KAAK,WAAW;AACpB,WAAK,YAAY,KAAK,YAAY,kBAAkB,cAAc;AAAA,IACnE;AAEA,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,oBAA2B;AAC1B,QAAI,KAAK,uBAAwB,QAAO,CAAC;AACzC,WAAO,KAAK;AAAA,EACb;AAAA,EAEQ;AAAA;AAAA,EAGR,IAAI,iBAAwB;AAC3B,QAAI,CAAC,KAAK,iBAAiB;AAC1B,WAAK,kBAAkB,KAAK,kBAAkB;AAAA,IAC/C;AACA,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,YAAY;AACX,WAAO,IAAI,WAAW,KAAK,cAAc;AAAA,EAC1C;AAAA,EAEQ;AAAA;AAAA,EAGR,IAAI,SAAc;AACjB,QAAI,CAAC,KAAK,SAAS;AAClB,WAAK,UAAU,KAAK,UAAU;AAAA,IAC/B;AACA,WAAO,KAAK;AAAA,EACb;AAAA;AAAA,EAGA,IAAI,SAAS;AACZ,WAAO,KAAK,OAAO;AAAA,EACpB;AAAA,EAEQ;AAAA;AAAA,EAGR,IAAI,OAAO;AACV,QAAI,CAAC,KAAK,OAAO;AAChB,WAAK,QAAQ,KAAK,QAAQ;AAAA,IAC3B;AACA,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,UAAU;AACT,QAAI,CAAC,KAAK,UAAU;AACnB,aAAO;AAAA,IACR;AACA,UAAM,EAAE,SAAS,IAAI;AACrB,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AAChD,YAAM,OAAO,SAAS,CAAC;AACvB,YAAM,OAAO,UAAU,IAAI,KAAK,CAAC;AACjC,cAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK;AAAA,IACzC;AACA,WAAO,OAAO;AAAA,EACf;AAAA,EAEA,kBAAkB;AACjB,QAAI,OAAO;AAEX,UAAM,EAAE,SAAS,IAAI;AACrB,UAAM,IAAI,SAAS;AAEnB,QAAI,MAAM,EAAG,QAAO;AAEpB,YAAQ,IAAI,SAAS,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC;AAE1C,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC3B,cAAQ,IAAI,SAAS,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC;AAAA,IAC3C;AAEA,QAAI,KAAK,UAAU;AAClB,cAAQ;AAAA,IACT;AAEA,WAAO;AAAA,EACR;AAAA,EAEQ;AAAA;AAAA,EAGR,IAAI,SAAS;AACZ,QAAI,KAAK,QAAS,QAAO,KAAK;AAC9B,SAAK,UAAU,KAAK,UAAU,kBAAkB,cAAc;AAC9D,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,UAAU,UAA8B;AACvC,UAAM,WAAW,KAAK,YAAY,YAAY,kBAAkB,cAAc;AAC9E,QAAI,SAAS,WAAW,EAAG,QAAO;AAClC,QAAI,OAAO,SAAS,CAAC;AACrB,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACzC,YAAM,OAAO,SAAS,CAAC;AACvB,gBAAU,IAAI,KAAK,MAAM,IAAI;AAC7B,aAAO;AAAA,IACR;AACA,QAAI,KAAK,UAAU;AAClB,gBAAU,IAAI,KAAK,SAAS,SAAS,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC;AAAA,IAC9D;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,QAA0B;AACnC,WAAO;AAAA,EACR;AAGD;AAQO,MAAM,8BAA8B,WAAW;AAAA,EAIrD,YACkB,UACA,QACjB,MACC;AACD,UAAM,QAAQ;AAJG;AACA;AAIjB,SAAK,UAAU,IAAI,QAAQ,MAAM;AACjC,SAAK,aAAa,IAAI,UAAU,MAAM;AAEtC,QAAI,MAAM;AACT,UAAI,KAAK,WAAW,KAAM,MAAK,UAAU,KAAK;AAC9C,UAAI,KAAK,cAAc,KAAM,MAAK,aAAa,KAAK;AACpD,UAAI,KAAK,cAAc,KAAM,MAAK,aAAa,KAAK;AACpD,UAAI,KAAK,UAAU,KAAM,MAAK,SAAS,KAAK;AAAA,IAC7C;AAEA;AAAA,MACC,cAAc,KAAK,WAAW,QAAQ,KAAK,WAAW,MAAM;AAAA,MAC5D;AAAA,IACD;AAAA,EACD;AAAA,EAvBiB;AAAA,EACA;AAAA,EAwBjB,YAAY,SAAmC;AAC9C,WAAO,KAAK,SAAS,YAAY,OAAO,EAAE,IAAI,CAAC,MAAM,IAAI,aAAa,KAAK,QAAQ,CAAC,CAAC;AAAA,EACtF;AAAA,EAEA,oBAA2B;AAC1B,WAAO,KAAK,SAAS,kBAAkB,EAAE,IAAI,CAAC,MAAM,IAAI,aAAa,KAAK,QAAQ,CAAC,CAAC;AAAA,EACrF;AAAA,EAEA,aAAa,OAAgB,SAAkC;AAC9D,WAAO,IAAI;AAAA,MACV,KAAK;AAAA,MACL,KAAK,SAAS,aAAa,IAAI,aAAa,KAAK,SAAS,KAAK,GAAG,OAAO;AAAA,IAC1E;AAAA,EACD;AAAA,EAES,aACR,OACA,SAAS,GACT,WACA,SACU;AACV,WAAO,KAAK,SAAS;AAAA,MACpB,IAAI,aAAa,KAAK,SAAS,KAAK;AAAA,MACpC,SAAS,KAAK,WAAW;AAAA,MACzB;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAAA,EAES,gBAAgB,OAAgB,YAAY,OAAO,SAA6B;AACxF,WACC,KAAK,SAAS,gBAAgB,IAAI,aAAa,KAAK,SAAS,KAAK,GAAG,WAAW,OAAO,IACvF,KAAK,WAAW;AAAA,EAElB;AAAA,EAES,sBAAsB,GAAY,GAAY,SAA6B;AACnF,WACC,KAAK,SAAS;AAAA,MACb,IAAI,aAAa,KAAK,SAAS,CAAC;AAAA,MAChC,IAAI,aAAa,KAAK,SAAS,CAAC;AAAA,MAChC;AAAA,IACD,IAAI,KAAK,WAAW;AAAA,EAEtB;AAAA,EAES,mBACR,GACA,GACA,WAAW,GACX,SACU;AACV,WAAO,KAAK,SAAS;AAAA,MACpB,IAAI,aAAa,KAAK,SAAS,CAAC;AAAA,MAChC,IAAI,aAAa,KAAK,SAAS,CAAC;AAAA,MAChC,WAAW,KAAK,WAAW;AAAA,MAC3B;AAAA,IACD;AAAA,EACD;AAAA,EAES,qBAAqB,GAAY,GAAY,SAA6B;AAClF,WAAO,IAAI;AAAA,MACV,KAAK;AAAA,MACL,KAAK,SAAS;AAAA,QACb,IAAI,aAAa,KAAK,SAAS,CAAC;AAAA,QAChC,IAAI,aAAa,KAAK,SAAS,CAAC;AAAA,QAChC;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAES,gBAAgB,QAAiB,QAAgB,SAA6B;AACtF,WAAO,IAAI;AAAA,MACV,KAAK;AAAA,MACL,KAAK,SAAS;AAAA,QACb,IAAI,aAAa,KAAK,SAAS,MAAM;AAAA,QACrC,SAAS,KAAK,WAAW;AAAA,QACzB;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAES,iBAAiB,SAAoB,SAAwC;AACrF,WAAO,IAAI;AAAA,MACV,KAAK;AAAA,MACL,KAAK,SAAS,iBAAiB,IAAI,cAAc,KAAK,SAAS,OAAO,GAAG,OAAO;AAAA,IACjF;AAAA,EACD;AAAA,EAES,kBAAkB,UAAqB,SAAwC;AACvF,WAAO,IAAI;AAAA,MACV,KAAK;AAAA,MACL,KAAK,SAAS,kBAAkB,IAAI,cAAc,KAAK,SAAS,QAAQ,GAAG,OAAO;AAAA,IACnF;AAAA,EACD;AAAA,EAES,UAAU,OAAyB;AAC3C,WAAO,KAAK,SAAS,UAAU,IAAI,aAAa,KAAK,SAAS,KAAK,CAAC;AAAA,EACrE;AAAA,EAES,UAAU,WAAqB,MAAiD;AACxF,WAAO,IAAI,sBAAsB,KAAK,UAAU,IAAI,SAAS,WAAW,KAAK,MAAM,GAAG;AAAA,MACrF,SAAS,MAAM,WAAW,KAAK;AAAA,MAC/B,YAAY,MAAM,cAAc,KAAK;AAAA,MACrC,YAAY,MAAM,cAAc,KAAK;AAAA,MACrC,QAAQ,MAAM,UAAU,KAAK;AAAA,IAC9B,CAAC;AAAA,EACF;AAAA,EAEA,iBAAyB;AACxB,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACrE;AACD;",
4
+ "sourcesContent": ["import { assert, invLerp } from '@tldraw/utils'\nimport { Box } from '../Box'\nimport {\n\tintersectCirclePolygon,\n\tintersectCirclePolyline,\n\tintersectLineSegmentPolygon,\n\tintersectLineSegmentPolyline,\n\tintersectPolys,\n\tlinesIntersect,\n\tpolygonIntersectsPolyline,\n\tpolygonsIntersect,\n} from '../intersect'\nimport { Mat, MatModel } from '../Mat'\nimport { approximately, pointInPolygon } from '../utils'\nimport { Vec, VecLike } from '../Vec'\n\n/**\n * Filter geometry within a group.\n *\n * Filters are ignored when called directly on primitive geometries, but can be used to narrow down\n * the results of an operation on `Group2d` geometries.\n *\n * @public\n */\nexport interface Geometry2dFilters {\n\treadonly includeLabels?: boolean\n\treadonly includeInternal?: boolean\n}\n\n/** @public */\nexport const Geometry2dFilters: {\n\tEXCLUDE_NON_STANDARD: Geometry2dFilters\n\tINCLUDE_ALL: Geometry2dFilters\n\tEXCLUDE_LABELS: Geometry2dFilters\n\tEXCLUDE_INTERNAL: Geometry2dFilters\n} = {\n\tEXCLUDE_NON_STANDARD: {\n\t\tincludeLabels: false,\n\t\tincludeInternal: false,\n\t},\n\tINCLUDE_ALL: { includeLabels: true, includeInternal: true },\n\tEXCLUDE_LABELS: { includeLabels: false, includeInternal: true },\n\tEXCLUDE_INTERNAL: { includeLabels: true, includeInternal: false },\n}\n\n/** @public */\nexport interface TransformedGeometry2dOptions {\n\tisLabel?: boolean\n\tisEmptyLabel?: boolean\n\tisInternal?: boolean\n\tdebugColor?: string\n\tignore?: boolean\n\texcludeFromShapeBounds?: boolean\n}\n\n/** @public */\nexport interface Geometry2dOptions extends TransformedGeometry2dOptions {\n\tisFilled: boolean\n\tisClosed: boolean\n}\n\n/** @public */\nexport abstract class Geometry2d {\n\t// todo: consider making accessors for these too, so that they can be overridden in subclasses by geometries with more complex logic\n\tisFilled = false\n\tisClosed = true\n\tisLabel = false\n\tisEmptyLabel = false\n\tisInternal = false\n\texcludeFromShapeBounds = false\n\tdebugColor?: string\n\tignore?: boolean\n\n\tconstructor(opts: Geometry2dOptions) {\n\t\tconst {\n\t\t\tisLabel = false,\n\t\t\tisEmptyLabel = false,\n\t\t\tisInternal = false,\n\t\t\texcludeFromShapeBounds = false,\n\t\t} = opts\n\t\tthis.isFilled = opts.isFilled\n\t\tthis.isClosed = opts.isClosed\n\t\tthis.debugColor = opts.debugColor\n\t\tthis.ignore = opts.ignore\n\t\tthis.isLabel = isLabel\n\t\tthis.isEmptyLabel = isEmptyLabel\n\t\tthis.isInternal = isInternal\n\t\tthis.excludeFromShapeBounds = excludeFromShapeBounds\n\t}\n\n\tisExcludedByFilter(filters?: Geometry2dFilters) {\n\t\tif (!filters) return false\n\t\tif (this.isLabel && !filters.includeLabels) return true\n\t\tif (this.isInternal && !filters.includeInternal) return true\n\t\treturn false\n\t}\n\n\tabstract getVertices(filters: Geometry2dFilters): Vec[]\n\n\tabstract nearestPoint(point: VecLike, _filters?: Geometry2dFilters): Vec\n\n\thitTestPoint(point: VecLike, margin = 0, hitInside = false, _filters?: Geometry2dFilters) {\n\t\t// First check whether the point is inside\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn true\n\t\t}\n\t\t// Then check whether the distance is within the margin\n\t\treturn Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin\n\t}\n\n\tdistanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tVec.Dist(point, this.nearestPoint(point, filters)) *\n\t\t\t(this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)\n\t\t\t\t? -1\n\t\t\t\t: 1)\n\t\t)\n\t}\n\n\tdistanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\tif (Vec.Equals(A, B)) return this.distanceToPoint(A, false, filters)\n\t\tconst { vertices } = this\n\t\tif (vertices.length === 0) throw Error('nearest point not found')\n\t\tif (vertices.length === 1) return Vec.Dist(A, vertices[0])\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet d: number, p: Vec, q: Vec\n\t\tconst nextLimit = this.isClosed ? vertices.length : vertices.length - 1\n\t\tfor (let i = 0; i < vertices.length; i++) {\n\t\t\tp = vertices[i]\n\t\t\tif (i < nextLimit) {\n\t\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\t\t\t\tif (linesIntersect(A, B, p, next)) return 0\n\t\t\t}\n\t\t\tq = Vec.NearestPointOnLineSegment(A, B, p, true)\n\t\t\td = Vec.Dist2(p, q)\n\t\t\tif (d < dist) {\n\t\t\t\tdist = d\n\t\t\t\tnearest = q\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\tdist = Math.sqrt(dist) // return the actual distance, not the squared distance\n\t\treturn this.isClosed && this.isFilled && pointInPolygon(nearest, this.vertices) ? -dist : dist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0, filters?: Geometry2dFilters): boolean {\n\t\treturn this.distanceToLineSegment(A, B, filters) <= distance\n\t}\n\n\tintersectLineSegment(A: VecLike, B: VecLike, _filters?: Geometry2dFilters): VecLike[] {\n\t\tconst intersections = this.isClosed\n\t\t\t? intersectLineSegmentPolygon(A, B, this.vertices)\n\t\t\t: intersectLineSegmentPolyline(A, B, this.vertices)\n\n\t\treturn intersections ?? []\n\t}\n\n\tintersectCircle(center: VecLike, radius: number, _filters?: Geometry2dFilters): VecLike[] {\n\t\tconst intersections = this.isClosed\n\t\t\t? intersectCirclePolygon(center, radius, this.vertices)\n\t\t\t: intersectCirclePolyline(center, radius, this.vertices)\n\n\t\treturn intersections ?? []\n\t}\n\n\tintersectPolygon(polygon: VecLike[], _filters?: Geometry2dFilters): VecLike[] {\n\t\treturn intersectPolys(polygon, this.vertices, true, this.isClosed)\n\t}\n\n\tintersectPolyline(polyline: VecLike[], _filters?: Geometry2dFilters): VecLike[] {\n\t\treturn intersectPolys(polyline, this.vertices, false, this.isClosed)\n\t}\n\n\t/**\n\t * Find a point along the edge of the geometry that is a fraction `t` along the entire way round.\n\t */\n\tinterpolateAlongEdge(t: number, _filters?: Geometry2dFilters): Vec {\n\t\tconst { vertices } = this\n\n\t\tif (vertices.length === 0) return new Vec(0, 0)\n\t\tif (vertices.length === 1) return vertices[0]\n\t\tif (t <= 0) return vertices[0]\n\n\t\tconst distanceToTravel = t * this.length\n\t\tlet distanceTraveled = 0\n\n\t\tfor (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\t\t\tconst dist = Vec.Dist(curr, next)\n\t\t\tconst newDistanceTraveled = distanceTraveled + dist\n\t\t\tif (newDistanceTraveled >= distanceToTravel) {\n\t\t\t\tif (dist === 0) return curr\n\t\t\t\tconst p = Vec.Lrp(\n\t\t\t\t\tcurr,\n\t\t\t\t\tnext,\n\t\t\t\t\tinvLerp(distanceTraveled, newDistanceTraveled, distanceToTravel)\n\t\t\t\t)\n\t\t\t\treturn p\n\t\t\t}\n\t\t\tdistanceTraveled = newDistanceTraveled\n\t\t}\n\n\t\treturn this.isClosed ? vertices[0] : vertices[vertices.length - 1]\n\t}\n\n\t/**\n\t * Take `point`, find the closest point to it on the edge of the geometry, and return how far\n\t * along the edge it is as a fraction of the total length.\n\t */\n\tuninterpolateAlongEdge(point: VecLike, _filters?: Geometry2dFilters): number {\n\t\tconst { vertices, length } = this\n\t\tlet closestSegment = null\n\t\tlet closestDistance = Infinity\n\t\tlet distanceTraveled = 0\n\n\t\tif (vertices.length === 0 || vertices.length === 1) return 0\n\n\t\tfor (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % vertices.length]\n\n\t\t\tconst nearestPoint = Vec.NearestPointOnLineSegment(curr, next, point, true)\n\t\t\tconst distance = Vec.Dist(nearestPoint, point)\n\n\t\t\tif (distance < closestDistance) {\n\t\t\t\tclosestDistance = distance\n\t\t\t\tclosestSegment = {\n\t\t\t\t\tstart: curr,\n\t\t\t\t\tend: next,\n\t\t\t\t\tnearestPoint,\n\t\t\t\t\tdistanceToStart: distanceTraveled,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdistanceTraveled += Vec.Dist(curr, next)\n\t\t}\n\n\t\tassert(closestSegment)\n\n\t\tconst distanceAlongRoute =\n\t\t\tclosestSegment.distanceToStart + Vec.Dist(closestSegment.start, closestSegment.nearestPoint)\n\n\t\treturn length === 0 ? 0 : distanceAlongRoute / length\n\t}\n\n\tisPointInBounds(point: VecLike, margin = 0) {\n\t\tconst { bounds } = this\n\t\treturn !(\n\t\t\tpoint.x < bounds.minX - margin ||\n\t\t\tpoint.y < bounds.minY - margin ||\n\t\t\tpoint.x > bounds.maxX + margin ||\n\t\t\tpoint.y > bounds.maxY + margin\n\t\t)\n\t}\n\n\toverlapsPolygon(_polygon: VecLike[]): boolean {\n\t\tconst polygon = _polygon.map((v) => Vec.From(v))\n\n\t\t// Otherwise, check if the geometry itself overlaps the polygon\n\t\tconst { vertices, center, isFilled, isEmptyLabel, isClosed } = this\n\n\t\t// We'll do things in order of cheapest to most expensive checks\n\n\t\t// Skip empty labels\n\t\tif (isEmptyLabel) return false\n\n\t\t// If any of the geometry's vertices are inside the polygon, it's inside\n\t\tif (vertices.some((v) => pointInPolygon(v, polygon))) {\n\t\t\treturn true\n\t\t}\n\n\t\t// If the geometry is filled and closed and its center is inside the polygon, it's inside\n\t\tif (isClosed) {\n\t\t\tif (isFilled) {\n\t\t\t\t// If closed and filled, check if the center is inside the polygon\n\t\t\t\tif (pointInPolygon(center, polygon)) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\n\t\t\t\t// ..then, slightly more expensive check, see the geometry covers the entire polygon but not its center\n\t\t\t\tif (polygon.every((v) => pointInPolygon(v, vertices))) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If any the geometry's vertices intersect the edge of the polygon, it's inside.\n\t\t\t// for example when a rotated rectangle is moved over the corner of a parent rectangle\n\t\t\t// If the geometry is closed, intersect as a polygon\n\t\t\tif (polygonsIntersect(polygon, vertices)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t} else {\n\t\t\t// If the geometry is not closed, intersect as a polyline\n\t\t\tif (polygonIntersectsPolyline(polygon, vertices)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\n\t\t// If none of the above checks passed, the geometry is outside the polygon\n\t\treturn false\n\t}\n\n\ttransform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {\n\t\treturn new TransformedGeometry2d(this, transform, opts)\n\t}\n\n\tprivate _vertices: Vec[] | undefined\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget vertices(): Vec[] {\n\t\tif (!this._vertices) {\n\t\t\tthis._vertices = this.getVertices(Geometry2dFilters.EXCLUDE_LABELS)\n\t\t}\n\n\t\treturn this._vertices\n\t}\n\n\tgetBoundsVertices(): Vec[] {\n\t\tif (this.excludeFromShapeBounds) return []\n\t\treturn this.vertices\n\t}\n\n\tprivate _boundsVertices: Vec[] | undefined\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget boundsVertices(): Vec[] {\n\t\tif (!this._boundsVertices) {\n\t\t\tthis._boundsVertices = this.getBoundsVertices()\n\t\t}\n\t\treturn this._boundsVertices\n\t}\n\n\tgetBounds() {\n\t\treturn Box.FromPoints(this.boundsVertices)\n\t}\n\n\tprivate _bounds: Box | undefined\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget bounds(): Box {\n\t\tif (!this._bounds) {\n\t\t\tthis._bounds = this.getBounds()\n\t\t}\n\t\treturn this._bounds\n\t}\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget center() {\n\t\treturn this.bounds.center\n\t}\n\n\tprivate _area: number | undefined\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget area() {\n\t\tif (!this._area) {\n\t\t\tthis._area = this.getArea()\n\t\t}\n\t\treturn this._area\n\t}\n\n\tgetArea() {\n\t\tif (!this.isClosed) {\n\t\t\treturn 0\n\t\t}\n\t\tconst { vertices } = this\n\t\tlet area = 0\n\t\tfor (let i = 0, n = vertices.length; i < n; i++) {\n\t\t\tconst curr = vertices[i]\n\t\t\tconst next = vertices[(i + 1) % n]\n\t\t\tarea += curr.x * next.y - next.x * curr.y\n\t\t}\n\t\treturn area / 2\n\t}\n\n\ttoSimpleSvgPath() {\n\t\tlet path = ''\n\n\t\tconst { vertices } = this\n\t\tconst n = vertices.length\n\n\t\tif (n === 0) return path\n\n\t\tpath += `M${vertices[0].x},${vertices[0].y}`\n\n\t\tfor (let i = 1; i < n; i++) {\n\t\t\tpath += `L${vertices[i].x},${vertices[i].y}`\n\t\t}\n\n\t\tif (this.isClosed) {\n\t\t\tpath += 'Z'\n\t\t}\n\n\t\treturn path\n\t}\n\n\tprivate _length?: number\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tget length() {\n\t\tif (this._length) return this._length\n\t\tthis._length = this.getLength(Geometry2dFilters.EXCLUDE_LABELS)\n\t\treturn this._length\n\t}\n\n\tgetLength(_filters?: Geometry2dFilters) {\n\t\tconst vertices = this.getVertices(_filters ?? Geometry2dFilters.EXCLUDE_LABELS)\n\t\tif (vertices.length === 0) return 0\n\t\tlet prev = vertices[0]\n\t\tlet length = 0\n\t\tfor (let i = 1; i < vertices.length; i++) {\n\t\t\tconst next = vertices[i]\n\t\t\tlength += Vec.Dist(prev, next)\n\t\t\tprev = next\n\t\t}\n\t\tif (this.isClosed) {\n\t\t\tlength += Vec.Dist(vertices[vertices.length - 1], vertices[0])\n\t\t}\n\t\treturn length\n\t}\n\n\t/**\n\t * Called after a hit test succeeds. Return `true` to reject the hit and allow\n\t * shapes behind this one to be selected instead (e.g. transparent image pixels).\n\t */\n\tignoreHit(_point: VecLike): boolean {\n\t\treturn false\n\t}\n\n\tabstract getSvgPathData(first: boolean): string\n}\n\n// =================================================================================================\n// Because Geometry2d.transform depends on TransformedGeometry2d, we need to define it here instead\n// of in its own files. This prevents a circular import error.\n// =================================================================================================\n\n/** @public */\nexport class TransformedGeometry2d extends Geometry2d {\n\tprivate readonly inverse: MatModel\n\tprivate readonly decomposed\n\n\tconstructor(\n\t\tprivate readonly geometry: Geometry2d,\n\t\tprivate readonly matrix: MatModel,\n\t\topts?: TransformedGeometry2dOptions\n\t) {\n\t\tsuper(geometry)\n\t\tthis.inverse = Mat.Inverse(matrix)\n\t\tthis.decomposed = Mat.Decompose(matrix)\n\n\t\tif (opts) {\n\t\t\tif (opts.isLabel != null) this.isLabel = opts.isLabel\n\t\t\tif (opts.isInternal != null) this.isInternal = opts.isInternal\n\t\t\tif (opts.debugColor != null) this.debugColor = opts.debugColor\n\t\t\tif (opts.ignore != null) this.ignore = opts.ignore\n\t\t}\n\n\t\tassert(\n\t\t\tapproximately(this.decomposed.scaleX, this.decomposed.scaleY),\n\t\t\t'non-uniform scaling is not yet supported'\n\t\t)\n\t}\n\n\tgetVertices(filters: Geometry2dFilters): Vec[] {\n\t\treturn this.geometry.getVertices(filters).map((v) => Mat.applyToPoint(this.matrix, v))\n\t}\n\n\tgetBoundsVertices(): Vec[] {\n\t\treturn this.geometry.getBoundsVertices().map((v) => Mat.applyToPoint(this.matrix, v))\n\t}\n\n\tnearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec {\n\t\treturn Mat.applyToPoint(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.nearestPoint(Mat.applyToPoint(this.inverse, point), filters)\n\t\t)\n\t}\n\n\toverride hitTestPoint(\n\t\tpoint: VecLike,\n\t\tmargin = 0,\n\t\thitInside?: boolean,\n\t\tfilters?: Geometry2dFilters\n\t): boolean {\n\t\treturn this.geometry.hitTestPoint(\n\t\t\tMat.applyToPoint(this.inverse, point),\n\t\t\tmargin / this.decomposed.scaleX,\n\t\t\thitInside,\n\t\t\tfilters\n\t\t)\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tthis.geometry.distanceToPoint(Mat.applyToPoint(this.inverse, point), hitInside, filters) *\n\t\t\tthis.decomposed.scaleX\n\t\t)\n\t}\n\n\toverride distanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn (\n\t\t\tthis.geometry.distanceToLineSegment(\n\t\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\t\tfilters\n\t\t\t) * this.decomposed.scaleX\n\t\t)\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 this.geometry.hitTestLineSegment(\n\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\tdistance / this.decomposed.scaleX,\n\t\t\tfilters\n\t\t)\n\t}\n\n\toverride intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectLineSegment(\n\t\t\t\tMat.applyToPoint(this.inverse, A),\n\t\t\t\tMat.applyToPoint(this.inverse, B),\n\t\t\t\tfilters\n\t\t\t)\n\t\t)\n\t}\n\n\toverride intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters) {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectCircle(\n\t\t\t\tMat.applyToPoint(this.inverse, center),\n\t\t\t\tradius / this.decomposed.scaleX,\n\t\t\t\tfilters\n\t\t\t)\n\t\t)\n\t}\n\n\toverride intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters): VecLike[] {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectPolygon(Mat.applyToPoints(this.inverse, polygon), filters)\n\t\t)\n\t}\n\n\toverride intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters): VecLike[] {\n\t\treturn Mat.applyToPoints(\n\t\t\tthis.matrix,\n\t\t\tthis.geometry.intersectPolyline(Mat.applyToPoints(this.inverse, polyline), filters)\n\t\t)\n\t}\n\n\toverride ignoreHit(point: VecLike): boolean {\n\t\treturn this.geometry.ignoreHit(Mat.applyToPoint(this.inverse, point))\n\t}\n\n\toverride transform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {\n\t\treturn new TransformedGeometry2d(this.geometry, Mat.Multiply(transform, this.matrix), {\n\t\t\tisLabel: opts?.isLabel ?? this.isLabel,\n\t\t\tisInternal: opts?.isInternal ?? this.isInternal,\n\t\t\tdebugColor: opts?.debugColor ?? this.debugColor,\n\t\t\tignore: opts?.ignore ?? this.ignore,\n\t\t})\n\t}\n\n\tgetSvgPathData(): string {\n\t\tthrow new Error('Cannot get SVG path data for transformed geometry.')\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,5 @@
1
- import { Vec } from "../Vec.mjs";
2
1
  import { pointInPolygon } from "../utils.mjs";
2
+ import { Vec } from "../Vec.mjs";
3
3
  import { Edge2d } from "./Edge2d.mjs";
4
4
  import { Geometry2d } from "./Geometry2d.mjs";
5
5
  class Polyline2d extends Geometry2d {
@@ -13,7 +13,7 @@ class Polyline2d extends Geometry2d {
13
13
  throw new Error("Polyline2d: points must be an array of at least 2 points");
14
14
  }
15
15
  }
16
- // eslint-disable-next-line no-restricted-syntax
16
+ // eslint-disable-next-line tldraw/no-setter-getter
17
17
  get segments() {
18
18
  if (!this._segments) {
19
19
  this._segments = [];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Polyline2d.ts"],
4
- "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { pointInPolygon } from '../utils'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Polyline2d extends Geometry2d {\n\tprivate _points: Vec[]\n\tprivate _segments?: Edge2d[]\n\n\tconstructor(config: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & { points: Vec[] }) {\n\t\tsuper({ isClosed: false, isFilled: false, ...config })\n\t\tconst { points } = config\n\t\tthis._points = points\n\n\t\tif (points.length < 2) {\n\t\t\tthrow new Error('Polyline2d: points must be an array of at least 2 points')\n\t\t}\n\t}\n\n\t// eslint-disable-next-line no-restricted-syntax\n\tprotected get segments() {\n\t\tif (!this._segments) {\n\t\t\tthis._segments = []\n\t\t\tconst { vertices } = this\n\t\t\tfor (let i = 0, n = vertices.length - 1; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[i + 1]\n\t\t\t\tthis._segments.push(new Edge2d({ start, end }))\n\t\t\t}\n\n\t\t\tif (this.isClosed) {\n\t\t\t\tthis._segments.push(new Edge2d({ start: vertices[vertices.length - 1], end: vertices[0] }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getLength() {\n\t\treturn this.segments.reduce((acc, segment) => acc + segment.length, 0)\n\t}\n\n\tgetVertices() {\n\t\treturn this._points\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\t// Inlined: for each segment, Edge2d.nearestPoint(A) + Vec.Dist2(result, A), pick closest.\n\t\t// Inlines the per-segment nearest-point math to avoid N Edge2d.nearestPoint Vec allocations;\n\t\t// only allocates a single Vec at the end for the best result.\n\t\tconst { vertices } = this\n\t\tlet bestX = vertices[0].x\n\t\tlet bestY = vertices[0].y\n\t\tlet bestDist2 = (A.x - bestX) * (A.x - bestX) + (A.y - bestY) * (A.y - bestY)\n\n\t\tconst limit = this.isClosed ? vertices.length : vertices.length - 1\n\t\tfor (let i = 0; i < limit; i++) {\n\t\t\tconst start = vertices[i]\n\t\t\tconst end = vertices[(i + 1) % vertices.length]\n\t\t\tconst dx = end.x - start.x\n\t\t\tconst dy = end.y - start.y\n\t\t\tconst len2 = dx * dx + dy * dy\n\n\t\t\tlet nx: number, ny: number\n\t\t\tif (len2 === 0) {\n\t\t\t\tnx = start.x\n\t\t\t\tny = start.y\n\t\t\t} else {\n\t\t\t\tconst t = ((A.x - start.x) * dx + (A.y - start.y) * dy) / len2\n\t\t\t\tif (t <= 0) {\n\t\t\t\t\tnx = start.x\n\t\t\t\t\tny = start.y\n\t\t\t\t} else if (t >= 1) {\n\t\t\t\t\tnx = end.x\n\t\t\t\t\tny = end.y\n\t\t\t\t} else {\n\t\t\t\t\tnx = start.x + dx * t\n\t\t\t\t\tny = start.y + dy * t\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst ex = A.x - nx\n\t\t\tconst ey = A.y - ny\n\t\t\tconst d2 = ex * ex + ey * ey\n\t\t\tif (d2 < bestDist2) {\n\t\t\t\tbestX = nx\n\t\t\t\tbestY = ny\n\t\t\t\tbestDist2 = d2\n\t\t\t}\n\t\t}\n\n\t\treturn new Vec(bestX, bestY)\n\t}\n\n\toverride hitTestPoint(point: VecLike, margin = 0, hitInside = false): boolean {\n\t\treturn this.distanceToPoint(point, hitInside) <= margin\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\tconst { segments } = this\n\t\tlet minDist = Infinity\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tconst d = segments[i].distanceToPoint(point)\n\t\t\tif (d < minDist) minDist = d\n\t\t}\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn -minDist\n\t\t}\n\t\treturn minDist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { segments } = this\n\t\tfor (let i = 0, n = segments.length; i < n; i++) {\n\t\t\tif (segments[i].hitTestLineSegment(A, B, distance)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { vertices } = this\n\t\tif (vertices.length < 2) return ''\n\t\treturn vertices.reduce((acc, vertex, i) => {\n\t\t\tif (i === 0) return `M ${vertex.x} ${vertex.y}`\n\t\t\treturn `${acc} L ${vertex.x} ${vertex.y}`\n\t\t}, '')\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { pointInPolygon } from '../utils'\nimport { Vec, VecLike } from '../Vec'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Polyline2d extends Geometry2d {\n\tprivate _points: Vec[]\n\tprivate _segments?: Edge2d[]\n\n\tconstructor(config: Omit<Geometry2dOptions, 'isFilled' | 'isClosed'> & { points: Vec[] }) {\n\t\tsuper({ isClosed: false, isFilled: false, ...config })\n\t\tconst { points } = config\n\t\tthis._points = points\n\n\t\tif (points.length < 2) {\n\t\t\tthrow new Error('Polyline2d: points must be an array of at least 2 points')\n\t\t}\n\t}\n\n\t// eslint-disable-next-line tldraw/no-setter-getter\n\tprotected get segments() {\n\t\tif (!this._segments) {\n\t\t\tthis._segments = []\n\t\t\tconst { vertices } = this\n\t\t\tfor (let i = 0, n = vertices.length - 1; i < n; i++) {\n\t\t\t\tconst start = vertices[i]\n\t\t\t\tconst end = vertices[i + 1]\n\t\t\t\tthis._segments.push(new Edge2d({ start, end }))\n\t\t\t}\n\n\t\t\tif (this.isClosed) {\n\t\t\t\tthis._segments.push(new Edge2d({ start: vertices[vertices.length - 1], end: vertices[0] }))\n\t\t\t}\n\t\t}\n\n\t\treturn this._segments\n\t}\n\n\toverride getLength() {\n\t\treturn this.segments.reduce((acc, segment) => acc + segment.length, 0)\n\t}\n\n\tgetVertices() {\n\t\treturn this._points\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\t// Inlined: for each segment, Edge2d.nearestPoint(A) + Vec.Dist2(result, A), pick closest.\n\t\t// Inlines the per-segment nearest-point math to avoid N Edge2d.nearestPoint Vec allocations;\n\t\t// only allocates a single Vec at the end for the best result.\n\t\tconst { vertices } = this\n\t\tlet bestX = vertices[0].x\n\t\tlet bestY = vertices[0].y\n\t\tlet bestDist2 = (A.x - bestX) * (A.x - bestX) + (A.y - bestY) * (A.y - bestY)\n\n\t\tconst limit = this.isClosed ? vertices.length : vertices.length - 1\n\t\tfor (let i = 0; i < limit; i++) {\n\t\t\tconst start = vertices[i]\n\t\t\tconst end = vertices[(i + 1) % vertices.length]\n\t\t\tconst dx = end.x - start.x\n\t\t\tconst dy = end.y - start.y\n\t\t\tconst len2 = dx * dx + dy * dy\n\n\t\t\tlet nx: number, ny: number\n\t\t\tif (len2 === 0) {\n\t\t\t\tnx = start.x\n\t\t\t\tny = start.y\n\t\t\t} else {\n\t\t\t\tconst t = ((A.x - start.x) * dx + (A.y - start.y) * dy) / len2\n\t\t\t\tif (t <= 0) {\n\t\t\t\t\tnx = start.x\n\t\t\t\t\tny = start.y\n\t\t\t\t} else if (t >= 1) {\n\t\t\t\t\tnx = end.x\n\t\t\t\t\tny = end.y\n\t\t\t\t} else {\n\t\t\t\t\tnx = start.x + dx * t\n\t\t\t\t\tny = start.y + dy * t\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst ex = A.x - nx\n\t\t\tconst ey = A.y - ny\n\t\t\tconst d2 = ex * ex + ey * ey\n\t\t\tif (d2 < bestDist2) {\n\t\t\t\tbestX = nx\n\t\t\t\tbestY = ny\n\t\t\t\tbestDist2 = d2\n\t\t\t}\n\t\t}\n\n\t\treturn new Vec(bestX, bestY)\n\t}\n\n\toverride hitTestPoint(point: VecLike, margin = 0, hitInside = false): boolean {\n\t\treturn this.distanceToPoint(point, hitInside) <= margin\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\tconst { segments } = this\n\t\tlet minDist = Infinity\n\t\tfor (let i = 0; i < segments.length; i++) {\n\t\t\tconst d = segments[i].distanceToPoint(point)\n\t\t\tif (d < minDist) minDist = d\n\t\t}\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn -minDist\n\t\t}\n\t\treturn minDist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {\n\t\tconst { segments } = this\n\t\tfor (let i = 0, n = segments.length; i < n; i++) {\n\t\t\tif (segments[i].hitTestLineSegment(A, B, distance)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\tgetSvgPathData(): string {\n\t\tconst { vertices } = this\n\t\tif (vertices.length < 2) return ''\n\t\treturn vertices.reduce((acc, vertex, i) => {\n\t\t\tif (i === 0) return `M ${vertex.x} ${vertex.y}`\n\t\t\treturn `${acc} L ${vertex.x} ${vertex.y}`\n\t\t}, '')\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { Box } from "../Box.mjs";
2
- import { Vec } from "../Vec.mjs";
3
2
  import { PI, pointInPolygon } from "../utils.mjs";
3
+ import { Vec } from "../Vec.mjs";
4
4
  import { Arc2d } from "./Arc2d.mjs";
5
5
  import { Edge2d } from "./Edge2d.mjs";
6
6
  import { Geometry2d } from "./Geometry2d.mjs";
@@ -49,6 +49,7 @@ class Stadium2d extends Geometry2d {
49
49
  this._d = new Edge2d({ start: new Vec(w - r, h), end: new Vec(r, h) });
50
50
  }
51
51
  }
52
+ config;
52
53
  _w;
53
54
  _h;
54
55
  _a;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/primitives/geometry/Stadium2d.ts"],
4
- "sourcesContent": ["import { Box } from '../Box'\nimport { Vec, VecLike } from '../Vec'\nimport { PI, pointInPolygon } from '../utils'\nimport { Arc2d } from './Arc2d'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Stadium2d extends Geometry2d {\n\tprivate _w: number\n\tprivate _h: number\n\tprivate _a: Arc2d\n\tprivate _b: Edge2d\n\tprivate _c: Arc2d\n\tprivate _d: Edge2d\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width: w, height: h } = config\n\t\tthis._w = w\n\t\tthis._h = h\n\n\t\tif (h > w) {\n\t\t\tconst r = w / 2\n\t\t\tthis._a = new Arc2d({\n\t\t\t\tstart: new Vec(0, r),\n\t\t\t\tend: new Vec(w, r),\n\t\t\t\tcenter: new Vec(w / 2, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis._b = new Edge2d({ start: new Vec(w, r), end: new Vec(w, h - r) })\n\t\t\tthis._c = new Arc2d({\n\t\t\t\tstart: new Vec(w, h - r),\n\t\t\t\tend: new Vec(0, h - r),\n\t\t\t\tcenter: new Vec(w / 2, h - r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis._d = new Edge2d({ start: new Vec(0, h - r), end: new Vec(0, r) })\n\t\t} else {\n\t\t\tconst r = h / 2\n\t\t\tthis._a = new Arc2d({\n\t\t\t\tstart: new Vec(r, h),\n\t\t\t\tend: new Vec(r, 0),\n\t\t\t\tcenter: new Vec(r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis._b = new Edge2d({ start: new Vec(r, 0), end: new Vec(w - r, 0) })\n\t\t\tthis._c = new Arc2d({\n\t\t\t\tstart: new Vec(w - r, 0),\n\t\t\t\tend: new Vec(w - r, h),\n\t\t\t\tcenter: new Vec(w - r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis._d = new Edge2d({ start: new Vec(w - r, h), end: new Vec(r, h) })\n\t\t}\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet _d: number\n\t\tlet p: Vec\n\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\tfor (const part of [a, b, c, d]) {\n\t\t\tp = part.nearestPoint(A)\n\t\t\t_d = Vec.Dist2(p, A)\n\t\t\tif (_d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = _d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\tlet minDist = Infinity\n\t\tfor (const part of [a, b, c, d]) {\n\t\t\tconst dist = part.distanceToPoint(point)\n\t\t\tif (dist < minDist) minDist = dist\n\t\t}\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn -minDist\n\t\t}\n\t\treturn minDist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn [a, b, c, d].some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetVertices() {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn [a, b, c, d].reduce<Vec[]>((a, p) => {\n\t\t\ta.push(...p.vertices)\n\t\t\treturn a\n\t\t}, [])\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this._w, this._h)\n\t}\n\n\tgetLength() {\n\t\tconst { _h: h, _w: w } = this\n\t\tif (h > w) return (PI * (w / 2) + (h - w)) * 2\n\t\telse return (PI * (h / 2) + (w - h)) * 2\n\t}\n\n\tgetSvgPathData() {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn [a, b, c, d].map((p, i) => p.getSvgPathData(i === 0)).join(' ') + ' Z'\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box } from '../Box'\nimport { PI, pointInPolygon } from '../utils'\nimport { Vec, VecLike } from '../Vec'\nimport { Arc2d } from './Arc2d'\nimport { Edge2d } from './Edge2d'\nimport { Geometry2d, Geometry2dOptions } from './Geometry2d'\n\n/** @public */\nexport class Stadium2d extends Geometry2d {\n\tprivate _w: number\n\tprivate _h: number\n\tprivate _a: Arc2d\n\tprivate _b: Edge2d\n\tprivate _c: Arc2d\n\tprivate _d: Edge2d\n\n\tconstructor(\n\t\tpublic config: Omit<Geometry2dOptions, 'isClosed'> & {\n\t\t\twidth: number\n\t\t\theight: number\n\t\t}\n\t) {\n\t\tsuper({ ...config, isClosed: true })\n\t\tconst { width: w, height: h } = config\n\t\tthis._w = w\n\t\tthis._h = h\n\n\t\tif (h > w) {\n\t\t\tconst r = w / 2\n\t\t\tthis._a = new Arc2d({\n\t\t\t\tstart: new Vec(0, r),\n\t\t\t\tend: new Vec(w, r),\n\t\t\t\tcenter: new Vec(w / 2, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis._b = new Edge2d({ start: new Vec(w, r), end: new Vec(w, h - r) })\n\t\t\tthis._c = new Arc2d({\n\t\t\t\tstart: new Vec(w, h - r),\n\t\t\t\tend: new Vec(0, h - r),\n\t\t\t\tcenter: new Vec(w / 2, h - r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis._d = new Edge2d({ start: new Vec(0, h - r), end: new Vec(0, r) })\n\t\t} else {\n\t\t\tconst r = h / 2\n\t\t\tthis._a = new Arc2d({\n\t\t\t\tstart: new Vec(r, h),\n\t\t\t\tend: new Vec(r, 0),\n\t\t\t\tcenter: new Vec(r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis._b = new Edge2d({ start: new Vec(r, 0), end: new Vec(w - r, 0) })\n\t\t\tthis._c = new Arc2d({\n\t\t\t\tstart: new Vec(w - r, 0),\n\t\t\t\tend: new Vec(w - r, h),\n\t\t\t\tcenter: new Vec(w - r, r),\n\t\t\t\tsweepFlag: 1,\n\t\t\t\tlargeArcFlag: 1,\n\t\t\t})\n\t\t\tthis._d = new Edge2d({ start: new Vec(w - r, h), end: new Vec(r, h) })\n\t\t}\n\t}\n\n\tnearestPoint(A: VecLike): Vec {\n\t\tlet nearest: Vec | undefined\n\t\tlet dist = Infinity\n\t\tlet _d: number\n\t\tlet p: Vec\n\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\tfor (const part of [a, b, c, d]) {\n\t\t\tp = part.nearestPoint(A)\n\t\t\t_d = Vec.Dist2(p, A)\n\t\t\tif (_d < dist) {\n\t\t\t\tnearest = p\n\t\t\t\tdist = _d\n\t\t\t}\n\t\t}\n\t\tif (!nearest) throw Error('nearest point not found')\n\t\treturn nearest\n\t}\n\n\toverride distanceToPoint(point: VecLike, hitInside = false): number {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\tlet minDist = Infinity\n\t\tfor (const part of [a, b, c, d]) {\n\t\t\tconst dist = part.distanceToPoint(point)\n\t\t\tif (dist < minDist) minDist = dist\n\t\t}\n\t\tif (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {\n\t\t\treturn -minDist\n\t\t}\n\t\treturn minDist\n\t}\n\n\thitTestLineSegment(A: VecLike, B: VecLike): boolean {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn [a, b, c, d].some((edge) => edge.hitTestLineSegment(A, B))\n\t}\n\n\tgetVertices() {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn [a, b, c, d].reduce<Vec[]>((a, p) => {\n\t\t\ta.push(...p.vertices)\n\t\t\treturn a\n\t\t}, [])\n\t}\n\n\tgetBounds() {\n\t\treturn new Box(0, 0, this._w, this._h)\n\t}\n\n\tgetLength() {\n\t\tconst { _h: h, _w: w } = this\n\t\tif (h > w) return (PI * (w / 2) + (h - w)) * 2\n\t\telse return (PI * (h / 2) + (w - h)) * 2\n\t}\n\n\tgetSvgPathData() {\n\t\tconst { _a: a, _b: b, _c: c, _d: d } = this\n\t\treturn [a, b, c, d].map((p, i) => p.getSvgPathData(i === 0)).join(' ') + ' Z'\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["a"]
7
7
  }
@@ -5,6 +5,8 @@ class EditorAtom {
5
5
  this.name = name;
6
6
  this.getInitialState = getInitialState;
7
7
  }
8
+ name;
9
+ getInitialState;
8
10
  states = new WeakCache();
9
11
  getAtom(editor) {
10
12
  return this.states.get(editor, () => atom(this.name, this.getInitialState(editor)));
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/utils/EditorAtom.ts"],
4
4
  "sourcesContent": ["import { atom, Atom } from '@tldraw/state'\nimport { WeakCache } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\n\n/**\n * An Atom that is scoped to the lifetime of an Editor.\n *\n * This is useful for storing UI state for tldraw applications. Keeping state scoped to an editor\n * instead of stored in a global atom can prevent issues with state being shared between editors\n * when navigating between pages, or when multiple editor instances are used on the same page.\n *\n * @public\n */\nexport class EditorAtom<T> {\n\tprivate states = new WeakCache<Editor, Atom<T>>()\n\n\tconstructor(\n\t\tprivate name: string,\n\t\tprivate getInitialState: (editor: Editor) => T\n\t) {}\n\n\tgetAtom(editor: Editor): Atom<T> {\n\t\treturn this.states.get(editor, () => atom(this.name, this.getInitialState(editor)))\n\t}\n\n\tget(editor: Editor): T {\n\t\treturn this.getAtom(editor).get()\n\t}\n\n\tupdate(editor: Editor, update: (state: T) => T): T {\n\t\treturn this.getAtom(editor).update(update)\n\t}\n\n\tset(editor: Editor, state: T): T {\n\t\treturn this.getAtom(editor).set(state)\n\t}\n}\n"],
5
- "mappings": "AAAA,SAAS,YAAkB;AAC3B,SAAS,iBAAiB;AAYnB,MAAM,WAAc;AAAA,EAG1B,YACS,MACA,iBACP;AAFO;AACA;AAAA,EACN;AAAA,EALK,SAAS,IAAI,UAA2B;AAAA,EAOhD,QAAQ,QAAyB;AAChC,WAAO,KAAK,OAAO,IAAI,QAAQ,MAAM,KAAK,KAAK,MAAM,KAAK,gBAAgB,MAAM,CAAC,CAAC;AAAA,EACnF;AAAA,EAEA,IAAI,QAAmB;AACtB,WAAO,KAAK,QAAQ,MAAM,EAAE,IAAI;AAAA,EACjC;AAAA,EAEA,OAAO,QAAgB,QAA4B;AAClD,WAAO,KAAK,QAAQ,MAAM,EAAE,OAAO,MAAM;AAAA,EAC1C;AAAA,EAEA,IAAI,QAAgB,OAAa;AAChC,WAAO,KAAK,QAAQ,MAAM,EAAE,IAAI,KAAK;AAAA,EACtC;AACD;",
5
+ "mappings": "AAAA,SAAS,YAAkB;AAC3B,SAAS,iBAAiB;AAYnB,MAAM,WAAc;AAAA,EAG1B,YACS,MACA,iBACP;AAFO;AACA;AAAA,EACN;AAAA,EAFM;AAAA,EACA;AAAA,EAJD,SAAS,IAAI,UAA2B;AAAA,EAOhD,QAAQ,QAAyB;AAChC,WAAO,KAAK,OAAO,IAAI,QAAQ,MAAM,KAAK,KAAK,MAAM,KAAK,gBAAgB,MAAM,CAAC,CAAC;AAAA,EACnF;AAAA,EAEA,IAAI,QAAmB;AACtB,WAAO,KAAK,QAAQ,MAAM,EAAE,IAAI;AAAA,EACjC;AAAA,EAEA,OAAO,QAAgB,QAA4B;AAClD,WAAO,KAAK,QAAQ,MAAM,EAAE,OAAO,MAAM;AAAA,EAC1C;AAAA,EAEA,IAAI,QAAgB,OAAa;AAChC,WAAO,KAAK,QAAQ,MAAM,EAAE,IAAI,KAAK;AAAA,EACtC;AACD;",
6
6
  "names": []
7
7
  }
@@ -25,7 +25,7 @@ class ReadonlySharedStyleMap {
25
25
  if (value.type === "mixed") return void 0;
26
26
  return value.value;
27
27
  }
28
- // eslint-disable-next-line no-restricted-syntax
28
+ // eslint-disable-next-line tldraw/no-setter-getter
29
29
  get size() {
30
30
  return this.map.size;
31
31
  }