@heycys/gallery 0.0.0-stage → 0.1.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 (785) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -2
  3. package/THIRD-PARTY-NOTICES.md +3253 -0
  4. package/assets/writing-preferences.md +107 -0
  5. package/bin/gallery.mjs +10 -0
  6. package/browser/editor/components/bookmark/icons.mjs +6 -0
  7. package/browser/editor/components/bookmark/index.mjs +80 -0
  8. package/browser/editor/components/bookmark/page.mjs +147 -0
  9. package/browser/editor/components/builders.mjs +19 -0
  10. package/browser/editor/components/callout/index.mjs +39 -0
  11. package/browser/editor/components/callout/page.mjs +13 -0
  12. package/browser/editor/components/code/index.mjs +327 -0
  13. package/browser/editor/components/code/page.mjs +561 -0
  14. package/browser/editor/components/colors.mjs +50 -0
  15. package/browser/editor/components/columns/index.mjs +104 -0
  16. package/browser/editor/components/columns/page.mjs +297 -0
  17. package/browser/editor/components/details/index.mjs +72 -0
  18. package/browser/editor/components/details/page.mjs +86 -0
  19. package/browser/editor/components/dialog/index.mjs +83 -0
  20. package/browser/editor/components/dialog/page.mjs +219 -0
  21. package/browser/editor/components/divider/index.mjs +48 -0
  22. package/browser/editor/components/embed/icons.mjs +11 -0
  23. package/browser/editor/components/embed/index.mjs +123 -0
  24. package/browser/editor/components/embed/page.mjs +309 -0
  25. package/browser/editor/components/figure/index.mjs +87 -0
  26. package/browser/editor/components/figure/page.mjs +33 -0
  27. package/browser/editor/components/file/icons.mjs +14 -0
  28. package/browser/editor/components/file/index.mjs +77 -0
  29. package/browser/editor/components/file/page.mjs +114 -0
  30. package/browser/editor/components/flowchart/add.mjs +123 -0
  31. package/browser/editor/components/flowchart/index.mjs +246 -0
  32. package/browser/editor/components/flowchart/page.mjs +453 -0
  33. package/browser/editor/components/heading/index.mjs +51 -0
  34. package/browser/editor/components/highlight/index.mjs +79 -0
  35. package/browser/editor/components/icon/index.mjs +57 -0
  36. package/browser/editor/components/icon/page.mjs +286 -0
  37. package/browser/editor/components/icons.mjs +45 -0
  38. package/browser/editor/components/image/crop.mjs +189 -0
  39. package/browser/editor/components/image/index.mjs +104 -0
  40. package/browser/editor/components/image/page.mjs +385 -0
  41. package/browser/editor/components/image/viewer.mjs +213 -0
  42. package/browser/editor/components/installed/index.mjs +133 -0
  43. package/browser/editor/components/installed/page.mjs +422 -0
  44. package/browser/editor/components/installed/served.mjs +35 -0
  45. package/browser/editor/components/kit.mjs +64 -0
  46. package/browser/editor/components/list/index.mjs +194 -0
  47. package/browser/editor/components/list/join.mjs +68 -0
  48. package/browser/editor/components/list/numbers.mjs +107 -0
  49. package/browser/editor/components/list/page.mjs +632 -0
  50. package/browser/editor/components/math/index.mjs +88 -0
  51. package/browser/editor/components/math/page.mjs +236 -0
  52. package/browser/editor/components/math/tex-logo.mjs +6 -0
  53. package/browser/editor/components/media/icons.mjs +19 -0
  54. package/browser/editor/components/media/page.mjs +162 -0
  55. package/browser/editor/components/media/parts.mjs +60 -0
  56. package/browser/editor/components/media/size.mjs +20 -0
  57. package/browser/editor/components/media/toolbar.mjs +37 -0
  58. package/browser/editor/components/media/write.mjs +7 -0
  59. package/browser/editor/components/pages.mjs +46 -0
  60. package/browser/editor/components/paragraph/index.mjs +43 -0
  61. package/browser/editor/components/paragraph/page.mjs +52 -0
  62. package/browser/editor/components/placeholder-bar.mjs +17 -0
  63. package/browser/editor/components/placeholder.mjs +128 -0
  64. package/browser/editor/components/quote/index.mjs +33 -0
  65. package/browser/editor/components/registry.mjs +833 -0
  66. package/browser/editor/components/rows.mjs +16 -0
  67. package/browser/editor/components/section/index.mjs +41 -0
  68. package/browser/editor/components/section/page.mjs +141 -0
  69. package/browser/editor/components/sheets/index.mjs +137 -0
  70. package/browser/editor/components/sheets/page.mjs +227 -0
  71. package/browser/editor/components/sheets/pills.mjs +226 -0
  72. package/browser/editor/components/table/grid.mjs +73 -0
  73. package/browser/editor/components/table/index.mjs +306 -0
  74. package/browser/editor/components/table/page.mjs +672 -0
  75. package/browser/editor/components/table/slots.mjs +41 -0
  76. package/browser/editor/components/widget/index.mjs +50 -0
  77. package/browser/editor/page/annotate/anchors.mjs +229 -0
  78. package/browser/editor/page/annotate/card.mjs +102 -0
  79. package/browser/editor/page/annotate/index.mjs +1629 -0
  80. package/browser/editor/page/at-menu/index.mjs +317 -0
  81. package/browser/editor/page/autosave.mjs +977 -0
  82. package/browser/editor/page/beside.mjs +21 -0
  83. package/browser/editor/page/block-info.mjs +63 -0
  84. package/browser/editor/page/block-menu/colors.mjs +82 -0
  85. package/browser/editor/page/block-menu/index.mjs +215 -0
  86. package/browser/editor/page/blocks.mjs +246 -0
  87. package/browser/editor/page/caret.mjs +679 -0
  88. package/browser/editor/page/chip-fills.mjs +126 -0
  89. package/browser/editor/page/clipboard/import/colors.mjs +192 -0
  90. package/browser/editor/page/clipboard/import/html.mjs +792 -0
  91. package/browser/editor/page/clipboard/import/inline.mjs +232 -0
  92. package/browser/editor/page/clipboard/import/languages.mjs +42 -0
  93. package/browser/editor/page/clipboard/import/markdown.mjs +760 -0
  94. package/browser/editor/page/clipboard/import/math.mjs +100 -0
  95. package/browser/editor/page/clipboard/import/office.mjs +245 -0
  96. package/browser/editor/page/clipboard/import/read.mjs +120 -0
  97. package/browser/editor/page/clipboard/import/rich.mjs +29 -0
  98. package/browser/editor/page/clipboard/import/to-blocks.mjs +290 -0
  99. package/browser/editor/page/clipboard/index.mjs +797 -0
  100. package/browser/editor/page/clipboard/own/blocks.mjs +202 -0
  101. package/browser/editor/page/clipboard/own/chart-keys.mjs +58 -0
  102. package/browser/editor/page/clipboard/own/describe.mjs +115 -0
  103. package/browser/editor/page/clipboard/own/export.mjs +167 -0
  104. package/browser/editor/page/clipboard/own/ids.mjs +39 -0
  105. package/browser/editor/page/clipboard/own/index.mjs +13 -0
  106. package/browser/editor/page/clipboard/own/rules.mjs +44 -0
  107. package/browser/editor/page/clipboard/own/selection.mjs +159 -0
  108. package/browser/editor/page/clipboard/own/writers.mjs +326 -0
  109. package/browser/editor/page/columns/index.mjs +360 -0
  110. package/browser/editor/page/commit.mjs +1798 -0
  111. package/browser/editor/page/conflicts.mjs +269 -0
  112. package/browser/editor/page/convert.mjs +830 -0
  113. package/browser/editor/page/core.mjs +1655 -0
  114. package/browser/editor/page/drag/drop.mjs +307 -0
  115. package/browser/editor/page/drag/index.mjs +335 -0
  116. package/browser/editor/page/drag/preview.mjs +121 -0
  117. package/browser/editor/page/edge-scroll.mjs +50 -0
  118. package/browser/editor/page/editor.mjs +1725 -0
  119. package/browser/editor/page/emoji-picker/emoji-tab.mjs +278 -0
  120. package/browser/editor/page/emoji-picker/glyph-html.mjs +26 -0
  121. package/browser/editor/page/emoji-picker/grid.mjs +79 -0
  122. package/browser/editor/page/emoji-picker/icon-tab.mjs +217 -0
  123. package/browser/editor/page/emoji-picker/icons.mjs +32 -0
  124. package/browser/editor/page/emoji-picker/index.mjs +164 -0
  125. package/browser/editor/page/emoji-picker/styles.mjs +2 -0
  126. package/browser/editor/page/emoji-picker/support.mjs +202 -0
  127. package/browser/editor/page/emoji-picker/upload.mjs +235 -0
  128. package/browser/editor/page/export-report.mjs +23 -0
  129. package/browser/editor/page/fills.mjs +60 -0
  130. package/browser/editor/page/find/index.mjs +107 -0
  131. package/browser/editor/page/flags.mjs +70 -0
  132. package/browser/editor/page/format-bar/bar.mjs +448 -0
  133. package/browser/editor/page/format-bar/brush.mjs +77 -0
  134. package/browser/editor/page/format-bar/colors.mjs +46 -0
  135. package/browser/editor/page/format-bar/index.mjs +404 -0
  136. package/browser/editor/page/formula/index.mjs +236 -0
  137. package/browser/editor/page/formula/panel.mjs +336 -0
  138. package/browser/editor/page/formula/symbols.mjs +156 -0
  139. package/browser/editor/page/frame.mjs +74 -0
  140. package/browser/editor/page/frames.mjs +196 -0
  141. package/browser/editor/page/geometry.mjs +400 -0
  142. package/browser/editor/page/gesture.mjs +45 -0
  143. package/browser/editor/page/handle/index.mjs +639 -0
  144. package/browser/editor/page/handle-sizes.mjs +14 -0
  145. package/browser/editor/page/hints/index.mjs +84 -0
  146. package/browser/editor/page/history.mjs +401 -0
  147. package/browser/editor/page/insert/index.mjs +243 -0
  148. package/browser/editor/page/kept.mjs +38 -0
  149. package/browser/editor/page/links/address.mjs +40 -0
  150. package/browser/editor/page/links/index.mjs +866 -0
  151. package/browser/editor/page/links/pages.mjs +131 -0
  152. package/browser/editor/page/links/views.mjs +369 -0
  153. package/browser/editor/page/look.mjs +65 -0
  154. package/browser/editor/page/made.mjs +24 -0
  155. package/browser/editor/page/margin.mjs +352 -0
  156. package/browser/editor/page/markdown/index.mjs +88 -0
  157. package/browser/editor/page/markdown/rules.mjs +33 -0
  158. package/browser/editor/page/marks.mjs +377 -0
  159. package/browser/editor/page/media-menu/index.mjs +158 -0
  160. package/browser/editor/page/menu.mjs +500 -0
  161. package/browser/editor/page/merge.mjs +100 -0
  162. package/browser/editor/page/notices.mjs +142 -0
  163. package/browser/editor/page/offered.mjs +32 -0
  164. package/browser/editor/page/outline/folds.mjs +52 -0
  165. package/browser/editor/page/outline/index.mjs +697 -0
  166. package/browser/editor/page/outline/list.mjs +172 -0
  167. package/browser/editor/page/outline/read.mjs +201 -0
  168. package/browser/editor/page/outline/strip.mjs +281 -0
  169. package/browser/editor/page/outline/tree.mjs +248 -0
  170. package/browser/editor/page/overlay-layer.mjs +227 -0
  171. package/browser/editor/page/overlays.mjs +205 -0
  172. package/browser/editor/page/own.mjs +28 -0
  173. package/browser/editor/page/pads.mjs +71 -0
  174. package/browser/editor/page/page-objects.mjs +105 -0
  175. package/browser/editor/page/panel.mjs +64 -0
  176. package/browser/editor/page/placement.mjs +58 -0
  177. package/browser/editor/page/post.mjs +41 -0
  178. package/browser/editor/page/present-links.mjs +50 -0
  179. package/browser/editor/page/quiet.mjs +48 -0
  180. package/browser/editor/page/resize/index.mjs +327 -0
  181. package/browser/editor/page/select-all/index.mjs +262 -0
  182. package/browser/editor/page/selection/delete.mjs +59 -0
  183. package/browser/editor/page/selection/index.mjs +157 -0
  184. package/browser/editor/page/selection/marquee.mjs +174 -0
  185. package/browser/editor/page/session.mjs +117 -0
  186. package/browser/editor/page/slash-menu/index.mjs +291 -0
  187. package/browser/editor/page/storage.mjs +48 -0
  188. package/browser/editor/page/sync-state.mjs +267 -0
  189. package/browser/editor/page/table/aligns.mjs +29 -0
  190. package/browser/editor/page/table/cell-bar.mjs +138 -0
  191. package/browser/editor/page/table/cells.mjs +527 -0
  192. package/browser/editor/page/table/icons.mjs +40 -0
  193. package/browser/editor/page/table/index.mjs +985 -0
  194. package/browser/editor/page/table/lists.mjs +187 -0
  195. package/browser/editor/page/table/widths.mjs +308 -0
  196. package/browser/editor/page/tex.mjs +32 -0
  197. package/browser/editor/page/text-select/index.mjs +656 -0
  198. package/browser/editor/page/tooltip.mjs +98 -0
  199. package/browser/editor/page/type-grid.mjs +82 -0
  200. package/browser/editor/page/typing/code-edges.mjs +228 -0
  201. package/browser/editor/page/typing/index.mjs +276 -0
  202. package/browser/editor/page/typing/leave.mjs +68 -0
  203. package/browser/editor/page/ui.mjs +160 -0
  204. package/browser/shared/annotations.mjs +571 -0
  205. package/browser/shared/code-folds.mjs +10 -0
  206. package/browser/shared/code-languages.mjs +70 -0
  207. package/browser/shared/code-lines.mjs +30 -0
  208. package/browser/shared/colors.mjs +28 -0
  209. package/browser/shared/component-catalog.mjs +559 -0
  210. package/browser/shared/components/bookmark.mjs +26 -0
  211. package/browser/shared/components/callout.mjs +7 -0
  212. package/browser/shared/components/chart.mjs +20 -0
  213. package/browser/shared/components/code.mjs +37 -0
  214. package/browser/shared/components/columns.mjs +16 -0
  215. package/browser/shared/components/details.mjs +15 -0
  216. package/browser/shared/components/dialog.mjs +28 -0
  217. package/browser/shared/components/diff.mjs +18 -0
  218. package/browser/shared/components/divider.mjs +6 -0
  219. package/browser/shared/components/embed.mjs +25 -0
  220. package/browser/shared/components/figure.mjs +14 -0
  221. package/browser/shared/components/file.mjs +23 -0
  222. package/browser/shared/components/heading.mjs +6 -0
  223. package/browser/shared/components/highlight.mjs +9 -0
  224. package/browser/shared/components/icon.mjs +18 -0
  225. package/browser/shared/components/image.mjs +39 -0
  226. package/browser/shared/components/index.mjs +342 -0
  227. package/browser/shared/components/installed.mjs +162 -0
  228. package/browser/shared/components/list.mjs +146 -0
  229. package/browser/shared/components/math.mjs +49 -0
  230. package/browser/shared/components/mention.mjs +33 -0
  231. package/browser/shared/components/page.mjs +37 -0
  232. package/browser/shared/components/paragraph.mjs +9 -0
  233. package/browser/shared/components/quote.mjs +6 -0
  234. package/browser/shared/components/section.mjs +8 -0
  235. package/browser/shared/components/sheets.mjs +80 -0
  236. package/browser/shared/components/state.mjs +20 -0
  237. package/browser/shared/components/table.mjs +49 -0
  238. package/browser/shared/components/text.mjs +14 -0
  239. package/browser/shared/components/widget.mjs +10 -0
  240. package/browser/shared/copy-ids.mjs +72 -0
  241. package/browser/shared/css-references.mjs +110 -0
  242. package/browser/shared/emoji/custom.mjs +91 -0
  243. package/browser/shared/emoji/data/LICENSE-mingcute.txt +202 -0
  244. package/browser/shared/emoji/data/LICENSE-tabler.txt +21 -0
  245. package/browser/shared/emoji/data/README.md +26 -0
  246. package/browser/shared/emoji/data/categories.json +1 -0
  247. package/browser/shared/emoji/data/icons.json +1 -0
  248. package/browser/shared/emoji/data/keywords-en.json +1 -0
  249. package/browser/shared/emoji/data/keywords-zh.json +1 -0
  250. package/browser/shared/emoji/data/names.json +1 -0
  251. package/browser/shared/emoji/data/positions.json +1 -0
  252. package/browser/shared/emoji/data/twemoji-index.json +1 -0
  253. package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
  254. package/browser/shared/emoji/data.mjs +196 -0
  255. package/browser/shared/emoji/emoji.mjs +37 -0
  256. package/browser/shared/emoji/glyphs.mjs +134 -0
  257. package/browser/shared/emoji/icon-value.mjs +90 -0
  258. package/browser/shared/escape.mjs +20 -0
  259. package/browser/shared/export-wrap.mjs +89 -0
  260. package/browser/shared/files.mjs +33 -0
  261. package/browser/shared/html-tree.mjs +53 -0
  262. package/browser/shared/http.mjs +22 -0
  263. package/browser/shared/i18n/en.mjs +1164 -0
  264. package/browser/shared/i18n/index.mjs +132 -0
  265. package/browser/shared/ids.mjs +24 -0
  266. package/browser/shared/import-types.mjs +23 -0
  267. package/browser/shared/inline-spacing.mjs +97 -0
  268. package/browser/shared/layers.mjs +42 -0
  269. package/browser/shared/media.mjs +162 -0
  270. package/browser/shared/new-names.mjs +64 -0
  271. package/browser/shared/number-reading.mjs +92 -0
  272. package/browser/shared/old-names.mjs +143 -0
  273. package/browser/shared/page-address.mjs +140 -0
  274. package/browser/shared/page-links.mjs +86 -0
  275. package/browser/shared/paths.mjs +73 -0
  276. package/browser/shared/preferences.mjs +110 -0
  277. package/browser/shared/preview-server.mjs +247 -0
  278. package/browser/shared/qa-levels.mjs +93 -0
  279. package/browser/shared/reading-place.mjs +91 -0
  280. package/browser/shared/renamed-storage.mjs +220 -0
  281. package/browser/shared/reports.mjs +46 -0
  282. package/browser/shared/search.mjs +85 -0
  283. package/browser/shared/session.mjs +76 -0
  284. package/browser/shared/table-chart.mjs +113 -0
  285. package/browser/shared/table-hides.mjs +120 -0
  286. package/browser/shared/table-slots.mjs +75 -0
  287. package/browser/shared/words.mjs +23 -0
  288. package/browser/shared/workspace.mjs +535 -0
  289. package/browser/shared/writing-preferences.mjs +68 -0
  290. package/browser/shared/zoom.mjs +57 -0
  291. package/dist/chunk-2B5E4CDJ.mjs +2 -0
  292. package/dist/chunk-2PBALTR3.mjs +57 -0
  293. package/dist/chunk-342HXE3Q.mjs +2 -0
  294. package/dist/chunk-3LA3EMDE.mjs +15 -0
  295. package/dist/chunk-43B75J5T.mjs +2 -0
  296. package/dist/chunk-4K5KC6V2.mjs +2 -0
  297. package/dist/chunk-5FRMCDPY.mjs +16 -0
  298. package/dist/chunk-5L7RYZCL.mjs +2 -0
  299. package/dist/chunk-5LEK2CBS.mjs +2 -0
  300. package/dist/chunk-5OFN5AHC.mjs +2 -0
  301. package/dist/chunk-5SIYS5HN.mjs +2 -0
  302. package/dist/chunk-5TEK3RAD.mjs +2 -0
  303. package/dist/chunk-6CYG3Z4V.mjs +2 -0
  304. package/dist/chunk-6U2SLSDN.mjs +3 -0
  305. package/dist/chunk-742D2WWJ.mjs +19 -0
  306. package/dist/chunk-7GHT2UCA.mjs +15 -0
  307. package/dist/chunk-7QQBR7PB.mjs +2 -0
  308. package/dist/chunk-A55HN5OK.mjs +2 -0
  309. package/dist/chunk-ACOPDCNB.mjs +2 -0
  310. package/dist/chunk-AGDILNWB.mjs +2 -0
  311. package/dist/chunk-ATCJYAR4.mjs +2 -0
  312. package/dist/chunk-B3VTYBYR.mjs +960 -0
  313. package/dist/chunk-C564NU2H.mjs +77 -0
  314. package/dist/chunk-C7HWOBIF.mjs +2 -0
  315. package/dist/chunk-DB4WKGYF.mjs +7 -0
  316. package/dist/chunk-E7VYDG2X.mjs +2 -0
  317. package/dist/chunk-EUX7IC5J.mjs +48 -0
  318. package/dist/chunk-EVJ3BX3M.mjs +2 -0
  319. package/dist/chunk-EZY3WC6Z.mjs +15 -0
  320. package/dist/chunk-FQGQH4KM.mjs +2 -0
  321. package/dist/chunk-G7TOXONE.mjs +6 -0
  322. package/dist/chunk-GPF4YWWB.mjs +9 -0
  323. package/dist/chunk-GRAXKKG4.mjs +2 -0
  324. package/dist/chunk-GYQV7Y4J.mjs +120 -0
  325. package/dist/chunk-HMHK3EQ6.mjs +2 -0
  326. package/dist/chunk-HQQMJCQJ.mjs +10 -0
  327. package/dist/chunk-HYMEEXKN.mjs +4 -0
  328. package/dist/chunk-IERUOGC3.mjs +6 -0
  329. package/dist/chunk-ITNLYXXV.mjs +3 -0
  330. package/dist/chunk-L4DVONOG.mjs +2 -0
  331. package/dist/chunk-LAE5NQ4B.mjs +2 -0
  332. package/dist/chunk-LC7YNQFG.mjs +2 -0
  333. package/dist/chunk-LHTFLRB6.mjs +4 -0
  334. package/dist/chunk-LKX55H76.mjs +2 -0
  335. package/dist/chunk-MAFIGVXY.mjs +2 -0
  336. package/dist/chunk-NFIBI4IP.mjs +26 -0
  337. package/dist/chunk-NSKUTQ5J.mjs +5 -0
  338. package/dist/chunk-O52JMOCZ.mjs +2 -0
  339. package/dist/chunk-P2CAZPDP.mjs +3 -0
  340. package/dist/chunk-QAIHRH3I.mjs +13 -0
  341. package/dist/chunk-QMQUXTU4.mjs +12 -0
  342. package/dist/chunk-QR6A54KJ.mjs +3 -0
  343. package/dist/chunk-QVWVFC5K.mjs +6 -0
  344. package/dist/chunk-QYKCJ7FG.mjs +8 -0
  345. package/dist/chunk-QZY6Q64C.mjs +2 -0
  346. package/dist/chunk-TDQP3DKQ.mjs +10 -0
  347. package/dist/chunk-TMYZB6AV.mjs +2 -0
  348. package/dist/chunk-TX6JH7TR.mjs +2 -0
  349. package/dist/chunk-U3SSPL4K.mjs +8 -0
  350. package/dist/chunk-UH4SIXTR.mjs +2 -0
  351. package/dist/chunk-UNUEWH4S.mjs +2 -0
  352. package/dist/chunk-UXUK4PMC.mjs +27 -0
  353. package/dist/chunk-V4CPWKMZ.mjs +2 -0
  354. package/dist/chunk-V6XZ4VIR.mjs +2 -0
  355. package/dist/chunk-VACRB2NE.mjs +3 -0
  356. package/dist/chunk-W63L7367.mjs +7 -0
  357. package/dist/chunk-W7CXPCRV.mjs +6 -0
  358. package/dist/chunk-W7XHE4CT.mjs +2 -0
  359. package/dist/chunk-XINNG4F2.mjs +4 -0
  360. package/dist/chunk-Y34NR5JL.mjs +2 -0
  361. package/dist/chunk-YEY3RSFQ.mjs +2 -0
  362. package/dist/chunk-YL2DPWVS.mjs +4 -0
  363. package/dist/chunk-YXAUQPVK.mjs +8 -0
  364. package/dist/chunk-YZ5Z6H4W.mjs +4 -0
  365. package/dist/chunk-Z52HTUW7.mjs +4 -0
  366. package/dist/chunk-ZBIM6ARY.mjs +216 -0
  367. package/dist/cli.mjs +2 -0
  368. package/dist/server.mjs +2 -0
  369. package/dist/worker.mjs +5 -0
  370. package/kit/charts.js +355 -0
  371. package/kit/code.js +164 -0
  372. package/kit/dialogs.js +157 -0
  373. package/kit/math.js +1988 -0
  374. package/kit/report.css +2821 -0
  375. package/kit/runtime.js +1707 -0
  376. package/kit/sheets.js +123 -0
  377. package/kit/state.js +217 -0
  378. package/kit/tables.js +1449 -0
  379. package/kit/tokens.js +29 -0
  380. package/kit/ui.js +561 -0
  381. package/package.json +41 -4
  382. package/release.json +25 -0
  383. package/sdk/column-widths.d.ts +56 -0
  384. package/sdk/doc-charts.d.ts +82 -0
  385. package/sdk/doc-code.d.ts +28 -0
  386. package/sdk/doc-dialogs.d.ts +4 -0
  387. package/sdk/doc-kit.d.ts +141 -0
  388. package/sdk/doc-math.d.ts +3 -0
  389. package/sdk/doc-sheets.d.ts +15 -0
  390. package/sdk/doc-state.d.ts +41 -0
  391. package/sdk/doc-tables.d.ts +24 -0
  392. package/sdk/doc-tokens.d.ts +22 -0
  393. package/sdk/index.d.ts +30 -0
  394. package/skill/SKILL.md +138 -0
  395. package/skill/agents/openai.yaml +5 -0
  396. package/skill/references/building-components.md +327 -0
  397. package/skill/references/example-report.html +356 -0
  398. package/skill/references/writing-html.md +187 -0
  399. package/skill/sdk/column-widths.d.ts +56 -0
  400. package/skill/sdk/doc-charts.d.ts +82 -0
  401. package/skill/sdk/doc-code.d.ts +28 -0
  402. package/skill/sdk/doc-dialogs.d.ts +4 -0
  403. package/skill/sdk/doc-kit.d.ts +141 -0
  404. package/skill/sdk/doc-math.d.ts +3 -0
  405. package/skill/sdk/doc-sheets.d.ts +15 -0
  406. package/skill/sdk/doc-state.d.ts +41 -0
  407. package/skill/sdk/doc-tables.d.ts +24 -0
  408. package/skill/sdk/doc-tokens.d.ts +22 -0
  409. package/skill/sdk/index.d.ts +30 -0
  410. package/starter/doc.html +21 -0
  411. package/starter/doc.json +5 -0
  412. package/vendor/d3.v7.9.0.min.js +2 -0
  413. package/vendor/katex/auto-render.min.js +1 -0
  414. package/vendor/katex/contrib/mhchem.min.js +1 -0
  415. package/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  416. package/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  417. package/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  418. package/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  419. package/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  420. package/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  421. package/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  422. package/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  423. package/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  424. package/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  425. package/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  426. package/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  427. package/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  428. package/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  429. package/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  430. package/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  431. package/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  432. package/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  433. package/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  434. package/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  435. package/vendor/katex/katex.min.css +1 -0
  436. package/vendor/katex/katex.min.js +1 -0
  437. package/vendor/pdfjs/LICENSE +177 -0
  438. package/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
  439. package/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
  440. package/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
  441. package/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
  442. package/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
  443. package/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
  444. package/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
  445. package/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
  446. package/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
  447. package/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
  448. package/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
  449. package/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
  450. package/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
  451. package/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
  452. package/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
  453. package/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
  454. package/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
  455. package/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
  456. package/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
  457. package/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
  458. package/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
  459. package/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
  460. package/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
  461. package/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
  462. package/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
  463. package/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
  464. package/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  465. package/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
  466. package/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
  467. package/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
  468. package/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
  469. package/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
  470. package/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
  471. package/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  472. package/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
  473. package/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
  474. package/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
  475. package/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
  476. package/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
  477. package/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
  478. package/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
  479. package/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  480. package/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
  481. package/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
  482. package/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
  483. package/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  484. package/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
  485. package/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
  486. package/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
  487. package/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
  488. package/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
  489. package/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
  490. package/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
  491. package/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
  492. package/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
  493. package/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
  494. package/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
  495. package/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
  496. package/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
  497. package/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
  498. package/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
  499. package/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
  500. package/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
  501. package/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
  502. package/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
  503. package/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
  504. package/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
  505. package/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
  506. package/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
  507. package/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
  508. package/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
  509. package/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
  510. package/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
  511. package/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
  512. package/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
  513. package/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
  514. package/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
  515. package/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
  516. package/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
  517. package/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
  518. package/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
  519. package/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
  520. package/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
  521. package/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
  522. package/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
  523. package/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
  524. package/vendor/pdfjs/cmaps/H.bcmap +0 -0
  525. package/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
  526. package/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
  527. package/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
  528. package/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
  529. package/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
  530. package/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
  531. package/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
  532. package/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
  533. package/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
  534. package/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
  535. package/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
  536. package/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
  537. package/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
  538. package/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
  539. package/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
  540. package/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
  541. package/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
  542. package/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
  543. package/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
  544. package/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
  545. package/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
  546. package/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  547. package/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  548. package/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
  549. package/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
  550. package/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
  551. package/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
  552. package/vendor/pdfjs/cmaps/LICENSE +36 -0
  553. package/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
  554. package/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
  555. package/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
  556. package/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
  557. package/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
  558. package/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  559. package/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  560. package/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  561. package/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  562. package/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  563. package/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  564. package/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  565. package/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  566. package/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
  567. package/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
  568. package/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
  569. package/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
  570. package/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
  571. package/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
  572. package/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
  573. package/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
  574. package/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  575. package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  576. package/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  577. package/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  578. package/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  579. package/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  580. package/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  581. package/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  582. package/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  583. package/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  584. package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  585. package/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  586. package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  587. package/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  588. package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  589. package/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  590. package/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  591. package/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  592. package/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  593. package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  594. package/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  595. package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  596. package/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  597. package/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
  598. package/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
  599. package/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
  600. package/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
  601. package/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
  602. package/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
  603. package/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
  604. package/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
  605. package/vendor/pdfjs/cmaps/V.bcmap +0 -0
  606. package/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
  607. package/vendor/pdfjs/legacy/build/pdf.min.mjs +27 -0
  608. package/vendor/pdfjs/legacy/build/pdf.worker.min.mjs +27 -0
  609. package/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
  610. package/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
  611. package/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
  612. package/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  613. package/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
  614. package/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
  615. package/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
  616. package/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  617. package/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
  618. package/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
  619. package/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
  620. package/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +363 -0
  621. package/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
  622. package/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  623. package/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
  624. package/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
  625. package/vendor/types/@types/d3/LICENSE +21 -0
  626. package/vendor/types/@types/d3/index.d.ts +39 -0
  627. package/vendor/types/@types/d3/package.json +81 -0
  628. package/vendor/types/@types/d3-array/LICENSE +21 -0
  629. package/vendor/types/@types/d3-array/index.d.ts +1118 -0
  630. package/vendor/types/@types/d3-array/package.json +56 -0
  631. package/vendor/types/@types/d3-axis/LICENSE +21 -0
  632. package/vendor/types/@types/d3-axis/index.d.ts +293 -0
  633. package/vendor/types/@types/d3-axis/package.json +47 -0
  634. package/vendor/types/@types/d3-brush/LICENSE +21 -0
  635. package/vendor/types/@types/d3-brush/index.d.ts +255 -0
  636. package/vendor/types/@types/d3-brush/package.json +42 -0
  637. package/vendor/types/@types/d3-chord/LICENSE +21 -0
  638. package/vendor/types/@types/d3-chord/index.d.ts +471 -0
  639. package/vendor/types/@types/d3-chord/package.json +40 -0
  640. package/vendor/types/@types/d3-color/LICENSE +21 -0
  641. package/vendor/types/@types/d3-color/index.d.ts +669 -0
  642. package/vendor/types/@types/d3-color/package.json +55 -0
  643. package/vendor/types/@types/d3-contour/LICENSE +21 -0
  644. package/vendor/types/@types/d3-contour/index.d.ts +222 -0
  645. package/vendor/types/@types/d3-contour/package.json +38 -0
  646. package/vendor/types/@types/d3-delaunay/LICENSE +21 -0
  647. package/vendor/types/@types/d3-delaunay/index.d.ts +316 -0
  648. package/vendor/types/@types/d3-delaunay/package.json +30 -0
  649. package/vendor/types/@types/d3-dispatch/LICENSE +21 -0
  650. package/vendor/types/@types/d3-dispatch/index.d.ts +96 -0
  651. package/vendor/types/@types/d3-dispatch/package.json +51 -0
  652. package/vendor/types/@types/d3-drag/LICENSE +21 -0
  653. package/vendor/types/@types/d3-drag/index.d.ts +395 -0
  654. package/vendor/types/@types/d3-drag/package.json +42 -0
  655. package/vendor/types/@types/d3-dsv/LICENSE +21 -0
  656. package/vendor/types/@types/d3-dsv/index.d.ts +482 -0
  657. package/vendor/types/@types/d3-dsv/package.json +45 -0
  658. package/vendor/types/@types/d3-ease/LICENSE +21 -0
  659. package/vendor/types/@types/d3-ease/index.d.ts +316 -0
  660. package/vendor/types/@types/d3-ease/package.json +40 -0
  661. package/vendor/types/@types/d3-fetch/LICENSE +21 -0
  662. package/vendor/types/@types/d3-fetch/index.d.ts +282 -0
  663. package/vendor/types/@types/d3-fetch/package.json +37 -0
  664. package/vendor/types/@types/d3-force/LICENSE +21 -0
  665. package/vendor/types/@types/d3-force/index.d.ts +899 -0
  666. package/vendor/types/@types/d3-force/package.json +45 -0
  667. package/vendor/types/@types/d3-format/LICENSE +21 -0
  668. package/vendor/types/@types/d3-format/index.d.ts +337 -0
  669. package/vendor/types/@types/d3-format/package.json +45 -0
  670. package/vendor/types/@types/d3-geo/LICENSE +21 -0
  671. package/vendor/types/@types/d3-geo/index.d.ts +1371 -0
  672. package/vendor/types/@types/d3-geo/package.json +48 -0
  673. package/vendor/types/@types/d3-hierarchy/LICENSE +21 -0
  674. package/vendor/types/@types/d3-hierarchy/index.d.ts +928 -0
  675. package/vendor/types/@types/d3-hierarchy/package.json +50 -0
  676. package/vendor/types/@types/d3-interpolate/LICENSE +21 -0
  677. package/vendor/types/@types/d3-interpolate/index.d.ts +387 -0
  678. package/vendor/types/@types/d3-interpolate/package.json +47 -0
  679. package/vendor/types/@types/d3-path/LICENSE +21 -0
  680. package/vendor/types/@types/d3-path/index.d.ts +108 -0
  681. package/vendor/types/@types/d3-path/package.json +41 -0
  682. package/vendor/types/@types/d3-polygon/LICENSE +21 -0
  683. package/vendor/types/@types/d3-polygon/index.d.ts +41 -0
  684. package/vendor/types/@types/d3-polygon/package.json +40 -0
  685. package/vendor/types/@types/d3-quadtree/LICENSE +21 -0
  686. package/vendor/types/@types/d3-quadtree/index.d.ts +204 -0
  687. package/vendor/types/@types/d3-quadtree/package.json +45 -0
  688. package/vendor/types/@types/d3-random/LICENSE +21 -0
  689. package/vendor/types/@types/d3-random/index.d.ts +313 -0
  690. package/vendor/types/@types/d3-random/package.json +41 -0
  691. package/vendor/types/@types/d3-scale/LICENSE +21 -0
  692. package/vendor/types/@types/d3-scale/index.d.ts +2669 -0
  693. package/vendor/types/@types/d3-scale/package.json +53 -0
  694. package/vendor/types/@types/d3-scale-chromatic/LICENSE +21 -0
  695. package/vendor/types/@types/d3-scale-chromatic/index.d.ts +520 -0
  696. package/vendor/types/@types/d3-scale-chromatic/package.json +46 -0
  697. package/vendor/types/@types/d3-selection/LICENSE +21 -0
  698. package/vendor/types/@types/d3-selection/index.d.ts +1210 -0
  699. package/vendor/types/@types/d3-selection/package.json +56 -0
  700. package/vendor/types/@types/d3-shape/LICENSE +21 -0
  701. package/vendor/types/@types/d3-shape/index.d.ts +2792 -0
  702. package/vendor/types/@types/d3-shape/package.json +53 -0
  703. package/vendor/types/@types/d3-time/LICENSE +21 -0
  704. package/vendor/types/@types/d3-time/index.d.ts +697 -0
  705. package/vendor/types/@types/d3-time/package.json +46 -0
  706. package/vendor/types/@types/d3-time-format/LICENSE +21 -0
  707. package/vendor/types/@types/d3-time-format/index.d.ts +202 -0
  708. package/vendor/types/@types/d3-time-format/package.json +40 -0
  709. package/vendor/types/@types/d3-timer/LICENSE +21 -0
  710. package/vendor/types/@types/d3-timer/index.d.ts +68 -0
  711. package/vendor/types/@types/d3-timer/package.json +45 -0
  712. package/vendor/types/@types/d3-transition/LICENSE +21 -0
  713. package/vendor/types/@types/d3-transition/index.d.ts +664 -0
  714. package/vendor/types/@types/d3-transition/package.json +47 -0
  715. package/vendor/types/@types/d3-zoom/LICENSE +21 -0
  716. package/vendor/types/@types/d3-zoom/index.d.ts +611 -0
  717. package/vendor/types/@types/d3-zoom/package.json +48 -0
  718. package/vendor/types/@types/geojson/LICENSE +21 -0
  719. package/vendor/types/@types/geojson/index.d.ts +202 -0
  720. package/vendor/types/@types/geojson/package.json +46 -0
  721. package/vendor/typescript/LICENSE.txt +55 -0
  722. package/vendor/typescript/lib.decorators.d.ts +384 -0
  723. package/vendor/typescript/lib.decorators.legacy.d.ts +22 -0
  724. package/vendor/typescript/lib.dom.d.ts +39429 -0
  725. package/vendor/typescript/lib.dom.iterable.d.ts +571 -0
  726. package/vendor/typescript/lib.es2015.collection.d.ts +147 -0
  727. package/vendor/typescript/lib.es2015.core.d.ts +597 -0
  728. package/vendor/typescript/lib.es2015.d.ts +28 -0
  729. package/vendor/typescript/lib.es2015.generator.d.ts +77 -0
  730. package/vendor/typescript/lib.es2015.iterable.d.ts +605 -0
  731. package/vendor/typescript/lib.es2015.promise.d.ts +81 -0
  732. package/vendor/typescript/lib.es2015.proxy.d.ts +128 -0
  733. package/vendor/typescript/lib.es2015.reflect.d.ts +144 -0
  734. package/vendor/typescript/lib.es2015.symbol.d.ts +46 -0
  735. package/vendor/typescript/lib.es2015.symbol.wellknown.d.ts +326 -0
  736. package/vendor/typescript/lib.es2016.array.include.d.ts +116 -0
  737. package/vendor/typescript/lib.es2016.d.ts +21 -0
  738. package/vendor/typescript/lib.es2016.intl.d.ts +31 -0
  739. package/vendor/typescript/lib.es2017.arraybuffer.d.ts +21 -0
  740. package/vendor/typescript/lib.es2017.d.ts +26 -0
  741. package/vendor/typescript/lib.es2017.date.d.ts +31 -0
  742. package/vendor/typescript/lib.es2017.intl.d.ts +44 -0
  743. package/vendor/typescript/lib.es2017.object.d.ts +49 -0
  744. package/vendor/typescript/lib.es2017.sharedmemory.d.ts +135 -0
  745. package/vendor/typescript/lib.es2017.string.d.ts +45 -0
  746. package/vendor/typescript/lib.es2017.typedarrays.d.ts +53 -0
  747. package/vendor/typescript/lib.es2018.asyncgenerator.d.ts +77 -0
  748. package/vendor/typescript/lib.es2018.asynciterable.d.ts +53 -0
  749. package/vendor/typescript/lib.es2018.d.ts +24 -0
  750. package/vendor/typescript/lib.es2018.intl.d.ts +83 -0
  751. package/vendor/typescript/lib.es2018.promise.d.ts +30 -0
  752. package/vendor/typescript/lib.es2018.regexp.d.ts +37 -0
  753. package/vendor/typescript/lib.es2019.array.d.ts +79 -0
  754. package/vendor/typescript/lib.es2019.d.ts +24 -0
  755. package/vendor/typescript/lib.es2019.intl.d.ts +23 -0
  756. package/vendor/typescript/lib.es2019.object.d.ts +33 -0
  757. package/vendor/typescript/lib.es2019.string.d.ts +37 -0
  758. package/vendor/typescript/lib.es2019.symbol.d.ts +24 -0
  759. package/vendor/typescript/lib.es2020.bigint.d.ts +765 -0
  760. package/vendor/typescript/lib.es2020.d.ts +27 -0
  761. package/vendor/typescript/lib.es2020.date.d.ts +42 -0
  762. package/vendor/typescript/lib.es2020.intl.d.ts +474 -0
  763. package/vendor/typescript/lib.es2020.number.d.ts +28 -0
  764. package/vendor/typescript/lib.es2020.promise.d.ts +47 -0
  765. package/vendor/typescript/lib.es2020.sharedmemory.d.ts +99 -0
  766. package/vendor/typescript/lib.es2020.string.d.ts +44 -0
  767. package/vendor/typescript/lib.es2020.symbol.wellknown.d.ts +41 -0
  768. package/vendor/typescript/lib.es2021.d.ts +23 -0
  769. package/vendor/typescript/lib.es2021.intl.d.ts +166 -0
  770. package/vendor/typescript/lib.es2021.promise.d.ts +48 -0
  771. package/vendor/typescript/lib.es2021.string.d.ts +33 -0
  772. package/vendor/typescript/lib.es2021.weakref.d.ts +78 -0
  773. package/vendor/typescript/lib.es2022.array.d.ts +121 -0
  774. package/vendor/typescript/lib.es2022.d.ts +25 -0
  775. package/vendor/typescript/lib.es2022.error.d.ts +75 -0
  776. package/vendor/typescript/lib.es2022.intl.d.ts +145 -0
  777. package/vendor/typescript/lib.es2022.object.d.ts +26 -0
  778. package/vendor/typescript/lib.es2022.regexp.d.ts +39 -0
  779. package/vendor/typescript/lib.es2022.string.d.ts +25 -0
  780. package/vendor/typescript/lib.es5.d.ts +4601 -0
  781. package/vendor/typescript/package.json +4 -0
  782. package/vendor/typescript/typescript.js +446 -0
  783. package/web/assets/index-B6Ai3wsa.js +13 -0
  784. package/web/assets/index-SYPC3EZy.css +1 -0
  785. package/web/index.html +14 -0
@@ -0,0 +1,833 @@
1
+ import bookmark from "./bookmark/index.mjs";
2
+ import callout from "./callout/index.mjs";
3
+ import code from "./code/index.mjs";
4
+ import columns from "./columns/index.mjs";
5
+ import details from "./details/index.mjs";
6
+ import dialog from "./dialog/index.mjs";
7
+ import divider from "./divider/index.mjs";
8
+ import embed from "./embed/index.mjs";
9
+ import figure from "./figure/index.mjs";
10
+ import file from "./file/index.mjs";
11
+ import flowchart from "./flowchart/index.mjs";
12
+ import heading from "./heading/index.mjs";
13
+ import highlight from "./highlight/index.mjs";
14
+ import icon from "./icon/index.mjs";
15
+ import image from "./image/index.mjs";
16
+ import installed from "./installed/index.mjs";
17
+ import list from "./list/index.mjs";
18
+ import math from "./math/index.mjs";
19
+ import paragraph from "./paragraph/index.mjs";
20
+ import quote from "./quote/index.mjs";
21
+ import section from "./section/index.mjs";
22
+ import sheets from "./sheets/index.mjs";
23
+ import table from "./table/index.mjs";
24
+ import widget from "./widget/index.mjs";
25
+ import { CATEGORIES, componentOf } from "../../shared/components/index.mjs";
26
+ import { COLOR_CLASSES } from "./colors.mjs";
27
+ import { MEDIA_HOSTS } from "./media/parts.mjs";
28
+ import { t } from "../../shared/i18n/index.mjs";
29
+
30
+ // The kit's components as the editor sees them, gathered from their folders (src/editor/components/
31
+ // <name>/index.mjs), shared by the page and the server (src/editor/source/). Each is the editor's
32
+ // side of the kit's component of the same name (src/shared/components/), or of the one it names
33
+ // (`description`: the flowchart's is the list's, ol.doc-flow being a kind of list for the kit),
34
+ // whose category it takes: a basic block, a container, a card or a whole block (CATEGORIES there).
35
+ // Each describes itself:
36
+ //
37
+ // listed what 设置 › 组件 calls it (a function, as the server says it in both languages), for a
38
+ // component the reader meets in the "/" menu or as a block of its own; every component
39
+ // with a type in that menu says it. hideable: false, it stays offered whatever gallery.json
40
+ // says, its switch there off and locked (文本, 标题, 列表, 分区): what a page cannot do
41
+ // without. What is hidden goes from "/", 在下方新建 and the handle's grid and nothing else
42
+ // (page/offered.mjs); its blocks, its Markdown shortcut and "Blocks at a glance" stay.
43
+ // units the unit kinds it defines (blocks the reader selects, moves and deletes):
44
+ // { [kind]: { name, icon?, match, chapter?, fixed?, block?, handle?, below?, boxed?, beside?, inRow?, sharesHeight?, entersAfter?, resizable?, copy?, clipboard?, sizes?, toggles?, colors?, colorDefaults?, removedEmpty?, turnsEmpty?, canHaveChildren?, emptyIsNothing?, fromWords?, attributes? } }
45
+ // match: rules an element matches by its tag (one of `tag`), its class and its
46
+ // attribute, and by the element it stands in (`parent`: { tag?, class? }, a flowchart's
47
+ // step being an li whose parent is an ol.doc-flow), whichever are given; every
48
+ // component's rules are tried in `rank` order and the first match wins (anything left is
49
+ // "block", a report's own widget).
50
+ // chapter: stands in the page or a Sheet panel besides body text; fixed: never
51
+ // inside a flow; block: false, no block of its own for the reader (a column: a box
52
+ // selection and 选中外层 pass over it to the blocks in it, or the row); handle: where its
53
+ // handle stands, "line" (the default: at its first line), "bar" (a bar along its right
54
+ // side: a section), "none" (none of its own: the blocks it holds have theirs) or "outer"
55
+ // (its container's: a tab's, the Sheet area's, on the tab row); below: false, its menu
56
+ // offers no new block below it (a tab, a Sheet area); boxed: a block with a frame of its
57
+ // own, no text flowing beside it: a double click between two of them makes a paragraph,
58
+ // a click to its right selects it, Enter on it selected puts a paragraph after it unless
59
+ // it is a text block (beside.mjs), and it is a block of its own to Ctrl+A; beside: the
60
+ // same click and Enter without being boxed (a row of columns); inRow(element): whether
61
+ // this one stands beside another now, as a row of columns always does and a flowchart's
62
+ // node when a node shares its line (standsBeside: what stands so keeps the handle across
63
+ // its width, with no 批注 button, its right half being no margin); sharesHeight: its height
64
+ // the tallest's beside it (a column, a flowchart's step), so that a block growing in it may
65
+ // change no height outside it, and what stands beside the page follows such a block's size
66
+ // (annotate/); entersAfter: that Enter alone (a Sheet area); resizable: the elements of
67
+ // it whose edges resize (a selector: resize/ knows how each is dragged, and takes one of
68
+ // this kind that matches); copy:
69
+ // "itself", copied as itself (as a card is) although no card; clipboard: how an element of
70
+ // this kind is written out, where the first type of the kind does not say it (below).
71
+ // sizes: custom properties in its style attribute ("Sizes" in
72
+ // src/render/kit/styles/sizes.css) and the values each takes (a share, a length in px, none),
73
+ // the one that says `height` being what its bottom edge sets (resize/);
74
+ // toggles: classes it may switch on the page, besides its colors (`colors`: the families of
75
+ // colors it takes, components/colors.mjs: ["text", "background"] for a text block (body text,
76
+ // headings, list items), ["background"] for a block of other blocks or of code (a highlight
77
+ // block, a disclosure, a code block); none without; `colorDefaults`: the color of a family it
78
+ // shows with none of it, when that is one of the nine (a callout's background: blue), which
79
+ // 颜色 › marks for it in place of 默认, a pick of it taking the class away); attributes: attributes it may set on
80
+ // the page, each with the test of its values. icon: what its handle shows, for a
81
+ // kind no block type stands for (a type's own icon is its `types` entry's). removedEmpty:
82
+ // Backspace on the one empty block in it deletes it whole (a code block, a highlight block,
83
+ // a quote, a disclosure: typing/). turnsEmpty: it holds nothing to carry, so what it is
84
+ // turned into is an empty block of the type, in its place (a divider line: convert.mjs).
85
+ // canHaveChildren: notion-lite's, a block right after it goes under it by Tab, so the
86
+ // keys of a block stand after it as they stand in what it is in (a list: under its last item).
87
+ // emptyIsNothing: a block of it left empty counts as nothing written, in a container
88
+ // that says `removedEmpty`. fromWords: a block of it can be made again from its words alone.
89
+ // boxes the box kinds it defines (containers whose children are units): { [kind]: { role,
90
+ // name?, classes?, find?, owner?, takenBy?, also?, leaveByEnter?, lead?, firstLineActs?, firstBlock?, groups?, holdsOne?, emptyIsNothing?, outer?, selectAll? } }, classes being the kit's classes that make an element one
91
+ // (rank order, as above); the others the server knows by their tag (findUnits). find: where
92
+ // a unit's box of this kind is (a list item's lists, a disclosure's content, a Sheet area's
93
+ // panels); owner: the element of its unit that takes the box along (a Sheet panel's tab:
94
+ // boxOwner); takenBy: whether a unit's element is that one, for a box of this key, told from
95
+ // the element alone, which may be off the page with the box (takesBox);
96
+ // also: the unit kinds it takes besides what its role takes (a highlight block's icon);
97
+ // leaveByEnter: Enter on its empty last block moves that block out after it (typing/leave.mjs);
98
+ // lead: the kind of unit it opens with as its fixed head, which is no block to fall
99
+ // between (a highlight block's icon: a box selection passes over it, a place before it is
100
+ // the place after it); firstLineActs: its first block shows the container's handle, not a
101
+ // handle of its own (Notion's disableFirstItemHoverMenu: a highlight block's, a quote's);
102
+ // firstBlock: the type its first block (after its lead) always is, its first line (a
103
+ // flowchart's node: "paragraph", its title), which is turned into no other type (no
104
+ // 转换为, no Markdown shortcut there) and has nothing made, dropped or pasted before it;
105
+ // Enter splits it, what follows the caret a plain paragraph below it (core.mjs firstLineOf);
106
+ // firstSays: what that first line says empty, under the caret;
107
+ // groups: a plain <div> with no class in it is a group of blocks, not a block of its own (the
108
+ // same boxes as the shared descriptions' GROUPING_FLOWS: tests/unit/components.mjs);
109
+ // holdsOne: a change that leaves it empty puts an empty paragraph in it, so there is always a
110
+ // block to write in (a disclosure's content, a highlight block: core.mjs tidyEmptied);
111
+ // emptyIsNothing: as on a unit, of a box that is an element of its own, by its `classes`;
112
+ // outer: false, a block straight in it has no block around it for the reader, whatever
113
+ // stands around its element: no 选中外层 (a detail card's content: block-info.mjs outerOf);
114
+ // selectAll: the steps of Ctrl+A it is (select-all/): { content?, whole?, top? }, content:
115
+ // its blocks are a step, called what the text says (true: "{its name}里的全部内容");
116
+ // whole: the block it belongs to is a step, whole (a row of columns, a Sheet area); top:
117
+ // no step above it, what is behind it not being its own (a detail card's content)
118
+ // components classes of elements that are one block: nothing goes in or out, their text is the
119
+ // kit's UI or a field of theirs, and all that stands in one is its component's, whatever
120
+ // its tag (ownerOf); attributes, the same by attribute
121
+ // sealed a selector: what stands in such an element is no text of a text block around it, as
122
+ // a list item holding it (caret.mjs editable): its own text blocks are the only hosts in it
123
+ // readOnly why an element of it stays read-only, on hover and on a click (hints/): rules
124
+ // { rank, at, says }, at a selector found from the element (closest), says the reason
125
+ // in the reader's words, or null for an element that needs none, having a tool of its
126
+ // own. Every component's rules are tried in `rank` order, with the page's (PAGE below),
127
+ // and the first match wins: a rule ranked below the page's 80 goes before any control's,
128
+ // and is the one that can claim a button as its own.
129
+ // hosts the kinds of text block it defines (data-ge-kind): { [kind]: { name, caps, tex?, wrapped?, parts?, whole?, takes?, opensBefore?, opensAfter?, textFilters?, formula?, closed?, inner?, blankSays?, placeholder? } }, caps
130
+ // ({ bound, blockLevel }) giving what such a text block can do (source/); opensBefore:
131
+ // Enter at its very start, with words in it, puts an empty paragraph before its block
132
+ // where it does not split, as one that splits does (typing/); opensAfter: Enter at its
133
+ // very end, a paragraph after its block, where it does not split; textFilters: false, what
134
+ // is typed in it is taken as it is, no inline code, no space set by itself (notion-lite's);
135
+ // formula: false, no inline formula is offered in it or pasted as one, the kit drawing
136
+ // none there (takesFormula);
137
+ // closed: the page holds no text block for it until the reader opens it (a code block);
138
+ // inner(element): the text a save takes of one, as markup, where that is not what its
139
+ // nodes say (a code block's code);
140
+ // parts: the parts of components ([component id, part name]: a part of its shared
141
+ // description edited as text, src/shared/components/) whose elements are text blocks
142
+ // of this kind, found so by the server's scan; whole: the element (a selector) that is one
143
+ // text block of this kind, by the scan too, while it holds inline text alone (a callout); takes: the tag of a
144
+ // block that, standing alone in `whole` with nothing of its own, natural HTML makes its words; tex: its text is a formula's TeX alone; wrapped: the page makes the text block a
145
+ // span inside the element, which keeps its own behaviour (a Sheet tab's button);
146
+ // blankSays: what the status line says of one left blank that must hold words, as a
147
+ // type's says of a block of it (blankSaysOf); placeholder: what one says while it
148
+ // is empty under the caret, whatever part it is (placeholderOf)
149
+ // placeholders what an empty text block says while the caret is in it: { [part]: text }, part
150
+ // being a part of its shared description (src/shared/components/) whose element it is
151
+ // (placeholderOf); a heading's own is its type's `placeholder`, and a type's `placeholder:
152
+ // false` says nothing where a block of it would (a list item)
153
+ // types the blocks the reader can make on the page or turn a block into (the "/" menu,
154
+ // Markdown shortcuts, the block menu), written by the server in the kit's plain markup:
155
+ // { [type]: { tag, className?, kind, host?, box?, leaf?, wraps?, container?, part?, text?, inside?, tex?,
156
+ // empty?, resettable?, bare?, placeholder?, bar?, label?, icon?, hint?, markdown?, words?, turn?, menu?, fresh?,
157
+ // corner?, preload?, onSplit?, create?, takesAsIs?, holder?, nests?, joins?, leadIcon?, fromSelection?, clipboard?, glance? } } and, for the blocks the page
158
+ // and the server write apart from text, title?, content?, keyed?, written?,
159
+ // extras?, textHost?, blanks?, blankSays? (what each says is at its component). Leaves hold
160
+ // inline text; containers (`box`: the kind of box they are) hold blocks; bare: a block that
161
+ // holds no text of its own (a divider, a media block); bar: the gray bar a media block left empty shows (a function
162
+ // giving its markup, its words in the language t() says them in: components/placeholder.mjs
163
+ // mediaBar); resettable: an empty block of the type
164
+ // turns into body text on Enter, and the first of its container on Backspace at its start (a
165
+ // quote's paragraph, a list item: notion-lite's `resettable`, typing/leave.mjs). leaf: the text block a block turned
166
+ // into the type becomes; wraps: such a text block sits in a container of the type, found
167
+ // by `container` (a selector); text: a plain text leaf; empty: a leaf written with no
168
+ // text too (a paragraph, a heading, a list item, a code block, a callout: an empty
169
+ // one stays, as Notion's; the page's core.mjs and the server's source/checks.mjs read
170
+ // this and nothing else); inside: the element its text is written in, as plain text
171
+ // (a code block's code element); tex: its text is a formula's TeX alone (a display
172
+ // formula; a host's `tex` says the same of a text block); label, icon,
173
+ // hint (its Markdown) and words (search words): its menu row; markdown: what typed at
174
+ // a block's start turns it into a type, [{ match, type?, props?, alone? }] (notion-lite's
175
+ // `markdown`): match, a RegExp the whole text before the caret must be; type: the type
176
+ // it makes, the one it stands on without; props(match): what the shortcut sets on
177
+ // the block it makes, which its page object's `setProps` does, or null for not this
178
+ // time; alone: no text may stand after it, the block holding nothing else;
179
+ // rules are tried in the order of the definitions, a type a block cannot become passed
180
+ // over (page/markdown/rules.mjs); turn: its place among
181
+ // the types a text block is turned into; fresh: its place among the types made as an
182
+ // empty block that stands for an empty one; menu: [group, place], its place in the "/"
183
+ // menu (group "basic" or "advanced"), which the block menu's 在下方新建 shows too; host: the
184
+ // kind of text block a new one is (`hosts`; "flow" without: core.mjs newHost); corner: the
185
+ // type in whose cell of a type grid it sits, as a gray corner, when the grid has both
186
+ // (type-grid.mjs); preload: true, it needs something on the page as soon as a type grid
187
+ // offers it, and before a block with text is turned into it, which its page object's
188
+ // `preload` brings; onSplit(whole, tail): what the part split off a container of the type
189
+ // keeps of the whole (core.mjs newTail); create(what): how a type that is no text block is
190
+ // made (convert.mjs convertBlock), here when it is DOM alone, as `create` of the page
191
+ // object otherwise. Unlike notion-lite's `create`, which gives the data of a new block,
192
+ // this one makes the node and places it, there being no model to place it from, and it
193
+ // also runs when a block with text is turned into the type. `what` is { type, doc, text,
194
+ // put, stand, paragraph }: the type, the document, the text of the block it stands for,
195
+ // put(node) putting a node at that block's place, stand(node) making a node stand for
196
+ // that block (the save turns the unit it was into this), and paragraph() a new empty
197
+ // paragraph. It returns the node the caret or the choice goes to (null: none); a type
198
+ // without is a text block, made by convert.mjs standIn.
199
+ // takesAsIs: a block turned into it goes into it as it is, each keeping its type (a
200
+ // highlight block, a disclosure); holder: its place among the containers that turn into
201
+ // one another, what they hold carried along; nests: false, none inside another of its
202
+ // kind; joins: false, a block turned into it never joins the one beside it; leadIcon: the
203
+ // icon a new one opens with; fromSelection: { label, icon }, its row of the format bar's
204
+ // 更多, which makes a block of it from the selected text (its page object's `fromSelection`).
205
+ // entry a chip in the text that opens something of it (a link to a detail card): { at, removed },
206
+ // at a selector, removed what the page says when Backspace or Delete beside it took it
207
+ // away whole (typing/code-edges.mjs), edged as inline code is
208
+ // clipboard how a block is copied and written out, on a type (for its description) and, where a unit
209
+ // kind needs its own, on a unit (for an element of it, over what the first type of the kind
210
+ // says): { kind?, level?, html?, of?, read?, apart?, headed?, claims?, describe?, data?, keeps?,
211
+ // piece?, across?, endsIn?, lead?, run?, pastedIn?, check?, holds?, build?, text?, grid?, blocks? }
212
+ // (docs/editor.md, "Copying blocks").
213
+ // kind: how it is written out, in notion-lite's meaning: the writer of that name in
214
+ // page/clipboard/own/writers.mjs, which the copy and the page export both use; one that
215
+ // says none is a paragraph. level: a heading's. html: the writer of its text/html when that
216
+ // is not its kind's (notion-lite's clipboard.html). of(element): the clipboard of this very
217
+ // element, on a unit whose elements are not all written alike. read(element, how): what
218
+ // the page export's writer needs of an element, whose markup it does not know; `how` is
219
+ // the writer's own. apart: on a unit that is no block of the page's flow (a detail
220
+ // card), the selector of its elements, which a page export writes after that flow, in
221
+ // file order, and which show what they hold only when opened (APART, writtenApart);
222
+ // reached(element): on such a unit, whether anything on the page leads to the element,
223
+ // which the page export leaves out when nothing does.
224
+ // headed: an entry of a list that holds blocks, its first text block its line (a
225
+ // flowchart's node).
226
+ // The hooks after these are there because Gallery has no block model: notion-lite copies
227
+ // a block's record as it is, here a block is an element, so what is carried for one and
228
+ // how it is made again are its component's to say. An element goes by the unit it is, and
229
+ // a hook that says undefined leaves it to the kind its tag gives it, then to the types
230
+ // whose mark it carries (askClipboard), an element having another component's class or
231
+ // attribute besides its own; an hr is a divider whatever its class. claims: that mark, a
232
+ // selector (a highlight block's class).
233
+ // describe(node, what): the clipboard's JSON for an element, undefined when the element
234
+ // is not its own, null when it is and cannot be copied; a text block, a list and a quote
235
+ // need none. data(node, what): what a copy carries to be made anew where its unit
236
+ // is not (COPIED_AS_ITSELF below), `what` being { serializeInner, copyOf, clipboardOf, page };
237
+ // keeps: the editor's marks a pasted copy keeps;
238
+ // unsaid: what in the markup of a copy is none of its words, a selector (UNSAID below).
239
+ // piece(host, html, what): a text block selected in part. across(unit, what): what a
240
+ // selection across blocks takes of a block it goes through, undefined when the block is
241
+ // not its own; endsIn(unit, what): the same of a block it ends in (clipboard/own/
242
+ // selection.mjs). lead: it opens the blocks it stands with and is no block of their text
243
+ // (an icon). run: the type a run of them copied on their own makes (rules.mjs groupItems).
244
+ // pastedIn: a box that takes it from the clipboard though accepts() does not.
245
+ // check(block, what): whether the clipboard's JSON, which is not trusted, is such a block; a
246
+ // type that is no `text` type and has no hook is never pasted. holds(block): the
247
+ // blocks it holds where those are no `blocks`. build(what): the block made again, `what`
248
+ // being { doc, block, host(type?), box(type?), inline(html), inner(blocks), one(block),
249
+ // colored(element), pending(figure, src) }; a text type needs none, and a container
250
+ // with no hook is filled with its blocks. Where it needs the page's modules it
251
+ // is the `build` of its page.mjs, listed in builders.mjs: it runs with no editor too
252
+ // (the transfer worker, the unit tests), so it is on no page object.
253
+ // text(block, lines): its lines of text for a place that cannot split (clipboard/own/
254
+ // blocks.mjs joinedHtml). grid(data, columns, cell): a table's rows as a Markdown table's.
255
+ // blocks(unit, how): what a `flatten` writes when that is not the units it holds.
256
+ // glance its part of a row of "Blocks at a glance" (references/writing-html.md, whose table
257
+ // src/cli/glance-table.mjs writes from these), on a type, and on a component (one or a list)
258
+ // for what no type stands for; the colors, no component's, are the page's (PAGE below):
259
+ // { row, name, write, after?, before?, rule }. A type that says none has no row.
260
+ // row: its place among the rows; the parts of one place are one row, in the order
261
+ // of the definitions, a type's before its component's own. name: the block as the
262
+ // user calls it, on a type its menu row's `label` as the source writes it, for these are
263
+ // words for an Agent in whatever language the UI speaks: tests/unit/skill-docs.mjs holds
264
+ // the two together. write: what an Agent writes; after: what the file holds after an
265
+ // export, where that differs; before: what stands between its `write` and the one
266
+ // before it in the row, where that is no comma; rule: the section of that file that
267
+ // holds its rule.
268
+ //
269
+ // A component's behaviour on the page is its page.mjs, how the server writes it its file.mjs. Of
270
+ // the fields an engine reads, those that need the page are on the page object: create (above);
271
+ // preload(type), what a type that says `preload` needs brought, a promise while it comes and null
272
+ // once it is there; redraw(units), the blocks of a group turned while that was coming drawn again;
273
+ // menuVariants(), other entries of its type in the menus (notion-lite's, on the page object where
274
+ // they come from what the page holds: an instance's, one for each package), each { label, icon, words,
275
+ // preview?, create(what) } by its name, its key in a menu "type:name" (page-objects.mjs menuEntry);
276
+ // onCreated(block, type), what follows a new block of its type (by "/", Markdown, 在下方新建, or a
277
+ // block with no text turned from its menu: notion-lite's moment), true when what comes next is its
278
+ // own, so that no caret goes in it; activate(unit), what Enter on a selected block does, every page
279
+ // object being asked and each testing the element itself, true when it was its own (notion-lite's
280
+ // activate); setProps(block, props), what a Markdown shortcut's `props` set on the block it made, in
281
+ // its undo step, returning the containers that made (no model to set them on, as notion-lite's
282
+ // setField does); press(event), what a press does on what is its component's (ownerOf: the nearest
283
+ // element around it that is of a component), before anything else hears of it, true when it was its
284
+ // own; keys: the keys of a text block of the component (ownerOf), notion-lite's field, each given the
285
+ // one `ctx` (docs/editor.md, "The order of keys") and true when the key was its: enter(ctx),
286
+ // shiftEnter, commandEnter, tab(ctx, back), escape, backspace, delete; around: { [key](ctx) }, the same
287
+ // keys for a block of another component that stands in it (a node's for what it holds, Esc in an open
288
+ // card, a list's for what an item holds) or right after it (`canHaveChildren`), asked of what stands
289
+ // around the block, nearest first, after the block's own component; mergeRefused(block), what it says
290
+ // of a block of it holding blocks that Backspace could not join to the line above; menuItems(target), the rows of the block
291
+ // menu that a block of the component has (notion-lite's), by the kind of unit it is, each row as
292
+ // menu.mjs takes it; nameOf(target), what the reader calls this block where that is no kind's name (an
293
+ // instance, its package's), iconOf(target), the mark at the head of its menu;
294
+ // menu(target, { rect, reason, remove }), a menu in place of the block menu ({ items,
295
+ // label, width }, or null; reason: why the block may not go, remove(): delete it); rowBeside(target),
296
+ // a row for a block of another component, beside its color, every page object being asked and each
297
+ // testing the block itself; acceptsFile(file), whether a file pasted makes a block of it, and
298
+ // fromFiles(host, files), that block made below the block of `host` (notion-lite's, which gives the
299
+ // data of a new block; the first page object that takes a file in their order); fromLink(figure,
300
+ // url, options), a block of the component filled from an address (notion-lite's, here the figure
301
+ // is there first: one pasted with its address, `{ pasted: true }`, a bookmark in an embed's place).
302
+ // What the rest of the editor asks of a component that does something of its own where every block
303
+ // does something: click(event), as `press`; key(event), a key on what is its own, asked of the
304
+ // component of what it came down on before any text block is looked for, true when it was its own
305
+ // (a tab's F2); undoHere(node), whether Ctrl+Z with the focus on a node of it is the page's (a tab,
306
+ // where no text block hears it); field, a text field of it that is no text block of the page's
307
+ // being edited (a tab's name), before which the block tools stand back; typed(host) and afterText(host),
308
+ // what was typed in a text block of it and what a step of its text undone or redone asks of it;
309
+ // type(host, text), text put in a text block of it that takes it as it is (`textFilters`: pasted, a
310
+ // line break that came with no key); shortcut(host, data), what `data` just typed in a text block of it
311
+ // makes before any type's `markdown` is read, true when it made something (a list in a cell);
312
+ // fromSelection(), a block of its type made from the selected text; fromPage(page), one made from what
313
+ // a web page says of itself (a link turned into a bookmark); pageIcon(), the page's own icon as it
314
+ // shows, or nothing; columnOps, sectionOps, rowOps, what the block tools do with rows of columns and
315
+ // with sections, and what the gaps in a row resize, read of whichever page object says them as
316
+ // notion-lite's drag reads `columnOps`, which keeps the name in one place; modalOps, in the same way,
317
+ // what stands open over the page as a modal: open(), the ones open, the one on top last,
318
+ // listen(listener), told when that may have changed, closeTop(), the one on top closed, show(node),
319
+ // what holds `node` shown for what lands in it, returning where it is, and kept() and reopen(kept),
320
+ // for a page shown again; keepsKeys(node, event), whether what happens on a node is its own: its keys, the
321
+ // clipboard and a drag there, the editor letting go (keptByComponent, page-objects.mjs), `event` the key
322
+ // where one is asked about; dataOf(unit), what of a block its component writes, by part, as the file is to
323
+ // hold it (nothing where it writes nothing), what core.mjs dataChanges compares, dataIn(html), the same of
324
+ // the file's markup of one (a block a commit wrote whole), dataMost, what one commit carries of it in
325
+ // bytes, and definitionOf(unit), the stamp of what it was written by, which the commit carries;
326
+ // prepare(block, node), of a kind of text block that says `closed` or `tex`, as editing starts,
327
+ // returning its baseline where it has one; panel, an editor of it open over the page, which saving
328
+ // waits for and which a press elsewhere, or the page saved or left, ends (`dismiss()`), `holds(node)`
329
+ // saying what is no press elsewhere;
330
+ // nodes, the elements of it to keep in the top
331
+ // layer when a modal dialog opens; install(), called once the block tools are there; blockTools(tools),
332
+ // a part of it made with the block tools, { holds(node), hide(), nodes }; tidy(parents), what a
333
+ // structural step may leave untidy (history.mjs), each asked in turn; nestBlocks(units, delta),
334
+ // selected blocks indented or outdented; addNear(unit, before), the handle's "+" on a block of it,
335
+ // undefined to leave it to the page; openAt(pre, point), code closed opened (caret.mjs).
336
+ // A new kit component gets a folder of its own and a line below.
337
+ export const COMPONENTS = [paragraph, heading, list, flowchart, quote, callout, highlight, details, code, divider, section, sheets, table, figure, image, file, bookmark, embed, columns, math, dialog, widget, icon, installed];
338
+
339
+ /** The built-in components 设置 › 组件 lists: { id, name() (in the language t() says it in), hideable }, by the order above. */
340
+ export const LISTED_BLOCKS = COMPONENTS.filter((component) => component.listed).map(({ name, listed, hideable = true }) => ({ id: name, name: listed, hideable }));
341
+
342
+ /** The names of those the reader may hide. */
343
+ export const HIDEABLE = new Set(LISTED_BLOCKS.filter(({ hideable }) => hideable).map(({ id }) => id));
344
+
345
+ /** The built-in components `names`, gallery.json's `hidden`, hide: a package's id there says no block, and a hand's `paragraph` hides none. */
346
+ export const blocksHidden = (names) => names.filter((name) => HIDEABLE.has(name));
347
+
348
+ /** The shared description (src/shared/components/) a component edits: its own name's, or the one it names (`description`). */
349
+ export const descriptionOf = (component) => component.description ?? component.name;
350
+
351
+ // A block's identity: an opaque, meaningless id that the page's edits and merges find it by,
352
+ // wherever it moved and however it changed. Only units carry one (paragraphs, headings, list items,
353
+ // cards, tables, disclosures, sections...), never cells or inline elements.
354
+ // It binds nothing: a block with it still changes type, splits and merges like one without.
355
+ export const IDENTITY = "data-block-id";
356
+
357
+ // What is no component's: the page and its header, plain grouping divs, the text blocks every
358
+ // flow has (paragraphs, headings and list items, the report's title), and the caption of the media
359
+ // blocks, which stays with whichever of them there are.
360
+ const PAGE = {
361
+ glance: { row: 19, name: "颜色", write: "`doc-text-<color>`, `doc-highlight-<color>` on the block", rule: "Kit blocks" },
362
+ boxes: { main: { role: "root", name: t("页面") }, plain: { role: "flow", name: t("分组") }, header: { role: "lines", name: t("页眉"), also: ["icon"] } }, // the page's icon stands in the header
363
+ hosts: {
364
+ // A free text block may be left empty (Notion's): written as an empty element, one line high.
365
+ flow: { opensBefore: true, caps: ({ bound }) => bound ? ["split", "merge", "links"] : ["split", "merge", "remove", "empty", "links"] },
366
+ title: { name: t("文档主标题"), caps: () => ["plain"], blankSays: t("文档主标题还空着:写上标题后才会保存。") },
367
+ ...MEDIA_HOSTS,
368
+ },
369
+ readOnly: [
370
+ { rank: 80, at: "button, label, input, select, textarea", says: t("交互控件暂不能在页面上修改。") },
371
+ { rank: 110, at: "figure, svg, canvas", says: t("图是页面画出来的;要改它的数据或画法,请让 AI 修改。") },
372
+ ],
373
+ };
374
+
375
+ const all = (part) => Object.assign({}, ...[PAGE, ...COMPONENTS].map((component) => component[part] ?? {}));
376
+ const UNITS = all("units");
377
+ const BOXES = all("boxes");
378
+ const flagged = (flag) => new Set(Object.keys(UNITS).filter((kind) => UNITS[kind][flag]));
379
+ const byRank = (rows) => rows.sort((a, b) => a.rank - b.rank).map(({ rank, ...row }) => row);
380
+
381
+ /** Unit kinds by element, first match wins (source/ unitKind). */
382
+ export const UNIT_KINDS = byRank(Object.entries(UNITS).flatMap(([kind, unit]) => (unit.match ?? []).map((rule) => ({ ...rule, kind }))));
383
+
384
+ /** The kit's containers whose children are units, by class, and the kind of box each is (first match). */
385
+ export const BOX_CLASSES = byRank(Object.entries(BOXES).flatMap(([kind, box]) => (box.classes ?? []).map((rule) => ({ rank: rule.rank, row: [rule.class, kind] })))).map(({ row }) => row);
386
+
387
+ /** The component that defines each block type, by name: its page object in components/pages.mjs. */
388
+ export const TYPE_COMPONENT = Object.fromEntries(COMPONENTS.flatMap((component) => Object.keys(component.types ?? {}).map((type) => [type, component.name])));
389
+
390
+ /** The component that defines each kind of unit, by name. */
391
+ export const UNIT_COMPONENT = Object.fromEntries(COMPONENTS.flatMap((component) => Object.keys(component.units ?? {}).map((kind) => [kind, component.name])));
392
+
393
+ /** Elements that are one block, by class or by attribute. */
394
+ export const COMPONENT_CLASSES = COMPONENTS.flatMap((component) => component.components ?? []);
395
+ export const COMPONENT_ATTRIBUTES = COMPONENTS.flatMap((component) => component.attributes ?? []);
396
+
397
+ /** The category of each unit kind: its component's (src/shared/components/), "block", "container", "card" or "whole". */
398
+ export const UNIT_CATEGORY = Object.fromEntries(COMPONENTS.flatMap((component) => Object.keys(component.units ?? {}).map((kind) => [kind, componentOf(descriptionOf(component))?.category ?? null])));
399
+
400
+ /** The unit kinds of the basic blocks: their text blocks are their own lines, where a container's or a card's are blocks in it. */
401
+ export const BASIC_UNITS = new Set(Object.keys(UNIT_CATEGORY).filter((kind) => UNIT_CATEGORY[kind] === "block"));
402
+
403
+ /** What the reader calls each category. */
404
+ export const CATEGORY_NAMES = Object.fromEntries(Object.entries(CATEGORIES).map(([category, { name }]) => [category, name]));
405
+
406
+ /**
407
+ * The unit kinds copied as themselves (clipboard/own/, source/commit.mjs): a card, and a table or a
408
+ * row of columns (copy: "itself"), which the page can make but which keep all their own markup
409
+ * within the report.
410
+ */
411
+ export const COPIED_AS_ITSELF = new Set(Object.entries(UNITS).filter(([kind, unit]) => UNIT_CATEGORY[kind] === "card" || unit.copy === "itself").map(([kind]) => kind));
412
+
413
+ /** What the reader calls each kind of unit (block labels while dragging, the block menu). */
414
+ export const KIND_NAMES = Object.fromEntries(Object.entries(UNITS).filter(([, unit]) => unit.name).map(([kind, unit]) => [kind, unit.name]));
415
+
416
+ /** The icons of unit kinds no block type stands for (the block menu's 分区与分栏 row shows the columns'). */
417
+ export const KIND_ICONS = Object.fromEntries(Object.entries(UNITS).filter(([, unit]) => unit.icon).map(([kind, unit]) => [kind, unit.icon]));
418
+
419
+ /** What the reader calls each kind of box (the container a drop goes into). */
420
+ export const BOX_NAMES = Object.fromEntries(Object.entries(BOXES).filter(([, box]) => box.name).map(([kind, box]) => [kind, box.name]));
421
+
422
+ /** Why an element stays read-only, the first rule that finds it, in rank order: { at, says } (`readOnly`; hints/). */
423
+ export const READ_ONLY_HINTS = byRank([PAGE, ...COMPONENTS].flatMap((component) => component.readOnly ?? []));
424
+
425
+ /** The kinds of text block: what the reader calls each (refusals) and what each can do (source/). */
426
+ export const HOSTS = all("hosts");
427
+
428
+ /** What a text block left blank says: its kind's or its type's (`blankSays`), or null. */
429
+ export const blankSaysOf = (node) => HOSTS[node.getAttribute("data-ge-kind")]?.blankSays ?? BLOCK_TYPES[blockTypeOf(node)]?.blankSays ?? BLOCK_TYPES[textTypeOf(node)]?.blankSays ?? null;
430
+
431
+ /** Whether what is typed in a text block is read as text (`textFilters`: not in code, nor in a tab's name). */
432
+ export const textFilters = (host) => HOSTS[host.getAttribute("data-ge-kind")]?.textFilters !== false;
433
+
434
+ /** Whether a text block takes an inline formula (`formula`: not an instance's text part, where the kit draws none). */
435
+ export const takesFormula = (host) => HOSTS[host.getAttribute("data-ge-kind")]?.formula !== false;
436
+
437
+ /** Whether a text block's text is a formula's TeX alone (`tex`: a formula block's), which changes in the formula editor alone. */
438
+ export const texOnly = (host) => Boolean(HOSTS[host?.getAttribute("data-ge-kind")]?.tex);
439
+ export const HOST_NAMES = Object.fromEntries(Object.entries(HOSTS).filter(([, host]) => host.name).map(([kind, host]) => [kind, host.name]));
440
+
441
+ /**
442
+ * What a text block of `kind` can do, as the text of its data-ge-caps attribute: how the page makes
443
+ * one (nothing refers to it), which is what the server finds in the file for the same block unless
444
+ * that is bound (`bound`).
445
+ */
446
+ export const capsFor = (kind, { bound = false } = {}) => HOSTS[kind].caps({ bound, blockLevel: true }).join(" ");
447
+
448
+ const HINTS = COMPONENTS.flatMap((component) => Object.entries(component.placeholders ?? {})
449
+ .map(([part, text]) => ({ match: componentOf(descriptionOf(component)).match, at: componentOf(descriptionOf(component)).parts[part].at, text })));
450
+
451
+ /**
452
+ * What an empty text block says while the caret is in it, when its kind says (`placeholder` of
453
+ * `hosts`) or it is the part of a component that says (`placeholders` above), or null. Whatever the
454
+ * block's source: a part of the file says the same as one made on the page.
455
+ */
456
+ export const placeholderOf = (host) => HOSTS[host.getAttribute("data-ge-kind")]?.placeholder ?? HINTS.find(({ match, at }) => host.closest(match)?.querySelector(at) === host)?.text ?? null;
457
+
458
+ // ---------- block types ----------
459
+
460
+ /** The blocks the reader can make or turn a block into, by type (see `types` above). */
461
+ export const BLOCK_TYPES = all("types");
462
+
463
+ /** Whether a type (its entry in BLOCK_TYPES) is a container whose blocks stand straight in its element: no title, no content region of its own. */
464
+ export const holdsStraight = (spec) => Boolean(spec?.box) && !spec.content && !spec.title;
465
+
466
+ // What each type says of where it shows (`types` above): turn, its place among the types a text
467
+ // block is turned into; fresh, its place among the types made as an empty block that stands for an
468
+ // empty one (a divider, a media block, a table...); menu, [group, place] in the "/" menu. A type that
469
+ // is either must be in the menu, which the block menu's 在下方新建 shows too.
470
+ const inOrder = (rank) => {
471
+ const found = Object.entries(BLOCK_TYPES).map(([type, spec]) => [type, rank(spec)]).filter(([, place]) => place !== undefined).sort((a, b) => a[1] - b[1]);
472
+ for (let index = 1; index < found.length; index++) if (found[index][1] === found[index - 1][1]) throw new Error(`two block types share a place: ${found[index - 1][0]}, ${found[index][0]}`);
473
+ return found.map(([type]) => type);
474
+ };
475
+ for (const [type, spec] of Object.entries(BLOCK_TYPES)) {
476
+ if ((spec.turn !== undefined || spec.fresh !== undefined) && !spec.menu) throw new Error(`block type ${type} is made or turned into, so it needs a menu place`);
477
+ if (spec.menu && !LISTED_BLOCKS.some(({ id }) => id === TYPE_COMPONENT[type])) throw new Error(`block type ${type} has a menu place, so its component needs a line in the settings (listed)`);
478
+ }
479
+
480
+ /** The types a text block can be turned into, in menu order. */
481
+ export const TURN_INTO = inOrder((spec) => spec.turn);
482
+
483
+ /** The types made as an empty block standing for an empty one: no text is carried into them. */
484
+ export const FRESH = inOrder((spec) => spec.fresh);
485
+
486
+ /** The containers that turn into one another, what they hold carried along, in menu order (`holder`). */
487
+ export const HOLDERS = inOrder((spec) => spec.holder);
488
+
489
+ /** The "/" menu's groups of block types, in order: { basic, advanced } (the menu says their names). */
490
+ export const MENU_GROUPS = Object.fromEntries(["basic", "advanced"].map((group) => [group, inOrder((spec) => (spec.menu?.[0] === group ? spec.menu[1] : undefined))]));
491
+
492
+ /** The types a block is made of from selected text, each with its row of the format bar's 更多 (`fromSelection`). */
493
+ export const FROM_SELECTION = Object.entries(BLOCK_TYPES).filter(([, spec]) => spec.fromSelection).map(([type, spec]) => ({ type, ...spec.fromSelection }));
494
+
495
+ /** The Markdown shortcuts at a block's start, in the order of the definitions: each rule with its type (`markdown` above). */
496
+ export const MARKDOWN = Object.entries(BLOCK_TYPES).flatMap(([type, spec]) => (spec.markdown ?? []).map((rule) => ({ type, ...rule })));
497
+
498
+ const GLANCE_PARTS = [PAGE, ...COMPONENTS].flatMap((component) => [...Object.values(component.types ?? {}).map((spec) => spec.glance), component.glance].flat().filter(Boolean));
499
+
500
+ /** The rows of "Blocks at a glance", in their places: each the parts that say that place (`glance`). */
501
+ export const GLANCE = [...new Set(GLANCE_PARTS.map(({ row }) => row))].sort((a, b) => a - b).map((row) => GLANCE_PARTS.filter((part) => part.row === row));
502
+
503
+ /** Names, icons, Markdown shortcuts and search words of the block types, as menu rows show them. */
504
+ export const TYPE_INFO = Object.fromEntries(Object.entries(BLOCK_TYPES).filter(([, spec]) => spec.label)
505
+ .map(([type, { label, icon, hint, words }]) => [type, { label, icon, ...(hint ? { hint } : {}), words }]));
506
+
507
+ /**
508
+ * The type of block an element is, as its components describe it: its data-ge-type when it has
509
+ * one (made on the page), else the type whose tag and class it has. Null when none.
510
+ */
511
+ export function blockTypeOf(element) {
512
+ const marked = element.getAttribute?.("data-ge-type");
513
+ if (BLOCK_TYPES[marked]) return marked;
514
+ return CLASSED.find(([, spec]) => element.localName === spec.tag && element.classList.contains(spec.className))?.[0] ?? null;
515
+ }
516
+ const CLASSED = Object.entries(BLOCK_TYPES).filter(([, spec]) => spec.className);
517
+
518
+ /**
519
+ * The type of a text block's element: its own (blockTypeOf), else the plain type of its tag, which
520
+ * has no class to tell it by (a paragraph, a heading, a list item). Null when none.
521
+ */
522
+ export function textTypeOf(element) {
523
+ return blockTypeOf(element) ?? PLAIN[element.localName] ?? null;
524
+ }
525
+ const PLAIN = {};
526
+ for (const [type, spec] of Object.entries(BLOCK_TYPES)) {
527
+ if (spec.className || !["paragraph", "heading", "item"].includes(spec.kind)) continue;
528
+ if (PLAIN[spec.tag]) throw new Error(`two plain text types share <${spec.tag}>: ${PLAIN[spec.tag]}, ${type}`);
529
+ PLAIN[spec.tag] = type;
530
+ }
531
+
532
+ /** The component that defines each kind of text block, by name. */
533
+ export const HOST_COMPONENT = Object.fromEntries(COMPONENTS.flatMap((component) => Object.keys(component.hosts ?? {}).map((kind) => [kind, component.name])));
534
+
535
+ // The elements that are one block (`components`, `attributes`), with the component of each.
536
+ const ONE_BLOCK = COMPONENTS.flatMap((component) => [...(component.components ?? []).map((name) => `.${name}`), ...(component.attributes ?? []).map((name) => `[${name}]`)].map((at) => ({ at, name: component.name })));
537
+ const ONE_BLOCK_AT = ONE_BLOCK.map(({ at }) => at).join(", ");
538
+ /** What no text block around it reaches into (`sealed`), a selector, "" where no component says. */
539
+ export const SEALED = COMPONENTS.map((component) => component.sealed).filter(Boolean).join(", ");
540
+
541
+ const oneBlockOf = (element) => {
542
+ let whole = element.closest(ONE_BLOCK_AT);
543
+ for (let around = whole; around; around = around.parentElement?.closest(ONE_BLOCK_AT)) whole = around;
544
+ return whole && ONE_BLOCK.find(({ at }) => whole.matches(at)).name;
545
+ };
546
+
547
+ // The parts its description edits as text, with the component of each: a figure's title, a heading
548
+ // by its tag alone.
549
+ const TEXT_PARTS = COMPONENTS.flatMap((component) => {
550
+ const { match, parts = {} } = componentOf(descriptionOf(component)) ?? {};
551
+ return Object.values(parts).filter((part) => part.edit === "text").map(({ at }) => ({ name: component.name, match, at }));
552
+ });
553
+ const textPartOf = (element) => TEXT_PARTS.find(({ match, at }) => [...(element.closest(match)?.querySelectorAll(at) ?? [])].includes(element))?.name;
554
+
555
+ /**
556
+ * The component an element is of, by name, or null. Nothing inside an element that is one block is
557
+ * anyone else's, whatever its tag or class (a cell's list, a Sheet's tab). Else that of its kind of text
558
+ * block, where a component defines the kind (a cell, a tab's name), that of the text part of a
559
+ * component it is, that of the unit it is (a flowchart's node, though an li) and last that of its type
560
+ * (a list's item made on the page). What stands in a container is its own component's, not the
561
+ * container's, as notion-lite's ctx.def is the block the caret is in.
562
+ */
563
+ export const ownerOf = (element) => oneBlockOf(element) ?? HOST_COMPONENT[element.getAttribute("data-ge-kind")] ?? textPartOf(element) ?? UNIT_COMPONENT[element.getAttribute("data-ge-unit-kind")] ?? TYPE_COMPONENT[textTypeOf(element)] ?? null;
564
+
565
+ /** The chips in a text that open something of a component and go whole by Backspace or Delete (`entry`), with what the page says then. */
566
+ export const ENTRIES = COMPONENTS.map((component) => component.entry).filter(Boolean);
567
+
568
+ /** Whether a block right after this element goes under it by Tab (`canHaveChildren`). */
569
+ export const canHaveChildren = (element) => Boolean(UNITS[element.getAttribute("data-ge-unit-kind")]?.canHaveChildren);
570
+
571
+ /**
572
+ * The elements a new block's text blocks may be part of rather than blocks of their own (a new
573
+ * disclosure's summary, a new code block's pre), as their components declare them (`part`).
574
+ */
575
+ export const PART_SELECTOR = Object.values(BLOCK_TYPES).map((spec) => spec.part).filter(Boolean).join(", ");
576
+
577
+ /**
578
+ * The box of kind `kind` (and `key`) of a unit's element: where its component's description says
579
+ * (`find`: a list item's lists, a disclosure's content region, a Sheet area's panels), else the
580
+ * element itself when it is a box of that kind.
581
+ */
582
+ export function boxIn(unit, kind, key = null) {
583
+ const find = BOXES[kind]?.find;
584
+ if (find) return find(unit, key) ?? null;
585
+ return unit.getAttribute("data-ge-box-kind") === kind ? unit : null;
586
+ }
587
+
588
+ /**
589
+ * The element of the unit that takes the box `element` along (its component's `owner`: a Sheet
590
+ * panel's tab), or null. What changes in such a box changes that unit too: its hash covers it.
591
+ */
592
+ export const boxOwner = (element) => BOXES[element.getAttribute("data-ge-box-kind")]?.owner?.(element) ?? null;
593
+
594
+ /** Whether the unit `element` takes the box `{ kind, key }` along (its component's `takenBy`), the two on the page or not. */
595
+ export const takesBox = (element, { kind, key }) => Boolean(element && BOXES[kind]?.takenBy?.(element, key));
596
+
597
+ /** The text blocks that can be made again as new blocks, from their words alone (paragraphs, small text, headings). */
598
+ const FROM_WORDS = flagged("fromWords");
599
+ export const PLAIN_TEXT = new Set(Object.keys(BLOCK_TYPES).filter((type) => FROM_WORDS.has(BLOCK_TYPES[type].kind)));
600
+
601
+ /** Plain text leaves (paragraphs, small text, headings, callouts). */
602
+ export const TEXT_TYPES = new Set(Object.keys(BLOCK_TYPES).filter((type) => BLOCK_TYPES[type].text));
603
+
604
+ /** The heading type of each heading tag (H1 -> heading1). */
605
+ export const HEADING_TYPES = Object.fromEntries(Object.entries(BLOCK_TYPES).filter(([, spec]) => spec.kind === "heading").map(([type, spec]) => [spec.tag.toUpperCase(), type]));
606
+
607
+ // ---------- how a block is copied and written out ----------
608
+
609
+ const PARAGRAPH = { kind: "paragraph" };
610
+
611
+ /** The `clipboard` of a block type; one that says no kind is a paragraph (notion-lite's). */
612
+ export const clipboardOf = (type) => ({ ...PARAGRAPH, ...BLOCK_TYPES[type]?.clipboard });
613
+
614
+ // The type a unit kind goes by, when it says nothing itself: the first of that kind.
615
+ const TYPE_OF_KIND = {};
616
+ for (const [type, spec] of Object.entries(BLOCK_TYPES)) TYPE_OF_KIND[spec.kind] ??= type;
617
+
618
+ // The `clipboard` of an element as a unit of `kind`: what the unit says over what the first type of the
619
+ // kind does, its own where that says `of`. A kind that is none goes as a whole block, as anything no
620
+ // rule matches does.
621
+ function kindClipboard(kind, element) {
622
+ const said = UNITS[kind] ? { ...BLOCK_TYPES[TYPE_OF_KIND[kind]]?.clipboard, ...UNITS[kind].clipboard } : UNITS.block?.clipboard;
623
+ return { ...PARAGRAPH, ...said, ...said?.of?.(element) };
624
+ }
625
+
626
+ /** The `clipboard` of an element of the page, as the unit it is. */
627
+ export const unitClipboard = (element) => kindClipboard(element.getAttribute("data-ge-unit-kind"), element);
628
+
629
+ // The kind an element's tag gives it (`match` rules that name one, with what they say of its class,
630
+ // attribute and parent): a class of another component may have given it another.
631
+ const TAG_RULES = UNIT_KINDS.filter((rule) => rule.tag);
632
+ const isOf = (element, tag, name) => (!tag || [tag].flat().includes(element?.localName)) && (!name || Boolean(element?.classList.contains(name)));
633
+ export const tagKind = (element) => TAG_RULES.find(({ tag, class: name, attr, parent }) => isOf(element, tag, name) && (!attr || element.hasAttribute(attr)) && (!parent || isOf(element.parentElement, parent.tag, parent.class)))?.kind;
634
+
635
+ const CLAIMING = Object.values(BLOCK_TYPES).map((spec) => spec.clipboard).filter((clipboard) => clipboard?.claims);
636
+
637
+ /**
638
+ * What the hook `name` of the `clipboard` says of an element, which goes first of all by the unit it
639
+ * is. A hook that says undefined leaves it to the kind its tag gives it, then to the block whose mark
640
+ * it carries (`claims`): an element may have the class or the attribute of a component besides its
641
+ * own. A tag whose block holds nothing (`bare`: an hr) comes before the unit: no class makes that a
642
+ * block of another kind.
643
+ */
644
+ export function askClipboard(name, element, ...question) {
645
+ const kind = tagKind(element);
646
+ const owners = [unitClipboard(element), kindClipboard(kind, element)];
647
+ if (BLOCK_TYPES[TYPE_OF_KIND[kind]]?.bare) owners.reverse();
648
+ for (const clipboard of [...owners, ...CLAIMING.filter(({ claims }) => element.matches(claims))]) {
649
+ const answer = clipboard[name]?.(element, ...question);
650
+ if (answer !== undefined) return answer;
651
+ }
652
+ return undefined;
653
+ }
654
+
655
+ const WRITTEN_APART = Object.values(UNITS).map((unit) => unit.clipboard).filter((clipboard) => clipboard?.apart);
656
+
657
+ /** The elements that are no block of the page's flow (`apart`), as a selector. */
658
+ export const APART = WRITTEN_APART.map((clipboard) => clipboard.apart).join(", ");
659
+
660
+ /** What a page export writes after the page's flow: those elements of `document` that are reached, each with its `clipboard`. */
661
+ export const writtenApart = (document) => WRITTEN_APART.flatMap((clipboard) => [...document.querySelectorAll(clipboard.apart)].filter((element) => clipboard.reached?.(element) ?? true).map((element) => ({ element, clipboard })));
662
+
663
+ /** The `clipboard` hook `name` of each type that has it. */
664
+ export const clipboardHooks = (name) => Object.values(BLOCK_TYPES).map((spec) => spec.clipboard?.[name]).filter(Boolean);
665
+
666
+ /** The editor's marks a pasted copy keeps (`keeps`). */
667
+ export const COPY_KEEPS = new Set(Object.values(BLOCK_TYPES).flatMap((spec) => spec.clipboard?.keeps ?? []));
668
+
669
+ /** What in the markup of a block copied as itself is none of its words: what only a browser reads, and what a unit says (`unsaid`). */
670
+ export const UNSAID = ["script, style, template", ...Object.values(UNITS).flatMap((unit) => unit.clipboard?.unsaid ?? [])].join(", ");
671
+
672
+ // ---------- where blocks may go ----------
673
+ // The report is one document of chapters (sections and Sheet areas), each a flow of blocks. Every
674
+ // box (findUnits) has a role; the page and the server both check a move against it. Flows are
675
+ // the content of sections, panels, disclosures, dialogs, columns and plain grouping divs: body
676
+ // text and components read the same in all of them (see "body text in flows" in
677
+ // src/render/kit/styles/flow.css), so a block may go into any flow; a column takes any block but
678
+ // another row of columns. The report's header takes paragraphs (the lines under its title), a
679
+ // quote paragraphs, a row of columns its columns, a list its items, a tab row its own tabs. The
680
+ // opening summary is a highlight panel like any other.
681
+ const ROLES = Object.fromEntries(Object.entries(BOXES).map(([kind, box]) => [kind, box.role]));
682
+ /** What a chapter is: the page and Sheet panels hold these besides body text. */
683
+ export const CHAPTER = flagged("chapter");
684
+ const FIXED = flagged("fixed"); // never inside a flow
685
+
686
+ /** The kinds of box a plain <div> without a class is a group of blocks in (`groups`; source/units.mjs boxKind). */
687
+ export const GROUPING = new Set(Object.keys(BOXES).filter((kind) => BOXES[kind].groups));
688
+
689
+ /** The role of a box of this kind. */
690
+ export const boxRole = (kind) => ROLES[kind] ?? "flow";
691
+
692
+ /** The box kinds that always hold a block: one a change leaves empty gets an empty paragraph (`holdsOne`). */
693
+ export const HOLDS_ONE = new Set(Object.keys(BOXES).filter((kind) => BOXES[kind].holdsOne));
694
+
695
+ /** The box kinds whose empty last block Enter moves out after the box (`leaveByEnter`). */
696
+ export const LEAVES_BY_ENTER = new Set(Object.keys(BOXES).filter((kind) => BOXES[kind].leaveByEnter));
697
+
698
+ /** The unit kinds Backspace deletes whole once nothing is written in them (`removedEmpty`). */
699
+ export const REMOVED_EMPTY = Object.keys(UNITS).filter((kind) => UNITS[kind].removedEmpty);
700
+
701
+ /** Whether Backspace in any of the text blocks of a unit of this kind deletes it (`removedEmpty: "anywhere"`), not only in its first. */
702
+ export const removedFromAnywhere = (kind) => UNITS[kind]?.removedEmpty === "anywhere";
703
+
704
+ /**
705
+ * What may stand in a container Backspace deletes whole, nothing being written in it (`emptyIsNothing`:
706
+ * the tags of the text blocks and of what holds them, and the classes of a box that holds them, a
707
+ * disclosure's content): a block of any other kind is something there.
708
+ */
709
+ const NOTHING_EMPTY = flagged("emptyIsNothing");
710
+ export const TEXT_BLOCKS = [...new Set(Object.values(BLOCK_TYPES).filter((spec) => NOTHING_EMPTY.has(spec.kind)).map((spec) => spec.tag)), ...Object.values(BOXES).filter((box) => box.emptyIsNothing).flatMap((box) => box.classes.map((rule) => `.${rule.class}`))].join(", ");
711
+
712
+ /** Whether what a unit of this kind is turned into is an empty block in its place (`turnsEmpty`). */
713
+ export const turnsEmpty = (kind) => Boolean(UNITS[kind]?.turnsEmpty);
714
+
715
+ const ALSO = Object.fromEntries(Object.entries(BOXES).filter(([, box]) => box.also).map(([kind, box]) => [kind, new Set(box.also)]));
716
+
717
+ /** The kind of unit a box of this kind opens with as its fixed head (`lead`), or null. */
718
+ export const leadOf = (boxKind) => BOXES[boxKind]?.lead ?? null;
719
+ /** Whether a unit of `kind` is the lead of a box of `boxKind` (false for a box with none, whatever the kind: null is no lead). */
720
+ export const isLead = (boxKind, kind) => {
721
+ const lead = leadOf(boxKind);
722
+ return lead !== null && kind === lead;
723
+ };
724
+
725
+ /** Whether the first block of a box of this kind shows the box's handle (`firstLineActs`). */
726
+ export const firstLineActs = (boxKind) => Boolean(BOXES[boxKind]?.firstLineActs);
727
+
728
+ /** The type the first block of a box of this kind always is (`firstBlock`: a flowchart node's title, "paragraph"), or null. */
729
+ export const firstBlockOf = (boxKind) => BOXES[boxKind]?.firstBlock ?? null;
730
+
731
+ /** What that first line says empty (`firstSays`), or null. */
732
+ export const firstSaysOf = (boxKind) => BOXES[boxKind]?.firstSays ?? null;
733
+
734
+ // ---------- what the reader sees of a unit ----------
735
+
736
+ /** Whether a unit of this kind is a block of its own for the reader (`block`: no column is). */
737
+ export const isBlock = (kind) => UNITS[kind]?.block !== false;
738
+
739
+ /** Whether a block straight in a box of this kind may have a block around it (`outer`: none in a detail card's content). */
740
+ export const hasOuter = (boxKind) => BOXES[boxKind]?.outer !== false;
741
+
742
+ /** The unit kinds with a frame of their own (`boxed`): a double click between two makes a paragraph (insert/). */
743
+ export const BOXED = flagged("boxed");
744
+
745
+ /** The unit kinds a click to the right of one selects: the boxed ones and those that say `beside` (beside.mjs). */
746
+ export const BESIDE = new Set([...BOXED, ...flagged("beside")]);
747
+
748
+ /** Whether a unit of this kind stands beside another now, `element` being that unit (`beside`, `inRow`). */
749
+ export const standsBeside = (kind, element) => Boolean(UNITS[kind]?.beside || UNITS[kind]?.inRow?.(element));
750
+
751
+ /** The unit kinds whose height is the tallest's beside them (`sharesHeight`: annotate/). */
752
+ export const SHARES_HEIGHT = flagged("sharesHeight");
753
+
754
+ /** Whether `node` is a picture standing as a block, a block's first line before any words (its caption's): where the handle and a marker stand. */
755
+ export const standsAsPicture = (node) => node.matches("img") && getComputedStyle(node).display === "block";
756
+
757
+ /** The unit kinds Enter on one selected puts a paragraph after, unless it is a text block: those and the ones that say `entersAfter` (beside.mjs). */
758
+ export const ENTERS_AFTER = new Set([...BESIDE, ...flagged("entersAfter")]);
759
+
760
+ /** The unit kinds whose edges resize (`resizable`: resize/). */
761
+ export const RESIZABLE = flagged("resizable");
762
+
763
+ /** The elements those edges may belong to: their `resizable` selectors, as one. */
764
+ export const RESIZABLE_AT = Object.values(UNITS).map((unit) => unit.resizable).filter(Boolean).join(", ");
765
+
766
+ /** The steps of Ctrl+A a box of this kind is (`selectAll`), or null when it is none. */
767
+ export const selectAllOf = (boxKind) => BOXES[boxKind]?.selectAll ?? null;
768
+
769
+ /** Whether a block menu offers a new block below a unit of this kind (`below`: none for a tab or a Sheet area). */
770
+ export const takesBelow = (kind) => UNITS[kind]?.below !== false;
771
+
772
+ /** Where the handle of a unit of this kind stands: "line", "bar", "none" or "outer" (`handle`). */
773
+ export const handleOf = (kind) => UNITS[kind]?.handle ?? "line";
774
+
775
+ /** Whether a box of this kind takes a unit of this kind. */
776
+ export function accepts(boxKind, unitKind) {
777
+ if (ALSO[boxKind]?.has(unitKind)) return true; // a highlight block's icon, the page's icon in the header (it comes first: source/apply.mjs)
778
+ switch (boxRole(boxKind)) {
779
+ case "root": return CHAPTER.has(unitKind) || !FIXED.has(unitKind); // chapters, and body text as a flow takes it
780
+ case "flow": return !FIXED.has(unitKind);
781
+ case "lines": return unitKind === "paragraph"; // the header: its lines (and the page's icon: `also`)
782
+ case "quote": return unitKind === "paragraph";
783
+ case "column": return !FIXED.has(unitKind) && unitKind !== "columns"; // no row of columns in a column
784
+ case "columns": return unitKind === "column";
785
+ case "list": return unitKind === "item";
786
+ case "nest": return !FIXED.has(unitKind) && unitKind !== "columns"; // a list item holds blocks after its text (no row of columns)
787
+ case "steps": return unitKind === "step"; // a flowchart: its steps (nodes) alone
788
+ case "tabs": return unitKind === "tab";
789
+ default: return false;
790
+ }
791
+ }
792
+
793
+ // ---------- sizes, class switches and attributes ----------
794
+
795
+ /** The families of colors a unit kind takes (颜色 in the block menu), by kind: those that say `colors`. */
796
+ export const COLOR_FAMILIES = Object.fromEntries(Object.entries(UNITS).filter(([, unit]) => unit.colors?.length > 0).map(([kind, unit]) => [kind, unit.colors]));
797
+
798
+ /** The color of each family a unit kind shows with none of it, when that is one of the nine, by kind: those that say `colorDefaults` ({ background: "blue" }). */
799
+ export const COLOR_DEFAULTS = Object.fromEntries(Object.entries(UNITS).filter(([, unit]) => unit.colorDefaults).map(([kind, unit]) => [kind, unit.colorDefaults]));
800
+
801
+ /** Classes a block may switch on the page, by unit kind: its own, then its colors' (the server allows the same). */
802
+ export const TOGGLES = Object.fromEntries(Object.entries(UNITS).map(([kind, unit]) => [kind, [...(unit.toggles ?? []), ...(COLOR_FAMILIES[kind] ?? []).flatMap((family) => COLOR_CLASSES[family])]]).filter(([, names]) => names.length > 0));
803
+
804
+ /**
805
+ * Sizes a block may carry, by unit kind: custom properties in its style attribute ("Sizes" in
806
+ * src/render/kit/styles/sizes.css) and the values each takes: a share (a number), a length in px, or none.
807
+ */
808
+ export const SIZES = Object.fromEntries(Object.entries(UNITS).filter(([, unit]) => unit.sizes).map(([kind, unit]) => [kind, unit.sizes]));
809
+
810
+ // The last digit of arithmetic: a share worked out to the least or the most a size takes (1/24 less a
811
+ // rounding error) is that, not out of range.
812
+ const EDGE = 1e-9;
813
+
814
+ /** The text a size is written as (a share to three places, a length to a whole px), or null when the kind does not take it. */
815
+ export function sizeValue(kind, name, value) {
816
+ const rule = SIZES[kind]?.[name];
817
+ if (!rule || typeof value !== "string") return null;
818
+ const text = value.trim();
819
+ if (rule.none && text === "none") return text;
820
+ const match = (rule.px ? /^(\d+(?:\.\d+)?)px$/ : /^(\d*\.?\d+)$/).exec(text);
821
+ const number = match ? Number(match[1]) : NaN;
822
+ if (!(number >= rule.min - EDGE && number <= rule.max + EDGE)) return null;
823
+ return rule.px ? `${Math.round(number)}px` : String(Math.round(number * 1000) / 1000);
824
+ }
825
+
826
+ /**
827
+ * Attributes a block may set on the page, by unit kind (a code block's language): each with the
828
+ * test of the values it takes. Set or removed in its start tag, as classes are switched.
829
+ */
830
+ export const ATTRIBUTES = Object.fromEntries(Object.entries(UNITS).filter(([, unit]) => unit.attributes).map(([kind, unit]) => [kind, unit.attributes]));
831
+
832
+ /** Whether a kind takes this value of this attribute (null: the attribute removed). */
833
+ export const attributeValue = (kind, name, value) => Boolean(ATTRIBUTES[kind]?.[name]) && (value === null || (typeof value === "string" && ATTRIBUTES[kind][name](value)));