@jxsuite/studio 10.3.0 → 10.4.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.
- package/dist/chunks/{add-new-flow-3tkn72ey.js → add-new-flow-v0pm96mr.js} +2 -2
- package/dist/chunks/content-source-g38w0d3f.js +4 -0
- package/dist/chunks/{convert-to-repeater-gwzh9gar.js → convert-to-repeater-r8sfxjjm.js} +2 -2
- package/dist/chunks/entry-commands-t13dyw3c.js +4 -0
- package/dist/chunks/{extension-sections-338ee35t.js → extension-sections-vjzw46xb.js} +2 -2
- package/dist/chunks/file-ops-1sghzgcr.js +4 -0
- package/dist/chunks/{files-t07yqqej.js → files-zrqtgt41.js} +2 -2
- package/dist/chunks/{format-host-5ja5gxyk.js → format-host-9gy76erh.js} +2 -2
- package/dist/chunks/fs-events-45rhg3me.js +4 -0
- package/dist/chunks/grid-open-t4fq6bbm.js +4 -0
- package/dist/chunks/{grid-view-w9nfy203.js → grid-view-2f03wcgw.js} +2 -2
- package/dist/chunks/{iframe-host-wsg0bn73.js → iframe-host-9aq8ze3q.js} +2 -2
- package/dist/chunks/{jx-validate-ttr5ewf0.js → jx-validate-r4ax11e3.js} +2 -2
- package/dist/chunks/layers-panel-zr92pwdp.js +4 -0
- package/dist/chunks/media-library-j74rt0w4.js +4 -0
- package/dist/chunks/{media-open-yp9jm834.js → media-open-mypr0k6b.js} +2 -2
- package/dist/chunks/{media-picker-s41ngdfr.js → media-picker-pemtbsjv.js} +2 -2
- package/dist/chunks/{monaco-setup-g9kterhx.js → monaco-setup-0hw9f835.js} +2 -2
- package/dist/chunks/publish-panel-vg1n880b.js +4 -0
- package/dist/chunks/{publish-quick-w3nxd7q4.js → publish-quick-4fwngwrw.js} +2 -2
- package/dist/chunks/publish-workspace-jv4w2bx2.js +4 -0
- package/dist/chunks/quick-search-nh29rt8a.js +4 -0
- package/dist/chunks/right-panel-3ws9f2w0.js +4 -0
- package/dist/chunks/{source-control-6fk72me2.js → source-control-h3hcs5gy.js} +2 -2
- package/dist/chunks/{studio-jeb7hth3.js → studio-1ctnw3xv.js} +2 -2
- package/dist/chunks/{studio-15hwqgd8.js → studio-1y9mab9m.js} +2 -2
- package/dist/chunks/{studio-s7t4vp1d.js → studio-2e4hry72.js} +3 -3
- package/dist/chunks/{studio-0w3541dg.js → studio-2kpxm0eh.js} +3 -3
- package/dist/chunks/{studio-3c10v2q1.js → studio-2pk7kc7z.js} +2 -2
- package/dist/chunks/{studio-nwynxqtb.js → studio-2x972v58.js} +2 -2
- package/dist/chunks/{studio-fspe7m9t.js → studio-2zz4qbv9.js} +2 -2
- package/dist/chunks/{studio-ggx3j7nd.js → studio-3pz4t5a2.js} +2 -2
- package/dist/chunks/{studio-waekn290.js → studio-4bgvvzhv.js} +2 -2
- package/dist/chunks/{studio-y1b86ast.js → studio-61rg2cz5.js} +2 -2
- package/dist/chunks/{studio-nskxe9q1.js → studio-9gr7xs9r.js} +2 -2
- package/dist/chunks/{studio-wse1rs8t.js → studio-a88ej93p.js} +3 -3
- package/dist/chunks/{studio-zfdbmhp3.js → studio-acer0g8w.js} +2 -2
- package/dist/chunks/{studio-423tfdte.js → studio-amaz545p.js} +2 -2
- package/dist/chunks/{studio-ea6r1zyr.js → studio-az3wvyh2.js} +2 -2
- package/dist/chunks/{studio-5n193zqd.js → studio-bg8pzprg.js} +2 -2
- package/dist/chunks/{studio-bct64zmj.js → studio-bnc50f9h.js} +2 -2
- package/dist/chunks/{studio-3xk9zdgb.js → studio-brh8d2pr.js} +2 -2
- package/dist/chunks/{studio-fkrr7kgg.js → studio-c2fa783p.js} +3 -3
- package/dist/chunks/{studio-yzpskb0j.js → studio-cqxj4fcy.js} +2 -2
- package/dist/chunks/{studio-b4e0ftkt.js → studio-cw11h078.js} +2 -2
- package/dist/chunks/{studio-f8tyeyzt.js → studio-dn56z7sn.js} +3 -3
- package/dist/chunks/{studio-nn4f9m9c.js → studio-evq47j2z.js} +2 -2
- package/dist/chunks/{studio-e7vjyp04.js → studio-frc16j8v.js} +3 -3
- package/dist/chunks/{studio-wfct4h6n.js → studio-gnazwtv3.js} +2 -2
- package/dist/chunks/{studio-thz5t120.js → studio-hfqpfmpk.js} +2 -2
- package/dist/chunks/{studio-fj6c905s.js → studio-j5fcp6gj.js} +2 -2
- package/dist/chunks/{studio-s9fng7m8.js → studio-jd1qb1st.js} +3 -3
- package/dist/chunks/{studio-p2a03pgm.js → studio-jma2q8r9.js} +2 -2
- package/dist/chunks/{studio-yrcrncev.js → studio-knsjyx7n.js} +2 -2
- package/dist/chunks/{studio-8kx6m0rg.js → studio-mrjtnm62.js} +2 -2
- package/dist/chunks/{studio-b68k0z00.js → studio-nwf0c32p.js} +2 -2
- package/dist/chunks/{studio-hfxttkyr.js → studio-pj216fmn.js} +2 -2
- package/dist/chunks/{studio-x0gsfr1d.js → studio-pwctzka3.js} +3 -3
- package/dist/chunks/{studio-aam8zt8z.js → studio-q9hx2qp0.js} +2 -2
- package/dist/chunks/{studio-wgc54sxf.js → studio-qrzmfaf6.js} +2 -2
- package/dist/chunks/{studio-3q7mhbgx.js → studio-r6mx7vm5.js} +2 -2
- package/dist/chunks/{studio-stahswgb.js → studio-rr00ex23.js} +2 -2
- package/dist/chunks/{studio-321ym1tt.js → studio-s24mhq0z.js} +2 -2
- package/dist/chunks/{studio-bz0b5brj.js → studio-tmfcn347.js} +2 -2
- package/dist/chunks/{studio-a65kbs2e.js → studio-v7a7yb5w.js} +2 -2
- package/dist/chunks/{studio-2ggfzrrd.js → studio-wmjmsw0p.js} +3 -3
- package/dist/chunks/studio-xva3hzkv.js +5 -0
- package/dist/chunks/{studio-nf8esxxc.js → studio-xx3r3sb0.js} +2 -2
- package/dist/chunks/{studio-9qx1ywbv.js → studio-z3fztxrp.js} +4 -4
- package/dist/chunks/{studio-r050sez0.js → studio-z9453ypn.js} +2 -2
- package/dist/chunks/{workspace-9btkc8tk.js → workspace-6ztqcrsh.js} +2 -2
- package/dist/chunks/workspace-home-rse9h8a0.js +4 -0
- package/dist/manifest.json +46 -46
- package/dist/studio.js +10 -10
- package/package.json +11 -11
- package/src/surfaces/inspector-dock.json +3 -3
- package/dist/chunks/content-source-1vzxq1ba.js +0 -4
- package/dist/chunks/entry-commands-mx2whrjx.js +0 -4
- package/dist/chunks/file-ops-9bxvk59j.js +0 -4
- package/dist/chunks/fs-events-3424ezp3.js +0 -4
- package/dist/chunks/grid-open-1mpq9mzb.js +0 -4
- package/dist/chunks/layers-panel-hvy2e549.js +0 -4
- package/dist/chunks/media-library-ae67q4at.js +0 -4
- package/dist/chunks/publish-panel-gzfxcm0t.js +0 -4
- package/dist/chunks/publish-workspace-dppd82tc.js +0 -4
- package/dist/chunks/quick-search-tdxaam55.js +0 -4
- package/dist/chunks/right-panel-0yrw4cgz.js +0 -4
- package/dist/chunks/studio-53wy9ek3.js +0 -5
- package/dist/chunks/workspace-home-qcc4z5ag.js +0 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{X}from"./studio-9c6cbq2c.js";import{p}from"./studio-4fnb5648.js";import{w}from"./studio-sce30r7b.js";import{ph,us,iI}from"./studio-4zd6an2b.js";import{Jt,Ut}from"./studio-nzemfbkk.js";import{sn,dt,Fn}from"./studio-tpxcryf2.js";import{m,h,eu}from"./studio-yrcrncev.js";import{Kd}from"./studio-hh394phe.js";import{Jc,Ta,J$,RO,Y$,Nx,Ys,Ax,NO,AO,Ox,Mx,ov,nr,Vd,Yc,hh,fl,Px}from"./studio-y1b86ast.js";import{oA,Qw,ex,Xu}from"./studio-ggx3j7nd.js";import{ET,Gu}from"./studio-waekn290.js";import{zt}from"./studio-daksw8kh.js";import{_L,SL,CL,kL,Zu,XS,QS,eC,tC}from"./studio-p2a03pgm.js";import{_p}from"./studio-r050sez0.js";import{Ve,Ln,vt,E,R}from"./studio-9dq7rwc7.js";import{Me}from"./studio-0gvvqj3h.js";import{g}from"./studio-3qr08sxq.js";import{n,_}from"./studio-k3we3kqb.js";import{ce}from"./studio-0939t1q1.js";var H=[{key:"all",label:"All media"},{key:"image",label:"Images"},{key:"video",label:"Video"},{key:"audio",label:"Audio"},{key:"document",label:"Documents"},{key:"font",label:"Fonts"},{key:"unused",label:"Unused"}],lS=H.map((e)=>e.key);function re(e){return lS.some((t)=>t===e)}function T(e){return H.find((t)=>t.key===e)?.label??"All media"}var U=[{key:"newest",label:"Newest"},{key:"name",label:"Name"},{key:"size",label:"Size"}],Re=U.map((e)=>e.key);function ne(e){return Re.some((t)=>t===e)}function W(e,t,i){switch(t){case"all":return!0;case"unused":return i!==null&&i.has(e.file);default:return e.kind===t}}function A(e,t){let i=t.trim().toLowerCase();return i===""||e.name.toLowerCase().includes(i)}function q(e,t){return e.filter((a)=>W(a,t.filter,t.unused)&&A(a,t.query)).toSorted((a,r)=>Ae(t.sort,a,r)||a.file.localeCompare(r.file))}function Ae(e,t,i){switch(e){case"name":return t.name.localeCompare(i.name,void 0,{numeric:!0,sensitivity:"base"});case"size":return(i.bytes??-1)-(t.bytes??-1);default:return(i.modified??"").localeCompare(t.modified??"")}}function oe(e,t){let i={all:e.length,audio:0,document:0,font:0,image:0,unused:t===null?null:e.filter((a)=>t.has(a.file)).length,video:0};for(let a of e)i[a.kind]=(i[a.kind]??0)+1;return i}var Ie=132,ae=12;function le(e){return Math.max(1,Math.floor((e+ae)/(Ie+ae)))}function se(e,t,i,a,r=!1){if(a===0)return null;let o=Math.min(Math.max(e,0),a-1),l=o-o%i,c;switch(t){case"ArrowRight":{c=o+1;break}case"ArrowLeft":{c=o-1;break}case"ArrowDown":{c=o+i;break}case"ArrowUp":{c=o-i;break}case"Home":{c=r?0:l;break}case"End":{c=r?a-1:Math.min(l+i-1,a-1);break}default:return null}return c<0||c>=a?o:c}var de={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMediaLibrary",$description:"The Media workspace's library (`specs/studio.md` §22.6): the project's media as filters, a grid and the selected file's detail. ONE document in two modes. In `manage` it is the Media home tab, with Replace, Open in viewer, Rename, Duplicate and Delete under the detail; in `pick` it is the full-size picker inside a `jx-dialog` (`media-pick-dialog.json`), and the dialog's own footer answers Cancel or Use <file>. `media/media-library.ts` keeps every decision (which files a filter keeps, the sort, what a count may claim, where an arrow lands, what Replace writes) and hands this document strings and discriminants. **Unused is drawn with no number until the usage sweep has settled**, and Missing alt text and tags are not drawn at all: each needs a store that does not exist, and a filter that cannot be answered is not shipped as one that always answers nothing.",tagName:"div",attributes:{part:"media-library","data-jx-region":"${state.region}","data-mode":"${state.mode}","data-drop":"${state.dropActive}"},style:{$description:"Three columns over the whole stage: the filters, the grid with its toolbar, and the selected file's detail. Fills the pane's stage by its own geometry, as the workspace home does: the stage is `position: relative` (`pane-grid.json`). In pick mode the same columns fill the dialog's body instead, so the root's box is the only thing that differs between the two modes.",position:"absolute",inset:"0",display:"grid",gridTemplateColumns:"200px minmax(0, 1fr) 300px",boxSizing:"border-box",fontFamily:"var(--jx-font-sans)",fontSize:"var(--jx-text-md)",color:"var(--fg)",background:"var(--bg)",'&[data-mode="pick"]':{$description:"Inside a dialog there is no stage to fill: the box is the dialog body's, at a height the dialog can scroll within.",position:"relative",inset:"auto",height:"min(70vh, 620px)",gridTemplateColumns:"150px minmax(0, 1fr) 210px"},'&[data-drop="true"]':{$description:"The drop affordance is a STATE the flow holds, not a class a handler adds and forgets to take off.",outline:"2px dashed var(--accent)",outlineOffset:"-4px"},'& [part="filters"]':{display:"flex",flexDirection:"column",gap:"2px",padding:"var(--jx-space-3) var(--jx-space-2)",borderRight:"1px solid var(--border)",background:"var(--bg-panel)",overflowY:"auto"},'& [part="filters-heading"]':{margin:"0",padding:"var(--jx-space-2) var(--jx-space-2) var(--jx-space-1)",fontSize:"var(--jx-text-xs)",fontWeight:"600",letterSpacing:"0.06em",textTransform:"uppercase",color:"var(--fg-dim)"},'& [part="filter"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-2)",height:"30px",padding:"0 var(--jx-space-2)",border:"none",borderRadius:"var(--radius)",background:"none",color:"var(--fg)",font:"inherit",textAlign:"left",cursor:"pointer"},'& [part="filter"]:hover':{background:"var(--hover-bg)"},'& [part="filter"][aria-pressed="true"]':{background:"color-mix(in srgb, var(--accent) 16%, transparent)",color:"var(--fg)",fontWeight:"600"},'& [part="filter"]:focus-visible':{outline:"var(--jx-focus-ring)",outlineOffset:"-2px"},'& [part="filter-count"]':{marginLeft:"auto",fontSize:"var(--jx-text-xs)",color:"var(--fg-dim)",fontWeight:"400"},'& [part="main"]':{display:"flex",flexDirection:"column",minWidth:"0",minHeight:"0"},'& [part="toolbar"]':{display:"flex",alignItems:"center",flexWrap:"wrap",gap:"var(--jx-space-3)",padding:"var(--jx-space-3) var(--jx-space-4)",borderBottom:"1px solid var(--border)"},'& [part="title"]':{margin:"0 auto 0 0",fontSize:"var(--jx-text-lg)",fontWeight:"600"},'& [part="search"]':{width:"220px"},'& [part="sort"]':{width:"130px"},'& [part="upload"], & [part="empty-upload"]':{$description:"A LABEL around the file picker, not a button that clicks a hidden one: the picker is the control, so it takes focus, Enter opens it and a screen reader announces a file upload. A plain element because a label forwards a click to the input it contains and a custom element between the two would break that.",position:"relative",display:"inline-flex",alignItems:"center",gap:"6px",height:"28px",padding:"0 var(--jx-space-3)",border:"1px solid var(--border)",borderRadius:"var(--radius)",background:"var(--bg-panel)",color:"var(--fg)",font:"inherit",cursor:"pointer",":hover":{background:"var(--hover-bg)"},":has(:focus-visible)":{outline:"var(--jx-focus-ring)",outlineOffset:"2px"}},'& [part="upload-input"], & [part="replace-input"]':{$description:"Out of the way but still FOCUSABLE: `display: none` would take the control out of the tab order, and the label around it draws the focus ring for it.",position:"absolute",width:"1px",height:"1px",opacity:"0",pointerEvents:"none"},'& [part="upload-glyph"]':{"--jx-icon-size":"16px"},'& [part="body"]':{flex:"1",minHeight:"0",overflowY:"auto",padding:"var(--jx-space-4)"},'& [part="grid"]':{$description:"auto-fill over a minimum tile width; `media/media-library-model.ts` `gridColumns` does the same arithmetic, so ArrowDown lands on the tile drawn under the current one. Keep the two numbers in step.",display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(132px, 1fr))",gap:"12px",alignContent:"start"},'& [part="tile"]':{display:"flex",flexDirection:"column",gap:"4px",padding:"4px",borderRadius:"var(--jx-radius-md, 6px)",border:"2px solid transparent",cursor:"pointer",minWidth:"0",outline:"none"},'& [part="tile"]:hover':{background:"var(--hover-bg)"},'& [part="tile"][aria-selected="true"]':{borderColor:"var(--accent)"},'& [part="tile"]:focus-visible':{outline:"var(--jx-focus-ring)",outlineOffset:"2px"},'& [part="thumb"]':{display:"flex",alignItems:"center",justifyContent:"center",aspectRatio:"4 / 3",borderRadius:"var(--radius)",background:"var(--bg-input)",overflow:"hidden",color:"var(--fg-dim)","--jx-icon-size":"28px"},'& [part="thumb-img"]':{width:"100%",height:"100%",objectFit:"cover"},'& [part="tile-name"]':{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:"var(--jx-text-sm)"},'& [part="tile-caption"]':{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:"var(--jx-text-xs)",color:"var(--fg-dim)",minHeight:"1em"},'& [part="empty"]':{display:"flex",flexDirection:"column",alignItems:"center",gap:"var(--jx-space-3)",padding:"48px var(--jx-space-6)",textAlign:"center",color:"var(--fg-dim)","--jx-icon-size":"40px"},'& [part="empty-title"]':{margin:"0",fontSize:"var(--jx-text-lg)",fontWeight:"600",color:"var(--fg)"},'& [part="empty-detail"]':{margin:"0",maxWidth:"42ch",lineHeight:"1.5"},'& [part="detail"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-3)",padding:"var(--jx-space-4)",borderLeft:"1px solid var(--border)",background:"var(--bg-panel)",overflowY:"auto",minWidth:"0"},'& [part="detail-hint"]':{margin:"auto 0",textAlign:"center",color:"var(--fg-dim)"},'& [part="detail-preview"]':{display:"flex",alignItems:"center",justifyContent:"center",minHeight:"140px",maxHeight:"220px",borderRadius:"var(--radius)",background:"var(--bg-input)",overflow:"hidden",color:"var(--fg-dim)","--jx-icon-size":"40px"},'& [part="preview-img"], & [part="preview-video"]':{maxWidth:"100%",maxHeight:"220px",objectFit:"contain"},'& [part="preview-audio"]':{width:"100%"},'& [part="preview-specimen"]':{$description:"The viewer's specimen at a side pane's size. The face arrives as the `@font-face` the flow writes under a family name generated from the path (`media/media-pane.ts` `specimenOf`); the element carries only that name, as a custom property, and the fallback stack is a rule, here.",display:"flex",flexDirection:"column",gap:"var(--jx-space-2)",padding:"var(--jx-space-4)",maxWidth:"100%",color:"var(--fg)",fontFamily:"var(--jx-specimen-family, system-ui), system-ui, sans-serif"},'& [part="specimen-line"]':{margin:"0",lineHeight:"1.3",overflowWrap:"anywhere"},'& [part="specimen-line"][data-size="32"]':{fontSize:"32px"},'& [part="specimen-line"][data-size="14"]':{fontSize:"var(--jx-text-md)"},'& [part="detail-name"]':{margin:"0",fontSize:"var(--jx-text-md)",fontWeight:"600",overflowWrap:"anywhere"},'& [part="facts"]':{margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"},'& [part="group-title"]':{margin:"0",fontSize:"var(--jx-text-xs)",fontWeight:"600",color:"var(--fg-dim)"},'& [part="url"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-2)",minWidth:"0"},'& [part="url-value"]':{flex:"1",minWidth:"0",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontFamily:"var(--jx-font-mono)",fontSize:"var(--jx-text-sm)"},'& [part="usage"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-1)"},'& [part="usage-headline"]':{margin:"0",fontSize:"var(--jx-text-sm)"},'& [part="usage-list"]':{margin:"0",padding:"0",listStyle:"none",display:"flex",flexDirection:"column",gap:"2px"},'& [part="usage-row"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-2)"},'& [part="usage-link"]':{flex:"1",minWidth:"0",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",border:"none",background:"none",padding:"0",color:"var(--accent)",font:"inherit",fontSize:"var(--jx-text-sm)",textAlign:"left",cursor:"pointer",":hover":{textDecoration:"underline"},":focus-visible":{outline:"var(--jx-focus-ring)"}},'& [part="usage-count"]':{fontSize:"var(--jx-text-xs)",color:"var(--fg-dim)"},'& [part="actions"]':{display:"flex",flexWrap:"wrap",gap:"var(--jx-space-2)",marginTop:"var(--jx-space-2)"},'& [part="replace"]':{position:"relative",display:"inline-flex",alignItems:"center",height:"28px",padding:"0 var(--jx-space-3)",border:"1px solid var(--border)",borderRadius:"var(--radius)",background:"var(--bg)",color:"var(--fg)",font:"inherit",cursor:"pointer",":hover":{background:"var(--hover-bg)"},":has(:focus-visible)":{outline:"var(--jx-focus-ring)",outlineOffset:"2px"}}},ondragover:{$prototype:"Function",body:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/dragOver"},value:[]}],description:"A file dropped ANYWHERE on the library uploads, to the destination the Upload label names before the drop: public/media/."},ondragleave:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/dragOut"},value:[]}]},ondrop:{$prototype:"Function",body:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/drop"},value:[{$ref:"event#/dataTransfer/files"}]}]},children:[{tagName:"nav",attributes:{part:"filters","aria-label":"Media filters"},children:[{tagName:"h2",attributes:{part:"filters-heading"},textContent:"Library"},{$prototype:"Array",items:{$ref:"#/state/filters"},key:{$ref:"$map/item/key"},map:{tagName:"button",attributes:{part:"filter",type:"button","aria-pressed":"${$map.item.pressed}","data-filter":"${$map.item.key}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setFilter"},value:[{$ref:"$map/item/key"}]}]},children:[{tagName:"span",attributes:{part:"filter-label"},textContent:"${$map.item.label}"},{tagName:"span",attributes:{part:"filter-count"},textContent:"${$map.item.count}"}]}}]},{tagName:"section",attributes:{part:"main","aria-labelledby":"${state.titleId}"},children:[{tagName:"header",attributes:{part:"toolbar"},children:[{tagName:"h2",attributes:{part:"title",id:"${state.titleId}"},textContent:"${state.title}"},{tagName:"jx-textfield",attributes:{part:"search"},$props:{type:"search",size:"sm",label:"Search media",placeholder:"Search by name…",autocomplete:"off",value:{$ref:"#/state/query"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setQuery"},value:[{$ref:"event#/target/value"}]}]}},{tagName:"jx-select",attributes:{part:"sort"},$props:{label:"Sort",size:"sm",options:{$ref:"#/state/sortOptions"},value:{$ref:"#/state/sort"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setSort"},value:[{$ref:"event#/target/value"}]}]}},{tagName:"label",attributes:{part:"upload",title:"${state.uploadHint}"},children:[{tagName:"input",attributes:{part:"upload-input",type:"file",multiple:!0,accept:"${state.uploadAccept}"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/upload"},value:[{$ref:"event#/target"}]}],description:"The picker itself, so the destination in the label's tooltip is visible BEFORE the files are chosen. The flow takes the element rather than the file list because a file input that is not cleared refuses the same file twice."}},{tagName:"jx-icon",attributes:{part:"upload-glyph","aria-hidden":"true"},$props:{name:"upload-simple"}},{tagName:"span",textContent:"Upload"}]}]},{tagName:"div",attributes:{part:"body"},children:[{tagName:"div",attributes:{part:"grid-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/gridState"},cases:{loading:{tagName:"p",attributes:{part:"empty",role:"status"},textContent:"Reading the project's media…"},counting:{tagName:"p",attributes:{part:"empty",role:"status"},textContent:"${state.countingLabel}"},empty:{tagName:"div",attributes:{part:"empty"},children:[{tagName:"jx-icon",attributes:{part:"empty-glyph","aria-hidden":"true"},$props:{name:"image"}},{tagName:"p",attributes:{part:"empty-title"},textContent:"${state.emptyTitle}"},{tagName:"p",attributes:{part:"empty-detail"},textContent:"${state.emptyDetail}"},{tagName:"label",attributes:{part:"empty-upload",title:"${state.uploadHint}"},children:[{tagName:"input",attributes:{part:"upload-input",type:"file",multiple:!0,accept:"${state.uploadAccept}"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/upload"},value:[{$ref:"event#/target"}]}],description:"The picker itself, so the destination in the label's tooltip is visible BEFORE the files are chosen. The flow takes the element rather than the file list because a file input that is not cleared refuses the same file twice."}},{tagName:"jx-icon",attributes:{part:"upload-glyph","aria-hidden":"true"},$props:{name:"upload-simple"}},{tagName:"span",textContent:"Upload"}]}]},nomatch:{tagName:"div",attributes:{part:"empty"},children:[{tagName:"jx-icon",attributes:{part:"empty-glyph","aria-hidden":"true"},$props:{name:"image"}},{tagName:"p",attributes:{part:"empty-title"},textContent:"${state.emptyTitle}"},{tagName:"p",attributes:{part:"empty-detail"},textContent:"${state.emptyDetail}"},{tagName:"jx-button",attributes:{part:"reset"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/reset"},value:[]}]},children:[{tagName:"span",textContent:"Show all media"}]}]},listed:{tagName:"div",attributes:{part:"grid",role:"listbox","aria-labelledby":"${state.titleId}"},onkeydown:{$prototype:"Function",body:[{$switch:{$ref:"event#/key"},cases:{ArrowRight:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],ArrowLeft:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],ArrowDown:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],ArrowUp:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],Home:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],End:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],Enter:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/activateSelected"},value:[]}]}}],description:"The grid pattern: arrows move one tile, Home and End to the ends of the row, Ctrl+Home and Ctrl+End to the ends of the grid, and Enter opens the selected file (in pick mode, uses it). The flow computes where the move lands; the tile that receives it takes focus, so the roving tabindex follows the selection."},children:[{$prototype:"Array",items:{$ref:"#/state/tiles"},key:{$ref:"$map/item/key"},map:{tagName:"div",attributes:{part:"tile",role:"option","aria-selected":"${$map.item.selected}",tabindex:"${$map.item.tabindex}","data-file":"${$map.item.file}",title:"${$map.item.name}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/select"},value:[{$ref:"$map/item/file"}]}]},onfocus:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/focusTile"},value:[{$ref:"$map/item/file"}]}],description:"Selection follows focus, the listbox pattern: a Tab onto the grid lands on the roving stop and selects it, so the first Enter opens (in pick mode, uses) the tile the focus ring is on rather than nothing."},ondblclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/activate"},value:[{$ref:"$map/item/file"}]}]},oncontextmenu:{$prototype:"Function",body:[{$switch:{$ref:"#/state/mode"},cases:{manage:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/contextMenu"},value:[{$ref:"$map/item/file"},{$ref:"event#/clientX"},{$ref:"event#/clientY"}]}]}}],description:"Manage mode only: the detail pane's actions at the pointer. Pick mode's dialog is modal, and a menu in the popover layer outside it would be inert, so its right-click is left to the platform."},children:[{tagName:"div",attributes:{part:"thumb"},children:[{tagName:"div",attributes:{part:"thumb-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/thumbState"},cases:{image:{tagName:"img",attributes:{part:"thumb-img",src:"${$map.item.thumbSrc}",alt:"",draggable:"false"},onload:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/measure"},value:[{$ref:"$map/item/file"},{$ref:"event#/target/naturalWidth"},{$ref:"event#/target/naturalHeight"}]}]}},pending:{tagName:"span",attributes:{part:"thumb-pending","aria-hidden":"true"}},glyph:{tagName:"jx-icon",attributes:{part:"thumb-glyph","aria-hidden":"true"},$props:{name:{$ref:"$map/item/glyph"}}}},$description:"The thumbnail is asked for when the tile scrolls into view, not when the grid is built: `pending` until the flow's observer reports the tile, then the picture. A file the browser draws no picture of shows its kind's glyph."}]},{tagName:"span",attributes:{part:"tile-name"},textContent:"${$map.item.name}"},{tagName:"span",attributes:{part:"tile-caption"},textContent:"${$map.item.caption}"}]}}]}}}]}]},{tagName:"aside",attributes:{part:"detail","aria-label":"Details"},children:[{tagName:"div",attributes:{part:"detail-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/detailState"},cases:{none:{tagName:"p",attributes:{part:"detail-hint"},textContent:"${state.detailHint}"},shown:{tagName:"div",attributes:{part:"detail-body",role:"none"},style:{display:"contents"},children:[{tagName:"div",attributes:{part:"detail-preview"},children:[{tagName:"div",attributes:{part:"preview-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/previewKind"},cases:{image:{tagName:"img",attributes:{part:"preview-img",src:"${state.previewSrc}",alt:""},onload:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/measure"},value:[{$ref:"#/state/selectedFile"},{$ref:"event#/target/naturalWidth"},{$ref:"event#/target/naturalHeight"}]}]}},video:{tagName:"video",attributes:{part:"preview-video",src:"${state.previewSrc}",controls:!0}},audio:{tagName:"audio",attributes:{part:"preview-audio",src:"${state.previewSrc}",controls:!0}},font:{tagName:"div",attributes:{part:"preview-specimen",style:"${state.previewSpecimenFamily}"},children:[{tagName:"style",textContent:"${state.previewFontFace}"},{tagName:"p",attributes:{part:"specimen-line","data-size":"32"},textContent:"Aa"},{tagName:"p",attributes:{part:"specimen-line","data-size":"14"},textContent:"${state.previewSpecimen}"}]},glyph:{tagName:"jx-icon",attributes:{part:"preview-glyph","aria-hidden":"true"},$props:{name:{$ref:"#/state/previewGlyph"}}}}}]},{tagName:"h3",attributes:{part:"detail-name"},textContent:"${state.detailName}"},{tagName:"p",attributes:{part:"facts"},textContent:"${state.detailFacts}"},{tagName:"div",attributes:{part:"url-group"},children:[{tagName:"h4",attributes:{part:"group-title"},textContent:"Site URL"},{tagName:"div",attributes:{part:"url"},children:[{tagName:"code",attributes:{part:"url-value"},textContent:"${state.detailRef}"},{tagName:"jx-action-button",attributes:{part:"copy"},$props:{size:"sm",quiet:!0,hint:"Copy the site URL"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/copyRef"},value:[]}]},children:[{tagName:"span",textContent:"Copy"}]}]}]},{tagName:"div",attributes:{part:"usage-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/usageState"},cases:{shown:{tagName:"div",attributes:{part:"usage"},children:[{tagName:"h4",attributes:{part:"group-title"},textContent:"Used on"},{tagName:"p",attributes:{part:"usage-headline"},textContent:"${state.usageHeadline}"},{tagName:"div",attributes:{part:"usage-list-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasUsageFiles"},cases:{true:{tagName:"ul",attributes:{part:"usage-list"},children:[{$prototype:"Array",items:{$ref:"#/state/usageFiles"},key:{$ref:"$map/item/path"},map:{tagName:"li",attributes:{part:"usage-row","data-usage":"${$map.item.path}"},children:[{tagName:"button",attributes:{part:"usage-link",type:"button",title:"Open ${$map.item.path}"},textContent:"${$map.item.path}",onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openDocument"},value:[{$ref:"$map/item/path"}]}]}},{tagName:"span",attributes:{part:"usage-count"},textContent:"${$map.item.count}"}]}}]}}}]}},$description:'Hidden on a host with no reference index, which is a different fact from "nothing uses it": a confident zero is the one answer this pane must never invent.'},{tagName:"div",attributes:{part:"actions-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/mode"},cases:{manage:{tagName:"div",attributes:{part:"actions"},children:[{tagName:"label",attributes:{part:"replace",title:"Replace ${state.detailName} everywhere it is used"},children:[{tagName:"input",attributes:{part:"replace-input",type:"file",accept:"${state.replaceAccept}"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/replace"},value:[{$ref:"event#/target"}]}],description:"Replace writes the chosen file over this one's path, so every reference keeps resolving and now shows the new bytes (studio.md §9.3). The element rather than the list, so the input can be cleared."}},{tagName:"span",textContent:"Replace"}]},{tagName:"jx-button",attributes:{part:"open-viewer"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openViewer"},value:[]}]},children:[{tagName:"span",textContent:"Open in viewer"}]},{tagName:"div",attributes:{part:"edit-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/editable"},cases:{yes:{tagName:"jx-button",attributes:{part:"edit-image"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editImage"},value:[]}],description:"Withheld, not disabled, for a file the editor cannot write: a refused format is not offered rather than offered and then refused (studio.md §9.5)."},children:[{tagName:"span",textContent:"Edit image"}]},no:{tagName:"span",attributes:{hidden:!0}}}},{tagName:"jx-button",attributes:{part:"rename"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/rename"},value:[]}]},children:[{tagName:"span",textContent:"Rename"}]},{tagName:"div",attributes:{part:"duplicate-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/duplicable"},cases:{yes:{tagName:"jx-button",attributes:{part:"duplicate"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/duplicate"},value:[]}],description:"Withheld, not disabled, on a backend that cannot read a file's raw bytes: a copy read as text would be a broken file (studio.md §9.3)."},children:[{tagName:"span",textContent:"Duplicate"}]},no:{tagName:"span",attributes:{hidden:!0}}}},{tagName:"jx-button",attributes:{part:"delete"},$props:{size:"sm",variant:"negative"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/remove"},value:[]}]},children:[{tagName:"span",textContent:"Delete"}]}]}},$description:"Manage mode's actions. Pick mode has none here: its answer is the dialog's own footer, Cancel and Use <file>."}]}}}]}]};E("media-library",de);function Oe(){return{countingLabel:"",detailFacts:"",detailHint:"",detailName:"",detailRef:"",detailState:"none",dropActive:"false",emptyDetail:"",emptyTitle:"",filters:[],gridState:"loading",mode:"manage",previewFontFace:"",previewGlyph:"",previewKind:"glyph",previewSpecimen:"",previewSpecimenFamily:"",previewSrc:"",query:"",region:"",replaceAccept:"",editable:"no",duplicable:"no",selectedFile:"",sort:"",sortOptions:[],tiles:[],title:"",titleId:"",uploadAccept:"",uploadHint:"",usageFiles:[],usageHeadline:"",usageState:"hidden"}}function pe(e,t){Object.assign(e,t),e.hasUsageFiles=t.usageFiles.length>0}function Ke(e){let t=n(e)?void 0:e.attributes?.part;return n(t)?t:""}function ze(e){let t=e?.$map,i=_(t)&&"item"in t?t.item:void 0;return _(i)&&"file"in i&&n(i.file)?i.file:null}function V(e,t,i,a){if(a.clear)e.replaceChildren();let{tileHost:r,gridHost:o,inputHost:l,...c}=i,d=g({...Oe(),...c,hasUsageFiles:!1});pe(d,t);let f=null,b=!1,M=R("media-library",d,e,{onNodeCreated:(u,s,F,Ee)=>{if(b||!(u instanceof HTMLElement))return;let C=Ke(F);if(C==="tile"){let ie=ze(Ee);if(ie!==null)r(u,ie)}else if(C==="grid")o(u);else if(u instanceof HTMLInputElement&&C==="upload-input")l(u,"upload");else if(u instanceof HTMLInputElement&&C==="replace-input")l(u,"replace")}}).then((u)=>{if(b)u.dispose();else f=u;return u.root});return{attached:()=>{if(b)return!1;let u=f?.root;return u===void 0?!0:u instanceof HTMLElement&&e.contains(u)},dispose(){b=!0,f?.dispose(),f=null},ready:M,update:(u)=>pe(d,u)}}var ue={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMediaPickDialog",$description:"The full-size media picker (`specs/studio.md` §9.3): a `jx-dialog` whose body is the Media workspace's own library surface in pick mode, so the picker and the workspace are one surface at two sizes. The dialog owns modality, Escape, the backdrop and focus restoration, and its footer is the answer: Cancel, or Use <file>, disabled until a file is chosen. The body is an ISLAND: this document draws the slot and nothing in it, and `surfaces/media-pick-dialog.ts` mounts `media-library.json` there through `onNodeCreated`.",tagName:"jx-dialog",$props:{headline:{$ref:"#/state/headline"},confirmLabel:{$ref:"#/state/confirmLabel"},confirmDisabled:{$ref:"#/state/blocked"},cancelLabel:"Cancel",dismissible:!0,size:"xl"},attributes:{part:"media-pick"},onconfirm:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/confirm"},value:[]}]},oncancel:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},onclose:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},children:[{tagName:"div",attributes:{part:"library-slot"},style:{$description:"The library's box in pick mode is its own (`media-library.json`, `data-mode=\"pick\"`); the slot only gives it the dialog body's width.",minWidth:"0"}}]};E("media-pick-dialog",ue);var B="media-picker";function Ue(e){let t=n(e)?void 0:e.attributes?.part;return n(t)?t:""}function fe(e){let t=document.createElement("div");t.style.pointerEvents="auto",t.setAttribute(Ve,vt("dialog",B)),e.layer.append(t);let i=!1,a=()=>{if(i)return;i=!0,e.closed()},r=()=>i,o=g({...e.view,closed:a,confirm:e.confirm}),l=null,c=R("media-pick-dialog",o,t,{onNodeCreated:(d,f,b)=>{if(!r()&&d instanceof HTMLElement&&Ue(b)==="library-slot")e.body(d)}}).then(async(d)=>{l=d;let f=d.root;if(r())return d.dispose(),f;if(await sn(f),!r())Jt(f);return f});return{close(){let d=l?.root;if(d instanceof HTMLElement)Ut(d);l?.dispose(),l=null,t.remove(),a()},host:t,ready:c,update(d){Object.assign(o,d)}}}var uF="media-home",ve={audio:"play",document:"file-text",font:"text-aa",image:"image",video:"play"},We={audio:"Audio",document:"Document",font:"Font",image:"Image",video:"Video"},y={filter:"all",query:"",sort:"newest",selected:null},D=null,S=null,O=0,K=0,P=!1,Y=0;function J(){S=null,P=!1,O=0,K=0,Y+=1}function qe(){return[...L].some((e)=>!e.disposed&&e.choice.filter==="unused")}async function Be(e){if(P||S!==null||!ph())return;let t=Y;P=!0,O=0,K=e.length;let i=new Set;for(let a of e){let r=await Xu(a.file);if(t!==Y)return;if(!qe()){J();return}if(r.status==="ready"&&r.result.files.length===0)i.add(a.file);O+=1,x()}S=i,P=!1,x()}var L=new Set,k=new Map,Q=new Set,j=null;function we(){if(j!==null)return;let e=()=>{J(),x()},t=ET(e),i=iI(e);j=()=>{t(),i()}}function Ge(){if(L.size===0&&j)j(),j=null}function v(e){if(!e.disposed){if(e.handle?.update(ee(e)),e.onSelect?.(),Ye(e),e.focusOwed)queueMicrotask(()=>He(e));xe(e)}}function Ye(e){let t=e.reveal,i=t===null?void 0:e.tiles.get(t);if(i?.isConnected){if(e.reveal=null,i.scrollIntoView({block:"nearest"}),e.revealFocus)e.revealFocus=!1,i.focus()}}function xe(e){if(e.sweepTimer!==null||e.disposed)return;e.sweepTimer=setTimeout(()=>{e.sweepTimer=null,e.observer.releaseDetached();for(let[t,i]of e.tiles)if(!i.isConnected)e.tiles.delete(t);for(let t of[e.inputs.upload,e.inputs.replace])for(let i of t)if(!i.isConnected)t.delete(i)},0)}function $e(e){return[...e].find((t)=>t.isConnected)??null}function x(){for(let e of L)v(e)}function Z(e){if(e.disposed=!0,e.sweepTimer!==null)clearTimeout(e.sweepTimer),e.sweepTimer=null;e.inputs.upload.clear(),e.inputs.replace.clear(),e.observer.destroy(),e.handle?.dispose(),e.handle=null,e.tiles.clear(),L.delete(e),Ge()}function ke(e){let t=Gu(),i=t===null?null:e.images?t.filter((r)=>r.isImage):t;return{files:(i??[]).map((r)=>{let o=Yc(r.file);return{bytes:o?.bytes??null,file:r.file,kind:r.kind,modified:o?.modified??null,name:r.name}}),listed:i}}function Je(e){return H.filter((t)=>(t.key!=="unused"||ph())&&(!e.images||t.key==="image"||t.key==="unused"))}function wb(e){let{filter:t,query:i,selected:a}=e.choice;if(a===null)return null;let r=Gu()?.find((l)=>l.file===a)??null;if(r===null||e.images&&!r.isImage)return null;let o={bytes:null,file:r.file,kind:r.kind,modified:null,name:r.name};return W(o,t,S)&&A(o,i)?r:null}function Qe(e,t){if(t===0)return{emptyDetail:`Upload files or drop them anywhere here. They are saved under ${e.uploadDir}/, and anything already under public/ or a collection's images/ folder is listed here too.`,emptyTitle:e.images?"No images yet":"No media yet"};let{filter:i,query:a}=e.choice;if(a.trim()!=="")return{emptyDetail:`Nothing in ${T(i)} matches it.`,emptyTitle:`No matches for “${a.trim()}”`};if(i==="unused")return{emptyDetail:"Every file is referenced by at least one document.",emptyTitle:"No unused media"};return{emptyDetail:`${t} ${t===1?"file":"files"} in the project, none of them ${T(i).toLowerCase()}.`,emptyTitle:`No ${T(i).toLowerCase()}`}}function ee(e){let{choice:t}=e,{files:i,listed:a}=ke(e),r=oe(i,S),o=Je(e);if(!o.some((s)=>s.key===t.filter))t.filter=o[0]?.key??"all";let l=q(i,{filter:t.filter,query:t.query,sort:t.sort,unused:S}),c=Gu();if(t.filter==="unused"&&c!==null)Be(c);let d="listed";if(a===null)d="loading";else if(t.filter==="unused"&&S===null)d="counting";else if(i.length===0||l.length===0)d=i.length===0?"empty":"nomatch";let f=wb(e),b=l.some((s)=>s.file===t.selected)?t.selected:l[0]?.file??null,M=l.map((s)=>{let F=s.kind==="image";return{caption:Px(Yc(s.file))||We[s.kind],file:s.file,glyph:ve[s.kind],key:s.file,name:s.name,selected:s.file===t.selected?"true":"false",tabindex:s.file===b?"0":"-1",thumbSrc:F&&e.visible.has(s.file)?nr(s.file):"",thumbState:F?e.visible.has(s.file)?"image":"pending":"glyph"}}),u=e.images&&t.filter==="image"?"Images":T(t.filter);return{countingLabel:K>0?`Counting references… ${O} of ${K}`:"Counting references…",dropActive:e.dropActive?"true":"false",filters:o.map((s)=>{let F=r[s.key];return{count:F===null?"":String(F),key:s.key,label:e.images&&s.key==="image"?"All images":s.label,pressed:s.key===t.filter?"true":"false"}}),gridState:d,mode:e.mode,query:t.query,region:e.region,sort:t.sort,sortOptions:U.map((s)=>({label:s.label,value:s.key})),tiles:M,title:u,titleId:`media-library-title-${e.region.replaceAll(/[^\w-]/g,"-")}`,uploadAccept:e.images?"image/*":Jc(),uploadHint:`Upload into ${e.uploadDir}/`,...Qe(e,i.length),...Xe(e,f)}}function Xe(e,t){if(t===null)return{detailFacts:"",detailHint:e.mode==="pick"?"Choose a file to use it.":"Select a file to see its details.",detailName:"",detailRef:"",detailState:"none",previewFontFace:"",previewGlyph:"",previewKind:"glyph",previewSpecimen:"",previewSpecimenFamily:"",previewSrc:"",replaceAccept:"",editable:"no",duplicable:"no",selectedFile:"",usageFiles:[],usageHeadline:"",usageState:"hidden"};let i=Yc(t.file),a=ex(t.file);if(!Vd(t.file))hh(t.file).then(x);if(a===null||a.status==="pending")Xu(t.file).then(x);let r=_L(t.file),o=r==="image"||r==="video"||r==="audio"||r==="font"?r:"glyph",l=o==="font"?CL(t.file):{fontFace:"",specimen:"",specimenFamily:""};return{detailFacts:SL(t.file,i),detailHint:"",detailName:t.name,detailRef:t.ref,detailState:"shown",previewFontFace:l.fontFace,previewGlyph:ve[t.kind],previewKind:o,previewSpecimen:l.specimen,previewSpecimenFamily:l.specimenFamily,previewSrc:o==="glyph"?"":nr(t.file),replaceAccept:NO(t.file),editable:XS(t.file)?"yes":"no",duplicable:QS()?"yes":"no",selectedFile:t.file,...kL(a)}}var me=null,ge=null;function Se(){return me??=(ce("t07yqqej"),import("./files-t07yqqej.js")),me}function Fe(){return ge??=(ce("9bxvk59j"),import("./file-ops-9bxvk59j.js")),ge}function te(e){try{e.showPicker()}catch{e.focus()}}function N(e,t){e.choice.selected=t,v(e)}async function he(e,t){let i=await Ys([...t],{dir:e.uploadDir,only:e.images?"image":"media"}),[a]=i;if(!a)return;if(e.choice.filter!=="all"&&e.choice.filter!==a.kind)e.choice.filter=e.images?"image":"all";e.choice.query="",e.reveal=a.path,N(e,a.path)}async function eN(e){let t=e.split("/").pop()??e,{confirmFileDelete:i}=await Fe();if(!await i({name:t,path:e}))return!1;let{markLocalMutation:a}=await (ce("3424ezp3"),import("./fs-events-3424ezp3.js"));try{a(e),await p().deleteFile(e)}catch(l){return w.error(`Could not delete ${t}.`,{detail:X(l),path:e,source:"Media"}),!1}if(Kd([e]),us(),m.tabs.has(e))eu(e);for(let l of L)if(l.choice.selected===e)l.choice.selected=null;if(y.selected===e)y.selected=null;let r=ov(e),o=await Ze(r,a);return await Nx(o?ov(r):r),w.success(`Deleted ${t}`),!0}async function Ze(e,t){if(!RO(e))return!1;let i=p();try{if((await i.listDirectory(e)).length>0)return!1;return t(e),await i.deleteFile(e),!0}catch{return!1}}async function tN(e){if(eC(e,"renamed"))return null;let t=Mx(e),i=ov(e),{commitRename:a,listRenameSiblings:r,notifyMoveOutcome:o,renameStatus:l}=await Se(),c=await r(e,"Media");if(c===null)return null;let{renamePromptMessage:d}=await Fe(),f=await d(e),b=await Fn("Rename",{confirmLabel:"Rename",select:"stem",validate:(s)=>AO(e,s,c),value:t,...f!==void 0&&{message:f}});if(!b||b===t)return null;let M=Y$(i,b),u=Yc(e);try{let s=await a(e,M);if(y.selected===e)Le(M);if(await Nx(i),u?.width!=null&&u.height!=null)fl(M,u.width,u.height);return o(l(b,s),s,M),M}catch(s){return w.error(`Could not rename ${t}.`,{detail:X(s),path:e,source:"Media"}),null}}async function nN(e){if(eC(e,"duplicated"))return null;let t=await Ax(e);if(t===null)return null;return Le(t.path),x(),t.path}function Le(e){if(y.selected=e,!A({name:Mx(e)},y.query))y.query="";for(let{mount:t}of k.values())t.reveal=e,t.revealFocus=!0}function Ne(e){return{activate:(t)=>{N(e,t),ye(e,t)},activateSelected:()=>{let{selected:t}=e.choice;if(t!==null)ye(e,t)},contextMenu:(t,i,a)=>et(e,t,i,a),copyRef:()=>{let t=wb(e);if(t)Te(t)},dragOut:()=>{if(e.dropActive)e.dropActive=!1,v(e)},dragOver:()=>{if(!e.dropActive)e.dropActive=!0,v(e)},drop:(t)=>{if(e.dropActive=!1,v(e),t?.length)he(e,t)},focusTile:(t)=>{if(e.choice.selected!==t)N(e,t)},gridHost:(t)=>{e.grid=t},inputHost:(t,i)=>{e.inputs[i].add(t),xe(e);let a=D;if(e.mode==="manage"&&a?.role===i&&(i==="upload"||a.file===e.choice.selected))D=null,te(t)},key:(t,i)=>tt(e,t,i),measure:(t,i,a)=>{if(fl(t,i,a))x();else if(!Vd(t))hh(t).then(x)},openDocument:(t)=>{Se().then(({openFileInTab:i})=>i(t))},openViewer:()=>{let{selected:t}=e.choice;if(t!==null)Zu(t)},editImage:()=>{let{selected:t}=e.choice;if(t!==null)tC(t)},remove:()=>{let{selected:t}=e.choice;if(t!==null)eN(t)},rename:()=>{let{selected:t}=e.choice;if(t!==null)tN(t)},duplicate:()=>{let{selected:t}=e.choice;if(t!==null)nN(t)},replace:(t)=>{let[i]=t.files??[];t.value="";let{selected:a}=e.choice;if(i&&a!==null&&oA(a))Ox(a,i).then((r)=>{if(r)Qw(a);x()})},reset:()=>{e.choice.filter=e.images?"image":"all",e.choice.query="",v(e)},select:(t)=>N(e,t),setFilter:(t)=>{if(re(t))e.choice.filter=t,v(e)},setQuery:(t)=>{e.choice.query=t,v(e)},setSort:(t)=>{if(ne(t))e.choice.sort=t,v(e)},tileHost:(t,i)=>{e.tiles.set(i,t),je.set(t,i),e.observer.observe(t)},upload:(t)=>{let i=[...t.files??[]];if(t.value="",i.length>0)he(e,i)}}}function Te(e){if("clipboard"in navigator)navigator.clipboard.writeText(e.ref)}var I=null;function et(e,t,i,a){N(e,t);let r=wb(e);if(!r)return;I?.close();let o=(l,c,d,f={})=>({destructive:!1,disabled:!1,dividerAbove:!1,id:l,run:d,title:c,...f});I=zt({label:`${r.name} actions`,onClosed:(l)=>{if(I===l)I=null},origin:{x:i,y:a},region:"media-tile",rows:[o("open","Open in Viewer",()=>Zu(t)),...XS(t)?[o("edit","Edit Image",()=>tC(t))]:[],o("copy-url","Copy Site URL",()=>Te(r)),o("rename","Rename…",()=>{tN(t)},{dividerAbove:!0}),...QS()?[o("duplicate","Duplicate",()=>{nN(t)})]:[],o("replace","Replace…",()=>BP(t)),o("delete","Delete",()=>{eN(t)},{destructive:!0,dividerAbove:!0})]})}function ye(e,t){if(e.mode==="pick"){let i=wb(e);if(i)e.onPick?.(i);return}Zu(t)}function tt(e,t,i){let{files:a}=ke(e),r=q(a,{filter:e.choice.filter,query:e.choice.query,sort:e.choice.sort,unused:S}),o=r.findIndex((f)=>f.file===e.choice.selected),l=e.grid?le(Me(e.grid).width):1,c=o===-1?r.length>0?0:null:se(o,t,l,r.length,i),d=c===null?void 0:r[c];if(!d)return;N(e,d.file),e.tiles.get(d.file)?.focus()}var je=new WeakMap;function De(e,t,i,a,r,o){let l={choice:t,disposed:!1,dropActive:!1,grid:null,handle:null,images:r,inputs:{replace:new Set,upload:new Set},mode:e,observer:_p((c)=>{let d=je.get(c);if(d!==void 0&&!l.visible.has(d))l.visible.add(d),it(l)}),onPick:null,onSelect:null,paneId:a,reveal:null,revealFocus:!1,focusOwed:!1,region:i,sweepTimer:null,tiles:new Map,uploadDir:o,visible:new Set};return l}var G=new Set;function it(e){if(G.has(e))return;G.add(e),queueMicrotask(()=>{G.delete(e),v(e)})}function cS(e,t){let i=k.get(e);return i!==void 0&&i.tabId===t.id&&i.wrap.isConnected&&i.mount.handle!==null&&i.mount.handle.attached()}function vw(e){let t=k.get(e);if(!t)return;Z(t.mount),k.delete(e)}function JE(e,t){let{paneId:i,wrap:a}=e;if(cS(i,t))return;vw(i);let r=De("manage",y,Ln(i,"media-library"),i,!1,Ta);if(L.add(r),we(),r.handle=V(a,ee(r),Ne(r),{clear:!0}),k.set(i,{mount:r,tabId:t.id,wrap:a}),Q.delete(i))Ce(r)}async function Ce(e){await e.handle?.ready,He(e,!0)}function He(e,t=e.focusOwed){if(!t||e.disposed)return;let{selected:i}=e.choice,a=(i===null?void 0:e.tiles.get(i))??[...e.tiles.values()].find((r)=>r.getAttribute("tabindex")==="0");if(a?.isConnected){e.focusOwed=!1,a.focus();return}e.focusOwed=!0}function YE(e){let t=k.get(e);if(t?.wrap.isConnected&&t.mount.handle?.attached()===!0){Ce(t.mount);return}Q.add(e)}function HP(e){if(e.filter!==void 0)y.filter=e.filter;if(e.query!==void 0)y.query=e.query;if(e.select!==void 0){if(y.selected=e.select,y.filter!=="all")y.filter="all";y.query=""}x()}function hF(){let e=[...k.values()].map((t)=>$e(t.mount.inputs.upload)).find((t)=>t!==null)??null;if(e){te(e);return}D={file:null,role:"upload"}}function BP(e){HP({select:e});let t=null;for(let i of k.values())if(i.mount.choice.selected===e)t??=$e(i.mount.inputs.replace);if(t){te(t);return}D={file:e,role:"replace"}}var z=null;function be(e){let t=wb(e);return{blocked:t===null,confirmLabel:t?`Use ${t.name}`:e.images?"Use image":"Use file",headline:e.images?"Choose an image":"Choose media"}}function dS(){let e=z;if(z=null,e)Z(e.mount),e.dialog.close()}function pF(e){dS();let t={filter:e.images?"image":"all",query:"",selected:null,sort:"newest"},i=De("pick",t,`${vt("dialog",B)}/library`,null,e.images,J$(h.value?.documentPath??null)),a=(o)=>{dS(),e.onPick(o.ref)};i.onPick=a,L.add(i),we();let r=fe({body:(o)=>{i.handle=V(o,ee(i),Ne(i),{clear:!1})},closed:()=>{if(z?.mount===i)dS();else Z(i)},confirm:()=>{let o=wb(i);if(o)a(o)},layer:dt("dialog"),view:be(i)});i.onSelect=()=>r.update(be(i)),z={dialog:r,mount:i}}function ZE(){dS();for(let e of k.keys())vw(e);y.filter="all",y.query="",y.selected=null,y.sort="newest",D=null,Q.clear(),J()}
|
|
1
|
+
import{X}from"./studio-9c6cbq2c.js";import{p}from"./studio-4fnb5648.js";import{w}from"./studio-sce30r7b.js";import{ph,us,iI}from"./studio-4zd6an2b.js";import{Jt,Ut}from"./studio-nzemfbkk.js";import{sn,dt,Fn}from"./studio-tpxcryf2.js";import{m,h,eu}from"./studio-knsjyx7n.js";import{Kd}from"./studio-hh394phe.js";import{Jc,Ta,J$,RO,Y$,Nx,Ys,Ax,NO,AO,Ox,Mx,ov,nr,Vd,Yc,hh,fl,Px}from"./studio-61rg2cz5.js";import{oA,Qw,ex,Xu}from"./studio-3pz4t5a2.js";import{ET,Gu}from"./studio-4bgvvzhv.js";import{zt}from"./studio-daksw8kh.js";import{_L,SL,CL,kL,Zu,XS,QS,eC,tC}from"./studio-jma2q8r9.js";import{_p}from"./studio-z9453ypn.js";import{Ve,Ln,vt,E,R}from"./studio-9dq7rwc7.js";import{Me}from"./studio-0gvvqj3h.js";import{g}from"./studio-3qr08sxq.js";import{n,_}from"./studio-k3we3kqb.js";import{ce}from"./studio-0939t1q1.js";var H=[{key:"all",label:"All media"},{key:"image",label:"Images"},{key:"video",label:"Video"},{key:"audio",label:"Audio"},{key:"document",label:"Documents"},{key:"font",label:"Fonts"},{key:"unused",label:"Unused"}],lS=H.map((e)=>e.key);function re(e){return lS.some((t)=>t===e)}function T(e){return H.find((t)=>t.key===e)?.label??"All media"}var U=[{key:"newest",label:"Newest"},{key:"name",label:"Name"},{key:"size",label:"Size"}],Re=U.map((e)=>e.key);function ne(e){return Re.some((t)=>t===e)}function W(e,t,i){switch(t){case"all":return!0;case"unused":return i!==null&&i.has(e.file);default:return e.kind===t}}function A(e,t){let i=t.trim().toLowerCase();return i===""||e.name.toLowerCase().includes(i)}function q(e,t){return e.filter((a)=>W(a,t.filter,t.unused)&&A(a,t.query)).toSorted((a,r)=>Ae(t.sort,a,r)||a.file.localeCompare(r.file))}function Ae(e,t,i){switch(e){case"name":return t.name.localeCompare(i.name,void 0,{numeric:!0,sensitivity:"base"});case"size":return(i.bytes??-1)-(t.bytes??-1);default:return(i.modified??"").localeCompare(t.modified??"")}}function oe(e,t){let i={all:e.length,audio:0,document:0,font:0,image:0,unused:t===null?null:e.filter((a)=>t.has(a.file)).length,video:0};for(let a of e)i[a.kind]=(i[a.kind]??0)+1;return i}var Ie=132,ae=12;function le(e){return Math.max(1,Math.floor((e+ae)/(Ie+ae)))}function se(e,t,i,a,r=!1){if(a===0)return null;let o=Math.min(Math.max(e,0),a-1),l=o-o%i,c;switch(t){case"ArrowRight":{c=o+1;break}case"ArrowLeft":{c=o-1;break}case"ArrowDown":{c=o+i;break}case"ArrowUp":{c=o-i;break}case"Home":{c=r?0:l;break}case"End":{c=r?a-1:Math.min(l+i-1,a-1);break}default:return null}return c<0||c>=a?o:c}var de={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMediaLibrary",$description:"The Media workspace's library (`specs/studio.md` §22.6): the project's media as filters, a grid and the selected file's detail. ONE document in two modes. In `manage` it is the Media home tab, with Replace, Open in viewer, Rename, Duplicate and Delete under the detail; in `pick` it is the full-size picker inside a `jx-dialog` (`media-pick-dialog.json`), and the dialog's own footer answers Cancel or Use <file>. `media/media-library.ts` keeps every decision (which files a filter keeps, the sort, what a count may claim, where an arrow lands, what Replace writes) and hands this document strings and discriminants. **Unused is drawn with no number until the usage sweep has settled**, and Missing alt text and tags are not drawn at all: each needs a store that does not exist, and a filter that cannot be answered is not shipped as one that always answers nothing.",tagName:"div",attributes:{part:"media-library","data-jx-region":"${state.region}","data-mode":"${state.mode}","data-drop":"${state.dropActive}"},style:{$description:"Three columns over the whole stage: the filters, the grid with its toolbar, and the selected file's detail. Fills the pane's stage by its own geometry, as the workspace home does: the stage is `position: relative` (`pane-grid.json`). In pick mode the same columns fill the dialog's body instead, so the root's box is the only thing that differs between the two modes.",position:"absolute",inset:"0",display:"grid",gridTemplateColumns:"200px minmax(0, 1fr) 300px",boxSizing:"border-box",fontFamily:"var(--jx-font-sans)",fontSize:"var(--jx-text-md)",color:"var(--fg)",background:"var(--bg)",'&[data-mode="pick"]':{$description:"Inside a dialog there is no stage to fill: the box is the dialog body's, at a height the dialog can scroll within.",position:"relative",inset:"auto",height:"min(70vh, 620px)",gridTemplateColumns:"150px minmax(0, 1fr) 210px"},'&[data-drop="true"]':{$description:"The drop affordance is a STATE the flow holds, not a class a handler adds and forgets to take off.",outline:"2px dashed var(--accent)",outlineOffset:"-4px"},'& [part="filters"]':{display:"flex",flexDirection:"column",gap:"2px",padding:"var(--jx-space-3) var(--jx-space-2)",borderRight:"1px solid var(--border)",background:"var(--bg-panel)",overflowY:"auto"},'& [part="filters-heading"]':{margin:"0",padding:"var(--jx-space-2) var(--jx-space-2) var(--jx-space-1)",fontSize:"var(--jx-text-xs)",fontWeight:"600",letterSpacing:"0.06em",textTransform:"uppercase",color:"var(--fg-dim)"},'& [part="filter"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-2)",height:"30px",padding:"0 var(--jx-space-2)",border:"none",borderRadius:"var(--radius)",background:"none",color:"var(--fg)",font:"inherit",textAlign:"left",cursor:"pointer"},'& [part="filter"]:hover':{background:"var(--hover-bg)"},'& [part="filter"][aria-pressed="true"]':{background:"color-mix(in srgb, var(--accent) 16%, transparent)",color:"var(--fg)",fontWeight:"600"},'& [part="filter"]:focus-visible':{outline:"var(--jx-focus-ring)",outlineOffset:"-2px"},'& [part="filter-count"]':{marginLeft:"auto",fontSize:"var(--jx-text-xs)",color:"var(--fg-dim)",fontWeight:"400"},'& [part="main"]':{display:"flex",flexDirection:"column",minWidth:"0",minHeight:"0"},'& [part="toolbar"]':{display:"flex",alignItems:"center",flexWrap:"wrap",gap:"var(--jx-space-3)",padding:"var(--jx-space-3) var(--jx-space-4)",borderBottom:"1px solid var(--border)"},'& [part="title"]':{margin:"0 auto 0 0",fontSize:"var(--jx-text-lg)",fontWeight:"600"},'& [part="search"]':{width:"220px"},'& [part="sort"]':{width:"130px"},'& [part="upload"], & [part="empty-upload"]':{$description:"A LABEL around the file picker, not a button that clicks a hidden one: the picker is the control, so it takes focus, Enter opens it and a screen reader announces a file upload. A plain element because a label forwards a click to the input it contains and a custom element between the two would break that.",position:"relative",display:"inline-flex",alignItems:"center",gap:"6px",height:"28px",padding:"0 var(--jx-space-3)",border:"1px solid var(--border)",borderRadius:"var(--radius)",background:"var(--bg-panel)",color:"var(--fg)",font:"inherit",cursor:"pointer",":hover":{background:"var(--hover-bg)"},":has(:focus-visible)":{outline:"var(--jx-focus-ring)",outlineOffset:"2px"}},'& [part="upload-input"], & [part="replace-input"]':{$description:"Out of the way but still FOCUSABLE: `display: none` would take the control out of the tab order, and the label around it draws the focus ring for it.",position:"absolute",width:"1px",height:"1px",opacity:"0",pointerEvents:"none"},'& [part="upload-glyph"]':{"--jx-icon-size":"16px"},'& [part="body"]':{flex:"1",minHeight:"0",overflowY:"auto",padding:"var(--jx-space-4)"},'& [part="grid"]':{$description:"auto-fill over a minimum tile width; `media/media-library-model.ts` `gridColumns` does the same arithmetic, so ArrowDown lands on the tile drawn under the current one. Keep the two numbers in step.",display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(132px, 1fr))",gap:"12px",alignContent:"start"},'& [part="tile"]':{display:"flex",flexDirection:"column",gap:"4px",padding:"4px",borderRadius:"var(--jx-radius-md, 6px)",border:"2px solid transparent",cursor:"pointer",minWidth:"0",outline:"none"},'& [part="tile"]:hover':{background:"var(--hover-bg)"},'& [part="tile"][aria-selected="true"]':{borderColor:"var(--accent)"},'& [part="tile"]:focus-visible':{outline:"var(--jx-focus-ring)",outlineOffset:"2px"},'& [part="thumb"]':{display:"flex",alignItems:"center",justifyContent:"center",aspectRatio:"4 / 3",borderRadius:"var(--radius)",background:"var(--bg-input)",overflow:"hidden",color:"var(--fg-dim)","--jx-icon-size":"28px"},'& [part="thumb-img"]':{width:"100%",height:"100%",objectFit:"cover"},'& [part="tile-name"]':{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:"var(--jx-text-sm)"},'& [part="tile-caption"]':{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:"var(--jx-text-xs)",color:"var(--fg-dim)",minHeight:"1em"},'& [part="empty"]':{display:"flex",flexDirection:"column",alignItems:"center",gap:"var(--jx-space-3)",padding:"48px var(--jx-space-6)",textAlign:"center",color:"var(--fg-dim)","--jx-icon-size":"40px"},'& [part="empty-title"]':{margin:"0",fontSize:"var(--jx-text-lg)",fontWeight:"600",color:"var(--fg)"},'& [part="empty-detail"]':{margin:"0",maxWidth:"42ch",lineHeight:"1.5"},'& [part="detail"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-3)",padding:"var(--jx-space-4)",borderLeft:"1px solid var(--border)",background:"var(--bg-panel)",overflowY:"auto",minWidth:"0"},'& [part="detail-hint"]':{margin:"auto 0",textAlign:"center",color:"var(--fg-dim)"},'& [part="detail-preview"]':{display:"flex",alignItems:"center",justifyContent:"center",minHeight:"140px",maxHeight:"220px",borderRadius:"var(--radius)",background:"var(--bg-input)",overflow:"hidden",color:"var(--fg-dim)","--jx-icon-size":"40px"},'& [part="preview-img"], & [part="preview-video"]':{maxWidth:"100%",maxHeight:"220px",objectFit:"contain"},'& [part="preview-audio"]':{width:"100%"},'& [part="preview-specimen"]':{$description:"The viewer's specimen at a side pane's size. The face arrives as the `@font-face` the flow writes under a family name generated from the path (`media/media-pane.ts` `specimenOf`); the element carries only that name, as a custom property, and the fallback stack is a rule, here.",display:"flex",flexDirection:"column",gap:"var(--jx-space-2)",padding:"var(--jx-space-4)",maxWidth:"100%",color:"var(--fg)",fontFamily:"var(--jx-specimen-family, system-ui), system-ui, sans-serif"},'& [part="specimen-line"]':{margin:"0",lineHeight:"1.3",overflowWrap:"anywhere"},'& [part="specimen-line"][data-size="32"]':{fontSize:"32px"},'& [part="specimen-line"][data-size="14"]':{fontSize:"var(--jx-text-md)"},'& [part="detail-name"]':{margin:"0",fontSize:"var(--jx-text-md)",fontWeight:"600",overflowWrap:"anywhere"},'& [part="facts"]':{margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"},'& [part="group-title"]':{margin:"0",fontSize:"var(--jx-text-xs)",fontWeight:"600",color:"var(--fg-dim)"},'& [part="url"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-2)",minWidth:"0"},'& [part="url-value"]':{flex:"1",minWidth:"0",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontFamily:"var(--jx-font-mono)",fontSize:"var(--jx-text-sm)"},'& [part="usage"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-1)"},'& [part="usage-headline"]':{margin:"0",fontSize:"var(--jx-text-sm)"},'& [part="usage-list"]':{margin:"0",padding:"0",listStyle:"none",display:"flex",flexDirection:"column",gap:"2px"},'& [part="usage-row"]':{display:"flex",alignItems:"center",gap:"var(--jx-space-2)"},'& [part="usage-link"]':{flex:"1",minWidth:"0",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",border:"none",background:"none",padding:"0",color:"var(--accent)",font:"inherit",fontSize:"var(--jx-text-sm)",textAlign:"left",cursor:"pointer",":hover":{textDecoration:"underline"},":focus-visible":{outline:"var(--jx-focus-ring)"}},'& [part="usage-count"]':{fontSize:"var(--jx-text-xs)",color:"var(--fg-dim)"},'& [part="actions"]':{display:"flex",flexWrap:"wrap",gap:"var(--jx-space-2)",marginTop:"var(--jx-space-2)"},'& [part="replace"]':{position:"relative",display:"inline-flex",alignItems:"center",height:"28px",padding:"0 var(--jx-space-3)",border:"1px solid var(--border)",borderRadius:"var(--radius)",background:"var(--bg)",color:"var(--fg)",font:"inherit",cursor:"pointer",":hover":{background:"var(--hover-bg)"},":has(:focus-visible)":{outline:"var(--jx-focus-ring)",outlineOffset:"2px"}}},ondragover:{$prototype:"Function",body:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/dragOver"},value:[]}],description:"A file dropped ANYWHERE on the library uploads, to the destination the Upload label names before the drop: public/media/."},ondragleave:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/dragOut"},value:[]}]},ondrop:{$prototype:"Function",body:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/drop"},value:[{$ref:"event#/dataTransfer/files"}]}]},children:[{tagName:"nav",attributes:{part:"filters","aria-label":"Media filters"},children:[{tagName:"h2",attributes:{part:"filters-heading"},textContent:"Library"},{$prototype:"Array",items:{$ref:"#/state/filters"},key:{$ref:"$map/item/key"},map:{tagName:"button",attributes:{part:"filter",type:"button","aria-pressed":"${$map.item.pressed}","data-filter":"${$map.item.key}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setFilter"},value:[{$ref:"$map/item/key"}]}]},children:[{tagName:"span",attributes:{part:"filter-label"},textContent:"${$map.item.label}"},{tagName:"span",attributes:{part:"filter-count"},textContent:"${$map.item.count}"}]}}]},{tagName:"section",attributes:{part:"main","aria-labelledby":"${state.titleId}"},children:[{tagName:"header",attributes:{part:"toolbar"},children:[{tagName:"h2",attributes:{part:"title",id:"${state.titleId}"},textContent:"${state.title}"},{tagName:"jx-textfield",attributes:{part:"search"},$props:{type:"search",size:"sm",label:"Search media",placeholder:"Search by name…",autocomplete:"off",value:{$ref:"#/state/query"}},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setQuery"},value:[{$ref:"event#/target/value"}]}]}},{tagName:"jx-select",attributes:{part:"sort"},$props:{label:"Sort",size:"sm",options:{$ref:"#/state/sortOptions"},value:{$ref:"#/state/sort"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setSort"},value:[{$ref:"event#/target/value"}]}]}},{tagName:"label",attributes:{part:"upload",title:"${state.uploadHint}"},children:[{tagName:"input",attributes:{part:"upload-input",type:"file",multiple:!0,accept:"${state.uploadAccept}"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/upload"},value:[{$ref:"event#/target"}]}],description:"The picker itself, so the destination in the label's tooltip is visible BEFORE the files are chosen. The flow takes the element rather than the file list because a file input that is not cleared refuses the same file twice."}},{tagName:"jx-icon",attributes:{part:"upload-glyph","aria-hidden":"true"},$props:{name:"upload-simple"}},{tagName:"span",textContent:"Upload"}]}]},{tagName:"div",attributes:{part:"body"},children:[{tagName:"div",attributes:{part:"grid-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/gridState"},cases:{loading:{tagName:"p",attributes:{part:"empty",role:"status"},textContent:"Reading the project's media…"},counting:{tagName:"p",attributes:{part:"empty",role:"status"},textContent:"${state.countingLabel}"},empty:{tagName:"div",attributes:{part:"empty"},children:[{tagName:"jx-icon",attributes:{part:"empty-glyph","aria-hidden":"true"},$props:{name:"image"}},{tagName:"p",attributes:{part:"empty-title"},textContent:"${state.emptyTitle}"},{tagName:"p",attributes:{part:"empty-detail"},textContent:"${state.emptyDetail}"},{tagName:"label",attributes:{part:"empty-upload",title:"${state.uploadHint}"},children:[{tagName:"input",attributes:{part:"upload-input",type:"file",multiple:!0,accept:"${state.uploadAccept}"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/upload"},value:[{$ref:"event#/target"}]}],description:"The picker itself, so the destination in the label's tooltip is visible BEFORE the files are chosen. The flow takes the element rather than the file list because a file input that is not cleared refuses the same file twice."}},{tagName:"jx-icon",attributes:{part:"upload-glyph","aria-hidden":"true"},$props:{name:"upload-simple"}},{tagName:"span",textContent:"Upload"}]}]},nomatch:{tagName:"div",attributes:{part:"empty"},children:[{tagName:"jx-icon",attributes:{part:"empty-glyph","aria-hidden":"true"},$props:{name:"image"}},{tagName:"p",attributes:{part:"empty-title"},textContent:"${state.emptyTitle}"},{tagName:"p",attributes:{part:"empty-detail"},textContent:"${state.emptyDetail}"},{tagName:"jx-button",attributes:{part:"reset"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/reset"},value:[]}]},children:[{tagName:"span",textContent:"Show all media"}]}]},listed:{tagName:"div",attributes:{part:"grid",role:"listbox","aria-labelledby":"${state.titleId}"},onkeydown:{$prototype:"Function",body:[{$switch:{$ref:"event#/key"},cases:{ArrowRight:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],ArrowLeft:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],ArrowDown:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],ArrowUp:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],Home:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],End:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/key"},value:[{$ref:"event#/key"},{$ref:"event#/ctrlKey"}]}],Enter:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/activateSelected"},value:[]}]}}],description:"The grid pattern: arrows move one tile, Home and End to the ends of the row, Ctrl+Home and Ctrl+End to the ends of the grid, and Enter opens the selected file (in pick mode, uses it). The flow computes where the move lands; the tile that receives it takes focus, so the roving tabindex follows the selection."},children:[{$prototype:"Array",items:{$ref:"#/state/tiles"},key:{$ref:"$map/item/key"},map:{tagName:"div",attributes:{part:"tile",role:"option","aria-selected":"${$map.item.selected}",tabindex:"${$map.item.tabindex}","data-file":"${$map.item.file}",title:"${$map.item.name}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/select"},value:[{$ref:"$map/item/file"}]}]},onfocus:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/focusTile"},value:[{$ref:"$map/item/file"}]}],description:"Selection follows focus, the listbox pattern: a Tab onto the grid lands on the roving stop and selects it, so the first Enter opens (in pick mode, uses) the tile the focus ring is on rather than nothing."},ondblclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/activate"},value:[{$ref:"$map/item/file"}]}]},oncontextmenu:{$prototype:"Function",body:[{$switch:{$ref:"#/state/mode"},cases:{manage:[{preventDefault:!0},{operator:"call",target:{$ref:"#/state/contextMenu"},value:[{$ref:"$map/item/file"},{$ref:"event#/clientX"},{$ref:"event#/clientY"}]}]}}],description:"Manage mode only: the detail pane's actions at the pointer. Pick mode's dialog is modal, and a menu in the popover layer outside it would be inert, so its right-click is left to the platform."},children:[{tagName:"div",attributes:{part:"thumb"},children:[{tagName:"div",attributes:{part:"thumb-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"$map/item/thumbState"},cases:{image:{tagName:"img",attributes:{part:"thumb-img",src:"${$map.item.thumbSrc}",alt:"",draggable:"false"},onload:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/measure"},value:[{$ref:"$map/item/file"},{$ref:"event#/target/naturalWidth"},{$ref:"event#/target/naturalHeight"}]}]}},pending:{tagName:"span",attributes:{part:"thumb-pending","aria-hidden":"true"}},glyph:{tagName:"jx-icon",attributes:{part:"thumb-glyph","aria-hidden":"true"},$props:{name:{$ref:"$map/item/glyph"}}}},$description:"The thumbnail is asked for when the tile scrolls into view, not when the grid is built: `pending` until the flow's observer reports the tile, then the picture. A file the browser draws no picture of shows its kind's glyph."}]},{tagName:"span",attributes:{part:"tile-name"},textContent:"${$map.item.name}"},{tagName:"span",attributes:{part:"tile-caption"},textContent:"${$map.item.caption}"}]}}]}}}]}]},{tagName:"aside",attributes:{part:"detail","aria-label":"Details"},children:[{tagName:"div",attributes:{part:"detail-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/detailState"},cases:{none:{tagName:"p",attributes:{part:"detail-hint"},textContent:"${state.detailHint}"},shown:{tagName:"div",attributes:{part:"detail-body",role:"none"},style:{display:"contents"},children:[{tagName:"div",attributes:{part:"detail-preview"},children:[{tagName:"div",attributes:{part:"preview-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/previewKind"},cases:{image:{tagName:"img",attributes:{part:"preview-img",src:"${state.previewSrc}",alt:""},onload:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/measure"},value:[{$ref:"#/state/selectedFile"},{$ref:"event#/target/naturalWidth"},{$ref:"event#/target/naturalHeight"}]}]}},video:{tagName:"video",attributes:{part:"preview-video",src:"${state.previewSrc}",controls:!0}},audio:{tagName:"audio",attributes:{part:"preview-audio",src:"${state.previewSrc}",controls:!0}},font:{tagName:"div",attributes:{part:"preview-specimen",style:"${state.previewSpecimenFamily}"},children:[{tagName:"style",textContent:"${state.previewFontFace}"},{tagName:"p",attributes:{part:"specimen-line","data-size":"32"},textContent:"Aa"},{tagName:"p",attributes:{part:"specimen-line","data-size":"14"},textContent:"${state.previewSpecimen}"}]},glyph:{tagName:"jx-icon",attributes:{part:"preview-glyph","aria-hidden":"true"},$props:{name:{$ref:"#/state/previewGlyph"}}}}}]},{tagName:"h3",attributes:{part:"detail-name"},textContent:"${state.detailName}"},{tagName:"p",attributes:{part:"facts"},textContent:"${state.detailFacts}"},{tagName:"div",attributes:{part:"url-group"},children:[{tagName:"h4",attributes:{part:"group-title"},textContent:"Site URL"},{tagName:"div",attributes:{part:"url"},children:[{tagName:"code",attributes:{part:"url-value"},textContent:"${state.detailRef}"},{tagName:"jx-action-button",attributes:{part:"copy"},$props:{size:"sm",quiet:!0,hint:"Copy the site URL"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/copyRef"},value:[]}]},children:[{tagName:"span",textContent:"Copy"}]}]}]},{tagName:"div",attributes:{part:"usage-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/usageState"},cases:{shown:{tagName:"div",attributes:{part:"usage"},children:[{tagName:"h4",attributes:{part:"group-title"},textContent:"Used on"},{tagName:"p",attributes:{part:"usage-headline"},textContent:"${state.usageHeadline}"},{tagName:"div",attributes:{part:"usage-list-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasUsageFiles"},cases:{true:{tagName:"ul",attributes:{part:"usage-list"},children:[{$prototype:"Array",items:{$ref:"#/state/usageFiles"},key:{$ref:"$map/item/path"},map:{tagName:"li",attributes:{part:"usage-row","data-usage":"${$map.item.path}"},children:[{tagName:"button",attributes:{part:"usage-link",type:"button",title:"Open ${$map.item.path}"},textContent:"${$map.item.path}",onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openDocument"},value:[{$ref:"$map/item/path"}]}]}},{tagName:"span",attributes:{part:"usage-count"},textContent:"${$map.item.count}"}]}}]}}}]}},$description:'Hidden on a host with no reference index, which is a different fact from "nothing uses it": a confident zero is the one answer this pane must never invent.'},{tagName:"div",attributes:{part:"actions-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/mode"},cases:{manage:{tagName:"div",attributes:{part:"actions"},children:[{tagName:"label",attributes:{part:"replace",title:"Replace ${state.detailName} everywhere it is used"},children:[{tagName:"input",attributes:{part:"replace-input",type:"file",accept:"${state.replaceAccept}"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/replace"},value:[{$ref:"event#/target"}]}],description:"Replace writes the chosen file over this one's path, so every reference keeps resolving and now shows the new bytes (studio.md §9.3). The element rather than the list, so the input can be cleared."}},{tagName:"span",textContent:"Replace"}]},{tagName:"jx-button",attributes:{part:"open-viewer"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openViewer"},value:[]}]},children:[{tagName:"span",textContent:"Open in viewer"}]},{tagName:"div",attributes:{part:"edit-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/editable"},cases:{yes:{tagName:"jx-button",attributes:{part:"edit-image"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/editImage"},value:[]}],description:"Withheld, not disabled, for a file the editor cannot write: a refused format is not offered rather than offered and then refused (studio.md §9.5)."},children:[{tagName:"span",textContent:"Edit image"}]},no:{tagName:"span",attributes:{hidden:!0}}}},{tagName:"jx-button",attributes:{part:"rename"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/rename"},value:[]}]},children:[{tagName:"span",textContent:"Rename"}]},{tagName:"div",attributes:{part:"duplicate-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/duplicable"},cases:{yes:{tagName:"jx-button",attributes:{part:"duplicate"},$props:{size:"sm",variant:"secondary"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/duplicate"},value:[]}],description:"Withheld, not disabled, on a backend that cannot read a file's raw bytes: a copy read as text would be a broken file (studio.md §9.3)."},children:[{tagName:"span",textContent:"Duplicate"}]},no:{tagName:"span",attributes:{hidden:!0}}}},{tagName:"jx-button",attributes:{part:"delete"},$props:{size:"sm",variant:"negative"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/remove"},value:[]}]},children:[{tagName:"span",textContent:"Delete"}]}]}},$description:"Manage mode's actions. Pick mode has none here: its answer is the dialog's own footer, Cancel and Use <file>."}]}}}]}]};E("media-library",de);function Oe(){return{countingLabel:"",detailFacts:"",detailHint:"",detailName:"",detailRef:"",detailState:"none",dropActive:"false",emptyDetail:"",emptyTitle:"",filters:[],gridState:"loading",mode:"manage",previewFontFace:"",previewGlyph:"",previewKind:"glyph",previewSpecimen:"",previewSpecimenFamily:"",previewSrc:"",query:"",region:"",replaceAccept:"",editable:"no",duplicable:"no",selectedFile:"",sort:"",sortOptions:[],tiles:[],title:"",titleId:"",uploadAccept:"",uploadHint:"",usageFiles:[],usageHeadline:"",usageState:"hidden"}}function pe(e,t){Object.assign(e,t),e.hasUsageFiles=t.usageFiles.length>0}function Ke(e){let t=n(e)?void 0:e.attributes?.part;return n(t)?t:""}function ze(e){let t=e?.$map,i=_(t)&&"item"in t?t.item:void 0;return _(i)&&"file"in i&&n(i.file)?i.file:null}function V(e,t,i,a){if(a.clear)e.replaceChildren();let{tileHost:r,gridHost:o,inputHost:l,...c}=i,d=g({...Oe(),...c,hasUsageFiles:!1});pe(d,t);let f=null,b=!1,M=R("media-library",d,e,{onNodeCreated:(u,s,F,Ee)=>{if(b||!(u instanceof HTMLElement))return;let C=Ke(F);if(C==="tile"){let ie=ze(Ee);if(ie!==null)r(u,ie)}else if(C==="grid")o(u);else if(u instanceof HTMLInputElement&&C==="upload-input")l(u,"upload");else if(u instanceof HTMLInputElement&&C==="replace-input")l(u,"replace")}}).then((u)=>{if(b)u.dispose();else f=u;return u.root});return{attached:()=>{if(b)return!1;let u=f?.root;return u===void 0?!0:u instanceof HTMLElement&&e.contains(u)},dispose(){b=!0,f?.dispose(),f=null},ready:M,update:(u)=>pe(d,u)}}var ue={$schema:"https://jxsuite.com/schema/v1",$id:"StudioMediaPickDialog",$description:"The full-size media picker (`specs/studio.md` §9.3): a `jx-dialog` whose body is the Media workspace's own library surface in pick mode, so the picker and the workspace are one surface at two sizes. The dialog owns modality, Escape, the backdrop and focus restoration, and its footer is the answer: Cancel, or Use <file>, disabled until a file is chosen. The body is an ISLAND: this document draws the slot and nothing in it, and `surfaces/media-pick-dialog.ts` mounts `media-library.json` there through `onNodeCreated`.",tagName:"jx-dialog",$props:{headline:{$ref:"#/state/headline"},confirmLabel:{$ref:"#/state/confirmLabel"},confirmDisabled:{$ref:"#/state/blocked"},cancelLabel:"Cancel",dismissible:!0,size:"xl"},attributes:{part:"media-pick"},onconfirm:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/confirm"},value:[]}]},oncancel:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},onclose:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},children:[{tagName:"div",attributes:{part:"library-slot"},style:{$description:"The library's box in pick mode is its own (`media-library.json`, `data-mode=\"pick\"`); the slot only gives it the dialog body's width.",minWidth:"0"}}]};E("media-pick-dialog",ue);var B="media-picker";function Ue(e){let t=n(e)?void 0:e.attributes?.part;return n(t)?t:""}function fe(e){let t=document.createElement("div");t.style.pointerEvents="auto",t.setAttribute(Ve,vt("dialog",B)),e.layer.append(t);let i=!1,a=()=>{if(i)return;i=!0,e.closed()},r=()=>i,o=g({...e.view,closed:a,confirm:e.confirm}),l=null,c=R("media-pick-dialog",o,t,{onNodeCreated:(d,f,b)=>{if(!r()&&d instanceof HTMLElement&&Ue(b)==="library-slot")e.body(d)}}).then(async(d)=>{l=d;let f=d.root;if(r())return d.dispose(),f;if(await sn(f),!r())Jt(f);return f});return{close(){let d=l?.root;if(d instanceof HTMLElement)Ut(d);l?.dispose(),l=null,t.remove(),a()},host:t,ready:c,update(d){Object.assign(o,d)}}}var uF="media-home",ve={audio:"play",document:"file-text",font:"text-aa",image:"image",video:"play"},We={audio:"Audio",document:"Document",font:"Font",image:"Image",video:"Video"},y={filter:"all",query:"",sort:"newest",selected:null},D=null,S=null,O=0,K=0,P=!1,Y=0;function J(){S=null,P=!1,O=0,K=0,Y+=1}function qe(){return[...L].some((e)=>!e.disposed&&e.choice.filter==="unused")}async function Be(e){if(P||S!==null||!ph())return;let t=Y;P=!0,O=0,K=e.length;let i=new Set;for(let a of e){let r=await Xu(a.file);if(t!==Y)return;if(!qe()){J();return}if(r.status==="ready"&&r.result.files.length===0)i.add(a.file);O+=1,x()}S=i,P=!1,x()}var L=new Set,k=new Map,Q=new Set,j=null;function we(){if(j!==null)return;let e=()=>{J(),x()},t=ET(e),i=iI(e);j=()=>{t(),i()}}function Ge(){if(L.size===0&&j)j(),j=null}function v(e){if(!e.disposed){if(e.handle?.update(ee(e)),e.onSelect?.(),Ye(e),e.focusOwed)queueMicrotask(()=>He(e));xe(e)}}function Ye(e){let t=e.reveal,i=t===null?void 0:e.tiles.get(t);if(i?.isConnected){if(e.reveal=null,i.scrollIntoView({block:"nearest"}),e.revealFocus)e.revealFocus=!1,i.focus()}}function xe(e){if(e.sweepTimer!==null||e.disposed)return;e.sweepTimer=setTimeout(()=>{e.sweepTimer=null,e.observer.releaseDetached();for(let[t,i]of e.tiles)if(!i.isConnected)e.tiles.delete(t);for(let t of[e.inputs.upload,e.inputs.replace])for(let i of t)if(!i.isConnected)t.delete(i)},0)}function $e(e){return[...e].find((t)=>t.isConnected)??null}function x(){for(let e of L)v(e)}function Z(e){if(e.disposed=!0,e.sweepTimer!==null)clearTimeout(e.sweepTimer),e.sweepTimer=null;e.inputs.upload.clear(),e.inputs.replace.clear(),e.observer.destroy(),e.handle?.dispose(),e.handle=null,e.tiles.clear(),L.delete(e),Ge()}function ke(e){let t=Gu(),i=t===null?null:e.images?t.filter((r)=>r.isImage):t;return{files:(i??[]).map((r)=>{let o=Yc(r.file);return{bytes:o?.bytes??null,file:r.file,kind:r.kind,modified:o?.modified??null,name:r.name}}),listed:i}}function Je(e){return H.filter((t)=>(t.key!=="unused"||ph())&&(!e.images||t.key==="image"||t.key==="unused"))}function wb(e){let{filter:t,query:i,selected:a}=e.choice;if(a===null)return null;let r=Gu()?.find((l)=>l.file===a)??null;if(r===null||e.images&&!r.isImage)return null;let o={bytes:null,file:r.file,kind:r.kind,modified:null,name:r.name};return W(o,t,S)&&A(o,i)?r:null}function Qe(e,t){if(t===0)return{emptyDetail:`Upload files or drop them anywhere here. They are saved under ${e.uploadDir}/, and anything already under public/ or a collection's images/ folder is listed here too.`,emptyTitle:e.images?"No images yet":"No media yet"};let{filter:i,query:a}=e.choice;if(a.trim()!=="")return{emptyDetail:`Nothing in ${T(i)} matches it.`,emptyTitle:`No matches for “${a.trim()}”`};if(i==="unused")return{emptyDetail:"Every file is referenced by at least one document.",emptyTitle:"No unused media"};return{emptyDetail:`${t} ${t===1?"file":"files"} in the project, none of them ${T(i).toLowerCase()}.`,emptyTitle:`No ${T(i).toLowerCase()}`}}function ee(e){let{choice:t}=e,{files:i,listed:a}=ke(e),r=oe(i,S),o=Je(e);if(!o.some((s)=>s.key===t.filter))t.filter=o[0]?.key??"all";let l=q(i,{filter:t.filter,query:t.query,sort:t.sort,unused:S}),c=Gu();if(t.filter==="unused"&&c!==null)Be(c);let d="listed";if(a===null)d="loading";else if(t.filter==="unused"&&S===null)d="counting";else if(i.length===0||l.length===0)d=i.length===0?"empty":"nomatch";let f=wb(e),b=l.some((s)=>s.file===t.selected)?t.selected:l[0]?.file??null,M=l.map((s)=>{let F=s.kind==="image";return{caption:Px(Yc(s.file))||We[s.kind],file:s.file,glyph:ve[s.kind],key:s.file,name:s.name,selected:s.file===t.selected?"true":"false",tabindex:s.file===b?"0":"-1",thumbSrc:F&&e.visible.has(s.file)?nr(s.file):"",thumbState:F?e.visible.has(s.file)?"image":"pending":"glyph"}}),u=e.images&&t.filter==="image"?"Images":T(t.filter);return{countingLabel:K>0?`Counting references… ${O} of ${K}`:"Counting references…",dropActive:e.dropActive?"true":"false",filters:o.map((s)=>{let F=r[s.key];return{count:F===null?"":String(F),key:s.key,label:e.images&&s.key==="image"?"All images":s.label,pressed:s.key===t.filter?"true":"false"}}),gridState:d,mode:e.mode,query:t.query,region:e.region,sort:t.sort,sortOptions:U.map((s)=>({label:s.label,value:s.key})),tiles:M,title:u,titleId:`media-library-title-${e.region.replaceAll(/[^\w-]/g,"-")}`,uploadAccept:e.images?"image/*":Jc(),uploadHint:`Upload into ${e.uploadDir}/`,...Qe(e,i.length),...Xe(e,f)}}function Xe(e,t){if(t===null)return{detailFacts:"",detailHint:e.mode==="pick"?"Choose a file to use it.":"Select a file to see its details.",detailName:"",detailRef:"",detailState:"none",previewFontFace:"",previewGlyph:"",previewKind:"glyph",previewSpecimen:"",previewSpecimenFamily:"",previewSrc:"",replaceAccept:"",editable:"no",duplicable:"no",selectedFile:"",usageFiles:[],usageHeadline:"",usageState:"hidden"};let i=Yc(t.file),a=ex(t.file);if(!Vd(t.file))hh(t.file).then(x);if(a===null||a.status==="pending")Xu(t.file).then(x);let r=_L(t.file),o=r==="image"||r==="video"||r==="audio"||r==="font"?r:"glyph",l=o==="font"?CL(t.file):{fontFace:"",specimen:"",specimenFamily:""};return{detailFacts:SL(t.file,i),detailHint:"",detailName:t.name,detailRef:t.ref,detailState:"shown",previewFontFace:l.fontFace,previewGlyph:ve[t.kind],previewKind:o,previewSpecimen:l.specimen,previewSpecimenFamily:l.specimenFamily,previewSrc:o==="glyph"?"":nr(t.file),replaceAccept:NO(t.file),editable:XS(t.file)?"yes":"no",duplicable:QS()?"yes":"no",selectedFile:t.file,...kL(a)}}var me=null,ge=null;function Se(){return me??=(ce("zrqtgt41"),import("./files-zrqtgt41.js")),me}function Fe(){return ge??=(ce("1sghzgcr"),import("./file-ops-1sghzgcr.js")),ge}function te(e){try{e.showPicker()}catch{e.focus()}}function N(e,t){e.choice.selected=t,v(e)}async function he(e,t){let i=await Ys([...t],{dir:e.uploadDir,only:e.images?"image":"media"}),[a]=i;if(!a)return;if(e.choice.filter!=="all"&&e.choice.filter!==a.kind)e.choice.filter=e.images?"image":"all";e.choice.query="",e.reveal=a.path,N(e,a.path)}async function eN(e){let t=e.split("/").pop()??e,{confirmFileDelete:i}=await Fe();if(!await i({name:t,path:e}))return!1;let{markLocalMutation:a}=await (ce("45rhg3me"),import("./fs-events-45rhg3me.js"));try{a(e),await p().deleteFile(e)}catch(l){return w.error(`Could not delete ${t}.`,{detail:X(l),path:e,source:"Media"}),!1}if(Kd([e]),us(),m.tabs.has(e))eu(e);for(let l of L)if(l.choice.selected===e)l.choice.selected=null;if(y.selected===e)y.selected=null;let r=ov(e),o=await Ze(r,a);return await Nx(o?ov(r):r),w.success(`Deleted ${t}`),!0}async function Ze(e,t){if(!RO(e))return!1;let i=p();try{if((await i.listDirectory(e)).length>0)return!1;return t(e),await i.deleteFile(e),!0}catch{return!1}}async function tN(e){if(eC(e,"renamed"))return null;let t=Mx(e),i=ov(e),{commitRename:a,listRenameSiblings:r,notifyMoveOutcome:o,renameStatus:l}=await Se(),c=await r(e,"Media");if(c===null)return null;let{renamePromptMessage:d}=await Fe(),f=await d(e),b=await Fn("Rename",{confirmLabel:"Rename",select:"stem",validate:(s)=>AO(e,s,c),value:t,...f!==void 0&&{message:f}});if(!b||b===t)return null;let M=Y$(i,b),u=Yc(e);try{let s=await a(e,M);if(y.selected===e)Le(M);if(await Nx(i),u?.width!=null&&u.height!=null)fl(M,u.width,u.height);return o(l(b,s),s,M),M}catch(s){return w.error(`Could not rename ${t}.`,{detail:X(s),path:e,source:"Media"}),null}}async function nN(e){if(eC(e,"duplicated"))return null;let t=await Ax(e);if(t===null)return null;return Le(t.path),x(),t.path}function Le(e){if(y.selected=e,!A({name:Mx(e)},y.query))y.query="";for(let{mount:t}of k.values())t.reveal=e,t.revealFocus=!0}function Ne(e){return{activate:(t)=>{N(e,t),ye(e,t)},activateSelected:()=>{let{selected:t}=e.choice;if(t!==null)ye(e,t)},contextMenu:(t,i,a)=>et(e,t,i,a),copyRef:()=>{let t=wb(e);if(t)Te(t)},dragOut:()=>{if(e.dropActive)e.dropActive=!1,v(e)},dragOver:()=>{if(!e.dropActive)e.dropActive=!0,v(e)},drop:(t)=>{if(e.dropActive=!1,v(e),t?.length)he(e,t)},focusTile:(t)=>{if(e.choice.selected!==t)N(e,t)},gridHost:(t)=>{e.grid=t},inputHost:(t,i)=>{e.inputs[i].add(t),xe(e);let a=D;if(e.mode==="manage"&&a?.role===i&&(i==="upload"||a.file===e.choice.selected))D=null,te(t)},key:(t,i)=>tt(e,t,i),measure:(t,i,a)=>{if(fl(t,i,a))x();else if(!Vd(t))hh(t).then(x)},openDocument:(t)=>{Se().then(({openFileInTab:i})=>i(t))},openViewer:()=>{let{selected:t}=e.choice;if(t!==null)Zu(t)},editImage:()=>{let{selected:t}=e.choice;if(t!==null)tC(t)},remove:()=>{let{selected:t}=e.choice;if(t!==null)eN(t)},rename:()=>{let{selected:t}=e.choice;if(t!==null)tN(t)},duplicate:()=>{let{selected:t}=e.choice;if(t!==null)nN(t)},replace:(t)=>{let[i]=t.files??[];t.value="";let{selected:a}=e.choice;if(i&&a!==null&&oA(a))Ox(a,i).then((r)=>{if(r)Qw(a);x()})},reset:()=>{e.choice.filter=e.images?"image":"all",e.choice.query="",v(e)},select:(t)=>N(e,t),setFilter:(t)=>{if(re(t))e.choice.filter=t,v(e)},setQuery:(t)=>{e.choice.query=t,v(e)},setSort:(t)=>{if(ne(t))e.choice.sort=t,v(e)},tileHost:(t,i)=>{e.tiles.set(i,t),je.set(t,i),e.observer.observe(t)},upload:(t)=>{let i=[...t.files??[]];if(t.value="",i.length>0)he(e,i)}}}function Te(e){if("clipboard"in navigator)navigator.clipboard.writeText(e.ref)}var I=null;function et(e,t,i,a){N(e,t);let r=wb(e);if(!r)return;I?.close();let o=(l,c,d,f={})=>({destructive:!1,disabled:!1,dividerAbove:!1,id:l,run:d,title:c,...f});I=zt({label:`${r.name} actions`,onClosed:(l)=>{if(I===l)I=null},origin:{x:i,y:a},region:"media-tile",rows:[o("open","Open in Viewer",()=>Zu(t)),...XS(t)?[o("edit","Edit Image",()=>tC(t))]:[],o("copy-url","Copy Site URL",()=>Te(r)),o("rename","Rename…",()=>{tN(t)},{dividerAbove:!0}),...QS()?[o("duplicate","Duplicate",()=>{nN(t)})]:[],o("replace","Replace…",()=>BP(t)),o("delete","Delete",()=>{eN(t)},{destructive:!0,dividerAbove:!0})]})}function ye(e,t){if(e.mode==="pick"){let i=wb(e);if(i)e.onPick?.(i);return}Zu(t)}function tt(e,t,i){let{files:a}=ke(e),r=q(a,{filter:e.choice.filter,query:e.choice.query,sort:e.choice.sort,unused:S}),o=r.findIndex((f)=>f.file===e.choice.selected),l=e.grid?le(Me(e.grid).width):1,c=o===-1?r.length>0?0:null:se(o,t,l,r.length,i),d=c===null?void 0:r[c];if(!d)return;N(e,d.file),e.tiles.get(d.file)?.focus()}var je=new WeakMap;function De(e,t,i,a,r,o){let l={choice:t,disposed:!1,dropActive:!1,grid:null,handle:null,images:r,inputs:{replace:new Set,upload:new Set},mode:e,observer:_p((c)=>{let d=je.get(c);if(d!==void 0&&!l.visible.has(d))l.visible.add(d),it(l)}),onPick:null,onSelect:null,paneId:a,reveal:null,revealFocus:!1,focusOwed:!1,region:i,sweepTimer:null,tiles:new Map,uploadDir:o,visible:new Set};return l}var G=new Set;function it(e){if(G.has(e))return;G.add(e),queueMicrotask(()=>{G.delete(e),v(e)})}function cS(e,t){let i=k.get(e);return i!==void 0&&i.tabId===t.id&&i.wrap.isConnected&&i.mount.handle!==null&&i.mount.handle.attached()}function vw(e){let t=k.get(e);if(!t)return;Z(t.mount),k.delete(e)}function JE(e,t){let{paneId:i,wrap:a}=e;if(cS(i,t))return;vw(i);let r=De("manage",y,Ln(i,"media-library"),i,!1,Ta);if(L.add(r),we(),r.handle=V(a,ee(r),Ne(r),{clear:!0}),k.set(i,{mount:r,tabId:t.id,wrap:a}),Q.delete(i))Ce(r)}async function Ce(e){await e.handle?.ready,He(e,!0)}function He(e,t=e.focusOwed){if(!t||e.disposed)return;let{selected:i}=e.choice,a=(i===null?void 0:e.tiles.get(i))??[...e.tiles.values()].find((r)=>r.getAttribute("tabindex")==="0");if(a?.isConnected){e.focusOwed=!1,a.focus();return}e.focusOwed=!0}function YE(e){let t=k.get(e);if(t?.wrap.isConnected&&t.mount.handle?.attached()===!0){Ce(t.mount);return}Q.add(e)}function HP(e){if(e.filter!==void 0)y.filter=e.filter;if(e.query!==void 0)y.query=e.query;if(e.select!==void 0){if(y.selected=e.select,y.filter!=="all")y.filter="all";y.query=""}x()}function hF(){let e=[...k.values()].map((t)=>$e(t.mount.inputs.upload)).find((t)=>t!==null)??null;if(e){te(e);return}D={file:null,role:"upload"}}function BP(e){HP({select:e});let t=null;for(let i of k.values())if(i.mount.choice.selected===e)t??=$e(i.mount.inputs.replace);if(t){te(t);return}D={file:e,role:"replace"}}var z=null;function be(e){let t=wb(e);return{blocked:t===null,confirmLabel:t?`Use ${t.name}`:e.images?"Use image":"Use file",headline:e.images?"Choose an image":"Choose media"}}function dS(){let e=z;if(z=null,e)Z(e.mount),e.dialog.close()}function pF(e){dS();let t={filter:e.images?"image":"all",query:"",selected:null,sort:"newest"},i=De("pick",t,`${vt("dialog",B)}/library`,null,e.images,J$(h.value?.documentPath??null)),a=(o)=>{dS(),e.onPick(o.ref)};i.onPick=a,L.add(i),we();let r=fe({body:(o)=>{i.handle=V(o,ee(i),Ne(i),{clear:!1})},closed:()=>{if(z?.mount===i)dS();else Z(i)},confirm:()=>{let o=wb(i);if(o)a(o)},layer:dt("dialog"),view:be(i)});i.onSelect=()=>r.update(be(i)),z={dialog:r,mount:i}}function ZE(){dS();for(let e of k.keys())vw(e);y.filter="all",y.query="",y.selected=null,y.sort="newest",D=null,Q.clear(),J()}
|
|
2
2
|
export{lS,uF,wb,eN,tN,nN,cS,vw,JE,YE,HP,hF,BP,dS,pF,ZE};
|
|
3
3
|
|
|
4
4
|
//# debugId=676C28E656FDAB3164756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-
|
|
5
|
+
//# sourceMappingURL=studio-2x972v58.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{St,ti,Se,Fe,xh,m,Si,Ft}from"./studio-yrcrncev.js";import{p}from"./studio-4fnb5648.js";import{jt,fn}from"./studio-aam8zt8z.js";import{Zs,dt}from"./studio-tpxcryf2.js";import{Ls,Ud}from"./studio-bct64zmj.js";import{Fd,WT,BS,UT,qT}from"./studio-e7vjyp04.js";import{Nb,ss,Yl,Ww,Vw,Lp,Qo,$p}from"./studio-thz5t120.js";import{C}from"./studio-4f7thq0p.js";import{E,R}from"./studio-9dq7rwc7.js";import{g}from"./studio-3qr08sxq.js";import{n,Y,Q,wf}from"./studio-k3we3kqb.js";var T={$schema:"https://jxsuite.com/schema/v1",$id:"StudioGridOpen",$description:"Every grid-able source a project has, grouped by where it comes from: the project's own pages and content collections first, then each connection's tables. It is the ISLAND of a confirm dialog rather than a dialog of its own — `ui/layers.ts`'s dialog owns the headline, the cancel button, modality and focus, and this document is only the list — because a second answer to \"what is a dialog\" is a defect (studio-ui-guidelines.md §12.5). Group headings are why it is not the kit menu: a menu row can carry a divider above it and cannot carry a name for the run it opens.",tagName:"div",attributes:{part:"sources"},style:{display:"flex",flexDirection:"column",gap:"var(--jx-space-3)",minWidth:"280px",fontFamily:"var(--jx-font-sans)",fontSize:"var(--jx-text-md)",color:"var(--fg)",'& [part="group-title"]':{margin:"0",fontSize:"var(--jx-text-xs)",fontWeight:"600",textTransform:"uppercase",letterSpacing:"0.04em",color:"var(--fg-dim)"},'& [part="rows"]':{display:"flex",flexDirection:"column",gap:"1px",marginTop:"var(--jx-space-1)"},'& [part="source"]':{textAlign:"left",background:"none",border:"none",color:"var(--fg)",font:"inherit",padding:"var(--jx-space-2) var(--jx-space-2)",borderRadius:"var(--jx-radius-sm)",cursor:"pointer"},'& [part="source"]:hover':{background:"var(--bg-hover)"},'& [part="source"]:focus-visible':{outline:"var(--jx-focus-ring)",outlineOffset:"-2px"},'& [part="group-empty"]':{margin:"0",padding:"var(--jx-space-2)",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"}},children:[{$prototype:"Array",items:{$ref:"#/state/groups"},key:{$ref:"$map/item/key"},map:{$description:"One origin of grid-able sources. A connection with no tables says why it has none instead of drawing an empty box — an author who has not pushed a schema yet is exactly the reader who needs the sentence.",tagName:"section",attributes:{part:"group","data-group":"${$map.item.key}"},children:[{tagName:"h3",attributes:{part:"group-title"},textContent:"${$map.item.title}"},{tagName:"div",attributes:{part:"rows"},$switch:{$ref:"$map/item/state"},cases:{listed:{tagName:"div",attributes:{part:"rows-list",role:"none"},style:{display:"contents"},children:[{$prototype:"Array",items:{$ref:"$map/item/rows"},key:{$ref:"$map/item/id"},map:{tagName:"button",attributes:{part:"source",type:"button","data-source":"${$map.item.id}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/open"},value:[{$ref:"$map/item/id"}]}]},textContent:"${$map.item.label}"}}]},empty:{tagName:"p",attributes:{part:"group-empty"},textContent:"${$map.item.emptyMessage}"}}}]}}]};E("grid-open",T);function j(e,r,t){let o=g({groups:r,open:t}),i=null,s=!1,c=R("grid-open",o,e).then((y)=>{let a=y.root;if(s)return y.dispose(),a;return i=y,a});return{dispose(){s=!0,i?.dispose(),i=null},ready:c}}function x(){try{return p()}catch{return null}}function FS(){return Q(x()?.dataRows)}async function I(){let e=x();if(!Q(e?.dataConnections))return null;return e.dataConnections()}async function jN(e){let r=x();if(!Q(r?.dataConnectionTest))return{error:"Connection tests are not supported by this backend",ok:!1};try{return await r.dataConnectionTest(e)}catch(t){return{error:t instanceof Error?t.message:String(t),ok:!1}}}async function jT(e){let r=x();if(!Q(r?.dataPush))return{applied:!1,errors:["Schema push is not supported by this backend"],plan:[]};try{return await r.dataPush(e)}catch(t){return{applied:!1,errors:[t instanceof Error?t.message:String(t)],plan:[]}}}function k(e){let t=x()?.[e];if(t===void 0)throw Error(`The ${String(e)} surface is not supported by this backend`);return t}function v(e){return k("dataRows")(e)}function K(e){return k("dataInsertRow")(e)}function M(e){return k("dataUpdateRow")(e)}function O(e){return k("dataDeleteRow")(e)}function HN(e,r,t){let o=(c)=>c.replaceAll(/([a-z0-9])([A-Z])/g,"$1_$2").replaceAll(/[^A-Za-z0-9]+/g,"_").replaceAll(/^_+|_+$/g,"").toUpperCase(),s=[r??e,t.replace(/Env$/,"")].flatMap((c)=>{let y=o(c);return y?[y]:[]}).join("_")||"SECRET";return/^\d/.test(s)?`JX_${s}`:s}var H=["id","sku","slug","Slug"];function L(e){let r=new Set;return e.map((t,o)=>{let i=t.trim()===""?`column${o+1}`:t;if(r.has(i))i=`${i}__${o+1}`;return r.add(i),i})}function J(e,r){for(let t of H){let o=e.indexOf(t);if(o===-1)continue;let i=r.rows.map((s)=>s[o]??"");if(i.every((s)=>s!=="")&&new Set(i).size===i.length)return t}return null}function A(e,r){let t=Fd(e),o=L(t.headers),i=J(o,t),s=i?o.indexOf(i):-1,c=t.rows.map((d,u)=>s===-1?String(u):d[s]),y=new Map(c.map((d,u)=>[d,u])),a=xh(r,C?.projectConfig),l=a?.schema.properties??{},b=t.rows.slice(0,50).map((d)=>{let u={};for(let[S,G]of o.entries())u[G]=d[S]??"";return u}),f=new Map(Vw(b).map((d)=>[d.field,d])),w=new Map(Ww(a?.schema,{idField:i??void 0}).map((d)=>[d.field,d]));return{columns:o.map((d,u)=>{let G=(d in l?w.get(d):void 0)??f.get(d)??{editable:!0,field:d,kind:"string",title:t.headers[u]||d};return{...G,pk:d===i,title:t.headers[u]?.trim()||G.title}}),doc:t,fields:o,keys:c,keyToIndex:y,loadText:e}}function z(e,r){let t={},o=e.doc.rows[r]??[];for(let[i,s]of e.fields.entries()){let c=e.columns[i],y=o[i]??"";t[s]=c.kind==="string"||c.kind==="text"||c.kind==="readonly"?y:Lp(y,c)}return t}function F(e,r){let t=e.doc.rows.map((s)=>[...s]),o=(s)=>e.fields.indexOf(s);for(let s of r.cells){let c=e.keyToIndex.get(s.rowKey),y=o(s.field);if(c===void 0||y===-1)continue;t[c][y]=Qo(s.value)}for(let s of r.inserts){let c=e.fields.map((y)=>Qo(s.cells[y]??null));t.push(c)}let i=r.deletes.map((s)=>e.keyToIndex.get(s.rowKey)).filter((s)=>s!==void 0).toSorted((s,c)=>c-s);for(let s of i)t.splice(s,1);return{...e.doc,rows:t}}function _(e,r){return{cells:e.cells.map((t)=>({field:t.field,rowKey:t.rowKey,...r})),deletes:e.deletes.map((t)=>({rowKey:t.rowKey,...r})),inserts:e.inserts.map((t)=>({error:r.error,ok:r.ok,tempKey:t.tempKey}))}}function jS(e){let r=null,t=(o=!1)=>{if(!o&&r)return r;return r=p().readFile(e).then((i)=>A(i,e)),r};return{backingPaths:()=>new Map([[e,"*"]]),capabilities:{delete:!0,insert:!0,remotePaging:!1,remoteSort:!1},async columns(){return(await t()).columns},async commit(o){let i=await t(),s=p(),c=null;try{c=await s.readFile(e)}catch{c=null}if(c!==i.loadText&&!Ud(e))return _(o,{error:"File changed on disk — refresh to reload",ok:!1,stale:!0});let y=F(i,o),a=WT(y);return Ls(e),await s.writeFile(e,a),r=Promise.resolve(A(a,e)),_(o,{ok:!0})},id:e,label:e.split("/").pop()??e,async refresh(){await t(!0)},async rows(){let o=await t(),i=o.doc.rows.map((s,c)=>({cells:z(o,c),key:o.keys[c]}));return{rows:i,total:i.length}},async serializeForSource(o){let i=await t();return WT(F(i,o))}}}var U=50;function q(e){let r=e.toLowerCase();if(/(int|real|floa|doub|num|dec)/.test(r))return"number";if(r.includes("bool"))return"boolean";if(/(timestamp|datetime|date)/.test(r))return"date";return"string"}function Z(e){return!e.pk&&e.name!=="created_at"&&e.name!=="updated_at"}function W(e){if(e===void 0)return null;if(wf(e))return e;return JSON.stringify(e)}function N(e,r){let t=[],o="id",i=new Map,s=(a)=>{if(a.length>0)t=a,o=a.find((l)=>l.pk)?.name??"id"},c=(a)=>{let l={table:r};if(e)l.connection=e;if(l.limit=a?.limit??U,l.offset=a?.offset??0,a?.orderBy)l.dir=a.dir??"asc",l.orderBy=a.orderBy;return l},y=(a,l)=>{let b=a[o];if(n(b)||Y(b))return i.set(String(b),b),String(b);return`row-${l}`};return{capabilities:{delete:!0,insert:!0,remotePaging:!0,remoteSort:!0},async columns(){if(t.length===0){let a=await v(c({limit:1,offset:0}));s(a.columns)}return t.map((a)=>{let l=Z(a)?q(a.type):"readonly";return{editable:l!=="readonly",field:a.name,kind:l,pk:a.pk===!0,title:a.name,widthHint:a.pk?80:void 0}})},async commit(a){let l={cells:[],deletes:[],inserts:[]},b=new Map;for(let f of a.cells){let w=b.get(f.rowKey)??[];w.push({field:f.field,value:f.value}),b.set(f.rowKey,w)}for(let[f,w]of b){let h=i.get(f),d=(u,S)=>{for(let G of w)l.cells.push({error:S,field:G.field,ok:u,rowKey:f})};if(h===void 0){d(!1,"Row has no primary key — refresh the grid");continue}try{let u={};for(let G of w)u[G.field]=G.value;let S={pk:h,set:u,table:r};if(e)S.connection=e;await M(S),d(!0)}catch(u){d(!1,u instanceof Error?u.message:String(u))}}for(let f of a.inserts)try{let w={};for(let[G,P]of Object.entries(f.cells))if(P!==null)w[G]=P;let h={table:r,values:w};if(e)h.connection=e;let{row:d}=await K(h),u=d[o],S;if(n(u)||Y(u))S=String(u),i.set(S,u);l.inserts.push({newKey:S,ok:!0,tempKey:f.tempKey})}catch(w){l.inserts.push({error:w instanceof Error?w.message:String(w),ok:!1,tempKey:f.tempKey})}for(let f of a.deletes){let w=i.get(f.rowKey);if(w===void 0){l.deletes.push({error:"Row has no primary key — refresh the grid",ok:!1,rowKey:f.rowKey});continue}try{let h={pk:w,table:r};if(e)h.connection=e;await O(h),l.deletes.push({ok:!0,rowKey:f.rowKey})}catch(h){l.deletes.push({error:h instanceof Error?h.message:String(h),ok:!1,rowKey:f.rowKey})}}return l},id:ss({connection:e??"default",kind:"data",table:r}),label:r,async refresh(){t=[],i.clear()},async rows(a){let l=await v(c(a));return s(l.columns),{rows:l.rows.map((f,w)=>{let h=y(f,w),d={};for(let u of t)d[u.name]=W(f[u.name]);return{cells:d,key:h}}),total:l.total}}}}async function HT(e,r={}){let t=m.tabs.get(e);if(t)return Ft(e,{focus:r.focus!==!1}),t;try{await jt()}catch{}let o=jS(e),i=Si({capabilities:{modes:["grid","source"]},document:structuredClone(Nb),documentPath:e,id:e,sourceFormat:fn(e)?.name??null,...r.paneId!==void 0&&{paneId:r.paneId},...r.preview===!0&&{preview:!0},...r.focus===!1&&{focus:!1}});return $p(i,o).load(),i}function D(e){let r=Si({capabilities:{modes:["grid"]},document:structuredClone(Nb),documentPath:null,id:e.id});return $p(r,e).load(),r}function BN(e){let r=ss({kind:"collection",name:e}),t=m.tabs.get(r);if(t)return Ft(r),t;return D(UT(e))}function HS(){let e=ss({kind:"pages"}),r=m.tabs.get(e);if(r)return Ft(e),r;return D(qT())}function V(e,r){let t=ss({connection:e??"default",kind:"data",table:r}),o=m.tabs.get(t);if(o)return Ft(t),o;return D(N(e,r))}function X(e){let r=Yl(e);if(r?.kind==="pages")HS();else if(r?.kind==="collection")BN(r.name);else if(r?.kind==="data")V(r.connection,r.table)}function ee(e,r){return[{emptyMessage:"",key:"project",rows:[{id:ss({kind:"pages"}),label:"Pages"},...e.map(({name:t})=>({id:ss({kind:"collection",name:t}),label:`Collection: ${t}`}))],state:"listed",title:"Project"},...r.map((t)=>({emptyMessage:"No tables — push a schema first.",key:`data:${t.name}`,rows:t.tables.map((o)=>({id:ss({connection:t.name,kind:"data",table:o}),label:o})),state:t.tables.length===0?"empty":"listed",title:`Data · ${t.name}`}))]}async function BT(){let e=BS(),r=[];if(FS())r=(await I().catch(()=>null))?.connections??[];let t=null,o=Zs({cancelLabel:"Cancel",confirmLabel:"",headline:"Open Grid",island:(i)=>{t=j(i,ee(e,r),(s)=>{o.close(),X(s)})},layer:dt("dialog"),onCancel:()=>o.close(),onClosed:()=>{t?.dispose(),t=null},onConfirm:()=>{},region:"grid/open"});o.ready}function te(){return[{args:Se({name:Fe("The content collection's name, as project.json declares it.")}),category:"Project",id:"collection.editInGrid",level:"project",menus:["context/file","palette"],group:"5_data",requires:"a project that declares content collections",when:(e)=>e.project.open,run:(e,r)=>{let t=St("collection.editInGrid",r,"name"),o=BS().map((i)=>i.name);if(!o.includes(t))throw RangeError(`command "collection.editInGrid" argument "name": "${t}" is not a content `+"collection this project declares — it declares: "+`${o.length>0?o.join(", "):"none"}`);BN(t)},title:"Edit Collection in Grid"},{args:{additionalProperties:!1,properties:{connection:Fe('The connection name from project.json. Defaults to "default".'),table:Fe("The table to open.")},required:["table"],type:"object"},category:"Project",id:"data.openGrid",level:"project",menus:["palette"],group:"5_data",requires:"a platform that serves the data routes",when:(e)=>e.project.open,enablement:(e)=>e.capability.dataRows,run:(e,r)=>{let t=St("data.openGrid",r,"table");V(ti("data.openGrid",r,"connection"),t)},title:"Open Data Grid"}]}function zT(e){e.registerAll(te())}
|
|
1
|
+
import{St,ti,Se,Fe,xh,m,Si,Ft}from"./studio-knsjyx7n.js";import{p}from"./studio-4fnb5648.js";import{jt,fn}from"./studio-q9hx2qp0.js";import{Zs,dt}from"./studio-tpxcryf2.js";import{Ls,Ud}from"./studio-bnc50f9h.js";import{Fd,WT,BS,UT,qT}from"./studio-frc16j8v.js";import{Nb,ss,Yl,Ww,Vw,Lp,Qo,$p}from"./studio-hfqpfmpk.js";import{C}from"./studio-4f7thq0p.js";import{E,R}from"./studio-9dq7rwc7.js";import{g}from"./studio-3qr08sxq.js";import{n,Y,Q,wf}from"./studio-k3we3kqb.js";var T={$schema:"https://jxsuite.com/schema/v1",$id:"StudioGridOpen",$description:"Every grid-able source a project has, grouped by where it comes from: the project's own pages and content collections first, then each connection's tables. It is the ISLAND of a confirm dialog rather than a dialog of its own — `ui/layers.ts`'s dialog owns the headline, the cancel button, modality and focus, and this document is only the list — because a second answer to \"what is a dialog\" is a defect (studio-ui-guidelines.md §12.5). Group headings are why it is not the kit menu: a menu row can carry a divider above it and cannot carry a name for the run it opens.",tagName:"div",attributes:{part:"sources"},style:{display:"flex",flexDirection:"column",gap:"var(--jx-space-3)",minWidth:"280px",fontFamily:"var(--jx-font-sans)",fontSize:"var(--jx-text-md)",color:"var(--fg)",'& [part="group-title"]':{margin:"0",fontSize:"var(--jx-text-xs)",fontWeight:"600",textTransform:"uppercase",letterSpacing:"0.04em",color:"var(--fg-dim)"},'& [part="rows"]':{display:"flex",flexDirection:"column",gap:"1px",marginTop:"var(--jx-space-1)"},'& [part="source"]':{textAlign:"left",background:"none",border:"none",color:"var(--fg)",font:"inherit",padding:"var(--jx-space-2) var(--jx-space-2)",borderRadius:"var(--jx-radius-sm)",cursor:"pointer"},'& [part="source"]:hover':{background:"var(--bg-hover)"},'& [part="source"]:focus-visible':{outline:"var(--jx-focus-ring)",outlineOffset:"-2px"},'& [part="group-empty"]':{margin:"0",padding:"var(--jx-space-2)",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"}},children:[{$prototype:"Array",items:{$ref:"#/state/groups"},key:{$ref:"$map/item/key"},map:{$description:"One origin of grid-able sources. A connection with no tables says why it has none instead of drawing an empty box — an author who has not pushed a schema yet is exactly the reader who needs the sentence.",tagName:"section",attributes:{part:"group","data-group":"${$map.item.key}"},children:[{tagName:"h3",attributes:{part:"group-title"},textContent:"${$map.item.title}"},{tagName:"div",attributes:{part:"rows"},$switch:{$ref:"$map/item/state"},cases:{listed:{tagName:"div",attributes:{part:"rows-list",role:"none"},style:{display:"contents"},children:[{$prototype:"Array",items:{$ref:"$map/item/rows"},key:{$ref:"$map/item/id"},map:{tagName:"button",attributes:{part:"source",type:"button","data-source":"${$map.item.id}"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/open"},value:[{$ref:"$map/item/id"}]}]},textContent:"${$map.item.label}"}}]},empty:{tagName:"p",attributes:{part:"group-empty"},textContent:"${$map.item.emptyMessage}"}}}]}}]};E("grid-open",T);function j(e,r,t){let o=g({groups:r,open:t}),i=null,s=!1,c=R("grid-open",o,e).then((y)=>{let a=y.root;if(s)return y.dispose(),a;return i=y,a});return{dispose(){s=!0,i?.dispose(),i=null},ready:c}}function x(){try{return p()}catch{return null}}function FS(){return Q(x()?.dataRows)}async function I(){let e=x();if(!Q(e?.dataConnections))return null;return e.dataConnections()}async function jN(e){let r=x();if(!Q(r?.dataConnectionTest))return{error:"Connection tests are not supported by this backend",ok:!1};try{return await r.dataConnectionTest(e)}catch(t){return{error:t instanceof Error?t.message:String(t),ok:!1}}}async function jT(e){let r=x();if(!Q(r?.dataPush))return{applied:!1,errors:["Schema push is not supported by this backend"],plan:[]};try{return await r.dataPush(e)}catch(t){return{applied:!1,errors:[t instanceof Error?t.message:String(t)],plan:[]}}}function k(e){let t=x()?.[e];if(t===void 0)throw Error(`The ${String(e)} surface is not supported by this backend`);return t}function v(e){return k("dataRows")(e)}function K(e){return k("dataInsertRow")(e)}function M(e){return k("dataUpdateRow")(e)}function O(e){return k("dataDeleteRow")(e)}function HN(e,r,t){let o=(c)=>c.replaceAll(/([a-z0-9])([A-Z])/g,"$1_$2").replaceAll(/[^A-Za-z0-9]+/g,"_").replaceAll(/^_+|_+$/g,"").toUpperCase(),s=[r??e,t.replace(/Env$/,"")].flatMap((c)=>{let y=o(c);return y?[y]:[]}).join("_")||"SECRET";return/^\d/.test(s)?`JX_${s}`:s}var H=["id","sku","slug","Slug"];function L(e){let r=new Set;return e.map((t,o)=>{let i=t.trim()===""?`column${o+1}`:t;if(r.has(i))i=`${i}__${o+1}`;return r.add(i),i})}function J(e,r){for(let t of H){let o=e.indexOf(t);if(o===-1)continue;let i=r.rows.map((s)=>s[o]??"");if(i.every((s)=>s!=="")&&new Set(i).size===i.length)return t}return null}function A(e,r){let t=Fd(e),o=L(t.headers),i=J(o,t),s=i?o.indexOf(i):-1,c=t.rows.map((d,u)=>s===-1?String(u):d[s]),y=new Map(c.map((d,u)=>[d,u])),a=xh(r,C?.projectConfig),l=a?.schema.properties??{},b=t.rows.slice(0,50).map((d)=>{let u={};for(let[S,G]of o.entries())u[G]=d[S]??"";return u}),f=new Map(Vw(b).map((d)=>[d.field,d])),w=new Map(Ww(a?.schema,{idField:i??void 0}).map((d)=>[d.field,d]));return{columns:o.map((d,u)=>{let G=(d in l?w.get(d):void 0)??f.get(d)??{editable:!0,field:d,kind:"string",title:t.headers[u]||d};return{...G,pk:d===i,title:t.headers[u]?.trim()||G.title}}),doc:t,fields:o,keys:c,keyToIndex:y,loadText:e}}function z(e,r){let t={},o=e.doc.rows[r]??[];for(let[i,s]of e.fields.entries()){let c=e.columns[i],y=o[i]??"";t[s]=c.kind==="string"||c.kind==="text"||c.kind==="readonly"?y:Lp(y,c)}return t}function F(e,r){let t=e.doc.rows.map((s)=>[...s]),o=(s)=>e.fields.indexOf(s);for(let s of r.cells){let c=e.keyToIndex.get(s.rowKey),y=o(s.field);if(c===void 0||y===-1)continue;t[c][y]=Qo(s.value)}for(let s of r.inserts){let c=e.fields.map((y)=>Qo(s.cells[y]??null));t.push(c)}let i=r.deletes.map((s)=>e.keyToIndex.get(s.rowKey)).filter((s)=>s!==void 0).toSorted((s,c)=>c-s);for(let s of i)t.splice(s,1);return{...e.doc,rows:t}}function _(e,r){return{cells:e.cells.map((t)=>({field:t.field,rowKey:t.rowKey,...r})),deletes:e.deletes.map((t)=>({rowKey:t.rowKey,...r})),inserts:e.inserts.map((t)=>({error:r.error,ok:r.ok,tempKey:t.tempKey}))}}function jS(e){let r=null,t=(o=!1)=>{if(!o&&r)return r;return r=p().readFile(e).then((i)=>A(i,e)),r};return{backingPaths:()=>new Map([[e,"*"]]),capabilities:{delete:!0,insert:!0,remotePaging:!1,remoteSort:!1},async columns(){return(await t()).columns},async commit(o){let i=await t(),s=p(),c=null;try{c=await s.readFile(e)}catch{c=null}if(c!==i.loadText&&!Ud(e))return _(o,{error:"File changed on disk — refresh to reload",ok:!1,stale:!0});let y=F(i,o),a=WT(y);return Ls(e),await s.writeFile(e,a),r=Promise.resolve(A(a,e)),_(o,{ok:!0})},id:e,label:e.split("/").pop()??e,async refresh(){await t(!0)},async rows(){let o=await t(),i=o.doc.rows.map((s,c)=>({cells:z(o,c),key:o.keys[c]}));return{rows:i,total:i.length}},async serializeForSource(o){let i=await t();return WT(F(i,o))}}}var U=50;function q(e){let r=e.toLowerCase();if(/(int|real|floa|doub|num|dec)/.test(r))return"number";if(r.includes("bool"))return"boolean";if(/(timestamp|datetime|date)/.test(r))return"date";return"string"}function Z(e){return!e.pk&&e.name!=="created_at"&&e.name!=="updated_at"}function W(e){if(e===void 0)return null;if(wf(e))return e;return JSON.stringify(e)}function N(e,r){let t=[],o="id",i=new Map,s=(a)=>{if(a.length>0)t=a,o=a.find((l)=>l.pk)?.name??"id"},c=(a)=>{let l={table:r};if(e)l.connection=e;if(l.limit=a?.limit??U,l.offset=a?.offset??0,a?.orderBy)l.dir=a.dir??"asc",l.orderBy=a.orderBy;return l},y=(a,l)=>{let b=a[o];if(n(b)||Y(b))return i.set(String(b),b),String(b);return`row-${l}`};return{capabilities:{delete:!0,insert:!0,remotePaging:!0,remoteSort:!0},async columns(){if(t.length===0){let a=await v(c({limit:1,offset:0}));s(a.columns)}return t.map((a)=>{let l=Z(a)?q(a.type):"readonly";return{editable:l!=="readonly",field:a.name,kind:l,pk:a.pk===!0,title:a.name,widthHint:a.pk?80:void 0}})},async commit(a){let l={cells:[],deletes:[],inserts:[]},b=new Map;for(let f of a.cells){let w=b.get(f.rowKey)??[];w.push({field:f.field,value:f.value}),b.set(f.rowKey,w)}for(let[f,w]of b){let h=i.get(f),d=(u,S)=>{for(let G of w)l.cells.push({error:S,field:G.field,ok:u,rowKey:f})};if(h===void 0){d(!1,"Row has no primary key — refresh the grid");continue}try{let u={};for(let G of w)u[G.field]=G.value;let S={pk:h,set:u,table:r};if(e)S.connection=e;await M(S),d(!0)}catch(u){d(!1,u instanceof Error?u.message:String(u))}}for(let f of a.inserts)try{let w={};for(let[G,P]of Object.entries(f.cells))if(P!==null)w[G]=P;let h={table:r,values:w};if(e)h.connection=e;let{row:d}=await K(h),u=d[o],S;if(n(u)||Y(u))S=String(u),i.set(S,u);l.inserts.push({newKey:S,ok:!0,tempKey:f.tempKey})}catch(w){l.inserts.push({error:w instanceof Error?w.message:String(w),ok:!1,tempKey:f.tempKey})}for(let f of a.deletes){let w=i.get(f.rowKey);if(w===void 0){l.deletes.push({error:"Row has no primary key — refresh the grid",ok:!1,rowKey:f.rowKey});continue}try{let h={pk:w,table:r};if(e)h.connection=e;await O(h),l.deletes.push({ok:!0,rowKey:f.rowKey})}catch(h){l.deletes.push({error:h instanceof Error?h.message:String(h),ok:!1,rowKey:f.rowKey})}}return l},id:ss({connection:e??"default",kind:"data",table:r}),label:r,async refresh(){t=[],i.clear()},async rows(a){let l=await v(c(a));return s(l.columns),{rows:l.rows.map((f,w)=>{let h=y(f,w),d={};for(let u of t)d[u.name]=W(f[u.name]);return{cells:d,key:h}}),total:l.total}}}}async function HT(e,r={}){let t=m.tabs.get(e);if(t)return Ft(e,{focus:r.focus!==!1}),t;try{await jt()}catch{}let o=jS(e),i=Si({capabilities:{modes:["grid","source"]},document:structuredClone(Nb),documentPath:e,id:e,sourceFormat:fn(e)?.name??null,...r.paneId!==void 0&&{paneId:r.paneId},...r.preview===!0&&{preview:!0},...r.focus===!1&&{focus:!1}});return $p(i,o).load(),i}function D(e){let r=Si({capabilities:{modes:["grid"]},document:structuredClone(Nb),documentPath:null,id:e.id});return $p(r,e).load(),r}function BN(e){let r=ss({kind:"collection",name:e}),t=m.tabs.get(r);if(t)return Ft(r),t;return D(UT(e))}function HS(){let e=ss({kind:"pages"}),r=m.tabs.get(e);if(r)return Ft(e),r;return D(qT())}function V(e,r){let t=ss({connection:e??"default",kind:"data",table:r}),o=m.tabs.get(t);if(o)return Ft(t),o;return D(N(e,r))}function X(e){let r=Yl(e);if(r?.kind==="pages")HS();else if(r?.kind==="collection")BN(r.name);else if(r?.kind==="data")V(r.connection,r.table)}function ee(e,r){return[{emptyMessage:"",key:"project",rows:[{id:ss({kind:"pages"}),label:"Pages"},...e.map(({name:t})=>({id:ss({kind:"collection",name:t}),label:`Collection: ${t}`}))],state:"listed",title:"Project"},...r.map((t)=>({emptyMessage:"No tables — push a schema first.",key:`data:${t.name}`,rows:t.tables.map((o)=>({id:ss({connection:t.name,kind:"data",table:o}),label:o})),state:t.tables.length===0?"empty":"listed",title:`Data · ${t.name}`}))]}async function BT(){let e=BS(),r=[];if(FS())r=(await I().catch(()=>null))?.connections??[];let t=null,o=Zs({cancelLabel:"Cancel",confirmLabel:"",headline:"Open Grid",island:(i)=>{t=j(i,ee(e,r),(s)=>{o.close(),X(s)})},layer:dt("dialog"),onCancel:()=>o.close(),onClosed:()=>{t?.dispose(),t=null},onConfirm:()=>{},region:"grid/open"});o.ready}function te(){return[{args:Se({name:Fe("The content collection's name, as project.json declares it.")}),category:"Project",id:"collection.editInGrid",level:"project",menus:["context/file","palette"],group:"5_data",requires:"a project that declares content collections",when:(e)=>e.project.open,run:(e,r)=>{let t=St("collection.editInGrid",r,"name"),o=BS().map((i)=>i.name);if(!o.includes(t))throw RangeError(`command "collection.editInGrid" argument "name": "${t}" is not a content `+"collection this project declares — it declares: "+`${o.length>0?o.join(", "):"none"}`);BN(t)},title:"Edit Collection in Grid"},{args:{additionalProperties:!1,properties:{connection:Fe('The connection name from project.json. Defaults to "default".'),table:Fe("The table to open.")},required:["table"],type:"object"},category:"Project",id:"data.openGrid",level:"project",menus:["palette"],group:"5_data",requires:"a platform that serves the data routes",when:(e)=>e.project.open,enablement:(e)=>e.capability.dataRows,run:(e,r)=>{let t=St("data.openGrid",r,"table");V(ti("data.openGrid",r,"connection"),t)},title:"Open Data Grid"}]}function zT(e){e.registerAll(te())}
|
|
2
2
|
export{FS,jN,jT,HN,jS,HT,BN,HS,BT,zT};
|
|
3
3
|
|
|
4
4
|
//# debugId=67AF438E9428C4A664756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-
|
|
5
|
+
//# sourceMappingURL=studio-2zz4qbv9.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{X}from"./studio-9c6cbq2c.js";import{p,ye}from"./studio-4fnb5648.js";import{Lh,w}from"./studio-sce30r7b.js";import{mi}from"./studio-nvcn2ykc.js";import{ea,Zd,m,bl,wI}from"./studio-
|
|
1
|
+
import{X}from"./studio-9c6cbq2c.js";import{p,ye}from"./studio-4fnb5648.js";import{Lh,w}from"./studio-sce30r7b.js";import{mi}from"./studio-nvcn2ykc.js";import{ea,Zd,m,bl,wI}from"./studio-knsjyx7n.js";import{qd,La,lv}from"./studio-4zd6an2b.js";import{Ox,fl,Vm}from"./studio-61rg2cz5.js";import{YI,w1,b0,v0,ZI,ad,x1,vf,Uv,y0,w0,Fh,qv,hg,_1,XI,u2,h2,p2,QI,f2,eR,x0,m2,g2,b2}from"./studio-1410q5dw.js";import{C}from"./studio-4f7thq0p.js";import{Ln}from"./studio-9dq7rwc7.js";import{me,te,g,le}from"./studio-3qr08sxq.js";import{Y}from"./studio-k3we3kqb.js";import{ce}from"./studio-0939t1q1.js";var ls="image",D=[320,640,960,1280,1920],A=null,H=null;function B(){return A??=(ce("x7t8jbjn"),import("./image-editor-x7t8jbjn.js")),A}function W(){return H??=(ce("4afr4y6a"),import("./image-bake-4afr4y6a.js")),H}var E=new WeakMap;function x(t){return E.get(le(t))}function _(t){let e=le(t),r=E.get(e);if(!r){r=g({decoded:!1,generation:0,history:x0(),live:null,message:"Reading the image…",saving:!1,size:null,source:null,status:"loading",typed:!1}),E.set(e,r);let i=F(r);Zd(e,i),Zd(t,i)}return r}function F(t){return{canRedo:()=>!t.saving&&t.history.future.length>0,canUndo:()=>!t.saving&&t.history.past.length>0,redo:()=>{if(!t.saving)t.history=b2(t.history)},undo:()=>{if(!t.saving)t.history=g2(t.history)}}}function h(t){return t.live??t.history.present}function M(t,e,r){let i=t.source;if(t.source={bytes:e,url:URL.createObjectURL(new Blob([e],{type:r}))},t.status="ready",t.message="",i!==null)URL.revokeObjectURL(i.url)}function U(t){if(t.source!==null)URL.revokeObjectURL(t.source.url),t.source=null,t.status="loading"}async function R(t,e){if(t.source!==null)return;t.generation+=1;let{generation:r}=t;t.status="loading",t.message="Reading the image…";let i=ye()?p():null,u=i?.readFileBytes;if(u===void 0){t.status="refused",t.message="This backend cannot hand Studio a file's raw bytes, so it cannot edit one.";return}let o;try{o=new Uint8Array(await u.call(i,e))}catch(a){if(t.generation===r)t.status="refused",t.message=`Could not read ${e}: ${a instanceof Error?a.message:String(a)}`;return}if(t.generation!==r)return;let n=v0(e,o);if(n!==null){t.status="refused",t.message=n;return}t.size??=YI(o).size,M(t,o,w1(e)??"")}function al(t){let e=x(t),r=e?.size;if(e===void 0||r===null||r===void 0)return!1;return e.typed||!x1(h(e),r)}function P(t,e){t.live=null,t.history=m2(t.history,e)}var v=new Map;function LL(t,e){let r=v.get(t);return r!==void 0&&le(r.tab)===le(e)&&r.wrap.isConnected&&(r.surface===null||r.surface.attached())}function Xw(t){let e=v.get(t);if(!e)return;e.disposed=!0,e.scope.stop(),e.surface?.dispose(),v.delete(t);let r=x(e.tab);if(e.drag!==null&&r!==void 0)r.live=null;if(r!==void 0&&S(e.tab).length===0)r.typed=!1;if(S(e.tab).length===0&&r!==void 0&&!r.saving)U(r),r.generation+=1}function j(t){if(t.rows.length===0||t.rows.find((e)=>e.tabindex==="0")?.id!==t.active)t.rows=hg.map((e)=>({id:e,label:_1[e],tabindex:e===t.active?"0":"-1"}));return t.rows}function y(t){return`${Number(t.toFixed(4))}%`}function O(){let e=C?.projectConfig?.images?.widths;return Array.isArray(e)&&e.length>0&&e.every((r)=>Y(r))?e:D}var q=ZI.map(({id:t,label:e})=>({label:e,value:t}));function b(t,e){let r=t.tab.documentPath??"",i=r.split("/").pop()??r,u=h(e),o=e.size??{height:1,width:1},n=Fh(u.turns,o),a=qv(ad(u,o),u,o),l=Uv(u,o),c=y0(u,o),s=eR(u,o,O()),f=w1(r)??"",d=e.source!==null&&e.decoded&&e.size!==null,I=d&&(e.typed||!x1(u,o)),T=vf(u.turns);return{alt:`${i}, being edited`,aspect:u.aspect,aspectOptions:q,brightness:String(u.brightness),busy:e.saving||!d,undecoded:!d,cannotFit:e.saving||!d||s===null||s===c.width,cannotRedo:e.saving||e.history.future.length===0,cannotSave:e.saving||!I||ea(t.tab),cannotUndo:e.saving||e.history.past.length===0,clean:e.saving||!I,contrast:String(u.contrast),cropH:y(a.height/n.height*100),cropW:y(a.width/n.width*100),cropX:y(a.x/n.width*100),cropY:y(a.y/n.height*100),facts:d?`Output ${c.width} × ${c.height} · crop ${l.width} × ${l.height} · source ${o.width} × ${o.height}`:"",filter:w0(u)||"none",fitHint:s===null?"Already no wider than the largest width the build derives.":"The largest of the project's image widths (images.widths, or the build's defaults) below this crop.",fitLabel:s===null?"Fit for web":`Fit for web (${s} px)`,handleHelpId:`${Ln(t.paneId,"image")}/handle-help`,handles:j(t),imageHeight:T?y(o.height/n.height*100):"100%",imageTransform:`translate(-50%, -50%) scale(${u.flipH?-1:1}, ${u.flipV?-1:1}) rotate(${u.turns*90}deg)`,imageWidth:T?y(o.width/n.width*100):"100%",maxOutputWidth:String(l.width),maxWidth:`${n.width}px`,message:e.message,moveCursor:u.crop===null?"default":"move",name:i,quality:b0(f)?"shown":"hidden",qualityValue:String(u.quality),ratio:String(n.width/n.height),region:Ln(t.paneId,"image"),saturation:String(u.saturation),saving:e.saving,src:e.source?.url??"",status:e.status,warning:`Save overwrites ${r} and keeps no backup. Source control is how to get the original back.`,width:String(c.width)}}function N(t,e,r){let i=qv(ad(e,r),e,r);Lh(`${_1[t]}: crop ${i.width} × ${i.height} at ${i.x}, ${i.y}`)}function z(t){return hg.some((e)=>e===t)}function V(t,e){let r=()=>e.source===null||!e.decoded?null:e.size,i=()=>t.surface?.syncFields(b(t,e)),u=F(e),o=(n)=>{let a=r();if(a!==null&&!e.saving)P(e,n(h(e),a))};return{cycleHandle:(n,a)=>{if(!z(n))return;let l=hg.indexOf(n),c=a<0?-1:1,s=hg[(l+c+hg.length)%hg.length];t.active=s,t.surface?.update(b(t,e)),t.surface?.focusHandle(s),Lh(_1[s])},fieldEdited:()=>{e.typed=!0},fitForWeb:()=>{o((n,a)=>{let l=eR(n,a,O());return l===null?n:QI(n,a,l)})},flip:(n)=>{o((a)=>p2(a,n==="v"?"v":"h"))},handleDown:(n,a,l,c,s)=>{let f=r(),d=t.surface?.frameRect();if(f===null||!z(n)||!d||d.width<=0||e.saving)return;s.setPointerCapture(a),t.active=n,t.drag={handle:n,pointerId:a,scale:Fh(h(e).turns,f).width/d.width,start:h(e),startX:l,startY:c}},handleFocused:(n)=>{if(z(n)&&t.active!==n)t.active=n,t.surface?.update(b(t,e))},handleMove:(n,a,l)=>{let{drag:c}=t,s=r();if(c===null||c.pointerId!==n||s===null||e.saving)return;e.live=XI(c.start,s,c.handle,(a-c.startX)*c.scale,(l-c.startY)*c.scale)},handleUp:(n)=>{let{drag:a}=t;if(a===null||a.pointerId!==n)return;if(t.drag=null,e.live!==null)P(e,e.live)},imageFailed:(n)=>{if(e.source?.url!==n)return;U(e),e.status="refused",e.message=`${t.tab.documentPath??"This file"} could not be decoded, so it cannot be edited.`},imageLoaded:(n,a)=>{if(e.source===null||!(n>0&&a>0))return;if(e.decoded=!0,e.size?.width!==n||e.size.height!==a)e.size={height:a,width:n};fl(t.tab.documentPath??"",n,a)},nudge:(n,a,l,c)=>{let s=r();if(s===null||!z(n)||e.saving)return;let f=c?10:1,d=XI(h(e),s,n,a*f,l*f);P(e,d),N(n,d,s)},redo:()=>{u.redo(t.tab)},reset:()=>{o(()=>x0().present)},rotate:(n)=>{o((a)=>h2(a,n<0?-1:1))},save:()=>{$L(t.tab)},setAspect:(n)=>{let a=ZI.find((l)=>l.id===n);if(a)o((l,c)=>u2(l,c,a.id))},setValue:(n,a)=>{if(a.trim()!==""&&(n==="brightness"||n==="contrast"||n==="saturation"||n==="quality"))o((l)=>f2(l,n,Number(a)));e.typed=!1,i()},setWidth:(n)=>{o((a,l)=>QI(a,l,n.trim()===""?null:Number(n))),e.typed=!1,i()},undo:()=>{u.undo(t.tab)}}}function iA(t,e){let{paneId:r,wrap:i}=t;if(LL(r,e))return;Xw(r);let u=_(e),o={active:"nw",disposed:!1,drag:null,paneId:r,rows:[],scope:me(),surface:null,tab:e,wrap:i};v.set(r,o),R(u,e.documentPath??""),B().then(({mountImageEditorSurface:n})=>{if(o.disposed)return;o.surface=n(i,b(o,u),V(o,u)),o.scope.run(()=>{te(()=>{if(!o.disposed)o.surface?.update(b(o,u))})})})}async function Q(t,e){if(t.source===null)await R(t,e);if(t.source===null&&t.status==="loading")await R(t,e);return t.source}function S(t){let e=le(t);return[...v.values()].filter((r)=>le(r.tab)===e)}async function $L(t){let e=t.documentPath??"",r=e.split("/").pop()??e;if(ea(t))return w.warn(`You have read access to this session — the edit to ${r} stays in your browser and cannot be saved.`,{key:`image.readOnly:${e}`,path:e,source:"Collaboration"}),!1;let i=x(t);if(i===void 0||i.saving)return i===void 0;for(let u of S(t))u.surface?.flushFields(),u.drag=null;if(i.typed=!1,i.live!==null)P(i,i.live);i.saving=!0;try{let{size:u}=i,o=h(i);if(u===null||x1(o,u))return w.info(`${r} has no changes, so nothing was written.`,{key:`image.identity:${e}`}),!0;let n=(k)=>(w.error(`Could not save ${r}.`,{detail:k,path:e,source:"Image"}),!1),a=await Q(i,e);if(a===null)return n(i.message);let l=w1(e)??"",{bakeImage:c}=await W(),s;try{s=await c(o,a.bytes,l)}catch(k){return n(`The browser could not process this image: ${X(k)}`)}if(!s.ok)return n(s.reason);if(!bl(t))return!1;if(t.documentPath!==e)return n("It was renamed while saving, so the edit was not written to its old name.");let{blob:f}=s,d=Vm(a.bytes.byteLength),I=f.size>a.bytes.byteLength?", so the file grew":"";if(!await Ox(e,new File([f],r,{type:l}),{note:`${s.size.width} × ${s.size.height}, ${Vm(f.size)} (was ${d}${I})`}))return!1;return M(i,new Uint8Array(await f.arrayBuffer()),l),i.size=s.size,i.decoded=!0,fl(e,s.size.width,s.size.height),i.live=null,i.history=x0(),!0}finally{if(i.saving=!1,S(t).length===0)U(i),i.generation+=1}}function oA(t){let e=m.tabs.get(t);if(!e||!al(e))return!0;let r=t.split("/").pop()??t;return w.warn(`${r} has an unsaved edit. Save or discard it before replacing the file.`,{key:`image.replaceDirty:${t}`,path:t,source:"Image"}),!1}function Qw(t){let e=m.tabs.get(t),r=e&&x(e);if(!e||r===void 0||r.saving||al(e))return;if(U(r),r.generation+=1,r.size=null,r.decoded=!1,r.live=null,r.history=x0(),S(e).length>0)R(r,t)}wI(al);var G={message:"no media file to look for",status:"failed"};function L(t){let e=mi(t);return e===""?null:{path:e}}function ex(t){let e=L(t);return e===null?null:qd(e)}async function Xu(t){let e=L(t);return e===null?G:La(e)}function rA(t){if(t===null)return"Counting references…";switch(t.status){case"unsupported":return null;case"pending":return"Counting references…";case"failed":return"Usage unknown";default:return lv(t.result)}}
|
|
2
2
|
export{ls,al,LL,Xw,iA,$L,oA,Qw,ex,Xu,rA};
|
|
3
3
|
|
|
4
4
|
//# debugId=4EBD0C6B7B176E4464756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-
|
|
5
|
+
//# sourceMappingURL=studio-3pz4t5a2.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{p,ye}from"./studio-4fnb5648.js";import{dt}from"./studio-tpxcryf2.js";import{$s}from"./studio-hh394phe.js";import{oa,ra,At}from"./studio-1ks5d9y4.js";import{Jc,IO,Ys,rv,nr,Vd,Yc,OO,hh,fl,MO,Px}from"./studio-y1b86ast.js";import{Xc}from"./studio-zfdbmhp3.js";import{a0,wn}from"./studio-4f7thq0p.js";import{Ve,vt,E,R}from"./studio-9dq7rwc7.js";import{Me}from"./studio-0gvvqj3h.js";import{g}from"./studio-3qr08sxq.js";import{ce}from"./studio-0939t1q1.js";var C={$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, because 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."}}]};E("media-field",C);function G(t,e){t.label=e.label,t.value=e.value,t.thumbState=e.thumbState,t.thumbSrc=e.thumbSrc}function D(t,e,o){let i=g({browse:o.browse,edit:o.edit,label:e.label,thumbSrc:e.thumbSrc,thumbState:e.thumbState,upload:o.upload,value:e.value,warm:o.warm}),a=null,r=!1;return R("media-field",i,t).then((n)=>{if(r){n.dispose();return}a=n}),{dispose(){r=!0,a?.dispose(),a=null},update:(n)=>G(i,n)}}function qu(t){let{anchor:e,name:o,scope:i,slot:a}=t,r=document.createElement("div");r.style.pointerEvents="auto",r.setAttribute(Ve,vt("popover",a)),dt("popover").append(r);let n=new AbortController,s=null,l=null,c=!1,T=()=>n.signal.aborted,H=(x)=>{if(c)return;if(c=!0,n.abort(),l?.dispose(),l=null,r.remove(),x)t.onDismissed?.()},U=(async()=>{let x={signal:n.signal};if(t.onNodeCreated)x.onNodeCreated=t.onNodeCreated;let I=await R(o,i,r,x);if(T())return;if(l=I,s=I.root,s.setAttribute(Ve,vt("popover",a)),s.addEventListener("toggle",(S)=>{if("newState"in S&&S.newState==="closed")H(!0)}),!s.hasAttribute("popover"))await new Promise((S)=>{s?.addEventListener("jx-ready",()=>S(),{once:!0})});if(T())return;s.showPopover(e?{source:e}:void 0)})();return{close:()=>{if(c)return;if(s?.open)s.hidePopover();H(!1)},host:r,isOpen:()=>!c,ready:U}}var _={$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"]':{justifyContent:"flex-start"},'& [part="browse-all"]':{$description:"The last row, set apart by a rule: it does not pick a file, it opens the picker that shows all of them.",marginTop:"var(--jx-space-1)",paddingTop:"var(--jx-space-2)",borderTop:"1px solid var(--border)",justifyContent:"flex-start"}},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, and the marker is a control (the rule studio.md §5.6 states for every truncation marker): it raises the cap by fifty, so every file the Media workspace lists can be reached from here without a search. Inert "…21 more" text was the panel holding the answer and not showing it.',tagName:"jx-button",attributes:{part:"more"},$props:{variant:"secondary",size:"sm",quiet:!0},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/showMore"},value:[]}]},children:[{tagName:"span",textContent:"${state.moreLabel}"}]}}},{tagName:"jx-button",attributes:{part:"browse-all"},$props:{variant:"secondary",size:"sm",quiet:!0},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/browseAll"},value:[]}]},children:[{tagName:"span",textContent:"${state.browseAllLabel}"}]}]}]};E("media-browser",_);var X="media-picker";function Y(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,t.browseAllLabel=e.browseAllLabel}function V(t,e,o){let i=g({browseAll:e.browseAll,browseAllLabel:t.browseAllLabel,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,showMore:e.showMore,x:t.x,y:t.y}),a={anchor:o,name:"media-browser",scope:i,slot:X};if(e.dismissed)a.onDismissed=e.dismissed;let r=qu(a);return r.ready.then(()=>{if(r.isOpen())r.host.querySelector('[part="filter"] [part="input"]')?.focus()}),{close:r.close,host:r.host,isOpen:r.isOpen,ready:r.ready,update:(n)=>Y(i,n)}}var b=[],M=!1,L="images";function kT(t){let e=t.replaceAll("\\","/");return e.startsWith("public/")||new RegExp(`^content/[^/]+/${L}/`).test(e)}async function N(t,e){let o=[];try{let i=await $s(()=>e.listDirectory(t));OO(i);for(let a of i)if(a.type==="directory"){let r=await N(a.path,e);o.push(...r)}else{let r=At(a.name);if(ra.has(r))o.push({file:a.path,isImage:oa.has(r),kind:IO(a.name),name:a.name,ref:rv(a.path)})}}catch{}return o}async function Q(t){let e;try{e=(await t.listDirectory("content")).filter((a)=>a.type==="directory").map((a)=>a.path)}catch{return[]}let o=[];for(let i of e){let a=!1;try{a=(await t.listDirectory(i)).some((n)=>n.type==="directory"&&n.name===L)}catch{}if(a)o.push(...await N(`${i}/${L}`,t))}return o}async function Z(t){try{let e=await t.listDirectory(".");return new Set(e.filter((o)=>o.type==="directory").map((o)=>o.name).filter((o)=>o==="public"||o==="content"))}catch{return new Set(["public","content"])}}var h=null,O=0,A=new Set;function ET(t){return A.add(t),()=>{A.delete(t)}}function q(){for(let t of A)t()}function k(){if(M)return Promise.resolve();if(h)return h;if(!ye())return Promise.resolve();let t=O,e=(async()=>{let o=p(),i=await Z(o),[a,r]=await Promise.all([i.has("public")?N("public",o):[],i.has("content")?Q(o):[]]);if(t!==O)return;b=[...a,...r],M=!0,h=null,wn("leftPanel","rightPanel"),q()})();return h=e,e}function Gu(){if(!M)return k(),null;return b}function Dw(){b=[],M=!1,O+=1,h=null,MO(),q()}var z=null;function ee(){return z??=(ce("ae67q4at"),import("./media-library-ae67q4at.js")),z}async function zP(t,e={}){(await ee()).openMediaPickDialog({images:e.images===!0,onPick:t})}var y=50,d=null,f=null,v="",u=y,w={},B={x:0,y:0};function m(){let t=v.toLowerCase(),e=w.images?b.filter((r)=>r.isImage):b,o=t?e.filter((r)=>r.ref.toLowerCase().includes(t)||r.name.toLowerCase().includes(t)):e,a=o.slice(0,u).map((r)=>{let n=Px(Yc(r.file));return{caption:n,captionState:n?"shown":"hidden",file:r.file,key:r.file,name:r.name,path:r.ref,thumbSrc:r.isImage?nr(r.file):"",thumbState:r.isImage?"shown":"hidden"}});return{browseAllLabel:w.images?"Browse all images…":"Browse all media…",emptyLabel:e.length>0?"No matches":w.images?"No images in this project yet":"No media in this project yet",filter:v,moreLabel:`Show ${Math.min(o.length-u,y)} more`,moreState:o.length>u?"shown":"hidden",rows:a,rowsState:a.length>0?"listed":"empty",x:B.x,y:B.y}}function P(){let t=d;d=null,f=null,v="",u=y,t?.close()}var j=0;function te(t,e,o){if(!fl(t,e,o)){if(!Vd(t))hh(t).then(()=>d?.update(m()));return}if(j!==0)return;j=requestAnimationFrame(()=>{j=0,d?.update(m())})}function ES(t,e,o={}){P(),k().then(()=>d?.update(m())),f=e,w=o;let i=Me(t);B={x:i.left,y:i.bottom+4},d=V(m(),{browseAll:()=>{let a=f,r=w;if(P(),a)zP(a,r)},dismissed:()=>{d=null,f=null,v="",u=y},measure:te,pick:(a)=>{let r=f;P(),r?.(a)},showMore:()=>{u+=y,d?.update(m())},setFilter:(a)=>{v=a,d?.update(m())}},t)}async function WP(t,e){let o=await Ys([...t]),[i]=o;if(i)e(i.ref)}function TS(t){let e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=Jc(),e.addEventListener("change",()=>{if(e.files?.length)WP(e.files,t)}),e.click()}var re=400,F=new WeakMap;function W(t,e){let o=oa.has(At(e));return{label:t,thumbSrc:o&&e?Xc(e):"",thumbState:o&&e?"shown":"hidden",value:e}}function Kl(t,e,o,i,a={}){k();let r=F.get(t);if(r){r.prop=e,r.commit=i,r.options=a,r.handle.update(W(e,o));return}let n={commit:i,options:a,prop:e},s=D(t,W(e,o),{browse:(l)=>{ES(l,(c)=>n.commit(c),n.options)},edit:(l)=>a0(`media:${n.prop}`,re,(c)=>n.commit(c))(l),upload:()=>TS((l)=>n.commit(l)),warm:()=>{k()}});F.set(t,Object.assign(n,{handle:s}))}function Cm(t){let e=F.get(t);if(e)F.delete(t),e.handle.dispose()}
|
|
1
|
+
import{p,ye}from"./studio-4fnb5648.js";import{dt}from"./studio-tpxcryf2.js";import{$s}from"./studio-hh394phe.js";import{oa,ra,At}from"./studio-1ks5d9y4.js";import{Jc,IO,Ys,rv,nr,Vd,Yc,OO,hh,fl,MO,Px}from"./studio-61rg2cz5.js";import{Xc}from"./studio-acer0g8w.js";import{a0,wn}from"./studio-4f7thq0p.js";import{Ve,vt,E,R}from"./studio-9dq7rwc7.js";import{Me}from"./studio-0gvvqj3h.js";import{g}from"./studio-3qr08sxq.js";import{ce}from"./studio-0939t1q1.js";var C={$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, because 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."}}]};E("media-field",C);function G(t,e){t.label=e.label,t.value=e.value,t.thumbState=e.thumbState,t.thumbSrc=e.thumbSrc}function D(t,e,o){let i=g({browse:o.browse,edit:o.edit,label:e.label,thumbSrc:e.thumbSrc,thumbState:e.thumbState,upload:o.upload,value:e.value,warm:o.warm}),a=null,r=!1;return R("media-field",i,t).then((n)=>{if(r){n.dispose();return}a=n}),{dispose(){r=!0,a?.dispose(),a=null},update:(n)=>G(i,n)}}function qu(t){let{anchor:e,name:o,scope:i,slot:a}=t,r=document.createElement("div");r.style.pointerEvents="auto",r.setAttribute(Ve,vt("popover",a)),dt("popover").append(r);let n=new AbortController,s=null,l=null,c=!1,T=()=>n.signal.aborted,H=(x)=>{if(c)return;if(c=!0,n.abort(),l?.dispose(),l=null,r.remove(),x)t.onDismissed?.()},U=(async()=>{let x={signal:n.signal};if(t.onNodeCreated)x.onNodeCreated=t.onNodeCreated;let I=await R(o,i,r,x);if(T())return;if(l=I,s=I.root,s.setAttribute(Ve,vt("popover",a)),s.addEventListener("toggle",(S)=>{if("newState"in S&&S.newState==="closed")H(!0)}),!s.hasAttribute("popover"))await new Promise((S)=>{s?.addEventListener("jx-ready",()=>S(),{once:!0})});if(T())return;s.showPopover(e?{source:e}:void 0)})();return{close:()=>{if(c)return;if(s?.open)s.hidePopover();H(!1)},host:r,isOpen:()=>!c,ready:U}}var _={$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"]':{justifyContent:"flex-start"},'& [part="browse-all"]':{$description:"The last row, set apart by a rule: it does not pick a file, it opens the picker that shows all of them.",marginTop:"var(--jx-space-1)",paddingTop:"var(--jx-space-2)",borderTop:"1px solid var(--border)",justifyContent:"flex-start"}},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, and the marker is a control (the rule studio.md §5.6 states for every truncation marker): it raises the cap by fifty, so every file the Media workspace lists can be reached from here without a search. Inert "…21 more" text was the panel holding the answer and not showing it.',tagName:"jx-button",attributes:{part:"more"},$props:{variant:"secondary",size:"sm",quiet:!0},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/showMore"},value:[]}]},children:[{tagName:"span",textContent:"${state.moreLabel}"}]}}},{tagName:"jx-button",attributes:{part:"browse-all"},$props:{variant:"secondary",size:"sm",quiet:!0},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/browseAll"},value:[]}]},children:[{tagName:"span",textContent:"${state.browseAllLabel}"}]}]}]};E("media-browser",_);var X="media-picker";function Y(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,t.browseAllLabel=e.browseAllLabel}function V(t,e,o){let i=g({browseAll:e.browseAll,browseAllLabel:t.browseAllLabel,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,showMore:e.showMore,x:t.x,y:t.y}),a={anchor:o,name:"media-browser",scope:i,slot:X};if(e.dismissed)a.onDismissed=e.dismissed;let r=qu(a);return r.ready.then(()=>{if(r.isOpen())r.host.querySelector('[part="filter"] [part="input"]')?.focus()}),{close:r.close,host:r.host,isOpen:r.isOpen,ready:r.ready,update:(n)=>Y(i,n)}}var b=[],M=!1,L="images";function kT(t){let e=t.replaceAll("\\","/");return e.startsWith("public/")||new RegExp(`^content/[^/]+/${L}/`).test(e)}async function N(t,e){let o=[];try{let i=await $s(()=>e.listDirectory(t));OO(i);for(let a of i)if(a.type==="directory"){let r=await N(a.path,e);o.push(...r)}else{let r=At(a.name);if(ra.has(r))o.push({file:a.path,isImage:oa.has(r),kind:IO(a.name),name:a.name,ref:rv(a.path)})}}catch{}return o}async function Q(t){let e;try{e=(await t.listDirectory("content")).filter((a)=>a.type==="directory").map((a)=>a.path)}catch{return[]}let o=[];for(let i of e){let a=!1;try{a=(await t.listDirectory(i)).some((n)=>n.type==="directory"&&n.name===L)}catch{}if(a)o.push(...await N(`${i}/${L}`,t))}return o}async function Z(t){try{let e=await t.listDirectory(".");return new Set(e.filter((o)=>o.type==="directory").map((o)=>o.name).filter((o)=>o==="public"||o==="content"))}catch{return new Set(["public","content"])}}var h=null,O=0,A=new Set;function ET(t){return A.add(t),()=>{A.delete(t)}}function q(){for(let t of A)t()}function k(){if(M)return Promise.resolve();if(h)return h;if(!ye())return Promise.resolve();let t=O,e=(async()=>{let o=p(),i=await Z(o),[a,r]=await Promise.all([i.has("public")?N("public",o):[],i.has("content")?Q(o):[]]);if(t!==O)return;b=[...a,...r],M=!0,h=null,wn("leftPanel","rightPanel"),q()})();return h=e,e}function Gu(){if(!M)return k(),null;return b}function Dw(){b=[],M=!1,O+=1,h=null,MO(),q()}var z=null;function ee(){return z??=(ce("j74rt0w4"),import("./media-library-j74rt0w4.js")),z}async function zP(t,e={}){(await ee()).openMediaPickDialog({images:e.images===!0,onPick:t})}var y=50,d=null,f=null,v="",u=y,w={},B={x:0,y:0};function m(){let t=v.toLowerCase(),e=w.images?b.filter((r)=>r.isImage):b,o=t?e.filter((r)=>r.ref.toLowerCase().includes(t)||r.name.toLowerCase().includes(t)):e,a=o.slice(0,u).map((r)=>{let n=Px(Yc(r.file));return{caption:n,captionState:n?"shown":"hidden",file:r.file,key:r.file,name:r.name,path:r.ref,thumbSrc:r.isImage?nr(r.file):"",thumbState:r.isImage?"shown":"hidden"}});return{browseAllLabel:w.images?"Browse all images…":"Browse all media…",emptyLabel:e.length>0?"No matches":w.images?"No images in this project yet":"No media in this project yet",filter:v,moreLabel:`Show ${Math.min(o.length-u,y)} more`,moreState:o.length>u?"shown":"hidden",rows:a,rowsState:a.length>0?"listed":"empty",x:B.x,y:B.y}}function P(){let t=d;d=null,f=null,v="",u=y,t?.close()}var j=0;function te(t,e,o){if(!fl(t,e,o)){if(!Vd(t))hh(t).then(()=>d?.update(m()));return}if(j!==0)return;j=requestAnimationFrame(()=>{j=0,d?.update(m())})}function ES(t,e,o={}){P(),k().then(()=>d?.update(m())),f=e,w=o;let i=Me(t);B={x:i.left,y:i.bottom+4},d=V(m(),{browseAll:()=>{let a=f,r=w;if(P(),a)zP(a,r)},dismissed:()=>{d=null,f=null,v="",u=y},measure:te,pick:(a)=>{let r=f;P(),r?.(a)},showMore:()=>{u+=y,d?.update(m())},setFilter:(a)=>{v=a,d?.update(m())}},t)}async function WP(t,e){let o=await Ys([...t]),[i]=o;if(i)e(i.ref)}function TS(t){let e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=Jc(),e.addEventListener("change",()=>{if(e.files?.length)WP(e.files,t)}),e.click()}var re=400,F=new WeakMap;function W(t,e){let o=oa.has(At(e));return{label:t,thumbSrc:o&&e?Xc(e):"",thumbState:o&&e?"shown":"hidden",value:e}}function Kl(t,e,o,i,a={}){k();let r=F.get(t);if(r){r.prop=e,r.commit=i,r.options=a,r.handle.update(W(e,o));return}let n={commit:i,options:a,prop:e},s=D(t,W(e,o),{browse:(l)=>{ES(l,(c)=>n.commit(c),n.options)},edit:(l)=>a0(`media:${n.prop}`,re,(c)=>n.commit(c))(l),upload:()=>TS((l)=>n.commit(l)),warm:()=>{k()}});F.set(t,Object.assign(n,{handle:s}))}function Cm(t){let e=F.get(t);if(e)F.delete(t),e.handle.dispose()}
|
|
2
2
|
export{qu,kT,ET,Gu,Dw,zP,ES,WP,TS,Kl,Cm};
|
|
3
3
|
|
|
4
4
|
//# debugId=903D685F11A1727A64756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-
|
|
5
|
+
//# sourceMappingURL=studio-4bgvvzhv.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{X}from"./studio-9c6cbq2c.js";import{p,ye}from"./studio-4fnb5648.js";import{w}from"./studio-sce30r7b.js";import{us}from"./studio-4zd6an2b.js";import{fI,Yx,xv,h}from"./studio-yrcrncev.js";import{v1,mi,zv}from"./studio-nvcn2ykc.js";import{$s,Kd,HO,BO,zO}from"./studio-hh394phe.js";import{Ls}from"./studio-bct64zmj.js";import{oa,tR,nR,ra,At}from"./studio-1ks5d9y4.js";import{GC,rI,mh}from"./studio-zfdbmhp3.js";import{C}from"./studio-4f7thq0p.js";import{Y}from"./studio-k3we3kqb.js";var UC="__other__";function ds(t){return t.trim().toLowerCase().replaceAll(/\s+/g,"-").replaceAll(/[^a-z\d-]/g,"")}function q$(t){let e=t.lastIndexOf(".");return e>0?t.slice(e):""}function G$(t,e,n){let r=t.trim();if(n===void 0||e==="__other__")return r;if(n.kind==="fixed"){let i=ds(r);return i===""?"":`${i}${n.ext}`}return r.toLowerCase().endsWith(e.toLowerCase())?r:`${r}${e}`}function iv(t,e,n){let{choice:r,dir:i,known:o=new Set,rows:s=null,taken:a}=n,l=t.trim();if(!l)return r?.kind==="fixed"?"Enter a name.":"Enter a file name.";if(r?.kind==="fixed"&&ds(l)==="")return"Enter at least one letter or number.";let d=l.replaceAll("\\","/");if(d.startsWith("/")||d.endsWith("/"))return"Enter a name, not a path that starts or ends with a slash.";if(d.split("/").includes(".."))return"A name cannot step outside the destination folder.";if(d.includes("/")&&r!==void 0&&e!=="__other__")return`Pick Other… to create a file in a subfolder of ${i==="."?"the project root":i}.`;let u=q$(d);if(e!==""&&e!=="__other__"&&u!==""&&u.toLowerCase()!==e.toLowerCase()&&o.has(u.toLowerCase()))return`You picked ${s?.find((v)=>v.value===e)?.label??e}; this name ends in ${u}.`;if(r?.kind==="locked"&&e==="__other__"){if(u!==""&&u.toLowerCase()!==r.ext.toLowerCase()&&o.has(u.toLowerCase()))return r.because}let m=G$(t,e,r);return a.has(m.toLowerCase())?`${m} already exists in ${i}/.`:""}function Wm(t,e,n){let r=e.trim();if(r==="")return"Enter a file name.";if(/[/\\]/.test(r))return"Enter a name, not a path. A rename keeps the file in its folder.";let i=(t.split("/").pop()??t).toLowerCase();if(r.startsWith(".")&&!i.startsWith("."))return"A name cannot start with a dot: hidden files are not listed, so the file could disappear.";let o=r.toLowerCase();if(o!==i&&[...n].some((s)=>s.toLowerCase()===o))return`${r} already exists in this folder.`;return""}function x(t){let e=["B","KB","MB","GB"],n=t,r=0;while(n>=1024&&r<e.length-1)n/=1024,r+=1;return`${r===0?n:Number(n.toFixed(1))} ${e[r]}`}var R=["image/*","video/*","audio/*",".pdf",".svg",".woff",".woff2",".ttf",".otf"].join(",");function Jc(){return(ye()?p().assetCapabilities?.accept:void 0)??R}function zd(t){return ra.has(At(t))}function Wd(t){let e=t.type??"";if(e.startsWith("image/"))return"image";if(e.startsWith("video/"))return"video";if(e.startsWith("audio/"))return"audio";let n=At(t.name);if(oa.has(n))return"image";if(tR.has(n))return"video";if(nR.has(n))return"audio";return"file"}var K$=new Set([".woff",".woff2",".ttf",".otf"]);function IO(t){if(K$.has(At(t)))return"font";let e=Wd({name:t});return e==="file"?"document":e}var k=/^content\/([^/]+)\//,Ta="public/media";function J$(t){let e=t?k.exec(t.replaceAll("\\","/")):null;return e?`content/${e[1]}/images`:Ta}function RO(t){let e=t.replaceAll("\\","/");return e===Ta||/^content\/[^/]+\/images$/.test(e)}function T(t){let e=t.replaceAll("\\","/");if(e.startsWith("public/"))return e.slice(6);let n=/^content\/[^/]+\/(.+)$/.exec(e);if(n)return`./${n[1]}`;return`./${e}`}function P(t,e){let n=new Set([...e].map((o)=>o.toLowerCase()));if(!n.has(t.toLowerCase()))return t;let r=At(t),i=r?t.slice(0,-r.length):t;for(let o=1;;o++){let s=`${i}-${o}${r}`;if(!n.has(s.toLowerCase()))return s}}function Y$(t,e){let n=t.replaceAll("\\","/").replace(/\/+$/,"");return n==="."||n===""?e:`${n}/${e}`}var y=null;function DO(t){y=t}async function Nx(t,e){await(e===void 0?y?.(t):y?.(t,e))}function M(t){let e=t.replaceAll("\\","/"),n=e.lastIndexOf("/");return n>0?e.slice(0,n):"."}function I(t,e){let n=(o)=>e==="image"?oa.has(At(o.name)):zd(o.name),r=[],i=[];for(let o of t)if(n(o))r.push(o);else i.push(o.name);if(i.length>0)w.warn(i.length===1?`Skipped ${i[0]}`:`Skipped ${i.length} files`,{detail:e==="image"?`Only images can be used here: ${i.join(", ")}.`:`Studio lists images, video, audio, PDFs and fonts as media, so ${i.join(", ")} would not appear in it.`,source:"Media"});return r}async function Ys(t,e={}){let n=e.only===void 0?[...t]:I([...t],e.only);if(n.length===0)return[];let r=p(),i=e.dir??J$(h.value?.documentPath??null),o=e.source??"Media",s;try{let d=await $s(()=>r.listDirectory(i));s=new Set(d.map((u)=>u.name))}catch(d){if(e.dirExists===!0)return w.error(`Could not write to ${i}/.`,{detail:`The folder could not be read to choose a name that overwrites nothing: ${X(d)}`,path:i,source:o}),[];s=new Set}let a=ye()?p().assetCapabilities?.maxUploadBytes:void 0,l=[];for(let d of n){if(a!==void 0&&d.size>a){w.error(`${d.name} is too large.`,{detail:`This backend accepts at most ${x(a)}; that file is ${x(d.size)}.`,source:"Media"});continue}let u=P(d.name,s);s.add(u);let m=Y$(i,u);try{let{path:f}=await(e.write?e.write(m):r.uploadFile(m,d));Kd([f]),l.push({kind:Wd(d),name:u,path:f,ref:T(f)})}catch(f){w.error(`Could not upload ${d.name}.`,{detail:X(f),path:m,source:o})}}if(l.length>0){if(e.quiet!==!0)w.success(l.length===1?`Uploaded ${l[0].name} to ${i}/`:`Uploaded ${l.length} files to ${i}/`);await y?.(i)}return l}function L(t){try{let e=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(t);return e.startsWith("\uFEFF")?null:e}catch{return null}}function D(t){let e=t.slice(0,t.length-At(t).length);return`${e.replace(/-copy(?:-\d+)?$/,"")}-copy${t.slice(e.length)}`}async function Ax(t,e={}){let n=t.split("/").pop()??t,r=e.source??"Media",i;try{let a=p();if(a.readFileBytes===void 0)throw Error("This backend cannot read a file's raw bytes.");i=await a.readFileBytes(t)}catch(a){return w.error(`Could not duplicate ${n}.`,{detail:X(a),path:t,source:r}),null}let o=e.document===!0?L(i):null,[s]=await Ys([new File([i],D(n))],{dir:M(t),dirExists:!0,quiet:!0,source:r,...o!==null&&{write:async(a)=>(await p().writeFile(a,o),{path:a})}});if(!s)return null;if(s.path===t)return w.warn(`${n} was not duplicated.`,{detail:"The backend keeps identical files once, so it made no second file.",path:t,source:r}),null;return w.success(`Duplicated ${n} as ${s.name}`),s}var z=[new Set([".jpg",".jpeg"]),new Set([".tif",".tiff"])];function A(t){return z.find((e)=>e.has(t))??new Set([t])}function NO(t){return[...A(At(t))].join(",")}function N(t,e){return A(At(t)).has(At(e.name))}function AO(t,e,n){let r=Wm(t,e,n);if(r!=="")return r;if(!N(t,{name:e.trim()}))return`Keep the ${At(t)} extension. A rename does not convert the file, so another extension would break it on every page.`;return""}async function Ox(t,e,n={}){let r=t.split("/").pop()??t;if(!N(t,e))return w.error(`${e.name} cannot replace ${r}.`,{detail:`${r} is ${At(t)||"a file with no extension"} and ${e.name} is ${At(e.name)||"a file with no extension"}. Every page that uses ${r} would get bytes its address does not describe; choose a file of the same type, or upload it as a new file.`,path:t,source:"Media"}),!1;let i=ye()?p().assetCapabilities?.maxUploadBytes:void 0;if(i!==void 0&&e.size>i)return w.error(`${e.name} is too large.`,{detail:`This backend accepts at most ${x(i)}; that file is ${x(e.size)}.`,source:"Media"}),!1;Ls(t);let o;try{({path:o}=await p().uploadFile(t,e))}catch(s){return w.error(`Could not replace ${r}.`,{detail:X(s),path:t,source:"Media"}),!1}if(Kd([t,o]),o===t)BO(t);if(us(),await(o===t?Nx(M(t),t):Nx(M(t))),o!==t)return w.warn(`${r} was not replaced.`,{detail:`The backend stored the new file as ${o}, so every reference still shows the old one.`,path:t,source:"Media",tier:"problem"}),!1;return w.success(n.note===void 0?`Replaced ${r}`:`Replaced ${r}: ${n.note}`),!0}function Mx(t){let e=mi(t),n=e.lastIndexOf("/");return n===-1?e:e.slice(n+1)}function ov(t){let e=mi(t),n=e.lastIndexOf("/");return n===-1?".":e.slice(0,n)}function B(){return C?.projectConfig?.content??null}function _(t){return xv(t,B(),rI())}function U(t,e){return`${mi(e.urlPrefix)}/${t.slice(e.dir.length+1)}`}function rv(t){let e=mi(t);if(e.startsWith(`${v1}/`))return`/${e.slice(v1.length+1)}`;let n=_(e);return n?`/${U(e,n)}`:`/${e}`}function nr(t){let e=mi(t);if(e==="")return t;let{space:n,fileBaseUrl:r}=mh(),i=zO(e);if(n==="repo")return Yx(fI(`${r}${zv(e)}`,HO(e)),i);let o=zv(rv(e).slice(1));return Yx(GC(`/${o}`),i)}var c=new Map,E=new Map,g=new Map,b=new Set;function S(t){return At(t)===".svg"}function F(t){let e=t===null?null:/^\s*(\d+(?:\.\d+)?)\s*(?:px)?\s*$/.exec(t),n=e?Number(e[1]):Number.NaN;return n>0?n:null}function j(t){let e=new DOMParser().parseFromString(t,"image/svg+xml").documentElement;if(e.localName!=="svg")return null;let n=F(e.getAttribute("width")),r=F(e.getAttribute("height")),i=(e.getAttribute("viewBox")??"").trim().split(/[\s,]+/).map(Number),o=i[2]??Number.NaN,s=i[3]??Number.NaN,a=i.length===4&&o>0&&s>0,l=null;if(n!==null&&r!==null)l={height:r,width:n};else if(a&&n!==null)l={height:n*s/o,width:n};else if(a&&r!==null)l={height:r,width:r*o/s};else if(a)l={height:s,width:o};return l&&{height:Math.round(l.height),width:Math.round(l.width)}}async function K(t){b.add(t);try{let e=j(await p().readFile(t));if(e&&e.width>0&&e.height>0)g.set(t,e)}catch{}}function Vd(t){let e=mi(t);return c.has(e)&&(!S(e)||b.has(e))}function O(t,e){let n=Mx(t),r=g.get(t);return{bytes:Y(e?.size)?e.size:null,ext:At(n),height:r?.height??null,kind:Wd({name:n}),modified:e?.modified??null,name:n,path:t,width:r?.width??null}}function Yc(t){return c.get(mi(t))??null}function OO(t){for(let e of t){if(e.type!=="file")continue;let n=mi(e.path);if(!c.has(n))c.set(n,O(n,e))}}async function hh(t){let e=mi(t),n=c.get(e);if(n&&Vd(e))return n;let r=E.get(e);if(r)return r;let i=(async()=>{if(S(e)&&!b.has(e))await K(e);if(n){let a=g.get(e);return{...n,height:a?.height??null,width:a?.width??null}}let s;try{s=(await $s(()=>p().listDirectory(ov(e)))).find((l)=>mi(l.path)===e)}catch{s=void 0}return O(e,s)})();E.set(e,i);let o=await i;return E.delete(e),c.set(e,o),o}function fl(t,e,n){if(!(e>0&&n>0))return!1;let r=mi(t);if(S(r))return!1;let i=g.get(r);if(i&&i.width===e&&i.height===n)return!1;g.set(r,{height:n,width:e});let o=c.get(r);if(o)c.set(r,{...o,height:n,width:e});return!0}function MO(){c.clear(),g.clear(),b.clear()}function Vm(t){if(t<1024)return`${t} B`;if(t<1048576)return`${Math.round(t/1024)} KB`;return`${(t/1048576).toFixed(1)} MB`}function Px(t){if(!t)return"";let e=[];if(t.width!==null&&t.height!==null)e.push(`${t.width} × ${t.height}`);if(t.bytes!==null)e.push(Vm(t.bytes));return e.join(" · ")}
|
|
1
|
+
import{X}from"./studio-9c6cbq2c.js";import{p,ye}from"./studio-4fnb5648.js";import{w}from"./studio-sce30r7b.js";import{us}from"./studio-4zd6an2b.js";import{fI,Yx,xv,h}from"./studio-knsjyx7n.js";import{v1,mi,zv}from"./studio-nvcn2ykc.js";import{$s,Kd,HO,BO,zO}from"./studio-hh394phe.js";import{Ls}from"./studio-bnc50f9h.js";import{oa,tR,nR,ra,At}from"./studio-1ks5d9y4.js";import{GC,rI,mh}from"./studio-acer0g8w.js";import{C}from"./studio-4f7thq0p.js";import{Y}from"./studio-k3we3kqb.js";var UC="__other__";function ds(t){return t.trim().toLowerCase().replaceAll(/\s+/g,"-").replaceAll(/[^a-z\d-]/g,"")}function q$(t){let e=t.lastIndexOf(".");return e>0?t.slice(e):""}function G$(t,e,n){let r=t.trim();if(n===void 0||e==="__other__")return r;if(n.kind==="fixed"){let i=ds(r);return i===""?"":`${i}${n.ext}`}return r.toLowerCase().endsWith(e.toLowerCase())?r:`${r}${e}`}function iv(t,e,n){let{choice:r,dir:i,known:o=new Set,rows:s=null,taken:a}=n,l=t.trim();if(!l)return r?.kind==="fixed"?"Enter a name.":"Enter a file name.";if(r?.kind==="fixed"&&ds(l)==="")return"Enter at least one letter or number.";let d=l.replaceAll("\\","/");if(d.startsWith("/")||d.endsWith("/"))return"Enter a name, not a path that starts or ends with a slash.";if(d.split("/").includes(".."))return"A name cannot step outside the destination folder.";if(d.includes("/")&&r!==void 0&&e!=="__other__")return`Pick Other… to create a file in a subfolder of ${i==="."?"the project root":i}.`;let u=q$(d);if(e!==""&&e!=="__other__"&&u!==""&&u.toLowerCase()!==e.toLowerCase()&&o.has(u.toLowerCase()))return`You picked ${s?.find((v)=>v.value===e)?.label??e}; this name ends in ${u}.`;if(r?.kind==="locked"&&e==="__other__"){if(u!==""&&u.toLowerCase()!==r.ext.toLowerCase()&&o.has(u.toLowerCase()))return r.because}let m=G$(t,e,r);return a.has(m.toLowerCase())?`${m} already exists in ${i}/.`:""}function Wm(t,e,n){let r=e.trim();if(r==="")return"Enter a file name.";if(/[/\\]/.test(r))return"Enter a name, not a path. A rename keeps the file in its folder.";let i=(t.split("/").pop()??t).toLowerCase();if(r.startsWith(".")&&!i.startsWith("."))return"A name cannot start with a dot: hidden files are not listed, so the file could disappear.";let o=r.toLowerCase();if(o!==i&&[...n].some((s)=>s.toLowerCase()===o))return`${r} already exists in this folder.`;return""}function x(t){let e=["B","KB","MB","GB"],n=t,r=0;while(n>=1024&&r<e.length-1)n/=1024,r+=1;return`${r===0?n:Number(n.toFixed(1))} ${e[r]}`}var R=["image/*","video/*","audio/*",".pdf",".svg",".woff",".woff2",".ttf",".otf"].join(",");function Jc(){return(ye()?p().assetCapabilities?.accept:void 0)??R}function zd(t){return ra.has(At(t))}function Wd(t){let e=t.type??"";if(e.startsWith("image/"))return"image";if(e.startsWith("video/"))return"video";if(e.startsWith("audio/"))return"audio";let n=At(t.name);if(oa.has(n))return"image";if(tR.has(n))return"video";if(nR.has(n))return"audio";return"file"}var K$=new Set([".woff",".woff2",".ttf",".otf"]);function IO(t){if(K$.has(At(t)))return"font";let e=Wd({name:t});return e==="file"?"document":e}var k=/^content\/([^/]+)\//,Ta="public/media";function J$(t){let e=t?k.exec(t.replaceAll("\\","/")):null;return e?`content/${e[1]}/images`:Ta}function RO(t){let e=t.replaceAll("\\","/");return e===Ta||/^content\/[^/]+\/images$/.test(e)}function T(t){let e=t.replaceAll("\\","/");if(e.startsWith("public/"))return e.slice(6);let n=/^content\/[^/]+\/(.+)$/.exec(e);if(n)return`./${n[1]}`;return`./${e}`}function P(t,e){let n=new Set([...e].map((o)=>o.toLowerCase()));if(!n.has(t.toLowerCase()))return t;let r=At(t),i=r?t.slice(0,-r.length):t;for(let o=1;;o++){let s=`${i}-${o}${r}`;if(!n.has(s.toLowerCase()))return s}}function Y$(t,e){let n=t.replaceAll("\\","/").replace(/\/+$/,"");return n==="."||n===""?e:`${n}/${e}`}var y=null;function DO(t){y=t}async function Nx(t,e){await(e===void 0?y?.(t):y?.(t,e))}function M(t){let e=t.replaceAll("\\","/"),n=e.lastIndexOf("/");return n>0?e.slice(0,n):"."}function I(t,e){let n=(o)=>e==="image"?oa.has(At(o.name)):zd(o.name),r=[],i=[];for(let o of t)if(n(o))r.push(o);else i.push(o.name);if(i.length>0)w.warn(i.length===1?`Skipped ${i[0]}`:`Skipped ${i.length} files`,{detail:e==="image"?`Only images can be used here: ${i.join(", ")}.`:`Studio lists images, video, audio, PDFs and fonts as media, so ${i.join(", ")} would not appear in it.`,source:"Media"});return r}async function Ys(t,e={}){let n=e.only===void 0?[...t]:I([...t],e.only);if(n.length===0)return[];let r=p(),i=e.dir??J$(h.value?.documentPath??null),o=e.source??"Media",s;try{let d=await $s(()=>r.listDirectory(i));s=new Set(d.map((u)=>u.name))}catch(d){if(e.dirExists===!0)return w.error(`Could not write to ${i}/.`,{detail:`The folder could not be read to choose a name that overwrites nothing: ${X(d)}`,path:i,source:o}),[];s=new Set}let a=ye()?p().assetCapabilities?.maxUploadBytes:void 0,l=[];for(let d of n){if(a!==void 0&&d.size>a){w.error(`${d.name} is too large.`,{detail:`This backend accepts at most ${x(a)}; that file is ${x(d.size)}.`,source:"Media"});continue}let u=P(d.name,s);s.add(u);let m=Y$(i,u);try{let{path:f}=await(e.write?e.write(m):r.uploadFile(m,d));Kd([f]),l.push({kind:Wd(d),name:u,path:f,ref:T(f)})}catch(f){w.error(`Could not upload ${d.name}.`,{detail:X(f),path:m,source:o})}}if(l.length>0){if(e.quiet!==!0)w.success(l.length===1?`Uploaded ${l[0].name} to ${i}/`:`Uploaded ${l.length} files to ${i}/`);await y?.(i)}return l}function L(t){try{let e=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(t);return e.startsWith("\uFEFF")?null:e}catch{return null}}function D(t){let e=t.slice(0,t.length-At(t).length);return`${e.replace(/-copy(?:-\d+)?$/,"")}-copy${t.slice(e.length)}`}async function Ax(t,e={}){let n=t.split("/").pop()??t,r=e.source??"Media",i;try{let a=p();if(a.readFileBytes===void 0)throw Error("This backend cannot read a file's raw bytes.");i=await a.readFileBytes(t)}catch(a){return w.error(`Could not duplicate ${n}.`,{detail:X(a),path:t,source:r}),null}let o=e.document===!0?L(i):null,[s]=await Ys([new File([i],D(n))],{dir:M(t),dirExists:!0,quiet:!0,source:r,...o!==null&&{write:async(a)=>(await p().writeFile(a,o),{path:a})}});if(!s)return null;if(s.path===t)return w.warn(`${n} was not duplicated.`,{detail:"The backend keeps identical files once, so it made no second file.",path:t,source:r}),null;return w.success(`Duplicated ${n} as ${s.name}`),s}var z=[new Set([".jpg",".jpeg"]),new Set([".tif",".tiff"])];function A(t){return z.find((e)=>e.has(t))??new Set([t])}function NO(t){return[...A(At(t))].join(",")}function N(t,e){return A(At(t)).has(At(e.name))}function AO(t,e,n){let r=Wm(t,e,n);if(r!=="")return r;if(!N(t,{name:e.trim()}))return`Keep the ${At(t)} extension. A rename does not convert the file, so another extension would break it on every page.`;return""}async function Ox(t,e,n={}){let r=t.split("/").pop()??t;if(!N(t,e))return w.error(`${e.name} cannot replace ${r}.`,{detail:`${r} is ${At(t)||"a file with no extension"} and ${e.name} is ${At(e.name)||"a file with no extension"}. Every page that uses ${r} would get bytes its address does not describe; choose a file of the same type, or upload it as a new file.`,path:t,source:"Media"}),!1;let i=ye()?p().assetCapabilities?.maxUploadBytes:void 0;if(i!==void 0&&e.size>i)return w.error(`${e.name} is too large.`,{detail:`This backend accepts at most ${x(i)}; that file is ${x(e.size)}.`,source:"Media"}),!1;Ls(t);let o;try{({path:o}=await p().uploadFile(t,e))}catch(s){return w.error(`Could not replace ${r}.`,{detail:X(s),path:t,source:"Media"}),!1}if(Kd([t,o]),o===t)BO(t);if(us(),await(o===t?Nx(M(t),t):Nx(M(t))),o!==t)return w.warn(`${r} was not replaced.`,{detail:`The backend stored the new file as ${o}, so every reference still shows the old one.`,path:t,source:"Media",tier:"problem"}),!1;return w.success(n.note===void 0?`Replaced ${r}`:`Replaced ${r}: ${n.note}`),!0}function Mx(t){let e=mi(t),n=e.lastIndexOf("/");return n===-1?e:e.slice(n+1)}function ov(t){let e=mi(t),n=e.lastIndexOf("/");return n===-1?".":e.slice(0,n)}function B(){return C?.projectConfig?.content??null}function _(t){return xv(t,B(),rI())}function U(t,e){return`${mi(e.urlPrefix)}/${t.slice(e.dir.length+1)}`}function rv(t){let e=mi(t);if(e.startsWith(`${v1}/`))return`/${e.slice(v1.length+1)}`;let n=_(e);return n?`/${U(e,n)}`:`/${e}`}function nr(t){let e=mi(t);if(e==="")return t;let{space:n,fileBaseUrl:r}=mh(),i=zO(e);if(n==="repo")return Yx(fI(`${r}${zv(e)}`,HO(e)),i);let o=zv(rv(e).slice(1));return Yx(GC(`/${o}`),i)}var c=new Map,E=new Map,g=new Map,b=new Set;function S(t){return At(t)===".svg"}function F(t){let e=t===null?null:/^\s*(\d+(?:\.\d+)?)\s*(?:px)?\s*$/.exec(t),n=e?Number(e[1]):Number.NaN;return n>0?n:null}function j(t){let e=new DOMParser().parseFromString(t,"image/svg+xml").documentElement;if(e.localName!=="svg")return null;let n=F(e.getAttribute("width")),r=F(e.getAttribute("height")),i=(e.getAttribute("viewBox")??"").trim().split(/[\s,]+/).map(Number),o=i[2]??Number.NaN,s=i[3]??Number.NaN,a=i.length===4&&o>0&&s>0,l=null;if(n!==null&&r!==null)l={height:r,width:n};else if(a&&n!==null)l={height:n*s/o,width:n};else if(a&&r!==null)l={height:r,width:r*o/s};else if(a)l={height:s,width:o};return l&&{height:Math.round(l.height),width:Math.round(l.width)}}async function K(t){b.add(t);try{let e=j(await p().readFile(t));if(e&&e.width>0&&e.height>0)g.set(t,e)}catch{}}function Vd(t){let e=mi(t);return c.has(e)&&(!S(e)||b.has(e))}function O(t,e){let n=Mx(t),r=g.get(t);return{bytes:Y(e?.size)?e.size:null,ext:At(n),height:r?.height??null,kind:Wd({name:n}),modified:e?.modified??null,name:n,path:t,width:r?.width??null}}function Yc(t){return c.get(mi(t))??null}function OO(t){for(let e of t){if(e.type!=="file")continue;let n=mi(e.path);if(!c.has(n))c.set(n,O(n,e))}}async function hh(t){let e=mi(t),n=c.get(e);if(n&&Vd(e))return n;let r=E.get(e);if(r)return r;let i=(async()=>{if(S(e)&&!b.has(e))await K(e);if(n){let a=g.get(e);return{...n,height:a?.height??null,width:a?.width??null}}let s;try{s=(await $s(()=>p().listDirectory(ov(e)))).find((l)=>mi(l.path)===e)}catch{s=void 0}return O(e,s)})();E.set(e,i);let o=await i;return E.delete(e),c.set(e,o),o}function fl(t,e,n){if(!(e>0&&n>0))return!1;let r=mi(t);if(S(r))return!1;let i=g.get(r);if(i&&i.width===e&&i.height===n)return!1;g.set(r,{height:n,width:e});let o=c.get(r);if(o)c.set(r,{...o,height:n,width:e});return!0}function MO(){c.clear(),g.clear(),b.clear()}function Vm(t){if(t<1024)return`${t} B`;if(t<1048576)return`${Math.round(t/1024)} KB`;return`${(t/1048576).toFixed(1)} MB`}function Px(t){if(!t)return"";let e=[];if(t.width!==null&&t.height!==null)e.push(`${t.width} × ${t.height}`);if(t.bytes!==null)e.push(Vm(t.bytes));return e.join(" · ")}
|
|
2
2
|
export{UC,ds,q$,G$,iv,Wm,Jc,zd,Wd,K$,IO,Ta,J$,RO,Y$,DO,Nx,Ys,Ax,NO,AO,Ox,Mx,ov,rv,nr,Vd,Yc,OO,hh,fl,MO,Vm,Px};
|
|
3
3
|
|
|
4
4
|
//# debugId=44F9FA380FD26FC664756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-
|
|
5
|
+
//# sourceMappingURL=studio-61rg2cz5.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{p}from"./studio-4fnb5648.js";import{C}from"./studio-4f7thq0p.js";import{af}from"./studio-
|
|
1
|
+
import{p}from"./studio-4fnb5648.js";import{C}from"./studio-4f7thq0p.js";import{af}from"./studio-q9hx2qp0.js";import{oe}from"./studio-v5wktj6f.js";import{v,T0}from"./studio-k3we3kqb.js";async function qw(e,o){return p().codeService(e,o)}async function KN(e){return p().locateFile(e)}var Yu=new Map;async function Gw(e,o){let s=e.$prototype?C?.projectConfig?.imports?.[e.$prototype]:null,t=e.$src||s;if(!t||!e.$prototype)return null;let r=`${t}::${e.$prototype}`;if(Yu.has(r))return Yu.get(r);try{let n=p(),i=!s&&o.documentPath?`${location.origin}/${o.documentPath}`:void 0,a=await n.fetchPluginSchema(t,e.$prototype,i);return Yu.set(r,a),a}catch{return Yu.set(r,null),null}}function ZT(e,o){let s=e.getModel();if(!s)return;let t=af();if(!t)return;let r=o.flatMap((n)=>{let i=n.labels?.[0];if(!i)return[];let{line:a,column:c,length:u}=i.span;return[{code:n.url?{target:t.Uri.parse(n.url),value:n.code}:n.code,endColumn:c+(u||1),endLineNumber:a,message:n.message+(n.help?`
|
|
2
2
|
${n.help}`:""),severity:n.severity==="error"?t.MarkerSeverity.Error:t.MarkerSeverity.Warning,source:"oxlint",startColumn:c,startLineNumber:a}]});t.editor.setModelMarkers(s,"oxlint",r)}function JN(e,o){let s=(t)=>{if(!v(t))return null;let r=t.parameters;if(!Array.isArray(r)||r.length===0)return null;return T0(r)};if(e.type==="def"){let t=e.defName?s(o?.state?.[e.defName]):null;if(t)return t}else if(e.type==="event"){if(!o||!e.path)return["state","event"];let t=oe(o,e.path),r=t&&e.eventKey?s(t[e.eventKey]):null;if(r)return r}return["state","event"]}
|
|
3
3
|
export{qw,KN,Yu,Gw,ZT,JN};
|
|
4
4
|
|
|
5
5
|
//# debugId=EFAA4A356901D95164756E2164756E21
|
|
6
|
-
//# sourceMappingURL=studio-
|
|
6
|
+
//# sourceMappingURL=studio-9gr7xs9r.js.map
|