@heycys/gallery 0.1.1 → 0.2.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 (473) hide show
  1. package/THIRD-PARTY-NOTICES.md +2 -2
  2. package/browser/editor/components/align.mjs +58 -0
  3. package/browser/editor/components/code/index.mjs +1 -1
  4. package/browser/editor/components/columns/page.mjs +4 -4
  5. package/browser/editor/components/embed/index.mjs +2 -2
  6. package/browser/editor/components/embed/page.mjs +1 -1
  7. package/browser/editor/components/file/page.mjs +4 -4
  8. package/browser/editor/components/flowchart/add.mjs +7 -6
  9. package/browser/editor/components/flowchart/page.mjs +1 -1
  10. package/browser/editor/components/heading/index.mjs +7 -6
  11. package/browser/editor/components/icons.mjs +11 -0
  12. package/browser/editor/components/image/crop.mjs +6 -9
  13. package/browser/editor/components/image/index.mjs +2 -0
  14. package/browser/editor/components/image/page.mjs +172 -90
  15. package/browser/editor/components/installed/index.mjs +15 -4
  16. package/browser/editor/components/installed/page.mjs +103 -25
  17. package/browser/editor/components/installed/served.mjs +6 -5
  18. package/browser/editor/components/instances.mjs +18 -0
  19. package/browser/editor/components/list/page.mjs +3 -6
  20. package/browser/editor/components/media/icons.mjs +13 -8
  21. package/browser/editor/components/media/page.mjs +5 -3
  22. package/browser/editor/components/media/toolbar.mjs +12 -3
  23. package/browser/editor/components/paragraph/index.mjs +4 -3
  24. package/browser/editor/components/registry.mjs +30 -9
  25. package/browser/editor/components/table/index.mjs +61 -2
  26. package/browser/editor/components/table/page.mjs +1 -1
  27. package/browser/editor/page/after/index.mjs +288 -0
  28. package/browser/editor/page/align.mjs +91 -0
  29. package/browser/editor/page/annotate/card.mjs +3 -6
  30. package/browser/editor/page/autosave.mjs +310 -37
  31. package/browser/editor/page/beside.mjs +5 -6
  32. package/browser/editor/page/block-menu/index.mjs +6 -3
  33. package/browser/editor/page/blocks.mjs +3 -1
  34. package/browser/editor/page/board/client.mjs +57 -0
  35. package/browser/editor/page/board/hint.mjs +182 -0
  36. package/browser/editor/page/board/history.mjs +119 -0
  37. package/browser/editor/page/board/index.mjs +1059 -0
  38. package/browser/editor/page/board/motion.mjs +177 -0
  39. package/browser/editor/page/board/settings.mjs +210 -0
  40. package/browser/editor/page/caret.mjs +1 -1
  41. package/browser/editor/page/changes/bar.mjs +6 -14
  42. package/browser/editor/page/changes/index.mjs +2 -2
  43. package/browser/editor/page/clipboard/import/html.mjs +29 -6
  44. package/browser/editor/page/clipboard/import/inline.mjs +32 -0
  45. package/browser/editor/page/clipboard/import/markdown.mjs +58 -13
  46. package/browser/editor/page/clipboard/import/read.mjs +6 -1
  47. package/browser/editor/page/clipboard/import/to-blocks.mjs +44 -12
  48. package/browser/editor/page/clipboard/import/yuque.mjs +622 -0
  49. package/browser/editor/page/clipboard/index.mjs +133 -15
  50. package/browser/editor/page/clipboard/own/blocks.mjs +13 -14
  51. package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
  52. package/browser/editor/page/clipboard/own/describe.mjs +6 -2
  53. package/browser/editor/page/clipboard/own/selection.mjs +1 -1
  54. package/browser/editor/page/columns/index.mjs +48 -46
  55. package/browser/editor/page/commit.mjs +80 -22
  56. package/browser/editor/page/conflicts.mjs +7 -7
  57. package/browser/editor/page/core.mjs +34 -16
  58. package/browser/editor/page/custom-page.mjs +110 -0
  59. package/browser/editor/page/editor.mjs +71 -17
  60. package/browser/editor/page/emoji-picker/styles.mjs +7 -12
  61. package/browser/editor/page/emoji-picker/upload.mjs +2 -2
  62. package/browser/editor/page/handle/index.mjs +5 -8
  63. package/browser/editor/page/history.mjs +41 -6
  64. package/browser/editor/page/insert/index.mjs +20 -22
  65. package/browser/editor/page/links/index.mjs +5 -3
  66. package/browser/editor/page/links/pages.mjs +27 -9
  67. package/browser/editor/page/look.mjs +54 -3
  68. package/browser/editor/page/margin.mjs +18 -3
  69. package/browser/editor/page/media-menu/index.mjs +6 -7
  70. package/browser/editor/page/menu.mjs +33 -14
  71. package/browser/editor/page/notices.mjs +2 -2
  72. package/browser/editor/page/page-objects.mjs +9 -2
  73. package/browser/editor/page/panel.mjs +4 -9
  74. package/browser/editor/page/present-links.mjs +15 -5
  75. package/browser/editor/page/present-shell.mjs +63 -0
  76. package/browser/editor/page/resize/index.mjs +42 -29
  77. package/browser/editor/page/selection/index.mjs +10 -2
  78. package/browser/editor/page/served.mjs +14 -0
  79. package/browser/editor/page/session.mjs +48 -4
  80. package/browser/editor/page/slash-menu/index.mjs +3 -3
  81. package/browser/editor/page/table/binding.mjs +87 -0
  82. package/browser/editor/page/table/cells.mjs +102 -46
  83. package/browser/editor/page/table/index.mjs +24 -9
  84. package/browser/editor/page/table/pictures.mjs +299 -0
  85. package/browser/editor/page/table/views.mjs +103 -0
  86. package/browser/editor/page/table/widths.mjs +82 -10
  87. package/browser/editor/page/text-select/index.mjs +26 -12
  88. package/browser/editor/page/todo-writes.mjs +75 -0
  89. package/browser/editor/page/typing/index.mjs +97 -15
  90. package/browser/editor/page/typing/leave.mjs +19 -5
  91. package/browser/editor/page/ui.mjs +13 -0
  92. package/browser/shared/block-packs.mjs +419 -0
  93. package/browser/shared/board-places.mjs +224 -0
  94. package/browser/shared/card-size.mjs +59 -0
  95. package/browser/shared/colors.mjs +3 -2
  96. package/browser/shared/component-catalog.mjs +330 -46
  97. package/browser/shared/component-source.mjs +39 -0
  98. package/browser/shared/components/heading.mjs +2 -1
  99. package/browser/shared/components/index.mjs +12 -3
  100. package/browser/shared/components/installed.mjs +35 -3
  101. package/browser/shared/components/page.mjs +20 -8
  102. package/browser/shared/components/paragraph.mjs +8 -1
  103. package/browser/shared/components/state.mjs +5 -1
  104. package/browser/shared/components/table.mjs +1 -0
  105. package/browser/shared/document-look.mjs +10 -5
  106. package/browser/shared/drafts.mjs +432 -0
  107. package/browser/shared/emoji/line-icons.mjs +37 -0
  108. package/browser/shared/extension-sidebar.mjs +126 -0
  109. package/browser/shared/extensions.mjs +79 -0
  110. package/browser/shared/file-table.mjs +101 -0
  111. package/browser/shared/http.mjs +9 -0
  112. package/browser/shared/i18n/en.mjs +330 -27
  113. package/browser/shared/json-layout.mjs +47 -0
  114. package/browser/shared/net-cache.mjs +133 -0
  115. package/browser/shared/net-keys.mjs +32 -0
  116. package/browser/shared/net-policy.mjs +177 -0
  117. package/browser/shared/outline-shape.mjs +128 -0
  118. package/browser/shared/outline.mjs +359 -67
  119. package/browser/shared/pack-manifest.mjs +88 -0
  120. package/browser/shared/page-address.mjs +6 -3
  121. package/browser/shared/page-cards.mjs +308 -0
  122. package/browser/shared/page-links.mjs +69 -6
  123. package/browser/shared/pages.mjs +500 -0
  124. package/browser/shared/paths.mjs +6 -0
  125. package/browser/shared/pinyin.mjs +92 -0
  126. package/browser/shared/present-step.mjs +17 -0
  127. package/browser/shared/preview-server.mjs +3 -7
  128. package/browser/shared/session.mjs +8 -1
  129. package/browser/shared/shipped-blocks.mjs +299 -0
  130. package/browser/shared/sidebar-head.mjs +70 -0
  131. package/browser/shared/table-chart.mjs +33 -1
  132. package/browser/shared/todos.mjs +83 -0
  133. package/browser/shared/user-directory.mjs +24 -0
  134. package/browser/shared/versions.mjs +14 -0
  135. package/browser/shared/web-links.mjs +139 -0
  136. package/browser/shared/workspace-columns.mjs +120 -0
  137. package/browser/shared/workspace-name.mjs +154 -0
  138. package/browser/shared/workspace-query.mjs +125 -0
  139. package/browser/shared/workspace-registry.mjs +272 -0
  140. package/browser/shared/workspace.mjs +171 -20
  141. package/dist/chunk-2OHANJ6Q.mjs +2 -0
  142. package/dist/chunk-3MBRL2PM.mjs +16 -0
  143. package/dist/chunk-4OKWZY5E.mjs +2 -0
  144. package/dist/chunk-4OZWXZE5.mjs +5 -0
  145. package/dist/chunk-5K44HLTZ.mjs +2 -0
  146. package/dist/{chunk-5ZKJ3H4P.mjs → chunk-5XA2ZBAE.mjs} +3 -3
  147. package/dist/{chunk-4FS7Z7WR.mjs → chunk-67N2QJYT.mjs} +1 -1
  148. package/dist/chunk-6KBYRA2C.mjs +2 -0
  149. package/dist/chunk-6N3PX4XX.mjs +8 -0
  150. package/dist/{chunk-V5JTW2LH.mjs → chunk-6QBHU4DF.mjs} +1 -1
  151. package/dist/chunk-7JDX4E65.mjs +13 -0
  152. package/dist/chunk-7M2BQQGZ.mjs +2 -0
  153. package/dist/chunk-7OG26PGF.mjs +2 -0
  154. package/dist/chunk-AHN3NFKJ.mjs +3 -0
  155. package/dist/chunk-ALZ6ZENZ.mjs +3 -0
  156. package/dist/chunk-AR5D57ZD.mjs +170 -0
  157. package/dist/{chunk-W3BGBJQW.mjs → chunk-BFJGHSQN.mjs} +1 -1
  158. package/dist/{chunk-LS4F7JUM.mjs → chunk-BZ5RAF7L.mjs} +1 -1
  159. package/dist/chunk-CMA72MAG.mjs +2 -0
  160. package/dist/{chunk-LCTHTZIL.mjs → chunk-DAZL73VK.mjs} +91 -91
  161. package/dist/{chunk-Y6RLRPG3.mjs → chunk-DJISHPUL.mjs} +1 -1
  162. package/dist/chunk-DR73Y2UJ.mjs +3 -0
  163. package/dist/{chunk-FDLXYYG4.mjs → chunk-EAIFITAV.mjs} +1 -1
  164. package/dist/{chunk-TMYZB6AV.mjs → chunk-EKNHM3P4.mjs} +1 -1
  165. package/dist/chunk-EP25HDAJ.mjs +2 -0
  166. package/dist/{chunk-GB5SOYQJ.mjs → chunk-ERLAIBOA.mjs} +2 -2
  167. package/dist/chunk-EURLTOTZ.mjs +4 -0
  168. package/dist/chunk-F4ZA6JRZ.mjs +3 -0
  169. package/dist/chunk-F6HVDZR4.mjs +2 -0
  170. package/dist/chunk-FDMAXMQA.mjs +2 -0
  171. package/dist/chunk-FETSREUN.mjs +5 -0
  172. package/dist/chunk-GHOYKMQ3.mjs +4 -0
  173. package/dist/{chunk-2B5E4CDJ.mjs → chunk-GPIWQ4X4.mjs} +1 -1
  174. package/dist/chunk-HDWTZ763.mjs +12 -0
  175. package/dist/chunk-HPOI4ZX7.mjs +6 -0
  176. package/dist/{chunk-BGGDRNYQ.mjs → chunk-HXG7EOPJ.mjs} +1 -1
  177. package/dist/chunk-IA4PSIMD.mjs +2 -0
  178. package/dist/{chunk-E7LWZRXY.mjs → chunk-ITOH5EGO.mjs} +1 -1
  179. package/dist/chunk-IV64FFI4.mjs +2 -0
  180. package/dist/chunk-J43Z6LSS.mjs +2 -0
  181. package/dist/chunk-J5PUIV3Y.mjs +4 -0
  182. package/dist/chunk-JA7G53PC.mjs +2 -0
  183. package/dist/chunk-JEUK3ZO7.mjs +2 -0
  184. package/dist/chunk-JLTZF4LA.mjs +2 -0
  185. package/dist/chunk-JZT7I2OJ.mjs +2 -0
  186. package/dist/chunk-K5XATEOO.mjs +2 -0
  187. package/dist/chunk-L2SUIS5S.mjs +2 -0
  188. package/dist/chunk-L7UP52JO.mjs +2 -0
  189. package/dist/chunk-LM4XFQHZ.mjs +2 -0
  190. package/dist/chunk-MN7BZL4R.mjs +2 -0
  191. package/dist/chunk-MTYYHM2G.mjs +15 -0
  192. package/dist/chunk-MXUBKDRO.mjs +15 -0
  193. package/dist/chunk-NAMN3RAF.mjs +2 -0
  194. package/dist/{chunk-SYGN7GLU.mjs → chunk-OEXWRJME.mjs} +1 -1
  195. package/dist/chunk-OFHXGWOX.mjs +2 -0
  196. package/dist/chunk-ORID3AE7.mjs +166 -0
  197. package/dist/chunk-PAREWQGB.mjs +4 -0
  198. package/dist/chunk-PGDE24N5.mjs +2 -0
  199. package/dist/chunk-POTA2FV4.mjs +2 -0
  200. package/dist/chunk-PUOQ65NC.mjs +2 -0
  201. package/dist/chunk-Q4UEPUWF.mjs +2 -0
  202. package/dist/chunk-QE5RG76S.mjs +549 -0
  203. package/dist/chunk-R2ZDLJYT.mjs +10 -0
  204. package/dist/{chunk-7DTINW6U.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
  205. package/dist/chunk-SWUTTZCN.mjs +2 -0
  206. package/dist/chunk-TANZRINB.mjs +2 -0
  207. package/dist/chunk-TR7TWGHB.mjs +2 -0
  208. package/dist/chunk-U5XL7D6A.mjs +3 -0
  209. package/dist/{chunk-XNROSH2T.mjs → chunk-U7NZI6N4.mjs} +2 -2
  210. package/dist/chunk-UGWMMEJ5.mjs +15 -0
  211. package/dist/chunk-UJQJKNGK.mjs +2 -0
  212. package/dist/chunk-UYVCQK3H.mjs +22 -0
  213. package/dist/chunk-VFX2KNHP.mjs +4 -0
  214. package/dist/chunk-VS7JIGJW.mjs +24 -0
  215. package/dist/chunk-W7665ZEC.mjs +6 -0
  216. package/dist/chunk-WQDQWCX5.mjs +2 -0
  217. package/dist/chunk-YI43RG4P.mjs +2 -0
  218. package/dist/chunk-YLPSMDIS.mjs +5 -0
  219. package/dist/chunk-YNAWBAYN.mjs +3 -0
  220. package/dist/chunk-YROX2O22.mjs +2 -0
  221. package/dist/chunk-ZDLPUOAG.mjs +6 -0
  222. package/dist/{chunk-IVDLMMBD.mjs → chunk-ZHEHPMBK.mjs} +1 -1
  223. package/dist/chunk-ZQS6H473.mjs +16 -0
  224. package/dist/chunk-ZTHICSSF.mjs +2 -0
  225. package/dist/chunk-ZWWC4KLF.mjs +20 -0
  226. package/dist/cli.mjs +1 -1
  227. package/dist/server.mjs +1 -1
  228. package/dist/{chunk-U6KNPJPR.mjs → update-fetch.mjs} +1 -1
  229. package/dist/worker.mjs +1 -1
  230. package/kit/board.css +95 -0
  231. package/kit/board.js +250 -0
  232. package/kit/charts.js +5 -71
  233. package/kit/code.js +17 -17
  234. package/kit/report.css +335 -18
  235. package/kit/runtime.js +1638 -125
  236. package/kit/state.js +10 -1
  237. package/kit/tables.js +130 -43
  238. package/kit/ui.js +79 -35
  239. package/package.json +2 -1
  240. package/packs/gallery/card/component.json +14 -0
  241. package/packs/gallery/card/example.html +10 -0
  242. package/packs/gallery/card/preview.svg +1 -0
  243. package/packs/gallery/card/style.css +6 -0
  244. package/packs/gallery/card/template.html +6 -0
  245. package/packs/gallery/card/writing.md +14 -0
  246. package/packs/gallery/chart-card/component.json +15 -0
  247. package/packs/gallery/chart-card/example.html +14 -0
  248. package/packs/gallery/chart-card/kit.js +130 -0
  249. package/packs/gallery/chart-card/preview.svg +1 -0
  250. package/packs/gallery/chart-card/style.css +42 -0
  251. package/packs/gallery/chart-card/template.html +13 -0
  252. package/packs/gallery/chart-card/writing.md +20 -0
  253. package/packs/gallery/chart-view/component.json +20 -0
  254. package/packs/gallery/chart-view/example.html +13 -0
  255. package/packs/gallery/chart-view/kit.js +355 -0
  256. package/packs/gallery/chart-view/preview.svg +1 -0
  257. package/packs/gallery/chart-view/style.css +94 -0
  258. package/packs/gallery/chart-view/template.html +3 -0
  259. package/packs/gallery/chart-view/writing.md +22 -0
  260. package/packs/gallery/countdown/component.json +18 -0
  261. package/packs/gallery/countdown/example.html +3 -0
  262. package/packs/gallery/countdown/kit.js +216 -0
  263. package/packs/gallery/countdown/preview.svg +1 -0
  264. package/packs/gallery/countdown/style.css +118 -0
  265. package/packs/gallery/countdown/template.html +3 -0
  266. package/packs/gallery/countdown/writing.md +22 -0
  267. package/packs/gallery/habit/component.json +14 -0
  268. package/packs/gallery/habit/example.html +3 -0
  269. package/packs/gallery/habit/kit.js +334 -0
  270. package/packs/gallery/habit/preview.svg +1 -0
  271. package/packs/gallery/habit/style.css +174 -0
  272. package/packs/gallery/habit/template.html +3 -0
  273. package/packs/gallery/habit/writing.md +21 -0
  274. package/packs/gallery/heatmap/component.json +18 -0
  275. package/packs/gallery/heatmap/example.html +3 -0
  276. package/packs/gallery/heatmap/kit.js +513 -0
  277. package/packs/gallery/heatmap/preview.svg +1 -0
  278. package/packs/gallery/heatmap/style.css +189 -0
  279. package/packs/gallery/heatmap/template.html +3 -0
  280. package/packs/gallery/heatmap/writing.md +21 -0
  281. package/packs/gallery/kanban/component.json +18 -0
  282. package/packs/gallery/kanban/example.html +12 -0
  283. package/packs/gallery/kanban/kit.js +540 -0
  284. package/packs/gallery/kanban/preview.svg +1 -0
  285. package/packs/gallery/kanban/style.css +212 -0
  286. package/packs/gallery/kanban/template.html +3 -0
  287. package/packs/gallery/kanban/writing.md +20 -0
  288. package/packs/gallery/metric/component.json +22 -0
  289. package/packs/gallery/metric/example.html +15 -0
  290. package/packs/gallery/metric/kit.js +248 -0
  291. package/packs/gallery/metric/preview.svg +1 -0
  292. package/packs/gallery/metric/style.css +92 -0
  293. package/packs/gallery/metric/template.html +3 -0
  294. package/packs/gallery/metric/writing.md +23 -0
  295. package/packs/gallery/note/component.json +14 -0
  296. package/packs/gallery/note/example.html +3 -0
  297. package/packs/gallery/note/kit.js +129 -0
  298. package/packs/gallery/note/preview.svg +1 -0
  299. package/packs/gallery/note/style.css +97 -0
  300. package/packs/gallery/note/template.html +3 -0
  301. package/packs/gallery/note/writing.md +18 -0
  302. package/packs/gallery/pack.json +8 -0
  303. package/packs/gallery/recent/component.json +13 -0
  304. package/packs/gallery/recent/example.html +1 -0
  305. package/packs/gallery/recent/kit.js +293 -0
  306. package/packs/gallery/recent/preview.svg +1 -0
  307. package/packs/gallery/recent/style.css +85 -0
  308. package/packs/gallery/recent/template.html +1 -0
  309. package/packs/gallery/recent/writing.md +15 -0
  310. package/packs/gallery/static/component.json +13 -0
  311. package/packs/gallery/static/example.html +11 -0
  312. package/packs/gallery/static/preview.svg +1 -0
  313. package/packs/gallery/static/style.css +171 -0
  314. package/packs/gallery/static/template.html +1 -0
  315. package/packs/gallery/static/writing.md +18 -0
  316. package/packs/gallery/stats/component.json +13 -0
  317. package/packs/gallery/stats/example.html +1 -0
  318. package/packs/gallery/stats/kit.js +347 -0
  319. package/packs/gallery/stats/preview.svg +1 -0
  320. package/packs/gallery/stats/style.css +73 -0
  321. package/packs/gallery/stats/template.html +1 -0
  322. package/packs/gallery/stats/writing.md +11 -0
  323. package/packs/gallery/today/component.json +12 -0
  324. package/packs/gallery/today/example.html +1 -0
  325. package/packs/gallery/today/kit.js +220 -0
  326. package/packs/gallery/today/preview.svg +1 -0
  327. package/packs/gallery/today/style.css +149 -0
  328. package/packs/gallery/today/template.html +1 -0
  329. package/packs/gallery/today/writing.md +14 -0
  330. package/packs/gallery/todos/component.json +19 -0
  331. package/packs/gallery/todos/example.html +3 -0
  332. package/packs/gallery/todos/kit.js +489 -0
  333. package/packs/gallery/todos/preview.svg +1 -0
  334. package/packs/gallery/todos/style.css +214 -0
  335. package/packs/gallery/todos/template.html +3 -0
  336. package/packs/gallery/todos/writing.md +30 -0
  337. package/packs/gallery/weather/component.json +19 -0
  338. package/packs/gallery/weather/example.html +3 -0
  339. package/packs/gallery/weather/kit.js +387 -0
  340. package/packs/gallery/weather/preview.svg +1 -0
  341. package/packs/gallery/weather/style.css +140 -0
  342. package/packs/gallery/weather/template.html +3 -0
  343. package/packs/gallery/weather/writing.md +26 -0
  344. package/packs/gallery-soft/countdown/component.json +18 -0
  345. package/packs/gallery-soft/countdown/example.html +3 -0
  346. package/packs/gallery-soft/countdown/kit.js +206 -0
  347. package/packs/gallery-soft/countdown/preview.svg +1 -0
  348. package/packs/gallery-soft/countdown/style.css +211 -0
  349. package/packs/gallery-soft/countdown/template.html +3 -0
  350. package/packs/gallery-soft/countdown/writing.md +24 -0
  351. package/packs/gallery-soft/habit/component.json +14 -0
  352. package/packs/gallery-soft/habit/example.html +3 -0
  353. package/packs/gallery-soft/habit/kit.js +366 -0
  354. package/packs/gallery-soft/habit/preview.svg +1 -0
  355. package/packs/gallery-soft/habit/style.css +251 -0
  356. package/packs/gallery-soft/habit/template.html +3 -0
  357. package/packs/gallery-soft/habit/writing.md +23 -0
  358. package/packs/gallery-soft/heatmap/component.json +18 -0
  359. package/packs/gallery-soft/heatmap/example.html +3 -0
  360. package/packs/gallery-soft/heatmap/kit.js +498 -0
  361. package/packs/gallery-soft/heatmap/preview.svg +1 -0
  362. package/packs/gallery-soft/heatmap/style.css +181 -0
  363. package/packs/gallery-soft/heatmap/template.html +3 -0
  364. package/packs/gallery-soft/heatmap/writing.md +23 -0
  365. package/packs/gallery-soft/note/component.json +14 -0
  366. package/packs/gallery-soft/note/example.html +3 -0
  367. package/packs/gallery-soft/note/kit.js +162 -0
  368. package/packs/gallery-soft/note/preview.svg +1 -0
  369. package/packs/gallery-soft/note/style.css +148 -0
  370. package/packs/gallery-soft/note/template.html +3 -0
  371. package/packs/gallery-soft/note/writing.md +20 -0
  372. package/packs/gallery-soft/pack.json +8 -0
  373. package/packs/gallery-soft/recent/component.json +13 -0
  374. package/packs/gallery-soft/recent/example.html +1 -0
  375. package/packs/gallery-soft/recent/kit.js +335 -0
  376. package/packs/gallery-soft/recent/preview.svg +1 -0
  377. package/packs/gallery-soft/recent/style.css +160 -0
  378. package/packs/gallery-soft/recent/template.html +1 -0
  379. package/packs/gallery-soft/recent/writing.md +17 -0
  380. package/packs/gallery-soft/static/component.json +13 -0
  381. package/packs/gallery-soft/static/example.html +12 -0
  382. package/packs/gallery-soft/static/preview.svg +1 -0
  383. package/packs/gallery-soft/static/style.css +186 -0
  384. package/packs/gallery-soft/static/template.html +1 -0
  385. package/packs/gallery-soft/static/writing.md +20 -0
  386. package/packs/gallery-soft/stats/component.json +13 -0
  387. package/packs/gallery-soft/stats/example.html +1 -0
  388. package/packs/gallery-soft/stats/kit.js +341 -0
  389. package/packs/gallery-soft/stats/preview.svg +1 -0
  390. package/packs/gallery-soft/stats/style.css +119 -0
  391. package/packs/gallery-soft/stats/template.html +1 -0
  392. package/packs/gallery-soft/stats/writing.md +13 -0
  393. package/packs/gallery-soft/today/component.json +12 -0
  394. package/packs/gallery-soft/today/example.html +1 -0
  395. package/packs/gallery-soft/today/kit.js +222 -0
  396. package/packs/gallery-soft/today/preview.svg +1 -0
  397. package/packs/gallery-soft/today/style.css +178 -0
  398. package/packs/gallery-soft/today/template.html +1 -0
  399. package/packs/gallery-soft/today/writing.md +16 -0
  400. package/packs/gallery-soft/todos/component.json +19 -0
  401. package/packs/gallery-soft/todos/example.html +3 -0
  402. package/packs/gallery-soft/todos/kit.js +527 -0
  403. package/packs/gallery-soft/todos/preview.svg +1 -0
  404. package/packs/gallery-soft/todos/style.css +212 -0
  405. package/packs/gallery-soft/todos/template.html +3 -0
  406. package/packs/gallery-soft/todos/writing.md +32 -0
  407. package/packs/gallery-soft/weather/component.json +19 -0
  408. package/packs/gallery-soft/weather/example.html +3 -0
  409. package/packs/gallery-soft/weather/kit.js +411 -0
  410. package/packs/gallery-soft/weather/preview.svg +1 -0
  411. package/packs/gallery-soft/weather/style.css +185 -0
  412. package/packs/gallery-soft/weather/template.html +3 -0
  413. package/packs/gallery-soft/weather/writing.md +28 -0
  414. package/release.json +12 -10
  415. package/sdk/doc-kit.d.ts +396 -5
  416. package/sdk/doc-state.d.ts +2 -0
  417. package/skill/SKILL.md +56 -23
  418. package/skill/references/block-script.md +140 -0
  419. package/skill/references/building-blocks.md +257 -0
  420. package/skill/references/extensions.md +59 -0
  421. package/skill/references/pages-and-data.md +225 -0
  422. package/skill/references/writing-html.md +8 -4
  423. package/skill/sdk/doc-kit.d.ts +396 -5
  424. package/skill/sdk/doc-state.d.ts +2 -0
  425. package/web/assets/index-BM_K-Auu.css +1 -0
  426. package/web/assets/index-DRslOBiv.js +15 -0
  427. package/web/index.html +2 -2
  428. package/dist/chunk-3HIRPVLU.mjs +0 -2
  429. package/dist/chunk-5MHMDLZD.mjs +0 -4
  430. package/dist/chunk-64K7IPLO.mjs +0 -255
  431. package/dist/chunk-6QXGZM36.mjs +0 -8
  432. package/dist/chunk-6RGJOMJP.mjs +0 -16
  433. package/dist/chunk-AJ73XJF3.mjs +0 -2
  434. package/dist/chunk-AUZGSZJH.mjs +0 -13
  435. package/dist/chunk-BFE45AKL.mjs +0 -2
  436. package/dist/chunk-BXO2ZY5P.mjs +0 -2
  437. package/dist/chunk-CEH4MRCC.mjs +0 -2
  438. package/dist/chunk-CY2FNNAB.mjs +0 -16
  439. package/dist/chunk-DFUDV4LX.mjs +0 -2
  440. package/dist/chunk-DKXG4XDG.mjs +0 -2
  441. package/dist/chunk-EZQ34M3F.mjs +0 -124
  442. package/dist/chunk-EZY3WC6Z.mjs +0 -15
  443. package/dist/chunk-FUKQNOQS.mjs +0 -9
  444. package/dist/chunk-JPOSLGOC.mjs +0 -6
  445. package/dist/chunk-JVHHHGEA.mjs +0 -3
  446. package/dist/chunk-L3QKH4OK.mjs +0 -26
  447. package/dist/chunk-LAE5NQ4B.mjs +0 -2
  448. package/dist/chunk-LEF6DRCK.mjs +0 -59
  449. package/dist/chunk-NO5NJCHO.mjs +0 -2
  450. package/dist/chunk-NQPVAU63.mjs +0 -2
  451. package/dist/chunk-NSKUTQ5J.mjs +0 -5
  452. package/dist/chunk-O35FIXRB.mjs +0 -2
  453. package/dist/chunk-P2CAZPDP.mjs +0 -3
  454. package/dist/chunk-PL6GHLGD.mjs +0 -15
  455. package/dist/chunk-QJIR2BLP.mjs +0 -6
  456. package/dist/chunk-QUPLVPB2.mjs +0 -7
  457. package/dist/chunk-R7BNENLY.mjs +0 -4
  458. package/dist/chunk-S6O4UHLC.mjs +0 -2
  459. package/dist/chunk-SGJWQKEI.mjs +0 -2
  460. package/dist/chunk-TX6JH7TR.mjs +0 -2
  461. package/dist/chunk-TYK6VNAB.mjs +0 -10
  462. package/dist/chunk-UALRNVSE.mjs +0 -4
  463. package/dist/chunk-V3HXVQEM.mjs +0 -2
  464. package/dist/chunk-V5VXUJKG.mjs +0 -2
  465. package/dist/chunk-VBXMADMP.mjs +0 -2
  466. package/dist/chunk-VNV55RUA.mjs +0 -2
  467. package/dist/chunk-VPD2PS35.mjs +0 -2
  468. package/dist/chunk-W4VKN3GF.mjs +0 -7
  469. package/dist/chunk-W5BXXPDJ.mjs +0 -3
  470. package/dist/chunk-XUNHRCOG.mjs +0 -6
  471. package/skill/references/building-components.md +0 -367
  472. package/web/assets/index-Bh74DfsV.css +0 -1
  473. package/web/assets/index-UW0RyFFt.js +0 -13
@@ -0,0 +1,182 @@
1
+ import { language, t } from "../../../shared/i18n/index.mjs";
2
+ import { postAnswer } from "../post.mjs";
3
+ import { say } from "../notices.mjs";
4
+ import { addStyle, element } from "../ui.mjs";
5
+
6
+ // A custom page's first-open note (notes/plans/component-pages-plan-2026-11-07.md §5.2; docs/render.md
7
+ // "A custom page", **Notes of a page**): at the top of a page whose page.json says `hint` (the default home
8
+ // page's), while the page map says `hint` (src/server/routes.mjs: its note not yet closed in this
9
+ // workspace), a short note on its cards: how to move one (the grip at its top-right: drag it), open its
10
+ // menu (a click on the same grip: 大小, 设置, 删除), add one (添加自定义块: the first item of the ··· menu at the
11
+ // top right of the workbench's bar; a page open alone in a tab has it at the top right of its board) and
12
+ // take one out (the menu's 删除), and that a new card or a new page is the Agent's to make, with a sentence
13
+ // the reader can copy and say to one (its 复制 button). Its × closes it for good, for the workspace (POST
14
+ // /__gallery/pages/<slug>/hint: .gallery/hints.json), whichever browser shows the page next. In the
15
+ // editor's look: grays alone, a quiet fill, no colour; the kit's own light and dark through the
16
+ // editor's tokens (look.mjs).
17
+ //
18
+ // Its note of new default cards (showNews: the plan's 3.4), on a page with the default cards (its page.json's
19
+ // defaultCards) made before some of them, while the page map says `news`: which default cards it does not
20
+ // hold that came since, and that 加到这一页 puts them in the empty spots as 恢复默认卡片 in the page's menu
21
+ // does (the board's restoreDefaults: what is missing alone, the cards there untouched, one step of the
22
+ // page's undo). A page already made is never changed by itself: the reader is told once, at the top of
23
+ // the page, where the first-open note stands, and nothing moves on the board until they ask. Its × (or
24
+ // 加到这一页) says it for the workspace (POST /__gallery/pages/<slug>/hint with { cards: true }), which
25
+ // 恢复默认卡片 does too.
26
+ //
27
+ // And the middle of a blank page (showBlank: the workbench's 新建页面, which no one has written yet, while
28
+ // the page map says `blank`): that an Agent writes a custom page, any page it likes, a board of cards or
29
+ // not, with a request the reader can copy and say to one, as the first-open note's. Nothing of it is the
30
+ // file's: once an Agent writes page.html the page is shown again without it.
31
+ const STYLE = `
32
+ .ge-home-hint { box-sizing: border-box; max-width: var(--gallery-board-width, 944px); margin: 0 auto 12px; }
33
+ .ge-home-hint-box { position: relative; box-sizing: border-box; max-width: 720px; padding: 14px 44px 14px 16px; border-radius: 10px;
34
+ background: light-dark(rgb(55 53 47 / 4%), rgb(255 255 255 / 4.5%)); color: var(--ge-tx);
35
+ font: 14px/1.6 ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", Helvetica, "PingFang SC", "Microsoft YaHei", Arial, sans-serif; }
36
+ .ge-home-hint-box p { margin: 0; }
37
+ .ge-home-hint-box p + p { margin-top: 4px; }
38
+ .ge-home-hint-title { font-weight: 600; }
39
+ .ge-home-hint-box .ge-home-hint-ask { margin-top: 10px; color: var(--ge-tx2); }
40
+ .ge-home-hint-icon { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; margin: 0 2px; vertical-align: -3px; border-radius: 4px; background: var(--ge-hover); color: var(--ge-ico2); }
41
+ .ge-home-hint-icon svg { display: block; width: 10px; height: 12px; fill: currentColor; }
42
+ .ge-home-hint-say { display: flex; align-items: center; gap: 8px; margin-top: 6px; padding: 6px 6px 6px 12px; border-radius: 6px; background: var(--ge-bg); }
43
+ .ge-home-hint-say span { flex: 1; min-width: 0; color: var(--ge-tx); user-select: text; }
44
+ .ge-home-hint-copy, .ge-home-hint-close { flex: none; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; border: 0; border-radius: 6px; background: transparent; color: var(--ge-tx2); font: inherit; cursor: pointer; user-select: none; }
45
+ .ge-home-hint-copy { height: 28px; padding: 0 10px; font-size: 13px; }
46
+ .ge-home-hint-copy:hover, .ge-home-hint-close:hover { background: var(--ge-hover); color: var(--ge-tx); }
47
+ .ge-home-hint-copy:active, .ge-home-hint-close:active { background: var(--ge-press); }
48
+ .ge-home-hint-close { position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; color: var(--ge-ico3); }
49
+ .ge-home-hint-close svg { display: block; width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
50
+ .ge-home-hint-act { margin-top: 8px; }
51
+ .ge-home-hint-box .ge-home-hint-add { margin-left: -2px; background: var(--ge-btn-primary); color: var(--ge-btn-primary-text); }
52
+ .ge-home-hint-box .ge-home-hint-add:hover:not(:disabled) { background: var(--ge-btn-primary-hover); color: var(--ge-btn-primary-text); }
53
+ .ge-home-hint-box .ge-home-hint-add:disabled { opacity: .5; cursor: default; }
54
+ .ge-page-blank { box-sizing: border-box; display: flex; justify-content: center; padding: max(48px, 18vh) 16px 48px; }
55
+ .ge-page-blank .ge-home-hint-box { width: 100%; max-width: 520px; padding: 20px 20px 18px; }
56
+ .ge-page-blank .ge-home-hint-title { font-size: 16px; }
57
+ `;
58
+
59
+ const DOTS = '<svg viewBox="0 0 10 16" aria-hidden="true"><circle cx="2.5" cy="2" r="1.25"/><circle cx="7.5" cy="2" r="1.25"/><circle cx="2.5" cy="8" r="1.25"/><circle cx="7.5" cy="8" r="1.25"/><circle cx="2.5" cy="14" r="1.25"/><circle cx="7.5" cy="14" r="1.25"/></svg>';
60
+ const CLOSE = '<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M4 4l8 8M12 4l-8 8"/></svg>';
61
+
62
+ // `template` (t's words, {0}, {1}… where `nodes` go) as the nodes of a line.
63
+ function filled(template, nodes) {
64
+ return template.split(/\{(\d+)\}/).map((piece, index) => (index % 2 ? nodes[Number(piece)] ?? "" : piece)).filter((piece) => piece !== "");
65
+ }
66
+ const icon = (html) => element("span", { class: "ge-home-hint-icon", html });
67
+ // A note at the top of the home page, of the editor's UI (never the file's): `kind` its class beside ge-home-hint, `label` what it is called.
68
+ const noteOf = (kind, label, box) => element("div", { class: `ge-home-hint${kind ? ` ${kind}` : ""}`, role: "note", "aria-label": label, "data-doc-dev": "" }, box);
69
+
70
+ /**
71
+ * The note of new default cards, on the home page whose map says `news` ([{ block, name }]), at the top of
72
+ * the page, after the first-open note where that is shown; `restore`, the board's restoreDefaults. Returns
73
+ * the note, or null where none is shown.
74
+ */
75
+ export function showNews(map, { restore }) {
76
+ const main = document.querySelector("main.gallery-page");
77
+ if (!map?.news?.length || !main) return null;
78
+ addStyle(STYLE);
79
+ const named = ({ block, name }) => name?.[language === "en" ? "en" : "zh"] ?? name?.zh ?? block;
80
+ const add = element("button", { type: "button", class: "ge-home-hint-copy ge-home-hint-add", text: t("加到这一页") });
81
+ const close = element("button", { type: "button", class: "ge-home-hint-close", "aria-label": t("关闭这条说明"), title: t("关闭"), html: CLOSE });
82
+ const box = element("div", { class: "ge-home-hint-box" },
83
+ element("p", { class: "ge-home-hint-title", text: t("有了新的默认卡片") }),
84
+ element("p", { text: map.news.map(named).join(t("、")) }),
85
+ element("p", { class: "ge-home-hint-ask", text: t("点「加到这一页」放进空位,已有的卡片不动。以后也可以在这一页的菜单中点「恢复默认卡片」。") }),
86
+ element("div", { class: "ge-home-hint-act" }, add),
87
+ close);
88
+ const note = noteOf("ge-home-news", t("新的默认卡片"), box);
89
+ for (const button of [add, close]) button.addEventListener("mousedown", (event) => event.preventDefault());
90
+ const told = () => postAnswer(`/__gallery/pages/${map.slug}/hint`, map.token, { cards: true });
91
+ add.addEventListener("click", async () => {
92
+ add.disabled = true;
93
+ const answer = await restore();
94
+ if (!answer?.ok) {
95
+ add.disabled = false;
96
+ return say(t("没能把卡片放到这一页"), "error");
97
+ }
98
+ note.remove();
99
+ const added = answer.added ?? [];
100
+ say(added.length ? t("已放回默认卡片:{0}", added.map(named).join(t("、"))) : t("默认卡片都在,没有要放回的"));
101
+ });
102
+ close.addEventListener("click", async () => {
103
+ note.remove();
104
+ const answer = await told();
105
+ if (!answer?.ok) say(t("没能记下这条说明已关闭"), "error");
106
+ });
107
+ const first = main.querySelector(":scope > .ge-home-hint");
108
+ if (first) first.after(note);
109
+ else main.prepend(note);
110
+ return note;
111
+ }
112
+
113
+ /**
114
+ * The note shown, on the page whose map (`map`: slug, token) says `hint`, at the top of the page
115
+ * (`main.gallery-page`, before what the page holds). `hosted`: the page stands in a workbench, whose top
116
+ * bar's ··· menu has 添加自定义块 (the words say so), else the page's own at the top right of its board. Returns the
117
+ * note, or null where none is shown.
118
+ */
119
+ export function showHint(map, { hosted = false } = {}) {
120
+ const main = document.querySelector("main.gallery-page");
121
+ if (!map?.hint || !main) return null;
122
+ addStyle(STYLE);
123
+ // The sentence offered: one that names Gallery, so that the Agent takes up its skill.
124
+ const ask = t("用 Gallery 在「{0}」这一页加一张卡片,记我每天喝了几杯水。别动我摆好的卡片。", map.title ?? document.title);
125
+ const copy = element("button", { type: "button", class: "ge-home-hint-copy", text: t("复制") });
126
+ const close = element("button", { type: "button", class: "ge-home-hint-close", "aria-label": t("关闭这条说明"), title: t("关闭"), html: CLOSE });
127
+ const box = element("div", { class: "ge-home-hint-box" },
128
+ element("p", { class: "ge-home-hint-title", text: t("这一页的卡片可以自己摆") }),
129
+ element("p", {}, ...filled(hosted ? t("拖卡片右上角的 {0} 移动它,点一下它打开菜单(大小、设置、删除),点页面右上角的 ··· 里的「添加自定义块」加一张。") : t("拖卡片右上角的 {0} 移动它,点一下它打开菜单(大小、设置、删除),点页面右上方的「添加自定义块」加一张。"), [icon(DOTS)])),
130
+ element("p", { class: "ge-home-hint-ask", text: t("想要新卡片或新页面,跟 Agent 说,比如:") }),
131
+ element("div", { class: "ge-home-hint-say" }, element("span", { text: ask }), copy),
132
+ close);
133
+ const note = noteOf("", t("这一页的说明"), box);
134
+ for (const button of [copy, close]) button.addEventListener("mousedown", (event) => event.preventDefault());
135
+ copy.addEventListener("click", () => {
136
+ // The frame given the focus first: in a workbench a press its mousedown keeps from moving the focus
137
+ // leaves it in the workbench, and Chrome refuses a clipboard write to a document without it
138
+ // ("Document is not focused"), as the board's grip takes it for the page's keys.
139
+ window.focus();
140
+ navigator.clipboard?.writeText(ask).then(() => {
141
+ copy.textContent = t("已复制");
142
+ say(t("已复制这句话,发给 Agent 就行"));
143
+ }, () => say(t("没能复制:浏览器不允许写剪贴板。"), "error"));
144
+ });
145
+ close.addEventListener("click", async () => {
146
+ note.remove();
147
+ const answer = await postAnswer(`/__gallery/pages/${map.slug}/hint`, map.token, {});
148
+ if (!answer?.ok) say(t("没能记下这条说明已关闭"), "error");
149
+ });
150
+ main.prepend(note);
151
+ return note;
152
+ }
153
+
154
+ /**
155
+ * The middle of a blank page (the page map's `blank`: the workbench's 新建页面, which no one has written yet):
156
+ * that an Agent writes it, any page it likes, with a request to copy and say to one. Returns the note, or
157
+ * null where none is shown (no blank page, or no main.gallery-page to show it in).
158
+ */
159
+ export function showBlank(map) {
160
+ const main = document.querySelector("main.gallery-page");
161
+ if (!map?.blank || !main) return null;
162
+ addStyle(STYLE);
163
+ const title = map.title ?? document.title;
164
+ const ask = t("用 Gallery 把「{0}」这个自定义页写出来:放上我这周的待办,和离月底还有几天。", title);
165
+ const copy = element("button", { type: "button", class: "ge-home-hint-copy", text: t("复制") });
166
+ const box = element("div", { class: "ge-home-hint-box" },
167
+ element("p", { class: "ge-home-hint-title", text: t("这一页还是空的") }),
168
+ element("p", { text: t("自定义页由 Agent 来写:可以是一页卡片,也可以是它为你做的任何网页。") }),
169
+ element("p", { class: "ge-home-hint-ask", text: t("跟 Agent 说你想在这里放什么,比如:") }),
170
+ element("div", { class: "ge-home-hint-say" }, element("span", { text: ask }), copy));
171
+ const note = noteOf("ge-page-blank", t("空白的自定义页"), box);
172
+ copy.addEventListener("mousedown", (event) => event.preventDefault());
173
+ copy.addEventListener("click", () => {
174
+ window.focus(); // as the first-open note's 复制: Chrome writes no clipboard of a document without the focus
175
+ navigator.clipboard?.writeText(ask).then(() => {
176
+ copy.textContent = t("已复制");
177
+ say(t("已复制这句话,发给 Agent 就行"));
178
+ }, () => say(t("没能复制:浏览器不允许写剪贴板。"), "error"));
179
+ });
180
+ main.append(note);
181
+ return note;
182
+ }
@@ -0,0 +1,119 @@
1
+ // A custom page's own undo and redo (docs/render.md "A custom page", the board's editing): what the
2
+ // page did, each step a list of what to send the page service to take it back or do it again, never
3
+ // a copy of the file. Kept in the tab's sessionStorage by the page's slug, so that a page shown again
4
+ // (the hidden frame's swap after a card is added from the library, or after someone else wrote
5
+ // page.html) undoes what this one did: the next page takes the steps up, and forgets those of a card
6
+ // someone else changed meanwhile (`forgetChanged`: its base, as the page knew it last, is not the one
7
+ // it is served with), whose undo would write over what they did. Each step names its cards by id; what
8
+ // it sends is held to each card's base as the page knows it then, so a card someone else changed is
9
+ // refused by the service whenever the page has not yet heard of it.
10
+ //
11
+ // A step is one of:
12
+ // { kind: "cells", cards: [{ id, before: { x, y, w, h }, after: { x, y, w, h } }] } moved, resized, pushed
13
+ // { kind: "edit", id, parts: { <name>: { was, now } } } a block's data or its settings
14
+ // { kind: "remove", id, board, html } a card taken out
15
+ // { kind: "add", id, board, html } a card put in
16
+ // { kind: "group", steps: [step, …] } several at once (恢复默认卡片's cards)
17
+ // { kind: "checked", slug, ref, done } a to-do of document `slug` checked (done) or not by a block
18
+
19
+ const MOST = 100; // steps kept each way
20
+
21
+ const read = (key) => {
22
+ try {
23
+ const value = JSON.parse(sessionStorage.getItem(key) ?? "null");
24
+ return value && Array.isArray(value.undo) && Array.isArray(value.redo) && value.bases && typeof value.bases === "object" ? value : null;
25
+ } catch {
26
+ return null;
27
+ }
28
+ };
29
+
30
+ /** The page `slug`'s steps. */
31
+ export function createHistory(slug) {
32
+ const key = `gallery-edit:${slug}:page-history`; // an editor key as the others (gallery-edit:<slug>:<kind>, shared/renamed-storage.mjs): made after the rename, so no old name
33
+ const kept = read(key);
34
+ let undo = kept?.undo ?? [];
35
+ let redo = kept?.redo ?? [];
36
+ let bases = kept?.bases ?? {}; // a card's id -> its base as this page knew it last
37
+ let measure = kept?.measure ?? null; // a card just added whose height its content gives, to measure once shown
38
+ const save = () => {
39
+ try {
40
+ sessionStorage.setItem(key, JSON.stringify({ undo, redo, bases, measure }));
41
+ } catch {} // no storage: the steps last as long as the page
42
+ };
43
+ const touches = (step, id) => (step.kind === "group" ? step.steps.some((one) => touches(one, id)) : step.kind === "cells" ? step.cards.some((card) => card.id === id) : step.id === id);
44
+ const rename = (step, from, to) => {
45
+ if (step.kind === "group") for (const one of step.steps) rename(one, from, to);
46
+ else if (step.kind === "cells") for (const card of step.cards) card.id = card.id === from ? to : card.id;
47
+ else if (step.id === from) step.id = to;
48
+ };
49
+ return {
50
+ /** A step done: undo takes it back first; what was undone cannot be done again any more. */
51
+ push(step) {
52
+ undo.push(step);
53
+ if (undo.length > MOST) undo.shift();
54
+ redo = [];
55
+ save();
56
+ },
57
+ /** The step undo takes back now, left where it is (null: none). */
58
+ nextUndo: () => undo.at(-1) ?? null,
59
+ /** The step undo takes back now, taken off (null: none). */
60
+ takeUndo: () => {
61
+ const step = undo.pop() ?? null;
62
+ save();
63
+ return step;
64
+ },
65
+ takeRedo: () => {
66
+ const step = redo.pop() ?? null;
67
+ save();
68
+ return step;
69
+ },
70
+ /** A step undone (it can be done again) or done again (it can be undone again). */
71
+ undone(step) {
72
+ redo.push(step);
73
+ save();
74
+ },
75
+ redone(step) {
76
+ undo.push(step);
77
+ save();
78
+ },
79
+ /** Card `from` goes by `to` now (put back under another id): the steps say so. */
80
+ renamed(from, to) {
81
+ for (const step of [...undo, ...redo]) rename(step, from, to);
82
+ save();
83
+ },
84
+ /** The cards' bases as this page knows them now ({ id: base }), for the next page to hold its own against. */
85
+ know(now) {
86
+ bases = { ...now };
87
+ save();
88
+ },
89
+ /**
90
+ * The page shown again: the steps of each card whose base (`served`, { id: base }) is not the one the
91
+ * page before knew are forgotten, someone else's change of it standing; so is a card gone or come.
92
+ */
93
+ forgetChanged(served) {
94
+ const changed = Object.keys(bases).filter((id) => served[id] !== bases[id]);
95
+ const gone = (step) => changed.some((id) => touches(step, id));
96
+ undo = undo.filter((step) => !gone(step));
97
+ redo = redo.filter((step) => !gone(step));
98
+ bases = { ...served };
99
+ save();
100
+ },
101
+ /** A card added whose height is its content's: measured once the next page shows it (`take`: and forgotten). */
102
+ toMeasure(id) {
103
+ measure = id;
104
+ save();
105
+ },
106
+ takeMeasure() {
107
+ const id = measure;
108
+ measure = null;
109
+ save();
110
+ return id;
111
+ },
112
+ get canUndo() {
113
+ return undo.length > 0;
114
+ },
115
+ get canRedo() {
116
+ return redo.length > 0;
117
+ },
118
+ };
119
+ }