@jxsuite/studio 5.7.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/chunks/{2020-cs2sb9t1.js → 2020-nkxms0ay.js} +3 -3
  2. package/dist/chunks/adapter-m948ab5f.js +4 -0
  3. package/dist/chunks/{cf-account-picker-882a7ecm.js → cf-account-picker-n8hr38v7.js} +3 -3
  4. package/dist/chunks/cf-settings-356xdtne.js +4 -0
  5. package/dist/chunks/components-yk3t844e.js +4 -0
  6. package/dist/chunks/content-source-bawmyc09.js +4 -0
  7. package/dist/chunks/{convert-to-repeater-grfep2w8.js → convert-to-repeater-7wns8kf1.js} +3 -3
  8. package/dist/chunks/editor-6sc8nacq.js +4 -0
  9. package/dist/chunks/entry-commands-8ay9fh81.js +4 -0
  10. package/dist/chunks/{extension-sections-dp8endhx.js → extension-sections-na7rj3nr.js} +3 -3
  11. package/dist/chunks/file-ops-gye0qw56.js +4 -0
  12. package/dist/chunks/files-dmc2xvcq.js +4 -0
  13. package/dist/chunks/format-host-t76b53f8.js +4 -0
  14. package/dist/chunks/fs-events-cg4tpz06.js +4 -0
  15. package/dist/chunks/git-panel-yef7bshy.js +4 -0
  16. package/dist/chunks/{grid-view-5amhg604.js → grid-view-7tt4bxw1.js} +6 -6
  17. package/dist/chunks/iframe-host-tmz30gfp.js +4 -0
  18. package/dist/chunks/{index-9ydfe04y.js → index-gybvv7a6.js} +3 -3
  19. package/dist/chunks/index-nag78a9h.js +4 -0
  20. package/dist/chunks/{javascript-d9pqgc2p.js → javascript-rnvdp3k4.js} +2 -2
  21. package/dist/chunks/{jsonMode-800yvbem.js → jsonMode-zhwsprqk.js} +5 -5
  22. package/dist/chunks/jx-validate-3gbp5nkn.js +4 -0
  23. package/dist/chunks/layers-fvz99859.js +4 -0
  24. package/dist/chunks/layers-panel-gchmbf9p.js +4 -0
  25. package/dist/chunks/lit-html-9agdspkt.js +4 -0
  26. package/dist/chunks/media-picker-rhjvyy00.js +4 -0
  27. package/dist/chunks/menu-2e4y9j7b.js +4 -0
  28. package/dist/chunks/{monaco-binding-62dtmgbf.js → monaco-binding-2jnhjjvr.js} +3 -3
  29. package/dist/chunks/monaco-buffer-rp21359g.js +4 -0
  30. package/dist/chunks/{monaco-setup-tj13ndtm.js → monaco-setup-vhh7gayr.js} +3 -3
  31. package/dist/chunks/notify-h3www560.js +4 -0
  32. package/dist/chunks/platform-hz34wcd7.js +4 -0
  33. package/dist/chunks/publish-panel-exsmjzyj.js +4 -0
  34. package/dist/chunks/quick-search-pgaqeh0m.js +4 -0
  35. package/dist/chunks/references-2cgdxnb8.js +4 -0
  36. package/dist/chunks/right-panel-jf856w5w.js +4 -0
  37. package/dist/chunks/section-registry-jnf8r5gy.js +4 -0
  38. package/dist/chunks/studio-0f55h9ye.js +5 -0
  39. package/dist/chunks/{studio-hjbg8d5y.js → studio-0sqdhnew.js} +7 -7
  40. package/dist/chunks/{studio-1wvfxkyy.js → studio-0x3jyb8r.js} +4 -4
  41. package/dist/chunks/{studio-yr04mv2j.js → studio-19x1c75w.js} +4 -4
  42. package/dist/chunks/{studio-evwgp1ym.js → studio-2sqcndak.js} +4 -4
  43. package/dist/chunks/{studio-cvbkkfqb.js → studio-3aey7dd3.js} +4 -4
  44. package/dist/chunks/{studio-888knnkc.js → studio-3bpdkq2s.js} +4 -4
  45. package/dist/chunks/{studio-ceb34dxj.js → studio-47y6fbpf.js} +4 -4
  46. package/dist/chunks/{studio-c6w3tq7t.js → studio-4m3826v2.js} +4 -4
  47. package/dist/chunks/studio-4nx2dj1g.js +4 -0
  48. package/dist/chunks/{studio-p7c1agz0.js → studio-4xv5s47r.js} +5 -5
  49. package/dist/chunks/{studio-sxc0zvpt.js → studio-5g0ag7c0.js} +3 -3
  50. package/dist/chunks/{studio-semd1s8s.js → studio-5g4t8v6w.js} +4 -4
  51. package/dist/chunks/studio-5py436sf.js +5 -0
  52. package/dist/chunks/{studio-aje966s9.js → studio-77kt594t.js} +4 -4
  53. package/dist/chunks/{studio-56z7evx4.js → studio-8f87n763.js} +6 -6
  54. package/dist/chunks/studio-8mb00b84.js +5 -0
  55. package/dist/chunks/studio-8p51gq2h.js +6 -0
  56. package/dist/chunks/studio-954ds834.js +5 -0
  57. package/dist/chunks/{studio-xta2vxp6.js → studio-9ft45c83.js} +6 -6
  58. package/dist/chunks/studio-a2138x5k.js +7 -0
  59. package/dist/chunks/studio-a9yzstqj.js +5 -0
  60. package/dist/chunks/{studio-gp02nqnw.js → studio-acdksxx6.js} +4 -4
  61. package/dist/chunks/{studio-edbtvcd1.js → studio-anyrgzvb.js} +4 -4
  62. package/dist/chunks/{studio-dkn3x3hz.js → studio-ar8jcf2y.js} +4 -4
  63. package/dist/chunks/{studio-xry7tk3z.js → studio-bmn4mn9j.js} +5 -5
  64. package/dist/chunks/{studio-03wwfvyt.js → studio-cpxkgjrj.js} +4 -4
  65. package/dist/chunks/{studio-spf2skgc.js → studio-e7xxa0sj.js} +4 -4
  66. package/dist/chunks/{studio-01qza1n3.js → studio-ecaz25vk.js} +4 -4
  67. package/dist/chunks/{studio-5e9zsamh.js → studio-fzdywr6p.js} +6 -6
  68. package/dist/chunks/{studio-65fhspdd.js → studio-g5fmf0c1.js} +4 -4
  69. package/dist/chunks/studio-g7nse7zb.js +5 -0
  70. package/dist/chunks/studio-geq1ea6k.js +14 -0
  71. package/dist/chunks/{studio-n78gjfy8.js → studio-ghkb32r8.js} +4 -4
  72. package/dist/chunks/{studio-222rqyyc.js → studio-ghrhy2y7.js} +4 -4
  73. package/dist/chunks/{studio-a7xqhc3n.js → studio-grawhey1.js} +4 -4
  74. package/dist/chunks/{studio-eh0rac07.js → studio-h0xgswew.js} +4 -4
  75. package/dist/chunks/{studio-wma2c6g8.js → studio-h9c4p2tx.js} +4 -4
  76. package/dist/chunks/studio-jyzj5cxs.js +5 -0
  77. package/dist/chunks/{studio-x92tgnee.js → studio-mgx8yhnz.js} +31 -31
  78. package/dist/chunks/{studio-0scebvb9.js → studio-mpb04y1d.js} +5 -5
  79. package/dist/chunks/{studio-xy3tv3az.js → studio-n17mty64.js} +4 -4
  80. package/dist/chunks/{studio-gfn1kpxj.js → studio-nwh2eqsk.js} +5 -5
  81. package/dist/chunks/{studio-nt06yybj.js → studio-pxg4ap1e.js} +3 -3
  82. package/dist/chunks/{studio-zpnk016a.js → studio-q1h883bt.js} +5 -5
  83. package/dist/chunks/{studio-c6zdm25z.js → studio-q4tv82h7.js} +6 -6
  84. package/dist/chunks/{studio-st75kn99.js → studio-qbj760tx.js} +5 -5
  85. package/dist/chunks/{studio-y7jehjrp.js → studio-qpqa7vk3.js} +4 -4
  86. package/dist/chunks/{studio-j6gnhvaa.js → studio-qqz8e5gk.js} +4 -4
  87. package/dist/chunks/{studio-skzanb0k.js → studio-qvasen3f.js} +4 -4
  88. package/dist/chunks/studio-rggdb3hm.js +5 -0
  89. package/dist/chunks/{studio-4xppwncr.js → studio-sghy936h.js} +3 -3
  90. package/dist/chunks/{studio-9mqfamps.js → studio-skprc6ef.js} +4 -4
  91. package/dist/chunks/{studio-1x8x26k3.js → studio-tt2nactf.js} +4 -4
  92. package/dist/chunks/{studio-54g077x3.js → studio-txjjzrsm.js} +5 -5
  93. package/dist/chunks/{studio-f195h2hq.js → studio-tyasmc39.js} +4 -4
  94. package/dist/chunks/{studio-0bbxhhce.js → studio-v2bvmbjj.js} +4 -4
  95. package/dist/chunks/{studio-pwqfmt4p.js → studio-vk9ezads.js} +4 -4
  96. package/dist/chunks/{studio-fqq890ap.js → studio-vzacdfsc.js} +3 -3
  97. package/dist/chunks/{studio-zd4kayn2.js → studio-w4c0xmrw.js} +4 -4
  98. package/dist/chunks/{studio-tw7rre6s.js → studio-wfjqhhbk.js} +4 -4
  99. package/dist/chunks/{studio-tp642n5g.js → studio-wgh5kxpj.js} +4 -4
  100. package/dist/chunks/studio-xasj0796.js +5 -0
  101. package/dist/chunks/{studio-tzegmy4w.js → studio-y78s8r2n.js} +4 -4
  102. package/dist/chunks/{studio-7pgy3xaf.js → studio-z8w183sh.js} +4 -4
  103. package/dist/chunks/{studio-01kbbqg3.js → studio-zscd9ty4.js} +124 -124
  104. package/dist/chunks/{studio-mwxgyn9h.js → studio-zxp13sss.js} +6 -6
  105. package/dist/chunks/{studio-r3kaka4d.js → studio-zygnmm01.js} +4 -4
  106. package/dist/chunks/{tsMode-k9s9fcag.js → tsMode-gr0m4dzr.js} +5 -5
  107. package/dist/chunks/workspace-m15qtcqp.js +4 -0
  108. package/dist/chunks/{ws-client-0ja08haa.js → ws-client-nf61frr1.js} +3 -3
  109. package/dist/iframe-entry.js +3 -3
  110. package/dist/manifest.json +62 -62
  111. package/dist/studio.js +83 -83
  112. package/package.json +11 -11
  113. package/src/new-project/add-repo-modal.ts +459 -59
  114. package/src/platforms/cloud.ts +95 -18
  115. package/src/publish/pages-service.ts +7 -0
  116. package/src/publish/publish-panel.ts +16 -2
  117. package/src/surfaces/add-repo.json +721 -224
  118. package/src/surfaces/add-repo.ts +196 -31
  119. package/src/types.ts +42 -3
  120. package/src/ui/schema-form.ts +6 -2
  121. package/src/utils/project-dir.ts +24 -0
  122. package/dist/chunks/adapter-y5gdq19c.js +0 -4
  123. package/dist/chunks/cf-settings-20dznc3j.js +0 -4
  124. package/dist/chunks/components-q037dya7.js +0 -4
  125. package/dist/chunks/content-source-37x3vsap.js +0 -4
  126. package/dist/chunks/editor-j5sq149q.js +0 -4
  127. package/dist/chunks/entry-commands-c5h3nqck.js +0 -4
  128. package/dist/chunks/file-ops-937cvqk6.js +0 -4
  129. package/dist/chunks/files-tznwe1p1.js +0 -4
  130. package/dist/chunks/format-host-e2pjvd25.js +0 -4
  131. package/dist/chunks/fs-events-fv64ak3s.js +0 -4
  132. package/dist/chunks/git-panel-gb713ttc.js +0 -4
  133. package/dist/chunks/iframe-host-t819mcg5.js +0 -4
  134. package/dist/chunks/index-m0x5ztax.js +0 -4
  135. package/dist/chunks/jx-validate-zc9zp77s.js +0 -4
  136. package/dist/chunks/layers-4bsr82wz.js +0 -4
  137. package/dist/chunks/layers-panel-b6shnaax.js +0 -4
  138. package/dist/chunks/lit-html-cfn61dn7.js +0 -4
  139. package/dist/chunks/media-picker-ej0kdh1j.js +0 -4
  140. package/dist/chunks/menu-rtxf9chb.js +0 -4
  141. package/dist/chunks/monaco-buffer-nn4dtx27.js +0 -4
  142. package/dist/chunks/notify-ahs57a2z.js +0 -4
  143. package/dist/chunks/platform-v9xyfkbx.js +0 -4
  144. package/dist/chunks/publish-panel-bq36xcmj.js +0 -4
  145. package/dist/chunks/quick-search-zm00h9dh.js +0 -4
  146. package/dist/chunks/references-99ws0b0m.js +0 -4
  147. package/dist/chunks/right-panel-pq2f71q3.js +0 -4
  148. package/dist/chunks/section-registry-b2yzp9sw.js +0 -4
  149. package/dist/chunks/studio-0k9mvpgj.js +0 -14
  150. package/dist/chunks/studio-1a99w39s.js +0 -5
  151. package/dist/chunks/studio-693nhyky.js +0 -5
  152. package/dist/chunks/studio-aqmph6k4.js +0 -5
  153. package/dist/chunks/studio-c9d3pxf7.js +0 -5
  154. package/dist/chunks/studio-cxt150pj.js +0 -7
  155. package/dist/chunks/studio-e6re3rk1.js +0 -5
  156. package/dist/chunks/studio-frb0qbf7.js +0 -6
  157. package/dist/chunks/studio-gh97gngt.js +0 -5
  158. package/dist/chunks/studio-nbxqcgvf.js +0 -5
  159. package/dist/chunks/studio-t1eedsyx.js +0 -4
  160. package/dist/chunks/studio-vavmwshr.js +0 -5
  161. package/dist/chunks/studio-xk0z6msk.js +0 -5
  162. package/dist/chunks/workspace-b69mgm0e.js +0 -4
@@ -1,5 +1,5 @@
1
- var n;function NI(e){n=new URL("./",e).href}function zv(e){if(n===void 0)throw Error(`bundleUrl(${JSON.stringify(e)}) before setBundleBase(). An entry module (src/studio.ts or src/canvas/iframe-entry.ts) must call setBundleBase(import.meta.url) first; a test needs tests/with-dom.ts, which sets one.`);return new URL(e,n).href}
2
- export{NI,zv};
1
+ var n;function MI(e){n=new URL("./",e).href}function Wv(e){if(n===void 0)throw Error(`bundleUrl(${JSON.stringify(e)}) before setBundleBase(). An entry module (src/studio.ts or src/canvas/iframe-entry.ts) must call setBundleBase(import.meta.url) first; a test needs tests/with-dom.ts, which sets one.`);return new URL(e,n).href}
2
+ export{MI,Wv};
3
3
 
4
- //# debugId=498A34F958330ADF64756E2164756E21
5
- //# sourceMappingURL=studio-edbtvcd1.js.map
4
+ //# debugId=92B8B56B5BD8257064756E2164756E21
5
+ //# sourceMappingURL=studio-anyrgzvb.js.map
@@ -1,5 +1,5 @@
1
- import{p}from"./studio-y7jehjrp.js";import{rt,zt,T,R,Ct}from"./studio-spf2skgc.js";import{v}from"./studio-fqq890ap.js";import{Ir}from"./studio-888knnkc.js";import{Al,Ld,_c,Gi,Va,Id,Bu}from"./studio-c6w3tq7t.js";import{sb,bE,ab,yE,wE}from"./studio-xk0z6msk.js";import{Cc}from"./studio-a7xqhc3n.js";import{Tv,Ai}from"./studio-tp642n5g.js";import{Oe}from"./studio-vavmwshr.js";var E={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMediaField",$description:"The media field: a thumbnail of what the value names, the value itself, and the two doors to a different one. It is a LEAF a caller interpolates — the Inspector's Content tab, the Signals panel and the grid's image-cell panel each draw an empty host and `ui/media-picker.ts` mounts this into it — so it has no chrome of its own and takes its width from whatever row it lands in. **Browse is addressed through its `part`, not through a class.** `ui/regions.ts` derives `inspector/field:<prop>/browse` by finding the Browse control inside the Inspector's own `[data-prop]` row; the handle used to be `.media-picker-browse`, and a document emits no class, so `[part=\"browse\"]` is the handle now. The four `.media-picker*` rules from `styles/overlays.css` are TRANSCRIBED here rather than shared, for the reason `doc-header.json` gives: a class a document does not emit cannot style it. `--radius` becomes `--jx-radius-sm` on the way, because a document mounted in a pane's stage is outside `<sp-theme>` and would otherwise take a fallback rather than follow the theme.",tagName:"div",attributes:{part:"media-field"},style:{$description:"The row's own layout and the four transcribed `.media-picker*` rules. Upload and Browse never shrink, so the FIELD is what yields width when the row is narrow — the buttons would otherwise collapse into unreadable stubs before the text did.",display:"flex",alignItems:"center",gap:"var(--jx-space-1)",flex:"1",minWidth:"0",fontFamily:"var(--jx-font-sans)",fontSize:"var(--jx-text-md)",color:"var(--fg)",'& [part="value"]':{flex:"1",minWidth:"0"},'& [part="upload"]':{flexShrink:"0"},'& [part="browse"]':{flexShrink:"0"},'& [part="thumb"]':{width:"24px",height:"24px",objectFit:"cover",borderRadius:"var(--jx-radius-sm)",border:"1px solid var(--border)",flexShrink:"0"}},children:[{tagName:"span",attributes:{part:"thumb-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/thumbState"},cases:{shown:{$description:"Decorative on purpose: the field beside it already states the path in text, so a caption here would be the same fact twice to a screen reader and nothing to anyone else.",tagName:"img",attributes:{part:"thumb",src:"${state.thumbSrc}",alt:""}}}},{tagName:"jx-textfield",attributes:{part:"value"},$props:{size:"sm",label:"${state.label}",placeholder:"/image.jpg",value:{$ref:"#/state/value"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/edit"},value:[{$ref:"event#/target/value"}]}],description:"Every keystroke, because the host debounces it: the canvas follows the typing without a document write per character."},onfocus:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/warm"},value:[]}],description:"Entering the field is the earliest honest signal that a pick is coming, so the project's media are listed then rather than when Browse is pressed."}},{tagName:"jx-action-button",attributes:{part:"upload"},$props:{size:"sm",quiet:!0,icon:"upload-simple",label:"Upload media",hint:"Upload media"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/upload"},value:[]}]}},{tagName:"jx-action-button",attributes:{part:"browse"},$props:{size:"sm",quiet:!0,icon:"image",label:"Browse media",hint:"Browse media"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/browse"},value:[{$ref:"event#/currentTarget"}]}],description:"The button hands over ITSELF: the browser is a popover and the platform wants its invoker, both so a second press on this control toggles rather than reopens and so focus comes back here when it closes."}}]};T("media-field",E);function O(t,e){t.label=e.label,t.value=e.value,t.thumbState=e.thumbState,t.thumbSrc=e.thumbSrc}function j(t,e,r){let i=v({browse:r.browse,edit:r.edit,label:e.label,thumbSrc:e.thumbSrc,thumbState:e.thumbState,upload:r.upload,value:e.value,warm:r.warm}),a=null,o=!1;return R("media-field",i,t).then((n)=>{if(o){n.dispose();return}a=n}),{dispose(){o=!0,a?.dispose(),a=null},update:(n)=>O(i,n)}}function ld(t){let{anchor:e,name:r,scope:i,slot:a}=t,o=document.createElement("div");o.style.pointerEvents="auto",o.setAttribute(rt,zt("popover",a)),Ct("popover").append(o);let n=new AbortController,s=null,w=null,c=!1,F=(m)=>{if(c)return;if(c=!0,n.abort(),w?.dispose(),w=null,o.remove(),m)t.onDismissed?.()},A=(async()=>{let m=await R(r,i,o,{signal:n.signal,...t.onNodeCreated?{onNodeCreated:t.onNodeCreated}:{}});if(n.signal.aborted)return;if(w=m,s=m.root,s.setAttribute(rt,zt("popover",a)),s.addEventListener("toggle",(b)=>{if(b.newState==="closed")F(!0)}),!s.hasAttribute("popover"))await new Promise((b)=>{s?.addEventListener("jx-ready",()=>b(),{once:!0})});if(n.signal.aborted)return;s.showPopover(e?{source:e}:void 0)})();return{close:()=>{if(c)return;if(s?.open)s.hidePopover();F(!1)},host:o,isOpen:()=>!c,ready:A}}var L={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMediaBrowser",$description:'The project\'s media, offered under whatever control asked for them. **Not the kit menu, and the difference is the thumbnails.** `surfaces/menu.json` is the settled answer to "a list of actions" and a `MenuRowProjection` carries a title, a chord and a gate — there is nowhere in it for a picture, nowhere for the size caption beside it, and a `jx-menu` is itself `popover=auto`, so a filter field cannot stand above one inside a panel. This is a browser: you pick an image by looking at it. **It is a `jx-popover`, so the PLATFORM owns dismissal** — light dismiss, Escape, the top layer and focus back to the invoker are the popover\'s contract, which is why nothing here binds a document listener and why the panel can paint over a modal `<dialog>` that the layer-div popover it replaces could not. The rows are plain buttons in a group, exactly as `grid-views.json`\'s saved views are: a list of buttons is reachable by Tab, and a `role="listbox"` would be a keyboard contract nothing here implements.',tagName:"jx-popover",attributes:{part:"media-browser"},$props:{label:"Project media",x:{$ref:"#/state/x"},y:{$ref:"#/state/y"}},children:[{tagName:"div",attributes:{part:"body"},style:{$description:"A search box that stays put and a list that scrolls under it. The panel itself never scrolls — `jx-popover` says why — so the box is here rather than on the host.",display:"flex",flexDirection:"column",gap:"var(--jx-space-2)",padding:"var(--jx-space-2)",minWidth:"260px",maxHeight:"360px",fontFamily:"var(--jx-font-sans)",fontSize:"var(--jx-text-md)",color:"var(--fg)",'& [part="rows"]':{display:"flex",flexDirection:"column",gap:"2px",overflowY:"auto",minHeight:"0"},'& [part="row"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-2)",textAlign:"left",background:"none",border:"none",color:"var(--fg)",font:"inherit",padding:"var(--jx-space-1) var(--jx-space-2)",borderRadius:"var(--jx-radius-sm)",cursor:"pointer",minWidth:"0"},'& [part="row"]:hover':{background:"var(--bg-hover)"},'& [part="row"]:focus-visible':{outline:"var(--jx-focus-ring)",outlineOffset:"-2px"},'& [part="row-thumb"]':{width:"24px",height:"24px",objectFit:"cover",borderRadius:"var(--jx-radius-sm)",flexShrink:"0"},'& [part="row-text"]':{display:"flex",flexDirection:"column",minWidth:"0"},'& [part="row-name"]':{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},'& [part="row-caption"]':{color:"var(--fg-dim)",fontSize:"var(--jx-text-xs)"},'& [part="empty"]':{margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-xs)"},'& [part="more"]':{margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-xs)"}},children:[{tagName:"jx-textfield",attributes:{part:"filter"},$props:{type:"search",size:"sm",label:"Search media",placeholder:"Search media…",autocomplete:"off",value:{$ref:"#/state/filter"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setFilter"},value:[{$ref:"event#/target/value"}]}]}},{tagName:"div",attributes:{part:"rows-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/rowsState"},cases:{empty:{tagName:"p",attributes:{part:"empty"},textContent:"${state.emptyLabel}"},listed:{tagName:"div",attributes:{part:"rows"},children:[{$prototype:"Array",items:{$ref:"#/state/rows"},key:{$ref:"$map/item/key"},map:{$description:"One file. The row hands back the value a pick writes — the site URL — rather than an index, so the list may be filtered under it without changing what any row means.",tagName:"button",attributes:{part:"row",type:"button","data-path":"${$map.item.path}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/pick"},value:[{$ref:"$map/item/path"}]}]},children:[{tagName:"span",attributes:{part:"row-thumb-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/thumbState"},cases:{shown:{$description:"Decorative: the row's own text names the file. The load handler is the whole of the dimensions caption — measuring an image is a decode the `<img>` has finished by the time `load` fires, so the numbers are a read of work already done rather than a second fetch per row.",tagName:"img",attributes:{part:"row-thumb",src:"${$map.item.thumbSrc}",alt:""},onload:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/measure"},value:[{$ref:"$map/item/file"},{$ref:"event#/target/naturalWidth"},{$ref:"event#/target/naturalHeight"}]}]}}}},{tagName:"span",attributes:{part:"row-text"},children:[{tagName:"span",attributes:{part:"row-name"},textContent:"${$map.item.name}"},{tagName:"span",attributes:{part:"row-caption-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/captionState"},cases:{shown:{tagName:"span",attributes:{part:"row-caption"},textContent:"${$map.item.caption}"}}}]}]}}]}}},{tagName:"div",attributes:{part:"more-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/moreState"},cases:{shown:{$description:'A truncated list says so. Fifty rows is the cap the list has always had; the sentence is what keeps the cap from reading as "that is all there is".',tagName:"p",attributes:{part:"more"},textContent:"${state.moreLabel}"}}}]}]};T("media-browser",L);var D="media-picker";function V(t,e){t.x=e.x,t.y=e.y,t.filter=e.filter,t.rowsState=e.rowsState,t.rows=e.rows,t.emptyLabel=e.emptyLabel,t.moreState=e.moreState,t.moreLabel=e.moreLabel}function N(t,e,r){let i=v({emptyLabel:t.emptyLabel,filter:t.filter,measure:e.measure,moreLabel:t.moreLabel,moreState:t.moreState,pick:e.pick,rows:t.rows,rowsState:t.rowsState,setFilter:e.setFilter,x:t.x,y:t.y}),a=ld({anchor:r,name:"media-browser",scope:i,slot:D,...e.dismissed?{onDismissed:e.dismissed}:{}});return a.ready.then(()=>{if(a.isOpen())a.host.querySelector('[part="filter"] [part="input"]')?.focus()}),{close:a.close,host:a.host,isOpen:a.isOpen,ready:a.ready,update:(o)=>V(i,o)}}var h=[],S=!1;async function P(t,e){let r=[];try{let i=await Ir(()=>e.listDirectory(t));bE(i);for(let a of i)if(a.type==="directory"){let o=await P(a.path,e);r.push(...o)}else{let o=Gi(a.name);if(Ld.has(o))r.push({file:a.path,isImage:Al.has(o),name:a.name,path:Id(a.path)})}}catch{}return r}async function g(){if(S)return;let t=p();h=await P("public",t),S=!0,Ai("leftPanel","rightPanel","frontmatterPanel")}function Y_(){h=[],S=!1,yE()}var y=50,d=null,u=null,l="",M={x:0,y:0};function k(){let t=l.toLowerCase(),e=t?h.filter((a)=>a.path.toLowerCase().includes(t)||a.name.toLowerCase().includes(t)):h,i=e.slice(0,y).map((a)=>{let o=wE(sb(a.file));return{caption:o,captionState:o?"shown":"hidden",file:a.file,key:a.file,name:a.name,path:a.path,thumbSrc:a.isImage?Bu(a.file):"",thumbState:a.isImage?"shown":"hidden"}});return{emptyLabel:"No matches",filter:l,moreLabel:`…${e.length-y} more`,moreState:e.length>y?"shown":"hidden",rows:i,rowsState:i.length>0?"listed":"empty",x:M.x,y:M.y}}function B(){let t=d;d=null,u=null,l="",t?.close()}var x=0;function z(t,e,r){if(!ab(t,e,r)||x!==0)return;x=requestAnimationFrame(()=>{x=0,d?.update(k())})}function XR(t,e){B(),u=e;let r=Oe(t);M={x:r.left,y:r.bottom+4},d=N(k(),{dismissed:()=>{d=null,u=null,l=""},measure:z,pick:(i)=>{let a=u;B(),a?.(i)},setFilter:(i)=>{l=i,d?.update(k())}},t)}async function QR(t,e){let r=await Va([...t]),[i]=r;if(i)e(i.ref)}function e$(t){let e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=_c(),e.addEventListener("change",()=>{if(e.files?.length)QR(e.files,t)}),e.click()}var _=400,f=new WeakMap;function H(t,e){let r=Al.has(Gi(e));return{label:t,thumbSrc:r&&e?Cc(e):"",thumbState:r&&e?"shown":"hidden",value:e}}function cd(t,e,r,i){g();let a=f.get(t);if(a){a.prop=e,a.commit=i,a.handle.update(H(e,r));return}let o={commit:i,handle:null,prop:e};o.handle=j(t,H(e,r),{browse:(n)=>{g(),XR(n,(s)=>o.commit(s))},edit:(n)=>Tv(`media:${o.prop}`,_,(s)=>o.commit(s))(n),upload:()=>e$((n)=>o.commit(n)),warm:()=>{g()}}),f.set(t,o)}function uw(t){let e=f.get(t);if(e)f.delete(t),e.handle.dispose()}
2
- export{ld,Y_,XR,QR,e$,cd,uw};
1
+ import{p}from"./studio-qpqa7vk3.js";import{rt,zt,T,R,Ct}from"./studio-e7xxa0sj.js";import{v}from"./studio-vzacdfsc.js";import{Ir}from"./studio-3bpdkq2s.js";import{Nl,Id,Cc,Gi,Ua,Rd,zu}from"./studio-4m3826v2.js";import{ab,yE,lb,xE,_E}from"./studio-954ds834.js";import{kc}from"./studio-grawhey1.js";import{Lv,Ai}from"./studio-wgh5kxpj.js";import{Oe}from"./studio-a9yzstqj.js";var E={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMediaField",$description:"The media field: a thumbnail of what the value names, the value itself, and the two doors to a different one. It is a LEAF a caller interpolates — the Inspector's Content tab, the Signals panel and the grid's image-cell panel each draw an empty host and `ui/media-picker.ts` mounts this into it — so it has no chrome of its own and takes its width from whatever row it lands in. **Browse is addressed through its `part`, not through a class.** `ui/regions.ts` derives `inspector/field:<prop>/browse` by finding the Browse control inside the Inspector's own `[data-prop]` row; the handle used to be `.media-picker-browse`, and a document emits no class, so `[part=\"browse\"]` is the handle now. The four `.media-picker*` rules from `styles/overlays.css` are TRANSCRIBED here rather than shared, for the reason `doc-header.json` gives: a class a document does not emit cannot style it. `--radius` becomes `--jx-radius-sm` on the way, because a document mounted in a pane's stage is outside `<sp-theme>` and would otherwise take a fallback rather than follow the theme.",tagName:"div",attributes:{part:"media-field"},style:{$description:"The row's own layout and the four transcribed `.media-picker*` rules. Upload and Browse never shrink, so the FIELD is what yields width when the row is narrow — the buttons would otherwise collapse into unreadable stubs before the text did.",display:"flex",alignItems:"center",gap:"var(--jx-space-1)",flex:"1",minWidth:"0",fontFamily:"var(--jx-font-sans)",fontSize:"var(--jx-text-md)",color:"var(--fg)",'& [part="value"]':{flex:"1",minWidth:"0"},'& [part="upload"]':{flexShrink:"0"},'& [part="browse"]':{flexShrink:"0"},'& [part="thumb"]':{width:"24px",height:"24px",objectFit:"cover",borderRadius:"var(--jx-radius-sm)",border:"1px solid var(--border)",flexShrink:"0"}},children:[{tagName:"span",attributes:{part:"thumb-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/thumbState"},cases:{shown:{$description:"Decorative on purpose: the field beside it already states the path in text, so a caption here would be the same fact twice to a screen reader and nothing to anyone else.",tagName:"img",attributes:{part:"thumb",src:"${state.thumbSrc}",alt:""}}}},{tagName:"jx-textfield",attributes:{part:"value"},$props:{size:"sm",label:"${state.label}",placeholder:"/image.jpg",value:{$ref:"#/state/value"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/edit"},value:[{$ref:"event#/target/value"}]}],description:"Every keystroke, because the host debounces it: the canvas follows the typing without a document write per character."},onfocus:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/warm"},value:[]}],description:"Entering the field is the earliest honest signal that a pick is coming, so the project's media are listed then rather than when Browse is pressed."}},{tagName:"jx-action-button",attributes:{part:"upload"},$props:{size:"sm",quiet:!0,icon:"upload-simple",label:"Upload media",hint:"Upload media"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/upload"},value:[]}]}},{tagName:"jx-action-button",attributes:{part:"browse"},$props:{size:"sm",quiet:!0,icon:"image",label:"Browse media",hint:"Browse media"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/browse"},value:[{$ref:"event#/currentTarget"}]}],description:"The button hands over ITSELF: the browser is a popover and the platform wants its invoker, both so a second press on this control toggles rather than reopens and so focus comes back here when it closes."}}]};T("media-field",E);function O(t,e){t.label=e.label,t.value=e.value,t.thumbState=e.thumbState,t.thumbSrc=e.thumbSrc}function j(t,e,r){let i=v({browse:r.browse,edit:r.edit,label:e.label,thumbSrc:e.thumbSrc,thumbState:e.thumbState,upload:r.upload,value:e.value,warm:r.warm}),a=null,o=!1;return R("media-field",i,t).then((n)=>{if(o){n.dispose();return}a=n}),{dispose(){o=!0,a?.dispose(),a=null},update:(n)=>O(i,n)}}function cd(t){let{anchor:e,name:r,scope:i,slot:a}=t,o=document.createElement("div");o.style.pointerEvents="auto",o.setAttribute(rt,zt("popover",a)),Ct("popover").append(o);let n=new AbortController,s=null,w=null,c=!1,F=(m)=>{if(c)return;if(c=!0,n.abort(),w?.dispose(),w=null,o.remove(),m)t.onDismissed?.()},A=(async()=>{let m=await R(r,i,o,{signal:n.signal,...t.onNodeCreated?{onNodeCreated:t.onNodeCreated}:{}});if(n.signal.aborted)return;if(w=m,s=m.root,s.setAttribute(rt,zt("popover",a)),s.addEventListener("toggle",(b)=>{if(b.newState==="closed")F(!0)}),!s.hasAttribute("popover"))await new Promise((b)=>{s?.addEventListener("jx-ready",()=>b(),{once:!0})});if(n.signal.aborted)return;s.showPopover(e?{source:e}:void 0)})();return{close:()=>{if(c)return;if(s?.open)s.hidePopover();F(!1)},host:o,isOpen:()=>!c,ready:A}}var L={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMediaBrowser",$description:'The project\'s media, offered under whatever control asked for them. **Not the kit menu, and the difference is the thumbnails.** `surfaces/menu.json` is the settled answer to "a list of actions" and a `MenuRowProjection` carries a title, a chord and a gate — there is nowhere in it for a picture, nowhere for the size caption beside it, and a `jx-menu` is itself `popover=auto`, so a filter field cannot stand above one inside a panel. This is a browser: you pick an image by looking at it. **It is a `jx-popover`, so the PLATFORM owns dismissal** — light dismiss, Escape, the top layer and focus back to the invoker are the popover\'s contract, which is why nothing here binds a document listener and why the panel can paint over a modal `<dialog>` that the layer-div popover it replaces could not. The rows are plain buttons in a group, exactly as `grid-views.json`\'s saved views are: a list of buttons is reachable by Tab, and a `role="listbox"` would be a keyboard contract nothing here implements.',tagName:"jx-popover",attributes:{part:"media-browser"},$props:{label:"Project media",x:{$ref:"#/state/x"},y:{$ref:"#/state/y"}},children:[{tagName:"div",attributes:{part:"body"},style:{$description:"A search box that stays put and a list that scrolls under it. The panel itself never scrolls — `jx-popover` says why — so the box is here rather than on the host.",display:"flex",flexDirection:"column",gap:"var(--jx-space-2)",padding:"var(--jx-space-2)",minWidth:"260px",maxHeight:"360px",fontFamily:"var(--jx-font-sans)",fontSize:"var(--jx-text-md)",color:"var(--fg)",'& [part="rows"]':{display:"flex",flexDirection:"column",gap:"2px",overflowY:"auto",minHeight:"0"},'& [part="row"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-2)",textAlign:"left",background:"none",border:"none",color:"var(--fg)",font:"inherit",padding:"var(--jx-space-1) var(--jx-space-2)",borderRadius:"var(--jx-radius-sm)",cursor:"pointer",minWidth:"0"},'& [part="row"]:hover':{background:"var(--bg-hover)"},'& [part="row"]:focus-visible':{outline:"var(--jx-focus-ring)",outlineOffset:"-2px"},'& [part="row-thumb"]':{width:"24px",height:"24px",objectFit:"cover",borderRadius:"var(--jx-radius-sm)",flexShrink:"0"},'& [part="row-text"]':{display:"flex",flexDirection:"column",minWidth:"0"},'& [part="row-name"]':{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},'& [part="row-caption"]':{color:"var(--fg-dim)",fontSize:"var(--jx-text-xs)"},'& [part="empty"]':{margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-xs)"},'& [part="more"]':{margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-xs)"}},children:[{tagName:"jx-textfield",attributes:{part:"filter"},$props:{type:"search",size:"sm",label:"Search media",placeholder:"Search media…",autocomplete:"off",value:{$ref:"#/state/filter"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setFilter"},value:[{$ref:"event#/target/value"}]}]}},{tagName:"div",attributes:{part:"rows-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/rowsState"},cases:{empty:{tagName:"p",attributes:{part:"empty"},textContent:"${state.emptyLabel}"},listed:{tagName:"div",attributes:{part:"rows"},children:[{$prototype:"Array",items:{$ref:"#/state/rows"},key:{$ref:"$map/item/key"},map:{$description:"One file. The row hands back the value a pick writes — the site URL — rather than an index, so the list may be filtered under it without changing what any row means.",tagName:"button",attributes:{part:"row",type:"button","data-path":"${$map.item.path}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/pick"},value:[{$ref:"$map/item/path"}]}]},children:[{tagName:"span",attributes:{part:"row-thumb-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/thumbState"},cases:{shown:{$description:"Decorative: the row's own text names the file. The load handler is the whole of the dimensions caption — measuring an image is a decode the `<img>` has finished by the time `load` fires, so the numbers are a read of work already done rather than a second fetch per row.",tagName:"img",attributes:{part:"row-thumb",src:"${$map.item.thumbSrc}",alt:""},onload:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/measure"},value:[{$ref:"$map/item/file"},{$ref:"event#/target/naturalWidth"},{$ref:"event#/target/naturalHeight"}]}]}}}},{tagName:"span",attributes:{part:"row-text"},children:[{tagName:"span",attributes:{part:"row-name"},textContent:"${$map.item.name}"},{tagName:"span",attributes:{part:"row-caption-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/captionState"},cases:{shown:{tagName:"span",attributes:{part:"row-caption"},textContent:"${$map.item.caption}"}}}]}]}}]}}},{tagName:"div",attributes:{part:"more-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/moreState"},cases:{shown:{$description:'A truncated list says so. Fifty rows is the cap the list has always had; the sentence is what keeps the cap from reading as "that is all there is".',tagName:"p",attributes:{part:"more"},textContent:"${state.moreLabel}"}}}]}]};T("media-browser",L);var D="media-picker";function V(t,e){t.x=e.x,t.y=e.y,t.filter=e.filter,t.rowsState=e.rowsState,t.rows=e.rows,t.emptyLabel=e.emptyLabel,t.moreState=e.moreState,t.moreLabel=e.moreLabel}function N(t,e,r){let i=v({emptyLabel:t.emptyLabel,filter:t.filter,measure:e.measure,moreLabel:t.moreLabel,moreState:t.moreState,pick:e.pick,rows:t.rows,rowsState:t.rowsState,setFilter:e.setFilter,x:t.x,y:t.y}),a=cd({anchor:r,name:"media-browser",scope:i,slot:D,...e.dismissed?{onDismissed:e.dismissed}:{}});return a.ready.then(()=>{if(a.isOpen())a.host.querySelector('[part="filter"] [part="input"]')?.focus()}),{close:a.close,host:a.host,isOpen:a.isOpen,ready:a.ready,update:(o)=>V(i,o)}}var h=[],S=!1;async function P(t,e){let r=[];try{let i=await Ir(()=>e.listDirectory(t));yE(i);for(let a of i)if(a.type==="directory"){let o=await P(a.path,e);r.push(...o)}else{let o=Gi(a.name);if(Id.has(o))r.push({file:a.path,isImage:Nl.has(o),name:a.name,path:Rd(a.path)})}}catch{}return r}async function g(){if(S)return;let t=p();h=await P("public",t),S=!0,Ai("leftPanel","rightPanel","frontmatterPanel")}function X_(){h=[],S=!1,xE()}var y=50,d=null,u=null,l="",M={x:0,y:0};function k(){let t=l.toLowerCase(),e=t?h.filter((a)=>a.path.toLowerCase().includes(t)||a.name.toLowerCase().includes(t)):h,i=e.slice(0,y).map((a)=>{let o=_E(ab(a.file));return{caption:o,captionState:o?"shown":"hidden",file:a.file,key:a.file,name:a.name,path:a.path,thumbSrc:a.isImage?zu(a.file):"",thumbState:a.isImage?"shown":"hidden"}});return{emptyLabel:"No matches",filter:l,moreLabel:`…${e.length-y} more`,moreState:e.length>y?"shown":"hidden",rows:i,rowsState:i.length>0?"listed":"empty",x:M.x,y:M.y}}function B(){let t=d;d=null,u=null,l="",t?.close()}var x=0;function z(t,e,r){if(!lb(t,e,r)||x!==0)return;x=requestAnimationFrame(()=>{x=0,d?.update(k())})}function e$(t,e){B(),u=e;let r=Oe(t);M={x:r.left,y:r.bottom+4},d=N(k(),{dismissed:()=>{d=null,u=null,l=""},measure:z,pick:(i)=>{let a=u;B(),a?.(i)},setFilter:(i)=>{l=i,d?.update(k())}},t)}async function t$(t,e){let r=await Ua([...t]),[i]=r;if(i)e(i.ref)}function n$(t){let e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=Cc(),e.addEventListener("change",()=>{if(e.files?.length)t$(e.files,t)}),e.click()}var _=400,f=new WeakMap;function H(t,e){let r=Nl.has(Gi(e));return{label:t,thumbSrc:r&&e?kc(e):"",thumbState:r&&e?"shown":"hidden",value:e}}function dd(t,e,r,i){g();let a=f.get(t);if(a){a.prop=e,a.commit=i,a.handle.update(H(e,r));return}let o={commit:i,handle:null,prop:e};o.handle=j(t,H(e,r),{browse:(n)=>{g(),e$(n,(s)=>o.commit(s))},edit:(n)=>Lv(`media:${o.prop}`,_,(s)=>o.commit(s))(n),upload:()=>n$((n)=>o.commit(n)),warm:()=>{g()}}),f.set(t,o)}function hw(t){let e=f.get(t);if(e)f.delete(t),e.handle.dispose()}
2
+ export{cd,X_,e$,t$,n$,dd,hw};
3
3
 
4
- //# debugId=E3994757D515F61664756E2164756E21
5
- //# sourceMappingURL=studio-dkn3x3hz.js.map
4
+ //# debugId=F220B78B230A642664756E2164756E21
5
+ //# sourceMappingURL=studio-ar8jcf2y.js.map
@@ -1,7 +1,7 @@
1
- import{$o,bm,u}from"./studio-cvbkkfqb.js";import{y}from"./studio-zpnk016a.js";import{D}from"./studio-tp642n5g.js";var em=["application","project","document","selection"],fT=["global","canvas","caret","grid","code","dock","palette"],mT=["File","Edit","Selection","Insert","View","Document","Project","Source Control","Publish","Assistant","Collaborate","Help"],d=["commandbar/primary","commandbar/overflow","statusbar/project","statusbar/document","statusbar/selection","context/element","context/file","context/layer","context/tab","context/pane","blockbar","blockbar/format","outline/row","settings/menu","palette","never"],m={"commandbar/primary":{admits:["application","document"],note:"document only for Save / Undo / Redo / Open in Browser, by frequency; ≤5 total"},"commandbar/overflow":{admits:["application","project","document"],note:"never selection — the Command Bar is not a selection surface"},"statusbar/project":{admits:["project"],note:"the status bar's left field"},"statusbar/document":{admits:["document"],note:"the status bar's centre field"},"statusbar/selection":{admits:["selection"],note:"the status bar's right field"},"context/element":{admits:["selection"],note:"the canvas element menu acts on a selection"},"context/file":{admits:["project"],note:"a file row addresses the project's file set"},"context/layer":{admits:["selection"],note:"an outline row IS a selection"},"context/tab":{admits:["document"],note:"a tab addresses one document"},"context/pane":{admits:["document"],note:"a pane hosts one document"},blockbar:{admits:["selection"],note:"the floating bar owns selection-scoped verbs"},"blockbar/format":{admits:["selection"],note:"the bar's inline-format cluster — a range inside the selection is still the selection"},"outline/row":{admits:["selection"],note:"row actions act on the row's node"},"settings/menu":{admits:["application","project"],note:"the rail foot's gear menu — the settings family. It is a MENU, not a pinned slot, so it "+"may host two levels for the reason commandbar/overflow does: a menu prints each row's own name, chord and gate, and draws a divider where the level changes. The rail's PINNED groups stay single-level, in PANEL_PLACEMENT_MATRIX"},palette:{admits:["application","project","document","selection"],note:"the level-agnostic surface; it groups rows by level"},never:{admits:["application","project","document","selection"],note:"keyboard- and API-only; no rendered surface to be misplaced in"}},p=["rail/project","rail/document","navigator","inspector","dock.bottom"],f={"rail/project":{admits:["project"],note:"the rail's upper group — Files, Search, Source Control, Problems"},"rail/document":{admits:["document"],note:"the rail's lower group — Outline, Page, Data, Packages"},navigator:{admits:["project","document"],note:"whichever level the hosted panel declares; the panel header prints it"},inspector:{admits:["selection"],note:"the Inspector's tabs are selection surfaces"},"dock.bottom":{admits:["project","document"],note:"the panel header states which"}};function g(e){return e==="bottom"?"dock.bottom":e}function P(e){let t=[g(e.dock)];if(e.rail!==!1)t.push(`rail/${e.level}`);return t}function v(e){return p.includes(e)}function r(e){let t=[];if(!i(e.level))return t.push({panelId:e.id,placement:"—",level:String(e.level),message:`declares unknown level "${String(e.level)}" (expected one of: ${em.join(", ")})`}),t;for(let n of P(e)){if(!v(n)){t.push({panelId:e.id,placement:n,level:e.level,message:`is level "${e.level}" and would render in "${n}", which is not a panel `+"placement — the rail has a group for project and one for document, and nothing else"});continue}let o=f[n];if(!o.admits.includes(e.level))t.push({panelId:e.id,placement:n,level:e.level,message:`is level "${e.level}" but "${n}" admits only ${o.admits.join(", ")} — ${o.note}`})}return t}function b(e){return d.includes(e)}function i(e){return em.includes(e)}function gT(e){let t=[];if(!i(e.level))return t.push({commandId:e.id,placement:"—",level:String(e.level),message:`declares unknown level "${String(e.level)}" (expected one of: ${em.join(", ")})`}),t;for(let n of e.menus??[]){if(!b(n)){t.push({commandId:e.id,placement:String(n),level:e.level,message:`declares unknown placement "${String(n)}"`});continue}let o=m[n];if(!o.admits.includes(e.level))t.push({commandId:e.id,placement:n,level:e.level,message:`is level "${e.level}" but "${n}" admits only ${o.admits.join(", ")} — ${o.note}`})}return t}function vd(){let e=bm();return e.project.open=D!==null,e.project.isMultilingual=($o(D?.projectConfig??{}).i18n?.locales.length??0)>1,e.git.dirtyCount=y.git.status?.files?.length??0,e.document.open=u.value!==null,e}var h=/^[a-z][\w-]*$/,a=new Map;function qn(e){if(!h.test(e.id))throw Error(`Panel id "${e.id}" is malformed — expected /^[a-z][\\w-]*$/, because the id is also `+`the region "navigator/panel:${e.id}" and the value view.setActivity accepts.`);if(a.has(e.id))throw Error(`Panel "${e.id}" is already registered — a second definition site is the defect this `+"registry exists to prevent.");let t=r({id:e.id,level:e.level,dock:e.dock,rail:e.rail});if(t.length>0){let n=t.map((o)=>` ✗ ${e.id} ${o.message}`).join(`
1
+ import{$o,vm,u}from"./studio-3aey7dd3.js";import{y}from"./studio-q1h883bt.js";import{D}from"./studio-wgh5kxpj.js";var tm=["application","project","document","selection"],gT=["global","canvas","caret","grid","code","dock","palette"],bT=["File","Edit","Selection","Insert","View","Document","Project","Source Control","Publish","Assistant","Collaborate","Help"],d=["commandbar/primary","commandbar/overflow","statusbar/project","statusbar/document","statusbar/selection","context/element","context/file","context/layer","context/tab","context/pane","blockbar","blockbar/format","outline/row","settings/menu","palette","never"],m={"commandbar/primary":{admits:["application","document"],note:"document only for Save / Undo / Redo / Open in Browser, by frequency; ≤5 total"},"commandbar/overflow":{admits:["application","project","document"],note:"never selection — the Command Bar is not a selection surface"},"statusbar/project":{admits:["project"],note:"the status bar's left field"},"statusbar/document":{admits:["document"],note:"the status bar's centre field"},"statusbar/selection":{admits:["selection"],note:"the status bar's right field"},"context/element":{admits:["selection"],note:"the canvas element menu acts on a selection"},"context/file":{admits:["project"],note:"a file row addresses the project's file set"},"context/layer":{admits:["selection"],note:"an outline row IS a selection"},"context/tab":{admits:["document"],note:"a tab addresses one document"},"context/pane":{admits:["document"],note:"a pane hosts one document"},blockbar:{admits:["selection"],note:"the floating bar owns selection-scoped verbs"},"blockbar/format":{admits:["selection"],note:"the bar's inline-format cluster — a range inside the selection is still the selection"},"outline/row":{admits:["selection"],note:"row actions act on the row's node"},"settings/menu":{admits:["application","project"],note:"the rail foot's gear menu — the settings family. It is a MENU, not a pinned slot, so it "+"may host two levels for the reason commandbar/overflow does: a menu prints each row's own name, chord and gate, and draws a divider where the level changes. The rail's PINNED groups stay single-level, in PANEL_PLACEMENT_MATRIX"},palette:{admits:["application","project","document","selection"],note:"the level-agnostic surface; it groups rows by level"},never:{admits:["application","project","document","selection"],note:"keyboard- and API-only; no rendered surface to be misplaced in"}},p=["rail/project","rail/document","navigator","inspector","dock.bottom"],f={"rail/project":{admits:["project"],note:"the rail's upper group — Files, Search, Source Control, Problems"},"rail/document":{admits:["document"],note:"the rail's lower group — Outline, Page, Data, Packages"},navigator:{admits:["project","document"],note:"whichever level the hosted panel declares; the panel header prints it"},inspector:{admits:["selection"],note:"the Inspector's tabs are selection surfaces"},"dock.bottom":{admits:["project","document"],note:"the panel header states which"}};function g(e){return e==="bottom"?"dock.bottom":e}function P(e){let t=[g(e.dock)];if(e.rail!==!1)t.push(`rail/${e.level}`);return t}function v(e){return p.includes(e)}function r(e){let t=[];if(!i(e.level))return t.push({panelId:e.id,placement:"—",level:String(e.level),message:`declares unknown level "${String(e.level)}" (expected one of: ${tm.join(", ")})`}),t;for(let n of P(e)){if(!v(n)){t.push({panelId:e.id,placement:n,level:e.level,message:`is level "${e.level}" and would render in "${n}", which is not a panel `+"placement — the rail has a group for project and one for document, and nothing else"});continue}let o=f[n];if(!o.admits.includes(e.level))t.push({panelId:e.id,placement:n,level:e.level,message:`is level "${e.level}" but "${n}" admits only ${o.admits.join(", ")} — ${o.note}`})}return t}function b(e){return d.includes(e)}function i(e){return tm.includes(e)}function vT(e){let t=[];if(!i(e.level))return t.push({commandId:e.id,placement:"—",level:String(e.level),message:`declares unknown level "${String(e.level)}" (expected one of: ${tm.join(", ")})`}),t;for(let n of e.menus??[]){if(!b(n)){t.push({commandId:e.id,placement:String(n),level:e.level,message:`declares unknown placement "${String(n)}"`});continue}let o=m[n];if(!o.admits.includes(e.level))t.push({commandId:e.id,placement:n,level:e.level,message:`is level "${e.level}" but "${n}" admits only ${o.admits.join(", ")} — ${o.note}`})}return t}function yd(){let e=vm();return e.project.open=D!==null,e.project.isMultilingual=($o(D?.projectConfig??{}).i18n?.locales.length??0)>1,e.git.dirtyCount=y.git.status?.files?.length??0,e.document.open=u.value!==null,e}var h=/^[a-z][\w-]*$/,a=new Map;function qn(e){if(!h.test(e.id))throw Error(`Panel id "${e.id}" is malformed — expected /^[a-z][\\w-]*$/, because the id is also `+`the region "navigator/panel:${e.id}" and the value view.setActivity accepts.`);if(a.has(e.id))throw Error(`Panel "${e.id}" is already registered — a second definition site is the defect this `+"registry exists to prevent.");let t=r({id:e.id,level:e.level,dock:e.dock,rail:e.rail});if(t.length>0){let n=t.map((o)=>` ✗ ${e.id} ${o.message}`).join(`
2
2
  `);throw Error(`Panel "${e.id}" violates the level × placement matrix:
3
- ${n}`)}if(e.railLabel!==void 0&&(e.railLabel.trim()===""||!e.title.startsWith(e.railLabel)))throw Error(`Panel "${e.id}" declares railLabel "${e.railLabel}", which is not a leading part of its title "${e.title}": the rail button's accessible name is the title, and the words on screen must be inside it (WCAG 2.5.3, Label in Name).`);a.set(e.id,e)}function Au(e){return a.get(e)}function Lb(e){let t=[...a.values()];return e?t.filter((n)=>n.dock===e):t}function Ib(e,t){return e.when?e.when(t):!0}var s=[{level:"project",label:"Project"},{level:"document",label:"Document"}];function c(){return Lb().filter((e)=>e.rail!==!1)}function V1(e){let t=c();return s.map(({level:n,label:o})=>({level:n,label:o,panels:t.filter((l)=>l.level===n&&Ib(l,e))})).filter((n)=>n.panels.length>0)}function bT(){let e=c();return s.flatMap(({level:t})=>e.filter((n)=>n.level===t))}
4
- export{em,fT,mT,gT,vd,qn,Au,Lb,Ib,V1,bT};
3
+ ${n}`)}if(e.railLabel!==void 0&&(e.railLabel.trim()===""||!e.title.startsWith(e.railLabel)))throw Error(`Panel "${e.id}" declares railLabel "${e.railLabel}", which is not a leading part of its title "${e.title}": the rail button's accessible name is the title, and the words on screen must be inside it (WCAG 2.5.3, Label in Name).`);a.set(e.id,e)}function Nu(e){return a.get(e)}function Ib(e){let t=[...a.values()];return e?t.filter((n)=>n.dock===e):t}function Rb(e,t){return e.when?e.when(t):!0}var s=[{level:"project",label:"Project"},{level:"document",label:"Document"}];function c(){return Ib().filter((e)=>e.rail!==!1)}function q1(e){let t=c();return s.map(({level:n,label:o})=>({level:n,label:o,panels:t.filter((l)=>l.level===n&&Rb(l,e))})).filter((n)=>n.panels.length>0)}function yT(){let e=c();return s.flatMap(({level:t})=>e.filter((n)=>n.level===t))}
4
+ export{tm,gT,bT,vT,yd,qn,Nu,Ib,Rb,q1,yT};
5
5
 
6
- //# debugId=54344699E4A405A564756E2164756E21
7
- //# sourceMappingURL=studio-xry7tk3z.js.map
6
+ //# debugId=DD2CE04F09502EA564756E2164756E21
7
+ //# sourceMappingURL=studio-bmn4mn9j.js.map