@heycys/gallery 0.1.2 → 0.2.1

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 (338) 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/embed/page.mjs +1 -1
  5. package/browser/editor/components/file/page.mjs +4 -4
  6. package/browser/editor/components/heading/index.mjs +7 -6
  7. package/browser/editor/components/icon/page.mjs +6 -4
  8. package/browser/editor/components/icons.mjs +5 -2
  9. package/browser/editor/components/image/index.mjs +2 -0
  10. package/browser/editor/components/image/page.mjs +172 -90
  11. package/browser/editor/components/installed/index.mjs +6 -2
  12. package/browser/editor/components/installed/page.mjs +80 -13
  13. package/browser/editor/components/media/icons.mjs +13 -8
  14. package/browser/editor/components/media/page.mjs +5 -3
  15. package/browser/editor/components/media/toolbar.mjs +12 -3
  16. package/browser/editor/components/paragraph/index.mjs +4 -3
  17. package/browser/editor/components/registry.mjs +17 -5
  18. package/browser/editor/components/table/index.mjs +4 -2
  19. package/browser/editor/page/after/index.mjs +288 -0
  20. package/browser/editor/page/align.mjs +91 -0
  21. package/browser/editor/page/beside.mjs +5 -6
  22. package/browser/editor/page/block-menu/index.mjs +6 -3
  23. package/browser/editor/page/blocks.mjs +3 -1
  24. package/browser/editor/page/board/hint.mjs +64 -27
  25. package/browser/editor/page/board/index.mjs +160 -71
  26. package/browser/editor/page/board/motion.mjs +177 -0
  27. package/browser/editor/page/board/settings.mjs +4 -3
  28. package/browser/editor/page/clipboard/import/read.mjs +20 -2
  29. package/browser/editor/page/clipboard/index.mjs +10 -3
  30. package/browser/editor/page/clipboard/own/blocks.mjs +3 -4
  31. package/browser/editor/page/clipboard/own/describe.mjs +6 -2
  32. package/browser/editor/page/commit.mjs +2 -2
  33. package/browser/editor/page/core.mjs +3 -1
  34. package/browser/editor/page/custom-page.mjs +15 -11
  35. package/browser/editor/page/editor.mjs +31 -14
  36. package/browser/editor/page/history.mjs +19 -4
  37. package/browser/editor/page/insert/index.mjs +20 -22
  38. package/browser/editor/page/menu.mjs +15 -7
  39. package/browser/editor/page/page-objects.mjs +3 -7
  40. package/browser/editor/page/present-links.mjs +5 -4
  41. package/browser/editor/page/present-shell.mjs +63 -0
  42. package/browser/editor/page/selection/index.mjs +10 -2
  43. package/browser/editor/page/table/binding.mjs +87 -0
  44. package/browser/editor/page/table/icons.mjs +0 -2
  45. package/browser/editor/page/table/index.mjs +10 -14
  46. package/browser/editor/page/table/views.mjs +5 -52
  47. package/browser/editor/page/table/widths.mjs +82 -10
  48. package/browser/editor/page/typing/index.mjs +44 -12
  49. package/browser/editor/page/typing/leave.mjs +19 -5
  50. package/browser/shared/block-packs.mjs +23 -8
  51. package/browser/shared/component-catalog.mjs +15 -8
  52. package/browser/shared/component-source.mjs +3 -1
  53. package/browser/shared/components/heading.mjs +2 -1
  54. package/browser/shared/components/installed.mjs +1 -1
  55. package/browser/shared/components/page.mjs +2 -0
  56. package/browser/shared/components/paragraph.mjs +8 -1
  57. package/browser/shared/components/table.mjs +1 -0
  58. package/browser/shared/document-copy.mjs +43 -0
  59. package/browser/shared/drafts.mjs +10 -3
  60. package/browser/shared/emoji/icon-value.mjs +2 -2
  61. package/browser/shared/emoji/line-icons.mjs +37 -0
  62. package/browser/shared/extensions.mjs +83 -7
  63. package/browser/shared/http.mjs +9 -0
  64. package/browser/shared/i18n/en.mjs +50 -17
  65. package/browser/shared/outline-shape.mjs +6 -0
  66. package/browser/shared/outline.mjs +165 -12
  67. package/browser/shared/pack-manifest.mjs +12 -1
  68. package/browser/shared/pages.mjs +169 -57
  69. package/browser/shared/pinyin.mjs +92 -0
  70. package/browser/shared/present-step.mjs +17 -0
  71. package/browser/shared/sidebar-head.mjs +70 -0
  72. package/browser/shared/web-links.mjs +5 -0
  73. package/browser/shared/workspace-columns.mjs +11 -7
  74. package/dist/{chunk-N7AZZLGT.mjs → chunk-2GKGEVMR.mjs} +29 -24
  75. package/dist/chunk-2OHANJ6Q.mjs +2 -0
  76. package/dist/{chunk-HYMEEXKN.mjs → chunk-2RKIHJI2.mjs} +1 -1
  77. package/dist/{chunk-742D2WWJ.mjs → chunk-36FIRJIF.mjs} +2 -2
  78. package/dist/{chunk-BPL64HGA.mjs → chunk-3A5I2GJK.mjs} +1 -1
  79. package/dist/{chunk-RFDZXFJF.mjs → chunk-3OFXMN6N.mjs} +1 -1
  80. package/dist/chunk-46ACXOU5.mjs +2 -0
  81. package/dist/{chunk-PUOQ65NC.mjs → chunk-4AMTKWDO.mjs} +1 -1
  82. package/dist/{chunk-VTKNEYT3.mjs → chunk-4DNHHJSL.mjs} +1 -1
  83. package/dist/chunk-5DPABPBI.mjs +2 -0
  84. package/dist/chunk-5IIH335D.mjs +3 -0
  85. package/dist/chunk-5L26JUYA.mjs +2 -0
  86. package/dist/{chunk-3NJACR4W.mjs → chunk-5MEXZ2UF.mjs} +1 -1
  87. package/dist/{chunk-ZHEHPMBK.mjs → chunk-6MPKCH3P.mjs} +1 -1
  88. package/dist/{chunk-C564NU2H.mjs → chunk-74RPP2M2.mjs} +1 -1
  89. package/dist/chunk-7M2BQQGZ.mjs +2 -0
  90. package/dist/{chunk-VXACTLO3.mjs → chunk-7M7UPWU6.mjs} +1 -1
  91. package/dist/{chunk-ZB4H7ZN4.mjs → chunk-7N2LPG33.mjs} +1 -1
  92. package/dist/{chunk-UBBRTJ2R.mjs → chunk-7XDYK3UC.mjs} +1 -1
  93. package/dist/chunk-AEMVZYZQ.mjs +166 -0
  94. package/dist/{chunk-POQSE4C2.mjs → chunk-AFGUR7SY.mjs} +1 -1
  95. package/dist/{chunk-QKXMPUXC.mjs → chunk-AMDGVDNV.mjs} +1 -1
  96. package/dist/{chunk-KTKHRC6H.mjs → chunk-ASAXY2DJ.mjs} +1 -1
  97. package/dist/{chunk-NVRNLK25.mjs → chunk-BYSF5UMM.mjs} +2 -2
  98. package/dist/{chunk-U3SSPL4K.mjs → chunk-CCSGFCLZ.mjs} +1 -1
  99. package/dist/{chunk-NWFBE2YA.mjs → chunk-CG3UHDKH.mjs} +1 -1
  100. package/dist/chunk-CPS4SRPF.mjs +5 -0
  101. package/dist/{chunk-B4P2CM2J.mjs → chunk-CZ5KJSGK.mjs} +1 -1
  102. package/dist/chunk-DAMVDXR3.mjs +2 -0
  103. package/dist/{chunk-NG375ILQ.mjs → chunk-DH6GMDNN.mjs} +1 -1
  104. package/dist/chunk-DHB7UZ7F.mjs +3 -0
  105. package/dist/{chunk-MHW7ZKOU.mjs → chunk-DKR7LFIY.mjs} +1 -1
  106. package/dist/chunk-DLFZJJEE.mjs +2 -0
  107. package/dist/{chunk-6EZ7FNIK.mjs → chunk-F4ZA6JRZ.mjs} +1 -1
  108. package/dist/{chunk-6VTU6KEO.mjs → chunk-FCK6NXON.mjs} +1 -1
  109. package/dist/{chunk-ZWPMCK7P.mjs → chunk-FX42XU6J.mjs} +1 -1
  110. package/dist/chunk-FXQBADMN.mjs +5 -0
  111. package/dist/{chunk-W3BGBJQW.mjs → chunk-G4YP7GVC.mjs} +1 -1
  112. package/dist/{chunk-V6XZ4VIR.mjs → chunk-GWOYMENX.mjs} +1 -1
  113. package/dist/chunk-HATA2W7X.mjs +2 -0
  114. package/dist/{chunk-YI43RG4P.mjs → chunk-HBAUKKQH.mjs} +1 -1
  115. package/dist/{chunk-MAFIGVXY.mjs → chunk-HM4E43VM.mjs} +1 -1
  116. package/dist/{chunk-CRJEG7MT.mjs → chunk-JI6T3A4Y.mjs} +1 -1
  117. package/dist/{chunk-NFMCP2HI.mjs → chunk-JJNRIFND.mjs} +2 -2
  118. package/dist/chunk-JL6R4FG4.mjs +4 -0
  119. package/dist/{chunk-UMHUSOPJ.mjs → chunk-JXLSHVJ2.mjs} +1 -1
  120. package/dist/{chunk-FJYN7RTH.mjs → chunk-KFZBYDIS.mjs} +1 -1
  121. package/dist/{chunk-ZTHICSSF.mjs → chunk-KH24LWAT.mjs} +1 -1
  122. package/dist/{chunk-RKPWLGZ3.mjs → chunk-KUILYI7H.mjs} +1 -1
  123. package/dist/{chunk-RMECZA2K.mjs → chunk-L7W624FD.mjs} +1 -1
  124. package/dist/chunk-LE44MD3O.mjs +4 -0
  125. package/dist/{chunk-4K5KC6V2.mjs → chunk-LV24RY2E.mjs} +1 -1
  126. package/dist/{chunk-43B75J5T.mjs → chunk-MKTX5PGV.mjs} +1 -1
  127. package/dist/{chunk-LKX55H76.mjs → chunk-NAGMRVW4.mjs} +1 -1
  128. package/dist/{chunk-D4CKRD3V.mjs → chunk-NFABH3QW.mjs} +2 -2
  129. package/dist/{chunk-PVER7LSC.mjs → chunk-NIW7F7LU.mjs} +2 -2
  130. package/dist/{chunk-PAREWQGB.mjs → chunk-NWRZXELO.mjs} +1 -1
  131. package/dist/{chunk-OJKMINIU.mjs → chunk-OU3S466R.mjs} +15 -15
  132. package/dist/{chunk-5ZJA7CXT.mjs → chunk-PAFSFVYB.mjs} +1 -1
  133. package/dist/chunk-QCEATQC4.mjs +2 -0
  134. package/dist/{chunk-Y34NR5JL.mjs → chunk-QJ3TFJLQ.mjs} +1 -1
  135. package/dist/{chunk-IA4PSIMD.mjs → chunk-QK3VISCA.mjs} +1 -1
  136. package/dist/{chunk-ZUNVAXLH.mjs → chunk-QXVNUASA.mjs} +1 -1
  137. package/dist/{chunk-GRAXKKG4.mjs → chunk-QZ35UAB4.mjs} +1 -1
  138. package/dist/{chunk-UGWYKHBL.mjs → chunk-S2Y7VI4H.mjs} +2 -2
  139. package/dist/{chunk-OW5NWPOJ.mjs → chunk-SAHS56QM.mjs} +1 -1
  140. package/dist/{chunk-QOUEFUCH.mjs → chunk-SOD23RGL.mjs} +1 -1
  141. package/dist/chunk-TDWJKOLN.mjs +2 -0
  142. package/dist/{chunk-V6RIYQZZ.mjs → chunk-TOE6DPLH.mjs} +1 -1
  143. package/dist/chunk-UGO5N3EI.mjs +15 -0
  144. package/dist/{chunk-Q47PLKIJ.mjs → chunk-UGWMMEJ5.mjs} +1 -1
  145. package/dist/{chunk-NWR2LT5B.mjs → chunk-V5JRSGZF.mjs} +1 -1
  146. package/dist/{chunk-BZ5RAF7L.mjs → chunk-VA3KAQZD.mjs} +1 -1
  147. package/dist/chunk-VG5JEIUQ.mjs +12 -0
  148. package/dist/{chunk-UNOYVIYR.mjs → chunk-VGTMLQWZ.mjs} +1 -1
  149. package/dist/chunk-VKSRM7EY.mjs +22 -0
  150. package/dist/{chunk-YQGT4AB2.mjs → chunk-VNUWREXU.mjs} +1 -1
  151. package/dist/{chunk-AGDILNWB.mjs → chunk-VPVOAJ7X.mjs} +1 -1
  152. package/dist/{chunk-HLYV7RIH.mjs → chunk-WCWYNFDF.mjs} +1 -1
  153. package/dist/chunk-WTEGUPFG.mjs +16 -0
  154. package/dist/{chunk-N76HWBA3.mjs → chunk-XKOHV4H6.mjs} +1 -1
  155. package/dist/{chunk-HMYTM3GT.mjs → chunk-XMKHCUI6.mjs} +1 -1
  156. package/dist/{chunk-OUUP3WKT.mjs → chunk-XQRUG4G3.mjs} +1 -1
  157. package/dist/{chunk-32ZUEFZ7.mjs → chunk-YBB5LWZK.mjs} +1 -1
  158. package/dist/{chunk-SX4LJYT6.mjs → chunk-YFJU3O7G.mjs} +1 -1
  159. package/dist/chunk-YPPJVDQI.mjs +2 -0
  160. package/dist/chunk-ZANMKAWS.mjs +2 -0
  161. package/dist/{chunk-6QBHU4DF.mjs → chunk-ZCP7BTOZ.mjs} +1 -1
  162. package/dist/{chunk-ERLAIBOA.mjs → chunk-ZEY2RLBT.mjs} +2 -2
  163. package/dist/{chunk-SQ6Y2ZMA.mjs → chunk-ZO7SFB2E.mjs} +2 -2
  164. package/dist/cli.mjs +1 -1
  165. package/dist/server.mjs +1 -1
  166. package/dist/worker.mjs +1 -1
  167. package/kit/board.css +5 -5
  168. package/kit/code.js +15 -15
  169. package/kit/math.js +1 -1
  170. package/kit/report.css +123 -44
  171. package/kit/runtime.js +45 -7
  172. package/kit/tables.js +2 -0
  173. package/kit/ui.js +2 -0
  174. package/package.json +1 -1
  175. package/packs/gallery/chart-view/kit.js +3 -3
  176. package/packs/gallery/chart-view/writing.md +1 -1
  177. package/packs/gallery/countdown/component.json +1 -1
  178. package/packs/gallery/countdown/kit.js +89 -29
  179. package/packs/gallery/countdown/preview.svg +1 -1
  180. package/packs/gallery/countdown/style.css +88 -100
  181. package/packs/gallery/countdown/writing.md +2 -2
  182. package/packs/gallery/habit/component.json +3 -3
  183. package/packs/gallery/habit/kit.js +114 -75
  184. package/packs/gallery/habit/preview.svg +1 -1
  185. package/packs/gallery/habit/style.css +133 -205
  186. package/packs/gallery/habit/writing.md +2 -2
  187. package/packs/gallery/heatmap/component.json +2 -2
  188. package/packs/gallery/heatmap/kit.js +335 -173
  189. package/packs/gallery/heatmap/preview.svg +1 -1
  190. package/packs/gallery/heatmap/style.css +158 -170
  191. package/packs/gallery/heatmap/writing.md +2 -2
  192. package/packs/gallery/kanban/kit.js +3 -3
  193. package/packs/gallery/kanban/writing.md +1 -1
  194. package/packs/gallery/metric/kit.js +3 -3
  195. package/packs/gallery/metric/writing.md +1 -1
  196. package/packs/gallery/note/component.json +3 -3
  197. package/packs/gallery/note/kit.js +40 -13
  198. package/packs/gallery/note/preview.svg +1 -1
  199. package/packs/gallery/note/style.css +51 -30
  200. package/packs/gallery/note/writing.md +2 -2
  201. package/packs/gallery/recent/component.json +2 -2
  202. package/packs/gallery/recent/kit.js +141 -86
  203. package/packs/gallery/recent/preview.svg +1 -1
  204. package/packs/gallery/recent/style.css +53 -126
  205. package/packs/gallery/recent/writing.md +2 -2
  206. package/packs/gallery/static/component.json +2 -2
  207. package/packs/gallery/static/preview.svg +1 -1
  208. package/packs/gallery/static/style.css +99 -66
  209. package/packs/gallery/static/writing.md +2 -2
  210. package/packs/gallery/stats/component.json +3 -3
  211. package/packs/gallery/stats/kit.js +253 -72
  212. package/packs/gallery/stats/preview.svg +1 -1
  213. package/packs/gallery/stats/style.css +64 -142
  214. package/packs/gallery/stats/writing.md +2 -2
  215. package/packs/gallery/today/component.json +2 -2
  216. package/packs/gallery/today/kit.js +62 -27
  217. package/packs/gallery/today/preview.svg +1 -1
  218. package/packs/gallery/today/style.css +101 -72
  219. package/packs/gallery/today/writing.md +2 -2
  220. package/packs/gallery/todos/component.json +1 -1
  221. package/packs/gallery/todos/kit.js +218 -71
  222. package/packs/gallery/todos/preview.svg +1 -1
  223. package/packs/gallery/todos/style.css +170 -223
  224. package/packs/gallery/todos/writing.md +1 -1
  225. package/packs/gallery/weather/component.json +2 -2
  226. package/packs/gallery/weather/kit.js +165 -90
  227. package/packs/gallery/weather/preview.svg +1 -1
  228. package/packs/gallery/weather/style.css +100 -218
  229. package/packs/gallery/weather/writing.md +1 -1
  230. package/packs/gallery-soft/countdown/component.json +18 -0
  231. package/packs/gallery-soft/countdown/example.html +3 -0
  232. package/packs/gallery-soft/countdown/kit.js +206 -0
  233. package/packs/gallery-soft/countdown/preview.svg +1 -0
  234. package/packs/gallery-soft/countdown/style.css +211 -0
  235. package/packs/gallery-soft/countdown/template.html +3 -0
  236. package/packs/gallery-soft/countdown/writing.md +24 -0
  237. package/packs/gallery-soft/habit/component.json +14 -0
  238. package/packs/gallery-soft/habit/example.html +3 -0
  239. package/packs/gallery-soft/habit/kit.js +366 -0
  240. package/packs/gallery-soft/habit/preview.svg +1 -0
  241. package/packs/gallery-soft/habit/style.css +251 -0
  242. package/packs/gallery-soft/habit/template.html +3 -0
  243. package/packs/gallery-soft/habit/writing.md +23 -0
  244. package/packs/gallery-soft/heatmap/component.json +18 -0
  245. package/packs/gallery-soft/heatmap/example.html +3 -0
  246. package/packs/gallery-soft/heatmap/kit.js +498 -0
  247. package/packs/gallery-soft/heatmap/preview.svg +1 -0
  248. package/packs/gallery-soft/heatmap/style.css +181 -0
  249. package/packs/gallery-soft/heatmap/template.html +3 -0
  250. package/packs/gallery-soft/heatmap/writing.md +23 -0
  251. package/packs/gallery-soft/note/component.json +14 -0
  252. package/packs/gallery-soft/note/example.html +3 -0
  253. package/packs/gallery-soft/note/kit.js +162 -0
  254. package/packs/gallery-soft/note/preview.svg +1 -0
  255. package/packs/gallery-soft/note/style.css +148 -0
  256. package/packs/gallery-soft/note/template.html +3 -0
  257. package/packs/gallery-soft/note/writing.md +20 -0
  258. package/packs/gallery-soft/recent/component.json +13 -0
  259. package/packs/gallery-soft/recent/example.html +1 -0
  260. package/packs/gallery-soft/recent/kit.js +335 -0
  261. package/packs/gallery-soft/recent/preview.svg +1 -0
  262. package/packs/gallery-soft/recent/style.css +160 -0
  263. package/packs/gallery-soft/recent/template.html +1 -0
  264. package/packs/gallery-soft/recent/writing.md +17 -0
  265. package/packs/gallery-soft/static/component.json +13 -0
  266. package/packs/gallery-soft/static/example.html +12 -0
  267. package/packs/gallery-soft/static/preview.svg +1 -0
  268. package/packs/gallery-soft/static/style.css +186 -0
  269. package/packs/gallery-soft/static/template.html +1 -0
  270. package/packs/gallery-soft/static/writing.md +20 -0
  271. package/packs/gallery-soft/stats/component.json +13 -0
  272. package/packs/gallery-soft/stats/example.html +1 -0
  273. package/packs/gallery-soft/stats/kit.js +341 -0
  274. package/packs/gallery-soft/stats/preview.svg +1 -0
  275. package/packs/gallery-soft/stats/style.css +119 -0
  276. package/packs/gallery-soft/stats/template.html +1 -0
  277. package/packs/gallery-soft/stats/writing.md +13 -0
  278. package/packs/gallery-soft/today/component.json +12 -0
  279. package/packs/gallery-soft/today/example.html +1 -0
  280. package/packs/gallery-soft/today/kit.js +222 -0
  281. package/packs/gallery-soft/today/preview.svg +1 -0
  282. package/packs/gallery-soft/today/style.css +178 -0
  283. package/packs/gallery-soft/today/template.html +1 -0
  284. package/packs/gallery-soft/today/writing.md +16 -0
  285. package/packs/gallery-soft/todos/component.json +19 -0
  286. package/packs/gallery-soft/todos/example.html +3 -0
  287. package/packs/gallery-soft/todos/kit.js +527 -0
  288. package/packs/gallery-soft/todos/preview.svg +1 -0
  289. package/packs/gallery-soft/todos/style.css +212 -0
  290. package/packs/gallery-soft/todos/template.html +3 -0
  291. package/packs/gallery-soft/todos/writing.md +32 -0
  292. package/packs/gallery-soft/weather/component.json +19 -0
  293. package/packs/gallery-soft/weather/example.html +3 -0
  294. package/packs/gallery-soft/weather/kit.js +411 -0
  295. package/packs/gallery-soft/weather/preview.svg +1 -0
  296. package/packs/gallery-soft/weather/style.css +185 -0
  297. package/packs/gallery-soft/weather/template.html +3 -0
  298. package/packs/gallery-soft/weather/writing.md +28 -0
  299. package/release.json +10 -10
  300. package/skill/SKILL.md +15 -14
  301. package/skill/references/building-blocks.md +4 -4
  302. package/skill/references/extensions.md +11 -7
  303. package/skill/references/pages-and-data.md +13 -9
  304. package/skill/references/writing-html.md +2 -0
  305. package/web/assets/index-BHC5ZOMh.js +15 -0
  306. package/web/assets/index-xP0uw3a0.css +1 -0
  307. package/web/index.html +2 -2
  308. package/dist/chunk-2NRBY6AJ.mjs +0 -2
  309. package/dist/chunk-35NQ4PLQ.mjs +0 -2
  310. package/dist/chunk-3KJHLHUO.mjs +0 -2
  311. package/dist/chunk-4AV456RQ.mjs +0 -2
  312. package/dist/chunk-5XYHDBJ5.mjs +0 -2
  313. package/dist/chunk-6A53MZYZ.mjs +0 -2
  314. package/dist/chunk-6EXH3ORZ.mjs +0 -166
  315. package/dist/chunk-BVEFGE4B.mjs +0 -2
  316. package/dist/chunk-D4EURAX4.mjs +0 -4
  317. package/dist/chunk-DQCE7TJY.mjs +0 -5
  318. package/dist/chunk-FWNRPMCJ.mjs +0 -12
  319. package/dist/chunk-FWW4CSAZ.mjs +0 -2
  320. package/dist/chunk-GY3FAUVM.mjs +0 -2
  321. package/dist/chunk-JVHHHGEA.mjs +0 -3
  322. package/dist/chunk-L7UP52JO.mjs +0 -2
  323. package/dist/chunk-NAMN3RAF.mjs +0 -2
  324. package/dist/chunk-PZDLJJTJ.mjs +0 -3
  325. package/dist/chunk-SXHBYZST.mjs +0 -16
  326. package/dist/chunk-TEZAWDSQ.mjs +0 -2
  327. package/dist/chunk-UFNYFFKO.mjs +0 -20
  328. package/dist/chunk-UKSHDZZ6.mjs +0 -2
  329. package/dist/chunk-VJPFVNNW.mjs +0 -15
  330. package/dist/chunk-VS3ZMVGX.mjs +0 -5
  331. package/web/assets/index-BK2e_07w.js +0 -13
  332. package/web/assets/index-CWFI83mF.css +0 -1
  333. /package/dist/{chunk-YEY3RSFQ.mjs → chunk-5MMN3N5J.mjs} +0 -0
  334. /package/dist/{chunk-UH4SIXTR.mjs → chunk-74UW7QSL.mjs} +0 -0
  335. /package/dist/{chunk-W7XHE4CT.mjs → chunk-EKGYYOSP.mjs} +0 -0
  336. /package/dist/{chunk-QAIHRH3I.mjs → chunk-KNZJT4ET.mjs} +0 -0
  337. /package/dist/{chunk-A55HN5OK.mjs → chunk-N3DSBH5S.mjs} +0 -0
  338. /package/dist/{chunk-QR6A54KJ.mjs → chunk-ZW2A6GBW.mjs} +0 -0
@@ -0,0 +1,92 @@
1
+ // Pinyin as the "/" menu looks for a block by it (docs/editor.md, "In the menus"; the built-in blocks
2
+ // list their words in registry.mjs: 公式 is gongshi gs). A custom block's words are its manifest's, so
3
+ // that an author writes the pinyin of the whole name there (the check notes a name no word spells:
4
+ // cli/component-check.mjs wantsPinyin); the initials ("djs" for 倒计时, "daojishi") are not asked of
5
+ // anyone: they are made here, from a word that reads as pinyin and from the name itself.
6
+
7
+ // A syllable of pinyin, no tones: an initial or none, then a final. A word that can be read as pinyin
8
+ // is syllables one after another.
9
+ const SYLLABLE = "(?:(?:[zcs]h|[bpmfdtnlgkhjqxrzcsyw])?(?:[iuv]?(?:a(?:i|o|ng?)?|e(?:i|r|ng?)?|o(?:u|ng)?)|i(?:u|ng?)?|u(?:i|n)?|vn?))";
10
+ const ONE_SYLLABLE = new RegExp(`^${SYLLABLE}$`, "i");
11
+ const LONGEST_SYLLABLE = 6; // zhuang
12
+ const HAN = /\p{Script=Han}/u;
13
+
14
+ /**
15
+ * The syllables `word` reads as, fewest first, its apostrophes left out as an input method leaves
16
+ * them, or null for a word that is none. The fewest, since single finals read a word as more syllables
17
+ * than an input method composes it of (fenbiao as fen-bi-a-o, composed fen-biao).
18
+ */
19
+ export function syllablesOf(word) {
20
+ const letters = word.replaceAll("'", "");
21
+ const fewest = [0, ...Array(letters.length).fill(Infinity)];
22
+ const from = Array(letters.length + 1).fill(0);
23
+ for (let end = 1; end <= letters.length; end++) {
24
+ for (let start = Math.max(0, end - LONGEST_SYLLABLE); start < end; start++) {
25
+ if (fewest[start] + 1 < fewest[end] && ONE_SYLLABLE.test(letters.slice(start, end))) {
26
+ fewest[end] = fewest[start] + 1;
27
+ from[end] = start;
28
+ }
29
+ }
30
+ }
31
+ if (!letters || !Number.isFinite(fewest[letters.length])) return null;
32
+ const syllables = [];
33
+ for (let end = letters.length; end > 0; end = from[end]) syllables.unshift(letters.slice(from[end], end));
34
+ return syllables;
35
+ }
36
+
37
+ /** The fewest syllables of pinyin `word` reads as, or null for a word that is none. */
38
+ export const fewestSyllables = (word) => syllablesOf(word)?.length ?? null;
39
+
40
+ /** The first letters of the syllables of a word of pinyin ("daojishi" is "djs"), or null for a word that is none or one syllable. */
41
+ export function initialsOfWord(word) {
42
+ const syllables = syllablesOf(word.toLowerCase());
43
+ return syllables && syllables.length > 1 ? syllables.map((syllable) => syllable[0]).join("") : null;
44
+ }
45
+
46
+ // The characters that open each letter's run in the pinyin order of the platform's collation (阿 a, 八 b …
47
+ // 帀 z: no run for i, u or v), the classic way to find the first letter of a character's reading without a
48
+ // table. Known only where the platform's collation sorts Chinese by pinyin, which it is asked once.
49
+ const OPENERS = [..."阿八嚓哒妸发旮哈讥咔垃妈拿噢妑七呥仨他屲夕丫帀"];
50
+ const LETTERS = [..."abcdefghjklmnopqrstwxyz"];
51
+ let collator;
52
+
53
+ function sorted() {
54
+ if (collator !== undefined) return collator;
55
+ try {
56
+ const found = new Intl.Collator("zh-CN");
57
+ collator = OPENERS.every((each, at) => at === 0 || found.compare(OPENERS[at - 1], each) < 0) && found.compare("计", "时") < 0 ? found : null;
58
+ } catch {
59
+ collator = null;
60
+ }
61
+ return collator;
62
+ }
63
+
64
+ /** The first letter of a Chinese character's pinyin (its commonest reading), or null. */
65
+ function initialOf(character) {
66
+ const found = sorted();
67
+ if (!found || !HAN.test(character)) return null;
68
+ let letter = null;
69
+ for (let at = 0; at < OPENERS.length && found.compare(character, OPENERS[at]) >= 0; at++) letter = LETTERS[at];
70
+ return letter;
71
+ }
72
+
73
+ /** The initials of a name: a Chinese character's first letter of pinyin, a letter or digit as it is ("倒计时" is "djs"), none where the platform cannot tell. */
74
+ export function initialsOfName(name) {
75
+ let initials = "";
76
+ for (const character of name) {
77
+ const letter = initialOf(character) ?? (/[a-z0-9]/i.test(character) ? character.toLowerCase() : null);
78
+ if (letter) initials += letter;
79
+ }
80
+ return initials.length > 1 ? initials : "";
81
+ }
82
+
83
+ /**
84
+ * What "/" matches a custom block by (slash-menu matchScore: each word whole, or by its start): its names,
85
+ * its id and the manifest's words, then the initials of the name and of every word that reads as pinyin,
86
+ * so that 倒计时 is found by djs as 公式 is by gs.
87
+ */
88
+ export function searchWords({ name, id, words }) {
89
+ const given = `${name.zh} ${name.en} ${id} ${words}`.toLowerCase();
90
+ const initials = [initialsOfName(name.zh), ...words.split(/\s+/).filter(Boolean).map(initialsOfWord)].filter(Boolean);
91
+ return [given, ...new Set(initials)].join(" ");
92
+ }
@@ -0,0 +1,17 @@
1
+ // 演示视图 (the workbench's, src/workbench/app/features/present/): the controls the page keeps its keys for (a field to
2
+ // type in, an editable text, a block's instance: the reader's keys in them are theirs, Esc alone is the presentation's, unless the
3
+ // control used it), and 上一节 / 下一节, which the presentation does on a page of its own origin and a draft's page does itself
4
+ // (src/editor/page/present-shell.mjs), for the presentation cannot reach into a page of another origin.
5
+
6
+ export const KEEPS_KEYS = 'input:not([type="checkbox"], [type="radio"], [type="button"], [type="submit"], [type="reset"], [type="file"], [type="color"]), textarea, select, [contenteditable]:not([contenteditable="false"]), [data-doc-component]';
7
+
8
+ /**
9
+ * The report in window `win` scrolled to the next section (`direction` 1) or the one before (-1): the visible h2 and h1 of its main,
10
+ * placed 24px below the window's top; at the last, the page's end, at the first, its top.
11
+ */
12
+ export function stepSection(win, direction) {
13
+ const doc = win.document;
14
+ const tops = [...doc.querySelectorAll("main h2, main h1")].filter((node) => node.getClientRects().length).map((node) => node.getBoundingClientRect().top - 24);
15
+ const target = direction > 0 ? tops.find((top) => top > 4) : tops.filter((top) => top < -4).pop();
16
+ win.scrollTo({ top: target === undefined ? (direction > 0 ? doc.documentElement.scrollHeight : 0) : win.scrollY + target, behavior: "smooth" });
17
+ }
@@ -0,0 +1,70 @@
1
+ // The sidebar's head rows (docs/workbench.md "The sidebar", **Head**; the user's word of 2026-11-09):
2
+ // 新建, 搜索 and each custom page, one list the reader orders by dragging its rows (no row goes into
3
+ // another, none into the tree, no document among them), kept for the workspace in the outline file
4
+ // (.gallery/outline.json's `head`, which ./outline.mjs keeps as it writes the tree, so that every browser
5
+ // shows the order the reader gave). A row's key: "new" (新建), "search" (搜索), or "@<slug>" for a custom
6
+ // page (its address in the workbench, which no slug holds). Pure: the server's (shared/pages.mjs listPages,
7
+ // the workbench service's head) and the workbench's (its sidebar) alike.
8
+
9
+ /** The key of the head's 新建 row. */
10
+ export const HEAD_NEW = "new";
11
+ /** The key of the head's 搜索 row. */
12
+ export const HEAD_SEARCH = "search";
13
+ /** The key of custom page `slug`'s row: @<slug>. */
14
+ export const pageHeadKey = (slug) => `@${slug}`;
15
+ /** The custom page a head key names, or null (new, search). */
16
+ export const headPage = (key) => (typeof key === "string" && key.startsWith("@") ? key.slice(1) : null);
17
+ /** How many keys a stored head keeps at most (those of pages gone stay, so that one restored goes back to its place). */
18
+ export const MOST_HEAD = 200;
19
+
20
+ const KEY = /^(?:new|search|@[a-z0-9]+(?:-[a-z0-9]+)*)$/;
21
+
22
+ /**
23
+ * `value` as a head to store: an array of keys (new, search, @<slug>), each once, MOST_HEAD at most; null
24
+ * for anything else (not an array, a key that is none, one twice, too many).
25
+ */
26
+ export function storedHead(value) {
27
+ if (!Array.isArray(value) || value.length > MOST_HEAD) return null;
28
+ if (!value.every((key) => typeof key === "string" && KEY.test(key))) return null;
29
+ return new Set(value).size === value.length ? [...value] : null;
30
+ }
31
+
32
+ /**
33
+ * The head's rows in their order: the keys `stored` (a head as the outline file keeps it, or null) gives,
34
+ * those of pages that are not there passed over, then what it does not name: 新建 first and 搜索 after it
35
+ * where it names neither (as before any drag), and each page of `pages` (their slugs, in the order a page
36
+ * goes by when the reader gave it none: shared/pages.mjs inPageOrder) after the last row it names, in that
37
+ * order. Always holds new and search once each, and each page of `pages` once.
38
+ */
39
+ export function headOrder(stored, pages = []) {
40
+ const there = new Set(pages);
41
+ const named = (storedHead(stored) ?? []).filter((key) => key === HEAD_NEW || key === HEAD_SEARCH || there.has(headPage(key)));
42
+ if (!named.includes(HEAD_SEARCH)) named.unshift(HEAD_SEARCH);
43
+ if (!named.includes(HEAD_NEW)) named.splice(named.indexOf(HEAD_SEARCH), 0, HEAD_NEW);
44
+ for (const slug of pages) if (!named.includes(pageHeadKey(slug))) named.push(pageHeadKey(slug));
45
+ return named;
46
+ }
47
+
48
+ /**
49
+ * The head with the row `key` moved before the row `before` (null: last), the others as they were: what a
50
+ * drop on the head makes. Unchanged where `key` is not in it or is `before`.
51
+ */
52
+ export function movedInHead(head, key, before) {
53
+ if (!head.includes(key) || key === before) return [...head];
54
+ const rest = head.filter((one) => one !== key);
55
+ const at = before === null ? rest.length : rest.indexOf(before);
56
+ rest.splice(at < 0 ? rest.length : at, 0, key);
57
+ return rest;
58
+ }
59
+
60
+ /**
61
+ * The stored head `stored` (or null, when none is kept yet: `shown`, the head as the sidebar shows it now,
62
+ * stands for it) with page `slug`'s row put right after the row of `after` (a page's slug), else last: a
63
+ * new page's place. Keys of pages gone are kept where they stand.
64
+ */
65
+ export function headWithPage(stored, shown, slug, after = null) {
66
+ const head = (storedHead(stored) ?? storedHead(shown) ?? [HEAD_NEW, HEAD_SEARCH]).filter((key) => key !== pageHeadKey(slug));
67
+ const at = after ? head.indexOf(pageHeadKey(after)) : -1;
68
+ head.splice(at < 0 ? head.length : at + 1, 0, pageHeadKey(slug));
69
+ return head.slice(-MOST_HEAD);
70
+ }
@@ -37,6 +37,11 @@ export function isSiteIcon(value) {
37
37
  */
38
38
  export const WEB_SANDBOX = "allow-scripts allow-popups allow-top-navigation-by-user-activation allow-forms allow-same-origin allow-storage-access-by-user-activation allow-popups-to-escape-sandbox";
39
39
 
40
+ /** Login/error headings are not document names (also used for browser-provided clipboard titles). */
41
+ export function loginTitle(title) {
42
+ return /(?:^|[|·—–-]\s*)(?:钉钉)?统一身份认证\s*$|^(?:(?:登录|登入|sign[ -]?in|log[ -]?in)(?:$|\s*(?:[|·—–-]|to\b))|(?:401|403)(?:\s|$)|unauthorized|access denied|forbidden|无权访问|访问受限)|(?:[|·—–-]\s*)(?:登录|登入|sign[ -]?in|log[ -]?in)\s*$/i.test(title);
43
+ }
44
+
40
45
  const tidy = (value) => (typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "");
41
46
 
42
47
  /**
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { iconKind } from "./emoji/icon-value.mjs";
4
4
  import { isWorkspace, readRegistry, workspaceId, workspaceKey } from "./workspace-registry.mjs";
5
- import { defaultWorkspace, documentFiles, isSlugName } from "./workspace.mjs";
5
+ import { defaultWorkspace, documentFiles, isSlugName, readLink } from "./workspace.mjs";
6
6
 
7
7
  // The other workspaces a workspace's sidebar shows a column of (notes/plans/workspaces-links-plan-2026-11-08.md
8
8
  // §7.2; docs/workbench.md "Columns"): every workspace of the machine's registry (./workspace-registry.mjs) but
@@ -13,8 +13,8 @@ import { defaultWorkspace, documentFiles, isSlugName } from "./workspace.mjs";
13
13
  // as its own sidebar has them) and the place of its documents no column holds; the user's order of the
14
14
  // columns is the outline's after that.
15
15
  //
16
- // What a workspace's sidebar is read with (snapshotOf): its documents in its own sidebar's order, the document
17
- // each is under there (a web link or another workspace's draft passed over upward), and what its doc.json
16
+ // What a workspace's sidebar is read with (snapshotOf): its documents and links in its former local order,
17
+ // their same-workspace parents, and what their doc.json or link.json
18
18
  // says (title, description, an icon of the emoji or 图标 kind: no picture of another workspace's folder). It is
19
19
  // read from its files, never written, and kept SNAPSHOT_KEPT ms at most, so that the reads of a burst (a
20
20
  // command and the workbench's read after it, the list of 添加其他 Gallery 项目…) read each folder once while a
@@ -90,19 +90,19 @@ async function read(root, readOwn) {
90
90
  const documents = new Set();
91
91
  const order = [];
92
92
  const parentOf = new Map();
93
- // Its documents alone: its web links, the drafts of others its tree shows and a folder named by no slug are none.
94
- const isDocument = (key) => !own.links.includes(key) && !key.startsWith("~") && isSlugName(key);
93
+ // Own documents and links; another workspace's reference is not a second file here.
94
+ const isEntry = (key) => !key.startsWith("~") && isSlugName(key);
95
95
  const parentIn = (child) => {
96
96
  for (const [key, list] of Object.entries(own.children)) if (list.includes(child)) return key;
97
97
  return null;
98
98
  };
99
99
  const above = (slug) => {
100
100
  let up = parentIn(slug);
101
- while (up !== null && !(up === "" || up.startsWith(":")) && !isDocument(up)) up = parentIn(up);
101
+ while (up !== null && !(up === "" || up.startsWith(":")) && !isEntry(up)) up = parentIn(up);
102
102
  return up === null || up === "" || up.startsWith(":") ? null : up;
103
103
  };
104
104
  const walk = (key) => (own.children[key] ?? []).forEach((slug) => {
105
- if (isDocument(slug) && !documents.has(slug)) {
105
+ if (isEntry(slug) && !documents.has(slug)) {
106
106
  documents.add(slug);
107
107
  order.push(slug);
108
108
  parentOf.set(slug, above(slug));
@@ -111,6 +111,10 @@ async function read(root, readOwn) {
111
111
  });
112
112
  for (const { id } of own.groups) walk(id === "docs" ? "" : `:${id}`);
113
113
  const facts = new Map(await Promise.all(order.map(async (slug) => {
114
+ if (own.links.includes(slug)) {
115
+ const link = await readLink(path.join(root, slug));
116
+ return [slug, { ...link, kind: "link", title: link?.title ?? slug, description: "", path: path.join(root, slug, "link.json") }];
117
+ }
114
118
  const files = documentFiles(path.join(root, slug));
115
119
  const metadata = await fs.readFile(files.json, "utf8").then((text) => JSON.parse(text.replace(/^/, "")), () => null);
116
120
  const value = metadata && typeof metadata === "object" && !Array.isArray(metadata) ? metadata : {};
@@ -204,19 +204,23 @@ remove moves it to the trash, which the workbench's \u8BBE\u7F6E \u203A \u56DE\u
204
204
  Each is written through the workspace's running server when there is one (an open workbench shows it
205
205
  at once), else here.
206
206
  Exits 1 when a link, a column or an entry named is not there or the server refuses it; 2 for an
207
- address that is not http or https, an empty name, or two places at once.`,extension:`Usage: gallery extension list
207
+ address that is not http or https, an empty name, or two places at once.`,extension:`Usage: gallery extension new <id> "<title>" [--local]
208
+ gallery extension list
208
209
  gallery extension check <id>
209
210
  An extension (\u6269\u5C55) gives the sidebar a column of entries of its own, beside \u6587\u6863: a folder
210
211
  <workspace>/extensions/<id>/ whose sidebar.json lists them (a title, an optional icon, and entries each with
211
212
  an id, a title, an optional address (http or https), an optional icon and optional children). The workbench
212
213
  reads the file again within a second of every change; a click on an entry with an address opens that page beside
213
214
  the sidebar (as a web link's), one without opens and closes what is under it. The user may drag the column to
214
- another place; its entries are the extension's, never dragged, renamed or removed. A file that does not read
215
- shows the column with one row, \u6761\u76EE\u8BFB\u4E0D\u51FA\u6765\uFF1A<why>. Gallery only reads these files: the extension writes them
216
- (references/extensions.md in the skill says how).
217
- list prints each extension of the workspace (extensions/<id>/): its column's title and how many entries it
218
- holds, or why it shows none.
219
- check <id> reads extensions/<id>/sidebar.json as the sidebar does and prints what the sidebar will show:
215
+ another place, rename it and reorder its root entries; title/order edits write back to sidebar.json.
216
+ A file that does not read shows the column with one row, \u6761\u76EE\u8BFB\u4E0D\u51FA\u6765\uFF1A<why>.
217
+ new creates an empty sidebar.json in the DEFAULT workspace, shared by every project's sidebar. Add --local
218
+ to create it only in the selected workspace (--workspace still selects the project). Existing files are never
219
+ overwritten. Read the printed file and fill its entries (references/extensions.md in the skill says how).
220
+ Every sidebar reads the default workspace's extensions plus its own. A project sidebar.json with the same id
221
+ takes precedence in that project; an empty folder does not. No files are copied or moved automatically.
222
+ list prints the visible extensions, their source paths, titles and entry counts, or why they show none.
223
+ check <id> resolves the same public/project source as the sidebar and prints what the sidebar will show:
220
224
  the column, then each entry with its id, title and address, one under another indented; notes (an icon that
221
225
  is no emoji and no icon of the \u56FE\u6807 tab, which is left out) follow. Writes nothing.
222
226
  Exits 0 when the file reads; 1 when the extension is not there, has no sidebar.json or its file does not
@@ -394,22 +398,23 @@ Exits 2 for a host no block's needs can name, or a key that is empty or more tha
394
398
  gallery page try <slug> <card id> --select <selector> <value> [--then <key>] [--keep]
395
399
  gallery page try <slug> <card id> --steps <file> [--keep]
396
400
  gallery page check <slug>
397
- A custom page (\u81EA\u5B9A\u4E49\u9875) is a board of cards the workbench lists in its sidebar under \u65B0\u5EFA and \u641C\u7D22, kept in
398
- the workspace: pages/<slug>/, page.html (its look and its boards, each card one custom block's instance)
399
- and page.json ({ "title", "icon" }). Only an Agent makes one; the user moves, renames and trashes them.
401
+ A custom page (\u81EA\u5B9A\u4E49\u9875) is a page the workbench lists in its sidebar with \u65B0\u5EFA and \u641C\u7D22, kept in the
402
+ workspace: pages/<slug>/, page.html (free HTML: its look, its own scripts, and boards of cards, each card
403
+ one custom block's instance, where it has them) and page.json ({ "title", "icon" }). An Agent writes them
404
+ (the user may make a blank one for an Agent to write); the user orders, renames and trashes them.
400
405
  Documents and custom pages share one set of slugs: neither takes the other's, nor pages (the folder).
401
- The home page (\u9996\u9875) is pages/home, listed first.
406
+ The home page (\u9996\u9875) is pages/home, a page as any.
402
407
  new makes one: page.html with its title (in <title>: a page draws no big title) and one empty board (data-board-id="main"), and
403
- page.json with the title. A page writes no script: the server puts in the scripts and styles of the
404
- blocks its cards hold. Says where it wrote and what to write next, and with the workspace's server
408
+ page.json with the title; it goes last in the sidebar's head. The server puts in the scripts and styles
409
+ of the blocks its cards hold. Says where it wrote and what to write next, and with the workspace's server
405
410
  running ends with the \u4EA4\u7ED9\u7528\u6237 line gallery open has: the page's whole address, to send the user at once
406
411
  (without one, gallery page open <slug> --no-browser gives it).
407
412
  Exits 1 when the slug is taken (a document's, a page's, the trash's) or kept (exports, components, pages,
408
- assets, materials\u2026), or is home while the home page waits for the server's first start in the workspace
409
- (a server makes it, with its own cards; gallery open --no-browser starts one: said alone, as gallery page
410
- open, add, try and check of home say it in place of "no such page").
411
- list says the workspace's custom pages in the sidebar's order (home first, then gallery.json's
412
- pages.order, then by title): each one's slug, icon and title, its address (\u5730\u5740\uFF1A, the whole address with
413
+ assets, materials\u2026). Before the server's first start in the workspace makes the default home page (with
414
+ its own cards; gallery open --no-browser starts one), gallery page open, add, try and check of home say
415
+ so in place of "no such page".
416
+ list says the workspace's custom pages in the sidebar's order (the order the user dragged them to, then
417
+ gallery.json's pages.order, then by title): each one's slug, icon and title, its address (\u5730\u5740\uFF1A, the whole address with
413
418
  the workspace's server running, else /#@<slug>, after the port of a server) and where its page.html is;
414
419
  in a workspace with no page whose home page is not made yet, only that the home page waits for the server.
415
420
  open starts this workspace's Gallery server (or uses the one running), as gallery open does, and opens
@@ -466,17 +471,17 @@ document's alone; 2 a mistake in the command line (a card the page has not, a se
466
471
  nothing in the instance, a steps file that does not read); 3 when the trial was not seen through
467
472
  (UNVERIFIED: no server or browser, a page that loaded itself again).
468
473
  check says what is wrong with the page, each problem a FAIL line with its line in page.html, and what
469
- changed in it. Its structure: no script of its own (a <script> that runs, an on\u2026 attribute, a
470
- javascript: address), its boards in <main class="gallery-page">, each board's data-board-id and each
474
+ changed in it. Its structure (a page's own scripts, frames and stylesheets are none of its problems):
475
+ where it has boards or cards, its boards in <main class="gallery-page">, each board's data-board-id and each
471
476
  card's data-card-id there, of lowercase letters, digits and hyphens, and once in the page, each card a
472
477
  board's child holding one instance, its data-x, data-y, data-w and data-h whole numbers on the board
473
478
  (0 <= x, 1 <= w <= 12, x + w <= 12, 0 <= y, 1 <= h <= 24) and sharing a cell with no other card of its
474
479
  board, its block in the workspace, loading, not turned off and with page in its places; and each file of
475
480
  the page's own named (assets/<file>: the folder pages/<slug>/assets/, which the server serves at
476
- /pages/<slug>/assets/<file>) there, and neither a stylesheet nor a frame's (the server serves a page's
477
- own pictures by their type and any other file as bytes for saving: a stylesheet of assets/ is never
478
- applied and a frame of a file there downloads it, while a link, a font, a video or audio uses the bytes),
479
- a picture or stylesheet written relative any other way being one nothing serves. Then the cards with their ids and cells, and the changes since the page as
481
+ /pages/<slug>/assets/<file>) there, and no frame's but a picture's (the server serves a page's own
482
+ pictures by their type, its stylesheets and scripts as such, and any other file as bytes for saving: a
483
+ frame of a file there downloads it, while a link, a font, a video or audio uses the bytes), a picture,
484
+ stylesheet or script written relative any other way being one nothing serves. Then the cards with their ids and cells, and the changes since the page as
480
485
  the last check that found nothing saw it (or, before any, since the version the page service kept before
481
486
  its last write): cards added, removed, moved (to another board too), resized, their data parts changed
482
487
  (with the lines), a card's own markup, the page's own HTML; each change the page wrote since, a gesture
@@ -0,0 +1,2 @@
1
+ import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
+ import{constants as G}from"node:buffer";import E from"node:fs";import{Transform as H}from"node:stream";import{pipeline as P}from"node:stream/promises";import b from"node:zlib";import{refusal as k,said as M}from"../browser/shared/i18n/index.mjs";var A=67324752,Z=33639248,F=101010256,W=101075792,X=117853008,U=4294967295,T=2048;function v(t=new Date){let o=t.getHours()<<11|t.getMinutes()<<5|Math.floor(t.getSeconds()/2),e=Math.max(1980,t.getFullYear())-1980<<9|t.getMonth()+1<<5|t.getDate();return[o,e]}function tt(t){let[o,e]=v(),c=[],h=[],n=0;for(let a of t){let s=Buffer.isBuffer(a.data)?a.data:Buffer.from(a.data??"","utf8"),r=Buffer.from(a.name,"utf8"),u=s.length>64?b.deflateRawSync(s):null,w=u&&u.length<s.length?u:s,L=w===s?0:8,g=b.crc32(s);if(s.length>=U||n>=U)throw new Error("\u538B\u7F29\u5305\u592A\u5927\uFF08\u8D85\u8FC7 4GB\uFF09");let l=Buffer.alloc(30);l.writeUInt32LE(A,0),l.writeUInt16LE(20,4),l.writeUInt16LE(T,6),l.writeUInt16LE(L,8),l.writeUInt16LE(o,10),l.writeUInt16LE(e,12),l.writeUInt32LE(g,14),l.writeUInt32LE(w.length,18),l.writeUInt32LE(s.length,22),l.writeUInt16LE(r.length,26),l.writeUInt16LE(0,28);let d=Buffer.alloc(46);d.writeUInt32LE(Z,0),d.writeUInt16LE(20,4),d.writeUInt16LE(20,6),d.writeUInt16LE(T,8),d.writeUInt16LE(L,10),d.writeUInt16LE(o,12),d.writeUInt16LE(e,14),d.writeUInt32LE(g,16),d.writeUInt32LE(w.length,20),d.writeUInt32LE(s.length,24),d.writeUInt16LE(r.length,28),d.writeUInt32LE(n,42),c.push(l,r,w),h.push(d,r),n+=l.length+r.length+w.length}if(t.length>=65535)throw new Error("\u538B\u7F29\u5305\u91CC\u7684\u6587\u4EF6\u592A\u591A");let i=Buffer.concat(h),f=Buffer.alloc(22);return f.writeUInt32LE(F,0),f.writeUInt16LE(t.length,8),f.writeUInt16LE(t.length,10),f.writeUInt32LE(i.length,12),f.writeUInt32LE(n,16),Buffer.concat([...c,i,f])}var Y=new TextDecoder("utf-8",{fatal:!0}),j=new TextDecoder("gbk");function q(t,o){if(o&T)return t.toString("utf8");try{return Y.decode(t)}catch{return j.decode(t)}}var et=t=>t.length>=4&&t.readUInt32LE(0)===A,m=()=>new Error("ZIP \u6587\u4EF6\u5DF2\u635F\u574F"),I=(t,o)=>Number(t.readBigUInt64LE(o));function N(t,o){let e=Math.min(o,65557),c=t(o-e,e),h=-1;for(let r=c.length-22;r>=0;r-=1)if(c.readUInt32LE(r)===F){h=r;break}if(h<0)throw new Error("\u4E0D\u662F\u6709\u6548\u7684 ZIP \u6587\u4EF6");let n=c.readUInt16LE(h+10),i=c.readUInt32LE(h+12),f=c.readUInt32LE(h+16);if(n===65535||i===U||f===U){let r=t(o-e+h-20,20);if(r.readUInt32LE(0)!==X)throw m();let u=t(I(r,8),56);if(u.readUInt32LE(0)!==W)throw m();n=I(u,32),i=I(u,40),f=I(u,48)}let a=t(f,i),s=[];for(let r=0,u=0;u<n;u+=1){if(a.readUInt32LE(r)!==Z)throw m();let w=a.readUInt16LE(r+8),L=a.readUInt16LE(r+10),g=a.readUInt32LE(r+20),l=a.readUInt32LE(r+24),d=a.readUInt16LE(r+28),D=a.readUInt16LE(r+30),_=a.readUInt16LE(r+32),R=a.readUInt32LE(r+42),B=q(a.subarray(r+46,r+46+d),w),p=a.subarray(r+46+d,r+46+d+D);for(let x=0;x+4<=p.length;x+=4+p.readUInt16LE(x+2)){if(p.readUInt16LE(x)!==1)continue;let z=x+4;l===U&&(l=I(p,z),z+=8),g===U&&(g=I(p,z),z+=8),R===U&&(R=I(p,z))}if(r+=46+d+D+_,!B.endsWith("/")){if(w&1)throw k(M("{0} \u5DF2\u52A0\u5BC6",B));if(L!==0&&L!==8)throw k(M("{0}\uFF1A\u4E0D\u652F\u6301\u7684\u538B\u7F29\u65B9\u5F0F",B));s.push({name:B,method:L,packedSize:g,size:l,local:R})}}return s}var S=t=>k(M("{0}\uFF1A\u5927\u5C0F\u4E0D\u7B26",t.name),{code:"size"});function C(t,o){try{return b.inflateRawSync(t,{maxOutputLength:Math.min(G.MAX_LENGTH,Math.max(1,o.size))})}catch(e){throw e?.code==="ERR_BUFFER_TOO_LARGE"?S(o):e}}function O(t,o){let e=t(o.local,30);if(e.readUInt32LE(0)!==A)throw m();return o.local+30+e.readUInt16LE(26)+e.readUInt16LE(28)}function nt(t){let o=(e,c)=>{if(e<0||e+c>t.length)throw m();return t.subarray(e,e+c)};return N(o,t.length).map(e=>{let c=o(O(o,e),e.packedSize),h=e.method===0?Buffer.from(c):C(c,e);if(h.length!==e.size)throw S(e);return{name:e.name,data:h}})}function rt(t){let o=E.openSync(t,"r"),e=E.fstatSync(o).size,c=(n,i)=>{if(n<0||n+i>e)throw m();let f=Buffer.alloc(i);for(let a=0;a<i;){let s=E.readSync(o,f,a,i-a,n+a);if(s===0)throw m();a+=s}return f},h;try{h=N(c,e)}catch(n){throw E.closeSync(o),n}return{entries:h,read(n){let i=c(O(c,n),n.packedSize),f=n.method===0?i:C(i,n);if(f.length!==n.size)throw S(n);return f},async extract(n,i){let f=O(c,n);if(n.packedSize===0)await E.promises.writeFile(i,"");else{let a=E.createReadStream(t,{start:f,end:f+n.packedSize-1}),s=0,r=new H({transform(u,w,L){s+=u.length,L(s>n.size?S(n):null,u)}});await P(...n.method===0?[a]:[a,b.createInflateRaw()],r,E.createWriteStream(i))}if((await E.promises.stat(i)).size!==n.size)throw S(n)},close:()=>E.closeSync(o)}}export{tt as a,et as b,nt as c,rt as d};
@@ -1,4 +1,4 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{b as n,e as c}from"./chunk-A55HN5OK.mjs";c();var f=e=>n(e.replace(/^\uFEFF/," "),{sourceCodeLocationInfo:!0}),i=(e,o)=>e.slice(o.sourceCodeLocation.startOffset,o.sourceCodeLocation.endOffset);function a(e,o){let r=1;for(let t=e.indexOf(`
2
+ import{b as n,e as c}from"./chunk-N3DSBH5S.mjs";c();var f=e=>n(e.replace(/^\uFEFF/," "),{sourceCodeLocationInfo:!0}),i=(e,o)=>e.slice(o.sourceCodeLocation.startOffset,o.sourceCodeLocation.endOffset);function a(e,o){let r=1;for(let t=e.indexOf(`
3
3
  `);t!==-1&&t<o;t=e.indexOf(`
4
4
  `,t+1))r++;return r}export{f as a,i as b,a as c};
@@ -10,10 +10,10 @@ Error cause: ${lt(e)?e.stack:e}`)}this.#w()}#x(e){let r=Qt.createInterface(e),o=
10
10
  `)))};this.#t.on("exit",i),this.#t.on("error",i);let n=r>0?setTimeout(c,r):void 0;this.#h.on("line",d);let l=()=>{clearTimeout(n),this.#h.off("line",d),this.#t.off("exit",i),this.#t.off("error",i)};function c(){l(),a(new te(`Timed out after ${r} ms while waiting for the WS endpoint URL to appear in stdout!`))}for(let f of this.#n)d(f);function d(f){let p=f.match(e);p&&(l(),o(p[1]))}})}},rr=`Puppeteer was unable to kill the process which ran the browser binary.
11
11
  This means that, on future Puppeteer launches, Puppeteer might not be able to launch the browser.
12
12
  Please check your open processes and ensure that the browser processes that Puppeteer launched have been killed.
13
- If you think this is a bug, please report it on the Puppeteer issue tracker.`;function or(t){try{return process.kill(t,0)}catch(e){if(ar(e)&&e.code&&e.code==="ESRCH")return!1;throw e}}function lt(t){return typeof t=="object"&&t!==null&&"name"in t&&"message"in t}function ar(t){return lt(t)&&("errno"in t||"code"in t||"path"in t||"syscall"in t)}var te=class extends Error{constructor(e){super(e),this.name=this.constructor.name,Error.captureStackTrace(this,this.constructor)}};import gr from"node:assert";import{spawnSync as Ne}from"node:child_process";import{existsSync as A,readFileSync as Cr}from"node:fs";import{mkdir as mt,unlink as Rr}from"node:fs/promises";import L from"node:os";import H from"node:path";var S=class{#e;constructor(e){this.#e=e}supports(e){return!0}getDownloadUrl(e){return this.#r(e.browser,e.platform,e.buildId)}#r(e,r,o){return new URL(K[e](r,o,this.#e))}getExecutablePath(e){return U[e.browser](e.platform,e.buildId)}getName(){return"DefaultProvider"}};import{spawnSync as sr,spawn as ir,execFile as nr}from"node:child_process";import{constants as lr,createReadStream as cr,createWriteStream as ur}from"node:fs";import{mkdir as oe,readdir as hr,symlink as dr}from"node:fs/promises";import*as v from"node:path";import{Stream as fr,Writable as mr}from"node:stream";import{pipeline as ct}from"node:stream/promises";import{promisify as De}from"node:util";var M=De(nr);async function ht(t,e,r){if(v.isAbsolute(e)||(e=v.resolve(process.cwd(),e)),t.endsWith(".zip"))await oe(e,{recursive:!0}),await xr(t,e,r);else if(t.endsWith(".tar.bz2"))await ut(t,e,"bzip2",r);else if(t.endsWith(".dmg"))await oe(e),await br(t,e);else if(t.endsWith(".exe")){let o=sr(t,[`/ExtractDir=${e}`],{env:{__compat_layer:"RunAsInvoker"}});if(o.status!==0)throw new Error(`Failed to extract ${t} to ${e}: ${o.output}`)}else if(t.endsWith(".tar.xz"))await ut(t,e,"xz");else throw new Error(`Unsupported archive format: ${t}`)}function pr(t){let e=new fr.Transform({transform(r,o,a){t.stdin.write(r,o)?a():t.stdin.once("drain",a)},flush(r){t.stdout.destroyed?r():(t.stdin.end(),t.stdout.on("close",r))}});return t.stdin.on("error",r=>{"code"in r&&r.code==="EPIPE"?e.emit("end"):e.destroy(r)}),t.stdout.on("data",r=>e.push(r)).on("error",r=>e.destroy(r)),t.once("close",()=>e.end()),e}var wr={xz:"xz",bzip2:"bzip2"};async function ut(t,e,r,o){let{unpackTar:a}=await import("./chunk-QR6A54KJ.mjs");return await new Promise((i,n)=>{function l(f){return p=>{"code"in p&&p.code==="ENOENT"&&(p=new Error(`\`${f}\` utility is required to unpack this archive`,{cause:p})),n(p)}}let c=ir(wr[r],["-d"],{stdio:["pipe","pipe","inherit"]}).once("error",l(r)).once("exit",f=>{o?.(b.fileUtil)?.(`${r} exited, code=${f}`)}),d=a(e);d.once("error",l("tar")),d.once("finish",i),cr(t).pipe(pr(c)).pipe(d)})}async function br(t,e){let{stdout:r}=await M("hdiutil",["attach","-nobrowse","-noautoopen",t]),o=r.match(/\/Volumes\/(.*)/m);if(!o)throw new Error(`Could not find volume path in ${r}`);let a=o[0];try{let n=(await hr(a)).find(c=>typeof c=="string"&&c.endsWith(".app"));if(!n)throw new Error(`Cannot find app in ${a}`);let l=v.join(a,n);await M("cp",["-R",l,e])}finally{await M("hdiutil",["detach",a,"-quiet"])}}var j=class extends Error{};async function xr(t,e,r){for(let o of[Ir,Er])try{await o(t,e,r);return}catch(a){if(!(a instanceof j))throw a}throw new Error("Extraction failed: no zip archiver is available. Install `unzip` (or `tar.exe`/Powershell on Windows), or add the optional `yauzl` dependency.")}async function Er(t,e,r){let{default:o}=await import("yauzl").catch(()=>{throw new j("Extraction failed: The optional `yauzl` dependency is not installed.")}),a=De(o.open);try{let i=await a(t,{lazyEntries:!0});await new Promise((n,l)=>{i.on("error",l).on("end",n).on("entry",c=>{yr(i,c,e).then(()=>{i.readEntry()},l)}).readEntry()})}catch(i){throw new Error(`Extraction failed: ${t}`,{cause:i})}}async function Ir(t,e,r){try{if(process.platform==="win32"){let o=process.env.SystemRoot??process.env.SYSTEMROOT??"C:\\Windows";try{let a=`${o}\\System32\\tar.exe`;await M(a,["-xf",t,"-C",e]);return}catch(a){r?.(b.fileUtil)?.(`tar.exe extraction failed: ${a}`)}try{await M("powershell.exe",["-NoProfile","-NonInteractive","-Command","& { Expand-Archive -LiteralPath $args[0] -DestinationPath $args[1] -Force }",t,e]);return}catch(a){r?.(b.fileUtil)?.(`powershell.exe extraction failed: ${a}`)}await M("pwsh.exe",["-NoProfile","-NonInteractive","-Command","& { Expand-Archive -LiteralPath $args[0] -DestinationPath $args[1] -Force }",t,e])}else await M("unzip",["-o",t,"-d",e])}catch(o){throw o?.code==="ENOENT"?new j("Extraction failed: Required native binary ('tar.exe', 'powershell.exe', 'pwsh.exe' or 'unzip') was not found in the system PATH."):new Error(`Extraction failed: ${o?.stderr?.toString()||o?.message}`)}}function vr(t,e){let r=v.resolve(t),o=v.resolve(e);return o===r||o.startsWith(r+v.sep)}async function yr(t,e,r){let{S_IFMT:o,S_IFDIR:a,S_IFLNK:i}=lr,n=e.externalFileAttributes>>>16,l=(n&o)===a||e.fileName.endsWith("/")||e.versionMadeBy>>8===0&&e.externalFileAttributes===16,c=(n&o)===i,d=n===0?l?493:420:n&511,f=v.join(r,e.fileName);if(l){await oe(f,{recursive:!0,mode:d});return}await oe(v.dirname(f),{recursive:!0});let p=await De(t.openReadStream.bind(t))(e);if(c){let E=[];await ct(p,new mr({write(Te,Wr,It){Te instanceof Buffer&&E.push(Te),It()}}));let P=Buffer.concat(E).toString(),Et=v.resolve(v.dirname(f),P);if(!vr(r,Et))throw new Error(`Zip symlink "${e.fileName}" would point outside of the target directory.`);await dr(P,f);return}await ct(p,ur(f,{mode:d}))}var V=null,ae=class t{#e;#r=0;#o=0;#t=[];#s=!1;#a=0;#i=!1;constructor(e){this.#e=e}static createBarTicker(e,r,o=process.stderr){return(!V||V.#e!==o)&&(V=new t(o)),V.#n(e,r)}#c(){let e=this.#r++;return e>0&&this.#e.isTTY&&this.#e.write(`
13
+ If you think this is a bug, please report it on the Puppeteer issue tracker.`;function or(t){try{return process.kill(t,0)}catch(e){if(ar(e)&&e.code&&e.code==="ESRCH")return!1;throw e}}function lt(t){return typeof t=="object"&&t!==null&&"name"in t&&"message"in t}function ar(t){return lt(t)&&("errno"in t||"code"in t||"path"in t||"syscall"in t)}var te=class extends Error{constructor(e){super(e),this.name=this.constructor.name,Error.captureStackTrace(this,this.constructor)}};import gr from"node:assert";import{spawnSync as Ne}from"node:child_process";import{existsSync as A,readFileSync as Cr}from"node:fs";import{mkdir as mt,unlink as Rr}from"node:fs/promises";import L from"node:os";import H from"node:path";var S=class{#e;constructor(e){this.#e=e}supports(e){return!0}getDownloadUrl(e){return this.#r(e.browser,e.platform,e.buildId)}#r(e,r,o){return new URL(K[e](r,o,this.#e))}getExecutablePath(e){return U[e.browser](e.platform,e.buildId)}getName(){return"DefaultProvider"}};import{spawnSync as sr,spawn as ir,execFile as nr}from"node:child_process";import{constants as lr,createReadStream as cr,createWriteStream as ur}from"node:fs";import{mkdir as oe,readdir as hr,symlink as dr}from"node:fs/promises";import*as v from"node:path";import{Stream as fr,Writable as mr}from"node:stream";import{pipeline as ct}from"node:stream/promises";import{promisify as De}from"node:util";var M=De(nr);async function ht(t,e,r){if(v.isAbsolute(e)||(e=v.resolve(process.cwd(),e)),t.endsWith(".zip"))await oe(e,{recursive:!0}),await xr(t,e,r);else if(t.endsWith(".tar.bz2"))await ut(t,e,"bzip2",r);else if(t.endsWith(".dmg"))await oe(e),await br(t,e);else if(t.endsWith(".exe")){let o=sr(t,[`/ExtractDir=${e}`],{env:{__compat_layer:"RunAsInvoker"}});if(o.status!==0)throw new Error(`Failed to extract ${t} to ${e}: ${o.output}`)}else if(t.endsWith(".tar.xz"))await ut(t,e,"xz");else throw new Error(`Unsupported archive format: ${t}`)}function pr(t){let e=new fr.Transform({transform(r,o,a){t.stdin.write(r,o)?a():t.stdin.once("drain",a)},flush(r){t.stdout.destroyed?r():(t.stdin.end(),t.stdout.on("close",r))}});return t.stdin.on("error",r=>{"code"in r&&r.code==="EPIPE"?e.emit("end"):e.destroy(r)}),t.stdout.on("data",r=>e.push(r)).on("error",r=>e.destroy(r)),t.once("close",()=>e.end()),e}var wr={xz:"xz",bzip2:"bzip2"};async function ut(t,e,r,o){let{unpackTar:a}=await import("./chunk-ZW2A6GBW.mjs");return await new Promise((i,n)=>{function l(f){return p=>{"code"in p&&p.code==="ENOENT"&&(p=new Error(`\`${f}\` utility is required to unpack this archive`,{cause:p})),n(p)}}let c=ir(wr[r],["-d"],{stdio:["pipe","pipe","inherit"]}).once("error",l(r)).once("exit",f=>{o?.(b.fileUtil)?.(`${r} exited, code=${f}`)}),d=a(e);d.once("error",l("tar")),d.once("finish",i),cr(t).pipe(pr(c)).pipe(d)})}async function br(t,e){let{stdout:r}=await M("hdiutil",["attach","-nobrowse","-noautoopen",t]),o=r.match(/\/Volumes\/(.*)/m);if(!o)throw new Error(`Could not find volume path in ${r}`);let a=o[0];try{let n=(await hr(a)).find(c=>typeof c=="string"&&c.endsWith(".app"));if(!n)throw new Error(`Cannot find app in ${a}`);let l=v.join(a,n);await M("cp",["-R",l,e])}finally{await M("hdiutil",["detach",a,"-quiet"])}}var j=class extends Error{};async function xr(t,e,r){for(let o of[Ir,Er])try{await o(t,e,r);return}catch(a){if(!(a instanceof j))throw a}throw new Error("Extraction failed: no zip archiver is available. Install `unzip` (or `tar.exe`/Powershell on Windows), or add the optional `yauzl` dependency.")}async function Er(t,e,r){let{default:o}=await import("yauzl").catch(()=>{throw new j("Extraction failed: The optional `yauzl` dependency is not installed.")}),a=De(o.open);try{let i=await a(t,{lazyEntries:!0});await new Promise((n,l)=>{i.on("error",l).on("end",n).on("entry",c=>{yr(i,c,e).then(()=>{i.readEntry()},l)}).readEntry()})}catch(i){throw new Error(`Extraction failed: ${t}`,{cause:i})}}async function Ir(t,e,r){try{if(process.platform==="win32"){let o=process.env.SystemRoot??process.env.SYSTEMROOT??"C:\\Windows";try{let a=`${o}\\System32\\tar.exe`;await M(a,["-xf",t,"-C",e]);return}catch(a){r?.(b.fileUtil)?.(`tar.exe extraction failed: ${a}`)}try{await M("powershell.exe",["-NoProfile","-NonInteractive","-Command","& { Expand-Archive -LiteralPath $args[0] -DestinationPath $args[1] -Force }",t,e]);return}catch(a){r?.(b.fileUtil)?.(`powershell.exe extraction failed: ${a}`)}await M("pwsh.exe",["-NoProfile","-NonInteractive","-Command","& { Expand-Archive -LiteralPath $args[0] -DestinationPath $args[1] -Force }",t,e])}else await M("unzip",["-o",t,"-d",e])}catch(o){throw o?.code==="ENOENT"?new j("Extraction failed: Required native binary ('tar.exe', 'powershell.exe', 'pwsh.exe' or 'unzip') was not found in the system PATH."):new Error(`Extraction failed: ${o?.stderr?.toString()||o?.message}`)}}function vr(t,e){let r=v.resolve(t),o=v.resolve(e);return o===r||o.startsWith(r+v.sep)}async function yr(t,e,r){let{S_IFMT:o,S_IFDIR:a,S_IFLNK:i}=lr,n=e.externalFileAttributes>>>16,l=(n&o)===a||e.fileName.endsWith("/")||e.versionMadeBy>>8===0&&e.externalFileAttributes===16,c=(n&o)===i,d=n===0?l?493:420:n&511,f=v.join(r,e.fileName);if(l){await oe(f,{recursive:!0,mode:d});return}await oe(v.dirname(f),{recursive:!0});let p=await De(t.openReadStream.bind(t))(e);if(c){let E=[];await ct(p,new mr({write(Te,Wr,It){Te instanceof Buffer&&E.push(Te),It()}}));let P=Buffer.concat(E).toString(),Et=v.resolve(v.dirname(f),P);if(!vr(r,Et))throw new Error(`Zip symlink "${e.fileName}" would point outside of the target directory.`);await dr(P,f);return}await ct(p,ur(f,{mode:d}))}var V=null,ae=class t{#e;#r=0;#o=0;#t=[];#s=!1;#a=0;#i=!1;constructor(e){this.#e=e}static createBarTicker(e,r,o=process.stderr){return(!V||V.#e!==o)&&(V=new t(o)),V.#n(e,r)}#c(){let e=this.#r++;return e>0&&this.#e.isTTY&&this.#e.write(`
14
14
  `),e}#n(e,r){let o=this.#c();this.#t.push({title:e,total:r,downloaded:0,startTime:0,lastRendered:""});let a=!1;return i=>{let n=this.#t[o];n.startTime===0&&(n.startTime=Date.now()),n.downloaded+=i;let l=n.downloaded>=n.total;(l||Date.now()-this.#a>=100)&&this.#u(),l&&!a&&(a=!0,this.#l())}}#u(){this.#s||(this.#s=!0,queueMicrotask(()=>{this.#s=!1,this.#a=Date.now(),this.#d()}))}#h(e){let r=this.#t[e],o=Math.min(1,Math.max(0,r.downloaded/r.total)),a=Math.round(o*100),i=r.startTime>0?Date.now()-r.startTime:0,n=i>0?r.downloaded/i:0,l=n>0?(r.total-r.downloaded)/n/1e3:0,c=20,d=Math.round(c*o),f="=".repeat(d)+" ".repeat(c-d),p=o>=1?"unpacking":`${a}% ${l.toFixed(1)}s`;return`${r.title} [${f}] ${p} `}#d(){if(!this.#e.isTTY)return;let e=this.#r;if(e!==0){e>1&&this.#e.moveCursor(0,-(e-1));for(let r=0;r<e;r++){let o=this.#h(r);o!==this.#t[r].lastRendered&&(this.#e.cursorTo(0),this.#e.write(o),this.#e.clearLine(1),this.#t[r].lastRendered=o),r<e-1&&this.#e.moveCursor(0,1)}this.#e.cursorTo(0),this.#i&&(V=null,this.#e.write(`
15
15
  `))}}#l(){this.#o++,this.#o>=this.#r&&this.#r>0&&(this.#i=!0)}};var pt=new Map;function se(t){pt.set(t,process.hrtime())}function ie(t,e){let r=process.hrtime(),o=pt.get(t);if(!o)return;let a=r[0]*1e3+r[1]/1e6-(o[0]*1e3+o[1]/1e6);e?.(b.install)?.(`Duration for ${t}: ${a}ms`)}var B=class extends Error{};async function Sr(t){if(!t.platform)throw new Error("Platform must be defined");let e=t.logger,o=new C(t.cacheDir,t.logger).browserRoot(t.browser),a=[...t.providers||[]];t.baseUrl&&a.push(new S(t.baseUrl)),(!t.baseUrl||t.forceFallbackForTesting)&&a.push(new S);let i={browser:t.browser,platform:t.platform,buildId:t.buildId,progressCallback:t.downloadProgressCallback==="default"?await wt(t.browser,t.buildIdAlias??t.buildId):t.downloadProgressCallback},n=[];for(let d of a)try{if(!await d.supports(i)){e?.(b.install)?.(`Provider ${d.getName()} does not support ${t.browser} on ${t.platform}`);continue}d instanceof S||(e?.(b.install)?.(`\u26A0\uFE0F Using custom downloader: ${d.getName()}`),e?.(b.install)?.("\u26A0\uFE0F Puppeteer does not guarantee compatibility with non-default providers")),e?.(b.install)?.(`Trying provider: ${d.getName()} for ${t.browser} ${t.buildId}`);let f=await d.getDownloadUrl(i);if(!f){e?.(b.install)?.(`Provider ${d.getName()} returned no URL for ${t.browser} ${t.buildId}`);continue}return e?.(b.install)?.(`Successfully got URL from ${d.getName()}: ${f}`),A(o)||await mt(o,{recursive:!0}),await Ar(f,t,d,e)}catch(f){e?.(b.install)?.(`Provider ${d.getName()} failed: ${f.message}`),n.push({providerName:d.getName(),error:f})}let l=n.map(d=>` - ${d.providerName}: ${d.error.message}`).join(`
16
16
  `),c=`All providers failed for ${t.browser} ${t.buildId}:
17
17
  ${l}`;throw n.length>0&&n.every(d=>d.error instanceof B)?new B(c):new Error(c)}async function Le(t){if(t.platform??=y(),t.unpack??=!0,t.logger??=J,!t.platform)throw new Error(`Cannot download a binary for the provided platform: ${L.platform()} (${L.arch()})`);return t.providers??=[],await Sr(t)}async function dt(t,e){if(process.platform!=="linux"||t.platform!==s.LINUX&&t.platform!==s.LINUX_ARM)return;let r=H.join(H.dirname(t.executablePath),"deb.deps");if(!A(r)){e?.(b.install)?.(`deb.deps file was not found at ${r}`);return}let o=Cr(r,"utf-8").split(`
18
- `).join(",");if(process.getuid?.()!==0)throw new Error("Installing system dependencies requires root privileges");let a=Ne("apt-get",["-v"]);if(a.status!==0)throw new Error("Failed to install system dependencies: apt-get does not seem to be available");if(e?.(b.install)?.(`Trying to install dependencies: ${o}`),a=Ne("apt-get",["satisfy","-y",o,"--no-install-recommends"]),a.status!==0)throw new Error(`Failed to install system dependencies: status=${a.status},error=${a.error},stdout=${a.stdout.toString("utf8")},stderr=${a.stderr.toString("utf8")}`);e?.(b.install)?.(`Installed system dependencies ${o}`)}async function Ar(t,e,r,o){if(!r)throw new Error("Provider is required for installation");if(e.platform??=y(),!e.platform)throw new Error(`Cannot download a binary for the provided platform: ${L.platform()} (${L.arch()})`);let a=e.downloadProgressCallback;a==="default"&&(a=await wt(e.browser,e.buildIdAlias??e.buildId));let i=decodeURIComponent(t.toString()).split("/").pop();gr(i,`A malformed download URL was found: ${t}.`);let n=new C(e.cacheDir,e.logger),l=n.browserRoot(e.browser),c=H.join(l,`${e.buildId}-${i}`);if(A(l)||await mt(l,{recursive:!0}),e.expectedHash&&o?.(b.install)?.(`Using provided checksum for ${i}: ${e.expectedHash}`),!e.unpack)return A(c)||(o?.(b.install)?.(`Downloading binary from ${t}`),se("download"),await le(t,c,a,e.expectedHash),ie("download",o)),c;let d=n.installationDir(e.browser,e.platform,e.buildId),f=await r.getExecutablePath({browser:e.browser,buildId:e.buildId,platform:e.platform});o?.(b.install)?.(`Using executable path from provider: ${f}`);let p=new _(n,e.browser,e.buildId,e.platform);r instanceof S||n.writeExecutablePath(e.browser,e.platform,e.buildId,f);try{if(A(d)){if(!A(p.executablePath))throw new B(`The browser folder (${d}) exists but the executable (${p.executablePath}) is missing. An earlier install of this build probably did not finish. Delete ${d} and install the browser again.`);return await ft(p,o),e.installDeps&&await dt(p,o),p}if(A(c))o?.(b.install)?.(`Using existing archive at ${c}`);else{o?.(b.install)?.(`Downloading binary from ${t}`);try{se("download"),await le(t,c,a,e.expectedHash)}finally{ie("download",o)}}o?.(b.install)?.(`Installing ${c} to ${d}`);try{se("extract"),await ht(c,d,e.logger)}finally{ie("extract",o)}if(e.buildIdAlias){let E=p.readMetadata();E.aliases[e.buildIdAlias]=e.buildId,p.writeMetadata(E)}return await ft(p,o),e.installDeps&&await dt(p,o),p}finally{A(c)&&await Rr(c)}}async function ft(t,e){if((t.platform===s.WIN32||t.platform===s.WIN64)&&t.browser===u.CHROME&&t.platform===y())try{se("permissions");let r=H.dirname(t.executablePath),o=H.join(r,"setup.exe");if(!A(o))return;Ne(H.join(r,"setup.exe"),["--configure-browser-in-directory="+r],{shell:!1})}finally{ie("permissions",e)}}async function $r(t){if(t.platform??=y(),!t.platform)throw new Error(`Cannot detect the browser platform for: ${L.platform()} (${L.arch()})`);new C(t.cacheDir).uninstall(t.browser,t.platform,t.buildId)}async function Dr(t){return new C(t.cacheDir).getInstalledBrowsers()}async function Nr(t){if(t.platform??=y(),!t.platform)throw new Error(`Cannot download a binary for the provided platform: ${L.platform()} (${L.arch()})`);let e=[...t.providers||[],new S(t.baseUrl)],r={browser:t.browser,platform:t.platform,buildId:t.buildId};for(let o of e){if(!await o.supports(r))continue;let a=await o.getDownloadUrl(r);if(a&&await Oe(a))return!0}return!1}function Lr(t,e,r,o){return new URL(K[t](e,r,o))}async function wt(t,e){let r,o=0;return(a,i)=>{r||(r=ae.createBarTicker(`Downloading ${t} ${e} - ${Pr(i)}`,i));let n=a-o;o=a,r(n)}}function Pr(t){let e=t/1e3/1e3;return`${Math.round(e*10)/10} MB`}import{spawn as Tr}from"node:child_process";import bt from"node:fs";import Mr from"node:os";import Br from"node:path";import{stdin as Or,stdout as Ur}from"node:process";import*as xt from"node:readline";function _r(t){return Object.values(u).includes(t)}function Hr(t){return Object.values(s).includes(t)}var Fr="3.2.3",Pe=class{#e;#r;#o;#t;#s;#a;#i;constructor(e,r){e||(e={}),typeof e=="string"&&(e={cachePath:e}),this.#e=e.cachePath??process.cwd(),this.#r=r,this.#o=e.scriptName??"@puppeteer/browsers",this.#t=e.version??Fr,this.#s=e.allowCachePathOverride??!0,this.#a=e.pinnedBrowsers,this.#i=e.prefixCommand}#c(e,r){return e.positional("browser",{description:"Which browser to install <browser>[@<buildId|latest>]. `latest` will try to find the latest available build. `buildId` is a browser-specific identifier such as a version or a revision.",type:"string",coerce:o=>{let a={name:this.#d(o),buildId:this.#l(o)};if(!_r(a.name))throw new Error(`Unsupported browser '${a.name}'`);return a},demandOption:r})}#n(e){return e.option("platform",{type:"string",desc:"Platform that the binary needs to be compatible with.",choices:Object.values(s),default:y(),coerce:r=>{if(!Hr(r))throw new Error(`Unsupported platform '${r}'`);return r},defaultDescription:"Auto-detected"})}#u(e,r=!1){return this.#s?e.option("path",{type:"string",desc:"Path to the root folder for the browser downloads and installation. If a relative path is provided, it will be resolved relative to the current working directory. The installation folder structure is compatible with the cache structure used by Puppeteer.",defaultDescription:"Current working directory",...r?{}:{default:process.cwd()},demandOption:r}):e}async run(e){let{default:r}=await import("./chunk-C564NU2H.mjs"),{hideBin:o}=await import("./chunk-4K5KC6V2.mjs"),a=r(o(e)),i=a.scriptName(this.#o).version(this.#t);this.#i?i=i.command(this.#i.cmd,this.#i.description,n=>this.#h(n)):i=this.#h(i),await i.demandCommand(1).help().wrap(Math.min(120,a.terminalWidth())).parseAsync()}#h(e){let r=this.#a?"pinned":"latest",o=this.#a?"[browser]":"<browser>";return e.command(`install ${o}`,"Download and install the specified browser. If successful, the command outputs the actual browser buildId that was installed and the absolute path to the browser executable (see --format).",a=>{this.#a&&a.example("$0 install","Install all pinned browsers"),a.example("$0 install chrome",`Install the ${r} available build of the Chrome browser.`).example("$0 install chrome@latest","Install the latest available build for the Chrome browser.").example("$0 install chrome@stable","Install the latest available build for the Chrome browser from the stable channel.").example("$0 install chrome@beta","Install the latest available build for the Chrome browser from the beta channel.").example("$0 install chrome@dev","Install the latest available build for the Chrome browser from the dev channel.").example("$0 install chrome@canary","Install the latest available build for the Chrome Canary browser.").example("$0 install chrome@115","Install the latest available build for Chrome 115.").example("$0 install chromedriver@canary","Install the latest available build for ChromeDriver Canary.").example("$0 install chromedriver@115","Install the latest available build for ChromeDriver 115.").example("$0 install chromedriver@115.0.5790","Install the latest available patch (115.0.5790.X) build for ChromeDriver.").example("$0 install chrome-headless-shell","Install the latest available chrome-headless-shell build.").example("$0 install chrome-headless-shell@beta","Install the latest available chrome-headless-shell build corresponding to the Beta channel.").example("$0 install chrome-headless-shell@118","Install the latest available chrome-headless-shell 118 build.").example("$0 install chromium@1083080","Install the revision 1083080 of the Chromium browser.").example("$0 install firefox","Install the latest nightly available build of the Firefox browser.").example("$0 install firefox@stable","Install the latest stable build of the Firefox browser.").example("$0 install firefox@beta","Install the latest beta build of the Firefox browser.").example("$0 install firefox@devedition","Install the latest devedition build of the Firefox browser.").example("$0 install firefox@esr","Install the latest ESR build of the Firefox browser.").example("$0 install firefox@nightly","Install the latest nightly build of the Firefox browser.").example("$0 install firefox@stable_111.0.1","Install a specific version of the Firefox browser.").example("$0 install firefox --platform mac","Install the latest Mac (Intel) build of the Firefox browser."),this.#s&&a.example("$0 install firefox --path /tmp/my-browser-cache","Install to the specified cache directory.");let i=this.#c(a,!this.#a),n=this.#n(i);return this.#u(n,!1).option("base-url",{type:"string",desc:"Base URL to download from"}).option("install-deps",{type:"boolean",desc:"Whether to attempt installing system dependencies (only supported on Linux, requires root privileges).",default:!1}).option("format",{type:"string",desc:"Format to use for the output. Supported placeholders: {{browser}}, {{buildId}}, {{path}}, {{platform}}",default:"{{browser}}@{{buildId}} {{path}}"})},async a=>{if(this.#a&&!a.browser){let i=await Promise.allSettled(Object.entries(this.#a).map(async([n,l])=>{l.skipDownload||await this.#p({...a,browser:{name:n,buildId:l.buildId}})}));for(let n of i)if(n.status==="rejected")throw n.reason}else await this.#p(a)}).command("launch <browser>","Launch the specified browser",a=>{a.example("$0 launch chrome@115.0.5790.170","Launch Chrome 115.0.5790.170").example("$0 launch firefox@112.0a1","Launch the Firefox browser identified by the milestone 112.0a1.").example("$0 launch chrome@115.0.5790.170 --detached","Launch the browser but detach the sub-processes.").example("$0 launch chrome@canary --system","Try to locate the Canary build of Chrome installed on the system and launch it.").example("$0 launch chrome@115.0.5790.170 -- --version","Launch Chrome 115.0.5790.170 and pass custom argument to the binary.");let i=a.parserConfiguration({"populate--":!0}),n=this.#c(i,!0),l=this.#n(n);return this.#u(l).option("detached",{type:"boolean",desc:"Detach the child process.",default:!1}).option("system",{type:"boolean",desc:"Search for a browser installed on the system instead of the cache folder.",default:!1}).option("dumpio",{type:"boolean",desc:"Forwards the browser's process stdout and stderr",default:!1})},async a=>{let i=a["--"]?.filter(l=>typeof l=="string");a.browser.buildId=this.#m(a.browser.buildId,a.browser.name);let n=a.system?Ae({browser:a.browser.name,channel:ue(a.browser.buildId),platform:a.platform}):re({browser:a.browser.name,buildId:a.browser.buildId,cacheDir:a.path??this.#e,platform:a.platform});$e({args:i,executablePath:n,dumpio:a.dumpio,detached:a.detached})}).command("clear",this.#s?"Removes all installed browsers from the specified cache directory":`Removes all installed browsers from ${this.#e}`,a=>this.#u(a,!0),async a=>{let i=a.path??this.#e,n=this.#r??xt.createInterface({input:Or,output:Ur});n.question(`Do you want to permanently and recursively delete the content of ${i} (yes/No)? `,l=>{if(n.close(),!["y","yes"].includes(l.toLowerCase().trim())){console.log("Cancelled.");return}new C(i).clear(),console.log(`${i} cleared.`)})}).command("list","List all installed browsers in the cache directory",a=>(a.example("$0 list","List all installed browsers in the cache directory"),this.#s&&a.example("$0 list --path /tmp/my-browser-cache","List browsers installed in the specified cache directory"),this.#u(a)),async a=>{let i=a.path??this.#e,l=new C(i).getInstalledBrowsers();for(let c of l)console.log(`${c.browser}@${c.buildId} (${c.platform}) ${c.executablePath}`)}).command("bisect <path>","(experimental) Bisect Chrome for Testing using the specified script. Downloads https://chromium.googlesource.com/chromium/src.git/+/main/tools/bisect-builds.py to ~/bisect-builds.py if needed.",a=>a.positional("path",{type:"string",description:"Path to a script or test name to bisect.",demandOption:!0}).option("good",{type:"string",alias:"g",demandOption:!0,desc:"Last known good version"}).option("bad",{type:"string",alias:"b",demandOption:!0,desc:"First known bad version"}).option("cft",{type:"boolean",desc:"Use -cft",default:!0}),async a=>{let n=a.path.endsWith(".mjs")||a.path.endsWith(".cjs")||a.path.endsWith(".js")?`PUPPETEER_EXECUTABLE_PATH=%p node ${a.path}`:`BINARY=%p npm run ${a.path}`,l=Br.join(Mr.homedir(),"bisect-builds.py");if(!bt.existsSync(l)){console.log("Downloading bisect-builds.py...");let f=await fetch("https://chromium.googlesource.com/chromium/src.git/+/main/tools/bisect-builds.py?format=TEXT");if(!f.ok)throw new Error(`Failed to download bisect-builds.py: ${f.statusText}`);let p=await f.text(),E=Buffer.from(p,"base64").toString("utf-8");bt.writeFileSync(l,E,{mode:493}),console.log(`Saved bisect-builds.py to ${l}`)}let c="python3",d=[l,"-g",a.good,"-b",a.bad,a.cft?"-cft":"-s","-v","--verify-range","--not-interactive","-c",n];await new Promise((f,p)=>{let E=Tr(c,d,{stdio:"inherit"});E.on("error",P=>{p(P)}),E.on("exit",P=>{P!==0?p(new Error(`Process exited with code ${P}`)):f()})})}).demandCommand(1).help()}#d(e){return e.split("@").shift()}#l(e){let r=e.split("@");return r.length===2?r[1]:this.#a?"pinned":"latest"}#m(e,r){if(e==="pinned"){let o=this.#a?.[r];if(!o||!o.buildId)throw new Error(`No pinned version found for ${r}`);return o.buildId}return e}async#p(e){if(!e.browser)throw new Error("No browser arg provided");if(!e.platform)throw new Error("Could not resolve the current platform");e.browser.buildId=this.#m(e.browser.buildId,e.browser.name);let r=e.browser.buildId;e.browser.buildId=await Ce(e.browser.name,e.platform,e.browser.buildId);try{await Le({browser:e.browser.name,buildId:e.browser.buildId,platform:e.platform,cacheDir:e.path??this.#e,downloadProgressCallback:"default",baseUrl:e.baseUrl,buildIdAlias:r!==e.browser.buildId?r:void 0,installDeps:e.installDeps})}catch(a){if(!(a instanceof B))throw a;let i=this.#i?`${this.#o} ${this.#i.cmd}`:this.#o;throw new Error(`${a.message}
18
+ `).join(",");if(process.getuid?.()!==0)throw new Error("Installing system dependencies requires root privileges");let a=Ne("apt-get",["-v"]);if(a.status!==0)throw new Error("Failed to install system dependencies: apt-get does not seem to be available");if(e?.(b.install)?.(`Trying to install dependencies: ${o}`),a=Ne("apt-get",["satisfy","-y",o,"--no-install-recommends"]),a.status!==0)throw new Error(`Failed to install system dependencies: status=${a.status},error=${a.error},stdout=${a.stdout.toString("utf8")},stderr=${a.stderr.toString("utf8")}`);e?.(b.install)?.(`Installed system dependencies ${o}`)}async function Ar(t,e,r,o){if(!r)throw new Error("Provider is required for installation");if(e.platform??=y(),!e.platform)throw new Error(`Cannot download a binary for the provided platform: ${L.platform()} (${L.arch()})`);let a=e.downloadProgressCallback;a==="default"&&(a=await wt(e.browser,e.buildIdAlias??e.buildId));let i=decodeURIComponent(t.toString()).split("/").pop();gr(i,`A malformed download URL was found: ${t}.`);let n=new C(e.cacheDir,e.logger),l=n.browserRoot(e.browser),c=H.join(l,`${e.buildId}-${i}`);if(A(l)||await mt(l,{recursive:!0}),e.expectedHash&&o?.(b.install)?.(`Using provided checksum for ${i}: ${e.expectedHash}`),!e.unpack)return A(c)||(o?.(b.install)?.(`Downloading binary from ${t}`),se("download"),await le(t,c,a,e.expectedHash),ie("download",o)),c;let d=n.installationDir(e.browser,e.platform,e.buildId),f=await r.getExecutablePath({browser:e.browser,buildId:e.buildId,platform:e.platform});o?.(b.install)?.(`Using executable path from provider: ${f}`);let p=new _(n,e.browser,e.buildId,e.platform);r instanceof S||n.writeExecutablePath(e.browser,e.platform,e.buildId,f);try{if(A(d)){if(!A(p.executablePath))throw new B(`The browser folder (${d}) exists but the executable (${p.executablePath}) is missing. An earlier install of this build probably did not finish. Delete ${d} and install the browser again.`);return await ft(p,o),e.installDeps&&await dt(p,o),p}if(A(c))o?.(b.install)?.(`Using existing archive at ${c}`);else{o?.(b.install)?.(`Downloading binary from ${t}`);try{se("download"),await le(t,c,a,e.expectedHash)}finally{ie("download",o)}}o?.(b.install)?.(`Installing ${c} to ${d}`);try{se("extract"),await ht(c,d,e.logger)}finally{ie("extract",o)}if(e.buildIdAlias){let E=p.readMetadata();E.aliases[e.buildIdAlias]=e.buildId,p.writeMetadata(E)}return await ft(p,o),e.installDeps&&await dt(p,o),p}finally{A(c)&&await Rr(c)}}async function ft(t,e){if((t.platform===s.WIN32||t.platform===s.WIN64)&&t.browser===u.CHROME&&t.platform===y())try{se("permissions");let r=H.dirname(t.executablePath),o=H.join(r,"setup.exe");if(!A(o))return;Ne(H.join(r,"setup.exe"),["--configure-browser-in-directory="+r],{shell:!1})}finally{ie("permissions",e)}}async function $r(t){if(t.platform??=y(),!t.platform)throw new Error(`Cannot detect the browser platform for: ${L.platform()} (${L.arch()})`);new C(t.cacheDir).uninstall(t.browser,t.platform,t.buildId)}async function Dr(t){return new C(t.cacheDir).getInstalledBrowsers()}async function Nr(t){if(t.platform??=y(),!t.platform)throw new Error(`Cannot download a binary for the provided platform: ${L.platform()} (${L.arch()})`);let e=[...t.providers||[],new S(t.baseUrl)],r={browser:t.browser,platform:t.platform,buildId:t.buildId};for(let o of e){if(!await o.supports(r))continue;let a=await o.getDownloadUrl(r);if(a&&await Oe(a))return!0}return!1}function Lr(t,e,r,o){return new URL(K[t](e,r,o))}async function wt(t,e){let r,o=0;return(a,i)=>{r||(r=ae.createBarTicker(`Downloading ${t} ${e} - ${Pr(i)}`,i));let n=a-o;o=a,r(n)}}function Pr(t){let e=t/1e3/1e3;return`${Math.round(e*10)/10} MB`}import{spawn as Tr}from"node:child_process";import bt from"node:fs";import Mr from"node:os";import Br from"node:path";import{stdin as Or,stdout as Ur}from"node:process";import*as xt from"node:readline";function _r(t){return Object.values(u).includes(t)}function Hr(t){return Object.values(s).includes(t)}var Fr="3.2.3",Pe=class{#e;#r;#o;#t;#s;#a;#i;constructor(e,r){e||(e={}),typeof e=="string"&&(e={cachePath:e}),this.#e=e.cachePath??process.cwd(),this.#r=r,this.#o=e.scriptName??"@puppeteer/browsers",this.#t=e.version??Fr,this.#s=e.allowCachePathOverride??!0,this.#a=e.pinnedBrowsers,this.#i=e.prefixCommand}#c(e,r){return e.positional("browser",{description:"Which browser to install <browser>[@<buildId|latest>]. `latest` will try to find the latest available build. `buildId` is a browser-specific identifier such as a version or a revision.",type:"string",coerce:o=>{let a={name:this.#d(o),buildId:this.#l(o)};if(!_r(a.name))throw new Error(`Unsupported browser '${a.name}'`);return a},demandOption:r})}#n(e){return e.option("platform",{type:"string",desc:"Platform that the binary needs to be compatible with.",choices:Object.values(s),default:y(),coerce:r=>{if(!Hr(r))throw new Error(`Unsupported platform '${r}'`);return r},defaultDescription:"Auto-detected"})}#u(e,r=!1){return this.#s?e.option("path",{type:"string",desc:"Path to the root folder for the browser downloads and installation. If a relative path is provided, it will be resolved relative to the current working directory. The installation folder structure is compatible with the cache structure used by Puppeteer.",defaultDescription:"Current working directory",...r?{}:{default:process.cwd()},demandOption:r}):e}async run(e){let{default:r}=await import("./chunk-74RPP2M2.mjs"),{hideBin:o}=await import("./chunk-LV24RY2E.mjs"),a=r(o(e)),i=a.scriptName(this.#o).version(this.#t);this.#i?i=i.command(this.#i.cmd,this.#i.description,n=>this.#h(n)):i=this.#h(i),await i.demandCommand(1).help().wrap(Math.min(120,a.terminalWidth())).parseAsync()}#h(e){let r=this.#a?"pinned":"latest",o=this.#a?"[browser]":"<browser>";return e.command(`install ${o}`,"Download and install the specified browser. If successful, the command outputs the actual browser buildId that was installed and the absolute path to the browser executable (see --format).",a=>{this.#a&&a.example("$0 install","Install all pinned browsers"),a.example("$0 install chrome",`Install the ${r} available build of the Chrome browser.`).example("$0 install chrome@latest","Install the latest available build for the Chrome browser.").example("$0 install chrome@stable","Install the latest available build for the Chrome browser from the stable channel.").example("$0 install chrome@beta","Install the latest available build for the Chrome browser from the beta channel.").example("$0 install chrome@dev","Install the latest available build for the Chrome browser from the dev channel.").example("$0 install chrome@canary","Install the latest available build for the Chrome Canary browser.").example("$0 install chrome@115","Install the latest available build for Chrome 115.").example("$0 install chromedriver@canary","Install the latest available build for ChromeDriver Canary.").example("$0 install chromedriver@115","Install the latest available build for ChromeDriver 115.").example("$0 install chromedriver@115.0.5790","Install the latest available patch (115.0.5790.X) build for ChromeDriver.").example("$0 install chrome-headless-shell","Install the latest available chrome-headless-shell build.").example("$0 install chrome-headless-shell@beta","Install the latest available chrome-headless-shell build corresponding to the Beta channel.").example("$0 install chrome-headless-shell@118","Install the latest available chrome-headless-shell 118 build.").example("$0 install chromium@1083080","Install the revision 1083080 of the Chromium browser.").example("$0 install firefox","Install the latest nightly available build of the Firefox browser.").example("$0 install firefox@stable","Install the latest stable build of the Firefox browser.").example("$0 install firefox@beta","Install the latest beta build of the Firefox browser.").example("$0 install firefox@devedition","Install the latest devedition build of the Firefox browser.").example("$0 install firefox@esr","Install the latest ESR build of the Firefox browser.").example("$0 install firefox@nightly","Install the latest nightly build of the Firefox browser.").example("$0 install firefox@stable_111.0.1","Install a specific version of the Firefox browser.").example("$0 install firefox --platform mac","Install the latest Mac (Intel) build of the Firefox browser."),this.#s&&a.example("$0 install firefox --path /tmp/my-browser-cache","Install to the specified cache directory.");let i=this.#c(a,!this.#a),n=this.#n(i);return this.#u(n,!1).option("base-url",{type:"string",desc:"Base URL to download from"}).option("install-deps",{type:"boolean",desc:"Whether to attempt installing system dependencies (only supported on Linux, requires root privileges).",default:!1}).option("format",{type:"string",desc:"Format to use for the output. Supported placeholders: {{browser}}, {{buildId}}, {{path}}, {{platform}}",default:"{{browser}}@{{buildId}} {{path}}"})},async a=>{if(this.#a&&!a.browser){let i=await Promise.allSettled(Object.entries(this.#a).map(async([n,l])=>{l.skipDownload||await this.#p({...a,browser:{name:n,buildId:l.buildId}})}));for(let n of i)if(n.status==="rejected")throw n.reason}else await this.#p(a)}).command("launch <browser>","Launch the specified browser",a=>{a.example("$0 launch chrome@115.0.5790.170","Launch Chrome 115.0.5790.170").example("$0 launch firefox@112.0a1","Launch the Firefox browser identified by the milestone 112.0a1.").example("$0 launch chrome@115.0.5790.170 --detached","Launch the browser but detach the sub-processes.").example("$0 launch chrome@canary --system","Try to locate the Canary build of Chrome installed on the system and launch it.").example("$0 launch chrome@115.0.5790.170 -- --version","Launch Chrome 115.0.5790.170 and pass custom argument to the binary.");let i=a.parserConfiguration({"populate--":!0}),n=this.#c(i,!0),l=this.#n(n);return this.#u(l).option("detached",{type:"boolean",desc:"Detach the child process.",default:!1}).option("system",{type:"boolean",desc:"Search for a browser installed on the system instead of the cache folder.",default:!1}).option("dumpio",{type:"boolean",desc:"Forwards the browser's process stdout and stderr",default:!1})},async a=>{let i=a["--"]?.filter(l=>typeof l=="string");a.browser.buildId=this.#m(a.browser.buildId,a.browser.name);let n=a.system?Ae({browser:a.browser.name,channel:ue(a.browser.buildId),platform:a.platform}):re({browser:a.browser.name,buildId:a.browser.buildId,cacheDir:a.path??this.#e,platform:a.platform});$e({args:i,executablePath:n,dumpio:a.dumpio,detached:a.detached})}).command("clear",this.#s?"Removes all installed browsers from the specified cache directory":`Removes all installed browsers from ${this.#e}`,a=>this.#u(a,!0),async a=>{let i=a.path??this.#e,n=this.#r??xt.createInterface({input:Or,output:Ur});n.question(`Do you want to permanently and recursively delete the content of ${i} (yes/No)? `,l=>{if(n.close(),!["y","yes"].includes(l.toLowerCase().trim())){console.log("Cancelled.");return}new C(i).clear(),console.log(`${i} cleared.`)})}).command("list","List all installed browsers in the cache directory",a=>(a.example("$0 list","List all installed browsers in the cache directory"),this.#s&&a.example("$0 list --path /tmp/my-browser-cache","List browsers installed in the specified cache directory"),this.#u(a)),async a=>{let i=a.path??this.#e,l=new C(i).getInstalledBrowsers();for(let c of l)console.log(`${c.browser}@${c.buildId} (${c.platform}) ${c.executablePath}`)}).command("bisect <path>","(experimental) Bisect Chrome for Testing using the specified script. Downloads https://chromium.googlesource.com/chromium/src.git/+/main/tools/bisect-builds.py to ~/bisect-builds.py if needed.",a=>a.positional("path",{type:"string",description:"Path to a script or test name to bisect.",demandOption:!0}).option("good",{type:"string",alias:"g",demandOption:!0,desc:"Last known good version"}).option("bad",{type:"string",alias:"b",demandOption:!0,desc:"First known bad version"}).option("cft",{type:"boolean",desc:"Use -cft",default:!0}),async a=>{let n=a.path.endsWith(".mjs")||a.path.endsWith(".cjs")||a.path.endsWith(".js")?`PUPPETEER_EXECUTABLE_PATH=%p node ${a.path}`:`BINARY=%p npm run ${a.path}`,l=Br.join(Mr.homedir(),"bisect-builds.py");if(!bt.existsSync(l)){console.log("Downloading bisect-builds.py...");let f=await fetch("https://chromium.googlesource.com/chromium/src.git/+/main/tools/bisect-builds.py?format=TEXT");if(!f.ok)throw new Error(`Failed to download bisect-builds.py: ${f.statusText}`);let p=await f.text(),E=Buffer.from(p,"base64").toString("utf-8");bt.writeFileSync(l,E,{mode:493}),console.log(`Saved bisect-builds.py to ${l}`)}let c="python3",d=[l,"-g",a.good,"-b",a.bad,a.cft?"-cft":"-s","-v","--verify-range","--not-interactive","-c",n];await new Promise((f,p)=>{let E=Tr(c,d,{stdio:"inherit"});E.on("error",P=>{p(P)}),E.on("exit",P=>{P!==0?p(new Error(`Process exited with code ${P}`)):f()})})}).demandCommand(1).help()}#d(e){return e.split("@").shift()}#l(e){let r=e.split("@");return r.length===2?r[1]:this.#a?"pinned":"latest"}#m(e,r){if(e==="pinned"){let o=this.#a?.[r];if(!o||!o.buildId)throw new Error(`No pinned version found for ${r}`);return o.buildId}return e}async#p(e){if(!e.browser)throw new Error("No browser arg provided");if(!e.platform)throw new Error("Could not resolve the current platform");e.browser.buildId=this.#m(e.browser.buildId,e.browser.name);let r=e.browser.buildId;e.browser.buildId=await Ce(e.browser.name,e.platform,e.browser.buildId);try{await Le({browser:e.browser.name,buildId:e.browser.buildId,platform:e.platform,cacheDir:e.path??this.#e,downloadProgressCallback:"default",baseUrl:e.baseUrl,buildIdAlias:r!==e.browser.buildId?r:void 0,installDeps:e.installDeps})}catch(a){if(!(a instanceof B))throw a;let i=this.#i?`${this.#o} ${this.#i.cmd}`:this.#o;throw new Error(`${a.message}
19
19
  You can also empty the whole browser cache with \`npx ${i} clear\` and then run \`npx ${i} install\` again.`,{cause:a})}let o=re({browser:e.browser.name,buildId:e.browser.buildId,cacheDir:e.path??this.#e,platform:e.platform});console.log(e.format.replace(/{{browser}}/g,e.browser.name).replace(/{{buildId}}/g,e.browser.buildId).replace(/{{path}}/g,o).replace(/{{platform}}/g,e.platform))}};function kr(t,e,r,o="zip"){return`${t}-${e}-${r}.${o}`}export{u as a,s as b,h as c,m as d,Ce as e,Xt as f,Yt as g,Re as h,y as i,_ as j,C as k,re as l,Ae as m,$e as n,er as o,tr as p,ee as q,te as r,S as s,Le as t,$r as u,Dr as v,Nr as w,Lr as x,Pe as y,kr as z};
@@ -1,4 +1,4 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{e as D,f as x}from"./chunk-OUUP3WKT.mjs";import{a as d,b as u,c as w,d as y}from"./chunk-OJKMINIU.mjs";import{b as c,d as f,e as m,g as p,h as g,i as a,j as h}from"./chunk-SXHBYZST.mjs";import{k as l}from"./chunk-SX4LJYT6.mjs";import{a as s}from"./chunk-UMHUSOPJ.mjs";import S from"node:path";import{FILE as j}from"../browser/shared/annotations.mjs";import{editStateDirectory as L,reportsDirectory as i}from"../browser/shared/paths.mjs";import{documentDirectory as $,documentFiles as k}from"../browser/shared/workspace.mjs";function O({say:e=!0}={}){return o=>{let{text:t,changes:n}=c(o.html,{finish:l});if(e&&n.length&&console.log(p(o.htmlPath,n,{pending:!0}).join(`
2
+ import{e as D,f as x}from"./chunk-XQRUG4G3.mjs";import{a as d,b as u,c as w,d as y}from"./chunk-OU3S466R.mjs";import{b as c,d as f,e as m,g as p,h as g,i as a,j as h}from"./chunk-WTEGUPFG.mjs";import{k as l}from"./chunk-YFJU3O7G.mjs";import{a as s}from"./chunk-JXLSHVJ2.mjs";import S from"node:path";import{FILE as j}from"../browser/shared/annotations.mjs";import{editStateDirectory as L,reportsDirectory as i}from"../browser/shared/paths.mjs";import{documentDirectory as $,documentFiles as k}from"../browser/shared/workspace.mjs";function O({say:e=!0}={}){return o=>{let{text:t,changes:n}=c(o.html,{finish:l});if(e&&n.length&&console.log(p(o.htmlPath,n,{pending:!0}).join(`
3
3
  `)),e){let r=f(o.html);r.length&&console.log(D(o.htmlPath,r,r.length,{pending:!0}).join(`
4
4
  `));for(let N of x(o.htmlPath,m(s(o.html),o.metadata),{pending:!0}))console.log(N)}return t}}function b(e){for(let o of e){for(let t of g(o.html))console.log(`note ${o.slug}: ${t} (read-only in the preview)`);for(let t of a(o.html))console.log(`note ${o.slug}: ${t}`);for(let t of h(o.html))console.log(`note ${o.slug}: ${t}`)}}async function q(e){for(let o of e){let t=await w({stateDirectory:L,reportsDirectory:i,slug:o});for(let n of y(k($(o,i)).html,t))console.log(n)}}async function z(e){for(let o of e){let t=await d({stateDirectory:L,reportsDirectory:i,slug:o});for(let n of u(S.join($(o,i),j),t))console.log(n)}}export{O as a,b,q as c,z as d};
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
- import{c as Oe,f as we,g as ge,h as $e,i as We,j as ne,l as Y,m as Ge,n as Ae,o as Ke,p as Ve,q as ze,r as g,t as Qe,u as Ye}from"./chunk-QOUEFUCH.mjs";import{M as Xe}from"./chunk-VTKNEYT3.mjs";import{f as Te,i as Je}from"./chunk-NFMCP2HI.mjs";import{a as K}from"./chunk-JEUK3ZO7.mjs";import{a as me}from"./chunk-NWFBE2YA.mjs";import{a as Ue,b as Ze,f as pe,g as qe}from"./chunk-PUOQ65NC.mjs";import{e as Ne,g as te}from"./chunk-OJKMINIU.mjs";import{b as Se}from"./chunk-SXHBYZST.mjs";import{b as T,i as Pe}from"./chunk-4OZWXZE5.mjs";import{a as Be}from"./chunk-HYMEEXKN.mjs";import{f as Ee,j as He}from"./chunk-FWNRPMCJ.mjs";import{randomBytes as Ct}from"node:crypto";import{existsSync as It}from"node:fs";import N from"node:fs/promises";import A from"node:path";import{isInstance as Re,isSlot as jt,partOf as Mt}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as ke,FALLBACK as Rt,FIELDS as Dt,INSTANCE as ft,PACKAGE_ID as _t,SLOT as Ft}from"../browser/shared/components/installed.mjs";import{attr as ce,walk as Ht}from"../browser/shared/html-tree.mjs";import{documentDirectory as Pt,documentFiles as Bt,layoutOf as se,packageFolders as Jt,slugTaken as Ut}from"../browser/shared/workspace.mjs";var et=10,Ce=6,Zt=3,qt=100,De=1024,_e=900,Wt=4e3,le=3e4,Gt=1500,Ie=3e4,je=500,Kt=5e3,Vt=200,tt=20,nt=160,ye=12,zt=3600*1e3,Qt=["p","pi","pin"],he=e=>new Promise(t=>setTimeout(t,e));async function at(e){let{_keyDefinitions:t}=await import("./chunk-43B75J5T.mjs"),n=Object.hasOwn(t,e)?[e]:e.split("+"),a=new Set(["Control","Shift","Alt","Meta"]);if(n.some(s=>!Object.hasOwn(t,s))||n.slice(0,-1).some(s=>!a.has(s)))throw new T(`Not a key: ${e} (a key as a browser names it, Enter, Space, Escape, Tab, ArrowRight, a letter or a digit, after modifiers joined by "+": Shift+Tab, Control+Enter).`);return n}var ie={press:"<selector>",drag:'<selector>, with "to": <selector>',key:"[<selector>, <key>]",type:"[<selector>, <words>]",select:"[<selector>, <value>]"};async function ut(e,t=null){let n=d=>new T(t?`${t[0].toUpperCase()}${t.slice(1)}: ${d}`:`${d[0].toUpperCase()}${d.slice(1)}`);if(!e||typeof e!="object"||Array.isArray(e))throw n(`a step is an object naming one gesture: ${Object.entries(ie).map(([d,h])=>`"${d}": ${h}`).join(", ")}, and "then": <key> after it.`);let a=Object.keys(e).filter(d=>!Object.hasOwn(ie,d)&&!["to","then","replace"].includes(d));if(a.length)throw n(`no such field: ${a.join(", ")} (a step names one of ${Object.keys(ie).join(", ")}, "to" with a drag, "replace": true with typing and "then" after any).`);let s=Object.keys(ie).filter(d=>e[d]!==void 0),o=d=>t?`"${d}"`:`--${d}`;if(s.length!==1)throw n(s.length?`one gesture at a time: ${s.map(o).join(" or ")}.`:t?`name the gesture: ${Object.keys(ie).map(o).join(", ")}.`:"Say the gesture: --press <selector>, --drag <selector> --to <selector>, --key <selector> <key>, --type <selector> <words> or --select <selector> <value>; or --steps <file>.");let[i]=s;if(e.to!==void 0&&i!=="drag")throw n(`${o("to")} goes with ${o("drag")}: ${t?'"drag": <selector>, "to": <selector>':"--drag <selector> --to <selector>"}.`);if(i==="drag"&&e.to===void 0)throw n(`${o("drag")} takes ${o("to")}: ${t?'"drag": <selector>, "to": <selector>':"--drag <selector> --to <selector>"}, where it is dropped.`);if(e.replace!==void 0&&i!=="type")throw n(`${o("replace")} goes with ${o("type")}: it selects what the field holds before the words go in.`);if(e.replace!==void 0&&e.replace!==!0)throw n(`${o("replace")} is true: ${t?'"replace": true':"--replace"} selects what the field holds before the words go in.`);let l=(d,h)=>{if(typeof d!="string"||!d)throw n(`${h} is words: ${JSON.stringify(d)}.`);return d},c=(d,h)=>{if(!Array.isArray(d)||d.length!==2)throw n(`${o(i)} takes ${t?`[<selector>, ${h}]`:`<selector> ${h}`}.`);return[l(d[0],"a selector"),l(d[1],h)]},r={kind:i};if(i==="press"&&(r.at=l(e.press,"a selector")),i==="drag"&&Object.assign(r,{at:l(e.drag,"a selector"),to:l(e.to,"a selector")}),i==="key"){let[d,h]=c(e.key,"<key>");Object.assign(r,{at:d,key:h,keys:await at(h)})}return i==="type"&&([r.at,r.text]=c(e.type,"<words>"),e.replace&&(r.replace=!0)),i==="select"&&([r.at,r.value]=c(e.select,"<value>")),e.then!==void 0&&(r.then={key:l(e.then,"a key"),keys:await at(l(e.then,"a key"))}),r}async function Yt(e,t={},n=!1){if(n&&e.has("--steps"))throw new T('--steps <file> holds every gesture: --replace goes in a step of it, as { "type": [".name", "\u65B0\u540D\u5B57"], "replace": true }, not beside it.');if(e.has("--steps")){let s=["--press","--drag","--to","--key","--type","--select","--then"].filter(o=>e.has(o));if(s.length)throw new T(`--steps <file> holds every gesture: ${s.join(", ")} goes in it, not beside it.`);return null}let a={};for(let s of["press","drag","to","then"])e.has(`--${s}`)&&(a[s]=e.get(`--${s}`));for(let s of["key","type","select"])e.has(`--${s}`)&&(a[s]=[e.get(`--${s}`),t[`--${s}`]]);return n&&(a.replace=!0),ut(a)}async function Xt(e){let t=A.basename(e),n;try{n=await N.readFile(e,"utf8")}catch(o){throw new T(`No steps file: ${K(e)} (${o.code??ne(o)}).`)}let a;try{a=JSON.parse(n.replace(/^/,""))}catch(o){throw new T(`${t} is no JSON: ${ne(o)}. A steps file is a list of steps, as [{ "press": ".add" }, { "type": [".name", "\u65B0\u540D\u5B57"], "then": "Enter" }].`)}if(!Array.isArray(a)||a.length===0)throw new T(`${t} holds no list of steps: write [{ "press": ".add" }, { "type": [".name", "\u65B0\u540D\u5B57"], "then": "Enter" }].`);if(a.length>tt)throw new T(`${t} holds ${a.length} steps, and a trial makes ${tt} at most: try fewer at a time.`);let s=[];for(let[o,i]of a.entries())s.push(await ut(i,`step ${o+1} of ${t}`));return s}var pt=e=>{let t=e.parentNode;for(;t&&!Re(t);)t=t.parentNode;return t??null},en=(e,t)=>{for(let n=e.parentNode;n&&n!==t;n=n.parentNode)if(jt(n))return ce(n,Ft);return null};function wt(e){let t=[];return Ht(Be(e),n=>{if(!Re(n))return;let a=pt(n);t.push({element:n,id:ce(n,ke),blockId:ce(n,"data-block-id")??null,line:n.sourceCodeLocation?.startLine,in:a?{id:ce(a,ke),line:a.sourceCodeLocation?.startLine,slot:en(n,a)}:null})},{inTemplates:!1}),t}var gt=({line:e,in:t},n)=>`${n}:${e}${t?`, in ${t.slot?`the slot ${t.slot} of `:""}${t.id} at ${n}:${t.line}`:""}`,tn=(e,{id:t,blockId:n})=>n??(e.filter(a=>a.id===t).length===1?t:null);function nn(e,t,{slug:n,name:a}){let s=()=>e.map(c=>` ${tn(e,c)??"(no id yet: gallery export gives it one)"} ${c.id} at ${gt(c,a)}`).join(`
2
+ import{c as Oe,f as we,g as ge,h as $e,i as We,j as ne,l as Y,m as Ge,n as Ae,o as Ke,p as Ve,q as ze,r as g,t as Qe,u as Ye}from"./chunk-SOD23RGL.mjs";import{M as Xe}from"./chunk-4DNHHJSL.mjs";import{f as Te,i as Je}from"./chunk-JJNRIFND.mjs";import{a as K}from"./chunk-JEUK3ZO7.mjs";import{a as me}from"./chunk-CG3UHDKH.mjs";import{a as Ue,b as Ze,f as pe,g as qe}from"./chunk-4AMTKWDO.mjs";import{e as Ne,g as te}from"./chunk-OU3S466R.mjs";import{b as Se}from"./chunk-WTEGUPFG.mjs";import{b as T,i as Pe}from"./chunk-4OZWXZE5.mjs";import{a as Be}from"./chunk-2RKIHJI2.mjs";import{f as Ee,j as He}from"./chunk-VG5JEIUQ.mjs";import{randomBytes as Ct}from"node:crypto";import{existsSync as It}from"node:fs";import N from"node:fs/promises";import A from"node:path";import{isInstance as Re,isSlot as jt,partOf as Mt}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as ke,FALLBACK as Rt,FIELDS as Dt,INSTANCE as ft,PACKAGE_ID as _t,SLOT as Ft}from"../browser/shared/components/installed.mjs";import{attr as ce,walk as Ht}from"../browser/shared/html-tree.mjs";import{documentDirectory as Pt,documentFiles as Bt,layoutOf as se,packageFolders as Jt,slugTaken as Ut}from"../browser/shared/workspace.mjs";var et=10,Ce=6,Zt=3,qt=100,De=1024,_e=900,Wt=4e3,le=3e4,Gt=1500,Ie=3e4,je=500,Kt=5e3,Vt=200,tt=20,nt=160,ye=12,zt=3600*1e3,Qt=["p","pi","pin"],he=e=>new Promise(t=>setTimeout(t,e));async function at(e){let{_keyDefinitions:t}=await import("./chunk-MKTX5PGV.mjs"),n=Object.hasOwn(t,e)?[e]:e.split("+"),a=new Set(["Control","Shift","Alt","Meta"]);if(n.some(s=>!Object.hasOwn(t,s))||n.slice(0,-1).some(s=>!a.has(s)))throw new T(`Not a key: ${e} (a key as a browser names it, Enter, Space, Escape, Tab, ArrowRight, a letter or a digit, after modifiers joined by "+": Shift+Tab, Control+Enter).`);return n}var ie={press:"<selector>",drag:'<selector>, with "to": <selector>',key:"[<selector>, <key>]",type:"[<selector>, <words>]",select:"[<selector>, <value>]"};async function ut(e,t=null){let n=d=>new T(t?`${t[0].toUpperCase()}${t.slice(1)}: ${d}`:`${d[0].toUpperCase()}${d.slice(1)}`);if(!e||typeof e!="object"||Array.isArray(e))throw n(`a step is an object naming one gesture: ${Object.entries(ie).map(([d,h])=>`"${d}": ${h}`).join(", ")}, and "then": <key> after it.`);let a=Object.keys(e).filter(d=>!Object.hasOwn(ie,d)&&!["to","then","replace"].includes(d));if(a.length)throw n(`no such field: ${a.join(", ")} (a step names one of ${Object.keys(ie).join(", ")}, "to" with a drag, "replace": true with typing and "then" after any).`);let s=Object.keys(ie).filter(d=>e[d]!==void 0),o=d=>t?`"${d}"`:`--${d}`;if(s.length!==1)throw n(s.length?`one gesture at a time: ${s.map(o).join(" or ")}.`:t?`name the gesture: ${Object.keys(ie).map(o).join(", ")}.`:"Say the gesture: --press <selector>, --drag <selector> --to <selector>, --key <selector> <key>, --type <selector> <words> or --select <selector> <value>; or --steps <file>.");let[i]=s;if(e.to!==void 0&&i!=="drag")throw n(`${o("to")} goes with ${o("drag")}: ${t?'"drag": <selector>, "to": <selector>':"--drag <selector> --to <selector>"}.`);if(i==="drag"&&e.to===void 0)throw n(`${o("drag")} takes ${o("to")}: ${t?'"drag": <selector>, "to": <selector>':"--drag <selector> --to <selector>"}, where it is dropped.`);if(e.replace!==void 0&&i!=="type")throw n(`${o("replace")} goes with ${o("type")}: it selects what the field holds before the words go in.`);if(e.replace!==void 0&&e.replace!==!0)throw n(`${o("replace")} is true: ${t?'"replace": true':"--replace"} selects what the field holds before the words go in.`);let l=(d,h)=>{if(typeof d!="string"||!d)throw n(`${h} is words: ${JSON.stringify(d)}.`);return d},c=(d,h)=>{if(!Array.isArray(d)||d.length!==2)throw n(`${o(i)} takes ${t?`[<selector>, ${h}]`:`<selector> ${h}`}.`);return[l(d[0],"a selector"),l(d[1],h)]},r={kind:i};if(i==="press"&&(r.at=l(e.press,"a selector")),i==="drag"&&Object.assign(r,{at:l(e.drag,"a selector"),to:l(e.to,"a selector")}),i==="key"){let[d,h]=c(e.key,"<key>");Object.assign(r,{at:d,key:h,keys:await at(h)})}return i==="type"&&([r.at,r.text]=c(e.type,"<words>"),e.replace&&(r.replace=!0)),i==="select"&&([r.at,r.value]=c(e.select,"<value>")),e.then!==void 0&&(r.then={key:l(e.then,"a key"),keys:await at(l(e.then,"a key"))}),r}async function Yt(e,t={},n=!1){if(n&&e.has("--steps"))throw new T('--steps <file> holds every gesture: --replace goes in a step of it, as { "type": [".name", "\u65B0\u540D\u5B57"], "replace": true }, not beside it.');if(e.has("--steps")){let s=["--press","--drag","--to","--key","--type","--select","--then"].filter(o=>e.has(o));if(s.length)throw new T(`--steps <file> holds every gesture: ${s.join(", ")} goes in it, not beside it.`);return null}let a={};for(let s of["press","drag","to","then"])e.has(`--${s}`)&&(a[s]=e.get(`--${s}`));for(let s of["key","type","select"])e.has(`--${s}`)&&(a[s]=[e.get(`--${s}`),t[`--${s}`]]);return n&&(a.replace=!0),ut(a)}async function Xt(e){let t=A.basename(e),n;try{n=await N.readFile(e,"utf8")}catch(o){throw new T(`No steps file: ${K(e)} (${o.code??ne(o)}).`)}let a;try{a=JSON.parse(n.replace(/^/,""))}catch(o){throw new T(`${t} is no JSON: ${ne(o)}. A steps file is a list of steps, as [{ "press": ".add" }, { "type": [".name", "\u65B0\u540D\u5B57"], "then": "Enter" }].`)}if(!Array.isArray(a)||a.length===0)throw new T(`${t} holds no list of steps: write [{ "press": ".add" }, { "type": [".name", "\u65B0\u540D\u5B57"], "then": "Enter" }].`);if(a.length>tt)throw new T(`${t} holds ${a.length} steps, and a trial makes ${tt} at most: try fewer at a time.`);let s=[];for(let[o,i]of a.entries())s.push(await ut(i,`step ${o+1} of ${t}`));return s}var pt=e=>{let t=e.parentNode;for(;t&&!Re(t);)t=t.parentNode;return t??null},en=(e,t)=>{for(let n=e.parentNode;n&&n!==t;n=n.parentNode)if(jt(n))return ce(n,Ft);return null};function wt(e){let t=[];return Ht(Be(e),n=>{if(!Re(n))return;let a=pt(n);t.push({element:n,id:ce(n,ke),blockId:ce(n,"data-block-id")??null,line:n.sourceCodeLocation?.startLine,in:a?{id:ce(a,ke),line:a.sourceCodeLocation?.startLine,slot:en(n,a)}:null})},{inTemplates:!1}),t}var gt=({line:e,in:t},n)=>`${n}:${e}${t?`, in ${t.slot?`the slot ${t.slot} of `:""}${t.id} at ${n}:${t.line}`:""}`,tn=(e,{id:t,blockId:n})=>n??(e.filter(a=>a.id===t).length===1?t:null);function nn(e,t,{slug:n,name:a}){let s=()=>e.map(c=>` ${tn(e,c)??"(no id yet: gallery export gives it one)"} ${c.id} at ${gt(c,a)}`).join(`
3
3
  `);if(t===null){if(e.length===1)return 0;throw new T(`${n} holds ${e.length} instances: name one, gallery block try ${n} <instance id> \u2026
4
4
  ${s()}`)}let o=e.findIndex(({blockId:c})=>c===t);if(o>=0)return o;let i=t.includes("/")?t:`local/${t}`,l=_t.test(i)?e.flatMap((c,r)=>c.id===i?[r]:[]):[];if(l.length===1)return l[0];throw new T(l.length?`${n} holds ${l.length} instances of ${i}: name one by its id
5
5
  ${s()}`:`${n} holds no instance ${t}:
@@ -0,0 +1,2 @@
1
+ import { createRequire as __galleryRequire } from "node:module"; import { fileURLToPath as __galleryPath } from "node:url"; const require = __galleryRequire(import.meta.url); const __filename = __galleryPath(import.meta.url); const __dirname = __galleryPath(new URL(".", import.meta.url));
2
+ import{a,b}from"./chunk-FX42XU6J.mjs";import"./chunk-KUILYI7H.mjs";import"./chunk-2GKGEVMR.mjs";import"./chunk-VKSRM7EY.mjs";import"./chunk-LE44MD3O.mjs";import"./chunk-4OZWXZE5.mjs";import"./chunk-7XDYK3UC.mjs";import"./chunk-VG5JEIUQ.mjs";import"./chunk-N3DSBH5S.mjs";import"./chunk-5L7RYZCL.mjs";export{a as copiedLines,b as run};