@formicoidea/labre-core 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (637) hide show
  1. package/dist/_pkgs/affine-block-attachment/attachment-block.js +1 -1
  2. package/dist/_pkgs/affine-block-callout/callout-block.d.ts +6 -0
  3. package/dist/_pkgs/affine-block-callout/callout-block.js +26 -4
  4. package/dist/_pkgs/affine-block-callout/callout-keymap.js +59 -19
  5. package/dist/_pkgs/affine-block-callout/commands/callout-to-paragraph.d.ts +20 -0
  6. package/dist/_pkgs/affine-block-callout/commands/callout-to-paragraph.js +60 -0
  7. package/dist/_pkgs/affine-block-callout/commands/split-callout.d.ts +17 -0
  8. package/dist/_pkgs/affine-block-callout/commands/split-callout.js +42 -0
  9. package/dist/_pkgs/affine-block-callout/configs/slash-menu.js +9 -6
  10. package/dist/_pkgs/affine-block-callout/emoji-margin.d.ts +9 -0
  11. package/dist/_pkgs/affine-block-callout/emoji-margin.js +36 -0
  12. package/dist/_pkgs/affine-block-callout/emoji-menu.d.ts +5 -1
  13. package/dist/_pkgs/affine-block-callout/emoji-menu.js +5 -0
  14. package/dist/_pkgs/affine-block-code/code-block-inline.js +1 -1
  15. package/dist/_pkgs/affine-block-code/code-block.d.ts +14 -0
  16. package/dist/_pkgs/affine-block-code/code-block.js +44 -6
  17. package/dist/_pkgs/affine-block-code/code-toolbar/components/code-toolbar.d.ts +2 -0
  18. package/dist/_pkgs/affine-block-code/code-toolbar/components/code-toolbar.js +23 -14
  19. package/dist/_pkgs/affine-block-code/code-toolbar/components/more-menu.d.ts +16 -0
  20. package/dist/_pkgs/affine-block-code/code-toolbar/components/more-menu.js +93 -0
  21. package/dist/_pkgs/affine-block-code/code-toolbar/config.js +54 -5
  22. package/dist/_pkgs/affine-block-code/code-toolbar/index.js +1 -1
  23. package/dist/_pkgs/affine-block-code/effects.d.ts +2 -0
  24. package/dist/_pkgs/affine-block-code/effects.js +2 -0
  25. package/dist/_pkgs/affine-block-code/highlight/affine-code-unit.js +6 -1
  26. package/dist/_pkgs/affine-block-code/index.d.ts +1 -0
  27. package/dist/_pkgs/affine-block-code/index.js +1 -0
  28. package/dist/_pkgs/affine-block-code/line-numbers.d.ts +25 -0
  29. package/dist/_pkgs/affine-block-code/line-numbers.js +27 -0
  30. package/dist/_pkgs/affine-block-code/styles.js +31 -0
  31. package/dist/_pkgs/affine-block-data-view/data-view-block.js +1 -0
  32. package/dist/_pkgs/affine-block-database/components/title/index.js +4 -1
  33. package/dist/_pkgs/affine-block-database/configs/slash-menu.js +28 -1
  34. package/dist/_pkgs/affine-block-database/data-source.js +1 -2
  35. package/dist/_pkgs/affine-block-database/database-block.js +13 -0
  36. package/dist/_pkgs/affine-block-database/external-data-source.js +1 -1
  37. package/dist/_pkgs/affine-block-database/properties/paste-url.d.ts +24 -0
  38. package/dist/_pkgs/affine-block-database/properties/paste-url.js +98 -0
  39. package/dist/_pkgs/affine-block-database/properties/rich-text/cell-renderer.js +9 -19
  40. package/dist/_pkgs/affine-block-database/properties/title/text.js +20 -25
  41. package/dist/_pkgs/affine-block-database/views/index.js +1 -0
  42. package/dist/_pkgs/affine-block-edgeless-text/edgeless-text-block.js +11 -1
  43. package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.d.ts +3 -0
  44. package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.js +48 -1
  45. package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/font-size.d.ts +17 -0
  46. package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/font-size.js +24 -0
  47. package/dist/_pkgs/affine-block-embed/embed-figma-block/embed-figma-service.js +1 -1
  48. package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.js +2 -2
  49. package/dist/_pkgs/affine-block-embed-doc/common/doc-trashed.d.ts +9 -0
  50. package/dist/_pkgs/affine-block-embed-doc/common/doc-trashed.js +10 -0
  51. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/toolbar.js +1 -1
  52. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/embed-linked-doc-block.js +8 -4
  53. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/utils.js +1 -1
  54. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/toolbar.js +1 -1
  55. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.d.ts +4 -0
  56. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.js +23 -4
  57. package/dist/_pkgs/affine-block-frame/frame-manager.d.ts +13 -0
  58. package/dist/_pkgs/affine-block-frame/frame-manager.js +34 -2
  59. package/dist/_pkgs/affine-block-frame/frame-tool.js +1 -1
  60. package/dist/_pkgs/affine-block-image/components/page-image-block.js +1 -1
  61. package/dist/_pkgs/affine-block-image/image-edgeless-block.js +1 -1
  62. package/dist/_pkgs/affine-block-latex/styles.js +6 -1
  63. package/dist/_pkgs/affine-block-list/utils/forward-delete.js +1 -1
  64. package/dist/_pkgs/affine-block-note/commands/select-block.js +1 -1
  65. package/dist/_pkgs/affine-block-note/commands/select-blocks-between.js +1 -1
  66. package/dist/_pkgs/affine-block-note/move-block.js +1 -1
  67. package/dist/_pkgs/affine-block-note/note-edgeless-block.d.ts +9 -0
  68. package/dist/_pkgs/affine-block-note/note-edgeless-block.js +29 -1
  69. package/dist/_pkgs/affine-block-paragraph/utils/forward-delete.js +2 -2
  70. package/dist/_pkgs/affine-block-paragraph/utils/merge-with-prev.js +1 -1
  71. package/dist/_pkgs/affine-block-root/commands/pivot-commands.d.ts +37 -0
  72. package/dist/_pkgs/affine-block-root/commands/pivot-commands.js +168 -0
  73. package/dist/_pkgs/affine-block-root/commands/reading-commands.d.ts +23 -0
  74. package/dist/_pkgs/affine-block-root/commands/reading-commands.js +107 -0
  75. package/dist/_pkgs/affine-block-root/commands/tag-commands.d.ts +47 -0
  76. package/dist/_pkgs/affine-block-root/commands/tag-commands.js +159 -0
  77. package/dist/_pkgs/affine-block-root/configs/toolbar.d.ts +1 -0
  78. package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.js +10 -3
  79. package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/render-linked-doc.js +1 -1
  80. package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.js +27 -2
  81. package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.js +11 -2
  82. package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-service.js +14 -0
  83. package/dist/_pkgs/affine-block-root/edgeless/index.d.ts +1 -0
  84. package/dist/_pkgs/affine-block-root/edgeless/index.js +1 -0
  85. package/dist/_pkgs/affine-block-root/edgeless/reserved-keys.d.ts +21 -0
  86. package/dist/_pkgs/affine-block-root/edgeless/reserved-keys.js +34 -0
  87. package/dist/_pkgs/affine-block-root/edgeless/utils/clipboard-utils.js +1 -1
  88. package/dist/_pkgs/affine-block-root/edgeless/utils/clone-utils.d.ts +7 -1
  89. package/dist/_pkgs/affine-block-root/edgeless/utils/clone-utils.js +11 -2
  90. package/dist/_pkgs/affine-block-root/index.d.ts +4 -1
  91. package/dist/_pkgs/affine-block-root/index.js +4 -1
  92. package/dist/_pkgs/affine-block-root/keyboard/commands.d.ts +2 -0
  93. package/dist/_pkgs/affine-block-root/keyboard/commands.js +147 -0
  94. package/dist/_pkgs/affine-block-root/view.js +13 -4
  95. package/dist/_pkgs/affine-block-surface/adapters/markdown/element-adapter/type.js +1 -1
  96. package/dist/_pkgs/affine-block-surface/adapters/plain-text/element-adapter/type.js +1 -1
  97. package/dist/_pkgs/affine-block-surface/commands/reassociate-connectors.js +0 -1
  98. package/dist/_pkgs/affine-block-surface/effects.js +6 -0
  99. package/dist/_pkgs/affine-block-surface/element-model/index.d.ts +21 -3
  100. package/dist/_pkgs/affine-block-surface/element-model/index.js +14 -2
  101. package/dist/_pkgs/affine-block-surface/extensions/audit.d.ts +107 -0
  102. package/dist/_pkgs/affine-block-surface/extensions/audit.js +489 -0
  103. package/dist/_pkgs/affine-block-surface/extensions/crud-extension.d.ts +14 -0
  104. package/dist/_pkgs/affine-block-surface/extensions/crud-extension.js +37 -5
  105. package/dist/_pkgs/affine-block-surface/extensions/editor-anchored-panel.d.ts +133 -0
  106. package/dist/_pkgs/affine-block-surface/extensions/editor-anchored-panel.js +327 -0
  107. package/dist/_pkgs/affine-block-surface/extensions/element-renderer.js +1 -1
  108. package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.js +1 -1
  109. package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +17 -0
  110. package/dist/_pkgs/affine-block-surface/extensions/index.js +17 -0
  111. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.d.ts +172 -0
  112. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +393 -0
  113. package/dist/_pkgs/affine-block-surface/extensions/interchange.d.ts +306 -0
  114. package/dist/_pkgs/affine-block-surface/extensions/interchange.js +64 -0
  115. package/dist/_pkgs/affine-block-surface/extensions/map-quality-widget.d.ts +146 -0
  116. package/dist/_pkgs/affine-block-surface/extensions/map-quality-widget.js +528 -0
  117. package/dist/_pkgs/affine-block-surface/extensions/map-quality.d.ts +109 -0
  118. package/dist/_pkgs/affine-block-surface/extensions/map-quality.js +84 -0
  119. package/dist/_pkgs/affine-block-surface/extensions/morph-toolbar.d.ts +248 -0
  120. package/dist/_pkgs/affine-block-surface/extensions/morph-toolbar.js +248 -0
  121. package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.d.ts +15 -0
  122. package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.js +158 -0
  123. package/dist/_pkgs/affine-block-surface/extensions/reading-widget.d.ts +145 -0
  124. package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +588 -0
  125. package/dist/_pkgs/affine-block-surface/extensions/reading.d.ts +494 -0
  126. package/dist/_pkgs/affine-block-surface/extensions/reading.js +767 -0
  127. package/dist/_pkgs/affine-block-surface/extensions/spotlight.d.ts +45 -0
  128. package/dist/_pkgs/affine-block-surface/extensions/spotlight.js +177 -0
  129. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.d.ts +107 -0
  130. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.js +958 -0
  131. package/dist/_pkgs/affine-block-surface/extensions/tags-toolbar.d.ts +10 -0
  132. package/dist/_pkgs/affine-block-surface/extensions/tags-toolbar.js +295 -0
  133. package/dist/_pkgs/affine-block-surface/extensions/validation-toolbar.d.ts +27 -0
  134. package/dist/_pkgs/affine-block-surface/extensions/validation-toolbar.js +361 -0
  135. package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +2129 -0
  136. package/dist/_pkgs/affine-block-surface/extensions/validation.js +4620 -0
  137. package/dist/_pkgs/affine-block-surface/extensions/violation-detail-widget.d.ts +330 -0
  138. package/dist/_pkgs/affine-block-surface/extensions/violation-detail-widget.js +1004 -0
  139. package/dist/_pkgs/affine-block-surface/extensions/violation-timeline.d.ts +80 -0
  140. package/dist/_pkgs/affine-block-surface/extensions/violation-timeline.js +123 -0
  141. package/dist/_pkgs/affine-block-surface/framework-background/def.d.ts +610 -0
  142. package/dist/_pkgs/affine-block-surface/framework-background/def.js +206 -0
  143. package/dist/_pkgs/affine-block-surface/framework-background/facts.d.ts +188 -0
  144. package/dist/_pkgs/affine-block-surface/framework-background/facts.js +284 -0
  145. package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +5 -0
  146. package/dist/_pkgs/affine-block-surface/framework-background/index.js +5 -0
  147. package/dist/_pkgs/affine-block-surface/framework-background/interaction.d.ts +12 -0
  148. package/dist/_pkgs/affine-block-surface/framework-background/interaction.js +24 -0
  149. package/dist/_pkgs/affine-block-surface/framework-background/labels.d.ts +99 -0
  150. package/dist/_pkgs/affine-block-surface/framework-background/labels.js +193 -0
  151. package/dist/_pkgs/affine-block-surface/framework-background/renderer.d.ts +8 -0
  152. package/dist/_pkgs/affine-block-surface/framework-background/renderer.js +399 -0
  153. package/dist/_pkgs/affine-block-surface/index.d.ts +1 -0
  154. package/dist/_pkgs/affine-block-surface/index.js +1 -0
  155. package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.d.ts +69 -3
  156. package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.js +333 -44
  157. package/dist/_pkgs/affine-block-surface/renderer/dom-renderer.js +18 -2
  158. package/dist/_pkgs/affine-block-surface/renderer/overlay.js +1 -1
  159. package/dist/_pkgs/affine-block-surface/tool/default-tool.js +8 -0
  160. package/dist/_pkgs/affine-block-surface/utils/font.js +9 -3
  161. package/dist/_pkgs/affine-block-surface/view.d.ts +17 -0
  162. package/dist/_pkgs/affine-block-surface/view.js +57 -2
  163. package/dist/_pkgs/affine-block-surface-ref/portal/note.js +2 -2
  164. package/dist/_pkgs/affine-block-table/commands.js +1 -1
  165. package/dist/_pkgs/affine-block-table/selection-controller.d.ts +6 -0
  166. package/dist/_pkgs/affine-block-table/selection-controller.js +24 -1
  167. package/dist/_pkgs/affine-block-table/table-block.js +8 -2
  168. package/dist/_pkgs/affine-block-table/table-cell.js +5 -6
  169. package/dist/_pkgs/affine-block-table/table-keymap.d.ts +18 -0
  170. package/dist/_pkgs/affine-block-table/table-keymap.js +41 -0
  171. package/dist/_pkgs/affine-block-table/utils.d.ts +7 -0
  172. package/dist/_pkgs/affine-block-table/utils.js +12 -0
  173. package/dist/_pkgs/affine-block-table/view.js +2 -0
  174. package/dist/_pkgs/affine-components/caption/captioned-block-component.js +2 -1
  175. package/dist/_pkgs/affine-components/context-menu/button.d.ts +7 -0
  176. package/dist/_pkgs/affine-components/context-menu/button.js +7 -2
  177. package/dist/_pkgs/affine-components/context-menu/input.d.ts +4 -0
  178. package/dist/_pkgs/affine-components/context-menu/input.js +12 -0
  179. package/dist/_pkgs/affine-components/context-menu/menu-all.d.ts +2 -0
  180. package/dist/_pkgs/affine-components/context-menu/menu-renderer.js +8 -1
  181. package/dist/_pkgs/affine-components/context-menu/sub-menu.js +3 -0
  182. package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.js +1 -1
  183. package/dist/_pkgs/affine-components/embed-card-modal/embed-card-edit-modal.js +1 -1
  184. package/dist/_pkgs/affine-components/filterable-list/styles.js +1 -1
  185. package/dist/_pkgs/affine-components/highlight-dropdown-menu/highlight-duotone-icon.js +8 -8
  186. package/dist/_pkgs/affine-components/highlight-dropdown-menu/text-duotone-icon.js +11 -11
  187. package/dist/_pkgs/affine-components/icon-picker/affine-icon-picker-panel.d.ts +28 -0
  188. package/dist/_pkgs/affine-components/icon-picker/affine-icon-picker-panel.js +231 -0
  189. package/dist/_pkgs/affine-components/icon-picker/emoji-data.d.ts +40 -0
  190. package/dist/_pkgs/affine-components/icon-picker/emoji-data.js +99 -0
  191. package/dist/_pkgs/affine-components/icon-picker/emoji-picker-panel.d.ts +32 -0
  192. package/dist/_pkgs/affine-components/icon-picker/emoji-picker-panel.js +276 -0
  193. package/dist/_pkgs/affine-components/icon-picker/icon-data.d.ts +34 -0
  194. package/dist/_pkgs/affine-components/icon-picker/icon-data.js +83 -0
  195. package/dist/_pkgs/affine-components/icon-picker/icon-picker.d.ts +39 -0
  196. package/dist/_pkgs/affine-components/icon-picker/icon-picker.js +233 -0
  197. package/dist/_pkgs/affine-components/icon-picker/index.d.ts +8 -0
  198. package/dist/_pkgs/affine-components/icon-picker/index.js +15 -0
  199. package/dist/_pkgs/affine-components/icon-picker/recent-store.d.ts +8 -0
  200. package/dist/_pkgs/affine-components/icon-picker/recent-store.js +41 -0
  201. package/dist/_pkgs/affine-components/icon-picker/styles.d.ts +5 -0
  202. package/dist/_pkgs/affine-components/icon-picker/styles.js +166 -0
  203. package/dist/_pkgs/affine-components/icon-picker/types.d.ts +22 -0
  204. package/dist/_pkgs/affine-components/icon-picker/types.js +10 -0
  205. package/dist/_pkgs/affine-components/icons/text.js +426 -426
  206. package/dist/_pkgs/affine-components/open-doc-dropdown-menu/dropdown-menu.d.ts +1 -0
  207. package/dist/_pkgs/affine-components/peek/peekable.js +1 -1
  208. package/dist/_pkgs/affine-components/portal/portal.d.ts +1 -1
  209. package/dist/_pkgs/affine-components/toolbar/index.d.ts +1 -0
  210. package/dist/_pkgs/affine-components/toolbar/index.js +1 -0
  211. package/dist/_pkgs/affine-components/toolbar/menu-button.js +2 -1
  212. package/dist/_pkgs/affine-components/toolbar/picker-menu.d.ts +55 -0
  213. package/dist/_pkgs/affine-components/toolbar/picker-menu.js +47 -0
  214. package/dist/_pkgs/affine-components/toolbar/toolbar.js +11 -10
  215. package/dist/_pkgs/affine-foundation/view.js +11 -2
  216. package/dist/_pkgs/affine-fragment-frame-panel/body/frame-panel-body.js +2 -2
  217. package/dist/_pkgs/affine-fragment-frame-panel/header/frame-panel-header.js +2 -2
  218. package/dist/_pkgs/affine-fragment-frame-panel/header/frames-setting-menu.js +1 -1
  219. package/dist/_pkgs/affine-fragment-outline/mobile-outline-panel.js +1 -1
  220. package/dist/_pkgs/affine-gfx-brush/index.d.ts +1 -0
  221. package/dist/_pkgs/affine-gfx-brush/index.js +1 -0
  222. package/dist/_pkgs/affine-gfx-brush/renderer/dom/brush.d.ts +1 -0
  223. package/dist/_pkgs/affine-gfx-brush/renderer/dom/brush.js +11 -0
  224. package/dist/_pkgs/affine-gfx-brush/renderer/dom/highlighter.d.ts +1 -0
  225. package/dist/_pkgs/affine-gfx-brush/renderer/dom/highlighter.js +11 -0
  226. package/dist/_pkgs/affine-gfx-brush/renderer/dom/index.d.ts +2 -0
  227. package/dist/_pkgs/affine-gfx-brush/renderer/dom/index.js +2 -0
  228. package/dist/_pkgs/affine-gfx-brush/renderer/dom/shared.d.ts +14 -0
  229. package/dist/_pkgs/affine-gfx-brush/renderer/dom/shared.js +54 -0
  230. package/dist/_pkgs/affine-gfx-brush/renderer/index.d.ts +1 -0
  231. package/dist/_pkgs/affine-gfx-brush/renderer/index.js +4 -0
  232. package/dist/_pkgs/affine-gfx-brush/toolbar/components/pen/pen-tool-button.js +1 -1
  233. package/dist/_pkgs/affine-gfx-brush/view.d.ts +14 -0
  234. package/dist/_pkgs/affine-gfx-brush/view.js +29 -3
  235. package/dist/_pkgs/affine-gfx-connector/connector-manager.js +39 -16
  236. package/dist/_pkgs/affine-gfx-connector/connector-tool.d.ts +26 -1
  237. package/dist/_pkgs/affine-gfx-connector/connector-tool.js +12 -3
  238. package/dist/_pkgs/affine-gfx-connector/connector-watcher.js +1 -4
  239. package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.d.ts +123 -0
  240. package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.js +282 -0
  241. package/dist/_pkgs/affine-gfx-connector/direction/direction-widget.d.ts +65 -0
  242. package/dist/_pkgs/affine-gfx-connector/direction/direction-widget.js +395 -0
  243. package/dist/_pkgs/affine-gfx-connector/direction/index.d.ts +4 -0
  244. package/dist/_pkgs/affine-gfx-connector/direction/index.js +4 -0
  245. package/dist/_pkgs/affine-gfx-connector/direction/invert-direction.d.ts +72 -0
  246. package/dist/_pkgs/affine-gfx-connector/direction/invert-direction.js +185 -0
  247. package/dist/_pkgs/affine-gfx-connector/direction/typed-edge.d.ts +69 -0
  248. package/dist/_pkgs/affine-gfx-connector/direction/typed-edge.js +66 -0
  249. package/dist/_pkgs/affine-gfx-connector/effects.d.ts +2 -0
  250. package/dist/_pkgs/affine-gfx-connector/effects.js +2 -0
  251. package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.js +78 -41
  252. package/dist/_pkgs/affine-gfx-connector/element-renderer/index.js +1 -1
  253. package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.js +1 -1
  254. package/dist/_pkgs/affine-gfx-connector/index.d.ts +1 -0
  255. package/dist/_pkgs/affine-gfx-connector/index.js +1 -0
  256. package/dist/_pkgs/affine-gfx-connector/toolbar/config.d.ts +50 -0
  257. package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +68 -2
  258. package/dist/_pkgs/affine-gfx-connector/view.js +16 -0
  259. package/dist/_pkgs/affine-gfx-group/command/group-api.js +150 -62
  260. package/dist/_pkgs/affine-gfx-group/text/edgeless-group-title-editor.js +4 -1
  261. package/dist/_pkgs/affine-gfx-mindmap/adapter/markdown/index.js +1 -1
  262. package/dist/_pkgs/affine-gfx-mindmap/adapter/utils.js +1 -1
  263. package/dist/_pkgs/affine-gfx-mindmap/templates/index.js +583 -4
  264. package/dist/_pkgs/affine-gfx-mindmap/toolbar/mindmap-menu.js +23 -23
  265. package/dist/_pkgs/affine-gfx-mindmap/toolbar/mindmap-tool-button.js +5 -1
  266. package/dist/_pkgs/affine-gfx-mindmap/view/utils.js +1 -1
  267. package/dist/_pkgs/affine-gfx-note/overlay/overlay.js +1 -1
  268. package/dist/_pkgs/affine-gfx-note/toolbar/note-senior-button.js +1 -1
  269. package/dist/_pkgs/affine-gfx-pointer/tools/pan-tool.d.ts +16 -0
  270. package/dist/_pkgs/affine-gfx-pointer/tools/pan-tool.js +102 -32
  271. package/dist/_pkgs/affine-gfx-shape/commands.d.ts +2 -0
  272. package/dist/_pkgs/affine-gfx-shape/commands.js +33 -0
  273. package/dist/_pkgs/affine-gfx-shape/consts.js +1 -1
  274. package/dist/_pkgs/affine-gfx-shape/draggable/shape-draggable.js +1 -1
  275. package/dist/_pkgs/affine-gfx-shape/element-renderer/shape/polygon.js +17 -9
  276. package/dist/_pkgs/affine-gfx-shape/element-renderer/shape/utils.js +8 -3
  277. package/dist/_pkgs/affine-gfx-shape/element-renderer/shape-dom/index.js +48 -19
  278. package/dist/_pkgs/affine-gfx-shape/element-view.js +19 -12
  279. package/dist/_pkgs/affine-gfx-shape/index.d.ts +1 -1
  280. package/dist/_pkgs/affine-gfx-shape/index.js +1 -1
  281. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.js +1 -1
  282. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-vertex-editing-overlay.js +12 -7
  283. package/dist/_pkgs/affine-gfx-shape/overlay/shape-overlay.js +1 -1
  284. package/dist/_pkgs/affine-gfx-shape/polygon-tool.js +4 -2
  285. package/dist/_pkgs/affine-gfx-shape/shape-tool.js +1 -1
  286. package/dist/_pkgs/affine-gfx-shape/text/edgeless-shape-text-editor.d.ts +26 -0
  287. package/dist/_pkgs/affine-gfx-shape/text/edgeless-shape-text-editor.js +124 -15
  288. package/dist/_pkgs/affine-gfx-shape/view.js +3 -3
  289. package/dist/_pkgs/affine-gfx-template/builtin/other.js +66 -17
  290. package/dist/_pkgs/affine-gfx-template/toolbar/overlay-scrollbar.js +1 -1
  291. package/dist/_pkgs/affine-gfx-template/toolbar/template-panel.js +1 -1
  292. package/dist/_pkgs/affine-gfx-template/toolbar/template-tool-button.d.ts +2 -0
  293. package/dist/_pkgs/affine-gfx-template/toolbar/template-tool-button.js +18 -1
  294. package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.js +9 -5
  295. package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +1 -1
  296. package/dist/_pkgs/affine-inline-latex/command.js +46 -26
  297. package/dist/_pkgs/affine-inline-latex/latex-node/latex-node.d.ts +10 -0
  298. package/dist/_pkgs/affine-inline-latex/latex-node/latex-node.js +23 -0
  299. package/dist/_pkgs/affine-inline-link/command.js +1 -1
  300. package/dist/_pkgs/affine-inline-link/link-node/affine-link.js +4 -1
  301. package/dist/_pkgs/affine-inline-preset/adapters/html/html-inline.d.ts +3 -0
  302. package/dist/_pkgs/affine-inline-preset/adapters/html/html-inline.js +29 -1
  303. package/dist/_pkgs/affine-inline-preset/command/format-block.js +1 -1
  304. package/dist/_pkgs/affine-inline-preset/command/format-native.js +2 -2
  305. package/dist/_pkgs/affine-inline-preset/command/format-text.js +1 -1
  306. package/dist/_pkgs/affine-inline-preset/inline-spec.js +1 -1
  307. package/dist/_pkgs/affine-inline-reference/reference-node/reference-node.js +1 -1
  308. package/dist/_pkgs/affine-model/blocks/code/code-model.d.ts +1 -0
  309. package/dist/_pkgs/affine-model/blocks/code/code-model.js +1 -0
  310. package/dist/_pkgs/affine-model/elements/bpmn/node.d.ts +40 -7
  311. package/dist/_pkgs/affine-model/elements/bpmn/node.js +4 -2
  312. package/dist/_pkgs/affine-model/elements/bpmn/pool.d.ts +74 -17
  313. package/dist/_pkgs/affine-model/elements/bpmn/pool.js +55 -26
  314. package/dist/_pkgs/affine-model/elements/c4/board.d.ts +88 -0
  315. package/dist/_pkgs/affine-model/elements/c4/board.js +128 -0
  316. package/dist/_pkgs/affine-model/elements/c4/boundary.d.ts +63 -0
  317. package/dist/_pkgs/affine-model/elements/c4/boundary.js +134 -0
  318. package/dist/_pkgs/affine-model/elements/c4/index.d.ts +3 -0
  319. package/dist/_pkgs/affine-model/elements/c4/index.js +3 -0
  320. package/dist/_pkgs/affine-model/elements/c4/node.d.ts +97 -0
  321. package/dist/_pkgs/affine-model/elements/c4/node.js +130 -0
  322. package/dist/_pkgs/affine-model/elements/connector/connector.js +25 -1
  323. package/dist/_pkgs/affine-model/elements/context-map/context-map.d.ts +27 -0
  324. package/dist/_pkgs/affine-model/elements/context-map/context-map.js +94 -0
  325. package/dist/_pkgs/affine-model/elements/context-map/index.d.ts +1 -0
  326. package/dist/_pkgs/affine-model/elements/context-map/index.js +1 -0
  327. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.d.ts +34 -17
  328. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.js +28 -26
  329. package/dist/_pkgs/affine-model/elements/edgy/board.d.ts +32 -0
  330. package/dist/_pkgs/affine-model/elements/edgy/board.js +112 -0
  331. package/dist/_pkgs/affine-model/elements/edgy/facets.d.ts +12 -0
  332. package/dist/_pkgs/affine-model/elements/edgy/facets.js +25 -1
  333. package/dist/_pkgs/affine-model/elements/edgy/index.d.ts +1 -0
  334. package/dist/_pkgs/affine-model/elements/edgy/index.js +1 -0
  335. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.d.ts +36 -0
  336. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.js +103 -0
  337. package/dist/_pkgs/affine-model/elements/event-storming/index.d.ts +1 -0
  338. package/dist/_pkgs/affine-model/elements/event-storming/index.js +1 -0
  339. package/dist/_pkgs/affine-model/elements/framework-background/background.d.ts +42 -0
  340. package/dist/_pkgs/affine-model/elements/framework-background/background.js +42 -0
  341. package/dist/_pkgs/affine-model/elements/framework-background/index.d.ts +1 -0
  342. package/dist/_pkgs/affine-model/elements/framework-background/index.js +1 -0
  343. package/dist/_pkgs/affine-model/elements/index.d.ts +14 -1
  344. package/dist/_pkgs/affine-model/elements/index.js +4 -0
  345. package/dist/_pkgs/affine-model/elements/mindmap/mindmap.js +8 -3
  346. package/dist/_pkgs/affine-model/elements/mindmap/style.d.ts +10 -0
  347. package/dist/_pkgs/affine-model/elements/mindmap/style.js +8 -0
  348. package/dist/_pkgs/affine-model/elements/shape/api/polygon.js +2 -8
  349. package/dist/_pkgs/affine-model/elements/wardley/wardley.d.ts +21 -29
  350. package/dist/_pkgs/affine-model/elements/wardley/wardley.js +41 -48
  351. package/dist/_pkgs/affine-shared/adapters/html/block-adapter.js +1 -1
  352. package/dist/_pkgs/affine-shared/adapters/markdown/block-adapter.js +1 -1
  353. package/dist/_pkgs/affine-shared/adapters/markdown/delta-converter.d.ts +6 -1
  354. package/dist/_pkgs/affine-shared/adapters/markdown/delta-converter.js +161 -3
  355. package/dist/_pkgs/affine-shared/adapters/markdown/markdown.js +5 -1
  356. package/dist/_pkgs/affine-shared/adapters/notion-html/block-adapter.js +1 -1
  357. package/dist/_pkgs/affine-shared/adapters/notion-html/delta-converter.js +1 -1
  358. package/dist/_pkgs/affine-shared/adapters/plain-text/block-adapter.js +1 -1
  359. package/dist/_pkgs/affine-shared/adapters/plain-text/delta-converter.js +1 -1
  360. package/dist/_pkgs/affine-shared/adapters/types/delta-converter.d.ts +1 -0
  361. package/dist/_pkgs/affine-shared/adapters/utils/color.d.ts +24 -0
  362. package/dist/_pkgs/affine-shared/adapters/utils/color.js +283 -0
  363. package/dist/_pkgs/affine-shared/adapters/utils/index.d.ts +1 -0
  364. package/dist/_pkgs/affine-shared/adapters/utils/index.js +1 -0
  365. package/dist/_pkgs/affine-shared/commands/block-crud/get-selected-blocks.js +10 -2
  366. package/dist/_pkgs/affine-shared/commands/model-crud/draft-selected-models.js +1 -1
  367. package/dist/_pkgs/affine-shared/commands/selection/focus-block-end.js +1 -1
  368. package/dist/_pkgs/affine-shared/commands/selection/focus-block-start.js +1 -1
  369. package/dist/_pkgs/affine-shared/consts/index.d.ts +10 -0
  370. package/dist/_pkgs/affine-shared/consts/index.js +10 -0
  371. package/dist/_pkgs/affine-shared/services/artefact-catalogue-service.d.ts +55 -0
  372. package/dist/_pkgs/affine-shared/services/artefact-catalogue-service.js +35 -0
  373. package/dist/_pkgs/affine-shared/services/audit-service.d.ts +311 -0
  374. package/dist/_pkgs/affine-shared/services/audit-service.js +228 -0
  375. package/dist/_pkgs/affine-shared/services/command-usage-service.d.ts +31 -0
  376. package/dist/_pkgs/affine-shared/services/command-usage-service.js +109 -0
  377. package/dist/_pkgs/affine-shared/services/comment-service/block-comment-manager.js +1 -1
  378. package/dist/_pkgs/affine-shared/services/doc-display-meta-service.js +1 -1
  379. package/dist/_pkgs/affine-shared/services/edit-props-store.d.ts +7 -0
  380. package/dist/_pkgs/affine-shared/services/edit-props-store.js +11 -0
  381. package/dist/_pkgs/affine-shared/services/embed-iframe/embed-iframe-config.js +1 -1
  382. package/dist/_pkgs/affine-shared/services/font-loader/font-loader-service.d.ts +26 -1
  383. package/dist/_pkgs/affine-shared/services/font-loader/font-loader-service.js +124 -7
  384. package/dist/_pkgs/affine-shared/services/index.d.ts +7 -0
  385. package/dist/_pkgs/affine-shared/services/index.js +7 -0
  386. package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.d.ts +129 -0
  387. package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.js +312 -0
  388. package/dist/_pkgs/affine-shared/services/pivot-properties-service.d.ts +217 -0
  389. package/dist/_pkgs/affine-shared/services/pivot-properties-service.js +114 -0
  390. package/dist/_pkgs/affine-shared/services/telemetry-service/code-block.d.ts +1 -1
  391. package/dist/_pkgs/affine-shared/services/telemetry-service/lifecycle.d.ts +255 -1
  392. package/dist/_pkgs/affine-shared/services/telemetry-service/telemetry-service.d.ts +2 -2
  393. package/dist/_pkgs/affine-shared/services/telemetry-service/types.d.ts +6 -1
  394. package/dist/_pkgs/affine-shared/services/toolbar-service/action.d.ts +10 -0
  395. package/dist/_pkgs/affine-shared/services/toolbar-service/index.d.ts +1 -0
  396. package/dist/_pkgs/affine-shared/services/toolbar-service/index.js +1 -0
  397. package/dist/_pkgs/affine-shared/services/toolbar-service/layout.d.ts +134 -0
  398. package/dist/_pkgs/affine-shared/services/toolbar-service/layout.js +146 -0
  399. package/dist/_pkgs/affine-shared/services/toolbar-service/registry.d.ts +44 -0
  400. package/dist/_pkgs/affine-shared/services/toolbar-service/registry.js +161 -3
  401. package/dist/_pkgs/affine-shared/services/translation-service/index.d.ts +68 -0
  402. package/dist/_pkgs/affine-shared/services/translation-service/index.js +39 -0
  403. package/dist/_pkgs/affine-shared/services/universe-tag-defs-service.d.ts +155 -0
  404. package/dist/_pkgs/affine-shared/services/universe-tag-defs-service.js +256 -0
  405. package/dist/_pkgs/affine-shared/test-utils/affine-template.js +1 -1
  406. package/dist/_pkgs/affine-shared/utils/dom/point-to-range.d.ts +4 -0
  407. package/dist/_pkgs/affine-shared/utils/dom/point-to-range.js +58 -2
  408. package/dist/_pkgs/affine-shared/utils/dom/viewport.d.ts +60 -0
  409. package/dist/_pkgs/affine-shared/utils/dom/viewport.js +58 -0
  410. package/dist/_pkgs/affine-shared/utils/edgeless.js +1 -1
  411. package/dist/_pkgs/affine-shared/utils/file/filesys.d.ts +34 -0
  412. package/dist/_pkgs/affine-shared/utils/file/filesys.js +48 -7
  413. package/dist/_pkgs/affine-shared/utils/print-to-pdf.d.ts +21 -0
  414. package/dist/_pkgs/affine-shared/utils/print-to-pdf.js +166 -32
  415. package/dist/_pkgs/affine-shared/utils/zod-schema.d.ts +7 -0
  416. package/dist/_pkgs/affine-shared/utils/zod-schema.js +25 -1
  417. package/dist/_pkgs/affine-widget-drag-handle/utils.js +1 -1
  418. package/dist/_pkgs/affine-widget-drag-handle/watchers/edgeless-watcher.d.ts +19 -10
  419. package/dist/_pkgs/affine-widget-drag-handle/watchers/edgeless-watcher.js +122 -23
  420. package/dist/_pkgs/affine-widget-drag-handle/watchers/pointer-event-watcher.d.ts +2 -0
  421. package/dist/_pkgs/affine-widget-drag-handle/watchers/pointer-event-watcher.js +25 -4
  422. package/dist/_pkgs/affine-widget-edgeless-auto-connect/index.js +1 -1
  423. package/dist/_pkgs/affine-widget-edgeless-dragging-area/edgeless-dragging-area-rect.js +1 -1
  424. package/dist/_pkgs/affine-widget-edgeless-selected-rect/auto-complete-panel.js +10 -5
  425. package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-auto-complete.d.ts +15 -1
  426. package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-auto-complete.js +37 -32
  427. package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-element-link.js +5 -4
  428. package/dist/_pkgs/affine-widget-edgeless-selected-rect/edgeless-selected-rect.js +19 -9
  429. package/dist/_pkgs/affine-widget-edgeless-selected-rect/utils.d.ts +16 -2
  430. package/dist/_pkgs/affine-widget-edgeless-selected-rect/utils.js +19 -2
  431. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-default.d.ts +14 -0
  432. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-default.js +40 -0
  433. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.d.ts +158 -0
  434. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.js +572 -0
  435. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/catalogue-groups.d.ts +46 -0
  436. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/catalogue-groups.js +66 -0
  437. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/chord-format.d.ts +13 -0
  438. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/chord-format.js +50 -0
  439. package/dist/_pkgs/affine-widget-edgeless-toolbar/edgeless-toolbar.d.ts +6 -0
  440. package/dist/_pkgs/affine-widget-edgeless-toolbar/edgeless-toolbar.js +15 -5
  441. package/dist/_pkgs/affine-widget-edgeless-toolbar/effects.d.ts +2 -0
  442. package/dist/_pkgs/affine-widget-edgeless-toolbar/effects.js +2 -0
  443. package/dist/_pkgs/affine-widget-edgeless-toolbar/extension/index.d.ts +7 -0
  444. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.d.ts +5 -0
  445. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.js +5 -0
  446. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.d.ts +57 -0
  447. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.js +140 -0
  448. package/dist/_pkgs/affine-widget-edgeless-toolbar/view.js +9 -0
  449. package/dist/_pkgs/affine-widget-frame-title/edgeless-frame-title-editor.js +4 -1
  450. package/dist/_pkgs/affine-widget-keyboard-toolbar/icons.js +98 -98
  451. package/dist/_pkgs/affine-widget-keyboard-toolbar/keyboard-tool-panel.js +1 -1
  452. package/dist/_pkgs/affine-widget-linked-doc/import-doc/import-doc.js +1 -1
  453. package/dist/_pkgs/affine-widget-linked-doc/linked-doc-popover.js +2 -15
  454. package/dist/_pkgs/affine-widget-linked-doc/transformers/markdown.d.ts +10 -1
  455. package/dist/_pkgs/affine-widget-linked-doc/transformers/markdown.js +133 -6
  456. package/dist/_pkgs/affine-widget-linked-doc/transformers/utils.d.ts +10 -0
  457. package/dist/_pkgs/affine-widget-linked-doc/transformers/utils.js +120 -3
  458. package/dist/_pkgs/affine-widget-linked-doc/utils.d.ts +12 -0
  459. package/dist/_pkgs/affine-widget-linked-doc/utils.js +33 -0
  460. package/dist/_pkgs/affine-widget-page-dragging-area/index.js +1 -1
  461. package/dist/_pkgs/affine-widget-remote-selection/doc/doc-remote-selection.js +1 -1
  462. package/dist/_pkgs/affine-widget-remote-selection/edgeless/index.js +6 -4
  463. package/dist/_pkgs/affine-widget-slash-menu/slash-menu-popover.js +8 -4
  464. package/dist/_pkgs/affine-widget-slash-menu/utils.d.ts +9 -0
  465. package/dist/_pkgs/affine-widget-slash-menu/utils.js +24 -0
  466. package/dist/_pkgs/affine-widget-toolbar/toolbar.d.ts +6 -0
  467. package/dist/_pkgs/affine-widget-toolbar/toolbar.js +40 -8
  468. package/dist/_pkgs/affine-widget-toolbar/utils.d.ts +146 -3
  469. package/dist/_pkgs/affine-widget-toolbar/utils.js +744 -58
  470. package/dist/_pkgs/data-view/core/common/property-menu.js +3 -16
  471. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.d.ts +4 -0
  472. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +28 -1
  473. package/dist/_pkgs/data-view/core/data-view.d.ts +3 -1
  474. package/dist/_pkgs/data-view/core/data-view.js +25 -3
  475. package/dist/_pkgs/data-view/core/detail/field.js +2 -2
  476. package/dist/_pkgs/data-view/core/detail/selection.d.ts +4 -2
  477. package/dist/_pkgs/data-view/core/detail/selection.js +23 -7
  478. package/dist/_pkgs/data-view/core/effect.js +2 -0
  479. package/dist/_pkgs/data-view/core/filter/eval.js +36 -23
  480. package/dist/_pkgs/data-view/core/filter/filter-fn/matcher.d.ts +7 -0
  481. package/dist/_pkgs/data-view/core/filter/filter-fn/matcher.js +12 -0
  482. package/dist/_pkgs/data-view/core/group-by/compare-date-keys.d.ts +11 -0
  483. package/dist/_pkgs/data-view/core/group-by/compare-date-keys.js +55 -0
  484. package/dist/_pkgs/data-view/core/group-by/define.d.ts +6 -0
  485. package/dist/_pkgs/data-view/core/group-by/define.js +114 -0
  486. package/dist/_pkgs/data-view/core/group-by/matcher.d.ts +7 -0
  487. package/dist/_pkgs/data-view/core/group-by/matcher.js +13 -0
  488. package/dist/_pkgs/data-view/core/group-by/renderer/boolean-group.js +11 -11
  489. package/dist/_pkgs/data-view/core/group-by/renderer/date-group.d.ts +9 -0
  490. package/dist/_pkgs/data-view/core/group-by/renderer/date-group.js +97 -0
  491. package/dist/_pkgs/data-view/core/group-by/setting.js +86 -7
  492. package/dist/_pkgs/data-view/core/group-by/trait.d.ts +34 -0
  493. package/dist/_pkgs/data-view/core/group-by/trait.js +106 -10
  494. package/dist/_pkgs/data-view/core/utils/menu-title.js +17 -17
  495. package/dist/_pkgs/data-view/property-presets/multi-select/cell-renderer.js +3 -1
  496. package/dist/_pkgs/data-view/property-presets/number/define.js +2 -1
  497. package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +3 -1
  498. package/dist/_pkgs/data-view/view-presets/calendar/calendar-view-manager.d.ts +70 -0
  499. package/dist/_pkgs/data-view/view-presets/calendar/calendar-view-manager.js +449 -0
  500. package/dist/_pkgs/data-view/view-presets/calendar/define.d.ts +10 -0
  501. package/dist/_pkgs/data-view/view-presets/calendar/define.js +27 -0
  502. package/dist/_pkgs/data-view/view-presets/calendar/effect.d.ts +1 -0
  503. package/dist/_pkgs/data-view/view-presets/calendar/effect.js +4 -0
  504. package/dist/_pkgs/data-view/view-presets/calendar/index.d.ts +6 -0
  505. package/dist/_pkgs/data-view/view-presets/calendar/index.js +6 -0
  506. package/dist/_pkgs/data-view/view-presets/calendar/layout.d.ts +37 -0
  507. package/dist/_pkgs/data-view/view-presets/calendar/layout.js +138 -0
  508. package/dist/_pkgs/data-view/view-presets/calendar/pc/actions.d.ts +7 -0
  509. package/dist/_pkgs/data-view/view-presets/calendar/pc/actions.js +64 -0
  510. package/dist/_pkgs/data-view/view-presets/calendar/pc/dnd.d.ts +32 -0
  511. package/dist/_pkgs/data-view/view-presets/calendar/pc/dnd.js +159 -0
  512. package/dist/_pkgs/data-view/view-presets/calendar/pc/effect.d.ts +1 -0
  513. package/dist/_pkgs/data-view/view-presets/calendar/pc/effect.js +7 -0
  514. package/dist/_pkgs/data-view/view-presets/calendar/pc/hit-test.d.ts +1 -0
  515. package/dist/_pkgs/data-view/view-presets/calendar/pc/hit-test.js +28 -0
  516. package/dist/_pkgs/data-view/view-presets/calendar/pc/styles.d.ts +1 -0
  517. package/dist/_pkgs/data-view/view-presets/calendar/pc/styles.js +707 -0
  518. package/dist/_pkgs/data-view/view-presets/calendar/pc/view.d.ts +89 -0
  519. package/dist/_pkgs/data-view/view-presets/calendar/pc/view.js +849 -0
  520. package/dist/_pkgs/data-view/view-presets/calendar/renderer.d.ts +2 -0
  521. package/dist/_pkgs/data-view/view-presets/calendar/renderer.js +8 -0
  522. package/dist/_pkgs/data-view/view-presets/calendar/source.d.ts +8 -0
  523. package/dist/_pkgs/data-view/view-presets/calendar/source.js +3 -0
  524. package/dist/_pkgs/data-view/view-presets/calendar/types.d.ts +79 -0
  525. package/dist/_pkgs/data-view/view-presets/calendar/types.js +1 -0
  526. package/dist/_pkgs/data-view/view-presets/convert.js +28 -0
  527. package/dist/_pkgs/data-view/view-presets/effect.js +2 -0
  528. package/dist/_pkgs/data-view/view-presets/index.d.ts +2 -0
  529. package/dist/_pkgs/data-view/view-presets/index.js +3 -0
  530. package/dist/_pkgs/data-view/view-presets/kanban/kanban-view-manager.js +3 -1
  531. package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +2 -2
  532. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.d.ts +18 -0
  533. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.js +36 -0
  534. package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +2 -2
  535. package/dist/_pkgs/data-view/view-presets/table/mobile/group.d.ts +11 -0
  536. package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +89 -4
  537. package/dist/_pkgs/data-view/view-presets/table/pc/cell.d.ts +3 -0
  538. package/dist/_pkgs/data-view/view-presets/table/pc/cell.js +11 -2
  539. package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.d.ts +1 -0
  540. package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.js +39 -33
  541. package/dist/_pkgs/data-view/view-presets/table/pc/group.d.ts +10 -0
  542. package/dist/_pkgs/data-view/view-presets/table/pc/group.js +86 -5
  543. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.d.ts +1 -0
  544. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.js +39 -33
  545. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +18 -18
  546. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.d.ts +3 -0
  547. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.js +8 -0
  548. package/dist/_pkgs/data-view/view-presets/table/table-view-manager.js +3 -1
  549. package/dist/_pkgs/data-view/view-presets/table/utils.d.ts +3 -0
  550. package/dist/_pkgs/data-view/view-presets/table/utils.js +16 -1
  551. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.js +3 -1
  552. package/dist/_pkgs/global/gfx/curve.js +4 -3
  553. package/dist/_pkgs/std/clipboard/clipboard.js +13 -3
  554. package/dist/_pkgs/std/clipboard/utils.d.ts +5 -0
  555. package/dist/_pkgs/std/clipboard/utils.js +10 -0
  556. package/dist/_pkgs/std/event/dispatcher.js +27 -1
  557. package/dist/_pkgs/std/event/keymap.js +16 -6
  558. package/dist/_pkgs/std/extension/command-registry.d.ts +475 -0
  559. package/dist/_pkgs/std/extension/command-registry.js +431 -0
  560. package/dist/_pkgs/std/extension/dnd/index.d.ts +1 -1
  561. package/dist/_pkgs/std/extension/index.d.ts +2 -0
  562. package/dist/_pkgs/std/extension/index.js +2 -0
  563. package/dist/_pkgs/std/extension/shortcut.js +2 -1
  564. package/dist/_pkgs/std/extension/translation-manifest.d.ts +49 -0
  565. package/dist/_pkgs/std/extension/translation-manifest.js +71 -0
  566. package/dist/_pkgs/std/gfx/grid.js +1 -1
  567. package/dist/_pkgs/std/gfx/index.d.ts +7 -3
  568. package/dist/_pkgs/std/gfx/index.js +6 -2
  569. package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.js +6 -1
  570. package/dist/_pkgs/std/gfx/interactivity/manager.d.ts +8 -0
  571. package/dist/_pkgs/std/gfx/interactivity/manager.js +18 -0
  572. package/dist/_pkgs/std/gfx/layer.d.ts +1 -1
  573. package/dist/_pkgs/std/gfx/layer.js +1 -2
  574. package/dist/_pkgs/std/gfx/model/surface/decorators/field.js +9 -0
  575. package/dist/_pkgs/std/gfx/model/surface/decorators/index.d.ts +2 -2
  576. package/dist/_pkgs/std/gfx/model/surface/decorators/index.js +2 -2
  577. package/dist/_pkgs/std/gfx/model/surface/decorators/local.d.ts +14 -0
  578. package/dist/_pkgs/std/gfx/model/surface/decorators/local.js +22 -0
  579. package/dist/_pkgs/std/gfx/model/surface/decorators/observer.d.ts +2 -0
  580. package/dist/_pkgs/std/gfx/model/surface/decorators/observer.js +40 -1
  581. package/dist/_pkgs/std/gfx/model/surface/element-model.d.ts +442 -0
  582. package/dist/_pkgs/std/gfx/model/surface/element-model.js +510 -25
  583. package/dist/_pkgs/std/gfx/model/surface/pivot.d.ts +48 -0
  584. package/dist/_pkgs/std/gfx/model/surface/pivot.js +34 -0
  585. package/dist/_pkgs/std/gfx/model/surface/role.d.ts +153 -0
  586. package/dist/_pkgs/std/gfx/model/surface/role.js +117 -0
  587. package/dist/_pkgs/std/gfx/model/surface/surface-model.d.ts +70 -0
  588. package/dist/_pkgs/std/gfx/model/surface/surface-model.js +305 -17
  589. package/dist/_pkgs/std/gfx/model/surface/tags.d.ts +77 -0
  590. package/dist/_pkgs/std/gfx/model/surface/tags.js +246 -0
  591. package/dist/_pkgs/std/gfx/perf.d.ts +10 -0
  592. package/dist/_pkgs/std/gfx/perf.js +30 -0
  593. package/dist/_pkgs/std/gfx/selection.js +1 -1
  594. package/dist/_pkgs/std/gfx/tool/tool-controller.d.ts +13 -0
  595. package/dist/_pkgs/std/gfx/tool/tool-controller.js +26 -0
  596. package/dist/_pkgs/std/gfx/viewport.d.ts +12 -0
  597. package/dist/_pkgs/std/gfx/viewport.js +20 -2
  598. package/dist/_pkgs/std/inline/extensions/inline-manager.js +1 -1
  599. package/dist/_pkgs/std/inline/extensions/markdown-matcher.js +1 -1
  600. package/dist/_pkgs/std/inline/services/event.d.ts +2 -0
  601. package/dist/_pkgs/std/inline/services/event.js +96 -21
  602. package/dist/_pkgs/std/utils/layer.js +2 -6
  603. package/dist/_pkgs/std/utils/tree.d.ts +14 -0
  604. package/dist/_pkgs/std/utils/tree.js +59 -8
  605. package/dist/_pkgs/std/view/element/gfx-block-component.js +23 -13
  606. package/dist/_pkgs/store/extension/workspace/workspace-meta.d.ts +10 -0
  607. package/dist/_pkgs/store/model/block/flat-sync-controller.js +2 -12
  608. package/dist/_pkgs/store/model/store/crud.js +10 -4
  609. package/dist/_pkgs/store/reactive/flat-native-y/index.d.ts +1 -1
  610. package/dist/_pkgs/store/reactive/flat-native-y/index.js +24 -2
  611. package/dist/commands.d.ts +58 -0
  612. package/dist/commands.js +66 -0
  613. package/dist/extensions/command-telemetry.d.ts +21 -0
  614. package/dist/extensions/command-telemetry.js +89 -0
  615. package/dist/extensions/command-usage.d.ts +23 -0
  616. package/dist/extensions/command-usage.js +37 -0
  617. package/dist/extensions/store.d.ts +9 -4
  618. package/dist/extensions/store.js +27 -24
  619. package/dist/extensions/view.d.ts +9 -4
  620. package/dist/extensions/view.js +35 -8
  621. package/dist/flags.d.ts +98 -21
  622. package/dist/flags.js +103 -22
  623. package/dist/frameworks.d.ts +45 -0
  624. package/dist/frameworks.js +186 -0
  625. package/dist/schemas.d.ts +8 -5
  626. package/dist/schemas.js +28 -32
  627. package/dist/shortcuts.d.ts +16 -16
  628. package/dist/shortcuts.js +8 -36
  629. package/dist/translations.d.ts +56 -0
  630. package/dist/translations.js +200 -0
  631. package/package.json +16 -4
  632. package/dist/_pkgs/affine-block-root/keyboard/shortcuts.d.ts +0 -8
  633. package/dist/_pkgs/affine-block-root/keyboard/shortcuts.js +0 -48
  634. package/dist/_pkgs/affine-gfx-shape/shortcuts.d.ts +0 -6
  635. package/dist/_pkgs/affine-gfx-shape/shortcuts.js +0 -28
  636. package/dist/_pkgs/data-view/core/utils/cache.d.ts +0 -5
  637. package/dist/_pkgs/data-view/core/utils/cache.js +0 -28
@@ -0,0 +1,958 @@
1
+ import { ShapeStyle, ShapeType, StrokeStyle, TextAlign, } from '../../affine-model/index.js';
2
+ import DOMPurify from 'dompurify';
3
+ /**
4
+ * **SVG → a canvas sketch.** The platform's VISUAL-tier importer, shared by
5
+ * every framework that declares it (`docs/adr/0012`, P2).
6
+ *
7
+ * ## The heuristics statement, and its known failure modes
8
+ *
9
+ * _This paragraph is ADR 0012's open question 2 — "each visual capability owes
10
+ * a one-paragraph statement of its heuristics and its known failure modes" —
11
+ * answered ONCE, here, because every framework that declares `…:svg:import`
12
+ * wraps this one function and therefore owes the same statement. It is
13
+ * referenced by `bpmn:svg:import` and by `wardley:svg:import`; a framework that
14
+ * ever wants a narrower or wider guess writes its own parser and its own
15
+ * paragraph beside it._
16
+ *
17
+ * **What it guesses.** An SVG carries a rendering, not a model, so this reader
18
+ * recognises GEOMETRY and nothing else: `<rect>` becomes a rectangle,
19
+ * `<circle>` and `<ellipse>` an ellipse, `<polygon>` a polygon, `<line>`,
20
+ * `<polyline>` and `<path>` a brush stroke sampled at its vertices, and
21
+ * `<text>` an editable free-text element. Fill, stroke, stroke width, font size
22
+ * and text anchor are carried across where the shape model has a direct
23
+ * equivalent, with CSS inheritance down `<g>` honoured and colours passed
24
+ * through verbatim. Coordinates are user units placed by the outermost
25
+ * viewport: the `viewBox` origin is subtracted and the `viewBox`-to-`width`
26
+ * scale is applied uniformly (`min(width / viewBox width, height / viewBox
27
+ * height)`, which is what the default `preserveAspectRatio` means), then every
28
+ * `translate(…)` on the way down. Everything it emits is an ADR 0007 **level 1**
29
+ * element — a plain shape on the free surface, which the author then PROMOTES.
30
+ * It recognises no role, no relation and no framework vocabulary, and it never
31
+ * claims to: a Wardley component and a text box are both `<rect>` plus
32
+ * `<text>`, and deciding which is which is the one question only the author can
33
+ * answer.
34
+ *
35
+ * **Where it is known to be wrong, and the list is meant to be complete.** A
36
+ * `scale`, `rotate`, `matrix` or `skew` transform is IGNORED rather than
37
+ * applied, so anything under one lands at its untransformed position and size.
38
+ * Curves (`C`, `S`, `Q`, `T`, `A`) are flattened to their endpoints, so a
39
+ * rounded connector arrives as a polyline through its anchor points and an arc
40
+ * that doubles back arrives as a straight line. A `<path>` that outlines a
41
+ * filled region (an arrowhead, an icon glyph) arrives as an open stroke, not as
42
+ * a filled shape. `<image>`, `<defs>`, `<marker>`, gradients, filters,
43
+ * `<clipPath>` and `<mask>` are skipped by the reader, and `<use>` and
44
+ * `<foreignObject>` never reach it at all — the SANITIZER removes them, because
45
+ * they are two of the constructs an SVG can carry code in. A `<style>` sheet is
46
+ * skipped, and that one is worth naming twice: mermaid paints almost entirely
47
+ * through CSS classes, so a mermaid SVG arrives in the initial colours — mostly
48
+ * black — with only the note to say why. `<title>`, `<desc>` and `<metadata>`
49
+ * are dropped in silence, deliberately and as the only exception to the rule
50
+ * below: they render nothing, so there is nothing to have lost.
51
+ *
52
+ * **What this reader alters without a note, because a note could not help.**
53
+ * Text width and height are ESTIMATED from the font size and the character
54
+ * count, because measuring text needs a font a pure function of a string is not
55
+ * allowed to have, so a label box is approximately and not exactly the size it
56
+ * was. Whitespace inside a label is collapsed to single spaces and trimmed
57
+ * (`xml:space="preserve"` is not honoured). A `<tspan>`'s own `x`/`y`, its `dx`
58
+ * / `dy` offsets and `dominant-baseline` are ignored, so a label laid out span
59
+ * by span arrives as plain stacked lines in document order. `stroke-dasharray`
60
+ * is not read, so a dashed line arrives solid. `em` font sizes are resolved
61
+ * against the inherited size only, with no font-relative refinement.
62
+ *
63
+ * **Everything else is reported.** Every OTHER construct this reader ignores,
64
+ * alters or cannot resolve produces exactly one `warning` note per KIND — never
65
+ * one per instance — so a result that looks empty always says why.
66
+ *
67
+ * ## What it never does
68
+ *
69
+ * **It writes no `interchange` payload, on any element, ever** — P2's hard
70
+ * rule, pinned by an anti-decay test in this package's own spec. There is
71
+ * nothing to preserve that the elements do not already carry: an SVG round-trip
72
+ * would be a re-render rather than a round-trip, and a payload would advertise
73
+ * a promise this tier deliberately does not make. `carried` and `quarantined`
74
+ * are therefore `0` in every report it returns, and the surface that offers the
75
+ * import must say all of this BEFORE the file is read.
76
+ *
77
+ * ## Pure, and framework-agnostic
78
+ *
79
+ * Text in, serialized element props out (P3): no `std`, no surface, no DI, so
80
+ * labre-mcp calls the very same function the editor commands call. It produces
81
+ * only generic `shape` / `text` / `brush` props and knows the name of no
82
+ * framework — which is exactly why several frameworks can declare it. ADR 0012
83
+ * explicitly rejects inferring one framework from a `.svg`, so the capability
84
+ * is declared per framework and this parser is what each of them wraps.
85
+ */
86
+ /* ── The format, as far as it is shared ───────────────────────────────── */
87
+ /**
88
+ * The format id. Never used as a payload key, unlike every semantic format's —
89
+ * a visual import writes no payload at all — but it is what the report's
90
+ * headline calls itself ("SVG imported"), and what the registry's triple is
91
+ * built from.
92
+ */
93
+ export const SVG_SKETCH_FORMAT_ID = 'svg';
94
+ export const SVG_SKETCH_EXTENSION = '.svg';
95
+ export const SVG_SKETCH_MIME = 'image/svg+xml';
96
+ /* ── Small readers ────────────────────────────────────────────────────── */
97
+ /**
98
+ * happy-dom (the vitest environment two of the three packages that test this
99
+ * run in) does not implement namespace-aware lookups, so this file walks
100
+ * children by hand and compares `localName`, exactly as the BPMN reader does.
101
+ * `children` is also skipped in favour of `childNodes`, because the former is
102
+ * an `HTMLCollection` whose behaviour on a foreign-namespaced document is one
103
+ * more thing that differs between the two environments.
104
+ */
105
+ const ELEMENT_NODE = 1;
106
+ const TEXT_NODE = 3;
107
+ const CDATA_NODE = 4;
108
+ // `Node` and not `Element`, because only `childNodes` is ever read and one
109
+ // caller is DOMPurify's `RETURN_DOM` answer — which its own typed overload
110
+ // declares as a `Node`. Widening the parameter is more honest than casting the
111
+ // argument at that one call site.
112
+ function childElements(parent) {
113
+ const found = [];
114
+ for (const node of Array.from(parent.childNodes)) {
115
+ if (node.nodeType === ELEMENT_NODE)
116
+ found.push(node);
117
+ }
118
+ return found;
119
+ }
120
+ const nameOf = (element) => element.localName?.toLowerCase() ?? '';
121
+ /** One attribute as a finite number, or the caller's default. */
122
+ function num(element, name, fallback = 0) {
123
+ const raw = element.getAttribute(name);
124
+ if (raw === null)
125
+ return fallback;
126
+ // `parseFloat` and not `Number`, because a length is allowed to carry a unit
127
+ // (`12px`, `2em`). Only user units are honoured — anything else is read as
128
+ // its number, which is right for `px` and an approximation for the rest. A
129
+ // sketch is what this reader promises.
130
+ const value = Number.parseFloat(raw);
131
+ return Number.isFinite(value) ? value : fallback;
132
+ }
133
+ /**
134
+ * A length that must be an absolute number of user units, or `0`.
135
+ *
136
+ * `width="100%"` is the case this exists for: `parseFloat` reads it as `100`,
137
+ * and a viewport 100 units wide against a 1000-unit `viewBox` would scale the
138
+ * whole drawing to a tenth of its size. A percentage is a length this reader
139
+ * cannot resolve — it depends on a containing block there is none of — so it
140
+ * answers "no length declared" and the caller falls back to 1:1.
141
+ */
142
+ function absoluteLength(element, name) {
143
+ const raw = element.getAttribute(name);
144
+ if (raw === null || raw.includes('%'))
145
+ return 0;
146
+ const value = Number.parseFloat(raw);
147
+ return Number.isFinite(value) && value > 0 ? value : 0;
148
+ }
149
+ /** Every number in a string, in order — `points`, `viewBox`, a transform's args. */
150
+ function numbers(raw) {
151
+ const found = raw.match(/-?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?/g);
152
+ return found ? found.map(Number).filter(Number.isFinite) : [];
153
+ }
154
+ /* ── Notes: one per KIND, never one per instance ──────────────────────── */
155
+ /**
156
+ * The note channel, deduplicated on a key.
157
+ *
158
+ * D1's discipline, carried across to a tier that has no D1: nothing is dropped
159
+ * silently. What changes is the GRANULARITY — a file with four hundred
160
+ * `<use>` instances is one fact about the file, not four hundred, and a report
161
+ * nobody reads to the end is a report that was not written.
162
+ *
163
+ * Every note is a `warning`. The other four kinds would be lies here:
164
+ * `carried` and `quarantined` describe a payload this tier does not write, and
165
+ * `substituted-id` and `invented-layout` describe promises it does not make.
166
+ */
167
+ class Notebook {
168
+ constructor() {
169
+ this.seen = new Set();
170
+ this.notes = [];
171
+ }
172
+ once(key, message, element) {
173
+ if (this.seen.has(key))
174
+ return;
175
+ this.seen.add(key);
176
+ this.notes.push({
177
+ kind: 'warning',
178
+ message,
179
+ ...(element ? { element } : {}),
180
+ });
181
+ }
182
+ }
183
+ /** `style="fill:#fff;stroke:none"`, as a map. Wins over the attribute. */
184
+ function styleMap(element) {
185
+ const map = new Map();
186
+ const raw = element.getAttribute('style');
187
+ if (!raw)
188
+ return map;
189
+ for (const declaration of raw.split(';')) {
190
+ const colon = declaration.indexOf(':');
191
+ if (colon < 0)
192
+ continue;
193
+ const property = declaration.slice(0, colon).trim().toLowerCase();
194
+ const value = declaration.slice(colon + 1).trim();
195
+ if (property && value)
196
+ map.set(property, value);
197
+ }
198
+ return map;
199
+ }
200
+ /**
201
+ * `12`, `12px`, `12pt`, `1.5em` as a number of user units, or `undefined` for
202
+ * "this reader cannot resolve it, and has said so".
203
+ *
204
+ * Three units and no more. `px` and a bare number are user units already, `pt`
205
+ * is 4/3 of one by CSS's own definition, and `em` is the INHERITED size — which
206
+ * this reader has, and which is the only font-relative context a pure function
207
+ * of a string can honestly claim. Everything else (`%`, `ex`, `ch`, `rem`, the
208
+ * viewport units) needs a containing block or a loaded font, so it is refused
209
+ * with a note rather than silently read as its number: `font-size="200%"` read
210
+ * as 200 would draw a label fourteen times too big.
211
+ */
212
+ function fontSizeOf(raw, inherited, notes) {
213
+ const value = Number.parseFloat(raw);
214
+ if (!Number.isFinite(value) || value <= 0)
215
+ return undefined;
216
+ // The tail after the number as WRITTEN, not after `String(value)` — `12.0px`
217
+ // and `12px` are the same length and `String(12)` is two characters.
218
+ const unit = raw
219
+ .trim()
220
+ .replace(/^[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?/, '')
221
+ .trim()
222
+ .toLowerCase();
223
+ if (unit === '' || unit === 'px')
224
+ return value;
225
+ if (unit === 'pt')
226
+ return (value * 4) / 3;
227
+ if (unit === 'em')
228
+ return value * inherited;
229
+ notes.once(`font-unit:${unit}`, `Font sizes in \`${unit}\` cannot be resolved without a page to measure against; those labels use the inherited size.`);
230
+ return undefined;
231
+ }
232
+ /**
233
+ * This element's paint, on top of what it inherited.
234
+ *
235
+ * Inheritance is not a nicety: real files — bpmn.io's, mermaid's, Illustrator's
236
+ * — set `fill` and `stroke` once on a `<g>` and never again, so a reader that
237
+ * only looked at the leaf would import every shape in the SVG's initial colours
238
+ * and get the picture visibly wrong.
239
+ */
240
+ function paintOf(element, inherited, notes) {
241
+ const style = styleMap(element);
242
+ // `inherit` is resolved HERE, where the inherited value is in hand, rather
243
+ // than downstream where the only honest answer would be a neutral: the
244
+ // keyword means "whatever my parent had", and this function is the one place
245
+ // that knows.
246
+ const read = (property) => {
247
+ const raw = style.get(property) ?? element.getAttribute(property);
248
+ return raw === null || raw === undefined || raw.trim() === 'inherit'
249
+ ? undefined
250
+ : raw;
251
+ };
252
+ const strokeWidth = read('stroke-width');
253
+ const parsedWidth = strokeWidth === undefined ? undefined : Number.parseFloat(strokeWidth);
254
+ const fontSize = read('font-size');
255
+ return {
256
+ fill: read('fill') ?? inherited.fill,
257
+ stroke: read('stroke') ?? inherited.stroke,
258
+ strokeWidth: parsedWidth !== undefined && Number.isFinite(parsedWidth)
259
+ ? parsedWidth
260
+ : inherited.strokeWidth,
261
+ fontSize: (fontSize === undefined
262
+ ? undefined
263
+ : fontSizeOf(fontSize, inherited.fontSize ?? DEFAULT_FONT_SIZE, notes)) ?? inherited.fontSize,
264
+ textAnchor: read('text-anchor') ?? inherited.textAnchor,
265
+ };
266
+ }
267
+ /**
268
+ * Whether this element renders at all, with a note for each reason it does not.
269
+ *
270
+ * `display:none` removes the element AND its subtree from the rendering;
271
+ * `visibility:hidden` hides the element but not necessarily its children — this
272
+ * reader treats both as "skip the subtree", which is the coarser of the two and
273
+ * the one that keeps an invisible frame from arriving as a black rectangle over
274
+ * the drawing. Both are common: bpmn.io hides its own measurement layers this
275
+ * way, and an exporter's off-canvas scaffolding is the usual source of a
276
+ * "why is there a huge black box on my board" report.
277
+ */
278
+ function isHidden(element, notes) {
279
+ const style = styleMap(element);
280
+ const display = style.get('display') ?? element.getAttribute('display');
281
+ if (display?.trim() === 'none') {
282
+ notes.once('hidden:display', 'Parts of the file marked `display:none` were not imported — they draw nothing where the file came from either.');
283
+ return true;
284
+ }
285
+ const visibility = style.get('visibility') ?? element.getAttribute('visibility');
286
+ const hidden = visibility?.trim();
287
+ if (hidden === 'hidden' || hidden === 'collapse') {
288
+ notes.once('hidden:visibility', 'Parts of the file marked `visibility:hidden` were not imported — they draw nothing where the file came from either.');
289
+ return true;
290
+ }
291
+ return false;
292
+ }
293
+ /**
294
+ * Opacity is not carried, and that is a note rather than a drop.
295
+ *
296
+ * The shape model has no opacity of its own — a colour is a colour — so a
297
+ * half-transparent shade would have to be baked into the colour, which needs
298
+ * the backdrop it sits on. It is imported at full strength, which is visible
299
+ * and editable, and the note says the strength changed.
300
+ */
301
+ function noteOpacity(element, notes) {
302
+ const style = styleMap(element);
303
+ for (const property of ['opacity', 'fill-opacity', 'stroke-opacity']) {
304
+ const raw = style.get(property) ?? element.getAttribute(property);
305
+ if (raw === null || raw === undefined)
306
+ continue;
307
+ const value = Number.parseFloat(raw);
308
+ if (Number.isFinite(value) && value < 1) {
309
+ notes.once('opacity', 'Transparency is not carried: partly transparent shapes arrive at full strength.');
310
+ return;
311
+ }
312
+ }
313
+ }
314
+ /**
315
+ * The SVG initial values, which is what an unpainted element actually is.
316
+ *
317
+ * `fill: black` is the SPEC's initial value, not a choice — an attribute-free
318
+ * `<rect>` renders as a solid black box in every browser, and importing it
319
+ * hollow would be this reader redrawing the file rather than reading it.
320
+ */
321
+ const INITIAL_PAINT = { fill: 'black', stroke: 'none', strokeWidth: 1 };
322
+ /** The font size a `<text>` with none declared is drawn at. */
323
+ const DEFAULT_FONT_SIZE = 16;
324
+ /** What a paint served by `url(#…)` or `currentColor` falls back to. */
325
+ const NEUTRAL_STROKE = '#000000';
326
+ const NEUTRAL_FILL = '#cccccc';
327
+ /**
328
+ * A paint value as a colour the shape model will accept, or `undefined` for
329
+ * "nothing is painted here".
330
+ *
331
+ * The model takes a raw CSS colour string (`Color` is `string | {normal} |
332
+ * {dark, light}`), so a hex or an `rgb()` from the file is passed through
333
+ * verbatim and the picture keeps its colours. Two values cannot be: a paint
334
+ * server (`url(#gradient)`) needs a `<defs>` this reader skips, and
335
+ * `currentColor` needs an inherited CSS colour there is nobody to ask for.
336
+ * Both fall back to a neutral, and both say so.
337
+ */
338
+ function colorOf(raw, fallback, notes) {
339
+ const value = raw?.trim();
340
+ if (!value || value === 'none' || value === 'transparent')
341
+ return undefined;
342
+ if (value.startsWith('url(')) {
343
+ notes.once('paint-server', 'Gradients and patterns are not read; the shapes that used one are a flat neutral.');
344
+ return fallback;
345
+ }
346
+ if (value === 'currentColor') {
347
+ notes.once('current-color', '`currentColor` has no page to inherit from here; the shapes that used it are a flat neutral.');
348
+ return fallback;
349
+ }
350
+ return value;
351
+ }
352
+ const IDENTITY = { ox: 0, oy: 0, s: 1 };
353
+ const px = (frame, x) => x * frame.s + frame.ox;
354
+ const py = (frame, y) => y * frame.s + frame.oy;
355
+ /** A LENGTH is scaled and never offset — a width, a radius, a font size. */
356
+ const len = (frame, value) => value * frame.s;
357
+ const xywh = (x, y, w, h) => `[${x},${y},${w},${h}]`;
358
+ /**
359
+ * The frame a `<svg>` element establishes inside its parent's.
360
+ *
361
+ * The same arithmetic for the outermost one (whose parent frame is the
362
+ * identity) and for a nested one, which is why there is one function: a nested
363
+ * `<svg>` is a new viewport, its `x`/`y` place it in the parent's user space,
364
+ * and its own `viewBox` re-origins and re-scales what is inside it.
365
+ */
366
+ function viewportFrame(element, parent) {
367
+ const placed = {
368
+ ox: px(parent, num(element, 'x')),
369
+ oy: py(parent, num(element, 'y')),
370
+ s: parent.s,
371
+ };
372
+ const box = numbers(element.getAttribute('viewBox') ?? '');
373
+ if (box.length < 4)
374
+ return placed;
375
+ const [minX, minY, boxW, boxH] = box;
376
+ if (boxW <= 0 || boxH <= 0)
377
+ return placed;
378
+ const width = absoluteLength(element, 'width');
379
+ const height = absoluteLength(element, 'height');
380
+ // No declared size is not a broken file — it is the usual `<svg viewBox=…>`
381
+ // that fills whatever it is put in. There is no containing block here, so the
382
+ // viewBox IS the size and the scale stays the parent's.
383
+ const scale = width > 0 && height > 0
384
+ ? placed.s * Math.min(width / boxW, height / boxH)
385
+ : placed.s;
386
+ return {
387
+ ox: placed.ox - minX * scale,
388
+ oy: placed.oy - minY * scale,
389
+ s: scale,
390
+ };
391
+ }
392
+ /**
393
+ * The `translate(…)` this element contributes, and a note for every other kind
394
+ * of transform on it.
395
+ *
396
+ * v1 accumulates translations and IGNORES the rest — a scaled or rotated
397
+ * element is imported at its untransformed position rather than dropped,
398
+ * because a sketch missing a shape is worse than a sketch with a shape in the
399
+ * wrong place, and the author is about to move things anyway. What is not
400
+ * acceptable is doing it quietly, so each ignored KIND is named once.
401
+ */
402
+ function translated(element, frame, notes) {
403
+ const raw = element.getAttribute('transform');
404
+ if (!raw)
405
+ return frame;
406
+ let tx = 0;
407
+ let ty = 0;
408
+ for (const [, kind, args] of raw.matchAll(/([a-zA-Z]+)\s*\(([^)]*)\)/g)) {
409
+ const values = numbers(args);
410
+ if (kind === 'translate') {
411
+ tx += values[0] ?? 0;
412
+ ty += values[1] ?? 0;
413
+ continue;
414
+ }
415
+ notes.once(`transform:${kind}`, `\`${kind}\` transforms are ignored (best effort): what carried one is placed as if it did not.`);
416
+ }
417
+ // A translate is expressed in the PARENT's user units, so it is scaled by the
418
+ // frame it was written in and never by the one it creates.
419
+ return {
420
+ ox: frame.ox + tx * frame.s,
421
+ oy: frame.oy + ty * frame.s,
422
+ s: frame.s,
423
+ };
424
+ }
425
+ /* ── Path data ────────────────────────────────────────────────────────── */
426
+ /** How many numbers each path command takes, and where its ENDPOINT sits. */
427
+ const PATH_ARITY = {
428
+ m: 2,
429
+ l: 2,
430
+ h: 1,
431
+ v: 1,
432
+ c: 6,
433
+ s: 4,
434
+ q: 4,
435
+ t: 2,
436
+ a: 7,
437
+ z: 0,
438
+ };
439
+ /** The index, inside one command's arguments, of the x of its endpoint. */
440
+ const PATH_ENDPOINT = { c: 4, s: 2, q: 2, a: 5 };
441
+ /** The commands whose shape is thrown away when only the endpoint is kept. */
442
+ const CURVE_COMMANDS = new Set(['c', 's', 'q', 't', 'a']);
443
+ /**
444
+ * A `d` attribute as one polyline per subpath, in the element's own user space.
445
+ *
446
+ * `M/L/H/V/Z` are exact. Curves are flattened to their ENDPOINTS — coarse, and
447
+ * deliberately so: this is a sketch, the author is going to redraw whatever
448
+ * matters, and a proper flattener is a de Casteljau subdivision plus an arc
449
+ * parameterization for a fidelity nobody is promised. The first curve in the
450
+ * file says so in a note.
451
+ *
452
+ * A subpath per stroke, rather than one stroke through the whole `d`: a brush
453
+ * element is a single connected path, so joining two subpaths would draw a line
454
+ * across the drawing that the file never had.
455
+ */
456
+ function samplePath(d, notes) {
457
+ const subpaths = [];
458
+ let current = [];
459
+ let start = null;
460
+ let x = 0;
461
+ let y = 0;
462
+ const push = () => {
463
+ if (current.length >= 2)
464
+ subpaths.push(current);
465
+ else if (current.length === 1) {
466
+ notes.once('lone-point', 'A path that never moved anywhere draws nothing and was skipped.');
467
+ }
468
+ current = [];
469
+ };
470
+ for (const [, letter, rawArgs] of d.matchAll(/([MmLlHhVvCcSsQqTtAaZz])([^MmLlHhVvCcSsQqTtAaZz]*)/g)) {
471
+ const kind = letter.toLowerCase();
472
+ const relative = letter !== letter.toUpperCase();
473
+ const arity = PATH_ARITY[kind];
474
+ const args = numbers(rawArgs);
475
+ if (kind === 'z') {
476
+ if (start && current.length > 0)
477
+ current.push([start[0], start[1]]);
478
+ [x, y] = start ?? [x, y];
479
+ push();
480
+ continue;
481
+ }
482
+ if (CURVE_COMMANDS.has(kind)) {
483
+ notes.once('curve', 'Curves are approximated by their endpoints (best effort), so a curved path arrives as straight segments.');
484
+ }
485
+ // One command letter may carry SEVERAL argument groups (`L 1 2 3 4`), and
486
+ // a repeated `M` group is an implicit lineto — the spec's own rule, and the
487
+ // one every hand-written path generator relies on.
488
+ let group = 0;
489
+ for (let i = 0; i + arity <= args.length; i += arity, group += 1) {
490
+ const chunk = args.slice(i, i + arity);
491
+ if (kind === 'h') {
492
+ x = relative ? x + chunk[0] : chunk[0];
493
+ }
494
+ else if (kind === 'v') {
495
+ y = relative ? y + chunk[0] : chunk[0];
496
+ }
497
+ else {
498
+ const at = PATH_ENDPOINT[kind] ?? 0;
499
+ const [ex, ey] = [chunk[at], chunk[at + 1]];
500
+ x = relative ? x + ex : ex;
501
+ y = relative ? y + ey : ey;
502
+ }
503
+ if (kind === 'm' && group === 0) {
504
+ push();
505
+ start = [x, y];
506
+ }
507
+ current.push([x, y]);
508
+ }
509
+ }
510
+ push();
511
+ return subpaths;
512
+ }
513
+ /** The generic shape props every recognised outline lands with. */
514
+ function shapeProps(paint, frame, sketch) {
515
+ const fill = colorOf(paint.fill, NEUTRAL_FILL, sketch.notes);
516
+ const stroke = colorOf(paint.stroke, NEUTRAL_STROKE, sketch.notes);
517
+ return {
518
+ type: 'shape',
519
+ // `General`, never `Scribbled`: the file is a rendering somebody produced
520
+ // deliberately, and re-drawing it hand-sketched would be this reader
521
+ // inventing a style the source never had.
522
+ shapeStyle: ShapeStyle.General,
523
+ filled: fill !== undefined,
524
+ fillColor: fill ?? 'transparent',
525
+ strokeColor: stroke ?? 'transparent',
526
+ strokeStyle: stroke === undefined ? StrokeStyle.None : StrokeStyle.Solid,
527
+ strokeWidth: len(frame, paint.strokeWidth ?? 1),
528
+ };
529
+ }
530
+ const EMPTY_BOX_NOTE = 'Shapes with no width or height were skipped.';
531
+ function readRect(element, frame, paint, sketch) {
532
+ const w = num(element, 'width');
533
+ const h = num(element, 'height');
534
+ if (w <= 0 || h <= 0) {
535
+ sketch.notes.once('empty-box', EMPTY_BOX_NOTE);
536
+ return;
537
+ }
538
+ // `rx` is an absolute corner radius in user units, and the shape model reads
539
+ // a `radius` of 1 or more as absolute pixels (below 1 it is a RATIO of the
540
+ // shorter side). Sub-pixel radii are visually zero, so they are dropped
541
+ // rather than reinterpreted as a 40 % round-over — and a PERCENTAGE radius is
542
+ // refused outright for the same reason it would otherwise be read as its
543
+ // number: `rx="50%"` would round a box over by fifty pixels rather than into
544
+ // a pill.
545
+ const rawRadius = element.getAttribute('rx') ?? element.getAttribute('ry');
546
+ let radius = 0;
547
+ if (rawRadius?.includes('%')) {
548
+ sketch.notes.once('percent-radius', 'Corner radii given as a percentage were not read; those corners arrive square.');
549
+ }
550
+ else {
551
+ const scaled = len(frame, num(element, 'rx', num(element, 'ry')));
552
+ radius = scaled >= 1 ? scaled : 0;
553
+ }
554
+ sketch.elements.push({
555
+ ...shapeProps(paint, frame, sketch),
556
+ shapeType: ShapeType.Rect,
557
+ radius,
558
+ xywh: xywh(px(frame, num(element, 'x')), py(frame, num(element, 'y')), len(frame, w), len(frame, h)),
559
+ });
560
+ }
561
+ function readEllipse(element, frame, paint, sketch) {
562
+ const circle = nameOf(element) === 'circle';
563
+ const r = num(element, 'r');
564
+ const rx = circle ? r : num(element, 'rx');
565
+ const ry = circle ? r : num(element, 'ry');
566
+ if (rx <= 0 || ry <= 0) {
567
+ sketch.notes.once('empty-box', EMPTY_BOX_NOTE);
568
+ return;
569
+ }
570
+ const cx = num(element, 'cx');
571
+ const cy = num(element, 'cy');
572
+ sketch.elements.push({
573
+ ...shapeProps(paint, frame, sketch),
574
+ shapeType: ShapeType.Ellipse,
575
+ radius: 0,
576
+ xywh: xywh(px(frame, cx - rx), py(frame, cy - ry), len(frame, rx * 2), len(frame, ry * 2)),
577
+ });
578
+ }
579
+ /**
580
+ * A `<polygon>` as a polygon shape, with its outline kept.
581
+ *
582
+ * The shape model stores polygon `vertices` NORMALIZED into its bounding box
583
+ * (`[0, 1]` on each axis), which is what lets the shape be resized afterwards
584
+ * and is how EDGY's activity chevron is already declared. Two cases cannot be
585
+ * normalized and fall back to the bounding box as a plain rectangle, each with
586
+ * a note: fewer than three points is not an outline, and a polygon flat on one
587
+ * axis has a zero-width box to divide by.
588
+ */
589
+ function readPolygon(element, frame, paint, sketch) {
590
+ const flat = numbers(element.getAttribute('points') ?? '');
591
+ const points = [];
592
+ for (let i = 0; i + 1 < flat.length; i += 2) {
593
+ points.push([px(frame, flat[i]), py(frame, flat[i + 1])]);
594
+ }
595
+ const xs = points.map(p => p[0]);
596
+ const ys = points.map(p => p[1]);
597
+ const minX = Math.min(...xs);
598
+ const minY = Math.min(...ys);
599
+ const w = Math.max(...xs) - minX;
600
+ const h = Math.max(...ys) - minY;
601
+ if (points.length < 3 || w <= 0 || h <= 0) {
602
+ if (points.length === 0 || w < 0 || h < 0) {
603
+ sketch.notes.once('empty-box', EMPTY_BOX_NOTE);
604
+ return;
605
+ }
606
+ sketch.notes.once('flat-polygon', 'A polygon with fewer than three corners, or flat on one axis, arrives as its bounding rectangle.');
607
+ sketch.elements.push({
608
+ ...shapeProps(paint, frame, sketch),
609
+ shapeType: ShapeType.Rect,
610
+ radius: 0,
611
+ xywh: xywh(minX, minY, Math.max(w, 1), Math.max(h, 1)),
612
+ });
613
+ return;
614
+ }
615
+ sketch.elements.push({
616
+ ...shapeProps(paint, frame, sketch),
617
+ shapeType: ShapeType.Polygon,
618
+ radius: 0,
619
+ vertices: points.map(([x, y]) => [(x - minX) / w, (y - minY) / h]),
620
+ isClosed: true,
621
+ xywh: xywh(minX, minY, w, h),
622
+ });
623
+ }
624
+ /**
625
+ * A stroke — `<line>`, `<polyline>`, `<path>` — as one brush element per
626
+ * connected run of points, in CANVAS coordinates.
627
+ *
628
+ * ## Key order is load-bearing here, and it is not a style choice
629
+ *
630
+ * `BrushElementModel` declares `points` with a `@convert` that re-bases them
631
+ * onto the bound it derives, INFLATED BY `lineWidth`, and a `@derive` that
632
+ * writes `xywh` from the same arithmetic. `surface.addElement` copies props
633
+ * onto the model in `Object.keys` order, so `lineWidth` must be assigned BEFORE
634
+ * `points` or the conversion runs against the model's default width of 4 and
635
+ * the stroke lands with a box that is up to three pixels off on every side.
636
+ * **Do not reorder the literal below**; the integration spec
637
+ * (`integration-test/…/svg-sketch.spec.ts`) pins the resulting `xywh` on a live
638
+ * surface precisely because a unit test over plain props cannot see this.
639
+ *
640
+ * The points handed over are ABSOLUTE, which is what the brush tool itself
641
+ * passes: the model derives the box, so an importer that pre-computed `xywh`
642
+ * would be doing that arithmetic twice and disagreeing with the model about the
643
+ * line-width inflation.
644
+ */
645
+ function pushStroke(points, paint, frame, sketch) {
646
+ if (points.length < 2)
647
+ return;
648
+ const color = colorOf(paint.stroke, NEUTRAL_STROKE, sketch.notes) ??
649
+ // A path with no stroke and a fill is an outlined REGION — an arrowhead, a
650
+ // glyph. It is drawn as a stroke anyway (a brush is the only thing this
651
+ // reader has for an open path), so it takes the fill's colour rather than
652
+ // arriving invisible. And a shape with neither is still drawn, in the
653
+ // initial black, because that is what the file renders as.
654
+ colorOf(paint.fill, NEUTRAL_STROKE, sketch.notes) ??
655
+ NEUTRAL_STROKE;
656
+ sketch.elements.push({
657
+ type: 'brush',
658
+ color,
659
+ // BEFORE `points` — see this function's own documentation.
660
+ lineWidth: Math.max(len(frame, paint.strokeWidth ?? 1), 1),
661
+ points,
662
+ });
663
+ }
664
+ /**
665
+ * `<text>` and its children as an EDITABLE free-text element.
666
+ *
667
+ * The PO-critical path, and the one thing this tier promises without
668
+ * qualification: a label that arrives as a picture of a word is a label nobody
669
+ * can correct. `text` is handed over as a plain string and
670
+ * `TextElementModel.propsToY` turns it into the `Y.Text` the editor binds to,
671
+ * so the first double-click puts a caret in it.
672
+ *
673
+ * ## Children in DOCUMENT ORDER, text nodes included
674
+ *
675
+ * `<text>Hello <tspan>World</tspan></text>` is one label reading "Hello World",
676
+ * and a reader that collected only the `<tspan>`s would import "World" and
677
+ * lose the rest without noticing — the worst kind of loss, because the result
678
+ * still looks like a label. So the children are walked in order and every
679
+ * non-empty run, span or bare text node alike, becomes a line.
680
+ *
681
+ * Two approximations are unavoidable and are stated in this module's own
682
+ * failure-modes paragraph rather than in a note, because no note could help:
683
+ * SVG's `y` is a BASELINE and the model's box is a top edge, so the box is
684
+ * lifted by one font size; and the box's width is estimated from the character
685
+ * count, because measuring text needs a loaded font — which is exactly the
686
+ * thing a pure function of a string is not allowed to have. Whitespace inside
687
+ * a run is collapsed to single spaces and trimmed, so `xml:space="preserve"`
688
+ * is not honoured.
689
+ */
690
+ const CHARACTER_WIDTH_RATIO = 0.55;
691
+ const LINE_HEIGHT_RATIO = 1.2;
692
+ function readText(element, frame, paint, sketch) {
693
+ const lines = [];
694
+ const collapse = (raw) => raw.replace(/\s+/g, ' ').trim();
695
+ for (const node of Array.from(element.childNodes)) {
696
+ if (node.nodeType === TEXT_NODE || node.nodeType === CDATA_NODE) {
697
+ const line = collapse(node.nodeValue ?? '');
698
+ if (line)
699
+ lines.push(line);
700
+ }
701
+ else if (node.nodeType === ELEMENT_NODE) {
702
+ const child = node;
703
+ if (nameOf(child) !== 'tspan')
704
+ continue;
705
+ if (isHidden(child, sketch.notes))
706
+ continue;
707
+ const line = collapse(child.textContent ?? '');
708
+ if (line)
709
+ lines.push(line);
710
+ }
711
+ }
712
+ if (lines.length === 0) {
713
+ sketch.notes.once('empty-text', 'Empty text elements were skipped.');
714
+ return;
715
+ }
716
+ const fontSize = len(frame, paint.fontSize ?? DEFAULT_FONT_SIZE);
717
+ const widest = Math.max(...lines.map(line => line.length));
718
+ const w = Math.max(widest * fontSize * CHARACTER_WIDTH_RATIO, fontSize);
719
+ const h = lines.length * fontSize * LINE_HEIGHT_RATIO;
720
+ // `text-anchor` says which end of the box `x` names, and it INHERITS — a
721
+ // `<g text-anchor="middle">` around a whole diagram is how bpmn.io centres
722
+ // every label it writes, so reading it off the leaf alone would offset every
723
+ // one of them by half its width.
724
+ const anchor = (paint.textAnchor ?? 'start').trim();
725
+ const align = anchor === 'middle'
726
+ ? TextAlign.Center
727
+ : anchor === 'end'
728
+ ? TextAlign.Right
729
+ : TextAlign.Left;
730
+ const shift = anchor === 'middle' ? w / 2 : anchor === 'end' ? w : 0;
731
+ sketch.elements.push({
732
+ type: 'text',
733
+ text: lines.join('\n'),
734
+ fontSize,
735
+ textAlign: align,
736
+ color: colorOf(paint.fill, NEUTRAL_STROKE, sketch.notes) ?? NEUTRAL_STROKE,
737
+ xywh: xywh(px(frame, num(element, 'x')) - shift, py(frame, num(element, 'y')) - fontSize, w, h),
738
+ });
739
+ }
740
+ /** The names that are containers rather than drawings. */
741
+ const CONTAINERS = new Set(['g', 'a']);
742
+ /**
743
+ * What renders nothing and is therefore dropped in SILENCE — the one exception
744
+ * to "every ignored kind gets a note".
745
+ *
746
+ * A `<title>` is an accessible name, a `<desc>` a long description, a
747
+ * `<metadata>` block a machine-readable annotation. None of them paints a
748
+ * pixel, so there is no loss to report and a note about each would be three
749
+ * lines of noise on the first import of every file a real tool ever wrote.
750
+ * `<style>` is deliberately NOT here: it paints, and losing it is the single
751
+ * most visible thing this reader does to a mermaid diagram.
752
+ */
753
+ const NON_RENDERING = new Set(['title', 'desc', 'metadata']);
754
+ /** The sanitizer's own HTML wrapper, which no `.svg` on a disk ever contained. */
755
+ const PARSER_SCAFFOLDING = new Set(['html', 'head', 'body']);
756
+ function walk(parent, frame, inherited, sketch) {
757
+ for (const element of childElements(parent)) {
758
+ visit(element, frame, inherited, sketch);
759
+ }
760
+ }
761
+ /** One element and whatever it contains, placed in its parent's frame. */
762
+ function visit(element, frame, inherited, sketch) {
763
+ const name = nameOf(element);
764
+ if (NON_RENDERING.has(name))
765
+ return;
766
+ if (isHidden(element, sketch.notes))
767
+ return;
768
+ const here = translated(element, frame, sketch.notes);
769
+ const paint = paintOf(element, inherited, sketch.notes);
770
+ noteOpacity(element, sketch.notes);
771
+ if (CONTAINERS.has(name)) {
772
+ walk(element, here, paint, sketch);
773
+ return;
774
+ }
775
+ if (name === 'switch') {
776
+ // §5.10: a `<switch>` renders the FIRST child whose requirement attributes
777
+ // pass, and this reader evaluates none of them — so it takes the first,
778
+ // which is what a viewer that supports everything does, and says the
779
+ // alternatives went. Rendering all of them would stack every localisation
780
+ // of a label on top of itself.
781
+ const [first, ...rest] = childElements(element).filter(child => !NON_RENDERING.has(nameOf(child)));
782
+ if (rest.length > 0) {
783
+ sketch.notes.once('switch', 'A `<switch>` offers alternative renderings; the first was imported and the others were not.');
784
+ }
785
+ if (first)
786
+ visit(first, here, paint, sketch);
787
+ return;
788
+ }
789
+ if (name === 'svg') {
790
+ walk(element, viewportFrame(element, here), paint, sketch);
791
+ return;
792
+ }
793
+ emit(element, name, here, paint, sketch);
794
+ }
795
+ /** One recognised element, as props. Split out so `<switch>` can reuse it. */
796
+ function emit(element, name, frame, paint, sketch) {
797
+ switch (name) {
798
+ case 'rect':
799
+ readRect(element, frame, paint, sketch);
800
+ break;
801
+ case 'circle':
802
+ case 'ellipse':
803
+ readEllipse(element, frame, paint, sketch);
804
+ break;
805
+ case 'polygon':
806
+ readPolygon(element, frame, paint, sketch);
807
+ break;
808
+ case 'line':
809
+ pushStroke([
810
+ [px(frame, num(element, 'x1')), py(frame, num(element, 'y1'))],
811
+ [px(frame, num(element, 'x2')), py(frame, num(element, 'y2'))],
812
+ ], paint, frame, sketch);
813
+ break;
814
+ case 'polyline': {
815
+ const flat = numbers(element.getAttribute('points') ?? '');
816
+ const points = [];
817
+ for (let i = 0; i + 1 < flat.length; i += 2) {
818
+ points.push([px(frame, flat[i]), py(frame, flat[i + 1])]);
819
+ }
820
+ pushStroke(points, paint, frame, sketch);
821
+ break;
822
+ }
823
+ case 'path':
824
+ for (const subpath of samplePath(element.getAttribute('d') ?? '', sketch.notes)) {
825
+ pushStroke(subpath.map(([x, y]) => [px(frame, x), py(frame, y)]), paint, frame, sketch);
826
+ }
827
+ break;
828
+ case 'text':
829
+ readText(element, frame, paint, sketch);
830
+ break;
831
+ default:
832
+ // Everything this reader has no artefact for, named ONCE per kind:
833
+ // `<image>`, `<defs>`, `<marker>`, the gradients, the filters, `<style>`,
834
+ // and whatever SVG grows next. A drawing built out of symbol instances
835
+ // arrives nearly empty, and this is the line that tells its author why
836
+ // instead of leaving them to guess.
837
+ sketch.notes.once(`skipped:${name}`, `\`<${name}>\` is not recognised and was skipped.`, name);
838
+ }
839
+ }
840
+ /* ── The capability's function ────────────────────────────────────────── */
841
+ /**
842
+ * The document, sanitized, or an exception naming what is wrong with it.
843
+ *
844
+ * Well-formedness FIRST, because `DOMParser` reports a malformed document as a
845
+ * `parsererror` element rather than by throwing — a verdict in the shape of a
846
+ * document — and because DOMPurify's parser is the forgiving HTML one, which
847
+ * would quietly repair the very thing the caller needs to be told about. So:
848
+ * parse for the verdict, reading nothing out of the result but that; sanitize
849
+ * the SOURCE; and walk only what came back from the sanitizer.
850
+ *
851
+ * The sanitizer is not optional and it is not defensive programming. An `.svg`
852
+ * is an executable document — `<script>`, `<foreignObject>` with markup, event
853
+ * handler attributes — handed over by whoever sent the file. The same
854
+ * `USE_PROFILES: { svg: true }` guard is what the edgeless clipboard already
855
+ * puts in front of a pasted SVG.
856
+ */
857
+ function parseSvgRoot(source, notes) {
858
+ const doc = new DOMParser().parseFromString(source, 'image/svg+xml');
859
+ const error = doc.querySelector('parsererror');
860
+ if (error) {
861
+ // The FIRST line only. Chromium's `parsererror` is a whole rendered
862
+ // document — a heading, the message, then the offending source line with a
863
+ // caret under it — and pouring that into a toast makes the one sentence
864
+ // that matters unreadable.
865
+ const [summary = ''] = (error.textContent ?? '')
866
+ .split('\n')
867
+ .map(line => line.trim())
868
+ .filter(line => line.length > 0);
869
+ throw new Error(`This file is not well-formed XML, so no drawing can be read out of it: ${summary.slice(0, 200)}`);
870
+ }
871
+ if (nameOf(doc.documentElement) !== 'svg') {
872
+ throw new Error(`An SVG opens on <svg>; this one opens on <${doc.documentElement?.localName ?? 'nothing'}>.`);
873
+ }
874
+ const clean = DOMPurify.sanitize(source, {
875
+ USE_PROFILES: { svg: true },
876
+ RETURN_DOM: true,
877
+ });
878
+ // …and then say what the sanitizer took, which is NOT the same list as what
879
+ // the walk below skips. `<use>` and `<foreignObject>` never reach the walk at
880
+ // all — they are two of the SVG format's genuine attack surfaces and DOMPurify
881
+ // removes them outright — so a drawing built out of symbol instances arrives
882
+ // empty. Without this the only remark would be "nothing was recognised",
883
+ // which is true and useless. `DOMPurify.removed` is repopulated by each call
884
+ // and is read here immediately, before anything else can sanitize.
885
+ for (const entry of DOMPurify.removed) {
886
+ const removed = entry;
887
+ if (removed.element) {
888
+ // The node's OWN spelling, because `foreignObject` is camel-cased in the
889
+ // format and a remark that called it `foreignobject` would send its
890
+ // reader looking for something the spec does not have. The dedup key is
891
+ // folded; the sentence is not.
892
+ const name = removed.element.nodeName ?? '';
893
+ // The sanitizer parses into an HTML document and reports unwinding its
894
+ // own wrapper as a removal. Nobody wrote a `<body>` into an `.svg`, and a
895
+ // remark about one would be this reader telling the user about its own
896
+ // plumbing.
897
+ if (PARSER_SCAFFOLDING.has(name.toLowerCase()))
898
+ continue;
899
+ notes.once(`removed:${name.toLowerCase()}`, `\`<${name}>\` was removed while sanitizing the file — it is one of the constructs an SVG can carry code in — so nothing it drew was imported.`, name);
900
+ }
901
+ else if (removed.attribute) {
902
+ // Worded for what this actually is, which is broader than "unsafe": the
903
+ // sanitizer's allow-list drops an event handler AND a `requiredFeatures`,
904
+ // and calling the second one dangerous would be this reader accusing a
905
+ // perfectly ordinary file of something.
906
+ notes.once('removed-attribute', 'Attributes outside the safe SVG drawing vocabulary — event handlers, script URLs, and anything else the sanitizer does not know — were removed before the file was read.');
907
+ }
908
+ }
909
+ // No cast: `RETURN_DOM: true` in the literal selects DOMPurify's typed
910
+ // overload, which answers an `HTMLElement` — the sanitized body wrapper.
911
+ const root = childElements(clean).find(child => nameOf(child) === 'svg');
912
+ if (!root) {
913
+ throw new Error('Nothing survived sanitizing this SVG, so there is no drawing to read.');
914
+ }
915
+ return root;
916
+ }
917
+ /**
918
+ * An SVG file as a canvas sketch — the shared VISUAL-tier importer.
919
+ *
920
+ * See this module's own documentation for the heuristics statement and the
921
+ * known failure modes (ADR 0012, open question 2). The contract in one
922
+ * sentence: the picture arrives as editable elements, and nothing else is
923
+ * promised.
924
+ *
925
+ * A blank or unrecognisable drawing is `0` elements and a note, NOT an
926
+ * exception: the file was read, it simply held nothing this reader draws, and a
927
+ * throw would show the user an error toast where the truth is a remark.
928
+ * Malformed XML is the exception, because then the file was not read at all.
929
+ */
930
+ export function parseSvgSketch(source, context = {}) {
931
+ // A sketch has no document-level name to take: what a board is CALLED is the
932
+ // document's business, not any element's. Same answer the BPMN reader gives.
933
+ void context;
934
+ const sketch = { elements: [], notes: new Notebook() };
935
+ const root = parseSvgRoot(source, sketch.notes);
936
+ // The root `<svg>` paints like any other element — a `fill` on it is what
937
+ // every shape under it inherits — and it establishes the outermost viewport.
938
+ walk(root, viewportFrame(root, IDENTITY), paintOf(root, INITIAL_PAINT, sketch.notes), sketch);
939
+ if (sketch.elements.length === 0) {
940
+ sketch.notes.once('empty', 'No shape or text was recognised in this SVG, so nothing was drawn.');
941
+ }
942
+ return {
943
+ elements: sketch.elements,
944
+ report: {
945
+ mapped: sketch.elements.length,
946
+ // Always zero, and it is the tier's whole contract rather than an
947
+ // accident of this file: a visual import carries nothing and quarantines
948
+ // nothing, because it writes no `interchange` payload to carry anything
949
+ // IN (ADR 0012, P2). Pinned by an anti-decay test.
950
+ carried: 0,
951
+ quarantined: 0,
952
+ notes: sketch.notes.notes,
953
+ // …and no `sourceVersion`. An SVG declares a version of the SVG spec, not
954
+ // a version of a vocabulary this reader translates, so claiming one would
955
+ // be a fact about the file dressed up as a fact about the import.
956
+ },
957
+ };
958
+ }