@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,513 @@
1
+ // gallery/heatmap (编辑热力图): the workspace's record of edits by day, as GitHub draws a year of
2
+ // contributions: a column a week (Monday at the top, as a Chinese calendar starts it), a square a day,
3
+ // darker for a day of more, read through context.workspace.query("activity") (its manifest's needs hold
4
+ // "workspace": the server's record, .gallery/state/activity.json, a reader's commits and the Agent's
5
+ // writes, by day). Its one setting, `words` (按字数显示, the card's form: the grip at its top right ›
6
+ // 设置…, kept in its data part `settings`, which the board writes and this block only reads), draws the
7
+ // words a day added (its net change, a day that took more away than it added drawn as none) instead of
8
+ // how many edits it had. It asks for every day 53 weeks draw (the record keeps as many); a day before the
9
+ // record started is a small gray dot, never an empty square, and a day to come is not drawn. It reads again
10
+ // whenever the workspace says its record changed (the `data` signal, "activity") and as a day begins (the
11
+ // kit's clock), and draws again as its card changes size (`layout`, and its own ResizeObserver on the room
12
+ // the squares have) or its settings change (`source`). Where the workspace cannot be read (an exported
13
+ // file, where it has no server; a server that does not answer) the squares are empty and a line over them
14
+ // says why. The words are the page's language (the UI's where Gallery says it, else the page's lang).
15
+ //
16
+ // Its face (the pack's design B, in the kit's card tokens): a head of the chip (a calendar), 编辑热力图
17
+ // and its quiet meta; the squares the hero, five shades of the accent by how a day stands among the days
18
+ // recorded (`levelsOf`: the quarter of them with least, and so on, never by a straight line to the most,
19
+ // so that a busy day does not make every other pale); today's square ringed; the months' names over the
20
+ // weeks they begin in and 一 三 五 beside the rows; under them, less to more. Laid out by the card's cells
21
+ // (`data-layout`, by context.size): "full" (8 × 4, the default, and 12 × 4) squares of 23px, 4px apart,
22
+ // as many weeks as fit (14, 26), and at their left the figures (`summaryOf`): what the weeks are (近 14 周),
23
+ // the edits (or words) in them, large, the average a day, the days with any, the longest run of days in
24
+ // a row and today's, and a bar of how they split between the reader and the Agent; "compact" (4 × 4) squares
25
+ // of 21px over a line of the total and the days with any; "strip" (12 × 3, a card three cells high or
26
+ // less) squares of 14px (smaller where the card is lower), a year of them, the total and the days in the
27
+ // head's meta, and the day the record began said by the legend's dot. A record begun within the week is
28
+ // said so (从 11月11日 开始记录), and an export's figures say the time they are of (截至 …). A pointer on a
29
+ // square shows its day: its edits (or words), and the reader's and the Agent's.
30
+
31
+ const WORDS = {
32
+ zh: {
33
+ title: "编辑热力图",
34
+ weeks: (/** @type {number} */ count) => `近 ${count} 周`,
35
+ year: "过去一年",
36
+ added: "新增",
37
+ editsUnit: "次编辑",
38
+ wordsUnit: "字",
39
+ tenThousand: "万字",
40
+ average: (/** @type {string} */ value, /** @type {boolean} */ words) => ["平均每天 ", value, words ? " 字" : " 次"],
41
+ active: "有编辑的天数",
42
+ run: "最长连续",
43
+ today: "今天",
44
+ days: "天",
45
+ times: "次",
46
+ you: "你",
47
+ agent: "Agent",
48
+ activeDays: (/** @type {number} */ count) => `${count} 天有编辑`,
49
+ stripMeta: (/** @type {string} */ period, /** @type {string} */ total, /** @type {number} */ days) => [`${period} ${total}`, `${days} 天`],
50
+ totalEdits: (/** @type {string} */ count) => `${count} 次编辑`,
51
+ byWords: "按字数",
52
+ fresh: "刚开始记录",
53
+ freshSince: (/** @type {string} */ date) => `从 ${date} 开始记录`,
54
+ freshSaid: ["以后每天写了多少,", "都会在右边亮起一格"],
55
+ before: "开始记录之前",
56
+ beforeSince: (/** @type {string} */ date) => `${date} 开始记录之前`,
57
+ upTo: (/** @type {string} */ when) => `截至 ${when}`,
58
+ less: "少",
59
+ more: "多",
60
+ tip: (/** @type {string} */ date, /** @type {number} */ edits, /** @type {number} */ words, /** @type {boolean} */ byWords) => `${date} · ${byWords ? `${words >= 0 ? "+" : "−"}${Math.abs(words).toLocaleString("zh-CN")} 字` : `${edits} 次编辑`}`,
61
+ split: (/** @type {number} */ you, /** @type {number} */ agent) => `你 ${you} 次 · Agent ${agent} 次`,
62
+ unrecorded: "还没开始记录",
63
+ offline: "在 Gallery 里打开时显示",
64
+ failed: "读不到工作区的编辑记录",
65
+ date: (/** @type {Date} */ date) => `${date.getMonth() + 1}月${date.getDate()}日`,
66
+ weekday: (/** @type {Date} */ date) => `${date.getMonth() + 1}月${date.getDate()}日 ${["周日", "周一", "周二", "周三", "周四", "周五", "周六"][date.getDay()]}`,
67
+ month: (/** @type {number} */ month) => `${month + 1}月`,
68
+ rows: ["一", "", "三", "", "五", "", ""],
69
+ locale: "zh-CN",
70
+ },
71
+ en: {
72
+ title: "Editing heatmap",
73
+ weeks: (/** @type {number} */ count) => `Last ${count} weeks`,
74
+ year: "Past year",
75
+ added: " added",
76
+ editsUnit: "edits",
77
+ wordsUnit: "words",
78
+ tenThousand: "",
79
+ average: (/** @type {string} */ value, /** @type {boolean} */ words) => ["", value, words ? " words a day" : " a day"],
80
+ active: "Days with edits",
81
+ run: "Longest run",
82
+ today: "Today",
83
+ days: "d",
84
+ times: "",
85
+ you: "You",
86
+ agent: "Agent",
87
+ activeDays: (/** @type {number} */ count) => `${count} ${count === 1 ? "day" : "days"} with edits`,
88
+ stripMeta: (/** @type {string} */ period, /** @type {string} */ total, /** @type {number} */ days) => [`${period}: ${total}`, `${days} ${days === 1 ? "day" : "days"}`],
89
+ totalEdits: (/** @type {string} */ count) => `${count} edits`,
90
+ byWords: "by words",
91
+ fresh: "Just started",
92
+ freshSince: (/** @type {string} */ date) => `Recording since ${date}`,
93
+ freshSaid: ["Each day you write lights a square on the right"],
94
+ before: "Before recording",
95
+ beforeSince: (/** @type {string} */ date) => `Before ${date}`,
96
+ upTo: (/** @type {string} */ when) => `As of ${when}`,
97
+ less: "Less",
98
+ more: "More",
99
+ tip: (/** @type {string} */ date, /** @type {number} */ edits, /** @type {number} */ words, /** @type {boolean} */ byWords) => `${date} · ${byWords ? `${words >= 0 ? "+" : "−"}${Math.abs(words).toLocaleString("en")} words` : `${edits} ${edits === 1 ? "edit" : "edits"}`}`,
100
+ split: (/** @type {number} */ you, /** @type {number} */ agent) => `You ${you} · Agent ${agent}`,
101
+ unrecorded: "Not recorded yet",
102
+ offline: "Shown when opened in Gallery",
103
+ failed: "The workspace's record of edits could not be read",
104
+ date: (/** @type {Date} */ date) => `${["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][date.getMonth()]} ${date.getDate()}`,
105
+ weekday: (/** @type {Date} */ date) => `${["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][date.getDay()]}, ${["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][date.getMonth()]} ${date.getDate()}`,
106
+ month: (/** @type {number} */ month) => ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][month],
107
+ rows: ["Mon", "", "Wed", "", "Fri", "", ""],
108
+ locale: "en",
109
+ },
110
+ };
111
+
112
+ /** The language the page speaks: the UI's where Gallery says it (data-ge-language), else its lang's. */
113
+ function languageOf(/** @type {HTMLElement} */ root) {
114
+ const ui = root.getAttribute("data-ge-language");
115
+ return (ui !== null ? ui === "en" : /^en(?:-|$)/i.test(root.lang)) ? "en" : "zh";
116
+ }
117
+
118
+ const MOST_WEEKS = 53;
119
+ /** The days of the record it reads: as many as 53 weeks draw at the most (on a Sunday, its first square 370 days back). */
120
+ const DAYS = MOST_WEEKS * 7;
121
+ /** The weekdays' column and the months' row, in px. */
122
+ const LABELS = 20;
123
+ const MONTHS = 18;
124
+ const two = (/** @type {number} */ value) => String(value).padStart(2, "0");
125
+ /** A local day as the record writes it, YYYY-MM-DD. @param {Date} date */
126
+ const dayOf = (date) => `${date.getFullYear()}-${two(date.getMonth() + 1)}-${two(date.getDate())}`;
127
+ /** The day `count` days after `date` (before, negative), at noon. @param {Date} date @param {number} count */
128
+ const after = (date, count) => new Date(date.getFullYear(), date.getMonth(), date.getDate() + count, 12);
129
+
130
+ /**
131
+ * How a card of `size` (context.size: its cells, or null where no card holds it, a document) lays its face
132
+ * out: "grid" two cells high or less (8 × 2: the squares alone, the user's word of 2026-11-09), "strip" three
133
+ * cells high, "compact" four wide or less, else "full".
134
+ * @param {{ w: number, h: number } | null | undefined} size
135
+ * @returns {"full" | "compact" | "strip" | "grid"}
136
+ */
137
+ function layoutOf(size) {
138
+ if (!size) return "full";
139
+ if (size.h <= 2) return "grid";
140
+ if (size.h <= 3) return "strip";
141
+ return size.w <= 4 ? "compact" : "full";
142
+ }
143
+
144
+ /**
145
+ * The squares of a layout in a room of `width` x `height` px (the field's: the weekdays' column and the
146
+ * months' row inside it): { pitch (from one square to the next), cell (a square's side), gap, weeks }.
147
+ * "full" 23px squares 4px apart, "compact" 21px; "strip" and "grid" 14px, 3px apart, smaller where the room is
148
+ * lower (seven of them and the months' row in its height, 4px at the least, 2px apart under 10px); as many
149
+ * weeks as the width holds, 1 to 53.
150
+ * @param {"full" | "compact" | "strip" | "grid"} layout
151
+ * @param {number} width
152
+ * @param {number} height
153
+ */
154
+ function fitOf(layout, width, height) {
155
+ let pitch = layout === "full" ? 27 : layout === "compact" ? 25 : 17;
156
+ let gap = pitch === 17 ? 3 : 4;
157
+ if ((layout === "strip" || layout === "grid") && Number.isFinite(height)) {
158
+ pitch = Math.max(6, Math.min(17, Math.floor((height - MONTHS + gap) / 7)));
159
+ gap = pitch < 12 ? 2 : 3;
160
+ }
161
+ const weeks = Math.max(1, Math.min(MOST_WEEKS, Math.floor((width - LABELS + gap) / pitch)));
162
+ return { pitch, cell: pitch - gap, gap, weeks };
163
+ }
164
+
165
+ /**
166
+ * The weeks drawn, the last the one of `today` (a Date), `weeks` of them: [[{ date, day, future }…7]…],
167
+ * each a column, Monday first; `future` a day after today, which is not drawn.
168
+ * @param {Date} today
169
+ * @param {number} weeks
170
+ */
171
+ function weeksOf(today, weeks) {
172
+ const monday = after(today, -((today.getDay() + 6) % 7));
173
+ const columns = [];
174
+ for (let week = weeks - 1; week >= 0; week--) {
175
+ const start = after(monday, -7 * week);
176
+ columns.push(Array.from({ length: 7 }, (_, row) => {
177
+ const date = after(start, row);
178
+ return { date, day: dayOf(date), future: dayOf(date) > dayOf(today) };
179
+ }));
180
+ }
181
+ return columns;
182
+ }
183
+
184
+ /**
185
+ * The bounds of the levels of `values` (a day's edits, or the words it added, of every day recorded): the
186
+ * values at 38%, 68% and 90% of the days with any, so that each shade holds a share of the days; for fewer
187
+ * than five such days, a quarter, a half and three quarters of the most.
188
+ * @param {number[]} values
189
+ */
190
+ function levelsOf(values) {
191
+ const some = values.filter((value) => value > 0).sort((a, b) => a - b);
192
+ if (some.length < 5) {
193
+ const most = some[some.length - 1] ?? 0;
194
+ return [most / 4, most / 2, (3 * most) / 4];
195
+ }
196
+ return [some[Math.floor(some.length * 0.38)], some[Math.floor(some.length * 0.68)], some[Math.floor(some.length * 0.9)]];
197
+ }
198
+
199
+ /**
200
+ * The level of a day's square, 0 (none) to 4 (the most), of `value` by the bounds `levels` (levelsOf's).
201
+ * @param {number} value
202
+ * @param {number[]} levels
203
+ */
204
+ function levelOf(value, levels) {
205
+ if (!(value > 0)) return 0;
206
+ if (value <= levels[0]) return 1;
207
+ if (value <= levels[1]) return 2;
208
+ return value <= levels[2] ? 3 : 4;
209
+ }
210
+
211
+ /**
212
+ * What the card says of the record `days` (workspace.query("activity")'s data: [{ date, edits, words,
213
+ * reader, agent }], from the day it started or 53 weeks back to today) over the `weeks` it draws (`today`,
214
+ * a Date), counting `words` (the setting) or edits: `values` (each day's, by its date), `levels`, `since`
215
+ * (the first day recorded), and the figures: `total` (in the weeks drawn), `average` (a day, of the days
216
+ * recorded in them), `active` (days with any edit), `run` (the longest run of them), `today` (its value),
217
+ * `you` and `agent` (the edits of each), and `fresh` (the record began within the week).
218
+ * @param {Array<{ date: string, edits: number, words: number, reader?: { edits: number }, agent?: { edits: number } }>} days
219
+ * @param {boolean} words
220
+ * @param {number} weeks
221
+ * @param {Date} today
222
+ */
223
+ function summaryOf(days, words, weeks, today) {
224
+ const valueOf = (/** @type {{ edits: number, words: number }} */ day) => (words ? Math.max(0, day.words) : day.edits);
225
+ const values = new Map(days.map((day) => [day.date, valueOf(day)]));
226
+ const since = days[0]?.date ?? null;
227
+ const first = dayOf(after(today, -((today.getDay() + 6) % 7) - 7 * (weeks - 1)));
228
+ const shown = days.filter((day) => day.date >= first && day.date <= dayOf(today));
229
+ let run = 0;
230
+ let longest = 0;
231
+ for (const day of shown) {
232
+ run = day.edits > 0 ? run + 1 : 0;
233
+ longest = Math.max(longest, run);
234
+ }
235
+ const total = shown.reduce((sum, day) => sum + valueOf(day), 0);
236
+ const agent = shown.reduce((sum, day) => sum + (day.agent?.edits ?? 0), 0);
237
+ const you = shown.reduce((sum, day) => sum + (day.reader?.edits ?? 0), 0);
238
+ const now = days.find((day) => day.date === dayOf(today));
239
+ return {
240
+ values, since, levels: levelsOf([...values.values()]),
241
+ total, average: shown.length > 0 ? total / shown.length : 0, active: shown.filter((day) => day.edits > 0).length, run: longest,
242
+ today: now ? valueOf(now) : 0, you, agent, fresh: since !== null && since > dayOf(after(today, -7)),
243
+ };
244
+ }
245
+
246
+ /**
247
+ * An element of the face, of `kind` (its class).
248
+ * @template {keyof HTMLElementTagNameMap} K
249
+ * @param {K} tag
250
+ * @param {string} kind
251
+ * @param {string} [text]
252
+ */
253
+ function made(tag, kind, text) {
254
+ const node = document.createElement(tag);
255
+ node.className = `gallery-heatmap-${kind}`;
256
+ if (text !== undefined) node.textContent = text;
257
+ return node;
258
+ }
259
+
260
+ DocKit.component({
261
+ id: "gallery/heatmap",
262
+ on: ["data", "source", "layout", "clock"],
263
+ mount(host, context) {
264
+ const language = languageOf(document.documentElement);
265
+ const words = WORDS[language];
266
+ const format = (/** @type {number} */ value) => new Intl.NumberFormat(words.locale, { maximumFractionDigits: 0 }).format(value);
267
+ const face = made("div", "face");
268
+ const head = made("div", "head");
269
+ const meta = made("span", "line");
270
+ const chip = made("span", "chip");
271
+ chip.setAttribute("aria-hidden", "true");
272
+ chip.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="3.5" y="5" width="17" height="15.5" rx="3"/><path d="M3.5 10h17M8 3v4M16 3v4"/></svg>';
273
+ head.append(chip, made("span", "title", words.title), meta);
274
+ const body = made("div", "body");
275
+ // The figures beside the squares (a full card), or the line over them (a compact one).
276
+ const aside = made("div", "aside");
277
+ const period = made("span", "label");
278
+ const total = made("span", "total");
279
+ const totalNumber = made("span", "number");
280
+ const totalUnit = made("span", "unit");
281
+ total.append(totalNumber, totalUnit);
282
+ const average = made("span", "average");
283
+ const facts = made("dl", "facts");
284
+ const who = made("div", "who");
285
+ const split = made("span", "split");
286
+ const youBar = made("i", "you-bar");
287
+ const agentBar = made("i", "agent-bar");
288
+ split.append(youBar, agentBar);
289
+ const whoWords = made("span", "who-words");
290
+ who.append(split, whoWords);
291
+ aside.append(period, total, average, facts, who);
292
+ const field = made("div", "field");
293
+ const area = made("div", "area");
294
+ const months = made("div", "months");
295
+ const rows = made("div", "rows");
296
+ for (const label of words.rows) rows.append(made("span", "row", label));
297
+ const grid = made("div", "grid");
298
+ // The tip stands over the card, in the page's top layer (a popover; where a browser has none, fixed to the
299
+ // window), never inside the card, whose overflow a tip near its edge would widen into a scrollbar.
300
+ const tip = made("div", "tip");
301
+ const popover = typeof tip.showPopover === "function";
302
+ if (popover) tip.popover = "manual";
303
+ else tip.hidden = true;
304
+ tip.setAttribute("aria-hidden", "true");
305
+ area.append(months, rows, grid, tip);
306
+ const legend = made("div", "legend");
307
+ const note = made("span", "note");
308
+ legend.append(made("span", "less", words.less), ...[0, 1, 2, 3, 4].map((level) => {
309
+ const square = made("span", "square");
310
+ square.dataset.level = String(level);
311
+ return square;
312
+ }), made("span", "more", words.more), note);
313
+ const overlay = made("p", "overlay");
314
+ overlay.hidden = true;
315
+ field.append(area, legend, overlay);
316
+ body.append(aside, field);
317
+ // As wide as the corner a board's grip takes of the content's top right (--gallery-grip-room, a custom
318
+ // property CSS alone resolves), measured where the months' row is the face's first (the squares alone).
319
+ const gripRoom = made("i", "grip-room");
320
+ gripRoom.setAttribute("aria-hidden", "true");
321
+ face.append(head, body, gripRoom);
322
+ host.append(face);
323
+ const workspace = context.workspace;
324
+ if (!workspace) return void context.fail(new Error("its manifest's needs hold \"workspace\": context.workspace is not there"));
325
+
326
+ /** @type {Array<{ date: string, edits: number, words: number, reader?: { edits: number, words: number }, agent?: { edits: number, words: number } }> | null} */
327
+ let days = null;
328
+ let at = "";
329
+ let failure = "";
330
+ let drawn = "";
331
+ const kv = (/** @type {string} */ name, /** @type {string} */ value, /** @type {string} */ unit) => {
332
+ const row = made("div", "fact");
333
+ const said = made("dd", "fact-value", value);
334
+ if (unit) said.append(made("small", "fact-unit", unit));
335
+ row.append(made("dt", "fact-name", name), said);
336
+ return row;
337
+ };
338
+ const bigOf = (/** @type {number} */ value, /** @type {boolean} */ byWords) => {
339
+ if (!byWords) return [format(value), language === "zh" ? words.editsUnit : ` ${words.editsUnit}`];
340
+ if (language === "zh" && value >= 10_000) return [(value / 10_000).toFixed(1), words.tenThousand];
341
+ return [format(value), language === "zh" ? words.wordsUnit : ` ${words.wordsUnit}`];
342
+ };
343
+ const draw = () => {
344
+ const settings = context.readJSON("settings");
345
+ if (settings === undefined) return; // no JSON: the instance has failed, and Gallery shows what it holds
346
+ const byWords = settings !== null && typeof settings === "object" && settings.words === true;
347
+ const layout = layoutOf(context.size);
348
+ face.dataset.layout = layout;
349
+ const today = new Date();
350
+ // The room the squares have: the field's, the legend's taken off (a strip's height says how large they are).
351
+ const room = { width: field.clientWidth || 600, height: field.clientHeight > 0 ? field.clientHeight - legend.offsetHeight : Infinity };
352
+ const { pitch, cell, gap, weeks } = fitOf(layout, room.width, room.height);
353
+ const summary = summaryOf(days ?? [], byWords, weeks, today);
354
+ const exported = context.place === "export" && at;
355
+ const fresh = days !== null && summary.fresh;
356
+ face.toggleAttribute("data-fresh", fresh);
357
+ face.toggleAttribute("data-unread", Boolean(failure));
358
+ const key = JSON.stringify([layout, pitch, weeks, dayOf(today), byWords, days, failure, at]);
359
+ if (key === drawn) return;
360
+ drawn = key;
361
+ hide(); // the squares drawn anew: the one it stood over is gone
362
+ // The head's meta.
363
+ const [bigValue, bigUnit] = bigOf(summary.total, byWords);
364
+ const atWhen = exported ? (() => { const when = new Date(at); return `${words.date(when)} ${two(when.getHours())}:${two(when.getMinutes())}`; })() : "";
365
+ if (failure) meta.textContent = "";
366
+ else if (layout === "strip") {
367
+ const [first, second] = words.stripMeta(weeks >= 52 ? words.year : words.weeks(weeks), byWords ? `${bigValue} ${bigUnit.trim()}` : words.totalEdits(format(summary.total)), summary.active);
368
+ const dot = made("span", "dot", "·");
369
+ meta.replaceChildren(first, dot, second);
370
+ } else if (layout === "compact") meta.textContent = words.weeks(weeks) + (byWords ? ` · ${words.byWords}` : "");
371
+ else meta.textContent = fresh ? words.fresh : exported ? words.upTo(atWhen) : byWords ? words.byWords : "";
372
+ // The figures.
373
+ totalNumber.textContent = failure ? "—" : bigValue;
374
+ totalUnit.textContent = failure ? "" : bigUnit;
375
+ if (fresh && summary.since) {
376
+ period.textContent = words.freshSince(words.date(new Date(`${summary.since}T12:00:00`)));
377
+ average.replaceChildren();
378
+ // Its clauses each whole on a line where one fits (style.css), so that it breaks after the comma.
379
+ const said = made("p", "fresh");
380
+ said.append(...words.freshSaid.map((clause) => made("span", "clause", clause)));
381
+ facts.replaceChildren(said);
382
+ } else {
383
+ period.textContent = layout === "compact" ? "" : `${words.weeks(weeks)}${byWords ? words.added : ""}`;
384
+ const [before, value, afterwards] = words.average(byWords ? format(Math.round(summary.average)) : summary.average.toFixed(1), byWords);
385
+ average.replaceChildren(before, made("b", "strong", value), afterwards);
386
+ const todayName = exported ? words.date(new Date(at)) : words.today;
387
+ facts.replaceChildren(
388
+ kv(words.active, String(summary.active), words.days),
389
+ kv(words.run, String(summary.run), words.days),
390
+ kv(todayName, byWords ? format(summary.today) : String(summary.today), byWords ? words.wordsUnit : words.times),
391
+ );
392
+ }
393
+ if (layout === "compact") average.replaceChildren(words.activeDays(summary.active));
394
+ const both = summary.you + summary.agent;
395
+ const youShare = both > 0 ? Math.round((100 * summary.you) / both) : 0;
396
+ youBar.style.flex = String(summary.you || (both ? 0 : 1));
397
+ agentBar.style.flex = String(summary.agent);
398
+ const label = (/** @type {string} */ kind, /** @type {string} */ name, /** @type {number} */ share) => {
399
+ const piece = made("span", kind);
400
+ piece.append(made("i", "swatch"), `${name} `, made("b", "strong", `${share}%`));
401
+ return piece;
402
+ };
403
+ whoWords.replaceChildren(label("you", words.you, youShare), label("agent", words.agent, both > 0 ? 100 - youShare : 0));
404
+ who.hidden = both === 0 || fresh;
405
+ // The legend's note: since when the record is kept, where days before it are drawn.
406
+ const columns = weeksOf(today, weeks);
407
+ const firstDay = columns[0][0].day;
408
+ const before = days !== null && summary.since !== null && summary.since > firstDay;
409
+ note.replaceChildren(...(before && layout !== "compact" ? [made("s", "dot-key"), layout === "strip" ? words.beforeSince(words.date(new Date(`${summary.since}T12:00:00`))) : words.before] : []));
410
+ overlay.hidden = !failure;
411
+ overlay.textContent = failure;
412
+ // The squares.
413
+ face.style.setProperty("--gallery-heatmap-cell", `${cell}px`);
414
+ face.style.setProperty("--gallery-heatmap-gap", `${gap}px`);
415
+ face.style.setProperty("--gallery-heatmap-weeks", String(weeks));
416
+ const byDate = new Map((days ?? []).map((item) => [item.date, item]));
417
+ grid.replaceChildren(...columns.flatMap((column) => column.map(({ date, day, future }) => {
418
+ const square = made("span", "day");
419
+ if (future) {
420
+ square.classList.add("gallery-heatmap-future");
421
+ return square;
422
+ }
423
+ square.dataset.date = day;
424
+ if (day === dayOf(today)) square.classList.add("gallery-heatmap-today");
425
+ const recorded = days !== null && summary.since !== null && day >= summary.since;
426
+ if (!recorded) {
427
+ square.classList.add("gallery-heatmap-before");
428
+ square.setAttribute("aria-label", `${words.weekday(date)} · ${days === null ? failure : words.unrecorded}`);
429
+ return square;
430
+ }
431
+ const entry = byDate.get(day);
432
+ square.dataset.level = String(levelOf(summary.values.get(day) ?? 0, summary.levels));
433
+ square.setAttribute("aria-label", `${words.tip(words.weekday(date), entry?.edits ?? 0, entry?.words ?? 0, byWords)}(${words.split(entry?.reader?.edits ?? 0, entry?.agent?.edits ?? 0)})`);
434
+ return square;
435
+ })));
436
+ // A month's name over the week its first day falls in (the first week's too, but where the next is
437
+ // fewer than three weeks after it).
438
+ const starts = columns.flatMap((column, index) => (index === 0 || column[0].date.getMonth() !== columns[index - 1][0].date.getMonth() ? [index] : []));
439
+ if (starts.length > 1 && starts[1] < 3) starts.shift();
440
+ months.replaceChildren(...starts.map((index) => {
441
+ const name = made("span", "month", words.month(columns[index][0].date.getMonth()));
442
+ name.style.setProperty("--gallery-heatmap-week", String(index));
443
+ return name;
444
+ }));
445
+ // The squares alone: the months' row is the card's first, and a name that would reach into the grip's corner is left out.
446
+ if (layout === "grid") {
447
+ const end = face.getBoundingClientRect().right - gripRoom.offsetWidth;
448
+ for (const name of [...months.children]) if (name.getBoundingClientRect().right > end) name.remove();
449
+ }
450
+ };
451
+ // A pointer on a square: its day, its count and whose, over it (under it where the window has no room
452
+ // above), its middle at the square's but held 8px inside the window, the arrow at the square.
453
+ const hide = () => {
454
+ if (popover) {
455
+ if (tip.matches(":popover-open")) tip.hidePopover();
456
+ } else tip.hidden = true;
457
+ };
458
+ const show = (/** @type {Event} */ event) => {
459
+ const square = /** @type {HTMLElement | null} */ (/** @type {HTMLElement} */ (event.target).closest?.(".gallery-heatmap-day[data-date]"));
460
+ if (!square || !grid.contains(square)) return hide();
461
+ const [first, second] = (square.getAttribute("aria-label") ?? "").replace(/)$/, "").split("(");
462
+ tip.replaceChildren(first, ...(second ? [made("small", "tip-split", second)] : []));
463
+ if (popover) {
464
+ if (!tip.matches(":popover-open")) tip.showPopover();
465
+ } else tip.hidden = false;
466
+ const box = square.getBoundingClientRect();
467
+ const width = tip.offsetWidth;
468
+ const height = tip.offsetHeight;
469
+ const left = Math.max(8, Math.min(innerWidth - 8 - width, box.left + box.width / 2 - width / 2));
470
+ const below = box.top - 8 - height < 8;
471
+ tip.style.left = `${Math.round(left)}px`;
472
+ tip.style.top = `${Math.round(below ? box.bottom + 8 : box.top - 8 - height)}px`;
473
+ tip.style.setProperty("--gallery-heatmap-arrow", `${Math.round(Math.max(10, Math.min(width - 10, box.left + box.width / 2 - left)))}px`);
474
+ tip.toggleAttribute("data-below", below);
475
+ };
476
+ context.listen(grid, "pointerover", show);
477
+ context.listen(grid, "pointerleave", hide);
478
+ // A scroll (the page's, or a card's) moves the square from under it: gone until the pointer is on one again.
479
+ context.listen(document, "scroll", hide, { capture: true, passive: true });
480
+ context.signal?.addEventListener("abort", hide, { once: true });
481
+ let asking = 0; // the last read asked: an older answer that comes after it is dropped
482
+ const read = () => {
483
+ const ticket = ++asking;
484
+ workspace.query("activity", { days: DAYS }).then(({ data, at: when }) => {
485
+ if (ticket !== asking || context.signal.aborted) return;
486
+ days = data;
487
+ at = typeof when === "string" ? when : "";
488
+ failure = "";
489
+ draw();
490
+ }, (/** @type {any} */ error) => {
491
+ if (ticket !== asking || context.signal.aborted) return;
492
+ days = null;
493
+ failure = error?.code === "offline" ? words.offline : words.failed;
494
+ draw();
495
+ });
496
+ };
497
+ draw();
498
+ read();
499
+ // The room the squares have, its height too: a card given its height after the first draw (a board laid
500
+ // out late) is drawn again as it gets it.
501
+ if (typeof ResizeObserver === "function") {
502
+ const watch = new ResizeObserver(() => draw());
503
+ watch.observe(body);
504
+ context.signal?.addEventListener("abort", () => watch.disconnect(), { once: true });
505
+ }
506
+ return {
507
+ update(reason, detail) {
508
+ if ((reason === "data" && detail === "activity") || (reason === "clock" && detail === "day")) read();
509
+ else if (reason !== "data" && reason !== "clock") draw();
510
+ },
511
+ };
512
+ },
513
+ });
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 120"><rect width="240" height="120" rx="8" fill="#f3f3f1"/><rect x="10.5" y="8.5" width="219" height="103" rx="8" fill="#ffffff" stroke="#e6e6e3"/><rect x="20" y="16" width="10" height="10" rx="3" fill="#efefed"/><rect x="34" y="18.5" width="36" height="5" rx="2.5" fill="#37352f"/><rect x="20" y="34" width="18" height="4" rx="2" fill="#a6a5a1"/><rect x="20" y="42" width="36" height="12" rx="3" fill="#1d1d1b"/><rect x="20" y="58" width="30" height="4" rx="2" fill="#d4d3cf"/><rect x="20" y="70" width="26" height="3.5" rx="1.75" fill="#a6a5a1"/><rect x="62" y="70" width="10" height="3.5" rx="1.75" fill="#37352f"/><rect x="20" y="78" width="26" height="3.5" rx="1.75" fill="#a6a5a1"/><rect x="62" y="78" width="10" height="3.5" rx="1.75" fill="#37352f"/><rect x="20" y="86" width="26" height="3.5" rx="1.75" fill="#a6a5a1"/><rect x="62" y="86" width="10" height="3.5" rx="1.75" fill="#37352f"/><rect x="20" y="98" width="32" height="3" rx="1.5" fill="#4084cf"/><rect x="54" y="98" width="22" height="3" rx="1.5" fill="#b0cbeb"/><rect x="92" y="28" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="92" y="37" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="92" y="46" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="92" y="55" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="92" y="64" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="92" y="73" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="92" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="101" y="28" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="101" y="37" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="101" y="46" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="101" y="55" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="101" y="64" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="101" y="73" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="101" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="110" y="28" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="110" y="37" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="110" y="46" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="110" y="55" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="110" y="64" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="110" y="73" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="110" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="119" y="28" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="119" y="37" width="7" height="7" rx="1.8" fill="#2e5e9c"/><rect x="119" y="46" width="7" height="7" rx="1.8" fill="#2e5e9c"/><rect x="119" y="55" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="119" y="64" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="119" y="73" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="119" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="128" y="28" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="128" y="37" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="128" y="46" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="128" y="55" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="128" y="64" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="128" y="73" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="128" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="137" y="28" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="137" y="37" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="137" y="46" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="137" y="55" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="137" y="64" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="137" y="73" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="137" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="146" y="28" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="146" y="37" width="7" height="7" rx="1.8" fill="#2e5e9c"/><rect x="146" y="46" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="146" y="55" width="7" height="7" rx="1.8" fill="#2e5e9c"/><rect x="146" y="64" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="146" y="73" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="146" y="82" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="155" y="28" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="155" y="37" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="155" y="46" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="155" y="55" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="155" y="64" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="155" y="73" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="155" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="164" y="28" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="164" y="37" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="164" y="46" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="164" y="55" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="164" y="64" width="7" height="7" rx="1.8" fill="#2e5e9c"/><rect x="164" y="73" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="164" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="173" y="28" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="173" y="37" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="173" y="46" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="173" y="55" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="173" y="64" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="173" y="73" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="173" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="182" y="28" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="182" y="37" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="182" y="46" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="182" y="55" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="182" y="64" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="182" y="73" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="182" y="82" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="191" y="28" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="191" y="37" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="191" y="46" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="191" y="55" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="191" y="64" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="191" y="73" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="191" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="200" y="28" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="200" y="37" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="200" y="46" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="200" y="55" width="7" height="7" rx="1.8" fill="#4d88d3"/><rect x="200" y="64" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="200" y="73" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="200" y="82" width="7" height="7" rx="1.8" fill="#ececea"/><rect x="209" y="28" width="7" height="7" rx="1.8" fill="#d1e2f6"/><rect x="209" y="37" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="209" y="46" width="7" height="7" rx="1.8" fill="#90b6e3"/><rect x="209" y="55" width="7" height="7" rx="1.8" fill="#ececea"/></svg>