@macrulez/devtoolz 0.4.2 → 0.5.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/README.md +14 -170
- package/dist/cli.js +13 -125
- package/dist/cli.js.map +1 -1
- package/dist/commands/image-batch/cli.js +16 -0
- package/dist/commands/image-batch/cli.js.map +1 -1
- package/dist/commands/image-batch/config.d.ts +1 -0
- package/dist/commands/image-batch/config.js +11 -0
- package/dist/commands/image-batch/config.js.map +1 -1
- package/dist/commands/image-batch/run.d.ts +1 -0
- package/dist/commands/image-batch/run.js +2 -0
- package/dist/commands/image-batch/run.js.map +1 -1
- package/dist/commands/ui/cli.js +1 -1
- package/dist/commands/ui/cli.js.map +1 -1
- package/dist/commands/ui/fs-routes.d.ts +0 -4
- package/dist/commands/ui/fs-routes.js +5 -78
- package/dist/commands/ui/fs-routes.js.map +1 -1
- package/dist/commands/ui/modules/cleanup.js +2 -2
- package/dist/commands/ui/modules/cleanup.js.map +1 -1
- package/dist/commands/ui/modules/index.js +1 -8
- package/dist/commands/ui/modules/index.js.map +1 -1
- package/dist/index.d.ts +0 -9
- package/dist/index.js +0 -5
- package/dist/index.js.map +1 -1
- package/dist/ui/assets/ChecksPage-FhzZT8lq.js +1 -0
- package/dist/ui/assets/{ChecksPage-pbC0Txsh.css → ChecksPage-ZoPlxU6J.css} +1 -1
- package/dist/ui/assets/CleanupPage-9PuXSO_G.css +1 -0
- package/dist/ui/assets/{CleanupPage-B2ZTFOpP.js → CleanupPage-LpbZ2AB-.js} +4 -4
- package/dist/ui/assets/highlight-Ba7TPCSA.js +2 -0
- package/dist/ui/assets/highlight-fNCqOka7.css +1 -0
- package/dist/ui/assets/index-DTj3rBik.js +3 -0
- package/dist/ui/index.html +1 -1
- package/dist/utils/atomic-write.d.ts +1 -0
- package/dist/utils/atomic-write.js +15 -0
- package/dist/utils/atomic-write.js.map +1 -0
- package/dist/utils/backup-error.d.ts +2 -0
- package/dist/utils/backup-error.js +3 -0
- package/dist/utils/backup-error.js.map +1 -0
- package/dist/utils/backup.d.ts +19 -0
- package/dist/utils/backup.js +33 -0
- package/dist/utils/backup.js.map +1 -0
- package/dist/utils/restore.d.ts +28 -0
- package/dist/utils/restore.js +88 -0
- package/dist/utils/restore.js.map +1 -0
- package/package.json +1 -6
- package/dist/ui/assets/ChecksPage-MLWSelKP.js +0 -1
- package/dist/ui/assets/CleanupPage-k7sTI4iz.css +0 -1
- package/dist/ui/assets/FolderBrowser-BX3-y8sM.js +0 -1
- package/dist/ui/assets/FolderBrowser-DRh-WZPz.css +0 -1
- package/dist/ui/assets/ImageBatchPage-CvsCvu1q.js +0 -4
- package/dist/ui/assets/ImageBatchPage-DiK8ODUc.css +0 -1
- package/dist/ui/assets/ImageHashPage-Bbhxvjj0.js +0 -1
- package/dist/ui/assets/ImageHashPage-CUXnoJEA.css +0 -1
- package/dist/ui/assets/SourcePicker-C3qFDUoL.css +0 -1
- package/dist/ui/assets/SourcePicker-CVgtCk78.js +0 -1
- package/dist/ui/assets/UiSegmented-Q_ter8VK.css +0 -1
- package/dist/ui/assets/UiSegmented-YV1YATxM.js +0 -1
- package/dist/ui/assets/highlight-CsAszz7F.js +0 -2
- package/dist/ui/assets/index-pDKL0Y31.js +0 -3
- package/dist/ui/assets/useCopy-vCfkPGWW.js +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as N,x as W,e as O,o as l,c as n,C as L,f as a,t as u,D as S,g as y,h as C,p as c,y as J,n as M,r as b,b as j,q as Q,E as T,i as U,F as V,a as I,j as A,z as X,v as Y,k as D,G as Z,l as ee,A as B,s as te,H as se}from"./index-pDKL0Y31.js";const oe=["aria-label"],ae={class:"dialog__head"},le={class:"dialog__title"},ne={class:"dialog__body"},ie={key:0,class:"dialog__foot"},de=N({__name:"UiModal",props:{title:{},width:{default:"820px"},fixedHeight:{type:Boolean,default:!1}},emits:["close"],setup(i,{emit:$}){const r=i,v=$,s=b();function h(d){d.key==="Escape"&&v("close")}return W(()=>{window.addEventListener("keydown",h),document.body.style.overflow="hidden",s.value?.focus()}),O(()=>{window.removeEventListener("keydown",h),document.body.style.overflow=""}),(d,m)=>(l(),n("div",{class:"overlay",onMousedown:m[1]||(m[1]=L(k=>v("close"),["self"]))},[a("div",{ref_key:"dialog",ref:s,class:M(["dialog",{"dialog--fixed":r.fixedHeight}]),style:J({"--dialog-width":r.width}),role:"dialog","aria-modal":"true","aria-label":r.title,tabindex:"-1"},[a("header",ae,[a("h2",le,u(r.title),1),S(d.$slots,"actions",{},void 0),a("button",{class:"btn btn--ghost btn--small","aria-label":"Close",onClick:m[0]||(m[0]=k=>v("close"))},[y(C,{name:"close"})])]),a("div",ne,[S(d.$slots,"default",{},void 0)]),d.$slots.footer?(l(),n("footer",ie,[S(d.$slots,"footer",{},void 0)])):c("",!0)],14,oe)],32))}}),re=j(de,[["__scopeId","data-v-e779e4b0"]]),ue={class:"bar"},ce=["disabled"],ve=["value"],me=["value"],fe={class:"check muted"},be={key:0,class:"notice notice--error notice-inset"},he=["aria-busy"],pe={key:0,class:"muted empty"},ke=["checked","aria-label","onChange"],ge=["onClick"],_e={key:0,class:"row__icon"},we=["src"],ye={class:"row__name"},Ce={key:2,class:"muted"},$e={key:1,class:"muted empty"},xe={class:"muted"},ze=["disabled"],Se=["disabled"],Ue=N({__name:"FolderBrowser",props:{start:{},mode:{default:"sources"},title:{default:""}},emits:["close","confirm"],setup(i,{emit:$}){const r=i,v=$,s=b(),h=b(r.start),d=b(!1),m=b(!1),k=b(""),p=b(new Set),x=b(),_=new Map,z=B(()=>s.value?.path.includes("\\")?"\\":"/"),H=B(()=>(s.value?.entries??[]).filter(o=>r.mode!=="folder"||o.kind==="dir")),E=B(()=>s.value?.entries.filter(o=>o.kind==="image").length??0);function g(o){const e=s.value?.path??"";return e.endsWith(z.value)?e+o:e+z.value+o}function G(o,e){const t=e.endsWith("\\")||e.endsWith("/")?e:e+z.value;return o!==e&&o.startsWith(t)}async function f(o){const e=s.value?.path;e!==void 0&&_.set(e,x.value?.scrollTop??0),m.value=!0,k.value="";try{const t=await te.get(`/api/fs/list?path=${encodeURIComponent(o)}&hidden=${d.value?1:0}`);s.value=t,h.value=t.path;for(const w of[..._.keys()])G(w,t.path)&&_.delete(w);await se(),x.value?.scrollTo({top:_.get(t.path)??0})}catch(t){k.value=t instanceof Error?t.message:String(t)}finally{m.value=!1}}function P(o){o.kind==="dir"&&f(g(o.name))}function F(o){const e=g(o.name),t=new Set(p.value);t.has(e)?t.delete(e):t.add(e),p.value=t}function R(o){o.kind==="dir"?P(o):r.mode==="image"?v("confirm",[g(o.name)]):F(o)}function q(){s.value&&v("confirm",[s.value.path])}function K(){v("confirm",[...p.value])}return W(()=>{f(r.start)}),(o,e)=>(l(),Q(re,{title:i.title||(i.mode==="folder"?"Choose a folder":i.mode==="image"?"Choose an image":"Add folders or images"),"fixed-height":"",onClose:e[8]||(e[8]=t=>v("close"))},{footer:T(()=>[a("span",xe,u(E.value)+" image"+u(E.value===1?"":"s")+" here",1),e[13]||(e[13]=a("span",{class:"spacer"},null,-1)),i.mode!=="image"?(l(),n("button",{key:0,class:M(["btn",{"btn--primary":i.mode==="folder"}]),disabled:!s.value,onClick:q},u(i.mode==="folder"?"Use this folder":"Add this folder"),11,ze)):c("",!0),i.mode==="sources"?(l(),n("button",{key:1,class:"btn btn--primary",disabled:p.value.size===0,onClick:K}," Add "+u(p.value.size)+" selected ",9,Se)):c("",!0)]),default:T(()=>[a("div",ue,[a("button",{class:"btn btn--small",disabled:!s.value?.parent,title:"Parent folder",onClick:e[0]||(e[0]=t=>s.value?.parent&&f(s.value.parent))},[y(C,{name:"up",size:15}),e[9]||(e[9]=U(" Up ",-1))],8,ce),a("button",{class:"btn btn--small",title:"Home folder",onClick:e[1]||(e[1]=t=>s.value&&f(s.value.home))},[y(C,{name:"home",size:15}),e[10]||(e[10]=U(" Home ",-1))]),a("button",{class:"btn btn--small",title:"Start folder",onClick:e[2]||(e[2]=t=>s.value&&f(s.value.cwd))}," Start folder "),(s.value?.roots.length??0)>1?(l(),n("select",{key:0,class:"select bar__roots",value:s.value?.root,"aria-label":"Drive",onChange:e[3]||(e[3]=t=>f(t.target.value))},[(l(!0),n(V,null,I(s.value?.roots,t=>(l(),n("option",{key:t,value:t},u(t),9,me))),128))],40,ve)):c("",!0),a("form",{class:"bar__path",onSubmit:e[5]||(e[5]=L(t=>f(h.value),["prevent"]))},[A(a("input",{"onUpdate:modelValue":e[4]||(e[4]=t=>h.value=t),class:"input",spellcheck:"false","aria-label":"Folder path"},null,512),[[X,h.value]]),e[11]||(e[11]=a("button",{class:"btn btn--small",type:"submit"},"Go",-1))],32),a("label",fe,[A(a("input",{"onUpdate:modelValue":e[6]||(e[6]=t=>d.value=t),type:"checkbox",onChange:e[7]||(e[7]=t=>s.value&&f(s.value.path))},null,544),[[Y,d.value]]),e[12]||(e[12]=U(" Hidden ",-1))])]),k.value?(l(),n("div",be,u(k.value),1)):c("",!0),a("div",{ref_key:"list",ref:x,class:"list","aria-busy":m.value},[s.value&&H.value.length===0?(l(),n("div",pe," This folder has no subfolders or images. ")):c("",!0),(l(!0),n(V,null,I(H.value,t=>(l(),n("div",{key:t.name,class:M(["row",{"row--picked":p.value.has(g(t.name))}])},[i.mode==="sources"?(l(),n("input",{key:0,type:"checkbox",checked:p.value.has(g(t.name)),"aria-label":`Select ${t.name}`,onChange:w=>F(t)},null,40,ke)):c("",!0),a("button",{class:"row__main",onClick:w=>R(t)},[t.kind==="dir"?(l(),n("span",_e,[y(C,{name:"folder"})])):(l(),n("img",{key:1,class:"row__thumb",loading:"lazy",alt:"",src:D(Z)(g(t.name),96)},null,8,we)),a("span",ye,u(t.name),1),t.size!==void 0?(l(),n("span",Ce,u(D(ee)(t.size)),1)):c("",!0)],8,ge)],2))),128)),s.value?.truncated?(l(),n("div",$e,"Only the first entries are shown.")):c("",!0)],8,he)]),_:1},8,["title"]))}}),Me=j(Ue,[["__scopeId","data-v-1908c9a0"]]);export{Me as F,re as U};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.overlay[data-v-e779e4b0]{position:fixed;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;padding:20px;overflow:hidden;background:var(--backdrop)}.dialog[data-v-e779e4b0]{background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--shadow);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;width:min(var(--dialog-width),100%);max-height:100%;outline:none}.dialog--fixed[data-v-e779e4b0]{height:min(680px,100%)}.dialog__head[data-v-e779e4b0],.dialog__foot[data-v-e779e4b0]{display:flex;align-items:center;gap:10px;padding:12px 16px}.dialog__head[data-v-e779e4b0]{border-bottom:1px solid var(--border)}.dialog__title[data-v-e779e4b0]{flex:1;font-size:16px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dialog__body[data-v-e779e4b0]{flex:1;min-height:0;display:flex;flex-direction:column}.dialog__foot[data-v-e779e4b0]{border-top:1px solid var(--border)}.bar[data-v-1908c9a0]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:12px 16px}.bar__path[data-v-1908c9a0]{display:flex;flex:1;gap:6px;min-width:200px}.bar__path .input[data-v-1908c9a0]{flex:1;height:28px;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.bar__roots[data-v-1908c9a0]{height:28px}.notice-inset[data-v-1908c9a0]{margin:0 16px 12px}.spacer[data-v-1908c9a0]{flex:1}.list[data-v-1908c9a0]{flex:1;min-height:0;padding:0 8px 8px;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--border) transparent}.empty[data-v-1908c9a0]{padding:24px;text-align:center}.row[data-v-1908c9a0]{display:flex;align-items:center;gap:8px;padding:2px 8px;border-radius:9px}.row[data-v-1908c9a0]:hover{background:var(--surface-2)}.row--picked[data-v-1908c9a0]{background:var(--accent-soft)}.row__main[data-v-1908c9a0]{display:flex;flex:1;align-items:center;gap:10px;min-width:0;padding:4px 0;border:0;background:transparent;text-align:left;cursor:pointer}.row__icon[data-v-1908c9a0]{display:grid;place-items:center;width:40px;height:40px;color:var(--accent)}.row__thumb[data-v-1908c9a0]{width:40px;height:40px;border-radius:6px;background:var(--surface-2);object-fit:cover}.row__name[data-v-1908c9a0]{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{d as ne,x as pe,o as t,c as s,f as e,t as a,p as d,i as A,F as S,a as L,k as G,l as ce,C as Ge,j as R,z as se,g as q,h as Y,n as ae,v as fe,G as be,q as le,r as v,A as U,s as Q,M as Qe,b as oe,N as he,u as Ye,m as Ze,w as ye,e as Se,K as ve,L as Ie,y as Ce,B as Xe,O as ze}from"./index-pDKL0Y31.js";import{U as ge}from"./UiSegmented-YV1YATxM.js";import{F as Ve}from"./FolderBrowser-BX3-y8sM.js";import{S as et}from"./SourcePicker-CVgtCk78.js";const tt={class:"view"},st={key:0,class:"card block"},lt={key:0,class:"notice"},at={key:1,class:"notice notice--error"},nt={key:2,class:"muted"},ot={class:"list"},it={class:"item__main"},ut={class:"muted"},rt=["title"],dt={class:"item__actions"},ct=["onClick"],vt=["onClick"],pt={class:"custom"},mt=["disabled"],ft={key:1,class:"card block"},gt={class:"head"},ht={class:"muted"},bt={class:"item__path"},yt={key:0,class:"notice"},kt={key:1,class:"notice notice--error"},$t={class:"chips"},_t={key:2,class:"notice notice--warn"},wt={class:"actions"},Ct=["disabled"],St={key:0,class:"check"},Vt={class:"rows"},xt=["src"],Et=["src"],zt={class:"row__text"},At=["title"],Nt={class:"muted small"},Ot={key:0,class:"small row__message"},Bt={key:3,class:"actions"},jt={key:4,class:"muted small"},Ae="devtoolz-ui.open-backup",we=30,Tt=ne({__name:"BackupsView",props:{cwd:{}},setup(n){const k={restored:"restored","would-restore":"can be restored",modified:"changed since","missing-backup":"copy missing","damaged-backup":"copy damaged",error:"error"},i=v(""),g=v([]),f=v(),N=v(""),b=v(""),z=v(!1),j=v(!1),I=v(we),D=v(""),O=v(!1),C=U(()=>{const V=f.value?.counts;return V?V.modified+V["missing-backup"]+V["damaged-backup"]+V.error:0}),h=U(()=>f.value?.counts["would-restore"]??0),p=U(()=>f.value?.entries.slice(0,I.value)??[]);function r(V){const w=new Date(V);return Number.isNaN(w.getTime())?V:w.toLocaleString()}function _(V){return V==="would-restore"||V==="restored"?"good":V==="modified"?"warn":"bad"}function $(V){N.value=V instanceof Error?V.message:String(V)}async function F(){try{const V=await Q.get("/api/image-batch/backups");i.value=V.root,g.value=V.backups}catch(V){$(V)}}async function K(V){N.value="",b.value="",j.value=!1,I.value=we;try{f.value=await Q.get(`/api/image-batch/backup?dir=${encodeURIComponent(V)}`)}catch(w){f.value=void 0,$(w)}}function P(V){const w=V?.[0]??D.value;O.value=!1,w.trim()!==""&&(D.value=w,K(w))}async function M(){const V=f.value;if(!V)return;const w=j.value?V.files:h.value;if(window.confirm(`Put back ${w} original file${w===1?"":"s"} from this backup?`+(j.value?" Files changed after the replacement will be overwritten too.":""))){z.value=!0;try{const J=await Q.post("/api/image-batch/backup/restore",{dir:V.dir,force:j.value});b.value=`Restored ${J.counts.restored} file${J.counts.restored===1?"":"s"}.`,await K(V.dir)}catch(J){$(J)}finally{z.value=!1}}}async function te(V){if(window.confirm("Delete this backup for good? The saved originals cannot be recovered afterwards."))try{await Q.post("/api/image-batch/backup/delete",{dir:V}),b.value="The backup was deleted.",f.value?.dir===V&&(f.value=void 0),await F()}catch(w){$(w)}}return pe(async()=>{await F();try{const V=localStorage.getItem(Ae);V&&(localStorage.removeItem(Ae),await K(V))}catch{f.value=void 0}}),(V,w)=>(t(),s("div",tt,[f.value?(t(),s("section",ft,[e("div",gt,[e("div",null,[e("h2",null,"Backup of "+a(r(f.value.createdAt)),1),e("p",ht,a(f.value.files)+" file"+a(f.value.files===1?"":"s")+" · "+a(G(ce)(f.value.bytesBefore))+" originals, "+a(G(ce)(f.value.bytesAfter))+" after the replacement ",1),e("code",bt,a(f.value.dir),1)]),e("button",{class:"btn btn--ghost",onClick:w[3]||(w[3]=x=>(f.value=void 0,F()))},[q(Y,{name:"close",size:16}),w[15]||(w[15]=A(" Back to the list ",-1))])]),b.value?(t(),s("p",yt,a(b.value),1)):d("",!0),N.value?(t(),s("p",kt,a(N.value),1)):d("",!0),e("div",$t,[(t(!0),s(S,null,L(f.value.counts,(x,J)=>R((t(),s("span",{key:J,class:ae(["chip",`chip--${_(J)}`])},a(x)+" "+a(k[J]),3)),[[Qe,x>0]])),128))]),f.value.counts.modified?(t(),s("p",_t,a(f.value.counts.modified)+" file"+a(f.value.counts.modified===1?" was":"s were")+" changed after the replacement. They are left alone unless you tick the box below. ",1)):d("",!0),e("div",wt,[e("button",{class:"btn btn--primary",disabled:z.value||h.value===0&&!j.value,onClick:M}," Restore "+a(j.value?"everything":`${h.value} file${h.value===1?"":"s"}`),9,Ct),f.value.counts.modified?(t(),s("label",St,[R(e("input",{"onUpdate:modelValue":w[4]||(w[4]=x=>j.value=x),type:"checkbox"},null,512),[[fe,j.value]]),w[16]||(w[16]=A(" Overwrite files that changed since ",-1))])):d("",!0),e("button",{class:"btn btn--danger",onClick:w[5]||(w[5]=x=>te(f.value.dir))},"Delete this backup")]),e("ul",Vt,[(t(!0),s(S,null,L(p.value,x=>(t(),s("li",{key:x.path,class:"row"},[e("img",{class:"row__thumb",loading:"lazy",alt:"Original",src:G(be)(x.backup,120)},null,8,xt),w[17]||(w[17]=e("span",{class:"row__arrow muted"},"⇄",-1)),e("img",{class:"row__thumb",loading:"lazy",alt:"Now",src:G(be)(x.path,120)},null,8,Et),e("div",zt,[e("span",{class:"row__name",title:x.path},a(x.path),9,At),e("span",Nt," original "+a(G(ce)(x.bytesBefore))+" · replaced with "+a(G(ce)(x.bytesAfter)),1),x.message?(t(),s("span",Ot,a(x.message),1)):d("",!0)]),e("span",{class:ae(["chip",`chip--${_(x.status)}`])},a(k[x.status]),3)]))),128))]),f.value&&I.value<f.value.entries.length?(t(),s("div",Bt,[e("button",{class:"btn",onClick:w[6]||(w[6]=x=>I.value+=we)}," Show more ("+a(f.value.entries.length-I.value)+" left) ",1),e("button",{class:"btn",onClick:w[7]||(w[7]=x=>I.value=f.value.entries.length)}," Show all ("+a(f.value.entries.length)+") ",1)])):d("",!0),C.value?(t(),s("p",jt," The left picture is the saved original, the right one is the file as it is now on disk. ")):d("",!0)])):(t(),s("section",st,[w[14]||(w[14]=e("div",{class:"head"},[e("div",null,[e("h2",null,"Backups"),e("p",{class:"muted"}," “Replace the originals” copies each file here first, so a replacement can be undone. ")])],-1)),b.value?(t(),s("p",lt,a(b.value),1)):d("",!0),N.value?(t(),s("p",at,a(N.value),1)):d("",!0),g.value.length===0?(t(),s("p",nt,[w[9]||(w[9]=A(" No backups in ",-1)),e("code",null,a(i.value),1),w[10]||(w[10]=A(" yet. ",-1))])):d("",!0),e("ul",ot,[(t(!0),s(S,null,L(g.value,x=>(t(),s("li",{key:x.dir,class:"item"},[e("div",it,[e("strong",null,a(r(x.createdAt)),1),e("span",ut,a(x.files)+" file"+a(x.files===1?"":"s")+" · "+a(G(ce)(x.bytesBefore))+" → "+a(G(ce)(x.bytesAfter)),1),e("code",{class:"item__path",title:x.dir},a(x.dir),9,rt)]),e("div",dt,[e("button",{class:"btn btn--small",onClick:J=>K(x.dir)},"Open",8,ct),e("button",{class:"btn btn--small btn--danger",onClick:J=>te(x.dir)},"Delete",8,vt)])]))),128))]),e("div",pt,[w[12]||(w[12]=e("h3",null,"Another backup folder",-1)),w[13]||(w[13]=e("p",{class:"muted small"},[A(" If you chose your own backup folder, pick the dated folder inside it (the one with a "),e("code",null,"journal.json"),A("). ")],-1)),e("form",{class:"pathrow",onSubmit:w[2]||(w[2]=Ge(x=>P(),["prevent"]))},[R(e("input",{"onUpdate:modelValue":w[0]||(w[0]=x=>D.value=x),class:"input",spellcheck:"false",placeholder:"Path to the dated backup folder"},null,512),[[se,D.value]]),e("button",{class:"btn",type:"button",onClick:w[1]||(w[1]=x=>O.value=!0)},[q(Y,{name:"folder",size:16}),w[11]||(w[11]=A(" Browse ",-1))]),e("button",{class:"btn btn--primary",type:"submit",disabled:D.value.trim()===""}," Open ",8,mt)],32)])])),O.value?(t(),le(Ve,{key:2,start:n.cwd,mode:"folder",title:"Choose the backup folder",onClose:w[8]||(w[8]=x=>O.value=!1),onConfirm:P},null,8,["start"])):d("",!0)]))}}),Ut=oe(Tt,[["__scopeId","data-v-aa574981"]]),ke=Symbol("image-batch-navigate"),xe=Symbol("image-batch-project"),De={cwd:"",name:"this project",home:""};function It(n,k){const i=n.split(/[\\/]/).filter(Boolean);return{cwd:n,home:k,name:i[i.length-1]??n}}const Dt={class:"sharpen"},Mt={key:0,class:"grid"},Lt={class:"field"},Rt=["value"],Ft=["value"],Pt={key:1,class:"hint muted"},qt={class:"grid"},Jt={class:"field"},Kt=["value"],Wt=["value"],Ht={class:"field"},Gt=["value"],Qt=["value"],Yt={key:0,class:"grid"},Zt={class:"muted"},Xt=["value","onInput"],es=ne({__name:"SharpenSettings",props:Ze({options:{},manage:{type:Boolean}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(n){const k=n,i=he(ke,()=>{}),g=Ye(n,"modelValue"),f=v([]),N=v(!1),b=U(()=>f.value.filter(C=>!C.error)),z=U(()=>f.value.find(C=>C.name===g.value.preset));function j(C){const h=C.fields??{};return Object.entries(h).map(([p,r])=>`${p} ${r}`).join(", ")}function I(C){g.value={...g.value,mode:C},C==="preset"&&!g.value.preset&&b.value[0]&&(g.value={...g.value,mode:C,preset:b.value[0].name})}function D(C,h){g.value={...g.value,fine:{...g.value.fine,[C]:h}}}function O(C){const h=k.options.sharpen.fine.find(p=>p.key===C);return h?`${h.range[0]}–${h.range[1]}`:""}return pe(async()=>{try{f.value=await Q.get("/api/image-batch/sharpen-presets")}catch{f.value=[]}}),(C,h)=>(t(),s("div",Dt,[q(ge,{"model-value":g.value.mode,label:"Sharpening",options:[{value:"none",label:"None"},{value:"preset",label:"Saved preset"},{value:"custom",label:"Custom"}],"onUpdate:modelValue":I},null,8,["model-value"]),g.value.mode==="preset"?(t(),s("div",Mt,[e("label",Lt,[h[5]||(h[5]=e("span",null,"Preset",-1)),e("select",{class:"select",value:g.value.preset,onChange:h[0]||(h[0]=p=>g.value={...g.value,preset:p.target.value})},[(t(!0),s(S,null,L(b.value,p=>(t(),s("option",{key:p.name,value:p.name},a(p.name)+" · "+a(p.scope),9,Ft))),128))],40,Rt)]),n.manage?(t(),s("button",{key:0,class:"link",onClick:h[1]||(h[1]=p=>G(i)("sharpen"))},"Manage presets")):d("",!0),z.value?(t(),s("p",Pt,[z.value.description?(t(),s(S,{key:0},[A(a(z.value.description)+" — ",1)],64)):d("",!0),A(" "+a(j(z.value)),1)])):d("",!0)])):d("",!0),g.value.mode==="custom"?(t(),s(S,{key:1},[e("div",qt,[e("label",Jt,[h[6]||(h[6]=e("span",null,"Sharpen for",-1)),e("select",{class:"select",value:g.value.for,onChange:h[2]||(h[2]=p=>g.value={...g.value,for:p.target.value})},[(t(!0),s(S,null,L(n.options.sharpen.targets,p=>(t(),s("option",{key:p,value:p},a(p),9,Wt))),128))],40,Kt)]),e("label",Ht,[h[7]||(h[7]=e("span",null,"Amount",-1)),e("select",{class:"select",value:g.value.amount,onChange:h[3]||(h[3]=p=>g.value={...g.value,amount:p.target.value})},[(t(!0),s(S,null,L(n.options.sharpen.amounts,p=>(t(),s("option",{key:p,value:p},a(p),9,Qt))),128))],40,Gt)])]),e("button",{class:"link",onClick:h[4]||(h[4]=p=>N.value=!N.value)},a(N.value?"Hide":"Show")+" fine settings ",1),N.value?(t(),s("div",Yt,[(t(!0),s(S,null,L(n.options.sharpen.fine,p=>(t(),s("label",{key:p.key,class:"field"},[e("span",null,[A(a(p.key)+" ",1),e("small",Zt,"("+a(O(p.key))+")",1)]),e("input",{class:"input",inputmode:"decimal",placeholder:"table value",value:g.value.fine[p.key],onInput:r=>D(p.key,r.target.value)},null,40,Xt)]))),128))])):d("",!0)],64)):d("",!0)]))}}),Me=oe(es,[["__scopeId","data-v-1d132e3d"]]);function Le(){return{mode:"none",preset:"",for:"screen",amount:"standard",fine:{radius:"",flat:"",jagged:"",threshold:""}}}function ts(n){if(n.mode==="none")return;if(n.mode==="preset")return n.preset?{preset:n.preset}:void 0;const k={for:n.for,amount:n.amount};for(const[i,g]of Object.entries(n.fine))g.trim()!==""&&(k[i]=Number(g));return k}const Re=["widths","heights","size","longEdge","shortEdge","megapixels","percent"],ss={widths:[800,1600],heights:[600],size:"1920x1080",longEdge:[1600],shortEdge:[1080],megapixels:[2],percent:[50]};function ls(n,k,i){const g={...n};return i===void 0||i===""||Array.isArray(i)&&i.length===0||typeof i=="number"&&Number.isNaN(i)?delete g[k]:g[k]=i,g}function as(n){for(const k of Re)if(n[k]!==void 0)return k;return"original"}function ns(n,k){const i={...n};for(const g of Re)delete i[g];return delete i.matchOrientation,k!=="original"&&(i[k]=ss[k]),i}function os(n,k){if(k==="original")return"";const i=n[k];return Array.isArray(i)?i.join(", "):String(i??"")}function is(n){const k=n.split(/[,\s]+/).filter(Boolean);if(k.length===0)return[];const i=k.map(Number);return i.some(g=>!Number.isFinite(g))?void 0:i}function Ne(n){const k=Le();if(n==null)return{state:k,lossy:!1};if(typeof n=="string")return{state:{...k,mode:"preset",preset:n},lossy:!1};if(typeof n!="object"||Array.isArray(n))return{state:k,lossy:!0};const i=n;if(typeof i.preset=="string")return Object.keys(i).filter(N=>N!=="preset").length===0?{state:{...k,mode:"preset",preset:i.preset},lossy:!1}:{state:{...k,mode:"preset",preset:i.preset},lossy:!0};const g={...k,mode:"custom"};typeof i.for=="string"&&(g.for=i.for),typeof i.amount=="string"&&(g.amount=i.amount);for(const f of["radius","flat","jagged","threshold"])i[f]!==void 0&&(g.fine[f]=String(i[f]));return{state:g,lossy:!1}}function Oe(n){if(n.mode==="none")return;if(n.mode==="preset")return n.preset||void 0;const k={for:n.for,amount:n.amount};for(const[i,g]of Object.entries(n.fine))g.trim()!==""&&(k[i]=Number(g));return k}function us(){return{name:"New config",outputs:[{id:"responsive",widths:[400,800,1200],formats:["webp","jpg"],quality:"high"}]}}function rs(n){return{id:`recipe-${n}`,widths:[800],formats:["webp"],quality:"high"}}const ds={class:"recipe"},cs={key:0,class:"grid"},vs={class:"field"},ps=["value"],ms={key:0,class:"field"},fs=["value"],gs=["value"],hs={class:"group"},bs={class:"grid"},ys={class:"field"},ks=["value"],$s=["value"],_s={key:0,class:"field"},ws=["value"],Cs={key:1,class:"field"},Ss=["value"],Vs={key:2,class:"field"},xs=["value"],Es=["value"],zs={key:0,class:"check"},As=["checked"],Ns={class:"group"},Os={key:0,class:"notice notice--warn"},Bs={key:1,class:"pills"},js=["checked","onChange"],Ts={key:0,class:"muted small"},Us={class:"grid"},Is={key:0,class:"field"},Ds=["value"],Ms=["value"],Ls={key:1,class:"field"},Rs=["value"],Fs={key:2,class:"notice notice--warn"},Ps={class:"field"},qs=["value"],Js={class:"group"},Ks=["value","placeholder"],Ws={class:"pills"},Hs=["onClick"],Gs={class:"group"},Qs={key:0,class:"notice notice--warn"},Ys={class:"group"},Zs={key:0,class:"grid"},Xs=["value","onChange"],el=["value"],tl=["value","onChange"],sl={class:"field"},ll=["value"],al={class:"field"},nl=["value"],ol=ne({__name:"RecipeForm",props:{modelValue:{},options:{},presetNames:{},isDefaults:{type:Boolean}},emits:["update:modelValue"],setup(n,{emit:k}){const i=n,g=k,f={original:"Keep the original size",widths:"By width (px)",heights:"By height (px)",size:"Fit into a box",longEdge:"By the long side (px)",shortEdge:"By the short side (px)",megapixels:"By area (megapixels)",percent:"By percentage"},N=[{key:"metadata",label:"Metadata",options:["strip","keep","keep-icc"]},{key:"rotate",label:"Rotate (degrees)",options:["90","180","270"]}],b=[{key:"withoutEnlargement",label:"Never enlarge"},{key:"autoOrient",label:"Turn by EXIF orientation"},{key:"grayscale",label:"Grayscale"},{key:"flip",label:"Flip vertically"},{key:"flop",label:"Mirror horizontally"}],z=v(""),j=v(!1),I=v(!1),D=v(!1),O=v(Ne(i.modelValue.sharpen).state),C=U(()=>as(i.modelValue)),h=U(()=>Array.isArray(i.modelValue.formats)?i.modelValue.formats:void 0),p=U(()=>i.modelValue.formats!==void 0&&h.value===void 0),r=U(()=>i.modelValue.quality),_=U(()=>r.value!==void 0&&typeof r.value=="object"),$=U(()=>{const y=r.value;return y===void 0?"":typeof y=="number"?"custom":String(y)}),F=U(()=>typeof i.modelValue.name=="string"?i.modelValue.name:""),K=U(()=>i.modelValue.maxBytes===void 0?"":String(i.modelValue.maxBytes)),P=U(()=>{const y=i.modelValue.sharpen;return y!==void 0&&typeof y!="string"&&typeof y!="object"});function M(y,l){g("update:modelValue",ls(i.modelValue,y,l))}function te(){z.value=os(i.modelValue,C.value),j.value=!1}ye(C,te,{immediate:!0}),ye(()=>i.modelValue.sharpen,y=>{const l=Ne(y);D.value=l.lossy,JSON.stringify(Oe(O.value))!==JSON.stringify(y)&&(O.value=l.state)},{immediate:!0});function V(y){g("update:modelValue",ns(i.modelValue,y.target.value))}function w(y){z.value=y;const l=is(y);j.value=l===void 0,l&&l.length>0&&C.value!=="original"&&C.value!=="size"&&M(C.value,l)}function x(y){const l=h.value??[];M("formats",l.includes(y)?l.filter(u=>u!==y):[...l,y])}function J(y){y===""?M("quality",void 0):y==="custom"?M("quality",82):M("quality",y)}function de(y){const l=y.trim();l===""?M("maxBytes",void 0):M("maxBytes",/^\d+$/.test(l)?Number(l):l)}function ie(y){O.value=y,M("sharpen",Oe(y))}function Z(y){const l=i.modelValue[y];return l===void 0?"":String(l)}function ue(y,l){M(y,l===""?void 0:l==="true")}function X(y){M("name",(F.value||"{dir}/{name}")+"{"+y+"}")}function ee(y){return"{"+y+"}"}return(y,l)=>(t(),s("div",ds,[n.isDefaults?d("",!0):(t(),s("div",cs,[e("label",vs,[l[13]||(l[13]=e("span",null,"Recipe name",-1)),e("input",{class:"input",spellcheck:"false",value:String(n.modelValue.id??""),onInput:l[0]||(l[0]=u=>M("id",u.target.value))},null,40,ps)]),n.presetNames&&n.presetNames.length?(t(),s("label",ms,[l[15]||(l[15]=e("span",null,"Based on preset",-1)),e("select",{class:"select",value:String(n.modelValue.preset??""),onChange:l[1]||(l[1]=u=>M("preset",u.target.value))},[l[14]||(l[14]=e("option",{value:""},"None",-1)),(t(!0),s(S,null,L(n.presetNames,u=>(t(),s("option",{key:u,value:u},a(u),9,gs))),128))],40,fs)])):d("",!0)])),e("div",hs,[l[21]||(l[21]=e("h4",null,"Size",-1)),e("div",bs,[e("label",ys,[l[16]||(l[16]=e("span",null,"Method",-1)),e("select",{class:"select",value:C.value,onChange:V},[(t(!0),s(S,null,L(n.options.sizeMethods,u=>(t(),s("option",{key:u,value:u},a(f[u]),9,$s))),128))],40,ks)]),C.value==="size"?(t(),s("label",_s,[l[17]||(l[17]=e("span",null,"Box (width × height)",-1)),e("input",{class:"input",spellcheck:"false",value:String(n.modelValue.size??""),onInput:l[2]||(l[2]=u=>M("size",u.target.value))},null,40,ws)])):C.value!=="original"?(t(),s("label",Cs,[l[18]||(l[18]=e("span",null,"Values (comma-separated)",-1)),e("input",{class:ae(["input",{"input--bad":j.value}]),spellcheck:"false",value:z.value,onInput:l[3]||(l[3]=u=>w(u.target.value))},null,42,Ss)])):d("",!0),C.value==="size"?(t(),s("label",Vs,[l[19]||(l[19]=e("span",null,"How it fills the box",-1)),e("select",{class:"select",value:String(n.modelValue.fit??"inside"),onChange:l[4]||(l[4]=u=>M("fit",u.target.value))},[(t(!0),s(S,null,L(n.options.fitModes,u=>(t(),s("option",{key:u,value:u},a(u),9,Es))),128))],40,xs)])):d("",!0)]),C.value==="size"?(t(),s("label",zs,[e("input",{type:"checkbox",checked:n.modelValue.matchOrientation===!0,onChange:l[5]||(l[5]=u=>M("matchOrientation",u.target.checked||void 0))},null,40,As),l[20]||(l[20]=A(" Turn the box around for portrait images ",-1))])):d("",!0)]),e("div",Ns,[l[27]||(l[27]=e("h4",null,"Formats and quality",-1)),p.value?(t(),s("p",Os," The formats of this recipe are set in a form the editor cannot show. Use the JSON tab. ")):(t(),s("div",Bs,[(t(!0),s(S,null,L(n.options.formats,u=>(t(),s("label",{key:u,class:ae(["pill",{"pill--on":h.value?.includes(u)}])},[e("input",{type:"checkbox",checked:h.value?.includes(u),onChange:H=>x(u)},null,40,js),A(" "+a(u),1)],2))),128)),h.value?d("",!0):(t(),s("span",Ts,"none chosen — inherited from the defaults"))])),e("div",Us,[_.value?d("",!0):(t(),s("label",Is,[l[24]||(l[24]=e("span",null,"Quality",-1)),e("select",{class:"select",value:$.value,onChange:l[6]||(l[6]=u=>J(u.target.value))},[l[22]||(l[22]=e("option",{value:""},"Default (high)",-1)),(t(!0),s(S,null,L(n.options.qualityLevels,u=>(t(),s("option",{key:u,value:u},a(u),9,Ms))),128)),l[23]||(l[23]=e("option",{value:"custom"},"A number…",-1))],40,Ds)])),$.value==="custom"?(t(),s("label",Ls,[l[25]||(l[25]=e("span",null,"Quality (1–100)",-1)),e("input",{class:"input",inputmode:"numeric",value:String(n.modelValue.quality),onInput:l[7]||(l[7]=u=>M("quality",Number(u.target.value)))},null,40,Rs)])):d("",!0),_.value?(t(),s("p",Fs," Quality is set per format here. Use the JSON tab to change it. ")):d("",!0),e("label",Ps,[l[26]||(l[26]=e("span",null,"Largest file size",-1)),e("input",{class:"input",spellcheck:"false",placeholder:"e.g. 200KB (optional)",value:K.value,onInput:l[8]||(l[8]=u=>de(u.target.value))},null,40,qs)])])]),e("div",Js,[l[28]||(l[28]=e("h4",null,"File names",-1)),e("input",{class:"input",spellcheck:"false",value:F.value,placeholder:n.options.defaultTemplates[C.value],"aria-label":"File name template",onInput:l[9]||(l[9]=u=>M("name",u.target.value))},null,40,Ks),e("div",Ws,[(t(!0),s(S,null,L(n.options.templateVariables,u=>(t(),s("button",{key:u,class:"pill pill--button",onClick:H=>X(u)},a(ee(u)),9,Hs))),128))])]),e("div",Gs,[l[29]||(l[29]=e("h4",null,"Sharpening",-1)),D.value||P.value?(t(),s("p",Qs," This sharpening combines a preset with extra values. Use the JSON tab to edit it. ")):(t(),le(Me,{key:1,"model-value":O.value,options:n.options,"onUpdate:modelValue":ie},null,8,["model-value","options"]))]),e("div",Ys,[e("button",{class:"link",onClick:l[10]||(l[10]=u=>I.value=!I.value)},a(I.value?"Hide":"Show")+" advanced settings ",1),I.value?(t(),s("div",Zs,[(t(),s(S,null,L(N,u=>e("label",{key:u.key,class:"field"},[e("span",null,a(u.label),1),e("select",{class:"select",value:u.key==="rotate"?String(n.modelValue.rotate??""):String(n.modelValue[u.key]??""),onChange:H=>M(u.key,u.key==="rotate"&&H.target.value?Number(H.target.value):H.target.value)},[l[30]||(l[30]=e("option",{value:""},"Default",-1)),(t(!0),s(S,null,L(u.options,H=>(t(),s("option",{key:H,value:H},a(H),9,el))),128))],40,Xs)])),64)),(t(),s(S,null,L(b,u=>e("label",{key:u.key,class:"field"},[e("span",null,a(u.label),1),e("select",{class:"select",value:Z(u.key),onChange:H=>ue(u.key,H.target.value)},[...l[31]||(l[31]=[e("option",{value:""},"Default",-1),e("option",{value:"true"},"Yes",-1),e("option",{value:"false"},"No",-1)])],40,tl)])),64)),e("label",sl,[l[32]||(l[32]=e("span",null,"Blur (sigma)",-1)),e("input",{class:"input",inputmode:"decimal",value:n.modelValue.blur===void 0?"":String(n.modelValue.blur),onInput:l[11]||(l[11]=u=>M("blur",u.target.value===""?void 0:Number(u.target.value)))},null,40,ll)]),e("label",al,[l[33]||(l[33]=e("span",null,"Background (#rrggbb)",-1)),e("input",{class:"input",spellcheck:"false",value:String(n.modelValue.background??""),onInput:l[12]||(l[12]=u=>M("background",u.target.value))},null,40,nl)])])):d("",!0)])]))}}),Be=oe(ol,[["__scopeId","data-v-6d67983e"]]),il={class:"card block"},ul={class:"head"},rl={key:0,class:"muted"},dl={class:"grid"},cl={class:"field"},vl={class:"field"},pl={value:"project"},ml={class:"field"},fl=["value"],gl={class:"field"},hl=["value"],bl={key:0,class:"notice"},yl={class:"panel"},kl={class:"panel__body"},$l={class:"recipes"},_l={class:"panel__head"},wl=["onClick"],Cl={class:"muted small"},Sl={class:"panel__actions"},Vl=["disabled","onClick"],xl=["disabled","onClick"],El=["onClick"],zl=["onClick"],Al={key:0,class:"panel__body"},Nl=["value"],Ol={key:0,class:"notice notice--error"},Bl={key:0,class:"lines"},jl={key:3,class:"notice notice--error"},Tl={class:"actions"},Ul=["disabled"],Il=ne({__name:"ConfigEditor",props:{options:{},initial:{},copyOf:{}},emits:["saved","cancel"],setup(n,{emit:k}){const i=n,g=k,f=he(xe,De),N=v(i.initial!==void 0),b=v(i.copyOf?structuredClone(i.copyOf.raw):us()),z=v(i.initial?i.initial.name:i.copyOf?`${i.copyOf.name}-copy`:""),j=v(i.initial?.scope??"project"),I=v("form"),D=v(""),O=v(""),C=v(),h=v(""),p=v(!1),r=v(0);let _;const $=U(()=>Array.isArray(b.value.outputs)?b.value.outputs:[]),F=U(()=>b.value.defaults&&typeof b.value.defaults=="object"?b.value.defaults:{}),K=U(()=>b.value.presets&&typeof b.value.presets=="object"?Object.keys(b.value.presets):[]),P=U(()=>{const E=[];return K.value.length&&E.push(`${K.value.length} preset(s)`),Array.isArray(b.value.match)&&b.value.match.length&&E.push(`${b.value.match.length} rule(s)`),b.value.placeholders&&E.push("placeholders"),E}),M=U(()=>(C.value?.lines??[]).join(`
|
|
2
|
-
`)),te=U(()=>!p.value&&z.value.trim()!==""&&C.value?.ok===!0&&O.value==="");function V(E){b.value=E}function w(E,c){const B={...b.value};c.trim()===""?delete B[E]:B[E]=c,V(B)}function x(E){const c={...b.value};Object.keys(E).length===0?delete c.defaults:c.defaults=E,V(c)}function J(E,c){const B=[...$.value];B[E]=c,V({...b.value,outputs:B})}function de(){V({...b.value,outputs:[...$.value,rs($.value.length+1)]}),r.value=$.value.length}function ie(E){V({...b.value,outputs:$.value.filter((c,B)=>B!==E)}),r.value=Math.max(0,r.value-1)}function Z(E){const c=structuredClone($.value[E]??{});typeof c.id=="string"&&(c.id=`${c.id}-copy`);const B=[...$.value];B.splice(E+1,0,c),V({...b.value,outputs:B}),r.value=E+1}function ue(E,c){const B=E+c;if(B<0||B>=$.value.length)return;const W=[...$.value],[re]=W.splice(E,1);W.splice(B,0,re),V({...b.value,outputs:W}),r.value=B}function X(E,c){return typeof E.id=="string"&&E.id?E.id:`Recipe ${c+1}`}function ee(E){const c=[];for(const B of["widths","heights","longEdge","shortEdge","megapixels","percent"])Array.isArray(E[B])&&c.push(`${B} ${E[B].join(", ")}`);return typeof E.size=="string"&&c.push(`box ${E.size}`),Array.isArray(E.formats)&&c.push(E.formats.join("/")),c.join(" · ")}function y(E){D.value=E;try{const c=JSON.parse(E);if(c===null||typeof c!="object"||Array.isArray(c)){O.value="A config is a JSON object.";return}O.value="",b.value=c}catch(c){O.value=c instanceof Error?c.message:String(c)}}function l(E){if(E==="json"){D.value=JSON.stringify(b.value,null,2),O.value="",I.value="json";return}O.value||(I.value="form")}async function u(){try{C.value=await Q.post("/api/image-batch/config/validate",{raw:b.value})}catch(E){C.value={ok:!1,error:E instanceof Error?E.message:String(E)}}}ye(b,()=>{clearTimeout(_),_=setTimeout(()=>{u()},350)},{deep:!0});async function H(E=!1){p.value=!0,h.value="";try{await Q.post("/api/image-batch/config/save",{name:z.value,scope:j.value,raw:b.value,overwrite:E,...i.initial?{originalName:i.initial.name,originalScope:i.initial.scope}:{}}),g("saved",z.value)}catch(c){if(c instanceof Ie&&c.status===409&&c.body.exists===!0){if(window.confirm(`${c.message}. Replace it?`)){await H(!0);return}}else h.value=c instanceof Error?c.message:String(c)}finally{p.value=!1}}return pe(async()=>{if(i.initial)try{const E=await Q.get(`/api/image-batch/config?name=${encodeURIComponent(i.initial.name)}&scope=${i.initial.scope}`);b.value=E.raw}catch(E){h.value=E instanceof Error?E.message:String(E)}finally{N.value=!1}u()}),Se(()=>clearTimeout(_)),(E,c)=>(t(),s("section",il,[e("div",ul,[e("h2",null,a(n.initial?`Edit ${n.initial.name}`:n.copyOf?"Copy of a config":"New config"),1),e("button",{class:"btn btn--ghost",onClick:c[0]||(c[0]=B=>g("cancel"))},[q(Y,{name:"close",size:16}),c[8]||(c[8]=A(" Close ",-1))])]),N.value?(t(),s("p",rl,"Loading…")):(t(),s(S,{key:1},[e("div",dl,[e("label",cl,[c[9]||(c[9]=e("span",null,"File name",-1)),R(e("input",{"onUpdate:modelValue":c[1]||(c[1]=B=>z.value=B),class:"input",spellcheck:"false",placeholder:"web"},null,512),[[se,z.value]])]),e("label",vl,[c[11]||(c[11]=e("span",null,"Where to keep it",-1)),R(e("select",{"onUpdate:modelValue":c[2]||(c[2]=B=>j.value=B),class:"select"},[e("option",pl,"This project ("+a(G(f).name)+")",1),c[10]||(c[10]=e("option",{value:"global"},"All projects (your home folder)",-1))],512),[[ve,j.value]])]),e("label",ml,[c[12]||(c[12]=e("span",null,"Title",-1)),e("input",{class:"input",value:String(b.value.name??""),onInput:c[3]||(c[3]=B=>w("name",B.target.value))},null,40,fl)]),e("label",gl,[c[13]||(c[13]=e("span",null,"Description",-1)),e("input",{class:"input",value:String(b.value.description??""),onInput:c[4]||(c[4]=B=>w("description",B.target.value))},null,40,hl)])]),q(ge,{"model-value":I.value,label:"Editor mode",options:[{value:"form",label:"Form"},{value:"json",label:"JSON"}],"onUpdate:modelValue":l},null,8,["model-value"]),I.value==="form"?(t(),s(S,{key:0},[P.value.length?(t(),s("p",bl," This config also has "+a(P.value.join(", "))+". They are kept as they are; edit them in the JSON tab. ",1)):d("",!0),e("details",yl,[c[14]||(c[14]=e("summary",null,"Defaults for every recipe",-1)),e("div",kl,[q(Be,{"model-value":F.value,options:n.options,"preset-names":K.value,"is-defaults":"","onUpdate:modelValue":x},null,8,["model-value","options","preset-names"])])]),e("div",$l,[(t(!0),s(S,null,L($.value,(B,W)=>(t(),s("div",{key:W,class:ae(["panel",{"panel--open":r.value===W}])},[e("div",_l,[e("button",{class:"panel__title",onClick:re=>r.value=r.value===W?-1:W},[e("strong",null,a(X(B,W)),1),e("span",Cl,a(ee(B)),1)],8,wl),e("div",Sl,[e("button",{class:"btn btn--ghost btn--small",disabled:W===0,"aria-label":"Move up",onClick:re=>ue(W,-1)},[q(Y,{name:"up",size:14})],8,Vl),e("button",{class:"btn btn--ghost btn--small",disabled:W===$.value.length-1,"aria-label":"Move down",onClick:re=>ue(W,1)},[q(Y,{name:"down",size:14})],8,xl),e("button",{class:"btn btn--ghost btn--small","aria-label":"Duplicate recipe",onClick:re=>Z(W)},[q(Y,{name:"copy",size:14})],8,El),e("button",{class:"btn btn--ghost btn--small btn--danger","aria-label":"Remove recipe",onClick:re=>ie(W)},[q(Y,{name:"close",size:14})],8,zl)])]),r.value===W?(t(),s("div",Al,[q(Be,{"model-value":B,options:n.options,"preset-names":K.value,"onUpdate:modelValue":re=>J(W,re)},null,8,["model-value","options","preset-names","onUpdate:modelValue"])])):d("",!0)],2))),128))]),e("button",{class:"btn",onClick:de},[q(Y,{name:"plus",size:16}),c[15]||(c[15]=A(" Add a recipe",-1))])],64)):(t(),s(S,{key:1},[e("textarea",{class:"json",spellcheck:"false",value:D.value,"aria-label":"Config JSON",onInput:c[5]||(c[5]=B=>y(B.target.value))},null,40,Nl),O.value?(t(),s("p",Ol,a(O.value),1)):d("",!0)],64)),C.value?(t(),s("div",{key:2,class:ae(["check-panel",C.value.ok?"check-panel--ok":"check-panel--bad"]),role:"status"},[C.value.ok?(t(),s(S,{key:0},[c[16]||(c[16]=e("strong",null,"The config is valid.",-1)),C.value.lines?.length?(t(),s("pre",Bl,a(M.value),1)):d("",!0)],64)):(t(),s(S,{key:1},[A(a(C.value.error),1)],64))],2)):d("",!0),h.value?(t(),s("p",jl,a(h.value),1)):d("",!0),e("div",Tl,[e("button",{class:"btn btn--primary",disabled:!te.value,onClick:c[6]||(c[6]=B=>H(!1))},[q(Y,{name:"save",size:15}),c[17]||(c[17]=A(" Save config ",-1))],8,Ul),e("button",{class:"btn",onClick:c[7]||(c[7]=B=>g("cancel"))},"Cancel")])],64))]))}}),Dl=oe(Il,[["__scopeId","data-v-5992429e"]]),Ml={class:"view"},Ll={key:1,class:"card block"},Rl={class:"head"},Fl={key:0,class:"notice"},Pl={key:1,class:"notice notice--error"},ql={key:2,class:"muted"},Jl={class:"list"},Kl={class:"item__main"},Wl={class:"item__title"},Hl={class:"tag"},Gl={key:0,class:"tag"},Ql={key:0,class:"item__error"},Yl={key:1,class:"muted"},Zl=["title"],Xl={class:"item__actions"},ea=["onClick"],ta=["onClick"],sa=["onClick"],la=ne({__name:"ConfigsView",props:{options:{}},setup(n){const k=v([]),i=v(""),g=v(""),f=v("list"),N=v(),b=v();async function z(){try{k.value=await Q.get("/api/image-batch/configs")}catch(h){i.value=h instanceof Error?h.message:String(h)}}function j(){N.value=void 0,b.value=void 0,f.value="edit"}function I(h){N.value=h,b.value=void 0,f.value="edit"}async function D(h){try{const p=await Q.get(`/api/image-batch/config?name=${encodeURIComponent(h.name)}&scope=${h.scope}`);N.value=void 0,b.value={name:h.name,raw:p.raw},f.value="edit"}catch(p){i.value=p instanceof Error?p.message:String(p)}}async function O(h){if(window.confirm(`Delete the config “${h.name}”? A .bak copy is kept next to it.`))try{await Q.post("/api/image-batch/config/delete",{name:h.name,scope:h.scope}),g.value=`Deleted ${h.name}.`,await z()}catch(p){i.value=p instanceof Error?p.message:String(p)}}async function C(h){f.value="list",g.value=`Saved ${h}.`,await z()}return pe(z),(h,p)=>(t(),s("div",Ml,[f.value==="edit"?(t(),le(Dl,{key:0,options:n.options,initial:N.value?{name:N.value.name,scope:N.value.scope}:void 0,"copy-of":b.value,onSaved:C,onCancel:p[0]||(p[0]=r=>f.value="list")},null,8,["options","initial","copy-of"])):(t(),s("section",Ll,[e("div",Rl,[p[2]||(p[2]=e("div",null,[e("h2",null,"Configs"),e("p",{class:"muted"}," A config is a reusable set of rules: sizes, formats, quality, names, sharpening. Apply it to any folder from the Convert tab. ")],-1)),e("button",{class:"btn btn--primary",onClick:j},[q(Y,{name:"plus",size:16}),p[1]||(p[1]=A(" New config ",-1))])]),g.value?(t(),s("p",Fl,a(g.value),1)):d("",!0),i.value?(t(),s("p",Pl,a(i.value),1)):d("",!0),k.value.length===0&&!i.value?(t(),s("p",ql," No configs yet. Create the first one, or use quick settings on the Convert tab. ")):d("",!0),e("ul",Jl,[(t(!0),s(S,null,L(k.value,r=>(t(),s("li",{key:r.scope+r.name+r.path,class:"item"},[e("div",Kl,[e("div",Wl,[e("strong",null,a(r.name),1),e("span",Hl,a(r.scope),1),r.kind!=="json"?(t(),s("span",Gl,"."+a(r.kind),1)):d("",!0)]),r.error?(t(),s("p",Ql,a(r.error),1)):(t(),s("p",Yl,[r.title?(t(),s(S,{key:0},[A(a(r.title)+" — ",1)],64)):d("",!0),A(" "+a(r.recipes)+" recipe"+a(r.recipes===1?"":"s")+" ",1),r.rules?(t(),s(S,{key:1},[A(", "+a(r.rules)+" rule"+a(r.rules===1?"":"s"),1)],64)):d("",!0),r.description?(t(),s(S,{key:2},[A(" · "+a(r.description),1)],64)):d("",!0)])),e("code",{class:"item__path",title:r.path},a(r.path),9,Zl)]),e("div",Xl,[r.editable?(t(),s("button",{key:0,class:"btn btn--small",onClick:_=>I(r)},"Edit",8,ea)):d("",!0),r.editable&&!r.error?(t(),s("button",{key:1,class:"btn btn--small",onClick:_=>D(r)}," Duplicate ",8,ta)):d("",!0),e("button",{class:"btn btn--small btn--danger",onClick:_=>O(r)},"Delete",8,sa)])]))),128))])]))]))}}),aa=oe(la,[["__scopeId","data-v-5b011a56"]]),na={class:"card block"},oa={class:"head"},ia={class:"muted"},ua={class:"chips"},ra={key:0,class:"chip"},da={key:1,class:"chip chip--good"},ca={key:0,class:"notice"},va={key:1,class:"notice"},pa={key:2,class:"muted small"},ma={key:3,class:"muted small"},fa={key:4,class:"errors"},ga={class:"rows"},ha=["src"],ba=["src"],ya={key:1,class:"row__thumb row__thumb--empty muted"},ka={class:"row__text"},$a=["title"],_a={class:"muted small"},wa={key:0,class:"small row__message"},Ca={class:"row__sizes"},Sa={key:0},Va={key:1,class:"muted"},xa={key:2},Ea={key:5,class:"more"},je=30,za=ne({__name:"BatchResults",props:{report:{}},setup(n){const k=n,i=he(ke,()=>{});function g(){try{k.report.backupDir&&localStorage.setItem("devtoolz-ui.open-backup",k.report.backupDir)}catch{i("backups");return}i("backups")}const f=v(je),N={written:"written","up-to-date":"up to date",skipped:"skipped",conflict:"conflict","would-write":"would write","would-overwrite":"would overwrite",replaced:"replaced",kept:"kept original","already-processed":"already processed","would-replace":"would replace","would-keep":"would keep",error:"error"},b=new Set(["written","replaced","up-to-date"]),z=new Set(["error","conflict"]),j=new Set(["written","replaced","up-to-date","skipped","kept"]),I=U(()=>Object.entries(k.report.counts).filter(([,r])=>r>0)),D=U(()=>{const{bytesIn:r,bytesOut:_}=k.report;if(!(k.report.dryRun||r<=0||_<=0))return{bytes:r-_,percent:Math.round((1-_/r)*100)}}),O=U(()=>k.report.results.slice(0,f.value));function C(r){return b.has(r)?"good":z.has(r)?"bad":"neutral"}function h(r){if(r.before===void 0||r.bytes===void 0||r.before<=0)return"";const _=Math.round((r.bytes/r.before-1)*100);return`${_>0?"+":""}${_}%`}function p(r){return!k.report.dryRun&&j.has(r.status)&&r.status!=="skipped"}return(r,_)=>(t(),s("section",na,[e("div",oa,[e("h2",null,a(n.report.dryRun?"Plan":"Result"),1),e("span",ia,[A(a(n.report.results.length)+" file"+a(n.report.results.length===1?"":"s")+" ",1),n.report.configLabel?(t(),s(S,{key:0},[A(" · config "+a(n.report.configLabel),1)],64)):d("",!0)])]),e("div",ua,[(t(!0),s(S,null,L(I.value,([$,F])=>(t(),s("span",{key:$,class:ae(["chip",`chip--${C($)}`])},a(F)+" "+a(N[$]),3))),128)),n.report.deduped?(t(),s("span",ra,a(n.report.deduped)+" merged (same result)",1)):d("",!0),D.value?(t(),s("span",da,[A(" saved "+a(G(ce)(Math.max(D.value.bytes,0)))+" ",1),D.value.percent>0?(t(),s(S,{key:0},[A("(−"+a(D.value.percent)+"%)",1)],64)):d("",!0)])):d("",!0)]),n.report.dryRun?(t(),s("p",ca," This is a preview: nothing was written. Press “Convert” to do it. ")):d("",!0),n.report.backupDir&&!n.report.dryRun?(t(),s("p",va,[_[2]||(_[2]=A(" Originals were copied to ",-1)),e("code",null,a(n.report.backupDir),1),_[3]||(_[3]=A(" first. ",-1)),e("button",{class:"link",onClick:g},"View or restore this backup")])):d("",!0),n.report.derived.length?(t(),s("p",pa,a(n.report.derived.length)+" earlier result"+a(n.report.derived.length===1?" was":"s were")+" not treated as sources. ",1)):d("",!0),n.report.vectors.length?(t(),s("p",ma,a(n.report.vectors.length)+" SVG file"+a(n.report.vectors.length===1?" was":"s were")+" left out of the replacement. ",1)):d("",!0),n.report.failures.length?(t(),s("ul",fa,[(t(!0),s(S,null,L(n.report.failures,$=>(t(),s("li",{key:$.file},[e("code",null,a($.file),1),A(" — "+a($.message),1)]))),128))])):d("",!0),e("ul",ga,[(t(!0),s(S,null,L(O.value,$=>(t(),s("li",{key:`${$.sourceAbs}|${$.outputAbs}|${$.recipe}`,class:"row"},[e("img",{class:"row__thumb",loading:"lazy",alt:"",src:G(be)($.sourceAbs,120)},null,8,ha),_[4]||(_[4]=e("span",{class:"row__arrow muted"},"→",-1)),p($)?(t(),s("img",{key:0,class:"row__thumb",loading:"lazy",alt:"",src:G(be)($.outputAbs,120)},null,8,ba)):(t(),s("span",ya,a(n.report.dryRun?"plan":"—"),1)),e("div",ka,[e("span",{class:"row__name",title:$.outputAbs},a($.output),9,$a),e("span",_a,[A(" from "+a($.source)+" · "+a($.width)+"×"+a($.height)+" · "+a($.format)+" ",1),$.recipe?(t(),s(S,{key:0},[A(" · "+a($.recipe),1)],64)):d("",!0)]),$.message?(t(),s("span",wa,a($.message),1)):d("",!0)]),e("div",Ca,[$.before!==void 0?(t(),s("span",Sa,a(G(ce)($.before)),1)):d("",!0),$.before!==void 0&&$.bytes!==void 0?(t(),s("span",Va,"→")):d("",!0),$.bytes!==void 0?(t(),s("strong",xa,a(G(ce)($.bytes)),1)):d("",!0),h($)?(t(),s("span",{key:3,class:ae(["row__delta",{"row__delta--down":h($).startsWith("-")}])},a(h($)),3)):d("",!0)]),e("span",{class:ae(["chip",`chip--${C($.status)}`])},a(N[$.status]),3)]))),128))]),f.value<n.report.results.length?(t(),s("div",Ea,[e("button",{class:"btn",onClick:_[0]||(_[0]=$=>f.value+=je)}," Show more ("+a(n.report.results.length-f.value)+" left) ",1),e("button",{class:"btn",onClick:_[1]||(_[1]=$=>f.value=n.report.results.length)}," Show all ("+a(n.report.results.length)+") ",1)])):d("",!0)]))}}),Aa=oe(za,[["__scopeId","data-v-b00b9955"]]),Na={class:"view"},Oa={key:0,class:"notice notice--warn"},Ba={class:"card block"},ja={class:"pathrow"},Ta={class:"check"},Ua={key:1,class:"muted"},Ia={class:"check"},Da={class:"check"},Ma={key:3,class:"field narrow"},La={class:"card block"},Ra={class:"head"},Fa={key:0,class:"muted"},Pa={class:"field narrow"},qa=["value","disabled"],Ja={key:0,class:"muted"},Ka={class:"group"},Wa={class:"grid"},Ha={class:"field"},Ga=["value"],Qa={key:0,class:"field"},Ya={key:1,class:"field"},Za=["placeholder"],Xa={key:2,class:"field"},en=["value"],tn={key:0,class:"check"},sn={key:1,class:"muted small"},ln={class:"group"},an={key:0,class:"muted small"},nn={key:1,class:"pills"},on=["checked","onChange"],un={class:"grid"},rn={class:"field"},dn=["value"],cn={key:0,class:"field"},vn={class:"field"},pn={key:0,class:"group"},mn=["placeholder"],fn={class:"pills"},gn=["onClick"],hn={class:"muted small"},bn={class:"group"},yn={class:"runbar"},kn=["disabled"],$n=["disabled"],_n={key:0,class:"muted"},wn={key:1,class:"card block",role:"status"},Cn={class:"progress"},Sn={class:"muted"},Vn={key:2,class:"notice notice--error"},xn=ne({__name:"ConvertView",props:{cwd:{},options:{}},setup(n){const k=n,i=he(ke,()=>{}),g={original:"Keep the original size",widths:"By width (px)",heights:"By height (px)",size:"Fit into a box",longEdge:"By the long side (px)",shortEdge:"By the short side (px)",megapixels:"By area (megapixels)",percent:"By percentage"},f={original:"",widths:"e.g. 400, 800, 1200 — one file per size",heights:"e.g. 300, 600",size:"",longEdge:"e.g. 1600 — the same for landscape and portrait",shortEdge:"e.g. 1080",megapixels:"e.g. 2, 0.5",percent:"e.g. 50, 25"},N={name:"photo",ext:"jpg",orig:"photo.jpg",dir:"trips/2026",format:"webp",width:"800",height:"600",size:"800x600",long:"800",short:"600",mp:"0.48",percent:"50",scale:"2",index:"001",hash:"a1b2c3d4",date:"2026-10-08"},b=U(()=>k.options),z=v([]),j=v([]),I=v(!0),D=v(0),O=v("out"),C=v(""),h=v(!1),p=v("skip"),r=v(!0),_=v(!0),$=v(!1),F=v("quick"),K=v(""),P=v("widths"),M=v("800, 1600"),te=v("1920x1080"),V=v("inside"),w=v(!1),x=v(["webp"]),J=v(""),de=v("82"),ie=v(""),Z=v(""),ue=v(Le()),X=v("idle"),ee=v({done:0,total:0}),y=v(""),l=v();let u;const H=U(()=>k.cwd.includes("\\")?"\\":"/"),E=U(()=>y.value.toLowerCase().includes("sharp")),c=U(()=>z.value.find(T=>T.name===K.value)),B=U(()=>ee.value.total>0?Math.round(ee.value.done/ee.value.total*100):0),W=U(()=>b.value?.defaultTemplates[P.value]??"{dir}/{name}.{format}"),re=U(()=>(Z.value.trim()||W.value).replace(/\{([a-zA-Z]+)(?::(\d+))?\}/g,(o,m)=>N[m]??`{${m}}`)),$e=U(()=>j.value.length===0?"Add at least one folder or image.":D.value===0&&j.value.length>0?"No images found in the added sources.":O.value==="out"&&C.value.trim()===""?"Choose the folder for the results.":F.value==="config"&&K.value===""?"Choose a saved config.":F.value==="quick"&&O.value!=="replace"&&x.value.length===0?"Pick at least one format.":""),Ee=U(()=>$e.value===""&&X.value!=="running");function Fe(T){D.value=T?.total.files??0,j.value.length>0&&T===void 0&&(D.value=1)}function Pe(T){x.value=x.value.includes(T)?x.value.filter(o=>o!==T):[...x.value,T]}function qe(T){return"{"+T+"}"}function Je(T){C.value=T[0]??C.value,$.value=!1}function Ke(T){Z.value=(Z.value||W.value)+`{${T}}`}function We(){const T=j.value[0];if(C.value!==""||!T)return;const o=T.replace(/[\\/]+$/,"");C.value=`${o}${H.value}converted`}function He(){const T={sizeMethod:P.value};P.value==="size"?(T.box=te.value,T.fit=V.value,T.matchOrientation=w.value):P.value!=="original"&&(T.values=M.value.split(/[,\s]+/).filter(Boolean).map(Number)),T.formats=O.value==="replace"?["original"]:x.value,J.value==="custom"?T.quality=Number(de.value):J.value&&(T.quality=J.value),ie.value.trim()&&(T.maxBytes=ie.value.trim()),O.value!=="replace"&&Z.value.trim()&&(T.name=Z.value.trim());const o=ts(ue.value);return o&&(T.sharpen=o),T}async function _e(T,o=!1){if(!(!T&&O.value==="replace"&&!window.confirm(`This rewrites ${D.value} original file${D.value===1?"":"s"} in place.`+(r.value?" The originals are copied to a backup folder first.":" No backup will be made.")+`
|
|
3
|
-
|
|
4
|
-
Continue?`))){u?.(),X.value="running",y.value="",l.value=void 0,ee.value={done:0,total:0};try{const{jobId:m}=await Q.post("/api/image-batch/run",{paths:j.value,recursive:I.value,placement:O.value,out:C.value,flat:h.value,overwrite:p.value,backup:r.value,onlyIfSmaller:_.value,config:F.value==="config"?K.value:void 0,settings:F.value==="quick"?He():void 0,dryRun:T,installSharp:o});u=Xe(m,{onProgress:me=>{ee.value=me},onDone:me=>{l.value=me,X.value="done"},onFailed:me=>{y.value=me,X.value="failed"}})}catch(m){y.value=m instanceof Error?m.message:String(m),X.value="failed"}}}return pe(async()=>{try{z.value=await Q.get("/api/image-batch/configs")}catch(T){y.value=T instanceof Error?T.message:String(T),X.value="failed"}}),Se(()=>u?.()),(T,o)=>(t(),s("div",Na,[b.value&&!b.value.sharp?(t(),s("div",Oa," The sharp image library is not installed yet. Previews are limited, and the first run will offer to install it. ")):d("",!0),q(et,{sources:j.value,"onUpdate:sources":o[0]||(o[0]=m=>j.value=m),recursive:I.value,"onUpdate:recursive":o[1]||(o[1]=m=>I.value=m),"scan-url":"/api/image-batch/scan",start:n.cwd,onScanned:Fe},null,8,["sources","recursive","start"]),e("section",Ba,[o[34]||(o[34]=e("h2",null,"Where the results go",-1)),q(ge,{modelValue:O.value,"onUpdate:modelValue":[o[2]||(o[2]=m=>O.value=m),We],label:"Placement",options:[{value:"out",label:"A separate folder",hint:"the sources are not touched"},{value:"beside",label:"Next to each original",hint:"new files beside the sources"},{value:"replace",label:"Replace the originals",hint:"rewrites the files, with a backup"}]},null,8,["modelValue"]),O.value==="out"?(t(),s(S,{key:0},[e("div",ja,[R(e("input",{"onUpdate:modelValue":o[3]||(o[3]=m=>C.value=m),class:"input",spellcheck:"false",placeholder:"Folder for the results","aria-label":"Folder for the results"},null,512),[[se,C.value]]),e("button",{class:"btn",onClick:o[4]||(o[4]=m=>$.value=!0)},[q(Y,{name:"folder",size:16}),o[27]||(o[27]=A(" Browse ",-1))])]),e("label",Ta,[R(e("input",{"onUpdate:modelValue":o[5]||(o[5]=m=>h.value=m),type:"checkbox"},null,512),[[fe,h.value]]),o[28]||(o[28]=A(" Put everything in one folder (no subfolders) ",-1))])],64)):O.value==="beside"?(t(),s("p",Ua," Each result is written next to its original, with the size or format in the name. ")):(t(),s(S,{key:2},[o[31]||(o[31]=e("p",{class:"notice notice--warn"}," Each original is overwritten with its converted version, keeping its own format. Use the preview first. ",-1)),e("label",Ia,[R(e("input",{"onUpdate:modelValue":o[6]||(o[6]=m=>r.value=m),type:"checkbox"},null,512),[[fe,r.value]]),o[29]||(o[29]=A(" Copy the originals to a backup folder first",-1))]),e("label",Da,[R(e("input",{"onUpdate:modelValue":o[7]||(o[7]=m=>_.value=m),type:"checkbox"},null,512),[[fe,_.value]]),o[30]||(o[30]=A(" Replace a file only when the result is smaller ",-1))])],64)),O.value!=="replace"?(t(),s("label",Ma,[o[33]||(o[33]=e("span",null,"If a result already exists",-1)),R(e("select",{"onUpdate:modelValue":o[8]||(o[8]=m=>p.value=m),class:"select"},[...o[32]||(o[32]=[e("option",{value:"skip"},"Skip it",-1),e("option",{value:"overwrite"},"Overwrite it",-1),e("option",{value:"error"},"Stop and report it",-1)])],512),[[ve,p.value]])])):d("",!0)]),e("section",La,[e("div",Ra,[o[35]||(o[35]=e("h2",null,"What to do",-1)),q(ge,{modelValue:F.value,"onUpdate:modelValue":o[9]||(o[9]=m=>F.value=m),label:"Settings source",options:[{value:"quick",label:"Quick settings"},{value:"config",label:"Saved config"}]},null,8,["modelValue"])]),F.value==="config"?(t(),s(S,{key:0},[z.value.length===0?(t(),s("p",Fa,[o[36]||(o[36]=A(" No configs yet. ",-1)),e("button",{class:"link",onClick:o[10]||(o[10]=m=>G(i)("configs"))},"Create the first one"),o[37]||(o[37]=A(" or use quick settings. ",-1))])):(t(),s(S,{key:1},[e("label",Pa,[o[39]||(o[39]=e("span",null,"Config",-1)),R(e("select",{"onUpdate:modelValue":o[11]||(o[11]=m=>K.value=m),class:"select"},[o[38]||(o[38]=e("option",{value:"",disabled:""},"Choose a config…",-1)),(t(!0),s(S,null,L(z.value,m=>(t(),s("option",{key:m.name+m.scope,value:m.name,disabled:!!m.error},a(m.name)+" · "+a(m.scope),9,qa))),128))],512),[[ve,K.value]])]),e("button",{class:"link",onClick:o[12]||(o[12]=m=>G(i)("configs"))},"Manage configs"),c.value?(t(),s("p",Ja,[c.value.title?(t(),s(S,{key:0},[A(a(c.value.title)+" — ",1)],64)):d("",!0),A(" "+a(c.value.recipes)+" recipe"+a(c.value.recipes===1?"":"s")+" ",1),c.value.rules?(t(),s(S,{key:1},[A(", "+a(c.value.rules)+" rule"+a(c.value.rules===1?"":"s"),1)],64)):d("",!0),c.value.description?(t(),s(S,{key:2},[A(" · "+a(c.value.description),1)],64)):d("",!0)])):d("",!0)],64))],64)):b.value?(t(),s(S,{key:1},[e("div",Ka,[o[45]||(o[45]=e("h3",null,"Size",-1)),e("div",Wa,[e("label",Ha,[o[40]||(o[40]=e("span",null,"Method",-1)),R(e("select",{"onUpdate:modelValue":o[13]||(o[13]=m=>P.value=m),class:"select"},[(t(!0),s(S,null,L(b.value.sizeMethods,m=>(t(),s("option",{key:m,value:m},a(g[m]),9,Ga))),128))],512),[[ve,P.value]])]),P.value==="size"?(t(),s("label",Qa,[o[41]||(o[41]=e("span",null,"Box (width × height)",-1)),R(e("input",{"onUpdate:modelValue":o[14]||(o[14]=m=>te.value=m),class:"input",spellcheck:"false",placeholder:"1920x1080"},null,512),[[se,te.value]])])):P.value!=="original"?(t(),s("label",Ya,[o[42]||(o[42]=e("span",null,"Values",-1)),R(e("input",{"onUpdate:modelValue":o[15]||(o[15]=m=>M.value=m),class:"input",spellcheck:"false",placeholder:f[P.value]},null,8,Za),[[se,M.value]])])):d("",!0),P.value==="size"?(t(),s("label",Xa,[o[43]||(o[43]=e("span",null,"How it fills the box",-1)),R(e("select",{"onUpdate:modelValue":o[16]||(o[16]=m=>V.value=m),class:"select"},[(t(!0),s(S,null,L(b.value.fitModes,m=>(t(),s("option",{key:m,value:m},a(m),9,en))),128))],512),[[ve,V.value]])])):d("",!0)]),P.value==="size"?(t(),s("label",tn,[R(e("input",{"onUpdate:modelValue":o[17]||(o[17]=m=>w.value=m),type:"checkbox"},null,512),[[fe,w.value]]),o[44]||(o[44]=A(" Turn the box around for portrait images ",-1))])):f[P.value]?(t(),s("p",sn,a(f[P.value])+". Images are never enlarged. ",1)):d("",!0)]),e("div",ln,[o[51]||(o[51]=e("h3",null,"Formats",-1)),O.value==="replace"?(t(),s("p",an," Each file keeps its own format when the originals are replaced. ")):(t(),s("div",nn,[(t(!0),s(S,null,L(b.value.formats,m=>(t(),s("label",{key:m,class:ae(["pill",{"pill--on":x.value.includes(m)}])},[e("input",{type:"checkbox",checked:x.value.includes(m),onChange:me=>Pe(m)},null,40,on),A(" "+a(m),1)],2))),128))])),e("div",un,[e("label",rn,[o[48]||(o[48]=e("span",null,"Quality",-1)),R(e("select",{"onUpdate:modelValue":o[18]||(o[18]=m=>J.value=m),class:"select"},[o[46]||(o[46]=e("option",{value:""},"Default (high)",-1)),(t(!0),s(S,null,L(b.value.qualityLevels,m=>(t(),s("option",{key:m,value:m},a(m),9,dn))),128)),o[47]||(o[47]=e("option",{value:"custom"},"A number…",-1))],512),[[ve,J.value]])]),J.value==="custom"?(t(),s("label",cn,[o[49]||(o[49]=e("span",null,"Quality (1–100)",-1)),R(e("input",{"onUpdate:modelValue":o[19]||(o[19]=m=>de.value=m),class:"input",inputmode:"numeric"},null,512),[[se,de.value]])])):d("",!0),e("label",vn,[o[50]||(o[50]=e("span",null,"Largest file size",-1)),R(e("input",{"onUpdate:modelValue":o[20]||(o[20]=m=>ie.value=m),class:"input",spellcheck:"false",placeholder:"e.g. 200KB (optional)"},null,512),[[se,ie.value]])])])]),O.value!=="replace"?(t(),s("div",pn,[o[53]||(o[53]=e("h3",null,"File names",-1)),R(e("input",{"onUpdate:modelValue":o[21]||(o[21]=m=>Z.value=m),class:"input",spellcheck:"false",placeholder:W.value,"aria-label":"File name template"},null,8,mn),[[se,Z.value]]),e("div",fn,[(t(!0),s(S,null,L(b.value.templateVariables,m=>(t(),s("button",{key:m,class:"pill pill--button",onClick:me=>Ke(m)},a(qe(m)),9,gn))),128))]),e("p",hn,[o[52]||(o[52]=A(" Example: ",-1)),e("code",null,a(re.value),1),Z.value.trim()?d("",!0):(t(),s(S,{key:0},[A(" (the default for this size method)")],64))])])):d("",!0),e("div",bn,[o[54]||(o[54]=e("h3",null,"Sharpening",-1)),q(Me,{modelValue:ue.value,"onUpdate:modelValue":o[22]||(o[22]=m=>ue.value=m),options:b.value,manage:""},null,8,["modelValue","options"])])],64)):d("",!0)]),e("div",yn,[e("button",{class:"btn",disabled:!Ee.value,onClick:o[23]||(o[23]=m=>_e(!0))},"Preview",8,kn),e("button",{class:"btn btn--primary",disabled:!Ee.value,onClick:o[24]||(o[24]=m=>_e(!1))},[q(Y,{name:"play",size:15}),A(" "+a(X.value==="running"?"Working…":"Convert"),1)],8,$n),$e.value?(t(),s("span",_n,a($e.value),1)):d("",!0)]),X.value==="running"?(t(),s("div",wn,[e("div",Cn,[e("div",{class:"progress__bar",style:Ce({width:`${B.value}%`})},null,4)]),e("span",Sn,a(ee.value.done)+" of "+a(ee.value.total||"…")+" files",1)])):d("",!0),X.value==="failed"?(t(),s("div",Vn,[e("p",null,a(y.value),1),E.value?(t(),s("button",{key:0,class:"btn btn--small",onClick:o[25]||(o[25]=m=>_e(!1,!0))}," Install sharp and retry ")):d("",!0)])):d("",!0),l.value?(t(),le(Aa,{key:3,report:l.value},null,8,["report"])):d("",!0),$.value?(t(),le(Ve,{key:4,start:C.value||j.value[0]||n.cwd,mode:"folder",title:"Choose the folder for the results",onClose:o[26]||(o[26]=m=>$.value=!1),onConfirm:Je},null,8,["start"])):d("",!0)]))}}),En=oe(xn,[["__scopeId","data-v-ecb5fab6"]]),zn=["aria-busy"],An={class:"compare__scroll"},Nn={class:"compare__stage"},On=["src"],Bn=["src"],jn={class:"compare__tag compare__tag--left"},Tn={class:"compare__tag compare__tag--right"},Un=ne({__name:"UiCompare",props:{before:{},after:{},beforeLabel:{},afterLabel:{}},setup(n){const k=v(50),i=v(!0);return(g,f)=>(t(),s("div",{class:"compare","aria-busy":i.value},[e("div",An,[e("div",Nn,[e("img",{class:"compare__img",alt:"Before",src:n.before,onLoad:f[0]||(f[0]=N=>i.value=!1)},null,40,On),e("img",{class:"compare__img compare__img--top",alt:"After",src:n.after,style:Ce({clipPath:`inset(0 0 0 ${k.value}%)`})},null,12,Bn),e("span",{class:"compare__line",style:Ce({left:`${k.value}%`})},null,4),e("span",jn,a(n.beforeLabel??"Before"),1),e("span",Tn,a(n.afterLabel??"After"),1)])]),R(e("input",{"onUpdate:modelValue":f[1]||(f[1]=N=>k.value=N),class:"compare__range",type:"range",min:"0",max:"100","aria-label":"Comparison position"},null,512),[[se,k.value,void 0,{number:!0}]])],8,zn))}}),In=oe(Un,[["__scopeId","data-v-0ee1b3e3"]]),Dn={class:"card block"},Mn={class:"head"},Ln={class:"grid"},Rn={class:"field"},Fn={class:"field"},Pn={value:"project"},qn={class:"field wide"},Jn={class:"grid"},Kn={class:"field"},Wn=["value"],Hn={class:"field"},Gn=["value"],Qn={class:"grid"},Yn={class:"muted"},Zn=["onUpdate:modelValue"],Xn={key:0,class:"notice notice--error"},eo={key:1,class:"muted small"},to={class:"preview"},so={class:"head"},lo={class:"previewbar"},ao={class:"field inline"},no={key:0,class:"muted"},oo={key:2,class:"muted small"},io={key:2,class:"notice notice--error"},uo={class:"actions"},ro=["disabled"],Te="devtoolz-ui.sharpen-sample",co=ne({__name:"SharpenEditor",props:{options:{},cwd:{},initial:{},copyOf:{}},emits:["saved","cancel"],setup(n,{emit:k}){const i=n,g=k,f=he(xe,De),N=["radius","flat","jagged","threshold"];function b(){return i.initial??i.copyOf}function z(y){const l=b()?.fields?.[y];return l===void 0?"":String(l)}const j=U(()=>i.initial!==void 0),I=v(i.initial?i.initial.name:i.copyOf?.name??""),D=v(i.initial&&i.initial.scope!=="built-in"?i.initial.scope:"project"),O=v(b()?.description??""),C=v(String(b()?.fields?.for??"")),h=v(String(b()?.fields?.amount??"")),p=v({radius:z("radius"),flat:z("flat"),jagged:z("jagged"),threshold:z("threshold")}),r=v(""),_=v("800"),$=v(!1),F=v(),K=v(""),P=v(""),M=v(!1),te=v("");let V;const w=U(()=>Object.fromEntries(i.options.sharpen.fine.map(y=>[y.key,y.range])));function x(){const y={};C.value&&(y.for=C.value),h.value&&(y.amount=h.value);for(const l of N)p.value[l].trim()!==""&&(y[l]=Number(p.value[l]));return y}function J(y){const l=new URLSearchParams({path:r.value,width:_.value||"800"});if(y){l.set("sharpen","1");for(const[u,H]of Object.entries(x()))l.set(u,String(H))}return`/api/image-batch/sharpen-preview?${l.toString()}&v=${te.value}`}const de=U(()=>r.value?J(!1):""),ie=U(()=>r.value?J(!0):"");async function Z(){try{const y=await Q.post("/api/image-batch/sharpen-preset/params",{fields:x()});F.value=y.params,K.value=""}catch(y){F.value=void 0,K.value=y instanceof Error?y.message:String(y)}te.value=JSON.stringify(x())+_.value}function ue(){clearTimeout(V),V=setTimeout(()=>{Z()},300)}ye([C,h,p,_],ue,{deep:!0});function X(y){r.value=y[0]??"",$.value=!1;try{localStorage.setItem(Te,r.value)}catch{r.value=y[0]??""}}async function ee(y=!1){M.value=!0,P.value="";try{await Q.post("/api/image-batch/sharpen-preset/save",{name:I.value,scope:D.value,description:O.value,fields:x(),overwrite:y,...i.initial?{originalName:i.initial.name,originalScope:i.initial.scope}:{}}),g("saved",I.value)}catch(l){if(l instanceof Ie&&l.status===409){if(window.confirm(`${l.message}. Replace it?`)){await ee(!0);return}}else P.value=l instanceof Error?l.message:String(l)}finally{M.value=!1}}return pe(()=>{try{r.value=localStorage.getItem(Te)??""}catch{r.value=""}Z()}),Se(()=>clearTimeout(V)),(y,l)=>(t(),s("section",Dn,[e("div",Mn,[e("h2",null,a(j.value?"Edit preset":n.copyOf?"Copy of a built-in preset":"New sharpening preset"),1),e("button",{class:"btn btn--ghost",onClick:l[0]||(l[0]=u=>g("cancel"))},[q(Y,{name:"close",size:16}),l[11]||(l[11]=A(" Close ",-1))])]),e("div",Ln,[e("label",Rn,[l[12]||(l[12]=e("span",null,"Name",-1)),R(e("input",{"onUpdate:modelValue":l[1]||(l[1]=u=>I.value=u),class:"input",spellcheck:"false",placeholder:"web-crisp"},null,512),[[se,I.value]])]),e("label",Fn,[l[14]||(l[14]=e("span",null,"Where to keep it",-1)),R(e("select",{"onUpdate:modelValue":l[2]||(l[2]=u=>D.value=u),class:"select"},[e("option",Pn,"This project ("+a(G(f).name)+")",1),l[13]||(l[13]=e("option",{value:"global"},"All projects (your home folder)",-1))],512),[[ve,D.value]])]),e("label",qn,[l[15]||(l[15]=e("span",null,"Note (optional)",-1)),R(e("input",{"onUpdate:modelValue":l[3]||(l[3]=u=>O.value=u),class:"input",placeholder:"What it is for"},null,512),[[se,O.value]])])]),e("div",Jn,[e("label",Kn,[l[17]||(l[17]=e("span",null,"Sharpen for",-1)),R(e("select",{"onUpdate:modelValue":l[4]||(l[4]=u=>C.value=u),class:"select"},[l[16]||(l[16]=e("option",{value:""},"Default (screen)",-1)),(t(!0),s(S,null,L(n.options.sharpen.targets,u=>(t(),s("option",{key:u,value:u},a(u),9,Wn))),128))],512),[[ve,C.value]])]),e("label",Hn,[l[19]||(l[19]=e("span",null,"Amount",-1)),R(e("select",{"onUpdate:modelValue":l[5]||(l[5]=u=>h.value=u),class:"select"},[l[18]||(l[18]=e("option",{value:""},"Default (standard)",-1)),(t(!0),s(S,null,L(n.options.sharpen.amounts,u=>(t(),s("option",{key:u,value:u},a(u),9,Gn))),128))],512),[[ve,h.value]])])]),e("div",Qn,[(t(),s(S,null,L(N,u=>e("label",{key:u,class:"field"},[e("span",null,[A(a(u)+" ",1),e("small",Yn,"("+a(w.value[u]?.[0])+"–"+a(w.value[u]?.[1])+")",1)]),R(e("input",{"onUpdate:modelValue":H=>p.value[u]=H,class:"input",inputmode:"decimal",placeholder:"value from the table"},null,8,Zn),[[se,p.value[u]]])])),64))]),K.value?(t(),s("p",Xn,a(K.value),1)):F.value?(t(),s("p",eo,[A(" sharp receives: sigma "+a(F.value.sigma)+", flat "+a(F.value.m1)+", jagged "+a(F.value.m2),1),F.value.x1!==void 0?(t(),s(S,{key:0},[A(", threshold "+a(F.value.x1),1)],64)):d("",!0)])):d("",!0),e("div",to,[e("div",so,[l[21]||(l[21]=e("h3",null,"Preview",-1)),e("div",lo,[e("label",ao,[l[20]||(l[20]=e("span",null,"Width",-1)),R(e("input",{"onUpdate:modelValue":l[6]||(l[6]=u=>_.value=u),class:"input narrow",inputmode:"numeric","aria-label":"Preview width"},null,512),[[se,_.value]])]),e("button",{class:"btn btn--small",onClick:l[7]||(l[7]=u=>$.value=!0)},[q(Y,{name:"image",size:15}),A(" "+a(r.value?"Change image":"Choose an image"),1)])])]),r.value?K.value?d("",!0):(t(),le(In,{key:r.value,before:de.value,after:ie.value,"before-label":"Without sharpening","after-label":"Sharpened"},null,8,["before","after"])):(t(),s("p",no," Pick any photo to see the preset applied at the output size. Drag the slider to compare. ")),r.value?(t(),s("p",oo,a(r.value)+" — resized to "+a(_.value||800)+" px wide, then sharpened, as it would be at the output size. ",1)):d("",!0)]),P.value?(t(),s("p",io,a(P.value),1)):d("",!0),e("div",uo,[e("button",{class:"btn btn--primary",disabled:M.value||I.value.trim()==="",onClick:l[8]||(l[8]=u=>ee(!1))},[q(Y,{name:"save",size:15}),l[22]||(l[22]=A(" Save preset ",-1))],8,ro),e("button",{class:"btn",onClick:l[9]||(l[9]=u=>g("cancel"))},"Cancel")]),$.value?(t(),le(Ve,{key:3,start:r.value?r.value.replace(/[\\/][^\\/]*$/,""):n.cwd,mode:"image",onClose:l[10]||(l[10]=u=>$.value=!1),onConfirm:X},null,8,["start"])):d("",!0)]))}}),vo=oe(co,[["__scopeId","data-v-8e3f1eea"]]),po={class:"view"},mo={key:1,class:"card block"},fo={class:"head"},go={key:0,class:"notice"},ho={key:1,class:"notice notice--error"},bo={class:"list"},yo={class:"item__main"},ko={class:"item__title"},$o={key:0,class:"item__error"},_o={key:0,class:"muted"},wo={class:"item__facts"},Co={key:0,class:"muted"},So={class:"item__actions"},Vo=["onClick"],xo=["onClick"],Eo=["onClick"],zo=ne({__name:"SharpenView",props:{options:{},cwd:{}},setup(n){const k=v([]),i=v(""),g=v(""),f=v("list"),N=v(),b=v();async function z(){try{k.value=await Q.get("/api/image-batch/sharpen-presets")}catch(p){i.value=p instanceof Error?p.message:String(p)}}function j(){N.value=void 0,b.value=void 0,f.value="edit"}function I(p){N.value=p,b.value=void 0,f.value="edit"}function D(p){N.value=void 0,b.value=p,f.value="edit"}async function O(p){if(window.confirm(`Delete the preset “${p.name}”? A .bak copy is kept next to it.`))try{await Q.post("/api/image-batch/sharpen-preset/delete",{name:p.name,scope:p.scope}),g.value=`Deleted ${p.name}.`,await z()}catch(r){i.value=r instanceof Error?r.message:String(r)}}async function C(p){f.value="list",g.value=`Saved ${p}.`,await z()}function h(p){return Object.entries(p.fields??{}).map(([r,_])=>`${r} ${_}`).join(" · ")}return pe(z),(p,r)=>(t(),s("div",po,[f.value==="edit"?(t(),le(vo,{key:0,options:n.options,cwd:n.cwd,initial:N.value,"copy-of":b.value,onSaved:C,onCancel:r[0]||(r[0]=_=>f.value="list")},null,8,["options","cwd","initial","copy-of"])):(t(),s("section",mo,[e("div",fo,[r[2]||(r[2]=e("div",null,[e("h2",null,"Sharpening presets"),e("p",{class:"muted"}," Save a set of sharpening values once and use it by name in any config or run. ")],-1)),e("button",{class:"btn btn--primary",onClick:j},[q(Y,{name:"plus",size:16}),r[1]||(r[1]=A(" New preset ",-1))])]),g.value?(t(),s("p",go,a(g.value),1)):d("",!0),i.value?(t(),s("p",ho,a(i.value),1)):d("",!0),e("ul",bo,[(t(!0),s(S,null,L(k.value,_=>(t(),s("li",{key:_.scope+_.name,class:"item"},[e("div",yo,[e("div",ko,[e("strong",null,a(_.name),1),e("span",{class:ae(["tag",{"tag--builtin":_.scope==="built-in"}])},a(_.scope),3)]),_.error?(t(),s("p",$o,a(_.error),1)):(t(),s(S,{key:1},[_.description?(t(),s("p",_o,a(_.description),1)):d("",!0),e("p",wo,[A(a(h(_))+" ",1),_.params?(t(),s("span",Co," — sigma "+a(_.params.sigma)+", flat "+a(_.params.m1)+", jagged "+a(_.params.m2),1)):d("",!0)])],64))]),e("div",So,[_.scope!=="built-in"&&!_.error?(t(),s("button",{key:0,class:"btn btn--small",onClick:$=>I(_)}," Edit ",8,Vo)):d("",!0),_.error?d("",!0):(t(),s("button",{key:1,class:"btn btn--small",onClick:$=>D(_)},a(_.scope==="built-in"?"Copy to my presets":"Duplicate"),9,xo)),_.scope!=="built-in"?(t(),s("button",{key:2,class:"btn btn--small btn--danger",onClick:$=>O(_)}," Delete ",8,Eo)):d("",!0)])]))),128))])]))]))}}),Ao=oe(zo,[["__scopeId","data-v-519b182c"]]),No={class:"page"},Oo={class:"page__head"},Bo={class:"muted"},jo=["title"],To={key:0,class:"notice notice--error"},Ue="devtoolz-ui.image-batch-tab",Uo=ne({__name:"ImageBatchPage",props:{module:{},status:{}},setup(n){const k=n;function i(){try{const z=localStorage.getItem(Ue);if(z==="convert"||z==="configs"||z==="sharpen"||z==="backups")return z}catch{return"convert"}return"convert"}const g=v(i()),f=v(),N=v("");function b(z){g.value=z;try{localStorage.setItem(Ue,z)}catch{g.value=z}}return ze(ke,b),ze(xe,U(()=>It(k.status?.cwd??"",k.status?.home??"")).value),pe(async()=>{try{f.value=await Q.get("/api/image-batch/options")}catch(z){N.value=z instanceof Error?z.message:String(z)}}),(z,j)=>(t(),s("div",No,[e("header",Oo,[e("h1",null,a(n.module.title),1),e("p",Bo,a(n.module.description),1),n.status?.cwd?(t(),s("p",{key:0,class:"context",title:`Everything marked “This project” lives in ${n.status.cwd}`},[q(Y,{name:"folder",size:15}),j[0]||(j[0]=e("span",{class:"muted"},"Project folder",-1)),e("code",null,a(n.status.cwd),1)],8,jo)):d("",!0)]),q(ge,{"model-value":g.value,label:"Image Batch sections",options:[{value:"convert",label:"Convert"},{value:"configs",label:"Configs"},{value:"sharpen",label:"Sharpening"},{value:"backups",label:"Backups"}],"onUpdate:modelValue":b},null,8,["model-value"]),N.value?(t(),s("p",To,a(N.value),1)):f.value?(t(),s(S,{key:1},[g.value==="convert"?(t(),le(En,{key:0,cwd:k.status?.cwd??"",options:f.value},null,8,["cwd","options"])):g.value==="configs"?(t(),le(aa,{key:1,options:f.value},null,8,["options"])):g.value==="sharpen"?(t(),le(Ao,{key:2,options:f.value,cwd:k.status?.cwd??""},null,8,["options","cwd"])):(t(),le(Ut,{key:3,cwd:k.status?.cwd??""},null,8,["cwd"]))],64)):d("",!0)]))}}),Ro=oe(Uo,[["__scopeId","data-v-85ee2fe2"]]);export{Ro as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.view[data-v-aa574981]{display:flex;flex-direction:column;gap:16px}.block[data-v-aa574981]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.small[data-v-aa574981]{font-size:12px}.list[data-v-aa574981]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.item[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:12px;border:1px solid var(--border);border-radius:9px}.item__main[data-v-aa574981]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:260px}.item__path[data-v-aa574981]{color:var(--muted);font-size:11px;word-break:break-all}.item__actions[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.custom[data-v-aa574981]{display:flex;flex-direction:column;gap:8px;padding-top:12px;border-top:1px solid var(--border)}.custom h3[data-v-aa574981]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase}.pathrow[data-v-aa574981]{display:flex;flex-wrap:wrap;gap:8px}.pathrow .input[data-v-aa574981]{flex:1;min-width:220px;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.actions[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:center;gap:12px}.chips[data-v-aa574981]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.chip[data-v-aa574981]{padding:2px 10px;border-radius:999px;background:var(--surface-2);font-size:12px;white-space:nowrap}.chip--good[data-v-aa574981]{background:color-mix(in srgb,var(--ok) 18%,transparent);color:var(--ok)}.chip--warn[data-v-aa574981]{background:var(--warn-soft);color:var(--warn)}.chip--bad[data-v-aa574981]{background:var(--danger-soft);color:var(--danger)}.rows[data-v-aa574981]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.row[data-v-aa574981]{display:flex;align-items:center;gap:12px;padding:8px;border:1px solid var(--border);border-radius:9px}.row__thumb[data-v-aa574981]{flex:none;width:64px;height:64px;border-radius:6px;background:var(--surface-2);object-fit:cover}.row__text[data-v-aa574981]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.row__name[data-v-aa574981]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.row__message[data-v-aa574981]{color:var(--danger)}.sharpen[data-v-1d132e3d]{display:flex;flex-direction:column;gap:12px}.grid[data-v-1d132e3d]{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}.hint[data-v-1d132e3d]{align-self:end;font-size:12px}.link[data-v-1d132e3d]{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer}.link[data-v-1d132e3d]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.recipe[data-v-6d67983e]{display:flex;flex-direction:column;gap:16px}.group[data-v-6d67983e]{display:flex;flex-direction:column;gap:10px}.group h4[data-v-6d67983e]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase;margin:0}.grid[data-v-6d67983e]{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:14px}.small[data-v-6d67983e]{font-size:12px}.input--bad[data-v-6d67983e]{border-color:var(--danger)}.pills[data-v-6d67983e]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.pill[data-v-6d67983e]{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;border:1px solid var(--border);border-radius:999px;background:var(--surface);font-size:12px;cursor:pointer}.pill input[data-v-6d67983e]{display:none}.pill--on[data-v-6d67983e]{border-color:var(--accent);background:var(--accent-soft);color:var(--accent);font-weight:600}.pill--button[data-v-6d67983e]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace}.pill--button[data-v-6d67983e]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.link[data-v-6d67983e]{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer}.link[data-v-6d67983e]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.block[data-v-5992429e]{display:flex;flex-direction:column;gap:16px;padding:18px}.head[data-v-5992429e]{display:flex;align-items:center;justify-content:space-between;gap:12px}.grid[data-v-5992429e]{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}.small[data-v-5992429e]{font-size:12px}.recipes[data-v-5992429e]{display:flex;flex-direction:column;gap:8px}.panel[data-v-5992429e]{border:1px solid var(--border);border-radius:9px}.panel--open[data-v-5992429e]{border-color:var(--accent)}.panel__head[data-v-5992429e]{display:flex;align-items:center;gap:8px;padding:4px 8px 4px 12px}.panel__title[data-v-5992429e]{display:flex;flex-direction:column;gap:0;flex:1;min-width:0;padding:8px 0;border:0;background:transparent;text-align:left;cursor:pointer}.panel__title[data-v-5992429e]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.panel__title .small[data-v-5992429e]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.panel__actions[data-v-5992429e]{display:flex;flex-wrap:wrap;align-items:center;gap:2px;flex:none}.panel__body[data-v-5992429e]{padding:12px 16px 16px;border-top:1px solid var(--border)}.panel summary[data-v-5992429e]{padding:12px;cursor:pointer;font-weight:600}details.panel>.panel__body[data-v-5992429e]{border-top:1px solid var(--border)}.json[data-v-5992429e]{min-height:420px;padding:12px;border:1px solid var(--border);border-radius:9px;background:var(--surface-2);font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;resize:vertical;tab-size:2}.json[data-v-5992429e]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.check-panel[data-v-5992429e]{padding:10px 14px;border-radius:9px}.check-panel--ok[data-v-5992429e]{background:color-mix(in srgb,var(--ok) 14%,transparent)}.check-panel--bad[data-v-5992429e]{background:var(--danger-soft);color:var(--danger)}.lines[data-v-5992429e]{margin:8px 0 0;font-size:12px;white-space:pre-wrap}.actions[data-v-5992429e]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.view[data-v-5b011a56]{display:flex;flex-direction:column;gap:16px}.block[data-v-5b011a56]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-5b011a56]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.list[data-v-5b011a56]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.item[data-v-5b011a56]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:12px;border:1px solid var(--border);border-radius:9px}.item__main[data-v-5b011a56]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:260px}.item__title[data-v-5b011a56]{display:flex;align-items:center;gap:8px}.item__path[data-v-5b011a56]{color:var(--muted);font-size:11px;word-break:break-all}.item__error[data-v-5b011a56]{color:var(--danger);font-size:12px}.item__actions[data-v-5b011a56]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.tag[data-v-5b011a56]{padding:1px 8px;border-radius:999px;background:var(--surface-2);color:var(--muted);font-size:11px}.block[data-v-b00b9955]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-b00b9955]{display:flex;align-items:center;justify-content:space-between;gap:12px}.small[data-v-b00b9955]{font-size:12px}.chips[data-v-b00b9955]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.chip[data-v-b00b9955]{padding:2px 10px;border-radius:999px;background:var(--surface-2);font-size:12px;white-space:nowrap}.chip--good[data-v-b00b9955]{background:color-mix(in srgb,var(--ok) 18%,transparent);color:var(--ok)}.chip--bad[data-v-b00b9955]{background:var(--danger-soft);color:var(--danger)}.errors[data-v-b00b9955]{margin:0;padding:10px 14px 10px 28px;border-radius:10px;background:var(--danger-soft);color:var(--danger)}.rows[data-v-b00b9955]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.row[data-v-b00b9955]{display:flex;align-items:center;gap:12px;padding:8px;border:1px solid var(--border);border-radius:9px}.row__thumb[data-v-b00b9955]{flex:none;width:64px;height:64px;border-radius:6px;background:var(--surface-2);object-fit:cover}.row__thumb--empty[data-v-b00b9955]{display:grid;place-items:center;font-size:11px}.row__text[data-v-b00b9955]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}.row__name[data-v-b00b9955]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.row__message[data-v-b00b9955]{color:var(--danger)}.row__sizes[data-v-b00b9955]{display:flex;align-items:baseline;gap:6px;flex:none;font-size:12px}.row__delta[data-v-b00b9955]{color:var(--muted)}.row__delta--down[data-v-b00b9955]{color:var(--ok)}@media(max-width:760px){.row[data-v-b00b9955]{flex-wrap:wrap}.row__text[data-v-b00b9955]{flex-basis:60%}}.link[data-v-b00b9955]{padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer;text-decoration:underline}.more[data-v-b00b9955]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;justify-content:center}.view[data-v-ecb5fab6]{display:flex;flex-direction:column;gap:16px}.block[data-v-ecb5fab6]{display:flex;flex-direction:column;gap:14px;padding:18px}.head[data-v-ecb5fab6]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px}.group[data-v-ecb5fab6]{display:flex;flex-direction:column;gap:10px}.group h3[data-v-ecb5fab6]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase}.grid[data-v-ecb5fab6]{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}.narrow[data-v-ecb5fab6]{max-width:320px}.small[data-v-ecb5fab6]{font-size:12px}.pathrow[data-v-ecb5fab6]{display:flex;gap:8px}.pathrow .input[data-v-ecb5fab6]{flex:1;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.pills[data-v-ecb5fab6]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.pill[data-v-ecb5fab6]{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;border:1px solid var(--border);border-radius:999px;background:var(--surface);font-size:12px;cursor:pointer}.pill input[data-v-ecb5fab6]{display:none}.pill--on[data-v-ecb5fab6]{border-color:var(--accent);background:var(--accent-soft);color:var(--accent);font-weight:600}.pill--button[data-v-ecb5fab6]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace}.pill--button[data-v-ecb5fab6]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.runbar[data-v-ecb5fab6]{display:flex;flex-wrap:wrap;align-items:center;gap:14px}.link[data-v-ecb5fab6]{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--accent);cursor:pointer}.link[data-v-ecb5fab6]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.progress[data-v-ecb5fab6]{height:8px;overflow:hidden;border-radius:999px;background:var(--surface-2)}.progress__bar[data-v-ecb5fab6]{height:100%;background:var(--accent);transition:width .15s}.compare[data-v-0ee1b3e3]{display:flex;flex-direction:column;gap:8px}.compare__scroll[data-v-0ee1b3e3]{overflow:auto;border-radius:9px;background:var(--surface-2);max-height:70vh}.compare__stage[data-v-0ee1b3e3]{position:relative;width:fit-content;margin:0 auto;line-height:0}.compare__img[data-v-0ee1b3e3]{display:block;max-width:none}.compare__img--top[data-v-0ee1b3e3]{position:absolute;inset:0}.compare__line[data-v-0ee1b3e3]{position:absolute;top:0;bottom:0;width:2px;background:var(--accent);pointer-events:none}.compare__tag[data-v-0ee1b3e3]{position:absolute;top:8px;padding:2px 8px;border-radius:6px;background:#0009;color:#fff;font-size:11px;line-height:1.4}.compare__tag--left[data-v-0ee1b3e3]{left:8px}.compare__tag--right[data-v-0ee1b3e3]{right:8px}.compare__range[data-v-0ee1b3e3]{width:100%}.block[data-v-8e3f1eea]{display:flex;flex-direction:column;gap:16px;padding:18px}.head[data-v-8e3f1eea]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px}.grid[data-v-8e3f1eea]{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px}.wide[data-v-8e3f1eea]{grid-column:1/-1}.small[data-v-8e3f1eea]{font-size:12px}.preview[data-v-8e3f1eea]{display:flex;flex-direction:column;gap:12px}.previewbar[data-v-8e3f1eea]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.inline[data-v-8e3f1eea]{flex-direction:row;align-items:center}.narrow[data-v-8e3f1eea]{width:90px}.actions[data-v-8e3f1eea]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.view[data-v-519b182c]{display:flex;flex-direction:column;gap:16px}.block[data-v-519b182c]{display:flex;flex-direction:column;gap:12px;padding:18px}.head[data-v-519b182c]{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px}.list[data-v-519b182c]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.item[data-v-519b182c]{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;padding:12px;border:1px solid var(--border);border-radius:9px}.item__main[data-v-519b182c]{display:flex;flex-direction:column;gap:2px;flex:1;min-width:260px}.item__title[data-v-519b182c]{display:flex;align-items:center;gap:8px}.item__facts[data-v-519b182c]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.item__error[data-v-519b182c]{color:var(--danger);font-size:12px}.item__actions[data-v-519b182c]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.tag[data-v-519b182c]{padding:1px 8px;border-radius:999px;background:var(--surface-2);color:var(--muted);font-size:11px}.tag--builtin[data-v-519b182c]{background:var(--accent-soft);color:var(--accent)}.page[data-v-85ee2fe2]{display:flex;flex-direction:column;gap:16px;padding:28px 28px 60px}@media(max-width:760px){.page[data-v-85ee2fe2]{padding:18px 14px 40px}}.page__head p[data-v-85ee2fe2]{margin-top:4px}.context[data-v-85ee2fe2]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px;font-size:12px}.context code[data-v-85ee2fe2]{padding:2px 8px;border-radius:6px;background:var(--surface-2);word-break:break-all}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as ke,I as Xe,x as Ce,w as Ve,e as Ge,J as Me,r as R,A as G,o as x,c as M,b as $e,f,y as me,k as pe,G as rt,F as oe,a as de,g as J,t as I,p as O,i as le,h as fe,q as it,E as He,s as Le,n as Re,j as ye,z as Oe,K as Ye,B as yt,L as gt}from"./index-pDKL0Y31.js";import{S as bt}from"./SourcePicker-CVgtCk78.js";import{u as ut}from"./useCopy-vCfkPGWW.js";import{U as wt}from"./FolderBrowser-BX3-y8sM.js";function _t(e,t,a,s){if(e==="auto")return Math.max(1,Math.floor((t+s)/(a+s)));if(typeof e=="number")return Math.max(1,Math.floor(e));const o=Object.keys(e).filter(c=>c!=="default").map(Number).sort((c,m)=>c-m);for(const c of o)if(t<=c)return Math.max(1,Math.floor(e[c]));return Math.max(1,Math.floor(e.default))}function kt(e,t,a){return Math.max(0,(e-(t-1)*a)/t)}function xt(e,t){return t!==void 0?Math.max(1,Math.floor(t)):e===void 0||e==="auto"?2:typeof e=="number"?Math.max(1,Math.floor(e)):Math.max(1,Math.floor(e.default))}function Mt(e,t,a,s="balanced"){const o=Math.max(1,Math.floor(t)||1),c=new Array(o).fill(0),m=[];let r=0;for(const $ of e){const y=Math.min(Math.max(1,Math.floor($.span)||1),o);let v;if(s==="ordered")v=r+y<=o?r:0,r=v+y,r>=o&&(r=0);else{let b=0,_=1/0;for(let i=0;i<=o-y;i++){let p=0;for(let A=i;A<i+y;A++)p=Math.max(p,c[A]);p<_&&(_=p,b=i)}v=b}let d=0;for(let b=v;b<v+y;b++)d=Math.max(d,c[b]);m.push({id:$.id,laneIndex:v,span:y,mainPos:d});const S=d+$.mainSize+a;for(let b=v;b<v+y;b++)c[b]=S}const w=m.length?Math.max(0,Math.max(...c)-a):0;return{items:m,totalMainSize:w}}function St(e){const t=new Set;let a=!1;function s(){a||(a=!0,requestAnimationFrame(()=>{a=!1,e()}))}const o=typeof ResizeObserver>"u"?null:new ResizeObserver(s);return{observe(c){t.has(c)||(t.add(c),o?.observe(c))},unobserveAll(){for(const c of t)o?.unobserve(c);t.clear()},scheduleNow:s,destroy(){o?.disconnect(),t.clear()}}}var Ct=240,Je=16,Ze=600,$t=250,It="cubic-bezier(0.2, 0, 0, 1)";function Te(e){return typeof e.el=="function"?e.el():e.el??null}function zt(e){return(e instanceof HTMLImageElement?[e]:Array.from(e.querySelectorAll("img"))).filter(a=>!a.complete)}function At(e,t={}){const a=t.direction??"vertical",s=t.minLaneSize??Ct,o=t.placement??"balanced",c=typeof t.gap=="number"?t.gap:t.gap?.main??Je,m=typeof t.gap=="number"?t.gap:t.gap?.cross??Je,r=a==="horizontal"?t.rows??"auto":t.columns??"auto",w=!!t.virtualize,$=typeof t.virtualize=="object"?t.virtualize.overscan??Ze:Ze,y=t.scrollContainer??(a==="vertical"?"window":"self"),v=t.estimateSize,d=t.animate??!0,S=t.transitionDuration??$t,b=t.transitionEasing??It,_=`transform ${S}ms ${b}, opacity ${S}ms ${b}`;e.style.position="relative",d&&(e.style.setProperty("--mk-transition-duration",`${S}ms`),e.style.setProperty("--mk-transition-easing",b));let i=null;a==="horizontal"?(e.style.overflowX="auto",e.style.overflowY="hidden",i=document.createElement("div"),i.setAttribute("aria-hidden","true"),i.style.position="absolute",i.style.top="0",i.style.left="0",i.style.width="1px",i.style.height="1px",i.style.visibility="hidden",i.style.pointerEvents="none",e.appendChild(i)):e.style.overflowX="clip";const p=new Map;let A=[],L=[],N=[];const T=new Map,B=new WeakSet;let re=!1,Z=null;const ne=new Map;function ie(l,h){for(const g of ne.get(l)??[])g(h)}const V=St(n);function F(){V.scheduleNow()}const Q=w?y==="window"?window:y==="self"?e:y:null;Q?.addEventListener("scroll",F,{passive:!0});function ee(){return A.map((l,h)=>({id:l,key:p.get(l)?.order??h})).sort((l,h)=>l.key-h.key).map(l=>l.id)}function W(){V.unobserveAll(),V.observe(e);for(const l of A){const h=Te(p.get(l));h&&V.observe(h)}}function K(l){if(!d)return;const h=p.get(l),g=h?Te(h):null;g&&(g.classList.add("mk-item-leave"),g.style.transition=_,g.style.opacity="0")}function q(l){const h=g=>{g.target===l&&(l.style.willChange="auto",l.classList.remove("mk-item-moving"),l.removeEventListener("transitionend",h))};l.style.willChange="transform",l.addEventListener("transitionend",h)}function D(l,h,g){const P=`translate(${h}px, ${g}px)`;return l.style.transform===""?d?(l.style.transition="none",l.style.transform=P,l.style.opacity="0",l.classList.add("mk-item-enter"),!0):(l.style.transform=P,!1):(l.style.transform===P||(d&&(l.style.transition=_,l.classList.add("mk-item-moving"),q(l)),l.style.transform=P),!1)}function z(){if(y==="self"){const C=a==="vertical"?e.scrollTop:e.scrollLeft,j=a==="vertical"?e.clientHeight:e.clientWidth;return[C-$,C+j+$]}const l=e.getBoundingClientRect(),h=a==="vertical"?l.top:l.left;let g,P;if(y==="window")g=0,P=a==="vertical"?window.innerHeight:window.innerWidth;else{const C=y.getBoundingClientRect();g=a==="vertical"?C.top:C.left,P=a==="vertical"?y.clientHeight:y.clientWidth}return[g-h-$,g+P-h+$]}function u(l,h){if(w&&l.estimatedSize!==void 0)return l.estimatedSize;if(l.aspectRatio)return a==="vertical"?h/l.aspectRatio:h*l.aspectRatio;if(!w)return;if(v)return v(l);re||(re=!0,console.warn("[masonry-kit] `virtualize` is on but an item has no `estimatedSize`, no `aspectRatio`, and `estimateSize` returned nothing — falling back to a guessed size. Set one of these for accurate initial positions."));const g=[...T.values()];return g.length>0?g.reduce((P,C)=>P+C,0)/g.length:h}function n(){const l=e.getBoundingClientRect(),h=a==="vertical"?l.width:l.height,g=_t(r,h,s,m),P=kt(h,g,m),C=ee().filter(E=>E!==Z),j=new Map,U=new Map,te=new Map;for(const E of C){const ue=p.get(E),ve=a==="vertical"?ue.colSpan??1:ue.rowSpan??1,se=Math.min(Math.max(1,Math.floor(ve)||1),g);U.set(E,se);const H=se*P+(se-1)*m;te.set(E,H);const X=Te(ue);X&&(j.set(E,X),X.style.position="absolute",X.style.top="0",X.style.left="0",a==="vertical"?X.style.width=`${H}px`:X.style.height=`${H}px`)}const he=new Map,Ke=[];for(const E of C){const ue=p.get(E),ve=te.get(E),se=j.get(E);let H;if(se){const X=zt(se);if(X.length===0){const ae=a==="vertical"?se.getBoundingClientRect().height:se.getBoundingClientRect().width;ae>0&&(H=ae,T.set(E,ae))}else for(const ae of X)B.has(ae)||(B.add(ae),ae.addEventListener("load",n,{once:!0}),ae.addEventListener("error",n,{once:!0}))}H===void 0&&(H=T.get(E)),H===void 0&&(H=u(ue,ve)),H!==void 0&&(he.set(E,H),Ke.push({id:E,span:U.get(E),mainSize:H}))}const{items:mt,totalMainSize:qe}=Mt(Ke,g,c,o),Ie=w?z():null,ze=[],Ae=[],xe=[];for(const E of mt){const ue=te.get(E.id),ve=he.get(E.id),se=E.laneIndex*(P+m),H=a==="vertical"?se:E.mainPos,X=a==="vertical"?E.mainPos:se,ae=a==="vertical"?ue:ve,pt=a==="vertical"?ve:ue,Ee=j.get(E.id);Ee&&D(Ee,H,X)&&xe.push(Ee),ze.push({id:E.id,x:H,y:X,width:ae,height:pt}),(!Ie||E.mainPos+ve>=Ie[0]&&E.mainPos<=Ie[1])&&Ae.push(E.id)}if(a==="vertical"?e.style.height=`${qe}px`:i&&(i.style.transform=`translate(${qe}px, 0)`),xe.length>0){xe[0].offsetHeight;for(const E of xe)E.style.transition=_,E.style.opacity="1",q(E)}L=ze,N=Ae,ie("layout",{items:ze,visibleIds:Ae})}function k(l){const h=new Set(l.map(g=>g.id));for(const g of A)h.has(g)||(K(g),T.delete(g));p.clear(),A=l.map(g=>g.id);for(const g of l)p.set(g.id,g);W()}return V.observe(e),{setItems(l){k(l),n()},updateItem(l,h){const g=p.get(l);g&&(p.set(l,{...g,...h}),W(),n())},addItem(l,h){p.set(l.id,l),h===void 0||h>=A.length?A.push(l.id):A.splice(h,0,l.id),W(),n()},removeItem(l){K(l),p.delete(l),A=A.filter(h=>h!==l),T.delete(l),W(),n()},relayout:n,getLayout(){return[...L]},getVisibleIds(){return[...N]},setDragging(l){Z!==l&&(Z=l,n())},on(l,h){ne.has(l)||ne.set(l,new Set);const g=ne.get(l);return g.add(h),()=>g.delete(h)},destroy(){V.destroy(),Q?.removeEventListener("scroll",F),i?.remove(),p.clear(),A=[],L=[],N=[],T.clear(),Z=null,ne.clear()}}}function ct(e,t){if(e===t)return!0;if(typeof e!="object"||typeof t!="object"||e===null||t===null||typeof Node<"u"&&(e instanceof Node||t instanceof Node))return!1;const a=Object.keys(e),s=Object.keys(t);return a.length!==s.length?!1:a.every(o=>ct(e[o],t[o]))}function Et(e,t){if(e===t)return!0;const a=new Set([...Object.keys(e),...Object.keys(t)]);for(const s of a)if(!ct(e[s],t[s]))return!1;return!0}var ce={},Qe=new WeakMap,Lt=0;function Y(e){if(e.id!==void 0)return e.id;let t=Qe.get(e);return t===void 0&&(t=`mk-auto-${++Lt}`,Qe.set(e,t)),t}var Rt=0,et={position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",border:"0"},Ot=ke({name:"MasonryGrid",props:{items:{type:Array,required:!0},options:{type:Object,default:()=>({})},sortable:{type:Boolean,default:!1}},emits:["layout","reorder"],setup(e,{slots:t,emit:a}){const s=`mk-${++Rt}`,o=R(null),c=new Map,m=new Map;let r=null,w=null,$=null,y=null,v=!1;const d=Xe(e.options.virtualize?new Set:null),S=R(!1),b=Xe(new Map),_=new Map;let i=new Set;const p=G(()=>{const n=d.value===null?e.items:e.items.filter(h=>d.value.has(Y(h)));if(b.value.size===0)return n;const k=new Set(n.map(h=>Y(h))),l=[...b.value.values()].filter(h=>!k.has(Y(h)));return l.length===0?n:[...n,...l]});function A(n,k){if(n.size!==k.size)return!1;for(const l of n)if(!k.has(l))return!1;return!0}function L(){return e.options.animate??ce.animate??!0}function N(){return e.options.transitionDuration??ce.transitionDuration??250}function T(){const n=e.options.gap??ce.gap;return typeof n=="number"?{main:n,cross:n}:{main:n?.main??16,cross:n?.cross??16}}function B(){const k=(e.options.direction??ce.direction)==="horizontal"?e.options.rows??ce.rows:e.options.columns??ce.columns;return xt(k,e.options.ssrColumns??ce.ssrColumns)}function re(n){const k=new Set(n.map(h=>Y(h)));for(const h of n)_.set(Y(h),h);let l=null;for(const h of i){if(k.has(h)||b.value.has(h)||!c.get(h)||!L())continue;const g=_.get(h);g&&(l??(l=new Map(b.value)),l.set(h,g),setTimeout(()=>{const P=new Map(b.value);P.delete(h),b.value=P,_.delete(h)},N()))}l&&(b.value=l),i=k}function Z(){if(!r)return;const n=e.items.map(k=>{const l=Y(k);return{id:l,el:c.get(l),colSpan:k.colSpan,rowSpan:k.rowSpan,aspectRatio:k.aspectRatio,estimatedSize:k.estimatedSize,order:k.order}});r.setItems(n)}function ne(){v||(v=!0,queueMicrotask(()=>{v=!1,Z()}))}function ie(n){let k=m.get(n);return k||(k=l=>{l!==c.get(n)&&(l?c.set(n,l):(c.delete(n),m.delete(n)),ne())},m.set(n,k),k)}function V(){if(o.value){d.value=e.options.virtualize?new Set:null,i=new Set(e.items.map(n=>Y(n))),_.clear();for(const n of e.items)_.set(Y(n),n);r=At(o.value,{...ce,...e.options}),w=r.on("layout",n=>{if(S.value=!0,a("layout",n.items),e.options.virtualize){const k=new Set(n.visibleIds);(!d.value||!A(d.value,k))&&(d.value=k)}}),Z()}}const F=R(null),Q=R(""),ee=`${s}-instructions`,W=`${s}-live`;function K(n){Q.value=n}function q(n,k){return`item ${k.findIndex(h=>Y(h)===n)+1} of ${k.length}`}let D=null;function z(n,k,l){const h=n.findIndex(C=>Y(C)===k);if(h===-1)return n;const g=[...n],[P]=g.splice(h,1);return g.splice(Math.max(0,Math.min(l,g.length)),0,P),g}function u(n,k){if(!e.sortable||!r)return;const l=Y(k);if(n.key===" "||n.key==="Enter"){n.preventDefault(),F.value===l?(F.value=null,D=null,r.setDragging(null),K(`Dropped ${q(l,e.items)}.`)):F.value===null&&(F.value=l,D=e.items,r.setDragging(l),K(`Picked up ${q(l,e.items)}. Use arrow keys to move, space to drop, escape to cancel.`));return}if(F.value!==l)return;if(n.key==="Escape"){n.preventDefault(),F.value=null,r.setDragging(null),D&&a("reorder",D),D=null,K("Reordering cancelled.");return}const h=e.options.direction==="horizontal",g=h?"ArrowRight":"ArrowDown",P=h?"ArrowLeft":"ArrowUp";if(n.key!==g&&n.key!==P)return;n.preventDefault();const C=e.items.findIndex(he=>Y(he)===l),j=n.key===g?1:-1,U=C+j;if(U<0||U>=e.items.length)return;const te=z(e.items,l,U);a("reorder",te),K(`Moved to ${q(l,te)}.`)}return Ce(()=>{!o.value||typeof window>"u"||(V(),$=Ve(()=>e.items,n=>{re(n),Z()},{deep:!0}),y=Ve(()=>e.options,(n,k)=>{Et(n,k)||(w?.(),r?.destroy(),V())},{deep:!0}))}),Ge(()=>{$?.(),y?.(),w?.(),r?.destroy()}),()=>Me("div",{ref:o,class:"mk-grid",style:S.value?{}:{columns:B(),columnGap:`${T().cross}px`}},[...p.value.map(n=>{const k=Y(n),l=b.value.has(k),h=e.sortable?{tabindex:0,role:"button","aria-roledescription":"Reorderable item","aria-describedby":ee,"aria-pressed":F.value===k?"true":"false",onKeydown:g=>u(g,n)}:{};return Me("div",{key:k,class:"mk-item",style:{...S.value?{}:{breakInside:"avoid",marginBottom:`${T().main}px`},...l?{pointerEvents:"none"}:{}},ref:ie(k),...h},t.item?.({item:n}))}),e.sortable?Me("span",{id:ee,style:et},"Press space or enter to pick up this item. While picked up, use the arrow keys to move it, space or enter to drop it, or escape to cancel."):null,e.sortable?Me("span",{id:W,role:"status","aria-live":"polite",style:et},Q.value):null])}});const Tt={key:1,class:"canvas canvas--bad",title:"Could not decode this hash"},Pt=ke({__name:"PlaceholderCanvas",props:{rgba:{}},setup(e){const t=e,a=R();function s(){const o=a.value;if(!o||!t.rgba)return;o.width=t.rgba.width,o.height=t.rgba.height;const c=o.getContext("2d");if(!c)return;const m=c.createImageData(t.rgba.width,t.rgba.height);m.data.set(t.rgba.data),c.putImageData(m,0,0)}return Ce(s),Ve(()=>t.rgba,s),(o,c)=>e.rgba?(x(),M("canvas",{key:0,ref_key:"canvas",ref:a,class:"canvas"},null,512)):(x(),M("div",Tt,"?"))}}),dt=$e(Pt,[["__scopeId","data-v-af1c304e"]]);var Nt=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","#","$","%","*","+",",","-",".",":",";","=","?","@","[","]","^","_","{","|","}","~"],ge=e=>{let t=0;for(let a=0;a<e.length;a++){let s=e[a],o=Nt.indexOf(s);t=t*83+o}return t},Pe=e=>{let t=e/255;return t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},Ne=e=>{let t=Math.max(0,Math.min(1,e));return t<=.0031308?Math.trunc(t*12.92*255+.5):Math.trunc((1.055*Math.pow(t,.4166666666666667)-.055)*255+.5)},jt=e=>e<0?-1:1,je=(e,t)=>jt(e)*Math.pow(Math.abs(e),t),tt=class extends Error{constructor(e){super(e),this.name="ValidationError",this.message=e}},Dt=e=>{if(!e||e.length<6)throw new tt("The blurhash string must be at least 6 characters");let t=ge(e[0]),a=Math.floor(t/9)+1,s=t%9+1;if(e.length!==4+2*s*a)throw new tt(`blurhash length mismatch: length is ${e.length} but it should be ${4+2*s*a}`)},Ut=e=>{let t=e>>16,a=e>>8&255,s=e&255;return[Pe(t),Pe(a),Pe(s)]},Bt=(e,t)=>{let a=Math.floor(e/361),s=Math.floor(e/19)%19,o=e%19;return[je((a-9)/9,2)*t,je((s-9)/9,2)*t,je((o-9)/9,2)*t]},Ft=(e,t,a,s)=>{Dt(e),s=s|1;let o=ge(e[0]),c=Math.floor(o/9)+1,m=o%9+1,r=(ge(e[1])+1)/166,w=new Array(m*c);for(let v=0;v<w.length;v++)if(v===0){let d=ge(e.substring(2,6));w[v]=Ut(d)}else{let d=ge(e.substring(4+v*2,6+v*2));w[v]=Bt(d,r*s)}let $=t*4,y=new Uint8ClampedArray($*a);for(let v=0;v<a;v++)for(let d=0;d<t;d++){let S=0,b=0,_=0;for(let L=0;L<c;L++)for(let N=0;N<m;N++){let T=Math.cos(Math.PI*d*N/t)*Math.cos(Math.PI*v*L/a),B=w[N+L*m];S+=B[0]*T,b+=B[1]*T,_+=B[2]*T}let i=Ne(S),p=Ne(b),A=Ne(_);y[4*d+0+v*$]=i,y[4*d+1+v*$]=p,y[4*d+2+v*$]=A,y[4*d+3+v*$]=255}return y},Vt=Ft;const nt=new Map;function st(e,t){const a=e*4096+t;let s=nt.get(a);if(!s){s=new Float64Array(e*t);for(let o=0;o<e;o++)for(let c=0;c<t;c++)s[o*t+c]=Math.cos(Math.PI*o*(c+.5)/t);nt.set(a,s)}return s}function Ht(e,t,a,s,o,c,m){const r=st(a,o),w=st(s,c),$=new Float64Array(a);for(let y=0;y<c;y++){for(let v=0;v<a;v++){let d=0;for(let S=0;S<s;S++){const b=e[S*t+v];b!==0&&(d+=b*w[S*c+y])}$[v]=d}for(let v=0;v<o;v++){let d=0;for(let S=0;S<a;S++)d+=$[S]*r[S*o+v];m[y*o+v]=d}}}var we=class extends Error{constructor(e,t){super(t?`${e}: ${t}`:e),this.name="PlaceholderError",this.code=e}};const Gt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",ft=new Int8Array(128).fill(-1);for(let e=0;e<64;e++)ft[Gt.charCodeAt(e)]=e;function Wt(e){const t=e.length;if(t%4===1)throw new we("InvalidLength");const a=new Uint8Array(Math.floor(t*6/8));let s=0,o=0,c=0;for(let m=0;m<t;m++){const r=e.charCodeAt(m),w=r<128?ft[r]:-1;if(w<0)throw new we("InvalidCharacter");s=s<<6|w,o+=6,o>=8&&(o-=8,a[c++]=s>>o&255,s&=(1<<o)-1)}return a}function Kt(e){return typeof e=="string"?Wt(e):e}var ht=class{constructor(e,t=0){this.bytes=e,this.pos=t*8,this.end=e.length*8}bit(){if(this.pos>=this.end)return 0;const e=this.pos++;return this.bytes[e>>3]>>7-(e&7)&1}bits(e){let t=0;for(let a=0;a<e;a++)t=t<<1|this.bit();return t>>>0}};function qt(e,t){let a=0;for(;e.bit()===1;)a++;const s=a*(1<<t)+(t>0?e.bits(t):0);return s&1?-((s+1)/2):s/2}function Xt(e){return e?9:7}function Yt(e){return Math.pow(2,(e-32)/8)}function Jt(e,t){return e>=1?[t,Math.max(1,Math.round(t/e))]:[Math.max(1,Math.round(t*e)),t]}function Zt(e){if(e.length<7||e.length>1024)throw new we("InvalidLength");const t=new ht(e);if(t.bits(2)!==0)throw new we("UnsupportedVersion");const a=t.bit()===1;if(a&&e.length<9)throw new we("InvalidLength");const s={aspectCode:t.bits(6),alpha:a,Lx:t.bits(3)+1,Ly:t.bits(3)+1,Cx:t.bits(2)+1,Cy:t.bits(2)+1,Ax:1,Ay:1,dc:[0,0,0,0],scale:[0,0,0,0],k:[0,0,0,0]};for(let o=0;o<3;o++)s.dc[o]=t.bits(6);for(let o=0;o<3;o++)s.scale[o]=t.bits(4);for(let o=0;o<3;o++)s.k[o]=t.bits(2);return t.bit(),a&&(s.dc[3]=t.bits(5),s.Ax=t.bits(2)+1,s.Ay=t.bits(2)+1,s.scale[3]=t.bits(4),s.k[3]=t.bits(2)),s}const _e={qmaxL:7,qmaxC:3,smaxL:.64,smaxC:.32,reconOffset:0};function Qt(e){return e===0?_e.qmaxL:_e.qmaxC}function en(e,t,a,s){return 2*(e*s+t*a)<3*a*s}function We(e,t){return t===0?[e.Lx,e.Ly]:t===3?[e.Ax,e.Ay]:[e.Cx,e.Cy]}function tn(e){const t=[],a=e.alpha?[0,1,2,3]:[0,1,2];for(const s of a){const[o,c]=We(e,s);for(let m=0;m<c;m++)for(let r=0;r<o;r++)r===0&&m===0||!en(r,m,o,c)||t.push({ch:s,i:r,j:m,nx:o,ny:c,qmax:Qt(s)})}return t.sort((s,o)=>{const c=s.i*s.i*s.ny*s.ny+s.j*s.j*s.nx*s.nx,m=s.nx*s.nx*s.ny*s.ny,r=o.i*o.i*o.ny*o.ny+o.j*o.j*o.nx*o.nx,w=c*(o.nx*o.nx*o.ny*o.ny)-r*m;return w!==0?w:s.ch!==o.ch?s.ch-o.ch:s.j!==o.j?s.j-o.j:s.i-o.i}),t}function Se(e,t,a){return e<t?t:e>a?a:e}function nn(e,t){return e===0?t/63:e===3?t/31:t*.64/63-.32}const sn=Array.from({length:16},(e,t)=>Math.pow(2,-(15-t)/3));function an(e,t){return(e===1||e===2?_e.smaxC:_e.smaxL)*sn[t]}function on(e,t,a){if(e===0)return 0;const s=(Math.abs(e)-_e.reconOffset)/a,o=t*s*s;return e<0?-o:o}function ln(e){return e<=.0031308?12.92*e:1.055*Math.pow(e,1/2.4)-.055}function De(e,t,a,s){const o=e+.3963377774*t+.2158037573*a,c=e-.1055613458*t-.0638541728*a,m=e-.0894841775*t-1.291485548*a,r=o*o*o,w=c*c*c,$=m*m*m;s[0]=4.0767416621*r-3.3077115913*w+.2309699292*$,s[1]=-1.2684380046*r+2.6097574011*w-.3413193965*$,s[2]=-.0041960863*r-.7034186147*w+1.707614701*$}const Ue=-5e-4,Be=1.0005,at=[0,0,0];function ot(e){return e[0]>=Ue&&e[0]<=Be&&e[1]>=Ue&&e[1]<=Be&&e[2]>=Ue&&e[2]<=Be}function rn(e,t,a,s){if(De(e,t,a,s),!ot(s)){let o=0,c=1;for(let m=0;m<8;m++){const r=(o+c)/2;De(e,t*r,a*r,at),ot(at)?o=r:c=r}De(e,t*o,a*o,s)}for(let o=0;o<3;o++)s[o]=s[o]<0?0:s[o]>1?1:s[o]}function un(e,t){const a=t,s=t.alpha?[0,1,2,3]:[0,1,2],o=[];for(const r of s){const[w,$]=We(a,r),y=new Float64Array(w*$);y[0]=nn(r,t.dc[r]),o[r]=y}const c=s.map(r=>an(r,t.scale[r])),m=new ht(e,Xt(t.alpha));for(const r of tn(a)){let w=qt(m,t.k[r.ch]);w=w>r.qmax?r.qmax:w<-r.qmax?-r.qmax:w,o[r.ch][r.j*r.nx+r.i]=on(w,c[r.ch],r.qmax)}return o}function cn(e,t={}){const a=Kt(e),s=Zt(a),o=Math.round(Se(t.size??32,4,128)),c=t.dither??!0,[m,r]=Jt(Yt(s.aspectCode),o),w=un(a,s),$=s,y=m*r,v=[];for(let b=0;b<w.length;b++){const[_,i]=We($,b),p=new Float64Array(y);Ht(w[b],_,_,i,m,r,p),v.push(p)}const d=new Uint8ClampedArray(y*4),S=[0,0,0];for(let b=0;b<r;b++)for(let _=0;_<m;_++){const i=b*m+_;rn(Se(v[0][i],0,1),v[1][i],v[2][i],S);const p=c?lt(52.9829189*lt(.06711056*_+.00583715*b)):.5,A=i*4;for(let L=0;L<3;L++){const N=ln(S[L])*255;d[A+L]=Se(Math.floor(N+p),0,255)}d[A+3]=s.alpha?Math.round(Se(v[3][i],0,1)*255):255}return{width:m,height:r,data:d}}function lt(e){return e-Math.floor(e)}function dn(e){let{PI:t,min:a,max:s,cos:o,round:c}=Math,m=e[0]|e[1]<<8|e[2]<<16,r=e[3]|e[4]<<8,w=(m&63)/63,$=(m>>6&63)/31.5-1,y=(m>>12&63)/31.5-1,v=(m>>18&31)/31,d=m>>23,S=(r>>3&63)/63,b=(r>>9&63)/63,_=r>>15,i=s(3,_?d?5:7:r&7),p=s(3,_?r&7:d?5:7),A=d?(e[5]&15)/15:1,L=(e[5]>>4)/15,N=d?6:5,T=0,B=(q,D,z)=>{let u=[];for(let n=0;n<D;n++)for(let k=n?0:1;k*D<q*(D-n);k++)u.push(((e[N+(T>>1)]>>((T++&1)<<2)&15)/7.5-1)*z);return u},re=B(i,p,v),Z=B(3,3,S*1.25),ne=B(3,3,b*1.25),ie=d&&B(5,5,L),V=fn(e),F=c(V>1?32:32*V),Q=c(V>1?32/V:32),ee=new Uint8Array(F*Q*4),W=[],K=[];for(let q=0,D=0;q<Q;q++)for(let z=0;z<F;z++,D+=4){let u=w,n=$,k=y,l=A;for(let C=0,j=s(i,d?5:3);C<j;C++)W[C]=o(t/F*(z+.5)*C);for(let C=0,j=s(p,d?5:3);C<j;C++)K[C]=o(t/Q*(q+.5)*C);for(let C=0,j=0;C<p;C++)for(let U=C?0:1,te=K[C]*2;U*p<i*(p-C);U++,j++)u+=re[j]*W[U]*te;for(let C=0,j=0;C<3;C++)for(let U=C?0:1,te=K[C]*2;U<3-C;U++,j++){let he=W[U]*te;n+=Z[j]*he,k+=ne[j]*he}if(d)for(let C=0,j=0;C<5;C++)for(let U=C?0:1,te=K[C]*2;U<5-C;U++,j++)l+=ie[j]*W[U]*te;let h=u-2/3*n,g=(3*u-h+k)/2,P=g-k;ee[D]=s(0,255*a(1,g)),ee[D+1]=s(0,255*a(1,P)),ee[D+2]=s(0,255*a(1,h)),ee[D+3]=s(0,255*a(1,l))}return{w:F,h:Q,rgba:ee}}function fn(e){let t=e[3],a=e[2]&128,s=e[4]&128,o=s?a?5:7:t&7,c=s?t&7:a?5:7;return o/c}const be=32;function hn(e,t,a){const s=t>0&&a>0?t/a:1,o=s>=1?be:Math.max(1,Math.round(be*s)),c=s>=1?Math.max(1,Math.round(be/s)):be;try{return{width:o,height:c,data:Vt(e,o,c)}}catch{return null}}function vn(e){try{const t=atob(e),a=Uint8Array.from(t,o=>o.charCodeAt(0)),s=dn(a);return{width:s.w,height:s.h,data:new Uint8ClampedArray(s.rgba)}}catch{return null}}function mn(e){try{const t=cn(e,{size:be});return{width:t.width,height:t.height,data:new Uint8ClampedArray(t.data)}}catch{return null}}function vt(e,t,a,s){return e==="blurhash"?hn(t,a,s):e==="thumbhash"?vn(t):mn(t)}const pn={class:"item card"},yn=["aria-label"],gn=["alt","src"],bn={class:"strip__label"},wn=["src"],_n={class:"meta"},kn=["title"],xn={class:"muted"},Mn={class:"hashes"},Sn={class:"hashes__key"},Cn=["title"],$n=["aria-label","onClick"],In=ke({__name:"ResultCard",props:{entry:{}},emits:["open"],setup(e,{emit:t}){const a=e,s=t,o=["hazehash","blurhash","thumbhash"],{copied:c,copy:m}=ut(),r=G(()=>{const{width:y,height:v}=a.entry;return y>0&&v>0?Math.min(Math.max(y/v,.5),2):1}),w=G(()=>o.filter(y=>a.entry[y]!==void 0).map(y=>({type:y,rgba:vt(y,a.entry[y],a.entry.width,a.entry.height)}))),$=G(()=>{const y=[];for(const v of["hazehash","blurhash","thumbhash","color"]){const d=a.entry[v];d!==void 0&&y.push({key:v,value:d})}return y});return(y,v)=>(x(),M("article",pn,[f("button",{class:"item__open","aria-label":`Open ${e.entry.file}`,onClick:v[0]||(v[0]=d=>s("open"))},[f("span",{class:"shots",style:me({aspectRatio:String(r.value)})},[f("img",{class:"shot",loading:"lazy",alt:e.entry.file,src:pe(rt)(e.entry.path,480)},null,8,gn)],4),w.value.length>0?(x(),M("span",{key:0,class:"strip",style:me({aspectRatio:String(r.value*w.value.length)})},[(x(!0),M(oe,null,de(w.value,d=>(x(),M("span",{key:d.type,class:"strip__cell"},[J(dt,{rgba:d.rgba},null,8,["rgba"]),f("span",bn,I(d.type),1)]))),128))],4)):O("",!0),e.entry.preview?(x(),M("img",{key:1,class:"preview",alt:"Tiny preview",src:e.entry.preview},null,8,wn)):O("",!0)],8,yn),f("div",_n,[f("strong",{class:"meta__name",title:e.entry.path},I(e.entry.file),9,kn),f("span",xn,I(e.entry.width)+"×"+I(e.entry.height),1)]),f("ul",Mn,[(x(!0),M(oe,null,de($.value,d=>(x(),M("li",{key:d.key},[f("span",Sn,[d.key==="color"?(x(),M("span",{key:0,class:"swatch",style:me({background:d.value})},null,4)):O("",!0),le(" "+I(d.key),1)]),f("code",{class:"hashes__value",title:d.value},I(d.value),9,Cn),f("button",{class:"btn btn--ghost btn--small","aria-label":`Copy ${d.key}`,onClick:S=>pe(m)(d.key,d.value)},[J(fe,{name:pe(c)===d.key?"check":"copy",size:14},null,8,["name"])],8,$n)]))),128))])]))}}),zn=$e(In,[["__scopeId","data-v-ede0ed45"]]),An={class:"muted counter"},En=["disabled"],Ln=["disabled"],Rn={class:"scroll"},On={class:"stage"},Tn=["alt","src"],Pn={key:0,class:"compare"},Nn={key:0,class:"compare__item"},jn=["src"],Dn={class:"facts"},Un={class:"facts__row"},Bn={class:"facts__mono"},Fn={class:"facts__row"},Vn={class:"facts__mono facts__hash"},Hn=["aria-label","onClick"],Gn=ke({__name:"ResultModal",props:{entries:{},index:{}},emits:["close","update:index"],setup(e,{emit:t}){const a=e,s=t,o=["hazehash","blurhash","thumbhash"],{copied:c,copy:m}=ut(),r=G(()=>a.entries[a.index]),w=G(()=>a.index>0),$=G(()=>a.index<a.entries.length-1),y=G(()=>{const{width:_,height:i}=r.value;return _>0&&i>0?_/i:1}),v=G(()=>o.filter(_=>r.value[_]!==void 0).map(_=>({type:_,rgba:vt(_,r.value[_],r.value.width,r.value.height)}))),d=G(()=>{const _=[];for(const i of["hazehash","blurhash","thumbhash","color"]){const p=r.value[i];p!==void 0&&_.push({key:i,value:p})}return _});function S(_){const i=a.index+_;i>=0&&i<a.entries.length&&s("update:index",i)}function b(_){_.target instanceof HTMLInputElement||(_.key==="ArrowLeft"&&S(-1),_.key==="ArrowRight"&&S(1))}return Ce(()=>window.addEventListener("keydown",b)),Ge(()=>window.removeEventListener("keydown",b)),(_,i)=>(x(),it(wt,{title:r.value.file,width:"1040px",onClose:i[2]||(i[2]=p=>s("close"))},{actions:He(()=>[f("span",An,I(e.index+1)+" / "+I(e.entries.length),1),f("button",{class:"btn btn--small",disabled:!w.value,"aria-label":"Previous image",onClick:i[0]||(i[0]=p=>S(-1))},[J(fe,{name:"left",size:15})],8,En),f("button",{class:"btn btn--small",disabled:!$.value,"aria-label":"Next image",onClick:i[1]||(i[1]=p=>S(1))},[J(fe,{name:"right",size:15})],8,Ln)]),default:He(()=>[f("div",Rn,[f("div",On,[(x(),M("img",{key:r.value.path,class:"stage__img",alt:r.value.file,src:pe(rt)(r.value.path,1600)},null,8,Tn))]),v.value.length?(x(),M("div",Pn,[(x(!0),M(oe,null,de(v.value,p=>(x(),M("figure",{key:p.type,class:"compare__item"},[f("div",{class:"compare__frame",style:me({aspectRatio:String(y.value)})},[J(dt,{rgba:p.rgba},null,8,["rgba"])],4),f("figcaption",null,I(p.type),1)]))),128)),r.value.preview?(x(),M("figure",Nn,[f("div",{class:"compare__frame",style:me({aspectRatio:String(y.value)})},[f("img",{class:"compare__preview",alt:"Tiny preview",src:r.value.preview},null,8,jn)],4),i[3]||(i[3]=f("figcaption",null,"preview",-1))])):O("",!0)])):O("",!0),f("dl",Dn,[f("div",Un,[i[4]||(i[4]=f("dt",null,"File",-1)),f("dd",Bn,I(r.value.path),1)]),f("div",Fn,[i[5]||(i[5]=f("dt",null,"Size",-1)),f("dd",null,I(r.value.width)+" × "+I(r.value.height)+" px",1)]),(x(!0),M(oe,null,de(d.value,p=>(x(),M("div",{key:p.key,class:"facts__row"},[f("dt",null,[p.key==="color"?(x(),M("span",{key:0,class:"swatch",style:me({background:p.value})},null,4)):O("",!0),le(" "+I(p.key),1)]),f("dd",Vn,I(p.value),1),f("button",{class:"btn btn--ghost btn--small","aria-label":`Copy ${p.key}`,onClick:A=>pe(m)(p.key,p.value)},[J(fe,{name:pe(c)===p.key?"check":"copy",size:14},null,8,["name"])],8,Hn)]))),128))])])]),_:1},8,["title"]))}}),Wn=$e(Gn,[["__scopeId","data-v-4cbae639"]]),Kn={class:"page"},qn={class:"page__head"},Xn={class:"muted"},Yn={key:0,class:"notice notice--warn"},Jn={class:"card block"},Zn={class:"types"},Qn=["checked","onChange"],es={class:"type__title"},ts={class:"type__text muted"},ns={class:"grid"},ss={key:0,class:"field"},as=["min","max"],os={key:1,class:"field"},ls=["value"],rs={class:"field"},is=["value"],us={key:2,class:"field"},cs={class:"runbar"},ds=["disabled"],fs={key:0,class:"muted"},hs={key:1,class:"muted"},vs={key:1,class:"card block",role:"status"},ms={class:"progress"},ps={class:"muted"},ys={key:0},gs={key:2,class:"notice notice--error"},bs={key:3,class:"card block"},ws={class:"block__head"},_s={class:"muted"},ks={key:0},xs={key:1},Ms={key:0,class:"errors"},Ss={class:"tabs",role:"tablist"},Cs=["aria-selected"],$s=["aria-selected"],Is={key:0,class:"muted"},zs={key:1,class:"more"},As={class:"outbar"},Es=["disabled"],Ls={key:0,class:"muted"},Rs={class:"output"},Fe=48,Os=ke({__name:"ImageHashPage",props:{module:{},status:{}},setup(e){const t={columns:"auto",minLaneSize:250,gap:14},a=["auto","3x3","4x3","4x4","5x4","6x4","8x6"],s={json:"json",plain:"txt",csv:"csv",ts:"ts",js:"js"},o=R(),c=R([]),m=R(!0),r=R(["blurhash","thumbhash"]),w=R(28),$=R("auto"),y=R("json"),v=R("imageHashes"),d=R(null),S=R("idle"),b=R({done:0,total:0,cached:0}),_=R(""),i=R(),p=R("gallery"),A=R(Fe),L=R(""),N=R(""),T=R(!1);let B;const re=G(()=>_.value.toLowerCase().includes("sharp")),Z=G(()=>c.value.length>0&&r.value.length>0&&S.value!=="running"),ne=G(()=>b.value.total>0?Math.round(b.value.done/b.value.total*100):0),ie=G(()=>i.value?.entries.slice(0,A.value)??[]),V=G(()=>ie.value.map((z,u)=>({id:z.path,position:u})));function F(z){return ie.value[Number(z.position)]}function Q(z){r.value=r.value.includes(z)?r.value.filter(u=>u!==z):[...r.value,z]}function ee(z,u){const n=z.includes("\\")?"\\":"/";return`${z}${z.endsWith(n)?"":n}image-hashes.${s[u]??"txt"}`}async function W(z=!1){B?.(),S.value="running",_.value="",i.value=void 0,N.value="",b.value={done:0,total:0,cached:0},A.value=Fe,d.value=null;try{const{jobId:u}=await Le.post("/api/image-hash/run",{paths:c.value,recursive:m.value,types:r.value,components:$.value,budget:w.value,format:y.value,exportName:v.value,installSharp:z});B=yt(u,{onProgress:n=>{b.value=n},onDone:n=>{i.value=n,S.value="done",p.value="gallery",L.value=ee(n.base,n.format)},onFailed:n=>{_.value=n,S.value="failed"}})}catch(u){_.value=u instanceof Error?u.message:String(u),S.value="failed"}}async function K(){if(i.value?.output)try{await navigator.clipboard.writeText(i.value.output),T.value=!0,setTimeout(()=>T.value=!1,1200)}catch{T.value=!1}}function q(){const z=i.value?.output;if(!z)return;const u=new Blob([z],{type:"text/plain;charset=utf-8"}),n=document.createElement("a");n.href=URL.createObjectURL(u),n.download=`image-hashes.${s[i.value?.format??"json"]??"txt"}`,n.click(),URL.revokeObjectURL(n.href)}async function D(z=!1){if(i.value?.output){N.value="";try{const u=await Le.post("/api/image-hash/save",{path:L.value,content:i.value.output,overwrite:z});N.value=`Saved to ${u.path}`}catch(u){if(u instanceof gt&&u.status===409){window.confirm(`${u.message}. Replace it?`)&&await D(!0);return}N.value=u instanceof Error?u.message:String(u)}}}return Ce(async()=>{try{o.value=await Le.get("/api/image-hash/options"),w.value=o.value.budget.default,$.value=o.value.components.auto?"auto":o.value.components.default,v.value=o.value.exportName}catch(z){_.value=z instanceof Error?z.message:String(z),S.value="failed"}}),Ge(()=>{B?.()}),(z,u)=>(x(),M("div",Kn,[f("header",qn,[f("h1",null,I(e.module.title),1),f("p",Xn,I(e.module.description),1)]),o.value&&!o.value.sharp?(x(),M("div",Yn," The sharp image library is not installed yet. Previews are limited, and the first run will offer to install it. ")):O("",!0),J(bt,{sources:c.value,"onUpdate:sources":u[0]||(u[0]=n=>c.value=n),recursive:m.value,"onUpdate:recursive":u[1]||(u[1]=n=>m.value=n),"scan-url":"/api/image-hash/scan",start:e.status?.cwd??""},null,8,["sources","recursive","start"]),f("section",Jn,[u[19]||(u[19]=f("h2",null,"Placeholders",-1)),f("div",Zn,[(x(!0),M(oe,null,de(o.value?.types,n=>(x(),M("label",{key:n.id,class:Re(["type",{"type--on":r.value.includes(n.id)}])},[f("input",{type:"checkbox",checked:r.value.includes(n.id),onChange:k=>Q(n.id)},null,40,Qn),f("span",es,I(n.title),1),f("span",ts,I(n.description),1)],2))),128))]),f("div",ns,[r.value.includes("hazehash")?(x(),M("label",ss,[f("span",null,"Hazehash size: "+I(w.value)+" bytes",1),ye(f("input",{"onUpdate:modelValue":u[2]||(u[2]=n=>w.value=n),type:"range",min:o.value?.budget.min,max:o.value?.budget.max},null,8,as),[[Oe,w.value,void 0,{number:!0}]])])):O("",!0),r.value.includes("blurhash")?(x(),M("label",os,[u[16]||(u[16]=f("span",null,"Blurhash components",-1)),ye(f("select",{"onUpdate:modelValue":u[3]||(u[3]=n=>$.value=n),class:"select"},[(x(),M(oe,null,de(a,n=>f("option",{key:n,value:n},I(n==="auto"?"auto (by aspect ratio)":n),9,ls)),64))],512),[[Ye,$.value]])])):O("",!0),f("label",rs,[u[17]||(u[17]=f("span",null,"Output format",-1)),ye(f("select",{"onUpdate:modelValue":u[4]||(u[4]=n=>y.value=n),class:"select"},[(x(!0),M(oe,null,de(o.value?.formats,n=>(x(),M("option",{key:n,value:n},I(n),9,is))),128))],512),[[Ye,y.value]])]),y.value==="ts"||y.value==="js"?(x(),M("label",us,[u[18]||(u[18]=f("span",null,"Export name",-1)),ye(f("input",{"onUpdate:modelValue":u[5]||(u[5]=n=>v.value=n),class:"input",spellcheck:"false"},null,512),[[Oe,v.value]])])):O("",!0)])]),f("div",cs,[f("button",{class:"btn btn--primary",disabled:!Z.value,onClick:u[6]||(u[6]=n=>W(!1))},[J(fe,{name:"play",size:15}),le(" "+I(S.value==="running"?"Working…":"Compute hashes"),1)],8,ds),c.value.length===0?(x(),M("span",fs,"Add at least one folder or image.")):r.value.length===0?(x(),M("span",hs,"Pick at least one placeholder.")):O("",!0)]),S.value==="running"?(x(),M("div",vs,[f("div",ms,[f("div",{class:"progress__bar",style:me({width:`${ne.value}%`})},null,4)]),f("span",ps,[le(I(b.value.done)+" of "+I(b.value.total||"…")+" images",1),b.value.cached?(x(),M("span",ys," · "+I(b.value.cached)+" from cache",1)):O("",!0)])])):O("",!0),S.value==="failed"?(x(),M("div",gs,[f("p",null,I(_.value),1),re.value?(x(),M("button",{key:0,class:"btn btn--small",onClick:u[7]||(u[7]=n=>W(!0))}," Install sharp and retry ")):O("",!0)])):O("",!0),i.value?(x(),M("section",bs,[f("div",ws,[u[20]||(u[20]=f("h2",null,"Result",-1)),f("span",_s,[le(I(i.value.entries.length)+" image"+I(i.value.entries.length===1?"":"s")+" ",1),i.value.cached?(x(),M("span",ks,"· "+I(i.value.cached)+" cached",1)):O("",!0),i.value.errors.length?(x(),M("span",xs,"· "+I(i.value.errors.length)+" failed",1)):O("",!0)])]),i.value.errors.length?(x(),M("ul",Ms,[(x(!0),M(oe,null,de(i.value.errors,n=>(x(),M("li",{key:n.file},[f("code",null,I(n.file),1),le(" — "+I(n.message),1)]))),128))])):O("",!0),f("div",Ss,[f("button",{class:Re(["tab",{"tab--on":p.value==="gallery"}]),role:"tab","aria-selected":p.value==="gallery",onClick:u[8]||(u[8]=n=>p.value="gallery")}," Gallery ",10,Cs),f("button",{class:Re(["tab",{"tab--on":p.value==="output"}]),role:"tab","aria-selected":p.value==="output",onClick:u[9]||(u[9]=n=>p.value="output")}," Output ("+I(i.value.format)+") ",11,$s)]),p.value==="gallery"?(x(),M(oe,{key:1},[i.value.entries.length===0?(x(),M("p",Is,"No images were found.")):O("",!0),J(pe(Ot),{class:"gallery",items:V.value,options:t},{item:He(({item:n})=>[J(zn,{entry:F(n),onOpen:k=>d.value=Number(n.position)},null,8,["entry","onOpen"])]),_:1},8,["items"]),A.value<i.value.entries.length?(x(),M("div",zs,[f("button",{class:"btn",onClick:u[10]||(u[10]=n=>A.value+=Fe)}," Show more ("+I(i.value.entries.length-A.value)+" left) ",1),f("button",{class:"btn",onClick:u[11]||(u[11]=n=>A.value=i.value.entries.length)}," Show all ("+I(i.value.entries.length)+") ",1)])):O("",!0)],64)):(x(),M(oe,{key:2},[f("div",As,[f("button",{class:"btn btn--small",onClick:K},[J(fe,{name:T.value?"check":"copy",size:15},null,8,["name"]),le(" "+I(T.value?"Copied":"Copy"),1)]),f("button",{class:"btn btn--small",onClick:q},[J(fe,{name:"download",size:15}),u[21]||(u[21]=le(" Download ",-1))]),ye(f("input",{"onUpdate:modelValue":u[12]||(u[12]=n=>L.value=n),class:"input outbar__path",spellcheck:"false","aria-label":"File to write"},null,512),[[Oe,L.value]]),f("button",{class:"btn btn--small",disabled:L.value.trim()==="",onClick:u[13]||(u[13]=n=>D(!1))},[J(fe,{name:"save",size:15}),u[22]||(u[22]=le(" Write to file ",-1))],8,Es)]),N.value?(x(),M("p",Ls,I(N.value),1)):O("",!0),f("pre",Rs,I(i.value.output),1)],64))])):O("",!0),i.value&&d.value!==null?(x(),it(Wn,{key:4,index:d.value,"onUpdate:index":u[14]||(u[14]=n=>d.value=n),entries:i.value.entries,onClose:u[15]||(u[15]=n=>d.value=null)},null,8,["index","entries"])):O("",!0)]))}}),Ds=$e(Os,[["__scopeId","data-v-7ea67e46"]]);export{Ds as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.canvas[data-v-af1c304e]{display:block;width:100%;height:100%;object-fit:cover;background:var(--surface-2)}.canvas--bad[data-v-af1c304e]{display:grid;place-items:center;color:var(--danger)}.item[data-v-ede0ed45]{display:flex;flex-direction:column;gap:10px;padding:10px;min-width:0}.item__open[data-v-ede0ed45]{display:flex;flex-direction:column;gap:10px;padding:0;border:0;background:transparent;text-align:left;cursor:zoom-in}.item__open[data-v-ede0ed45]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.shots[data-v-ede0ed45]{display:block;overflow:hidden;border-radius:8px;background:var(--surface-2)}.shot[data-v-ede0ed45]{display:block;width:100%;height:100%;object-fit:cover;transition:transform .15s}.item__open:hover .shot[data-v-ede0ed45]{transform:scale(1.02)}.strip[data-v-ede0ed45]{display:flex;overflow:hidden;border-radius:8px}.strip__cell[data-v-ede0ed45]{position:relative;flex:1}.strip__label[data-v-ede0ed45]{position:absolute;left:4px;bottom:3px;padding:0 5px;border-radius:4px;background:#0000008c;color:#fff;font-size:10px}.preview[data-v-ede0ed45]{width:100%;border-radius:8px}.meta[data-v-ede0ed45]{display:flex;align-items:baseline;justify-content:space-between;gap:8px}.meta__name[data-v-ede0ed45]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hashes[data-v-ede0ed45]{display:flex;flex-direction:column;gap:2px;margin:0;padding:0;list-style:none}.hashes li[data-v-ede0ed45]{display:flex;align-items:center;gap:8px}.hashes__key[data-v-ede0ed45]{display:flex;align-items:center;gap:6px;flex:none;width:84px;color:var(--muted);font-size:12px}.hashes__value[data-v-ede0ed45]{flex:1;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.swatch[data-v-ede0ed45]{display:inline-block;width:12px;height:12px;border:1px solid var(--border);border-radius:4px}.counter[data-v-4cbae639]{font-size:12px}.scroll[data-v-4cbae639]{display:flex;flex-direction:column;gap:16px;padding:16px;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--border) transparent}.stage[data-v-4cbae639]{display:flex;align-items:center;justify-content:center;padding:12px;border-radius:9px;background:repeating-conic-gradient(var(--surface-2) 0% 25%,transparent 0% 50%) 50%/20px 20px}.stage__img[data-v-4cbae639]{display:block;max-width:100%;max-height:56vh;border-radius:6px;object-fit:contain}.compare[data-v-4cbae639]{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}.compare__item[data-v-4cbae639]{display:flex;flex-direction:column;gap:6px;margin:0}.compare__item figcaption[data-v-4cbae639]{font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--muted);text-transform:uppercase}.compare__frame[data-v-4cbae639]{overflow:hidden;border-radius:9px;background:var(--surface-2)}.compare__preview[data-v-4cbae639]{display:block;width:100%;height:100%;object-fit:cover}.facts[data-v-4cbae639]{display:flex;flex-direction:column;gap:4px;margin:0}.facts__row[data-v-4cbae639]{display:flex;align-items:center;gap:12px;min-height:32px}.facts dt[data-v-4cbae639]{display:flex;align-items:center;gap:6px;flex:none;width:96px;color:var(--muted);font-size:12px}.facts dd[data-v-4cbae639]{flex:1;min-width:0;margin:0}.facts__mono[data-v-4cbae639]{font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;word-break:break-all}.swatch[data-v-4cbae639]{display:inline-block;width:12px;height:12px;border:1px solid var(--border);border-radius:4px}.page[data-v-7ea67e46]{display:flex;flex-direction:column;gap:16px;padding:28px 28px 60px}@media(max-width:760px){.page[data-v-7ea67e46]{padding:18px 14px 40px}}.page__head p[data-v-7ea67e46]{margin-top:4px}.block[data-v-7ea67e46]{display:flex;flex-direction:column;gap:14px;padding:18px}.block__head[data-v-7ea67e46]{display:flex;align-items:center;justify-content:space-between;gap:12px}.types[data-v-7ea67e46]{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:10px}.type[data-v-7ea67e46]{display:grid;grid-template-columns:auto 1fr;column-gap:10px;row-gap:2px;padding:12px;border:1px solid var(--border);border-radius:10px;cursor:pointer}.type--on[data-v-7ea67e46]{border-color:var(--accent);background:var(--accent-soft)}.type input[data-v-7ea67e46]{grid-row:1/3;margin-top:3px}.type__title[data-v-7ea67e46]{font-weight:600}.type__text[data-v-7ea67e46]{font-size:12px}.grid[data-v-7ea67e46]{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}.runbar[data-v-7ea67e46]{display:flex;align-items:center;gap:14px}.progress[data-v-7ea67e46]{height:8px;overflow:hidden;border-radius:999px;background:var(--surface-2)}.progress__bar[data-v-7ea67e46]{height:100%;background:var(--accent);transition:width .15s}.errors[data-v-7ea67e46]{margin:0;padding:10px 14px 10px 28px;border-radius:10px;background:var(--danger-soft);color:var(--danger)}.tabs[data-v-7ea67e46]{display:flex;gap:4px;border-bottom:1px solid var(--border)}.tab[data-v-7ea67e46]{padding:8px 14px;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--muted);cursor:pointer}.tab[data-v-7ea67e46]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.tab--on[data-v-7ea67e46]{border-bottom-color:var(--accent);color:var(--text);font-weight:600}.gallery[data-v-7ea67e46]{width:100%}.more[data-v-7ea67e46]{display:flex;flex-wrap:wrap;align-items:center;gap:8px;justify-content:center}.outbar[data-v-7ea67e46]{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.outbar__path[data-v-7ea67e46]{flex:1;min-width:220px;height:28px;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px}.output[data-v-7ea67e46]{max-height:420px;margin:0;padding:14px;border-radius:10px;background:var(--surface-2);font-size:12px;white-space:pre-wrap;word-break:break-all;overflow:auto}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.block[data-v-f42c443b]{display:flex;flex-direction:column;gap:14px;padding:18px}.block__head[data-v-f42c443b]{display:flex;align-items:center;justify-content:space-between;gap:12px}.sources[data-v-f42c443b]{display:flex;flex-direction:column;gap:8px;margin:0;padding:0;list-style:none}.source[data-v-f42c443b]{display:flex;align-items:center;gap:10px;padding:6px 6px 6px 12px;border-radius:9px;background:var(--surface-2)}.source--bad[data-v-f42c443b]{background:var(--danger-soft);color:var(--danger)}.source__path[data-v-f42c443b]{flex:1;min-width:0;font-family:ui-monospace,Cascadia Code,SF Mono,Menlo,Consolas,monospace;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.source__stats[data-v-f42c443b]{flex:none;color:var(--muted);font-size:12px}.source--bad .source__stats[data-v-f42c443b]{color:inherit}.source__x[data-v-f42c443b]{display:grid;place-items:center;width:24px;height:24px;flex:none;border:0;border-radius:50%;background:transparent;color:inherit;cursor:pointer}.source__x[data-v-f42c443b]:hover{background:#7f7f7f33}@media(max-width:560px){.source[data-v-f42c443b]{flex-wrap:wrap}.source__stats[data-v-f42c443b]{order:3;width:100%}}.summary[data-v-f42c443b]{padding:10px 14px;border-radius:9px;background:var(--accent-soft)}.summary--warn[data-v-f42c443b]{background:var(--warn-soft);color:var(--warn)}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as T,u as x,w as U,e as q,o,c as n,f as r,t as u,g as _,h as C,i as f,F as p,a as A,n as B,j as D,v as P,k as j,l as $,p as b,q as E,m as S,r as w,s as L,b as R}from"./index-pDKL0Y31.js";import{F as G}from"./FolderBrowser-BX3-y8sM.js";const H={class:"card block"},J={class:"block__head"},K={key:0,class:"muted"},O={key:1,class:"sources"},Q=["title"],W={class:"source__stats"},X=["aria-label","onClick"],Y={class:"check"},Z={key:0,class:"muted"},ee=T({__name:"SourcePicker",props:S({scanUrl:{},start:{},title:{}},{sources:{required:!0},sourcesModifiers:{},recursive:{type:Boolean,required:!0},recursiveModifiers:{}}),emits:S(["scanned"],["update:sources","update:recursive"]),setup(c,{emit:F}){const M=c,l=x(c,"sources"),d=x(c,"recursive"),h=F,v=w(!1),t=w(),i=w(!1);let g,m=0;function k(e,s){return`${e} ${s}${e===1?"":"s"}`}function y(e){return t.value?.sources.find(s=>s.path===e)}function N(e){return e?e.exists?e.kind==="file"?$(e.bytes):e.files===0?"no images":`${k(e.files,"image")} · ${k(e.folders,"folder")} · ${$(e.bytes)}`:"not found":i.value?"…":""}function V(e){l.value=[...new Set([...l.value,...e])],v.value=!1}function z(e){l.value=l.value.filter(s=>s!==e)}function I(){if(clearTimeout(g),l.value.length===0){t.value=void 0,i.value=!1,h("scanned",void 0);return}i.value=!0,g=setTimeout(async()=>{const e=++m;try{const s=await L.post(M.scanUrl,{paths:l.value,recursive:d.value});e===m&&(t.value=s,h("scanned",s))}catch{e===m&&(t.value=void 0,h("scanned",void 0))}finally{e===m&&(i.value=!1)}},200)}return U([l,d],I,{deep:!0,immediate:!0}),q(()=>clearTimeout(g)),(e,s)=>(o(),n("section",H,[r("div",J,[r("h2",null,u(c.title??"Images"),1),r("button",{class:"btn",onClick:s[0]||(s[0]=a=>v.value=!0)},[_(C,{name:"plus",size:16}),s[3]||(s[3]=f(" Add folder or images ",-1))])]),l.value.length===0?(o(),n("p",K," Add the folders and images to process. Subfolders are included when the box below is ticked. ")):(o(),n("ul",O,[(o(!0),n(p,null,A(l.value,a=>(o(),n("li",{key:a,class:B(["source",{"source--bad":y(a)?.exists===!1}])},[_(C,{name:y(a)?.kind==="file"?"image":"folder",size:16},null,8,["name"]),r("span",{class:"source__path",title:a},u(a),9,Q),r("span",W,u(N(y(a))),1),r("button",{class:"source__x","aria-label":`Remove ${a}`,onClick:se=>z(a)},[_(C,{name:"close",size:14})],8,X)],2))),128))])),r("label",Y,[D(r("input",{"onUpdate:modelValue":s[1]||(s[1]=a=>d.value=a),type:"checkbox"},null,512),[[P,d.value]]),s[4]||(s[4]=f(" Include subfolders",-1))]),l.value.length>0?(o(),n("p",{key:2,class:B(["summary",{"summary--warn":t.value&&t.value.total.files===0}]),role:"status"},[i.value&&!t.value?(o(),n(p,{key:0},[f("Counting images…")],64)):t.value&&t.value.total.files===0?(o(),n(p,{key:1},[f(" No images found. Check the paths"+u(d.value?"":' or tick "Include subfolders"')+". ",1)],64)):t.value?(o(),n(p,{key:2},[r("strong",null,u(k(t.value.total.files,"image")),1),f(" in "+u(k(t.value.total.folders,"folder"))+" · "+u(j($)(t.value.total.bytes))+" ",1),i.value?(o(),n("span",Z,"· updating…")):b("",!0)],64)):b("",!0)],2)):b("",!0),v.value?(o(),E(G,{key:3,start:l.value[0]??c.start,onClose:s[2]||(s[2]=a=>v.value=!1),onConfirm:V},null,8,["start"])):b("",!0)]))}}),le=R(ee,[["__scopeId","data-v-f42c443b"]]);export{le as S};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.seg[data-v-56d7f4ee]{display:inline-flex;align-self:flex-start;flex-wrap:wrap;padding:3px;border:1px solid var(--border);border-radius:9px;background:var(--surface-2)}.seg__btn[data-v-56d7f4ee]{padding:5px 12px;border:0;border-radius:6px;background:transparent;color:var(--muted);cursor:pointer}.seg__btn[data-v-56d7f4ee]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.seg__btn--on[data-v-56d7f4ee]{background:var(--surface);color:var(--text);font-weight:600;box-shadow:var(--shadow)}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as o,u as r,o as s,c as t,F as n,a as d,n as i,t as c,m as u,b as m}from"./index-pDKL0Y31.js";const _=["aria-label"],v=["aria-checked","title","onClick"],b=o({__name:"UiSegmented",props:u({options:{},label:{}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(a){const l=r(a,"modelValue");return(g,k)=>(s(),t("div",{class:"seg",role:"radiogroup","aria-label":a.label},[(s(!0),t(n,null,d(a.options,e=>(s(),t("button",{key:e.value,class:i(["seg__btn",{"seg__btn--on":l.value===e.value}]),role:"radio","aria-checked":l.value===e.value,title:e.hint,onClick:f=>l.value=e.value},c(e.label),11,v))),128))],8,_))}}),p=m(b,[["__scopeId","data-v-56d7f4ee"]]);export{p as U};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/scss-Cw6XMfVs.js","assets/css-Z72CF80r.js","assets/html-BlS82ilI.js","assets/javascript-wDzz0qaB.js","assets/vue-CwSeJimo.js","assets/typescript-BPQ3VLAy.js","assets/json-Cp-IABpG.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{_ as t}from"./index-pDKL0Y31.js";const c={ts:"typescript",js:"javascript",md:"markdown",yml:"yaml"},m=new Set(["typescript","tsx","javascript","jsx","vue","json","css","scss","html","markdown","yaml"]);let n;function d(){return n??=(async()=>{const[{createHighlighterCore:_},{createJavaScriptRegexEngine:i}]=await Promise.all([t(()=>import("./core-DVezgdzc.js"),[]),t(()=>import("./engine-javascript-CNmxVhbB.js"),[])]);return _({themes:[t(()=>import("./github-light-DAi9KRSo.js"),[]),t(()=>import("./github-dark-DHJKELXO.js"),[])],langs:[t(()=>import("./typescript-BPQ3VLAy.js"),[]),t(()=>import("./tsx-COt5Ahok.js"),[]),t(()=>import("./javascript-wDzz0qaB.js"),[]),t(()=>import("./jsx-g9-lgVsj.js"),[]),t(()=>import("./css-Z72CF80r.js"),[]),t(()=>import("./scss-Cw6XMfVs.js"),__vite__mapDeps([0,1])),t(()=>import("./html-BlS82ilI.js"),__vite__mapDeps([2,3,1])),t(()=>import("./json-Cp-IABpG.js"),[]),t(()=>import("./markdown-Cvjx9yec.js"),[]),t(()=>import("./yaml-Buea-lGh.js"),[]),t(()=>import("./vue-CwSeJimo.js"),__vite__mapDeps([4,1,3,5,6,2]))],engine:i()})})(),n}function s(_){return _.split(/\r\n|\r|\n/).map(i=>[{text:i,light:"",dark:"",bold:!1,italic:!1}])}async function v(_,i){const o=c[i]??i;if(!m.has(o))return s(_);try{return(await d()).codeToTokensWithThemes(_,{lang:o,themes:{light:"github-light",dark:"github-dark"}}).map(l=>l.map(r=>{const e=r.variants.light,E=r.variants.dark,a=e?.fontStyle??0;return{text:r.content,light:e?.color??"",dark:E?.color??"",bold:(a&2)!==0,italic:(a&1)!==0}}))}catch{return s(_)}}export{v as h,s as p};
|