@tldraw/editor 4.5.3 → 4.6.0-canary.00a8c03b5687

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 (279) hide show
  1. package/dist-cjs/index.d.ts +37 -6
  2. package/dist-cjs/index.js +6 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +7 -5
  5. package/dist-cjs/lib/TldrawEditor.js.map +3 -3
  6. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +3 -2
  7. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +2 -2
  8. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +1 -1
  9. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +8 -5
  11. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
  12. package/dist-cjs/lib/config/TLSessionStateSnapshot.js +8 -5
  13. package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +2 -2
  14. package/dist-cjs/lib/config/TLUserPreferences.js +3 -2
  15. package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
  16. package/dist-cjs/lib/config/createTLStore.js +1 -0
  17. package/dist-cjs/lib/config/createTLStore.js.map +2 -2
  18. package/dist-cjs/lib/config/createTLUser.js.map +1 -1
  19. package/dist-cjs/lib/editor/Editor.js +511 -366
  20. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  21. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +25 -64
  22. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  23. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +22 -5
  24. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
  25. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +4 -3
  26. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
  27. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +5 -0
  28. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +2 -2
  29. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +71 -112
  30. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
  31. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +20 -55
  32. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +1 -1
  33. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js +11 -52
  34. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +1 -1
  35. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +19 -56
  36. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +1 -1
  37. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +2 -2
  38. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
  39. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +16 -55
  40. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +1 -1
  41. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +60 -70
  42. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  43. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  44. package/dist-cjs/lib/exports/ExportDelay.js +12 -53
  45. package/dist-cjs/lib/exports/ExportDelay.js.map +1 -1
  46. package/dist-cjs/lib/exports/FontEmbedder.js +23 -65
  47. package/dist-cjs/lib/exports/FontEmbedder.js.map +2 -2
  48. package/dist-cjs/lib/exports/StyleEmbedder.js +27 -15
  49. package/dist-cjs/lib/exports/StyleEmbedder.js.map +3 -3
  50. package/dist-cjs/lib/exports/domUtils.js +15 -0
  51. package/dist-cjs/lib/exports/domUtils.js.map +2 -2
  52. package/dist-cjs/lib/exports/embedMedia.js +15 -12
  53. package/dist-cjs/lib/exports/embedMedia.js.map +2 -2
  54. package/dist-cjs/lib/exports/exportToSvg.js +8 -7
  55. package/dist-cjs/lib/exports/exportToSvg.js.map +2 -2
  56. package/dist-cjs/lib/exports/getSvgAsImage.js +181 -29
  57. package/dist-cjs/lib/exports/getSvgAsImage.js.map +3 -3
  58. package/dist-cjs/lib/exports/getSvgJsx.js +21 -9
  59. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  60. package/dist-cjs/lib/globals/environment.js +4 -3
  61. package/dist-cjs/lib/globals/environment.js.map +2 -2
  62. package/dist-cjs/lib/hooks/useCanvasEvents.js +2 -2
  63. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  64. package/dist-cjs/lib/hooks/useDocumentEvents.js +13 -11
  65. package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
  66. package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js +3 -2
  67. package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
  68. package/dist-cjs/lib/hooks/useScreenBounds.js +10 -6
  69. package/dist-cjs/lib/hooks/useScreenBounds.js.map +2 -2
  70. package/dist-cjs/lib/hooks/useViewportHeight.js +13 -11
  71. package/dist-cjs/lib/hooks/useViewportHeight.js.map +3 -3
  72. package/dist-cjs/lib/license/Watermark.js +10 -0
  73. package/dist-cjs/lib/license/Watermark.js.map +2 -2
  74. package/dist-cjs/lib/primitives/Box.js +25 -25
  75. package/dist-cjs/lib/primitives/Box.js.map +1 -1
  76. package/dist-cjs/lib/primitives/Vec.js +36 -23
  77. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  78. package/dist-cjs/lib/primitives/geometry/Arc2d.js +6 -13
  79. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  80. package/dist-cjs/lib/primitives/geometry/Circle2d.js +31 -2
  81. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  82. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +9 -0
  83. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  84. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js +10 -1
  85. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
  86. package/dist-cjs/lib/primitives/geometry/Edge2d.js +32 -18
  87. package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
  88. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +13 -1
  89. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  90. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +6 -6
  91. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +1 -1
  92. package/dist-cjs/lib/primitives/geometry/Polyline2d.js +52 -13
  93. package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
  94. package/dist-cjs/lib/primitives/geometry/Stadium2d.js +12 -0
  95. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
  96. package/dist-cjs/lib/primitives/geometry/geometry.bench.js +133 -0
  97. package/dist-cjs/lib/primitives/geometry/geometry.bench.js.map +7 -0
  98. package/dist-cjs/lib/primitives/intersect.js +16 -15
  99. package/dist-cjs/lib/primitives/intersect.js.map +2 -2
  100. package/dist-cjs/lib/primitives/utils.js +0 -1
  101. package/dist-cjs/lib/primitives/utils.js.map +2 -2
  102. package/dist-cjs/lib/utils/SharedStylesMap.js +1 -1
  103. package/dist-cjs/lib/utils/SharedStylesMap.js.map +1 -1
  104. package/dist-cjs/lib/utils/browserCanvasMaxSize.js +3 -2
  105. package/dist-cjs/lib/utils/browserCanvasMaxSize.js.map +2 -2
  106. package/dist-cjs/lib/utils/dom.js +15 -2
  107. package/dist-cjs/lib/utils/dom.js.map +2 -2
  108. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +2 -1
  109. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  110. package/dist-cjs/version.js +3 -3
  111. package/dist-cjs/version.js.map +1 -1
  112. package/dist-esm/index.d.mts +37 -6
  113. package/dist-esm/index.mjs +8 -1
  114. package/dist-esm/index.mjs.map +2 -2
  115. package/dist-esm/lib/TldrawEditor.mjs +7 -5
  116. package/dist-esm/lib/TldrawEditor.mjs.map +3 -3
  117. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +2 -1
  118. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +2 -2
  119. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +1 -1
  120. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  121. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +8 -5
  122. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
  123. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs +8 -5
  124. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  125. package/dist-esm/lib/config/TLUserPreferences.mjs +3 -2
  126. package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
  127. package/dist-esm/lib/config/createTLStore.mjs +1 -0
  128. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  129. package/dist-esm/lib/config/createTLUser.mjs.map +1 -1
  130. package/dist-esm/lib/editor/Editor.mjs +512 -368
  131. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  132. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +25 -64
  133. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  134. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +24 -5
  135. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
  136. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +4 -3
  137. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
  138. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +5 -0
  139. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
  140. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +71 -112
  141. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
  142. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +20 -55
  143. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +1 -1
  144. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs +11 -52
  145. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +1 -1
  146. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +19 -56
  147. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +1 -1
  148. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +2 -2
  149. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
  150. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +16 -55
  151. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +1 -1
  152. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +60 -70
  153. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  154. package/dist-esm/lib/exports/ExportDelay.mjs +12 -53
  155. package/dist-esm/lib/exports/ExportDelay.mjs.map +1 -1
  156. package/dist-esm/lib/exports/FontEmbedder.mjs +23 -65
  157. package/dist-esm/lib/exports/FontEmbedder.mjs.map +2 -2
  158. package/dist-esm/lib/exports/StyleEmbedder.mjs +29 -16
  159. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +3 -3
  160. package/dist-esm/lib/exports/domUtils.mjs +15 -0
  161. package/dist-esm/lib/exports/domUtils.mjs.map +2 -2
  162. package/dist-esm/lib/exports/embedMedia.mjs +16 -13
  163. package/dist-esm/lib/exports/embedMedia.mjs.map +2 -2
  164. package/dist-esm/lib/exports/exportToSvg.mjs +8 -7
  165. package/dist-esm/lib/exports/exportToSvg.mjs.map +2 -2
  166. package/dist-esm/lib/exports/getSvgAsImage.mjs +181 -29
  167. package/dist-esm/lib/exports/getSvgAsImage.mjs.map +3 -3
  168. package/dist-esm/lib/exports/getSvgJsx.mjs +21 -9
  169. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  170. package/dist-esm/lib/globals/environment.mjs +4 -3
  171. package/dist-esm/lib/globals/environment.mjs.map +2 -2
  172. package/dist-esm/lib/hooks/useCanvasEvents.mjs +2 -2
  173. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  174. package/dist-esm/lib/hooks/useDocumentEvents.mjs +13 -11
  175. package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
  176. package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs +3 -2
  177. package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
  178. package/dist-esm/lib/hooks/useScreenBounds.mjs +10 -6
  179. package/dist-esm/lib/hooks/useScreenBounds.mjs.map +2 -2
  180. package/dist-esm/lib/hooks/useViewportHeight.mjs +13 -11
  181. package/dist-esm/lib/hooks/useViewportHeight.mjs.map +3 -3
  182. package/dist-esm/lib/license/Watermark.mjs +10 -0
  183. package/dist-esm/lib/license/Watermark.mjs.map +2 -2
  184. package/dist-esm/lib/primitives/Box.mjs +25 -25
  185. package/dist-esm/lib/primitives/Box.mjs.map +1 -1
  186. package/dist-esm/lib/primitives/Vec.mjs +36 -23
  187. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  188. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +6 -13
  189. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  190. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +31 -2
  191. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  192. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +9 -0
  193. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  194. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs +10 -1
  195. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
  196. package/dist-esm/lib/primitives/geometry/Edge2d.mjs +32 -18
  197. package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
  198. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +14 -2
  199. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  200. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +6 -6
  201. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +1 -1
  202. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs +52 -13
  203. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
  204. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +13 -1
  205. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
  206. package/dist-esm/lib/primitives/geometry/geometry.bench.mjs +132 -0
  207. package/dist-esm/lib/primitives/geometry/geometry.bench.mjs.map +7 -0
  208. package/dist-esm/lib/primitives/intersect.mjs +17 -16
  209. package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
  210. package/dist-esm/lib/primitives/utils.mjs +0 -1
  211. package/dist-esm/lib/primitives/utils.mjs.map +2 -2
  212. package/dist-esm/lib/utils/SharedStylesMap.mjs +1 -1
  213. package/dist-esm/lib/utils/SharedStylesMap.mjs.map +1 -1
  214. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs +3 -2
  215. package/dist-esm/lib/utils/browserCanvasMaxSize.mjs.map +2 -2
  216. package/dist-esm/lib/utils/dom.mjs +15 -2
  217. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  218. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +2 -1
  219. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  220. package/dist-esm/version.mjs +3 -3
  221. package/dist-esm/version.mjs.map +1 -1
  222. package/package.json +8 -8
  223. package/src/index.ts +10 -6
  224. package/src/lib/TldrawEditor.tsx +7 -5
  225. package/src/lib/components/default-components/CanvasShapeIndicators.tsx +2 -1
  226. package/src/lib/components/default-components/DefaultCanvas.tsx +1 -1
  227. package/src/lib/components/default-components/DefaultErrorFallback.tsx +9 -5
  228. package/src/lib/config/TLSessionStateSnapshot.ts +8 -5
  229. package/src/lib/config/TLUserPreferences.ts +3 -2
  230. package/src/lib/config/createTLStore.ts +3 -0
  231. package/src/lib/config/createTLUser.ts +3 -3
  232. package/src/lib/editor/Editor.ts +53 -15
  233. package/src/lib/editor/managers/ClickManager/ClickManager.ts +1 -1
  234. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +7 -6
  235. package/src/lib/editor/managers/FocusManager/FocusManager.ts +10 -7
  236. package/src/lib/editor/managers/FontManager/FontManager.test.ts +1 -0
  237. package/src/lib/editor/managers/FontManager/FontManager.ts +4 -3
  238. package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +16 -0
  239. package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +7 -2
  240. package/src/lib/editor/managers/InputsManager/InputsManager.ts +30 -30
  241. package/src/lib/editor/managers/TextManager/TextManager.test.ts +4 -5
  242. package/src/lib/editor/managers/TextManager/TextManager.ts +2 -2
  243. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +3 -2
  244. package/src/lib/editor/types/misc-types.ts +8 -2
  245. package/src/lib/exports/FontEmbedder.ts +10 -9
  246. package/src/lib/exports/StyleEmbedder.ts +33 -15
  247. package/src/lib/exports/domUtils.ts +20 -0
  248. package/src/lib/exports/embedMedia.ts +23 -17
  249. package/src/lib/exports/exportToSvg.tsx +8 -7
  250. package/src/lib/exports/getSvgAsImage.ts +292 -32
  251. package/src/lib/exports/getSvgJsx.test.ts +103 -101
  252. package/src/lib/exports/getSvgJsx.tsx +33 -10
  253. package/src/lib/globals/environment.ts +4 -3
  254. package/src/lib/hooks/useCanvasEvents.ts +2 -3
  255. package/src/lib/hooks/useDocumentEvents.ts +16 -11
  256. package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +3 -3
  257. package/src/lib/hooks/useScreenBounds.ts +10 -6
  258. package/src/lib/hooks/useViewportHeight.ts +13 -11
  259. package/src/lib/license/Watermark.tsx +10 -0
  260. package/src/lib/primitives/Box.ts +25 -25
  261. package/src/lib/primitives/Vec.ts +52 -25
  262. package/src/lib/primitives/geometry/Arc2d.ts +10 -15
  263. package/src/lib/primitives/geometry/Circle2d.ts +40 -2
  264. package/src/lib/primitives/geometry/CubicBezier2d.ts +10 -0
  265. package/src/lib/primitives/geometry/CubicSpline2d.ts +11 -1
  266. package/src/lib/primitives/geometry/Edge2d.ts +41 -18
  267. package/src/lib/primitives/geometry/Ellipse2d.ts +15 -2
  268. package/src/lib/primitives/geometry/Geometry2d.ts +6 -6
  269. package/src/lib/primitives/geometry/Polyline2d.ts +61 -13
  270. package/src/lib/primitives/geometry/Stadium2d.ts +14 -1
  271. package/src/lib/primitives/geometry/geometry.bench.ts +179 -0
  272. package/src/lib/primitives/intersect.ts +27 -27
  273. package/src/lib/primitives/utils.ts +4 -4
  274. package/src/lib/test/TestEditor.ts +1 -0
  275. package/src/lib/utils/SharedStylesMap.ts +1 -1
  276. package/src/lib/utils/browserCanvasMaxSize.ts +4 -2
  277. package/src/lib/utils/dom.ts +34 -2
  278. package/src/lib/utils/sync/TLLocalSyncClient.ts +1 -0
  279. package/src/version.ts +3 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/config/TLSessionStateSnapshot.ts"],
4
- "sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { UnknownRecord } from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tTLINSTANCE_ID,\n\tTLPageId,\n\tTLShapeId,\n\tTLStore,\n\tpageIdValidator,\n\tpluckPreservingValues,\n\tshapeIdValidator,\n} from '@tldraw/tlschema'\nimport {\n\tdeleteFromSessionStorage,\n\tgetFromSessionStorage,\n\tisEqual,\n\tsetInSessionStorage,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { tlenv } from '../globals/environment'\n\nconst tabIdKey = 'TLDRAW_TAB_ID_v2' as const\n\nconst window = globalThis.window as\n\t| {\n\t\t\tnavigator: Window['navigator']\n\t\t\taddEventListener: Window['addEventListener']\n\t\t\tTLDRAW_TAB_ID_v2?: string\n\t }\n\t| undefined\n\n// https://stackoverflow.com/a/9039885\nfunction iOS() {\n\tif (!window) return false\n\treturn (\n\t\t['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\twindow.navigator.platform\n\t\t) ||\n\t\t// iPad on iOS 13 detection\n\t\t(tlenv.isDarwin && 'ontouchend' in document)\n\t)\n}\n\n/**\n * A string that is unique per browser tab\n * @public\n */\nexport const TAB_ID: string = window\n\t? (window[tabIdKey] ??\n\t\tgetFromSessionStorage(tabIdKey) ??\n\t\t`TLDRAW_INSTANCE_STATE_V1_` + uniqueId())\n\t: '<error>'\nif (window) {\n\twindow[tabIdKey] = TAB_ID\n\tif (iOS()) {\n\t\t// iOS does not trigger beforeunload\n\t\t// so we need to keep the sessionStorage value around\n\t\t// and hope the user doesn't figure out a way to duplicate their tab\n\t\t// in which case they'll have two tabs with the same UI state.\n\t\t// It's not a big deal, but it's not ideal.\n\t\t// And anyway I can't see a way to duplicate a tab in iOS Safari.\n\t\tsetInSessionStorage(tabIdKey, TAB_ID)\n\t} else {\n\t\tdeleteFromSessionStorage(tabIdKey)\n\t}\n}\n\nwindow?.addEventListener('beforeunload', () => {\n\tsetInSessionStorage(tabIdKey, TAB_ID)\n})\n\nconst Versions = {\n\tInitial: 0,\n} as const\n\nconst CURRENT_SESSION_STATE_SNAPSHOT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrate(snapshot: any) {\n\tif (snapshot.version < Versions.Initial) {\n\t\t// initial version\n\t\t// noop\n\t}\n\t// add further migrations down here. see TLUserPreferences.ts for an example.\n\n\t// finally\n\tsnapshot.version = CURRENT_SESSION_STATE_SNAPSHOT_VERSION\n}\n\n/**\n * The state of the editor instance, not including any document state.\n *\n * @public\n */\nexport interface TLSessionStateSnapshot {\n\tversion: number\n\tcurrentPageId?: TLPageId\n\tisFocusMode?: boolean\n\texportBackground?: boolean\n\tisDebugMode?: boolean\n\tisToolLocked?: boolean\n\tisGridMode?: boolean\n\tpageStates?: Array<{\n\t\tpageId: TLPageId\n\t\tcamera?: { x: number; y: number; z: number }\n\t\tselectedShapeIds?: TLShapeId[]\n\t\tfocusedGroupId?: TLShapeId | null\n\t}>\n}\n\nconst sessionStateSnapshotValidator: T.Validator<TLSessionStateSnapshot> = T.object({\n\tversion: T.number,\n\tcurrentPageId: pageIdValidator.optional(),\n\tisFocusMode: T.boolean.optional(),\n\texportBackground: T.boolean.optional(),\n\tisDebugMode: T.boolean.optional(),\n\tisToolLocked: T.boolean.optional(),\n\tisGridMode: T.boolean.optional(),\n\tpageStates: T.arrayOf(\n\t\tT.object({\n\t\t\tpageId: pageIdValidator,\n\t\t\tcamera: T.object({\n\t\t\t\tx: T.number,\n\t\t\t\ty: T.number,\n\t\t\t\tz: T.number,\n\t\t\t}).optional(),\n\t\t\tselectedShapeIds: T.arrayOf(shapeIdValidator).optional(),\n\t\t\tfocusedGroupId: shapeIdValidator.nullable().optional(),\n\t\t})\n\t).optional(),\n})\n\nfunction migrateAndValidateSessionStateSnapshot(state: unknown): TLSessionStateSnapshot | null {\n\tif (!state || typeof state !== 'object') {\n\t\tconsole.warn('Invalid instance state')\n\t\treturn null\n\t}\n\tif (!('version' in state) || typeof state.version !== 'number') {\n\t\tconsole.warn('No version in instance state')\n\t\treturn null\n\t}\n\tif (state.version !== CURRENT_SESSION_STATE_SNAPSHOT_VERSION) {\n\t\tstate = structuredClone(state)\n\t\tmigrate(state)\n\t}\n\n\ttry {\n\t\treturn sessionStateSnapshotValidator.validate(state)\n\t} catch (e) {\n\t\tconsole.warn(e)\n\t\treturn null\n\t}\n}\n\n/**\n * Creates a signal of the instance state for a given store.\n * @public\n * @param store - The store to create the instance state snapshot signal for\n * @returns\n */\nexport function createSessionStateSnapshotSignal(\n\tstore: TLStore\n): Signal<TLSessionStateSnapshot | null> {\n\tconst $allPageIds = store.query.ids('page')\n\n\treturn computed<TLSessionStateSnapshot | null>(\n\t\t'sessionStateSnapshot',\n\t\t() => {\n\t\t\tconst instanceState = store.get(TLINSTANCE_ID)\n\t\t\tif (!instanceState) return null\n\n\t\t\tconst allPageIds = [...$allPageIds.get()]\n\t\t\treturn {\n\t\t\t\tversion: CURRENT_SESSION_STATE_SNAPSHOT_VERSION,\n\t\t\t\tcurrentPageId: instanceState.currentPageId,\n\t\t\t\texportBackground: instanceState.exportBackground,\n\t\t\t\tisFocusMode: instanceState.isFocusMode,\n\t\t\t\tisDebugMode: instanceState.isDebugMode,\n\t\t\t\tisToolLocked: instanceState.isToolLocked,\n\t\t\t\tisGridMode: instanceState.isGridMode,\n\t\t\t\tpageStates: allPageIds.map((id) => {\n\t\t\t\t\tconst ps = store.get(InstancePageStateRecordType.createId(id))\n\t\t\t\t\tconst camera = store.get(CameraRecordType.createId(id))\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpageId: id,\n\t\t\t\t\t\tcamera: {\n\t\t\t\t\t\t\tx: camera?.x ?? 0,\n\t\t\t\t\t\t\ty: camera?.y ?? 0,\n\t\t\t\t\t\t\tz: camera?.z ?? 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tselectedShapeIds: ps?.selectedShapeIds ?? [],\n\t\t\t\t\t\tfocusedGroupId: ps?.focusedGroupId ?? null,\n\t\t\t\t\t} satisfies NonNullable<TLSessionStateSnapshot['pageStates']>[0]\n\t\t\t\t}),\n\t\t\t} satisfies TLSessionStateSnapshot\n\t\t},\n\t\t{ isEqual }\n\t)\n}\n\n/**\n * Options for {@link loadSessionStateSnapshotIntoStore}\n * @public\n */\nexport interface TLLoadSessionStateSnapshotOptions {\n\t/**\n\t * By default, some session state flags like `isDebugMode` are not overwritten when loading a snapshot.\n\t * These are usually considered \"sticky\" by users while the document data is not.\n\t * If you want to overwrite these flags, set this to `true`.\n\t */\n\tforceOverwrite?: boolean\n}\n\n/**\n * Loads a snapshot of the editor's instance state into the store of a new editor instance.\n *\n * @public\n * @param store - The store to load the instance state into\n * @param snapshot - The instance state snapshot to load\n * @returns\n */\nexport function loadSessionStateSnapshotIntoStore(\n\tstore: TLStore,\n\tsnapshot: TLSessionStateSnapshot,\n\topts?: TLLoadSessionStateSnapshotOptions\n) {\n\tconst res = migrateAndValidateSessionStateSnapshot(snapshot)\n\tif (!res) return\n\n\tconst existingInstance = store.get(TLINSTANCE_ID)\n\tconst preserved = pluckPreservingValues(existingInstance)\n\tconst primary = opts?.forceOverwrite ? res : preserved\n\tconst secondary = opts?.forceOverwrite ? preserved : res\n\n\tconst instanceState = store.schema.types.instance.create({\n\t\tid: TLINSTANCE_ID,\n\t\t...preserved,\n\t\t// the integrity checker will ensure that the currentPageId is valid\n\t\tcurrentPageId: res.currentPageId ?? existingInstance?.currentPageId,\n\t\tisDebugMode: primary?.isDebugMode ?? secondary?.isDebugMode,\n\t\tisFocusMode: primary?.isFocusMode ?? secondary?.isFocusMode,\n\t\tisToolLocked: primary?.isToolLocked ?? secondary?.isToolLocked,\n\t\tisGridMode: primary?.isGridMode ?? secondary?.isGridMode,\n\t\texportBackground: primary?.exportBackground ?? secondary?.exportBackground,\n\t})\n\n\tstore.atomic(() => {\n\t\tfor (const ps of res.pageStates ?? []) {\n\t\t\tif (!store.has(ps.pageId)) continue\n\t\t\tconst cameraId = CameraRecordType.createId(ps.pageId)\n\t\t\tconst instancePageState = InstancePageStateRecordType.createId(ps.pageId)\n\t\t\tconst previousCamera = store.get(cameraId)\n\t\t\tconst previousInstanceState = store.get(instancePageState)\n\t\t\tstore.put([\n\t\t\t\tCameraRecordType.create({\n\t\t\t\t\tid: cameraId,\n\t\t\t\t\tx: ps.camera?.x ?? previousCamera?.x,\n\t\t\t\t\ty: ps.camera?.y ?? previousCamera?.y,\n\t\t\t\t\tz: ps.camera?.z ?? previousCamera?.z,\n\t\t\t\t}),\n\t\t\t\tInstancePageStateRecordType.create({\n\t\t\t\t\tid: instancePageState,\n\t\t\t\t\tpageId: ps.pageId,\n\t\t\t\t\tselectedShapeIds: ps.selectedShapeIds ?? previousInstanceState?.selectedShapeIds,\n\t\t\t\t\tfocusedGroupId: ps.focusedGroupId ?? previousInstanceState?.focusedGroupId,\n\t\t\t\t}),\n\t\t\t])\n\t\t}\n\n\t\tstore.put([instanceState])\n\t\tstore.ensureStoreIsUsable()\n\t})\n}\n\n/**\n * @internal\n */\nexport function extractSessionStateFromLegacySnapshot(\n\tstore: Record<string, UnknownRecord>\n): TLSessionStateSnapshot | null {\n\tconst instanceRecords = []\n\tfor (const record of Object.values(store)) {\n\t\tif (record.typeName?.match(/^(instance.*|pointer|camera)$/)) {\n\t\t\tinstanceRecords.push(record)\n\t\t}\n\t}\n\n\t// for scratch documents, we need to extract the most recently-used instance and it's associated page states\n\t// but oops we don't have the concept of \"most recently-used\" so we'll just take the first one\n\tconst oldInstance = instanceRecords.filter(\n\t\t(r) => r.typeName === 'instance' && r.id !== TLINSTANCE_ID\n\t)[0] as any\n\tif (!oldInstance) return null\n\n\tconst result: TLSessionStateSnapshot = {\n\t\tversion: CURRENT_SESSION_STATE_SNAPSHOT_VERSION,\n\t\tcurrentPageId: oldInstance.currentPageId,\n\t\texportBackground: !!oldInstance.exportBackground,\n\t\tisFocusMode: !!oldInstance.isFocusMode,\n\t\tisDebugMode: !!oldInstance.isDebugMode,\n\t\tisToolLocked: !!oldInstance.isToolLocked,\n\t\tisGridMode: false,\n\t\tpageStates: instanceRecords\n\t\t\t.filter((r: any) => r.typeName === 'instance_page_state' && r.instanceId === oldInstance.id)\n\t\t\t.map((ps: any) => {\n\t\t\t\tconst camera = (store[ps.cameraId] as any) ?? { x: 0, y: 0, z: 1 }\n\t\t\t\treturn {\n\t\t\t\t\tpageId: ps.pageId,\n\t\t\t\t\tcamera: {\n\t\t\t\t\t\tx: camera.x,\n\t\t\t\t\t\ty: camera.y,\n\t\t\t\t\t\tz: camera.z,\n\t\t\t\t\t},\n\t\t\t\t\tselectedShapeIds: ps.selectedShapeIds,\n\t\t\t\t\tfocusedGroupId: ps.focusedGroupId,\n\t\t\t\t} satisfies NonNullable<TLSessionStateSnapshot['pageStates']>[0]\n\t\t\t}),\n\t}\n\n\ttry {\n\t\tsessionStateSnapshotValidator.validate(result)\n\t\treturn result\n\t} catch {\n\t\treturn null\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Signal, computed } from '@tldraw/state'\nimport { UnknownRecord } from '@tldraw/store'\nimport {\n\tCameraRecordType,\n\tInstancePageStateRecordType,\n\tTLINSTANCE_ID,\n\tTLPageId,\n\tTLShapeId,\n\tTLStore,\n\tpageIdValidator,\n\tpluckPreservingValues,\n\tshapeIdValidator,\n} from '@tldraw/tlschema'\nimport {\n\tdeleteFromSessionStorage,\n\tgetFromSessionStorage,\n\tisEqual,\n\tsetInSessionStorage,\n\tstructuredClone,\n\tuniqueId,\n} from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { tlenv } from '../globals/environment'\nimport { getGlobalDocument, getGlobalWindow } from '../utils/dom'\n\nconst tabIdKey = 'TLDRAW_TAB_ID_v2' as const\n\nconst window = globalThis.window as\n\t| {\n\t\t\tnavigator: Window['navigator']\n\t\t\taddEventListener: Window['addEventListener']\n\t\t\tTLDRAW_TAB_ID_v2?: string\n\t }\n\t| undefined\n\n// https://stackoverflow.com/a/9039885\nfunction iOS() {\n\tif (!window) return false\n\treturn (\n\t\t['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\t\tgetGlobalWindow().navigator.platform\n\t\t) ||\n\t\t// iPad on iOS 13 detection\n\t\t(tlenv.isDarwin && 'ontouchend' in getGlobalDocument())\n\t)\n}\n\n/**\n * A string that is unique per browser tab\n * @public\n */\nexport const TAB_ID: string = window\n\t? (window[tabIdKey] ??\n\t\tgetFromSessionStorage(tabIdKey) ??\n\t\t`TLDRAW_INSTANCE_STATE_V1_` + uniqueId())\n\t: '<error>'\nif (window) {\n\twindow[tabIdKey] = TAB_ID\n\tif (iOS()) {\n\t\t// iOS does not trigger beforeunload\n\t\t// so we need to keep the sessionStorage value around\n\t\t// and hope the user doesn't figure out a way to duplicate their tab\n\t\t// in which case they'll have two tabs with the same UI state.\n\t\t// It's not a big deal, but it's not ideal.\n\t\t// And anyway I can't see a way to duplicate a tab in iOS Safari.\n\t\tsetInSessionStorage(tabIdKey, TAB_ID)\n\t} else {\n\t\tdeleteFromSessionStorage(tabIdKey)\n\t}\n}\n\nif (typeof window !== 'undefined') {\n\tgetGlobalWindow().addEventListener('beforeunload', () => {\n\t\tsetInSessionStorage(tabIdKey, TAB_ID)\n\t})\n}\n\nconst Versions = {\n\tInitial: 0,\n} as const\n\nconst CURRENT_SESSION_STATE_SNAPSHOT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrate(snapshot: any) {\n\tif (snapshot.version < Versions.Initial) {\n\t\t// initial version\n\t\t// noop\n\t}\n\t// add further migrations down here. see TLUserPreferences.ts for an example.\n\n\t// finally\n\tsnapshot.version = CURRENT_SESSION_STATE_SNAPSHOT_VERSION\n}\n\n/**\n * The state of the editor instance, not including any document state.\n *\n * @public\n */\nexport interface TLSessionStateSnapshot {\n\tversion: number\n\tcurrentPageId?: TLPageId\n\tisFocusMode?: boolean\n\texportBackground?: boolean\n\tisDebugMode?: boolean\n\tisToolLocked?: boolean\n\tisGridMode?: boolean\n\tpageStates?: Array<{\n\t\tpageId: TLPageId\n\t\tcamera?: { x: number; y: number; z: number }\n\t\tselectedShapeIds?: TLShapeId[]\n\t\tfocusedGroupId?: TLShapeId | null\n\t}>\n}\n\nconst sessionStateSnapshotValidator: T.Validator<TLSessionStateSnapshot> = T.object({\n\tversion: T.number,\n\tcurrentPageId: pageIdValidator.optional(),\n\tisFocusMode: T.boolean.optional(),\n\texportBackground: T.boolean.optional(),\n\tisDebugMode: T.boolean.optional(),\n\tisToolLocked: T.boolean.optional(),\n\tisGridMode: T.boolean.optional(),\n\tpageStates: T.arrayOf(\n\t\tT.object({\n\t\t\tpageId: pageIdValidator,\n\t\t\tcamera: T.object({\n\t\t\t\tx: T.number,\n\t\t\t\ty: T.number,\n\t\t\t\tz: T.number,\n\t\t\t}).optional(),\n\t\t\tselectedShapeIds: T.arrayOf(shapeIdValidator).optional(),\n\t\t\tfocusedGroupId: shapeIdValidator.nullable().optional(),\n\t\t})\n\t).optional(),\n})\n\nfunction migrateAndValidateSessionStateSnapshot(state: unknown): TLSessionStateSnapshot | null {\n\tif (!state || typeof state !== 'object') {\n\t\tconsole.warn('Invalid instance state')\n\t\treturn null\n\t}\n\tif (!('version' in state) || typeof state.version !== 'number') {\n\t\tconsole.warn('No version in instance state')\n\t\treturn null\n\t}\n\tif (state.version !== CURRENT_SESSION_STATE_SNAPSHOT_VERSION) {\n\t\tstate = structuredClone(state)\n\t\tmigrate(state)\n\t}\n\n\ttry {\n\t\treturn sessionStateSnapshotValidator.validate(state)\n\t} catch (e) {\n\t\tconsole.warn(e)\n\t\treturn null\n\t}\n}\n\n/**\n * Creates a signal of the instance state for a given store.\n * @public\n * @param store - The store to create the instance state snapshot signal for\n * @returns\n */\nexport function createSessionStateSnapshotSignal(\n\tstore: TLStore\n): Signal<TLSessionStateSnapshot | null> {\n\tconst $allPageIds = store.query.ids('page')\n\n\treturn computed<TLSessionStateSnapshot | null>(\n\t\t'sessionStateSnapshot',\n\t\t() => {\n\t\t\tconst instanceState = store.get(TLINSTANCE_ID)\n\t\t\tif (!instanceState) return null\n\n\t\t\tconst allPageIds = [...$allPageIds.get()]\n\t\t\treturn {\n\t\t\t\tversion: CURRENT_SESSION_STATE_SNAPSHOT_VERSION,\n\t\t\t\tcurrentPageId: instanceState.currentPageId,\n\t\t\t\texportBackground: instanceState.exportBackground,\n\t\t\t\tisFocusMode: instanceState.isFocusMode,\n\t\t\t\tisDebugMode: instanceState.isDebugMode,\n\t\t\t\tisToolLocked: instanceState.isToolLocked,\n\t\t\t\tisGridMode: instanceState.isGridMode,\n\t\t\t\tpageStates: allPageIds.map((id) => {\n\t\t\t\t\tconst ps = store.get(InstancePageStateRecordType.createId(id))\n\t\t\t\t\tconst camera = store.get(CameraRecordType.createId(id))\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpageId: id,\n\t\t\t\t\t\tcamera: {\n\t\t\t\t\t\t\tx: camera?.x ?? 0,\n\t\t\t\t\t\t\ty: camera?.y ?? 0,\n\t\t\t\t\t\t\tz: camera?.z ?? 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tselectedShapeIds: ps?.selectedShapeIds ?? [],\n\t\t\t\t\t\tfocusedGroupId: ps?.focusedGroupId ?? null,\n\t\t\t\t\t} satisfies NonNullable<TLSessionStateSnapshot['pageStates']>[0]\n\t\t\t\t}),\n\t\t\t} satisfies TLSessionStateSnapshot\n\t\t},\n\t\t{ isEqual }\n\t)\n}\n\n/**\n * Options for {@link loadSessionStateSnapshotIntoStore}\n * @public\n */\nexport interface TLLoadSessionStateSnapshotOptions {\n\t/**\n\t * By default, some session state flags like `isDebugMode` are not overwritten when loading a snapshot.\n\t * These are usually considered \"sticky\" by users while the document data is not.\n\t * If you want to overwrite these flags, set this to `true`.\n\t */\n\tforceOverwrite?: boolean\n}\n\n/**\n * Loads a snapshot of the editor's instance state into the store of a new editor instance.\n *\n * @public\n * @param store - The store to load the instance state into\n * @param snapshot - The instance state snapshot to load\n * @returns\n */\nexport function loadSessionStateSnapshotIntoStore(\n\tstore: TLStore,\n\tsnapshot: TLSessionStateSnapshot,\n\topts?: TLLoadSessionStateSnapshotOptions\n) {\n\tconst res = migrateAndValidateSessionStateSnapshot(snapshot)\n\tif (!res) return\n\n\tconst existingInstance = store.get(TLINSTANCE_ID)\n\tconst preserved = pluckPreservingValues(existingInstance)\n\tconst primary = opts?.forceOverwrite ? res : preserved\n\tconst secondary = opts?.forceOverwrite ? preserved : res\n\n\tconst instanceState = store.schema.types.instance.create({\n\t\tid: TLINSTANCE_ID,\n\t\t...preserved,\n\t\t// the integrity checker will ensure that the currentPageId is valid\n\t\tcurrentPageId: res.currentPageId ?? existingInstance?.currentPageId,\n\t\tisDebugMode: primary?.isDebugMode ?? secondary?.isDebugMode,\n\t\tisFocusMode: primary?.isFocusMode ?? secondary?.isFocusMode,\n\t\tisToolLocked: primary?.isToolLocked ?? secondary?.isToolLocked,\n\t\tisGridMode: primary?.isGridMode ?? secondary?.isGridMode,\n\t\texportBackground: primary?.exportBackground ?? secondary?.exportBackground,\n\t})\n\n\tstore.atomic(() => {\n\t\tfor (const ps of res.pageStates ?? []) {\n\t\t\tif (!store.has(ps.pageId)) continue\n\t\t\tconst cameraId = CameraRecordType.createId(ps.pageId)\n\t\t\tconst instancePageState = InstancePageStateRecordType.createId(ps.pageId)\n\t\t\tconst previousCamera = store.get(cameraId)\n\t\t\tconst previousInstanceState = store.get(instancePageState)\n\t\t\tstore.put([\n\t\t\t\tCameraRecordType.create({\n\t\t\t\t\tid: cameraId,\n\t\t\t\t\tx: ps.camera?.x ?? previousCamera?.x,\n\t\t\t\t\ty: ps.camera?.y ?? previousCamera?.y,\n\t\t\t\t\tz: ps.camera?.z ?? previousCamera?.z,\n\t\t\t\t}),\n\t\t\t\tInstancePageStateRecordType.create({\n\t\t\t\t\tid: instancePageState,\n\t\t\t\t\tpageId: ps.pageId,\n\t\t\t\t\tselectedShapeIds: ps.selectedShapeIds ?? previousInstanceState?.selectedShapeIds,\n\t\t\t\t\tfocusedGroupId: ps.focusedGroupId ?? previousInstanceState?.focusedGroupId,\n\t\t\t\t}),\n\t\t\t])\n\t\t}\n\n\t\tstore.put([instanceState])\n\t\tstore.ensureStoreIsUsable()\n\t})\n}\n\n/**\n * @internal\n */\nexport function extractSessionStateFromLegacySnapshot(\n\tstore: Record<string, UnknownRecord>\n): TLSessionStateSnapshot | null {\n\tconst instanceRecords = []\n\tfor (const record of Object.values(store)) {\n\t\tif (record.typeName?.match(/^(instance.*|pointer|camera)$/)) {\n\t\t\tinstanceRecords.push(record)\n\t\t}\n\t}\n\n\t// for scratch documents, we need to extract the most recently-used instance and it's associated page states\n\t// but oops we don't have the concept of \"most recently-used\" so we'll just take the first one\n\tconst oldInstance = instanceRecords.filter(\n\t\t(r) => r.typeName === 'instance' && r.id !== TLINSTANCE_ID\n\t)[0] as any\n\tif (!oldInstance) return null\n\n\tconst result: TLSessionStateSnapshot = {\n\t\tversion: CURRENT_SESSION_STATE_SNAPSHOT_VERSION,\n\t\tcurrentPageId: oldInstance.currentPageId,\n\t\texportBackground: !!oldInstance.exportBackground,\n\t\tisFocusMode: !!oldInstance.isFocusMode,\n\t\tisDebugMode: !!oldInstance.isDebugMode,\n\t\tisToolLocked: !!oldInstance.isToolLocked,\n\t\tisGridMode: false,\n\t\tpageStates: instanceRecords\n\t\t\t.filter((r: any) => r.typeName === 'instance_page_state' && r.instanceId === oldInstance.id)\n\t\t\t.map((ps: any) => {\n\t\t\t\tconst camera = (store[ps.cameraId] as any) ?? { x: 0, y: 0, z: 1 }\n\t\t\t\treturn {\n\t\t\t\t\tpageId: ps.pageId,\n\t\t\t\t\tcamera: {\n\t\t\t\t\t\tx: camera.x,\n\t\t\t\t\t\ty: camera.y,\n\t\t\t\t\t\tz: camera.z,\n\t\t\t\t\t},\n\t\t\t\t\tselectedShapeIds: ps.selectedShapeIds,\n\t\t\t\t\tfocusedGroupId: ps.focusedGroupId,\n\t\t\t\t} satisfies NonNullable<TLSessionStateSnapshot['pageStates']>[0]\n\t\t\t}),\n\t}\n\n\ttry {\n\t\tsessionStateSnapshotValidator.validate(result)\n\t\treturn result\n\t} catch {\n\t\treturn null\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,7 @@ import { atom } from "@tldraw/state";
2
2
  import { getDefaultTranslationLocale } from "@tldraw/tlschema";
3
3
  import { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from "@tldraw/utils";
4
4
  import { T } from "@tldraw/validate";
5
+ import { getGlobalWindow } from "../utils/dom.mjs";
5
6
  const USER_DATA_KEY = "TLDRAW_USER_DATA_v3";
6
7
  const userTypeValidator = T.object({
7
8
  id: T.string,
@@ -102,8 +103,8 @@ function getRandomColor() {
102
103
  return USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)];
103
104
  }
104
105
  function userPrefersReducedMotion() {
105
- if (typeof window !== "undefined" && window.matchMedia) {
106
- return window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? false;
106
+ if (typeof window !== "undefined" && getGlobalWindow().matchMedia) {
107
+ return getGlobalWindow().matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? false;
107
108
  }
108
109
  return false;
109
110
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/config/TLUserPreferences.ts"],
4
- "sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getDefaultTranslationLocale } from '@tldraw/tlschema'\nimport { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\n\nconst USER_DATA_KEY = 'TLDRAW_USER_DATA_v3'\n\n/**\n * A user of tldraw\n *\n * @public\n */\nexport interface TLUserPreferences {\n\tid: string\n\tname?: string | null\n\tcolor?: string | null\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale?: string | null\n\tanimationSpeed?: number | null\n\tareKeyboardShortcutsEnabled?: boolean | null\n\tedgeScrollSpeed?: number | null\n\tcolorScheme?: 'light' | 'dark' | 'system'\n\tisSnapMode?: boolean | null\n\tisWrapMode?: boolean | null\n\tisDynamicSizeMode?: boolean | null\n\tisPasteAtCursorMode?: boolean | null\n\tenhancedA11yMode?: boolean | null\n\tinputMode?: 'trackpad' | 'mouse' | null\n\tisZoomDirectionInverted?: boolean | null\n}\n\ninterface UserDataSnapshot {\n\tversion: number\n\tuser: TLUserPreferences\n}\n\ninterface UserChangeBroadcastMessage {\n\ttype: typeof broadcastEventKey\n\torigin: string\n\tdata: UserDataSnapshot\n}\n\n/** @public */\nexport const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUserPreferences>({\n\tid: T.string,\n\tname: T.string.nullable().optional(),\n\tcolor: T.string.nullable().optional(),\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale: T.string.nullable().optional(),\n\tanimationSpeed: T.number.nullable().optional(),\n\tareKeyboardShortcutsEnabled: T.boolean.nullable().optional(),\n\tedgeScrollSpeed: T.number.nullable().optional(),\n\tcolorScheme: T.literalEnum('light', 'dark', 'system').optional(),\n\tisSnapMode: T.boolean.nullable().optional(),\n\tisWrapMode: T.boolean.nullable().optional(),\n\tisDynamicSizeMode: T.boolean.nullable().optional(),\n\tisPasteAtCursorMode: T.boolean.nullable().optional(),\n\tenhancedA11yMode: T.boolean.nullable().optional(),\n\tinputMode: T.literalEnum('trackpad', 'mouse').nullable().optional(),\n\tisZoomDirectionInverted: T.boolean.nullable().optional(),\n})\n\nconst Versions = {\n\tAddAnimationSpeed: 1,\n\tAddIsSnapMode: 2,\n\tMakeFieldsNullable: 3,\n\tAddEdgeScrollSpeed: 4,\n\tAddExcalidrawSelectMode: 5,\n\tAddDynamicSizeMode: 6,\n\tAllowSystemColorScheme: 7,\n\tAddPasteAtCursor: 8,\n\tAddKeyboardShortcuts: 9,\n\tAddShowUiLabels: 10,\n\tAddPointerPeripheral: 11,\n\tRenameShowUiLabelsToEnhancedA11yMode: 12,\n\tAddZoomDirectionInverted: 13,\n} as const\n\nconst CURRENT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrateSnapshot(data: { version: number; user: any }) {\n\tif (data.version < Versions.AddAnimationSpeed) {\n\t\tdata.user.animationSpeed = 1\n\t}\n\tif (data.version < Versions.AddIsSnapMode) {\n\t\tdata.user.isSnapMode = false\n\t}\n\tif (data.version < Versions.MakeFieldsNullable) {\n\t\t// noop\n\t}\n\tif (data.version < Versions.AddEdgeScrollSpeed) {\n\t\tdata.user.edgeScrollSpeed = 1\n\t}\n\tif (data.version < Versions.AddExcalidrawSelectMode) {\n\t\tdata.user.isWrapMode = false\n\t}\n\tif (data.version < Versions.AllowSystemColorScheme) {\n\t\tif (data.user.isDarkMode === true) {\n\t\t\tdata.user.colorScheme = 'dark'\n\t\t} else if (data.user.isDarkMode === false) {\n\t\t\tdata.user.colorScheme = 'light'\n\t\t}\n\t\tdelete data.user.isDarkMode\n\t}\n\n\tif (data.version < Versions.AddDynamicSizeMode) {\n\t\tdata.user.isDynamicSizeMode = false\n\t}\n\tif (data.version < Versions.AddPasteAtCursor) {\n\t\tdata.user.isPasteAtCursorMode = false\n\t}\n\tif (data.version < Versions.AddKeyboardShortcuts) {\n\t\tdata.user.areKeyboardShortcutsEnabled = true\n\t}\n\tif (data.version < Versions.AddShowUiLabels) {\n\t\tdata.user.showUiLabels = false\n\t}\n\tif (data.version < Versions.RenameShowUiLabelsToEnhancedA11yMode) {\n\t\tdata.user.enhancedA11yMode = data.user.showUiLabels\n\t\tdelete data.user.showUiLabels\n\t}\n\n\tif (data.version < Versions.AddPointerPeripheral) {\n\t\tdata.user.inputMode = null\n\t}\n\n\tif (data.version < Versions.AddZoomDirectionInverted) {\n\t\tdata.user.isZoomDirectionInverted = false\n\t}\n\n\t// finally\n\tdata.version = CURRENT_VERSION\n}\n\n/** @internal */\nexport const USER_COLORS = [\n\t'#FF802B',\n\t'#EC5E41',\n\t'#F2555A',\n\t'#F04F88',\n\t'#E34BA9',\n\t'#BD54C6',\n\t'#9D5BD2',\n\t'#7B66DC',\n\t'#02B1CC',\n\t'#11B3A3',\n\t'#39B178',\n\t'#55B467',\n] as const\n\nfunction getRandomColor() {\n\treturn USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]\n}\n\n/** @internal */\nexport function userPrefersReducedMotion() {\n\tif (typeof window !== 'undefined' && window.matchMedia) {\n\t\treturn window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false\n\t}\n\n\treturn false\n}\n\n/** @public */\nexport const defaultUserPreferences = Object.freeze({\n\tname: '',\n\tlocale: getDefaultTranslationLocale(),\n\tcolor: getRandomColor(),\n\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tedgeScrollSpeed: 1,\n\tanimationSpeed: userPrefersReducedMotion() ? 0 : 1,\n\tareKeyboardShortcutsEnabled: true,\n\tisSnapMode: false,\n\tisWrapMode: false,\n\tisDynamicSizeMode: false,\n\tisPasteAtCursorMode: false,\n\tenhancedA11yMode: false,\n\tcolorScheme: 'light',\n\tinputMode: null,\n\tisZoomDirectionInverted: false,\n}) satisfies Readonly<Omit<TLUserPreferences, 'id'>>\n\n/** @public */\nexport function getFreshUserPreferences(): TLUserPreferences {\n\treturn {\n\t\tid: uniqueId(),\n\t\tcolor: getRandomColor(),\n\t}\n}\n\nfunction migrateUserPreferences(userData: unknown): TLUserPreferences {\n\tif (userData === null || typeof userData !== 'object') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tif (!('version' in userData) || !('user' in userData) || typeof userData.version !== 'number') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tconst snapshot = structuredClone(userData) as any\n\n\tmigrateSnapshot(snapshot)\n\n\ttry {\n\t\treturn userTypeValidator.validate(snapshot.user)\n\t} catch {\n\t\treturn getFreshUserPreferences()\n\t}\n}\n\nfunction loadUserPreferences(): TLUserPreferences {\n\tconst userData = (JSON.parse(getFromLocalStorage(USER_DATA_KEY) || 'null') ??\n\t\tnull) as null | UserDataSnapshot\n\n\treturn migrateUserPreferences(userData)\n}\n\nconst globalUserPreferences = atom<TLUserPreferences | null>('globalUserData', null)\n\nfunction storeUserPreferences() {\n\tsetInLocalStorage(\n\t\tUSER_DATA_KEY,\n\t\tJSON.stringify({\n\t\t\tversion: CURRENT_VERSION,\n\t\t\tuser: globalUserPreferences.get(),\n\t\t})\n\t)\n}\n\n/** @public */\nexport function setUserPreferences(user: TLUserPreferences) {\n\tuserTypeValidator.validate(user)\n\tglobalUserPreferences.set(user)\n\tstoreUserPreferences()\n\tbroadcastUserPreferencesChange()\n}\n\nconst isTest = typeof process !== 'undefined' && process.env.NODE_ENV === 'test'\n\nconst channel =\n\ttypeof BroadcastChannel !== 'undefined' && !isTest\n\t\t? new BroadcastChannel('tldraw-user-sync')\n\t\t: null\n\nchannel?.addEventListener('message', (e) => {\n\tconst data = e.data as undefined | UserChangeBroadcastMessage\n\tif (data?.type === broadcastEventKey && data?.origin !== getBroadcastOrigin()) {\n\t\tglobalUserPreferences.set(migrateUserPreferences(data.data))\n\t}\n})\n\nlet _broadcastOrigin = null as null | string\nfunction getBroadcastOrigin() {\n\tif (_broadcastOrigin === null) {\n\t\t_broadcastOrigin = uniqueId()\n\t}\n\treturn _broadcastOrigin\n}\nconst broadcastEventKey = 'tldraw-user-preferences-change' as const\n\nfunction broadcastUserPreferencesChange() {\n\tchannel?.postMessage({\n\t\ttype: broadcastEventKey,\n\t\torigin: getBroadcastOrigin(),\n\t\tdata: {\n\t\t\tuser: getUserPreferences(),\n\t\t\tversion: CURRENT_VERSION,\n\t\t},\n\t} satisfies UserChangeBroadcastMessage)\n}\n\n/** @public */\nexport function getUserPreferences(): TLUserPreferences {\n\tlet prefs = globalUserPreferences.get()\n\tif (!prefs) {\n\t\tprefs = loadUserPreferences()\n\t\tsetUserPreferences(prefs)\n\t}\n\treturn prefs\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getDefaultTranslationLocale } from '@tldraw/tlschema'\nimport { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\nimport { getGlobalWindow } from '../utils/dom'\n\nconst USER_DATA_KEY = 'TLDRAW_USER_DATA_v3'\n\n/**\n * A user of tldraw\n *\n * @public\n */\nexport interface TLUserPreferences {\n\tid: string\n\tname?: string | null\n\tcolor?: string | null\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale?: string | null\n\tanimationSpeed?: number | null\n\tareKeyboardShortcutsEnabled?: boolean | null\n\tedgeScrollSpeed?: number | null\n\tcolorScheme?: 'light' | 'dark' | 'system'\n\tisSnapMode?: boolean | null\n\tisWrapMode?: boolean | null\n\tisDynamicSizeMode?: boolean | null\n\tisPasteAtCursorMode?: boolean | null\n\tenhancedA11yMode?: boolean | null\n\tinputMode?: 'trackpad' | 'mouse' | null\n\tisZoomDirectionInverted?: boolean | null\n}\n\ninterface UserDataSnapshot {\n\tversion: number\n\tuser: TLUserPreferences\n}\n\ninterface UserChangeBroadcastMessage {\n\ttype: typeof broadcastEventKey\n\torigin: string\n\tdata: UserDataSnapshot\n}\n\n/** @public */\nexport const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUserPreferences>({\n\tid: T.string,\n\tname: T.string.nullable().optional(),\n\tcolor: T.string.nullable().optional(),\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale: T.string.nullable().optional(),\n\tanimationSpeed: T.number.nullable().optional(),\n\tareKeyboardShortcutsEnabled: T.boolean.nullable().optional(),\n\tedgeScrollSpeed: T.number.nullable().optional(),\n\tcolorScheme: T.literalEnum('light', 'dark', 'system').optional(),\n\tisSnapMode: T.boolean.nullable().optional(),\n\tisWrapMode: T.boolean.nullable().optional(),\n\tisDynamicSizeMode: T.boolean.nullable().optional(),\n\tisPasteAtCursorMode: T.boolean.nullable().optional(),\n\tenhancedA11yMode: T.boolean.nullable().optional(),\n\tinputMode: T.literalEnum('trackpad', 'mouse').nullable().optional(),\n\tisZoomDirectionInverted: T.boolean.nullable().optional(),\n})\n\nconst Versions = {\n\tAddAnimationSpeed: 1,\n\tAddIsSnapMode: 2,\n\tMakeFieldsNullable: 3,\n\tAddEdgeScrollSpeed: 4,\n\tAddExcalidrawSelectMode: 5,\n\tAddDynamicSizeMode: 6,\n\tAllowSystemColorScheme: 7,\n\tAddPasteAtCursor: 8,\n\tAddKeyboardShortcuts: 9,\n\tAddShowUiLabels: 10,\n\tAddPointerPeripheral: 11,\n\tRenameShowUiLabelsToEnhancedA11yMode: 12,\n\tAddZoomDirectionInverted: 13,\n} as const\n\nconst CURRENT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrateSnapshot(data: { version: number; user: any }) {\n\tif (data.version < Versions.AddAnimationSpeed) {\n\t\tdata.user.animationSpeed = 1\n\t}\n\tif (data.version < Versions.AddIsSnapMode) {\n\t\tdata.user.isSnapMode = false\n\t}\n\tif (data.version < Versions.MakeFieldsNullable) {\n\t\t// noop\n\t}\n\tif (data.version < Versions.AddEdgeScrollSpeed) {\n\t\tdata.user.edgeScrollSpeed = 1\n\t}\n\tif (data.version < Versions.AddExcalidrawSelectMode) {\n\t\tdata.user.isWrapMode = false\n\t}\n\tif (data.version < Versions.AllowSystemColorScheme) {\n\t\tif (data.user.isDarkMode === true) {\n\t\t\tdata.user.colorScheme = 'dark'\n\t\t} else if (data.user.isDarkMode === false) {\n\t\t\tdata.user.colorScheme = 'light'\n\t\t}\n\t\tdelete data.user.isDarkMode\n\t}\n\n\tif (data.version < Versions.AddDynamicSizeMode) {\n\t\tdata.user.isDynamicSizeMode = false\n\t}\n\tif (data.version < Versions.AddPasteAtCursor) {\n\t\tdata.user.isPasteAtCursorMode = false\n\t}\n\tif (data.version < Versions.AddKeyboardShortcuts) {\n\t\tdata.user.areKeyboardShortcutsEnabled = true\n\t}\n\tif (data.version < Versions.AddShowUiLabels) {\n\t\tdata.user.showUiLabels = false\n\t}\n\tif (data.version < Versions.RenameShowUiLabelsToEnhancedA11yMode) {\n\t\tdata.user.enhancedA11yMode = data.user.showUiLabels\n\t\tdelete data.user.showUiLabels\n\t}\n\n\tif (data.version < Versions.AddPointerPeripheral) {\n\t\tdata.user.inputMode = null\n\t}\n\n\tif (data.version < Versions.AddZoomDirectionInverted) {\n\t\tdata.user.isZoomDirectionInverted = false\n\t}\n\n\t// finally\n\tdata.version = CURRENT_VERSION\n}\n\n/** @internal */\nexport const USER_COLORS = [\n\t'#FF802B',\n\t'#EC5E41',\n\t'#F2555A',\n\t'#F04F88',\n\t'#E34BA9',\n\t'#BD54C6',\n\t'#9D5BD2',\n\t'#7B66DC',\n\t'#02B1CC',\n\t'#11B3A3',\n\t'#39B178',\n\t'#55B467',\n] as const\n\nfunction getRandomColor() {\n\treturn USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]\n}\n\n/** @internal */\nexport function userPrefersReducedMotion() {\n\tif (typeof window !== 'undefined' && getGlobalWindow().matchMedia) {\n\t\treturn getGlobalWindow().matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false\n\t}\n\n\treturn false\n}\n\n/** @public */\nexport const defaultUserPreferences = Object.freeze({\n\tname: '',\n\tlocale: getDefaultTranslationLocale(),\n\tcolor: getRandomColor(),\n\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tedgeScrollSpeed: 1,\n\tanimationSpeed: userPrefersReducedMotion() ? 0 : 1,\n\tareKeyboardShortcutsEnabled: true,\n\tisSnapMode: false,\n\tisWrapMode: false,\n\tisDynamicSizeMode: false,\n\tisPasteAtCursorMode: false,\n\tenhancedA11yMode: false,\n\tcolorScheme: 'light',\n\tinputMode: null,\n\tisZoomDirectionInverted: false,\n}) satisfies Readonly<Omit<TLUserPreferences, 'id'>>\n\n/** @public */\nexport function getFreshUserPreferences(): TLUserPreferences {\n\treturn {\n\t\tid: uniqueId(),\n\t\tcolor: getRandomColor(),\n\t}\n}\n\nfunction migrateUserPreferences(userData: unknown): TLUserPreferences {\n\tif (userData === null || typeof userData !== 'object') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tif (!('version' in userData) || !('user' in userData) || typeof userData.version !== 'number') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tconst snapshot = structuredClone(userData) as any\n\n\tmigrateSnapshot(snapshot)\n\n\ttry {\n\t\treturn userTypeValidator.validate(snapshot.user)\n\t} catch {\n\t\treturn getFreshUserPreferences()\n\t}\n}\n\nfunction loadUserPreferences(): TLUserPreferences {\n\tconst userData = (JSON.parse(getFromLocalStorage(USER_DATA_KEY) || 'null') ??\n\t\tnull) as null | UserDataSnapshot\n\n\treturn migrateUserPreferences(userData)\n}\n\nconst globalUserPreferences = atom<TLUserPreferences | null>('globalUserData', null)\n\nfunction storeUserPreferences() {\n\tsetInLocalStorage(\n\t\tUSER_DATA_KEY,\n\t\tJSON.stringify({\n\t\t\tversion: CURRENT_VERSION,\n\t\t\tuser: globalUserPreferences.get(),\n\t\t})\n\t)\n}\n\n/** @public */\nexport function setUserPreferences(user: TLUserPreferences) {\n\tuserTypeValidator.validate(user)\n\tglobalUserPreferences.set(user)\n\tstoreUserPreferences()\n\tbroadcastUserPreferencesChange()\n}\n\nconst isTest = typeof process !== 'undefined' && process.env.NODE_ENV === 'test'\n\nconst channel =\n\ttypeof BroadcastChannel !== 'undefined' && !isTest\n\t\t? new BroadcastChannel('tldraw-user-sync')\n\t\t: null\n\nchannel?.addEventListener('message', (e) => {\n\tconst data = e.data as undefined | UserChangeBroadcastMessage\n\tif (data?.type === broadcastEventKey && data?.origin !== getBroadcastOrigin()) {\n\t\tglobalUserPreferences.set(migrateUserPreferences(data.data))\n\t}\n})\n\nlet _broadcastOrigin = null as null | string\nfunction getBroadcastOrigin() {\n\tif (_broadcastOrigin === null) {\n\t\t_broadcastOrigin = uniqueId()\n\t}\n\treturn _broadcastOrigin\n}\nconst broadcastEventKey = 'tldraw-user-preferences-change' as const\n\nfunction broadcastUserPreferencesChange() {\n\tchannel?.postMessage({\n\t\ttype: broadcastEventKey,\n\t\torigin: getBroadcastOrigin(),\n\t\tdata: {\n\t\t\tuser: getUserPreferences(),\n\t\t\tversion: CURRENT_VERSION,\n\t\t},\n\t} satisfies UserChangeBroadcastMessage)\n}\n\n/** @public */\nexport function getUserPreferences(): TLUserPreferences {\n\tlet prefs = globalUserPreferences.get()\n\tif (!prefs) {\n\t\tprefs = loadUserPreferences()\n\t\tsetUserPreferences(prefs)\n\t}\n\treturn prefs\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -18,6 +18,7 @@ function createTLSchemaFromUtils(opts) {
18
18
  return createTLSchema({
19
19
  shapes: "shapeUtils" in opts && opts.shapeUtils ? utilsToMap(checkShapesAndAddCore(opts.shapeUtils)) : void 0,
20
20
  bindings: "bindingUtils" in opts && opts.bindingUtils ? utilsToMap(checkBindings(opts.bindingUtils)) : void 0,
21
+ records: "records" in opts ? opts.records : void 0,
21
22
  migrations: "migrations" in opts ? opts.migrations : void 0
22
23
  });
23
24
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/config/createTLStore.ts"],
4
- "sourcesContent": ["import { Signal } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tcreateTLSchema,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tonMount,\n\tcollaboration,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\tonMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
5
- "mappings": "AACA,SAA2D,aAA0B;AACrF;AAAA,EAOC;AAAA,OACM;AACP,SAAS,aAAa,cAAc;AACpC,SAAS,cAAc;AACvB,SAA2B,oBAAoB;AAC/C,SAAsC,qBAAqB;AAC3D,SAAoC,6BAA6B;AA4CjE,MAAM,sBAA4D,CAAC,UAAU,MAAM,MAAM;AAGlF,MAAM,yBAAuC;AAAA,EACnD,QAAQ,OAAO,GAAG,SAAS;AAC1B,WAAO,EAAE,KAAK,MAAM,YAAY,cAAc,IAAI,EAAE;AAAA,EACrD;AACD;AAUO,SAAS,wBACf,MACsC;AACtC,MAAI,YAAY,QAAQ,KAAK,OAAQ,QAAO,KAAK;AAEjD,SAAO,eAAe;AAAA,IACrB,QACC,gBAAgB,QAAQ,KAAK,aAC1B,WAAW,sBAAsB,KAAK,UAAU,CAAC,IACjD;AAAA,IACJ,UACC,kBAAkB,QAAQ,KAAK,eAC5B,WAAW,cAAc,KAAK,YAAY,CAAC,IAC3C;AAAA,IACJ,YAAY,gBAAgB,OAAO,KAAK,aAAa;AAAA,EACtD,CAAC;AACF;AASO,SAAS,cAAc;AAAA,EAC7B;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,GAAG;AACJ,IAAoB,CAAC,GAAY;AAChC,QAAM,SAAS,wBAAwB,IAAI;AAE3C,QAAM,QAAQ,IAAI,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACP,QAAQ,OAAO;AAAA,QACf,SAAS,OAAO,WAAW;AAAA,QAC3B,QAAQ,OAAO,WAAW,MAAM,QAAQ,QAAQ;AAAA,MACjD;AAAA,MACA,SAAS,CAAC,WAAW;AACpB,eAAO,kBAAkB,MAAM;AAC/B,kBAAU,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACD;AAAA,EACD,CAAC;AAED,MAAI,KAAK,UAAU;AAClB,QAAI,YAAa,OAAM,IAAI,MAAM,8CAA8C;AAC/E,iBAAa,OAAO,KAAK,UAAU,EAAE,4BAA4B,KAAK,CAAC;AAAA,EACxE;AAEA,SAAO;AACR;AAEA,SAAS,WAAyD,OAAY;AAC7E,SAAO,OAAO;AAAA,IACb,MAAM,IAAI,CAAC,MAAiC;AAAA,MAC3C,EAAE;AAAA,MACF;AAAA,QACC,OAAO,EAAE;AAAA,QACT,YAAY,EAAE;AAAA,MACf;AAAA,IACD,CAAC;AAAA,EACF;AACD;",
4
+ "sourcesContent": ["import { Signal } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tCustomRecordInfo,\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tcreateTLSchema,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t\t\trecords?: Record<string, CustomRecordInfo>\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\trecords: 'records' in opts ? opts.records : undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tonMount,\n\tcollaboration,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\tonMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
5
+ "mappings": "AACA,SAA2D,aAA0B;AACrF;AAAA,EAQC;AAAA,OACM;AACP,SAAS,aAAa,cAAc;AACpC,SAAS,cAAc;AACvB,SAA2B,oBAAoB;AAC/C,SAAsC,qBAAqB;AAC3D,SAAoC,6BAA6B;AA6CjE,MAAM,sBAA4D,CAAC,UAAU,MAAM,MAAM;AAGlF,MAAM,yBAAuC;AAAA,EACnD,QAAQ,OAAO,GAAG,SAAS;AAC1B,WAAO,EAAE,KAAK,MAAM,YAAY,cAAc,IAAI,EAAE;AAAA,EACrD;AACD;AAUO,SAAS,wBACf,MACsC;AACtC,MAAI,YAAY,QAAQ,KAAK,OAAQ,QAAO,KAAK;AAEjD,SAAO,eAAe;AAAA,IACrB,QACC,gBAAgB,QAAQ,KAAK,aAC1B,WAAW,sBAAsB,KAAK,UAAU,CAAC,IACjD;AAAA,IACJ,UACC,kBAAkB,QAAQ,KAAK,eAC5B,WAAW,cAAc,KAAK,YAAY,CAAC,IAC3C;AAAA,IACJ,SAAS,aAAa,OAAO,KAAK,UAAU;AAAA,IAC5C,YAAY,gBAAgB,OAAO,KAAK,aAAa;AAAA,EACtD,CAAC;AACF;AASO,SAAS,cAAc;AAAA,EAC7B;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,GAAG;AACJ,IAAoB,CAAC,GAAY;AAChC,QAAM,SAAS,wBAAwB,IAAI;AAE3C,QAAM,QAAQ,IAAI,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACP,QAAQ,OAAO;AAAA,QACf,SAAS,OAAO,WAAW;AAAA,QAC3B,QAAQ,OAAO,WAAW,MAAM,QAAQ,QAAQ;AAAA,MACjD;AAAA,MACA,SAAS,CAAC,WAAW;AACpB,eAAO,kBAAkB,MAAM;AAC/B,kBAAU,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACD;AAAA,EACD,CAAC;AAED,MAAI,KAAK,UAAU;AAClB,QAAI,YAAa,OAAM,IAAI,MAAM,8CAA8C;AAC/E,iBAAa,OAAO,KAAK,UAAU,EAAE,4BAA4B,KAAK,CAAC;AAAA,EACxE;AAEA,SAAO;AACR;AAEA,SAAS,WAAyD,OAAY;AAC7E,SAAO,OAAO;AAAA,IACb,MAAM,IAAI,CAAC,MAAiC;AAAA,MAC3C,EAAE;AAAA,MACF;AAAA,QACC,OAAO,EAAE;AAAA,QACT,YAAY,EAAE;AAAA,MACf;AAAA,IACD,CAAC;AAAA,EACF;AACD;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/config/createTLUser.ts"],
4
- "sourcesContent": ["import { Signal, computed, isSignal } from '@tldraw/state'\nimport { useAtom } from '@tldraw/state-react'\nimport { useEffect, useMemo } from 'react'\nimport { useShallowObjectIdentity } from '../hooks/useIdentity'\nimport { TLUserPreferences, getUserPreferences, setUserPreferences } from './TLUserPreferences'\n\n/** @public */\nexport interface TLUser {\n\treadonly userPreferences: Signal<TLUserPreferences>\n\t// eslint-disable-next-line @typescript-eslint/method-signature-style\n\treadonly setUserPreferences: (userPreferences: TLUserPreferences) => void\n}\n\nconst defaultLocalStorageUserPrefs = computed('defaultLocalStorageUserPrefs', () =>\n\tgetUserPreferences()\n)\n\n/** @public */\nexport function createTLUser(\n\topts = {} as {\n\t\tuserPreferences?: Signal<TLUserPreferences>\n\t\t// eslint-disable-next-line @typescript-eslint/method-signature-style\n\t\tsetUserPreferences?: (userPreferences: TLUserPreferences) => void\n\t}\n): TLUser {\n\treturn {\n\t\tuserPreferences: opts.userPreferences ?? defaultLocalStorageUserPrefs,\n\t\tsetUserPreferences: opts.setUserPreferences ?? setUserPreferences,\n\t}\n}\n\n/**\n * @public\n */\nexport function useTldrawUser(opts: {\n\tuserPreferences?: Signal<TLUserPreferences> | TLUserPreferences\n\t// eslint-disable-next-line @typescript-eslint/method-signature-style\n\tsetUserPreferences?: (userPreferences: TLUserPreferences) => void\n}): TLUser {\n\tconst prefs = useShallowObjectIdentity(opts.userPreferences ?? defaultLocalStorageUserPrefs)\n\tconst userAtom = useAtom<TLUserPreferences | Signal<TLUserPreferences>>('userAtom', prefs)\n\tuseEffect(() => {\n\t\tuserAtom.set(prefs)\n\t}, [prefs, userAtom])\n\n\treturn useMemo(\n\t\t() =>\n\t\t\tcreateTLUser({\n\t\t\t\tuserPreferences: computed('userPreferences', () => {\n\t\t\t\t\tconst userStuff = userAtom.get()\n\t\t\t\t\treturn isSignal(userStuff) ? userStuff.get() : userStuff\n\t\t\t\t}),\n\t\t\t\tsetUserPreferences: opts.setUserPreferences,\n\t\t\t}),\n\t\t[userAtom, opts.setUserPreferences]\n\t)\n}\n"],
4
+ "sourcesContent": ["import { Signal, computed, isSignal } from '@tldraw/state'\nimport { useAtom } from '@tldraw/state-react'\nimport { useEffect, useMemo } from 'react'\nimport { useShallowObjectIdentity } from '../hooks/useIdentity'\nimport { TLUserPreferences, getUserPreferences, setUserPreferences } from './TLUserPreferences'\n\n/** @public */\nexport interface TLUser {\n\treadonly userPreferences: Signal<TLUserPreferences>\n\t// eslint-disable-next-line tldraw/method-signature-style\n\treadonly setUserPreferences: (userPreferences: TLUserPreferences) => void\n}\n\nconst defaultLocalStorageUserPrefs = computed('defaultLocalStorageUserPrefs', () =>\n\tgetUserPreferences()\n)\n\n/** @public */\nexport function createTLUser(\n\topts = {} as {\n\t\tuserPreferences?: Signal<TLUserPreferences>\n\t\t// eslint-disable-next-line tldraw/method-signature-style\n\t\tsetUserPreferences?: (userPreferences: TLUserPreferences) => void\n\t}\n): TLUser {\n\treturn {\n\t\tuserPreferences: opts.userPreferences ?? defaultLocalStorageUserPrefs,\n\t\tsetUserPreferences: opts.setUserPreferences ?? setUserPreferences,\n\t}\n}\n\n/**\n * @public\n */\nexport function useTldrawUser(opts: {\n\tuserPreferences?: Signal<TLUserPreferences> | TLUserPreferences\n\t// eslint-disable-next-line tldraw/method-signature-style\n\tsetUserPreferences?: (userPreferences: TLUserPreferences) => void\n}): TLUser {\n\tconst prefs = useShallowObjectIdentity(opts.userPreferences ?? defaultLocalStorageUserPrefs)\n\tconst userAtom = useAtom<TLUserPreferences | Signal<TLUserPreferences>>('userAtom', prefs)\n\tuseEffect(() => {\n\t\tuserAtom.set(prefs)\n\t}, [prefs, userAtom])\n\n\treturn useMemo(\n\t\t() =>\n\t\t\tcreateTLUser({\n\t\t\t\tuserPreferences: computed('userPreferences', () => {\n\t\t\t\t\tconst userStuff = userAtom.get()\n\t\t\t\t\treturn isSignal(userStuff) ? userStuff.get() : userStuff\n\t\t\t\t}),\n\t\t\t\tsetUserPreferences: opts.setUserPreferences,\n\t\t\t}),\n\t\t[userAtom, opts.setUserPreferences]\n\t)\n}\n"],
5
5
  "mappings": "AAAA,SAAiB,UAAU,gBAAgB;AAC3C,SAAS,eAAe;AACxB,SAAS,WAAW,eAAe;AACnC,SAAS,gCAAgC;AACzC,SAA4B,oBAAoB,0BAA0B;AAS1E,MAAM,+BAA+B;AAAA,EAAS;AAAA,EAAgC,MAC7E,mBAAmB;AACpB;AAGO,SAAS,aACf,OAAO,CAAC,GAKC;AACT,SAAO;AAAA,IACN,iBAAiB,KAAK,mBAAmB;AAAA,IACzC,oBAAoB,KAAK,sBAAsB;AAAA,EAChD;AACD;AAKO,SAAS,cAAc,MAInB;AACV,QAAM,QAAQ,yBAAyB,KAAK,mBAAmB,4BAA4B;AAC3F,QAAM,WAAW,QAAuD,YAAY,KAAK;AACzF,YAAU,MAAM;AACf,aAAS,IAAI,KAAK;AAAA,EACnB,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpB,SAAO;AAAA,IACN,MACC,aAAa;AAAA,MACZ,iBAAiB,SAAS,mBAAmB,MAAM;AAClD,cAAM,YAAY,SAAS,IAAI;AAC/B,eAAO,SAAS,SAAS,IAAI,UAAU,IAAI,IAAI;AAAA,MAChD,CAAC;AAAA,MACD,oBAAoB,KAAK;AAAA,IAC1B,CAAC;AAAA,IACF,CAAC,UAAU,KAAK,kBAAkB;AAAA,EACnC;AACD;",
6
6
  "names": []
7
7
  }