@heycys/gallery 0.2.1 → 0.2.3

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 (169) hide show
  1. package/THIRD-PARTY-NOTICES.md +1 -1
  2. package/browser/editor/page/annotate/index.mjs +3 -2
  3. package/browser/editor/page/board/index.mjs +2 -1
  4. package/browser/editor/page/board/settings.mjs +2 -1
  5. package/browser/editor/page/core.mjs +3 -2
  6. package/browser/editor/page/custom-page.mjs +4 -3
  7. package/browser/editor/page/editor.mjs +13 -7
  8. package/browser/editor/page/emoji-picker/support.mjs +3 -2
  9. package/browser/editor/page/links/index.mjs +1 -12
  10. package/browser/editor/page/links/pages.mjs +3 -2
  11. package/browser/editor/page/outline/folds.mjs +3 -0
  12. package/browser/editor/page/post.mjs +2 -1
  13. package/browser/editor/page/present-links.mjs +4 -3
  14. package/browser/editor/page/present-shell.mjs +3 -58
  15. package/browser/editor/page/session.mjs +3 -37
  16. package/browser/editor/page/storage.mjs +5 -5
  17. package/browser/shared/component-catalog.mjs +2 -2
  18. package/browser/shared/drafts.mjs +26 -51
  19. package/browser/shared/emoji/icon-value.mjs +2 -1
  20. package/browser/shared/extension-manifest.mjs +90 -0
  21. package/browser/shared/extensions.mjs +26 -16
  22. package/browser/shared/http.mjs +1 -1
  23. package/browser/shared/i18n/en.mjs +46 -15
  24. package/browser/shared/media.mjs +2 -1
  25. package/browser/shared/outline.mjs +11 -51
  26. package/browser/shared/page-address.mjs +8 -15
  27. package/browser/shared/paths.mjs +2 -1
  28. package/browser/shared/preferences.mjs +3 -1
  29. package/browser/shared/preview-server.mjs +51 -63
  30. package/browser/shared/service-location.mjs +18 -0
  31. package/browser/shared/session.mjs +3 -6
  32. package/browser/shared/workspace-address.mjs +22 -0
  33. package/browser/shared/workspace-columns.mjs +1 -2
  34. package/browser/shared/workspace-registry.mjs +6 -40
  35. package/browser/shared/workspace.mjs +3 -6
  36. package/browser/shared/writing-preferences.mjs +6 -4
  37. package/dist/{chunk-5MEXZ2UF.mjs → chunk-225ALKYI.mjs} +1 -1
  38. package/dist/{chunk-7N2LPG33.mjs → chunk-2HS7ZBPU.mjs} +1 -1
  39. package/dist/chunk-3F57LEN5.mjs +2 -0
  40. package/dist/{chunk-MKTX5PGV.mjs → chunk-43B75J5T.mjs} +1 -1
  41. package/dist/{chunk-VKSRM7EY.mjs → chunk-4B2TB5K2.mjs} +1 -1
  42. package/dist/{chunk-LV24RY2E.mjs → chunk-4K5KC6V2.mjs} +1 -1
  43. package/dist/chunk-5GK7HS62.mjs +2 -0
  44. package/dist/chunk-6GV3CBB2.mjs +2 -0
  45. package/dist/{chunk-TOE6DPLH.mjs → chunk-6NLXUKAY.mjs} +1 -1
  46. package/dist/{chunk-ZCP7BTOZ.mjs → chunk-6QBHU4DF.mjs} +1 -1
  47. package/dist/{chunk-QXVNUASA.mjs → chunk-6QWQXHAV.mjs} +1 -1
  48. package/dist/chunk-6XD6U3QA.mjs +5 -0
  49. package/dist/{chunk-DKR7LFIY.mjs → chunk-6Y3HYOBM.mjs} +1 -1
  50. package/dist/{chunk-36FIRJIF.mjs → chunk-742D2WWJ.mjs} +2 -2
  51. package/dist/{chunk-7M7UPWU6.mjs → chunk-7EFHNQ5B.mjs} +1 -1
  52. package/dist/{chunk-2GKGEVMR.mjs → chunk-7UZUQQ7Q.mjs} +25 -24
  53. package/dist/{chunk-VPVOAJ7X.mjs → chunk-AGDILNWB.mjs} +1 -1
  54. package/dist/{chunk-5IIH335D.mjs → chunk-ALZ6ZENZ.mjs} +1 -1
  55. package/dist/{chunk-G4YP7GVC.mjs → chunk-BFJGHSQN.mjs} +1 -1
  56. package/dist/{chunk-AMDGVDNV.mjs → chunk-BQNTTFPL.mjs} +1 -1
  57. package/dist/chunk-BX5AKINW.mjs +15 -0
  58. package/dist/{chunk-PAFSFVYB.mjs → chunk-BYNPEUDS.mjs} +1 -1
  59. package/dist/{chunk-74RPP2M2.mjs → chunk-C564NU2H.mjs} +1 -1
  60. package/dist/{chunk-DH6GMDNN.mjs → chunk-CRDG6EF2.mjs} +1 -1
  61. package/dist/{chunk-7XDYK3UC.mjs → chunk-E7656LR7.mjs} +1 -1
  62. package/dist/{chunk-KFZBYDIS.mjs → chunk-ECZBLQKK.mjs} +1 -1
  63. package/dist/{chunk-ZEY2RLBT.mjs → chunk-ERLAIBOA.mjs} +2 -2
  64. package/dist/{chunk-YFJU3O7G.mjs → chunk-FJLM7YE7.mjs} +1 -1
  65. package/dist/{chunk-AFGUR7SY.mjs → chunk-FNCCVGKX.mjs} +1 -1
  66. package/dist/{chunk-VNUWREXU.mjs → chunk-FOJ3K5Z3.mjs} +1 -1
  67. package/dist/{chunk-WCWYNFDF.mjs → chunk-FQ72LZHB.mjs} +1 -1
  68. package/dist/chunk-G7N7YFVD.mjs +2 -0
  69. package/dist/chunk-GIRXJBGC.mjs +2 -0
  70. package/dist/{chunk-VA3KAQZD.mjs → chunk-GKOBB6DH.mjs} +1 -1
  71. package/dist/chunk-GMJD7ID3.mjs +2 -0
  72. package/dist/chunk-GQJMVSSN.mjs +2 -0
  73. package/dist/{chunk-QZ35UAB4.mjs → chunk-GRAXKKG4.mjs} +1 -1
  74. package/dist/{chunk-SAHS56QM.mjs → chunk-HX4DLE3J.mjs} +1 -1
  75. package/dist/{chunk-2RKIHJI2.mjs → chunk-HYMEEXKN.mjs} +1 -1
  76. package/dist/{chunk-QK3VISCA.mjs → chunk-IA4PSIMD.mjs} +1 -1
  77. package/dist/chunk-IS7N3N6Q.mjs +168 -0
  78. package/dist/{chunk-CZ5KJSGK.mjs → chunk-JJNHKGTD.mjs} +1 -1
  79. package/dist/chunk-JPG2LBQM.mjs +11 -0
  80. package/dist/chunk-JYK5WJPM.mjs +2 -0
  81. package/dist/{chunk-LE44MD3O.mjs → chunk-KLQP46Y3.mjs} +1 -1
  82. package/dist/chunk-L55NOXBE.mjs +4 -0
  83. package/dist/{chunk-FXQBADMN.mjs → chunk-LCB6MARS.mjs} +1 -1
  84. package/dist/{chunk-SOD23RGL.mjs → chunk-LJLVCU6W.mjs} +8 -8
  85. package/dist/{chunk-NAGMRVW4.mjs → chunk-LKX55H76.mjs} +1 -1
  86. package/dist/chunk-LMUZQK5O.mjs +2 -0
  87. package/dist/{chunk-CG3UHDKH.mjs → chunk-M4NRDYI5.mjs} +1 -1
  88. package/dist/{chunk-HM4E43VM.mjs → chunk-MAFIGVXY.mjs} +1 -1
  89. package/dist/chunk-NLDF35P5.mjs +2 -0
  90. package/dist/{chunk-3OFXMN6N.mjs → chunk-NMF3IPYA.mjs} +1 -1
  91. package/dist/chunk-ONKC4BCC.mjs +2 -0
  92. package/dist/{chunk-CPS4SRPF.mjs → chunk-OU6ZZVBX.mjs} +2 -2
  93. package/dist/{chunk-NWRZXELO.mjs → chunk-PAREWQGB.mjs} +1 -1
  94. package/dist/{chunk-BYSF5UMM.mjs → chunk-PKVK6WFC.mjs} +2 -2
  95. package/dist/{chunk-4AMTKWDO.mjs → chunk-PUOQ65NC.mjs} +1 -1
  96. package/dist/{chunk-L7W624FD.mjs → chunk-QJAVCTY7.mjs} +1 -1
  97. package/dist/{chunk-6MPKCH3P.mjs → chunk-QNECWMGR.mjs} +1 -1
  98. package/dist/{chunk-HBAUKKQH.mjs → chunk-QP7BOHE4.mjs} +1 -1
  99. package/dist/chunk-QVGOPHOF.mjs +2 -0
  100. package/dist/{chunk-NFABH3QW.mjs → chunk-RRKJMHNX.mjs} +2 -2
  101. package/dist/chunk-S3SX3COT.mjs +20 -0
  102. package/dist/chunk-SQ3FQCCN.mjs +8 -0
  103. package/dist/{chunk-ZO7SFB2E.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
  104. package/dist/{chunk-3A5I2GJK.mjs → chunk-T4Y2ZSVX.mjs} +1 -1
  105. package/dist/{chunk-VG5JEIUQ.mjs → chunk-TKWEX4FD.mjs} +2 -2
  106. package/dist/{chunk-CCSGFCLZ.mjs → chunk-U3SSPL4K.mjs} +1 -1
  107. package/dist/{chunk-DHB7UZ7F.mjs → chunk-U5XL7D6A.mjs} +1 -1
  108. package/dist/{chunk-JXLSHVJ2.mjs → chunk-UMHUSOPJ.mjs} +1 -1
  109. package/dist/chunk-UTF7GBQU.mjs +4 -0
  110. package/dist/chunk-UTMAY3WK.mjs +2 -0
  111. package/dist/{chunk-S2Y7VI4H.mjs → chunk-V4ZHRALW.mjs} +2 -2
  112. package/dist/{chunk-GWOYMENX.mjs → chunk-V6XZ4VIR.mjs} +1 -1
  113. package/dist/{chunk-WTEGUPFG.mjs → chunk-VRPVVMRB.mjs} +1 -1
  114. package/dist/{chunk-XKOHV4H6.mjs → chunk-W5NPH5UA.mjs} +1 -1
  115. package/dist/{chunk-VGTMLQWZ.mjs → chunk-WD4U6XXT.mjs} +1 -1
  116. package/dist/{chunk-4DNHHJSL.mjs → chunk-XBNFXWAW.mjs} +1 -1
  117. package/dist/chunk-XZV72SQ4.mjs +2 -0
  118. package/dist/{chunk-QJ3TFJLQ.mjs → chunk-Y34NR5JL.mjs} +1 -1
  119. package/dist/{chunk-YBB5LWZK.mjs → chunk-YFJB534W.mjs} +1 -1
  120. package/dist/{chunk-V5JRSGZF.mjs → chunk-YN37ZDLW.mjs} +1 -1
  121. package/dist/chunk-Z6OKLRHC.mjs +2 -0
  122. package/dist/chunk-ZLS2FRS6.mjs +3 -0
  123. package/dist/{chunk-JI6T3A4Y.mjs → chunk-ZMHUDYLV.mjs} +1 -1
  124. package/dist/{chunk-KH24LWAT.mjs → chunk-ZTHICSSF.mjs} +1 -1
  125. package/dist/cli.mjs +1 -1
  126. package/dist/server.mjs +1 -1
  127. package/dist/worker.mjs +1 -1
  128. package/kit/math.js +1 -1
  129. package/kit/runtime.js +13 -2
  130. package/kit/state.js +2 -0
  131. package/kit/ui.js +5 -1
  132. package/package.json +1 -1
  133. package/release.json +7 -7
  134. package/skill/SKILL.md +13 -13
  135. package/skill/references/building-blocks.md +1 -1
  136. package/skill/references/extensions.md +45 -9
  137. package/web/assets/index-D8P8uhDW.js +15 -0
  138. package/web/assets/{index-xP0uw3a0.css → index-FLb9jCfl.css} +1 -1
  139. package/web/index.html +2 -2
  140. package/dist/chunk-46ACXOU5.mjs +0 -2
  141. package/dist/chunk-5DPABPBI.mjs +0 -2
  142. package/dist/chunk-5L26JUYA.mjs +0 -2
  143. package/dist/chunk-AEMVZYZQ.mjs +0 -166
  144. package/dist/chunk-ASAXY2DJ.mjs +0 -2
  145. package/dist/chunk-DAMVDXR3.mjs +0 -2
  146. package/dist/chunk-DLFZJJEE.mjs +0 -2
  147. package/dist/chunk-EKNHM3P4.mjs +0 -2
  148. package/dist/chunk-FCK6NXON.mjs +0 -3
  149. package/dist/chunk-FX42XU6J.mjs +0 -2
  150. package/dist/chunk-HATA2W7X.mjs +0 -2
  151. package/dist/chunk-JJNRIFND.mjs +0 -8
  152. package/dist/chunk-JL6R4FG4.mjs +0 -4
  153. package/dist/chunk-KUILYI7H.mjs +0 -4
  154. package/dist/chunk-NIW7F7LU.mjs +0 -4
  155. package/dist/chunk-OU3S466R.mjs +0 -20
  156. package/dist/chunk-QCEATQC4.mjs +0 -2
  157. package/dist/chunk-TDWJKOLN.mjs +0 -2
  158. package/dist/chunk-UGO5N3EI.mjs +0 -15
  159. package/dist/chunk-XMKHCUI6.mjs +0 -15
  160. package/dist/chunk-XQRUG4G3.mjs +0 -2
  161. package/dist/chunk-YPPJVDQI.mjs +0 -2
  162. package/dist/chunk-ZANMKAWS.mjs +0 -2
  163. package/web/assets/index-BHC5ZOMh.js +0 -15
  164. /package/dist/{chunk-N3DSBH5S.mjs → chunk-A55HN5OK.mjs} +0 -0
  165. /package/dist/{chunk-KNZJT4ET.mjs → chunk-QAIHRH3I.mjs} +0 -0
  166. /package/dist/{chunk-ZW2A6GBW.mjs → chunk-QR6A54KJ.mjs} +0 -0
  167. /package/dist/{chunk-74UW7QSL.mjs → chunk-UH4SIXTR.mjs} +0 -0
  168. /package/dist/{chunk-EKGYYOSP.mjs → chunk-W7XHE4CT.mjs} +0 -0
  169. /package/dist/{chunk-5MMN3N5J.mjs → chunk-YEY3RSFQ.mjs} +0 -0
@@ -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{a as ue,b as we,k as ge,v as $e,w as be}from"./chunk-SOD23RGL.mjs";import{M as ye}from"./chunk-4DNHHJSL.mjs";import"./chunk-342HXE3Q.mjs";import"./chunk-3A5I2GJK.mjs";import{c as R,f as ke}from"./chunk-S2Y7VI4H.mjs";import"./chunk-XQRUG4G3.mjs";import{a as P}from"./chunk-JEUK3ZO7.mjs";import"./chunk-4AMTKWDO.mjs";import"./chunk-QXVNUASA.mjs";import"./chunk-FCK6NXON.mjs";import"./chunk-OU3S466R.mjs";import"./chunk-QK3VISCA.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-F4ZA6JRZ.mjs";import"./chunk-7M2BQQGZ.mjs";import"./chunk-TOE6DPLH.mjs";import{b as de,h as D}from"./chunk-WTEGUPFG.mjs";import"./chunk-2GKGEVMR.mjs";import{n as ie}from"./chunk-LE44MD3O.mjs";import"./chunk-4OZWXZE5.mjs";import{a as pe,j as fe,s as me}from"./chunk-XMKHCUI6.mjs";import{d as re,e as le,i as I,j as ce,k as he}from"./chunk-SAHS56QM.mjs";import"./chunk-KH24LWAT.mjs";import{a as g}from"./chunk-YFJU3O7G.mjs";import"./chunk-NWRZXELO.mjs";import"./chunk-G4YP7GVC.mjs";import"./chunk-DHB7UZ7F.mjs";import{a as z,c as S}from"./chunk-2RKIHJI2.mjs";import"./chunk-JXLSHVJ2.mjs";import"./chunk-XKOHV4H6.mjs";import"./chunk-KFZBYDIS.mjs";import{c as ae}from"./chunk-7XDYK3UC.mjs";import{a as F,f as te,h as se,j as U,r as ne,s as oe}from"./chunk-VG5JEIUQ.mjs";import"./chunk-N3DSBH5S.mjs";import"./chunk-5L7RYZCL.mjs";import{isUtf8 as Ue}from"node:buffer";import X from"node:fs";import E from"node:path";import{instanceSlots as ze,instancesOf as Y,isInstance as Z,partOf as W}from"../browser/shared/components/index.mjs";import{fewestSyllables as Oe}from"../browser/shared/pinyin.mjs";import{ATTRIBUTE as $,refusedInCopy as De}from"../browser/shared/components/installed.mjs";import{attr as b,elementsOf as Q,walk as A}from"../browser/shared/html-tree.mjs";import{blankedCss as M}from"../browser/shared/css-references.mjs";import{ATTRIBUTE as G,SLOT as Le}from"../browser/shared/components/installed.mjs";var Ae=new Set(["media","supports","container","layer","starting-style"]);function K(e,t){let s=0,o="";for(let n=0;n<e.length;n++){let i=e[n];i==="\\"?n++:o?o=i===o?"":o:i==='"'||i==="'"?o=i:i===")"||i==="]"?s--:(s===0&&t(i,n),(i==="("||i==="[")&&s++)}}function Ce(e){let t=M(e),s=M(e,{strings:!0}),o={children:[]},n=[o],i=0,r=0;for(let a=0;a<t.length;a++){let l=t[a];if(l==="\\")a++;else if(l==="("||l==="[")r++;else if(l===")"||l==="]")r=Math.max(0,r-1);else{if(r>0)continue;if(l==="{"){let c={prelude:s.slice(i,a),start:i,children:[]};n.at(-1).children.push(c),n.push(c),i=a+1}else l==="}"?(n.length>1&&n.pop(),i=a+1):l===";"&&(i=a+1)}}return o.children}function _(e){let t=[],s=0;return K(e,(o,n)=>{o===","&&(t.push({text:e.slice(s,n),start:s}),s=n+1)}),t.push({text:e.slice(s),start:s}),t.filter(({text:o})=>o.trim())}function H(e){let t=[],s=e.trim(),o="",n=0,i=0,r=a=>{(i||a)>n&&t.push({combinator:o,compound:s.slice(n,i||a)}),i=0};return K(s,(a,l)=>{/\s/.test(a)?l===n?n=l+1:i||=l:">+~".includes(a)?(r(l),o=a,n=l+1):i&&(r(l),o=" ",n=l)}),r(s.length),t}function B(e){let t=[],s=-1,o=0,n="";for(let r=0;r<e.length;r++){let a=e[r];a==="\\"?r++:n?n=a===n?"":n:a==='"'||a==="'"?n=a:a==="("?o++:a===")"?o--:a==="["&&o===0?s=r:a==="]"&&o===0&&s>=0&&(t.push(e.slice(s,r+1)),s=-1)}let i=!1;return K(e,r=>{i||=r==="&"}),{attributes:t,nesting:i,scope:/(?:^|[^\w-]):scope\b/.test(e)}}var Ie=e=>new RegExp(`^\\[\\s*${G}\\s*=\\s*(["'])${e.replace(/[/-]/g,"\\$&")}\\1\\s*i?\\s*\\]$`,"i"),Pe=e=>M(e).replace(/\\.|\[[^\]]*\]/g,"").includes("&");function xe(e,t,s,o=!1){let n=H(e),i=({compound:f})=>B(f).attributes.some(h=>t.test(h)),r=({compound:f})=>{let{nesting:h,scope:m}=B(f);return!!s&&(h||m)},a=f=>["+","~"].includes(f?.combinator),l=f=>n.slice(f).some(({combinator:h},m)=>(m+f===0?h||" ":h)===" "),c=n.findLastIndex(f=>i(f)||r(f));if(c<0)return!s||Pe(e)?{why:"outside"}:{why:s==="instance"&&a(n[0])?"beside":null,subject:"inside",deep:o||l(0)};let p=i(n[c])||s==="instance";return{why:p&&a(n[c+1])?"beside":null,subject:p&&c===n.length-1?"instance":"inside",deep:!i(n[c])&&o||l(c+1)}}var Se=e=>e.some(({subject:t})=>t==="instance")?"instance":"inside",Re=new RegExp(`^\\[\\s*${Le}\\s*(?:\\]|=)`,"i"),Fe=e=>_(/\)\s*to\s*\(([^)]*)\)/i.exec(e)?.[1]??"").some(({text:t})=>H(t).length===1&&B(t).attributes.some(s=>Re.test(s))),je=(e,t)=>Ne(e,t).outside;function Ee(e,t,s){if(s.length===0)return[];let o=`slot${s.length===1?"":"s"} ${s.join(" and ")}`;return Ne(e,t).deep.map(({line:n,words:i})=>({line:n,what:`${i} also reaches the blocks in ${o}, the document's: write each step with > or wrap the rules in @scope ([${G}="${t}"]) to ([${Le}])`}))}function Ne(e,t){let s=Ie(t),o=`[${G}="${t}"]`,n=[],i=[],r=(l,c,p)=>{let f=c.replace(/\s+/g," ").trim();n.push({line:S(e,l),what:p==="beside"?`${f} reaches what stands beside the instance: what it styles has to stand in it`:`${f} reaches outside the instance: start it at ${o}`})},a=(l,c,p=!1,f=!1)=>{for(let h of l){let m=h.prelude.length-h.prelude.trimStart().length,u=h.start+m,y=/^@([\w-]+)\s*/.exec(h.prelude.trim());if(y){let d=y[1].toLowerCase();if(Ae.has(d))a(h.children,c,p,f);else if(d==="page")n.push({line:S(e,u),what:"@page reaches the paper of the whole document: an instance has no page of its own"});else if(d==="scope"){let x=/^@scope\s*\(([^)]*)\)/i.exec(h.prelude.trim())?.[1]??"",L=_(x).map(({text:j})=>({...xe(j,s,c),steps:H(j).length}));x&&L.every(({why:j,steps:Te})=>!j&&Te===1)?a(h.children,Se(L),!1,f||Fe(h.prelude.trim())):r(u,h.prelude,"outside")}continue}let k=_(h.prelude).map(({text:d,start:x})=>{let L=xe(d,s,c,p),j=h.start+x+d.length-d.trimStart().length;return L.why?r(j,d,L.why):L.deep&&!f&&!p&&i.push({line:S(e,j),words:d.replace(/\s+/g," ").trim()}),L});k.some(({why:d})=>d)||a(h.children,Se(k),k.some(d=>d.deep),f)}};return a(Ce(e),null),{outside:n,deep:i}}var w="template.html",N="example.html",O="component.json",Me=new Set(["localStorage","sessionStorage"]),_e=/^\S+: (?:line \d+ of )?its (?:kit\.js|style\.css) /,Be=/(?: (?:names a file that )?is not in the document's folder|: it is (?:no file of|not in) the document's .*)$|^external resources are not portable: .*$/,Ge=": an example stands in no document: write a picture as a data: address, or draw it from style.css with a file the manifest's assets name",Ke=e=>e.replace(Be,t=>(t.startsWith("external")?t:"")+Ge),T=(e,t)=>I({folder:e},t);function C(e,t){let s=null;try{s=X.readFileSync(E.join(e,t))}catch{return null}return Ue(s)?null:{file:t,what:"it is not UTF-8: save it as UTF-8 (PowerShell's > writes UTF-16; Set-Content -Encoding utf8 does not)"}}function J(e,t){let s=/^line (\d+): | \(line (\d+)\)/.exec(t);return s?{file:e,line:Number(s[1]??s[2]),what:t.replace(s[0],"")}:{file:e,what:t}}function v(e,t){let s=g.parseJsonText(O,e),o=s.statements[0]?.expression,n=null;for(let i of t.split(".")){let r=o?.properties?.find(({name:a})=>a?.text===i);if(!r)break;n=s.getLineAndCharacterOfPosition(r.getStart(s)).line+1,o=r.initializer}return n}function He(e,{message:t,text:s="",values:o=[]}){let n=/at position (\d+)/.exec(t)?.[1];if(n)return S(e,Number(n));for(let i of[...o.map(String),...s.match(/[a-zA-Z][\w.]*/g)??[]]){let r=v(e,i);if(r)return r}return null}var Je=e=>D(e).map(t=>/^line (\d+): <([^>]+)>: ([\s\S]*)$/.exec(t)).filter(Boolean).map(([,t,s,o])=>({line:Number(t),tag:s,why:o}));function qe(e,{file:t,tree:s,html:o}){let n=[],i=Je(o),r=Object.entries(e.parts).filter(([,c])=>c.edit==="text"),a=Object.entries(e.parts).filter(([,c])=>c.edit==="data"),l=(c,p)=>{let f=!1;return A(c,h=>{f||=h===p}),f};for(let c of Y(s,e))for(let[p,f]of r)for(let h of W(c,f.at)){let m=h.sourceCodeLocation?.startLine,u=Q(h).find(d=>ae.has(d.tagName)),y=i.find(d=>d.line===m&&d.tag===h.tagName),k=a.find(([,d])=>W(c,d.at).some(x=>x===h||l(x,h)||l(h,x)))?.[0];k?n.push({file:t,line:m,what:`the part ${p} (${f.at}) is edited as text, and stands in the part ${k}, edited as data, or around it, which is the component's: the editor leaves it read-only: name elements apart`}):u?n.push({file:t,line:m,what:`the part ${p} (${f.at}) is edited as text and holds a block, its <${u.tagName}> at line ${u.sourceCodeLocation?.startLine}: a text part holds words and marks alone, and the editor would leave this one read-only: write its \`at\` as what holds the words (${f.at} > ${u.tagName}), or give each block a part of its own`}):y&&n.push({file:t,line:m,what:`the part ${p} (${f.at}) is edited as text, and the editor would leave it read-only for what it holds: ${y.why}. A text part holds words and marks alone`})}return n}var ee=new RegExp("\\p{Script=Han}","u"),ve=e=>[...e].filter(t=>ee.test(t)).length,Ve={test:e=>{let t=Oe(e);return t!==null&&t<=8}};function We({name:e,words:t}){let s=ve(e.zh),o=t.split(/\s+/).filter(Boolean);return s===0?ee.test(t)&&!o.some(n=>Ve.test(n)):!o.some(n=>Oe(n.toLowerCase())===s)}function Xe({id:e,folder:t,catalog:s,off:o,parts:n}){let i=s.packages.get(e),r=s.problems.get(e)?.problem,a=T(t,O)??"",l=[];r&&l.push({file:O,line:He(a,r),what:U("en",r)}),i?.template===null&&l.push({file:w,what:`there is none, and it is what "/" puts in a document: with none, no menu offers the block: write one <div ${$}="${e}"> with what a new instance holds`}),l.push(...n);let c=C(t,"writing.md");c&&l.push(c);let p=c||T(t,"writing.md")?.trim()?[]:[{file:"writing.md",what:"there is none, so gallery block show has nothing to say of how to write it"}];i&&We(i)&&p.push({file:O,line:v(a,"words")??v(a,"name.zh"),what:ee.test(i.name.zh)?`no word of words spells its whole name ${i.name.zh} in pinyin as an input method composes it, its ${ve(i.name.zh)} Chinese characters a syllable each in one word (as \u65B9\u6848\u6253\u5206 is fangandafen): "/" finds it while those letters are being composed only by such a word. What is counted is how many syllables a word reads as, not which characters they spell`:'its words are Chinese and none of them is pinyin: "/" goes by the letters an input method is composing, so write the pinyin there (\u770B\u677F kanban)'});let f=(()=>{try{return ie(X.readFileSync(E.join(t,"preview.svg")),e)}catch{return null}})();return f&&p.push({file:"preview.svg",what:`it is Gallery's ${f.id} picture, byte for byte (a block made with --recipe keeps its recipe's drawing, which the menu shows beside this block's name): draw this block's own, or delete preview.svg, which the menu does without`}),o&&p.push({file:"gallery.json",what:"the user turned it off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868, which is theirs to change and says nothing of the block: it is checked as if it were on, and the instances of a document show what they hold, read-only, until it is on"}),i&&(l.push(...Ze(i)),p.push(...Ye(i,a))),{title:"manifest",problems:l,notes:p}}function Ye({places:e,parts:t,card:s},o){let n=[];if(e.includes("page"))for(let[i,r]of Object.entries(t))r.edit==="text"&&n.push({file:O,line:v(o,`parts.${i}`),what:`the part ${i} is edited as text, which is read-only on a custom page (no editor runs there): a block whose places hold page keeps what a reader changes there in a data part, with its own field or the card's settings`});else v(o,"card")&&n.push({file:O,line:v(o,"card"),what:`card is for a custom page's board, and its places (${e.join(", ")}) hold no page: nothing reads it`});return n}function Ze(e){if(e.settings.length===0||!e.template)return[];let t=ne(e.template,e.id),s=t?W(t.root,e.parts[F].at):[];if(s.length!==1||(b(s[0],"type")??"").trim().toLowerCase()!=="application/json")return[{file:w,what:`its manifest has settings, and the template holds ${s.length===1?`a <${s[0].tagName}> where`:`${s.length} elements of`} its settings part (${e.parts[F].at}): it is to hold one <script type="application/json">, the values a new card starts with ({} for each setting's default)`}];let o=s[0].childNodes.map(n=>n.value??"").join("").trim();try{let n=JSON.parse(o||"{}");if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("it is no object");return[]}catch(n){return[{file:w,line:s[0].sourceCodeLocation?.startLine,what:`its settings part is not a JSON object (${n.message}): write {} or the values of some of its settings, by key`}]}}function Qe(e){let t=g.createSourceFile("kit.js",e,g.ScriptTarget.Latest,!0,g.ScriptKind.JS),s=[],o=n=>{let i=g.isCallExpression(n)&&g.isPropertyAccessExpression(n.expression)?n.expression:null;if(i?.name.text==="component"&&/\bDocKit$/.test(i.expression.getText(t))){let[r]=n.arguments,a=r&&g.isObjectLiteralExpression(r)?r.properties.find(c=>c.name?.getText(t)==="id"):null,l=a&&g.isPropertyAssignment(a)&&g.isStringLiteralLike(a.initializer)?a.initializer.text:null;s.push({id:l,at:n.getStart(t)})}g.forEachChild(n,o)};return o(t),s}function et(e){let t="kit.js";if(!e.files.includes("kit.js"))return{title:t,none:"none: a static block"};let s=C(e.folder,t);if(s)return{title:t,stops:!0,problems:[s]};let o=I(e,"kit.js")??"",n=pe(o);if(n)return{title:t,stops:!0,problems:[{file:t,line:n.line,what:`a browser refuses it: ${n.message}`}]};let i=he(e).map(({line:c,what:p})=>({file:t,line:c,what:p})),r=i.length>0;for(let{name:c,at:p}of re(o,Me))i.push({file:t,line:S(o,p),what:`uses ${c}: an instance keeps what a reader chose with context.state`});let a=Qe(o);for(let{id:c,at:p}of a)c!==null&&c!==e.id&&i.push({file:t,line:S(o,p),what:`it registers ${c}, and this block is ${e.id}`});let l=a.length?[]:[{file:t,what:`no DocKit.component({ id: "${e.id}", mount(host, context) { \u2026 } }) is to be read in it, and a script may make that call in ways reading does not tell: running it says whether it starts one`}];for(let{line:c,code:p,message:f,refused:h}of le(o,{assets:e.assets}))(h?i:l).push({file:t,line:c,what:`TS${p}: ${f}`});return{title:t,stops:r,problems:i.sort((c,p)=>(c.line??0)-(p.line??0)),notes:l}}function tt(e){let t="style.css";if(!e.files.includes("style.css"))return{title:t,none:"none"};let s=C(e.folder,t);if(s)return{title:t,stops:!0,problems:[s]};let o=I(e,"style.css")??"",n=ce(e),i=[...je(o,e.id),...n].map(({line:l,what:c})=>({file:t,line:l,what:c})),r=Object.entries(e.parts??{}).filter(([,{edit:l}])=>l==="flow").map(([l])=>l),a=Ee(o,e.id,r).map(({line:l,what:c})=>({file:t,line:l,what:c}));return{title:t,stops:n.length>0,problems:i.sort((l,c)=>l.line-c.line),notes:a}}function st(e,{tree:t}){let s=null;A(t,a=>{s??=a.tagName==="main"?a:null});let o=Q(s??{}),n=(s?.childNodes??[]).some(a=>a.nodeName==="#text"&&a.value.trim()),[i]=o;if(o.length!==1||n||!Z(i)||b(i,$)!==e)return[{file:w,line:i?.sourceCodeLocation?.startLine,what:`a template is one element, a <div ${$}="${e}"> or a <section>, and it holds ${o.length===1&&!n?`<${i.tagName}${b(i,$)?` ${$}="${b(i,$)}"`:""}>`:`${o.length} element${o.length===1?"":"s"}${n?" and words":""}`}`}];let r=[];return A({childNodes:[i]},a=>{b(a,"data-block-id")!==void 0&&r.push({file:w,line:a.sourceCodeLocation?.startLine,what:"it writes a data-block-id, which every instance made of it would repeat: leave it out, Gallery gives a block its id"})}),r}var nt=[[e=>b(e,"data-doc-chart")!==void 0,e=>`a chart (<${e.tagName} data-doc-chart="${b(e,"data-doc-chart")}">)`],[e=>e.tagName==="figure",()=>"a card (<figure>)"],[e=>e.tagName==="caption",()=>"a table's <caption>"],[Z,e=>`an instance of ${b(e,$)}`]];function ot(e,t){let s=null;if(A(z(t),i=>{s??=Z(i)&&b(i,$)===e?i:null}),!s)return[];let o=[],n=(i,r)=>{for(let a of Q(i)){let l=nt.find(([c])=>c(a));l?o.push({file:w,line:a.sourceCodeLocation?.startLine,what:`its slot ${b(r,"data-doc-slot")} holds ${l[1](a)}, which a new block from "/" would not have: a menu makes what a template's slot holds as a paste of it makes blocks, and a paste makes no chart, card, table caption or instance of a block. Keep the template's slots to blocks the page makes (paragraphs, headings, lists, quotes, code, a plain table, a disclosure), and show the rest in example.html`}):n(a.tagName==="template"?a.content:a,r)}};for(let i of ze(s))n(i,i);return o}function it(e,{tree:t}){let s=oe(e);if(!s)return[];let[o]=Y(t,e),n=null;return o&&A({childNodes:[o]},i=>{De(i.tagName,i.attrs)&&(n??=i)}),[{file:w,line:(n??o)?.sourceCodeLocation?.startLine,what:U("en",s)}]}function at(e){return[[w,"component-template"],[N,"component-example"]].flatMap(([t,s])=>{let o=T(e,t);if(o===null||!o.trim()||C(e,t))return[];let n=ge(s,o),{text:i}=de(n);return[{file:t,slug:s,written:n,html:i,tree:z(i)}]})}function rt({id:e,folder:t,found:s,pages:o,parts:n}){let i="template.html and example.html",r=[],a=[];for(let h of[w,N]){let m=C(t,h);m?r.push(m):h===w&&!T(t,h)?.trim()&&s.template!==null?r.push({file:h,what:"it is empty"}):h===N&&!o.some(u=>u.file===h)&&r.push({file:h,what:`there is none or it is empty: write an instance as a writer would fill it, a <div ${$}="${e}">; it is what this check runs`})}let l=o.find(h=>h.file===w);l&&r.push(...st(e,l),...ot(e,l.written));let c=o.find(h=>h.file===N);c&&Y(c.tree,s).length===0&&r.push({file:N,what:`it holds no instance of ${e}: a <div ${$}="${e}">`});let p=o.map(({slug:h,written:m,html:u,file:y})=>({file:y,slug:h,written:m,html:u,directory:E.join(t,h),htmlPath:E.join(t,h,"doc.html"),metadata:{title:h,description:h,type:"component"}})),f=fe(p);for(let h of p){for(let m of f.get(h.slug)??[])_e.test(m)||r.push(J(h.file,Ke(m)));for(let m of me(h))a.push(J(h.file,m));for(let m of D(h.html)){let u=J(h.file,`${m} (read-only in the preview)`);n.some(({file:y,line:k})=>y===u.file&&k===u.line)||a.push(u)}}return l&&!r.some(({file:h})=>h===w)&&r.push(...it(s,l)),{title:i,problems:r,notes:a}}function lt(e,t){let s=te(e,void 0,{on:t}),o=R(e,t);if(!s.packages.has(t)&&!s.problems.has(t))return null;se(e,s);let n=s.packages.has(t)&&s.settings.disabled.includes(t),i=s.packages.get(t)??{id:t,folder:o,files:["kit.js","style.css"].filter(c=>X.existsSync(E.join(o,c)))},r=at(o),a=s.packages.has(t)?null:"its manifest does not load",l=a?[]:r.flatMap(c=>qe(i,c));return{found:s.packages.get(t)??null,pages:r,sections:[Xe({id:t,folder:o,catalog:s,off:n,parts:l}),et(i),tt(i),a?{title:"template.html and example.html",skipped:a}:rt({id:t,folder:o,found:i,pages:r,parts:l})]}}var q=({file:e,line:t})=>t?`${e}:${t}`:e;function V({title:e,problems:t=[],notes:s=[],told:o=[],none:n,skipped:i,unverified:r,pictures:a},l){let c=r?`UNVERIFIED ${r}`:i?`not run: ${i}`:n??(t.length?`${t.length} problem${t.length===1?"":"s"}`:`ok${s.length?`, ${s.length} note${s.length===1?"":"s"}`:""}`);return[`${l}. ${e}: ${c}`,...t.map(p=>` FAIL ${q(p)}: ${p.what}`),...s.map(p=>` note ${q(p)}: ${p.what}`),...o.map(p=>` way back ${q(p)}: ${p.what}`),...a?[ct(a)]:[]]}function ct({folder:e,overviews:t,each:s,edited:o=[],asExport:n=[],documents:i=!1}){let r=t.length?`${P(E.join(e,t[0]))}${t.slice(1).map(c=>` and ${c}`).join("")}, the three widths of each theme side by side; then each at full size: `:`${P(e)}: `,a=n.length===0?"":n.length===o.length?", each the same picture as the export's at its width: the block draws nothing more where a reader can edit":`, ${n.join(" and ")} the same picture as the export's at its width`,l=o.length?`; and ${o.join(" and ")}, as the editing page draws it (context.canEdit() true)${a}`:"";return` Pictures (none looked at for you; ${i?"each instance under a line naming where it stands in the document":"example.html above the line, template.html below it, each under its name"}): ${r}${s.join(", ")}${l}`}function ht([e,t,s,o]){return e.problems.length?"the manifest":t.stops?"kit.js":s.stops?"style.css":o.skipped||o.problems.length?"template.html and example.html":null}async function Ut(e,t,{documents:s=!1}={}){let o=lt(e,t);o||(console.error(ke(e,t)),process.exit(1)),console.log(`${t}: ${P(R(e,t))}`),o.sections.forEach((p,f)=>console.log(V(p,f+1).join(`
2
+ import{a as ue,b as we,k as ge,v as $e,w as be}from"./chunk-LJLVCU6W.mjs";import{M as ye}from"./chunk-XBNFXWAW.mjs";import"./chunk-342HXE3Q.mjs";import"./chunk-T4Y2ZSVX.mjs";import{c as R,f as ke}from"./chunk-V4ZHRALW.mjs";import"./chunk-5GK7HS62.mjs";import{a as P}from"./chunk-JEUK3ZO7.mjs";import"./chunk-PUOQ65NC.mjs";import"./chunk-6QWQXHAV.mjs";import"./chunk-ZLS2FRS6.mjs";import"./chunk-S3SX3COT.mjs";import"./chunk-IA4PSIMD.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-F4ZA6JRZ.mjs";import"./chunk-7M2BQQGZ.mjs";import"./chunk-6NLXUKAY.mjs";import{b as de,h as D}from"./chunk-VRPVVMRB.mjs";import"./chunk-7UZUQQ7Q.mjs";import{n as ie}from"./chunk-KLQP46Y3.mjs";import"./chunk-4OZWXZE5.mjs";import{a as pe,j as fe,s as me}from"./chunk-BX5AKINW.mjs";import{d as re,e as le,i as I,j as ce,k as he}from"./chunk-HX4DLE3J.mjs";import"./chunk-ZTHICSSF.mjs";import{a as g}from"./chunk-FJLM7YE7.mjs";import"./chunk-PAREWQGB.mjs";import"./chunk-BFJGHSQN.mjs";import"./chunk-U5XL7D6A.mjs";import{a as z,c as S}from"./chunk-HYMEEXKN.mjs";import"./chunk-UMHUSOPJ.mjs";import"./chunk-W5NPH5UA.mjs";import"./chunk-ECZBLQKK.mjs";import{c as ae}from"./chunk-E7656LR7.mjs";import{a as F,f as te,h as se,j as U,r as ne,s as oe}from"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";import{isUtf8 as Ue}from"node:buffer";import X from"node:fs";import E from"node:path";import{instanceSlots as ze,instancesOf as Y,isInstance as Z,partOf as W}from"../browser/shared/components/index.mjs";import{fewestSyllables as Oe}from"../browser/shared/pinyin.mjs";import{ATTRIBUTE as $,refusedInCopy as De}from"../browser/shared/components/installed.mjs";import{attr as b,elementsOf as Q,walk as A}from"../browser/shared/html-tree.mjs";import{blankedCss as M}from"../browser/shared/css-references.mjs";import{ATTRIBUTE as G,SLOT as Le}from"../browser/shared/components/installed.mjs";var Ae=new Set(["media","supports","container","layer","starting-style"]);function K(e,t){let s=0,o="";for(let n=0;n<e.length;n++){let i=e[n];i==="\\"?n++:o?o=i===o?"":o:i==='"'||i==="'"?o=i:i===")"||i==="]"?s--:(s===0&&t(i,n),(i==="("||i==="[")&&s++)}}function Ce(e){let t=M(e),s=M(e,{strings:!0}),o={children:[]},n=[o],i=0,r=0;for(let a=0;a<t.length;a++){let l=t[a];if(l==="\\")a++;else if(l==="("||l==="[")r++;else if(l===")"||l==="]")r=Math.max(0,r-1);else{if(r>0)continue;if(l==="{"){let c={prelude:s.slice(i,a),start:i,children:[]};n.at(-1).children.push(c),n.push(c),i=a+1}else l==="}"?(n.length>1&&n.pop(),i=a+1):l===";"&&(i=a+1)}}return o.children}function _(e){let t=[],s=0;return K(e,(o,n)=>{o===","&&(t.push({text:e.slice(s,n),start:s}),s=n+1)}),t.push({text:e.slice(s),start:s}),t.filter(({text:o})=>o.trim())}function H(e){let t=[],s=e.trim(),o="",n=0,i=0,r=a=>{(i||a)>n&&t.push({combinator:o,compound:s.slice(n,i||a)}),i=0};return K(s,(a,l)=>{/\s/.test(a)?l===n?n=l+1:i||=l:">+~".includes(a)?(r(l),o=a,n=l+1):i&&(r(l),o=" ",n=l)}),r(s.length),t}function B(e){let t=[],s=-1,o=0,n="";for(let r=0;r<e.length;r++){let a=e[r];a==="\\"?r++:n?n=a===n?"":n:a==='"'||a==="'"?n=a:a==="("?o++:a===")"?o--:a==="["&&o===0?s=r:a==="]"&&o===0&&s>=0&&(t.push(e.slice(s,r+1)),s=-1)}let i=!1;return K(e,r=>{i||=r==="&"}),{attributes:t,nesting:i,scope:/(?:^|[^\w-]):scope\b/.test(e)}}var Ie=e=>new RegExp(`^\\[\\s*${G}\\s*=\\s*(["'])${e.replace(/[/-]/g,"\\$&")}\\1\\s*i?\\s*\\]$`,"i"),Pe=e=>M(e).replace(/\\.|\[[^\]]*\]/g,"").includes("&");function xe(e,t,s,o=!1){let n=H(e),i=({compound:f})=>B(f).attributes.some(h=>t.test(h)),r=({compound:f})=>{let{nesting:h,scope:m}=B(f);return!!s&&(h||m)},a=f=>["+","~"].includes(f?.combinator),l=f=>n.slice(f).some(({combinator:h},m)=>(m+f===0?h||" ":h)===" "),c=n.findLastIndex(f=>i(f)||r(f));if(c<0)return!s||Pe(e)?{why:"outside"}:{why:s==="instance"&&a(n[0])?"beside":null,subject:"inside",deep:o||l(0)};let p=i(n[c])||s==="instance";return{why:p&&a(n[c+1])?"beside":null,subject:p&&c===n.length-1?"instance":"inside",deep:!i(n[c])&&o||l(c+1)}}var Se=e=>e.some(({subject:t})=>t==="instance")?"instance":"inside",Re=new RegExp(`^\\[\\s*${Le}\\s*(?:\\]|=)`,"i"),Fe=e=>_(/\)\s*to\s*\(([^)]*)\)/i.exec(e)?.[1]??"").some(({text:t})=>H(t).length===1&&B(t).attributes.some(s=>Re.test(s))),je=(e,t)=>Ne(e,t).outside;function Ee(e,t,s){if(s.length===0)return[];let o=`slot${s.length===1?"":"s"} ${s.join(" and ")}`;return Ne(e,t).deep.map(({line:n,words:i})=>({line:n,what:`${i} also reaches the blocks in ${o}, the document's: write each step with > or wrap the rules in @scope ([${G}="${t}"]) to ([${Le}])`}))}function Ne(e,t){let s=Ie(t),o=`[${G}="${t}"]`,n=[],i=[],r=(l,c,p)=>{let f=c.replace(/\s+/g," ").trim();n.push({line:S(e,l),what:p==="beside"?`${f} reaches what stands beside the instance: what it styles has to stand in it`:`${f} reaches outside the instance: start it at ${o}`})},a=(l,c,p=!1,f=!1)=>{for(let h of l){let m=h.prelude.length-h.prelude.trimStart().length,u=h.start+m,y=/^@([\w-]+)\s*/.exec(h.prelude.trim());if(y){let d=y[1].toLowerCase();if(Ae.has(d))a(h.children,c,p,f);else if(d==="page")n.push({line:S(e,u),what:"@page reaches the paper of the whole document: an instance has no page of its own"});else if(d==="scope"){let x=/^@scope\s*\(([^)]*)\)/i.exec(h.prelude.trim())?.[1]??"",L=_(x).map(({text:j})=>({...xe(j,s,c),steps:H(j).length}));x&&L.every(({why:j,steps:Te})=>!j&&Te===1)?a(h.children,Se(L),!1,f||Fe(h.prelude.trim())):r(u,h.prelude,"outside")}continue}let k=_(h.prelude).map(({text:d,start:x})=>{let L=xe(d,s,c,p),j=h.start+x+d.length-d.trimStart().length;return L.why?r(j,d,L.why):L.deep&&!f&&!p&&i.push({line:S(e,j),words:d.replace(/\s+/g," ").trim()}),L});k.some(({why:d})=>d)||a(h.children,Se(k),k.some(d=>d.deep),f)}};return a(Ce(e),null),{outside:n,deep:i}}var w="template.html",N="example.html",O="component.json",Me=new Set(["localStorage","sessionStorage"]),_e=/^\S+: (?:line \d+ of )?its (?:kit\.js|style\.css) /,Be=/(?: (?:names a file that )?is not in the document's folder|: it is (?:no file of|not in) the document's .*)$|^external resources are not portable: .*$/,Ge=": an example stands in no document: write a picture as a data: address, or draw it from style.css with a file the manifest's assets name",Ke=e=>e.replace(Be,t=>(t.startsWith("external")?t:"")+Ge),T=(e,t)=>I({folder:e},t);function C(e,t){let s=null;try{s=X.readFileSync(E.join(e,t))}catch{return null}return Ue(s)?null:{file:t,what:"it is not UTF-8: save it as UTF-8 (PowerShell's > writes UTF-16; Set-Content -Encoding utf8 does not)"}}function J(e,t){let s=/^line (\d+): | \(line (\d+)\)/.exec(t);return s?{file:e,line:Number(s[1]??s[2]),what:t.replace(s[0],"")}:{file:e,what:t}}function v(e,t){let s=g.parseJsonText(O,e),o=s.statements[0]?.expression,n=null;for(let i of t.split(".")){let r=o?.properties?.find(({name:a})=>a?.text===i);if(!r)break;n=s.getLineAndCharacterOfPosition(r.getStart(s)).line+1,o=r.initializer}return n}function He(e,{message:t,text:s="",values:o=[]}){let n=/at position (\d+)/.exec(t)?.[1];if(n)return S(e,Number(n));for(let i of[...o.map(String),...s.match(/[a-zA-Z][\w.]*/g)??[]]){let r=v(e,i);if(r)return r}return null}var Je=e=>D(e).map(t=>/^line (\d+): <([^>]+)>: ([\s\S]*)$/.exec(t)).filter(Boolean).map(([,t,s,o])=>({line:Number(t),tag:s,why:o}));function qe(e,{file:t,tree:s,html:o}){let n=[],i=Je(o),r=Object.entries(e.parts).filter(([,c])=>c.edit==="text"),a=Object.entries(e.parts).filter(([,c])=>c.edit==="data"),l=(c,p)=>{let f=!1;return A(c,h=>{f||=h===p}),f};for(let c of Y(s,e))for(let[p,f]of r)for(let h of W(c,f.at)){let m=h.sourceCodeLocation?.startLine,u=Q(h).find(d=>ae.has(d.tagName)),y=i.find(d=>d.line===m&&d.tag===h.tagName),k=a.find(([,d])=>W(c,d.at).some(x=>x===h||l(x,h)||l(h,x)))?.[0];k?n.push({file:t,line:m,what:`the part ${p} (${f.at}) is edited as text, and stands in the part ${k}, edited as data, or around it, which is the component's: the editor leaves it read-only: name elements apart`}):u?n.push({file:t,line:m,what:`the part ${p} (${f.at}) is edited as text and holds a block, its <${u.tagName}> at line ${u.sourceCodeLocation?.startLine}: a text part holds words and marks alone, and the editor would leave this one read-only: write its \`at\` as what holds the words (${f.at} > ${u.tagName}), or give each block a part of its own`}):y&&n.push({file:t,line:m,what:`the part ${p} (${f.at}) is edited as text, and the editor would leave it read-only for what it holds: ${y.why}. A text part holds words and marks alone`})}return n}var ee=new RegExp("\\p{Script=Han}","u"),ve=e=>[...e].filter(t=>ee.test(t)).length,Ve={test:e=>{let t=Oe(e);return t!==null&&t<=8}};function We({name:e,words:t}){let s=ve(e.zh),o=t.split(/\s+/).filter(Boolean);return s===0?ee.test(t)&&!o.some(n=>Ve.test(n)):!o.some(n=>Oe(n.toLowerCase())===s)}function Xe({id:e,folder:t,catalog:s,off:o,parts:n}){let i=s.packages.get(e),r=s.problems.get(e)?.problem,a=T(t,O)??"",l=[];r&&l.push({file:O,line:He(a,r),what:U("en",r)}),i?.template===null&&l.push({file:w,what:`there is none, and it is what "/" puts in a document: with none, no menu offers the block: write one <div ${$}="${e}"> with what a new instance holds`}),l.push(...n);let c=C(t,"writing.md");c&&l.push(c);let p=c||T(t,"writing.md")?.trim()?[]:[{file:"writing.md",what:"there is none, so gallery block show has nothing to say of how to write it"}];i&&We(i)&&p.push({file:O,line:v(a,"words")??v(a,"name.zh"),what:ee.test(i.name.zh)?`no word of words spells its whole name ${i.name.zh} in pinyin as an input method composes it, its ${ve(i.name.zh)} Chinese characters a syllable each in one word (as \u65B9\u6848\u6253\u5206 is fangandafen): "/" finds it while those letters are being composed only by such a word. What is counted is how many syllables a word reads as, not which characters they spell`:'its words are Chinese and none of them is pinyin: "/" goes by the letters an input method is composing, so write the pinyin there (\u770B\u677F kanban)'});let f=(()=>{try{return ie(X.readFileSync(E.join(t,"preview.svg")),e)}catch{return null}})();return f&&p.push({file:"preview.svg",what:`it is Gallery's ${f.id} picture, byte for byte (a block made with --recipe keeps its recipe's drawing, which the menu shows beside this block's name): draw this block's own, or delete preview.svg, which the menu does without`}),o&&p.push({file:"gallery.json",what:"the user turned it off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868, which is theirs to change and says nothing of the block: it is checked as if it were on, and the instances of a document show what they hold, read-only, until it is on"}),i&&(l.push(...Ze(i)),p.push(...Ye(i,a))),{title:"manifest",problems:l,notes:p}}function Ye({places:e,parts:t,card:s},o){let n=[];if(e.includes("page"))for(let[i,r]of Object.entries(t))r.edit==="text"&&n.push({file:O,line:v(o,`parts.${i}`),what:`the part ${i} is edited as text, which is read-only on a custom page (no editor runs there): a block whose places hold page keeps what a reader changes there in a data part, with its own field or the card's settings`});else v(o,"card")&&n.push({file:O,line:v(o,"card"),what:`card is for a custom page's board, and its places (${e.join(", ")}) hold no page: nothing reads it`});return n}function Ze(e){if(e.settings.length===0||!e.template)return[];let t=ne(e.template,e.id),s=t?W(t.root,e.parts[F].at):[];if(s.length!==1||(b(s[0],"type")??"").trim().toLowerCase()!=="application/json")return[{file:w,what:`its manifest has settings, and the template holds ${s.length===1?`a <${s[0].tagName}> where`:`${s.length} elements of`} its settings part (${e.parts[F].at}): it is to hold one <script type="application/json">, the values a new card starts with ({} for each setting's default)`}];let o=s[0].childNodes.map(n=>n.value??"").join("").trim();try{let n=JSON.parse(o||"{}");if(typeof n!="object"||n===null||Array.isArray(n))throw new Error("it is no object");return[]}catch(n){return[{file:w,line:s[0].sourceCodeLocation?.startLine,what:`its settings part is not a JSON object (${n.message}): write {} or the values of some of its settings, by key`}]}}function Qe(e){let t=g.createSourceFile("kit.js",e,g.ScriptTarget.Latest,!0,g.ScriptKind.JS),s=[],o=n=>{let i=g.isCallExpression(n)&&g.isPropertyAccessExpression(n.expression)?n.expression:null;if(i?.name.text==="component"&&/\bDocKit$/.test(i.expression.getText(t))){let[r]=n.arguments,a=r&&g.isObjectLiteralExpression(r)?r.properties.find(c=>c.name?.getText(t)==="id"):null,l=a&&g.isPropertyAssignment(a)&&g.isStringLiteralLike(a.initializer)?a.initializer.text:null;s.push({id:l,at:n.getStart(t)})}g.forEachChild(n,o)};return o(t),s}function et(e){let t="kit.js";if(!e.files.includes("kit.js"))return{title:t,none:"none: a static block"};let s=C(e.folder,t);if(s)return{title:t,stops:!0,problems:[s]};let o=I(e,"kit.js")??"",n=pe(o);if(n)return{title:t,stops:!0,problems:[{file:t,line:n.line,what:`a browser refuses it: ${n.message}`}]};let i=he(e).map(({line:c,what:p})=>({file:t,line:c,what:p})),r=i.length>0;for(let{name:c,at:p}of re(o,Me))i.push({file:t,line:S(o,p),what:`uses ${c}: an instance keeps what a reader chose with context.state`});let a=Qe(o);for(let{id:c,at:p}of a)c!==null&&c!==e.id&&i.push({file:t,line:S(o,p),what:`it registers ${c}, and this block is ${e.id}`});let l=a.length?[]:[{file:t,what:`no DocKit.component({ id: "${e.id}", mount(host, context) { \u2026 } }) is to be read in it, and a script may make that call in ways reading does not tell: running it says whether it starts one`}];for(let{line:c,code:p,message:f,refused:h}of le(o,{assets:e.assets}))(h?i:l).push({file:t,line:c,what:`TS${p}: ${f}`});return{title:t,stops:r,problems:i.sort((c,p)=>(c.line??0)-(p.line??0)),notes:l}}function tt(e){let t="style.css";if(!e.files.includes("style.css"))return{title:t,none:"none"};let s=C(e.folder,t);if(s)return{title:t,stops:!0,problems:[s]};let o=I(e,"style.css")??"",n=ce(e),i=[...je(o,e.id),...n].map(({line:l,what:c})=>({file:t,line:l,what:c})),r=Object.entries(e.parts??{}).filter(([,{edit:l}])=>l==="flow").map(([l])=>l),a=Ee(o,e.id,r).map(({line:l,what:c})=>({file:t,line:l,what:c}));return{title:t,stops:n.length>0,problems:i.sort((l,c)=>l.line-c.line),notes:a}}function st(e,{tree:t}){let s=null;A(t,a=>{s??=a.tagName==="main"?a:null});let o=Q(s??{}),n=(s?.childNodes??[]).some(a=>a.nodeName==="#text"&&a.value.trim()),[i]=o;if(o.length!==1||n||!Z(i)||b(i,$)!==e)return[{file:w,line:i?.sourceCodeLocation?.startLine,what:`a template is one element, a <div ${$}="${e}"> or a <section>, and it holds ${o.length===1&&!n?`<${i.tagName}${b(i,$)?` ${$}="${b(i,$)}"`:""}>`:`${o.length} element${o.length===1?"":"s"}${n?" and words":""}`}`}];let r=[];return A({childNodes:[i]},a=>{b(a,"data-block-id")!==void 0&&r.push({file:w,line:a.sourceCodeLocation?.startLine,what:"it writes a data-block-id, which every instance made of it would repeat: leave it out, Gallery gives a block its id"})}),r}var nt=[[e=>b(e,"data-doc-chart")!==void 0,e=>`a chart (<${e.tagName} data-doc-chart="${b(e,"data-doc-chart")}">)`],[e=>e.tagName==="figure",()=>"a card (<figure>)"],[e=>e.tagName==="caption",()=>"a table's <caption>"],[Z,e=>`an instance of ${b(e,$)}`]];function ot(e,t){let s=null;if(A(z(t),i=>{s??=Z(i)&&b(i,$)===e?i:null}),!s)return[];let o=[],n=(i,r)=>{for(let a of Q(i)){let l=nt.find(([c])=>c(a));l?o.push({file:w,line:a.sourceCodeLocation?.startLine,what:`its slot ${b(r,"data-doc-slot")} holds ${l[1](a)}, which a new block from "/" would not have: a menu makes what a template's slot holds as a paste of it makes blocks, and a paste makes no chart, card, table caption or instance of a block. Keep the template's slots to blocks the page makes (paragraphs, headings, lists, quotes, code, a plain table, a disclosure), and show the rest in example.html`}):n(a.tagName==="template"?a.content:a,r)}};for(let i of ze(s))n(i,i);return o}function it(e,{tree:t}){let s=oe(e);if(!s)return[];let[o]=Y(t,e),n=null;return o&&A({childNodes:[o]},i=>{De(i.tagName,i.attrs)&&(n??=i)}),[{file:w,line:(n??o)?.sourceCodeLocation?.startLine,what:U("en",s)}]}function at(e){return[[w,"component-template"],[N,"component-example"]].flatMap(([t,s])=>{let o=T(e,t);if(o===null||!o.trim()||C(e,t))return[];let n=ge(s,o),{text:i}=de(n);return[{file:t,slug:s,written:n,html:i,tree:z(i)}]})}function rt({id:e,folder:t,found:s,pages:o,parts:n}){let i="template.html and example.html",r=[],a=[];for(let h of[w,N]){let m=C(t,h);m?r.push(m):h===w&&!T(t,h)?.trim()&&s.template!==null?r.push({file:h,what:"it is empty"}):h===N&&!o.some(u=>u.file===h)&&r.push({file:h,what:`there is none or it is empty: write an instance as a writer would fill it, a <div ${$}="${e}">; it is what this check runs`})}let l=o.find(h=>h.file===w);l&&r.push(...st(e,l),...ot(e,l.written));let c=o.find(h=>h.file===N);c&&Y(c.tree,s).length===0&&r.push({file:N,what:`it holds no instance of ${e}: a <div ${$}="${e}">`});let p=o.map(({slug:h,written:m,html:u,file:y})=>({file:y,slug:h,written:m,html:u,directory:E.join(t,h),htmlPath:E.join(t,h,"doc.html"),metadata:{title:h,description:h,type:"component"}})),f=fe(p);for(let h of p){for(let m of f.get(h.slug)??[])_e.test(m)||r.push(J(h.file,Ke(m)));for(let m of me(h))a.push(J(h.file,m));for(let m of D(h.html)){let u=J(h.file,`${m} (read-only in the preview)`);n.some(({file:y,line:k})=>y===u.file&&k===u.line)||a.push(u)}}return l&&!r.some(({file:h})=>h===w)&&r.push(...it(s,l)),{title:i,problems:r,notes:a}}function lt(e,t){let s=te(e,void 0,{on:t}),o=R(e,t);if(!s.packages.has(t)&&!s.problems.has(t))return null;se(e,s);let n=s.packages.has(t)&&s.settings.disabled.includes(t),i=s.packages.get(t)??{id:t,folder:o,files:["kit.js","style.css"].filter(c=>X.existsSync(E.join(o,c)))},r=at(o),a=s.packages.has(t)?null:"its manifest does not load",l=a?[]:r.flatMap(c=>qe(i,c));return{found:s.packages.get(t)??null,pages:r,sections:[Xe({id:t,folder:o,catalog:s,off:n,parts:l}),et(i),tt(i),a?{title:"template.html and example.html",skipped:a}:rt({id:t,folder:o,found:i,pages:r,parts:l})]}}var q=({file:e,line:t})=>t?`${e}:${t}`:e;function V({title:e,problems:t=[],notes:s=[],told:o=[],none:n,skipped:i,unverified:r,pictures:a},l){let c=r?`UNVERIFIED ${r}`:i?`not run: ${i}`:n??(t.length?`${t.length} problem${t.length===1?"":"s"}`:`ok${s.length?`, ${s.length} note${s.length===1?"":"s"}`:""}`);return[`${l}. ${e}: ${c}`,...t.map(p=>` FAIL ${q(p)}: ${p.what}`),...s.map(p=>` note ${q(p)}: ${p.what}`),...o.map(p=>` way back ${q(p)}: ${p.what}`),...a?[ct(a)]:[]]}function ct({folder:e,overviews:t,each:s,edited:o=[],asExport:n=[],documents:i=!1}){let r=t.length?`${P(E.join(e,t[0]))}${t.slice(1).map(c=>` and ${c}`).join("")}, the three widths of each theme side by side; then each at full size: `:`${P(e)}: `,a=n.length===0?"":n.length===o.length?", each the same picture as the export's at its width: the block draws nothing more where a reader can edit":`, ${n.join(" and ")} the same picture as the export's at its width`,l=o.length?`; and ${o.join(" and ")}, as the editing page draws it (context.canEdit() true)${a}`:"";return` Pictures (none looked at for you; ${i?"each instance under a line naming where it stands in the document":"example.html above the line, template.html below it, each under its name"}): ${r}${s.join(", ")}${l}`}function ht([e,t,s,o]){return e.problems.length?"the manifest":t.stops?"kit.js":s.stops?"style.css":o.skipped||o.problems.length?"template.html and example.html":null}async function Ut(e,t,{documents:s=!1}={}){let o=lt(e,t);o||(console.error(ke(e,t)),process.exit(1)),console.log(`${t}: ${P(R(e,t))}`),o.sections.forEach((p,f)=>console.log(V(p,f+1).join(`
3
3
  `)));let n=ht(o.sections),i=R(e,t),r=n?{title:ue,skipped:`${n} first`}:await $e(e,o.found,{example:T(i,N),template:T(i,w)});console.log(V(r,5).join(`
4
4
  `));let a=s?n?[{title:we(),skipped:`${n} first`}]:await be(e,o.found):[];a.forEach((p,f)=>console.log(V(p,6+f).join(`
5
5
  `)));let l=ye([r,...a].filter(({pictures:p})=>p).map(({pictures:{folder:p,overviews:f,each:h,edited:m=[]}})=>({folder:p,files:[...f,...h,...m].map(u=>E.join(p,u))})));l&&console.log(l);let c=[...o.sections,r,...a].reduce((p,{problems:f=[]})=>p+f.length,0);c?(console.log(`FAIL ${t}: ${c} problem${c===1?"":"s"}`),process.exitCode=1):r.unverified||a.some(({unverified:p})=>p)?(console.log(`UNVERIFIED ${t}: the rest passed, and no browser ran ${r.unverified?"it":"the documents' instances"}: export a document that holds it and open that in Chrome or Edge.`),process.exitCode=3):console.log(`OK ${t}${s?" and its instances in the workspace's documents":""}`)}export{Ut as checkCommand,Oe as fewestSyllables,lt as readSections,V as sectionLines,We as wantsPinyin};
@@ -1,16 +1,16 @@
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{a as je}from"./chunk-JEUK3ZO7.mjs";import{a as Te,b as Ne,c as Xe,d as Ze,g as Oe,h as et}from"./chunk-4AMTKWDO.mjs";import{g as Qe}from"./chunk-TOE6DPLH.mjs";import{b as Se}from"./chunk-WTEGUPFG.mjs";import{p as Ee}from"./chunk-XMKHCUI6.mjs";import{a as le}from"./chunk-2RKIHJI2.mjs";import{a as ve,f as Ye,p as ze}from"./chunk-VG5JEIUQ.mjs";import T from"node:fs/promises";import he from"node:os";import x from"node:path";import{pathToFileURL as Re}from"node:url";import{instancesOf as ot,isInstance as bt}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as $t,FALLBACK as xt,INSTANCE as de,SLOT as vt,SLOT_PART as tt}from"../browser/shared/components/installed.mjs";import{jsonIn as Et}from"../browser/shared/json-layout.mjs";import{QUERY_ROUTE as St}from"../browser/shared/workspace-query.mjs";import{documentDirectory as jt,documentFiles as Tt,layoutOf as it,listDocumentSlugs as Nt,PACKAGE_MANIFEST as Ot}from"../browser/shared/workspace.mjs";var At="in a browser, under the export's policy",ce=(e=null)=>e?`the instances in ${e}, in a browser under the export's policy`:"the workspace's documents",q="component-check",ae=[360,736,1024],Ae=["light","dark"],Lt=[1024,360],nt=1e4,rt=6e4,se=3e4,Dn=12e4,lt=2e3,Rt=3e3,Dt=60,Mn=15e3,Mt=2,Pt=8,Ct=se/2,_t=/^(?:wasm-)?eval$/,It=new Set(["TargetCloseError","ConnectionClosedError"]),Pn=e=>e.evaluateOnNewDocument(Ft,St);function Ft(e){let t=globalThis.fetch;if(typeof t!="function"||globalThis.__galleryQueries)return;let i={pending:new Map,count:0};globalThis.__galleryQueries=i,globalThis.fetch=function(r,n){let a=t.apply(this,arguments);try{let p=new URL(typeof r=="string"?r:r?.url??String(r),location.href);if(p.pathname===e){let u=++i.count,w=/\/__gallery\/components\/([a-z0-9-]+\/[a-z0-9-]+)\/kit\.js/.exec(new Error().stack??"");i.pending.set(u,{kind:p.searchParams.get("kind"),block:w?w[1]:null,at:Date.now()});let l=()=>{i.pending.delete(u)};Promise.resolve(a).then(l,l)}}catch{}return a}}var oe=e=>String(e?.message??e).split(`
2
+ import{a as Te}from"./chunk-JEUK3ZO7.mjs";import{a as Ne,b as Oe,c as Xe,d as Ze,g as Ae,h as et}from"./chunk-PUOQ65NC.mjs";import{g as Qe}from"./chunk-6NLXUKAY.mjs";import{b as je}from"./chunk-VRPVVMRB.mjs";import{p as Se}from"./chunk-BX5AKINW.mjs";import{a as ce}from"./chunk-HYMEEXKN.mjs";import{a as Ee,f as le,p as ze}from"./chunk-TKWEX4FD.mjs";import T from"node:fs/promises";import pe from"node:os";import x from"node:path";import{pathToFileURL as De}from"node:url";import{instancesOf as ot,isInstance as bt}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as $t,FALLBACK as xt,INSTANCE as he,SLOT as vt,SLOT_PART as tt}from"../browser/shared/components/installed.mjs";import{jsonIn as Et}from"../browser/shared/json-layout.mjs";import{QUERY_ROUTE as St}from"../browser/shared/workspace-query.mjs";import{documentDirectory as jt,documentFiles as Tt,layoutOf as it,listDocumentSlugs as Nt,PACKAGE_MANIFEST as Ot}from"../browser/shared/workspace.mjs";var At="in a browser, under the export's policy",de=(e=null)=>e?`the instances in ${e}, in a browser under the export's policy`:"the workspace's documents",q="component-check",ae=[360,736,1024],Le=["light","dark"],Lt=[1024,360],nt=1e4,rt=6e4,se=3e4,Dn=12e4,lt=2e3,Rt=3e3,Dt=60,Mn=15e3,Mt=2,Pt=8,Ct=se/2,_t=/^(?:wasm-)?eval$/,It=new Set(["TargetCloseError","ConnectionClosedError"]),Pn=e=>e.evaluateOnNewDocument(Ft,St);function Ft(e){let t=globalThis.fetch;if(typeof t!="function"||globalThis.__galleryQueries)return;let i={pending:new Map,count:0};globalThis.__galleryQueries=i,globalThis.fetch=function(r,n){let a=t.apply(this,arguments);try{let p=new URL(typeof r=="string"?r:r?.url??String(r),location.href);if(p.pathname===e){let u=++i.count,w=/\/__gallery\/components\/([a-z0-9-]+\/[a-z0-9-]+)\/kit\.js/.exec(new Error().stack??"");i.pending.set(u,{kind:p.searchParams.get("kind"),block:w?w[1]:null,at:Date.now()});let l=()=>{i.pending.delete(u)};Promise.resolve(a).then(l,l)}}catch{}return a}}var oe=e=>String(e?.message??e).split(`
3
3
  `)[0],ct=(e,t)=>`<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${e}</title></head><body><main class="doc-page" data-doc-id="${e}">${t}
4
4
  </main></body></html>
5
5
  `,Bt=({example:e,template:t})=>`<p>example.html</p>${e}
6
- <hr><p>template.html</p>${t}`,Ht=e=>{for(let t=e.parentNode;t;t=t.parentNode)if(bt(t))return!0;return!1},dt=(e,t)=>ot(e,t).filter(i=>!Ht(i)),De=(e,t)=>dt(le(e),t).map(({sourceCodeLocation:{startLine:i,startOffset:r,endOffset:n}})=>({line:i,markup:e.slice(r,n)}));async function ht(e,t){let i=x.join(t,"components",...e.id.split("/"));for(let r of[Ot,"template.html",...e.files]){let n=ze(e,r);if(!n)continue;let a=await T.readFile(n);await T.mkdir(x.dirname(x.join(i,r)),{recursive:!0}),await T.writeFile(x.join(i,r),r==="kit.js"?`${a}
6
+ <hr><p>template.html</p>${t}`,Ht=e=>{for(let t=e.parentNode;t;t=t.parentNode)if(bt(t))return!0;return!1},dt=(e,t)=>ot(e,t).filter(i=>!Ht(i)),Me=(e,t)=>dt(ce(e),t).map(({sourceCodeLocation:{startLine:i,startOffset:r,endOffset:n}})=>({line:i,markup:e.slice(r,n)}));async function ht(e,t){let i=x.join(t,"components",...e.id.split("/"));for(let r of[Ot,"template.html",...e.files]){let n=ze(e,r);if(!n)continue;let a=await T.readFile(n);await T.mkdir(x.dirname(x.join(i,r)),{recursive:!0}),await T.writeFile(x.join(i,r),r==="kit.js"?`${a}
7
7
  //# sourceURL=kit.js
8
8
  `:a)}}async function Wt(e,{example:t,template:i},r){await ht(e,r);let n=x.join(r,q);await T.mkdir(n);let a=`${t}
9
- `,p=Se(ct(q,Bt({example:t,template:i}))).text;await T.writeFile(x.join(n,"doc.html"),p),await T.writeFile(x.join(n,"doc.json"),JSON.stringify({title:q,description:q,type:"component"}));let w=await(await Ee({directory:r}))(q),l=x.join(r,"export.html");await T.writeFile(l,w);let f=a.split(`
10
- `).length-1,s=De(p,e).map(({line:c})=>c>f?{file:"template.html",line:c-f}:{file:"example.html",line:c});return{html:w,file:l,places:s,source:p}}function qt({match:e,instance:t,slot:i,parts:r,boards:n}){if(!Object.entries(r).some(([l,{edit:f}])=>f==="data"&&!n.includes(l)))return[];let a=[...document.querySelectorAll(e)].filter(l=>!l.parentElement.closest(t)),p=l=>l.parentElement?.closest(`${t}, ${i}`)??null,u=l=>`<${l.localName}${l.classList.length?` class="${l.getAttribute("class")}"`:""}>`,w=l=>{let f=(l.textContent||l.getAttribute("aria-label")||l.getAttribute("placeholder")||l.getAttribute("title")||"").replace(/\s+/g," ").trim().slice(0,24);return`${u(l)}${f?` "${f}"`:""}`};return a.flatMap((l,f)=>{let s=[...l.querySelectorAll("button, input, select, textarea")].filter(c=>p(c)===l).filter(c=>{if(c.disabled||c.readOnly||c.type==="hidden")return!1;let h=c.getBoundingClientRect(),b=getComputedStyle(c);return h.width>0&&h.height>0&&b.visibility!=="hidden"&&b.display!=="none"});return s.length?[{at:f,what:s.slice(0,3).map(w).join(", "),counts:[s.length]}]:[]})}async function Gt({match:e,instance:t,slotPart:i,slotName:r,fallback:n,parts:a,boards:p,at:u,source:w,still:l,step:f,times:s,typed:c,typing:h}){let b=()=>[...document.querySelectorAll(e)].filter(o=>!o.parentElement.closest(t)),k=o=>new Promise(d=>setTimeout(d,o)),g=()=>new Promise(o=>{requestAnimationFrame(o),setTimeout(o,100)}),m=async o=>{await g(),await g();let d=o.outerHTML;for(let y=0,v=Date.now()+l;y<3;){if(Date.now()>v)return null;await k(f);let E=o.outerHTML;y=E===d?y+1:0,d=E}return d},_=o=>{let d=document.createElement("template");return d.innerHTML=o,d.content.firstElementChild},$=o=>`<${o.localName}${o.classList.length?` class="${o.getAttribute("class")}"`:""}>`,S=o=>o.nodeType===1?$(o):`the words "${o.data.trim().slice(0,40)}"`,B=o=>[...o.childNodes].filter(d=>d.nodeType===1||d.nodeType===3&&d.data.trim()),H=(o,d)=>["style","class"].includes(d)&&!o.getAttribute(d)?.trim()?null:o.getAttribute(d),D=(o,d)=>{for(let E of new Set([...o.getAttributeNames(),...d.getAttributeNames()]))if(H(o,E)!==H(d,E))return`${E} on ${$(d)}, ${JSON.stringify(H(o,E))} then ${JSON.stringify(H(d,E))}`;let[y,v]=[B(o),B(d)];for(let E=0;E<Math.max(y.length,v.length);E++){let[N,M]=[y[E],v[E]];if(!N||!M)return`${$(d)} ${N?`without ${S(N)}`:`with ${S(M)} more`}`;if(N.nodeType!==M.nodeType||N.localName!==M.localName||N.nodeType===3&&N.data.trim()!==M.data.trim())return`in ${$(d)}, ${S(N)} then ${S(M)}`;let I=N.nodeType===1?D(N,M):null;if(I)return I}return null},pe=o=>{let d=new Map;for(let y of o)d.set($(y),(d.get($(y))??0)+1);return d},Ce=()=>[...document.querySelectorAll("*")].filter(o=>!o.closest(t)),_e=o=>[...o.at(-1).keys()].filter(d=>o.length>2&&o.every((y,v)=>v===0||(y.get(d)??0)>(o[v-1].get(d)??0))),Ie=o=>o.parentElement?.closest(`${t}, ${i}`)??null,Fe=o=>[...o.querySelectorAll(i)].filter(d=>Ie(d)===o),G=o=>{let d=o.cloneNode(!0);return Fe(d).forEach(y=>y.replaceChildren()),d},Z=o=>Fe(o).map(d=>{let y=[];for(let v=d.parentElement;v&&v!==o;v=v.parentElement)y.unshift($(v));return{name:d.getAttribute(r),place:y.join(" > "),blocks:[...DocKit.dehydrate(d.cloneNode(!0)).children].map(v=>v.localName).join(" "),html:DocKit.dehydrate(d.cloneNode(!0)).outerHTML}}),ue=(o,d,y,{markup:v=!0}={})=>o.flatMap(({name:E,place:N,blocks:M,html:I})=>{let A=d.find(W=>W.name===E),X=A?A.place!==N?`moved the slot ${E} (${A.place?`in ${A.place}`:"straight in the instance"}, where the file has it ${N?`in ${N}`:"straight in the instance"})`:A.blocks!==M?`changed the blocks the slot ${E} holds (${M||"none"}, then ${A.blocks||"none"})`:v&&A.html!==I?`changed what the slot ${E} holds`:null:`took the slot ${E} off the instance`;return X?[{kind:"written-in",part:E,how:`${X}, ${y}`}]:[]}),Be=o=>d=>Ie(d)===o,we=(o,d=()=>!0)=>Object.entries(a).filter(([,{edit:y}])=>d(y)).flatMap(([y,v])=>[...o.querySelectorAll(v.at)].filter(Be(o)).map(E=>({name:y,node:E}))),ee=o=>we(o,d=>d==="text"),K=o=>Object.entries(a).filter(([,{edit:d}])=>d==="data").map(([d,y])=>({name:d,node:[...o.querySelectorAll(y.at)].find(Be(o))})).filter(({node:d})=>d),C=[],V=b()[u];if(!V)return[{kind:"gone"}];if(V.hasAttribute(n))return[{kind:"fallback"}];let fe=await m(V);if(fe===null)return[{kind:"moving"}];let ie=_(w),He=Z(V);C.push(...ue(Z(ie),He,"as it mounts",{markup:!1}));let me=ee(ie);ee(V).forEach(({name:o,node:d},y)=>{me[y]&&me[y].node.innerHTML!==d.innerHTML&&C.push({kind:"redrawn",part:o,how:`the file says ${JSON.stringify(me[y].node.textContent.trim())}, the page ${JSON.stringify(d.textContent.trim())}`})});let ge=DocKit.dehydrate(V.cloneNode(!0)),[We,qe]=[G(ie),G(ge)],ke=D(We,qe);if(ke){let o=we(qe),d=we(We).find(({node:y},v)=>o[v]&&D(y,o[v].node))?.name;C.push({kind:"left",what:ke,...d?{part:d}:{}})}let ft=K(ge);for(let[o,{name:d,node:y}]of K(ie).entries())!ke&&ft[o]?.node.innerHTML!==y.innerHTML&&C.push({kind:"data",part:d});let Q=[],ye=new MutationObserver(o=>Q.push(...o));ye.observe(document.documentElement,{subtree:!0,childList:!0,characterData:!0});let Ge=new Set,Ue=o=>{Q.push(...ye.takeRecords());for(let{name:d,node:y}of o)(!y.isConnected||Q.some(({target:v})=>y.contains(v)))&&Ge.add(d);Q.length=0},be=[fe],$e=[pe(Ce())],Je=o=>{be.push(o),$e.push(pe(Ce())),C.push(...ue(He,Z(j),"as it mounts again"))},j=ge,xe=ee(j);Q.length=0,V.replaceWith(j);let U=await m(j);if(Ue(xe),U!==null){Je(U);for(let o=0;o<s&&U!==null;o++){let d=j.cloneNode(!0);xe=ee(d),Q.length=0,j.replaceWith(d),j=d,U=await m(j),Ue(xe),U!==null&&Je(U)}}ye.disconnect(),U===null&&C.push({kind:"moving"});for(let o of Ge)C.push({kind:"redrawn",part:o,how:"a mount changes it"});let Ke=be.map(o=>pe(G(_(o)).querySelectorAll("*"))),Ve=_e(Ke);for(let o of Ve)C.push({kind:"piles",what:o,counts:Ke.map(d=>d.get(o)??0)});for(let o of _e($e))C.push({kind:"piles",what:o,outside:!0,counts:$e.map(d=>d.get(o)??0)});if(!Ve.length){let o=be.slice(1).map(d=>D(G(_(fe)),G(_(d)))).find(Boolean);o&&C.push({kind:"changed",what:o})}let re=U===null?[]:ee(j).filter(({node:o})=>o.textContent.trim()),mt=[...new Set([...new Map(re.map(o=>[o.name,o])).values(),...re])].slice(0,c),gt=Date.now()+h;for(let{node:o}of mt){if(Date.now()>gt)break;let d=document.createTreeWalker(o,NodeFilter.SHOW_TEXT).nextNode(),y=d.data;d.data=`${y}\u2026`;let v=re.map(({node:N})=>N.textContent);await m(j);let E=re.find(({node:N},M)=>!N.isConnected||N.textContent!==v[M]);if(E){C.push({kind:"redrawn",part:E.name,how:"a change of its words does not stand"});break}d.data=y,await m(j)}return U!==null&&K(j).length>0&&C.push(...await kt()),C;async function kt(){let o=[],d=null,y=!1,v="as it hears that it can write (the editable signal)",E=[],N=I=>{if(I.target!==j)return;let{parts:A,run:X}=I.detail,W=A.map(({part:O})=>O.innerHTML),P=A.map(({part:O})=>O.cloneNode(!0)),te=X(Object.fromEntries(A.map(({name:O},R)=>[O,P[R]]))),J=A.find(({part:O},R)=>O.innerHTML!==W[R]),Y=A.find(({part:O},R)=>P[R].cloneNode(!1).outerHTML!==O.cloneNode(!1).outerHTML);if(J&&A.forEach(({part:O},R)=>{O.innerHTML=W[R]}),!y){let O=J??Y??A.find((R,ne)=>P[ne].innerHTML!==W[ne]);O&&!E.some(R=>R.when===v)?E.push({kind:"unasked",part:O.name,when:v}):te&&!O&&I.preventDefault();return}J?d??=`it writes the part ${J.name} on the page, not the draft context.edit hands it, so the editor refuses the edit`:te&&Y&&(d??=`it changes the part ${Y.name}'s own tag or attributes, which are the file's: a change writes what a part holds, so the editor refuses the edit`),!(J||!te||Y)&&(A.forEach(({part:O},R)=>{o.push({part:O,before:W[R]}),O.replaceChildren(...P[R].childNodes)}),I.preventDefault())};document.addEventListener("doc-component-edit",N);try{return[...await M(),...E]}finally{document.removeEventListener("doc-component-edit",N)}async function M(){dispatchEvent(new Event("doc-editable")),await m(j),v="as it mounts";let I=j.cloneNode(!0);j.replaceWith(I),j=I;let A=await m(j);v="as it hears its part changed (the source signal)";let X=Z(j),W=DocKit.dehydrate(j.cloneNode(!0)),P=[];y=!0;try{if(!DocKit.example(j))return K(j).every(({name:F})=>p.includes(F))?[]:[{kind:"no-example"}]}catch(F){return[{kind:"example",what:`it throws: ${F?.message??F}`}]}finally{y=!1}let te=await m(j),J=DocKit.dehydrate(j.cloneNode(!0)),Y=Object.fromEntries(K(J).map(({name:F,node:z},yt)=>[F,z.innerHTML,K(W)[yt]?.node.innerHTML]).filter(([,F,z])=>F!==z));d?P.push({kind:"example",what:d}):o.length===0?P.push({kind:"example",what:"context.edit was not taken: it was not called, or it answered false, and the console says why"}):Object.keys(Y).length===0?P.push({kind:"example",what:"it changes nothing a part holds"}):P.push({kind:"wrote",parts:Y});for(let F of[W,J])for(let{node:z}of K(F))z.textContent="";let O=D(G(W),G(J));O&&P.push({kind:"example",what:`it changes what is no data part: ${O}`}),P.push(...ue(X,Z(j),"as its example makes its edit"));for(let{part:F,before:z}of o.reverse())F.innerHTML=z;let R=await m(j),ne=A!==null&&R!==null?D(G(_(A)),G(_(R))):null;return te===null||R===null?P.push({kind:"moving"}):ne&&!O&&P.push({kind:"undo",what:ne}),P}}}var Ut=e=>e.map(({name:t,removed:i,added:r,lines:n})=>`${t} (-${i} +${r} of its ${n} line${n===1?"":"s"})`).join(" and "),Jt="a write changes the lines it means and no others: a row moved by context.rows, which takes the blank before it along, JSON written back by context.editJSON and laid out in template.html and example.html as it writes it (block-script.md, Two examples)";function Le(e,t){try{return JSON.parse(e),Et(e,JSON.parse(t))===t}catch{return!1}}var Kt="it changes nothing a part holds";function Vt({kind:e,what:t,part:i,how:r,when:n,counts:a,outside:p,parts:u,back:w,line:l,json:f},s,{script:c}){let h=k=>({...s,what:k}),b=k=>({...s,what:k,note:!0});switch(e){case"wrote":return{...s,told:!0,what:`its example wrote ${Ut(u)}; the server took it${w?"; put back as an undo does, it shows what it showed":""}`};case"laid":return b(`its example's write lays the part ${i} out anew (${r}): ${Jt}${f?`; this write is context.editJSON's, and what the file held is laid out otherwise: lay ${i} out as it writes it`:""}`);case"drops":return{...b(`${t} listens for dragover and not for dragenter: a drop goes where both are cancelled, and the move that enters it asks dragenter alone, so that a release then (on a card's words, its padding) drops nothing: cancel dragenter as dragover is cancelled (preventDefault)`),file:"kit.js",line:l};case"controls":return{...b(`where nothing is written (this look is an export: context.canEdit() is false) the instance of ${s.file}${s.line?`:${s.line}`:""} still shows ${t}${a[0]>3?` and ${a[0]-3} more`:""}, enabled, and the block has a data part: a reader presses a control that writes to no effect, and the export says the block can be edited. Draw a control that writes only while context.canEdit(), and hide it by the hidden attribute (the kit holds [hidden] over any display the style gives it) or disable it; ignore this for a control that only changes what a reader looks at, a filter or a tab, which an export keeps. Compare 1024-light.png with edit-1024-light.png: the second is what a reader who can edit sees`),file:"kit.js",line:void 0};case"gone":return h("the page does not hold this instance");case"fallback":return h(c?"its component failed or never started: the instance shows what it holds, read-only":"the instance shows as one of no custom block");case"moving":return b("what it shows never holds still (an animation?), so its mounts could not be compared");case"redrawn":return h(`the component redraws its text part ${i}: ${r}. A text part is the file's, what the user types in: read it, and draw in what is the component's`);case"left":return h(`dehydrate does not leave it as the file has it, so a copy of the view would hold what the kit made of it: ${t}. ${i?`That stands in its part ${i}, which is the file's: read a part, and draw in what is the component's`:"Name what it draws in the manifest's runtime, or take it off in dehydrate"}`);case"data":return h(`a mount changes its data part ${i}, so that a page would write what the component left there, with nothing edited: read a data part, and change it by context.edit alone`);case"no-example":return b("it has a data part and its component offers no example of an edit, so nothing has tried the way back to the file: give DocKit.component an example(host, context) that makes a small context.edit");case"example":return t===Kt?{...s,file:"kit.js",line:void 0,what:`its example(host, context) changes nothing a part holds on the instance of ${s.file}${s.line?`:${s.line}`:""}: the check runs it on every instance of example.html and of template.html, and template.html's is empty, with nothing to change a value of (the first entry of a list it does not hold yet). Make example() make a change that works on an empty instance too (add an entry, set a field), and have it call the function a reader's control calls, so that it tries the code a reader runs`}:h(`its example: ${t}`);case"refused":return h("what its example wrote cannot go in the file: a script, a handler, an address of code, data-block-id or data-ge-*, what does not read back as itself, or what is no JSON in a script of data");case"undo":return h(`with what its example wrote put back, as an undo does, it does not show what it showed: ${t}: draw from the part, and on the source signal`);case"unasked":return h(`it writes its data part ${i} with no reader's gesture, ${n}, once the page takes edits: a page would write it each time it opened. Call context.edit on a gesture alone, a press, a drop or a key, and draw what the part holds as it is`);case"written-in":return h(`kit.js ${r}: a slot is the document's, its blocks the reader's: read it with context.part, never write in it or move it, and draw outside it`);case"piles":return h(p?`${t} piles up outside the instance on each put-back (${a.join(", then ")} of them), so an undo adds another: a component draws in its instance, and what it has to put elsewhere it takes away again in destroy`:`${t} piles up on each put-back (${a.join(", then ")} of them): it is declared in neither the manifest's runtime nor dehydrate, so an undo adds another`);default:return h(`a mount does not give the same DOM again: ${t}`)}}var Yt=e=>[...new Map(e.toReversed().map(t=>[`${t.finding.kind}|${t.finding.part??""}|${["piles","example"].includes(t.finding.kind)?t.finding.what:""}|${t.finding.when??""}|${t.finding.line??""}`,t])).values()].toReversed(),zt=4e6;function Me(e,t,i=(r,n)=>r===n){let[r,n]=[e.split(`
9
+ `,p=je(ct(q,Bt({example:t,template:i}))).text;await T.writeFile(x.join(n,"doc.html"),p),await T.writeFile(x.join(n,"doc.json"),JSON.stringify({title:q,description:q,type:"component"}));let w=await(await Se({directory:r,catalog:le(r)}))(q),l=x.join(r,"export.html");await T.writeFile(l,w);let f=a.split(`
10
+ `).length-1,s=Me(p,e).map(({line:c})=>c>f?{file:"template.html",line:c-f}:{file:"example.html",line:c});return{html:w,file:l,places:s,source:p}}function qt({match:e,instance:t,slot:i,parts:r,boards:n}){if(!Object.entries(r).some(([l,{edit:f}])=>f==="data"&&!n.includes(l)))return[];let a=[...document.querySelectorAll(e)].filter(l=>!l.parentElement.closest(t)),p=l=>l.parentElement?.closest(`${t}, ${i}`)??null,u=l=>`<${l.localName}${l.classList.length?` class="${l.getAttribute("class")}"`:""}>`,w=l=>{let f=(l.textContent||l.getAttribute("aria-label")||l.getAttribute("placeholder")||l.getAttribute("title")||"").replace(/\s+/g," ").trim().slice(0,24);return`${u(l)}${f?` "${f}"`:""}`};return a.flatMap((l,f)=>{let s=[...l.querySelectorAll("button, input, select, textarea")].filter(c=>p(c)===l).filter(c=>{if(c.disabled||c.readOnly||c.type==="hidden")return!1;let h=c.getBoundingClientRect(),b=getComputedStyle(c);return h.width>0&&h.height>0&&b.visibility!=="hidden"&&b.display!=="none"});return s.length?[{at:f,what:s.slice(0,3).map(w).join(", "),counts:[s.length]}]:[]})}async function Gt({match:e,instance:t,slotPart:i,slotName:r,fallback:n,parts:a,boards:p,at:u,source:w,still:l,step:f,times:s,typed:c,typing:h}){let b=()=>[...document.querySelectorAll(e)].filter(o=>!o.parentElement.closest(t)),k=o=>new Promise(d=>setTimeout(d,o)),g=()=>new Promise(o=>{requestAnimationFrame(o),setTimeout(o,100)}),m=async o=>{await g(),await g();let d=o.outerHTML;for(let y=0,v=Date.now()+l;y<3;){if(Date.now()>v)return null;await k(f);let E=o.outerHTML;y=E===d?y+1:0,d=E}return d},_=o=>{let d=document.createElement("template");return d.innerHTML=o,d.content.firstElementChild},$=o=>`<${o.localName}${o.classList.length?` class="${o.getAttribute("class")}"`:""}>`,S=o=>o.nodeType===1?$(o):`the words "${o.data.trim().slice(0,40)}"`,B=o=>[...o.childNodes].filter(d=>d.nodeType===1||d.nodeType===3&&d.data.trim()),H=(o,d)=>["style","class"].includes(d)&&!o.getAttribute(d)?.trim()?null:o.getAttribute(d),D=(o,d)=>{for(let E of new Set([...o.getAttributeNames(),...d.getAttributeNames()]))if(H(o,E)!==H(d,E))return`${E} on ${$(d)}, ${JSON.stringify(H(o,E))} then ${JSON.stringify(H(d,E))}`;let[y,v]=[B(o),B(d)];for(let E=0;E<Math.max(y.length,v.length);E++){let[N,M]=[y[E],v[E]];if(!N||!M)return`${$(d)} ${N?`without ${S(N)}`:`with ${S(M)} more`}`;if(N.nodeType!==M.nodeType||N.localName!==M.localName||N.nodeType===3&&N.data.trim()!==M.data.trim())return`in ${$(d)}, ${S(N)} then ${S(M)}`;let I=N.nodeType===1?D(N,M):null;if(I)return I}return null},ue=o=>{let d=new Map;for(let y of o)d.set($(y),(d.get($(y))??0)+1);return d},_e=()=>[...document.querySelectorAll("*")].filter(o=>!o.closest(t)),Ie=o=>[...o.at(-1).keys()].filter(d=>o.length>2&&o.every((y,v)=>v===0||(y.get(d)??0)>(o[v-1].get(d)??0))),Fe=o=>o.parentElement?.closest(`${t}, ${i}`)??null,Be=o=>[...o.querySelectorAll(i)].filter(d=>Fe(d)===o),G=o=>{let d=o.cloneNode(!0);return Be(d).forEach(y=>y.replaceChildren()),d},Z=o=>Be(o).map(d=>{let y=[];for(let v=d.parentElement;v&&v!==o;v=v.parentElement)y.unshift($(v));return{name:d.getAttribute(r),place:y.join(" > "),blocks:[...DocKit.dehydrate(d.cloneNode(!0)).children].map(v=>v.localName).join(" "),html:DocKit.dehydrate(d.cloneNode(!0)).outerHTML}}),we=(o,d,y,{markup:v=!0}={})=>o.flatMap(({name:E,place:N,blocks:M,html:I})=>{let A=d.find(W=>W.name===E),X=A?A.place!==N?`moved the slot ${E} (${A.place?`in ${A.place}`:"straight in the instance"}, where the file has it ${N?`in ${N}`:"straight in the instance"})`:A.blocks!==M?`changed the blocks the slot ${E} holds (${M||"none"}, then ${A.blocks||"none"})`:v&&A.html!==I?`changed what the slot ${E} holds`:null:`took the slot ${E} off the instance`;return X?[{kind:"written-in",part:E,how:`${X}, ${y}`}]:[]}),He=o=>d=>Fe(d)===o,fe=(o,d=()=>!0)=>Object.entries(a).filter(([,{edit:y}])=>d(y)).flatMap(([y,v])=>[...o.querySelectorAll(v.at)].filter(He(o)).map(E=>({name:y,node:E}))),ee=o=>fe(o,d=>d==="text"),K=o=>Object.entries(a).filter(([,{edit:d}])=>d==="data").map(([d,y])=>({name:d,node:[...o.querySelectorAll(y.at)].find(He(o))})).filter(({node:d})=>d),C=[],V=b()[u];if(!V)return[{kind:"gone"}];if(V.hasAttribute(n))return[{kind:"fallback"}];let me=await m(V);if(me===null)return[{kind:"moving"}];let ie=_(w),We=Z(V);C.push(...we(Z(ie),We,"as it mounts",{markup:!1}));let ge=ee(ie);ee(V).forEach(({name:o,node:d},y)=>{ge[y]&&ge[y].node.innerHTML!==d.innerHTML&&C.push({kind:"redrawn",part:o,how:`the file says ${JSON.stringify(ge[y].node.textContent.trim())}, the page ${JSON.stringify(d.textContent.trim())}`})});let ke=DocKit.dehydrate(V.cloneNode(!0)),[qe,Ge]=[G(ie),G(ke)],ye=D(qe,Ge);if(ye){let o=fe(Ge),d=fe(qe).find(({node:y},v)=>o[v]&&D(y,o[v].node))?.name;C.push({kind:"left",what:ye,...d?{part:d}:{}})}let ft=K(ke);for(let[o,{name:d,node:y}]of K(ie).entries())!ye&&ft[o]?.node.innerHTML!==y.innerHTML&&C.push({kind:"data",part:d});let Q=[],be=new MutationObserver(o=>Q.push(...o));be.observe(document.documentElement,{subtree:!0,childList:!0,characterData:!0});let Ue=new Set,Je=o=>{Q.push(...be.takeRecords());for(let{name:d,node:y}of o)(!y.isConnected||Q.some(({target:v})=>y.contains(v)))&&Ue.add(d);Q.length=0},$e=[me],xe=[ue(_e())],Ke=o=>{$e.push(o),xe.push(ue(_e())),C.push(...we(We,Z(j),"as it mounts again"))},j=ke,ve=ee(j);Q.length=0,V.replaceWith(j);let U=await m(j);if(Je(ve),U!==null){Ke(U);for(let o=0;o<s&&U!==null;o++){let d=j.cloneNode(!0);ve=ee(d),Q.length=0,j.replaceWith(d),j=d,U=await m(j),Je(ve),U!==null&&Ke(U)}}be.disconnect(),U===null&&C.push({kind:"moving"});for(let o of Ue)C.push({kind:"redrawn",part:o,how:"a mount changes it"});let Ve=$e.map(o=>ue(G(_(o)).querySelectorAll("*"))),Ye=Ie(Ve);for(let o of Ye)C.push({kind:"piles",what:o,counts:Ve.map(d=>d.get(o)??0)});for(let o of Ie(xe))C.push({kind:"piles",what:o,outside:!0,counts:xe.map(d=>d.get(o)??0)});if(!Ye.length){let o=$e.slice(1).map(d=>D(G(_(me)),G(_(d)))).find(Boolean);o&&C.push({kind:"changed",what:o})}let re=U===null?[]:ee(j).filter(({node:o})=>o.textContent.trim()),mt=[...new Set([...new Map(re.map(o=>[o.name,o])).values(),...re])].slice(0,c),gt=Date.now()+h;for(let{node:o}of mt){if(Date.now()>gt)break;let d=document.createTreeWalker(o,NodeFilter.SHOW_TEXT).nextNode(),y=d.data;d.data=`${y}\u2026`;let v=re.map(({node:N})=>N.textContent);await m(j);let E=re.find(({node:N},M)=>!N.isConnected||N.textContent!==v[M]);if(E){C.push({kind:"redrawn",part:E.name,how:"a change of its words does not stand"});break}d.data=y,await m(j)}return U!==null&&K(j).length>0&&C.push(...await kt()),C;async function kt(){let o=[],d=null,y=!1,v="as it hears that it can write (the editable signal)",E=[],N=I=>{if(I.target!==j)return;let{parts:A,run:X}=I.detail,W=A.map(({part:O})=>O.innerHTML),P=A.map(({part:O})=>O.cloneNode(!0)),te=X(Object.fromEntries(A.map(({name:O},R)=>[O,P[R]]))),J=A.find(({part:O},R)=>O.innerHTML!==W[R]),Y=A.find(({part:O},R)=>P[R].cloneNode(!1).outerHTML!==O.cloneNode(!1).outerHTML);if(J&&A.forEach(({part:O},R)=>{O.innerHTML=W[R]}),!y){let O=J??Y??A.find((R,ne)=>P[ne].innerHTML!==W[ne]);O&&!E.some(R=>R.when===v)?E.push({kind:"unasked",part:O.name,when:v}):te&&!O&&I.preventDefault();return}J?d??=`it writes the part ${J.name} on the page, not the draft context.edit hands it, so the editor refuses the edit`:te&&Y&&(d??=`it changes the part ${Y.name}'s own tag or attributes, which are the file's: a change writes what a part holds, so the editor refuses the edit`),!(J||!te||Y)&&(A.forEach(({part:O},R)=>{o.push({part:O,before:W[R]}),O.replaceChildren(...P[R].childNodes)}),I.preventDefault())};document.addEventListener("doc-component-edit",N);try{return[...await M(),...E]}finally{document.removeEventListener("doc-component-edit",N)}async function M(){dispatchEvent(new Event("doc-editable")),await m(j),v="as it mounts";let I=j.cloneNode(!0);j.replaceWith(I),j=I;let A=await m(j);v="as it hears its part changed (the source signal)";let X=Z(j),W=DocKit.dehydrate(j.cloneNode(!0)),P=[];y=!0;try{if(!DocKit.example(j))return K(j).every(({name:F})=>p.includes(F))?[]:[{kind:"no-example"}]}catch(F){return[{kind:"example",what:`it throws: ${F?.message??F}`}]}finally{y=!1}let te=await m(j),J=DocKit.dehydrate(j.cloneNode(!0)),Y=Object.fromEntries(K(J).map(({name:F,node:z},yt)=>[F,z.innerHTML,K(W)[yt]?.node.innerHTML]).filter(([,F,z])=>F!==z));d?P.push({kind:"example",what:d}):o.length===0?P.push({kind:"example",what:"context.edit was not taken: it was not called, or it answered false, and the console says why"}):Object.keys(Y).length===0?P.push({kind:"example",what:"it changes nothing a part holds"}):P.push({kind:"wrote",parts:Y});for(let F of[W,J])for(let{node:z}of K(F))z.textContent="";let O=D(G(W),G(J));O&&P.push({kind:"example",what:`it changes what is no data part: ${O}`}),P.push(...we(X,Z(j),"as its example makes its edit"));for(let{part:F,before:z}of o.reverse())F.innerHTML=z;let R=await m(j),ne=A!==null&&R!==null?D(G(_(A)),G(_(R))):null;return te===null||R===null?P.push({kind:"moving"}):ne&&!O&&P.push({kind:"undo",what:ne}),P}}}var Ut=e=>e.map(({name:t,removed:i,added:r,lines:n})=>`${t} (-${i} +${r} of its ${n} line${n===1?"":"s"})`).join(" and "),Jt="a write changes the lines it means and no others: a row moved by context.rows, which takes the blank before it along, JSON written back by context.editJSON and laid out in template.html and example.html as it writes it (block-script.md, Two examples)";function Re(e,t){try{return JSON.parse(e),Et(e,JSON.parse(t))===t}catch{return!1}}var Kt="it changes nothing a part holds";function Vt({kind:e,what:t,part:i,how:r,when:n,counts:a,outside:p,parts:u,back:w,line:l,json:f},s,{script:c}){let h=k=>({...s,what:k}),b=k=>({...s,what:k,note:!0});switch(e){case"wrote":return{...s,told:!0,what:`its example wrote ${Ut(u)}; the server took it${w?"; put back as an undo does, it shows what it showed":""}`};case"laid":return b(`its example's write lays the part ${i} out anew (${r}): ${Jt}${f?`; this write is context.editJSON's, and what the file held is laid out otherwise: lay ${i} out as it writes it`:""}`);case"drops":return{...b(`${t} listens for dragover and not for dragenter: a drop goes where both are cancelled, and the move that enters it asks dragenter alone, so that a release then (on a card's words, its padding) drops nothing: cancel dragenter as dragover is cancelled (preventDefault)`),file:"kit.js",line:l};case"controls":return{...b(`where nothing is written (this look is an export: context.canEdit() is false) the instance of ${s.file}${s.line?`:${s.line}`:""} still shows ${t}${a[0]>3?` and ${a[0]-3} more`:""}, enabled, and the block has a data part: a reader presses a control that writes to no effect, and the export says the block can be edited. Draw a control that writes only while context.canEdit(), and hide it by the hidden attribute (the kit holds [hidden] over any display the style gives it) or disable it; ignore this for a control that only changes what a reader looks at, a filter or a tab, which an export keeps. Compare 1024-light.png with edit-1024-light.png: the second is what a reader who can edit sees`),file:"kit.js",line:void 0};case"gone":return h("the page does not hold this instance");case"fallback":return h(c?"its component failed or never started: the instance shows what it holds, read-only":"the instance shows as one of no custom block");case"moving":return b("what it shows never holds still (an animation?), so its mounts could not be compared");case"redrawn":return h(`the component redraws its text part ${i}: ${r}. A text part is the file's, what the user types in: read it, and draw in what is the component's`);case"left":return h(`dehydrate does not leave it as the file has it, so a copy of the view would hold what the kit made of it: ${t}. ${i?`That stands in its part ${i}, which is the file's: read a part, and draw in what is the component's`:"Name what it draws in the manifest's runtime, or take it off in dehydrate"}`);case"data":return h(`a mount changes its data part ${i}, so that a page would write what the component left there, with nothing edited: read a data part, and change it by context.edit alone`);case"no-example":return b("it has a data part and its component offers no example of an edit, so nothing has tried the way back to the file: give DocKit.component an example(host, context) that makes a small context.edit");case"example":return t===Kt?{...s,file:"kit.js",line:void 0,what:`its example(host, context) changes nothing a part holds on the instance of ${s.file}${s.line?`:${s.line}`:""}: the check runs it on every instance of example.html and of template.html, and template.html's is empty, with nothing to change a value of (the first entry of a list it does not hold yet). Make example() make a change that works on an empty instance too (add an entry, set a field), and have it call the function a reader's control calls, so that it tries the code a reader runs`}:h(`its example: ${t}`);case"refused":return h("what its example wrote cannot go in the file: a script, a handler, an address of code, data-block-id or data-ge-*, what does not read back as itself, or what is no JSON in a script of data");case"undo":return h(`with what its example wrote put back, as an undo does, it does not show what it showed: ${t}: draw from the part, and on the source signal`);case"unasked":return h(`it writes its data part ${i} with no reader's gesture, ${n}, once the page takes edits: a page would write it each time it opened. Call context.edit on a gesture alone, a press, a drop or a key, and draw what the part holds as it is`);case"written-in":return h(`kit.js ${r}: a slot is the document's, its blocks the reader's: read it with context.part, never write in it or move it, and draw outside it`);case"piles":return h(p?`${t} piles up outside the instance on each put-back (${a.join(", then ")} of them), so an undo adds another: a component draws in its instance, and what it has to put elsewhere it takes away again in destroy`:`${t} piles up on each put-back (${a.join(", then ")} of them): it is declared in neither the manifest's runtime nor dehydrate, so an undo adds another`);default:return h(`a mount does not give the same DOM again: ${t}`)}}var Yt=e=>[...new Map(e.toReversed().map(t=>[`${t.finding.kind}|${t.finding.part??""}|${["piles","example"].includes(t.finding.kind)?t.finding.what:""}|${t.finding.when??""}|${t.finding.line??""}`,t])).values()].toReversed(),zt=4e6;function Pe(e,t,i=(r,n)=>r===n){let[r,n]=[e.split(`
11
11
  `),t.split(`
12
- `)],a=0;for(;a<r.length&&a<n.length&&i(r[a],n[a]);)a++;let p=0;for(;p<r.length-a&&p<n.length-a&&i(r[r.length-1-p],n[n.length-1-p]);)p++;let[u,w]=[r.slice(a,r.length-p),n.slice(a,n.length-p)];if(u.length===0&&w.length===0)return[];if(u.length*w.length>zt)return[{removed:u,added:w}];let l=Array.from({length:u.length+1},()=>new Uint32Array(w.length+1));for(let c=u.length-1;c>=0;c--)for(let h=w.length-1;h>=0;h--)l[c][h]=i(u[c],w[h])?l[c+1][h+1]+1:Math.max(l[c+1][h],l[c][h+1]);let f=[],s=null;for(let c=0,h=0;c<u.length||h<w.length;)c<u.length&&h<w.length&&i(u[c],w[h])?(s=null,c++,h++):(s||f.push(s={removed:[],added:[]}),h<w.length&&(c===u.length||l[c][h+1]>=l[c+1][h])?s.added.push(w[h++]):s.removed.push(u[c++]));return f}function Qt(e,t){let i=n=>n.filter(a=>a.trim()).length,r=Me(e,t);return{removed:r.reduce((n,a)=>n+i(a.removed),0),added:r.reduce((n,a)=>n+i(a.added),0),lines:i(e.split(`
13
- `))}}function Cn(e,t){let i=r=>r.map(n=>n.trim()).filter(Boolean);return Me(e,t).map(({removed:r,added:n})=>({removed:i(r),added:i(n)})).filter(({removed:r,added:n})=>r.length+n.length>0)}function at(e,t){let i=0,r=0;for(let[n,a]of e.entries())if(n>0&&i>0&&i<t&&r++,i+=a.replace(/\s+/g,"").length,i>=t)break;return r}function Xt(e,t){let i=r=>r.filter(n=>!n.trim()).length;for(let{removed:r,added:n}of Me(e,t,(a,p)=>a.trim()===p.trim())){if(i(n)>i(r))return"a line left blank";let[a,p]=[r.join("").replace(/\s+/g,""),n.join("").replace(/\s+/g,"")],u=0;for(;u<a.length&&u<p.length&&a[u]===p[u];)u++;let w=0;for(;w<a.length-u&&w<p.length-u&&a[a.length-1-w]===p[p.length-1-w];)w++;for(let[l,f,s]of[[u,r,n],[w,r.toReversed(),n.toReversed()]]){let[c,h]=[at(f,l)+1,at(s,l)+1];if(c!==h)return`${c} line${c===1?"":"s"} became ${h}`}}return null}function Zt(e,t){let i=Xt(e,t);return i&&!(Le(e,t)&&Le(e,e))?i:null}function en(e,{source:t,found:i,at:r,findings:n}){let a=Qe(t,dt(le(t),i)[r],e.parts,new Map([[i.id,i]]));if(!a)return[{kind:"refused"}];let p=Object.keys(e.parts),u=a.map(({start:l,end:f,text:s},c)=>({name:p[c],before:t.slice(l,f),after:s}));return[{kind:"wrote",back:!n.some(({kind:l})=>l==="undo"||l==="moving"),parts:u.map(({name:l,before:f,after:s})=>({name:l,...Qt(f,s)}))},...u.flatMap(({name:l,before:f,after:s})=>{let c=Zt(f,s);return c?[{kind:"laid",part:l,how:c,json:Le(f,s)}]:[]})]}var tn=2e3;function nn({match:e,instance:t,at:i,most:r}){let n=[...document.querySelectorAll(e)].filter(a=>!a.parentElement.closest(t))[i];return n?[window,document,n,...n.querySelectorAll("*")].slice(0,r):[]}function an(e){return e.map((t,i)=>i<2?{parent:i-1,named:""}:{parent:i===2?1:e.indexOf(t.parentElement),named:`<${t.localName}${t.classList.length?` class="${t.getAttribute("class")}"`:""}>`})}function sn(){let e=new DragEvent("dragenter",{bubbles:!0,cancelable:!0,composed:!0,dataTransfer:new DataTransfer});return this.dispatchEvent(e),e.defaultPrevented}async function on(e,{match:t,at:i}){let r=new Map,n=({scriptId:a,url:p})=>r.set(a,p);e.on("Debugger.scriptParsed",n);try{await e.send("Debugger.enable"),await e.send("Debugger.setSkipAllPauses",{skip:!0});let{result:a}=await e.send("Runtime.evaluate",{expression:`(${nn})(${JSON.stringify({match:t,instance:de,at:i,most:tn})})`,objectGroup:"drops"}),{result:p}=await e.send("Runtime.callFunctionOn",{objectId:a.objectId,functionDeclaration:String(an),arguments:[{objectId:a.objectId}],returnByValue:!0}),{result:u}=await e.send("Runtime.getProperties",{objectId:a.objectId,ownProperties:!0}),w=u.filter(({name:c,value:h})=>/^\d+$/.test(c)&&h?.objectId).sort((c,h)=>Number(c.name)-Number(h.name)),l=[];for(let{value:c}of w)l.push((await e.send("DOMDebugger.getEventListeners",{objectId:c.objectId})).listeners);let f=(c,h)=>l[c]?.some(b=>b.type===h),s=[];for(let c=2;c<l.length;c++){let h=l[c].find(k=>k.type==="dragover"&&r.get(k.scriptId)==="kit.js");if(!h)continue;let b=!1;for(let k=c;k>=2&&!b;k=p.value[k].parent)b=f(k,"dragenter");if(!b&&(f(0,"dragenter")||f(1,"dragenter"))){let{result:k}=await e.send("Runtime.callFunctionOn",{objectId:w[c].value.objectId,functionDeclaration:String(sn),returnByValue:!0});b=k.value===!0}b||s.push({kind:"drops",what:p.value[c].named,line:h.lineNumber+1})}return s}finally{e.off("Debugger.scriptParsed",n),await e.send("Runtime.releaseObjectGroup",{objectGroup:"drops"}).catch(()=>{}),await e.send("Debugger.disable").catch(()=>{})}}function rn(e,t){let i={errors:new Map,notes:new Set,failed:new Set,dialogs:new Set,windows:0,opened:[],asked:1,pending:[]},r=n=>{let[a]=n.split(`
12
+ `)],a=0;for(;a<r.length&&a<n.length&&i(r[a],n[a]);)a++;let p=0;for(;p<r.length-a&&p<n.length-a&&i(r[r.length-1-p],n[n.length-1-p]);)p++;let[u,w]=[r.slice(a,r.length-p),n.slice(a,n.length-p)];if(u.length===0&&w.length===0)return[];if(u.length*w.length>zt)return[{removed:u,added:w}];let l=Array.from({length:u.length+1},()=>new Uint32Array(w.length+1));for(let c=u.length-1;c>=0;c--)for(let h=w.length-1;h>=0;h--)l[c][h]=i(u[c],w[h])?l[c+1][h+1]+1:Math.max(l[c+1][h],l[c][h+1]);let f=[],s=null;for(let c=0,h=0;c<u.length||h<w.length;)c<u.length&&h<w.length&&i(u[c],w[h])?(s=null,c++,h++):(s||f.push(s={removed:[],added:[]}),h<w.length&&(c===u.length||l[c][h+1]>=l[c+1][h])?s.added.push(w[h++]):s.removed.push(u[c++]));return f}function Qt(e,t){let i=n=>n.filter(a=>a.trim()).length,r=Pe(e,t);return{removed:r.reduce((n,a)=>n+i(a.removed),0),added:r.reduce((n,a)=>n+i(a.added),0),lines:i(e.split(`
13
+ `))}}function Cn(e,t){let i=r=>r.map(n=>n.trim()).filter(Boolean);return Pe(e,t).map(({removed:r,added:n})=>({removed:i(r),added:i(n)})).filter(({removed:r,added:n})=>r.length+n.length>0)}function at(e,t){let i=0,r=0;for(let[n,a]of e.entries())if(n>0&&i>0&&i<t&&r++,i+=a.replace(/\s+/g,"").length,i>=t)break;return r}function Xt(e,t){let i=r=>r.filter(n=>!n.trim()).length;for(let{removed:r,added:n}of Pe(e,t,(a,p)=>a.trim()===p.trim())){if(i(n)>i(r))return"a line left blank";let[a,p]=[r.join("").replace(/\s+/g,""),n.join("").replace(/\s+/g,"")],u=0;for(;u<a.length&&u<p.length&&a[u]===p[u];)u++;let w=0;for(;w<a.length-u&&w<p.length-u&&a[a.length-1-w]===p[p.length-1-w];)w++;for(let[l,f,s]of[[u,r,n],[w,r.toReversed(),n.toReversed()]]){let[c,h]=[at(f,l)+1,at(s,l)+1];if(c!==h)return`${c} line${c===1?"":"s"} became ${h}`}}return null}function Zt(e,t){let i=Xt(e,t);return i&&!(Re(e,t)&&Re(e,e))?i:null}function en(e,{source:t,found:i,at:r,findings:n}){let a=Qe(t,dt(ce(t),i)[r],e.parts,new Map([[i.id,i]]));if(!a)return[{kind:"refused"}];let p=Object.keys(e.parts),u=a.map(({start:l,end:f,text:s},c)=>({name:p[c],before:t.slice(l,f),after:s}));return[{kind:"wrote",back:!n.some(({kind:l})=>l==="undo"||l==="moving"),parts:u.map(({name:l,before:f,after:s})=>({name:l,...Qt(f,s)}))},...u.flatMap(({name:l,before:f,after:s})=>{let c=Zt(f,s);return c?[{kind:"laid",part:l,how:c,json:Re(f,s)}]:[]})]}var tn=2e3;function nn({match:e,instance:t,at:i,most:r}){let n=[...document.querySelectorAll(e)].filter(a=>!a.parentElement.closest(t))[i];return n?[window,document,n,...n.querySelectorAll("*")].slice(0,r):[]}function an(e){return e.map((t,i)=>i<2?{parent:i-1,named:""}:{parent:i===2?1:e.indexOf(t.parentElement),named:`<${t.localName}${t.classList.length?` class="${t.getAttribute("class")}"`:""}>`})}function sn(){let e=new DragEvent("dragenter",{bubbles:!0,cancelable:!0,composed:!0,dataTransfer:new DataTransfer});return this.dispatchEvent(e),e.defaultPrevented}async function on(e,{match:t,at:i}){let r=new Map,n=({scriptId:a,url:p})=>r.set(a,p);e.on("Debugger.scriptParsed",n);try{await e.send("Debugger.enable"),await e.send("Debugger.setSkipAllPauses",{skip:!0});let{result:a}=await e.send("Runtime.evaluate",{expression:`(${nn})(${JSON.stringify({match:t,instance:he,at:i,most:tn})})`,objectGroup:"drops"}),{result:p}=await e.send("Runtime.callFunctionOn",{objectId:a.objectId,functionDeclaration:String(an),arguments:[{objectId:a.objectId}],returnByValue:!0}),{result:u}=await e.send("Runtime.getProperties",{objectId:a.objectId,ownProperties:!0}),w=u.filter(({name:c,value:h})=>/^\d+$/.test(c)&&h?.objectId).sort((c,h)=>Number(c.name)-Number(h.name)),l=[];for(let{value:c}of w)l.push((await e.send("DOMDebugger.getEventListeners",{objectId:c.objectId})).listeners);let f=(c,h)=>l[c]?.some(b=>b.type===h),s=[];for(let c=2;c<l.length;c++){let h=l[c].find(k=>k.type==="dragover"&&r.get(k.scriptId)==="kit.js");if(!h)continue;let b=!1;for(let k=c;k>=2&&!b;k=p.value[k].parent)b=f(k,"dragenter");if(!b&&(f(0,"dragenter")||f(1,"dragenter"))){let{result:k}=await e.send("Runtime.callFunctionOn",{objectId:w[c].value.objectId,functionDeclaration:String(sn),returnByValue:!0});b=k.value===!0}b||s.push({kind:"drops",what:p.value[c].named,line:h.lineNumber+1})}return s}finally{e.off("Debugger.scriptParsed",n),await e.send("Runtime.releaseObjectGroup",{objectGroup:"drops"}).catch(()=>{}),await e.send("Debugger.disable").catch(()=>{})}}function rn(e,t){let i={errors:new Map,notes:new Set,failed:new Set,dialogs:new Set,windows:0,opened:[],asked:1,pending:[]},r=n=>{let[a]=n.split(`
14
14
  `);i.errors.has(a)||i.errors.set(a,Number(/\bkit\.js:(\d+)/.exec(n)?.[1])||null)};return e.on("pageerror",n=>r(n.stack??n.message)),e.on("console",n=>{let a=n.type();!["error","warn","warning"].includes(a)||!Xe(n,t,["kit.js"])||i.pending.push(Promise.all(n.args().map(p=>p.evaluate(u=>u instanceof Error?u.stack:String(u)).catch(()=>""))).then(p=>{let u=p.join(" ")||n.text();a==="error"?r(u):i.notes.add(u.split(`
15
- `)[0])}))}),e.on("requestfailed",n=>{n.frame()===e.mainFrame()&&!n.isNavigationRequest()&&i.failed.add(n.url())}),e.on("request",n=>{n.isNavigationRequest()&&n.frame()===e.mainFrame()&&i.opened.push(n.url())}),i}async function ln(e,t){let i=await e.createCDPSession();return await i.send("Page.enable"),i.on("Page.javascriptDialogOpening",({type:r})=>{t.add(r),i.send("Page.handleJavaScriptDialog",{accept:!1}).catch(()=>{})}),i}function L(e,t,i=se){let r=0,n=()=>Object.assign(new Error(t),{stuck:!0,doing:t,limit:i}),a=new Promise((u,w)=>{r=setTimeout(()=>w(n()),i)}),p=e.catch(u=>{throw It.has(u.name)?n():Object.assign(u,{doing:t})});return Promise.race([p,a]).finally(()=>clearTimeout(r))}var cn=e=>`${Number((e/1e3).toFixed(1))} s`,pt=e=>`the browser did not answer within ${cn(e.limit)}, waiting until ${e.doing}`,Pe=e=>new Promise(t=>{if(!e.connected)return t(!0);e.once("disconnected",()=>t(!0)),setTimeout(()=>t(!1),lt)});function dn({match:e,instance:t}){let{clientWidth:i,scrollWidth:r}=document.documentElement;if(r<=i+1)return null;let n=[...document.querySelectorAll(e)].filter(a=>!a.parentElement.closest(t));return{wide:r,at:n.findIndex(a=>[a,...a.querySelectorAll("*")].some(p=>p.getBoundingClientRect().right>i+1))}}var st=16,hn="#8f8f8f";async function pn(e,t,i){let r=await Promise.all(t.map(async n=>`data:image/png;base64,${(await T.readFile(n)).toString("base64")}`));await e.setViewport({width:ae.reduce((n,a)=>n+a,0)+st*(ae.length-1),height:900}),await e.setContent(`<!doctype html><body style="margin: 0; display: flex; align-items: flex-start; gap: ${st}px; background: ${hn}">${r.map((n,a)=>`<img src="${n}" width="${ae[a]}" alt="" style="display: block">`).join("")}</body>`,{waitUntil:"load"}),await e.screenshot({path:i,fullPage:!0})}async function ut(e,{file:t,html:i,source:r,places:n,found:a,out:p,loading:u,answer:w=se}){let l=(m,_)=>L(m,_,w),f=await l(e.createBrowserContext(),"a browser context opened"),s=await l(f.newPage(),"a tab opened"),c=Re(t).href,h=rn(s,c),b=await l(ln(s,h.dialogs),"the tab was set to refuse dialogs");f.on("targetcreated",m=>{m.type()==="page"&&(h.windows+=1,m.page().then(_=>_?.close()).then(()=>s.bringToFront()).catch(()=>{}))});let k={heard:h,blocked:[],late:[],taken:[],overviews:[],edited:[],asExport:[],answers:[],wide:[],stuck:null,stopped:null,gone:null},g=async m=>k.late.push(...await L(et(s,{timeout:nt}),m,3*nt+se));await l(Ze(s),"the tab was set to keep what the policy blocks"),await l(s.setViewport({width:736,height:900}),"the window went to 736px"),await l(s.emulateMediaFeatures([{name:"prefers-color-scheme",value:"light"}]),"the light theme came");try{await L(s.goto(c,{waitUntil:"load",timeout:0}),"the page opened",u),await g("the page opened");for(let $ of Ae){await L(s.emulateMediaFeatures([{name:"prefers-color-scheme",value:$}]),`the ${$} theme came`);for(let S of ae){if(await L(s.setViewport({width:S,height:900}),`the window went to ${S}px`),await g(`it was drawn at ${S}px`),$===Ae[0]){let H=await L(s.evaluate(dn,{match:a.match,instance:de}),`it was measured at ${S}px`);H&&k.wide.push({width:S,...H})}let B=x.join(p,`${S}-${$}.png`);await L(s.screenshot({path:B,fullPage:!0}),`it was pictured at ${S}px`),k.taken.push(B)}}await L(s.emulateMediaFeatures([{name:"prefers-color-scheme",value:"light"}]),"the light theme came"),await L(s.setViewport({width:736,height:900}),"the window went to 736px");let m=De(i,a);for(let{at:$,...S}of await L(s.evaluate(qt,{match:a.match,instance:de,slot:tt,parts:a.parts,boards:a.settings?.length?[ve]:[]}),"the page was asked what each instance still shows"))k.answers.push({finding:{kind:"controls",...S},place:n[$]});let _=a.files.includes("kit.js")&&Object.values(a.parts).some(({edit:$})=>$==="data");for(let $=0;$<m.length;$++){let S=await L(s.evaluate(Gt,{match:a.match,instance:de,slotPart:tt,slotName:vt,fallback:xt,parts:a.parts,boards:a.settings?.length?[ve]:[],at:$,source:m[$].markup,still:Rt,step:Dt,times:Mt,typed:Pt,typing:Ct}),"an instance was put back"),B=S.find(({kind:D})=>D==="wrote"),H=[...S.filter(D=>D!==B),...B?en(B,{source:r,found:a,at:$,findings:S}):[]];_&&!S.some(({kind:D})=>D==="gone"||D==="fallback")&&H.push(...await L(on(b,{match:a.match,at:$}),"the page was asked what an instance listens to")),k.answers.push(...H.map(D=>({finding:D,place:n[$]})))}k.blocked=await L(s.evaluate(()=>globalThis.__qaViolations),"the page was asked what it blocked"),h.asked+=1,await L(s.goto(c,{waitUntil:"load",timeout:0}),"the page opened again",u),await g("the page opened again"),await L(s.evaluate(()=>dispatchEvent(new Event("doc-editable"))),"the page was told it takes edits"),await g("it was drawn as the editing page draws it");for(let $ of Lt){await L(s.setViewport({width:$,height:900}),`the window went to ${$}px`),await g(`it was drawn at ${$}px as the editing page draws it`);let S=x.join(p,`edit-${$}-light.png`);await L(s.screenshot({path:S,fullPage:!0}),`it was pictured at ${$}px as the editing page draws it`),k.edited.push(S),(await T.readFile(S)).equals(await T.readFile(x.join(p,`${$}-light.png`)))&&k.asExport.push(S)}k.blocked.push(...await L(s.evaluate(()=>globalThis.__qaViolations),"the page was asked what it blocked"));for(let $ of Ae){let S=x.join(p,`overview-${$}.png`);await L(pn(s,ae.map(B=>x.join(p,`${B}-${$}.png`)),S),`the ${$} pictures were put side by side`),k.overviews.push(S)}}catch(m){if(m.syscall)throw m;await Pe(e)?k.gone=m.doing??"the page answered":m.stuck?k.stuck=m.doing:k.stopped=oe(m)}return await Promise.race([Promise.all(h.pending),new Promise(m=>setTimeout(m,lt).unref())]),k}var un=(e,t)=>e.startsWith(t)?e.slice(t.length):e;function wn(e,t,i){let r=new Map;for(let{url:n,directive:a,source:p,line:u}of e){if(_t.test(n)){let l=!p&&u>0;r.set(`${n}|${p}|${u}`,{file:l?"kit.js":"the page",...l?{line:u}:{},what:"the export's policy blocks code made from words (eval, new Function, a string given to setTimeout): an export runs none"});continue}let w=/^[a-z][a-z0-9+.-]*$/.test(n)?t.filter(l=>l.startsWith(`${n}:`)):[];for(let l of w.length?w:[n])r.set(`${l}|${a}`,{file:"the page",what:`the export's policy blocks ${un(l,i)||"something"} (${a}): ${a==="img-src"?"a picture of an instance is a data: address, or a file its style names":"an export holds all it needs"}`})}return[...r.values()]}function wt({heard:e,blocked:t,late:i,answers:r,wide:n,stuck:a,stopped:p},{places:u,script:w,folder:l}){let f=Yt(r).map(({finding:g,place:m})=>Vt(g,m,{script:w})),s=[...e.failed],c=s.filter(g=>!t.some(m=>m.url&&g.startsWith(m.url))),h=e.opened.length>e.asked?"it loads itself again (location.reload(), a new location.href), so a reader's page would not stay":a?`it stopped answering while waiting until ${a}${w?": a script that never ends, or a component that changes what it hears (a text part, on its source signal)":""}`:p&&`the look at it stopped: ${p}`,b=n.map(({width:g,wide:m})=>`${m}px wide in a ${g}px window`).join(", "),k=u[n.find(({at:g})=>g>=0)?.at]??{file:"the page"};return{problems:[...[...e.errors].map(([g,m])=>({file:m?"kit.js":"the page",line:m,what:`the console says ${g}`})),...wn(t,s,l),...c.map(g=>({file:"the page",what:`it could not load ${g.slice(0,120)}`})),...[...e.dialogs].map(g=>({file:"the page",what:`it opens a dialog (${g}), which stops a reader's page until it is answered: show what it says in the instance`})),...e.windows?[{file:"the page",what:"it opens a window, which takes a reader away from the page: show it in the instance, or link to it"}]:[],...h?[{file:"the page",what:h}]:[],...n.length?[{...k,what:`the page is ${b}: a reader scrolls the whole page sideways, and gallery qa fails it: let it fit the window (max-width: 100%), or put what is wider in a frame of its own that scrolls`}]:[],...f.filter(({note:g,told:m})=>!g&&!m)],notes:[...[...e.notes].map(g=>({file:"the page",what:`the console says ${g}`})),...f.filter(({note:g})=>g),...i.map(g=>({file:"the page",what:`waited for ${g}`}))],told:f.filter(({told:g})=>g)}}async function _n(e,t,{example:i,template:r},{find:n=Te,start:a=Oe,loading:p=rt,answer:u=se}={}){let w=At,l=null,f=null;try{l=await T.mkdtemp(x.join(he.tmpdir(),"gallery-component-check-"));let s=await Wt(t,{example:i,template:r},l),c=n();if(!c)return{title:w,unverified:"no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one)"};try{f=await a({executablePath:c,args:Ne()})}catch(g){return{title:w,unverified:`the browser ${c} did not start, twice, each time with a fresh profile (${oe(g)}; GALLERY_BROWSER=<its executable> picks another)`}}let h=x.join(it(e).qa,"components",...t.id.split("/"));await T.rm(h,{recursive:!0,force:!0}),await T.mkdir(h,{recursive:!0});let b=await ut(f.browser,{...s,found:t,out:h,loading:p,answer:u}),k=wt(b,{places:s.places,script:t.files.includes("kit.js"),folder:Re(`${l}${x.sep}`).href});return b.gone?{title:w,...k,unverified:`the browser went while waiting until ${b.gone}, so it says nothing of the block`}:{title:w,...k,...b.taken.length?{pictures:{folder:h,overviews:b.overviews.map(g=>x.basename(g)),each:b.taken.map(g=>x.basename(g)),edited:b.edited.map(g=>x.basename(g)),asExport:b.asExport.map(g=>x.basename(g))}}:{}}}catch(s){return s.reason==="check"?{title:w,problems:s.failures.map(c=>({file:"the export",what:c}))}:s.syscall?{title:w,unverified:`cannot write ${je(s.syscall==="mkdtemp"?he.tmpdir():s.path)} (${s.code})`}:f&&await Pe(f.browser)?{title:w,unverified:"the browser went before the page opened"}:s.stuck?{title:w,problems:[{file:"the page",what:`${pt(s)}, so the look stopped and the browser was closed`}]}:{title:w,problems:[{file:"the page",what:`the look at it stopped: ${oe(s)}`}]}}finally{await f?.close(),l&&await T.rm(l,{recursive:!0,force:!0,maxRetries:5,retryDelay:200}).catch(()=>{})}}async function fn(e,t){let i=[];for(let r of await Nt(e)){let n=jt(r,e),a=Tt(n).html,p=await T.readFile(a,"utf8").catch(()=>null);if(p===null)continue;let u=ot(le(p),t),w=f=>{for(let s=f.parentNode;s;s=s.parentNode)if(u.includes(s))return!0;return!1},l=u.filter(f=>!w(f)).map(({sourceCodeLocation:{startLine:f,startOffset:s,endOffset:c}})=>({line:f,markup:p.slice(s,c)}));l.length&&i.push({slug:r,place:`${r}/${x.basename(a)}`,directory:n,instances:l})}return i}async function mn(e,t,i,r){let n=t.instances.map(({line:s,markup:c})=>`<p>${t.place}:${s}</p>${c}`).join(`
16
- `);for(let s of new Set([e.id,...[...n.matchAll(new RegExp(`${$t}="([^"]+)"`,"g"))].map(([,c])=>c)])){let c=s===e.id?e:i.get(s);c&&await ht(c,r)}let a=x.join(r,q);await T.mkdir(a),await T.cp(x.join(t.directory,"assets"),x.join(a,"assets"),{recursive:!0}).catch(s=>{if(s.code!=="ENOENT")throw s});let p=Se(ct(q,n)).text;await T.writeFile(x.join(a,"doc.html"),p),await T.writeFile(x.join(a,"doc.json"),JSON.stringify({title:q,description:q,type:"component"}));let w=await(await Ee({directory:r}))(q),l=x.join(r,"export.html");await T.writeFile(l,w);let f=De(p,e).map((s,c)=>({file:t.place,line:t.instances[c]?.line??null}));return{html:w,file:l,places:f,source:p}}async function In(e,t,{find:i=Te,start:r=Oe,loading:n=rt}={}){let a=await fn(e,t);if(a.length===0)return[{title:ce(),none:`none holds an instance of ${t.id}`}];let p=i();if(!p)return[{title:ce(),unverified:"no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one)"}];let u;try{u=await r({executablePath:p,args:Ne()})}catch(f){return[{title:ce(),unverified:`the browser ${p} did not start, twice, each time with a fresh profile (${oe(f)}; GALLERY_BROWSER=<its executable> picks another)`}]}let{packages:w}=Ye(e),l=[];try{for(let f of a){let s=ce(f.place),c=null;try{c=await T.mkdtemp(x.join(he.tmpdir(),"gallery-component-check-"));let h=await mn(t,f,w,c),b=x.join(it(e).qa,"components",...t.id.split("/"),"documents",f.slug);await T.rm(b,{recursive:!0,force:!0}),await T.mkdir(b,{recursive:!0});let k=await ut(u.browser,{...h,found:t,out:b,loading:n}),g=wt(k,{places:h.places,script:t.files.includes("kit.js"),folder:Re(`${c}${x.sep}`).href});if(k.gone){l.push({title:s,...g,unverified:`the browser went while waiting until ${k.gone}, so it says nothing of these instances`});break}l.push({title:s,...g,...k.taken.length?{pictures:{folder:b,overviews:k.overviews.map(m=>x.basename(m)),each:k.taken.map(m=>x.basename(m)),edited:k.edited.map(m=>x.basename(m)),asExport:k.asExport.map(m=>x.basename(m)),documents:!0}}:{}})}catch(h){if(h.reason==="check")l.push({title:s,problems:h.failures.map(b=>({file:f.place,what:`its instances, exported alone: ${b}`}))});else if(h.syscall)l.push({title:s,unverified:`cannot write ${je(h.syscall==="mkdtemp"?he.tmpdir():h.path)} (${h.code})`});else if(await Pe(u.browser)){l.push({title:s,unverified:"the browser went before the page opened"});break}else if(h.stuck){l.push({title:s,problems:[{file:"the page",what:`${pt(h)}, so the look at them stopped, the browser was closed, and no document after them was looked at`}]});break}else l.push({title:s,problems:[{file:"the page",what:`the look at them stopped: ${oe(h)}`}]})}finally{c&&await T.rm(c,{recursive:!0,force:!0,maxRetries:5,retryDelay:200}).catch(()=>{})}}}finally{await u.close()}return l}export{At as a,ce as b,rt as c,se as d,Dn as e,Rt as f,Dt as g,Mn as h,Pn as i,oe as j,ct as k,Ut as l,Jt as m,Qt as n,Cn as o,Zt as p,ln as q,L as r,cn as s,pt as t,Pe as u,_n as v,In as w};
15
+ `)[0])}))}),e.on("requestfailed",n=>{n.frame()===e.mainFrame()&&!n.isNavigationRequest()&&i.failed.add(n.url())}),e.on("request",n=>{n.isNavigationRequest()&&n.frame()===e.mainFrame()&&i.opened.push(n.url())}),i}async function ln(e,t){let i=await e.createCDPSession();return await i.send("Page.enable"),i.on("Page.javascriptDialogOpening",({type:r})=>{t.add(r),i.send("Page.handleJavaScriptDialog",{accept:!1}).catch(()=>{})}),i}function L(e,t,i=se){let r=0,n=()=>Object.assign(new Error(t),{stuck:!0,doing:t,limit:i}),a=new Promise((u,w)=>{r=setTimeout(()=>w(n()),i)}),p=e.catch(u=>{throw It.has(u.name)?n():Object.assign(u,{doing:t})});return Promise.race([p,a]).finally(()=>clearTimeout(r))}var cn=e=>`${Number((e/1e3).toFixed(1))} s`,pt=e=>`the browser did not answer within ${cn(e.limit)}, waiting until ${e.doing}`,Ce=e=>new Promise(t=>{if(!e.connected)return t(!0);e.once("disconnected",()=>t(!0)),setTimeout(()=>t(!1),lt)});function dn({match:e,instance:t}){let{clientWidth:i,scrollWidth:r}=document.documentElement;if(r<=i+1)return null;let n=[...document.querySelectorAll(e)].filter(a=>!a.parentElement.closest(t));return{wide:r,at:n.findIndex(a=>[a,...a.querySelectorAll("*")].some(p=>p.getBoundingClientRect().right>i+1))}}var st=16,hn="#8f8f8f";async function pn(e,t,i){let r=await Promise.all(t.map(async n=>`data:image/png;base64,${(await T.readFile(n)).toString("base64")}`));await e.setViewport({width:ae.reduce((n,a)=>n+a,0)+st*(ae.length-1),height:900}),await e.setContent(`<!doctype html><body style="margin: 0; display: flex; align-items: flex-start; gap: ${st}px; background: ${hn}">${r.map((n,a)=>`<img src="${n}" width="${ae[a]}" alt="" style="display: block">`).join("")}</body>`,{waitUntil:"load"}),await e.screenshot({path:i,fullPage:!0})}async function ut(e,{file:t,html:i,source:r,places:n,found:a,out:p,loading:u,answer:w=se}){let l=(m,_)=>L(m,_,w),f=await l(e.createBrowserContext(),"a browser context opened"),s=await l(f.newPage(),"a tab opened"),c=De(t).href,h=rn(s,c),b=await l(ln(s,h.dialogs),"the tab was set to refuse dialogs");f.on("targetcreated",m=>{m.type()==="page"&&(h.windows+=1,m.page().then(_=>_?.close()).then(()=>s.bringToFront()).catch(()=>{}))});let k={heard:h,blocked:[],late:[],taken:[],overviews:[],edited:[],asExport:[],answers:[],wide:[],stuck:null,stopped:null,gone:null},g=async m=>k.late.push(...await L(et(s,{timeout:nt}),m,3*nt+se));await l(Ze(s),"the tab was set to keep what the policy blocks"),await l(s.setViewport({width:736,height:900}),"the window went to 736px"),await l(s.emulateMediaFeatures([{name:"prefers-color-scheme",value:"light"}]),"the light theme came");try{await L(s.goto(c,{waitUntil:"load",timeout:0}),"the page opened",u),await g("the page opened");for(let $ of Le){await L(s.emulateMediaFeatures([{name:"prefers-color-scheme",value:$}]),`the ${$} theme came`);for(let S of ae){if(await L(s.setViewport({width:S,height:900}),`the window went to ${S}px`),await g(`it was drawn at ${S}px`),$===Le[0]){let H=await L(s.evaluate(dn,{match:a.match,instance:he}),`it was measured at ${S}px`);H&&k.wide.push({width:S,...H})}let B=x.join(p,`${S}-${$}.png`);await L(s.screenshot({path:B,fullPage:!0}),`it was pictured at ${S}px`),k.taken.push(B)}}await L(s.emulateMediaFeatures([{name:"prefers-color-scheme",value:"light"}]),"the light theme came"),await L(s.setViewport({width:736,height:900}),"the window went to 736px");let m=Me(i,a);for(let{at:$,...S}of await L(s.evaluate(qt,{match:a.match,instance:he,slot:tt,parts:a.parts,boards:a.settings?.length?[Ee]:[]}),"the page was asked what each instance still shows"))k.answers.push({finding:{kind:"controls",...S},place:n[$]});let _=a.files.includes("kit.js")&&Object.values(a.parts).some(({edit:$})=>$==="data");for(let $=0;$<m.length;$++){let S=await L(s.evaluate(Gt,{match:a.match,instance:he,slotPart:tt,slotName:vt,fallback:xt,parts:a.parts,boards:a.settings?.length?[Ee]:[],at:$,source:m[$].markup,still:Rt,step:Dt,times:Mt,typed:Pt,typing:Ct}),"an instance was put back"),B=S.find(({kind:D})=>D==="wrote"),H=[...S.filter(D=>D!==B),...B?en(B,{source:r,found:a,at:$,findings:S}):[]];_&&!S.some(({kind:D})=>D==="gone"||D==="fallback")&&H.push(...await L(on(b,{match:a.match,at:$}),"the page was asked what an instance listens to")),k.answers.push(...H.map(D=>({finding:D,place:n[$]})))}k.blocked=await L(s.evaluate(()=>globalThis.__qaViolations),"the page was asked what it blocked"),h.asked+=1,await L(s.goto(c,{waitUntil:"load",timeout:0}),"the page opened again",u),await g("the page opened again"),await L(s.evaluate(()=>dispatchEvent(new Event("doc-editable"))),"the page was told it takes edits"),await g("it was drawn as the editing page draws it");for(let $ of Lt){await L(s.setViewport({width:$,height:900}),`the window went to ${$}px`),await g(`it was drawn at ${$}px as the editing page draws it`);let S=x.join(p,`edit-${$}-light.png`);await L(s.screenshot({path:S,fullPage:!0}),`it was pictured at ${$}px as the editing page draws it`),k.edited.push(S),(await T.readFile(S)).equals(await T.readFile(x.join(p,`${$}-light.png`)))&&k.asExport.push(S)}k.blocked.push(...await L(s.evaluate(()=>globalThis.__qaViolations),"the page was asked what it blocked"));for(let $ of Le){let S=x.join(p,`overview-${$}.png`);await L(pn(s,ae.map(B=>x.join(p,`${B}-${$}.png`)),S),`the ${$} pictures were put side by side`),k.overviews.push(S)}}catch(m){if(m.syscall)throw m;await Ce(e)?k.gone=m.doing??"the page answered":m.stuck?k.stuck=m.doing:k.stopped=oe(m)}return await Promise.race([Promise.all(h.pending),new Promise(m=>setTimeout(m,lt).unref())]),k}var un=(e,t)=>e.startsWith(t)?e.slice(t.length):e;function wn(e,t,i){let r=new Map;for(let{url:n,directive:a,source:p,line:u}of e){if(_t.test(n)){let l=!p&&u>0;r.set(`${n}|${p}|${u}`,{file:l?"kit.js":"the page",...l?{line:u}:{},what:"the export's policy blocks code made from words (eval, new Function, a string given to setTimeout): an export runs none"});continue}let w=/^[a-z][a-z0-9+.-]*$/.test(n)?t.filter(l=>l.startsWith(`${n}:`)):[];for(let l of w.length?w:[n])r.set(`${l}|${a}`,{file:"the page",what:`the export's policy blocks ${un(l,i)||"something"} (${a}): ${a==="img-src"?"a picture of an instance is a data: address, or a file its style names":"an export holds all it needs"}`})}return[...r.values()]}function wt({heard:e,blocked:t,late:i,answers:r,wide:n,stuck:a,stopped:p},{places:u,script:w,folder:l}){let f=Yt(r).map(({finding:g,place:m})=>Vt(g,m,{script:w})),s=[...e.failed],c=s.filter(g=>!t.some(m=>m.url&&g.startsWith(m.url))),h=e.opened.length>e.asked?"it loads itself again (location.reload(), a new location.href), so a reader's page would not stay":a?`it stopped answering while waiting until ${a}${w?": a script that never ends, or a component that changes what it hears (a text part, on its source signal)":""}`:p&&`the look at it stopped: ${p}`,b=n.map(({width:g,wide:m})=>`${m}px wide in a ${g}px window`).join(", "),k=u[n.find(({at:g})=>g>=0)?.at]??{file:"the page"};return{problems:[...[...e.errors].map(([g,m])=>({file:m?"kit.js":"the page",line:m,what:`the console says ${g}`})),...wn(t,s,l),...c.map(g=>({file:"the page",what:`it could not load ${g.slice(0,120)}`})),...[...e.dialogs].map(g=>({file:"the page",what:`it opens a dialog (${g}), which stops a reader's page until it is answered: show what it says in the instance`})),...e.windows?[{file:"the page",what:"it opens a window, which takes a reader away from the page: show it in the instance, or link to it"}]:[],...h?[{file:"the page",what:h}]:[],...n.length?[{...k,what:`the page is ${b}: a reader scrolls the whole page sideways, and gallery qa fails it: let it fit the window (max-width: 100%), or put what is wider in a frame of its own that scrolls`}]:[],...f.filter(({note:g,told:m})=>!g&&!m)],notes:[...[...e.notes].map(g=>({file:"the page",what:`the console says ${g}`})),...f.filter(({note:g})=>g),...i.map(g=>({file:"the page",what:`waited for ${g}`}))],told:f.filter(({told:g})=>g)}}async function _n(e,t,{example:i,template:r},{find:n=Ne,start:a=Ae,loading:p=rt,answer:u=se}={}){let w=At,l=null,f=null;try{l=await T.mkdtemp(x.join(pe.tmpdir(),"gallery-component-check-"));let s=await Wt(t,{example:i,template:r},l),c=n();if(!c)return{title:w,unverified:"no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one)"};try{f=await a({executablePath:c,args:Oe()})}catch(g){return{title:w,unverified:`the browser ${c} did not start, twice, each time with a fresh profile (${oe(g)}; GALLERY_BROWSER=<its executable> picks another)`}}let h=x.join(it(e).qa,"components",...t.id.split("/"));await T.rm(h,{recursive:!0,force:!0}),await T.mkdir(h,{recursive:!0});let b=await ut(f.browser,{...s,found:t,out:h,loading:p,answer:u}),k=wt(b,{places:s.places,script:t.files.includes("kit.js"),folder:De(`${l}${x.sep}`).href});return b.gone?{title:w,...k,unverified:`the browser went while waiting until ${b.gone}, so it says nothing of the block`}:{title:w,...k,...b.taken.length?{pictures:{folder:h,overviews:b.overviews.map(g=>x.basename(g)),each:b.taken.map(g=>x.basename(g)),edited:b.edited.map(g=>x.basename(g)),asExport:b.asExport.map(g=>x.basename(g))}}:{}}}catch(s){return s.reason==="check"?{title:w,problems:s.failures.map(c=>({file:"the export",what:c}))}:s.syscall?{title:w,unverified:`cannot write ${Te(s.syscall==="mkdtemp"?pe.tmpdir():s.path)} (${s.code})`}:f&&await Ce(f.browser)?{title:w,unverified:"the browser went before the page opened"}:s.stuck?{title:w,problems:[{file:"the page",what:`${pt(s)}, so the look stopped and the browser was closed`}]}:{title:w,problems:[{file:"the page",what:`the look at it stopped: ${oe(s)}`}]}}finally{await f?.close(),l&&await T.rm(l,{recursive:!0,force:!0,maxRetries:5,retryDelay:200}).catch(()=>{})}}async function fn(e,t){let i=[];for(let r of await Nt(e)){let n=jt(r,e),a=Tt(n).html,p=await T.readFile(a,"utf8").catch(()=>null);if(p===null)continue;let u=ot(ce(p),t),w=f=>{for(let s=f.parentNode;s;s=s.parentNode)if(u.includes(s))return!0;return!1},l=u.filter(f=>!w(f)).map(({sourceCodeLocation:{startLine:f,startOffset:s,endOffset:c}})=>({line:f,markup:p.slice(s,c)}));l.length&&i.push({slug:r,place:`${r}/${x.basename(a)}`,directory:n,instances:l})}return i}async function mn(e,t,i,r){let n=t.instances.map(({line:s,markup:c})=>`<p>${t.place}:${s}</p>${c}`).join(`
16
+ `);for(let s of new Set([e.id,...[...n.matchAll(new RegExp(`${$t}="([^"]+)"`,"g"))].map(([,c])=>c)])){let c=s===e.id?e:i.get(s);c&&await ht(c,r)}let a=x.join(r,q);await T.mkdir(a),await T.cp(x.join(t.directory,"assets"),x.join(a,"assets"),{recursive:!0}).catch(s=>{if(s.code!=="ENOENT")throw s});let p=je(ct(q,n)).text;await T.writeFile(x.join(a,"doc.html"),p),await T.writeFile(x.join(a,"doc.json"),JSON.stringify({title:q,description:q,type:"component"}));let w=await(await Se({directory:r,catalog:le(r)}))(q),l=x.join(r,"export.html");await T.writeFile(l,w);let f=Me(p,e).map((s,c)=>({file:t.place,line:t.instances[c]?.line??null}));return{html:w,file:l,places:f,source:p}}async function In(e,t,{find:i=Ne,start:r=Ae,loading:n=rt}={}){let a=await fn(e,t);if(a.length===0)return[{title:de(),none:`none holds an instance of ${t.id}`}];let p=i();if(!p)return[{title:de(),unverified:"no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one)"}];let u;try{u=await r({executablePath:p,args:Oe()})}catch(f){return[{title:de(),unverified:`the browser ${p} did not start, twice, each time with a fresh profile (${oe(f)}; GALLERY_BROWSER=<its executable> picks another)`}]}let{packages:w}=le(e),l=[];try{for(let f of a){let s=de(f.place),c=null;try{c=await T.mkdtemp(x.join(pe.tmpdir(),"gallery-component-check-"));let h=await mn(t,f,w,c),b=x.join(it(e).qa,"components",...t.id.split("/"),"documents",f.slug);await T.rm(b,{recursive:!0,force:!0}),await T.mkdir(b,{recursive:!0});let k=await ut(u.browser,{...h,found:t,out:b,loading:n}),g=wt(k,{places:h.places,script:t.files.includes("kit.js"),folder:De(`${c}${x.sep}`).href});if(k.gone){l.push({title:s,...g,unverified:`the browser went while waiting until ${k.gone}, so it says nothing of these instances`});break}l.push({title:s,...g,...k.taken.length?{pictures:{folder:b,overviews:k.overviews.map(m=>x.basename(m)),each:k.taken.map(m=>x.basename(m)),edited:k.edited.map(m=>x.basename(m)),asExport:k.asExport.map(m=>x.basename(m)),documents:!0}}:{}})}catch(h){if(h.reason==="check")l.push({title:s,problems:h.failures.map(b=>({file:f.place,what:`its instances, exported alone: ${b}`}))});else if(h.syscall)l.push({title:s,unverified:`cannot write ${Te(h.syscall==="mkdtemp"?pe.tmpdir():h.path)} (${h.code})`});else if(await Ce(u.browser)){l.push({title:s,unverified:"the browser went before the page opened"});break}else if(h.stuck){l.push({title:s,problems:[{file:"the page",what:`${pt(h)}, so the look at them stopped, the browser was closed, and no document after them was looked at`}]});break}else l.push({title:s,problems:[{file:"the page",what:`the look at them stopped: ${oe(h)}`}]})}finally{c&&await T.rm(c,{recursive:!0,force:!0,maxRetries:5,retryDelay:200}).catch(()=>{})}}}finally{await u.close()}return l}export{At as a,de as b,rt as c,se as d,Dn as e,Rt as f,Dt as g,Mn as h,Pn as i,oe as j,ct as k,Ut as l,Jt as m,Qt as n,Cn as o,Zt as p,ln as q,L as r,cn as s,pt as t,Ce as u,_n as v,In as w};
@@ -1,2 +1,2 @@
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{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"./chunk-36FIRJIF.mjs";import"./chunk-5L7RYZCL.mjs";export{a as Browser,b as BrowserPlatform,c as BrowserTag,o as CDP_WEBSOCKET_ENDPOINT_REGEX,y as CLI,k as Cache,d as ChromeReleaseChannel,s as DefaultProvider,j as InstalledBrowser,q as Process,r as TimeoutError,p as WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX,z as buildArchiveFilename,w as canDownload,l as computeExecutablePath,m as computeSystemExecutablePath,f as createProfile,i as detectBrowserPlatform,x as getDownloadUrl,v as getInstalledBrowsers,h as getVersionComparator,t as install,n as launch,e as resolveBuildId,g as resolveDefaultUserDataDir,u as uninstall};
2
+ import{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"./chunk-742D2WWJ.mjs";import"./chunk-5L7RYZCL.mjs";export{a as Browser,b as BrowserPlatform,c as BrowserTag,o as CDP_WEBSOCKET_ENDPOINT_REGEX,y as CLI,k as Cache,d as ChromeReleaseChannel,s as DefaultProvider,j as InstalledBrowser,q as Process,r as TimeoutError,p as WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX,z as buildArchiveFilename,w as canDownload,l as computeExecutablePath,m as computeSystemExecutablePath,f as createProfile,i as detectBrowserPlatform,x as getDownloadUrl,v as getInstalledBrowsers,h as getVersionComparator,t as install,n as launch,e as resolveBuildId,g as resolveDefaultUserDataDir,u as uninstall};
@@ -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 as h,b as v,d as p,e as S,h as j,j as I}from"./chunk-GMJD7ID3.mjs";import{a as A}from"./chunk-JEUK3ZO7.mjs";import{a as C}from"./chunk-JPG2LBQM.mjs";import"./chunk-ALZ6ZENZ.mjs";import"./chunk-IA4PSIMD.mjs";import{g as O}from"./chunk-7M2BQQGZ.mjs";import{b as i,f as g,i as y}from"./chunk-4OZWXZE5.mjs";import"./chunk-ZTHICSSF.mjs";import"./chunk-UMHUSOPJ.mjs";import"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";import D from"node:path";import{pageLinks as F,pageOfLink as J}from"../browser/shared/page-links.mjs";import{reportsDirectory as E}from"../browser/shared/paths.mjs";import{findPreviewServer as K}from"../browser/shared/preview-server.mjs";import{topOf as M}from"../browser/shared/outline-shape.mjs";import{LINK_FILE as U,linkAddress as P,linkIcon as T}from"../browser/shared/web-links.mjs";var $=t=>t.replace(/\s+/g," ").trim(),k=t=>t==null?"none":JSON.stringify(t);async function x(t,e){let n=await K(),o=n?await j(n,e,t):null;if(o)return o;let[,s]=await C({edits:{},reports:{},reportsDirectory:E,web:{icon:a=>O(a)}}).run(t,e);return s}function _(t,e){let n=[...t.documents.values()].filter(({url:a})=>a!==void 0),o=J(F(n),e.replace(/^.*#/,""));return o?{slug:o,link:t.documents.get(o)}:{refused:t.documents.get(e)?`${p(t,e)} is a document, not a web link: gallery set changes a document.`:`No web link "${e}": gallery list --tree shows the sidebar's entries.`}}var W=(t,e)=>t.groups.find(n=>[v(n),n.id].some(o=>o.toLowerCase()===$(e).toLowerCase()))??null;async function B(t,e,n){if(t.length!==2)throw new i('Name the address and the name: gallery link add <url> "<name>".');let[o,s]=t,a=P(o);if(a.refused)throw new i(`Not an address a web link takes: ${o} (${{url:"no address",scheme:"http or https only",long:"2048 characters at most"}[a.refused]}).`);if(!$(s))throw new i("The name is never empty.");let d=n.get("--column"),u=n.get("--under"),l=n.get("--after"),c=n.get("--icon");if(d!==void 0&&u!==void 0)throw new i("--column and --under are two places: give one.");if(l!==void 0&&e.has("--first"))throw new i("--after and --first are two places: give one.");if(c!==void 0&&!T(c))throw new i(`Not an icon a web link takes: ${c} (an emoji, or an icon of the \u56FE\u6807 tab as /icons/<name>_<color>.svg).`);let f=await h(),w;if(d!==void 0){let L=W(f,d);L||(console.error(`No column "${d}" in the sidebar (${f.groups.map(v).join(", ")}): nothing added.`),process.exit(1)),w=M(L.id)}u!==void 0&&(w=(await y(u)).slug);let r=l===void 0?null:(await y(l)).slug,q=e.has("--first")||u===void 0&&r===null,m=await x("link",{url:a.url,title:$(s),...c?{icon:c}:{},...w!==void 0?{parent:w}:{},after:r,first:q});m?.ok||(console.error(`Not added: ${m?.message??m?.reason??"no answer"}.`),process.exit(1));let b=await h(),{slug:N,url:z}=m.link;console.log(`Added the web link ${p(b,N)}: ${z}`),console.log(`Placed it ${I(b,{parent:m.parent,index:m.index})}.`),console.log(S(b,N)),console.log(`It is ${A(D.join(E,N,U))}; the workbench shows the page beside the sidebar (a site that refuses frames: \u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00).`)}async function G(t,e){if(t.length!==1)throw new i("Name one web link, then what to set: --url, --title, --icon.");if(!["--url","--title","--icon"].some(r=>e.has(r)))throw new i('Say what to set: --url <address>, --title "<name>", --icon <emoji|none>.');let n=e.has("--title")?$(e.get("--title")):void 0;if(n==="")throw new i("--title takes the words of the name: a web link's name is never empty.");let o;if(e.has("--url")){let r=P(e.get("--url"));if(r.refused)throw new i(`Not an address a web link takes: ${e.get("--url")}.`);o=r.url}let s;if(e.has("--icon")){let r=e.get("--icon").trim();if(r!=="none"&&!T(r))throw new i(`Not an icon a web link takes: ${r} (an emoji, none, or an icon of the \u56FE\u6807 tab).`);s=r==="none"?null:r}let a=await h(),d=_(a,t[0]);d.refused&&(console.error(d.refused),process.exit(1));let{slug:u,link:l}=d,c=await x("link-set",{slug:u,...o!==void 0?{url:o}:{},...n!==void 0?{title:n}:{},...s!==void 0?{icon:s}:{}});c?.ok||(console.error(`Not set: ${c?.message??c?.reason??"no answer"}.`),process.exit(1));let f=c.link,w=[...n!==void 0&&n!==l.title?[` title: ${k(l.title)} \u2192 ${k(f.title)}`]:[],...o!==void 0&&f.url!==l.url?[` url: ${l.url} \u2192 ${f.url}`]:[],...s!==void 0&&(f.icon??null)!==(l.icon??null)?[` icon: ${k(l.icon)} \u2192 ${k(f.icon??null)}`]:[]];if(!w.length)return void console.log(`Nothing to change: ${u} has ${e.size===1?"that already":"those already"}.`);console.log(`Set the web link ${u}:`);for(let r of w)console.log(r)}async function H(t){if(t.length!==1)throw new i("Name one web link to move to the trash.");let e=await h(),n=_(e,t[0]);n.refused&&(console.error(n.refused),process.exit(1));let o=await x("trash",{slug:n.slug,kind:"link"});o?.ok||(console.error(`Not moved to the trash: ${o?.message??o?.reason??"no answer"}.`),process.exit(1)),console.log(`Moved the web link ${p(e,n.slug)} to the trash: the workbench's \u8BBE\u7F6E \u203A \u56DE\u6536\u533A restores it where it was.`)}async function se(t){let[e,...n]=t;if(e==="add"){let{positional:o,options:s,values:a}=g({options:["--first"],values:["--column","--under","--after","--icon"],argv:n});return B(o,s,a)}if(e==="set"){let{positional:o,values:s}=g({values:["--url","--title","--icon"],argv:n});return G(o,s)}if(e==="remove"){let{positional:o}=g({argv:n});return H(o)}throw new i(e?`No such action: link ${e} (add, set, remove).`:"Say what to do: gallery link add, set or remove.")}export{se as run};
@@ -1,2 +1,2 @@
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 H,f as K,g as Q}from"./chunk-OU3S466R.mjs";import{d as D,f as E,g as T,h as F}from"./chunk-VG5JEIUQ.mjs";import{existsSync as R}from"node:fs";var U=120;function W(n,I){let p=({packages:s,problems:c})=>new Map([...s,...c].map(([a,{stamp:t}])=>[a,t])),[l,f]=[p(n),p(I)];return[...new Set([...l.keys(),...f.keys()])].filter(s=>l.get(s)!==f.get(s)).sort()}function A({root:n,tell:I,delay:p=U,quiet:l=Q,hold:f=H,limit:s=K,now:c=Date.now,timers:a={set:(t,m)=>setTimeout(t,m),clear:t=>clearTimeout(t)}}){let t=null,m=0,u=null,r=new Map;T(n);let M=i=>{t&&m<=c()+i||(a.clear(t),m=c()+i,t=a.set(w,i),t.unref?.())};function w({settled:i=!1}={}){t=null;let d=T(n),o=E(n,d.settings),b=c();o.stamp!==u?.stamp&&(u={stamp:o.stamp,at:b});let y=b-u.at;if(y<l&&!i)return M(l-y);let g=new Map(o.packages),k=new Map(o.problems),h=1/0;for(let[e,L]of d.packages){if(!(!o.settings.disabled.includes(e)&&(k.has(e)||!g.has(e)&&R(L.folder)))){r.delete(e);continue}r.has(e)||r.set(e,u.at);let O=Math.min(f-y,s-(b-r.get(e)));if(O<=0){r.delete(e);continue}g.set(e,L),k.delete(e),h=Math.min(h,O)}let{settings:C,packs:S}=o,x=D({packages:g,problems:k,settings:C,packs:S});if(x!==d.stamp){let e={packages:g,problems:k,settings:C,packs:S,stamp:x};F(n,e),I(e,W(d,e))}h!==1/0&&M(h)}return{changed:()=>M(p),taken(){a.clear(t),w({settled:!0})},close(){a.clear(t),t=null}}}export{U as a,A as b};
2
+ import{e as H,f as K,g as Q}from"./chunk-S3SX3COT.mjs";import{d as D,f as E,g as T,h as F}from"./chunk-TKWEX4FD.mjs";import{existsSync as R}from"node:fs";var U=120;function W(n,I){let p=({packages:s,problems:c})=>new Map([...s,...c].map(([a,{stamp:t}])=>[a,t])),[l,f]=[p(n),p(I)];return[...new Set([...l.keys(),...f.keys()])].filter(s=>l.get(s)!==f.get(s)).sort()}function A({root:n,tell:I,delay:p=U,quiet:l=Q,hold:f=H,limit:s=K,now:c=Date.now,timers:a={set:(t,m)=>setTimeout(t,m),clear:t=>clearTimeout(t)}}){let t=null,m=0,u=null,r=new Map;T(n);let M=i=>{t&&m<=c()+i||(a.clear(t),m=c()+i,t=a.set(w,i),t.unref?.())};function w({settled:i=!1}={}){t=null;let d=T(n),o=E(n,d.settings),b=c();o.stamp!==u?.stamp&&(u={stamp:o.stamp,at:b});let y=b-u.at;if(y<l&&!i)return M(l-y);let g=new Map(o.packages),k=new Map(o.problems),h=1/0;for(let[e,L]of d.packages){if(!(!o.settings.disabled.includes(e)&&(k.has(e)||!g.has(e)&&R(L.folder)))){r.delete(e);continue}r.has(e)||r.set(e,u.at);let O=Math.min(f-y,s-(b-r.get(e)));if(O<=0){r.delete(e);continue}g.set(e,L),k.delete(e),h=Math.min(h,O)}let{settings:C,packs:S}=o,x=D({packages:g,problems:k,settings:C,packs:S});if(x!==d.stamp){let e={packages:g,problems:k,settings:C,packs:S,stamp:x};F(n,e),I(e,W(d,e))}h!==1/0&&M(h)}return{changed:()=>M(p),taken(){a.clear(t),w({settled:!0})},close(){a.clear(t),t=null}}}export{U as a,A as b};
@@ -1,2 +1,2 @@
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{d as e}from"./chunk-36FIRJIF.mjs";function a(r){switch(r){case"chrome":return e.STABLE;case"chrome-dev":return e.DEV;case"chrome-beta":return e.BETA;case"chrome-canary":return e.CANARY}}export{a};
2
+ import{d as e}from"./chunk-742D2WWJ.mjs";function a(r){switch(r){case"chrome":return e.STABLE;case"chrome-dev":return e.DEV;case"chrome-beta":return e.BETA;case"chrome-canary":return e.CANARY}}export{a};
@@ -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{c as l,d as g}from"./chunk-L55NOXBE.mjs";import{j as p,k as d}from"./chunk-4B2TB5K2.mjs";import{u as f}from"./chunk-KLQP46Y3.mjs";import{b as h,f as u}from"./chunk-4OZWXZE5.mjs";import b from"node:fs/promises";import x from"node:path";import{reportsDirectory as j}from"../browser/shared/paths.mjs";import{sameDirectory as i}from"../browser/shared/preview-server.mjs";import{copyOldDocuments as v,defaultWorkspace as k,ensureWorkspace as D,layoutOf as G}from"../browser/shared/workspace.mjs";import{nameProblem as N,writeWorkspaceName as O}from"../browser/shared/workspace-name.mjs";import{registerQuietly as C}from"../browser/shared/workspace-registry.mjs";var $=(o,t)=>`${o} ${t}${o===1?"":"s"}`;function W(o,t,r){let{preferences:s}=G(r);return[o.copied.length?`Copied ${$(o.copied.length,"document")} from ${t}: ${o.copied.join(", ")}`:`Copied no documents from ${t}.`,...o.skipped.length?[`Skipped (the slug is taken here, or the folder's name is no slug): ${o.skipped.join(", ")}`]:[],...o.kept.length?[`Left behind (a name a workspace keeps for itself, for its custom blocks here, which no new document takes): ${o.kept.join(", ")}`]:[],...o.preferences==="copied"?[`\u5199\u4F5C\u504F\u597D\uFF1Acopied (${s})`]:o.preferences==="kept"?[`\u5199\u4F5C\u504F\u597D\uFF1Akept the workspace's (${s}); the old one was not copied`]:[],...o.outline?[`Sidebar order: ${o.outline}`]:[],...o.page?[`\u5199\u4F5C\u504F\u597D's page: ${o.page==="copied"?"copied":"kept the workspace's"}`]:[],...o.emoji?[`Emoji library: ${o.emoji} added`]:[],...o.history?[`Recent versions: ${$(o.history,"document")}`]:[],...o.packages.length?[`Custom blocks: ${o.packages.join(", ")}`]:[]]}async function q(o){let{values:t}=u({values:["--from","--name"],argv:o}),r=j,s=t.get("--name"),c=s===void 0?null:N(s);if(c)throw new h(c);let m;try{let{made:e,ours:a,reads:y}=await D(r,{state:i(r,k())});a||(console.error(g(r,y)),process.exit(1)),m=e}catch(e){if(!e.code)throw e;console.error(l(r,e.code)),process.exit(1)}if(console.log(`\u5DE5\u4F5C\u533A\uFF1A${r}\uFF08${m?"\u65B0\u5EFA":"\u5DF2\u6709"}\uFF09`),s!==void 0)try{let e=await O(r,s);console.log(`\u540D\u5B57\uFF1A${e.name}${e.before&&e.before!==e.name?` (it was "${e.before}")`:""}`)}catch(e){console.error(e.code?l(r,e.code):e.message),process.exit(1)}if(await C(r),t.has("--from")){let e=x.resolve(t.get("--from"));await b.stat(e).then(a=>a.isDirectory(),()=>!1)||(console.error(`No such folder: ${e} (--from names an older Gallery's reports/ folder).`),process.exit(1)),i(e,r)&&(console.error(`${e} is this workspace: --from names another folder (an older Gallery's reports/).`),process.exit(1));for(let a of W(await v({from:e,to:r}),e,r))console.log(a)}if(!i(r,k())){console.log('Next: gallery new <slug> "<title>" makes a document; gallery open opens Gallery.');return}let w=await f(r);for(let e of w.packs)e.failed?console.warn(`\u5757\u5305\uFF1AGallery's pack ${e.id} was not installed (${e.failed}); a later start tries again.`):e.first&&console.log(`\u5757\u5305\uFF1A${e.name.zh} (${e.id} ${e.version}, ${e.added.length+e.same.length+e.updated.length} blocks)${e.id==="gallery-soft"?", switched off: \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868 turns it on":""}`);let n=await p(r);n.did==="made"?console.log(`\u9996\u9875\uFF1A${n.file} (the home page, its cards Gallery's today and note; the workbench opens it first)`):n.did==="failed"&&console.warn(`\u9996\u9875\uFF1A${d(n)}`),console.log('Next: gallery new <slug> "<title>" makes a document; gallery open opens the workbench.')}export{W as a,q as b};
@@ -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-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(`
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-LJLVCU6W.mjs";import{M as Xe}from"./chunk-XBNFXWAW.mjs";import{f as Te,i as Je}from"./chunk-SQ3FQCCN.mjs";import{a as K}from"./chunk-JEUK3ZO7.mjs";import{a as me}from"./chunk-M4NRDYI5.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-S3SX3COT.mjs";import{b as Se}from"./chunk-VRPVVMRB.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-TKWEX4FD.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(`
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,c,d,e,f,g,h}from"./chunk-XZV72SQ4.mjs";import"./chunk-V4ZHRALW.mjs";import"./chunk-SQ3FQCCN.mjs";import"./chunk-JEUK3ZO7.mjs";import"./chunk-6QWQXHAV.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-7UZUQQ7Q.mjs";import"./chunk-4B2TB5K2.mjs";import"./chunk-KLQP46Y3.mjs";import"./chunk-4OZWXZE5.mjs";import"./chunk-HX4DLE3J.mjs";import"./chunk-FJLM7YE7.mjs";import"./chunk-HYMEEXKN.mjs";import"./chunk-E7656LR7.mjs";import"./chunk-TKWEX4FD.mjs";import"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";export{c as HOME_NOT_MADE,g as emptyRequiredOf,d as missingPageSaid,a as pageAddressOf,b as pageAloneOf,h as run,e as setsOf,f as settingsGiven};
@@ -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 _}from"./chunk-BYSF5UMM.mjs";import{n as G,p as Le,r as Ee,s as Ne,t as Ie,x as Oe}from"./chunk-3OFXMN6N.mjs";import{c as he,d as pe,e as ue,f as fe,g as we,h as ge,i as me,j as z,l as $e,n as Y,o as ke,q as be,r as ye,s as xe,t as ve,u as Se}from"./chunk-SOD23RGL.mjs";import{M as Ae}from"./chunk-4DNHHJSL.mjs";import"./chunk-342HXE3Q.mjs";import"./chunk-3A5I2GJK.mjs";import{d as Ce,g as je}from"./chunk-5L26JUYA.mjs";import"./chunk-S2Y7VI4H.mjs";import"./chunk-XQRUG4G3.mjs";import{i as ie}from"./chunk-JJNRIFND.mjs";import{a as W}from"./chunk-JEUK3ZO7.mjs";import"./chunk-CG3UHDKH.mjs";import{a as re,b as le,e as de,f as K,g as ce}from"./chunk-4AMTKWDO.mjs";import"./chunk-QXVNUASA.mjs";import"./chunk-FCK6NXON.mjs";import"./chunk-OU3S466R.mjs";import"./chunk-QK3VISCA.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-F4ZA6JRZ.mjs";import"./chunk-7M2BQQGZ.mjs";import"./chunk-TOE6DPLH.mjs";import"./chunk-WTEGUPFG.mjs";import"./chunk-2GKGEVMR.mjs";import{a as H,b as j,c as P,d as D,f as oe}from"./chunk-VKSRM7EY.mjs";import{a as te,e as B,f as ae}from"./chunk-LE44MD3O.mjs";import{b as se}from"./chunk-4OZWXZE5.mjs";import"./chunk-XMKHCUI6.mjs";import"./chunk-SAHS56QM.mjs";import"./chunk-KH24LWAT.mjs";import"./chunk-YFJU3O7G.mjs";import"./chunk-NWRZXELO.mjs";import{j as ne}from"./chunk-G4YP7GVC.mjs";import"./chunk-DHB7UZ7F.mjs";import"./chunk-2RKIHJI2.mjs";import"./chunk-JXLSHVJ2.mjs";import"./chunk-XKOHV4H6.mjs";import"./chunk-KFZBYDIS.mjs";import"./chunk-7XDYK3UC.mjs";import{f as Z,j as ee}from"./chunk-VG5JEIUQ.mjs";import{b as X,e as _e}from"./chunk-N3DSBH5S.mjs";import"./chunk-5L7RYZCL.mjs";_e();import{existsSync as Ue}from"node:fs";import R from"node:fs/promises";import O from"node:path";import{isInstance as Ke}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as He,INSTANCE as Ye}from"../browser/shared/components/installed.mjs";import{attr as M,hasClass as q,walk as Re}from"../browser/shared/html-tree.mjs";import{assetFile as Qe,imageFile as Te,referencedFile as Me}from"../browser/shared/media.mjs";import{pageAssetAddress as Ve,pageExists as Je,pageFiles as Xe}from"../browser/shared/pages.mjs";import{layoutOf as U}from"../browser/shared/workspace.mjs";var Q=[1280,1920,600],De=["light","dark"],Ze=900,et=3e4,tt=new Set(["iframe","frame","object","embed"]),at=/^\d+$/,ot={x:[0,11],y:[0,1/0],w:[1,12],h:[1,24]};function st(e,{catalog:g,folder:o,slug:h}){let i=[],s=d=>d?.sourceCodeLocation?.startLine??1,n=(d,a)=>i.push({line:typeof d=="number"?d:s(d),what:a}),t=X(e.replace(/^/," "),{sourceCodeLocationInfo:!0}),c=[],f=[];Re(t,d=>{d.tagName&&(d.tagName==="main"&&q(d,"gallery-page")&&c.push(d),q(d,"gallery-board")&&f.push(d),q(d,"gallery-card")&&!q(d.parentNode,"gallery-board")&&n(d,`a card (class gallery-card) that is no board's child: each card stands right in a <div class="gallery-board" data-board-id="\u2026">, which lays it out, and this one is laid out by none`))},{inTemplates:!1}),c.length===0&&(f.length>0||j(e).cards.length>0)&&n(1,`no <main class="gallery-page">: a page's boards stand in one (it is how a block knows it is on a page: context.place "page", and how the page follows the theme)`);let y=new Map;for(let d of f){let a=d.parentNode;for(;a&&!(a.tagName==="main"&&q(a,"gallery-page"));)a=a.parentNode;c.length&&!a&&n(d,`a board outside <main class="gallery-page">: its cards' blocks would not know they are on a page`);let r=M(d,"data-board-id");r===void 0||r===""?n(d,"a board with no data-board-id: write one (main, side\u2026), of lowercase letters, digits and hyphens, once in the page"):H.test(r)?y.has(r)?n(d,`data-board-id="${r}" again (line ${y.get(r)} has it): each board's id is its own`):y.set(r,s(d)):n(d,`data-board-id="${r}": a board's id is lowercase letters, digits and single hyphens (main, side-2)`)}let S=new Map,N=new Map;for(let d of j(e).cards){let{node:a}=d,r=M(a,"data-card-id"),k=r&&H.test(r)?`card ${r}`:"this card";r===void 0||r===""?n(a,"a card with no data-card-id: write one (c<n>, the lowest none holds, or a name of your own), of lowercase letters, digits and hyphens: its place, its writes and the reader's state go by it"):H.test(r)?S.has(r)?n(a,`data-card-id="${r}" again (line ${S.get(r)} has it): each card's id is its own, and the page's writes go by it`):S.set(r,s(a)):n(a,`data-card-id="${r}": a card's id is lowercase letters, digits and single hyphens (c3, water)`);let u=0;Re(a,x=>{x!==a&&Ke(x)&&(u+=1)},{inTemplates:!1}),u===0?n(a,`${k} holds no instance of a custom block (an element with ${He}): a card is one block's instance, gallery/static's for what only shows`):u>1?n(a,`${k} holds ${u} instances: a card holds one (put each on a card of its own)`):d.instance&&d.instance.parentNode!==a&&n(d.instance,`${k}'s instance stands inside another element of the card: write it right in the card's <section>`);let b={};for(let x of["x","y","w","h"]){let A=M(a,`data-${x}`),[L,E]=ot[x];A===void 0?n(a,`${k} has no data-${x}: a card says its place and size in whole cells, data-x data-y data-w data-h`):at.test(A.trim())?Number(A)<L||Number(A)>E?n(a,`${k}'s data-${x}="${A}": ${x} is ${E===1/0?`${L} or more`:`${L} to ${E}`}${x==="w"?" (a row is 12 cells)":""}`):b[x]=Number(A):n(a,`${k}'s data-${x}="${A}" is no whole number`)}b.x!==void 0&&b.w!==void 0&&b.x+b.w>12?n(a,`${k} reaches past the row's end: data-x ${b.x} and data-w ${b.w} make ${b.x+b.w}, and a row is 12 cells (x + w is 12 at most)`):Object.keys(b).length===4&&N.set(d.board,[...N.get(d.board)??[],{id:r??null,...b,line:s(a)}]),d.block&&nt(d.block,g,x=>n(d.instance,`${k}'s block ${d.block}: ${x}`))}for(let d of N.values())for(let a=0;a<d.length;a++)for(let r=a+1;r<d.length;r++){let[k,u]=[d[a],d[r]];k.x<u.x+u.w&&u.x<k.x+k.w&&k.y<u.y+u.h&&u.y<k.y+k.h&&n(u.line,`card ${u.id??"here"} (x ${u.x}, y ${u.y}, ${u.w} \xD7 ${u.h}) shares cells with card ${k.id??`at line ${k.line}`} (x ${k.x}, y ${k.y}, ${k.w} \xD7 ${k.h}): no two cards of a board overlap; move one to a free spot (gallery page add finds one for a new card)`)}return i.push(...it(e,{folder:o,slug:h})),i.sort((d,a)=>d.line-a.line)}function nt(e,g,o){let h=g.packages.get(e);if(h){h.places.includes("page")||o(`a block of documents (its manifest's places has no "page"): on a custom page its card says so and runs nothing`);return}let i=g.problems.get(e);g.settings.disabled.includes(e)?o("turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868: its card says so and runs nothing (the user turns it on again)"):i?o(`it does not load (${ee("en",i.problem)}): gallery block check ${e} says why`):ae(e)&&B(e)?o(`one of Gallery's own blocks, not yet in this workspace: gallery block add ${B(e).pack===te?B(e).name:e} puts it in`):o("no custom block of that id in this workspace: gallery block list lists them")}function it(e,{folder:g,slug:o}){let h=[],i=`${Ve(o,"assets/")}`;for(let s of ne(e,()=>!0)){let n=s.value.trim(),t=["a","area"].includes(s.node.tagName)&&s.how==="href",c=Me(n)??(n.startsWith(i)?Me(n.slice(i.length-7)):null),f=`"${n.length>60?`${n.slice(0,60)}\u2026`:n}"`,y=s.how==="css"?`<style>'s url() ${f}`:`<${s.node.tagName}>'s ${s.how==="style"?"style url()":s.how} ${f}`;if(c!==null){Qe(c)?tt.has(s.node.tagName)&&!Te(c)?h.push({line:s.line,what:`${y}: a frame of a file of the page's assets/ downloads it and shows nothing, as the server hands out a page's own file that is no picture, stylesheet or script for saving only: write what it shows in the page itself, frame a site by its https address, or offer the file with a link, <a href="${c}" download>`}):Ue(O.join(g,c))||h.push({line:s.line,what:`${y}: ${c} is not in the page's folder (${W(O.join(g,"assets"))}): put the file there${Te(c)?"":", or link to it"}`}):h.push({line:s.line,what:`${y} names a file the server serves none by: the page's own files go right in pages/${o}/assets/, each named with letters, digits, dots, dashes and underscores (assets/cover.png)`});continue}t||!n||/^(?:[a-z][a-z0-9+.-]*:|\/|#|\?)/i.test(n)||h.push({line:s.line,what:`${y} is relative to /pages/${o}, where nothing is served: put the file in pages/${o}/assets/ and write assets/<file>`})}return h}function rt(e,g){let o=P(e).text,h=[];for(let i of j(o).cards){let s=i.block?g.packages.get(i.block):null;if(!s?.settings?.some(f=>f.required)||!s.parts.settings)continue;let n=G(D(o,i),_,{...s,parts:{settings:s.parts.settings}})?.parts.find(({name:f})=>f==="settings"),t={};try{t=n?.text.trim()?JSON.parse(n.text):{}}catch{continue}let c=je(s,t);c.length&&h.push({id:i.id,block:i.block,line:i.node.sourceCodeLocation?.startLine??1,empty:c})}return h}var lt=({id:e,block:g,empty:o})=>`card ${e} (${g}) holds no ${o.map(({key:h,label:i,zh:s})=>`${h} (${s&&s!==i?`${i}, ${s}`:i})`).join(" and no ")} in its settings, which it cannot show anything without: it shows its ask for one (the grip at its top right \u203A \u8BBE\u7F6E\u2026), and no picture of the page shows what it is for. Ask the user for it, or take it from what the workspace says (\u5199\u4F5C\u504F\u597D, the documents), write it in the card's settings part, and tell them in the handoff which you did`,dt=(e,g=!1)=>{let o=h=>M(e.node,`data-${h}`)??"-";return`x ${o("x")}, y ${o("y")}, ${o("w")} \xD7 ${o("h")}${g?` on ${e.board??"-"}`:""}`},Fe=e=>`${e.board},${M(e.node,"data-x")},${M(e.node,"data-y")}`,Pe=e=>`${M(e.node,"data-w")},${M(e.node,"data-h")}`;function ct(e,g,o){let[h,i]=[P(e).text,P(g).text],[s,n]=[j(h).cards,j(i).cards],t=new Set([...s,...n].map(a=>a.board)).size>1,c=a=>dt(a,t),f={added:[],removed:[],moved:[],resized:[],data:[],markup:[],page:null,kept:0};for(let a of s)n.some(r=>r.id===a.id)||f.removed.push({id:a.id,block:a.block,cells:c(a)});for(let a of n)s.some(r=>r.id===a.id)||f.added.push({id:a.id,block:a.block,cells:c(a)});for(let a of n){let r=s.find($=>$.id===a.id);if(!r)continue;let[k,u]=[Fe(r)!==Fe(a),Pe(r)!==Pe(a)];k&&f.moved.push({id:a.id,block:a.block,was:c(r),now:c(a)}),u&&f.resized.push({id:a.id,block:a.block,was:c(r),now:c(a)});let[b,x]=[D(h,r),D(i,a)];if(b===x){!k&&!u&&(f.kept+=1);continue}let A=r.block===a.block?o.packages.get(a.block):null,L=A?{...A,parts:Object.fromEntries(Object.entries(A.parts).filter(([,$])=>$.edit==="data"))}:null,[E,l]=L?[G(b,_,L),G(x,_,L)]:[null,null];if(!E||!l){f.markup.push({id:a.id,block:A?a.block:null});continue}let v=E.parts.flatMap(({name:$,text:m},I)=>m===l.parts[I].text?[]:[{name:$,...Y(m,l.parts[I].text),runs:ke(m,l.parts[I].text)}]);v.length&&f.data.push({id:a.id,block:a.block,parts:v}),E.outside!==l.outside&&f.markup.push({id:a.id,block:a.block})}let y=(a,r)=>{let k="",u=0;for(let b of[...r].sort((x,A)=>x.start-A.start))k+=a.slice(u,b.start),u=b.end;return k+a.slice(u)},[S,N]=[y(h,s),y(i,n)],d=a=>a.replace(/\s+/g," ");return d(S)!==d(N)&&(f.page=Y(S.replace(/^\s*\n/gm,""),N.replace(/^\s*\n/gm,""))),f}var ze="(the user's, on the page)",We="(put there by Gallery)";function ht(e,g){let o=n=>{let t=new Map;for(let c of g)if(c.by===n)for(let[f,y]of Object.entries(c.cards??{}))t.set(f,new Set([...t.get(f)??[],...Array.isArray(y)?y:[]]));return t},h=o("page"),i=o("gallery"),s=n=>t=>{let c=!!h.get(t.id)?.has(n);return{...t,user:c,...!c&&i.get(t.id)?.has(n)?{gallery:!0}:{}}};return{...e,added:e.added.map(s("added")),removed:e.removed.map(s("removed")),moved:e.moved.map(s("cells")),resized:e.resized.map(s("cells")),data:e.data.map(s("content")),markup:e.markup.map(s("content"))}}function pt(e,g){let o=({id:t,block:c})=>`${t}${c?` (${c})`:""}`,h=t=>t.user?` ${ze}`:t.gallery?` ${We}`:"",i=[];for(let t of e.added)i.push(` added ${o(t)} at ${t.cells}${h(t)}`);for(let t of e.removed)i.push(` removed ${o(t)}, which stood at ${t.cells}${h(t)}`);for(let t of e.moved)i.push(` moved ${o(t)}: ${t.was} then ${t.now}${h(t)}`);for(let t of e.resized)e.moved.some(c=>c.id===t.id)||i.push(` resized ${o(t)}: ${t.was} then ${t.now}${h(t)}`);for(let t of e.data)i.push(` data ${o(t)}: ${$e(t.parts)}${h(t)}`,...Le(t.parts).map(c=>` ${c}`));for(let t of e.markup)i.push(` markup ${o(t)}: its markup outside its place and its data parts${t.block?"":" (a block the workspace has not: its markup whole)"}${h(t)}`);if(e.page&&i.push(` page its own HTML outside the cards: -${e.page.removed} +${e.page.added} of its ${e.page.lines} line${e.page.lines===1?"":"s"}`),i.length===0)return[`No change since ${g}: every card where it was, with the data it had.`];let s=["added","removed","moved","resized","data","markup"].some(t=>e[t].some(c=>c.user)),n=["added","removed","moved","resized","data","markup"].some(t=>e[t].some(c=>c.gallery));return[`Changes since ${g}:`,...i,...e.kept?[e.kept===1?" The other card as it was.":` The other ${e.kept} cards as they were.`]:[],...s?[` Each change marked ${ze} is the user's own gesture on the page since then (a move, a resize, a card added or deleted there, what they typed in it), which the page wrote: leave it as it is, never put it back.`]:[],...n?[` Each change marked ${We} is Gallery's own doing, not the user's and not yours: the cards it put on the home page when it made it (\u95EE\u5019\u4E0E\u65E5\u671F, \u4FBF\u7B7E): leave it as it is.`]:[]]}async function ut(e,g){let{qa:o,state:h}=U(e),i=O.join(o,g,"checked.html"),s=await R.readFile(i,"utf8").catch(()=>null);if(s!==null){let{mtime:y}=await R.stat(i);return{text:s,since:`the last check that found nothing (${qe(y)}, local time, ${W(i)})`,at:y.getTime()}}let n=O.join(h,"pages",g),t=(await R.readdir(n).catch(()=>[])).filter(y=>/^\d{15}-\d{4}\.html$/.test(y)).sort();if(t.length===0)return null;let c=O.join(n,t.at(-1)),f=Number(t.at(-1).slice(0,15));return{text:await R.readFile(c,"utf8"),since:`the page as it was before its last write (${qe(new Date(f))}, local time; used because no check has passed yet)`,at:f}}var qe=e=>`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")} ${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`;function ft(e,g){let o=t=>`<${t.localName}${t.getAttribute("src")?` src="${t.getAttribute("src").slice(0,80)}"`:""}>`,h=[...document.querySelectorAll(".gallery-board > .gallery-card")].map(t=>{let c=t.parentElement.getBoundingClientRect(),f=t.getBoundingClientRect(),y=[...t.children].find(S=>S.matches(e));return{id:t.getAttribute("data-card-id"),block:y?.getAttribute(g)??null,out:f.width>0&&(f.left<c.left-1||f.right>c.right+1),tall:t.scrollHeight>t.clientHeight+1?{needs:t.scrollHeight,has:t.clientHeight}:null,wide:t.scrollWidth>t.clientWidth+1?{needs:t.scrollWidth,has:t.clientWidth}:null,fallback:!!y?.hasAttribute("data-doc-fallback"),error:(t.querySelector(".doc-kit-error")?.textContent??"").trim()||null,broken:[...t.querySelectorAll("img")].filter(S=>S.complete&&S.naturalWidth===0).map(o)}}),i=[...document.querySelectorAll("img")].filter(t=>!t.closest(".gallery-card")&&t.complete&&t.naturalWidth===0).map(o),s=document.documentElement.scrollWidth,n=[...globalThis.__galleryQueries?.pending.values()??[]].map(({kind:t,block:c,at:f})=>({kind:t,block:c,waited:Date.now()-f}));return{cards:h,broken:i,stuck:n,wide:s>innerWidth+1?s:0,columns:document.querySelector(".gallery-board")?.getAttribute("data-columns")??null}}async function wt(e,{address:g,out:o,readers:h=new Set,wait:i=ge,limits:s={}}){let{loading:n=he,ready:t=et,answer:c=pe,closing:f=de,looking:y=ue}=s,S=new Map,N=new Map,d=[],a=!1,r=(l,v,$,m,I=S)=>{if(a)return;let w=I.get(l)??{card:v,what:$,looks:[]};w.looks.push(m),I.set(l,w)},k="a browser context opened",u=(l,v,$=c)=>(k=v,ye(l,v,$)),b=Q.flatMap(l=>De.map(v=>({width:l,theme:v,view:`${l} ${v}`}))),x=null,A=async({width:l,theme:v,view:$})=>{let m=await u(x.newPage(),"a tab opened");try{m.on("pageerror",p=>r(`error ${z(p)}`,null,`the page threw: ${z(p)}`,$)),m.on("console",p=>{p.type()==="error"&&!/^Failed to load resource/.test(p.text())&&r(`console ${p.text().split(`
2
+ import{c as _}from"./chunk-PKVK6WFC.mjs";import{n as G,p as Le,r as Ee,s as Ne,t as Ie,x as Oe}from"./chunk-NMF3IPYA.mjs";import{c as he,d as pe,e as ue,f as fe,g as we,h as ge,i as me,j as z,l as $e,n as Y,o as ke,q as be,r as ye,s as xe,t as ve,u as Se}from"./chunk-LJLVCU6W.mjs";import{M as Ae}from"./chunk-XBNFXWAW.mjs";import"./chunk-342HXE3Q.mjs";import"./chunk-T4Y2ZSVX.mjs";import{d as Ce,g as je}from"./chunk-XZV72SQ4.mjs";import"./chunk-V4ZHRALW.mjs";import"./chunk-5GK7HS62.mjs";import{i as ie}from"./chunk-SQ3FQCCN.mjs";import{a as W}from"./chunk-JEUK3ZO7.mjs";import"./chunk-M4NRDYI5.mjs";import{a as re,b as le,e as de,f as K,g as ce}from"./chunk-PUOQ65NC.mjs";import"./chunk-6QWQXHAV.mjs";import"./chunk-ZLS2FRS6.mjs";import"./chunk-S3SX3COT.mjs";import"./chunk-IA4PSIMD.mjs";import"./chunk-2OHANJ6Q.mjs";import"./chunk-F4ZA6JRZ.mjs";import"./chunk-7M2BQQGZ.mjs";import"./chunk-6NLXUKAY.mjs";import"./chunk-VRPVVMRB.mjs";import"./chunk-7UZUQQ7Q.mjs";import{a as H,b as j,c as P,d as D,f as oe}from"./chunk-4B2TB5K2.mjs";import{a as te,e as B,f as ae}from"./chunk-KLQP46Y3.mjs";import{b as se}from"./chunk-4OZWXZE5.mjs";import"./chunk-BX5AKINW.mjs";import"./chunk-HX4DLE3J.mjs";import"./chunk-ZTHICSSF.mjs";import"./chunk-FJLM7YE7.mjs";import"./chunk-PAREWQGB.mjs";import{j as ne}from"./chunk-BFJGHSQN.mjs";import"./chunk-U5XL7D6A.mjs";import"./chunk-HYMEEXKN.mjs";import"./chunk-UMHUSOPJ.mjs";import"./chunk-W5NPH5UA.mjs";import"./chunk-ECZBLQKK.mjs";import"./chunk-E7656LR7.mjs";import{f as Z,j as ee}from"./chunk-TKWEX4FD.mjs";import{b as X,e as _e}from"./chunk-A55HN5OK.mjs";import"./chunk-5L7RYZCL.mjs";_e();import{existsSync as Ue}from"node:fs";import R from"node:fs/promises";import O from"node:path";import{isInstance as Ke}from"../browser/shared/components/index.mjs";import{ATTRIBUTE as He,INSTANCE as Ye}from"../browser/shared/components/installed.mjs";import{attr as M,hasClass as q,walk as Re}from"../browser/shared/html-tree.mjs";import{assetFile as Qe,imageFile as Te,referencedFile as Me}from"../browser/shared/media.mjs";import{pageAssetAddress as Ve,pageExists as Je,pageFiles as Xe}from"../browser/shared/pages.mjs";import{layoutOf as U}from"../browser/shared/workspace.mjs";var Q=[1280,1920,600],De=["light","dark"],Ze=900,et=3e4,tt=new Set(["iframe","frame","object","embed"]),at=/^\d+$/,ot={x:[0,11],y:[0,1/0],w:[1,12],h:[1,24]};function st(e,{catalog:g,folder:o,slug:h}){let i=[],s=d=>d?.sourceCodeLocation?.startLine??1,n=(d,a)=>i.push({line:typeof d=="number"?d:s(d),what:a}),t=X(e.replace(/^/," "),{sourceCodeLocationInfo:!0}),c=[],f=[];Re(t,d=>{d.tagName&&(d.tagName==="main"&&q(d,"gallery-page")&&c.push(d),q(d,"gallery-board")&&f.push(d),q(d,"gallery-card")&&!q(d.parentNode,"gallery-board")&&n(d,`a card (class gallery-card) that is no board's child: each card stands right in a <div class="gallery-board" data-board-id="\u2026">, which lays it out, and this one is laid out by none`))},{inTemplates:!1}),c.length===0&&(f.length>0||j(e).cards.length>0)&&n(1,`no <main class="gallery-page">: a page's boards stand in one (it is how a block knows it is on a page: context.place "page", and how the page follows the theme)`);let y=new Map;for(let d of f){let a=d.parentNode;for(;a&&!(a.tagName==="main"&&q(a,"gallery-page"));)a=a.parentNode;c.length&&!a&&n(d,`a board outside <main class="gallery-page">: its cards' blocks would not know they are on a page`);let r=M(d,"data-board-id");r===void 0||r===""?n(d,"a board with no data-board-id: write one (main, side\u2026), of lowercase letters, digits and hyphens, once in the page"):H.test(r)?y.has(r)?n(d,`data-board-id="${r}" again (line ${y.get(r)} has it): each board's id is its own`):y.set(r,s(d)):n(d,`data-board-id="${r}": a board's id is lowercase letters, digits and single hyphens (main, side-2)`)}let S=new Map,N=new Map;for(let d of j(e).cards){let{node:a}=d,r=M(a,"data-card-id"),k=r&&H.test(r)?`card ${r}`:"this card";r===void 0||r===""?n(a,"a card with no data-card-id: write one (c<n>, the lowest none holds, or a name of your own), of lowercase letters, digits and hyphens: its place, its writes and the reader's state go by it"):H.test(r)?S.has(r)?n(a,`data-card-id="${r}" again (line ${S.get(r)} has it): each card's id is its own, and the page's writes go by it`):S.set(r,s(a)):n(a,`data-card-id="${r}": a card's id is lowercase letters, digits and single hyphens (c3, water)`);let u=0;Re(a,x=>{x!==a&&Ke(x)&&(u+=1)},{inTemplates:!1}),u===0?n(a,`${k} holds no instance of a custom block (an element with ${He}): a card is one block's instance, gallery/static's for what only shows`):u>1?n(a,`${k} holds ${u} instances: a card holds one (put each on a card of its own)`):d.instance&&d.instance.parentNode!==a&&n(d.instance,`${k}'s instance stands inside another element of the card: write it right in the card's <section>`);let b={};for(let x of["x","y","w","h"]){let A=M(a,`data-${x}`),[L,E]=ot[x];A===void 0?n(a,`${k} has no data-${x}: a card says its place and size in whole cells, data-x data-y data-w data-h`):at.test(A.trim())?Number(A)<L||Number(A)>E?n(a,`${k}'s data-${x}="${A}": ${x} is ${E===1/0?`${L} or more`:`${L} to ${E}`}${x==="w"?" (a row is 12 cells)":""}`):b[x]=Number(A):n(a,`${k}'s data-${x}="${A}" is no whole number`)}b.x!==void 0&&b.w!==void 0&&b.x+b.w>12?n(a,`${k} reaches past the row's end: data-x ${b.x} and data-w ${b.w} make ${b.x+b.w}, and a row is 12 cells (x + w is 12 at most)`):Object.keys(b).length===4&&N.set(d.board,[...N.get(d.board)??[],{id:r??null,...b,line:s(a)}]),d.block&&nt(d.block,g,x=>n(d.instance,`${k}'s block ${d.block}: ${x}`))}for(let d of N.values())for(let a=0;a<d.length;a++)for(let r=a+1;r<d.length;r++){let[k,u]=[d[a],d[r]];k.x<u.x+u.w&&u.x<k.x+k.w&&k.y<u.y+u.h&&u.y<k.y+k.h&&n(u.line,`card ${u.id??"here"} (x ${u.x}, y ${u.y}, ${u.w} \xD7 ${u.h}) shares cells with card ${k.id??`at line ${k.line}`} (x ${k.x}, y ${k.y}, ${k.w} \xD7 ${k.h}): no two cards of a board overlap; move one to a free spot (gallery page add finds one for a new card)`)}return i.push(...it(e,{folder:o,slug:h})),i.sort((d,a)=>d.line-a.line)}function nt(e,g,o){let h=g.packages.get(e);if(h){h.places.includes("page")||o(`a block of documents (its manifest's places has no "page"): on a custom page its card says so and runs nothing`);return}let i=g.problems.get(e);g.settings.disabled.includes(e)?o("turned off in \u8BBE\u7F6E \u203A \u7EC4\u4EF6\u5217\u8868: its card says so and runs nothing (the user turns it on again)"):i?o(`it does not load (${ee("en",i.problem)}): gallery block check ${e} says why`):ae(e)&&B(e)?o(`one of Gallery's own blocks, not yet in this workspace: gallery block add ${B(e).pack===te?B(e).name:e} puts it in`):o("no custom block of that id in this workspace: gallery block list lists them")}function it(e,{folder:g,slug:o}){let h=[],i=`${Ve(o,"assets/")}`;for(let s of ne(e,()=>!0)){let n=s.value.trim(),t=["a","area"].includes(s.node.tagName)&&s.how==="href",c=Me(n)??(n.startsWith(i)?Me(n.slice(i.length-7)):null),f=`"${n.length>60?`${n.slice(0,60)}\u2026`:n}"`,y=s.how==="css"?`<style>'s url() ${f}`:`<${s.node.tagName}>'s ${s.how==="style"?"style url()":s.how} ${f}`;if(c!==null){Qe(c)?tt.has(s.node.tagName)&&!Te(c)?h.push({line:s.line,what:`${y}: a frame of a file of the page's assets/ downloads it and shows nothing, as the server hands out a page's own file that is no picture, stylesheet or script for saving only: write what it shows in the page itself, frame a site by its https address, or offer the file with a link, <a href="${c}" download>`}):Ue(O.join(g,c))||h.push({line:s.line,what:`${y}: ${c} is not in the page's folder (${W(O.join(g,"assets"))}): put the file there${Te(c)?"":", or link to it"}`}):h.push({line:s.line,what:`${y} names a file the server serves none by: the page's own files go right in pages/${o}/assets/, each named with letters, digits, dots, dashes and underscores (assets/cover.png)`});continue}t||!n||/^(?:[a-z][a-z0-9+.-]*:|\/|#|\?)/i.test(n)||h.push({line:s.line,what:`${y} is relative to /pages/${o}, where nothing is served: put the file in pages/${o}/assets/ and write assets/<file>`})}return h}function rt(e,g){let o=P(e).text,h=[];for(let i of j(o).cards){let s=i.block?g.packages.get(i.block):null;if(!s?.settings?.some(f=>f.required)||!s.parts.settings)continue;let n=G(D(o,i),_,{...s,parts:{settings:s.parts.settings}})?.parts.find(({name:f})=>f==="settings"),t={};try{t=n?.text.trim()?JSON.parse(n.text):{}}catch{continue}let c=je(s,t);c.length&&h.push({id:i.id,block:i.block,line:i.node.sourceCodeLocation?.startLine??1,empty:c})}return h}var lt=({id:e,block:g,empty:o})=>`card ${e} (${g}) holds no ${o.map(({key:h,label:i,zh:s})=>`${h} (${s&&s!==i?`${i}, ${s}`:i})`).join(" and no ")} in its settings, which it cannot show anything without: it shows its ask for one (the grip at its top right \u203A \u8BBE\u7F6E\u2026), and no picture of the page shows what it is for. Ask the user for it, or take it from what the workspace says (\u5199\u4F5C\u504F\u597D, the documents), write it in the card's settings part, and tell them in the handoff which you did`,dt=(e,g=!1)=>{let o=h=>M(e.node,`data-${h}`)??"-";return`x ${o("x")}, y ${o("y")}, ${o("w")} \xD7 ${o("h")}${g?` on ${e.board??"-"}`:""}`},Fe=e=>`${e.board},${M(e.node,"data-x")},${M(e.node,"data-y")}`,Pe=e=>`${M(e.node,"data-w")},${M(e.node,"data-h")}`;function ct(e,g,o){let[h,i]=[P(e).text,P(g).text],[s,n]=[j(h).cards,j(i).cards],t=new Set([...s,...n].map(a=>a.board)).size>1,c=a=>dt(a,t),f={added:[],removed:[],moved:[],resized:[],data:[],markup:[],page:null,kept:0};for(let a of s)n.some(r=>r.id===a.id)||f.removed.push({id:a.id,block:a.block,cells:c(a)});for(let a of n)s.some(r=>r.id===a.id)||f.added.push({id:a.id,block:a.block,cells:c(a)});for(let a of n){let r=s.find($=>$.id===a.id);if(!r)continue;let[k,u]=[Fe(r)!==Fe(a),Pe(r)!==Pe(a)];k&&f.moved.push({id:a.id,block:a.block,was:c(r),now:c(a)}),u&&f.resized.push({id:a.id,block:a.block,was:c(r),now:c(a)});let[b,x]=[D(h,r),D(i,a)];if(b===x){!k&&!u&&(f.kept+=1);continue}let A=r.block===a.block?o.packages.get(a.block):null,L=A?{...A,parts:Object.fromEntries(Object.entries(A.parts).filter(([,$])=>$.edit==="data"))}:null,[E,l]=L?[G(b,_,L),G(x,_,L)]:[null,null];if(!E||!l){f.markup.push({id:a.id,block:A?a.block:null});continue}let v=E.parts.flatMap(({name:$,text:m},I)=>m===l.parts[I].text?[]:[{name:$,...Y(m,l.parts[I].text),runs:ke(m,l.parts[I].text)}]);v.length&&f.data.push({id:a.id,block:a.block,parts:v}),E.outside!==l.outside&&f.markup.push({id:a.id,block:a.block})}let y=(a,r)=>{let k="",u=0;for(let b of[...r].sort((x,A)=>x.start-A.start))k+=a.slice(u,b.start),u=b.end;return k+a.slice(u)},[S,N]=[y(h,s),y(i,n)],d=a=>a.replace(/\s+/g," ");return d(S)!==d(N)&&(f.page=Y(S.replace(/^\s*\n/gm,""),N.replace(/^\s*\n/gm,""))),f}var ze="(the user's, on the page)",We="(put there by Gallery)";function ht(e,g){let o=n=>{let t=new Map;for(let c of g)if(c.by===n)for(let[f,y]of Object.entries(c.cards??{}))t.set(f,new Set([...t.get(f)??[],...Array.isArray(y)?y:[]]));return t},h=o("page"),i=o("gallery"),s=n=>t=>{let c=!!h.get(t.id)?.has(n);return{...t,user:c,...!c&&i.get(t.id)?.has(n)?{gallery:!0}:{}}};return{...e,added:e.added.map(s("added")),removed:e.removed.map(s("removed")),moved:e.moved.map(s("cells")),resized:e.resized.map(s("cells")),data:e.data.map(s("content")),markup:e.markup.map(s("content"))}}function pt(e,g){let o=({id:t,block:c})=>`${t}${c?` (${c})`:""}`,h=t=>t.user?` ${ze}`:t.gallery?` ${We}`:"",i=[];for(let t of e.added)i.push(` added ${o(t)} at ${t.cells}${h(t)}`);for(let t of e.removed)i.push(` removed ${o(t)}, which stood at ${t.cells}${h(t)}`);for(let t of e.moved)i.push(` moved ${o(t)}: ${t.was} then ${t.now}${h(t)}`);for(let t of e.resized)e.moved.some(c=>c.id===t.id)||i.push(` resized ${o(t)}: ${t.was} then ${t.now}${h(t)}`);for(let t of e.data)i.push(` data ${o(t)}: ${$e(t.parts)}${h(t)}`,...Le(t.parts).map(c=>` ${c}`));for(let t of e.markup)i.push(` markup ${o(t)}: its markup outside its place and its data parts${t.block?"":" (a block the workspace has not: its markup whole)"}${h(t)}`);if(e.page&&i.push(` page its own HTML outside the cards: -${e.page.removed} +${e.page.added} of its ${e.page.lines} line${e.page.lines===1?"":"s"}`),i.length===0)return[`No change since ${g}: every card where it was, with the data it had.`];let s=["added","removed","moved","resized","data","markup"].some(t=>e[t].some(c=>c.user)),n=["added","removed","moved","resized","data","markup"].some(t=>e[t].some(c=>c.gallery));return[`Changes since ${g}:`,...i,...e.kept?[e.kept===1?" The other card as it was.":` The other ${e.kept} cards as they were.`]:[],...s?[` Each change marked ${ze} is the user's own gesture on the page since then (a move, a resize, a card added or deleted there, what they typed in it), which the page wrote: leave it as it is, never put it back.`]:[],...n?[` Each change marked ${We} is Gallery's own doing, not the user's and not yours: the cards it put on the home page when it made it (\u95EE\u5019\u4E0E\u65E5\u671F, \u4FBF\u7B7E): leave it as it is.`]:[]]}async function ut(e,g){let{qa:o,state:h}=U(e),i=O.join(o,g,"checked.html"),s=await R.readFile(i,"utf8").catch(()=>null);if(s!==null){let{mtime:y}=await R.stat(i);return{text:s,since:`the last check that found nothing (${qe(y)}, local time, ${W(i)})`,at:y.getTime()}}let n=O.join(h,"pages",g),t=(await R.readdir(n).catch(()=>[])).filter(y=>/^\d{15}-\d{4}\.html$/.test(y)).sort();if(t.length===0)return null;let c=O.join(n,t.at(-1)),f=Number(t.at(-1).slice(0,15));return{text:await R.readFile(c,"utf8"),since:`the page as it was before its last write (${qe(new Date(f))}, local time; used because no check has passed yet)`,at:f}}var qe=e=>`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")} ${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`;function ft(e,g){let o=t=>`<${t.localName}${t.getAttribute("src")?` src="${t.getAttribute("src").slice(0,80)}"`:""}>`,h=[...document.querySelectorAll(".gallery-board > .gallery-card")].map(t=>{let c=t.parentElement.getBoundingClientRect(),f=t.getBoundingClientRect(),y=[...t.children].find(S=>S.matches(e));return{id:t.getAttribute("data-card-id"),block:y?.getAttribute(g)??null,out:f.width>0&&(f.left<c.left-1||f.right>c.right+1),tall:t.scrollHeight>t.clientHeight+1?{needs:t.scrollHeight,has:t.clientHeight}:null,wide:t.scrollWidth>t.clientWidth+1?{needs:t.scrollWidth,has:t.clientWidth}:null,fallback:!!y?.hasAttribute("data-doc-fallback"),error:(t.querySelector(".doc-kit-error")?.textContent??"").trim()||null,broken:[...t.querySelectorAll("img")].filter(S=>S.complete&&S.naturalWidth===0).map(o)}}),i=[...document.querySelectorAll("img")].filter(t=>!t.closest(".gallery-card")&&t.complete&&t.naturalWidth===0).map(o),s=document.documentElement.scrollWidth,n=[...globalThis.__galleryQueries?.pending.values()??[]].map(({kind:t,block:c,at:f})=>({kind:t,block:c,waited:Date.now()-f}));return{cards:h,broken:i,stuck:n,wide:s>innerWidth+1?s:0,columns:document.querySelector(".gallery-board")?.getAttribute("data-columns")??null}}async function wt(e,{address:g,out:o,readers:h=new Set,wait:i=ge,limits:s={}}){let{loading:n=he,ready:t=et,answer:c=pe,closing:f=de,looking:y=ue}=s,S=new Map,N=new Map,d=[],a=!1,r=(l,v,$,m,I=S)=>{if(a)return;let w=I.get(l)??{card:v,what:$,looks:[]};w.looks.push(m),I.set(l,w)},k="a browser context opened",u=(l,v,$=c)=>(k=v,ye(l,v,$)),b=Q.flatMap(l=>De.map(v=>({width:l,theme:v,view:`${l} ${v}`}))),x=null,A=async({width:l,theme:v,view:$})=>{let m=await u(x.newPage(),"a tab opened");try{m.on("pageerror",p=>r(`error ${z(p)}`,null,`the page threw: ${z(p)}`,$)),m.on("console",p=>{p.type()==="error"&&!/^Failed to load resource/.test(p.text())&&r(`console ${p.text().split(`
3
3
  `)[0]}`,null,`the console says ${p.text().split(`
4
4
  `)[0]}`,$)}),m.on("response",p=>{let C=new URL(p.url());p.status()>=400&&C.origin===new URL(g).origin&&C.pathname!=="/favicon.ico"&&r(`request ${C.pathname}`,null,`${C.pathname} answered ${p.status()}`,$)}),await u(be(m,{add:p=>r(`dialog ${p}`,null,`it opened a dialog (${p}), which stops a reader's page until it is answered`,$)}),"the tab was set to refuse dialogs"),await u(me(m),"the tab was set to watch the page's reads of the workspace"),await u(m.setViewport({width:l,height:Ze}),`the window went to ${l}px`),await u(m.emulateMediaFeatures([{name:"prefers-color-scheme",value:v}]),`the ${v} theme came`),await u(m.goto(g,{waitUntil:"load",timeout:0}),"the page opened",n),await u(m.waitForSelector("html[data-doc-ready][data-doc-drawn]",{timeout:0}),"the page was drawn (its html got data-doc-drawn)",t),await u(m.evaluate(()=>document.fonts?.ready.then(()=>!0)),"the page's fonts loaded");let I=await u(m.$("main"),"the page's main was found")??await u(m.$("body"),"the page's body was found");await u(I.evaluate(Oe,{still:fe,step:we,wait:i}),"the page held still");let w=await u(m.evaluate(ft,Ye,He),"the page was looked at");for(let{kind:p,block:C,waited:Ge}of w.stuck){let V=w.cards.filter(F=>C?F.block===C:h.has(F.block)),J=F=>`the workspace had not answered ${F} read of "${p}" ${Math.round(Ge/1e3)} s after it asked, so its picture shows it before it drew what it reads, which the picture then does not tell (open the page in Gallery to see it)`;if(V.length)for(let F of V)r(`unanswered ${F.id} ${p}`,F.id,J("its"),$,N);else r(`unanswered ${p}`,null,J("a card's"),$,N)}w.wide&&r("wide",null,`the page is ${w.wide}px wide in a window ${l}px wide: something of its own reaches past the window (a width of its own, a long word), and a reader scrolls it sideways`,$);for(let p of w.broken)r(`broken ${p}`,null,`a picture that does not load: ${p}`,$);for(let p of w.cards){p.fallback&&r(`fallback ${p.id}`,p.id,`its block failed: the card shows what its instance holds, read-only${p.error?` (${p.error.slice(0,200)})`:""}`,$),p.out&&r(`out ${p.id}`,p.id,"it is drawn out of its board",$),p.tall&&r(`tall ${p.id}`,p.id,`what it holds does not fit it: ${p.tall.needs}px high in a card that shows ${p.tall.has}px, the rest scrolling inside the card (give the card more cells, data-h, or a size its block lists; a block whose content grows says card.fit "content")`,$),p.wide&&r(`wide ${p.id}`,p.id,`what it holds is wider than the card: ${p.wide.needs}px in a card ${p.wide.has}px wide`,$);for(let C of p.broken)r(`broken ${p.id} ${C}`,p.id,`a picture that does not load: ${C}`,$)}let T=O.join(o,`${l}-${v}.png`);await u(m.screenshot({path:T,fullPage:!0}),"the page was pictured"),a||d.push(T)}finally{await K(m.close(),f)}},L=l=>({problems:[...S.values()],notes:[...N.values()],pictures:d,unverified:null,stuck:!1,...l}),E=null;try{x=await u(e.createBrowserContext(),"a browser context opened");for(let l of b)E=l,await gt(A(l),y,()=>k);return L({})}catch(l){return await Se(e)?L({unverified:`the browser went while it looked (${z(l)})`}):l.stuck?(r("stopped",null,mt(l,b.indexOf(E??b[0])<b.length-1),(E??b[0]).view),L({stuck:!0})):L({unverified:`the look stopped: ${z(l)}`})}finally{a=!0,await K(x?.close(),f)}}function gt(e,g,o){let h=0,i=new Promise((s,n)=>{h=setTimeout(()=>n(Object.assign(new Error(o()),{stuck:!0,doing:o(),limit:g,whole:!0})),g)});return Promise.race([e,i]).finally(()=>clearTimeout(h))}function mt(e,g){return`${e.whole?`the look was not done in ${xe(e.limit)}, waiting until ${e.doing}`:ve(e)}; the look stopped here and the browser was closed${g?", so the looks after it were not made":""}. A script of the page that never ends does this, and so may a browser that stalled: run the check once more, and if it stops at the same place again, the page holds it up`}function Be(e){let g=[...new Set(e.map(i=>i.split(" ")[0]))],o=[...new Set(e.map(i=>i.split(" ")[1]))],h=i=>i.length<2?i.join(""):`${i.slice(0,-1).join(", ")} and ${i.at(-1)}`;return`at ${h(g)}px${o.length===De.length?"":`, ${h(o)}`}`}async function Ht(e,g){if(g.length!==1)throw new se("gallery page check takes one page's slug.");let[o]=g,h=Xe(o,e);Je(o,e)||(console.error(await Ce(o,e)),process.exit(1));let i=new Date,s=await R.readFile(h.html,"utf8"),n=O.basename(h.html),t=Z(e),{boards:c,cards:f}=j(s);console.log(`${o}: ${W(h.html)}, ${c.length} board${c.length===1?"":"s"} and ${f.length} card${f.length===1?"":"s"}`);let y=[],S=st(s,{catalog:t,folder:h.folder,slug:o});for(let{line:l,what:v}of S)y.push(` FAIL ${n}:${l}: ${v}`);console.log(S.length?`Structure: ${S.length} problem${S.length===1?"":"s"}`:"Structure: nothing wrong (the page's own HTML, scripts and frames its own; every board's and card's id once, one instance a card, the cells on the board and none shared, every block one a page runs, every file of assets/ there)");for(let l of y)console.log(l);for(let l of j(P(s).text).cards)console.log(` ${l.id} ${l.block??"(no instance)"} x ${l.x}, y ${l.y}, ${l.w} \xD7 ${l.h}${c.length>1?` on ${l.board}`:""} ${n}:${l.node.sourceCodeLocation?.startLine}`);let N=rt(s,t);for(let l of N)console.log(` note ${n}:${l.line}: ${lt(l)}`);let d=await ut(e,o),a=d?await oe(U(e).state,o,d.at):[];console.log((d?pt(ht(ct(d.text,s,t),a),d.since):["No earlier version to tell changes against: the next check that finds nothing keeps this one, and says what changed since."]).join(`
5
- `));let r=new Map(j(P(s).text).cards.map(l=>[l.id,l.node.sourceCodeLocation?.startLine??1])),k=(l,v=null,$=0)=>{if(l)return{line:`FAIL ${o}: ${l} problem${l===1?"":"s"}`,code:1};if(v)return{line:`UNVERIFIED ${o}: ${v}; its structure was checked, and nothing is wrong with it`,code:3};let m=N.length?`; and ${N.length===1?"one card asks":`${N.length} cards ask`} for a setting no one gave (see "note" above): ${N.map(({id:I,empty:w})=>`${I} (${w.map(({key:T})=>T).join(", ")})`).join(", ")}`:"";return{line:`OK ${o}: its structure, and its ${f.length} card${f.length===1?"":"s"} at ${Q.join(", ")}px in light and dark${$?`; but ${$===1?"one card was":`${$} cards were`} pictured before the workspace answered it (see "note" above), so ${$===1?"its picture does":"their pictures do"} not show what ${$===1?"it reads":"they read"}`:""}${m}`,code:0}},u=await ie({command:`gallery page check ${o}`}),b=async(l,v,$=0)=>{let{line:m,code:I}=k(l,v,$);if(console.log(m),I===0){let w=O.join(U(e).qa,o,"checked.html");await R.mkdir(O.dirname(w),{recursive:!0}),await R.writeFile(w,s),await R.utimes(w,i,i)}process.exitCode=I};if(!u.ok)return b(S.length,`${u.message}, so the page was not looked at`);let x=re();if(!x)return b(S.length,"no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one), so the page was not looked at");await Ie(e);let A=await Ee(e,{directory:h.folder,files:h,text:s}),L=O.join(U(e).qa,o,"check"),E=null;try{let{pageAloneOf:l}=await import("./chunk-DAMVDXR3.mjs"),v=l(u.port,A.slug);console.log(`Looked at: ${v} (a scratch copy of ${o}, gone at the end: nothing a block does as it opens writes ${n}), at ${Q.join(", ")}px, light and dark`);try{E=await ce({executablePath:x,args:le()})}catch(w){return b(S.length,`the browser ${x} did not start, twice (${z(w)}), so the page was not looked at`)}await R.rm(L,{recursive:!0,force:!0}),await R.mkdir(L,{recursive:!0});let $=new Set([...t.packages.values()].filter(({needs:w})=>w?.includes("workspace")).map(({id:w})=>w)),m=await wt(E.browser,{address:v,out:L,readers:$});m.stuck&&(await E.close(),E=null);for(let{card:w,what:T,looks:p}of m.problems)console.log(` FAIL ${n}:${w?r.get(w)??1:1}: ${w?`card ${w}: `:""}${T} (${Be(p)})`);let I=new Map(j(s).cards.map(w=>[w.id,w.block]));for(let{card:w,what:T,looks:p}of m.notes)console.log(` note ${n}:${w?r.get(w)??1:1}: ${w?`card ${w}${I.get(w)?` (${I.get(w)})`:""}: `:""}${T} (${Be(p)})`);return m.pictures.length&&(console.log(`Pictures of the page in ${W(L)}: ${m.pictures.map(w=>O.basename(w)).join(", ")}`),console.log(Ae([{folder:O.dirname(L),files:m.pictures}]))),b(S.length+m.problems.length,m.unverified,new Set(m.notes.map(({card:w})=>w??"")).size)}finally{await E?.close(),await Ne(e,A.slug)}}export{We as GALLERYS_MARK,Q as LOOK_WIDTHS,De as THEMES,ze as USERS_MARK,ut as baselineOf,pt as changesSaid,rt as emptyRequired,lt as emptyRequiredSaid,wt as look,ht as markedTheUsers,ct as pageChanges,Ht as pageCheckCommand,st as structureProblems};
5
+ `));let r=new Map(j(P(s).text).cards.map(l=>[l.id,l.node.sourceCodeLocation?.startLine??1])),k=(l,v=null,$=0)=>{if(l)return{line:`FAIL ${o}: ${l} problem${l===1?"":"s"}`,code:1};if(v)return{line:`UNVERIFIED ${o}: ${v}; its structure was checked, and nothing is wrong with it`,code:3};let m=N.length?`; and ${N.length===1?"one card asks":`${N.length} cards ask`} for a setting no one gave (see "note" above): ${N.map(({id:I,empty:w})=>`${I} (${w.map(({key:T})=>T).join(", ")})`).join(", ")}`:"";return{line:`OK ${o}: its structure, and its ${f.length} card${f.length===1?"":"s"} at ${Q.join(", ")}px in light and dark${$?`; but ${$===1?"one card was":`${$} cards were`} pictured before the workspace answered it (see "note" above), so ${$===1?"its picture does":"their pictures do"} not show what ${$===1?"it reads":"they read"}`:""}${m}`,code:0}},u=await ie({command:`gallery page check ${o}`}),b=async(l,v,$=0)=>{let{line:m,code:I}=k(l,v,$);if(console.log(m),I===0){let w=O.join(U(e).qa,o,"checked.html");await R.mkdir(O.dirname(w),{recursive:!0}),await R.writeFile(w,s),await R.utimes(w,i,i)}process.exitCode=I};if(!u.ok)return b(S.length,`${u.message}, so the page was not looked at`);let x=re();if(!x)return b(S.length,"no Chrome, Edge or Chromium found (GALLERY_BROWSER=<its executable> picks one), so the page was not looked at");await Ie(e);let A=await Ee(e,{directory:h.folder,files:h,text:s}),L=O.join(U(e).qa,o,"check"),E=null;try{let{pageAloneOf:l}=await import("./chunk-ONKC4BCC.mjs"),v=l(u.port,A.slug);console.log(`Looked at: ${v} (a scratch copy of ${o}, gone at the end: nothing a block does as it opens writes ${n}), at ${Q.join(", ")}px, light and dark`);try{E=await ce({executablePath:x,args:le()})}catch(w){return b(S.length,`the browser ${x} did not start, twice (${z(w)}), so the page was not looked at`)}await R.rm(L,{recursive:!0,force:!0}),await R.mkdir(L,{recursive:!0});let $=new Set([...t.packages.values()].filter(({needs:w})=>w?.includes("workspace")).map(({id:w})=>w)),m=await wt(E.browser,{address:v,out:L,readers:$});m.stuck&&(await E.close(),E=null);for(let{card:w,what:T,looks:p}of m.problems)console.log(` FAIL ${n}:${w?r.get(w)??1:1}: ${w?`card ${w}: `:""}${T} (${Be(p)})`);let I=new Map(j(s).cards.map(w=>[w.id,w.block]));for(let{card:w,what:T,looks:p}of m.notes)console.log(` note ${n}:${w?r.get(w)??1:1}: ${w?`card ${w}${I.get(w)?` (${I.get(w)})`:""}: `:""}${T} (${Be(p)})`);return m.pictures.length&&(console.log(`Pictures of the page in ${W(L)}: ${m.pictures.map(w=>O.basename(w)).join(", ")}`),console.log(Ae([{folder:O.dirname(L),files:m.pictures}]))),b(S.length+m.problems.length,m.unverified,new Set(m.notes.map(({card:w})=>w??"")).size)}finally{await E?.close(),await Ne(e,A.slug)}}export{We as GALLERYS_MARK,Q as LOOK_WIDTHS,De as THEMES,ze as USERS_MARK,ut as baselineOf,pt as changesSaid,rt as emptyRequired,lt as emptyRequiredSaid,wt as look,ht as markedTheUsers,ct as pageChanges,Ht as pageCheckCommand,st as structureProblems};
@@ -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{a as u}from"./chunk-JXLSHVJ2.mjs";import l from"node:fs/promises";import p from"node:path";import{escapeMarkup as g}from"../browser/shared/escape.mjs";import{sha256 as b}from"../browser/shared/files.mjs";import{reportsDirectory as E,starterDirectory as y}from"../browser/shared/paths.mjs";import{listReportSlugs as T,slugPattern as S}from"../browser/shared/reports.mjs";import{documentDirectory as N,documentFiles as $,layoutOf as O,slugTaken as P}from"../browser/shared/workspace.mjs";async function j(t,c){if(!S.test(t))throw new Error(`A document's folder name must be lowercase kebab-case: ${t}`);let n=N(t,c),{html:r,json:i}=$(n),[m,o]=[p.basename(r),p.basename(i)],e,f;try{[e,f]=await Promise.all([l.readFile(r),l.readFile(i,"utf8")])}catch(s){if(s.code!=="ENOENT")throw s;let h=await l.stat(n).then(()=>!0,()=>!1);throw new Error(h?`${n} needs both ${m} and ${o}.`:`${n} does not exist.`)}let a;try{a=JSON.parse(f)}catch(s){throw new Error(`${o} is not valid JSON: ${s.message}`)}if(typeof a.title!="string")throw new Error(`${o} is missing a title.`);for(let s of["description","type"])if(typeof a[s]!="string"||a[s].trim()==="")throw new Error(`${o} is missing a non-empty ${s}.`);if(a.source!==void 0&&typeof a.source!="string")throw new Error(`${o} source must be a string when given.`);return{slug:t,directory:n,htmlPath:r,metadataPath:i,html:e.toString("utf8"),fileSha256:b(e),metadata:a}}async function z(t=[],{directory:c=E,prepare:n=null}={}){let r=t.length>0?[...new Set(t)]:await T(c);if(r.length===0)throw new Error(`No documents in ${p.resolve(c)} yet: gallery new <slug> "<title>" makes one.`);let i=[],m=new Map;for(let o of r)try{let e=await j(o,c);n&&([e.written,e.html]=[u(e.html),n(e)]),i.push(e)}catch(e){m.set(o,[e.message])}return{reports:i,failures:m}}var v=/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/,F=/\n[ \t]*<!-- Starter content:[^\n]*-->\n[ \t]*<section\b[^>]*\sdata-doc-placeholder\b[\s\S]*?<\/section>/;async function M(t,c,n,{directory:r=E,blank:i=!1,lang:m=null,page:o=!1}={}){if(!S.test(t))throw new Error("Slug must be lowercase kebab-case.");if(P(t,r))throw Object.assign(new Error(`"${t}" is taken in ${p.resolve(r)}`),{code:"EEXIST"});let e=o?O(r).preferencesPage:p.resolve(r),f=p.join(e,t),{html:a,metadata:s}=await R(t,c,n,{blank:i,lang:m});await l.mkdir(e,{recursive:!0}),await l.mkdir(f,{recursive:!1});let h=$(f);return await Promise.all([l.writeFile(h.html,a),l.writeFile(h.json,`${JSON.stringify(s,null,2)}
2
+ import{a as u}from"./chunk-UMHUSOPJ.mjs";import l from"node:fs/promises";import p from"node:path";import{escapeMarkup as g}from"../browser/shared/escape.mjs";import{sha256 as b}from"../browser/shared/files.mjs";import{reportsDirectory as E,starterDirectory as y}from"../browser/shared/paths.mjs";import{listReportSlugs as T,slugPattern as S}from"../browser/shared/reports.mjs";import{documentDirectory as N,documentFiles as $,layoutOf as O,slugTaken as P}from"../browser/shared/workspace.mjs";async function j(t,c){if(!S.test(t))throw new Error(`A document's folder name must be lowercase kebab-case: ${t}`);let n=N(t,c),{html:r,json:i}=$(n),[m,o]=[p.basename(r),p.basename(i)],e,f;try{[e,f]=await Promise.all([l.readFile(r),l.readFile(i,"utf8")])}catch(s){if(s.code!=="ENOENT")throw s;let h=await l.stat(n).then(()=>!0,()=>!1);throw new Error(h?`${n} needs both ${m} and ${o}.`:`${n} does not exist.`)}let a;try{a=JSON.parse(f)}catch(s){throw new Error(`${o} is not valid JSON: ${s.message}`)}if(typeof a.title!="string")throw new Error(`${o} is missing a title.`);for(let s of["description","type"])if(typeof a[s]!="string"||a[s].trim()==="")throw new Error(`${o} is missing a non-empty ${s}.`);if(a.source!==void 0&&typeof a.source!="string")throw new Error(`${o} source must be a string when given.`);return{slug:t,directory:n,htmlPath:r,metadataPath:i,html:e.toString("utf8"),fileSha256:b(e),metadata:a}}async function z(t=[],{directory:c=E,prepare:n=null}={}){let r=t.length>0?[...new Set(t)]:await T(c);if(r.length===0)throw new Error(`No documents in ${p.resolve(c)} yet: gallery new <slug> "<title>" makes one.`);let i=[],m=new Map;for(let o of r)try{let e=await j(o,c);n&&([e.written,e.html]=[u(e.html),n(e)]),i.push(e)}catch(e){m.set(o,[e.message])}return{reports:i,failures:m}}var v=/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/,F=/\n[ \t]*<!-- Starter content:[^\n]*-->\n[ \t]*<section\b[^>]*\sdata-doc-placeholder\b[\s\S]*?<\/section>/;async function M(t,c,n,{directory:r=E,blank:i=!1,lang:m=null,page:o=!1}={}){if(!S.test(t))throw new Error("Slug must be lowercase kebab-case.");if(P(t,r))throw Object.assign(new Error(`"${t}" is taken in ${p.resolve(r)}`),{code:"EEXIST"});let e=o?O(r).preferencesPage:p.resolve(r),f=p.join(e,t),{html:a,metadata:s}=await R(t,c,n,{blank:i,lang:m});await l.mkdir(e,{recursive:!0}),await l.mkdir(f,{recursive:!1});let h=$(f);return await Promise.all([l.writeFile(h.html,a),l.writeFile(h.json,`${JSON.stringify(s,null,2)}
3
3
  `)]),{slug:t,directory:f,metadata:s}}async function R(t,c,n,{blank:r=!1,lang:i=null}={}){let m=w=>g(w).replaceAll("'","&#39;"),[o,e]=await Promise.all([l.readFile(p.join(y,"doc.html"),"utf8"),l.readFile(p.join(y,"doc.json"),"utf8")]),f={...JSON.parse(e),title:c,description:n},a=r?o.replace(F,`
4
4
  <p></p>`):o;if(r&&a===o)throw new Error("The starter's placeholder section was not found.");let s=typeof i=="string"&&v.test(i)?a.replace(/(<html\b[^>]*\slang=")[^"]*"/,(w,d)=>`${d}${i}"`):a,h={SLUG:t,TITLE:m(c)};return{html:s.replace(/__REPORT_(SLUG|TITLE)__/g,(w,d)=>h[d]),metadata:f}}export{z as a,M as b,R as c};