PageSourceSearch

https://www.saveboard.co/assets/app-CSq5VWoY.js

js saveboard.co collected 2026-10-02 01:20:45 UTC 1,108,289 bytes, 36 lines download raw bytes

1import{j as n,a as P0,A as ph,L as vg,f as _0,S as E0,b as Ko,g as ip,C as Os,R as Ms,w as k0,d as Il,s as N0,h as iE,u as cE,r as lE,e as Jh,i as dE,k as uE,l as pE,m as mE,c as j0,P as R0}from"./styles-Xn1Oq4tX.js";import{r as d,a as ty}from"./vendor-sentry-Bio_lJNr.js";import{c as L0}from"./vendor-supabase-DLA3YV1Q.js";import{Q as B0}from"./vendor-qrcode-CAsQZhHc.js";(function(){try{var e=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};e.SENTRY_RELEASE={id:"0a079a60f28e46e39fcced142af855a9ae4a0862"};var t=new e.Error().stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="3d8ae2e1-3b2b-4792-9113-1e4a8de45e9c",e._sentryDebugIdIdentifier="sentry-dbid-3d8ae2e1-3b2b-4792-9113-1e4a8de45e9c")}catch{}})();const T0=/^https?:\/\//i,cp=(e=null)=>{const t=String(e?.avatar_url||e?.avatarUrl||"").trim();return T0.test(t)?t:""},tI=(e=null)=>e?.avatar_path||e?.avatarPath?null:cp(e)||null,mn=Object.freeze({standard:"standard",wide:"wide",large:"large"}),D0=new Set(Object.values(mn)),zn=e=>{const t=String(e??"").trim().toLowerCase();return D0.has(t)?t:mn.standard},O0=(e,t)=>{const r=Math.max(1,Math.floor(Number(t)||1)),a=zn(e);return a===mn.large?{columnSpan:Math.min(2,r),rowSpan:2}:a===mn.wide?{columnSpan:Math.min(2,r),rowSpan:1}:{columnSpan:1,rowSpan:1}},M0=(e=[],t=1)=>{const r=Math.max(1,Math.floor(Number(t)||1));if(!Array.isArray(e)||e.length===0)return r;const a=[];let s=0,o=0;return e.forEach(i=>{const{columnSpan:c,rowSpan:l}=O0(i?.cardSize,r);let u=!1;for(let p=0;!u;p+=1)for(let m=0;m<=r-c;m+=1){let f=!0;for(let h=0;h<l&&f;h+=1){const b=a[p+h];for(let v=0;v<c;v+=1)if(b?.has(m+v)){f=!1;break}}if(f){for(let h=0;h<l;h+=1){const b=p+h,v=a[b]??new Set;for(let S=0;S<c;S+=1)v.add(m+S);a[b]=v}o+=c*l,s=Math.max(s,p+l),u=!0;break}}}),Math.max(0,s*r-o)},Yu=2,Bs="#fafafa",ym="manual",U0=/^auto(?:[:_-]v?(\d+))?(?:[:_-](high|medium|low))?$/i,F0=new Set(["custom","manual","solid","white"]),Xw=new Set(["high","medium","low"]),$0=/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i,fE=0,z0=.06,rI=.18,nI=.042,V0=56,hE=208,gE=24,gs=(e,t,r)=>Math.min(r,Math.max(t,e)),Ku=(e,t="")=>{const r=String(e||"").trim().match($0);return r?`#${(r[1].length===3?r[1].split("").map(s=>`${s}${s}`).join(""):r[1]).toLowerCase()}`:t},Qh=({r:e=0,g:t=0,b:r=0}={})=>`#${[e,t,r].map(a=>Math.round(gs(Number(a)||0,0,255)).toString(16).padStart(2,"0")).join("")}`,bE=e=>{const t=gs(Number(e)||0,0,1);return t>=.78?"high":t>=.56?"medium":"low"},H0=e=>{const t=String(e||"").trim().toLowerCase(),r=t.match(U0);if(!t||r){const a=Number(r?.[1]||0);return{confidenceLevel:Xw.has(r?.[2])?r[2]:"low",detectorVersion:Number.isFinite(a)?a:0,isLegacyAutomatic:!r?.[1],mode:"auto",raw:t||"auto"}}return{confidenceLevel:"high",detectorVersion:null,isLegacyAutomatic:!1,mode:"manual",raw:(F0.has(t),t)}},fS=({confidence:e=fE,confidenceLevel:t="",detectorVersion:r=Yu}={})=>{const a=Xw.has(t)?t:bE(e);return`auto:v${Math.max(1,Math.trunc(Number(r)||Yu))}:${a}`},ao=(e={},t=Bs)=>{const r=e.imageBackgroundMode??e.backgroundMode,a=e.imageBackgroundColor??e.backgroundColor,s=H0(r);return{color:Ku(a,Ku(t,Bs)),confidenceLevel:s.confidenceLevel,detectorVersion:s.detectorVersion,isLegacyAutomatic:s.isLegacyAutomatic,mode:s.mode,storedMode:s.raw}},W0=(e={},t=Bs)=>ao(e,t),hS=(e={})=>{const t=ao(e);return t.mode==="auto"&&t.detectorVersion!==Yu},sa=({color:e=Bs,confidence:t=fE,confidenceLevel:r="",detectorVersion:a=Yu,ok:s=!1,reason:o="",samples:i=[],transparent:c=!1}={})=>{const l=gs(Number(t)||0,0,1);return{color:Ku(e,Bs),confidence:l,confidenceLevel:Xw.has(r)?r:bE(l),detectorVersion:a,ok:!!s,reason:o,samples:i,transparent:!!c}},ry=e=>{const t=gs(e/255,0,1);return t<=.04045?t/12.92:((t+.055)/1.055)**2.4},Jw=({r:e=0,g:t=0,b:r=0}={})=>{const a=ry(e),s=ry(t),o=ry(r),i=.4122214708*a+.5363325363*s+.0514459929*o,c=.2119034982*a+.6806995451*s+.1073969566*o,l=.0883024619*a+.2817188376*s+.6299787005*o,u=Math.cbrt(i),p=Math.cbrt(c),m=Math.cbrt(l);return{l:.2104542553*u+.793617785*p-.0040720468*m,a:1.9779984951*u-2.428592205*p+.4505937099*m,b:.0259040371*u+.7827717662*p-.808675766*m}}
1,Zh=(e={},t={})=>Math.hypot(Number(e.l||0)-Number(t.l||0),Number(e.a||0)-Number(t.a||0),Number(e.b||0)-Number(t.b||0)),ny=(e,t)=>{const r=[...e].sort((o,i)=>o.value-i.value),a=t/2;let s=0;for(const o of r)if(s+=o.weight,s>=a)return o.value;return r.at(-1)?.value||0},G0=(e,t)=>{if(!e.length)return 0;const r=[...e].sort((a,s)=>a-s);return r[Math.min(r.length-1,Math.max(0,Math.floor((r.length-1)*t)))]},Qw=(e,t,r,a,s)=>{const o=gs(Math.trunc(a),0,t-1),c=(gs(Math.trunc(s),0,r-1)*t+o)*4;return{r:e[c],g:e[c+1],b:e[c+2],a:e[c+3]}},q0=(e,t,r,a,s,o)=>{const i=[[a-1,s],[a+1,s],[a,s-1],[a,s+1]];let c=0;return i.forEach(([l,u])=>{if(l<0||u<0||l>=t||u>=r)return;const p=Qw(e,t,r,l,u);p.a<hE||(c=Math.max(c,Zh(o,Jw(p))))}),c},Y0=({data:e,width:t,height:r})=>{const a=Math.max(3,Math.round(Math.min(t,r)*z0)),s=Math.max(a*2,Math.round(t*rI)),o=Math.max(a*2,Math.round(r*rI)),i=[];let c=0,l=0,u=0;for(let p=0;p<r;p+=1)for(let m=0;m<t;m+=1){const f=p,h=r-1-p,b=m,v=t-1-m,S=Math.min(f,h,b,v);if(S>=a)continue;l+=1;const C=Qw(e,t,r,m,p);if(C.a<gE){u+=1;continue}if(c+=1,C.a<hE)continue;const I=Jw(C),A=q0(e,t,r,m,p,I),E=1.8-S/Math.max(1,a-1)*1.2,y=1/(1+(A/.018)**2),N=C.a/255*E*Math.max(.04,y),_=[];f<a&&_.push("top"),v<a&&_.push("right"),h<a&&_.push("bottom"),b<a&&_.push("left");const P=(m<s||m>=t-s)&&(p<o||p>=r-o);i.push({...C,edges:_,gradient:A,isCorner:P,lab:I,weight:N})}return{meaningfulPixelCount:c,perimeterPixelCount:l,samples:i,transparentPixelCount:u}},K0=e=>{const t=new Map;return e.forEach(r=>{const a=[Math.round(r.lab.l/.018),Math.round(r.lab.a/.018),Math.round(r.lab.b/.018)].join(":"),s=t.get(a)||{l:0,a:0,b:0,weight:0};s.l+=r.lab.l*r.weight,s.a+=r.lab.a*r.weight,s.b+=r.lab.b*r.weight,s.weight+=r.weight,t.set(a,s)}),[...t.values()].sort((r,a)=>a.weight-r.weight).slice(0,V0).map(r=>({l:r.l/r.weight,a:r.a/r.weight,b:r.b/r.weight}))},X0=(e,t,r)=>{const a=e.filter(y=>Zh(y.lab,t)<=nI);if(!a.length)return null;const s=a.reduce((y,N)=>y+N.weight,0),o={r:ny(a.map(y=>({value:y.r,weight:y.weight})),s),g:ny(a.map(y=>({value:y.g,weight:y.weight})),s),b:ny(a.map(y=>({value:y.b,weight:y.weight})),s)},i=Jw(o),c=e.filter(y=>Zh(y.lab,i)<=nI),l=c.reduce((y,N)=>y+N.weight,0),u={top:0,right:0,bottom:0,left:0};let p=0,m=0;c.forEach(y=>
1{y.edges.forEach(N=>{u[N]+=y.weight}),y.isCorner&&(p+=y.weight),m+=y.gradient*y.weight});const f=Object.fromEntries(Object.entries(u).map(([y,N])=>[y,N/Math.max(1e-4,r.edgeWeights[y])])),h=Object.values(f).filter(y=>y>=.24).length,b=Object.values(f).map(y=>Math.min(1,y/.62)).reduce((y,N)=>y+N,0)/4,v=l/Math.max(1e-4,r.weight),S=p/Math.max(1e-4,r.cornerWeight),C=1-gs(m/Math.max(1e-4,l)/.055,0,1),I=c.map(y=>Zh(y.lab,i)),A=G0(I,.9),k=1-gs(A/.06,0,1),E=(v*.43+b*.31+C*.16+Math.min(1,S)*.1)*(.62+k*.38);return{centerColor:o,cornerCoverage:S,coverage:v,dispersion:A,edgeCoverage:f,memberCount:c.length,score:E,supportedEdgeCount:h,uniformity:C}},J0=({data:e,width:t,height:r}={})=>{const a=Math.trunc(Number(t)||0),s=Math.trunc(Number(r)||0);if(!e||a<2||s<2||e.length<a*s*4)return sa({reason:"invalid-pixel-buffer"});const o=Y0({data:e,width:a,height:s}),i=o.transparentPixelCount/Math.max(1,o.perimeterPixelCount);if(i>.58)return sa({confidence:.76,reason:"transparent-perimeter",transparent:!0});if(o.samples.length<24)return sa({confidence:i>.35?.74:0,reason:i>.35?"transparent-perimeter":"insufficient-opaque-perimeter",transparent:i>.35});const c={cornerWeight:0,edgeWeights:{top:0,right:0,bottom:0,left:0},weight:0};o.samples.forEach(f=>{c.weight+=f.weight,f.isCorner&&(c.cornerWeight+=f.weight),f.edges.forEac
1h(h=>{c.edgeWeights[h]+=f.weight})});const u=K0(o.samples).map(f=>X0(o.samples,f,c)).filter(Boolean).sort((f,h)=>Math.abs(h.score-f.score)>1e-4?h.score-f.score:Qh(f.centerColor).localeCompare(Qh(h.centerColor)))[0];if(!!!(u&&u.score>=.54&&u.coverage>=.32&&u.supportedEdgeCount>=2&&u.dispersion<=.046))return sa({confidence:u?.score||0,reason:i>.58?"transparent-complex-perimeter":"low-confidence-complex-perimeter",samples:u?[{coverage:Number(u.coverage.toFixed(3)),dispersion:Number(u.dispersion.toFixed(4)),edges:u.supportedEdgeCount,score:Number(u.score.toFixed(3))}]:[],transparent:i>.58});const m=gs(u.score+Math.min(.08,Math.max(0,u.supportedEdgeCount-2)*.025),0,1);return sa({color:Qh(u.centerColor),confidence:m,ok:!0,reason:m>=.78?"stable-perimeter-background":"probable-perimeter-background",samples:[{coverage:Number(u.coverage.toFixed(3)),dispersion:Number(u.dispersion.toFixed(4)),edgeCoverage:Object.fromEntries(Object.entries(u.edgeCoverage).map(([f,h])=>[f,Number(h.toFixed(3))])),edges:u.supportedEdgeCount,score:Number(u.score.toFixed(3)),uniformity:Number(u.uniformity.toFixed(3))}],transparent:i>.58})},Q0=({containerHeight:e,containerLeft:t=0,containerTop:r=0,containerWidth:a,naturalHeight:s,naturalWidth:o}={})=>{const i=Number(a)||0,c=Number(e)||0,l=Number(o)||0,u=Number(s)||0;if(i<=0||c<=0||l<=0||u<=0)return null;const p=Math.min(i/l,c/u),m=l*p,f=u*p;return{bottom:r+(c+f)/2,height:f,left:t+(i-m)/2,right:t+(i+m)/2,top:r+(c-f)/2,width:m}},Z0=({pointX:e,pointY:t,...r}={})=>{const a=Q0(r);return!a||e<a.left||e>a.right||t<a.top||t>a.bottom?{inside:!1,x:0,y:0}:{inside:!0,x:gs((e-a.left)/a.width,0,1),y:gs((t-a.top)/a.height,0,1)}},eB=({alphaThreshold:e=gE,data:t,height:r,radius:a=2,width:s,x:o,y:i}={})=>{const c=Math.trunc(Number(s)||0),l=Math.trunc(Number(r)||0);if(!t||c<1||l<1)return"";const u=gs(Math.round(Number(o)||0),0,c-1),p=gs(Math.round(Number(i)||0),0,l-1),m=gs(Math.trunc(Number(a)||0),0,12),f=[];for(let v=-m;v<=m;v+=1)for(let S=-m;S<=m;S+=1){const C=u+S,I=p+v;if(C<0||C>=c||I<0||I>=l)continue;const A=Qw(t,c,l,C,I);A.a>=e&&f.push(A)}if(!f.length)return"";const h=Math.floor(f.length/2),b=v=>[...f].map(S=>S[v]).sort((S,C)=>S-C)[h];return Qh({r:b("r"),g:b("g"),b:b("b")})},Lr=Object.freeze({normal:"normal",minimal:"minimal"}),tB=Object.freeze(Object.values(Lr).flatMap(e=>Object.values(mn).map(t=>`${e}:${t}`))),vE=new Set(tB),aI=.5,sI=4,au=(e,t,r,a)=>{const s=Number(e);return Number.isFinite(s)?Math.min(r,Math.max(t,s)):a},oI=(e,t="cover")=>e==="contain"||e==="cover"?e:t,yE=(e={})=>{const t=e?.imageBackgroundMode!==void 0||e?.backgroundMode!==void 0,r=e?.imageBackgroundColor!==void 0||e?.backgroundColor!==void 0;if(!t&&!r)return{};const a=ao(e);return{imageBackgroundMode:a.mode==="manual"?ym:a.storedMode,imageBackgroundColor:a.color}},vi=(e=Lr.normal,t=mn.standard)=>`${e===Lr.minimal?Lr.minimal:Lr.normal}:${zn(t)}`,Al=(e={},t={})=>({fit:oI(e?.fit??e?.imageFit,oI(t?.fit??t?.imageFit)),scale:au(e?.scale??e?.imageScale,aI,sI,au(t?.scale??t?.imageScale,aI,sI,1)),offsetX:au(e?.offsetX??e?.imagePositionX,0,100,au(t?.offsetX??t?.imagePositionX,0,100,50)),offsetY:au(e?.offsetY??e?.imagePositionY,0,100,au(t?.offsetY??t?.imagePositionY,0,100,50)),...yE(e)}),ya=(e={})=>!e||typeof e!="object"||Array.isArray(e)?{}:Object.keys(e).filter(t=>vE.has(t)&&e[t]&&typeof e[t]=="object"&&!Array.isArray(e[t])).sort().reduce((t,r)=>(t[r]=Al(e[r]),t),{}),Zw=(e={})=>Al({fit:e.imageFit,scale:e.imageScale,offsetX:e.imagePositionX,offsetY:e.imagePositionY}),Nm=({base:e={},mode:t,overrides:r={},size:a}={})=>{const s=Al(e),o=ya(r),i=vi(t,a);return o[i]||s},hc=(e={})=>{const t=Al(e);return{imageFit:t.fit,imageScale:t.scale,imagePositionX:t.offsetX,imagePositionY:t.offsetY}},em=(e={})=>Al({fit:e.imageFit,scale:e.imageScale,offsetX:e.imagePositionX,offsetY:e.imagePositionY}),SE=(e={})=>Al({...Al(e),fit:"cover",scale:1,offsetX:50,offsetY:50}),wE=(e={},t,r={})=>{const a=ya(e);return vE.has(t)?{...a,[t]:Al(r)}:a},rB=(e={},t)=>{const r=ya(e);if(!Object.hasOwn(r,t))return r;const a={...r};return delete a[t],a},gS=(e={},{mode:t,size:r}={})=>{const a=Nm({base:Zw(e),mode:t,overrides:e.imageFramingOverrides??e.image_framing_overrides,size:r??e.cardSize??e.card_size});return{...e,...hc(a),...yE(a)}},CE=Object.freeze(["imageUrl","image_url","imageURL","image"]),ay=Object.freeze(["image","imageUrl","image_url","imageURL"]),xE=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),nB=e=>String(e??"").trim(),aB=(e="")=>{const t=String(e||"").trim().toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/g,"");if(!t||t.includes(":")||t==="localhost"||t==="0.0.0.0"||t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".internal")||t.endsWith(".test"))return!0;const r=t.split(".");if(r.length===4&&r.every(a=>/^\d+$/.test(a)&&Number(a)>=0&&Number(a)<=255)){const[a,s]=r.map(Number);return a===0||a===10||a===127||a===169&&s===254||a===172&&s>=16&&s<=31||a===192&&s===168}return!1},sB=e=>{try{const t=new URL(e);return(t.protocol==="http:"||t.protocol==="https:")&&!t.username&&!t.password&&!aB(t.hostname)}catch{return!1}}
1,IE=({isPlaceholder:e,key:t,value:r})=>{const a=nB(r);if(!a)return{key:t,kind:"explicit-clear",value:""};if(e(a))return{key:t,kind:"placeholder",value:a};if(/^data:image\/(?:avif|gif|jpe?g|png|svg\+xml|webp)(?:;|,)/i.test(a))return{key:t,kind:"local-upload",value:a};if(/^blob:/i.test(a))return{key:t,kind:"transient",value:a};if(/^(?:file|filesystem):/i.test(a))return{key:t,kind:"invalid",value:a};if(/^\/(?!\/)[^\s]*$/.test(a))return{key:t,kind:"local-path",value:a};try{const s=new URL(a);if((s.protocol==="http:"||s.protocol==="https:")&&!s.username&&!s.password)return{key:t,kind:"external",value:a}}catch{}return{key:t,kind:"invalid",value:a}},sy=(e,t,r)=>t.map(a=>e.find(s=>s.key===a&&r(s))).find(Boolean)||null,tm=e=>[...new Set(e.map(t=>t.value))],vc=(e={})=>e.kind==="local-upload"?{image:e.value,imageUrl:""}:e.kind==="external"?{image:e.value,imageUrl:e.value}:e.kind==="local-path"?{image:e.value,imageUrl:""}:{},vu=(e={})=>e.kind==="external"||e.kind==="local-path"||e.kind==="local-upload",oB=(e=[])=>{let t=2166136261,r=2654435769;const a=[...e].sort().join("\0");for(let s=0;s<a.length;s+=1){const o=a.charCodeAt(s);t=Math.imul(t^o,16777619),r=Math.imul(r^o,2246822507)}return`${(t>>>0).toString(16).padStart(8,"0")}${(r>>>0).toString(16).padStart(8,"0")}`},iB=(e,{isPlaceholder:t=()=>!1,key:r="imageUrl",present:a=!0}={})=>a&&e!==void 0?IE({isPlaceholder:t,key:r,value:e}):{key:r,kind:"missing",value:""},bs=(e={},{isPlaceholder:t=()=>!1}={})=>{const r=CE.filter(S=>xE(e,S)&&e[S]!==void 0).map(S=>IE({isPlaceholder:t,key:S,value:e[S]}));if(!r.length)return{candidates:[],diagnosticCode:"image-reference-missing",explicitClear:!1,hasConflict:!1,kind:"missing",present:!1,requiresReview:!1,sourceKey:"",value:""};const a=r.filter(S=>S.kind==="local-upload"),s=r.filter(S=>S.kind==="external"),o=r.filter(S=>S.kind==="local-path"),i=[...a,...s],c=tm(i),l=tm(a),u=tm(s);if(a.length){const S=sy(r,ay,I=>I.kind==="local-upload"),C=l.length>1;return{candidates:c,diagnosticCode:C?"image-reference-conflicting-uploads":s.length?"image-reference-local-upload-over-external":"image-reference-local-upload",explicitClear:!1,hasConflict:C,kind:"local-upload",present:!0,requiresReview:C,sourceKey:S.key,value:S.value}}if(s.length){const S=sy(r,ay,I=>I.kind==="external"),C=u.length>1;return{candidates:u,diagnosticCode:C?"image-reference-conflicting-external-aliases":"image-reference-external",explicitClear:!1,hasConflict:C,kind:"external",present:!0,requiresReview:C,sourceKey:S.key,value:S.value}}if(o.length){const S=sy(r,ay,A=>A.kind==="local-path"),C=tm(o),I=C.length>1;return{candidates:C,diagnosticCode:I?"image-reference-conflicting-local-paths":"image-reference-local-path",explicitClear:!1,hasConflict:I,kind:"local-path",present:!0,requiresReview:I,sourceKey:S.key,value:S.value}}const p=r.some(S=>S.kind==="explicit-clear"),m=r.filter(S=>S.kind==="placeholder"),f=r.filter(S=>S.kind==="transient"),h=r.filter(S=>S.kind==="invalid"),b=f.length?"transient":h.length?"invalid":m.length?"placeholder":"explicit-clear",v=r.find(S=>S.kind===b)||r[0];return{candidates:tm(r.filter(S=>S.value)),diagnosticCode:`image-reference-${b}`,explicitClear:b==="explicit-clear"&&p,hasConflict:!1,kind:b,present:!0,requiresReview:b==="transient"||b==="invalid",sourceKey:v?.key||"",value:v?.value||""}},AE=(e={},t={})=>{const r=bs(e,t);return vu(r)?r.value:""},eC=(e={},t={})=>{const r=bs(e,t);return r.kind==="external"&&!r.hasConflict&&sB(r.value)?r.value:""},tC=(e={},{isPlaceholder:t=()=>!1,previousRecord:r=null}={})=>{const a=bs(e,{isPlaceholder:t});if((a.kind==="external"||a.kind==="local-upload")&&!a.hasConflict)return{action:"set",reference:a,value:a.value};if(a.explicitClear)return{action:"clear",reference:a,value:null};const s=r?bs(r,{isPlaceholder:t}):bs({},{isPlaceholder:t});return(s.kind==="external"||s.kind==="local-upload")&&!s.hasConflict?{action:"preserve",reference:a,value:s.value}:a.kind==="local-path"&&!a.hasConflict?{action:"omit",reference:a,value:void 0}:{action:a.requiresReview||a.hasConflict?"review":"omit",reference:a,value:void 0}},PE=(e={},{emptyValue:t="",isPlaceholder:r=()=>!1}={})=>{const a=bs(e,{isPlaceholder:r});return a.hasConflict?`[image-reference-conflict:${a.candidates.length}:${oB(a.candidates)}]`:a.kind==="external"||a.kind==="local-upload"?a.value:t},cB=(e={})=>CE.some(t=>xE(e,t)&&e[t]!==void 0),lp=(e={},t={},{isPlaceholder:r=()=>!1,preferCurrentImage:a=!1,preferCurrentLocalUpload:s=!0}={})=>{const o=bs(e,{isPlaceholder:r}),i=bs(t,{isPlaceholder:r});return a&&vu(o)?vc(o):a&&o.explicitClear?{image:"",imageUrl:""}:i.explicitClear?{image:"",imageUrl:""}:i.hasConflict||i.kind==="missing"?vu(o)?vc(o):{}:i.kind==="invalid"||i.kind==="transient"?vu(o)?vc(o):{image:"",imageReferenceIssue:i.diagnosticCode,imageUrl:""}:s&&o.kind==="local-upload"&&i.kind==="external"?vc(o):vu(i)?vc(i):vu(o)?vc(o):{}},bS=(e={},{isPlaceholder:t=()=>!1,previousRecord:r=null}={})=>{const a=bs(e,{isPlaceholder:t});if(a.kind==="local-path"&&!a.hasConflict)return{...e,...vc(a)};const s=tC(e,{isPlaceholder:t,previousRecord:r});if(s.action==="set"||s.action==="preserve"){const o=iB(s.value,{isPlaceholder:t});return{...e,...vc(o)}}return s.action==="clear"?{...e,image:"",imageUrl:""}:s.action==="review"?s.reference.hasConflict?{...e}:{...e,image:"",imageUrl:""}:e},lB=(e={})=>vc(e),_E="https://lwfhechwnembraawvehr.supabase.co".trim()||"",EE="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imx3ZmhlY2h3bmVtYnJhYXd2ZWhyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODI2NzE3MDQsImV4cCI6MjA5ODI0NzcwNH0.4P2QHXyjPnlZ61u2ZAL6oS9ww0zLI2cLn6R43SwOe6A".trim()||"",dB="true".trim()||"",uB="",mh=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,fh=6,hh=280,vS="profile-avatars",pB=10*1024*1024,iI=3600,mB=60*1e3,fB={"image/jpeg":"jpg","
1image/png":"png","image/webp":"webp"},hB=({clearImage:e=!1,imageUrl:t}={})=>({p_clear_image:e===!0,p_image_url:eC({imageUrl:t})||null}),oy=3,eg=30,gB=/^[a-z0-9_.]+$/,yb=new Set(["abuse","admin","admin-reports","administrator","account","accounts","api","app","auth","billing","callback","board","boards","dashboard","discover","explore","help","legal","login","logout","me","mod","moderator","my-list","mylist","official","owner","premium","pricing","privacy","profile","profiles","public","register","report","reports","root","saveboards","reset-password","saveboard","search","security","settings","share","sign-in","sign-up","signin","signup","staff","store","stores","support","system","team","terms","u","updates","user","users","verified","www"]),kE=(e="")=>String(e||"").trim().toLowerCase().replace(/^@+/,"").replace(/[._-]+/g,""),bB=new Set(Array.from(yb).flatMap(e=>[e,kE(e)])),su="username, display_name, avatar_url, avatar_path, avatar_position_x, avatar_position_y, avatar_zoom, bio, profile_visibility, created_at, updated_at",cI="Public boards could not load.",vB="Public items could not load.",NE="Public profile update did not complete.",gh="Public item update did not complete.",lI="Private board link could not load.",il=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,yB=new Set(["profile","board","item"]),SB=new Set(["spam","scam_or_malicious_link","offensive","impersonation","privacy","other"]),wB=new Set(["new","reviewed","dismissed","actioned"]),CB=1e3,xB=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return t.includes("duplicate_open_report")||r==="23505"?"You already sent a report for this. Thanks - we'll review it.":t.includes("report_rate_limited")?"Please wait a moment before sending another report.":t.includes("report_target_unavailable")?"This content is no longer available to report.":t.includes("not_authenticated")||r==="28000"?"Sign in to report this.":"Could not send report. Please try again."},IB=new Set(["1","true","yes","on"]),AB=new Set(["0","false","no","off"]),dI=[_E?"":"NEXT_PUBLIC_SUPABASE_URL",EE?"":"NEXT_PUBLIC_SUPABASE_ANON_KEY"].filter(Boolean),uI=(e,t=!1)=>{const r=String(e||"").trim().toLowerCase();return r?IB.has(r)?!0:AB.has(r)?!1:t:t},An={isConfigured:dI.length===0,missingEnv:dI,providers:{google:uI(dB,!1),apple:uI(uB,!1)}},ae=An.isConfigured?L0(_E,EE,{auth:{autoRefreshToken:!0,detectSessionInUrl:!0,persistSession:!0}}):null,jE=d.createContext(null),iy=()=>typeof window>"u"?"/auth/callback":`${window.location.origin}/auth/callback`,PB=()=>{if(typeof window>"u")return"/account/reset-password";try{const e=new URL("/account/reset-password",window.location.origin);return e.searchParams.set("type","recovery"),e.toString()}catch{return`${window.location.origin}/account/reset-password?type=recovery`}},_B=()=>{if(typeof window>"u")return{authCode:"",callbackError:"",isPasswordResetRoute:!1,isRecovery:!1};const e=new URLSearchParams(window.location.search),t=new URLSearchParams(window.location.hash.replace(/^#/,"")),r=String(e.get("code")||"").trim(),a=String(e.get("type")||t.get("type")||"").trim().toLowerCase(),s=e.get("error_description")||e.get("error")||t.get("error_description")||t.get("error")||"",o=window.location.pathname==="/account/reset-password",i=t.has("access_token")||t.has("refresh_token");return{authCode:r,callbackError:s,isPasswordResetRoute:o,isRecovery:a==="recovery"||o&&!!(r||i)}},rC="saveboard.passwordRecoveryReady",bh=()=>{if(typeof window>"u")return!1;try{return window.sessionStorage.getItem(rC)==="true"}catch{return!1}},cy=()=>{if(!(typeof window>"u"))try{window.sessionStorage.setItem(rC,"true")}catch{}},td=()=>{if(!(typeof window>"u"))try{window.sessionStorage.removeItem(rC)}catch{}},pI=()=>"Sign-in was cancelled or could not be completed.",EB=e=>{const t=String(e?.code||"").toLowerCase(),r=String(e?.message||"").toLowerCase();return t.includes("rate_limit")||r.includes("rate limit")||r.includes("too many")?"Too many confirmation emails were requested. Wait a few minutes, then try again.":r.includes("already")||r.includes("registered")?"An account already exists for this email. Sign in instead.":r.includes("password")?"Use a stronger password.":r.includes("email")?"Could not create account. Check the email and try again.":"Could not create account. Check the details and try again."},kB=e=>String(e?.message||"").toLowerCase().includes("confirm")?"Check your email to confirm your account, then sign in.":"Could not sign in. Check your email and password.",NB=()=>
1"Could not send reset link. Please try again.",jB=()=>"Could not update password. Please request a new reset link.",RE=(e="")=>String(e||"").replace(/[^a-zA-Z0-9_-]/g,""),mI=(e="",t="")=>{const r=RE(t),a=String(e||"").trim();return!r||!a.startsWith(`${r}/`)?"":a},ly=(e,t,r,a)=>{const s=Number(e);return Number.isFinite(s)?Math.min(a,Math.max(r,s)):t},ou=(e={})=>({avatar_position_x:ly(e?.avatar_position_x??e?.avatarPositionX,50,0,100),avatar_position_y:ly(e?.avatar_position_y??e?.avatarPositionY,50,0,100),avatar_zoom:ly(e?.avatar_zoom??e?.avatarZoom,1,1,3)}),dy=async(e=[])=>{if(!ae)return;const t=Array.from(new Set(e.map(r=>String(r||"").trim()).filter(Boolean)));if(t.length)try{await ae.storage.from(vS).remove(t)}catch{}},Xa=(e="")=>String(e||"").trim().replace(/^@+/,"").toLowerCase(),no=(e="")=>{const r=String(e||"").trim().replace(/^@+/,""),a=Xa(e);return a?r.includes("@")?"Use a username, not an email address.":a.length<oy?`Use ${oy}-${eg} characters.`:a.length>eg?`Use ${oy}-${eg} characters.`:gB.test(a)?/^[_.]|[_.]$/.test(a)?"Do not start or end with a dot or underscore.":/[_.]{2,}/.test(a)?"Use 3–30 letters, numbers, or simple separators.":yb.has(a)||bB.has(kE(a))?"This username is reserved.":"":"Use 3–30 letters, numbers, or simple separators.":"Enter a username."},rm=(e="")=>String(e||"").trim().toLowerCase()==="private"?"private":"public",vh=(e="")=>String(e||"").trim().replace(/\s+/g," "),RB=(e={})=>{const t=e.cover_image_urls||e.coverImageUrls||e.images;return Array.isArray(t)?t.map(r=>String(r||"").trim()).filter(Boolean).slice(0,4):[]},yh=(e={})=>{const t=String(e.title||e.name||"").trim();return{description:String(e.description||"").trim(),id:String(e.id||e.board_id||t||"public-board"),images:RB(e),visibility:e.visibility==="public"?"public":e.visibility==="private"?"private":"",likeCount:Math.max(0,Number(e.like_count||e.likeCount||0)||0),name:t||"Untitled board",productCount:Math.max(0,Number(e.item_count||e.itemCount||e.productCount||0)||0),publishedAt:e.published_at||e.publishedAt||"",sortOrder:Math.max(0,Number(e.sort_order||e.sortOrder||0)||0)}},Sh=(e={})=>{const t=String(e.title||"").trim();return{brand:String(e.brand||"").trim(),cardSize:zn(e.card_size??e.cardSize),imageFramingOverrides:ya(e.image_framing_overrides??e.imageFramingOverrides),currency:String(e.currency||"").trim(),id:String(e.id||""),imageUrl:String(e.image_url||e.imageUrl||"").trim(),isVisible:e.is_visible!==!1&&e.isVisible!==!1,localItemId:String(e.local_item_id||e.localItemId||"").trim(),priceText:String(e.price_text||e.priceText||"").trim(),publicBoardId:String(e.public_board_id||e.publicBoardId||"").trim(),publishedAt:e.published_at||e.publishedAt||"",sortOrder:Math.max(0,Number(e.sort_order||e.sortOrder||0)||0),sourceLabel:String(e.source_label||e.sourceLabel||"").trim(),sourceUrl:String(e.source_url||e.sourceUrl||"").trim(),title:t||"Untitled item"}},uy=(e={})=>({createdAt:e.created_at||e.createdAt||"",details:String(e.details||"").trim(),id:String(e.id||"").trim(),reason:String(e.reason||"").trim(),status:String(e.status||"").trim(),targetId:String(e.target_id||e.targetId||"").trim(),targetOwnerUsername:Xa(e.target_owner_username||e.targetOwnerUsername||""),targetType:String(e.target_type||e.targetType||"").trim(),updatedAt:e.updated_at||e.updatedAt||""}),yS=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="42p01"||r==="42703"||t.includes("schema cache")||t.includes("public_profiles")||t.includes("profiles")||t.includes("username")?"Profile cloud saving is not available yet.":""},fI=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="23505"||t.includes("duplicate")||t.includes("unique")?"That username is already taken.":r==="23514"||t.includes("check constraint")?"Choose another username.":yS(e)||"Could not update profile. Try again."},uc=(e,t=NE)=>{const r=String(e?.message||"").toLowerCase(),a=String(e?.code||"").toLowerCase();return a==="42p01"||a==="42703"||a==="42883"||a==="42501"||r.includes("public_boards")||r.includes("public board")||r.includes("schema cache")||r.includes("permission")||r.includes("row-level security"),t},LB=e=>{const t=String(e?.message||"").toLowerCase();return t.includes("bucket")||t.includes("not found")||t.includes("policy")||t.includes("permission")||t.includes("unauthorized")||t.includes("row-level security")?"Supabase Storage bucket/policy is required for avatar upload.":"Could not upload profile photo. Try again."};function BB({children:e}
1){const[t,r]=d.useState(null),[a,s]=d.useState(bh),[o,i]=d.useState(null),[c,l]=d.useState(!1),[u,p]=d.useState(!!ae),[m,f]=d.useState(""),h=d.useRef(new Map),b=d.useRef(""),v=d.useRef(""),S=d.useRef(""),C=d.useCallback(async F=>{if(!F)return null;const te={...F,...ou(F)},me=String(te.avatar_path||"").trim();if(!ae||!me)return te;const ie=Date.now(),Ae=h.current.get(me);if(Ae?.url&&Ae.expiresAt>ie+mB)return{...te,avatar_url:Ae.url};try{const{data:Re,error:ne}=await ae.storage.from(vS).createSignedUrl(me,iI);return ne||!Re?.signedUrl?(h.current.delete(me),{...te,avatar_url:""}):(h.current.set(me,{expiresAt:ie+iI*1e3,url:Re.signedUrl}),{...te,avatar_url:Re.signedUrl})}catch{return h.current.delete(me),{...te,avatar_url:""}}},[]);d.useEffect(()=>{const F=t?.user?.id||"";b.current!==F&&(h.current.clear(),b.current=F)},[t?.user?.id]),d.useEffect(()=>{if(!ae){p(!1);return}let F=!0;ae.auth.getSession().then(({data:me,error:ie})=>{F&&(r(me.session||null),f(ie?"Could not load your account session.":""))}).catch(()=>{F&&f("Could not load your account session.")}).finally(()=>{F&&p(!1)});const{data:te}=ae.auth.onAuthStateChange((me,ie)=>{S.current=me,me==="PASSWORD_RECOVERY"&&(cy(),s(!0)),me==="SIGNED_OUT"&&(td(),s(!1)),r(ie||null),p(!1),f("")});return()=>{F=!1,te.subscription.unsubscribe()}},[]),d.useEffect(()=>{if(!ae||typeof window>"u")return;const F=_B();if(!F.isPasswordResetRoute||!F.isRecovery)return;let te=!0;return(async()=>{if(p(!0),f(""),F.callbackError){te&&(f(pI(F.callbackError)),p(!1));return}let ie=null;if(F.authCode)try{S.current="",{error:ie}=await ae.auth.exchangeCodeForSession(F.authCode)}catch{ie=new Error("password-recovery-exchange-failed")}if(ie){te&&(f("This reset link is no longer valid. Please request a new one."),p(!1));return}let Ae=null;try{Ae=(await ae.auth.getSession()).data?.session||null}catch{Ae=null}if(te){if(!Ae?.user?.id){f("This reset link is no longer valid. Please request a new one."),p(!1);return}cy(),s(!0),r(Ae),p(!1),(window.location.search||window.location.hash)&&window.history.replaceState(null,"","/account/reset-password")}})(),()=>{te=!1}},[]),d.useEffect(()=>{const F=t?.user?.id||"";if(!ae||!F){v.current="",i(null),l(!1);return}let te=!0;return v.current!==F&&i(null),v.current=F,l(!0),(async()=>{try{const{data:ie,error:Ae}=await ae.from("profiles").select(su).eq("id",F).maybeSingle();if(!te||Ae)return;const Re=await C(ie);te&&i(Re||null)}catch{}finally{te&&l(!1)}})(),()=>{te=!1}},[C,t?.user?.id]);const I=d.useCallback(async F=>{const te=String(F||"").trim().toLowerCase();if(!mh.test(te)){const ie="Enter a valid email address.";return f(ie),{error:ie}}if(!ae){const ie="Account sign-in is not configured yet.";return f(ie),{error:ie}}p(!0),f("");let me=null;try{({error:me}=await ae.auth.signInWithOtp({email:te,options:{emailRedirectTo:iy()}}))}catch{me=new Error("magic-link-failed")}if(p(!1),me){const ie="Could not send the sign-in link. Check the email and try again.";return f(ie),{error:ie}}return{error:""}},[]),A=d.useCallback(async({email:F,password:te})=>{const me=String(F||"").trim().toLowerCase(),ie=String(te||"");if(!mh.test(me)){const ne="Enter a valid email address.";return f(ne),{error:ne}}if(!ie){const ne="Enter a password.";return f(ne),{error:ne}}if(ie.length<fh){const ne=`Use at least ${fh} characters for your password.`;return f(ne),{error:ne}}if(!ae){const ne="Account sign-in is not configured yet.";return f(ne),{error:ne}}p(!0),f("");let Ae=null,Re=null;try{({data:Ae,error:Re}=await ae.auth.signUp({email:me,password:ie,options:{emailRedirectTo:iy()}}))}catch(ne){Re=ne||new Error("sign-up-failed")}if(p(!1),Re){const ne=EB(Re);return f(ne),{error:ne}}return Ae?.session&&(td(),s(!1),r(Ae.session)),{error:"",needsConfirmation:!!(Ae?.user&&!Ae?.session),session:Ae?.session||null,user:Ae?.user||null}},[]),k=d.useCallback(async({email:F,password:te})=>{const me=String(F||"").trim().toLowerCase(),ie=String(te||"");if(!mh.test(me)){const ne="Enter a valid email address.";return f(ne),{error:ne}}if(!ie){const ne="Enter your password.";return f(ne),{error:ne}}if(!ae){const ne="Account sign-in is not configured yet.";return f(ne),{error:ne}}p(!0),f("");let Ae=null,Re=null;try{({data:Ae,error:Re}=await ae.auth.signInWithPassword({email:me,password:ie}))}catch(ne){Re=ne||new Error("password-sign-in-failed")}if(p(!1),Re){const ne=kB(Re);return f(ne),{error:ne}}return Ae?.session&&(td(),s(!1),r(Ae.session)),{error:"",session:Ae?.session||null,user:Ae?.user||null}},[]),E=d.useCallback(async F=>{const te=String(F||"").trim().toLowerCase();if(!mh.test(te)){const ie="Enter a valid email address.";return f(ie),{error:ie}}if(!ae){const ie="Account sign-in is not configured yet.";return f(ie),{error:ie}}p(!0),f("");let me=null;try{({error:me}=await ae.auth.resetPasswordForEmail(te,{redirectTo:PB()}))}catch(ie){me=ie||new Error("password-reset-failed")}if(p(!1),me){const ie=NB();return f(ie),{error:ie}}return{error:""}},[]),y=d.useCallback(async F=>{const te=String(F||"");if(!te){const ne="Enter a new password.";return f(ne),{error:ne}}if(te.length<fh){const ne=`Use at least ${fh} characters for your password.`;return f(ne),{error:ne}}if(!ae){const ne="Account sign-in is not configured yet.";return f(ne),{error:ne}}p(!0),f("");let me=t,ie=null;try{const ne=await ae.auth.getSession();me=ne.data?.session||null,ie=ne.error||null}catch(ne){ie=ne||new Error("password-reset-session-failed")}if(ie||!me?.user?.id||!a&&!bh()){p(!1);const ne="This reset link is no longer valid. Please request a new one.";return f(ne),{error:ne}}let Ae=null,Re=null;try{({data:Ae,error:Re}=await ae.auth.updateUser({password:te}))}catch(ne){Re=ne||new Error("password-update-failed")}if(p(!1),Re){const ne=jB();return f(ne),{error:ne}}return td(),s(!1),r(me),{error:"",user:Ae?.user||me.user||null}},[a,t]),N=d.useCallback(async F=>{if(!ae){const me="Account sign-in is not configured yet.";return f(me),{error:me}}if(!An.providers[F]){const ie=`${F==="apple"?"Apple":"Google"} sign-in is not available yet.`;return f(ie),{error:ie}}f("");let te=null;try{({error:te}=await ae.auth.signInWithOAuth({provider:F,options:{redirectTo:iy()}}))}
1catch{te=new Error(`${F}-sign-in-failed`)}if(te){const ie=`${F==="apple"?"Apple":"Google"} sign-in is not available yet.`;return f(ie),{error:ie}}return{error:""}},[]),_=d.useCallback(()=>N("google"),[N]),P=d.useCallback(()=>N("apple"),[N]),V=d.useCallback(async F=>{const te=Xa(F),me=no(te);if(me)return{available:!1,error:me};if(!ae)return{available:!1,error:"Account sign-in is not configured yet."};if(!t?.user)return{available:!1,error:"Sign in to choose a username."};if(o?.username===te)return{available:!0,error:""};let ie=null,Ae=null;try{({data:ie,error:Ae}=await ae.rpc("is_profile_username_available",{profile_username:te}))}catch(Re){Ae=Re||new Error("username-check-failed")}return Ae?{available:!1,error:yS(Ae)||"Could not check username availability."}:ie!==!0?{available:!1,error:"That username is already taken."}:{available:!0,error:""}},[o?.username,t?.user]),L=d.useCallback(async F=>{const te=Xa(F);if(no(te)||!ae)return{error:"",profile:null};let ie=null,Ae=null;try{({data:ie,error:Ae}=await ae.rpc("get_public_profile_by_username",{profile_username:te}).maybeSingle())}catch(Re){Ae=Re||new Error("profile-lookup-failed")}return Ae?{error:yS(Ae)||"Could not load this profile.",profile:null}:{error:"",profile:await C(ie)||null}},[C]),z=d.useCallback(async F=>{const te=Xa(F);if(no(te)||!ae)return{boards:[],error:""};let ie=null,Ae=null;try{({data:ie,error:Ae}=await ae.rpc("get_public_profile_boards",{profile_username:te}))}catch(Re){Ae=Re||new Error("public-board-lookup-failed")}return Ae?{boards:[],error:uc(Ae,cI)}:{boards:Array.isArray(ie)?ie.map(yh):[],error:""}},[]),B=d.useCallback(async({publicBoardId:F="",username:te=""}={})=>{const me=Xa(te),ie=no(me),Ae=String(F||"").trim();if(ie||!ae||!il.test(Ae))return{board:null,error:""};let Re=null,ne=null;try{({data:Re,error:ne}=await ae.rpc("get_public_board_for_profile",{p_public_board_id:Ae,profile_username:me}))}catch(kt){ne=kt||new Error("public-board-detail-lookup-failed")}if(ne)return{board:null,error:uc(ne,cI)};const ht=Array.isArray(Re)?Re[0]:Re;return{board:ht?yh(ht):null,error:""}},[]),re=d.useCallback(async(F="")=>{if(!ae)return{error:"",items:[]};const te=String(F||"").trim();if(!te)return{error:"",items:[]};let me=null,ie=null;try{({data:me,error:ie}=await ae.rpc("get_public_board_items",{p_public_board_id:te}))}catch(Ae){ie=Ae||new Error("public-board-item-lookup-failed")}return ie?{error:uc(ie,vB),items:[]}:{error:"",items:Array.isArray(me)?me.map(Sh):[]}},[]),Z=d.useCallback(async(F="")=>{if(!ae||!t?.user?.id)return{error:"Sign in to share private boards.",publicBoardId:"",shareToken:""};const te=String(F||"").trim();if(!il.test(te))return{error:"Could not create a private board link.",publicBoardId:"",shareToken:""};let me=null,ie=null;try{({data:me,error:ie}=await ae.rpc("create_private_board_share_link",{p_public_board_id:te}))}catch(ne){ie=ne||new Error("private-board-share-link-failed")}const Ae=Array.isArray(me)?me[0]:me,Re=String(Ae?.share_token||Ae?.shareToken||"").trim();return ie||!il.test(Re)?{error:uc(ie,"Could not create a private board link."),publicBoardId:"",shareToken:""}:{error:"",publicBoardId:String(Ae?.public_board_id||Ae?.publicBoardId||te).trim(),shareToken:Re}},[t?.user?.id]),D=d.useCallback(async F=>{if(!ae||!t?.user?.id)return{error:"Sign in to manage private links."};try{const{data:te,error:me}=await ae.rpc("get_owner_private_board_share_link",{p_local_board_id:String(F||"").trim()});if(me)return{error:"Could not check the private link. Try again."};const ie=Array.isArray(te)?te[0]:te;return{error:"",publicBoardId:ie?.public_board_id||"",shareToken:ie?.share_token||""}}catch{return{error:"Could not check the private link. Try again."}}},[t?.user?.id]),K=d.useCallback(async F=>{if(!ae||!t?.user?.id||!il.test(F))return{error:"Could not revoke the private link."};try{const{data:te,error:me}=await ae.rpc("revoke_private_board_share_link",{p_public_board_id:F});return{error:me||te!==!0?"Could not revoke the private link. Try again.":""}}catch{return{error:"Could not revoke the private link. Try again."}}},[t?.user?.id]),ee=d.useCallback(async({publicBoardId:F="",shareToken:te="",username:me=""}={})=>{const ie=Xa(me),Ae=no(ie),Re=String(F||"").trim(),ne=String(te||"").trim();if(Ae||!ae||!il.test(Re)||!il.test(ne))return{board:null,error:"",profile:null};let ht=null,kt=null;try{({data:ht,error:kt}=await ae.rpc("get_private_board_for_share_link",{p_profile_username:ie,p_public_board_id:Re,p_share_token:ne}))}catch(Qe){kt=Qe||new Error("private-board-detail-lookup-failed")}if(kt)return{board:null,error:uc(kt,lI),profile:null};const Ee=Array.isArray(ht)?ht[0]:ht;if(!Ee)return{board:null,error:"",profile:null};const xe=await C({avatar_path:Ee.profile_avatar_path,avatar_position_x:Ee.profile_avatar_position_x,avatar_position_y:Ee.profile_avatar_position_y,avatar_url:Ee.profile_avatar_url,avatar_zoom:Ee.profile_avatar_zoom,bio:Ee.profile_bio,created_at:Ee.profile_created_at,display_name:Ee.profile_display_name,profile_visibility:Ee.profile_visibility,updated_at:Ee.profile_updated_at,username:Ee.profile_username});return{board:{...yh(Ee),isUnlistedShare:!0},error:"",profile:xe}},[C]),J=d.useCallback(async({publicBoardId:F="",shareToken:te=""}={})=>
1{if(!ae)return{error:"",items:[]};const me=String(F||"").trim(),ie=String(te||"").trim();if(!il.test(me)||!il.test(ie))return{error:"",items:[]};let Ae=null,Re=null;try{({data:Ae,error:Re}=await ae.rpc("get_private_board_items_for_share_link",{p_public_board_id:me,p_share_token:ie}))}catch(ne){Re=ne||new Error("private-board-item-lookup-failed")}return Re?{error:uc(Re,lI),items:[]}:{error:"",items:Array.isArray(Ae)?Ae.map(Sh):[]}},[]),fe=d.useCallback(async({description:F="",itemCount:te=0,localBoardId:me="",sortOrder:ie=0,title:Ae="",visibility:Re="private"}={})=>{if(!ae||!t?.user?.id)return{board:null,error:"Sign in to publish public boards."};const ne=String(me||"").trim(),ht=String(Ae||"").trim(),kt=String(Re||"").trim().toLowerCase()==="public"?"public":"private";if(!ne||!ht)return{board:null,error:NE};let Ee=null,xe=null;try{({data:Ee,error:xe}=await ae.rpc("upsert_public_board_metadata",{p_description:String(F||"").trim()||null,p_item_count:Math.max(0,Number(te||0)||0),p_local_board_id:ne,p_sort_order:Math.max(0,Number(ie||0)||0),p_title:ht,p_visibility:kt}))}catch(Pe){xe=Pe||new Error("public-board-sync-failed")}if(xe)return{board:null,error:uc(xe)};const Qe=Array.isArray(Ee)?Ee[0]:Ee;return{board:Qe?yh(Qe):null,error:""}},[t?.user?.id]),De=d.useCallback(async(F="")=>{if(!ae||!t?.user?.id)return{error:"Sign in to publish public items.",items:[]};const te=String(F||"").trim();if(!te)return{error:gh,items:[]};let me=null,ie=null;try{({data:me,error:ie}=await ae.rpc("get_owner_public_board_items",{p_public_board_id:te}))}catch(Ae){ie=Ae||new Error("public-board-item-load-failed")}return ie?{error:uc(ie,gh),items:[]}:{error:"",items:Array.isArray(me)?me.map(Sh):[]}},[t?.user?.id]),Be=d.useCallback(async({brand:F="",cardSize:te="standard",clearImage:me=!1,currency:ie="",imageUrl:Ae="",imageFramingOverrides:Re={},isVisible:ne=!0,localItemId:ht="",priceText:kt="",publicBoardId:Ee="",sortOrder:xe=0,sourceLabel:Qe="",sourceUrl:Pe="",title:Ct=""}={})=>{if(!ae||!t?.user?.id)return{error:"Sign in to publish public items.",item:null};const nr=String(Ee||"").trim(),en=String(ht||"").trim(),st=String(Ct||"").trim();if(!nr||!en||!st)return{error:gh,item:null};let gr=null,Xt=null;const fn=hB({clearImage:me,imageUrl:Ae});try{({data:gr,error:Xt}=await ae.rpc("sync_public_board_item_metadata",{p_brand:String(F||"").trim()||null,p_card_size:zn(te),p_currency:String(ie||"").trim()||null,...fn,p_image_framing_overrides:ya(Re),p_is_visible:!!ne,p_local_item_id:en,p_price_text:String(kt||"").trim()||null,p_public_board_id:nr,p_sort_order:Math.max(0,Number(xe||0)||0),p_source_label:String(Qe||"").trim()||null,p_source_url:String(Pe||"").trim()||null,p_title:st}))}catch(ft){Xt=ft||new Error("public-board-item-sync-failed")}if(Xt)return{error:uc(Xt,gh),item:null};const Ke=Array.isArray(gr)?gr[0]:gr;return{error:"",item:Ke?Sh(Ke):null}},[t?.user?.id]),Fe=d.useCallback(async({details:F="",reason:te="",targetId:me="",targetOwnerUsername:ie="",targetType:Ae=""}={})=>{if(!ae||!t?.user?.id)return{error:"Sign in to report this.",ok:!1};const Re=String(Ae||"").trim().toLowerCase(),ne=String(me||"").trim().slice(0,160),ht=String(te||"").trim().toLowerCase(),kt=Xa(ie).slice(0,eg),Ee=String(F||"").replace(/\s+/g," ").trim().slice(0,CB);if(!yB.has(Re)||!ne||!SB.has(ht))return{error:"Could not send report. Please try again.",ok:!1};let xe=null;try{({error:xe}=await ae.from("content_reports").insert({details:Ee||null,reason:ht,target_id:ne,target_owner_username:kt||null,target_type:Re}))}catch(Qe){xe=Qe||new Error("content-report-failed")}return xe?{error:xB(xe),ok:!1}:{error:"",ok:!0}},[t?.user?.id]),ke=d.useCallback(async()=>{if(!ae||!t?.user?.id)return{isAdmin:!1};let F=!1,te=null;try{({data:F,error:te}=await ae.rpc("is_report_admin"))}catch(me){te=me||new Error("report-admin-check-failed")}return te?{isAdmin:!1}:{isAdmin:F===!0}},[t?.user?.id]),We=d.useCallback(async()=>{if(!ae||!t?.user?.id)return{error:"Sign in to view reports.",reports:[]};let F=[],te=null;try{({data:F,error:te}=await ae.from("content_reports").select("id,target_type,target_id,target_owner_username,reason,details,status,created_at,updated_at").order("created_at",{ascending:!1}).limit(100))}catch(me){te=me||new Error("content-report-fetch-failed")}return te?{error:"Reports are not available.",reports:[]}:{error:"",reports:Array.isArray(F)?F.map(uy).filter(me=>me.id):[]}},[t?.user?.id]),de=d.useCallback(async({reportId:F="",status:te=""}={})=>
1{if(!ae||!t?.user?.id)return{error:"Sign in to update reports.",report:null};const me=String(F||"").trim(),ie=String(te||"").trim().toLowerCase();if(!me||!wB.has(ie))return{error:"Could not update report.",report:null};let Ae=null,Re=null;try{({data:Ae,error:Re}=await ae.from("content_reports").update({status:ie}).eq("id",me).select("id,target_type,target_id,target_owner_username,reason,details,status,created_at,updated_at").maybeSingle())}catch(ne){Re=ne||new Error("content-report-update-failed")}return Re?{error:"Could not update report.",report:null}:{error:"",report:Ae?uy(Ae):null}},[t?.user?.id]),ye=d.useCallback(async({action:F="",reportId:te=""}={})=>{if(!ae||!t?.user?.id)return{error:"Sign in to update reports.",report:null};const me=String(te||"").trim(),ie=String(F||"").trim(),Ae=ie==="unpublish-board"?"admin_unpublish_public_board":ie==="hide-item"?"admin_hide_public_board_item":ie==="set-profile-private"?"admin_set_public_profile_private":"";if(!me||!Ae)return{error:"Could not apply moderation action.",report:null};let Re=null,ne=null;try{({data:Re,error:ne}=await ae.rpc(Ae,{report_id:me}))}catch(kt){ne=kt||new Error("content-report-moderation-action-failed")}if(ne)return{error:"Could not apply moderation action.",report:null};const ht=Array.isArray(Re)?Re[0]:Re;return{error:"",report:ht?uy(ht):null}},[t?.user?.id]),ge=d.useCallback(async({bio:F=void 0,displayName:te="",username:me="",profileVisibility:ie=""}={})=>{if(!ae){const st="Account sign-in is not configured yet.";return f(st),{error:st}}if(!t?.user){const st="Sign in to update your profile.";return f(st),{error:st}}const Ae=t.user.user_metadata||{},Re=String(te||"").trim(),ne=Xa(me),ht=vh(F===void 0?o?.bio||"":F),kt=rm(ie||o?.profile_visibility||"private"),Ee=no(ne);if(Ee)return f(Ee),{error:Ee};if(ht.length>hh){const st=`Use ${hh} characters or fewer for your bio.`;return f(st),{error:st}}const xe={avatar_path:o?.avatar_path||null,...ou(o),avatar_url:tI(o),bio:ht||null,display_name:Re||null,email:t.user.email||null,id:t.user.id,profile_visibility:kt,user_id:t.user.id,username:ne},Qe={...Ae,display_name:Re,full_name:Re,name:Re,preferred_username:ne,user_name:ne,username:ne};p(!0),f("");let Pe=null,Ct=null,nr=null,en=null;try{({data:nr,error:en}=await ae.from("profiles").upsert(xe,{onConflict:"id"}).select(su).single()),nr=await C(nr)}catch(st){en=st||new Error("profile-row-update-failed")}if(en){const st=fI(en);return p(!1),f(st),{error:st}}try{({data:Pe,error:Ct}=await ae.auth.updateUser({data:Qe}))}catch(st){Ct=st||new Error("profile-update-failed")}if(Ct){const st="Profile updated, but account metadata could not refresh. Try reloading.";return p(!1),i(nr||null),f(st),{error:st}}try{const{data:st}=await ae.auth.getSession();st?.session?r(st.session):Pe?.user&&r({...t,user:Pe.user})}catch{Pe?.user&&r({...t,user:Pe.user})}return i(nr||null),p(!1),{error:"",profile:nr||null,user:Pe?.user||null}},[C,o?.avatar_path,o?.avatar_position_x,o?.avatar_position_y,o?.avatar_url,o?.avatar_zoom,o?.bio,o?.profile_visibility,t]),ze=d.useCallback(async({bio:F=void 0,displayName:te="",profileVisibility:me=""}={})=>{if(!ae){const Ct="Account sign-in is not configured yet.";return f(Ct),{error:Ct}}if(!t?.user){const Ct="Sign in to update your profile.";return f(Ct),{error:Ct}}const ie=t.user.user_metadata||{},Ae=String(te||"").trim().replace(/\s+/g," ");if(!Ae){const Ct="Enter a name.";return f(Ct),{error:Ct}}const Re=vh(F===void 0?o?.bio||"":F);if(Re.length>hh){const Ct=`Use ${hh} characters or fewer for your bio.`;return f(Ct),{error:Ct}}const ne=rm(me||o?.profile_visibility||"private"),ht={avatar_path:o?.avatar_path||null,...ou(o),avatar_url:tI(o),bio:Re||null,display_name:Ae,email:t.user.email||null,id:t.user.id,profile_visibility:ne,user_id:t.user.id},kt={...ie,display_name:Ae,full_name:Ae,name:Ae};p(!0),f("");let Ee=null,xe=null,Qe=null,Pe=null;try{({data:Qe,error:Pe}=await ae.from("profiles").upsert(ht,{onConflict:"id"}).select(su).single()),Qe=await C(Qe)}catch(Ct){Pe=Ct||new Error("profile-display-name-update-failed")}if(Pe){const Ct=fI(Pe);return p(!1),f(Ct),{error:Ct}}try{({data:Ee,error:xe}=await ae.auth.updateUser({data:kt}))}catch(Ct){xe=Ct||new Error("profile-metadata-update-failed")}if(xe){const Ct="Profile updated, but account metadata could not refresh. Try reloading.";return p(!1),i(Qe||null),f(Ct),{error:Ct}}try{const{data:Ct}=await ae.auth.getSession();Ct?.session?r(Ct.session):Ee?.user&&r({...t,user:Ee.user})}catch{Ee?.user&&r({...t,user:Ee.user})}return i(Qe||null),p(!1),{error:"",profile:Qe||null,user:Ee?.user||null}},[C,o?.avatar_path,o?.avatar_position_x,o?.avatar_position_y,o?.avatar_url,o?.avatar_zoom,o?.bio,o?.profile_visibility,t]),W=d.useCallback(async F=>{const te=String(F?.type||"").toLowerCase(),me=fB[te]||"";if(!me){const Qe="Choose a JPG, PNG, or WebP image.";return f(Qe),{error:Qe}}if(Number(F?.size||0)>pB){const Qe="Choose an image under 10 MB.";return f(Qe),{error:Qe}}if(!ae){const Qe="Account sign-in is not configured yet.";return f(Qe),{error:Qe}}if(!t?.user?.id){const Qe="Sign in to update your profile photo.";return f(Qe),{error:Qe}}const ie=RE(t.user.id);if(!ie){const Qe="Could not upload profile photo. Try again.";return f(Qe),{error:Qe}}const Ae=`${ie}/avatar-${Date.now()}.${me}`,Re=mI(o?.avatar_path,t.user.id);p(!0),f("");let ne=null,ht=null;try{({data:ne,error:ht}=await ae.storage.from(vS).upload(Ae,F,{cacheControl:"31536000",contentType:te,upsert:!1}))}catch(Qe){ht=Qe||new Error("avatar-upload-failed")}if(ht){const Qe=LB(ht);return p(!1),f(Qe),{error:Qe}}const kt=ne?.path||Ae;let Ee=null,xe=null;try{({data:Ee,error:xe}
1=await ae.from("profiles").upsert({avatar_path:kt,...ou(o),avatar_url:null,email:t.user.email||null,id:t.user.id,profile_visibility:rm(o?.profile_visibility),user_id:t.user.id},{onConflict:"id"}).select(su).single()),Ee=await C(Ee)}catch(Qe){xe=Qe||new Error("avatar-profile-update-failed")}if(xe){await dy([kt]);const Qe="Could not upload profile photo. Try again.";return p(!1),f(Qe),{error:Qe}}return Re&&Re!==kt&&(h.current.delete(Re),await dy([Re])),i(Ee||null),p(!1),{avatarPath:kt,avatarUrl:Ee?.avatar_url||"",error:"",profile:Ee||null}},[C,o?.avatar_path,o?.avatar_position_x,o?.avatar_position_y,o?.avatar_zoom,o?.profile_visibility,t]),Le=d.useCallback(async()=>{if(!ae){const ie="Account sign-in is not configured yet.";return f(ie),{error:ie}}if(!t?.user?.id){const ie="Sign in to update your profile photo.";return f(ie),{error:ie}}p(!0),f("");const F=mI(o?.avatar_path,t.user.id);let te=null,me=null;try{({data:te,error:me}=await ae.from("profiles").upsert({avatar_path:null,...ou(),avatar_url:null,email:t.user.email||null,id:t.user.id,profile_visibility:rm(o?.profile_visibility),user_id:t.user.id},{onConflict:"id"}).select(su).single()),te=await C(te)}catch(ie){me=ie||new Error("avatar-profile-remove-failed")}if(me){const ie="Could not remove profile photo. Try again.";return p(!1),f(ie),{error:ie}}return F&&(h.current.delete(F),await dy([F])),i(te||null),p(!1),{error:"",profile:te||null}},[C,o?.avatar_path,o?.profile_visibility,t]),et=d.useCallback(async({x:F=50,y:te=50,zoom:me=1}={})=>{if(!ae){const ne="Account sign-in is not configured yet.";return f(ne),{error:ne}}if(!t?.user?.id){const ne="Sign in to update your profile photo.";return f(ne),{error:ne}}if(!o?.avatar_path&&!o?.avatar_url){const ne="Upload a profile photo before adjusting it.";return f(ne),{error:ne}}const ie=ou({avatar_position_x:F,avatar_position_y:te,avatar_zoom:me});p(!0),f("");let Ae=null,Re=null;try{({data:Ae,error:Re}=await ae.from("profiles").upsert({...ie,avatar_path:o?.avatar_path||null,avatar_url:o?.avatar_path?null:o?.avatar_url||null,email:t.user.email||null,id:t.user.id,profile_visibility:rm(o?.profile_visibility),user_id:t.user.id},{onConflict:"id"}).select(su).single()),Ae=await C(Ae)}catch(ne){Re=ne||new Error("avatar-frame-update-failed")}if(Re){const ne="Could not save profile photo framing. Please try again.";return p(!1),f(ne),{error:ne}}return i(Ae||null),p(!1),{error:"",profile:Ae||null}},[C,o?.avatar_path,o?.avatar_url,o?.profile_visibility,t]),pt=d.useCallback(async()=>{if(!ae){const te="Account sign-out is not configured yet.";return f(te),{error:te}}p(!0),f("");let F=null;try{({error:F}=await ae.auth.signOut({scope:"local"}))}catch{F=new Error("sign-out-failed")}if(p(!1),F){const te="Could not sign out. Try again in a moment.";return f(te),{error:te}}return r(null),i(null),l(!1),v.current="",h.current.clear(),b.current="",td(),s(!1),{error:""}},[]),$t=d.useCallback(async()=>{if(ae)try{await ae.auth.signOut({scope:"local"})}catch{}return r(null),i(null),l(!1),v.current="",h.current.clear(),b.current="",td(),s(!1),f(""),{error:""}},[]),pe=d.useCallback(async()=>{if(!ae)return{error:"Account sign-in is not configured yet."};if(typeof window>"u")return{error:""};const F=new URLSearchParams(window.location.search),te=new URLSearchParams(window.location.hash.replace(/^#/,"")),ie=String(F.get("type")||te.get("type")||"").trim().toLowerCase()==="recovery"||bh(),Ae=F.get("error_description")||F.get("error")||te.get("error_description")||te.get("error");let Re=ie;if(Ae)return{error:pI()};const ne=F.get("code");if(ne){let kt=null;try{S.current="",{error:kt}=await ae.auth.exchangeCodeForSession(ne)}catch{kt=new Error("callback-exchange-failed")}if(kt)return{error:"Could not complete sign-in. Try the link again."};await new Promise(Ee=>window.setTimeout(Ee,0)),Re=Re||S.current==="PASSWORD_RECOVERY"||bh()}else{let kt=null;try{({error:kt}=await ae.auth.getSession())}catch{kt=new Error("callback-session-failed")}if(kt)return{error:"Could not read your sign-in session."}}let ht=null;try{ht=(await ae.auth.getSession()).data?.session||null}catch{ht=null}return Re?ht?.user?.id?(cy(),s(!0),r(ht),{error:"",recovery:!0}):{error:"This reset link is no longer valid. Please request a new one.",recovery:!0}:{error:""}},[]),Tt=d.useMemo(()=>({authError:m,applyContentReportModerationAction:ye,checkReportAdminAccess:ke,checkUsernameAvailability:V,clearAuthError:()=>f(""),clearPasswordRecovery:()=>{td(),s(!1)},completePasswordReset:y,completeAuthCallback:pe,createPrivateBoardShareLink:Z,getOwnerPrivateBoardShareLink:D,revokePrivateBoardShareLink:K,fetchContentReports:We,fetchPrivateBoardByShareToken:ee,fetchPrivateBoardItemsByShareToken:J,fetchOwnerPublicBoardItems:De,fetchPublicBoardByUsernameAndId:B,fetchPublicBoardItemsByBoardId:re,fetchPublicBoardsByUsername:z,fetchPublicProfileByUsername:L,hydrateProfileRow:C,isConfigured:An.isConfigured,loading:u,missingEnv:An.missingEnv,profile:o,profileLoading:c,passwordRecoveryIsActive:a,removeProfileAvatar:Le,requestPasswordReset:E,session:t,clearLocalSession:$t,socialProviders:An.providers,signInWithApple:P,signInWithEmail:I,signInWithGoogle:_,signInWithPassword:k,signUpWithPassword:A,signOut:pt,submitContentReport:Fe,syncPublicBoardMetadata:fe,syncPublicBoardItemMetadata:Be,updateContentReportStatus:de,updateProfileAvatarFrame:et,updateUserDisplayName:ze,updateUserProfile:ge,uploadProfileAvatar:W,user:t?.user||null}),[m,ye,ke,V,y,pe,Z,D,K,We,ee,J,De,B,re,z,L,C,u,a,o,c,Le,E,t,$t,P,I,_,k,pt,A,Fe,fe,Be,de,et,ze,ge,W]);return n.jsx(jE.Provider,{value:Tt,children:e})}const LE=()=>{const e=d.useContext(jE);if(!e)throw new Error("useAuth must be used inside AuthProvider.");return e},TB="https://chromewebstore.google.com/detail/leibkbbemccemgjbpkmphhdc
1pjcpmekh",DB=[{copy:"Paste a link or use the Chrome extension. Saveboard captures available details; you can review and edit them before saving.",number:1,title:"Save from anywhere"},{copy:"Gifts, the flat, a trip, a someday list. Boards are visual, quick to skim and easy to rearrange.",number:2,title:"Sort into boards"},{copy:"Boards are saved to your account, so they are there on your laptop and your phone.",number:3,title:"On every device"},{copy:"Boards start private. Invite collaborators, share a link, or publish a board for anyone to discover.",number:4,title:"Share, or don’t"}],OB=6,MB=e=>{const t=Number.isFinite(Number(e))?Math.max(0,Math.trunc(Number(e))):0;return`${t} ${t===1?"item":"items"}`};function UB({BoardCover:e,board:t,index:r,onOpenProfile:a,onOpenPublicBoard:s}){return n.jsxs("li",{className:"sbBoardTile",children:[n.jsxs(vg,{className:"sbBoardLink",href:t.href,onNavigate:()=>s?.(t),children:[n.jsx("span",{className:"sbBoardCover",children:e?n.jsx(e,{coverItemIds:t.list?.coverItemIds,list:t.list,products:t.products}):null}),n.jsxs("span",{className:"sbBoardCaption",children:[n.jsx("span",{"aria-hidden":"true",className:"sbBoardIndex",children:Ko(r)}),n.jsx("span",{className:"sbBoardName",children:t.name})]})]}),n.jsxs("div",{className:"sbBoardMeta",children:[t.ownerUsername?n.jsxs(vg,{className:"sbBoardOwner",href:t.ownerHref,onNavigate:()=>a?.(t),children:["@",t.ownerUsername]}):n.jsx("span",{className:"sbBoardOwner"}),n.jsx("span",{className:"sbBoardCount",children:MB(t.productCount)})]})]})}function FB(){return n.jsx("ul",{"aria-hidden":"true",className:"sbBoardGrid isSkeleton",children:Array.from({length:OB},(e,t)=>n.jsxs("li",{className:"sbBoardTile isSkeleton",children:[n.jsx("span",{className:"sbBoardCover"}),n.jsxs("span",{className:"sbBoardCaption",children:[n.jsx("span",{className:"sbBoardIndex",children:Ko(t)}),n.jsx("span",{className:"sbBoardName sbSkeletonLine"})]})]},t))})}function $B({BoardCover:e,featuredBoards:t=[],featuredEnabled:r=!1,featuredLoading:a=!1,monochromeEnabled:s,onOpenAccount:o,onOpenApp:i,onOpenDiscover:c,onOpenGuide:l,onOpenProfile:u,onOpenPublicBoard:p,onToggleTheme:m,theme:f}){const h=Array.isArray(t)?t:[],b=h.length>0,v=!b&&r&&a;return n.jsxs("main",{className:`sbLanding${s?" monochromeMode":""}`,children:[n.jsx("a",{className:"sbSkipLink",href:"#landing-title",children:"Skip to content"}),n.jsx(P0,{theme:f,onToggleTheme:m,onOpenDiscover:c,onOpenGuide:l,onOpenAccount:o,onOpenApp:i}),n.jsxs("section",{"aria-labelledby":"landing-title",className:"sbHero",children:[n.jsxs("div",{className:"sbHeroCopy",children:[n.jsx("h1",{id:"landing-title",tabIndex:-1,children:"Good finds. All in one place."}),n.jsxs("p",{children:["Saveboard is a visual wishlist for the whole internet. Save the things you love from shops into boards, keep the price and the link with each one, and find everything again when you need it.",n.jsx("span",{"aria-hidden":"true",className:"sbCursor"})]}),n.jsxs("a",{className:"sbTextLink sbExtensionLink",href:TB,target:"_blank",rel:"noopener noreferrer",children:[n.jsxs("svg",{"aria-hidden":"true",className:"sbExtensionIcon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",children:[n.jsx("circle",{cx:"12",cy:"12",r:"9"}),n.jsx("circle",{cx:"12",cy:"12",r:"3.5"}),n.jsx("path",{d:"M12 8.5h8.3M15.03 13.75l-4.15 7.19M8.97 13.75 4.82 6.56"})]}),n.jsx("span",{children:"Get the Chrome extension"})," ",n.jsx(ph,{})]})]}),n.jsxs("div",{className:"sbHeroAside",children:[n.jsx("h2",{id:"featured-title",children:"Featured lists"}),n.jsx("p",{children:"Picked by Saveboard from boards people have made public. Open one to see how a board feels."}),n.jsxs(vg,{className:"sbTextLink",href:"/discover",onNavigate:c,children:["See all in Discover ",n.jsx(ph,{})]})]})]}),n.jsx("section",{"aria-busy":v||void 0,"aria-labelledby":"featured-title",className:"sbFeatured",children:b?n.jsx("ul",{className:"sbBoardGrid",children:h.map((S,C)=>n.jsx(UB,{BoardCover:e,board:S,index:C,onOpenProfile:u,onOpenPublicBoard:p},S.id||S.href||C))}):v?n.jsx(FB,{}):n.jsxs("p",{className:"sbFeaturedNote",children:[n.jsx("span",{children:"Featured lists are being picked by hand."}),n.jsxs(vg,{className:"sbTextLink",href:"/discover",onNavigate:c,children:["Explore public boards in Discover ",n.jsx(ph,{})]})]})}),n.jsxs("section",{"aria-labelledby":"how-title",className:"sbHow",children:[n.jsx("div",{className:"sbHowLabel",children:n.jsx("h2",{id:"how-title",children:"How it works"})}),n.jsxs("div",{className:"sbHowBody",children:[n.jsx("ol",{className:"sbHowList",children:DB.map(S=>n.jsxs("li",{className:"sbHowRow",children:[n.jsx("span",{"aria-hidden":"true",className:"sbHowIndex",children:_0(S.number)}),n.jsx("h3",{children:S.title}),n.jsx("p",{children:S.copy})]},S.number))}),n.jsxs("div",{className:"sbHowActions",children:[n.jsxs("button",{className:"sbButton",onClick:i,type:"button",children:["Start collecting ",n.jsx(ph,{})]}),n.jsx("span",{className:"sbHowNote",children:"Free to start. Your boards are saved to your account."})]})]})]}),n.jsx(E0,{onOpenDiscover:c,onOpenGuide:l,onOpenAccount:o,onOpenApp:i})]})}const zB=6,VB=8,ud=e=>(typeof e=="string"?e:e==null?"":String(e)).trim(),py=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?Math.trunc(t):0},BE=(e="")=>ud(e).replace(/^@+/,"").toLowerCase(),nC=(e="")=>`/u/${encodeURIComponent(BE(e))}`,HB=(e="",t="")=>`${nC(e)}/boards/${encodeURIComponent(ud(t))}`,WB=(e={},t="")=>{const r=BE(t),a=ud(e?.id||e?.board_id),s=(Array.isArray(e?.images)?e.images:Array.isArray(e?.cover_image_urls)?e.cover_image_urls:[]).map(o=>
1ud(o)).filter(Boolean).slice(0,4);return{description:ud(e?.description),href:a&&r?HB(r,a):"",id:a,images:s,likeCount:py(e?.likeCount??e?.like_count),name:ud(e?.name||e?.title)||"Untitled board",ownerHref:r?nC(r):"",productCount:py(e?.productCount??e?.item_count??e?.itemCount),publishedAt:ud(e?.publishedAt||e?.published_at),sortOrder:py(e?.sortOrder??e?.sort_order),username:r}},GB=({boards:e=[],status:t="idle"}={})=>Array.isArray(e)&&e.length?"ready":t==="loading"||t==="idle"?"loading":t==="error"?"error":"empty";async function bd(e,t={},{signal:r}={}){if(!ae)throw new Error("Discover is unavailable right now.");let a=ae.rpc(e,t);r&&(a=a.abortSignal(r));const{data:s,error:o}=await a;if(o)throw new Error(o.message||"Discover could not load.");return s}const hI=e=>WB(e,e.username);function qB(e={}){const t=(e.sections||[]).map(r=>({...r,boards:(r.boards||[]).map(hI)}));return{featured:t.find(r=>r.slug==="featured")?.boards||[],collections:t.filter(r=>r.slug!=="featured"&&r.boards.length),recent:(e.recent||[]).map(hI),profiles:(e.savers||[]).map(r=>({...r,href:nC(r.username),boardCount:Number(r.board_count),itemCount:Number(r.item_count)}))}}const TE=()=>window.dispatchEvent(new Event("saveboard:discover-changed")),wh=()=>({featured:[],collections:[],recent:[],profiles:[],status:"loading"});function SS({enabled:e,surfaceKey:t,prepare:r}){const[a,s]=d.useState(wh),[o,i]=d.useState(0),[c,l]=d.useState(8),u=d.useRef(null),p=d.useRef(0),m=d.useRef(r);m.current=r;const f=d.useCallback(async C=>{try{const I=await bd("get_discover_home_v1",{},{signal:C});c>8&&(I.recent=await bd("get_discover_recent_v1",{p_limit:c},{signal:C}));const A=qB(I);return await m.current?.(A),{...A,status:"ready"}}catch{return{...wh(),status:"error"}}},[c]),h=d.useCallback(async(C,I)=>{const A=new AbortController,k=setTimeout(()=>A.abort(),15e3);try{const E=await f(A.signal);I()&&(u.current={...E,surfaceKey:C},s(u.current))}finally{clearTimeout(k)}},[f]);d.useEffect(()=>{if(!e)return;let C=!0,I;const A=async()=>{const y=++p.current;I?.abort(),I=new AbortController;const N=I,_=setTimeout(()=>N.abort(),15e3);s({...wh(),surfaceKey:t});try{const P=await f(N.signal);C&&y===p.current&&s({...P,surfaceKey:t})}finally{clearTimeout(_)}},k=()=>{document.visibilityState==="visible"&&A()};u.current?.surfaceKey===t?(s(u.current),u.current=null):A(),window.addEventListener("focus",k),document.addEventListener("visibilitychange",k),window.addEventListener("saveboard:discover-changed",A);const E=setInterval(k,3e4);return()=>{C=!1,++p.current,clearInterval(E),I?.abort(),window.removeEventListener("focus",k),document.removeEventListener("visibilitychange",k),window.removeEventListener("saveboard:discover-changed",A)}},[e,t,o,f]);const b=d.useCallback(()=>i(C=>C+1),[]),v=d.useCallback(()=>l(C=>Math.min(C+8,24)),[]),S=a.surfaceKey===t?a:wh();return d.useMemo(()=>({...S,prepareNavigation:h,retry:b,canLoadMore:S.recent.length===c&&c<24,loadMore:v}),[a,t,h,b,c,v])}const wS=e=>e&&{p_revision:e.revision,p_sections:e.sections.map(t=>({id:t.id,enabled:t.enabled,boards:t.boards.map(r=>r.id)})),p_savers:e.savers.map(t=>t.id)},YB=(e,t)=>JSON.stringify(wS(e))===JSON.stringify(wS(t)),gI=(e,t,r)=>{const a=[...e];return[a[t],a[t+r]]=[a[t+r],a[t]],a};function bI({row:e,image:t,saver:r}){const[a,s]=d.useState(null),o=e.eligible===!1;return n.jsxs(n.Fragment,{children:[n.jsx("div",{className:`adminDiscoverThumb${r?" adminDiscoverAvatar":""}`,"aria-hidden":"true",children:!o&&t&&a!==t?n.jsx("img",{src:t,alt:"",loading:"lazy",onError:()=>s(t)}):n.jsx("span",{children:o?"—":(e.title||e.username||"SB").slice(0,2).toUpperCase()})}),n.jsxs("div",{className:"adminDiscoverIdentity",children:[n.jsx("strong",{children:o?"Unavailable selection":r?`@${e.username}`:e.title}),n.jsx("span",{className:"adminDiscoverByline",children:o?e.id:r?"Selected saver":`@${e.username}`}),n.jsx("div",{className:"adminDiscoverChips",children:o?n.jsx("span",{className:"adminDiscoverChip isUnavailable",children:"Hidden from Discover"}):n.jsxs(n.Fragment,{children:[n.jsx("span",{className:"adminDiscoverChip",children:"Public"}),n.jsx("span",{className:"adminDiscoverChip",children:r?"Listed boards":"Discover listed"})]})})]})]})}function KB({auth:e,renderPreview:t}){const[r,a]=d.useState(null),[s,o]=d.useState(null),[i,c]=d.use
1State(""),[l,u]=d.useState("featured"),[p,m]=d.useState([]),[f,h]=d.useState(!1),[b,v]=d.useState(""),[S,C]=d.useState(""),[I,A]=d.useState(""),[k,E]=d.useState(!1),y=d.useRef(null),N=d.useRef(null),_=d.useRef(0),P=d.useRef(0),V=!!(r&&!YB(r,s)),L=I==="load"||I==="save",z=SS({enabled:!!r,surfaceKey:"admin-editorial-media"}),B=SS({enabled:!!(r&&k),surfaceKey:"admin-preview"}),re=async()=>{const ye=++_.current;++P.current,A("load"),v(""),m([]),h(!1);try{const ge=await bd("admin_get_discover_v1");if(ye!==_.current)return;a(ge),o(ge)}catch{ye===_.current&&v("Discover administration is available only to authorized SaveBoard admins. If your access is unchanged, try loading again.")}finally{ye===_.current&&A("")}};d.useEffect(()=>(a(null),o(null),E(!1),e.loading||re(),()=>{++_.current,++P.current}),[e.loading,e.user?.id]),d.useLayoutEffect(()=>{if(!V&&I!=="save")return;const ye=window.location.href,ge=window.history.state,ze=Le=>{Le.preventDefault(),Le.returnValue=""},W=Le=>{window.location.href!==ye&&(window.confirm(I==="save"?"A save is still in progress. Leave this page?":"Discard your unsaved Discover changes?")||(Le.preventDefault(),window.history.pushState(ge,"",ye)))};return window.addEventListener("beforeunload",ze),window.addEventListener("saveboard:before-route-change",W),()=>{window.removeEventListener("beforeunload",ze),window.removeEventListener("saveboard:before-route-change",W)}},[V,I]);const Z=ye=>{++P.current,u(ye),m([]),h(!1),C(""),I==="search"&&A("")},D=r?.sections.find(ye=>ye.slug===l),K=l==="savers",ee=r?.sections.filter(ye=>ye.slug!=="featured")||[],J=K?r?.savers||[]:D?.boards||[],fe=ye=>{v(""),a(ge=>K?{...ge,savers:ye}:{...ge,sections:ge.sections.map(ze=>ze.slug===l?{...ze,boards:ye}:ze)})},De=async ye=>{ye.preventDefault();const ge=++P.current;A("search"),C(""),m([]),h(!1);try{const ze=await bd("admin_search_discover_v1",{p_query:i.trim().replace(/^@/,""),p_kind:K?"savers":"boards"});ge===P.current&&(m(ze),h(!0))}catch{ge===P.current&&C("Search could not load. Please try again.")}finally{ge===P.current&&A("")}},Be=async()=>{const ye=++_.current;++P.current,A("save"),v("");try{const ge=await bd("admin_save_discover_v1",wS(r));if(ye!==_.current)return;a(ge),o(ge),TE(),v("Discover configuration saved.")}catch{ye===_.current&&v("Save failed. Your edits are still here. Content may have become ineligible or another admin saved changes. Reload configuration to get the latest saved version.")}finally{ye===_.current&&A("")}},Fe=()=>{E(!0),B.retry(),requestAnimationFrame(()=>{y.current?.focus({preventScroll:!0}),y.current?.scrollIntoView({block:"center"})})},ke=()=>{(!V||window.confirm("Discard your unsaved Discover changes and reload the saved configuration?"))&&re()},We=new Map([...z.featured,...z.collections.flatMap(ye=>ye.boards),...z.recent].map(ye=>[ye.id,ye.images?.[0]])),de=ye=>ye.eligible===!1?null:K?z.profiles.find(ge=>ge.username===ye.username)?.images?.[0]:ye.cover_image_urls?.[0]||We.get(ye.id);return n.jsxs("main",{className:"adminDiscoverPage",children:[n.jsxs("header",{className:"adminDiscoverHeader",children:[n.jsxs("div",{children:[n.jsx("p",{className:"adminDiscoverEyebrow",children:"SaveBoard / Editorial"}),n.jsx("h1",{children:"Discover administration"}),n.jsx("p",{children:"Choose what to feature. Owners choose what to share."})]}),n.jsx("a",{className:"adminDiscoverTextLink",href:"/admin/reports",children:"Content reports ↗"})]}),n.jsx("div",{className:"adminDiscoverNotice",role:"status","aria-live":"polite",children:b}),r?n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"adminDiscoverSaveBar",children:[n.jsxs("div",{children:[n.jsx("span",{className:`adminDiscoverSaveState${V?" isDirty":""}`,children:I==="save"?"Saving changes…":V?"Unsaved changes":"All changes saved"}),n.jsx("small",{children:"Changes across all sections are saved together."})]}),n.jsxs("div",{className:"adminDiscoverActions",children:[n.jsx("button",{ref:N,disabled:L,onClick:Fe,children:"Preview Discover"}),n.jsx("button",{className:"adminDiscoverPrimary",disabled:!V||L,onClick:Be,children:I==="save"?"Saving…":"Save changes"})]})]}),n.jsxs("nav",{className:"adminDiscoverNav","aria-label":"Editorial areas",children:[n.jsxs("button",{"aria-pressed":l==="featured",disabled:L,onClick:()=>Z("featured"),children:["Featured boards ",n.jsx("span",{children:r.sections.find(ye=>ye.slug==="featured")?.boards.length||0})]}),n.jsxs("button",{"aria-pressed":!K&&l!=="featured",disabled:L,onClick:()=>Z(ee[0]?.slug||"home"),children:["Categories ",n.jsx("span",{children:ee.length})]}),n.jsxs("button",{"aria-pressed":K,disabled:L,onClick:()=>Z("savers"),children:["Featured savers ",n.jsx("span",{children:r.savers.length})]})]}),n.jsxs("div",{className:"adminDiscoverWorkspace",children:[n.jsxs("section",{className:"adminDiscoverPanel","aria-label":"Editorial selections",children:[n.jsxs("div",{className:"adminDiscoverPanelHeading",children:[n.jsxs("div",{children:[n.jsx("p",{className:"adminDiscoverEyebrow",children:K?"People":l==="featured"?"Picked by SaveBoard":"Curated category"}),n.jsx("h2",{children:K?"Featured savers":D?.title})]}),n.jsxs("span",{className:"adminDiscoverCount",children:[J.length," / 8"]})]}),!K&&l!=="featured"?n.jsxs("label",{className:"adminDiscoverCategory",children:["Editorial section",n.jsx("select",{disabled:L,value:l,onCh
1ange:ye=>Z(ye.target.value),children:ee.map(ye=>n.jsx("option",{value:ye.slug,children:ye.title},ye.id))})]}):null,n.jsxs("div",{className:"adminDiscoverSectionMeta",children:[D?n.jsxs("label",{children:[n.jsx("input",{type:"checkbox",disabled:L,checked:D.enabled,onChange:ye=>{v(""),a(ge=>({...ge,sections:ge.sections.map(ze=>ze.id===D.id?{...ze,enabled:ye.target.checked}:ze)}))}}),"Show section"]}):n.jsx("span",{children:"Profiles with eligible, opted-in boards only."}),n.jsx("span",{children:"Ordered as shown in Discover"})]}),D&&!D.enabled?n.jsx("p",{className:"adminDiscoverHint",children:"This section is hidden. Its selections are kept."}):null,J.length?n.jsx("ol",{className:"adminDiscoverSelections",children:J.map((ye,ge)=>n.jsxs("li",{children:[n.jsx("span",{className:"adminDiscoverPosition","aria-hidden":"true",children:Ko(ge)}),n.jsx(bI,{row:ye,image:de(ye),saver:K}),n.jsxs("div",{className:"adminDiscoverRowActions",children:[n.jsxs("div",{className:"adminDiscoverOrder",children:[n.jsx("button",{title:"Move up","aria-label":`Move selection ${ge+1} up`,disabled:L||ge===0,onClick:()=>fe(gI(J,ge,-1)),children:"↑"}),n.jsx("button",{title:"Move down","aria-label":`Move selection ${ge+1} down`,disabled:L||ge===J.length-1,onClick:()=>fe(gI(J,ge,1)),children:"↓"})]}),n.jsx("button",{className:"adminDiscoverRemove",disabled:L,onClick:()=>fe(J.filter(ze=>ze.id!==ye.id)),children:"Remove"})]})]},ye.id))}):n.jsxs("div",{className:"adminDiscoverEmpty",children:[n.jsxs("h3",{children:["No ",K?"savers":"boards"," selected yet"]}),n.jsxs("p",{children:["Search eligible ",K?"savers":"boards"," and add your first selection."]})]}),n.jsxs("footer",{className:"adminDiscoverPanelFooter",children:[n.jsx("span",{children:J.length===8?"Section full · remove a selection to add another.":`${8-J.length} spaces available`}),n.jsx("button",{disabled:L,onClick:ke,children:"Reload configuration"})]})]}),n.jsxs("aside",{className:"adminDiscoverPanel adminDiscoverPicker","aria-label":"Eligible content picker",children:[n.jsx("div",{className:"adminDiscoverPanelHeading",children:n.jsxs("div",{children:[n.jsx("p",{className:"adminDiscoverEyebrow",children:"Find a selection"}),n.jsxs("h2",{children:["Add ",K?"savers":"boards"]})]})}),n.jsx("p",{className:"adminDiscoverHint",children:K?"Search by handle. Only savers with eligible Discover-listed boards appear.":"Search board names or handles across all accounts. Only eligible public, Discover-listed boards appear."}),n.jsxs("form",{onSubmit:De,children:[n.jsxs("label",{htmlFor:"discover-editorial-search",children:["Search eligible ",K?"savers":"boards"]}),n.jsxs("div",{className:"adminDiscoverSearch",children:[n.jsx("input",{id:"discover-editorial-search",type:"search",placeholder:K?"@username":"Board name or @username",value:i,onChange:ye=>{++P.current,c(ye.target.value),m([]),h(!1),I==="search"&&A("")},minLength:2,maxLength:120,required:!0,disabled:L}),n.jsx("button",{disabled:!!I||i.trim().replace(/^@/,"").length<2,children:I==="search"?"Searching…":"Search"})]})]}),S?n.jsx("p",{role:"alert",className:"adminDiscoverHint",children:S}):null,n.jsx("p",{className:"adminDiscoverResultCount","aria-live":"polite",children:I==="search"?"Finding eligible content…":f?`${p.length} eligible ${p.length===1?"result":"results"}`:"Enter at least two characters to search."}),f&&!p.length?n.jsxs("div",{className:"adminDiscoverEmpty",children:[n.jsx("h3",{children:"No eligible matches"}),n.jsx("p",{children:"Try another name or handle. Public boards only appear here after their owner enables Discover listing."})]}):null,n.jsx("ul",{className:"adminDiscoverResults",children:p.map(ye=>{const ge=J.some(ze=>ze.id===ye.id);return n.jsxs("li",{children:[n.jsx(bI,{row:ye,image:de(ye),saver:K}),n.jsx("button",{disabled:L||ge||J.length>=8,onClick:()=>fe([...J,{...ye,eligible:!0}]),children:ge?"Added":"Add"})]},ye.id)})}),n.jsx("p",{className:"adminDiscoverConsentNote",children:"Editorial selection never publishes a board or enables an owner’s Discover preference."})]})]}),k?n.jsxs("section",{className:"adminDiscoverPreview","aria-label":"Saved Discover preview",children:[n.jsxs("div",{className:"adminDiscoverPanelHeading",children:[n.jsxs("div",{children:[n.jsx("h2",{ref:y,tabIndex:-1,
1children:"Live Discover preview"}),n.jsx("p",{children:"Current saved content. Unsaved edits are not included."})]}),n.jsx("button",{onClick:()=>{E(!1),N.current?.focus()},children:"Close preview"})]}),t(B)]}):null]}):n.jsxs("section",{className:"adminDiscoverEmpty",children:[n.jsx("h2",{children:I==="load"||e.loading?"Loading your editorial workspace…":"Editorial access required"}),n.jsx("p",{children:"This workspace is reserved for authorized SaveBoard admins."}),n.jsx("button",{disabled:!!I||e.loading,onClick:re,children:"Check access again"})]})]})}function XB({boardId:e,isPublic:t}){const[r,a]=d.useState(null),[s,o]=d.useState(!1),[i,c]=d.useState(""),l=d.useRef(0);if(d.useEffect(()=>{const p=++l.current;let m=!0;return a(null),c(""),o(!1),t&&bd("get_board_discovery_preference",{p_local_board_id:e}).then(f=>{m&&a(f)}).catch(()=>{m&&c("Discover preference could not load. Reopen Share to try again.")}),()=>{m=!1,l.current===p&&++l.current}},[e,t]),!t)return null;const u=async p=>{const m=l.current;o(!0),c("");try{const f=await bd("set_board_discovery_preference",{p_local_board_id:e,p_listed:p});m===l.current&&a(f),TE()}catch{m===l.current&&c("Could not change Discover listing. Check that your board and profile are public, then try again.")}finally{m===l.current&&o(!1)}};return n.jsxs("section",{className:"boardDiscoveryPreference","aria-label":"Discover visibility",children:[n.jsxs("label",{children:[n.jsx("input",{type:"checkbox",checked:r?.listed===!0,disabled:!r?.available||s,onChange:p=>u(p.target.checked)}),n.jsx("span",{children:"Allow this board to appear in Discover"})]}),n.jsx("p",{children:"Your public board, handle and cover images may appear even to signed-out visitors. Making your board or profile private turns this off."}),r&&!r.available?n.jsx("p",{children:"Publish this board and make your profile public to enable Discover."}):null,i?n.jsx("p",{role:"alert",children:i}):null]})}const JB="Record changed or is no longer available.",wc=e=>String(e??"").trim(),CS=e=>{const t=Date.parse(e||"");return Number.isFinite(t)?new Date(t).toISOString():""},Br=e=>{const t=Number(e);return Number.isSafeInteger(t)&&t>0?t:null},QB=(e={})=>({cloudUpdatedAt:CS(e.updated_at),syncRevision:Br(e.revision),updatedAt:CS(e.updated_at)}),yg=e=>Array.isArray(e)?e.map(yg):e&&typeof e=="object"?Object.fromEntries(Object.keys(e).sort().map(t=>[t,yg(e[t])])):e,DE=(e,t)=>{if(Object.is(e,t))return!0;if(e&&typeof e=="object"||t&&typeof t=="object")try{return JSON.stringify(yg(e))===JSON.stringify(yg(t))}catch{return!1}return!1},aC=(e={},t={})=>Object.entries(t).every(([r,a])=>DE(e[r],a)),OE=({after:e={},allowedFields:t=[],before:r={}}={})=>t.reduce((a,s)=>(DE(r?.[s],e?.[s])||(a[s]=e?.[s]??null),a),{}),ZB=({allowedFields:e=[],patch:t={}}={})=>{const r=new Set(e);return Object.entries(t&&typeof t=="object"&&!Array.isArray(t)?t:{}).reduce((a,[s,o])=>(r.has(s)&&(a[s]=o??null),a),{})};class xr extends Error{constructor(t,{cause:r,code:a="expected-revision-write-failed"}={}){super(t,r?{cause:r}:void 0),this.name="ExpectedRevisionWriteError",this.code=a}}const ME=({client:e,id:t,table:r,userId:a})=>{if(!e?.from||!wc(r)||!wc(a)||!wc(t))throw new xr("Cloud write is not configured.",{code:"invalid-write-context"})},eT=({data:e,error:t,operation:r})=>{if(t)throw new xr(`${r} did not finish.`,{cause:t});if(!Array.isArray(e)||e.length!==1)throw new xr(`${r} did not return one server record.`,{code:"unexpected-write-acknowledgement"});return e[0]},xS=({id:e,operation:t,row:r,userId:a})=>{if(wc(r?.id)!==wc(e)||wc(r?.user_id)!==wc(a))throw new xr(`${t} returned a different record.`,{code:"unexpected-write-identity"});return r},IS=({operation:e,row:t})=>{if(!Br(t?.revision)||!CS(t?.updated_at))throw new xr(`${e} did not return server version metadata.`,{code:"missing-server-version-acknowledgement"});return t},vI=async({client:e,id:t,selectColumns:r,table:a,userId:s})=>{const o=await e.from(a).select(r).eq("user_id",s).eq("id",t).limit(1);if(o.error)throw new xr("Latest cloud record could not be read.",{cause:o.error,code:"latest-record-read-failed"});if(!Array.isArray(o.data))throw new xr("Latest cloud record returned an invali
1d response.",{code:"invalid-latest-record-response"});return o.data[0]||null},yI=({attemptedPatch:e,latest:t,reason:r})=>({attemptedPatch:e,conflict:!0,latest:t,message:JB,ok:!1,reason:r}),UE=async({client:e,row:t,selectColumns:r,table:a,userId:s}={})=>{const o=wc(t?.id);ME({client:e,id:o,table:a,userId:s});const i={...t&&typeof t=="object"&&!Array.isArray(t)?t:{}};if(delete i.revision,delete i.updated_at,delete i.deleted_at,delete i.deleted_by,delete i.deletion_id,delete i.deletion_reason,delete i.purge_after,delete i.restored_at,delete i.restored_by,delete i.created_by,delete i.updated_by,i.user_id!==s)throw new xr("Cloud insert owner did not match the signed-in user.",{code:"invalid-insert-owner"});const c=await e.from(a).insert(i).select(r),l=IS({operation:"Cloud insert",row:xS({id:o,operation:"Cloud insert",row:eT({data:c.data,error:c.error,operation:"Cloud insert"}),userId:s})});return{insertedRow:i,ok:!0,row:l}},FE=async({acceptAlreadyApplied:e=!1,allowedFields:t=[],client:r,expectedRevision:a,id:s,patch:o,selectColumns:i,table:c,userId:l}={})=>{const u=wc(s);ME({client:r,id:u,table:c,userId:l});const p=ZB({allowedFields:t,patch:o}),m=Br(a);if(!m){const b=await vI({client:r,id:u,selectColumns:i,table:c,userId:l});return yI({attemptedPatch:p,latest:b,reason:"missing-expected-revision"})}if(!Object.keys(p).length)return{ok:!0,reason:"no-change",row:null,skipped:!0};const f=await r.from(c).update(p).eq("user_id",l).eq("id",u).eq("revision",m).is("deleted_at",null).select(i);if(f.error)throw new xr("Cloud update did not finish.",{cause:f.error});if(!Array.isArray(f.data))throw new xr("Cloud update returned an invalid response.",{code:"invalid-update-response"});if(f.data.length===1){const b=IS({operation:"Cloud update",row:xS({id:u,operation:"Cloud update",row:f.data[0],userId:l})});return{attemptedPatch:p,ok:!0,row:b,skipped:!1}}if(f.data.length>1)throw new xr("Cloud update returned more than one record.",{code:"unexpected-update-row-count"});const h=await vI({client:r,id:u,selectColumns:i,table:c,userId:l});if(e&&h&&!h.deleted_at&&Br(h.revision)>m&&aC(h,p)){const b=IS({operation:"Cloud retry",row:xS({id:u,operation:"Cloud retry",row:h,userId:l})});return{attemptedPatch:p,ok:!0,recoveredExisting:!0,row:b,skipped:!1}}return yI({attemptedPatch:p,latest:h,reason:"changed-or-unavailable"})},SI=(e={})=>e.syncConflict==="changed-or-unavailable"&&!e.cloudDeletedAt&&!e.syncSuppressed&&Br(e.syncRevision)>Br(e.syncPendingWriteRevision)&&!!Br(e.syncPendingWriteRevision)&&Object.keys(e.syncConflictPatch||{}).length>0,tT={title:"Title",note:"Private notes",list_id:"Board",brand:"Brand",url:"Product link",image:"Image",price:"Price",currency:"Currency",description:"Description",image_background_color:"Image background"},rT=(e={},t=[])=>Object.entries(e).map(([r,a])=>({label:tT[r]||r.replaceAll("_"," "),value:r==="list_id"?t.find(s=>s.id===a)?.name||"Unavailable board":a===null||a===""?"(empty)":typeof a=="object"?JSON.stringify(a):String(a)})),wI=Object.freeze(["editor","viewer"]),lo=(e="")=>String(e||"").trim().toLowerCase()==="viewer"?"viewer":"editor",Sb=e=>lo(e)==="editor",yi=e=>Sb(e)?{label:"Editor",summary:"Can add, edit and reorder items"}:{label:"Viewer",summary:"Can only view items"},sC=(e={})=>!!(String(e?.boardId||"").trim()&&String(e?.ownerId||"").trim()),$E="This board is no longer shared with you.",my=(e="")=>String(e||"")===$E,Qr=e=>String(e??"").trim(),nT="shared:",zE=(e={})=>`${nT}${Qr(e.ownerId)}:${Qr(e.boardId)}`,aT=(e={})=>{const t=Qr(e?.owner?.username).replace(/^@+/,"");return t?`@${t}`:Qr(e?.owner?.displayName)||"another Saveboard user"},CI=(e={})=>`Shared by ${aT(e)} · ${Sb(e?.role)?"Editor":"Viewer"}`,jl=Object.freeze({canAddItems:!0,canDeleteItems:!0,canEditItems:!0,canManageBoard:!0,canMoveItemsBetweenBoards:!0,canReorderItems:!0,canChangeItemStatus:!0,canUseTrash:!0}),sT=e=>{const t=Sb(lo(e));return Object.freeze({canAddItems:t,canDeleteItems:t,canEditItems:t,canManageBoard:!1,canMoveItemsBetweenBoards:!1,canReorderItems:t,canChangeItemStatus:!1,canUseTrash:!1})},oT=({isShared:e=!1,role:t=""}={})=>e?sT(t):jl,iT=(e=null)=>!e?.boardId||!e?.ownerId?null:{collaboratorRole:lo(e.role),createdAt:e.sharedAt||"",description:e.boardDescription||"",id:zE(e),isPublic:!1,isSharedBoard:!0,name:Qr(e.boardTitle)||"Shared board",ownerId:e.ownerId,ownerUsername:Qr(e?.owner?.username).replace(/^@+/,""),sharedBoardId:e.boardId,sortOrder:0,updatedAt:e.updatedAt||"",userId:e.ownerId},cT=(e=null,t=null)=>
1{if(!e?.id||!t?.boardId)return null;const r=zE(t),a=Qr(t.boardTitle)||"Shared board",s=Qr(e.price);return{brand:Qr(e.brand),category:a,colour:"",createdAt:e.createdAt||"",currency:"",id:e.id,image:Qr(e.imageUrl),imageUrl:Qr(e.imageUrl),isSharedBoardItem:!0,listId:r,listName:a,price:s,privateNotes:"",publicNotes:"",sharedBoardId:t.boardId,sharedBoardOwnerId:t.ownerId,sharedItemRevision:e.revision||null,size:"",sortOrder:Number.isFinite(Number(e.sortOrder))?Number(e.sortOrder):0,source:Qr(e.source),status:Qr(e.status)||"active",title:Qr(e.title),updatedAt:e.updatedAt||"",url:Qr(e.url),userId:t.ownerId,variant:""}},lT=(e=[],t=null)=>(Array.isArray(e)?e:[]).map(r=>cT(r,t)).filter(Boolean),xI=(e={})=>({brand:Qr(e.brand),imageUrl:Qr(e.imageUrl||e.image),price:Qr(e.price),source:Qr(e.source),title:Qr(e.title),url:Qr(e.url)}),dT=Object.freeze(["privateNotes","publicNotes","size","colour","variant"]),uT=(e={})=>dT.filter(t=>Qr(e[t])),cd=(e={})=>e?.isSharedBoardItem===!0&&!!(Qr(e?.sharedBoardOwnerId)&&Qr(e?.sharedBoardId)),pT=(e=[],t="",r="")=>{const a=[...Array.isArray(e)?e:[]].sort((c,l)=>(Number(c?.sortOrder)||0)-(Number(l?.sortOrder)||0)),s=a.findIndex(c=>Qr(c?.id)===Qr(t)),o=a.findIndex(c=>Qr(c?.id)===Qr(r));if(s<0||o<0||s===o)return null;const i=[...a];return i.splice(o,0,...i.splice(s,1)),i.map((c,l)=>({...c,sortOrder:l}))},Cu="create-rejected",tg=Cu,Hn=e=>String(e??"").trim(),VE=(e={},{userId:t=""}={})=>{const r=Hn(t);return!!(r&&Hn(e?.id)&&Hn(e?.userId)===r&&e?.syncPendingCloudWrite===!0&&!Br(e?.syncRevision)&&!Br(e?.syncPendingWriteRevision)&&!Hn(e?.syncConflict)&&!e?.cloudDeletedAt&&!e?.syncSuppressed)},oC=(e={},t={})=>VE(e,t),Sg=(e={},t={})=>VE(e,t)&&!e?.isSharedBoard&&!Hn(e?.collaboratorRole)&&!Hn(e?.ownerUsername)&&e?.isArchived!==!0,mT=(e=[],{inFlightIds:t=new Set,userId:r=""}={})=>{const a=Hn(r);return a?(Array.isArray(e)?e:[]).filter(s=>Sg(s,{userId:a})).filter(s=>!t.has(Hn(s.id))):[]},fT=(e={},t="")=>!!e?.id&&Hn(e.userId)===t&&!e.cloudDeletedAt&&!e.syncSuppressed&&!e.isArchived,hT=(e=[],t=[],{inFlightIds:r=new Set,userId:a=""}={})=>{const s=Hn(a);if(!s)return[];const o=new Map((Array.isArray(t)?t:[]).map(i=>[Hn(i?.id),i]));return(Array.isArray(e)?e:[]).filter(i=>oC(i,{userId:s})).filter(i=>!r.has(Hn(i.id))).map(i=>({list:o.get(Hn(i.listId))||null,product:i})).filter(({list:i})=>fT(i,s))},gT=new Set(["board-create-retry-conflict","product-create-content-mismatch","unexpected-product-create-identity","unexpected-product-create-parent","inactive-product-create-acknowledgement","invalid-product-create-revision","unexpected-idempotent-product-create-row-count","invalid-insert-owner","unexpected-write-identity"]),bT=new Set(["22P02","23502","23503","23514","42501","42703","PGRST102","PGRST204"]),vT=e=>{const t=Number(e);return Number.isInteger(t)?t:null},HE=e=>{const t=new Set;let r=e;for(;r&&typeof r=="object"&&!t.has(r);){t.add(r);const a=Hn(r.code);if(gT.has(a)||bT.has(a))return"rejected";const s=vT(r.status??r.statusCode);if(s!==null&&s>=400&&s<500&&s!==408&&s!==425&&s!==429)return"rejected";r=r.cause}return"transient"},yT=e=>HE(e),WE=(e,t)=>Hn(e?.syncConflict)===Cu?{label:"Couldn't save to account",tone:"rejected"}:t?{label:"Not in your account yet",tone:"pending"}:null,II=(e={},t=0)=>{const r=Number(t);if(!Number.isFinite(r)||r<=0)return!1;const a=Date.parse(Hn(e?.createdAt)||Hn(e?.updatedAt)||"");return Number.isFinite(a)&&a<r},ST=(e={},{userId:t=""}={})=>WE(e,oC(e,{userId:Hn(t)||Hn(e?.userId)})),wT=(e={},{userId:t=""}={})=>WE(e,Sg(e,{userId:Hn(t)||Hn(e?.userId)})),CT="/assets/google-g-logo-C04TftDU.svg",Da=Object.freeze({landingViewed:"landing_viewed",discoverViewed:"discover_viewed",signupStarted:"signup_started",accountAuthenticated:"account_authenticated",firstBoardCreated:"first_board_created",firstItemSaved:"first_item_saved",boardPublished:"board_published",collaborationInviteAccepted:"collaboration_invite_accepted"});new Set(Object.values(Da));Da.firstBoardCreated,Da.firstItemSaved;Da.landingViewed,Da.discoverViewed,Da.signupStarted;const Si=()=>({recorded:!1,reason:"disabled-for-launch"}
1),wd="GBP",wb=[{code:"GBP",symbol:"£",label:"British Pound",display:"£ GBP"},{code:"USD",symbol:"$",label:"US Dollar",display:"$ USD"},{code:"EUR",symbol:"€",label:"Euro",display:"€ EUR"},{code:"NZD",symbol:"NZ$",label:"New Zealand Dollar",display:"NZ$ NZD"},{code:"AUD",symbol:"A$",label:"Australian Dollar",display:"A$ AUD"},{code:"CAD",symbol:"C$",label:"Canadian Dollar",display:"C$ CAD"},{code:"JPY",symbol:"¥",label:"Japanese Yen",display:"¥ JPY"},{code:"CHF",symbol:"CHF",label:"Swiss Franc",display:"CHF CHF"},{code:"CNY",symbol:"¥",label:"Chinese Yuan",display:"¥ CNY"},{code:"HKD",symbol:"HK$",label:"Hong Kong Dollar",display:"HK$ HKD"},{code:"SGD",symbol:"S$",label:"Singapore Dollar",display:"S$ SGD"},{code:"AED",symbol:"د.إ",label:"UAE Dirham",display:"د.إ AED"},{code:"SAR",symbol:"ر.س",label:"Saudi Riyal",display:"ر.س SAR"},{code:"INR",symbol:"₹",label:"Indian Rupee",display:"₹ INR"},{code:"KRW",symbol:"₩",label:"South Korean Won",display:"₩ KRW"},{code:"ZAR",symbol:"R",label:"South African Rand",display:"R ZAR"},{code:"SEK",symbol:"kr",label:"Swedish Krona",display:"kr SEK"},{code:"NOK",symbol:"kr",label:"Norwegian Krone",display:"kr NOK"},{code:"DKK",symbol:"kr",label:"Danish Krone",display:"kr DKK"},{code:"PLN",symbol:"zł",label:"Polish Zloty",display:"zł PLN"},{code:"TRY",symbol:"₺",label:"Turkish Lira",display:"₺ TRY"},{code:"BRL",symbol:"R$",label:"Brazilian Real",display:"R$ BRL"},{code:"MXN",symbol:"MX$",label:"Mexican Peso",display:"MX$ MXN"}],AS=new Map(wb.map(e=>[e.code,e])),AI=new Map([["£","GBP"],["$","USD"],["US$","USD"],["€","EUR"],["NZ$","NZD"],["A$","AUD"],["AU$","AUD"],["C$","CAD"],["CA$","CAD"],["¥","JPY"],["¥","JPY"],["CHF","CHF"],["HK$","HKD"],["S$","SGD"],["د.إ","AED"],["ر.س","SAR"],["₹","INR"],["₩","KRW"],["R","ZAR"],["KR","SEK"],["ZŁ","PLN"],["₺","TRY"],["R$","BRL"],["MX$","MXN"]]),xT=(e="")=>String(e||"").trim(),Nd=(e,t=wd)=>{const r=xT(e);if(!r)return t;const a=r.toUpperCase();return AS.has(a)?a:AI.get(r)||AI.get(a)||t},GE=(e,t=wd)=>{const r=Nd(e,t);return AS.get(r)||AS.get(wd)},Hm=(e,t=wd)=>GE(e,t).symbol,Cb=(e="")=>{const t=String(e||"");return t?/(?:\bNZD\b|NZ\$)/i.test(t)?"NZD":/(?:\bAUD\b|A\$|AU\$)/i.test(t)?"AUD":/(?:\bCAD\b|C\$|CA\$)/i.test(t)?"CAD":/(?:\bHKD\b|HK\$)/i.test(t)?"HKD":/(?:\bSGD\b|S\$)/i.test(t)?"SGD":/(?:\bBRL\b|R\$)/i.test(t)?"BRL":/(?:\bMXN\b|MX\$)/i.test(t)?"MXN":/(?:\bUSD\b|US\$|\$)/i.test(t)?"USD":/(?:\bGBP\b|£)/i.test(t)?"GBP":/(?:\bEUR\b|€)/i.test(t)?"EUR":/(?:\bCNY\b|CN¥|RMB|人民币)/i.test(t)?"CNY":/(?:\bJPY\b|¥|¥)/i.test(t)?"JPY":/\bCHF\b/i.test(t)?"CHF":/(?:\bAED\b|د\.إ)/i.test(t)?"AED":/(?:\bSAR\b|ر\.س)/i.test(t)?"SAR":/(?:\bINR\b|₹)/i.test(t)?"INR":/(?:\bKRW\b|₩)/i.test(t)?"KRW":/\bZAR\b/i.test(t)?"ZAR":/\bSEK\b/i.test(t)?"SEK":/\bNOK\b/i.test(t)?"NOK":/\bDKK\b/i.test(t)?"DKK":/(?:\bPLN\b|zł)/i.test(t)?"PLN":/(?:\bTRY\b|₺)/i.test(t)?"TRY":"":""},IT=new Set(["created","manual-edit","manual-check","scheduled-check","url-import","extension-save","unknown"]),AT=["GBP","USD","EUR","NZD","AUD","CAD","JPY","CHF","CNY","HKD","SGD","AED","SAR","INR","KRW","ZAR","SEK","NOK","DKK","PLN","TRY","BRL","MXN","NZ$","A$","AU$","C$","CA$","HK$","S$","R$","MX$","US$","$","£","€","¥","¥","₹","₩","₺","د.إ","ر.س"],On=(e="")=>String(e??"").trim().replace(/\s+/g," "),qE=e=>On(e).replace(/,/g,"").match(/\d+(?:\.\d+)?/g)||[],PT=e=>AT.reduce((t,r)=>t.replaceAll(r.toUpperCase(),""),e.toUpperCase().replace(/\s+/g,"")),ts=e=>{const t=On(e);return t?!/^[-–—]+$/.test(PT(t)):!1},YE=e=>{const t=Number(e);return Number.isFinite(t)?t:null},_T=(e,t=new Date().toISOString())=>{const r=new Date(e||t);return Number.isFinite(r.getTime())?r.toISOString():t},ET=(e,t="")=>Cb(e)||Nd(t,""),Us=(e={})=>{const t=On(e.price);if(!ts(t))return{approximate:!1,price:t};const r=qE(t),a=YE(r[0]),s=ET(t,e.currency),o=r.length>1&&/(?:-|–|—|to)/i.test(t),i=/\bfrom\b|\+|approx|estimated|starting/i.test(t)||o;return{amount:a??void 0,approximate:i,currency:s||void 0,price:t}},xb=(e={})=>{const t=On(e.targetPrice);if(!ts(t))return{};const r=Us({price:t,currency:e.targetCurrency||e.currency});
1return{targetPrice:t,...r.currency?{targetCurrency:r.currency}:{},...Number.isFinite(r.amount)?{targetAmount:r.amount}:{}}},iC=(e={},{id:t="",source:r="unknown",recordedAt:a=""}={})=>{const s=On(e.price);if(!ts(s))return null;const o=Us({price:s,currency:e.currency});return{id:t,price:s,...o.currency?{currency:o.currency}:{},...Number.isFinite(o.amount)?{amount:o.amount}:{},...o.approximate?{approximate:!0}:{},source:IT.has(r)?r:"unknown",recordedAt:_T(a)}},kT=(e={},t=0)=>{const r=iC({price:e.price,currency:e.currency},{id:String(e.id||`price-history-${t+1}`),source:e.source,recordedAt:e.recordedAt||e.recorded_at||e.capturedAt||e.createdAt});if(!r)return null;const a=YE(e.amount);return{...r,...a!==null?{amount:a}:{},...e.approximate===!0||e.isApproximate===!0?{approximate:!0}:{}}},NT=(e=[])=>[...e].sort((t,r)=>{const a=Date.parse(t.recordedAt),s=Date.parse(r.recordedAt);return Number.isFinite(a)&&Number.isFinite(s)&&a!==s?a-s:String(t.id).localeCompare(String(r.id),void 0,{sensitivity:"base"})}),Rl=(e=[])=>NT((Array.isArray(e)?e:[]).map((t,r)=>kT(t,r)).filter(Boolean)),fy=(e={})=>{const t=On(e.price);if(!ts(t))return"";const r=Us({price:t,currency:e.currency});return Number.isFinite(r.amount)&&r.currency?[r.currency,r.amount.toFixed(4),r.approximate?"approx":"exact"].join("|"):[r.currency||"",t.toLowerCase()].join("|")},wg=(e={},t={})=>!!(fy(e)&&fy(e)===fy(t)),PI=(e={},{createId:t,source:r="created",recordedAt:a=""}={})=>{const s=Rl(e.priceHistory);if(s.length||!ts(e.price))return{...e,priceHistory:s};const o=iC(e,{id:t?.()||"",source:r,recordedAt:a});return{...e,priceHistory:o?[o]:s}},_I=(e={},t={},{createId:r,recordedAt:a="",source:s="manual-edit"}={})=>{const o=Rl(t.priceHistory||e.priceHistory);if(!ts(t.price)||wg(e,t))return{...t,priceHistory:o};const i=o[o.length-1]||null;if(i&&wg(i,t))return{...t,priceHistory:o};const c=iC(t,{id:r?.()||"",source:s,recordedAt:a});return{...t,priceHistory:c?[...o,c]:o}},jT=(e={})=>{const t=Rl(e.priceHistory),r=t[0]||null,a=t[t.length-1]||null,s=On(e.price),o=Us({price:s,currency:e.currency}),i=r?Us(r):null,l=new Set([i?.currency,o?.currency,...t.map(p=>p.currency)].filter(Boolean)).size>1,u=t.length>1&&i&&o&&i.currency&&i.currency===o.currency&&Number.isFinite(i.amount)&&Number.isFinite(o.amount);return{amountChange:u?o.amount-i.amount:null,canCompareAmount:u,currentParsedPrice:o,currentPrice:s,firstEntry:r,firstParsedPrice:i,hasMixedCurrencies:l,latestEntry:a,priceHistory:t}},KE=(e={})=>{const t=xb(e),r=t.targetPrice||"";if(!r)return{canCompareAmount:!1,currentPrice:On(e.price),hasMixedCurrencies:!1,hasTargetPrice:!1,targetPrice:""};const a=On(e.price),s=Us({price:a,currency:e.currency}),o=Us({price:r,currency:t.targetCurrency||e.targetCurrency||e.currency}),c=new Set([s.currency,o.currency].filter(Boolean)).size>1,l=!c&&s.currency&&o.currency&&Number.isFinite(s.amount)&&Number.isFinite(o.amount),u=l?s.amount-o.amount:null;return{amountAboveTarget:u,canCompareAmount:l,currentParsedPrice:s,currentPrice:a,hasMixedCurrencies:c,hasTargetPrice:!0,isApproximate:!!(s.approximate||o.approximate),targetAmount:t.targetAmount,targetCurrency:t.targetCurrency,targetParsedPrice:o,targetPrice:r,targetReached:l?u<=0:!1}},RT=new Set(["target-hit","price-drop"]),LT=new Set(["pending","seen","dismissed","sent","failed"]),BT=new Set(["manual-check","scheduled-check"]),Cg=new Set(["pending","seen","sent"]),TT=.75,jm=(e="")=>{const t=String(e||"").trim();if(!t)return"";const r=Date.parse(t);return Number.isFinite(r)?new Date(r).toISOString():""},DT=e=>{const t=Number(e);return Number.isFinite(t)?t:null},OT=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?Math.floor(t):0},EI=e=>e===!0||String(e??"").trim().toLowerCase()==="true"||String(e??"").trim()==="1",XE=(e="")=>{const t=String(e||"").trim();return RT.has(t)?t:""},MT=(e="pending")=>{const t=String(e||"").trim();return LT.has(t)?t:"pending"},UT=(e="manual-check")=>{const t=String(e||"").trim();return BT.has(t)?t:"manual-check"},FT=(e={},t="")=>["price-alert",e.productId||"product",e.type||"event",On(e.currentPrice).toLowerCase().replace(/[^a-z0-9]+/g,"-")||"price",t.replace(/[^a-z0-9]+/gi,"-")||"now"].filter(
1Boolean).join("-"),Ib=(e={},{hasTargetPrice:t=!1}={})=>{if(!e||typeof e!="object")return null;const r=EI(e.alertOnTargetPrice)&&t,a=EI(e.alertOnAnyDrop),s=r||a,o=On(e.lastNotifiedPrice),i=jm(e.lastNotifiedAt);return!s&&!o&&!i?null:{enabled:s,...r?{alertOnTargetPrice:!0}:{},...a?{alertOnAnyDrop:!0}:{},...o?{lastNotifiedPrice:o}:{},...i?{lastNotifiedAt:i}:{}}},$T=(e={})=>{const t=KE(e);return Ib(e.priceAlert,{hasTargetPrice:t.hasTargetPrice})},JE=(e={},t=0)=>{if(!e||typeof e!="object")return null;const r=XE(e.type),a=String(e.userId||e.user_id||"").trim(),s=String(e.productId||e.product_id||"").trim(),o=On(e.currentPrice||e.current_price||e.price);if(!r||!s||!ts(o))return null;const i=On(e.previousPrice||e.previous_price),c=On(e.targetPrice||e.target_price),l=Us({price:o,currency:e.currency}),u=DT(e.amount),p=jm(e.createdAt||e.created_at)||new Date(0).toISOString(),m=jm(e.sentAt||e.sent_at),f=jm(e.lastAttemptAt||e.last_attempt_at),h=OT(e.attemptCount||e.attempt_count),b=On(e.lastErrorReason||e.last_error_reason).toLowerCase();return{id:String(e.id||`price-alert-event-${t+1}`),...a?{userId:a}:{},productId:s,type:r,...i?{previousPrice:i}:{},currentPrice:o,...l.currency?{currency:l.currency}:{},...u!==null?{amount:u}:Number.isFinite(l.amount)?{amount:l.amount}:{},...c?{targetPrice:c}:{},createdAt:p,status:MT(e.status),source:UT(e.source),...m?{sentAt:m}:{},...f?{lastAttemptAt:f}:{},...h>0?{attemptCount:h}:{},...b?{lastErrorReason:b}:{}}},zT=(e=[])=>[...e].sort((t,r)=>{const a=Date.parse(t.createdAt),s=Date.parse(r.createdAt);return Number.isFinite(a)&&Number.isFinite(s)&&a!==s?a-s:String(t.id).localeCompare(String(r.id),void 0,{sensitivity:"base"})}),kI=(e="",t="")=>{const r=Us({price:e,currency:t});return r.currency&&Number.isFinite(r.amount)?[r.currency,r.amount.toFixed(4),r.approximate?"approx":"exact"].join(":"):On(e).toLowerCase()},Wm=(e={})=>[String(e.userId||e.user_id||"").trim(),String(e.productId||"").trim(),XE(e.type),kI(e.currentPrice,e.currency),kI(e.targetPrice,e.currency)].join("|"),Vo=(e=[])=>{const t=new Set,r=new Set;return zT((Array.isArray(e)?e:[]).map((a,s)=>JE(a,s)).filter(Boolean)).filter(a=>{if(t.has(a.id))return!1;if(t.add(a.id),!Cg.has(a.status))return!0;const s=Wm(a);return r.has(s)?!1:(r.add(s),!0)})},VT=(e=[])=>{const t=Vo(e),r=t.some(s=>s.type==="target-hit"),a=t.some(s=>s.type==="price-drop");return r&&a?"Target price reached. Price dropped":r?"Target price reached":a?"Price dropped":""},HT=(e={},t={})=>{const r=Wm(t);return Vo(e.priceAlertEvents).some(a=>Cg.has(a.status)&&Wm(a)===r)},hy=(e={},t="")=>{const r=Us({price:e.price||e.currentPrice,currency:e.currency||t});return!ts(r.price)||!r.currency||!Number.isFinite(r.amount)||r.approximate?null:r},NI=(e={},{createId:t,createdAt:r=new Date().toISOString(),currentPrice:a,previousPrice:s,source:o="manual-c
1heck",targetPrice:i,type:c}={})=>{const l=jm(r)||new Date().toISOString(),u=JE({id:t?.()||FT({currentPrice:a.price,productId:e.id,type:c},l),productId:e.id,userId:e.userId||e.user_id,type:c,previousPrice:s?.price,currentPrice:a.price,currency:a.currency,amount:a.amount,targetPrice:i?.price,createdAt:l,status:"pending",source:o});return!u||HT(e,u)?null:u},WT=(e={},t={},r={},{checkedAt:a=new Date().toISOString(),confidence:s=1,createId:o,source:i="manual-check"}={})=>{const c=Number(s);if(Number.isFinite(c)&&c<TT)return[];const l=xb(e),u=Ib(e.priceAlert,{hasTargetPrice:!!l.targetPrice});if(!u?.enabled||!e.id)return[];const p=hy(r,e.currency);if(!p)return[];const m=hy(t,e.currency);if(m&&m.currency===p.currency&&m.amount===p.amount)return[];const f=[],h=l.targetPrice?hy({price:l.targetPrice,currency:l.targetCurrency||e.targetCurrency||p.currency},p.currency):null;if(u.alertOnTargetPrice&&h&&h.currency===p.currency&&p.amount<=h.amount){const b=NI(e,{createId:o,createdAt:a,currentPrice:p,previousPrice:m,source:i,targetPrice:h,type:"target-hit"});b&&f.push(b)}if(u.alertOnAnyDrop&&m&&m.currency===p.currency&&p.amount<m.amount){const b=NI(e,{createId:o,createdAt:a,currentPrice:p,previousPrice:m,source:i,type:"price-drop"});b&&f.push(b)}return f},GT=(e={},t=[])=>{const r=Vo(e.priceAlertEvents),a=[],s=new Set(r.filter(i=>Cg.has(i.status)).map(i=>Wm(i)));Vo(t).forEach(i=>{if(Cg.has(i.status)){const c=Wm(i);if(s.has(c))return;s.add(c)}a.push(i)});const o=Vo([...r,...a]);return{...e,...o.length?{priceAlertEvents:o}:{}}},qT=new Set(["manual","daily","weekly"]),YT=new Set(["success","failed","no-price","blocked","timeout","low-confidence"]),KT={daily:1,weekly:7},xg=(e="")=>{const t=Date.parse(e);return Number.isFinite(t)?new Date(t).toISOString():""},QE=(e="manual")=>qT.has(e)?e:"manual",ZE=(e="")=>YT.has(e)?e:"",XT=e=>e===!0||String(e??"").trim().toLowerCase()==="true"||String(e??"").trim()==="1",cC=(e=0)=>{const t=Number(e);return Number.isFinite(t)&&t>0?Math.floor(t):0},JT=(e,t)=>{const r=new Date(e);return r.setUTCDate(r.getUTCDate()+t),r.toISOString()},QT=()=>({enabled:!1,cadence:"manual"}),Xu=(e={},{keepEmpty:t=!1}={})=>{if(!e||typeof e!="object")return t?QT():null;const r=XT(e.enabled),a=QE(e.cadence),s=xg(e.lastCheckedAt),o=r&&a!=="manual"?xg(e.nextCheckAt):"",i=ZE(e.lastCheckStatus),c=cC(e.failCount);return!t&&!r&&a==="manual"&&!s&&!i&&c===0?null:{enabled:r,cadence:a,...s?{lastCheckedAt:s}:{},...o?{nextCheckAt:o}:{},...i?{lastCheckStatus:i}:{},...c>0?{failCount:c}:{}}},ek=(e={})=>Xu(e.priceTracking,{keepEmpty:!0}),ZT=(e="manual",t=new Date().toISOString(),r=0)=>{const a=QE(e);if(a==="manual")return"";const s=new Date(xg(t)||new Date().toISOString()),o=cC(r);if(o>=4)return"";const i=o>=2?a==="daily"?7:14:KT[a];return JT(s,i)},eD=(e="")=>{const t=String(e||"").replace(/_/g,"-");return t==="no-price-found"?"no-price":t==="blocked"||t==="timeout"||t==="low-confidence"?t:"failed"},jI=(e={},{status:t="success",checkedAt:r=new Date().toISOString()}={})=>{const a=Xu(e,{keepEmpty:!0}),s=ZE(t)||"failed",o=xg(r)||new Date().toISOString(),i=s==="success"?0:cC(a.failCount)+1,c=a.enabled&&a.cadence!=="manual"?ZT(a.cadence,o,i):"";return Xu({...a,lastCheckedAt:o,lastCheckStatus:s,failCount:i,nextCheckAt:c},{keepEmpty:!0})},tD=new Set(["unknown","in_stock","low_stock","out_of_stock","unavailable","preorder","discontinued"]),rD=new Set(["manual","checked","imported"]),Fs=(e="unknown")=>{const t=String(e||"").trim().toLowerCase().replace(/[\s-]+/g,"_");return tD.has(t)?t:"unknown"},tk=(e="")=>{const t=String(e||"").trim().toLowerCase().replace(/[\s-]+/g,"_");return rD.has(t)?t:""},Ig=(e="",t="")=>{const r=new Date(e);if(Number.isFinite(r.getTime()))return r.toISOString();const a=new Date(t);return Number.isFinite(a.getTime())?a.toISOString():""},rk=e=>{const t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(1,t)):null},nk=(e="unknown",t="unknown")=>{const r=Fs(e),a=Fs(t);return r===a?{humanLabel:"",severity:"none",shouldCreateFutureAlert:!1,transitionType:"none"}:a==="discontinued"?{humanLabel:"Discontinued",severity:"high",shouldCreateFutureAlert:!0,transitionType:"discontinued"}:r==="out_of_stock"&&a==="in_stock"?{humanLabel:"Back in stock",severity:"high",shouldCreateFutureAlert:!0,transitionType:"back-in-stock"}:r==="unavailable"&&a==="in_stock"?{humanLabel:"Available again",severity:"high",shouldCreateFutureAlert:!0,transitionType:"available-again"}:r==="preorder"&&a==="in_stock"?{humanLabel:"Now available",severity:"medium",shouldCreateFutureAlert:!0,transitionType:"now-available"}:a==="out_of_stock"?{humanLabel:"Recently sold out",severity:"medium",shouldCreateFutureAlert:r!=="unknown",transitionType:"sold-out"}:a==="low_stock"?{humanLabel:"Low stock",severity:"medium",shouldCreateFutureAlert:r!=="unknown",transitionType:"low-stock"}:r==="unknown"&&a==="in_stock"?{humanLabel:"First known in stock",severity:"low",shouldCreateFutureAlert:!1,transitionType:"first-known-in-stock"}:r==="unknown"&&a!=="unknown"?{humanLabel:"First known status",severity:"low",shouldCreateFutureAlert:!1,transitionType:"first-known"}:{humanLabel:"Availability changed",severity:"low",shouldCreateFutureAlert:!1,transitionType:"availability-changed"}},vf=(e=[])=>Array.isArray(e)?e.map(t=>{if(!t||typeof t!="object"||Array.isArray(t))return null;const r=Fs(t.status),a=Fs(t.previousStatus||t.previous_status),s=tk(t.source),o=Ig(t.checkedAt||t.checked_at||t.createdAt||t.created_at),i=Ig(t.createdAt||t.created_at||t.checkedAt||t.checked_at),c=rk(t.confidence),l=String(t.message||"").trim(),u=String(t.id||"").trim();return r==="unknown"&&!o&&!i&&!s&&!l&&c===null?null:{...u?{id:u}:{},status:r,...a!==r?{previousStatus:a}:{},...c!==null?{confidence:c}:{},...s?{source:s}:{},...l?{message:l}:{},checkedAt:o,createdAt:i}}
1).filter(Boolean).sort((t,r)=>{const a=Date.parse(t.createdAt||t.checkedAt||""),s=Date.parse(r.createdAt||r.checkedAt||"");return(Number.isFinite(a)?a:0)-(Number.isFinite(s)?s:0)}).slice(-50):[],nD=(e=[],t={},r={},{checkedAt:a=new Date().toISOString(),createdAt:s=a,source:o=r.source}={})=>{const i=vf(e),c=Fs(t?.status),l=Fs(r?.status),u=nk(c,l);if(c===l||c==="unknown"&&l==="unknown")return{changed:!1,history:i,transition:u};if(i.at(-1)?.status===l)return{changed:!1,history:i,transition:u};const m=Ig(r.checkedAt||a,a),f=Ig(s,m),h=rk(r.confidence),b=tk(o),v=String(r.message||"").trim(),S={status:l,previousStatus:c,...h!==null?{confidence:h}:{},...b?{source:b}:{},...v?{message:v}:{},checkedAt:m,createdAt:f};return{changed:!0,history:[...i,S].slice(-50),transition:u}},aD=new Set(["back-in-stock","low-stock","sold-out","now-available","discontinued","availability-changed"]),sD=new Set(["pending","seen","dismissed","sent","failed"]),oD=new Set(["manual","checked","imported"]),Ag=new Set(["pending","seen","sent"]),lC=(e="")=>String(e||"").trim().toLowerCase().replace(/[\s_]+/g,"-"),pd=(e="",t="")=>{const r=Date.parse(String(e||""));if(Number.isFinite(r))return new Date(r).toISOString();const a=Date.parse(String(t||""));return Number.isFinite(a)?new Date(a).toISOString():""},iD=e=>{const t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(1,t)):null},ak=(e="")=>{const t=lC(e);return aD.has(t)?t:""},cD=(e="pending")=>{const t=lC(e);return sD.has(t)?t:"pending"},sk=(e="manual")=>{const t=lC(e);return oD.has(t)?t:"manual"},ok=(e="")=>{const t=pd(e);return t?t.slice(0,10):""},Gm=(e={})=>[String(e.productId||e.product_id||"").trim(),ak(e.type),Fs(e.previousStatus||e.previous_status),Fs(e.currentStatus||e.current_status||e.status),sk(e.source),ok(e.createdAt||e.created_at)].join("|"),ik=(e={},t="")=>["availability-alert",e.productId||"product",e.type||"event",e.previousStatus||"unknown",e.currentStatus||"unknown",ok(t)||"date"].filter(Boolean).join("-").replace(/[^a-z0-9-]+/gi,"-").replace(/-+/g,"-").toLowerCase(),ck=(e={},t=0)=>{if(!e||typeof e!="object"||Array.isArray(e))return null;const r=ak(e.type),a=String(e.productId||e.product_id||"").trim(),s=String(e.userId||e.user_id||"").trim(),o=Fs(e.previousStatus||e.previous_status),i=Fs(e.currentStatus||e.current_status||e.status);if(!r||!a||i==="unknown")return null;const c=pd(e.createdAt||e.created_at)||new Date(0).toISOString(),l=pd(e.seenAt||e.seen_at),u=pd(e.dismissedAt||e.dismissed_at),p=pd(e.sentAt||e.sent_at),m=pd(e.failedAt||e.failed_at),f=iD(e.confidence),h=String(e.failureReason||e.failure_reason||"").trim().toLowerCase(),b=String(e.message||"").trim();return{id:String(e.id||ik({productId:a,type:r,previousStatus:o,currentStatus:i},c)||`availability-alert-event-${t+1}`),...s?{userId:s}:{},productId:a,type:r,...o!==i?{previousStatus:o}:{},currentStatus:i,status:cD(e.status),source:sk(e.source),...f!==null?{confidence:f}:{},...b?{message:b}:{},createdAt:c,...l?{seenAt:l}:{},...u?{dismissedAt:u}:{},...p?{sentAt:p}:{},...m?{failedAt:m}:{},...h?{failureReason:h}:{}}},lD=(e=[])=>[...e].sort((t,r)=>{const a=Date.parse(t.createdAt),s=Date.parse(r.createdAt);return Number.isFinite(a)&&Number.isFinite(s)&&a!==s?a-s:String(t.id).localeCompare(String(r.id),void 0,{sensitivity:"base"})}),Bi=(e=[])=>{const t=new Set,r=new Set;return lD((Array.isArray(e)?e:[]).map((a,s)=>ck(a,s)).filter(Boolean)).filter(a=>{if(t.has(a.id))return!1;if(t.add(a.id),!Ag.has(a.status))return!0;const s=Gm(a);return r.has(s)?!1:(r.add(s),!0)})},dD=(e="")=>e==="available-again"||e==="now-available"?"now-available":e==="back-in-stock"||e==="low-stock"||e==="sold-out"||e==="discontinued"?e:"",uD=(e={},t={})=>{const r=Gm(t);return Bi(e.availabilityAlertEvents).some(a=>Ag.has(a.status)&&Gm(a)===r)},pD=(e={},t={},r={},{checkedAt:a=new Date().toISOString(),createId:s,source:o=r?.source||"manual",transition:i=nk(t?.status,r?.status)}={})=>{if(!e.id||!i?.shouldCreateFutureAlert)return null;const c=Fs(r?.status),l=Fs(t?.status),u=dD(i.transitionType);if(!u||l==="unknown"||c==="unknown"||c===l)return null;const p=pd(a)||new Date().toISOString(),m=ck({id:s?.()||ik({currentStatus:c,previousStatus:l,productId:e.id,type:u},p),productId:e.id,type:u,previousStatus:l,currentStatus:c,status:"pending",source:o,confidence:r?.confidence,message:r?.message||i.humanLabel,createdAt:p});return!m||uD(e,m)?null:m},mD=(e={},t=[])=>{const r=Bi(e.availabilityAlertEvents),a=[],s=new Set(r.filter(i=>Ag.has(i.status)).map(i=>Gm(i)));Bi(t).forEach(i=>
1{if(Ag.has(i.status)){const c=Gm(i);if(s.has(c))return;s.add(c)}a.push(i)});const o=Bi([...r,...a]);return{...e,...o.length?{availabilityAlertEvents:o}:{}}},fD=(e=[])=>Bi(e).slice(-1)[0]||null,Mi="local-user",lk=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,hD=512,so=e=>String(e??"").trim(),Cd=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),gD=e=>!!e&&typeof e=="object"&&!Array.isArray(e),bD=["cloudDeletedAt","cloudDeletionId","cloudDeletionReason","cloudPurgeAfter","cloudRestoredAt","cloudUpdatedAt","deleted_at","deletion_id","restored_at"],dk=["collaborationId","collaboration_id","collaboratorId","collaborator_id","sharedBoardId","shared_board_id"],vD=[...dk,"accessRole","access_role","collaborationRole","collaboration_role","role","sharedRole","shared_role"],yD=["publicBoardId","public_board_id","publicProjectionId","public_projection_id","publicationId","publication_id","publishedAt","published_at"],SD=["cloudDeletedAt","cloudDeletionId","cloudDeletionReason","cloudPurgeAfter","deletedAt","deleted_at","deletedBy","deleted_by","deletionId","deletion_id","deletionReason","deletion_reason","purgeAfter","purge_after"],qm=(e,t)=>t.some(r=>so(e?.[r])),RI=(e,t)=>[...new Set(t.map(r=>so(e?.[r])).filter(Boolean))],wD=(e={})=>!!(qm(e,vD)||Cd(e,"boardId")||Cd(e,"board_id")||e?.isCollaborative===!0||e?.isSharedProjection===!0),CD=(e={})=>!!(qm(e,yD)||e?.isPublicOnly===!0||e?.isPublicProjection===!0||e?.publicOnly===!0),xD=(e={})=>e?.deletionProtected===!0||e?.isDeletionProtected===!0||e?.needsReview===!0||e?.protectedForReview===!0||e?.requiresReview===!0||e?.syncReviewRequired===!0,ID=(e={})=>so(e?.syncConflict)||so(e?.syncConflictAt)?!0:!Cd(e,"syncConflictPatch")||e.syncConflictPatch==null?!1:!gD(e.syncConflictPatch)||Object.keys(e.syncConflictPatch).length>0,LI=(e={})=>{const t=RI(e,["userId","user_id"]);if(t.length!==1||!lk.test(t[0]))return{ownerId:"",reason:t.length>1?"canonical-owner-ambiguous":"canonical-owner-unavailable"};const r=t[0].toLowerCase();return RI(e,["userId","user_id","ownerId","owner_id"]).map(s=>s.toLowerCase()).some(s=>s!==r)?{ownerId:"",reason:"canonical-owner-ambiguous"}:{ownerId:r,reason:""}},AD=(e={})=>{if(!Cd(e,"syncRevision")||e.syncRevision===void 0||e.syncRevision===null||e.syncRevision==="")return{reason:"authoritative-revision-unavailable",revision:null};const t=[e.syncRevision];Cd(e,"revision")&&e.revision!==void 0&&e.revision!==null&&e.revision!==""&&t.push(e.revision);const r=t.map(Number);return r.some(a=>!Number.isSafeInteger(a)||a<=0)?{reason:"authoritative-revision-invalid",revision:null}:new Set(r).size!==1?{reason:"authoritative-revision-ambiguous",revision:null}:{reason:"",revision:r[0]}},PD=(e={})=>{const t=so(e.cloudUpdatedAt);if(!t||!Number.isFinite(Date.parse(t)))return!1;const r=so(e.updated_at);return!r||Number.isFinite(Date.parse(r))&&Date.parse(r)===Date.parse(t)},ja=({boardId:e="",eligibility:t,expectedRevision:r=null,ownerId:a="",reason:s})=>({allowed:t!==Bn.blocked,boardId:e,eligibility:t,expectedRevision:r,ownerId:a,reason:s}),Zs=Object.freeze({ambiguous:"ambiguous",cloud:"cloud-backed",local:"local-only"}),Bn=Object.freeze({blocked:"blocked",cloud:"cloud-owner",local:"local-only"}),Ga=Object.freeze({activeLifecycleUnavailable:"active-lifecycle-unavailable",ambiguousProvenance:"ambiguous-provenance",authenticationUnavailable:"authentication-unavailable",canonicalOwnerAmbiguous:"canonical-owner-ambiguous",canonicalOwnerUnavailable:"canonical-owner-unavailable",cloudOwner:"cloud-owner",collaborationProjection:"collaboration-projection",inactiveLifecycle:"inactive-lifecycle",invalidBoardIdentity:"invalid-board-identity",localOnly:"local-only",ownerMismatch:"owner-mismatch",protected:"protected",publicProjection:"public-projection",revisionAmbiguous:"authoritative-revision-ambiguous",revisionInvalid:"authoritative-revision-invalid",revisionUnavailable:"authoritative-revision-unavailable",unresolvedConflict:"unresolved-conflict",updateTimestampUnavailable:"authoritative-update-timestamp-unavailable",writePending:"cloud-write-pending"}),uk=e=>{if(!e||!so(e.id))return Zs.ambiguous;const t=[e.userId,e.user_id,e.ownerId,e.owner_id].map(so).filter(
1Boolean),r=[...new Set(t)];if(r.length!==1)return Zs.ambiguous;if(r[0]!==Mi||qm(e,dk))return Zs.cloud;const a=Object.hasOwn(e,"syncRevision")||Object.hasOwn(e,"revision"),s=Number(e.syncRevision??e.revision);return qm(e,bD)||e.syncSuppressed===!0?Zs.cloud:a?Number.isInteger(s)&&s>0?Zs.cloud:Zs.ambiguous:e.syncPendingCloudWrite===!0||so(e.syncConflict)||so(e.syncConflictAt)?Zs.ambiguous:Zs.local},BI=e=>uk(e)===Zs.local,gy=({authenticatedUserId:e="",board:t=null,isProtected:r=!1}={})=>{const a=typeof t?.id=="string"?t.id.trim():"";if(r||xD(t))return ja({boardId:a,eligibility:Bn.blocked,reason:Ga.protected});if(wD(t))return ja({boardId:a,eligibility:Bn.blocked,reason:Ga.collaborationProjection});if(CD(t))return ja({boardId:a,eligibility:Bn.blocked,reason:Ga.publicProjection});if(!a||a.length>hD||/[\u0000-\u001f\u007f-\u009f]/.test(a))return ja({eligibility:Bn.blocked,reason:Ga.invalidBoardIdentity});const s=uk(t);if(s===Zs.local)return ja({boardId:a,eligibility:Bn.local,reason:Ga.localOnly});if(s!==Zs.cloud){const l=LI(t);return ja({boardId:a,eligibility:Bn.blocked,reason:l.reason===Ga.canonicalOwnerAmbiguous?l.reason:Ga.ambiguousProvenance})}const o=so(e).toLowerCase();if(!lk.test(o))return ja({boardId:a,eligibility:Bn.blocked,reason:Ga.authenticationUnavailable});const i=LI(t);if(!i.ownerId)return ja({boardId:a,eligibility:Bn.blocked,reason:i.reason});if(i.ownerId!==o)return ja({boardId:a,eligibility:Bn.blocked,ownerId:i.ownerId,reason:Ga.ownerMismatch});if(t.syncPendingCloudWrite===!0||Cd(t,"syncPendingCloudWrite")&&t.syncPendingCloudWrite!==!1&&t.syncPendingCloudWrite!=null)return ja({boardId:a,eligibility:Bn.blocked,ownerId:i.ownerId,reason:Ga.writePending});if(ID(t))return ja({boardId:a,eligibility:Bn.blocked,ownerId:i.ownerId,reason:Ga.unresolvedConflict});if(t.syncSuppressed===!0||t.isArchived===!0||qm(t,SD)||so(t.archivedAt||t.archived_at))return ja({boardId:a,eligibility:Bn.blocked,ownerId:i.ownerId,reason:Ga.inactiveLifecycle});if(t.syncSuppressed!==!1||Cd(t,"isArchived")&&t.isArchived!==!1&&t.isArchived!=null)return ja({boardId:a,eligibility:Bn.blocked,ownerId:i.ownerId,reason:Ga.activeLifecycleUnavailable});const c=AD(t);return c.revision?PD(t)?ja({boardId:a,eligibility:Bn.cloud,expectedRevision:c.revision,ownerId:i.ownerId,reason:Ga.cloudOwner}):ja({boardId:a,eligibility:Bn.blocked,expectedRevision:c.revision,ownerId:i.ownerId,reason:Ga.updateTimestampUnavailable}):ja({boardId:a,eligibility:Bn.blocked,ownerId:i.ownerId,reason:c.reason})},_D=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,ED="00000000-0000-0000-0000-000000000000",kD=/[\u0000-\u001f\u007f]/,In=Object.freeze({alreadyDeleted:"already-deleted",applied:"applied",lifecycle:"lifecycle",malformed:"malformed",permission:"permission",replay:"replay",stale:"stale",transport:"transport",unknown:"unknown"}),ND=Object.freeze({"authentication-unavailable":In.permission,"invalid-input":In.malformed,"ledger-inconsistent":In.lifecycle,"not-active":In.lifecycle,"not-found-or-unavailable":In.permission,"operation-id-conflict":In.lifecycle,"revision-conflict":In.stale}),jD=Object.freeze(["ownerId","owner_id","user","userId","user_id"]),Cc=e=>String(e??"").trim(),pk=e=>{const t=Number(e);return Number.isSafeInteger(t)&&t>0?t:null},TI=e=>{const t=Number(e);return Number.isSafeInteger(t)&&t>=0?t:null},RD=e=>{if(typeof e!="string"||!e.trim())return"";const t=Date.parse(e);return Number.isFinite(t)?new Date(t).toISOString():""},rg=e=>{const t=Cc(e);return _D.test(t)&&t.toLowerCase()!==ED?t:""},PS=({classification:e,errorCode:t="",outcome:r="",reason:a="",requestedOperationId:s=""})=>({applied:!1,classification:e,conflict:e===In.stale,errorCode:Cc(t),idempotentReplay:!1,ok:!1,outcome:Cc(r),reason:Cc(a)||Cc(r)||e,...s?{requestedOperationId:s}:{}}),_S=e=>Cc(e?.code??e?.statusCode??e?.status).toUpperCase(),DI=e=>{const t=_S(e),r=Number(e?.status??e?.statusCode),a=Cc(e?.name).toLowerCase(),s=Cc(e?.message).toLowerCase();return["40001","55P03"].includes(t)?In.stale:["28000","28P01","42501","PGRST301","PGRST302"].includes(t)||r===401||r===403?In.permission:t==="55000"?In.lifecycle:["22023","22P02"].includes(t)?In.malformed:["PGRST000","PGRST001","PGRST002","PGRST003","57014"].includes(t)||r>=500||a==="aborterror"||a==="typeerror"||/(?:failed to fetch|network|timed? out|timeout|connection)/i.test(s)?In.transport:In.unknown},hd=(e,t="")=>PS({classification:In.malformed,reason:e,requestedOperationId:t}),LD=e=>{if(!e||typeof e!="object"||Array.isArray(e))return{error:hd("invalid-request")};if(jD.some(s=>Object.prototype.hasOwnProperty.call(e,s)))return{error:hd("owner-input-not-allowed")};const t=typeof e.listId=="string"?e.listId.trim():"",r=pk(e.expectedRevision),a=typeof e.o
1perationId=="string"?rg(e.operationId):"";return typeof e.client?.rpc!="function"||!t||t.length>512||kD.test(t)||!r||!a?{error:hd("invalid-request")}:{client:e.client,expectedRevision:r,listId:t,operationId:a}},BD=({expectedListId:e,row:t})=>{if(!t||typeof t!="object"||Array.isArray(t))return null;const r=typeof t.list_id=="string"?t.list_id.trim():"",a=rg(t.operation_id),s=t.owner_id===null?"":rg(t.owner_id),o=t.revision===null?null:pk(t.revision),i=t.deleted_at===null?"":RD(t.deleted_at),c=t.deletion_id===null?"":rg(t.deletion_id),l=TI(t.child_products_affected),u=TI(t.collaboration_records_affected);return r!==e||!a||l===null||u===null||typeof t.public_projection_removed!="boolean"||typeof t.ok!="boolean"||typeof t.applied!="boolean"||typeof t.conflict!="boolean"||typeof t.idempotent_replay!="boolean"||t.owner_id!==null&&!s||t.revision!==null&&!o||t.deleted_at!==null&&!i||t.deletion_id!==null&&!c?null:{applied:t.applied,childProductsAffected:l,collaborationRecordsAffected:u,conflict:t.conflict,deletedAt:i,deletionId:c,idempotentReplay:t.idempotent_replay,listId:r,ok:t.ok,operationId:a,outcome:Cc(t.outcome),ownerId:s,publicProjectionRemoved:t.public_projection_removed,revision:o}},TD=({acknowledgement:e,expectedRevision:t,requestedOperationId:r})=>{const{applied:a,conflict:s,deletedAt:o,deletionId:i,idempotentReplay:c,operationId:l,outcome:u,ownerId:p,revision:m}=e;return s||!p||!m||!o||!i?null:u==="trashed"&&a&&!c&&l===r&&m===t+1?In.applied:u==="already-deleted"&&!a&&c&&l===r&&m===t+1?In.replay:u==="already-deleted"&&!a&&!c&&l!==r?In.alreadyDeleted:null},DD=({acknowledgement:e,requestedOperationId:t})=>{const r=ND[e.outcome]||"",a=["operation-id-conflict","revision-conflict"].includes(e.outcome);if(!r||e.ok||e.applied||e.idempotentReplay||e.conflict!==a||e.operationId!==t||e.childProductsAffected!==0||e.collaborationRecordsAffected!==0||e.publicProjectionRemoved)return null;const s=["ledger-inconsistent","not-active","operation-id-conflict","revision-conflict"].includes(e.outcome);return s&&(!e.ownerId||!e.revision)||!s&&(e.ownerId||e.revision)?null:r},OD=async(e={})=>{const t=LD(e);if(t.error)return t.error;const{client:r,expectedRevision:a,listId:s,operationId:o}=t;let i;try{i=await r.rpc("trash_private_list",{p_expected_revision:a,p_list_id:s,p_operation_id:o})}catch(u){const p=DI(u);return PS({classification:p,errorCode:_S(u),reason:"rpc-threw",requestedOperationId:o})}if(i?.error){const u=DI(i.error);return PS({classification:u,errorCode:_S(i.error),reason:"rpc-error",requestedOperationId:o})}if(!Array.isArray(i?.data)||i.data.length!==1)return hd("invalid-acknowledgement-row-count",o);const c=BD({expectedListId:s,row:i.data[0]});if(!c)return hd("invalid-acknowledgement-shape",o);if(c.ok){const u=TD({acknowledgement:c,expectedRevision:a,requestedOperationId:o});return u?{...c,classification:u,requestedOperationId:o}:hd("invalid-success-acknowledgement",o)}const l=DD({acknowledgement:c,requestedOperationId:o});return l?{...c,classification:l,reason:c.outcome,requestedOperationId:o}:hd("invalid-rejection-acknowledgement",o)},MD=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,UD="00000000-0000-0000-0000-000000000000",FD=new Set(["applied","replay","already-deleted"]),OI=12e3,Vr=e=>String(e??"").trim(),ES=(e,t)=>t.some(r=>Vr(e?.[r])),dC=e=>{const t=Number(e);return Number.isSafeInteger(t)&&t>0?t:null},Pi=e=>{const t=Vr(e);return MD.test(t)&&t.toLowerCase()!==UD?t.toLowerCase():""},uC=e=>{const t=Date.parse(e||"");return Number.isFinite(t)?new Date(t).toISOString():""},ng=(e={})=>{const t=[...new Set([e.userId,e.user_id].map(Vr).filter(Boolean))];return t.length===1?t[0].toLowerCase():""},$D=({listId:e="",ownerId:t="",products:r=[]}={})=>{const a=Vr(e),s=Pi(t);return!a||!s||!Array.isArray(r)?0:r.filter(o=>{const i=Vr(o?.listId??o?.list_id),c=[...new Set([o?.userId,o?.user_id].map(Vr).filter(Boolean))].map(u=>u.toLowerCase()),l=c.length===1?c[0]:"";return!!(i===a&&[s,Mi].includes(l)&&o?.syncSuppressed!==!0&&!ES(o,["cloudDeletedAt","deletedAt","deleted_at","deletionId","deletion_id"]))}).length},xu=(e={},{authenticatedOwnerId:t=""}={})=>{const r=Vr(e.id),a=Vr(e.name),s=ng(e),o=Vr(t).toLowerCase();return!!(r&&a&&(s===Mi||o&&s===o)&&e.syncSuppressed!==!0&&e.isArchived!==!0&&!ES(e,["archivedAt","archived_at","cloudDeletedAt","deletedAt","deleted_at","deletionId","deletion_id"])&&!ES(e,["accessRole","access_role","collaborationId","collaboration_id","collaborationRole","collaboration_role","publicBoardId","public_board_id","sharedBoardId","shared_board_id"])&&e.isCollaborative!==!0&&e.isPublicOnly!==!0&&e.isPublicProjection!==!0)},mk=({authenticatedOwnerId:e="",currentDefaultList:t="",fallbackDefaultList:r="Wishlist",lists:a=[]}={})=>{const s=(Array.isArray(a)?a:[]).filter(p=>xu(p,{authenticatedOwnerId:e})).sort((p,m)=>(Number(p.sortOrder)||0)-(Number(m.sortOrder)||0)||Vr(p.name).localeCompare(Vr(m.name))||Vr(p.id).localeCompare(Vr(m.id))),o=Vr(t).toLowerCase(),i=s.find(p=>Vr(p.name).toLowerCase()===o)||null;if(i)return{changed:!1,defaultList:i.name,hasActiveFallback:!0};const c=Vr(r)||"Wishlist",u=s.find(p=>Vr(p.name).toLowerCase()===c.toLowerCase())||s[0]||null;return{changed:Vr(t)!==Vr(u?.name||c),defaultList:u?.name||c,hasActiveFallback:!!u}},fk=(e={},t="")=>{const r=e&&typeof e=="object"?e:{},a=Pi(r.ownerId),s=Vr(r.listId),o=Pi(r.operationId),i=dC(r.expectedRevision),c=uC(r.requestedAt),l=Vr(r.state).toLowerCase();return!a||a!==Pi(t)||!s||!o||!i||!c||!["pending","uncertain"].includes(l)?null:{expectedRevision:i,listId:s,operationId:o,ownerId:a,requestedAt:c,state:l}},zD=()=>
1{if(typeof globalThis.crypto?.randomUUID=="function")return globalThis.crypto.randomUUID();if(typeof globalThis.crypto?.getRandomValues=="function"){const e=globalThis.crypto.getRandomValues(new Uint8Array(16));e[6]=e[6]&15|64,e[8]=e[8]&63|128;const t=[...e].map(r=>r.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return""},VD=({authenticatedOwnerId:e="",createOperationId:t=zD,existingOperation:r=null,expectedRevision:a,listId:s="",now:o=()=>new Date}={})=>{const i=Pi(e),c=Vr(s),l=dC(a),u=fk(r,i);if(u&&u.listId===c)return{...r,recovered:!0};if(!i||!c||!l||typeof t!="function"||typeof o!="function")return null;const p=Pi(t()),m=uC(o()?.toISOString?.());return!p||!m?null:{expectedRevision:l,listId:c,operationId:p,ownerId:i,recovered:!1,requestedAt:m,state:"pending",updatedAt:m}},HD=async({clearTimeoutFn:e=globalThis.clearTimeout,request:t,setTimeoutFn:r=globalThis.setTimeout,timeoutMs:a=OI}={})=>{if(typeof t!="function"||typeof r!="function"||typeof e!="function")return{kind:"failure",reason:"invalid-request"};const s=Number(a),o=Number.isFinite(s)&&s>0?s:OI;let i=null;const c=Promise.resolve().then(t);c.catch(()=>{});const l=new Promise(u=>{i=r(()=>u({kind:"timeout"}),o)});try{return await Promise.race([c.then(u=>({kind:"result",result:u}),u=>({error:u,kind:"failure"})),l])}finally{i!==null&&e(i)}},WD=({acknowledgement:e={},pendingOperation:t})=>{const r=Vr(e.classification),a=Pi(e.ownerId),s=Pi(e.operationId),o=Pi(e.requestedOperationId),i=dC(e.revision),c=uC(e.deletedAt),l=Pi(e.deletionId),u=Number(e.childProductsAffected),p=Number(e.collaborationRecordsAffected),m=Number.isSafeInteger(u)&&u>=0&&Number.isSafeInteger(p)&&p>=0,f=o===t.operationId,h=s===t.operationId,b=i===t.expectedRevision+1,v=r==="applied"&&e.applied===!0&&h&&b||r==="replay"&&e.applied===!1&&e.idempotentReplay===!0&&h&&b||r==="already-deleted"&&e.applied===!1&&e.idempotentReplay===!1&&!h;return e.ok!==!0||!FD.has(r)||!v||!f||a!==t.ownerId||Vr(e.listId)!==t.listId||!s||!i||!c||!l||!m||typeof e.publicProjectionRemoved!="boolean"?null:{childProductsAffected:u,classification:r,collaborationRecordsAffected:p,deletedAt:c,deletionId:l,operationId:s,ownerId:a,publicProjectionRemoved:e.publicProjectionRemoved,requestedOperationId:o,revision:i}},GD=({acknowledgement:e={},authenticatedOwnerId:t="",currentDefaultList:r="",fallbackDefaultList:a="Wishlist",lists:s=[],pendingOperation:o={},products:i=[]}={})=>{const c=fk(o,t);if(!c)return{ok:!1,outcome:"pending-operation-mismatch"};const l=WD({acknowledgement:e,pendingOperation:c});if(!l)return{ok:!1,outcome:"acknowledgement-mismatch"};if((Array.isArray(s)?s:[]).filter(h=>Vr(h?.id)===c.listId&&ng(h)===c.ownerId).length!==1)return{ok:!1,outcome:"canonical-board-mismatch"};const p=s.map(h=>Vr(h?.id)===c.listId&&ng(h)===c.ownerId?{...h,cloudDeletedAt:l.deletedAt,cloudDeletionId:l.deletionId,cloudDeletionReason:"user_trash",cloudPurgeAfter:"",cloudRestoredAt:"",cloudRestoredBy:"",cloudUpdatedAt:l.deletedAt,syncConflict:"",syncConflictAt:"",syncConflictPatch:void 0,syncPendingCloudWrite:!1,syncRevision:l.revision,syncSuppressed:!0}:h),m=(Array.isArray(i)?i:[]).map(h=>{const b=Vr(h?.userId??h?.user_id).toLowerCase();return Vr(h?.listId??h?.list_id)!==c.listId||![c.ownerId,Mi].includes(b)?h:{...h,cloudDeletedAt:l.deletedAt,cloudDeletionId:l.deletionId,cloudDeletionReason:"parent_list_trash",cloudPurgeAfter:"",cloudRestoredAt:"",cloudRestoredBy:"",syncPendingCloudWrite:!1,syncSuppressed:!0}}),f=mk({authenticatedOwnerId:c.ownerId,currentDefaultList:r,fallbackDefaultList:a,lists:p});return{...l,defaultList:f.defaultList,defaultListChanged:f.changed,hasActiveDefaultFallback:f.hasActiveFallback,list:p.find(h=>Vr(h?.id)===c.listId&&ng(h)===c.ownerId),lists:p,ok:!0,outcome:l.classification,products:m,suppressedProductCount:m.filter((h,b)=>h!==i[b]&&h.syncSuppressed===!0).length}},qD=160,YD=220,KD=2,Ts=new Map,ld=new Map,Mu=[];let Sm=0,kS=0,hk=0,gk=0,bk=0;const xd=()=>{const e=new Error("Image analysis was cancelled.");return e.name="AbortError",e},XD=(e,t)=>{try{const r=t||(typeof window<"u"?window.location.href:"http://localhost/"),a=new URL(r),s=new URL(String(e||""),a);return s.protocol==="data:"||s.protocol==="blob:"?!1:s.origin!==a.origin}catch{return!1}},JD=(e="")=>{const t=String(e||"");let r=2166136261;for(let a=0;a<t.length;a+=1)r^=t.charCodeAt(a),r=Math.imul(r,16777619);return`${t.length}:${(r>>>0).toString(36)}:${t.slice(0,24)}:${t.slice(-24)}`},vk=e=>`${Yu}:${JD(e)}`,QD=(e,t)=>{Ts.delete(e),Ts.set(e,t),Ts.size>YD&&Ts.delete(Ts.keys().next().value)},yk=()=>{for(;Sm<KD&&Mu.length;){const e=Mu.shift();if(e.signal?.aborted){e.reject(xd());continue}Sm+=1,kS=Math.max(kS,Sm),Promise.resolve().then(e.task).then(e.resolve,e.reject).finally(()=>{Sm-=1,yk()})}},Sk=(e,t)=>new Promise((r,a)=>{if(t?.aborted){a(xd());return}const s={reject:a,resolve:r,signal:t,task:e},o=()=>{const l=Mu.indexOf(s);l!==-1&&(Mu.splice(l,1),a(xd()))};t?.addEventListener("abort",o,{once:!0});const i=r,c=a;s.resolve=l=>{t?.removeEventListener("abort",o),i(l)},s.reject=l=>{t?.removeEventListener("abort",o),c(l)},Mu.push(s),yk()}),wk=(e,t)=>new Promise((r,a)=>{if(t?.aborted){a(xd());return}const s=new Image;let o=!1;const i=()=>
1{t?.removeEventListener("abort",l),s.onload=null,s.onerror=null},c=(u,p)=>{o||(o=!0,i(),u(p))},l=()=>{s.src="",c(a,xd())};t?.addEventListener("abort",l,{once:!0}),XD(e)&&(s.crossOrigin="anonymous"),s.decoding="async",s.onload=()=>c(r,s),s.onerror=()=>c(a,new Error("image-load-failed")),s.src=e}),Ck=(e,t)=>{const r=document.createElement("canvas");r.width=e,r.height=t;const a=r.getContext("2d",{willReadFrequently:!0});if(!a)throw new Error("canvas-context-unavailable");return a.imageSmoothingEnabled=!0,a.imageSmoothingQuality="high",{canvas:r,context:a}},pC=e=>e?.name==="SecurityError"||String(e?.message||"").toLowerCase().includes("tainted")?"canvas-tainted":String(e?.message||"").includes("canvas-context-unavailable")?"canvas-context-unavailable":"canvas-sampling-error",ZD=async(e,t)=>{try{const r=await wk(e,t);if(t?.aborted)throw xd();const a=Math.min(1,qD/Math.max(r.naturalWidth,r.naturalHeight)),s=Math.max(2,Math.round(r.naturalWidth*a)),o=Math.max(2,Math.round(r.naturalHeight*a)),{context:i}=Ck(s,o);i.clearRect(0,0,s,o),i.drawImage(r,0,0,s,o);const c=i.getImageData(0,0,s,o);return J0({data:c.data,height:o,width:s})}catch(r){if(r?.name==="AbortError")return sa({reason:"aborted"});const a=String(r?.message||"")==="image-load-failed"?"image-load-failed":pC(r);return sa({reason:a})}},eO=(e,t)=>t?t.aborted?Promise.resolve(sa({reason:"aborted"})):new Promise(r=>{const a=()=>r(sa({reason:"aborted"}));t.addEventListener("abort",a,{once:!0}),e.then(s=>{t.removeEventListener("abort",a),r(s)})}):e,MI=(e,t)=>{e.subscriberCount+=1;let r=!1;const a=()=>{r||(r=!0,e.subscriberCount=Math.max(0,e.subscriberCount-1),e.subscriberCount===0&&!e.finished&&e.controller.abort())};return t?.aborted?(a(),Promise.resolve(sa({reason:"aborted"}))):new Promise(s=>{const o=()=>{t?.removeEventListener("abort",o),a(),s(sa({reason:"aborted"}))};t?.addEventListener("abort",o,{once:!0}),e.promise.then(i=>{t?.removeEventListener("abort",o),!r&&(a(),s(i))})})},Pg=(e,{force:t=!1,signal:r}={})=>{const a=String(e||"").trim();if(!a)return Promise.resolve(sa({reason:"missing-image"}));hk+=1;const s=vk(a);if(t&&Ts.delete(s),Ts.has(s)){gk+=1;const l=Ts.get(s);return Ts.delete(s),Ts.set(s,l),eO(Promise.resolve(l),r)}const o=ld.get(s);if(o)if(t||o.controller.signal.aborted)ld.get(s)===o&&ld.delete(s),t&&!o.controller.signal.aborted&&o.controller.abort();else return bk+=1,MI(o,r);const i={controller:new AbortController,finished:!1,promise:null,subscriberCount:0},c=Sk(()=>ZD(a,i.controller.signal),i.controller.signal).catch(l=>sa({reason:l?.name==="AbortError"?"aborted":pC(l)})).then(l=>(l.reason!=="aborted"&&QD(s,l),l)).finally(()=>{i.finished=!0,ld.get(s)===i&&ld.delete(s)});return i.promise=c,ld.set(s,i),MI(i,r)},tO=async(e,{radius:t=3,signal:r,x:a=.5,y:s=.5}={})=>{const o=String(e||"").trim();if(!o)return{color:"",ok:!1,reason:"missing-image"};try{return await Sk(async()=>{const i=await wk(o,r);if(r?.aborted)throw xd();const c=Math.round(UI(a)*Math.max(0,i.naturalWidth-1)),l=Math.round(UI(s)*Math.max(0,i.naturalHeight-1)),u=Math.max(1,Math.min(9,Math.trunc(Number(t)||3))),p=Math.max(0,c-u),m=Math.max(0,l-u),f=Math.min(i.naturalWidth-1,c+u),h=Math.min(i.naturalHeight-1,l+u),b=f-p+1,v=h-m+1,{context:S}=Ck(b,v);S.clearRect(0,0,b,v),S.drawImage(i,p,m,b,v,0,0,b,v);const C=S.getImageData(0,0,b,v),I=eB({data:C.data,height:v,radius:Math.max(b,v),width:b,x:Math.floor(b/2),y:Math.floor(v/2)});return I?{color:I,ok:!0,reason:"sampled-image-neighbourhood"}:{color:"",ok:!1,reason:"transparent-neighbourhood"}},r)}catch(i){return i?.name==="AbortError"?{color:"",ok:!1,reason:"aborted"}:{color:"",ok:!1,reason:pC(i)}}},UI=e=>Math.min(1,Math.max(0,Number(e)||0)),rO=(e="")=>{if(!e){Ts.clear();return}Ts.delete(vk(e))},nO=()=>({activeDecodeCount:Sm,cacheHitCount:gk,cacheSize:Ts.size,deduplicatedRequestCount:bk,detectionRequestCount:hk,inFlightCount:ld.size,peakDecodeCount:kS,queuedDecodeCount:Mu.length}),aO=`
2  <rect width="360" height="520" fill="#163A5F"/>
3  <style>:root { --font-ui: "Geist"; }</style>
4  <g fill="#fcfcfa" font-family="var(--font-ui)" font-size="31" font-weight="700" letter-spacing="0">
5    <text x="105" y="272">Save</text>
6    <circle cx="181" cy="262" r="7.5"/>
7    <text x="197" y="272">board</text>
8  </g>
9`,xk=`data:image/svg+xml;utf8,${encodeURIComponent(`
10    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 520" preserveAspectRatio="xMidYMid slice">
11      <rect width="360" height="520" fill="#163A5F"/>
12      ${aO}
13    </svg>
14  `)}`,NS="data:image/svg+xml;utf8,%0A%20%20%20%20%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20360%20520%22%20preserveAspectRatio%3D%22xMidYMid%20slice%22%3E%0A%20%20%20%20%20%20%3Crect%20width%3D%22360%22%20height%3D%22520%22%20fill%3D%22%23163A5F%22%2F%3E%0A%20%20%20%20%20%20%0A%20%20%3Crect%20width%3D%22360%22%20height%3D%22520%22%20fill%3D%22%23163A5F%22%2F%3E%0A%20%20%3Cg%20fill%3D%22%23fcfcfa%22%20font-family%3D%22Inter%2C%20Helvetica%2
14C%20Arial%2C%20sans-serif%22%20font-size%3D%2231%22%20font-weight%3D%22700%22%20letter-spacing%3D%220%22%3E%0A%20%20%20%20%3Ctext%20x%3D%22105%22%20y%3D%22272%22%3ESave%3C%2Ftext%3E%0A%20%20%20%20%3Ccircle%20cx%3D%22181%22%20cy%3D%22262%22%20r%3D%227.5%22%2F%3E%0A%20%20%20%20%3Ctext%20x%3D%22197%22%20y%3D%22272%22%3Eboard%3C%2Ftext%3E%0A%20%20%3C%2Fg%3E%0A%0A%20%20%20%20%3C%2Fsvg%3E%0A%20%20",jS="data:image/svg+xml;utf8,%0A%20%20%20%20%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20360%20520%22%3E%0A%20%20%20%20%20%20%3Crect%20width%3D%22360%22%20height%3D%22520%22%20fill%3D%22%23fcfcfa%22%2F%3E%0A%20%20%20%20%20%20%0A%20%20%3Crect%20width%3D%22360%22%20height%3D%22520%22%20fill%3D%22%23b11226%22%2F%3E%0A%20%20%3Cg%20fill%3D%22%23fcfcfa%22%20font-family%3D%22Inter%2C%20Helvetica%2C%20Arial%2C%20sans-serif%22%20font-size%3D%2231%22%20font-weight%3D%22700%22%20letter-spacing%3D%220%22%3E%0A%20%20%20%20%3Ctext%20x%3D%22105%22%20y%3D%22272%22%3ESave%3C%2Ftext%3E%0A%20%20%20%20%3Ccircle%20cx%3D%22181%22%20cy%3D%22262%22%20r%3D%227.5%22%2F%3E%0A%20%20%20%20%3Ctext%20x%3D%22197%22%20y%3D%22272%22%3Eboard%3C%2Ftext%3E%0A%20%20%3C%2Fg%3E%0A%0A%20%20%20%20%3C%2Fsvg%3E%0A%20%20",sO=867,oO="a62ea9ad",iO=820,cO="142b84d5",Ik="[saveboard-official-placeholder]",Ak=e=>{const t=String(e??"").trim(),r=t.indexOf(",");let a=t;if(/^data:image\/svg\+xml(?:;|,)/i.test(t)&&r!==-1){a=t.slice(r+1);for(let o=0;o<3;o+=1)try{const i=decodeURIComponent(a);if(i===a)break;a=i}catch{break}}a=a.replace(/\s+/g," ").trim();let s=2166136261;for(let o=0;o<a.length;o+=1)s^=a.charCodeAt(o),s=Math.imul(s,16777619)>>>0;return s.toString(16).padStart(8,"0")};if(NS.length!==sO||Ak(NS)!==oO)throw new Error("Historical SaveBoard placeholder allowlist invariant failed.");if(jS.length!==iO||Ak(jS)!==cO)throw new Error("Legacy red SaveBoard placeholder allowlist invariant failed.");const lO=new Set([xk,NS,jS]),dO=new Set(["budgetCurrency","currency","targetCurrency"]),uO=["sortOrder","sort_order"],Pk=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),_k=e=>!!e&&typeof e=="object"&&!Array.isArray(e),pO=e=>{const t=Date.parse(e||"");return Number.isFinite(t)?t:null},_g=e=>String(e??"").trim(),mO=e=>e===!0||e===1||String(e??"").trim().toLowerCase()==="true",pl=e=>{if(e==null||e==="")return null;const t=Number(e);return Number.isFinite(t)?t:null},Rm=e=>{const t=pO(e);return t===null?"":new Date(t).toISOString()},md=e=>Array.isArray(e)?e.map(md):_k(e)?Object.keys(e).sort().reduce((t,r)=>(t[r]=md(e[r]),t),{}):e??null,Ot=(e,t=e,r=_g,a=[])=>({keys:[...new Set([t,e,...a])],localKey:e,normalize:r}),fO=Object.freeze([Ot("id"),Ot("userId","user_id"),Ot("name"),Ot("slug"),Ot("description"),Ot("publicDescription","public_description"),Ot("isPublic","is_public",mO),Ot("archivedAt","archived_at",Rm),Ot("sortOrder","sort_order",pl),Ot("budget","budget_amount",pl,["budgetAmount"]),Ot("budgetCurrency","budget_currency"),Ot("createdAt","created_at",Rm)]),hO=Object.freeze([Ot("id"),Ot("userId","user_id"),Ot("listId","list_id"),Ot("title"),Ot("price"),Ot("brand"),Ot("cardSize","card_size",zn),Ot("imageFramingOverrides","image_framing_overrides",ya),Ot("source"),Ot("url"),Ot("imageUrl","image_url",_g,["image"]),Ot("privateNotes","note",_g,["notes"]),Ot("publicNotes","public_note"),Ot("size"),Ot("colour"),Ot("variant"),Ot("status"),Ot("sortOrder","sort_order",pl),Ot("imageFit","image_fit"),Ot("imageScale","image_scale",pl),Ot("imagePositionX","image_position_x",pl),Ot("imagePositionY","image_position_y",pl),Ot("imageBackgroundMode","image_background_mode"),Ot("imageBackgroundColor","image_background_color"),Ot("currency"),Ot("priceAmount","price_amount",pl),Ot("targetPrice","target_price"),Ot("targetCurrency","target_currency"),Ot("targetAmount","target_amount",pl),Ot("priceAlert","price_alert",md),Ot("priceTracking","price_tracking",md),Ot("availability","availability",md),Ot("availabilityTracking","availability_tracking",md),Ot("availabilityHistory","availability_history",md),Ot("archivedAt","archived_at",Rm),Ot("purchasedAt","purchased_at",Rm),Ot("createdAt","created_at",Rm)]),gO=e=>{if(e==="list"||e==="board")return"list";if(e==="product"||e==="item")return"product";throw new TypeError("Canonical sync equivalence requires a list or product entity type.")},FI=(e={})=>{const t=Number(e.syncRevision??e.revision);return Number.isSafeInteger(t)&&t>0?t:null},bO=(e,t)=>{const r=t.keys.find(a=>Pk(e,a));return r?e[r]:void 0}
14,vO=e=>e==="list"?fO:hO,_c=e=>{const t=String(e??"").trim();return t?Nd(t,"")||t.toUpperCase():""},yO=e=>String(e??"").trim()===xk,Vn=e=>lO.has(String(e??"").trim()),SO=e=>{const t=String(e??"").trim();return!t||Vn(t)?Ik:t},RS=(e,t)=>{const r=vO(e).reduce((a,s)=>{if(s.localKey!=="sortOrder"){const o=s.localKey==="imageUrl"?PE(t,{emptyValue:Ik,isPlaceholder:Vn}):bO(t,s);a[s.localKey]=s.normalize(o)}return a},{});return Object.fromEntries(Object.entries(r).map(([a,s])=>{if(e==="product"&&a==="currency"){const i=_g(s)||Cb(r.price);return[a,_c(i)]}return dO.has(a)?[a,_c(s)]:a==="imageUrl"?[a,String(s).startsWith("[image-reference-conflict:")?s:SO(s)]:[a,s]}))},Pl=(e={})=>RS("product",e),wO=(e,t)=>{const r=FI(e),a=FI(t);if(r===null||a===null||r!==a)throw new TypeError("Canonical equal-revision comparison requires the same valid server revision on both records.")},$I=(e,t)=>{const r=_k(e?.syncConflictPatch)?e.syncConflictPatch:null,a=uO.find(s=>r&&Pk(r,s));return a?{cloudValue:t==="cloud"?r[a]:void 0,field:"sortOrder",kind:"pending-reorder",localValue:t==="local"?r[a]:void 0,side:t}:null},CO=(e,t)=>JSON.stringify(e)===JSON.stringify(t),Ll=({cloudRecord:e={},entityType:t,localRecord:r={}}={})=>(wO(r,e),mC({cloudRecord:e,entityType:t,localRecord:r})),mC=({cloudRecord:e={},entityType:t,localRecord:r={}}={})=>{const a=gO(t),s=RS(a,r),o=RS(a,e),c=[...new Set([...Object.keys(s),...Object.keys(o)])].sort().filter(p=>!CO(s[p],o[p])).map(p=>({cloudValue:o[p],field:p,kind:"persisted-field",localValue:s[p]})),l=$I(r,"local"),u=$I(e,"cloud");return l&&c.push(l),u&&c.push(u),c},Ek=(e={})=>Ll(e).length===0,Ls=e=>String(e||"").trim(),fC=(e={},t={})=>e.fit===t.fit&&Number(e.scale)===Number(t.scale)&&Number(e.offsetX)===Number(t.offsetX)&&Number(e.offsetY)===Number(t.offsetY),hC=(e={},t={})=>JSON.stringify(Pl(e))===JSON.stringify(Pl(t)),xO=({mode:e="normal",product:t={}}={})=>{const r=zn(t.cardSize??t.card_size),a=vi(e,r),s=Nm({base:Zw(t),mode:e,overrides:t.imageFramingOverrides??t.image_framing_overrides,size:r}),o=SE(s),i=fC(s,o),c=i?ya(t.imageFramingOverrides??t.image_framing_overrides):wE(t.imageFramingOverrides??t.image_framing_overrides,a,o);return{candidate:i?t:{...t,imageFramingOverrides:c},contextKey:a,currentFraming:s,fittedFraming:o,noOp:i,product:t,size:r}},IO=({product:e={},userId:t=""}={})=>{const r=Ls(t),a=Number(e.syncRevision??e.revision);return!!(Ls(e.id)&&r&&Ls(e.userId??e.user_id)===r&&Ls(e.listId??e.list_id)&&Number.isSafeInteger(a)&&a>0)},AO=({acknowledgedProduct:e={},candidate:t={},contextKey:r="",expectedRevision:a,userId:s=""}={})=>{const o=Number(e.syncRevision??e.revision),i=Ls(s),c=Ls(t.listId??t.list_id),l=ya(e.imageFramingOverrides??e.image_framing_overrides)[r],u=ya(t.imageFramingOverrides??t.image_framing_overrides)[r];return!!(Ls(e.id)===Ls(t.id)&&i&&Ls(e.userId??e.user_id)===i&&c&&Ls(e.listId??e.list_id)===c&&Number.isSafeInteger(o)&&o===Number(a)+1&&fC(l,u)&&hC(e,t))},PO=({candidate:e={},durableProduct:t={},contextKey:r=""}={})=>{const a=ya(t.imageFramingOverrides??t.image_framing_overrides)[r],s=ya(e.imageFramingOverrides??e.image_framing_overrides)[r];return!!(Ls(t.id)===Ls(e.id)&&fC(a,s)&&hC(t,e))},_O=async(e,t)=>{let r;try{return await Promise.race([Promise.resolve().then(e),new Promise(a=>{r=setTimeout(()=>a({ok:!1,reason:"timeout",stop:!0}),Math.max(1,Number(t)||1))})])}finally{clearTimeout(r)}},EO=async({hasUsableImage:e=()=>!1,mode:t="normal",persistChange:r,products:a=[],resolveProduct:s=o=>o}={})=>{const o=[],i=[],c=[],l=Array.isArray(a)?a:[];for(let u=0;u<l.length;u+=1){const p=l[u],m=s(p)||p;if(!Ls(m?.id)){c.push({product:m,reason:"missing-identity"});continue}if(!e(m)){i.push({product:m,reason:"missing-image"});continue}const h=xO({mode:t,product:m});if(h.noOp){i.push({...h,reason:"already-fitted"});continue}let b;try{b=await r(h)}catch(v){b={error:v,ok:!1,reason:"persistence-failed"}}if(b?.ok&&b.product){o.push({...h,product:b.product});continue}if(c.push({...h,reason:b?.reason||"persistence-failed"}),b?.stop){l.slice(u+1).forEach(v=>{c.push({product:v,reason:"operation-stopped"})});break}}return{fitted:o,needsReview:c,skipped:i}},kO=()=>{let e=!1;return{isPending:()=>e,run:async t=>{if(e)return{accepted:!1,reason:"already-pending"};e=!0;try{return{accepted:!0,result:await t()}}finally{e=!1}}}},zI=(e,t,r=`${t}s`)=>`${e} ${e===1?t:r}`,NO=({fitted:e=[],needsReview:t=[],skipped:r=[]}={})=>{const a=[];return e.length&&a.push(zI(e.length,"image fitted","images fitted")),r.length&&a.push(zI(r.length,"skipped","skipped")),t.length&&a.push(`${t.length} ${t.length===1?"needs":"need"} review`),a.join(" · ")||"No images needed fitting"},jO=new Set(["editor","viewer"]),VI={editor:0,viewer:1},gC=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,kk=256,RO=240,HI=160,LO=8192,Ch="Collaborative boards could not load. Please try again.",xc=(e,t)=>{if(typeof e!="string")return"";const r=e.trim();return r&&r.length<=t?r:""},LS=(e,t)=>e==null||e===""?"":xc(e,t),WI=e=>{const t=LS(e,LO);if(!t)return"";
14try{const r=new URL(t);return r.protocol==="https:"||r.protocol==="http:"?r.toString():""}catch{return""}},GI=e=>{if(typeof e!="number"&&typeof e!="string")return null;const t=typeof e=="string"?e.trim():e;if(t==="")return null;const r=Number(t);return Number.isSafeInteger(r)&&r>=0?r:null},qI=e=>{if(typeof e!="string"||!e.trim())return"";const t=Date.parse(e);return Number.isFinite(t)?new Date(t).toISOString():""},Nk=(e,t)=>{const r=xc(e,64).toLowerCase(),a=xc(t,kk);return!gC.test(r)||!a?"":JSON.stringify([r,a])},BO=(e,t)=>{if(!e||typeof e!="object"||Array.isArray(e))return null;const r=xc(e.owner_id,64).toLowerCase(),a=xc(e.board_id,kk),s=xc(e.access_role,16).toLowerCase(),o=xc(e.board_title,RO),i=GI(e.item_count),c=GI(e.active_collaborator_count),l=qI(e.shared_at),u=qI(e.updated_at),p=Nk(r,a);return!p||r===t||!jO.has(s)||!o||typeof e.is_public!="boolean"||i===null||c===null||!l||!u?null:{boardId:a,collaboratorCount:c,compositeKey:p,coverImageUrl:WI(e.cover_image_url),isPublic:e.is_public,itemCount:i,ownerAvatarUrl:WI(e.owner_avatar_url),ownerDisplayName:LS(e.owner_display_name,HI),ownerId:r,ownerUsername:LS(e.owner_username,HI).replace(/^@+/,""),role:s,sharedAt:l,title:o,updatedAt:u}},TO=(e,t)=>{const r=VI[e.role],a=VI[t.role];return a!==r?a<r:t.updatedAt>e.updatedAt},BS=(e=[])=>{const t=new Map;for(const r of Array.isArray(e)?e:[]){const a=Nk(r?.ownerId,r?.boardId);if(!a||a!==r?.compositeKey)continue;const s=t.get(a);(!s||TO(s,r))&&t.set(a,r)}return t},DO=(e,t)=>{const r=xc(t,64).toLowerCase();if(!gC.test(r)||!Array.isArray(e))return null;const a=e.map(s=>BO(s,r)).filter(Boolean);return Array.from(BS(a).values())},OO=(e,t)=>t?.ok?Array.from(BS(t.boards).values()):Array.from(BS(e).values()),MO=async({client:e,isConfigured:t=!0,userId:r}={})=>{const a=xc(r,64).toLowerCase();if(!gC.test(a))return{boards:[],error:"",ok:!0,skipped:!0};if(!t||!e||typeof e.rpc!="function")return{boards:[],error:Ch,ok:!1,reason:"rpc-unavailable",skipped:!1};try{const{data:s,error:o}=await e.rpc("get_accessible_boards");if(o)return{boards:[],error:Ch,ok:!1,reason:"rpc-error",skipped:!1};const i=DO(s,a);return i?{boards:i,error:"",ok:!0,skipped:!1}:{boards:[],error:Ch,ok:!1,reason:"malformed-response",skipped:!1}}catch{return{boards:[],error:Ch,ok:!1,reason:"rpc-error",skipped:!1}}},UO=e=>{const t=String(e?.user?.id||"").trim();return t&&e?.access_token?t:""},bC="Board collaboration is not available yet.",FO="Sign in to manage board collaboration.",jd=e=>Array.isArray(e)?e:e?[e]:[],Bc=e=>jd(e)[0]||null,$O=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?Math.trunc(t):0},Eg=(e={},t="")=>({avatarUrl:e[`${t}_avatar_url`]||e[`${t}AvatarUrl`]||"",displayName:e[`${t}_display_name`]||e[`${t}DisplayName`]||"",username:e[`${t}_username`]||e[`${t}Username`]||""}),zO=(e="")=>{const t=String(e||"").trim().toLowerCase();return["inbound","incoming","recipient","received"].includes(t)?"received":["outbound","outgoing","owner","sent"].includes(t)?"sent":t},VO=(e="")=>String(e||"").trim().toLowerCase(),yf=(e=null)=>e?{acceptedAt:e.accepted_at||e.acceptedAt||"",boardId:e.board_id||e.boardId||"",boardTitle:e.board_title||e.boardTitle||"",createdAt:e.created_at||e.createdAt||"",declinedAt:e.declined_at||e.declinedAt||"",direction:zO(e.direction||e.invite_direction||e.inviteDirection||""),expiredAt:e.expired_at||e.expiredAt||"",expiresAt:e.expires_at||e.expiresAt||"",id:e.invite_id||e.inviteId||e.id||"",invited:Eg(e,"invited"),owner:Eg(e,"owner"),ownerId:e.owner_id||e.ownerId||"",revokedAt:e.revoked_at||e.revokedAt||"",role:lo(e.role),status:VO(e.status||"")}:null,vC=(e=null)=>e?{boardId:e.board_id||e.boardId||"",boardTitle:e.board_title||e.boardTitle||"",collaboratorUserId:e.collaborator_user_id||e.collaboratorUserId||"",createdAt:e.created_at||e.createdAt||"",profile:Eg(e,"collaborator"),role:lo(e.role),status:e.status||"",updatedAt:e.updated_at||e.updatedAt||""}:null,HO=(e=null)=>e?{boardDescription:e.board_description||e.boardDescription||"",boardId:e.board_id||e.boardId||"",boardTitle:e.board_title||e.boardTitle||"",coverImageUrl:e.cover_image_url||e.coverImageUrl||"",itemCount:$O(e.item_count??e.itemCount),owner:Eg(e,"owner"),ownerId:e.owner_id||e.ownerId||"",role:lo(e.access_role||e.role),sharedAt:e.shared_at||e.sharedAt||"",updatedAt:e.updated_at||e.updatedAt||""}:null,Ab=(e=null)=>
14e?{boardId:e.board_id||e.boardId||"",brand:e.brand||"",createdAt:e.created_at||e.createdAt||"",id:e.item_id||e.itemId||e.id||"",imageUrl:e.image_url||e.imageUrl||"",price:e.price||"",revision:Number.isSafeInteger(Number(e.revision))&&Number(e.revision)>0?Number(e.revision):null,sortOrder:Number.isFinite(Number(e.sort_order??e.sortOrder))?Number(e.sort_order??e.sortOrder):0,source:e.source||"",status:e.status||"active",title:e.title||"",updatedAt:e.updated_at||e.updatedAt||"",url:e.url||""}:null,jk=(e,t="Could not update board collaboration.")=>{const r=String(e?.message||"").toLowerCase(),a=String(e?.code||"").toLowerCase();return a==="28000"||r.includes("not_authenticated")?FO:r.includes("cannot_invite_self")?"You cannot invite yourself to your own board.":r.includes("collaboration_invite_exists")?"This invite is already pending.":r.includes("collaborator_already_active")?"This person is already a collaborator.":r.includes("profile_not_found")?"No profile was found for that username.":r.includes("shared_board_view_only")?"You have view-only access to this board.":r.includes("shared_board_unavailable")?"This board is no longer shared with you.":r.includes("invalid_collaborator_role")?"Choose Editor or Viewer.":r.includes("collaboration_invite_cooldown")?"This person was recently uninvited. Try again in a few minutes.":r.includes("collaboration_board_pending_limit")||r.includes("collaboration_owner_pending_limit")?"Too many invites are pending. Revoke some before inviting more.":r.includes("invite_expired")||r.includes("collaboration_invite_stale")?"This invite has expired.":r.includes("board_collaboration_retry")||r.includes("collaboration_invite_retry")?"The board is busy. Try again in a moment.":r.includes("board_collaboration_parent_unavailable")?"This board is no longer available.":r.includes("board_not_found")||r.includes("invite_not_found")||a==="p0002"?"This board collaboration is not available anymore.":r.includes("collaborator_not_active")?"You no longer have edit access to this shared board.":r.includes("shared_board_not_found")||r.includes("shared_item_not_found")?"This shared board item is not available anymore.":r.includes("invalid_item_title")||r.includes("invalid_item_payload")||r.includes("invalid_item_status")||r.includes("invalid_shared_item")||r.includes("invalid_shared_item_order")?"Check the item details and try again.":a==="42p01"||a==="42703"||a==="42883"||a==="42501"||r.includes("board_collaboration")||r.includes("permission")||r.includes("row-level security")||r.includes("schema cache")?bC:t},Ma=async(e,t={},r)=>{if(!An.isConfigured||!ae)return{data:null,error:bC,ok:!1};let a=null,s=null;try{({data:a,error:s}=await ae.rpc(e,t))}catch(o){s=o||new Error("board-collaboration-rpc-failed")}return s?{data:null,error:jk(s,r),ok:!1}:{data:a,error:"",ok:!0}},Sf=(e={})=>({p_board_id:String(e?.boardId||"").trim(),p_owner_id:String(e?.ownerId||"").trim()}),Rk=e=>{const t=String(e||"").trim().replace(/^@+/,"");return t.length<=80&&t.replace(/[^\p{L}\p{N}]/gu,"").length>=2},WO=async e=>{const t=String(e||"").trim().replace(/^@+/,"");if(!Rk(t))return{people:[],error:""};const r=await Ma("search_public_profiles",{q:t,limit_count:7,for_collaboration:!0},"Could not find people.");return{error:r.error,people:jd(r.data).filter(a=>a.user_id&&a.username).slice(0,7).map(a=>({userId:a.user_id,username:a.username,displayName:a.display_name||"",avatarUrl:a.avatar_url||"",following:a.following===!0,followsYou:a.follows_you===!0}))}},GO=async(e,t)=>{if(!t)return{ok:!1,error:"Choose an account first."};const r=await Ma("create_board_collaboration_invite",{p_board_id:String(e||"").trim(),p_role:"editor",p_invited_user_id:t},"Could not invite this collaborator.");return{ok:r.ok,error:r.error}},Lk=async(e,t,r="editor")=>{const a=Xa(t),s=no(a);if(s)return{error:s,invite:null,ok:!1};const o=await Ma("invite_board_collaborator_by_username",{p_board_id:String(e||"").trim(),p_role:lo(r),p_username:a},"Could not invite this collaborator.");return{error:o.error,invite:yf(Bc(o.data)),ok:o.ok}},qO=async e=>{const t=await Ma("accept_board_collaboration_invite",{p_invite_id:e},"Could not accept this invite.");return{error:t.error,invite:yf(Bc(t.data)),ok:t.ok}},YO=async e=>{const t=await Ma("decline_board_collaboration_invite",{p_invite_id:e},"Could not decline this invite.");return{error:t.error,invite:yf(Bc(t.data)),ok:t.ok}},KO=async e=>{const t=await Ma("revoke_board_collaboration_invite",{p_invite_id:e},"Could not revoke this invite.");return{error:t.error,invite:yf(Bc(t.data)),ok:t.ok}},XO=async(e,t)=>{const r=await Ma("remove_board_collaborator",{p_board_id:String(e||"").trim(),p_collaborator_user_id:t},"Could not remove this collaborator.");return{collaborator:vC(Bc(r.data)),error:r.error,ok:r.ok}},Bk=async()=>{const e=await Ma("get_board_collaboration_invites",{},"Could not load board collaboration invites.");
14return{error:e.error,invites:jd(e.data).map(yf).filter(Boolean),ok:e.ok}},JO=async(e,t="")=>{const r=String(t||"").trim(),a=await Ma("get_board_collaborators",r?{p_board_id:String(e||"").trim(),p_owner_id:r}:{p_board_id:String(e||"").trim()},"Could not load board collaborators.");return{collaborators:jd(a.data).map(vC).filter(Boolean),error:a.error,ok:a.ok}},QO=async(e,t,r)=>{const a=await Ma("update_board_collaborator_role",{p_board_id:String(e||"").trim(),p_collaborator_user_id:t,p_role:lo(r)},"Could not change this collaborator's role.");return{collaborator:vC(Bc(a.data)),error:a.error,ok:a.ok}},ZO=async e=>{const t=String(e||"").trim();if(!t)return{available:!1,error:"This board collaboration is not available anymore.",ok:!1};if(!An.isConfigured||!ae)return{available:!1,error:bC,ok:!1};let r=null,a=null;try{({data:r,error:a}=await ae.from("lists").select("id").eq("id",t).maybeSingle())}catch(s){a=s||new Error("board-collaboration-availability-failed")}return a?{available:!1,error:jk(a,"Could not check board collaboration."),ok:!1}:{available:!!r?.id,error:"",ok:!0}},YI=async()=>{const e=await Ma("get_accessible_boards",{},"Could not load shared boards.");return{boards:jd(e.data).filter(t=>["editor","viewer"].includes(String(t?.access_role||"").toLowerCase())).map(HO).filter(Boolean),error:e.error,ok:e.ok}},eM=async e=>{if(!sC(e))return{error:$E,items:[],ok:!1};const t=await Ma("get_shared_board_items",Sf(e),"Could not load shared board items.");return{error:t.error,items:jd(t.data).map(Ab).filter(Boolean),ok:t.ok}},by=async(e,t={})=>{const r=await Ma("shared_board_add_item",{...Sf(e),p_item:t},"Could not add this shared board item.");return{error:r.error,item:Ab(Bc(r.data)),ok:r.ok}},tM=async(e,t,r={})=>{const a=Number(t?.revision);if(!Number.isSafeInteger(a)||a<=0)return{conflict:!1,error:"Refresh the board before editing this item.",item:null,ok:!1};const s=await Ma("shared_board_update_item",{...Sf(e),p_expected_revision:a,p_item_id:String(t?.id||"").trim(),p_patch:r},"Could not update this shared board item."),o=Bc(s.data),i=!!o?.conflict,c=s.ok&&o?.ok===!0;return{conflict:i,error:s.error||(c?"":i?"This item changed elsewhere. It has been refreshed.":"This item is no longer on the board."),item:o?.item_id?Ab(o):null,ok:c}},rM=async(e,t)=>{const r=Number(t?.revision);if(!Number.isSafeInteger(r)||r<=0)return{conflict:!1,error:"Refresh the board before removing this item.",ok:!1};const a=await Ma("shared_board_trash_item",{...Sf(e),p_expected_revision:r,p_item_id:String(t?.id||"").trim()},"Could not move this shared board item to Trash."),s=Bc(a.data),o=a.ok&&s?.ok===!0,i=!!s?.conflict;return{conflict:i,error:a.error||(o?"":i?"This item changed elsewhere. It has been refreshed.":"This item is no longer on the board."),ok:o,outcome:String(s?.outcome||"")}},nM=async(e,t=[])=>{const r=await Ma("shared_board_reorder_items",{...Sf(e),p_item_ids:Array.isArray(t)?t.map(a=>String(a||"").trim()):[]},"Could not reorder shared board items.");return{error:r.error,items:jd(r.data).map(Ab).filter(Boolean),ok:r.ok}};function TS({person:e}){const t=cp(e);return n.jsxs(n.Fragment,{children:[n.jsx("span",{className:"collaboratorAvatar","aria-hidden":"true",children:t?n.jsx("img",{alt:"",src:t,onError:r=>{r.currentTarget.hidden=!0}}):(e.displayName||e.username).slice(0,1).toUpperCase()}),n.jsxs("span",{className:"collaboratorIdentity",children:[n.jsx("strong",{children:e.displayName||e.username}),n.jsxs("small",{children:["@",e.username]})]})]})}function aM({currentUserId:e,currentUsername:t,addedUsers:r,disabled:a,onAdd:s}){const o=d.useId(),i=d.useRef(null),c=d.useRef(null),l=d.useRef(0),[u,p]=d.useState(""),[m,f]=d.useState(null),[h,b]=d.useState([]),[v,S]=d.useState("idle"),[C,I]=d.useState(!1),[A,k]=d.useState(-1),[E,y]=d.useState(!1),N=u.trim().replace(/^@+/,""),_=Rk(N),P=Xa(N),V=D=>D.userId&&D.userId===e||t&&D.username===t?"You · Cannot invite yourself":r.some(K=>D.userId&&K.userId===D.userId||K.username===D.username)?"Already added":"",L=V({username:P}),z=!no(P),B=C&&!m&&_;d.useEffect(()=>{const D=K=>{c.current?.contains(K.target)||I(!1)};return document.addEventListener("pointerdown",D,!0),()=>document.removeEventListener("pointerdown",D,!0)},[]),d.useEffect(()=>{const D=++l.current;if(b([]),k(-1),!_||m||E||a||!e){S("idle");return}S("loading");const K=setTimeout(async()=>{const ee=await WO(N);D===l.current&&(b(ee.people),S(ee.error?"error":"ready"))},180);return()=>{clearTimeout(K),++l.current}},[u,N,_,m,E,a,e]),d.useEffect(()=>{B&&A>=0&&document.getElementById(`${o}-option-${A}`)?.scrollIntoView({block:"nearest"})},[A,B,o]);const re=D=>{!D||V(D)||a||(++l.current,f(D),p(`@${D.username}`),I(!1),k(-1))},Z=D=>
14{if(!(D.nativeEvent.isComposing||E))if(D.key==="Escape"&&C)D.preventDefault(),D.stopPropagation(),I(!1);else if(D.key==="ArrowDown"||D.key==="ArrowUp"){if(m||!_)return;D.preventDefault(),I(!0);const K=D.key==="ArrowDown"?1:-1;let ee=A<0?K>0?-1:h.length:A;for(let J=0;J<h.length;J+=1)if(ee=(ee+K+h.length)%h.length,!V(h[ee])){k(ee);break}}else D.key==="Enter"?(D.preventDefault(),B&&A>=0&&re(h[A])):D.key==="Tab"&&I(!1)};return n.jsxs("div",{ref:c,className:"collaboratorPicker",onBlur:D=>{D.relatedTarget&&!D.currentTarget.contains(D.relatedTarget)&&I(!1)},children:[n.jsxs("div",{className:"createBoardInviteEntry",children:[n.jsx("input",{ref:i,id:`${o}-search`,type:"search",name:"collaborator-search",role:"combobox","aria-label":"Find collaborators","aria-autocomplete":"list","aria-haspopup":"listbox","aria-controls":B?`${o}-results`:void 0,"aria-expanded":B,"aria-activedescendant":B&&A>=0?`${o}-option-${A}`:void 0,"aria-describedby":m?`${o}-selected`:void 0,autoComplete:"off",autoCapitalize:"none",autoCorrect:"off",spellCheck:!1,placeholder:"Search people",maxLength:80,disabled:a,value:u,onCompositionStart:()=>y(!0),onCompositionEnd:()=>y(!1),onFocus:()=>{!m&&_&&I(!0)},onChange:D=>{++l.current,p(D.target.value),f(null),b([]),k(-1),I(!0)},onKeyDown:Z}),n.jsx("button",{type:"button",disabled:a||!m||!!V(m),onClick:()=>{!m||V(m)||(s(m),f(null),p(""),I(!1),i.current?.focus())},children:"Add"})]}),m?n.jsxs("div",{className:"collaboratorSelected",id:`${o}-selected`,role:"status",children:[n.jsx(TS,{person:m}),n.jsx("span",{className:"collaboratorContext",children:"Selected"})]}):null,B?n.jsxs("div",{className:"collaboratorSuggestions",children:[n.jsx("div",{id:`${o}-results`,role:"listbox","aria-label":"Matching accounts","aria-busy":v==="loading",children:h.map((D,K)=>{const ee=V(D),J=ee||(D.following&&D.followsYou?"Following · Follows you":D.following?"Following":D.followsYou?"Follows you":"");return n.jsxs("div",{id:`${o}-option-${K}`,role:"option","aria-selected":A===K,"aria-disabled":!!ee,className:`collaboratorOption${A===K?" isActive":""}`,onMouseDown:fe=>fe.preventDefault(),onClick:()=>re(D),children:[n.jsx(TS,{person:D}),J?n.jsx("span",{className:"collaboratorContext",children:J}):null]},D.userId)})}),n.jsx("p",{className:"collaboratorSearchStatus",role:"status",children:v==="loading"?"Finding people…":v==="error"?"Could not find people. Edit your search to try again.":h.length?"Public accounts · Choose one, then Add.":"No matching public accounts."})]}):null,!m&&_?n.jsxs("details",{className:"collaboratorExactInvite",children:[n.jsx("summary",{children:"Know their exact username?"}),n.jsx("p",{children:"Suggestions show public accounts only. Queue a complete username to invite when you create this board. No private account details are looked up or shown."}),n.jsxs("button",{type:"button",disabled:a||!z||!!L,onClick:()=>{!z||L||(s({kind:"exact",username:P}),p(""),I(!1),i.current?.focus())},children:["Queue exact @",P]}),L?n.jsx("p",{role:"status",children:L}):null]}):null]})}const sM=192,Tk=24,Dk=38,oM=.08,iM=1.12,cM=4,rd=(e,t,r)=>Math.min(r,Math.max(t,e)),lM=(e="")=>{const t=String(e).trim().match(/^#([0-9a-f]{6})$/i);if(!t)return null;const r=t[1];return{r:Number.parseInt(r.slice(0,2),16),g:Number.parseInt(r.slice(2,4),16),b:Number.parseInt(r.slice(4,6),16)}},Ok=(e,t)=>Math.hypot(e.r-t.r,e.g-t.g,e.b-t.b),Mk=(e,t)=>({r:e[t],g:e[t+1],b:e[t+2],a:e[t+3]}),dM=e=>{if(!e.length)return null;const t=e.reduce((r,a)=>({r:r.r+a.r,g:r.g+a.g,b:r.b+a.b}),{r:0,g:0,b:0});return{r:t.r/e.length,g:t.g/e.length,b:t.b/e.length}},uM=({data:e,width:t,height:r})=>{const a=[],s=Math.max(1,Math.floor(t*.04)),o=Math.max(1,Math.floor(r*.04));if([[0,0],[t-1,0],[0,r-1],[t-1,r-1],[s,o],[t-1-s,o],[s,r-1-o],[t-1-s,r-1-o],[Math.floor(t/2),0],[Math.floor(t/2),r-1],[0,Math.floor(r/2)],[t-1,Math.floor(r/2)]].forEach(([l,u])=>{const p=Mk(e,(u*t+l)*4);p.a>Tk&&a.push(p)}),!a.length)return null;const c=a.map(l=>{const u=a.filter(p=>Ok(l,p)<=Dk);return{average:dM(u),count:u.length}}).sort((l,u)=>u.count-l.count);return c[0]?.count>=3?c[0].average:null},KI=(e,t,r=.003)=>{if(!t)return null;const a=Math.max(1,t*r);let s=0,o=0;for(;o<e.length-1&&s+e[o]<=a;)s+=e[o],o+=1;let i=0,c=e.length-1;for(;c>o&&i+e[c]<=a;)i+=e[c],c-=1;return{start:o,end:c}},pM=({data:e,width:t,height:r,backgroundColor:a="",alphaThreshold:s=Tk,backgroundTolerance:o=Dk}={})=>
14{if(!e||!Number.isFinite(t)||!Number.isFinite(r)||t<2||r<2)return{ok:!1,reason:"invalid-image-data"};const i=lM(a)||uM({data:e,width:t,height:r});if(!i)return{ok:!1,reason:"background-unavailable"};const c=new Uint8Array(t*r);let l=0;for(let v=0;v<t*r;v+=1){const S=Mk(e,v*4);if(S.a<=s)continue;const C=S.a/255,I={r:i.r+(S.r-i.r)*C,g:i.g+(S.g-i.g)*C,b:i.b+(S.b-i.b)*C};Ok(I,i)>o&&(c[v]=1,l+=1)}const u=Math.max(12,Math.round(t*r*.0015));if(l<u)return{ok:!1,reason:"insufficient-content",backgroundColor:i};const p=new Uint32Array(r),m=new Uint32Array(t);let f=0;for(let v=0;v<r;v+=1)for(let S=0;S<t;S+=1){const C=v*t+S;if(!c[C])continue;let I=0;for(let A=-1;A<=1;A+=1){const k=v+A;if(!(k<0||k>=r))for(let E=-1;E<=1;E+=1){if(E===0&&A===0)continue;const y=S+E;y>=0&&y<t&&c[k*t+y]&&(I+=1)}}I<2||(p[v]+=1,m[S]+=1,f+=1)}if(f<u)return{ok:!1,reason:"content-was-noise",backgroundColor:i};const h=KI(m,f),b=KI(p,f);return!h||!b||h.end<=h.start||b.end<=b.start?{ok:!1,reason:"content-bounds-unavailable",backgroundColor:i}:{ok:!0,reason:"content-bounds-detected",backgroundColor:i,bounds:{x:h.start,y:b.start,width:h.end-h.start+1,height:b.end-b.start+1},imageWidth:t,imageHeight:r,contentPixelRatio:f/(t*r)}},mM=({bounds:e,imageWidth:t,imageHeight:r,frameAspectRatio:a,safetyMarginRatio:s=oM,minimumAutoScale:o=iM,maximumScale:i=cM}={})=>{if(!e||!Number.isFinite(t)||!Number.isFinite(r)||!Number.isFinite(a)||t<=0||r<=0||a<=0)return{ok:!1,reason:"invalid-framing-input"};const c=e.width*s,l=e.height*s,u=rd(e.x-c,0,t),p=rd(e.y-l,0,r),m=rd(e.x+e.width+c,0,t),f=rd(e.y+e.height+l,0,r),h=Math.max(1,m-u),b=Math.max(1,f-p),v=u+h/2,S=p+b/2,C=a,I=1,A=Math.max(C/t,I/r),k=Math.min(C/(A*h),I/(A*b)),E=rd(k,1,i);if(E<o)return{ok:!0,reason:"already-tightly-framed",imageFit:"cover",imageScale:1,imagePositionX:50,imagePositionY:50,expandedBounds:{x:u,y:p,width:h,height:b}};const y=t*A,N=r*A,_=C-E*y,P=I-E*N,V=Math.abs(_)<1e-6?.5:(C/2-E*A*v)/_,L=Math.abs(P)<1e-6?.5:(I/2-E*A*S)/P;return{ok:!0,reason:"embedded-margins-framed",imageFit:"cover",imageScale:Number(E.toFixed(3)),imagePositionX:Number((rd(V,0,1)*100).toFixed(1)),imagePositionY:Number((rd(L,0,1)*100).toFixed(1)),expandedBounds:{x:u,y:p,width:h,height:b}}},fM=(e={})=>{const t=pM(e);if(!t.ok)return t;const r=mM({bounds:t.bounds,imageWidth:t.imageWidth,imageHeight:t.imageHeight,frameAspectRatio:e.frameAspectRatio,safetyMarginRatio:e.safetyMarginRatio});return{...t,...r,bounds:t.bounds}},Uk=40,Fk=(e="")=>String(e||"").trim().replace(/^@+/,"").toLowerCase(),hM=(e=null)=>{const t=Fk(e?.username);return t?{avatarPath:String(e?.avatar_path??e?.avatarPath??"").trim(),avatarUrl:String(e?.avatar_url??e?.avatarUrl??"").trim(),displayName:String(e?.display_name??e?.displayName??"").trim(),followedAt:String(e?.followed_at??e?.followedAt??""),isViewer:!!(e?.is_viewer??e?.isViewer),username:t,viewerIsFollowing:!!(e?.viewer_is_following??e?.viewerIsFollowing)}:null},gM=(e=[],{pageSize:t=Uk}={})=>{const r=new Set,a=(Array.isArray(e)?e:[]).map(hM).filter(o=>o&&!r.has(o.username)&&r.add(o.username)),s=a[a.length-1]||null;return{hasMore:a.length>=Math.max(1,t),nextCursor:s?.followedAt||"",rows:a}},bM=(e=[],t="",r=!1)=>{const a=Fk(t);return e.map(s=>s.username===a?{...s,viewerIsFollowing:!!r}:s)},vM=({isViewer:e=!1,viewerIsFollowing:t=!1}={},{isPending:r=!1}={})=>e?"":r?"…":t?"Following":"Follow",Pb="Social follows are not available yet.",yM="Could not load profile social summary.",SM="Could not follow this profile.",wM="Could not unfollow this profile.",Lm=(e={})=>({canFollow:!1,error:null,followersCount:0,followingCount:0,isPrivate:null,viewerIsFollowing:!1,...e}),XI=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?Math.trunc(t):0},yC=e=>Array.isArray(e)?e[0]||null:e||null,_b=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="42p01"||r==="42703"||r==="42883"||r==="42501"||t.includes("schema cache")||t.includes("profile_follows")||t.includes("follow_public_profile")||t.includes("unfollow_public_profile")||t.includes("get_public_profile_social_summary")||t.includes("permission")||t.includes("row-level security")?Pb:""},CM=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="28000"||t.includes("not_authenticated")?"Sign in to follow profiles.":t.includes("follow_rate_limited")?"Please wait a moment before trying again.":t.includes("cannot_follow_self")||t.includes("self")?"You cannot follow yourself.":r==="p0002"||t.includes("public_profile_not_found")||t.includes("private")?"This profile is private.":_b(e)||SM},xM=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to manage followed profiles.":t.includes("follow_rate_limited")?"Please wait a moment before trying again.":_b(e)||wM},$k=async e=>{if(!An.isConfigured||!ae)return{error:Pb,user:null};let t=null,r=null;try{({data:t,error:r}=await ae.auth.getSession())}catch(s){r=s||new Error("profile-follow-user-load-failed")}const a=t?.session?.user||null;return r||!a?.id?{error:e,user:null}:{error:"",user:a}},SC=(e=null)=>e?Lm({canFollow:!!(e.can_follow??e.canFollow),followersCount:XI(e.followers_count??e.followersCount),followingCount:XI(e.following_count??e.followingCount),isPrivate:!1,viewerIsFollowing:!!(e.viewer_is_following??e.viewerIsFollowing)}):Lm(),Ym=async e=>{const t=Xa(e),r=no(t);if(r)return Lm({error:r});if(!An.isConfigured||!ae)return Lm({error:Pb});let a=null,s=null;try{({data:a,error:s}=await ae.rpc("get_public_profile_social_summary",{profile_username:t}))}catch(o){s=o||new Error("profile-social-summary-load-failed")}return s?Lm({error:_b(s)||yM}):SC(yC(a))},zk=async e=>{const t=Xa(e),r=no(t);if(r)return{error:r,ok:!1};const a=await $k("Sign in to follow profiles.");if(a.error)return{error:a.error,ok:!1};const s=await Ym(t);if(s.error)return{error:s.error,ok:!1};if(s.viewerIsFollowing)return{alreadyFollowing:!0,ok:!0,summary:s};let o=null,i=null;try{({data:o,error:i}=await ae.rpc("follow_public_profile",{profile_username:t}))}catch(c){i=c||new Error("profile-follow-failed")}return i?{error:CM(i),ok:!1}:{ok:!0,summary:SC(yC(o))}},Vk=async e=>{const t=Xa(e),r=no(t);if(r)return{error:r,ok:!1};const a=await $k("Sign in to manage followed profiles.");if(a.error)return{error:a.error,ok:!1};let s=null,o=null;try{({data:s,error:o}=await ae.rpc("unfollow_public_profile",{profile_username:t}))}catch(i){o=i||new Error("profile-unfollow-failed")}return o?{error:xM(o),ok:!1}:{ok:!0,summary:SC(yC(s))}},IM="Could not load this list.",Hk=async(e,t,{before:r="",pageSize:a=Uk}={})=>{const s=Xa(t),o=no(s);if(o)return{error:o,hasMore:!1,nextCursor:"",rows:[]};if(!An.isConfigured||!ae)return{error:Pb,hasMore:!1,nextCursor:"",rows:[]};let i=null,c=null;try{({data:i,error:c}=await ae.rpc(e,{before_followed_at:r||null,page_limit:a,profile_username:s}))}catch(l){c=l||new Error("profile-social-list-load-failed")}return c?{error:_b(c)||IM,hasMore:!1,nextCursor:"",rows:[]}:{error:"",...gM(i,{pageSize:a})}},AM=(e,t)=>Hk("get_public_profile_followers",e,t),PM=(e,t)=>Hk("get_public_profile_following",e,t),_l=Object.freeze({BOARD_CREATED_PUBLIC:"board_created_public",BOARD_MADE_PUBLIC:"board_made_public",ITEM_ADDED_TO_PUBLIC_BOARD:"item_added_to_public_board"}),_M=Object.freeze(Object.values(_l)),Wk="Public activity is not available yet.",EM="Could not record activity.",kM="Could not load following activity.",kg="This activity cannot be shared.",NM=new Set(["auth_id","email","local_board_id","local_item_id","notes","private_notes","profile_id","user_id"]),Ic=e=>String(e||"").trim(),eo=e=>Ic(e)||null,wC=e=>Ic(e).toLowerCase(),jM=e=>{const t=Number(e);return Number.isFinite(t)?Math.min(100,Math.max(1,Math.trunc(t))):30},RM=e=>e?e instanceof Date?Number.isNaN(e.getTime())?null:e.toISOString():Ic(e)||null:null,Gk=e=>!!(e&&typeof e=="object"&&!Array.isArray(e)),LM=e=>e==null?"":Gk(e)?Object.keys(e).some(t=>
14NM.has(t))?kg:"":kg,CC=e=>Gk(e)?e:{},BM=e=>Array.isArray(e)?e[0]||null:e||null,qk=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="42p01"||r==="42703"||r==="42883"||r==="42501"||t.includes("schema cache")||t.includes("profile_activity")||t.includes("create_profile_activity")||t.includes("get_following_activity")||t.includes("permission")||t.includes("row-level security")?Wk:""},TM=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="28000"||t.includes("not_authenticated")?"Sign in to create activity.":r==="22023"||t.includes("unsupported_profile_activity_event")||t.includes("unsafe_profile_activity_metadata")||t.includes("invalid_profile_activity_metadata")||t.includes("public_board_required")||t.includes("public_item_required")||t.includes("public_item_not_allowed_for_event")||t.includes("check constraint")?kg:qk(e)||EM},DM=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to see following activity.":qk(e)||kM},Yk=async e=>{if(!An.isConfigured||!ae)return{error:Wk,user:null};let t=null,r=null;try{({data:t,error:r}=await ae.auth.getSession())}catch(s){r=s||new Error("profile-activity-user-load-failed")}const a=t?.session?.user||null;return r||!a?.id?{error:e,user:null}:{error:"",user:a}},OM=(e=null)=>e?{boardId:eo(e.board_id??e.boardId),createdAt:Ic(e.created_at??e.createdAt),eventType:wC(e.event_type??e.eventType),id:Ic(e.id),itemId:eo(e.item_id??e.itemId),metadata:CC(e.metadata)}:null,MM=(e=null)=>e?{actorAvatarUrl:eo(e.actor_avatar_url??e.actorAvatarUrl),actorId:null,actorName:Ic(e.actor_display_name??e.actorDisplayName)||"Saveboard user",actorUsername:Ic(e.actor_username??e.actorUsername).replace(/^@+/,""),boardDescription:eo(e.board_description??e.boardDescription),boardId:eo(e.board_id??e.boardId),boardTitle:eo(e.board_title??e.boardTitle),createdAt:Ic(e.created_at??e.createdAt),eventType:wC(e.event_type??e.eventType),id:Ic(e.event_id??e.id),itemId:eo(e.item_id??e.itemId),itemImageUrl:eo(e.item_image_url??e.itemImageUrl),itemSourceLabel:eo(e.item_source_label??e.itemSourceLabel),itemSourceUrl:eo(e.item_source_url??e.itemSourceUrl),itemTitle:eo(e.item_title??e.itemTitle),metadata:CC(e.metadata)}:null,Kk=async({boardId:e=null,dedupeKey:t="",eventType:r="",itemId:a=null,metadata:s={}}={})=>{const o=wC(r);if(!_M.includes(o))return{error:kg,ok:!1};const i=LM(s);if(i)return{error:i,ok:!1};const c=await Yk("Sign in to create activity.");if(c.error)return{error:c.error,ok:!1};let l=null,u=null;try{({data:l,error:u}=await ae.rpc("create_profile_activity",{p_board_id:e||null,p_dedupe_key:eo(t),p_event_type:o,p_item_id:a||null,p_metadata:CC(s)}))}catch(p){u=p||new Error("profile-activity-create-failed")}return u?{error:TM(u),ok:!1}:{activity:OM(BM(l)),ok:!0}},UM=async({before:e=null,limit:t=30}={})=>{const r=await Yk("Sign in to see following activity.");if(r.error)return{activities:[],error:r.error};let a=null,s=null;try{({data:a,error:s}=await ae.rpc("get_following_activity",{before_timestamp:RM(e),limit_count:jM(t)}))}catch(o){s=o||new Error("following-activity-load-failed")}return s?{activities:[],error:DM(s)}:{activities:Array.isArray(a)?a.map(MM).filter(Boolean):[],error:""}},Xk="Public board likes are not available right now.",Jk="Sign in to like public boards.",Qk="This board is not available to like.",FM=e=>Array.isArray(e)?e[0]||null:e||null,$M=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?Math.trunc(t):0},zM=(e=null,t={})=>({likeCount:$M(e?.like_count??e?.likeCount??t.likeCount),viewerHasLiked:!!(e?.viewer_has_liked??e?.viewerHasLiked??t.viewerHasLiked)}),VM=(e,t="Could not update like.")=>{const r=String(e?.message||"").toLowerCase(),a=String(e?.code||"").toLowerCase();return a==="28000"||r.includes("not_authenticated")?Jk:a==="p0002"||r.includes("public_board_not_found")?Qk:a==="42p01"||a==="42703"||a==="42883"||a==="42501"||r.includes("public_board_likes")||r.includes("like_public_board")||r.includes("unlike_public_board")||r.includes("get_public_board_like_state")||r.includes("permission")||r.includes("row-level security")||r.includes("schema cache")?Xk:t},xC=async(e,t,r)=>{const a=String(t||"").trim();if(!a)return{error:Qk,ok:!1,state:null};if(!An.isConfigured||!ae)return{error:Xk,ok:!1,state:null};let s=null,o=null;try{({data:s,error:o}=await ae.rpc(e,{p_public_board_id:a}))}catch(i){o=i||new Error("public-board-like-failed")}return o?{error:VM(o,r),ok:!1,state:null}:{error:"",ok:!0,state:zM(FM(s))}},HM=async e=>xC("get_public_board_like_state",e,"Could not load board likes."),WM=async e=>xC("like_public_board",e,"Could not like this board."),GM=async e=>xC("unlike_public_board",e,"Could not unlike this board."),qM=Jk,Zk=2,eN=8,YM="Public search is unavailable right now.",KM=(e="")=>String(e||"").trim().replace(/\s+/g," "),XM=e=>{const t=Number(e);return Number.isFinite(t)?Math.min(Math.max(Math.trunc(t),1),20):eN},JM=(e={})=>{const t=String(e?.code||"").toLowerCase(),r=String(e?.message||"").toLowerCase();return t==="42p01"||t==="42703"||t==="42883"||t==="42501"||r.includes("schema cache")||r.includes("search_public_profiles")||r.includes("search_public_boards")||r.includes("permission")||r.includes("row-level security")},QM=(e={})=>{const t=String(e.username||"").trim().replace(/^@+/,"").toLowerCase();return{avatarUrl:String(e.avatar_url||e.avatarUrl||"").trim(),createdAt:e.created_at||e.createdAt||"",displayName:String(e.dis
14play_name||e.displayName||"").trim(),updatedAt:e.updated_at||e.updatedAt||"",username:t}},ZM=(e={})=>{const t=String(e.owner_username||e.ownerUsername||"").trim().replace(/^@+/,"").toLowerCase();return{description:String(e.description||"").trim(),id:String(e.id||"").trim(),itemCount:Math.max(0,Number(e.item_count||e.itemCount||0)||0),likeCount:Math.max(0,Number(e.like_count||e.likeCount||0)||0),ownerDisplayName:String(e.owner_display_name||e.ownerDisplayName||"").trim(),ownerUsername:t,publishedAt:e.published_at||e.publishedAt||"",title:String(e.title||"").trim(),updatedAt:e.updated_at||e.updatedAt||""}},JI=async(e,t,r,a)=>{try{let s=ae.rpc(e,{limit_count:XM(r),q:t});a&&(s=s.abortSignal(a));const{data:o,error:i}=await s;return i?{data:[],error:i}:{data:Array.isArray(o)?o:[],error:null}}catch(s){return{data:[],error:s||new Error("public-search-failed")}}},eU=async(e,t=eN,{signal:r}={})=>{const a=KM(e);if(a.length<Zk)return{error:"",people:[],publicBoards:[]};if(!An.isConfigured||!ae)return{error:"",people:[],publicBoards:[]};const[s,o]=await Promise.all([JI("search_public_profiles",a,t,r),JI("search_public_boards",a,t,r)]),i=s.data.map(QM).filter(p=>p.username),c=o.data.map(ZM).filter(p=>
14p.id&&p.ownerUsername&&p.title),l=[s.error,o.error].filter(Boolean);return{error:l.length?l.some(JM)?YM:"Could not load public search results.":"",people:i,publicBoards:c}},gc=Object.freeze({BOARD_COLLABORATION_INVITE_ACCEPTED:"board_collaboration_invite_accepted",BOARD_COLLABORATION_INVITE_DECLINED:"board_collaboration_invite_declined",BOARD_COLLABORATION_INVITE_RECEIVED:"board_collaboration_invite_received",FOLLOWED_USER_CREATED_PUBLIC_BOARD:"followed_user_created_public_board",FOLLOWED_USER_MADE_BOARD_PUBLIC:"followed_user_made_board_public",PUBLIC_BOARD_LIKED:"public_board_liked",SOMEONE_FOLLOWED_YOU:"someone_followed_you"});Object.freeze(Object.values(gc));const tN="Updates are not available yet.",tU="Could not load updates.",rU="Could not load update count.",DS="Could not mark update as read.",nU="Could not mark updates as read.",OS="Could not clear notification.",aU=new Set(["actor_id","auth_id","email","local_board_id","local_item_id","notes","private_notes","profile_id","recipient_id","user_id"]),_i=e=>String(e||"").trim(),fi=e=>_i(e)||null,sU=e=>_i(e).toLowerCase(),rN=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?Math.trunc(t):0},oU=e=>{const t=Number(e);return Number.isFinite(t)?Math.min(100,Math.max(1,Math.trunc(t))):30},iU=e=>e?e instanceof Date?Number.isNaN(e.getTime())?null:e.toISOString():_i(e)||null:null,cU=e=>!!(e&&typeof e=="object"&&!Array.isArray(e)),lU=e=>cU(e)?Object.fromEntries(Object.entries(e).filter(([t])=>!aU.has(t))):{},nN=e=>Array.isArray(e)?e[0]||null:e||null,wf=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="42p01"||r==="42703"||r==="42883"||r==="42501"||t.includes("schema cache")||t.includes("notifications")||t.includes("get_notifications")||t.includes("get_unread_notification_count")||t.includes("mark_notification_read")||t.includes("mark_all_notifications_read")||t.includes("dismiss_notification")||t.includes("permission")||t.includes("row-level security")?tN:""},dU=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to view updates.":wf(e)||tU},uU=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to view updates.":wf(e)||rU},pU=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to manage updates.":wf(e)||DS},mU=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to manage updates.":wf(e)||nU},fU=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to manage updates.":wf(e)||OS},Cf=async e=>{if(!An.isConfigured||!ae)return{error:tN,user:null};let t=null,r=null;try{({data:t,error:r}=await ae.auth.getSession())}catch(s){r=s||new Error("notification-user-load-failed")}const a=t?.session?.user||null;return r||!a?.id?{error:e,user:null}:{error:"",user:a}},hU=(e=null)=>e?{activityId:fi(e.activity_id??e.activityId),actorAvatarUrl:fi(e.actor_avatar_url??e.actorAvatarUrl),actorId:null,actorName:_i(e.actor_display_name??e.actorDisplayName)||"Saveboard user",actorUsername:_i(e.actor_username??e.actorUsername).replace(/^@+/,""),boardId:fi(e.board_id??e.boardId),boardTitle:fi(e.board_title??e.boardTitle),createdAt:_i(e.created_at??e.createdAt),dismissedAt:fi(e.dismissed_at??e.dismissedAt),id:_i(e.notification_id??e.id),itemId:fi(e.item_id??e.itemId),itemTitle:fi(e.item_title??e.itemTitle),metadata:lU(e.metadata),readAt:fi(e.read_at??e.readAt),type:sU(e.notification_type??e.type)}:null,aN=(e=null)=>e?{dismissedAt:fi(e.dismissed_at??e.dismissedAt),id:_i(e.id??e.notification_id??e.notificationId),readAt:fi(e.read_at??e.readAt)}:null,gU=async({before:e=null,includeDismissed:t=!1,limit:r=30}={})=>{const a=await Cf("Sign in to view updates.");if(a.error)return{error:a.error,notifications:[]};let s=null,o=null;try{({data:s,error:o}=await ae.rpc("get_notifications",{before_timestamp:iU(e),include_dismissed:!!t,limit_count:oU(r)}))}catch(i){o=i||new Error("notifications-load-failed")}return o?{error:dU(o),notifications:[]}
14:{error:"",notifications:Array.isArray(s)?s.map(hU).filter(Boolean):[]}},bU=async()=>{const e=await Cf("Sign in to view updates.");if(e.error)return{count:0,error:e.error,ok:!1};let t=null,r=null;try{({data:t,error:r}=await ae.rpc("get_unread_notification_count"))}catch(a){r=a||new Error("notification-count-load-failed")}return r?{count:0,error:uU(r),ok:!1}:{count:rN(t),ok:!0}},vU=async e=>{const t=_i(e);if(!t)return{error:DS,ok:!1};const r=await Cf("Sign in to manage updates.");if(r.error)return{error:r.error,ok:!1};let a=null,s=null;try{({data:a,error:s}=await ae.rpc("mark_notification_read",{notification_id:t}))}catch(i){s=i||new Error("notification-mark-read-failed")}if(s)return{error:pU(s),ok:!1};const o=aN(nN(a));return o?{notification:o,ok:!0}:{error:DS,ok:!1}},yU=async()=>{const e=await Cf("Sign in to manage updates.");if(e.error)return{count:0,error:e.error,ok:!1};let t=null,r=null;try{({data:t,error:r}=await ae.rpc("mark_all_notifications_read"))}catch(a){r=a||new Error("notifications-mark-all-read-failed")}return r?{count:0,error:mU(r),ok:!1}:{count:rN(t),ok:!0}},QI=async e=>{const t=_i(e);if(!t)return{error:OS,ok:!1};const r=await Cf("Sign in to manage updates.");if(r.error)return{error:r.error,ok:!1};let a=null,s=null;try{({data:a,error:s}=await ae.rpc("dismiss_notification",{notification_id:t}))}catch(i){s=i||new Error("notification-dismiss-failed")}if(s)return{error:fU(s),ok:!1};const o=aN(nN(a));return o?{notification:o,ok:!0}:{error:OS,ok:!1}},hr=Object.freeze({BOARD_COLLABORATION_UPDATES:"boardCollaborationUpdates",EMAIL_UPDATES:"emailUpdates",FOLLOWED_USER_ADDED_ITEMS_TO_PUBLIC_BOARD:"followedUserAddedItemsToPublicBoard",FOLLOWED_USER_CREATED_PUBLIC_BOARD:"followedUserCreatedPublicBoard",FOLLOWED_USER_MADE_BOARD_PUBLIC:"followedUserMadeBoardPublic",ITEM_LIKED_PUBLIC:"itemLikedPublic",PUBLIC_BOARD_LIKED:"publicBoardLiked",PUSH_UPDATES:"pushUpdates",SOMEONE_FOLLOWED_YOU:"someoneFollowedYou"}),Ei=Object.freeze({[hr.SOMEONE_FOLLOWED_YOU]:!0,[hr.FOLLOWED_USER_CREATED_PUBLIC_BOARD]:!0,[hr.FOLLOWED_USER_MADE_BOARD_PUBLIC]:!0,[hr.FOLLOWED_USER_ADDED_ITEMS_TO_PUBLIC_BOARD]:!1,[hr.ITEM_LIKED_PUBLIC]:!1,[hr.PUBLIC_BOARD_LIKED]:!0,[hr.BOARD_COLLABORATION_UPDATES]:!0,[hr.EMAIL_UPDATES]:!1,[hr.PUSH_UPDATES]:!1}),sN="Updates preferences are not available yet.",SU="Could not load Updates preferences.",wU="Could not update Updates preferences.",oN=Object.freeze({[hr.BOARD_COLLABORATION_UPDATES]:"p_board_collaboration_updates",[hr.EMAIL_UPDATES]:"p_email_updates",[hr.FOLLOWED_USER_ADDED_ITEMS_TO_PUBLIC_BOARD]:"p_followed_user_added_items_to_public_board",[hr.FOLLOWED_USER_CREATED_PUBLIC_BOARD]:"p_followed_user_created_public_board",[hr.FOLLOWED_USER_MADE_BOARD_PUBLIC]:"p_followed_user_made_board_public",[hr.ITEM_LIKED_PUBLIC]:"p_item_liked_public",[hr.PUBLIC_BOARD_LIKED]:"p_public_board_liked",[hr.PUSH_UPDATES]:"p_push_updates",[hr.SOMEONE_FOLLOWED_YOU]:"p_someone_followed_you"}),CU=Object.freeze({board_collaboration_updates:hr.BOARD_COLLABORATION_UPDATES,email_updates:hr.EMAIL_UPDATES,followed_user_added_items_to_public_board:hr.FOLLOWED_USER_ADDED_ITEMS_TO_PUBLIC_BOARD,followed_user_created_public_board:hr.FOLLOWED_USER_CREATED_PUBLIC_BOARD,followed_user_made_board_public:hr.FOLLOWED_USER_MADE_BOARD_PUBLIC,item_liked_public:hr.ITEM_LIKED_PUBLIC,public_board_liked:hr.PUBLIC_BOARD_LIKED,push_updates:hr.PUSH_UPDATES,someone_followed_you:hr.SOMEONE_FOLLOWED_YOU}),xU=Object.freeze(Object.values(oN)),iN=e=>!!(e&&typeof e=="object"&&!Array.isArray(e)),cN=e=>Array.isArray(e)?e[0]||null:e||null,lN=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="42p01"||r==="42703"||r==="42883"||r==="42501"||t.includes("schema cache")||t.includes("notification_preferences")||t.includes("get_notification_preferences")||t.includes("update_notification_preferences")||t.includes("permission")||t.includes("row-level security")?sN:""},IU=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to manage Updates preferences.":l
14N(e)||SU},AU=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?"Sign in to update Updates preferences.":lN(e)||wU},dN=async e=>{if(!An.isConfigured||!ae)return{error:sN,user:null};let t=null,r=null;try{({data:t,error:r}=await ae.auth.getSession())}catch(s){r=s||new Error("updates-preferences-user-load-failed")}const a=t?.session?.user||null;return r||!a?.id?{error:e,user:null}:{error:"",user:a}},PU=(e,t)=>typeof e=="boolean"?e:t,uN=(e=null)=>iN(e)?Object.fromEntries(Object.entries(Ei).map(([t,r])=>{const a=Object.entries(CU).find(([,o])=>o===t)?.[0],s=e[t]??(a?e[a]:void 0);return[t,PU(s,r)]})):{...Ei},_U=(e={})=>{const t=Object.fromEntries(xU.map(a=>[a,null]));if(!iN(e))return{hasKnownPreference:!1,rpcArguments:t};let r=!1;return Object.entries(oN).forEach(([a,s])=>{typeof e[a]=="boolean"&&(t[s]=e[a],r=!0)}),{hasKnownPreference:r,rpcArguments:t}},pN=async()=>{const e=await dN("Sign in to manage Updates preferences.");if(e.error)return{error:e.error,ok:!1,preferences:{...Ei}};let t=null,r=null;try{({data:t,error:r}=await ae.rpc("get_notification_preferences"))}catch(a){r=a||new Error("updates-preferences-load-failed")}return r?{error:IU(r),ok:!1,preferences:{...Ei}}:{ok:!0,preferences:uN(cN(t))}},EU=async(e={})=>{const{hasKnownPreference:t,rpcArguments:r}=_U(e);if(!t)return pN();const a=await dN("Sign in to update Updates preferences.");if(a.error)return{error:a.error,ok:!1,preferences:{...Ei}};let s=null,o=null;try{({data:s,error:o}=await ae.rpc("update_notification_preferences",r))}catch(i){o=i||new Error("updates-preferences-update-failed")}return o?{error:AU(o),ok:!1,preferences:{...Ei}}:{ok:!0,preferences:uN(cN(s))}},kU=new Set(["manual","checked","imported"]),NU=new Set(["manual","daily","weekly"]),jU=new Set(["success","failed","blocked","timeout","low-confidence","unknown"]),Xn=(e,t="")=>String(e??"").trim()||t,wm=e=>Xn(e)||null,mN=(e,t=0)=>{const r=Number(e);return Number.isFinite(r)?Math.trunc(r):t},fN=e=>{const t=Number(e);return Number.isFinite(t)?t:null},hN=(e,t=new Date().toISOString())=>{const r=new Date(e||t);return Number.isFinite(r.getTime())?r.toISOString():t},ki=e=>{if(!e)return null;const t=new Date(e);return Number.isFinite(t.getTime())?t.toISOString():null},ZI=e=>!e||typeof e!="object"||Array.isArray(e)?null:Object.keys(e).length?e:null,RU=e=>Array.isArray(e)&&e.length?e:null,IC=(e="")=>String(e||"").trim().toLowerCase().replace(/[\s-]+/g,"_"),xh=e=>e===!0||String(e??"").trim().toLowerCase()==="true"||String(e??"").trim()==="1",LU=(e="")=>{const t=IC(e);return kU.has(t)?t:""},BU=(e="manual")=>{const t=IC(e);return NU.has(t)?t:"manual"},TU=(e="")=>{const t=IC(e).replace(/_/g,"-");return jU.has(t)?t:""},DU=e=>{const t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(1,t)):null},gN=(e=null)=>{const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{status:e},r=Fs(t.status),a=LU(t.source),s=ki(t.checkedAt||t.checked_at),o=ki(t.updatedAt||t.updated_at),i=DU(t.confidence),c=Xn(t.message);return r!=="unknown"||a||s||o||i!==null||c?{status:r,...a?{source:a}:{},...c?{message:c}:{},...s?{checkedAt:s}:{},...o?{updatedAt:o}:{},...i!==null?{confidence:i}:{}}:null},bN=(e=null)=>{if(!e||typeof e!="object"||Array.isArray(e))return null;const t=xh(e.enabled),r=xh(e.alertOnBackInStock??e.alert_on_back_in_stock),a=xh(e.alertOnLowStock??e.alert_on_low_stock),s=xh(e.alertOnOutOfStock??e.alert_on_out_of_stock),o=BU(e.cadence),i=ki(e.lastCheckedAt||e.last_checked_at),c=ki(e.nextCheckAt||e.next_check_at),l=TU(e.lastCheckStatus||e.last_check_status),u=Math.max(0,mN(e.failCount??e.fail_count,0));return t||r||a||s||o!=="manual"||i||c||l||u>0?{enabled:t,...r?{alertOnBackInStock:!0}:{},...a?{alertOnLowStock:!0}:{},...s?{alertOnOutOfStock:!0}:{},...o!=="manual"?{cadence:o}:{},...i?{lastCheckedAt:i}:{},...c?{nextCheckAt:c}:{},...l?{lastCheckStatus:l}:{},...u>0?{failCount:u}:{}}:null},OU=(e={},t="")=>Xn(t||e.userId||e.user_id),MU=(e={})=>Xn(e.id||e.productId||e.product_id),UU=(e={})=>{const t=gN(e.availability),r=bN(e.availabilityTracking),a=vf(e.availabilityHistory);return{availability:ZI(t),availability_tracking:ZI(r),availability_history:RU(a),last_availability_checked_at:ki(r?.lastCheckedAt||t?.checkedAt),next_availability_check_at:ki(r?.nextCheckAt),last_availability_check_status:wm(r?.lastCheckStatus),availability_fail_count:mN(r?.failCount,0)}},FU=(e={},{availabilityAlertEvents:t=[]}={})=>{const r=gN(e.availability),a=bN({...e.availability_tracking&&typeof e.availability_tracking=="object"?e.availability_tracking:{},lastCheckedAt:e.last_availability_checked_at,nextCheckAt:e.next_availability_check_at,lastCheckStatus:e.last_availability_check_status,failCount:e.availability_fail_count}),s=vf(e.availability_history),o=Bi(t);return{...r?{availability:r}:{},...a?{availabilityTracking:a}:{},...s.length?{availabilityHistory:s}:{},...o.length?{availabilityAlertEvents:o}:{}}}
14,$U=(e={},t={},r="")=>{const a=Xn(r||e.userId||e.user_id||OU(t)),s=Xn(e.productId||e.product_id||MU(t)),o=Bi([{...e,productId:s}])[0];if(!a||!s||!o)return null;const i=hN(o.createdAt);return{id:o.id,user_id:a,product_id:s,type:o.type,previous_status:wm(o.previousStatus),current_status:o.currentStatus,status:o.status,source:wm(o.source),confidence:fN(o.confidence),message:wm(o.message),created_at:i,event_day:i.slice(0,10),seen_at:ki(o.seenAt),dismissed_at:ki(o.dismissedAt),sent_at:ki(o.sentAt),failed_at:ki(o.failedAt),failure_reason:wm(o.failureReason)}},zU=(e=[],t="")=>(Array.isArray(e)?e:[]).flatMap(r=>Bi(r.availabilityAlertEvents).map(a=>$U(a,r,t))).filter(Boolean),VU=(e={})=>({id:Xn(e.id),userId:Xn(e.user_id),productId:Xn(e.product_id),type:Xn(e.type),previousStatus:Xn(e.previous_status),currentStatus:Xn(e.current_status),status:Xn(e.status,"pending"),source:Xn(e.source,"checked"),confidence:fN(e.confidence)??void 0,message:Xn(e.message),createdAt:hN(e.created_at),seenAt:Xn(e.seen_at),dismissedAt:Xn(e.dismissed_at),sentAt:Xn(e.sent_at),failedAt:Xn(e.failed_at),failureReason:Xn(e.failure_reason)}),HU=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),zt=(e,t="")=>String(e??"").trim()||t,Ni=e=>zt(e)||null,Iu=e=>{const t=Number(e);return Number.isFinite(t)?t:null},WU=e=>{if(e==null||typeof e=="string"&&!e.trim()||typeof e!="number"&&typeof e!="string")return;const t=Number(e);return Number.isFinite(t)?t:void 0},Eb=(e,t=0)=>{const r=Number(e);return Number.isFinite(r)?Math.trunc(r):t},Ju=(e,t=new Date().toISOString())=>{const r=new Date(e||t);return Number.isFinite(r.getTime())?r.toISOString():t},Ng=e=>{if(!e)return null;const t=new Date(e);return Number.isFinite(t.getTime())?t.toISOString():null},eA=e=>!e||typeof e!="object"||Array.isArray(e)?null:Object.keys(e).length?e:null,vN=(e={},t="")=>zt(t||e.userId||e.user_id),yN=(e={})=>zt(e.id||e.productId||e.product_id),GU=(e={})=>{const t=Us({price:e.price,currency:e.currency}),r=xb(e),a=Ib(e.priceAlert,{hasTargetPrice:!!r.targetPrice}),s=Xu(e.priceTracking);return{currency:Ni(t.currency||e.currency),price_amount:Number.isFinite(t.amount)?t.amount:null,target_price:Ni(r.targetPrice),target_currency:Ni(r.targetCurrency),target_amount:Number.isFinite(r.targetAmount)?r.targetAmount:null,price_alert:eA(a),price_tracking:eA(s),last_checked_at:Ng(s?.lastCheckedAt),next_check_at:Ng(s?.nextCheckAt),last_check_status:Ni(s?.lastCheckStatus),fail_count:Eb(s?.failCount,0)}},qU=(e={},t={},r="")=>{const a=vN(t,r),s=yN(t),o=Rl([e])[0];return!a||!s||!o?null:{id:zt(o.id,`${s}-${o.recordedAt}`),user_id:a,product_id:s,list_id:Ni(t.listId||t.list_id),price:o.price,currency:Ni(o.currency),amount:Number.isFinite(o.amount)?o.amount:null,approximate:!!o.approximate,source:zt(o.source,"unknown"),recorded_at:Ju(o.recordedAt)}},YU=(e=[],t="")=>(Array.isArray(e)?e:[]).flatMap(r=>Rl(r.priceHistory).map(a=>qU(a,r,t))).filter(Boolean),KU=(e={})=>({id:zt(e.id),price:zt(e.price),currency:zt(e.currency),amount:Iu(e.amount)??void 0,approximate:!!e.approximate,source:zt(e.source,"unknown"),recordedAt:Ju(e.recorded_at||e.recordedAt||e.created_at)}),XU=(e={},t={},r="")=>{const a=zt(r||e.userId||e.user_id||vN(t)),s=zt(e.productId||e.product_id||yN(t)),o=Vo([{...e,productId:s,userId:a}])[0];return!a||!s||!o?null:{id:o.id,user_id:a,product_id:s,type:o.type,previous_price:Ni(o.previousPrice),current_price:o.currentPrice,currency:Ni(o.currency),amount:Number.isFinite(o.amount)?o.amount:null,target_price:Ni(o.targetPrice),status:o.status,source:o.source,created_at:Ju(o.createdAt),sent_at:Ng(o.sentAt),last_attempt_at:Ng(o.lastAttemptAt),attempt_count:Eb(o.attemptCount,0),last_error_reason:Ni(o.lastErrorReason)}},JU=(e=[],t="")=>(Array.isArray(e)?e:[]).flatMap(r=>Vo(r.priceAlertEvents).map(a=>XU(a,r,t))).filter(Boolean),QU=(e={})=>({id:zt(e.id),userId:zt(e.user_id),productId:zt(e.product_id),type:zt(e.type),previousPrice:zt(e.previous_price),currentPrice:zt(e.current_price),currency:zt(e.currency),amount:Iu(e.amount)??void 0,targetPrice:zt(e.target_price),createdAt:Ju(e.created_at),status:zt(e.status,"pending"),source:zt(e.source,"scheduled-check"),sentAt:zt(e.sent_at),lastAttemptAt:zt(e.last_attempt_at),attemptCount:Eb(e.attempt_count,0),lastErrorReason:zt(e.last_error_reason)}),kb=(e={},{availabilityAlertEvents:t=[],index:r=0,listName:a="",priceAlertEvents:s=[],priceHistory:o=[]}={})=>
14{const i=WU(e.price_amount),c={targetPrice:zt(e.target_price),targetCurrency:zt(e.target_currency),targetAmount:Iu(e.target_amount)??void 0},l=Xu({...e.price_tracking&&typeof e.price_tracking=="object"?e.price_tracking:{},lastCheckedAt:e.last_checked_at,nextCheckAt:e.next_check_at,lastCheckStatus:e.last_check_status,failCount:e.fail_count},{keepEmpty:!!(e.price_tracking||e.last_checked_at||e.next_check_at||e.last_check_status||e.fail_count)}),u=HU(e,"image_url")?bs({image_url:e.image_url},{isPlaceholder:Vn}):null,p=u?u.kind==="external"||u.kind==="local-upload"?lB(u):u.kind==="placeholder"?{image:u.value,imageUrl:u.value}:u.explicitClear?{image:"",imageUrl:""}:{imageReferenceIssue:u.diagnosticCode}:{};return{id:zt(e.id,`product-${r+1}`),userId:zt(e.user_id),listId:zt(e.list_id),listName:a,category:a,title:zt(e.title,"Untitled product"),price:zt(e.price),...i!==void 0?{priceAmount:i}:{},currency:zt(e.currency),brand:zt(e.brand),cardSize:zn(e.card_size??e.cardSize),imageFramingOverrides:ya(e.image_framing_overrides??e.imageFramingOverrides),source:zt(e.source),url:zt(e.url),...p,privateNotes:zt(e.note),publicNotes:zt(e.public_note),size:zt(e.size),colour:zt(e.colour),variant:zt(e.variant),status:zt(e.status,"active"),sortOrder:Eb(e.sort_order,r),imageFit:zt(e.image_fit),imageScale:Iu(e.image_scale),imagePositionX:Iu(e.image_position_x),imagePositionY:Iu(e.image_position_y),imageBackgroundMode:zt(e.image_background_mode),imageBackgroundColor:zt(e.image_background_color),createdAt:Ju(e.created_at),updatedAt:Ju(e.updated_at,e.created_at),archivedAt:zt(e.archived_at)||void 0,purchasedAt:zt(e.purchased_at)||void 0,...c.targetPrice?c:{},...e.price_alert?{priceAlert:e.price_alert}:{},...l?{priceTracking:l}:{},...FU(e,{availabilityAlertEvents:t}),...o.length?{priceHistory:Rl(o)}:{},...s.length?{priceAlertEvents:Vo(s)}:{}}},MS=(e={})=>String(e?.id||"").trim(),ZU=e=>{if(e==null||e==="")return null;const t=Number(e);return Number.isFinite(t)?t:null},e1=new Set(["cloudDeletedAt","cloudDeletionId","cloudDeletionReason","cloudPurgeAfter","cloudRestoredAt","cloudRestoredBy","cloudUpdatedAt","syncConflict","syncConflictAt","syncConflictPatch","syncPendingCloudWrite","syncRevision","syncSuppressed"]),t1=(e={})=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),r1=(e={})=>Object.fromEntries(Object.entries(e).filter(([t])=>!e1.has(t))),tA=(e=[],t=[],r="list")=>{const a=new Map((Array.isArray(e)?e:[]).map(s=>[MS(s),s]).filter(([s])=>s));return(Array.isArray(t)?t:[]).map(s=>{const o=r1(a.get(MS(s))||{}),i={...o,...t1(s)};return r==="product"&&Object.assign(i,lp(o,s,{isPlaceholder:Vn,preferCurrentLocalUpload:!1})),i})},vy=(e=[],t=[])=>{const r=t.map(MS).filter(Boolean),a=new Set(r),s=(Array.isArray(e)?e:[]).map(o=>String(o||"").trim()).filter((o,i,c)=>o&&a.has(o)&&c.indexOf(o)===i);return r.forEach(o=>{s.includes(o)||s.push(o)}),s},SN=({backup:e={},lists:t=[],products:r=[]}={})=>{const a=tA(e.lists,t,"list"),s=tA(e.products,r,"product"),o=vy(e.boardOrder||e.listOrder,a);return{...e,lists:a,products:s,boardOrder:o,listOrder:vy(e.listOrder||o,a),productOrder:vy(e.productOrder,s)}},Ui=e=>String(e??"").trim(),iu=(e,t)=>{for(const r of t){const a=Ui(e?.[r]);if(a)return a}return""},n1=e=>{const t=Ui(e);return!!(t&&Number.isFinite(Date.parse(t)))},wN=(e,t)=>{for(const r of t){const a=Ui(e?.[r]);if(n1(a))return a}return""},a1=(e,t)=>t.some(r=>Ui(e?.[r])),s1=(e={})=>!!(a1(e,["accessRole","access_role","collaborationId","collaboration_id","collaborationRole","collaboration_role","publicBoardId","public_board_id","publicProjectionId","public_projection_id","sharedBoardId","shared_board_id"])||e.isCollaborative===!0||e.isPublicOnly===!0||e.isPublicProjection===!0||e.isSharedProjection===!0),ji=(e="")=>Ui(e).replace(/\s+/g," ").toLowerCase(),es=(e={})=>e.syncSuppressed===!0?!0:!!wN(e,["cloudDeletedAt","deletedAt","deleted_at"]),rA=(e={})=>{if(!e||typeof e!="object"||Array.isArray(e))return e;const t=wN(e,["cloudDeletedAt","deletedAt","deleted_at"]),r=iu(e,["cloudDeletionId","deletionId","deletion_id"]),a=iu(e,["cloudDeletionReason","deletionReason","deletion_reason"]),s=iu(e,["cloudPurgeAfter","purgeAfter","purge_after"]),o=iu(e,["cloudRestoredAt","restoredAt","restored_at"]),i=iu(e,["cloudRestoredBy","restoredBy","restored_by"]),c=iu(e,["cloudUpdatedAt","updated_at"]),l=Number(e.syncRevision??e.revision),u=Object.hasOwn(e,"cloudDeletedAt")&&e.cloudDeletedAt==="",p={...Object.fromEntries(Object.entries(e).filter(([m])=>!["cloudDeletedAt","deletedAt","deleted_at","isDeleted","isTombstoned"].includes(m))),...t?{cloudDeletedAt:t}:u?{cloudDeletedAt:""}:{},...r?{cloudDeletionId:r}:{},...a?{cloudDeletionReason:a}:{},...s?{cloudPurgeAfter:s}:{},...o?{cloudRestoredAt:o}:{},...i?{cloudRestoredBy:i}:{},...c?{cloudUpdatedAt:c}:{}
14,...Number.isSafeInteger(l)&&l>0?{syncRevision:l}:{}};return es(p)?{...p,syncSuppressed:!0}:p},US=(e={},{authenticatedOwnerId:t=""}={})=>{if(!ji(e.name)||es(e)||s1(e))return!1;const r=Ui(t).toLowerCase();if(!r)return!0;const a=[e.userId,e.user_id,e.ownerId,e.owner_id].map(o=>Ui(o).toLowerCase()).filter(Boolean),s=[...new Set(a)];return!!(!s.length||s.some(o=>o===Mi||o===r))},yu=(e=[],t="",{authenticatedOwnerId:r="",excludeListId:a=""}={})=>{const s=ji(t),o=Ui(a);return s&&(Array.isArray(e)?e:[]).find(i=>Ui(i?.id)!==o&&ji(i?.name)===s&&US(i,{authenticatedOwnerId:r}))||null},AC=(e=[],t="")=>{const r=ji(t);if(!r)return[];const a=new Map;return(Array.isArray(e)?e:[]).forEach((s,o)=>{if(ji(s?.name)!==r)return;const i=Ui(s?.id),c=i?`id:${i}`:`missing:${o}`;a.has(c)||a.set(c,s)}),[...a.values()]},ro=(e=[],t="")=>{const r=AC(e,t);return r.length===1?r[0]:null},o1=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Id=e=>String(e??"").trim(),$n=(e={})=>Id(e.id),CN=(e,t)=>{const r=[...new Set(t.map(a=>Id(e?.[a])).filter(Boolean))];return r.length===1?r[0]:""},i1=(e={})=>CN(e,["userId","user_id"]),Uu=(e={})=>CN(e,["listId","list_id"]),nA=(e={})=>{const t=[...new Set([e.syncRevision,e.revision].filter(r=>r!==void 0).map(Number))];return t.length===1?t[0]:Number.NaN},c1=(e={})=>Id(e.cloudUpdatedAt||e.updated_at),fd=e=>{const t=new Error(e);return t.name="BootstrapUploadProvenanceError",t},yy=(e,t)=>!!(e&&i1(e)===t&&Number.isInteger(nA(e))&&nA(e)>0&&Number.isFinite(Date.parse(c1(e)))&&e.syncSuppressed===!1&&!Id(e.cloudDeletedAt||e.deleted_at)),Au=(e=[])=>{const t=new Map;for(const r of Array.isArray(e)?e:[]){const a=$n(r);if(!a||t.has(a))throw fd("Cloud upload acknowledgement contained an invalid record identity.");t.set(a,r)}return t},jg=e=>Array.isArray(e)?e.map(jg):!e||typeof e!="object"?e:Object.fromEntries(Object.keys(e).sort().filter(t=>e[t]!==void 0).map(t=>[t,jg(e[t])])),aA=(e=[],t=[])=>JSON.stringify(jg(e))===JSON.stringify(jg(t)),l1="bootstrap-upload-awaiting-authoritative-ack",d1=({conflictAt:e=new Date().toISOString(),currentSnapshot:t,uploadedLists:r=[],uploadedProducts:a=[]}={})=>{const s=new Set((Array.isArray(r)?r:[]).map($n).filter(Boolean)),o=new Set((Array.isArray(a)?a:[]).map($n).filter(Boolean)),i=c=>({...c,syncConflict:Id(c.syncConflict)||l1,syncConflictAt:Id(c.syncConflictAt)||e,syncPendingCloudWrite:!0});return{...t||{},lists:(Array.isArray(t?.lists)?t.lists:[]).map(c=>s.has($n(c))?i(c):c),products:(Array.isArray(t?.products)?t.products:[]).map(c=>o.has($n(c))?i(c):c)}},Ih=({currentSnapshot:e,uploadedLists:t=[],uploadedLocalBackup:r,uploadedProducts:a=[]}={})=>{if(!e||!r||!Array.isArray(e.lists)||!Array.isArray(e.products)||!Array.isArray(r.lists)||!Array.isArray(r.products))return!1;let s,o,i,c;try{s=Au(r.lists),o=Au(r.products),i=Au(Array.isArray(t)?t:[]),c=Au(Array.isArray(a)?a:[])}catch{return!1}const l=Array.isArray(t)?t:[],u=Array.isArray(a)?a:[],p=new Set([...s.values()].filter(m=>!i.has($n(m))).filter(es).map($n));return i.size!==l.length||c.size!==u.length||l.some(m=>!s.has($n(m)))||u.some(m=>{const f=o.get($n(m)),h=Uu(m);return!f||Uu(f)!==h||!i.has(h)})||[...s.values()].some(m=>!i.has($n(m))&&!p.has($n(m)))||[...o.values()].some(m=>c.has($n(m))?!1:!es(m)&&!p.has(Uu(m)))?!1:aA(r.lists,e.lists)&&aA(r.products,e.products)},xN=({authenticatedUserId:e,authoritativeBackup:t,privateOwnerScoped:r=!1,uploadedLists:a=[],uploadedProducts:s=[]}={})=>{const o=Id(e);if(!o1.test(o)||r!==!0)throw fd("Cloud upload acknowledgement was not authoritatively owner scoped.");if(!t||!Array.isArray(t.lists)||!Array.isArray(t.products))throw fd("Cloud upload acknowledgement was incomplete.");const i=Au(t.lists),c=Au(t.products),l=Array.isArray(a)?a:[],u=Array.isArray(s)?s:[];if(!l.length)throw fd("Cloud upload acknowledgement did not identify any uploaded boards.");for(const p of l){const m=$n(p),f=i.get(m);if(!m||!yy(f,o))throw fd("Cloud did not acknowledge every uploaded board with authoritative provenance.")}for(const p of u){const m=$n(p),f=Uu(p),h=c.get(m),b=i.get(f);if(!m||!f||!yy(h,o)||Uu(h)!==f||!yy(b,o))throw fd("Cloud did not acknowledge every uploaded product with authoritative parent provenance.")}return!0},u1=({authenticatedUserId:e,authoritativeBackup:t,localBackup:r,privateOwnerScoped:a=!1,uploadedLists:s=[],uploadedProducts:o=[]}={})=>
14{if(!r||typeof r!="object"||Array.isArray(r))throw fd("Local upload snapshot was unavailable for authoritative reconciliation.");xN({authenticatedUserId:e,authoritativeBackup:t,privateOwnerScoped:a,uploadedLists:s,uploadedProducts:o});const i=new Set(s.map($n)),c=new Set(o.map($n)),l=t.lists.filter(h=>i.has($n(h))),u=t.products.filter(h=>c.has($n(h))),p=(Array.isArray(r.lists)?r.lists:[]).filter(h=>!i.has($n(h))&&es(h)),m=new Set(p.map($n)),f=(Array.isArray(r.products)?r.products:[]).filter(h=>!c.has($n(h))&&(es(h)||m.has(Uu(h))));return SN({backup:r,lists:[...l,...p],products:[...u,...f]})},FS=e=>String(e??"").trim(),Rg=["raw-cloud-row","cloud-product-mapping","cloud-candidate-constructed","wishlist-storage-normalization","hydration-gate-evaluated","unchanged-local-snapshot-reapplied","local-persistence-started","local-persistence-verified","verified-snapshot-reread","verified-hydrated-snapshot-applied","list-category-name-fallback-normalization","foreground-input-observed"],PC=["preserved-existing","missing-parent-fallback","category-match","list-name-match","ambiguous-name-match","default-list-fallback","explicit-local-move","unknown"],sA=24,p1=new Set(Rg),m1=new Set(PC),IN=["none","existing-read","write-started","write-verified","verified-reread","unchanged-local-snapshot-reapplied","verified-hydrated-snapshot-applied"],f1=new Set(IN),oo=e=>{const t=FS(e);if(!t)return"missing";let r=2166136261;for(let a=0;a<t.length;a+=1)r^=t.charCodeAt(a),r=Math.imul(r,16777619)>>>0;return`fnv1a32:${r.toString(16).padStart(8,"0")}`},h1=(e={},t={})=>e.phase===t.phase&&e.parentFingerprint===t.parentFingerprint&&e.normalizationDecision===t.normalizationDecision&&e.parentExistedAtPhase===t.parentExistedAtPhase&&e.sourceParentExistedBeforeNormalization===t.sourceParentExistedBeforeNormalization&&e.listsHydratedBeforeProductNormalization===t.listsHydratedBeforeProductNormalization&&e.storageEvidence===t.storageEvidence,Sy=(e={})=>{const t=(e.events||[]).map(({sequence:o,...i})=>({...i})),r=t.find(o=>o.changedAtPhase)||null,a=t.find(o=>o.phase==="raw-cloud-row")||null,s=t.filter(o=>["wishlist-storage-normalization","list-category-name-fallback-normalization"].includes(o.phase));return{phases:t,firstChangedPhase:r?.phase||"none",firstChangedTargetFingerprint:r?.parentFingerprint||"",cloudParentExisted:!!a?.parentExistedAtPhase,normalizedBeforeListsAvailable:s.some(o=>o.listsHydratedBeforeProductNormalization===!1),unchangedLocalSnapshotReapplied:t.some(o=>o.storageEvidence==="unchanged-local-snapshot-reapplied"),verifiedHydratedSnapshotApplied:t.some(o=>o.storageEvidence==="verified-hydrated-snapshot-applied"),persistenceVerified:t.some(o=>o.storageEvidence==="write-verified"),explicitMoveEvidence:!!e.explicitMoveEvidence}},g1=()=>{const e=new Map;let t=1;const r=o=>{const i=oo(o);return i==="missing"?null:(e.has(i)||e.set(i,{events:[],explicitMoveEvidence:!1,explicitMoveTargetFingerprint:""}),e.get(i))};return{clear:()=>e.clear(),get:o=>{const i=e.get(oo(o));return i?Sy(i):null},markExplicitMove:({enabled:o=!0,productId:i="",toParentId:c=""}={})=>{if(!o)return null;const l=r(i);return l?(l.explicitMoveEvidence=!0,l.explicitMoveTargetFingerprint=oo(c),Sy(l)):null},record:({enabled:o=!0,listsHydratedBeforeProductNormalization:i=null,normalizationDecision:c="unknown",parentExists:l=!1,parentId:u="",phase:p,productId:m="",sourceParentExists:f=null,storageEvidence:h="none"}={})=>{if(!o||!p1.has(p))return null;const b=r(m);if(!b)return null;const v=oo(u),S=b.events.at(-1)||null,I=b.explicitMoveEvidence&&b.explicitMoveTargetFingerprint&&b.explicitMoveTargetFingerprint===v&&["verified-snapshot-reread","foreground-input-observed"].includes(p)?"explicit-local-move":m1.has(c)?c:"unknown",A={sequence:t,phase:p,parentFingerprint:v,changedAtPhase:!!(S&&S.parentFingerprint!==v),parentExistedAtPhase:!!l,sourceParentExistedBeforeNormalization:f===null?null:!!f,normalizationDecision:I,listsHydratedBeforeProductNormalization:i===null?null:!!i,storageEvidence:f1.has(h)?h:"none"};return t+=1,(!S||!h1(S,A))&&(b.events.push(A),b.events.length>sA&&b.events.splice(0,b.events.length-sA)),Sy(b)}}},b1=({lists:e=[],product:t={}}={})=>{const r=FS(t.listId),a=r&&e.find(u=>String(u?.id||"")===r)||null,s=t.category||t.listName,o=a?[]:AC(e,s),i=a?null:ro(e,s),c=a||i;let l="unknown";return a?l="preserved-existing":i?.name===t.category?l="category-match":i?.name===t.listName?l="list-name-match":o.length>1&&(l="ambiguous-name-match"),{matchingList:c,normalizationDecision:l,parentExists:!!c,parentId:FS(c?.id||r),sourceParentExists:!!a,sourceParentId:r}},_C=g1(),Ec=e=>_C.record(e),v1=e=>_C.markExplicitMove(e),y1=e=>_C.get(e),S1=new Set(["42703","PGRST204"]),w1=["revision","deleted_at","deleted_by","deletion_id","deletion_reason","purge_after","restored_at","restored_by","created_by","updated_by"],EC="equal-revision-active-conflict",C1="local-user",x1=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Rc=e=>{const t=Date.parse(e||"");return Number.isFinite(t)?t:null},AN=(e,t)=>{const r=String(e||""),a=String(t||"");if(r===a)return!0;const s=Rc(r);return s!==null&&s===Rc(a)},Nb=(e,t)=>
14Object.prototype.hasOwnProperty.call(e||{},t),jb=e=>!!e&&typeof e=="object"&&!Array.isArray(e),kC=(e={})=>Nb(e,"syncConflictPatch")&&jb(e.syncConflictPatch),Qn=e=>{const t=Number(e);return Number.isSafeInteger(t)&&t>0?t:null},Nn=(e={})=>Qn(e.syncRevision??e.revision),$S=(e={})=>e.updated_at||e.updatedAt||e.cloudUpdatedAt||"",zS=(e={},t={})=>{const r=Nn(e),a=Nn(t);if(r!==null&&a!==null)return{cloudRevision:a,localRevision:r,order:a===r?"equal":a>r?"cloud-newer":"local-newer",source:"revision"};const s=Rc($S(e)),o=Rc($S(t));return s===null||o===null?{cloudRevision:a,localRevision:r,order:"unknown",source:"missing"}:{cloudRevision:a,localRevision:r,order:o===s?"equal":o>s?"cloud-newer":"local-newer",source:"updated_at"}},Ds=e=>String(e??"").trim(),I1=e=>e===!0||e===1||String(e??"").trim().toLowerCase()==="true",ml=e=>{if(e==null||e==="")return null;const t=Number(e);return Number.isFinite(t)?t:null},vd=e=>{const t=Rc(e);return t===null?"":new Date(t).toISOString()},VS=e=>Array.isArray(e)?e.map(VS):jb(e)?Object.keys(e).sort().reduce((t,r)=>(t[r]=VS(e[r]),t),{}):e??null,nm=e=>VS(e),Mt=(e,t=e,r=Ds,a=[])=>({keys:[...new Set([t,e,...a])],localKey:e,normalize:r}),PN=Object.freeze([Mt("id"),Mt("userId","user_id"),Mt("name"),Mt("slug"),Mt("description"),Mt("publicDescription","public_description"),Mt("isPublic","is_public",I1),Mt("archivedAt","archived_at",vd),Mt("sortOrder","sort_order",ml),Mt("budget","budget_amount",ml,["budgetAmount"]),Mt("budgetCurrency","budget_currency"),Mt("createdAt","created_at",vd)]),HS=Object.freeze([Mt("id"),Mt("userId","user_id"),Mt("listId","list_id"),Mt("title"),Mt("price"),Mt("brand"),Mt("cardSize","card_size",zn),Mt("imageFramingOverrides","image_framing_overrides",ya),Mt("source"),Mt("url"),Mt("imageUrl","image_url",Ds,["image"]),Mt("privateNotes","note",Ds,["notes"]),Mt("publicNotes","public_note"),Mt("size"),Mt("colour"),Mt("variant"),Mt("status"),Mt("sortOrder","sort_order",ml),Mt("imageFit","image_fit"),Mt("imageScale","image_scale",ml),Mt("imagePositionX","image_position_x",ml),Mt("imagePositionY","image_position_y",ml),Mt("imageBackgroundMode","image_background_mode"),Mt("imageBackgroundColor","image_background_color"),Mt("currency"),Mt("priceAmount","price_amount",ml),Mt("targetPrice","target_price"),Mt("targetCurrency","target_currency"),Mt("targetAmount","target_amount",ml),Mt("priceAlert","price_alert",nm),Mt("priceTracking","price_tracking",nm),Mt("availability","availability",nm),Mt("availabilityTracking","availability_tracking",nm),Mt("availabilityHistory","availability_history",nm),Mt("archivedAt","archived_at",vd),Mt("purchasedAt","purchased_at",vd),Mt("createdAt","created_at",vd)]),A1=new Set(["sortOrder"]),NC=e=>e==="list"?PN:HS,jC=e=>{if(e==="list"||e==="board")return"list";if(e==="product"||e==="item")return"product";throw new Error("Active sync reconciliation requires a list or product entity type.")},Qu=(e={},t)=>{const r=t.keys.find(a=>Nb(e,a));return r?{found:!0,value:e[r]}:{found:!1,value:void 0}},WS=(e,t={},{ignoreLocalOrder:r=!1}={})=>NC(e).reduce((a,s)=>(r&&A1.has(s.localKey)||(a[s.localKey]=s.localKey==="imageUrl"?PE(t,{emptyValue:"",isPlaceholder:Vn}):s.normalize(Qu(t,s).value)),a),{}),Pu=(e,t={},r={})=>WS(jC(e),t,r),oA=(e,t,r,a)=>JSON.stringify(WS(e,t,a))===JSON.stringify(WS(e,r,a)),Rb=(e={})=>vd(e.updated_at||e.cloudUpdatedAt||e.updatedAt),P1=(e={})=>vd(e.cloudUpdatedAt||e.updated_at),_1=(e,t={},r={})=>{const a={...t};NC(e).forEach(i=>{if(e==="product"&&i.localKey==="imageUrl")return;const c=Qu(r,i);c.found&&(a[i.localKey]=i.normalize(c.value))}),e==="product"&&Object.assign(a,lp(t,r,{isPlaceholder:Vn,preferCurrentImage:Lb(t),preferCurrentLocalUpload:!1}));const s=Nn(r),o=Rb(r);return s!==null&&(a.syncRevision=s),o&&(a.cloudUpdatedAt=o,a.updatedAt=o),a},Lb=(e={})=>e.syncPendingCloudWrite===!0||!!e.syncConflict||kC(e),E1=({cloudRecord:e={},entityType:t,patch:r}={})=>
14{if(!jb(r))return!1;const a=Object.entries(r);if(!a.length)return!1;const s=NC(jC(t));return a.every(([o,i])=>{const c=s.find(u=>u.keys.includes(o));if(!c)return!1;const l=Qu(e,c);return l.found?JSON.stringify(c.normalize(l.value)??null)===JSON.stringify(c.normalize(i)??null):!1})},k1="pending-local-change-versus-newer-cloud",_N=({cloudRecord:e={},entityType:t,localRecord:r={}}={})=>{if(!Lb(r)||!kC(r))return!1;const a=Nn(e),s=Nn(r);if(a===null)return!1;const o=s===null||a>s,i=a===s&&String(r.syncConflict||"")===k1;return!o&&!i?!1:E1({cloudRecord:e,entityType:t,patch:r.syncConflictPatch})},N1=({cloudRecord:e={},localRecord:t={},payloadsMatch:r=!1}={})=>{const a=Nn(e),s=Nn(t);if(a!==null&&s!==null)return{cloudRevision:a,localRevision:s,order:a===s?"equal":a>s?"cloud-newer":"local-newer",source:"revision"};if(a!==null||s!==null)return{cloudRevision:a,localRevision:s,order:r&&a!==null?"cloud-newer":"unknown",source:"revision-transition"};const o=Rb(e),i=P1(t);if(o&&i){const c=Rc(o),l=Rc(i);return{cloudRevision:a,localRevision:s,order:c===l?"equal":c>l?"cloud-newer":"local-newer",source:"server-updated-at"}}return{cloudRevision:a,localRevision:s,order:r&&o?"cloud-newer":"unknown",source:o||i?"partial-server-updated-at":"missing"}},nd=({cloudRecord:e={},entityType:t,localRecord:r={},reason:a}={})=>{if(!Lb(r))return null;const s=kC(r)?r.syncConflictPatch:{};return{baseRevision:r.syncPendingWriteRevision||Nn(r),cloudRevision:Nn(e),cloudUpdatedAt:Rb(e),existing:!!r.syncConflict,key:`${t}:${String(r.id||e.id||"")}`,patch:s,reason:r.syncConflict||a||"pending-local-change-versus-newer-cloud"}},cu=({cloudRecord:e={},conflictDraft:t,record:r={},reason:a}={})=>({...r,syncConflict:r.syncConflict||a||"active-record-needs-review",syncConflictAt:r.syncConflictAt||Rb(e)||r.cloudUpdatedAt||"",...t?{syncConflictPatch:t.patch}:{},...t&&Object.keys(t.patch).length?{syncPendingWriteRevision:t.baseRevision}:{},...t?{syncPendingCloudWrite:!1}:{}}),Lg=(e={})=>!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),RC=(e={})=>!Nb(e,"syncConflictPatch")||e.syncConflictPatch===null?!0:jb(e.syncConflictPatch)&&Object.keys(e.syncConflictPatch).length===0,GS=(e={})=>Ds(Qu(e,PN[1]).value),j1=(e={})=>{const t=GS(e);return!t||t===C1},EN=(e={},t="")=>({...e,...Nb(e,"user_id")?{user_id:t}:{},userId:t}),wy=e=>x1.test(Ds(e)),R1=({cloudRecord:e={},comparison:t,context:r={},localRecord:a={}}={})=>{const s=Ds(r.authenticatedUserId),o=GS(e),i=GS(a),c=Ds(a.id),l=Ds(e.id);return r.privateOwnerScoped!==!0?{hardReviewReason:"list-owner-private-scope-unproven",normalizationCandidate:!1}:wy(s)?wy(o)?o!==s?{hardReviewReason:"list-owner-cloud-auth-mismatch",normalizationCandidate:!1}:!c||c!==l?{hardReviewReason:"list-owner-record-id-mismatch",normalizationCandidate:!1}:!Lg(a)||!Lg(e)?{hardReviewReason:"list-owner-inactive-record",normalizationCandidate:!1}:j1(a)?t?.source!=="revision"||t?.order!=="equal"||t.localRevision===null||t.localRevision!==t.cloudRevision?{hardReviewReason:"list-owner-revision-not-equal",normalizationCandidate:!1}:RC(a)?a.syncPendingCloudWrite===!0?{hardReviewReason:"list-owner-pending-cloud-write",normalizationCandidate:!1}:Ds(a.syncConflict)&&Ds(a.syncConflict)!==EC?{hardReviewReason:"list-owner-existing-conflict",normalizationCandidate:!1}:{cloudOwnerId:o,hardReviewReason:"",normalizationCandidate:!0,recordForComparison:EN(a,o)}:{hardReviewReason:"list-owner-pending-patch",normalizationCandidate:!1}:wy(i)?i!==o?{hardReviewReason:"list-owner-mismatch",normalizationCandidate:!1}:{cloudOwnerId:o,hardReviewReason:"",normalizationCandidate:!1}:{hardReviewReason:"list-owner-local-value-malformed",normalizationCandidate:!1}:{hardReviewReason:"list-owner-cloud-value-malformed",normalizationCandidate:!1}:{hardReviewReason:"list-owner-authentication-required",normalizationCandidate:!1}},L1=({cloudRecord:e={},comparison:t,localRecord:r={},payloadsMatch:a=!1}={})=>Lg(r)&&Lg(e)&&t?.source==="revision"&&t?.order==="equal"&&t.localRevision!==null&&t.localRevision===t.cloudRevision&&a&&r.syncConflict===EC&&RC(r)&&r.syncPendingCloudWrite!==!0,kN=(e={})=>({...e,syncConflict:"",syncConflictPatch:void 0,syncPendingCloudWrite:void 0}),B1=(e={},t="")=>({...EN(e.syncConflict===EC?kN(e):e,t)}),Cy=({activeRecord:e,applyCloud:t,cloudRecord:r,localRecord:a,parentBoardIds:s}={})=>
14{const o=Ds(Qu(a,HS[2]).value),i=Ds(Qu(r,HS[2]).value),c=!!(o||i)&&o!==i;return i?s&&!s.has(i)?{action:"review-missing-parent",addToListId:"",apply:!1,changed:c,fromListId:o,removeFromListId:"",toListId:i}:c?{action:t?"apply-cloud-move":"review-move",addToListId:t?i:"",apply:!!(t&&e),changed:!0,fromListId:o,removeFromListId:t?o:"",toListId:i}:null:{action:"review-missing-parent",addToListId:"",apply:!1,changed:c,fromListId:o,removeFromListId:"",toListId:i}},T1=e=>{if(e==null)return null;const t=e instanceof Set?[...e]:e;return new Set((Array.isArray(t)?t:[]).map(r=>Ds(r)).filter(Boolean))},Bo=({action:e,activeRecord:t,cloudBase:r,comparison:a,conflictDraft:s=null,payloadsMatch:o,reason:i,relationship:c=null,requiresReview:l=!1,suppressed:u=!1}={})=>({action:e,activeRecord:t,cloudBase:r,comparison:a,conflictDraft:s,payloadsMatch:o,reason:i,relationship:c,requiresReview:l,suppressed:u,writesPerformed:0}),iA=({availableParentBoardIds:e,cloudRecord:t={},entityType:r,listOwnershipContext:a,localRecord:s={}}={})=>{const o=jC(r),i=oA(o,s,t),c=N1({cloudRecord:t,localRecord:s,payloadsMatch:i}),l=o==="list"?R1({cloudRecord:t,comparison:c,context:a,localRecord:s}):null,u=l?.recordForComparison||s,p=c.source==="revision"&&c.order==="equal"?Ek({cloudRecord:t,entityType:o,localRecord:u}):oA(o,u,t),m=T1(e),f=_1(o,s,t),h=!!(t.deleted_at||t.deletedAt||t.cloudDeletedAt||t.syncSuppressed),b=!!(s.deleted_at||s.deletedAt||s.cloudDeletedAt||s.syncSuppressed),v=t.restored_at||t.restoredAt||t.cloudRestoredAt||"",S=t.restored_by||t.restoredBy||t.cloudRestoredBy||"",I=!!(o==="product"&&b&&!h&&t.validatedCloudRestore===!0&&Number.isFinite(Date.parse(v))&&c.order==="cloud-newer")?{...f,cloudDeletedAt:"",cloudDeletionId:"",cloudDeletionReason:"",cloudPurgeAfter:"",cloudRestoredAt:v,cloudRestoredBy:S,syncSuppressed:!1}:f;if(h){const y=Lb(s)?"pending-local-change-versus-cloud-tombstone":"cloud-tombstone",N=nd({cloudRecord:t,entityType:o,localRecord:s,reason:y});return Bo({action:"suppress",activeRecord:null,cloudBase:{...I,cloudDeletedAt:t.deleted_at||t.deletedAt||t.cloudDeletedAt||"",cloudRestoredAt:"",cloudRestoredBy:"",syncSuppressed:!0},comparison:c,conflictDraft:N,payloadsMatch:p,reason:y,requiresReview:!!N,suppressed:!0})}if(l?.hardReviewReason){const y=l.hardReviewReason,N=nd({cloudRecord:t,entityType:o,localRecord:s,reason:y});return Bo({action:"review",activeRecord:cu({cloudRecord:t,conflictDraft:N,record:s,reason:y}),cloudBase:I,comparison:c,conflictDraft:N,payloadsMatch:p,reason:y,requiresReview:!0})}const A=o==="product"?Cy({activeRecord:I,applyCloud:c.order==="cloud-newer",cloudRecord:t,localRecord:s,parentBoardIds:m}):null;if(A?.action==="review-missing-parent"){const y="cloud-product-parent-board-unavailable",N=nd({cloudRecord:t,entityType:o,localRecord:s,reason:y});return Bo({action:"review",activeRecord:cu({cloudRecord:t,conflictDraft:N,record:s,reason:y}),cloudBase:I,comparison:c,conflictDraft:N,payloadsMatch:p,reason:y,relationship:A,requiresReview:!0})}if(_N({cloudRecord:t,entityType:o,localRecord:s})){const y={...I,syncConflict:"",syncConflictAt:"",syncConflictPatch:void 0,syncPendingCloudWrite:!1,syncPendingWriteRevision:void 0};return Bo({action:"apply-cloud",activeRecord:y,cloudBase:I,comparison:c,payloadsMatch:p,reason:"pending-local-change-acknowledged-by-cloud",relationship:o==="product"?Cy({activeRecord:y,applyCloud:!0,cloudRecord:t,localRecord:s,parentBoardIds:m}):null})}if(c.order==="cloud-newer"){const y=nd({cloudRecord:t,entityType:o,localRecord:s,reason:"pending-local-change-versus-newer-cloud"}),N=y?y.reason:c.source==="revision"?"cloud-revision-newer":c.source==="revision-transition"?"cloud-revision-metadata-available":"cloud-server-timestamp-newer",_=y?cu({cloudRecord:t,conflictDraft:y,record:I,reason:N}):{...I,syncConflict:"",syncConflictAt:"",syncConflictPatch:void 0,syncPendingCloudWrite:!1},P=o==="product"?Cy({activeRecord:_,applyCloud:!0,cloudRecord:t,localRecord:s,parentBoardIds:m}):null;return Bo({action:"apply-cloud",activeRecord:_,cloudBase:I,comparison:c,conflictDraft:y,payloadsMatch:p,reason:N,relationship:P,requiresReview:!!y})}
14if(c.order==="equal"&&p){if(l?.normalizationCandidate)return Bo({action:"apply-local-owner-normalization",activeRecord:B1(s,l.cloudOwnerId),cloudBase:I,comparison:c,payloadsMatch:p,reason:"normalized-local-list-owner"});if(L1({cloudRecord:t,comparison:c,localRecord:s,payloadsMatch:p}))return Bo({action:"apply-local-metadata-cleanup",activeRecord:kN(s),cloudBase:I,comparison:c,payloadsMatch:p,reason:"resolved-equal-revision-conflict-metadata"});const y=nd({cloudRecord:t,entityType:o,localRecord:s,reason:"existing-local-conflict-draft"});return Bo({action:"no-op",activeRecord:y?cu({cloudRecord:t,conflictDraft:y,record:s,reason:y.reason}):s,cloudBase:I,comparison:c,conflictDraft:y,payloadsMatch:p,reason:y?y.reason:"active-records-match",requiresReview:!!y})}if(c.order==="local-newer"){const y=c.source==="revision"?"stale-cloud-revision":"stale-cloud-server-timestamp",N=nd({cloudRecord:t,entityType:o,localRecord:s,reason:y});return Bo({action:"retain-local",activeRecord:cu({cloudRecord:t,conflictDraft:N,record:s,reason:y}),cloudBase:I,comparison:c,conflictDraft:N,payloadsMatch:p,reason:y,relationship:A,requiresReview:!0})}if(p&&c.source==="missing")return Bo({action:"no-op",activeRecord:s,cloudBase:I,comparison:c,payloadsMatch:p,reason:"legacy-active-records-match"});const k=c.order==="equal"?c.source==="revision"?"equal-revision-active-conflict":"equal-server-timestamp-active-conflict":c.source==="revision-transition"?"mixed-revision-active-conflict":"legacy-active-version-ambiguous",E=nd({cloudRecord:t,entityType:o,localRecord:s,reason:k});return Bo({action:"review",activeRecord:cu({cloudRecord:t,conflictDraft:E,record:s,reason:k}),cloudBase:I,comparison:c,conflictDraft:E,payloadsMatch:p,reason:k,relationship:A,requiresReview:!0})},qS=(e={})=>{if(e.syncPendingCloudWrite===!0)return!0;const t=Rc(e.updatedAt||e.updated_at),r=Rc(e.cloudUpdatedAt);return t!==null&&r!==null&&t>r},Km=(e={},t={})=>{const r=zS(e,t),a=t.deleted_at||t.deletedAt||"";if(e.syncSuppressed===!0&&AN(e.cloudDeletedAt,a)&&Nn(e)===Nn(t)){const i=e.syncConflict==="equal-revision-tombstone-conflict"&&!qS(e)&&RC(e)?"":e.syncConflict;return{comparison:r,reason:i||"cloud-tombstone",requiresReview:!!i,suppress:!0}}return qS(e)?{comparison:r,reason:"pending-local-edit-after-cloud-delete",requiresReview:!0,suppress:!0}:r.source!=="revision"?{comparison:r,reason:"legacy-tombstone-revision-unknown",requiresReview:!0,suppress:!0}:r.order==="cloud-newer"?{comparison:r,reason:"cloud-tombstone",requiresReview:!1,suppress:!0}:{comparison:r,reason:r.order==="equal"?"equal-revision-tombstone-conflict":"local-newer-than-cloud-tombstone",requiresReview:!0,suppress:!0}},D1=(e={},t={})=>{const r=t.deleted_at||t.deletedAt||"";return e.syncSuppressed===!0&&AN(e.cloudDeletedAt,r)?{reason:e.syncConflict||"parent-board-tombstone",requiresReview:!!e.syncConflict,suppress:!0}:qS(e)?{reason:"pending-local-edit-after-board-delete",requiresReview:!0,suppress:!0}:Nn(t)===null?{reason:"legacy-parent-tombstone-revision-unknown",requiresReview:!0,suppress:!0}:{reason:"parent-board-tombstone",requiresReview:!1,suppress:!0}},cA=(e=[])=>new Map(e.filter(t=>t?.id).map(t=>[String(t.id),t])),xy=({classification:e,entityType:t,parentListId:r="",row:a})=>({deletedAt:a.deleted_at||a.deletedAt||"",deletionId:a.deletion_id||a.deletionId||"",entityType:t,id:String(a.id||""),parentListId:String(r||""),reason:e.reason,requiresReview:e.requiresReview,revision:Nn(a),updatedAt:$S(a)}),O1=({cloudLists:e=[],cloudProducts:t=[],localLists:r=[],localProducts:a=[]}={})=>{const s=cA(r),o=cA(a),i=[],c=[],l=new Map;e.filter(m=>m?.id&&(m.deleted_at||m.deletedAt)).forEach(m=>{const f=String(m.id);l.set(f,m);const h=s.get(f);if(!h)return;const b=Km(h,m);i.push(xy({classification:b,entityType:"list",row:m}))}),t.filter(m=>m?.id&&(m.deleted_at||m.deletedAt)).forEach(m=>{const f=String(m.id),h=o.get(f);if(!h)return;const b=Km(h,m);c.push(xy({classification:b,entityType:"product",parentListId:m.list_id||m.listId,row:m}))});const u=new Set(c.map(m=>m.id));a.forEach(m=>{const f=String(m?.id||""),h=String(m?.list_id||m?.listId||""),b=l.get(h);if(!f||!b||u.has(f))return;const v=D1(m,b);c.push(xy({classification:v,entityType:"product",parentListId:h,row:{...b,id:f}}))});const p=[...i,...c].filter(m=>m.requiresReview);return{conflicts:{pendingLocalDeleteConflicts:p.filter(m=>m.reason.startsWith("pending-local-edit-after-")).length,tombstoneReviewConflicts:p.length},listSuppressions:i,productSuppressions:c}},M1=e=>{if(!e)return!1;const t=String(e.code||"").toUpperCase();if(S1.has(t))return!0;
14const r=[e.message,e.details,e.hint].filter(Boolean).join(" ").toLowerCase(),a=w1.some(o=>r.includes(o)),s=r.includes("does not exist")||r.includes("schema cache")||r.includes("could not find");return a&&s},YS=async({read:e,tiers:t=[]}={})=>{if(typeof e!="function"||!t.length)throw new Error("Schema-compatible sync read is not configured.");let r=null;for(let a=0;a<t.length;a+=1){const s=t[a],o=await e(s);if(r=o,!o?.error)return{data:o?.data||[],schemaMode:s.mode};if(!(a<t.length-1)||!M1(o.error))return{error:o.error,schemaMode:s.mode}}return{error:r?.error||new Error("Schema-compatible sync read failed."),schemaMode:t.at(-1)?.mode||"unknown"}},Zu=(e={})=>e.syncSuppressed===!0||!!e.cloudDeletedAt,NN=Object.freeze(["fnv1a32:1c4691d0","fnv1a32:8fd7c281","fnv1a32:84e7d77e","fnv1a32:46df05e3","fnv1a32:4e3db392","fnv1a32:7f15b0c8","fnv1a32:4307cd6b","fnv1a32:aca4c935","fnv1a32:cf433589","fnv1a32:f3a0d56d","fnv1a32:35283681","fnv1a32:149b55b6","fnv1a32:c67e3074","fnv1a32:ac8d43fa","fnv1a32:ad8d458d","fnv1a32:bac8b8a9"]),U1="mixed-revision-active-conflict",F1=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,$1=new Set(["listId","list_id"]),Fi=e=>String(e??"").trim(),El=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),Bb=e=>!!e&&typeof e=="object"&&!Array.isArray(e),js=(e={})=>Fi(e.id),Xm=(e={})=>Fi(e.userId||e.user_id),ep=(e={})=>Fi(e.listId||e.list_id),Ad=(e={})=>Qn(e.syncRevision??e.revision),jN=e=>F1.test(Fi(e)),Jm=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),Qm=(e={})=>!!(e.collaborationId||e.collaboration_id||e.collaboratorId||e.collaborator_id||e.sharedBoardId||e.shared_board_id||e.isCollaborative||e.isSharedProjection),RN=(e={})=>Bb(e.syncConflictPatch)?Object.keys(e.syncConflictPatch).sort():[],z1=(e={})=>El(e,"syncConflictPatch")&&Bb(e.syncConflictPatch)&&RN(e).length===0,LN=(e={})=>(e.priceAmount===null||e.priceAmount===void 0||e.priceAmount==="")&&(e.price_amount===null||e.price_amount===void 0||e.price_amount===""),lA=(e,t)=>JSON.stringify(e)===JSON.stringify(t),V1=(e={},t=0)=>({active:!Jm(e),id:js(e),inputPosition:t,ownerId:Xm(e),parentId:ep(e),priceAmountState:El(e,"price_amount")?e.price_amount===null?"null":"present":"absent",privateOwnerScoped:!Qm(e),rawCloudRow:Bb(e)?{...e}:null,revision:Ad(e)}),H1=(e=[])=>(Array.isArray(e)?e:[]).map(V1),Iy=(e=[])=>{const t=new Map;
14return(Array.isArray(e)?e:[]).forEach(r=>{const a=oo(js(r)),s=t.get(a)||[];s.push(r),t.set(a,s)}),t},dA=(e={})=>{const t={...e,syncRevision:1};return delete t.priceAmount,delete t.price_amount,t},W1=(e,t)=>[...new Set(Ll({cloudRecord:dA(t),entityType:"product",localRecord:dA(e)}).map(r=>r.field))].sort(),G1=({authenticatedUserId:e,cloudListsById:t,cloudRecord:r,localListsById:a,localRecord:s,rawEvidence:o})=>{const i=[],c=ep(s),l=ep(r);if(!c||!l||c!==l||o.parentId!==l)return i.push("parent-mismatch"),i;const u=a.get(c),p=t.get(l);return!u||!p||Jm(u)||Jm(p)?(i.push("parent-missing-or-inactive"),i):((Xm(u)!==e||Xm(p)!==e||Qm(u)||Qm(p))&&i.push("parent-ownership-unproven"),i)},BN=({authenticatedUserId:e,cloudListsById:t,cloudRecord:r,explicitMoveProductIds:a,localListsById:s,localRecord:o,privateOwnerScoped:i,rawEvidence:c})=>{const l=[];(!i||!jN(e))&&l.push("private-owner-scope-unproven"),(Xm(o)!==e||Xm(r)!==e||c.ownerId!==e||!c.privateOwnerScoped||Qm(o)||Qm(r))&&l.push("owner-mismatch-or-shared-record"),(Jm(o)||Jm(r)||!c.active)&&l.push("inactive-or-tombstoned"),o.syncPendingCloudWrite===!0&&l.push("pending-cloud-write"),(a.has(js(o))||RN(o).some(f=>$1.has(f)))&&l.push("pending-or-explicit-move"),l.push(...G1({authenticatedUserId:e,cloudListsById:t,cloudRecord:r,localListsById:s,localRecord:o,rawEvidence:c})),String(o.price??"")!==String(r.price??"")&&l.push("price-text-mismatch");const u=_c(o.currency),p=_c(r.currency);(!u||u!==p)&&l.push("currency-mismatch"),LN(o)||l.push("local-price-amount-present"),c.priceAmountState!=="null"&&l.push("raw-cloud-price-amount-not-null");let m=[];try{m=W1(o,r)}catch{l.push("canonical-comparison-failed")}return m.length&&l.push("canonical-semantic-difference"),{differences:m,reasons:[...new Set(l)]}},q1=e=>{const{cloudRecord:t,localRecord:r}=e;return Ad(r)!==1||Ad(t)!==1||String(r.syncConflict||"").trim()||El(r,"syncConflictPatch")||El(r,"syncConflictAt")?!1:BN(e).reasons.length===0},Y1=e=>{const{cloudRecord:t,localRecord:r,rawEvidence:a}=e;if(q1(e))return{decision:"already-resolved",reasons:[],semanticDifferenceFields:[]};const s=[];Ad(r)!==null&&s.push("local-revision-not-missing"),(Ad(t)!==1||a.revision!==1)&&s.push("cloud-revision-not-one"),z1(r)||s.push("patch-not-exactly-empty"),Str
14ing(r.syncConflict||"").trim()!==U1&&s.push("conflict-reason-not-historical");const o=BN(e);return s.push(...o.reasons),s.length?{decision:"skipped",reasons:[...new Set(s)],semanticDifferenceFields:o.differences}:{decision:"eligible",reasons:[],semanticDifferenceFields:[]}},K1=({authenticatedUserId:e="",cloudLists:t=[],cloudProducts:r=[],explicitLocalMoveProductIds:a=[],localLists:s=[],localProducts:o=[],privateOwnerScoped:i=!1,rawCloudProductEvidence:c=[]}={})=>{const l=Fi(e),u=Iy(o),p=Iy(r),m=Iy(c),f=new Map(s.map(S=>[js(S),S]).filter(([S])=>S)),h=new Map(t.map(S=>[js(S),S]).filter(([S])=>S)),b=new Set(a.map(Fi).filter(Boolean)),v=NN.map(S=>{const C=u.get(S)||[],I=p.get(S)||[],A=m.get(S)||[],k=[];if(C.length!==1&&k.push(C.length?"duplicate-local-fingerprint":"local-record-missing"),I.length!==1&&k.push(I.length?"duplicate-cloud-fingerprint":"cloud-record-missing"),A.length!==1&&k.push(A.length?"duplicate-raw-cloud-fingerprint":"raw-cloud-evidence-missing"),k.length)return{decision:"skipped",fingerprint:S,id:"",reasons:k,semanticDifferenceFields:[]};const E=C[0],y=I[0],N=A[0];return js(E)!==js(y)||js(E)!==js(N)?{decision:"skipped",fingerprint:S,id:"",reasons:["record-identity-mismatch"],semanticDifferenceFields:[]}:{...Y1({authenticatedUserId:l,cloudListsById:h,cloudRecord:y,explicitMoveProductIds:b,localListsById:f,localRecord:E,privateOwnerScoped:i,rawEvidence:N}),cloudRecord:y,fingerprint:S,id:js(E),localRecord:E,rawEvidence:N}});return{alreadyResolvedCount:v.filter(S=>S.decision==="already-resolved").length,eligibleCount:v.filter(S=>S.decision==="eligible").length,records:v,skippedCount:v.filter(S=>S.decision==="skipped").length}},X1=e=>({alreadyResolvedCount:e.alreadyResolvedCount,allowlistCount:NN.length,eligibleCount:e.eligibleCount,records:e.records.map(({decision:t,fingerprint:r,reasons:a,semanticDifferenceFields:s})=>({decision:t,fingerprint:r,reasons:[...a],semanticDifferenceFields:[...s]})),skippedCount:e.skippedCount}),J1=(e,t)=>{const r=String(e||""),a=String(t||"");return r===a||(!r||Vn(r))&&(!a||Vn(a))},Q1=({cloudRecord:e,localRecord:t})=>{const r={...t,...e};return Number.isFinite(Number(t.sortOrder))&&(r.sortOrder=Number(t.sortOrder)),_c(t.currency)===_c(e.currency)&&(r.currency=t.currency),J1(t.imageUrl||t.image,e.imageUrl||e.image)&&(El(t,"imageUrl")&&(r.imageUrl=t.imageUrl),El(t,"image")&&(r.image=t.image)),delete r.priceAmount,delete r.price_amount,r.syncConflict="",r.syncPendingCloudWrite=!1,delete r.syncConflictAt,delete r.syncConflictPatch,r},Z1=({cloudRecord:e,rawEvidence:t})=>{if(!Bb(t?.rawCloudRow))return null;const r=t.rawCloudRow,a=Ad(r);return a===null?null:{...kb(r,{index:Number.isSafeInteger(t.inputPosition)?t.inputPosition:0,listName:String(e?.listName||e?.category||"").trim()}),cloudUpdatedAt:r.updated_at||"",deleted_at:r.deleted_at,revision:a,updated_at:r.updated_at}},eF=({eligibleRecords:e,localSnapshot:t,verifiedSnapshot:r})=>{if(!lA(t.lists||[],r.lists||[]))return!1;const a=new Set(e.map(i=>i.id)),s=new Map((t.products||[]).map(i=>[js(i),i])),o=new Map((r.products||[]).map(i=>[js(i),i]));if(s.size!==o.size)return!1;for(const[i,c]of s.entries()){const l=o.get(i);if(!l||!a.has(i)&&!lA(c,l))return!1}return e.every(i=>{const c=o.get(i.id),l=Z1(i);if(!c||!l||Ad(c)!==1||String(c.syncConflict||"").trim()||El(c,"syncConflictAt")||El(c,"syncConflictPatch")||c.syncPendingCloudWrite===!0||ep(c)!==ep(l)||!LN(c)||Number(c.sortOrder)!==Number(i.localRecord.sortOrder))return!1;try{return Ek({cloudRecord:l,entityType:"product",localRecord:c})}catch{return!1}})},Ah=({accountId:e,getAccountScopeId:t,isSessionCurrent:r})=>Fi(t())===Fi(e)&&r()===!0,tF=({accountId:e="",apply:t=!1,authenticatedUserId:r="",cloudSnapshot:a={},explicitLocalMoveProductIds:s=[],getAccountScopeId:o,isSessionCurrent:i=()=>!0,privateOwnerScoped:c=!1,rawCloudProductEvidence:l=[],storage:u}={})=>{if(!u?.readAccountHydrationSnapshot||!u?.commitAccountHydrationSnapshot||typeof o!="function"||typeof i!="function")throw new TypeError("Legacy QA product cleanup is not configured.");if(t!==!0&&t!==!1)throw new TypeError("Legacy QA product cleanup a
14pply must be a boolean.");const p=Fi(e),m=Fi(r);if(!jN(p)||p!==m||!Ah({accountId:p,getAccountScopeId:o,isSessionCurrent:i}))return{applied:!1,mode:t?"apply":"dry-run",reason:"account-context-not-current",status:"blocked",writesPerformed:0};const f=u.readAccountHydrationSnapshot(p);if(!Ah({accountId:p,getAccountScopeId:o,isSessionCurrent:i}))return{applied:!1,mode:t?"apply":"dry-run",reason:"account-context-superseded",status:"blocked",writesPerformed:0};const h=K1({authenticatedUserId:m,cloudLists:a.lists||[],cloudProducts:a.products||[],explicitLocalMoveProductIds:s,localLists:f.lists||[],localProducts:f.products||[],privateOwnerScoped:c,rawCloudProductEvidence:l}),b=X1(h),v={applied:!1,localWritesPerformed:0,mode:t?"apply":"dry-run",plan:b,resolvedCount:0,status:t?"unchanged":"dry-run-complete",writesPerformed:0};if(!t||h.eligibleCount===0)return v;if(!Ah({accountId:p,getAccountScopeId:o,isSessionCurrent:i}))return{...v,reason:"account-context-superseded",status:"blocked"};const S=h.records.filter(y=>y.decision==="eligible"),C=new Map(S.map(y=>[y.id,y])),I=(f.products||[]).map(y=>{const N=C.get(js(y));return N?Q1({cloudRecord:N.cloudRecord,localRecord:y}):y}),A={...f,products:I},k=u.commitAccountHydrationSnapshot({accountId:p,cloudSnapshot:a,expectedCloudParents:S.map(y=>({parentId:ep(y.cloudRecord),productId:y.id})),localSnapshot:f,snapshot:A,useCloudAncillaryState:!1}),E=k?.verifiedSnapshot;if(!E||!eF({eligibleRecords:S,localSnapshot:f,verifiedSnapshot:E}))throw k?.rollback?.(),new Error("Legacy QA product cleanup persistence verification failed.");return Ah({accountId:p,getAccountScopeId:o,isSessionCurrent:i})?{...v,applied:!0,localWritesPerformed:1,resolvedCount:S.length,safetySnapshotSaved:!!k.safetySnapshotSaved,snapshot:E,status:"applied-and-verified"}:(k?.rollback?.(),{...v,reason:"account-context-superseded",status:"blocked"})},uA=e=>String(e??"").trim(),rF=e=>!!e&&typeof e=="object"&&!Array.isArray(e),LC=["raw-cloud-row","mapped-cloud-list","backup-normalization-input","backup-normalization-result","hydration-merge-evidence","foreground-review-evidence"],nF=["retained","duplicate-name-dropped","reserved-dashboard-dropped","invalid-record-dropped","normalization-not-observed"],aF=new Set(LC),BC=new Set(nF),sF=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),oF=(e={})=>!!(e.collaborationId||e.collaboration_id||e.collaboratorId||e.collaborator_id||e.sharedBoardId||e.shared_board_id||e.isCollaborative||e.isSharedProjection),iF=(e={})=>Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r))),Ay=(e={})=>({recordFingerprint:e.recordFingerprint||"missing",rawCloudPresence:!!e.rawCloudPresence,inputPosition:Number.isInteger(e.inputPosition)?e.inputPosition:null,retained:typeof e.retained=="boolean"?e.retained:null,normalizationOutcome:BC.has(e.normalizationOutcome)?e.normalizationOutcome:"normalization-not-observed",retainedWinnerFingerprint:e.retainedWinnerFingerprint||"",retainedWinnerSameIdentity:typeof e.retainedWinnerSameIdentity=="boolean"?e.retainedWinnerSameIdentity:null,recordClassification:e.recordClassification==="tombstone"?"tombstone":"active",scopeClassification:["private-owner","shared-or-collaborative","unknown"].includes(e.scopeClassification)?e.scopeClassification:"unknown",phases:LC.filter(t=>e.phases?.has(t))}),Tb=e=>{if(!rF(e))return null;const t=/^fnv1a32:[0-9a-f]{8}$/.test(String(e.recordFingerprint||""))?String(e.recordFingerprint):"missing",r=/^fnv1a32:[0-9a-f]{8}$/.test(String(e.retainedWinnerFingerprint||""))?String(e.retainedWinnerFingerprint):"";return{recordFingerprint:t,rawCloudPresence:!!e.rawCloudPresence,inputPosition:Number.isInteger(e.inputPosition)&&e.inputPosition>=0?e.inputPosition:null,retained:typeof e.retained=="boolean"?e.retained:null,normalizationOutcome:BC.has(e.normalizationOutcome)?e.normalizationOutcome:"normalization-not-observed",retainedWinnerFingerprint:r,retainedWinnerSameIdentity:typeof e.retainedWinnerSameIdentity=="boolean"?e.retainedWinnerSameIdentity:null,recordClassification:e.recordClassification==="tombstone"?"tombstone":"active",scopeClassification:["private-owner","shared-or-collaborative","unknown"].includes(e.scopeClassification)?e.scopeClassification:"unknown",phases:LC.filter(a=>e.phases?.includes(a))}},TN=e=>{const t={};return e.forEach(r=>{t[r.normalizationOutcome]=Number(t[r.normalizationOutcome]||0)+1}),{totalRecords:e.length,rawCloudRecords:e.filter(r=>r.rawCloudPresence).length,normalizationInputRecords:e.filter(r=>r.phases.includes("backup-normalization-input")).length,retainedRecords:e.filter(r=>r.retained===!0).length,droppedRecords:e.filter(r=>r.retained===!1).length,hydrationMergeEvidenceRecords:e.filter(r=>r.phases.includes("hydration-merge-evidence")).length,foregroundReviewEvidenceRecords:e.filter(r=>r.phases.includes("foreground-review-evidence")).length,recordsByOutcome:iF(t),records:e}},cF=e=>{const t=(Array.isArray(e?.records)?e.records:[]).map(Tb).filter(r=>r?.recordFingerprint!=="missing");return TN(t)},lF=()=>{const e=new Map;return{clear:()=>e.clear(),get:s=>{const o=e.get(oo(s));return o?Ay(o):null},record:({inputPosition:s=null,listId:o="",normalizationOutcome:i="normalization-not-observed",phase:c,privateOwnerScoped:l=!1,rawCloudPresence:u=!1,record:p={},retained:m=null,retainedWinnerId:f=""}={})=>
14{if(!aF.has(c))return null;const h=oo(o);if(h==="missing")return null;const b=e.get(h)||{inputPosition:null,normalizationOutcome:"normalization-not-observed",phases:new Set,rawCloudPresence:!1,recordClassification:"active",recordFingerprint:h,retained:null,retainedWinnerFingerprint:"",retainedWinnerSameIdentity:null,scopeClassification:"unknown"};return b.phases.add(c),b.rawCloudPresence=b.rawCloudPresence||!!u,Number.isInteger(s)&&s>=0&&(b.inputPosition=s),sF(p)&&(b.recordClassification="tombstone"),oF(p)?b.scopeClassification="shared-or-collaborative":l&&b.scopeClassification==="unknown"&&(b.scopeClassification="private-owner"),typeof m=="boolean"&&(b.retained=m),BC.has(i)&&i!=="normalization-not-observed"&&(b.normalizationOutcome=i),f&&(b.retainedWinnerFingerprint=oo(f),b.retainedWinnerSameIdentity=uA(f)===uA(o)),e.set(h,b),Ay(b)},snapshot:()=>{const s=[...e.values()].map(Ay).sort((o,i)=>{const c=o.inputPosition??Number.MAX_SAFE_INTEGER,l=i.inputPosition??Number.MAX_SAFE_INTEGER;return c-l||o.recordFingerprint.localeCompare(i.recordFingerprint)});return TN(s)}}},Db=lF(),dF=()=>Db.clear(),tp=e=>Db.record(e),uF=e=>Db.get(e),pF=()=>Db.snapshot(),Fu="This item changed on another device. Review your change.",pi=Object.freeze({editorReviewRequired:"editor-review-required",missingCurrentRevision:"missing-current-revision",missingEditorSession:"missing-editor-session",missingLatestBaseRevision:"missing-latest-base-revision",missingOpeningRevision:"missing-opening-revision",missingStoreRevision:"missing-store-revision",recordIdentityChanged:"record-identity-changed",recoveryEvidenceChanged:"recovery-evidence-changed",revisionMismatch:"revision-mismatch"}),DN="verified-missing-opening-revision",KS=e=>Array.isArray(e)?e.map(KS):!e||typeof e!="object"?e:Object.fromEntries(Object.entries(e).map(([t,r])=>[t,KS(r)])),TC=e=>!e||typeof e!="object"||Object.isFrozen(e)?e:(Object.values(e).forEach(TC),Object.freeze(e)),DC=(e={})=>TC(KS(e)),OC=(e={})=>Br(e.syncRevision??e.revision),Pd=(e={})=>String(e.id||"").trim(),Bg=e=>Array.isArray(e)?e.map(Bg):!e||typeof e!="object"?e:Object.keys(e).sort().reduce((t,r)=>(t[r]=Bg(e[r]),t),{}),mF=(e,t)=>{try{return JSON.stringify(Bg(e))===JSON.stringify(Bg(t))}catch{return!1}},Ob=e=>Object.freeze(e),fF=({product:e,products:t=[]}={})=>{const r=Pd(e);return r?(Array.isArray(t)?t:[]).find(a=>Pd(a)===r)||e:e||null},MC=(e={},{formGeneration:t=0,requiresExpectedRevision:r}={})=>{const a=DC(e),s=OC(a),o=typeof r=="boolean"?r:!!s,i=!!a.syncConflict||o&&!s;return Ob({dirty:!1,formGeneration:t,latestBase:a,latestBaseRevision:s,needsReview:i,openingRevision:s,openingSnapshot:a,productId:Pd(a),requiresExpectedRevision:o,reviewCount:i?1:0})},Zm=e=>
14e?.recovery?.kind===DN&&!!e.recovery.protectedLocalSnapshot,ON=(e,t)=>Zm(e)&&Pd(t)===e.productId&&mF(t,e.recovery.protectedLocalSnapshot),hF=({cloudOpeningSnapshot:e={},formGeneration:t=0,protectedLocalRecord:r={}}={})=>{const a=MC(e,{formGeneration:t,requiresExpectedRevision:!0}),s=DC(r);if(a.openingRevision!==1||a.needsReview||!a.productId||a.productId!==Pd(s))throw new TypeError("Missing-opening-revision recovery requires a clean revision-1 cloud snapshot.");return Ob({...a,recovery:TC({kind:DN,protectedLocalSnapshot:s})})},pA=e=>e?.productId?`${e.productId}:${e.openingRevision||"legacy"}:${Number(e.formGeneration)||0}`:"product-editor-closed",mA=(e,t)=>!e||e.dirty===!!t?e:Ob({...e,dirty:!!t}),Ph=(e,t,r)=>e.needsReview&&e.latestBaseRevision===r?e:Ob({...e,latestBase:t,latestBaseRevision:r,needsReview:!0,reviewCount:1}),fA=(e,t)=>{if(!e?.productId||Pd(t)!==e.productId)return e;const r=DC(t),a=OC(r),s=Br(e.openingRevision);return Zm(e)?ON(e,r)?e:Ph(e,r,a):!e.requiresExpectedRevision&&!s&&!a?e:!s||!a||a<s?Ph(e,r,a):a===s?r.syncConflict?Ph(e,r,a):e:e.dirty?Ph(e,r,a):MC(r,{formGeneration:(Number(e.formGeneration)||0)+1,requiresExpectedRevision:e.requiresExpectedRevision})},Tg=({latestRecord:e,session:t}={})=>{if(t?.requiresExpectedRevision&&e?.syncPendingCloudWrite)return{blocked:!0,ok:!1,reason:"previous-cloud-save-pending",message:"The previous cloud save is unconfirmed. Retry it before saving another edit.",openingSnapshot:t.openingSnapshot};const r=Br(t?.openingRevision),a=OC(e),s=Br(t?.latestBaseRevision),o=Zm(t)&&!ON(t,e),i=a||(Zm(t)&&!o?r:null),c=[i,s].filter(Boolean).reduce((p,m)=>Math.max(p,m),0),l=!!t?.productId&&Pd(e)===t.productId;if(!t?.requiresExpectedRevision&&l)return{blocked:!1,expectedRevision:null,latestRevision:a||s||null,message:"",ok:!0,openingSnapshot:t.openingSnapshot,reason:""};const u=t?l?r?o?pi.recoveryEvidenceChanged:i?s?c?r!==c?pi.revisionMismatch:t.needsReview?pi.editorReviewRequired:"":pi.missingCurrentRevision:pi.missingLatestBaseRevision:pi.missingStoreRevision:pi.missingOpeningRevision:pi.recordIdentityChanged:pi.missingEditorSession;return u?{blocked:!0,expectedRevision:r,latestRevision:c||null,message:Fu,ok:!1,openingSnapshot:t?.openingSnapshot||null,reason:u}:{blocked:!1,expectedRevision:r,latestRevision:c,message:"",ok:!0,openingSnapshot:t.openingSnapshot,reason:""}},gF=({latestRecord:e,session:t,submit:r}={})=>{const a=Tg({latestRecord:e,session:t});return a.ok?{...a,result:r?.(a),submitted:!0}:{...a,submitted:!1}},ef=e=>!!e&&typeof e=="object"&&!Array.isArray(e),tf=e=>String(e??"").trim(),XS=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),_h=/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/gi,bF="equal-revision-active-conflict",Dg=["reorder","relationship-move","content","lifecycle","unknown"],MN=["absent","empty","nonempty"],UN=["none","same-parent","different-parent","pending-local-move","missing-local-parent","missing-cloud-parent","unknown"],vF=new Set(["availability","availabilityhistory","availabilitytracking","brand","color","colour","currency","image","imagebackgroundcolor","imagebackgroundmode","imagefit","imagepositionx","imagepositiony","imagescale","imageurl","note","notes","price","pricealert","priceamount","pricetracking","privatenotes","publicnote","publicnotes","size","source","targetamount","targetcurrency","targetprice","title","url","variant"]),yF=new Set(["archivedat","deletedat","deletedby","deletionid","deletionreason","purchasedat","purgeafter","restoredat","restoredby","status"]),SF=new Set(["availability","availabilityhistory","availabilitytracking","brand","budget","budgetamount","colour","description","image","imageurl","name","note","notes","price","pricealert","priceamount","pricetracking","privatenotes","publicdescription","publicnote","publicnotes","size","slug","source","targetamount","targetprice","title","url","variant"]),wF=(e="")=>{const t=String(e||"").replace(/^\?/,"");return new URLSearchParams(t).get("syncDebug")==="1"},Ti=e=>{const t=tf(e);return t?t.length<=8?`${t.slice(0,2)}...${t.slice(-2)}`:`${t.slice(0,4)}...${t.slice(-4)}`:""},CF=(e,t)=>JSON.stringify(e)===JSON.stringify(t),xF=e=>String(e??"").replace(/[^a-z0-9]/gi,"").toLowerCase(),$u=e=>{const t=String(e??"").trim();return!t||/^[a-z0-9][a-z0-9._:-]{0,127}$/i.test(t)?t:"[redacted-reason]"},FN=e=>{const t=String(e??"");return/^[a-z][a-z0-9_]{0,63}$/i.test(t)?t:"[redacted-key]"},IF=e=>{const t=xF(e);return t==="sortorder"?"reorder":t==="listid"?"relationship-move":vF.has(t)?"content":yF.has(t)?"lifecycle":"unknown"},$N=(e={})=>
14{if(!(XS(e,"syncConflictPatch")&&e.syncConflictPatch!==null&&e.syncConflictPatch!==void 0))return{patchKeys:[],patchKinds:[],patchState:"absent"};const r=ef(e.syncConflictPatch)?Object.keys(e.syncConflictPatch):[],a=ef(e.syncConflictPatch)&&r.length===0?"empty":"nonempty",s=[...new Set(r.map(FN))].sort(),o=[...new Set(r.map(IF))].sort((i,c)=>Dg.indexOf(i)-Dg.indexOf(c));return a==="nonempty"&&o.length===0&&o.push("unknown"),{patchKeys:s,patchKinds:o,patchState:a}},Og=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),hA=(e={})=>{const t=["image_url","imageUrl","image"],r=t.find(s=>XS(e,s)&&String(e[s]??"").trim()),a=t.find(s=>XS(e,s));return String(e[r||a]??"").trim()},zN=e=>{const t=String(e??"").trim();return t?/^https?:\/\//i.test(t)?"http":/^data:image\/svg\+xml(?:;|,)/i.test(t)?"data-svg":/^data:image\/[a-z0-9.+-]+(?:;|,)/i.test(t)?"data-bitmap":"other":"empty"},VN=e=>{const t=String(e??"").trim(),r=t.indexOf(",");if(zN(t)!=="data-svg"||r===-1)return"";let a=t.slice(r+1);if(/;base64/i.test(t.slice(0,r)))try{a=typeof globalThis.atob=="function"?globalThis.atob(a):""}catch{return""}for(let s=0;s<3;s+=1)try{const o=decodeURIComponent(a);if(o===a)break;a=o}catch{break}return a},AF=e=>{const t=VN(e);if(!t||!/<svg\b/i.test(t)||/<image\b/i.test(t))return!1;const r=/\bSave\s*board\b/i.test(t)||/\bSave\b/i.test(t)&&/\bBoard\b/i.test(t),a=/<rect\b[^>]*width=["'](?:360|100%)["'][^>]*height=["'](?:520|100%)["']/i.test(t),s=/#(?:163a5f|102f4e|eaf0f6|9f1d35|ef4444|dc2626|b91c1c|b11226|c12632)\b/i.test(t);return r||a&&s},PF=e=>{const t=String(e??"").trim();if(!t)return"";const a=(VN(t)||t).replace(/\s+/g," ").trim();let s=2166136261;for(let o=0;o<a.length;o+=1)s^=a.charCodeAt(o),s=Math.imul(s,16777619)>>>0;return`fnv1a32:${s.toString(16).padStart(8,"0")}`},Mg=e=>{const t=String(e??"").trim();return{kind:zN(t),matchesCurrentOfficialPlaceholder:!!(t&&yO(t)),isSaveBoardPlaceholderSvgCandidate:AF(t),encodedLength:t.length,fingerprint:PF(t)}},_F=({cloudRecord:e={},entityType:t,localRecord:r={},outcome:a={},patchKinds:s=[]}={})=>{if(t==="list"||t==="board")return"none";if(s.includes("relationship-move"))return"pending-local-move";const o=tf(r.listId||r.list_id),i=tf(e.listId||e.list_id);return!o&&!i?"unknown":i?!o||a.reason==="cloud-product-parent-board-unavailable"||a.relationship?.action==="review-missing-parent"?"missing-local-parent":o===i?"same-parent":"different-parent":"missing-cloud-parent"},EF=({cloudRecord:e={},entityType:t,localRecord:r={}}={})=>{const a=Nn(r),s=Nn(e);return a===null||a!==s?[]:[...new Set(Ll({cloudRecord:e,entityType:t,localRecord:r}).map(({field:o})=>o))].sort()},kF=({canonicalDifferenceFields:e=[],cloudRecord:t={},localRecord:r={},patchState:a,relationshipClassification:s}={})=>{const o=[];(Og(r)||Og(t))&&o.push("inactive-record","tombstone");const c=Nn(r),l=Nn(t);(c===null||c!==l)&&o.push("revision-not-equal"),e.length&&o.push("canonical-difference"),String(r.syncConflict||"")!==bF&&o.push("different-conflict-reason"),a==="nonempty"&&o.push("nonempty-patch"),r.syncPendingCloudWrite===!0&&o.push("pending-cloud-write"),["none","same-parent"].includes(s)||o.push("relationship-difference");const u=[...new Set(o)];return{cleanupBlockers:u,cleanupEligibility:u.length===0}},rf=(e,t="")=>{const r=String(t||"").replace(/[^a-z0-9]/gi,"").toLowerCase();if(/token|secret|password|email/.test(r))return e?"[redacted]":e??null;if(r==="userid"||r==="ownerid"||r.endsWith("userid"))return e?"[current-user]":e??null;if(SF.has(r))return e==null||e===""?e??null:`[redacted-${r}]`;if(r==="id"||r==="listid"||r==="productid"||r==="boardid"||r==="recordid")return Ti(e);if((r==="url"||r==="imageurl")&&typeof e=="string"&&e)try{const a=new URL(e);a.username="",a.password="";const s=[...new Set([...a.searchParams.keys()])];return a.search="",s.forEach(o=>a.searchParams.set(o,"[redacted]")),a.hash="",a.toString()}catch{return"[redacted-url]"}if(Array.isArray(e))return e.map(a=>rf(a));if(ef(e))return Object.fromEntries(Object.entries(e).map(([a,s])=>[a,rf(s,a)]));if(typeof e=="string"){if(/\b[^\s@]+@[^\s@]+\.[^\s@]+\b/.test(e))return"[redacted-email]";if(_h.test(e))return _h.lastIndex=0,e.replace(_h,a=>Ti(a));_h.lastIndex=0}return e??null},JS=(e,t,r="")=>CF(e,t)?[]:ef(e)&&ef(t)?[...new Set([...Object.keys(e),...Object.keys(t)])].sort().flatMap(a=>JS(e[a],t[a],r?`${r}.${a}`:a)):[{field:r||"value",local:e??null,cloud:t??null}],gA=(e={})=>rf(e),Py=(e={})=>rf(e),NF=e=>{if(!e)return null;const t=$N({syncConflictPatch:e.patch});return{baseRevision:e.baseRevision??null,cloudRevision:e.cloudRevision??null,cloudUpdatedAt:e.cloudUpdatedAt||"",existing:!!e.existing,key:e.key?`${String(e.key).split(":")[0]}:${Ti(String(e.key).split(":").slice(1).join(":"))}`:"",patchKeys:t.patchKeys,patchKinds:t.patchKinds,patchState:t.patchState,reason:$u(e.reason)}}
14,UC=e=>{if(!e||typeof e!="object")return null;const t=(Array.isArray(e.phases)?e.phases:[]).filter(s=>Rg.includes(s?.phase)).map(s=>({phase:s.phase,parentFingerprint:/^fnv1a32:[0-9a-f]{8}$|^missing$/.test(String(s.parentFingerprint||""))?s.parentFingerprint:"missing",changedAtPhase:!!s.changedAtPhase,parentExistedAtPhase:!!s.parentExistedAtPhase,sourceParentExistedBeforeNormalization:s.sourceParentExistedBeforeNormalization===null?null:!!s.sourceParentExistedBeforeNormalization,normalizationDecision:PC.includes(s.normalizationDecision)?s.normalizationDecision:"unknown",listsHydratedBeforeProductNormalization:s.listsHydratedBeforeProductNormalization===null?null:!!s.listsHydratedBeforeProductNormalization,storageEvidence:IN.includes(s.storageEvidence)?s.storageEvidence:"none"})),r=Rg.includes(e.firstChangedPhase)?e.firstChangedPhase:"none",a=/^fnv1a32:[0-9a-f]{8}$/.test(String(e.firstChangedTargetFingerprint||""))?e.firstChangedTargetFingerprint:"";return{phases:t,firstChangedPhase:r,firstChangedTargetFingerprint:a,cloudParentExisted:!!e.cloudParentExisted,normalizedBeforeListsAvailable:!!e.normalizedBeforeListsAvailable,explicitMoveEvidence:!!e.explicitMoveEvidence,unchangedLocalSnapshotReapplied:!!e.unchangedLocalSnapshotReapplied,verifiedHydratedSnapshotApplied:!!e.verifiedHydratedSnapshotApplied,persistenceVerified:!!e.persistenceVerified}},bA=({cloudRecord:e={},entityType:t,listNormalizationProvenance:r=null,localRecord:a={},outcome:s={},parentPhaseProvenance:o=null}={})=>{const i=t==="list"||t==="board"?"list":"product",c=Pu(t,a),l=Pu(t,e),u=Pu(t,a,{ignoreLocalOrder:!0}),p=Pu(t,e,{ignoreLocalOrder:!0}),m=$u(s.reason),f=$u(a.syncConflict),h=$N(a),b=EF({cloudRecord:e,entityType:t,localRecord:a}),v=_F({cloudRecord:e,entityType:i,localRecord:a,outcome:s,patchKinds:h.patchKinds}),S=kF({canonicalDifferenceFields:b,cloudRecord:e,localRecord:a,patchState:h.patchState,relationshipClassification:v}),C=Og(a)||Og(e)||s.suppressed===!0;return{recordId:tf(a.id||e.id),recordFingerprint:oo(a.id||e.id),redactedRecordId:Ti(a.id||e.id),entityType:i,recordClassification:C?"tombstone":"active",parentBoardId:tf(a.listId||a.list_id||e.listId||e.list_id),localRevision:Nn(a),cloudRevision:Nn(e),outcome:s.action||"unknown",reason:m,requiresReview:!!s.requiresReview,canonicalLocalPersistedPayload:gA(c),canonicalCloudPersistedPayload:gA(l),fieldDifferences:JS(c,l).map(({field:I})=>({field:I})),semanticFieldDifferences:JS(u,p).map(({field:I})=>({field:I})),storedConflictReason:f,patchState:h.patchState,patchKeys:h.patchKeys,patchKinds:h.patchKinds,pendingCloudWrite:a.syncPendingCloudWrite===!0,canonicalDifferenceFields:b,relationshipClassification:v,cleanupEligibility:S.cleanupEligibility,cleanupBlockers:S.cleanupBlockers,imageComparisonClassification:{local:Mg(hA(a)),cloud:Mg(hA(e))},parentPhaseProvenance:i==="product"?UC(o):null,listNormalizationProvenance:i==="list"?Tb(r):null,syncConflict:f,syncPendingCloudWrite:a.syncPendingCloudWrite===!0,existingConflictDraft:NF(s.conflictDraft),relationship:s.relationship?{action:s.relationship.action||"",apply:!!s.relationship.apply,changed:!!s.relationship.changed,fromListId:Ti(s.relationship.fromListId),toListId:Ti(s.relationship.toListId)}:null,reviewSources:{equalRevisionComparison:!!(s.requiresReview&&(m==="equal-revision-active-conflict"||m==="equal-server-timestamp-active-conflict")),historicalConflictMetadata:!!a.syncConflict,missingParentRelationship:m==="cloud-product-parent-board-unavailable",pendingPatchOrWrite:!!(a.syncPendingCloudWrite===!0||a.syncConflictPatch||s.conflictDraft)}}},jF=(e={})=>Object.values(e).reduce((t,r)=>{const a=Number(r);return t+(Number.isFinite(a)&&a>0?a:0)},0),vA=(e=[])=>[...new Set((Array.isArray(e)?e:[]).map(t=>String(t?.field||t||"")).filter(Boolean))].sort(),yA=e=>e?{...QS(e),parentBoardId:Ti(e.parentBoardId)}:null,RF=({aggregateConflicts:e={},editorNeedsReview:t=!1,editorSession:r=null,parentBoardDiagnostic:a=null,productDiagnostic:s=null,queueState:o={},storeRecord:i=null}={})=>{const c=r?Tg({latestRecord:i,session:r}):null,l=!!s?.requiresReview,u=!!a?.requiresReview,p=!!(o.recordPendingCloudWrite||o.conflictRegistryContainsRecord||s?.reviewSources?.pendingPatchOrWrite),m=!!s?.reviewSources?.historicalConflictMetadata,f=!!s?.reviewSources?.missingParentRelationship,h=!!s?.reviewSources?.equalRevisionComparison,b=!!(l&&!h&&
14!f&&!m&&!p),v=!!((r?.needsReview||t||c?.blocked)&&!l&&!u&&!p&&!m&&!f),S=!!(jF(e)&&!l&&!u&&!p&&!m&&!f&&!v),C=[h&&"item-equal-revision-comparison",b&&"item-reconciliation",u&&"parent-board-review",f&&"missing-parent-relationship",m&&"historical-conflict-metadata",p&&"write-queue-or-pending-patch",S&&"account-aggregate-review-only",v&&"editor-session-logic"].filter(Boolean);return{diagnosticVersion:5,generatedAt:new Date().toISOString(),mode:"read-only-sync-review",selectedItem:yA(s)||{redactedRecordId:Ti(i?.id),localRevision:Nn(i||{}),cloudRevision:null,outcome:"not-captured",reason:"no-foreground-record-diagnostic"},parentBoard:a?yA(a):{outcome:"not-captured",reason:s?.parentBoardId?"parent-board-diagnostic-unavailable":"item-parent-board-unavailable",requiresReview:!1},aggregateForegroundReviewCounters:e,topLevelConflictMap:e,pendingWriteQueueState:{conflictRegistryContainsRecord:!!o.conflictRegistryContainsRecord,queueSessionMatches:!!o.queueSessionMatches,recordPendingCloudWrite:!!o.recordPendingCloudWrite,queueDepth:"not-introspectable-from-promise-chain"},editor:{productId:Ti(r?.productId||i?.id),openingRevision:r?.openingRevision??null,latestBaseRevision:r?.latestBaseRevision??null,currentStoreRevision:Nn(i||{}),dirty:!!r?.dirty,needsReview:!!(r?.needsReview||t),needsReviewSource:C,submissionBlocked:!!c?.blocked,submissionReasonCode:c?.reason||""},reviewOrigin:C.length?C:["none-for-selected-item"],writesPerformed:0}};function QS(e={}){return{recordFingerprint:e.recordFingerprint||oo(e.recordId),redactedRecordId:e.redactedRecordId||Ti(e.recordId),entityType:e.entityType||"unknown",recordClassification:e.recordClassification||"active",localRevision:e.localRevision??null,cloudRevision:e.cloudRevision??null,outcome:e.outcome||"unknown",reason:$u(e.reason),requiresReview:!!e.requiresReview,fieldDifferences:vA(e.fieldDifferences),storedConflictReason:$u(e.storedConflictReason),patchState:MN.includes(e.patchState)?e.patchState:"absent",patchKeys:[...new Set((e.patchKeys||[]).map(FN))].sort(),patchKinds:Dg.filter(t=>e.patchKinds?.includes(t)),pendingCloudWrite:!!e.pendingCloudWrite,canonicalDifferenceFields:vA(e.canonicalDifferenceFields),relationshipClassification:UN.includes(e.relationshipClassification)?e.relationshipClassification:"unknown",cleanupEligibility:!!e.cleanupEligibility,cleanupBlockers:[...new Set((e.cleanupBlockers||[]).map($u).filter(Boolean))].sort(),imageComparisonClassification:rf(e.imageComparisonClassification||{local:Mg(""),cloud:Mg("")}),parentPhaseProvenance:UC(e.parentPhaseProvenance),listNormalizationProvenance:Tb(e.listNormalizationProvenance)}}const Bm=e=>Object.fromEntries(e.map(t=>[t,0])),gi=(e,t)=>{const r=String(t||"none");e[r]=Number(e[r]||0)+1},fl=(e={})=>Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r))),LF=(e=[])=>{const t=e.filter(p=>p.entityType==="product"),r=Bm([...Rg,"none"]),a=Bm(PC),s={};let o=0,i=0,c=0,l=0;t.forEach(p=>{const m=UC(p.parentPhaseProvenance),f=m?.firstChangedPhase||"none";gi(r,f),m?.phases?.length&&(l+=1,o+=m.normalizedBeforeListsAvailable?1:0,i+=m.cloudParentExisted?1:0,c+=m.explicitMoveEvidence?1:0,[...new Set(m.phases.map(h=>h.normalizationDecision))].forEach(h=>gi(a,h)),m.firstChangedTargetFingerprint&&gi(s,m.firstChangedTargetFingerprint))});const u=Object.fromEntries(Object.entries(s).filter(([,p])=>p>1).sort(([p],[m])=>p.localeCompare(m)));return{recordsWithEvidence:l,recordsByFirstChangedPhase:fl(r),recordsByNormalizationDecision:fl(a),productsNormalizedBeforeListsAvailable:o,productsWhoseCloudParentExisted:i,productsRepeatedlyRemappedToSameLocalTargetFingerprint:Object.values(u).reduce((p,m)=>p+m,0),repeatedLocalTargetFingerprints:u,productsWithExplicitMoveEvidence:c,productsWithNoExplicitMoveEvidence:t.length-c}},BF=(e=[])=>{const t=Bm(MN),r=Bm(Dg),a=Bm(UN),s={},o={},i={},c=[];let l=0,u=0,p=0;e.forEach(v=>{gi(t,v.patchState),(v.patchKinds||[]).forEach(C=>gi(r,C)),gi(a,v.relationshipClassification),gi(s,v.storedConflictReason||"none"),(v.canonicalDifferenceFields||[]).forEach(C=>gi(o,C)),(v.cleanupBlockers||[]).forEach(C=>gi(i,C)),l+=v.pendingCloudWrite?1:0,p+=v.cleanupEligibility?1:0;const S=Object.values(v.imageComparisonClassification||{});S.some(C=>C?.matchesCurrentOfficialPlaceholder)&&(u+=1),c.push([...new Set(S.filter(C=>C?.isSaveBoardPlaceholderSvgCandidate&&!C.matchesCurrentOfficialPlaceholder&&C.fingerprint).map(C=>C.fingerprint))])});const m={};
14c.forEach(v=>{v.forEach(S=>gi(m,S))});const f=Object.fromEntries(Object.entries(m).filter(([,v])=>v>1).sort(([v],[S])=>v.localeCompare(S))),h=new Set(Object.keys(f)),b=c.filter(v=>v.some(S=>h.has(S))).length;return{totalActiveReviewRecords:e.length,listReviewRecords:e.filter(v=>v.entityType==="list").length,productReviewRecords:e.filter(v=>v.entityType==="product").length,recordsByPatchState:fl(t),recordsByPatchKind:fl(r),recordsWithPendingCloudWrites:l,recordsByConflictReason:fl(s),recordsByCanonicalDifferenceField:fl(o),recordsByRelationshipClassification:fl(a),recordsMatchingCurrentOfficialPlaceholder:u,recordsMatchingOtherRepeatedSaveBoardSvgFingerprint:b,otherRepeatedSaveBoardSvgFingerprints:f,recordsEligibleForMetadataCleanup:p,recordsBlockedByCleanupBlocker:fl(i),productParentPhaseProvenance:LF(e)}},TF=({aggregateConflicts:e={},diagnostics:t={}}={})=>{const r=Array.isArray(t.lists)?t.lists:[],a=Array.isArray(t.products)?t.products:[],s=[...r,...a].filter(c=>c.requiresReview),o=s.filter(c=>c.recordClassification!=="tombstone"),i=s.filter(c=>c.recordClassification==="tombstone");return{diagnosticVersion:5,generatedAt:new Date().toISOString(),mode:"read-only-sync-review",evidenceState:"foreground",message:"Foreground evidence available",aggregateForegroundReviewCounters:e,activeReviewClassificationCounts:BF(o),tombstoneEvidence:{reviewConflictCount:Number(e.tombstoneReviewConflicts||0),diagnosticRecordsExcludedFromActiveClassification:i.length},recordEvidence:{listCount:r.length,productCount:a.length,reviewLists:o.filter(c=>c.entityType==="list").map(QS),reviewProducts:o.filter(c=>c.entityType==="product").map(QS)},writesPerformed:0}},DF=()=>({diagnosticVersion:5,generatedAt:new Date().toISOString(),mode:"read-only-sync-review",evidenceState:"waiting",message:"Waiting for sync evidence",writesPerformed:0}),OF=({initialSearch:e="",targetWindow:t=null}={})=>{const r=wF(e),a=new Set;let s={enabled:r,evidenceState:r?"waiting":"disabled",packet:r?DF():null},o=null;const i=()=>{t&&(r?t.SAVEBOARD_SYNC_DIAGNOSTIC=s.packet:delete t.SAVEBOARD_SYNC_DIAGNOSTIC)};i();const c=(u,p)=>(o&&p==="foreground"&&(o={...o,transaction:{...o.transaction||{},foregroundEnabled:!0}}),{...u,diagnosticVersion:5,...o?{accountHydration:o}:{}}),l=(u,p)=>(s={enabled:!0,evidenceState:p,packet:u},i(),a.forEach(m=>m()),s);return{enabled:r,getSnapshot:()=>s,publish:(u,p="foreground")=>{if(!r)return s;const m=Py({...c(u,p),evidenceState:p,writesPerformed:0});return l(m,p)},recordAccountHydrationEvidence:(u={})=>{if(!r)return s;o=Py({...u,writesPerformed:0});const p=Py({diagnosticVersion:5,generatedAt:new Date().toISOString(),mode:"read-only-sync-review",evidenceState:"hydration",message:"Account hydration evidence available",accountHydration:o,writesPerformed:0});return l(p,"hydration")},subscribe:u=>(a.add(u),()=>a.delete(u))}},MF=typeof window>"u"?null:window,UF="",Ug=OF({initialSearch:UF,targetWindow:MF}),Ac=()=>Ug.enabled,SA=(e,t)=>Ug.publish(e,t),HN=e=>{try{return Ug.recordAccountHydrationEvidence(e)}catch{return Ug.getSnapshot()}},WN="mylist.cloudBackupState",wA="mylist.backupDeviceId",Fg=1,$g=3,GN="cloudBackup",FC="cloudBackupPayload",qN="This browser",FF="Restore stopped because Saveboard could not create a safety backup.",$F=new Set(["manual","pre_restore_safety","imported","legacy"]),zF=["app","appName","schemaVersion","version","exportedAt","backedUpAt","lists","products","boardOrder","listOrder","productOrder","settings","viewState","extension","metadata"],VF=["availability","availabilityTracking","availabilityHistory","availabilityAlertEvents"],HF=["priceHistory","targetPrice","targetCurrency","targetAmount","priceAlert","priceTracking","priceAlertEvents"],YN=new Set(["active","purchased","archived"]),WF=new Set(["boardOrder",GN,FC,"extension","metadata","priceAlertEvents","priceSnapshots","productOrder","viewState"]),Jn=(e,t)=>{const r=new Error(e);return r.name="CloudBackupError",r.cause=t,r},KN=()=>{if(typeof window>"u")return{};try{const e=window.localStorage.getItem(WN);return e?JSON.parse(e):{}}catch{return{}}},GF=e=>{if(!(typeof window>"u"))try{window.localStorage.setItem(WN,JSON.stringify(e))}catch{}},_y=()=>typeof crypto<"u"&&crypto.randomUUID?`browser-${crypto.randomUUID()}`:`browser-${Date.now()}-${Math.random().toString(16).slice(2)}`,CA=()=>{if(typeof window>"u")return _y();try{const e=window.localStorage.getItem(wA);if(e)return e;const t=_y();return window.localStorage.setItem(wA,t),t}catch{return _y()}},hi=e=>e&&KN()[e]||null,$C=(e,t)=>{if(!e)return t;const r=KN(),a={...t,schemaVersion:Fg};return r[e]=a,GF(r),a},ad=(e,t)=>$C(e,t),Pc=e=>{const t=new Date(e);return Number.isFinite(t.getTime())?new Intl.DateTimeFormat(void 0,{dateStyle:"medium",timeStyle:"short"}).format(t):""},Bt=(e,t="")=>String(e??"").trim()||t,XN=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),Xr=e=>Bt(e)||null,Lc=(e,t=null)=>{const r=Number(e);return Number.isFinite(r)?Math.trunc(r):t},Eh=e=>{const t=Number(e);return Number.isFinite(t)?t:null},Ri=(e,t=new Date().toISOString())=>{const r=new Date(e||t);return Number.isFinite(r.getTime())?r.toISOString():t}
14,xA=(e=[])=>[...e].sort((t,r)=>{const a=Lc(t?.sort_order,Number.MAX_SAFE_INTEGER),s=Lc(r?.sort_order,Number.MAX_SAFE_INTEGER);return a!==s?a-s:Bt(t?.id).localeCompare(Bt(r?.id),void 0,{sensitivity:"base"})}),Ci=e=>{if(!e)return null;const t=new Date(e);return Number.isFinite(t.getTime())?t.toISOString():null},fs=e=>!!(e&&typeof e=="object"&&!Array.isArray(e)),Mb=(e={})=>Object.fromEntries(Object.entries(fs(e)?e:{}).filter(([t])=>!WF.has(t))),Bl=()=>{if(!An.isConfigured||!ae)throw Jn("Cloud backup is not configured yet.")},Tc=e=>{if(!e?.id)throw Jn("Sign in before backing up to your account.");return e},JN=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return t.includes("relation")&&t.includes("does not exist")?"Cloud backup is not set up yet. Apply the Supabase schema, then try again.":t.includes("column")&&t.includes("does not exist")?"Cloud backup schema is out of date. Apply the latest Supabase migrations, then try again.":t.includes("row-level security")||t.includes("permission")||r==="42501"?"Cloud backup is not allowed for this account yet. Check the Supabase access policies.":t.includes("failed to fetch")||t.includes("fetch failed")||t.includes("network")?"Could not reach cloud backup. Check your connection and try again.":"Cloud backup could not be completed. Try again in a moment."},qF=e=>{if(e?.error)throw Jn(JN(e.error),e.error);return e},Dn=async e=>{try{return qF(await e)}catch(t){throw t?.name==="CloudBackupError"?t:Jn(JN(t),t)}},YF=(e,t,r=null,a=t)=>{const s=Bt(e.listId);if(s)return t.some(l=>l.id===s)?s:null;const o=Bt(e.listName||e.category),i=AC(a,o);if(i.length>1)return null;const c=Bt(i[0]?.id);return c?t.some(l=>l.id===c)?c:null:r},QN=(e={})=>zF.reduce((t,r)=>(e[r]!==void 0&&(t[r]=e[r]),t),{}),IA=(e=[],t=[])=>e.filter(r=>t.some(a=>r?.[a]!==void 0)).length,ZN=(e="manual")=>$F.has(e)?e:"manual",KF=(e={})=>{if(!Array.isArray(e.lists)||!Array.isArray(e.products)||!fs(e.settings))throw Jn("Local Saveboard data could not be prepared for account backup snapshot.")},ej=({backup:e,backedUpAt:t,metadataSource:r="manual-cloud-backup"})=>{const a=QN(e),s=Lc(a.schemaVersion??a.version,$g)||$g,o=Array.isArray(a.lists)?a.lists:[],i=Array.isArray(a.products)?a.products:[],c=Mb(a.settings||{});return{...a,app:Bt(a.app,"my-list"),appName:Bt(a.appName,"Saveboard"),schemaVersion:s,version:s,exportedAt:Ri(a.exportedAt,t),backedUpAt:t,lists:o,products:i,boardOrder:Array.isArray(a.boardOrder)?a.boardOrder:o.map(l=>l.id).filter(Boolean),listOrder:Array.isArray(a.listOrder)?a.listOrder:o.map(l=>l.id).filter(Boolean),productOrder:Array.isArray(a.productOrder)?a.productOrder:i.map(l=>l.id).filter(Boolean),settings:c,viewState:fs(a.viewState)?a.viewState:{},extension:fs(a.extension)?a.extension:{},metadata:{...fs(a.metadata)?a.metadata:{},cloudBackupSchemaVersion:Fg,cloudBackupFormatVersion:s,backedUpAt:t,source:r}}},XF=({backup:e,backedUpAt:t=new Date().toISOString(),source:r="manual-cloud-backup"}={})=>ej({backup:e,backedUpAt:t,metadataSource:r}),tj=(e={})=>({id:Bt(e.id),appVersion:Bt(e.app_version),createdAt:Bt(e.created_at),deviceId:Bt(e.device_id),deviceLabel:Bt(e.device_label,qN),listCount:_u(e.list_count),payload:e.payload||null,productCount:_u(e.product_count),schemaVersion:Bt(e.schema_version),snapshotType:ZN(e.snapshot_type),updatedAt:Bt(e.updated_at)}),JF=(e,t)=>e==="pre_restore_safety"?`Before restore - ${Pc(t)||"this browser"}`:qN,QF=async({appVersion:e="",backup:t,deviceId:r=CA(),deviceLabel:a="",snapshotType:s="manual",user:o}={})=>{Bl();const i=Tc(o);KF(t);const c=ZN(s),l=new Date().toISOString(),u=XF({backup:t,backedUpAt:l,source:c==="pre_restore_safety"?"pre-restore-safety-snapshot":"manual-cloud-backup"}),p=Array.isArray(u.lists)?u.lists:[],m=Array.isArray(u.products)?u.products:[],f=Bt(r)||CA(),h=Bt(a)||JF(c,l),b=await Dn(ae.from("account_backup_snapshots").insert({app_version:Xr(e),device_id:f,device_label:Xr(h),list_count:p.length,payload:u,product_count:m.length,schema_version:Bt(u.schemaVersion),snapshot_type:c,updated_at:l,user_id:i.id}).select("id, user_id, device_id, device_label, snapshot_type, schema_version, app_version, list_count, product_count, created_at, updated_at").single());return tj(b.data)},AA=async({backup:e,user:t}={})=>{try{return await QF({backup:e,deviceLabel:"",snapshotType:"pre_restore_safety",user:t})}catch(r){throw Jn(FF,r)}},PA=async({user:e}={})=>{Bl();const t=Tc(e);return((await Dn(ae.from("account_backup_snapshots").select("id, user_id, device_id, device_label, snapshot_type, schema_version, app_version, list_count, product_count, created_at, updated_at").eq("user_id",t.id).order("updated_at",{ascending:!1}))).data||[]).map(tj)},ZF=async({snapshotId:e,user:t}={})=>{Bl();const r=Tc(t),a=Bt(e);
14if(!a||!(await Dn(ae.from("account_backup_snapshots").delete().eq("user_id",r.id).eq("id",a).select("id").maybeSingle())).data)throw Jn("Could not delete this backup.");return{snapshotId:a}},e2=(e={})=>{const t=fs(e)?e[FC]:null;if(!t)return null;if(!fs(t)||!Array.isArray(t.lists)||!Array.isArray(t.products)||!fs(t.settings))throw Jn("Account backup looks incomplete. Your local data was not changed.");const r=Lc(t.schemaVersion??t.version,null);if(!r||r<1)throw Jn("Account backup looks incompatible. Your local data was not changed.");return{...QN(t),app:Bt(t.app,"my-list"),appName:Bt(t.appName,"Saveboard"),schemaVersion:r,version:r,exportedAt:Ri(t.exportedAt,t.backedUpAt||new Date().toISOString()),backedUpAt:Ci(t.backedUpAt)||void 0,settings:Mb(t.settings),viewState:fs(t.viewState)?t.viewState:{},extension:fs(t.extension)?t.extension:{},metadata:fs(t.metadata)?t.metadata:{}}},dp=({backup:e,user:t})=>{const r=Tc(t),a=Array.isArray(e?.lists)?e.lists:null,s=Array.isArray(e?.products)?e.products:null,o=e?.settings&&typeof e.settings=="object"&&!Array.isArray(e.settings)?e.settings:null;if(!a||!s||!o)throw Jn("Local Saveboard data could not be prepared for cloud backup.");const i=new Date().toISOString(),c={id:r.id,email:Xr(r.email),display_name:Xr(r.user_metadata?.full_name||r.user_metadata?.name),updated_at:i},l=a.map(P=>Bt(P.id));if(l.some(P=>!P)||new Set(l).size!==l.length)throw Jn("Cloud backup stopped because a board has an invalid identity. Refresh Saveboard and try again.");const p=a.filter(P=>!es(P)).map((P,V)=>{const L=Ri(P.createdAt,i);return{id:Bt(P.id),user_id:r.id,name:Bt(P.name,"Untitled list"),slug:Xr(P.slug),description:Xr(P.description),public_description:Xr(P.publicDescription),is_public:!!P.isPublic,created_at:L,updated_at:Ri(P.updatedAt,L),archived_at:Ci(P.archivedAt||(P.isArchived?P.updatedAt||L:"")),sort_order:Lc(P.sortOrder,V),budget_amount:Eh(P.budgetAmount??P.budget),budget_currency:Xr(P.budgetCurrency||P.currency)}}),m=[...new Set(l)],f=p[0]?.id||null,h=s.map(P=>Bt(P.id));if(h.some(P=>!P)||new Set(h).size!==h.length)throw Jn("Cloud backup stopped because an item has an invalid identity. Refresh Saveboard and try again.");const b=s.filter(P=>!es(P)),v=b.map((P,V)=>{const L=Ri(P.createdAt,i),z=YN.has(P.status)?P.status:"active",B=tC(P,{isPlaceholder:Vn});if(B.action==="review")throw Jn("Cloud sync stopped because an item image reference needs review. No item data was changed.");const re=B.action==="set"?{image_url:Xr(B.value)}:B.action==="clear"?{image_url:null}:{};return{id:Bt(P.id),user_id:r.id,list_id:YF(P,p,f,a),title:Bt(P.title,"Untitled product"),price:Xr(P.price),brand:Xr(P.brand),card_size:zn(P.cardSize??P.card_size),image_framing_overrides:ya(P.imageFramingOverrides??P.image_framing_overrides),source:Xr(P.source),url:Xr(P.url),...re,note:Xr(P.privateNotes??P.notes),public_note:Xr(P.publicNotes),size:Xr(P.size),colour:Xr(P.colour),variant:Xr(P.variant),status:z,sort_order:Lc(P.sortOrder,V),image_fit:Xr(P.imageFit),image_scale:Eh(P.imageScale),image_position_x:Eh(P.imagePositionX),image_position_y:Eh(P.imagePositionY),image_background_mode:Xr(P.imageBackgroundMode),image_background_color:Xr(P.imageBackgroundColor),created_at:L,updated_at:Ri(P.updatedAt,L),archived_at:Ci(P.archivedAt||(z==="archived"?P.updatedAt||L:"")),purchased_at:Ci(P.purchasedAt||(z==="purchased"?P.updatedAt||L:"")),...UU(P),...GU(P)}}),S=[...new Set(h)];if(v.some(P=>!P.list_id))throw Jn("Cloud backup stopped because an item has an ambiguous board identity. Open the item and choose its board again.");const C=YU(s,r.id),I=JU(s,r.id),A=zU(s,r.id),k=ej({backup:e,backedUpAt:i}),E=Mb(o),y=IA(b,VF),N=IA(b,HF),_={user_id:r.id,settings_json:{...E,boardOrder:e.boardOrder||e.listOrder||p.map(P=>P.id),extension:e.extension||{},metadata:{...fs(e.metadata)?e.metadata:{},cloudBackupSchemaVersion:Fg,backedUpAt:i,exportedAt:k.exportedAt,backedUpFrom:"local-browser",availabilityProductCount:y,availabilityAlertEventCount:A.length,pricedProductDataCount:N,priceAlertEventCount:I.length,priceSnapshotCount:C.length},productOrder:e.productOrder||v.map(P=>P.id),viewState:e.viewState||{},[GN]:{schemaVersion:Fg,backupFormatVersion:k.schemaVersion,backedUpAt:i,exportedAt:k.exportedAt,listCount:p.length,productC
14ount:v.length,priceSnapshotCount:C.length,priceAlertEventCount:I.length,availabilityAlertEventCount:A.length,availabilityProductCount:y,pricedProductDataCount:N},[FC]:k},updated_at:i};return{listIds:m,lists:p,availabilityAlertEventIds:A.map(P=>P.id),availabilityAlertEvents:A,productIds:S,products:v,profile:c,priceAlertEventIds:I.map(P=>P.id),priceAlertEvents:I,priceSnapshotIds:C.map(P=>P.id),priceSnapshots:C,settings:_}},xf=({lists:e=[],products:t=[],settings:r=null})=>{const a=[r?.updated_at,r?.updatedAt,...e.map(s=>s.updated_at||s.created_at),...e.map(s=>s.updatedAt||s.createdAt),...t.map(s=>s.updated_at||s.created_at),...t.map(s=>s.updatedAt||s.createdAt)].map(s=>Date.parse(s)).filter(Number.isFinite);return a.length?new Date(Math.max(...a)).toISOString():""},_u=e=>Lc(e,0)||0,kh=(e,t,r)=>`${e} ${e===1?t:r}`,t2=({lists:e=[],products:t=[],settings:r=null}={})=>{const a=Array.isArray(e)?e:[],s=Array.isArray(t)?t:[];return{hasLocalData:a.length>0||s.length>0,latestUpdatedAt:xf({lists:a,products:s,settings:r}),listCount:a.length,productCount:s.length}},r2=({local:e={},cloud:t={}}={})=>{const r=_u(e.listCount),a=_u(e.productCount),s=_u(t.listCount),o=_u(t.productCount),i=!!(e.hasLocalData??(r>0||a>0)),c=t.hasCloudData===!0||t.hasCloudData===!1||!!t.checkedAt||Number.isFinite(Number(t.listCount))||Number.isFinite(Number(t.productCount)),l=!!(t.hasCloudData??(c&&(s>0||o>0||!!(t.latestUpdatedAt||t.lastBackedUpAt)))),u=e.latestUpdatedAt||e.lastUpdatedAt||"",p=t.latestUpdatedAt||t.lastBackedUpAt||"",m=r-s,f=a-o,h=Date.parse(u),b=Date.parse(p);let v="Refresh status to compare this browser with cloud backup.",S="unknown";return c&&(!i&&!l?(v="No local products or cloud backup yet.",S="empty"):i&&!l?(v="Local data is ready to back up.",S="local-only"):!i&&l?(v="Cloud backup is available to restore.",S="cloud-only"):f>0?(v=`Local has ${kh(f,"more product","more products")} than cloud.`,S="local-different"):f<0?(v=`Cloud has ${kh(Math.abs(f),"more product","more products")} than this browser.`,S="cloud-different"):m>0?(v=`Local has ${kh(m,"more board","more boards")} than cloud.`,S="local-different"):m<0?(v=`Cloud has ${kh(Math.abs(m),"more board","more boards")} than this browser.`,S="cloud-different"):Number.isFinite(h)&&Number.isFinite(b)&&Math.abs(h-b)>6e4?(v=h>b?"Local data appears newer than cloud.":"Cloud backup appears newer than this browser.",S=h>b?"local-newer":"cloud-newer"):(v="Local and cloud appear up to date.",S="matched")),{cloud:{exists:l,known:c,latestUpdatedAt:p,listCount:s,productCount:o},freshness:S,listDifference:m,local:{exists:i,known:!0,latestUpdatedAt:u,listCount:r,productCount:a},productDifference:f,summary:v}},n2=({lists:e,products:t,settings:r})=>{if(!Array.isArray(e)||!Array.isArray(t))throw Jn("Could not restore backup. Your local data was not changed.");if(!e.length&&!t.length&&!r)throw Jn("No cloud backup found yet.");if(t.length&&!e.length)throw Jn("Could not restore backup. Your local data was not changed.");const a=new Set(e.map(i=>Bt(i?.id)).filter(Boolean)),s=e.some(i=>!i||typeof i!="object"||!Bt(i.id)||!Bt(i.name)),o=t.some(i=>!i||typeof i!="object"||!Bt(i.id)||!Bt(i.title)||!a.has(Bt(i.list_id)));if(s||o||r&&typeof r!="object")throw Jn("Could not restore backup. Your local data was not changed.")},Ey=(e=[],t)=>{const r=new Map;return e.forEach(a=>{const s=Bt(a.product_id);if(!s)return;const o=r.get(s)||[];o.push(t(a)),r.set(s,o)}),r},Ub=({availabilityAlertEvents:e=[],captureParentProvenance:t=!1,lists:r=[],privateOwnerScoped:a=!1,products:s=[],settings:o=null,priceSnapshots:i=[],priceAlertEvents:c=[]})=>{const l=o?.settings_json&&fs(o.settings_json)?o.settings_json:{},u=new Date().toISOString(),p=e2(l);if(p&&!r.length&&!s.length)return{...p,metadata:{...p.metadata,source:"cloud-restore",restoredAt:u}};n2({lists:r,products:s,settings:o}),t&&(dF(),r.forEach((_,P)=>{tp({inputPosition:P,listId:_?.id,phase:"raw-cloud-row",privateOwnerScoped:a,rawCloudPresence:!0,record:_})}));const m=xA(r),f=new Map(m.map(_=>[Bt(_.id),Bt(_.name,"Wishlist")])),h=new Set(m.map(_=>Bt(_.id)).filter(Boolean)),b=xA(s),v=Ey(i,KU),S=Ey(c,QU),C=Ey(e,VU),I=m[0]?.name||"W
14ishlist",A=(_={})=>{const P=Lc(_.revision,null);return{cloudDeletedAt:Ci(_.deleted_at)||void 0,cloudDeletionId:Xr(_.deletion_id)||void 0,cloudDeletionReason:Xr(_.deletion_reason)||void 0,cloudPurgeAfter:Ci(_.purge_after)||void 0,cloudRestoredAt:Ci(_.restored_at)||void 0,cloudRestoredBy:Xr(_.restored_by)||void 0,cloudUpdatedAt:Ci(_.updated_at)||void 0,syncConflict:"",...P&&P>0?{syncRevision:P}:{},syncSuppressed:!!_.deleted_at}},k=m.map((_,P)=>({id:Bt(_.id,`list-${P+1}`),userId:Bt(_.user_id),name:Bt(_.name,"Untitled list"),slug:Xr(_.slug)||void 0,description:Xr(_.description)||"",publicDescription:Xr(_.public_description)||"",isPublic:!!_.is_public,sortOrder:Lc(_.sort_order,P),budget:ZU(_.budget_amount),budgetCurrency:Xr(_.budget_currency)||void 0,createdAt:Ri(_.created_at,u),updatedAt:Ri(_.updated_at,_.created_at||u),archivedAt:Ci(_.archived_at)||void 0,isArchived:!!_.archived_at,...A(_)}));t&&k.forEach((_,P)=>{tp({inputPosition:P,listId:_?.id,phase:"mapped-cloud-list",privateOwnerScoped:a,rawCloudPresence:!0,record:_})});const E=b.map((_,P)=>{const V=Bt(_.list_id),L=V||k[0]?.id||"",z=f.get(L)||I;t&&Ec({enabled:!0,normalizationDecision:"preserved-existing",parentExists:!!(V&&h.has(V)),parentId:V,phase:"raw-cloud-row",productId:_.id});const B=kb(_,{availabilityAlertEvents:C.get(Bt(_.id))||[],index:P,listName:z,priceAlertEvents:S.get(Bt(_.id))||[],priceHistory:v.get(Bt(_.id))||[]}),re={...B,listId:L,listName:z,category:z,status:YN.has(B.status)?B.status:"active",createdAt:Ri(_.created_at,u),updatedAt:Ri(_.updated_at,_.created_at||u),...A(_)};return t&&Ec({enabled:!0,listsHydratedBeforeProductNormalization:!0,normalizationDecision:V===L?"preserved-existing":"missing-parent-fallback",parentExists:!!(L&&k.some(Z=>Bt(Z.id)===L)),parentId:L,phase:"cloud-product-mapping",productId:_.id,sourceParentExists:!!(V&&h.has(V))}),re}),y=_=>{if(!t)return _;const P=new Set((_.lists||[]).map(V=>Bt(V?.id)).filter(Boolean));return(_.products||[]).forEach(V=>{const L=Bt(V?.listId||V?.list_id);Ec({enabled:!0,listsHydratedBeforeProductNormalization:!0,normalizationDecision:"preserved-existing",parentExists:!!(L&&P.has(L)),parentId:L,phase:"cloud-candidate-constructed",productId:V?.id,sourceParentExists:!!(L&&P.has(L))})}),_};if(p){const _=SN({backup:p,lists:k,products:E});return y({..._,metadata:{..._.metadata,source:"cloud-restore",restoredAt:u}})}const N=xf({lists:m,products:b,settings:o});return y({app:"my-list",appName:"Saveboard",schemaVersion:$g,version:$g,exportedAt:N||u,lists:k,products:E,boardOrder:l.boardOrder||k.map(_=>_.id),listOrder:l.boardOrder||k.map(_=>_.id),productOrder:l.productOrder||E.map(_=>_.id),settings:Mb(l),viewState:l.viewState||{},extension:l.extension||{},metadata:{...fs(l.metadata)?l.metadata:{},source:"cloud-restore",restoredAt:u}})},ky=async(e,t,r="user_id")=>(await Dn(ae.from(e).select(r,{count:"exact",head:!0}).eq(r,t))).count||0,Ny=async(e,t)=>(await Dn(ae.from(e).select("updated_at").eq("user_id",t).order("updated_at",{ascending:!1,nullsFirst:!1}).limit(1).maybeSingle())).data?.updated_at||"",ZS=async({user:e})=>{Bl();const t=Tc(e),[r,a,s,o,i,c]=await Promise.all([ky("lists",t.id),ky("products",t.id),ky("settings",t.id),Ny("lists",t.id),Ny("products",t.id),Ny("settings",t.id)]),l=xf({lists:[{updated_at:o}],products:[{updated_at:i}],settings:{updated_at:c}});return{hasCloudData:r>0||a>0||s>0,lastBackedUpAt:l,latestUpdatedAt:l,listCount:r,productCount:a,settingsCount:s,checkedAt:new Date().toISOString()}},a2=({user:e})=>ZS({user:e}),s2=async({user:e})=>{Bl();const t=Tc(e),[r,a,s,o,i,c]=await Promise.all([Dn(ae.from("lists").select("*").eq("user_id",t.id).order("sort_order",{ascending:!0,nullsFirst:!1}).order("created_at",{ascending:!0})),Dn(ae.from("products").select("*").eq("user_id",t.id).order("sort_order",{ascending:!0,nullsFirst:!1}).order("created_at",{ascending:!0})),Dn(ae.from("settings").select("settings_json, updated_at").eq("user_id",t.id).maybeSingle()),Dn(ae.from("price_snapshots").select("*").eq("user_id",t.id).order("recorded_at",{ascending:!0})),Dn(ae.from("price_alert_events").select("*").eq("user_id",t.id).order("created_at",{ascending:!0})),Dn(ae.from("availability_alert_events").select("*").eq("user_id",t.id).order("created_at",{ascending:!0}))]),l={availabilityAlertEvents:c.data||[],lists:r.data||[],products:a.data||[],priceAlertEvents:i.data||[],priceSnapshots:o.data||[],settings:s.data||null},u=Ub(l),p=xf(l)||u.exportedAt;return{backup:u,cloudBackedUpAt:p,listCount:u.lists.length,productC
14ount:u.products.length}},ew=async({user:e})=>{Bl();const t=Tc(e),[r,a,s]=await Promise.all([Dn(ae.from("lists").select("*").eq("user_id",t.id).order("sort_order",{ascending:!0,nullsFirst:!1}).order("created_at",{ascending:!0})),Dn(ae.from("products").select("*").eq("user_id",t.id).order("sort_order",{ascending:!0,nullsFirst:!1}).order("created_at",{ascending:!0})),Dn(ae.from("settings").select("settings_json, updated_at").eq("user_id",t.id).maybeSingle())]),o={lists:r.data||[],products:a.data||[],settings:s.data||null};if(!(o.lists.length>0||o.products.length>0))return{backup:null,cloudBackedUpAt:"",hasCloudData:!1,listCount:0,privateOwnerScoped:!0,productCount:0,rawProductCleanupEvidence:[]};const c=Ub({...o,captureParentProvenance:Ac(),privateOwnerScoped:!0}),l=xf(o)||c.exportedAt;return{backup:c,cloudBackedUpAt:l,hasCloudData:!0,listCount:c.lists.length,privateOwnerScoped:!0,productCount:c.products.length,rawProductCleanupEvidence:H1(o.products)}},Eu=async(e,t,r)=>{t.length&&await Dn(ae.from(e).upsert(t,r))},o2=(e=[],t=[])=>{const r=new Set((Array.isArray(t)?t:[]).map(s=>Bt(s?.id)).filter(Boolean)),a={inserts:[],updates:[],upserts:[]};
14return(Array.isArray(e)?e:[]).forEach(s=>{if(XN(s,"image_url")){a.upserts.push(s);return}if(r.has(Bt(s?.id))){a.updates.push(s);return}a.inserts.push(s)}),a},rj=async({productRows:e=[],userId:t=""}={})=>{const r=e.filter(o=>!XN(o,"image_url")).map(o=>Bt(o?.id)).filter(Boolean),a=[];for(let o=0;o<r.length;o+=150){const i=await Dn(ae.from("products").select("id").eq("user_id",t).in("id",r.slice(o,o+150)));a.push(...i.data||[])}const s=o2(e,a);await Eu("products",s.upserts,{onConflict:"user_id,id"}),s.inserts.length&&await Dn(ae.from("products").insert(s.inserts));for(const o of s.updates){const{id:i,user_id:c,...l}=o;await Dn(ae.from("products").update(l).eq("user_id",c||t).eq("id",i))}},i2=(e=[],t=[],{preserveDeletedRows:r=!1}={})=>{const a=new Set(t);return(Array.isArray(e)?e:[]).filter(s=>!(r&&Ci(s?.deleted_at))).map(s=>s?.id).filter(s=>s&&!a.has(s))},am=async(e,t,r,{preserveDeletedRows:a=!1}={})=>{const s=["id",...a?["deleted_at"]:[]].join(","),o=await Dn(ae.from(e).select(s).eq("user_id",t)),i=i2(o.data,r,{preserveDeletedRows:a});if(!i.length)return 0;let c=ae.from(e).delete().eq("user_id",t).in("id",i);a&&(c=c.is("deleted_at",null));const l=await Dn(c.select("id"));return Array.isArray(l.data)?l.data.length:0},c2=async({backup:e,prepareLocalUpload:t,user:r})=>{Bl();const a=Tc(r),s=dp({backup:e,user:a}),o=s.lists.map(h=>({id:h.id})),i=s.products.map(h=>({id:h.id,listId:h.list_id}));if(typeof t!="function")throw Jn("Cloud upload stopped because local review safeguards were unavailable.");const c=await t({uploadedLists:o,uploadedProducts:i});if(!c?.prepared)return{cancelled:!0,listCount:s.lists.length,productCount:s.products.length,reason:c?.reason||"bootstrap-local-preparation-failed"};await Eu("lists",s.lists,{onConflict:"user_id,id"}),await rj({productRows:s.products,userId:a.id});const l=await ew({user:a}),u=u1({authenticatedUserId:a.id,authoritativeBackup:l.backup,localBackup:e,privateOwnerScoped:l.privateOwnerScoped===!0,uploadedLists:o,uploadedProducts:i}),p=new Date().toISOString(),m=hi(a.id)||{},f=$C(a.id,{...m,checkedAt:p,hasCloudData:!0,latestUpdatedAt:l.cloudBackedUpAt||p,listCount:s.lists.length,productCount:s.products.length});return{authoritativeBackup:u,cloudBackedUpAt:l.cloudBackedUpAt,cancelled:!1,listCount:s.lists.length,preparation:c,privateOwnerScoped:!0,productCount:s.products.length,state:f,uploadedLists:o,uploadedProducts:i,uploadedAt:p}},l2=async({backup:e,confirmBackup:t,user:r})=>{Bl();const a=Tc(r),s=dp({backup:e,user:a}),o=await a2({user:a});if(t&&!await t(o))return{cancelled:!0,existingSummary:o};await Dn(ae.from("profiles").upsert(s.profile,{onConflict:"id"})),await Eu("lists",s.lists,{onConflict:"user_id,id"}),await rj({productRows:s.products,userId:a.id}),await Eu("price_snapshots",s.priceSnapshots,{onConflict:"user_id,id"}),await Eu("price_alert_events",s.priceAlertEvents,{onConflict:"user_id,id"}),await Eu("availability_alert_events",s.availabilityAlertEvents,{onConflict:"user_id,id"});const i=await am("availability_alert_events",a.id,s.availabilityAlertEventIds),c=await am("price_alert_events",a.id,s.priceAlertEventIds),l=await am("price_snapshots",a.id,s.priceSnapshotIds),u=await am("products",a.id,s.productIds,{preserveDeletedRows:!0}),p=await am("lists",a.id,s.listIds,{preserveDeletedRows:!0});await Dn(ae.from("settings").upsert(s.settings,{onConflict:"user_id"}));const m=new Date().toISOString(),f=hi(a.id)||{},h=$C(a.id,{...f,checkedAt:m,hasCloudData:!0,lastBackedUpAt:m,latestUpdatedAt:m,listCount:s.lists.length,productCount:s.products.length});return{cancelled:!1,deletedAvailabilityAlertEventCount:i,deletedListCount:p,deletedPriceAlertEventCount:c,deletedPriceSnapshotCount:l,deletedProductCount:u,existingSummary:o,listCount:s.lists.length,productCount:s.products.length,state:h,uploadedAt:m}},tw=(e,t="billing-failed")=>{const r=new Error(e);return r.reason=t,r},d2=(e={})=>{const t=String(e?.id||"").trim();if(!t)throw tw("Sign in to view billing.","unauthenticated");return t},nj=async({user:e})=>{if(!An.isConfigured||!ae)throw tw("Billing is not available yet.","auth-config-missing");const t=d2(e),{data:r,error:a}=await ae.from("billing_profiles").select("*").eq("user_id",t).maybeSingle();if(a)throw tw("Could not confirm billing status.","billing-profile-read-failed");return r||null},jy={BASE_URL:"/",DEV:!1,MODE:"production",NEXT_PUBLIC_AUTH_GOOGLE_ENABLED:"true",NEXT_PUBLIC_SUPABASE_ANON_KEY:"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imx3ZmhlY2h3bmVtYnJhYXd2ZWhyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODI2NzE3MDQsImV4cCI6MjA5ODI0NzcwNH0.4P2QHXyjPnlZ61u2ZAL6oS9ww0zLI2cLn6R43SwOe6A",NEXT_PUBLIC_SUPABASE_URL:"https://lwfhechwnembraawvehr.supabase.co",NEXT_PUBLIC_VERCEL_OBSERVABILITY_CLIENT_CONFIG:'{"analytics":{"scriptSrc":"0b66313c7c4444d3/script.js","viewEndpoint":"0b66313c7c4444d3/view","eventEndpoint":"0b66313c7c4444d3/event","sessionEndpoint":"0b66313c7c4444d3/session"},"speedInsights":{"scriptSrc":"39c2d0cdad3cc473/script.js","endpoint":"39c2d0cdad3cc473/vitals"}}',PROD:!0,SSR:!1,VITE_MYLIST_ACCOUNT_DELETION_BETA_ENABLED:"true",VITE_MYLIST_PASSWORD_RESET_BETA_ENABLED:"true",VITE_SENTRY_DSN:"https://8ba6141980c0435bb9a8f83c732ccd6a@o4511721880551424.ingest.us.sentry.io/4511721889071104",VITE_VERCEL_BRANCH_URL:"my-list-git-main-preflightbrieftool-1859s-projects.vercel.app",VITE_VERCEL_DEPLOYMENT_ID:"dpl_Gphzt39T7k44AJNJih4RFw93Ypvr",VITE_VERCEL_ENV:"production",VITE_VERCEL_GIT_COMMIT_AUTHOR_LOGIN:"caleb872",VITE_VERCEL_GIT_COMMIT_AUTHOR_NAME:"c
14aleb872",VITE_VERCEL_GIT_COMMIT_MESSAGE:`Merge pull request #115 from zemba-ellis/codex/global-page-transitions
15
16Make SaveBoard navigation calm and race-safe`,VITE_VERCEL_GIT_COMMIT_REF:"main",VITE_VERCEL_GIT_COMMIT_SHA:"0a079a60f28e46e39fcced142af855a9ae4a0862",VITE_VERCEL_GIT_PREVIOUS_SHA:"",VITE_VERCEL_GIT_PROVIDER:"github",VITE_VERCEL_GIT_PULL_REQUEST_ID:"",VITE_VERCEL_GIT_REPO_ID:"1278951468",VITE_VERCEL_GIT_REPO_OWNER:"zemba-ellis",VITE_VERCEL_GIT_REPO_SLUG:"my-list",VITE_VERCEL_OBSERVABILITY_CLIENT_CONFIG:'{"analytics":{"scriptSrc":"0b66313c7c4444d3/script.js","viewEndpoint":"0b66313c7c4444d3/view","eventEndpoint":"0b66313c7c4444d3/event","sessionEndpoint":"0b66313c7c4444d3/session"},"speedInsights":{"scriptSrc":"39c2d0cdad3cc473/script.js","endpoint":"39c2d0cdad3cc473/vitals"}}',VITE_VERCEL_PROJECT_ID:"prj_M8EDhbH7lOPV43DIBaxvPMiUp0Am",VITE_VERCEL_PROJECT_PRODUCTION_URL:"www.saveboard.co",VITE_VERCEL_TARGET_ENV:"production",VITE_VERCEL_URL:"my-list-dfddhysr6-preflightbrieftool-1859s-projects.vercel.app"};var _A={};const u2=new Set(["1","true","yes","on","enabled"]),p2=new Set(["0","false","no","off","disabled"]),m2=Object.freeze({availabilityTrackingEnabled:"VITE_MYLIST_AVAILABILITY_TRACKING_ENABLED",billingUiEnabled:"VITE_MYLIST_BILLING_UI_ENABLED",priceTrackingEnabled:"VITE_MYLIST_PRICE_TRACKING_ENABLED",priceTrackingOverviewEnabled:"VITE_MYLIST_PRICE_TRACKING_OVERVIEW_ENABLED",passwordResetBetaEnabled:"VITE_MYLIST_PASSWORD_RESET_BETA_ENABLED",accountDeletionBetaEnabled:"VITE_MYLIST_ACCOUNT_DELETION_BETA_ENABLED",restockUiEnabled:"VITE_MYLIST_RESTOCK_UI_ENABLED",trueSyncCloudNewerPullEnabled:"VITE_MYLIST_TRUE_SYNC_CLOUD_NEWER_PULL_ENABLED",trueSyncDryRunEnabled:"VITE_MYLIST_TRUE_SYNC_DRY_RUN_ENABLED",trueSyncEmptyPullEnabled:"VITE_MYLIST_TRUE_SYNC_EMPTY_PULL_ENABLED",trueSyncManualBetaEnabled:"VITE_MYLIST_TRUE_SYNC_MANUAL_BETA_ENABLED",trueSyncNowQaEnabled:"VITE_MYLIST_TRUE_SYNC_NOW_QA_ENABLED",trueSyncPopulatedPullEnabled:"VITE_MYLIST_TRUE_SYNC_POPULATED_PULL_ENABLED",trueSyncPullMergePreviewEnabled:"VITE_MYLIST_TRUE_SYNC_PULL_MERGE_PREVIEW_ENABLED",trueSyncStatusModelEnabled:"VITE_MYLIST_TRUE_SYNC_STATUS_MODEL_ENABLED",trueSyncTombstoneProductsEnabled:"VITE_MYLIST_TRUE_SYNC_TOMBSTONE_PRODUCTS_ENABLED",trueSyncWriteThroughBoardsEnabled:"VITE_MYLIST_TRUE_SYNC_WRITE_THROUGH_BOARDS_ENABLED",trueSyncWriteThroughProductsEnabled:"VITE_MYLIST_TRUE_SYNC_WRITE_THROUGH_PRODUCTS_ENABLED"}),f2=Object.freeze({availabilityTrackingEnabled:!1,billingUiEnabled:!1,priceTrackingEnabled:!1,priceTrackingOverviewEnabled:!1,passwordResetBetaEnabled:!1,accountDeletionBetaEnabled:!1,restockUiEnabled:!1,trueSyncCloudNewerPullEnabled:!1,trueSyncDryRunEnabled:!1,trueSyncEmptyPullEnabled:!1,trueSyncManualBetaEnabled:!1,trueSyncNowQaEnabled:!1,trueSyncPopulatedPullEnabled:!1,trueSyncPullMergePreviewEnabled:!1,trueSyncStatusModelEnabled:!1,trueSyncTombstoneProductsEnabled:!1,trueSyncWriteThroughBoardsEnabled:!1,trueSyncWriteThroughProductsEnabled:!1}),h2=(e="")=>String(e??"").trim(),g2=()=>{try{return jy&&typeof jy=="object"?jy:{}}catch{return{}}},b2=()=>{try{return typeof process<"u"&&_A?_A:{}}catch{return{}}},v2=(e=null)=>e&&typeof e=="object"?e:{...b2(),...g2()},y2=(e,t=!1)=>{const r=h2(e).toLowerCase();return r?u2.has(r)?!0:p2.has(r)?!1:!!t:!!t},S2=(e,{defaultValue:t=!1,env:r=null}={})=>{const a=v2(r);return y2(a[e],t)},w2=(e=null)=>Object.fromEntries(Object.entries(m2).map(([t,r])=>[t,S2(r,{defaultValue:f2[t],env:e})])),xi=Object.freeze({public:"public",auth:"auth",gated:"gated",retired:"retired"}),rw="/account",zC="/app",aj="next",zg="saveboard.auth.returnTo",sj=(e="")=>{const t=String(e||"").trim();if(!t.startsWith("/"))return"/";const r=t.split(/[?#]/)[0];return r.length>1&&r.replace(/\/+$/,"")||"/"},oj=(e="")=>{const t=sj(e);return t==="/"||t==="/guide"||t==="/privacy"||t==="/terms"||t==="/discover"||t.startsWith("/discover/")?xi.public:t===rw||t==="/account/reset-password"||t==="/auth/callback"||t.startsWith("/auth/")?xi.auth:t.startsWith("/share/")?xi.retired:xi.gated},C2=(e="")=>{const t=String(e||"");if(!t.startsWith("/")||t.startsWith("//")||t.startsWith("/\\")||/[�-��]/.test(t)||/^\/[^/?#]*:/.test(t))return!1;const r=sj(t),a=oj(r);return a!==xi.auth&&a!==xi.retired}
16,Fb=(e="",t=zC)=>C2(e)?String(e):t,x2=(e="")=>{const t=Fb(e,"");return!t||t===zC?rw:`${rw}?${aj}=${encodeURIComponent(t)}`},ij=(e="")=>{try{const t=new URLSearchParams(String(e||""));return Fb(t.get(aj)||"","")}catch{return""}},cj=e=>{if(e)return e;try{return typeof window<"u"?window.sessionStorage:null}catch{return null}},EA=(e="",t=null)=>{const r=Fb(e,""),a=cj(t);if(!a)return r;try{r?a.setItem(zg,r):a.removeItem(zg)}catch{}return r},I2=({search:e="",storage:t=null,fallback:r=zC}={})=>{const a=ij(e),s=cj(t);let o="";if(s)try{o=Fb(s.getItem(zg)||"",""),s.removeItem(zg)}catch{o=""}return a||o||r},A2=Object.freeze(["manual","newest","oldest","priceAsc","priceDesc","titleAsc","titleDesc"]),VC="manual",nw="allItems",HC=e=>A2.includes(e),aw=(e,t=VC)=>HC(e)?e:t,lj=e=>{if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[r,a]of Object.entries(e))typeof r=="string"&&r&&HC(a)&&(t[r]=a);return t},P2=({allItemsSortMode:e="",boardKey:t="",boardSortModes:r={},defaultSortMode:a=VC}={})=>{const s=t===nw?e:r?.[t];return HC(s)?s:aw(a)},_2=(e={},t=[])=>{const r=lj(e),a=new Set((Array.isArray(t)?t:[]).map(o=>String(o||"")).filter(Boolean)),s=Object.entries(r).filter(([o])=>a.has(o));return s.length===Object.keys(r).length?e:Object.fromEntries(s)},io=Object.freeze({FREE:"free",PREMIUM:"premium"}),na=Object.freeze({NONE:"none",TRIALING:"trialing",ACTIVE:"active",PAST_DUE:"past_due",CANCELED:"canceled",INCOMPLETE:"incomplete",INCOMPLETE_EXPIRED:"incomplete_expired",UNPAID:"unpaid"}),E2=5,k2=10,N2=100,j2=100,kA=24,NA=!0,Ry="weekly",Ly="daily",R2=new Set(Object.values(io)),L2=new Set(Object.values(na)),B2=new Set([na.TRIALING,na.ACTIVE]),T2=Object.freeze({[io.FREE]:Object.freeze({plan:io.FREE,localListsAndProducts:"unlimited",localPriceHistory:!0,manualPriceChecks:!0,manualChecksPerDay:k2,manualCheckRateLimitEnabled:NA,manualCheckWindowHours:kA,targetPrices:!0,localAlertRules:!0,trackedProductsLimit:E2,scheduledCadences:Object.freeze(["manual",Ry]),allowedCadences:Object.freeze(["manual",Ry]),defaultScheduledCadence:Ry,automaticChecksEnabled:!0,emailAlerts:!1,emailAlertsEnabled:!1,priceDropAlerts:"local-events-only",targetHitAlerts:"local-events-only"}),[io.PREMIUM]:Object.freeze({plan:io.PREMIUM,localListsAndProducts:"unlimited",localPriceHistory:!0,manualPriceChecks:!0,manualChecksPerDay:j2,manualCheckRateLimitEnabled:NA,manualCheckWindowHours:kA,targetPrices:!0,localAlertRules:!0,trackedProductsLimit:N2,scheduledCadences:Object.freeze(["manual","weekly",Ly]),allowedCadences:Object.freeze(["manual","weekly",Ly]),defaultScheduledCadence:Ly,automaticChecksEnabled:!0,emailAlerts:!0,emailAlertsEnabled:!0,priceDropAlerts:!0,targetHitAlerts:!0})}),dj=(e=io.FREE)=>{const t=typeof e=="string"?e:e?.plan||e?.tier||e?.subscriptionPlan||e?.subscriptionTier,r=String(t||"").trim().toLowerCase();return R2.has(r)?r:io.FREE},nf=(e=na.NONE)=>{const t=String(e||"").trim().toLowerCase();return L2.has(t)?t:na.NONE},$b=(e={},t)=>{const r=dj(e),a=nf(e&&typeof e=="object"?e.subscriptionStatus||e.subscription_status:t);return r===io.PREMIUM&&B2.has(a)},D2=(e=null)=>$b(e)?io.PREMIUM:io.FREE,O2=(e=io.FREE,t)=>e&&typeof e=="object"?D2(e):dj(e),WC=(e=io.FREE,t)=>{const r=O2(e),a=T2[r];return{...a,allowedCadences:[...a.allowedCadences],scheduledCadences:[...a.scheduledCadences]}},uj=new Set(["ac.uk","co.jp","co.nz","co.uk","com.au","com.br","com.mx","com.sg","com.tr","com.tw","com.ua","com.hk","com.cn","gov.uk","net.au","net.uk","org.au","org.uk"]),GC=new Map([["amazon.co.uk","Amazon"],["amazon.com","Amazon"],["apple.com","Apple"],["asos.com","ASOS"],["boots.com","Boots"],["hm.com","H&M"],["johnlewis.com","John Lewis"],["la-gent.com","La Gent"],["louisvuitton.com","Louis Vuitton"],["made.com","MADE.COM"],["mrporter.com","MR PORTER"],["net-a-porter.com","NET-A-PORTER"],["nike.com","Nike"],["selfridges.com","Selfridges"],["sohoskin.com","Soho Skin"],["spacenk.com","Space NK"],["zara.com","Zara"]]),M2=new Map([["amazon.co.uk",["marketplace","shopping"]],["amazon.com",["marketplace","shopping"]],["apple.com",["tech","electronics"]],["asos.com",["fashion","clothing","shoes","trainers"]],["boots.com",["beauty","health","pharmacy","skincare"]],["cultbeauty.co.uk",["beauty","skincare"]],["hm.com",["fashion","clothing","home","homeware","interiors"]],["ikea.com",["home","furniture","interiors","homeware"]],["johnlewis.com",["home","furniture","interiors","homeware","fashion","electronics","department-store","gifts"]],["la-gent.com",["fashion","accessories"]],["lightsandlamps.com",["lighting","lamps","home","interiors"]],["lookfantastic.com",["beauty","skincare"]],["louisvuitton.com",["luxury","fashion","bags","accessories"]],["made.com",["home","furniture","interiors","homeware"]],["mrporter.com",["fashion","menswear","luxury"]],["net-a-porter.com",["fashion","womenswear","luxury"]],["nike.com",["
16sportswear","fashion","clothing","shoes","trainers"]],["selfridges.com",["luxury","fashion","beauty","fragrance","gifts","department-store"]],["sohoskin.com",["beauty","skincare"]],["spacenk.com",["beauty","skincare","fragrance"]],["toa.st",["fashion","homeware"]],["zara.com",["fashion","clothing"]]]),jA=new Set(["buy online","current page","manual entry","official site","official store","online shop","online store","product","products","shop","shop online","store","website"]),U2=60,F2=20,$2=32,z2=/[^a-z0-9 ._-]+/g,V2=20,H2=/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/,W2=/^(?:[a-z]{2,}|xn--[a-z0-9-]+)$/,G2=[{keywords:["lamp","lamps","light","lights","lighting","shade","shades","pendant","sconce","bulb","chandelier"],tags:["lighting","lamps","home","interiors"]},{keywords:["home","homes","interior","interiors","decor","décor","home decor","rug","rugs","cushion","cushions","vase","mirror","linen","bedding","homeware","homewares","furnishing","furnishings"],tags:["home","interiors"]},{keywords:["sofa","chair","chairs","tables","dining table","coffee table","side table","console table","bedside table","furniture"],tags:["home","interiors","furniture"]},{keywords:["beauty","skincare","skin care","makeup","cosmetic","cosmetics","serum","cleanser","cream","moisturiser","moisturizer","spf","exfoliator","retinol","toner","mask","balm","oil"],tags:["beauty","skincare"]},{keywords:["perfume","fragrance","fragrances","scent","cologne","eau de parfum","candle"],tags:["fragrance","beauty","gifts"]},{keywords:["fashion","clothing","clothes","apparel","shirt","jacket","coat","trousers","trainers","sneaker","sneakers","shoes","boots","bag","bags","denim","dress","skirt","knit","jeans"],tags:["fashion","clothing"]},{keywords:["menswear","mens","men","mr porter","suiting","tailoring"],tags:["menswear","fashion"]},{keywords:["womenswear","womens","women","net a porter"],tags:["womenswear","fashion"]},{keywords:["tech","technology","electronics","electronic","phone","iphone","ipad","macbook","laptop","tablet","speaker","speakers","headphones","camera","watch","charger","television","tv"],tags:["tech","electronics"]},{keywords:["toy","toys","kids","baby"],tags:["kids","family"]},{keywords:["gift","gifts","gifting","hamper","birthday","present","christmas"],tags:["gifts"]}],ia=e=>e==null?"":String(e).replace(/\s+/g," ").trim(),By=e=>ia(e).toLowerCase().replace(/[^a-z0-9]+/g,""),q2=(e,t)=>!!(GC.has(e)&&ia(t).length>U2),Y2=e=>/^[a-z][a-z\d+.-]*:\/\//i.test(e),K2=e=>e.replace(/^[<("'`]+|[>)"'`,.]+$/g,""),X2=e=>e.replace(/^(?:www\.)+/i,""),J2=e=>X2(ia(e).toLowerCase().replace(/\.$/,"")),Q2=e=>{const t=e.split(".");return t.length<2||t.some(r=>!H2.test(r))?!1:W2.test(t[t.length-1])},Z2=e=>{const t=J2(e);if(!Q2(t))return null;const r=t.split(".");if(r.length<=2)return t;const a=r.slice(-2).join(".");return uj.has(a)&&r.length>=3?r.slice(-3).join("."):r.slice(-2).join(".")},e$=e=>{const t=K2(ia(e));if(!t||t.includes("@"))return"";try{return new URL(Y2(t)?t:`https://${t}`).hostname}catch{return t.replace(/^(?:https?:)?\/\//i,"").split(/[/?#]/)[0].split(":")[0]}},Tr=e=>{const t=e$(e);return t?Z2(t):null},pj=e=>{const t=Tr(e);if(!t)return"";const r=t.split("."),a=r.slice(-2).join(".");return uj.has(a)&&r.length>=3?r[r.length-3]:r[r.length-2]||""},sw=(e,t="")=>{const r=ia(e).replace(/\s+(?:official site|official store|online store|shop online|buy online)$/i,"").trim().slice(0,120);return q2(t,r)?"":r},RA=e=>!!Tr(e)||/^(?:(?:https?:)?\/\/|www\.)/i.test(ia(e)),t$=(e,t)=>{const r=By(e),a=GC.get(t),s=By(a),o=By(pj(t));return!r||!o?!1:r===o||s&&r===s||r.includes(o)||o.includes(r)},r$=(e,t={})=>{const r=[t.storeName,t.store,t.merchantName,t.merchant,t.retailerName,t.retailer,t.sourceName,t.sourceLabel,t.source];for(const s of r){const o=sw(s,e);if(!(!o||jA.has(o.toLowerCase())||RA(o)))return o}const a=sw(t.brand,e);return a&&!jA.has(a.toLowerCase())&&!RA(a)&&t$(a,e)?a:""},n$=e=>{const t=ia(e);return t?t.length<=3&&t===t.toUpperCase()?t:`${t.charAt(0).toUpperCase()}${t.slice(1).toLowerCase()}`:""},mj=e=>{const t=Tr(e);if(!t)return"";const r=GC.get(t);
16return r||pj(t).split(/[-_]+/).map(n$).filter(Boolean).join(" ")},If=(e,t={})=>{const r=Tr(e);return r?r$(r,t)||mj(r)||r:""},a$=(e={})=>[e.url,e.sourceUrl,e.source_url,e.productUrl,e.product_url,e.canonicalUrl,e.canonical_url,e.domain,e.sourceDomain,e.source_domain,e.merchantDomain,e.merchant_domain,e.storeUrl,e.store_url,e.source,e.merchant,e.store],Af=(e={})=>{if(!e||typeof e!="object")return null;for(const t of a$(e)){const r=Tr(t);if(r)return r}return null},fj=(e={})=>ia(e.id||e.itemId||e.productId||e.localItemId||e.local_item_id),hj=(e={})=>ia(e.listId||e.boardId||e.list_id||e.board_id||e.publicBoardId||e.public_board_id),ow=e=>{const t=ia(e);if(!t)return null;const r=Date.parse(t);return Number.isFinite(r)?{timestamp:t,time:r}:null},gj=(e={})=>[e.savedAt,e.saved_at,e.createdAt,e.created_at,e.updatedAt,e.updated_at,e.capturedAt,e.captured_at,e.addedAt,e.added_at].map(ow).filter(Boolean),s$=(e={})=>gj(e).sort((t,r)=>r.time-t.time)[0]||null,o$=(e={})=>gj(e).sort((t,r)=>t.time-r.time)[0]||null,bj=(e,t)=>{const r=Date.parse(e||""),a=Date.parse(t||""),s=Number.isFinite(r),o=Number.isFinite(a);return s&&o&&r!==a?a-r:s!==o?s?-1:1:0},vj=(e={},t,r,a=!1)=>typeof e[t]=="boolean"?e[t]:typeof e[r]=="boolean"?e[r]:!!a,yj=e=>e.sort((t,r)=>{const a=bj(t.lastSavedAt,r.lastSavedAt);return a!==0?a:t.displayName.localeCompare(r.displayName,void 0,{sensitivity:"base"})||t.domain.localeCompare(r.domain)}),i$=(e,t)=>{const r=Tr(t||e);return r?`https://${r}`:""},qC=(e,t)=>({id:`domain:${e}`,domain:e,displayName:If(e,t),url:`https://${e}`,savedItemCount:0,itemIds:[],listIds:[],lastSavedAt:null,firstSavedAt:null,categories:[],manualTags:[],manuallyAdded:!1,favourite:!1}),c$=(e,t,r)=>{if(!r||!e.displayName)return!!r;const a=mj(t)||t;return e.displayName===a&&r!==a},Sj=(e=[])=>{const t=new Map;
16return(Array.isArray(e)?e:[]).forEach(r=>{if(!r||typeof r!="object")return;const a=Af(r);if(!a)return;const s=t.get(a)||qC(a,r),o=fj(r),i=hj(r),c=s$(r),l=o$(r);s.savedItemCount+=1,o&&!s.itemIds.includes(o)&&s.itemIds.push(o),i&&!s.listIds.includes(i)&&s.listIds.push(i),c&&bj(c.timestamp,s.lastSavedAt)<0&&(s.lastSavedAt=c.timestamp),l&&(!s.firstSavedAt||Date.parse(l.timestamp)<Date.parse(s.firstSavedAt))&&(s.firstSavedAt=l.timestamp);const u=If(a,r);c$(s,a,u)&&(s.displayName=u),t.set(a,s)}),yj([...t.values()])},Tl=e=>{const t=new Map;return(Array.isArray(e)?e.flatMap(a=>String(a||"").split(",")):typeof e=="string"?e.split(","):[]).map(ia).filter(Boolean).forEach(a=>{const s=a.toLowerCase();t.has(s)||t.set(s,a)}),[...t.values()]},l$=e=>ia(e).toLowerCase().replace(/^#+/,"").replace(z2," ").replace(/\s+/g," ").trim().slice(0,$2).trim(),zb=e=>{const t=new Map;return(Array.isArray(e)?e.flatMap(a=>String(a??"").split(",")):typeof e=="string"?e.split(","):[]).map(l$).filter(Boolean).forEach(a=>{t.size<F2&&!t.has(a)&&t.set(a,a)}),[...t.values()]},wj=e=>` ${ia(e).toLowerCase().replace(/[’']/g,"").replace(/&/g," and ").replace(/[^a-z0-9]+/g," ").replace(/\s+/g," ").trim()} `,d$=(e,t)=>{const r=wj(t).trim();return!!(r&&e.includes(` ${r} `))},Nh=e=>{const t=wj(e);return t.trim()?G2.flatMap(r=>r.keywords.some(a=>d$(t,a))?r.tags:[]):[]},u$=(e={},t={},r="")=>{const a=[t.items,t.products,t.savedItems,e.items,e.products].filter(Array.isArray),s=new Set([...Array.isArray(e.itemIds)?e.itemIds:[],...Array.isArray(e.productIds)?e.productIds:[]].map(ia).filter(Boolean)),o=new Map;return a.flat().forEach(i=>{if(!i||typeof i!="object")return;const c=fj(i),l=Af(i);(r&&l===r||c&&s.has(c))&&o.set(c||`${l||"item"}:${o.size}`,i)}),[...o.values()]},p$=(e={})=>ia(e.name||e.title||e.label||e.listName||e.boardName||e.slug),m$=(e={})=>ia(e.id||e.listId||e.boardId||e.list_id||e.board_id||e.publicBoardId||e.public_board_id),f$=(e={})=>[e.listName,e.boardName,e.category,typeof e.list=="string"?e.list:e.list?.name||e.list?.title,typeof e.board=="string"?e.board:e.board?.name||e.board?.title],h$=(e={},t={},r=[])=>{const a=[],s=new Set([...Array.isArray(e.listIds)?e.listIds:[],...Array.isArray(e.boardIds)?e.boardIds:[]].map(ia).filter(Boolean));return r.forEach(i=>{const c=hj(i);c&&s.add(c),a.push(...f$(i))}),[t.lists,t.boards,t.listRecords,t.boardRecords].filter(Array.isArray).flat().forEach(i=>{const c=p$(i);if(!c)return;const l=m$(i);l&&s.has(l)&&a.push(c)}),a},g$=(e={})=>[e.title,e.name,e.brand,e.source,e.storeName,e.store,e.merchantName,e.merchant,e.retailerName,e.retailer,e.description,e.notes,e.privateNotes,e.publicNotes],lu=(e,t)=>{zb(t).forEach(r=>{e.length<V2&&!e.includes(r)&&e.push(r)})},b$=(e={},t={})=>{const r=e&&typeof e=="object"?e:{},a=t&&typeof t=="object"?t:{},s=Tr(r.domain||r.url||r.source),o=u$(r,a,s||""),i=[];return s&&lu(i,M2.get(s)||[]),lu(i,r.categories),h$(r,a,o).forEach(c=>{lu(i,Nh(c))}),o.forEach(c=>{g$(c).forEach(l=>{lu(i,Nh(l))})}),lu(i,Nh(r.notes)),lu(i,Nh(r.displayName||r.name||r.domain)),i},af=(e={},t=null)=>{const r=e&&typeof e=="object"?e:{},a=t&&typeof t=="object"?t:{},s=Tr(r.domain||r.url||r.source||a.domain||a.url);if(!s)return null;const o=new Date().toISOString(),i=ow(r.createdAt||r.created_at||a.createdAt||a.created_at)?.timestamp||o,c=ow(r.updatedAt||r.updated_at)?.timestamp||o,l=Tl(Object.hasOwn(r,"categories")?r.categories:a.categories),u=zb(Object.hasOwn(r,"manualTags")?r.manualTags:a.manualTags),p=sw(Object.hasOwn(r,"displayName")?r.displayName:Object.hasOwn(r,"name")?r.name:a.displayName||a.name,s)||If(s,r);return{id:ia(r.id||a.id)||`manual:${s}`,domain:s,displayName:p,url:i$(r.url||r.domain||a.url||a.domain,s),categories:l,manualTags:u,notes:ia(Object.hasOwn(r,"notes")?r.notes:a.notes),favourite:vj(r,"favourite","favorite",a.favourite||a.favorite),manuallyAdded:!0,createdAt:i,updatedAt:c}},Cj=(e={})=>af(e),v$=(e={},t=null)=>{const r=af(e,t);return r?{...t||qC(r.domain,e),...r,id:r.id||t?.id||`manual:${r.domain}`,manuallyAdded:!0}:null},xj=(e=[],t=[])=>{const r=new Map;return(Array.isArray(t)?t:[]).forEach(a=>{const s=Tr(a?.domain||a?.url);s&&r.set(s,{...qC(s,a),...a,domain:s,id:a.id||`domain:${s}`,url:a.url||`https://${s}`,categories:Tl(a.categories),manualTags:[],manuallyAdded:!!a.manuallyAdded,favourite:vj(a,"favourite","favorite")})}
16),(Array.isArray(e)?e:[]).forEach(a=>{const s=Tr(a?.domain||a?.url||a?.source);if(!s)return;const o=v$(a,r.get(s)||null);o&&r.set(s,o)}),yj([...r.values()])},Ij="Store sync is not available yet.",y$="Could not load cloud stores.",S$="Could not sync this store.",w$="Could not delete this cloud store.",Pf="Enter a valid store website.",Dl="Sign in to sync stores.",yd=e=>String(e??"").replace(/\s+/g," ").trim(),YC=e=>Array.isArray(e)?e[0]||null:e||null,Ty=e=>{const t=yd(e);return t&&Number.isFinite(Date.parse(t))?t:""},Vg=(e,t=!1)=>{if(typeof e=="boolean")return e;if(typeof e=="string"){const r=e.trim().toLowerCase();if(["1","true","yes","on"].includes(r))return!0;if(["0","false","no","off"].includes(r))return!1}return!!t},Aj=(e,t)=>{const r=t?`https://${t}`:"",a=yd(e);return!a||!/^https?:\/\//i.test(a)?r:a.slice(0,2048)},KC=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="42p01"||r==="42703"||r==="42883"||r==="42501"||t.includes("schema cache")||t.includes("user_stores")||t.includes("get_user_stores")||t.includes("upsert_user_store")||t.includes("delete_user_store")||t.includes("permission")||t.includes("row-level security")?Ij:""},C$=e=>{const t=String(e?.message||"").toLowerCase();return String(e?.code||"").toLowerCase()==="28000"||t.includes("not_authenticated")?Dl:KC(e)||y$},Pj=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="28000"||t.includes("not_authenticated")?Dl:r==="22023"||t.includes("invalid_store_domain")||t.includes("check constraint")?Pf:KC(e)||S$},x$=e=>{const t=String(e?.message||"").toLowerCase(),r=String(e?.code||"").toLowerCase();return r==="28000"||t.includes("not_authenticated")?Dl:r==="22023"||t.includes("invalid_store_domain")?Pf:KC(e)||w$},Vb=async(e=Dl)=>{if(!An.isConfigured||!ae)return{error:Ij,user:null};let t=null,r=null;try{({data:t,error:r}=await ae.auth.getUser())}catch(a){r=a||new Error("store-cloud-user-load-failed")}return r||!t?.user?.id?{error:e,user:null}:{error:"",user:t.user}},Hb=(e=null,{includeDeleted:t=!1}={})=>{if(!e||typeof e!="object"||Ty(e.deleted_at??e.deletedAt)&&!t)return null;const a=Tr(e.canonical_domain||e.domain||e.url);if(!a)return null;const s=yd(e.display_name??e.displayName??e.name)||If(a,e),o=Tl(e.categories);return{id:`manual:${a}`,domain:a,displayName:s,url:Aj(e.url,a),categories:o,notes:yd(e.notes),favourite:Vg(e.favourite??e.favorite),manuallyAdded:Vg(e.manually_added??e.manuallyAdded,!0),createdAt:Ty(e.created_at??e.createdAt),updatedAt:Ty(e.updated_at??e.updatedAt)}},I$=(e=[])=>(Array.isArray(e)?e:[]).map(t=>Hb(t)).filter(Boolean),_j=(e={})=>{if(!e||typeof e!="object")return null;const t=Tr(e.domain||e.url||e.source);if(!t)return null;const r=yd(e.displayName??e.display_name??e.name).slice(0,120)||If(t,e),a=Tl(e.categories).map(s=>yd(s).slice(0,60)).filter(Boolean).slice(0,24);return{p_canonical_domain:t,p_display_name:r||null,p_url:Aj(e.url,t),p_categories:a,p_notes:yd(e.notes).slice(0,2e3),p_favourite:Vg(e.favourite??e.favorite),p_manually_added:Vg(e.manuallyAdded??e.manually_added,!0)}},Ej=async e=>{let t=null,r=null;try{({data:t,error:r}=await ae.rpc("upsert_user_store",e))}catch(a){r=a||new Error("store-cloud-upsert-failed")}return{data:t,error:r}},A$=async()=>{const e=await Vb(Dl);if(e.error)return{error:e.error,ok:!1,stores:[]};let t=null,r=null;try{({data:t,error:r}=await ae.rpc("get_user_stores"))}catch(a){r=a||new Error("store-cloud-load-failed")}return r?{error:C$(r),ok:!1,stores:[]}:{ok:!0,stores:I$(t)}},P$=async(e={})=>{const t=_j(e);if(!t)return{error:Pf,ok:!1,store:null};const r=await Vb(Dl);if(r.error)return{error:r.error,ok:!1,store:null};const{data:a,error:s}=await Ej(t);return s?{error:Pj(s),ok:!1,store:null}:{ok:!0,store:Hb(YC(a))}},_$=async(e="")=>{const t=Tr(e);if(!t)return{domain:"",error:Pf,ok:!1,store:null};const r=await Vb(Dl);if(r.error)return{domain:t,error:r.error,ok:!1,store:null};let a=null,s=null;try{({data:a,error:s}=await ae.rpc("delete_user_store",{p_canonical_domain:t}))}catch(o){s=o||new Error("store-cloud-delete-failed")}return s?{domain:t,error:x$(s),ok:!1,store:null}:{domain:t,ok:!0,store:Hb(YC(a),{includeDeleted:!0}
16)}},E$=async(e=[])=>{const t=Array.isArray(e)?e:[],r=await Vb(Dl);if(r.error)return{attempted:0,error:r.error,errors:[{domain:"",error:r.error}],failed:0,ok:!1,stores:[],succeeded:0};const a=[],s=[];for(const o of t){const i=_j(o),c=i?.p_canonical_domain||Tr(o?.domain||o?.url)||"";if(!i){s.push({domain:c,error:Pf});continue}const{data:l,error:u}=await Ej(i);if(u){s.push({domain:c,error:Pj(u)});continue}const p=Hb(YC(l));p&&a.push(p)}return{attempted:t.length,errors:s,failed:s.length,ok:s.length===0,stores:a,succeeded:a.length}},LA=new Set(["active","purchased","archived"]),k$="Sync dry-run is only available for signed-in Personal mode.",kj=e=>[{columns:`${e},deleted_at,revision`,mode:"phase1"},{columns:`${e},deleted_at`,mode:"legacy-tombstone"},{columns:e,mode:"legacy"}],N$=kj("id,user_id,name,is_public,sort_order,updated_at"),j$=kj("id,user_id,list_id,title,status,sort_order,updated_at,archived_at,purchased_at"),jh=(e,t="")=>String(e??"").trim()||t,Hg=e=>e===!0||e==="true"||e===1,BA=(e,t=null)=>{const r=Number(e);return Number.isFinite(r)?Math.trunc(r):t},Nj=e=>{const t=Date.parse(e||"");return Number.isFinite(t)?t:null},jj=(e={})=>!!(e.deleted_at||e.deletedAt),TA=(e=[])=>new Map(e.filter(t=>t?.id&&!jj(t)).map(t=>[String(t.id),t])),iw=(e=[])=>e.filter(jj).map(t=>String(t.id||"")).filter(Boolean),DA=(e=[])=>[...e].sort((t,r)=>{const a=BA(t?.sort_order,Number.MAX_SAFE_INTEGER),s=BA(r?.sort_order,Number.MAX_SAFE_INTEGER);return a!==s?a-s:String(t?.id||"").localeCompare(String(r?.id||""),void 0,{sensitivity:"base"})}),Rj=(e=[],t=[])=>{const r=new Set(e.map(i=>String(i?.id||"")).filter(Boolean)),a=new Set(t.map(i=>String(i?.id||"")).filter(Boolean)),s=DA(e).map(i=>String(i.id||"")).filter(i=>i&&a.has(i));return DA(t).map(i=>String(i.id||"")).filter(i=>i&&r.has(i)).reduce((i,c,l)=>i+(s[l]===c?0:1),0)},OA=(e=[])=>{const t=new Map;return e.forEach(r=>{const a=String(r?.list_id||"");a&&t.set(a,[...t.get(a)||[],r])}),t},R$=(e=[],t=[])=>{const r=OA(e),a=OA(t);let s=0;return a.forEach((o,i)=>{s+=Rj(r.get(i)||[],o)}),s},L$=(e=[])=>e.filter(t=>Nj(t.updated_at||t.updatedAt)===null).length,B$=(e={},t={},r=[])=>r.filter(([a,s=a])=>{const o=e[a],i=t[s];return typeof o=="boolean"||typeof i=="boolean"?Hg(o)!==Hg(i):String(o??"")!==String(i??"")}),MA=({activeCloudById:e,cloudRows:t,localRows:r,updateFields:a})=>{const s=new Map(r.map(m=>[String(m.id),m])),o=new Set(iw(t));let i=0,c=0,l=L$(r),u=0;r.forEach(m=>{const f=String(m.id||""),h=e.get(f);if(!h){i+=1,o.has(f)&&(u+=1);return}l+=Nj(h.updated_at||h.updatedAt)===null?1:0,B$(m,h,a).length&&(c+=1)});const p=[...e.keys()].filter(m=>!s.has(m)).length;return{missingUpdatedAt:l,tombstoneConflicts:u,wouldCreate:i,wouldTombstoneLater:p,wouldUpdate:c}},T$=({activeCloudListsById:e,activeCloudProductsById:t,localLists:r,localProducts:a})=>{const s=new Set(r.map(u=>String(u.id||"")).filter(Boolean)),o=new Set(e.keys());let i=0,c=0,l=0;return a.forEach(u=>{const p=String(u.list_id||"");(!p||!s.has(p))&&(i+=1);const m=t.get(String(u.id||""));m&&String(m.list_id||"")!==p&&(l+=1)}),t.forEach(u=>{const p=String(u.list_id||"");(!p||!o.has(p))&&(c+=1)}),i+c+l},D$=({activeCloudListsById:e,activeCloudProductsById:t,localLists:r,localProducts:a})=>{let s=0,o=0;return r.forEach(i=>{const c=e.get(String(i.id||""));c&&Hg(i.is_public)!==Hg(c.is_public)&&(o+=1)}),a.forEach(i=>{const c=t.get(String(i.id||""));if(!c)return;const l=LA.has(jh(i.status).toLowerCase())?jh(i.status).toLowerCase():"active",u=LA.has(jh(c.status).toLowerCase())?jh(c.status).toLowerCase():"active";l!==u&&(s+=1)}),{orderingMismatches:Rj(r,[...e.values()])+R$(a,[...t.values()]),statusMismatches:s,visibilityMismatches:o}},O$=async e=>{const[t,r]=await Promise.all([YS({read:a=>ae.from("lists").select(a.columns).eq("user_id",e),tiers:N$}),YS({read:a=>ae.from("products").select(a.columns).eq("user_id",e),tiers:j$})]);if(t.error||r.error)throw new Error("Could not run sync dry-run right now.");return{lists:t.data||[],products:r.data||[]}},UA=async({localLists:e=[],localProducts:t=[],user:r}={})=>{if(!An.isConfigured||!ae||!r?.id)return{blocked:!0,message:k$};const a=dp({backup:{lists:e,products:t,settings:{},boardOrder:e.map(b=>
16b.id).filter(Boolean),productOrder:t.map(b=>b.id).filter(Boolean),metadata:{source:"true-sync-dry-run"}},user:r}),s=await O$(r.id),o=a.lists||[],i=a.products||[],c=TA(s.lists),l=TA(s.products),u=MA({activeCloudById:c,cloudRows:s.lists,localRows:o,updateFields:[["name"],["is_public"]]}),p=MA({activeCloudById:l,cloudRows:s.products,localRows:i,updateFields:[["list_id"],["title"],["status"]]}),m=T$({activeCloudListsById:c,activeCloudProductsById:l,localLists:o,localProducts:i}),f=D$({activeCloudListsById:c,activeCloudProductsById:l,localLists:o,localProducts:i}),h=[];return(u.missingUpdatedAt||p.missingUpdatedAt)&&h.push("Some rows are missing comparable updated_at timestamps."),(u.tombstoneConflicts||p.tombstoneConflicts)&&h.push("Some local rows match cloud tombstones and need explicit conflict handling before live sync."),m&&h.push("Some item-to-board relationships do not line up."),{blocked:!1,cloud:{boards:c.size,boardTombstones:iw(s.lists).length,products:l.size,productTombstones:iw(s.products).length},local:{boards:o.length,products:i.length},relationships:{mismatches:m},tombstoneConflicts:{localBoardsConflictingWithCloudTombstones:u.tombstoneConflicts,localProductsConflictingWithCloudTombstones:p.tombstoneConflicts},status:{mismatches:f.statusMismatches},visibility:{mismatches:f.visibilityMismatches},ordering:{mismatches:f.orderingMismatches},writesPerformed:0,wouldCreate:{boards:u.wouldCreate,products:p.wouldCreate},wouldTombstone:{boards:u.wouldTombstoneLater,products:p.wouldTombstoneLater},wouldUpdate:{boards:u.wouldUpdate,products:p.wouldUpdate},warnings:h}},FA=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,bi=e=>String(e??"").trim(),cw=e=>!!e&&typeof e=="object"&&!Array.isArray(e),$A=e=>{const t=Number(e);return Number.isSafeInteger(t)&&t>0?t:null},zA=e=>{const t=Date.parse(e||"");return Number.isFinite(t)?t:null},VA=(e={})=>bi(e.id),HA=(e={})=>bi(e.userId||e.user_id),WA=(e={})=>bi(e.listId||e.list_id),GA=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),qA=(e={})=>!!(e.collaborationId||e.collaboration_id||e.collaboratorId||e.collaborator_id||e.sharedBoardId||e.shared_board_id||e.isCollaborative||e.isSharedProjection),M$=(e={})=>{if(!Object.hasOwn(e,"syncConflictPatch"))return!1;const t=e.syncConflictPatch;return t!=null&&(!cw(t)||Object.keys(t).length>0)},qa=e=>({action:"protect-local",reason:e}),Lj=({authenticatedUserId:e,availableParentIds:t=new Set,cloudRecord:r={},explicitMovePending:a=!1,localRecord:s={},privateOwnerScoped:o=!1}={})=>{if(!cw(s)||!cw(r))return qa("cloud-restore-record-invalid");if(!GA(s)||GA(r))return null;const i=bi(e),c=VA(s),l=VA(r);if(!c||c!==l)return qa("cloud-restore-product-mismatch");if(!o||!FA.test(i))return qa("cloud-restore-ownership-unproven");if(HA(s)!==i||HA(r)!==i||qA(s)||qA(r))return qa("cloud-restore-owner-mismatch");const u=WA(s),p=WA(r);if(!u||u!==p)return qa("cloud-restore-parent-mismatch");if(!t.has(p))return qa("cloud-restore-parent-unavailable");const m=!!(r.deleted_by||r.deletion_id||r.deletion_reason||r.purge_after||r.cloudDeletionId||r.cloudDeletionReason||r.cloudPurgeAfter);if(bi(s.status).toLowerCase()!=="active"||bi(r.status).toLowerCase()!=="active"||m)return qa("cloud-restore-lifecycle-invalid");if(s.syncPendingCloudWrite===!0)return qa("pending-cloud-write");if(M$(s))return qa("pending-local-patch");if(a)return qa("explicit-local-move");if(bi(s.syncConflict))return qa("unresolved-local-conflict");const f=$A(s.syncRevision??s.revision),h=$A(r.syncRevision??r.revision);if(!f||!h)return qa("cloud-restore-revision-invalid");if(h<=f)return qa(h===f?"equal-revision-restore-conflict":"local-revision-newer");const b=zA(s.cloudDeletedAt||s.deleted_at||s.deletedAt||""),v=bi(s.cloudDeletionId||s.deletion_id),S=bi(s.cloudDeletionReason||s.deletion_reason);if(s.syncSuppressed!==!0||b===null||!FA.test(v)||S!=="user_trash")return qa("cloud-restore-deletion-evidence-invalid");const C=r.cloudRestoredAt||r.restored_at||r.restoredAt||"",I=zA(C),A=bi(r.cloudRestoredBy||r.restored_by||r.restoredBy);return I===null||I<=b||A!==i?qa("cloud-restore-evidence-invalid"):{action:"apply-cloud",cloudRevision:h,localRevision:f,reason:"authoritative-cloud-restore",restoredAt:new Date(I).toISOString(),restoredBy:A}},pn=e=>String(e??"").trim(),YA=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),KA=(e=[])=>new Map(e.filter(t=>pn(t?.id)).map(t=>[pn(t.id),t])),U$=(e={},t={})=>JSON.stringify(e)!==JSON.stringify(t),XA=(e,t)=>{t?.requiresReview&&(t.conflictDraft?e.pendingActiveRecordConflicts+=1:t.reason==="cloud-product-parent-board-unavailable"?e.missingBoardProductUpdates+=1:t.reason==="equal-revision-active-conflict"?e.equalRevisionConflicts+=1:String(t.reason||"").startsWith("stale-cloud")?e.staleCloudActiveRecordConflicts+=1:e.legacyActiveRecordConflicts+=1)},JA=(e,t)=>
16t?.action==="apply-cloud"||t?.action==="apply-local-metadata-cleanup"||t?.action==="apply-local-owner-normalization"||t?.activeRecord&&t.action!=="no-op"&&U$(e,t.activeRecord),F$=({authenticatedUserId:e="",cloudLists:t=[],cloudListsArePrivateOwnerScoped:r=!1,cloudProducts:a=[],includeDiagnostics:s=!1,localLists:o=[],localProducts:i=[]}={})=>{const c=KA(o),l=KA(i),u=t.filter(y=>pn(y?.id)&&!YA(y)),p=a.filter(y=>pn(y?.id)&&!YA(y)),m=new Set(u.map(y=>pn(y.id))),f=new Map(u.map(y=>[pn(y.id),String(y.name||"").trim()])),h=new Set(o.map(y=>pn(y?.id)).filter(y=>y&&m.has(y))),b=[],v=[],S=s?{lists:[],products:[]}:null,C=[],I=[],A=[],k={equalRevisionConflicts:0,legacyActiveRecordConflicts:0,missingBoardProductUpdates:0,pendingActiveRecordConflicts:0,staleCloudActiveRecordConflicts:0};u.forEach(y=>{const N=c.get(pn(y.id));if(!N)return;const _=iA({cloudRecord:y,entityType:"list",listOwnershipContext:{authenticatedUserId:e,privateOwnerScoped:r},localRecord:N});b.push(_),S&&(_.requiresReview&&tp({listId:N.id,phase:"foreground-review-evidence",privateOwnerScoped:r,record:y}),S.lists.push(bA({cloudRecord:y,entityType:"list",listNormalizationProvenance:uF(N.id),localRecord:N,outcome:_}))),XA(k,_),JA(N,_)&&C.push(_.activeRecord)}),p.forEach(y=>{const N=l.get(pn(y.id));if(!N)return;const _={...kb(y,{listName:f.get(pn(y.list_id))||N.listName||N.category||""}),cloudUpdatedAt:y.updated_at||"",deleted_at:y.deleted_at,restored_at:y.restored_at,restored_by:y.restored_by,revision:y.revision,updated_at:y.updated_at},P=Lj({authenticatedUserId:e,availableParentIds:h,cloudRecord:_,localRecord:N,privateOwnerScoped:r});if(_.validatedCloudRestore=P?.action==="apply-cloud",s){const L=pn(N.listId||N.list_id);Ec({enabled:!0,listsHydratedBeforeProductNormalization:!0,normalizationDecision:"preserved-existing",parentExists:!!(L&&h.has(L)),parentId:L,phase:"foreground-input-observed",productId:N.id,sourceParentExists:!!(L&&h.has(L)),storageEvidence:"existing-read"})}const V=iA({availableParentBoardIds:h,cloudRecord:_,entityType:"product",localRecord:N});v.push(V),S&&S.products.push(bA({cloudRecord:_,entityType:"product",localRecord:N,outcome:V,parentPhaseProvenance:y1(N.id)})),XA(k,V),V.relationship&&A.push({id:pn(y.id),...V.relationship}),JA(N,V)&&I.push(V.activeRecord)});const E=[...k.pendingActiveRecordConflicts?["Some local changes need review against newer cloud records."]:[],...k.equalRevisionConflicts?["Some rows have equal revisions but different content."]:[],...k.legacyActiveRecordConflicts?["Some legacy rows do not have enough server version metadata for automatic reconciliation."]:[],...k.staleCloudActiveRecordConflicts?["Some cloud rows appear older than the last acknowledged local server revision."]:[],...k.missingBoardProductUpdates?["Some cloud product updates point to a missing board."]:[]];return{conflicts:k,...S?{diagnostics:S}:{},listOutcomes:b,lists:C,productOutcomes:v,products:I,relationships:A,supabaseWritesPerformed:0,warnings:E,writesPerformed:0}},$$=({currentLists:e=[],currentProducts:t=[],incomingLists:r=[],incomingProducts:a=[]}={})=>{const s=new Set(e.map(b=>pn(b?.id)).filter(Boolean)),o=new Set(t.map(b=>pn(b?.id)).filter(Boolean)),i=new Map,c=new Map;r.forEach(b=>{const v=pn(b?.id);v&&s.has(v)&&!i.has(v)&&i.set(v,b)});const l=e.map(b=>i.get(pn(b?.id))||b),u=new Map(l.map(b=>[pn(b?.id),String(b?.name||"").trim()]).filter(([b])=>b));a.forEach(b=>{const v=pn(b?.id),S=pn(b?.listId||b?.list_id);v&&o.has(v)&&u.has(S)&&!c.has(v)&&c.set(v,{...b,listId:S})});const p=t.map(b=>{const v=c.get(pn(b?.id))||b,S=u.get(pn(v?.listId));return S?{...v,category:S,listName:S}:v}),m=l.map(b=>pn(b?.id)).filter(Boolean),f=p.map(b=>pn(b?.id)).filter(Boolean),h=p.every(b=>u.has(pn(b?.listId)));return{boardCount:i.size,lists:l,productCount:c.size,products:p,valid:new Set(m).size===m.length&&new Set(f).size===f.length&&h,writesPerformed:0}},z$=({editorRecord:e=null,hasUnsavedChanges:t=!1,refreshedRecords:r=[]}={})=>{if(!e?.id)return{baseChanged:!1,record:e,requiresReview:!1};const a=r.find(c=>pn(c?.id)===pn(e.id));if(!a)return{baseChanged:!1,record:e,requiresReview:!1};const s=Nn(e),o=Nn(a);return s!==o||String(e.cloudUpdatedAt||"")!==String(a.cloudUpdatedAt||"")?t?{baseChanged:!0,record:e,requiresReview:!0}:{baseChanged:!0,record:a,requiresReview:!!a.syncConflict}:{baseChanged:!1,record:e,requiresReview:!!e.syncConflict}},V$="Sync merge preview is only available for signed-in Personal mode.",H$="Sync cloud update pull is only available for signed-in Personal mode.",W$="Sync empty-browser pull is only available for signed-in Personal mode.",G$="Sync populated pull is only available for signed-in Personal mode.",q$="No active cloud boards were found to pull.",Y$="No newer cloud board or product updates to apply.",QA="No new cloud boards or products to pull.",K$=["list_id","title","status"],X$=["name","is_public"],J$=["id","user_id","name","slug","description","public_description","is_public","created_at","updated_at","archived_at","sort_order","budget_amount","budget_currency"],Q$=["id","user_id","list_id","title","price","brand","card_size","image_framing_overrides","source","url","image_url","note","public_note","size","colour","variant","status","sort_order","image_fit","
16image_scale","image_position_x","image_position_y","image_background_mode","image_background_color","currency","price_amount","target_price","target_currency","target_amount","price_alert","price_tracking","last_checked_at","next_check_at","last_check_status","fail_count","availability","availability_tracking","availability_history","last_availability_checked_at","next_availability_check_at","last_availability_check_status","availability_fail_count","created_at","updated_at","archived_at","purchased_at"],Z$=["deleted_at","revision","deleted_by","deletion_id","deletion_reason","purge_after","restored_at","restored_by","created_by","updated_by"],Bj=e=>[{columns:[...e,...Z$].join(","),mode:"phase1"},{columns:[...e,"deleted_at"].join(","),mode:"legacy-tombstone"},{columns:e.join(","),mode:"legacy"}],ez=Bj(J$),tz=Bj(Q$),ZA=e=>e===!0||e==="true"||e===1,rz=e=>{const t=Date.parse(e||"");return Number.isFinite(t)?t:null},rp=(e={})=>!!(e.deleted_at||e.deletedAt),Rh=(e=[])=>new Map(e.filter(t=>t?.id).map(t=>[String(t.id),t])),eP=(e=[])=>new Map(e.filter(t=>t?.id&&!rp(t)).map(t=>[String(t.id),t])),co=(e=[])=>e.filter(rp).map(t=>String(t.id||"")).filter(Boolean),tP=(e={},t={},r=[])=>r.some(a=>{const s=e[a],o=t[a];if(a==="slug"&&!String(o??"").trim())return!1;if(a==="budget_amount"&&!String(o??"").trim()){const i=Number(s);if(!s||i===0)return!1}return typeof s=="boolean"||typeof o=="boolean"?ZA(s)!==ZA(o):String(s??"")!==String(o??"")}),Lh=(e=[])=>e.filter(t=>rz(t.updated_at||t.updatedAt)===null).length,rP=async({table:e,tiers:t,userId:r})=>YS({read:a=>ae.from(e).select(a.columns).eq("user_id",r),tiers:t}),Wb=async e=>{const[t,r]=await Promise.all([rP({table:"lists",tiers:ez,userId:e}),rP({table:"products",tiers:tz,userId:e})]);if(t.error||r.error)throw new Error("Could not preview cloud pull merge right now.");return{lists:t.data||[],products:r.data||[],schemaModes:{lists:t.schemaMode,products:r.schemaMode}}},Wg=(e=[])=>[...e].sort((t,r)=>{const a=Number(t?.sort_order),s=Number(r?.sort_order),o=Number.isFinite(a)?a:Number.MAX_SAFE_INTEGER,i=Number.isFinite(s)?s:Number.MAX_SAFE_INTEGER;return o!==i?o-i:String(t?.id||"").localeCompare(String(r?.id||""),void 0,{sensitivity:"base"})}),nz=e=>{const t=Wg((e.lists||[]).filter(l=>!rp(l))),r=new Set(t.map(l=>String(l.id||"")).filter(Boolean)),a=Wg((e.products||[]).filter(l=>!rp(l))),s=a.filter(l=>r.has(String(l.list_id||""))),o=a.length-s.length,i=[...o?["Some cloud products were skipped because their board was missing."]:[]];if(!t.length&&!s.length)return{blocked:!0,message:q$,skippedProductsMissingBoard:o,warnings:i};const c=Ub({lists:t,products:s,settings:null});return{blocked:!1,ignoredBoardTombstones:co(e.lists).length,ignoredProductTombstones:co(e.products).length,lists:c.lists||[],message:`Pulled ${c.lists?.length||0} boards and ${c.products?.length||0} products from cloud.`,productCount:c.products?.length||0,products:c.products||[],skippedProductsMissingBoard:o,supabaseWritesPerformed:0,warnings:i,writesPerformed:0}},az=({cloudRows:e,localLists:t=[],localProducts:r=[]}={})=>{const a=Wg((e.lists||[]).filter(y=>!rp(y))),s=new Set(a.map(y=>String(y.id||"")).filter(Boolean)),o=Wg((e.products||[]).filter(y=>!rp(y)&&s.has(String(y.list_id||"")))),i=new Set(t.map(y=>String(y?.id||"")).filter(Boolean)),c=new Set(r.map(y=>String(y?.id||"")).filter(Boolean)),l=a.filter(y=>!i.has(String(y.id||""))),u=new Set(l.map(y=>String(y.id||"")).filter(Boolean)),p=new Set([...i,...u]),m=o.filter(y=>!c.has(String(y.id||""))),f=m.filter(y=>p.has(String(y.list_id||""))),h=m.length-f.length,b=new Set(f.map(y=>String(y.list_id||"")).filter(Boolean)),v=a.filter(y=>u.has(String(y.id||""))||b.has(String(y.id||""))),S=new Map(t.map(y=>[String(y?.id||""),String(y?.name||"").trim()]).filter(([y])=>y)),C=[...h?["Some cloud products were skipped because their board was missing."]:[]];if(!l.length&&!f.length)return{blocked:!1,boardCount:0,ignoredBoardTombstones:co(e.lists).length,ignoredProductTombstones:co(e.products).length,lists:[],message:QA,productCount:0,products:[],safetySnapshotSaved:!1,skippedProductsMissingBoard:h,supabaseWritesPerformed:0,warnings:C,writesPerformed:0};const I=Ub({lists:v,products:f,settings:null}),A=new Map([...I.lists.map(y=>
16[String(y.id||""),y.name]),...S]),k=(I.lists||[]).filter(y=>u.has(String(y.id||""))),E=(I.products||[]).map(y=>{const N=A.get(String(y.listId||""))||y.listName||y.category||"";return{...y,category:N,listName:N}});return{blocked:!1,boardCount:k.length,ignoredBoardTombstones:co(e.lists).length,ignoredProductTombstones:co(e.products).length,lists:k,message:k.length||E.length?`Pulled ${k.length} new boards and ${E.length} new products from cloud.`:QA,productCount:E.length,products:E,safetySnapshotSaved:!1,skippedProductsMissingBoard:h,supabaseWritesPerformed:0,warnings:C,writesPerformed:0}},sz=({authenticatedUserId:e="",cloudRows:t,includeDiagnostics:r=!1,localLists:a=[],localProducts:s=[]}={})=>{const o=F$({authenticatedUserId:e,cloudLists:t.lists,cloudListsArePrivateOwnerScoped:!0,cloudProducts:t.products,includeDiagnostics:r,localLists:a,localProducts:s}),i=O1({cloudLists:t.lists,cloudProducts:t.products,localLists:a,localProducts:s}),c={...o.conflicts,...i.conflicts},l=[...o.warnings,...i.conflicts.tombstoneReviewConflicts?["Some deleted cloud records were hidden and need sync review before any local edit can be uploaded."]:[]];if(!o.lists.length&&!o.products.length&&!i.listSuppressions.length&&!i.productSuppressions.length)return{blocked:!1,boardCount:0,conflicts:c,...o.diagnostics?{diagnostics:o.diagnostics}:{},ignoredBoardTombstones:co(t.lists).length,ignoredProductTombstones:co(t.products).length,listSuppressions:[],lists:[],message:Y$,productCount:0,productSuppressions:[],products:[],safetySnapshotSaved:!1,supabaseWritesPerformed:0,warnings:l,writesPerformed:0};const u=o.lists,p=o.products;return{blocked:!1,boardCount:u.length,conflicts:c,...o.diagnostics?{diagnostics:o.diagnostics}:{},ignoredBoardTombstones:co(t.lists).length,ignoredProductTombstones:co(t.products).length,listSuppressions:i.listSuppressions,lists:u,message:u.length||p.length?`Updated ${u.length} boards and ${p.length} products from cloud.`:"Cloud deletions were hidden locally without removing cached data.",productCount:p.length,productSuppressions:i.productSuppressions,products:p,relationships:o.relationships,safetySnapshotSaved:!1,supabaseWritesPerformed:0,warnings:l,writesPerformed:0}},oz=({cloudRows:e,localListRows:t,localLists:r=[],localProductRows:a,localProducts:s=[]})=>{const o=eP(e.lists),i=eP(e.products),c=Rh(t),l=Rh(a),u=Rh(r),p=Rh(s),m=new Set(co(e.lists)),f=new Set(co(e.products)),h=new Set(o.keys()),b=new Set(c.keys());let v=0,S=0,C=0,I=0,A=0,k=0,E=0,y=0;o.forEach((V,L)=>{const z=c.get(L);if(!z){v+=1;return}zS(u.get(L)||z,V).order==="cloud-newer"&&tP(z,V,X$)&&(S+=1)}),c.forEach((V,L)=>{m.has(L)&&(C+=1)}
16),i.forEach((V,L)=>{const z=String(V.list_id||"");if(!z||!h.has(z)){E+=1;return}const B=l.get(L);if(!B){I+=1;return}zS(p.get(L)||B,V).order==="cloud-newer"&&tP(B,V,K$)&&(A+=1)}),a.forEach(V=>{const L=String(V.id||""),z=String(V.list_id||"");f.has(L)&&(k+=1),(!z||!b.has(z))&&(y+=1)});const N=t.length-S-C,_=a.length-A-k,P=Lh(t)+Lh(a)+Lh(e.lists)+Lh(e.products);return{boards:{cloudActive:o.size,cloudTombstones:m.size,local:t.length,localMatchingCloudTombstones:C,wouldAddFromCloud:v,wouldKeepLocal:Math.max(0,N),wouldUpdateFromCloud:S},products:{cloudActive:i.size,cloudTombstones:f.size,local:a.length,localSuppressedByCloudTombstones:k,wouldAddFromCloud:I,wouldKeepLocal:Math.max(0,_),wouldUpdateFromCloud:A},relationships:{cloudProductsMissingBoard:E,localProductsMissingBoard:y,missingBoardIssues:E+y},warnings:[...P?["Some rows are missing comparable updated_at timestamps."]:[],...C?["Cloud board tombstones will suppress matching local boards and their cached items."]:[],...k?["Some local products match cloud tombstones and must not be resurrected."]:[],...E||y?["Some item-to-board relationships need review before merge."]:[]],writesPerformed:0}},Bh=async({localLists:e=[],localProducts:t=[],user:r}={})=>{if(!An.isConfigured||!ae||!r?.id)return{blocked:!0,message:V$};const a=dp({backup:{lists:e,products:t,settings:{},boardOrder:e.map(i=>i.id).filter(Boolean),productOrder:t.map(i=>i.id).filter(Boolean),metadata:{source:"true-sync-pull-merge-preview"}},user:r}),s=await Wb(r.id);return{...oz({cloudRows:s,localListRows:a.lists||[],localLists:e,localProductRows:a.products||[],localProducts:t}),blocked:!1,message:"Cloud pull merge preview only. No changes were made."}},iz=async({user:e}={})=>{if(!An.isConfigured||!ae||!e?.id)return{blocked:!0,message:W$};const t=await Wb(e.id),r=nz(t);return{...r,boardCount:r.lists?.length||0}},Dy=async({localLists:e=[],localProducts:t=[],user:r}={})=>{if(!An.isConfigured||!ae||!r?.id)return{blocked:!0,message:G$};const a=await Wb(r.id);return az({cloudRows:a,localLists:e,localProducts:t})},Oy=async({includeDiagnostics:e=!1,localLists:t=[],localProducts:r=[],user:a}={})=>{if(!An.isConfigured||!ae||!a?.id)return{blocked:!0,message:H$};const s=await Wb(a.id);return sz({authenticatedUserId:a.id,cloudRows:s,includeDiagnostics:e,localLists:t,localProducts:r})},nP=5e3,cz=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Oa=e=>String(e||"").trim(),lz=e=>Oa(e?.userId??e?.user_id),dz=e=>Oa(e?.listId??e?.list_id),XC=e=>Br(e?.syncRevision??e?.revision),uz=e=>String(e?.status||"").trim().toLowerCase(),pz=e=>!!e&&uz(e)==="active"&&e.syncSuppressed!==!0&&!e.cloudDeletedAt&&!e.deletedAt&&!e.deleted_at,Gg=(e,t)=>Oa(e?.id)===t.productId&&lz(e)===t.ownerId&&dz(e)===t.listId&&pz(e),Tj=(e,t)=>mC({cloudRecord:t,entityType:"product",localRecord:e}),Dj=(e,t)=>Tj(e,t).length===0,Oj=({expectedListId:e,expectedOwnerId:t,expectedProductId:r,record:a}={})=>{const s={listId:Oa(e),ownerId:Oa(t),productId:Oa(r)}
16,o=XC(a);return{ok:!!(s.listId&&s.ownerId&&s.productId&&Gg(a,s)&&o),revision:o}},mz=({acknowledgedProduct:e,durableProduct:t,expectedListId:r,expectedOwnerId:a,expectedProductId:s,liveProduct:o}={})=>{const i={listId:Oa(r),ownerId:Oa(a),productId:Oa(s)},c=Oj({expectedListId:i.listId,expectedOwnerId:i.ownerId,expectedProductId:i.productId,record:e});if(!c.ok)return{action:"reject",ok:!1,reason:"malformed-acknowledgement"};const l=[t,o].filter(Boolean);if(!l.length||l.some(v=>!Gg(v,i)))return{action:"reject",ok:!1,reason:"current-product-invalid"};const u=l.map(v=>({record:v,revision:XC(v)})),p=u.reduce((v,S)=>Math.max(v,S.revision||0),0),m=c.revision,f=u.filter(v=>p?v.revision===p:!v.revision).map(v=>v.record);if(f.some((v,S)=>f.slice(S+1).some(C=>!Dj(v,C))))return{action:"reject",currentRevision:p,ok:!1,reason:"current-product-divergent"};if(!p||m>p)return{action:"apply",currentRevision:p||null,ok:!0,productId:i.productId,revision:m};if(m<p)return{action:"reject",currentRevision:p,ok:!1,reason:"stale-acknowledgement"};const b=Tj(f[0],e);return b.length?{action:"reject",currentRevision:p,differingFields:b.map(v=>v.field),ok:!1,reason:"divergent-acknowledgement"}:{action:"equivalent",currentRevision:p,ok:!0,productId:i.productId,revision:m}},us=e=>({ok:!1,persisted:!1,reason:e,status:"queued",verifiedFinalSuccess:!1}),fz=e=>new Promise(t=>{setTimeout(t,e)}),lw=e=>{const t=Oa(e);return cz.test(t)?t.toLowerCase():""},hz=async({captureId:e,expectedOwnerId:t,expectedSessionGenerationKey:r,isSessionCurrent:a,markCaptureHandled:s,pollIntervalMs:o=20,readCanonicalProduct:i,resolveLocalProduct:c,syncProductWriteThrough:l,timeoutMs:u=nP}={})=>{const p=lw(e),m=Oa(t),f=Oa(r),h=()=>{try{return a?.()===!0}catch{return!1}};if(!p||!m||!f||typeof c!="function"||typeof l!="function"||typeof i!="function"||!h())return us("authentication-unavailable");let b;try{b=c({captureId:Oa(e),productId:p})}catch{return us("local-persistence-failed")}if(b&&typeof b.then=="function")return us("local-persistence-must-be-synchronous");const v=b?.product||null,S=b?.list||null,C={listId:Oa(S?.id),ownerId:m,productId:p};if(!C.listId||!Gg(v,C))return us("local-product-invalid");const I=Number(u),A=Number.isFinite(I)&&I>0?I:nP,k=Date.now()+A;let E;const y=new Promise(Z=>{E=setTimeout(()=>Z({kind:"timeout"}),A)});let N;try{N=l(v,S,b)}catch{N=Promise.reject(new Error("Cloud acknowledgement failed before starting."))}const _=Promise.resolve(N).then(Z=>({kind:"result",result:Z}),()=>({kind:"failure"})),P=await Promise.race([_,y]);if(clearTimeout(E),P.kind==="timeout")return us("acknowledgement-timeout");if(P.kind!=="result"||!P.result?.ok)return us(P.kind==="failure"?"cloud-write-failed":P.result?.reason||"acknowledgement-rejected");if(!h())return us("session-changed");const L=(Array.isArray(P.result.acknowledgedProducts)?P.result.acknowledgedProducts:[]).find(Z=>Oa(Z?.id)===C.productId),z=Oj({expectedListId:C.listId,expectedOwnerId:C.ownerId,expectedProductId:C.productId,record:L}),B=z.revision;if(!z.ok)return us("malformed-acknowledgement");if(!(Array.isArray(P.result.acknowledgementDecisions)?P.result.acknowledgementDecisions.find(Z=>Oa(Z?.productId)===C.productId&&Z?.ok===!0&&["apply","equivalent"].includes(Z?.action)&&Br(Z?.revision)===B):null))return us("acknowledgement-decision-missing");for(;Date.now()<k;){if(!h())return us("session-changed");let Z;try{Z=await i(C.productId)}catch{return us("canonical-reread-failed")}if(Gg(Z,C)&&XC(Z)===B&&Dj(Z,L)){if(!h())return us("session-changed");try{s?.(e)}catch{return us("capture-handle-failed")}return{acknowledgedProduct:L,durableList:S,durableProduct:Z,ok:!0,persisted:!0,revision:B,status:"imported",verifiedFinalSuccess:!0}}const D=k-Date.now();D>0&&await fz(Math.min(Math.max(1,Number(o)||20),D))}return us("canonical-reread-mismatch")},gz=new Set(["active","archived","purchased","trash"]),np=e=>String(e||"").trim(),ag=(e={})=>np(e.userId??e.user_id??e.ownerId??e.owner_id),bz=(e={})=>np(e.listId??e.list_id),JC=e=>gz.has(e)?e:"active",Mj=(e={})=>{const t=String(e.cloudDeletedAt??e.deleted_at??"").trim();return!!(t&&!Number.isNaN(Date.parse(t)))},vz=(e={})=>e.syncSuppressed===!0||Mj(e),yz=(e=[])=>{const t=new Map,r=new Set;
16return(Array.isArray(e)?e:[]).forEach(a=>{const s=np(a?.id);if(s){if(t.has(s)){r.add(s);return}t.set(s,a)}}),r.forEach(a=>t.delete(a)),t},Sz=(e,t)=>{const r=ag(e);return!t||r===t},wz=({ownerId:e="",products:t=[]}={})=>{const r=np(e),a=yz(t),s=[],o=[],i=[],c=[];return a.forEach(l=>{if(!Sz(l,r))return;if(vz(l)){Mj(l)&&c.push(l);return}const u=JC(l.status);u==="archived"?o.push(l):u==="purchased"?i.push(l):s.push(l)}),{active:s,archived:o,purchased:i,trash:c}},Cz=({board:e,ownerId:t,product:r})=>{const a=np(e?.id),s=ag(e),o=np(t);return!a||bz(r)!==a||o&&(s!==o||ag(r)!==o)?!1:!s||ag(r)===s},xz=({activeListRecord:e=null,allItemsIsSelected:t=!1,ownerId:r="",products:a=[],requestedStatus:s="active",signedIn:o=!1}={})=>{const i=wz({ownerId:r,products:a});if(!!(e?.id&&!t))return{products:i.active.filter(u=>Cz({board:e,ownerId:r,product:u})),status:"active",view:"board"};const l=JC(s);return{products:l==="trash"&&!o?[]:i[l]||i.active,status:l,view:"aggregate"}},du=({dashboardList:e,listName:t}={})=>{const r=String(t||e||"");return{activeList:r,dashboardViewMode:r===e?"overview":"list",status:"active"}}
16,Iz=({dashboardList:e,status:t}={})=>({activeList:String(e||""),dashboardViewMode:"allItems",status:JC(t)}),aP=8e3,sP=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,_a=e=>String(e??"").trim(),qg=e=>{const t=Number(e);return Number.isInteger(t)&&t>0?t:null},Uj=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),_s=(e,t={})=>({applied:!1,conflict:!1,ok:!1,outcome:e,restored:!1,skipped:!1,...t}),My=e=>{try{return e?.()===!0}catch{return!1}},Az=async({clearTimeoutFn:e,request:t,setTimeoutFn:r,timeoutMs:a})=>{let s=null;const o=Promise.resolve().then(t);o.catch(()=>{});const i=new Promise(c=>{s=r(()=>c({kind:"timeout"}),a)});try{return await Promise.race([o.then(c=>({kind:"result",result:c}),c=>({error:c,kind:"failure"})),i])}finally{s!==null&&e(s)}},Pz=({expectedRevision:e,listId:t,ownerId:r,productId:a,result:s})=>{const o=_a(s?.outcome),i=qg(s?.revision),c=Date.parse(s?.restoredAt||""),l=_a(s?.ownerId)===r&&_a(s?.productId)===a&&_a(s?.listId)===t,u=o==="restored"?s?.applied===!0&&i===e+1&&Number.isFinite(c)&&sP.test(_a(s?.deletionId))&&sP.test(_a(s?.operationId)):o==="already-active"?s?.applied===!1&&i!==null&&i>=e:!1;return{ok:l&&u,outcome:o,revision:i}},_z=({listId:e,ownerId:t,product:r,productId:a,revision:s})=>_a(r?.id)===a&&_a(r?.userId??r?.user_id)===t&&_a(r?.listId??r?.list_id)===e&&_a(r?.status).toLowerCase()==="active"&&!Uj(r)&&qg(r?.syncRevision??r?.revision)===s,Ez=async({applyConfirmedProduct:e,clearTimeoutFn:t=globalThis.clearTimeout,expectedOwnerId:r,expectedRevision:a,expectedSessionGenerationKey:s,isSessionCurrent:o,mapAcknowledgedProduct:i,product:c,requestRestore:l,setTimeoutFn:u=globalThis.setTimeout,timeoutMs:p=aP}={})=>{const m=_a(r),f=_a(s),h=_a(c?.id),b=_a(c?.userId??c?.user_id),v=_a(c?.listId??c?.list_id),S=qg(a),C=_a(c?.status).toLowerCase();if(!m||!f||!h||b!==m||!v||C!=="active"||!Uj(c)||!S||typeof l!="function"||typeof i!="function"||typeof e!="function"||typeof u!="function"||typeof t!="function")return _s("invalid-input",{skipped:!0});if(!My(o))return _s("session-changed");const I=Number(p),A=await Az({clearTimeoutFn:t,request:()=>l({expectedRevision:S,product:c}),setTimeoutFn:u,timeoutMs:Number.isFinite(I)&&I>0?I:aP});if(A.kind==="timeout")return _s("timeout");if(A.kind==="failure")return _s("request-failed",{error:A.error});if(!My(o))return _s("session-changed");const k=A.result;if(!k||typeof k!="object")return _s("malformed-response");if(k.ok!==!0)return{..._s(_a(k.outcome)||"rejected"),conflict:k.conflict===!0,revision:qg(k.revision)};const E=Pz({expectedRevision:S,listId:v,ownerId:m,productId:h,result:k});if(!E.ok||!k.row)return _s("malformed-response");let y;try{y=i(k.row,c)}catch(_){return _s("malformed-response",{error:_})}if(!_z({listId:v,ownerId:m,product:y,productId:h,revision:E.revision}))return _s("malformed-response");if(!My(o))return _s("session-changed");let N;try{N=e({acknowledgedProduct:y,expectedRevision:S,listId:v,ownerId:m,productId:h})}catch(_){return _s("local-persistence-failed",{error:_})}return!N?.ok||!N.product?_s(N?.outcome||"local-persistence-failed"):{...k,product:N.product,restored:!0,skipped:!1}},oP=8e3,iP=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,ms=e=>String(e??"").trim(),Yg=e=>{const t=Number(e);return Number.isInteger(t)&&t>0?t:null},kz=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),di=(e,t={})=>({applied:!1,conflict:!1,ok:!1,outcome:e,removed:!1,skipped:!1,...t}),Uy=e=>{try{return e?.()===!0}catch{return!1}},Nz=({expectedRevision:e,listId:t,productId:r,result:a}={})=>{const s=Yg(a?.revision),o=ms(a?.outcome),i=Yg(e),c=Date.parse(a?.deletedAt||""),l=ms(a?.productId)===ms(r)&&ms(a?.listId)===ms(t),u=Number.isFinite(c)&&iP.test(ms(a?.deletionId))&&iP.test(ms(a?.operationId)),p=i!==null&&s!==null&&(o==="trashed"?a?.applied===!0&&s===i+1:o==="already-deleted"?a?.applied===!1&&s>=i+1:!1);return{ok:l&&u&&p,outcome:o,revision:s,validIdentity:l,validLifecycleEvidence:u,validRevisionTransition:p}},jz=async({clearTimeoutFn:e,request:t,setTimeoutFn:r,timeoutMs:a})=>{let s=null;const o=Promise.resolve().then(t);o.catch(()=>{});const i=new Promise(c=>{s=r(()=>c({kind:"timeout"}),a)});try{return await Promise.race([o.then(c=>({kind:"result",result:c}),c=>({error:c,kind:"failure"})),i])}finally{s!==null&&e(s)}},Rz=async({clearTimeoutFn:e=globalThis.clearTimeout,expectedOwnerId:t,expectedRevision:r,expectedSessionGenerationKey:a,isSessionCurrent:s,product:o,removeConfirmedProduct:i,requestTrash:c,setTimeoutFn:l=globalThis.setTimeout,timeoutMs:u=oP}={})=>{const p=ms(t),m=ms(a),f=ms(o?.id),h=ms(o?.userId??o?.user_id),b=ms(o?.listId??o?.list_id),v=Yg(r),S=ms(o?.status).toLowerCase();if(!p||!m||!f||h!==p||!b||S!=="active"||kz(o)||!v||typeof c!="function"||typeof i!="function"||typeof l!="function"||typeof e!="function")return di("invalid-input",{skipped:!0});if(!Uy(s))return di("session-changed");const C=Number(u),I=Number.isFinite(C)&&C>0?C:oP,A=await jz({clearTimeoutFn:e,request:()=>c({expectedRevision:v,product:o}),setTimeoutFn:l,timeoutMs:I});if(A.kind==="timeout")return di("timeout");if(A.kind==="failure")return di("request-failed",{error:A.error});if(!Uy(s))return di("session-changed");const k=A.result;if(!k||typeof k!="object")return di("malformed-response");if(k.ok!==!0)return{...di(ms(k.outcome)||"rejected"),conflict:k.conflict===!0,revision:Yg(k.revision)};if(!Nz({expectedRevision:v,listId:b,productId:f,result:k}).ok)return di("malformed-response");if(!Uy(s))return di("session-changed");try{i(f,k)}catch(y){return di("local-removal-failed",{error:y})}return{...k,removed:!0,skipped:!1}}
16,Hr=Object.freeze({invalidList:"invalid-list",invalidProduct:"invalid-product",missingList:"missing-list",missingProduct:"missing-product",noSupabase:"supabase-unavailable",noUser:"missing-user",tombstoneReview:"cloud-tombstone-review"}),QC=Object.freeze(["name","slug","description","public_description","is_public","archived_at","sort_order","budget_amount","budget_currency"]),Fj=Object.freeze(["list_id","title","price","brand","card_size","image_framing_overrides","source","url","image_url","note","public_note","size","colour","variant","status","sort_order","image_fit","image_scale","image_position_x","image_position_y","image_background_mode","image_background_color","archived_at","purchased_at","availability","availability_tracking","availability_history","last_availability_checked_at","next_availability_check_at","last_availability_check_status","availability_fail_count","currency","price_amount","target_price","target_currency","target_amount","price_alert","price_tracking","last_checked_at","next_check_at","last_check_status","fail_count"]),Lz="products_pkey",Bz=new Set(["already-deleted","trashed"]),Tz=new Set(["authentication-unavailable","invalid-input","ledger-inconsistent","not-active","not-found-or-unavailable","parent-unavailable","revision-conflict"]),Dz=new Set(["already-active","restored"]),Oz=new Set(["authentication-unavailable","invalid-input","ledger-inconsistent","not-found-or-unavailable","not-restorable","parent-unavailable","revision-conflict"]),Kg=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Mz=new Set(["createdAt"]),Uz=Object.freeze([["last_availability_checked_at","timestamp"],["next_availability_check_at","timestamp"],["last_availability_check_status","text"],["availability_fail_count","number"],["last_checked_at","timestamp"],["next_check_at","timestamp"],["last_check_status","text"],["fail_count","number"]]),Xg=["id","user_id","name","slug","description","public_description","is_public","created_at","updated_at","archived_at","sort_order","budget_amount","budget_currency","revision","deleted_at","deleted_by","deletion_id","deletion_reason","purge_after","restored_at","restored_by","created_by","updated_by"].join(","),sf=["id","user_id","list_id","title","price","brand","card_size","image_framing_overrides","source","url","image_url","note","public_note","size","colour","variant","status","sort_order","image_fit","image_scale","image_position_x","image_position_y","image_background_mode","image_background_color","created_at","updated_at","archived_at","purchased_at","availability","availability_tracking","availability_history","last_availability_checked_at","next_availability_check_at","last_availability_check_status","availability_fail_count","currency","price_amount","target_price","target_currency","target_amount","price_alert","price_tracking","last_checked_at","next_check_at","last_check_status","fail_count","revision","deleted_at","deleted_by","deletion_id","deletion_reason","purge_after","restored_at","restored_by","created_by","updated_by"].join(","),Zr=e=>({ok:!1,reason:e,skipped:!0}),Rd=e=>e||(An.isConfigured?ae:null),Ho=(e,t="")=>{const r=Date.parse(e||"");return Number.isFinite(r)?new Date(r).toISOString():t},mr=e=>String(e??"").trim(),cP=(e={})=>{const t=e.sort_order??e.sortOrder;if(t==null||t==="")return null;const r=Number(t);return Number.isFinite(r)?r:null},lP=(e,t)=>{if(t==="timestamp")return Ho(e);if(t==="number"){if(e==null||e==="")return null;const r=Number(e);return Number.isFinite(r)?r:null}return mr(e)},$j=e=>{const t=new Set;let r=e;for(;r&&typeof r=="object"&&!t.has(r);){if(t.add(r),mr(r.code)==="23505"){const a=mr(r.constraint??r.constraint_name);return a||mr(r.message).match(/unique constraint ["']([^"']+)["']/i)?.[1]||""}r=r.cause}return""},Fz=({existingRow:e,intendedRow:t})=>{const r=Pl(t),a=Pl(e);Mz.forEach(i=>{delete r[i],delete a[i]});const o=[...new Set([...Object.keys(r),...Object.keys(a)])].sort().filter(i=>JSON.stringify(r[i])!==JSON.stringify(a[i]));return cP(t)!==cP(e)&&o.push("sortOrder"),Uz.forEach(([i,c])=>
16{lP(t?.[i],c)!==lP(e?.[i],c)&&o.push(i)}),o},dP=({intendedRow:e,row:t,userId:r})=>{const a=mr(e?.id),s=mr(e?.list_id);if(mr(t?.id)!==a||mr(t?.user_id)!==mr(r))throw new xr("Cloud product create returned a different record.",{code:"unexpected-product-create-identity"});if(mr(t?.list_id)!==s)throw new xr("Cloud product create returned a different board.",{code:"unexpected-product-create-parent"});if(mr(t?.status).toLowerCase()!=="active"||t?.archived_at||t?.deleted_at||t?.deleted_by||t?.deletion_id||t?.deletion_reason||t?.purge_after)throw new xr("Cloud product create returned an inactive record.",{code:"inactive-product-create-acknowledgement"});if(!Br(t?.revision))throw new xr("Cloud product create did not return a valid revision.",{code:"invalid-product-create-revision"});if(Fz({existingRow:t,intendedRow:e}).length)throw new xr("Cloud product create returned different product content.",{code:"product-create-content-mismatch"});return t},zj=(e={})=>({cloudDeletedAt:Ho(e.deleted_at),cloudDeletionId:String(e.deletion_id||""),cloudDeletionReason:String(e.deletion_reason||""),cloudPurgeAfter:Ho(e.purge_after),cloudRestoredAt:Ho(e.restored_at),cloudRestoredBy:String(e.restored_by||""),...QB(e),syncSuppressed:!!e.deleted_at}),dw=({list:e,user:t})=>dp({backup:{boardOrder:e?.id?[e.id]:[],lists:e?[e]:[],metadata:{source:"true-sync-board-write-through-pilot"},productOrder:[],products:[],settings:{}},user:t}).lists[0]||null,uw=({list:e,product:t,user:r})=>{const a=dp({backup:{boardOrder:e?.id?[e.id]:[],lists:e?[e]:[],metadata:{source:"true-sync-product-write-through-pilot"},productOrder:t?.id?[t.id]:[],products:t?[t]:[],settings:{}},user:r});return{list:a.lists[0]||null,product:a.products[0]||null}},uP=(e={})=>({id:e.listId||e.list_id,isPublic:!1,name:e.listName||e.category||"Wishlist",sortOrder:0}),pP=({currentList:e,previousList:t,user:r}={})=>{const a=dw({list:t,user:r}),s=dw({list:e,user:r});return a&&s?OE({after:s,allowedFields:QC,before:a}):{}},mP=({currentList:e,currentProduct:t,previousList:r,previousProduct:a,user:s}={})=>{const o=uw({list:r||uP(a),product:a,user:s}).product,i=uw({list:e||uP(t),product:bS(t,{isPlaceholder:Vn,previousRecord:a}),user:s}).product;if(!o||!i)return{};const c=OE({after:i,allowedFields:Fj,before:o});return Object.hasOwn(i,"image_url")||delete c.image_url,c},sm=(e={},t={})=>({...t,id:e.id||t.id,userId:e.user_id||t.userId,name:e.name??t.name,slug:e.slug??t.slug,description:e.description??"",publicDescription:e.public_description??"",isPublic:!!e.is_public,sortOrder:Number.isFinite(Number(e.sort_order))?Number(e.sort_order):t.sortOrder,budget:e.budget_amount??void 0,budgetCurrency:e.budget_currency??void 0,createdAt:Ho(e.created_at,t.createdAt),updatedAt:Ho(e.updated_at,t.updatedAt),archivedAt:Ho(e.archived_at)||void 0,isArchived:!!e.archived_at,...zj(e)}),om=({attemptedPatch:e,fallback:t={},listName:r=null,row:a={}}={})=>{const s=typeof r=="string"?r:t.listName||t.category||"Wishlist",o=kb(a,{index:Number(t.sortOrder)||0,listName:s}),c=e!==void 0&&!cB(e)?lp(t,{},{isPlaceholder:Vn,preferCurrentImage:!0}):{};return{...t,...o,...c,listName:s,category:s,...zj(a)}},of=async({client:e,id:t,selectColumns:r,table:a,userId:s})=>{const o=await e.from(a).select(r).eq("user_id",s).eq("id",t).limit(2);if(o.error)throw new xr("Editor recovery could not read the current cloud record.",{cause:o.error,code:"editor-recovery-read-failed"});if(!Array.isArray(o.data))throw new xr("Editor recovery received an invalid cloud response.",{code:"invalid-editor-recovery-response"});return o.data},$z=async({client:e,productId:t,user:r}={})=>{const a=Rd(e);if(!a)return{...Zr(Hr.noSupabase),writesPerformed:0};const s=String(r?.id||"").trim(),o=String(t||"").trim();if(!s)return{...Zr(Hr.noUser),writesPerformed:0};if(!o)return{...Zr(Hr.invalidProduct),writesPerformed:0};const i=await of({client:a,id:o,selectColumns:sf,table:"products",userId:s});if(i.length!==1||String(i[0]?.user_id||"")!==s)return{...Zr(Hr.missingProduct),writesPerformed:0};const c=String(i[0]?.list_id||"").trim();if(!c)return{...Zr(Hr.missingList),writesPerformed:0};const l=await of({client:a,id:c,selectColumns:Xg,table:"lists",userId:s});return l.length!==1||String(l[0]?.user_id||"")!==s?{...Zr(Hr.missingList),writesPerformed:0}:{ok:!0,parentRow:l[0],privateOwnerScoped:!0,row:i[0],skipped:!1,writesPerformed:0}},Fy=async({client:e,list:t,user:r}={})=>{const a=Rd(e);if(!a)return Zr(Hr.noSupabase);if(!r?.id)return Zr(Hr.noUser);
16if(!t?.id||Zu(t))return Zr(Zu(t)?Hr.tombstoneReview:Hr.invalidList);const s=dw({list:t,user:r});if(!s?.id||s.user_id!==r.id)return Zr(Hr.invalidList);try{return await UE({client:a,row:s,selectColumns:Xg,table:"lists",userId:r.id})}catch(o){if($j(o)!=="lists_pkey")throw o;const i=await of({client:a,id:s.id,selectColumns:Xg,table:"lists",userId:r.id}),c=i[0];if(i.length!==1||c?.id!==s.id||c?.user_id!==r.id||c.deleted_at||!Br(c.revision)||!Ho(c.updated_at))throw new xr("The existing cloud board cannot be recovered for this pending creation.",{code:"board-create-retry-conflict"});const l=Object.fromEntries(QC.map(p=>[p,s[p]??null]));return{contentDiverged:!aC(c,l),ok:!0,recoveredExisting:!0,row:c,skipped:!1}}},zz=async({client:e,list:t,product:r,user:a}={})=>{const s=Rd(e);if(!s)return Zr(Hr.noSupabase);if(!a?.id)return Zr(Hr.noUser);if(!t?.id)return Zr(Hr.missingList);if(!r?.id)return Zr(Hr.invalidProduct);if(Zu(t)||Zu(r))return Zr(Hr.tombstoneReview);const o=uw({list:t,product:r,user:a});if(!o.product?.id||o.product.user_id!==a.id||o.product.list_id!==t.id)return Zr(Hr.invalidProduct);try{const i=await UE({client:s,row:o.product,selectColumns:sf,table:"products",userId:a.id});return{...i,row:dP({intendedRow:o.product,row:i.row,userId:a.id})}}catch(i){if($j(i)!==Lz)throw i;const c=await of({client:s,id:o.product.id,selectColumns:sf,table:"products",userId:a.id});if(c.length!==1)throw new xr("Existing cloud product acknowledgement did not return exactly one record.",{code:"unexpected-idempotent-product-create-row-count"});return{ok:!0,recoveredExisting:!0,row:dP({intendedRow:o.product,row:c[0],userId:a.id})}}},Vz=async({client:e,expectedRevision:t,list:r,patch:a,user:s}={})=>{const o=Rd(e);return o?s?.id?r?.id?FE({allowedFields:QC,client:o,expectedRevision:t,id:r.id,patch:a,selectColumns:Xg,table:"lists",userId:s.id}):Zr(Hr.invalidList):Zr(Hr.noUser):Zr(Hr.noSupabase)},fP=async({acceptAlreadyApplied:e=!1,client:t,expectedRevision:r,patch:a,product:s,user:o}={})=>{const i=Rd(t);return i?o?.id?s?.id?FE({acceptAlreadyApplied:e,allowedFields:Fj,client:i,expectedRevision:r,id:s.id,patch:a,selectColumns:sf,table:"products",userId:o.id}):Zr(Hr.invalidProduct):Zr(Hr.noUser):Zr(Hr.noSupabase)},Hz=async({client:e,expectedRevision:t,product:r,user:a}={})=>{const s=Rd(e);if(!s?.rpc)return Zr(Hr.noSupabase);const o=mr(a?.id),i=mr(r?.id),c=mr(r?.userId??r?.user_id),l=mr(r?.listId??r?.list_id),u=Br(t),p=mr(r?.status).toLowerCase();if(!o)return Zr(Hr.noUser);if(!i||c!==o||!l||p!=="active"||Zu(r)||!u)return Zr(Hr.invalidProduct);const m=await s.rpc("trash_private_product",{p_expected_revision:u,p_product_id:i});if(m?.error)throw new xr("Cloud item Trash did not finish.",{cause:m.error,code:"product-trash-rpc-failed"});const f=Array.isArray(m?.data)?m.data:m?.data&&typeof m.data=="object"?[m.data]:[];if(f.length!==1)throw new xr("Cloud item Trash returned an invalid response.",{code:"invalid-product-trash-response"});const h=f[0]||{},b=mr(h.outcome),v=Br(h.revision),S=mr(h.product_id),C=mr(h.list_id),I=Ho(h.deleted_at),A=mr(h.deletion_id),k=mr(h.operation_id),E=h.ok===!0,y=h.applied===!0,N=h.conflict===!0||b==="revision-conflict";if(S&&S!==i)throw new xr("Cloud item Trash returned a different item.",{code:"unexpected-product-trash-identity"});if(C&&C!==l)throw new xr("Cloud item Trash returned a different board.",{code:"unexpected-product-trash-parent"});if(E){const _=u+1;if(!Bz.has(b)||S!==i||C!==l||!v||!I||!Kg.test(A)||!Kg.test(k)||b==="trashed"&&(!y||v!==_)||b==="already-deleted"&&(y||v<_))throw new xr("Cloud item Trash acknowledgement was malformed.",{code:"malformed-product-trash-acknowledgement"})}else if(y||!Tz.has(b)||N&&b!=="revision-conflict")throw new xr("Cloud item Trash rejection was malformed.",{code:"malformed-product-trash-rejection"});return{applied:y,conflict:N,deletedAt:I,deletionId:A,listId:C,ok:E,operationId:k,outcome:b,productId:S||i,revision:v,skipped:!1}},Wz=async({client:e,expectedRevision:t,product:r,user:a}={})=>{const s=Rd(e);if(!s?.rpc)return Zr(Hr.noSupabase);const o=mr(a?.id),i=mr(r?.id),c=mr(r?.userId??r?.user_id),l=mr(r?.listId??r?.list_id),u=Br(t),p=mr(r?.status).toLowerCase();if(!o)return Zr(Hr.noUser);
16if(!i||c!==o||!l||p!=="active"||!Zu(r)||!u)return Zr(Hr.invalidProduct);const m=await s.rpc("restore_private_product",{p_expected_revision:u,p_product_id:i});if(m?.error)throw new xr("Cloud item Restore did not finish.",{cause:m.error,code:"product-restore-rpc-failed"});const f=Array.isArray(m?.data)?m.data:m?.data&&typeof m.data=="object"?[m.data]:[];if(f.length!==1)throw new xr("Cloud item Restore returned an invalid response.",{code:"invalid-product-restore-response"});const h=f[0]||{},b=mr(h.outcome),v=Br(h.revision),S=mr(h.product_id),C=mr(h.owner_id),I=mr(h.list_id),A=mr(h.status).toLowerCase(),k=Ho(h.deleted_at),E=Ho(h.restored_at),y=mr(h.deletion_id),N=mr(h.operation_id),_=h.ok===!0,P=h.applied===!0,V=h.conflict===!0||b==="revision-conflict";if(S&&S!==i)throw new xr("Cloud item Restore returned a different item.",{code:"unexpected-product-restore-identity"});if(C&&C!==o)throw new xr("Cloud item Restore returned a different owner.",{code:"unexpected-product-restore-owner"});if(I&&I!==l)throw new xr("Cloud item Restore returned a different board.",{code:"unexpected-product-restore-parent"});if(_){const L=u+1;if(!Dz.has(b)||S!==i||C!==o||I!==l||A!=="active"||!v||k||b==="restored"&&(!P||v!==L||!E||!Kg.test(y)||!Kg.test(N))||b==="already-active"&&(P||v<u))throw new xr("Cloud item Restore acknowledgement was malformed.",{code:"malformed-product-restore-acknowledgement"});const z=await of({client:s,id:i,selectColumns:sf,table:"products",userId:o}),B=z[0]||null;if(z.length!==1||mr(B?.id)!==i||mr(B?.user_id)!==o||mr(B?.list_id)!==l||mr(B?.status).toLowerCase()!=="active"||B?.deleted_at||Br(B?.revision)!==v)throw new xr("Cloud item Restore could not verify the active item.",{code:"invalid-product-restore-authoritative-row"});return{applied:P,conflict:V,deletionId:y,listId:I,ok:_,operationId:N,outcome:b,ownerId:C,productId:S,restoredAt:E,revision:v,row:B,skipped:!1}}if(P||!Oz.has(b)||V&&b!=="revision-conflict")throw new xr("Cloud item Restore rejection was malformed.",{code:"malformed-product-restore-rejection"});return{applied:P,conflict:V,deletionId:y,listId:I,ok:_,operationId:N,outcome:b,ownerId:C,productId:S||i,restoredAt:E,revision:v,skipped:!1}},Jg=e=>String(e||"").trim(),Gz=(e,t)=>{const r=Jg(e),a=Jg(t);return!!(r&&a&&r!==a)},qz=async({fetchImpl:e=globalThis.fetch,url:t="/app-version.json"}={})=>{if(typeof e!="function")throw new Error("Version checks are unavailable.");const r=t.includes("?")?"&":"?",a=await e(`${t}${r}checked=${Date.now()}`,{cache:"no-store",headers:{Accept:"application/json"}});if(!a?.ok)throw new Error("Could not check the deployed app version.");const s=await a.json(),o=Jg(s?.version);if(!o)throw new Error("The deployed app version is unavailable.");return o},pw="saveboard.cloud-review-warning.dismissals.v1",Vj=1,Yz=24,Kz=2160*60*60*1e3,Xz=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?Math.floor(t):0},ap=e=>{const t=String(e??"");let r=2166136261;for(let a=0;a<t.length;a+=1)r^=t.charCodeAt(a),r=Math.imul(r,16777619)>>>0;return r.toString(16).padStart(8,"0")},Jz=(e={})=>String(e.id||e.activeRecord?.id||e.cloudBase?.id||"").trim(),hP=e=>{const t=Number(e);return Number.isSafeInteger(t)&&t>0?t:null},Qz=e=>{const t=String(e||"").toLowerCase();return t?t.includes("parent")||t.includes("relationship")||t.includes("missing-board")?"relationship":t.includes("delete")||t.includes("tombstone")||t.includes("restore")?"lifecycle":t.includes("owner")?"ownership":t.includes("legacy")||t.includes("revision")||t.includes("conflict")||t.includes("patch")?"record-review":`review-${ap(t)}`:"review"},Zz=e=>{const t=String(e||"").toLowerCase();return t?t.includes("missing board")||t.includes("relationship")?"relationship":t.includes("delete")||t.includes("tombstone")?"lifecycle":t.includes("owner")?"ownership":t.includes("revision")||t.includes("conflict")||t.includes("local changes")?"record-review":`review-${ap(t)}`:"review"},Th=(e,t)=>{if(!e?.requiresReview)return null;const r=Jz(e),a=e.comparison||{};return{cloudRevision:hP(a.cloudRevision??e.revision),entityType:t,localRevision:hP(a.localRevision),reason:Qz(e.reason),recordFingerprint:r?`fnv1a32:${ap(r)}`:"missing"}},eV=(e={})=>Object.entries(e||{}).map(([t,r])=>[String(t),Xz(r)]).filter(([,t])=>t>0).sort(([t],[r])=>t.localeCompare(r)),ZC=({blocked:e=!1,conflicts:t={},listOutcomes:r=[],listSuppressions:a=[],productOutcomes:s=[],productSuppressions:o=[],warnings:i=[]}={})=>{const c=[...r.map(u=>Th(u,"board")),...a.map(u=>Th(u,"board")),...s.map(u=>Th(u,"product")),...o.map(u=>
16Th(u,"product"))].filter(Boolean).sort((u,p)=>[u.entityType,u.recordFingerprint,u.reason].join(":").localeCompare([p.entityType,p.recordFingerprint,p.reason].join(":"))),l={blocked:!!e,conflicts:eV(t),records:c,warningCategories:[...new Set((i||[]).map(Zz))].sort()};return{...l,fingerprint:`cloud-review:v1:${ap(JSON.stringify(l))}`,reviewCount:c.length||l.conflicts.reduce((u,[,p])=>u+p,0),type:"cloud-review"}},tV=(e,t="")=>e?`cloud-review:v1:${ap(`${ap(t)}:${e}`)}`:"",Hj=(e,t)=>e.filter(r=>/^cloud-review:v1:[0-9a-f]{8}$/.test(String(r?.fingerprint||""))&&Number.isFinite(Number(r?.dismissedAt))&&t-Number(r.dismissedAt)<=Kz).sort((r,a)=>Number(a.dismissedAt)-Number(r.dismissedAt)).slice(0,Yz),ex=(e,t=Date.now())=>{if(!e?.getItem)return[];try{const r=JSON.parse(e.getItem(pw)||"null");return r?.version===Vj?Hj(r.entries||[],t):[]}catch{return[]}},Wj=(e,t,r=Date.now())=>{if(!e?.setItem)return;const a=Hj(t,r);try{a.length?e.setItem(pw,JSON.stringify({entries:a,version:Vj})):e.removeItem?.(pw)}catch{}},rV=(e,t,r=Date.now())=>{if(!t)return;const a=ex(e,r).filter(s=>s.fingerprint!==t);Wj(e,[{dismissedAt:r,fingerprint:t},...a],r)},gP=(e,t,r=Date.now())=>{t&&Wj(e,ex(e,r).filter(a=>a.fingerprint!==t),r)},nV=({now:e=()=>Date.now(),storage:t=null}={})=>{const r=new Set;let a="",s="";const o=i=>ex(t,e()).some(c=>c.fingerprint===i);return{dismiss(i=s){return i?(rV(t,i,e()),s===i&&(s=""),!0):!1},report(i,c=""){const l=tV(i?.fingerprint||"",c);return l?(a&&a!==l&&(gP(t,a,e()),r.delete(a)),a=l,o(l)?(s="",{fingerprint:l,show:!1,status:"suppressed"}):r.has(l)?{fingerprint:l,keepVisible:s===l,show:!1,status:"existing"}:(r.add(l),s=l,{fingerprint:l,show:!0,status:"new"})):{fingerprint:"",show:!1,status:"ignored"}},resolve(){a&&(gP(t,a,e()),r.delete(a));const i=a;return a="",s="",i}}},aV=7e3,Gj=5e3,qj=15e3,sV=100;class tx extends Error{constructor(t="Foreground cloud refresh was superseded."){super(t),this.name="ForegroundRefreshCancelledError",this.code="foreground-refresh-cancelled"}}class oV extends Error{constructor(t="Foreground cloud refresh timed out."){super(t),this.name="ForegroundRefreshTimeoutError",this.code="foreground-refresh-timeout"}}const mw=e=>e?.reason instanceof Error?e.reason:new tx,hl=e=>{if(e?.aborted)throw mw(e)},fw=(e,{signal:t}={})=>t?t.aborted?Promise.reject(mw(t)):new Promise((r,a)=>{const s=()=>a(mw(t));t.addEventListener("abort",s,{once:!0}),Promise.resolve(e).then(r,a).finally(()=>{t.removeEventListener("abort",s)})}):Promise.resolve(e),To=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?t:0},Cm=(...e)=>[...new Set(e.flatMap(t=>t?.warnings||[]).map(t=>String(t||"").trim()).filter(Boolean))],Dh=(e,t=[])=>{const r=Cm({warnings:t},e);return{added:{boards:0,products:0},blocked:!0,changed:!1,cloudReviewWarning:ZC({blocked:!0,conflicts:e?.conflicts||{},listOutcomes:e?.listOutcomes||[],listSuppressions:e?.listSuppressions||[],productOutcomes:e?.productOutcomes||[],productSuppressions:e?.productSuppressions||[],warnings:r}),destructiveWritesPerformed:0,message:e?.message||"Cloud refresh needs review. Your local data was not overwritten.",needsAttention:!0,supabaseWritesPerformed:0,suppressed:{boards:0,products:0},updated:{boards:0,products:0},warnings:r}},iV=({createAbortController:e=()=>new AbortController,clearTimer:t=S=>clearTimeout(S),getGeneration:r=()=>0,getNow:a=()=>Date.now(),initialLastStartedAt:s,isEnabled:o=()=>!0,isOnline:i=()=>!0,isVisible:c=()=>!0,minimumIntervalMs:l=Gj,onCancel:u=()=>{},onError:p=()=>{},onResult:m=()=>{},onStart:f=()=>{},refresh:h,setTimer:b=(S,C)=>setTimeout(S,C),timeoutMs:v=qj}={})=>{if(typeof h!="function")throw new Error("Foreground refresh controller is not configured.");const S=Math.max(0,Number(l)||0),C=Math.max(0,Number(v)||0);let I=!1,A=null,k=1,E=!1,y=null,N=Number.isFinite(Number(s))?Number(s):a()-S;const _=()=>!!(o()&&i()&&c()),P=()=>{y!==null&&(t(y),y=null)};let V;const L=()=>
16{if(I||y!==null||!E||!_())return;const Z=Math.max(0,S-(a()-N));y=b(()=>{y=null,!(I||!E)&&(E=!1,V())},Z)},z=Z=>{Z?.timeoutTimer!==null&&(t(Z.timeoutTimer),Z.timeoutTimer=null)},B=({notify:Z=!0,reason:D="superseded"}={})=>{const K=A;if(!K)return!1;A=null,K.cancelled=!0,z(K);const ee=new tx(D==="signed-out"?"Foreground cloud refresh stopped because the session ended.":"Foreground cloud refresh was superseded by a newer session.");return K.abortController.abort(ee),K.rejectBoundary(ee),Z&&!I&&u(ee,K.context),!0},re=()=>{if(I||A||!_())return null;P(),E=!1,N=a();const Z=e(),D={generation:r(),requestId:k,signal:Z.signal};k+=1;let K=()=>{};const ee=new Promise((Be,Fe)=>{K=Fe}),J={abortController:Z,cancelled:!1,context:D,rejectBoundary:K,timeoutTimer:null};A=J,f(D);const fe=Promise.resolve().then(()=>h(D)),De=Promise.race([fe,ee]);return J.promise=De,C>0&&(J.timeoutTimer=b(()=>{if(I||A!==J||J.cancelled)return;const Be=new oV;J.abortController.abort(Be),J.rejectBoundary(Be)},C)),De.then(Be=>{!I&&!J.cancelled&&A===J&&m(Be,D)},Be=>{!I&&!J.cancelled&&A===J&&(E=!1,P(),p(Be,D))}).finally(()=>{z(J),A===J&&(A=null),!I&&E&&L()}),De};return V=()=>I||!_()?{status:"skipped"}:A?(E=!0,{status:"scheduled"}):a()-N>=S?(re(),{status:"started"}):(E=!0,L(),{status:"scheduled"}),{cancel:({reason:Z="superseded"}={})=>(E=!1,P(),B({reason:Z})),dispose:()=>{I=!0,E=!1,P(),B({notify:!1,reason:"unmounted"})},getState:()=>({disposed:I,generation:A?.context?.generation??null,inFlight:!!A,lastStartedAt:N,trailingRequested:E,trailingScheduled:y!==null}),requestRefresh:V}},cV=({clearTimer:e=i=>clearTimeout(i),coalesceDelayMs:t=sV,documentTarget:r,requestRefresh:a,setTimer:s=(i,c)=>setTimeout(i,c),windowTarget:o}={})=>{if(!r?.addEventListener||!r?.removeEventListener||typeof a!="function"||!o?.addEventListener||!o?.removeEventListener)throw new Error("Foreground refresh lifecycle is not configured.");let i=null;const c=()=>{i===null&&(i=s(()=>{i=null,r.visibilityState==="visible"&&a()},Math.max(0,Number(t)||0)))},l=()=>{r.visibilityState==="visible"&&c()};return o.addEventListener("focus",c),o.addEventListener("online",c),o.addEventListener("pageshow",c),r.addEventListener("visibilitychange",l),()=>{i!==null&&(e(i),i=null),o.removeEventListener("focus",c),o.removeEventListener("online",c),o.removeEventListener("pageshow",c),r.removeEventListener("visibilitychange",l)}},lV=async({applyAddOnlyPull:e,applyCloudNewerPull:t,prepareAddOnlyPull:r,prepareCloudNewerPull:a,readLocalRows:s,signal:o}={})=>{if(typeof e!="function"||typeof t!="function"||typeof r!="function"||typeof a!="function"||typeof s!="function")throw new Error("Foreground cloud refresh is not configured.");hl(o);const i=s(),c=JSON.stringify(i),l=await fw(r(i),{signal:o});if(hl(o),JSON.stringify(s())!==c)return{cancelled:!0,reason:"local-state-changed-during-refresh",writesPerformed:0};if(l?.blocked)return Dh(l);let u={boardCount:0,productCount:0};if((l?.lists?.length||l?.products?.length)&&(hl(o),u=e({lists:l.lists||[],products:l.products||[]}),u?.blocked))return Dh(u,Cm(l));hl(o);const p=s(),m=JSON.stringify(p),f=await fw(a(p),{signal:o});if(hl(o),JSON.stringify(s())!==m)return{cancelled:!0,reason:"local-state-changed-during-refresh",writesPerformed:0};if(f?.blocked)return Dh(f,Cm(l));let h={boardCount:0,productCount:0};if((f?.lists?.length||f?.products?.length||f?.listSuppressions?.length||f?.productSuppressions?.length)&&(hl(o),h=t({conflicts:f.conflicts||{},listSuppressions:f.listSuppressions||[],lists:f.lists||[],productSuppressions:f.productSuppressions||[],products:f.products||[]}),h?.blocked))return Dh(h,Cm(l,f));const b=To(u?.boardCount??l?.boardCount),v=To(u?.productCount??l?.productCount),S=To(h?.boardCount??f?.boardCount),C=To(h?.productCount??f?.productCount),I=To(h?.suppressedBoardCount),A=To(h?.suppressedProductCount),k=b+v+S+C+I+A>0,E=Cm(l,f),y=f?.conflicts||{},N=Object.values(y).reduce((V,L)=>V+To(L),0),_=E.length>0||N>0,P=_?ZC({conflicts:y,listOutcomes:f?.listOutcomes||[],listSuppressions:f?.listSuppressions||[],productOutcomes:f?.productOutcomes||[],productSuppressions:f?.productSuppressions||[],warnings:E}):null;return{added:{boards:b,products:v},blocked:!1,changed:k,cloudReviewWarning:P,conflicts:y,destructiveWritesPerformed:0,ignoredBoardTombstones:Math.max(To(l?.ignoredBoardTombstones),To(f?.ignoredBoardTombstones)),ignoredProductTomb
16stones:Math.max(To(l?.ignoredProductTombstones),To(f?.ignoredProductTombstones)),message:_?"Cloud refresh completed, but some changes need review. Pending local changes were preserved.":k?"Cloud changes refreshed.":"Cloud data is up to date.",needsAttention:_,supabaseWritesPerformed:0,suppressed:{boards:I,products:A},updated:{boards:S,products:C},warnings:E}},bP=Jg("0a079a60f28e46e39fcced142af855a9ae4a0862"),dV=6e4,uV=5*6e4,pV=()=>{try{return typeof window>"u"?null:window.localStorage}catch{return null}},hw={checkedAt:"",fingerprint:"",message:"",result:null,status:"idle"},mV=(e,t=new Date().toISOString())=>e?.cancelled||e?.signedOut||e?.skipped?{...hw,checkedAt:t}:e?.blocked||e?.needsAttention?{checkedAt:t,message:e?.message||"Some cloud changes need review. Local data was not overwritten.",result:e||null,status:"attention"}:{checkedAt:t,message:e?.changed?e.message||"Cloud changes refreshed.":"",result:e||null,status:e?.changed?"synced":"idle"},fV=(e,t=new Date().toISOString())=>({checkedAt:t,message:e?.code==="foreground-refresh-timeout"?"Cloud refresh took too long. Your browser data is safe; return to Saveboard to try again.":"Could not refresh cloud data. Your saved browser data is still available.",result:null,status:"error"}),hV=({enabled:e,minimumIntervalMs:t=Gj,refresh:r,sessionKey:a="",timeoutMs:s=qj}={})=>{const[o,i]=d.useState(hw),c=d.useRef(null),l=d.useRef(null),u=d.useRef(!!e),p=d.useRef(0),m=d.useRef(r),f=d.useRef(""),h=String(a||(e?"enabled":""));u.current=!!e,m.current=r,f.current=h;const b=d.useCallback(()=>(l.current||(l.current=nV({storage:pV()})),l.current),[]);d.useEffect(()=>{if(typeof window>"u"||typeof document>"u")return;const C=iV({getGeneration:()=>p.current,isEnabled:()=>u.current&&!!f.current,isOnline:()=>navigator.onLine!==!1,isVisible:()=>document.visibilityState==="visible",minimumIntervalMs:t,onError:(k,E)=>{E?.generation===p.current&&i(fV(k))},onResult:(k,E)=>{if(E?.generation===p.current){const y=mV(k);if(y.status==="attention"){const N=k?.cloudReviewWarning||ZC({blocked:k?.blocked,conflicts:k?.conflicts||{},warnings:k?.warnings||[]}),_=b().report(N,f.current);i(P=>_.keepVisible&&P.status==="attention"&&P.fingerprint===_.fingerprint?P:_.show?{...y,fingerprint:_.fingerprint}:{...y,fingerprint:_.fingerprint,message:"",status:"idle"})}else b().resolve(),i(y)}},onStart:k=>{k?.generation===p.current&&i(E=>E.status==="attention"?E:{checkedAt:"",fingerprint:"",message:"Refreshing cloud data...",result:null,status:"refreshing"})},refresh:k=>m.current?.({...k,sessionKey:f.current}),setTimer:(k,E)=>window.setTimeout(k,E),clearTimer:k=>window.clearTimeout(k),timeoutMs:s});c.current=C;const A=cV({clearTimer:k=>window.clearTimeout(k),documentTarget:document,requestRefresh:()=>C.requestRefresh(),setTimer:(k,E)=>window.setTimeout(k,E),windowTarget:window});return()=>{c.current===C&&(c.current=null),C.dispose(),A()}},[b,t,s]),d.useEffect(()=>{p.current+=1;const C=c.current;C?.cancel({reason:h?"session-changed":"signed-out"}),l.current=null,i(hw),e&&h&&C?.requestRefresh()},[h,e]);const v=d.useCallback(()=>{i(C=>(C.status==="attention"&&C.fingerprint&&b().dismiss(C.fingerprint),{...C,message:"",status:"idle"}))},[b]);d.useEffect(()=>{if(o.status!=="attention"||!o.fingerprint)return;const C=window.setTimeout(v,aV);return()=>window.clearTimeout(C)},[v,o.fingerprint,o.status]);const S=d.useCallback(()=>c.current?.requestRefresh()||{status:"skipped"},[]);return{...o,dismiss:v,requestRefresh:S}},gV=()=>{const[e,t]=d.useState(""),[r,a]=d.useState(""),[s,o]=d.useState(!1),i=d.useRef(0),c=d.useRef(null);return d.useEffect(()=>{if(typeof window>"u"||typeof document>"u")return;let u=!0;const p=({force:b=!1}={})=>{const v=Date.now();if(document.visibilityState!=="visible"||c.current||!b&&v-i.current<dV)return;i.current=v;const S=qz();c.current=S,S.then(C=>{u&&(t(C),o(Gz(bP,C)&&C!==r))},()=>{}).finally(()=>{c.current===S&&(c.current=null)})},m=()=>{document.visibilityState==="visible"&&p()},f=window.setTimeout(()=>p({force:!0}),1500),h=window.setInterval(()=>p(),uV);return window.addEventListener("focus",p),window.addEventListener("pageshow",p),document.addEventListener("visibilitychange",m),()=>{u=!1,window.clearTimeout(f),window.clearInterval(h),window.removeEventListener("focus",p),window.removeEventListener("pageshow",p),document.removeEventListener("visibilitychange",m)}},[r]),{dismissUpdate:d.useCallback(()=>{a(e),o(!1)},[e]),loadedVersion:bP,updateAvailable:s}},vP=[".productEditorForm",'[role="dialog"] input:not([type="hidden"]):not([disabled])','[role="dialog"] textarea:not([disabled])','[role="dialog"] select:not([disabled])','[role="dialog"] [contenteditable="true"]'].join(",");function bV(){const{dismissUpdate:e,updateAvailable:t}=gV(),[r,a]=d.useState(!1);return d.useEffect(()=>{if(typeof document>"u"||!t){a(!1);return}const s=()=>{a(!!document.querySelector(vP))},o=new MutationObserver(s);return s(),o.observe(document.body,{childList:!0,subtree:!0}),()=>o.disconnect()},[t]),!t||r?null:n.jsxs("aside",{"aria-live":"polite",className:"appVersionPrompt",role:"status",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"New version available"}),n.jsx("p",{children:"Reload when you are ready to use the latest Saveboard update."})]}),n.jsxs("div",{className:"appVersionPromptActions",children:[n.jsx("button",{className:"appVersionLaterButton",onClick:e,type:"button",children:"Later"}),n.jsx("button",{className:"appVersionReloadButton",onClick:()=>{document.querySelector(vP)||window.location.reload()},type:"button",children:"Reload"})]})]})}function vV({state:e}){return!e||!["attention","error"].includes(e.status)?null:n.jsxs("aside",{"aria-live":"polite",className:`foregroundCloudRefreshNotice is-${e.status}`,role:e.status==="error"?"alert":"status",children:[n.jsx("span",{children:e.status==="attention"?"Some local changes still need review.":e.message}),n.jsx("button",{"aria-label":"Dismiss cloud refresh notice",onClick:e.dismiss,type:"button",children:"×"})]})}const yV=/\b(?:approx(?:imate(?:ly)?)?|estimated|from|starting)\b|\+/i,SV=/(?:-|–|—|\bto\b)/i,wV=new Set(wb.map(({code:e})=>e)),CV="equal-revision-active-conflict",Yj=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),xV=e=>!!e&&typeof e=="object"&&!Array.isArray(e),Kj=(e={})=>!Yj(e,"syncConflictPatch")||e.syncConflictPatch==null?"absent":xV(e.syncConflictPatch)?Object.keys(e.syncConflictPatch).length?"nonempty":"empty":"malformed",IV=(e={})=>{const t=Yj(e,"priceAmount")?e.priceAmount:e.price_amount;if(t==null||t==="")return null;const r=Number(t);return Number.isFinite(r)?r:null},AV=e=>/\d\s+\d|\d['’]\d/.test(e)?!0:(e.match(/\d[\d.,]*/g)||[]).some(r=>(r.match(/\./g)||[]).length>1?!0:r.includes(",")?!/^\d{1,3}(?:,\d{3})+(?:\.\d+)?$/.test(r):!1),PV=e=>{const t=String(e||"").trim().toUpperCase();return t?wV.has(t)?"recognized":"unrecognized":"missing"},_V=({cloudRecord:e,localRecord:t,parsedCurrency:r})=>{const a=_c(r),s=_c(t.currency),o=_c(e.currency);return!a||!s||!o?"unable-to-compare":a===s&&s===o?"equivalent":"different"},EV=({cloudRecord:e,parsedAmount:t})=>{const r=IV(e);return!Number.isFinite(t)||r===null?"unable-to-compare":t===r?"equal":"different"},rx=({cloudRecord:e={},explicitMovePending:t=!1,localRecord:r={}}={})=>{const a=Kj(r);if(a==="nonempty")return{parserOutcome:"not-run",singleNumber:!1,rangeDetected:!1,approximatePriceTextDetected:!1,localeFormatAmbiguity:!1,safeFailureReason:"current-pending-patch",parsedCurrencyClassification:"not-run",persistedCurrencyComparison:"unable-to-compare",numericComparison:"unable-to-compare",patchClassification:a,finalClassification:"current-pending-patch"};const s=On(r.price),o=qE(s),i=Us({price:s,currency:r.currency}),c=Number.isFinite(i.amount),l=o.length>1&&SV.test(s),u=yV.test(s),p=AV(s),m=PV(i.currency),f=_V({cloudRecord:e,localRecord:r,parsedCurrency:i.currency}),h=EV({cloudRecord:e,parsedAmount:i.amount}),b=o.length===1;
16let v="",S="ambiguous-price";return a==="malformed"?v="malformed-patch":r.syncPendingCloudWrite===!0?v="pending-cloud-write":t?v="pending-local-move":s?c?p?v="locale-format-ambiguous":l?v="range-price":u||i.approximate===!0?v="approximate-price":b?m!=="recognized"?v="currency-unavailable":f!=="equivalent"?v=f==="different"?"currency-mismatch":"currency-unavailable":h==="unable-to-compare"?v="cloud-amount-unavailable":h==="different"?(v="parsed-amount-different",S="genuine-price-difference"):S="legacy-price-equivalent":v="multiple-numeric-values":v="nonnumeric-price":v="missing-price",{parserOutcome:c?"success":"failure",singleNumber:b,rangeDetected:l,approximatePriceTextDetected:u,localeFormatAmbiguity:p,safeFailureReason:v,parsedCurrencyClassification:m,persistedCurrencyComparison:f,numericComparison:h,patchClassification:a,finalClassification:S}},kV=(e,t)=>({parserOutcome:"not-run",singleNumber:!1,rangeDetected:!1,approximatePriceTextDetected:!1,localeFormatAmbiguity:!1,safeFailureReason:t,parsedCurrencyClassification:"not-run",persistedCurrencyComparison:"unable-to-compare",numericComparison:"unable-to-compare",patchClassification:e,finalClassification:"ineligible"}),Xj=({cloudParentExists:e=!1,cloudRecord:t={},explicitMovePending:r=!1,localRecord:a={},ownershipClassification:s="unknown",relationshipClassification:o="unknown",revisionClassification:i="unknown",semanticDifferenceFields:c=[]}={})=>{const l=Kj(a),u=[...new Set(c.map(h=>String(h||"")).filter(Boolean))].sort(),p=i!=="equal-valid"?"revision-not-equal":String(a.syncConflict||"").trim()!==CV?"different-conflict-reason":l!=="empty"?"patch-not-empty":a.syncPendingCloudWrite===!0?"pen
16ding-cloud-write":r?"pending-local-move":s!=="owner-match"?"ownership-not-valid":o!=="same-parent"||!e?"parent-not-valid":u.length!==1||u[0]!=="priceAmount"?"additional-semantic-difference":"";if(p)return kV(l,p);const m=rx({cloudRecord:t,explicitMovePending:r,localRecord:a}),f=m.finalClassification==="legacy-price-equivalent"?"equal-revision-legacy-price-equivalent":m.finalClassification==="genuine-price-difference"?"equal-revision-genuine-price-difference":"equal-revision-ambiguous-price";return{...m,finalClassification:f}},sg=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Jj="local-user",Qj="equal-revision-active-conflict",Zj=["budget","budgetAmount","budget_amount"],NV=new Set(["listId","list_id"]),Wo=e=>String(e??"").trim(),sp=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),nx=e=>!!e&&typeof e=="object"&&!Array.isArray(e),wl=(e={})=>Wo(e.id),Qg=(e={})=>Wo(e.userId||e.user_id),gw=(e={})=>Wo(e.listId||e.list_id),Zg=e=>Array.isArray(e)?e.map(t=>t===void 0?null:Zg(t)):nx(e)?Object.fromEntries(Object.keys(e).filter(t=>e[t]!==void 0).sort().map(t=>[t,Zg(e[t])])):e,eR=(e,t)=>JSON.stringify(Zg(e))===JSON.stringify(Zg(t)),jV=(e={})=>Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r))),yn=(e,t)=>{const r=String(t||"none");e[r]=Number(e[r]||0)+1},eb=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),tb=(e={})=>!!(e.collaborationId||e.collaboration_id||e.collaboratorId||e.collaborator_id||e.sharedBoardId||e.shared_board_id||e.isCollaborative||e.isSharedProjection),bw=(e,t)=>{const r=t.find(a=>sp(e,a));return r&&e[r]!==void 0?{present:!0,value:e[r]}:{present:!1,value:void 0}},vw=(e={})=>{const t=bw(e,Zj);return!t.present||t.value===null||t.value===void 0||typeof t.value=="string"&&!t.value.trim()?"absent":typeof t.value!="number"||!Number.isFinite(t.value)?"not-numeric":t.value===0?"zero":"nonzero"},yw=({present:e=!0,value:t}={})=>
16{if(!e||t===void 0)return"absent";if(t===null)return"null";if(Array.isArray(t))return"array";if(typeof t=="object")return"object";if(typeof t=="number")return Number.isFinite(t)?"numeric-number":"other";if(typeof t!="string")return"other";const r=t.trim();return r?/^[+-]?(?:\d+(?:\.\d+)?|\.\d+)$/.test(r)?"numeric-string":/\d/.test(r)&&/(?:[$£€¥]|\b(?:USD|GBP|EUR|JPY)\b)/i.test(r)?"formatted-currency-string":"nonnumeric-string":"empty-string"},yP=({present:e,value:t})=>{const r=yw({present:e,value:t});if(r==="numeric-number")return Number(t);if(r==="numeric-string")return Number(String(t).trim());if(r==="formatted-currency-string"){const a=String(t).replace(/[^0-9+.-]/g,"");return a&&Number.isFinite(Number(a))?Number(a):null}return null},RV=(e,t)=>{if(!e.present&&!t.present)return"both-absent";if(!e.present||!t.present)return"one-absent";if(e.value===null&&t.value===null)return"same-null";const r=yP(e),a=yP(t);return r!==null&&a!==null?r===a?"same-numeric-value":"different-numeric-value":typeof e.value=="string"&&typeof t.value=="string"?e.value.trim()===t.value.trim()?"same-string-after-trimming":"genuinely-different-representation":typeof e.value=="object"||typeof t.value=="object"?"unable-to-compare-safely":Object.is(e.value,t.value)?"same-representation":"genuinely-different-representation"},SP=(e,t,r)=>{const a=bw(e,r),s=bw(t,r);return{localShape:yw(a),cloudShape:yw(s),comparison:RV(a,s)}},wP=e=>{if(!e)return"record-absent";const t=sp(e,"syncRevision")||sp(e,"revision"),r=e.syncRevision??e.revision;return!t||r===null||r===void 0||r===""?"missing":Qn(r)===null?"invalid":"valid-positive"},tR=(e,t)=>{const r=Qn(e?.syncRevision??e?.revision),a=Qn(t?.syncRevision??t?.revision);return e?t?r===null&&a!==null?"missing-local-valid-cloud":r!==null&&a===null?"valid-local-missing-cloud":r===null&&a===null?"both-missing-or-invalid":r===a?"equal-valid":r>a?"local-valid-newer":"cloud-valid-newer":r===null?"cloud-absent-local-revision-missing":"cloud-absent-valid-local":a===null?"local-absent-cloud-revision-missing":"local-absent-valid-cloud"},ax=(e={})=>!sp(e,"syncConflictPatch")||e.syncConflictPatch===void 0?"absent":e.syncConflictPatch===null?"null":nx(e.syncConflictPatch)?Object.keys(e.syncConflictPatch).length?"nonempty":"empty":"malformed",LV=(e={},t=new Set)=>t.has(wl(e))?"explicit-move-recorded":nx(e.syncConflictPatch)&&Object.keys(e.syncConflictPatch).some(r=>NV.has(r))?"pending-move-patch":"none",rR=({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:a})=>{if(tb(r)||tb(t))return"shared-projection";if(!a||!sg.test(Wo(e)))return"ownership-unproven";if(!t)return"local-only-ownership-unverified";const s=Qg(t),o=Qg(r);return sg.test(s)?s!==Wo(e)?"cloud-owner-mismatch":r?!o||o===Jj?"local-owner-placeholder":sg.test(o)?o===s?"owner-match":"local-owner-mismatch":"local-owner-malformed":"cloud-owner-validated":"cloud-owner-malformed"},CP=(e={})=>Zj.filter(t=>sp(e,t)&&e[t]!==void 0).map(t=>e[t]),BV=({authenticatedUserId:e,cloudRecord:t,localRecord:r,localPatchState:a,ownership:s,pendingCloudWrite:o,privateOwnerScoped:i,revisionClassification:c})=>{const l=CP(r),u=CP(t),p=Qg(t),m={...r,...sp(r,"user_id")?{user_id:p}:{},userId:p};if(!i||s!=="local-owner-placeholder"||Qg(r)!==Jj||!wl(r)||wl(r)!==wl(t)||eb(r)||eb(t)||tb(r)||tb(t)||c!=="equal-valid"||l.length===0||!l.every(h=>typeof h=="number"&&Number.isFinite(h)&&h===0)||!u.every(h=>h===null)||String(r.syncConflict||"").trim()!==Qj||a!=="empty"||o||!sg.test(Wo(e))||p!==Wo(e))return!1;const f=[...new Set(Ll({cloudRecord:t,entityType:"list",localRecord:m}).map(h=>h.field))].sort();return f.length===1&&f[0]==="budget"},nR=({authenticatedUserId:e="",cloudRecord:t=null,localRecord:r=null,privateOwnerScoped:a=!1}={})=>{const s=vw(r||{}),o=vw(t||{}),i=ax(r||{}),c=r?.syncPendingCloudWrite===!0,l=tR(r,t),u=rR({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:a}),p=u==="owner-match"||u==="local-owner-placeholder",m=BV({authenticatedUserId:e,cloudRecord:t||{},localRecord:r||{},localPatchState:i,ownership:u,pendingCloudWrite:c,privateOwnerScoped:a,revisionClassification:l});
16let f="intentional-or-ambiguous-budget";return m?f="legacy-equal-revision-budget-equivalent":l==="equal-valid"?f="equal-revision-conflict":s==="not-numeric"||o==="not-numeric"?f="invalid-budget":(s==="absent"||s==="zero")&&o==="absent"&&l==="missing-local-valid-cloud"&&i==="empty"&&!c&&p&&(f="legacy-budget-equivalent"),{localBudgetClassification:s,cloudBudgetClassification:o,patchState:i,pendingCloudWrite:c,revisionClassification:l,finalClassification:f}},TV=({cloudRecord:e,entityType:t,explicitMove:r,localRecord:a})=>{if(t==="list")return"none";if(r!=="none")return"pending-local-move";const s=gw(a),o=gw(e);return!s&&!o?"both-parent-values-missing":s?o?s===o?"same-parent":"different-parent":"missing-cloud-parent":"missing-local-parent"},DV=(e,t,r)=>{if(!t||!r)return[];const a=Pu(e,t),s=Pu(e,r);return[...new Set([...Object.keys(a),...Object.keys(s)])].filter(o=>!eR(a[o],s[o])).sort()},OV=(e,t,r,a)=>a==="equal-valid"?[...new Set(Ll({cloudRecord:r,entityType:e,localRecord:t}).map(s=>s.field))].sort():[],MV=({decision:e,explicitMove:t,localRecord:r,relationship:a,revision:s})=>{const o=[],i=ax(r);return r?.syncPendingCloudWrite===!0&&o.push("current-pending-write"),i==="nonempty"&&o.push("current-nonempty-patch"),i==="malformed"&&o.push("malformed-patch"),t!=="none"&&o.push("explicit-or-pending-move"),s==="local-valid-newer"&&o.push("higher-local-revision"),s==="missing-local-valid-cloud"&&o.push("missing-local-valid-cloud-revision"),r?.syncConflict&&o.push("stored-conflict-metadata"),e.reason==="unacknowledged-content-difference"&&s==="equal-valid"&&o.push("equal-revision-canonical-content-difference"),e.reason==="local-only-record"&&o.push("local-only-record"),/owner|ownership|shared|collaborator/.test(String(e.reason||""))&&o.push("ownership-ambiguity"),(a.includes("missing")||e.reason==="cloud-parent-missing")&&o.push("missing-parent"),e.reason==="inactive-or-tombstoned"&&o.push("tombstone-state"),[...new Set(o)].sort()},xP=({authenticatedUserId:e,cloudRecords:t,decisions:r,entityType:a,explicitMoveProductIds:s,availableParentIds:o,listNormalizationProvenanceByFingerprint:i,localRecords:c,mergedRecords:l,privateOwnerScoped:u})=>{const p=new Map(c.map(y=>[wl(y),y]).filter(([y])=>y)),m=new Map(t.map(y=>[wl(y),y]).filter(([y])=>y)),f=new Map(l.map(y=>[wl(y),y]).filter(([y])=>y)),h=new Set(p.keys()),b=new Set(m.keys()),v={action:{},reason:{},localRevisionState:{},cloudRevisionState:{},revisionRelationship:{},patchState:{},pendingWriteState:{},explicitMoveState:{},ownershipClassification:{},relationshipClassification:{},protectionCause:{},budgetLocalShape:{},budgetCloudShape:{},budgetComparison:{},legacyBudgetLocalClassification:{},legacyBudgetCloudClassification:{},legacyBudgetFinalClassification:{},priceAmountLocalShape:{},priceAmountCloudShape:{},priceAmountComparison:{},legacyPriceParserOutcome:{},legacyPriceCurrencyComparison:{},legacyPriceNumericComparison:{},legacyPriceFinalClassification:{},legacyPriceFailureReason:{}},S=[];let C=0,I=0,A=0,k=0,E=0;return r.forEach(y=>{const N=p.get(Wo(y.id)),_=m.get(Wo(y.id)),P=f.get(Wo(y.id)),V=y.action==="apply-cloud"||y.action==="add-cloud-only",L=V&&(!N||!eR(N,P)),z=ax(N),B=wP(N),re=wP(_),Z=tR(N,_),D=a==="product"?LV(N,s):"none",K=rR({authenticatedUserId:e,cloudRecord:_,localRecord:N,privateOwnerScoped:u}),ee=TV({cloudRecord:_,entityType:a,explicitMove:D,localRecord:N}),J=SP(N,_,["budget","budgetAmount","budget_amount"]),fe=SP(N,_,["priceAmount","price_amount"]),De=DV(a,N,_),Be=OV(a,N,_,Z),Fe=MV({decision:y,explicitMove:D,localRecord:N,relationship:ee,revision:Z}),ke=a==="list"&&N&&_&&(Z==="missing-local-valid-cloud"||Z==="equal-valid"&&De.includes("budget"))&&vw(_)==="absent"?nR({authenticatedUserId:e,cloudRecord:_,localRecord:N,privateOwnerScoped:u}):null,We=a!=="product"?null:Z==="missing-local-valid-cloud"?rx({cloudRecord:_,explicitMovePending:D!=="none",localRecord:N}):Z==="equal-valid"&&!eb(N)&&!eb(_)&&String(N?.syncConflict||"").trim()===Qj?Xj({cloudParentExists:o.has(gw(_)),cloudRecord:_,explicitMovePending:D!=="none",localRecord:N,ownershipClassification:K,relationshipClassification:ee,revisionClassification:Z,semanticDifferenceFields:Be}):null,de=oo(y.id),ye=a==="list"?Tb(i.get(de)):null;yn(v.action,y.action),yn(v.reason,y.reason),yn(v.localRevisionState,B),yn(v.cloudRevisionState,re),yn(v.revisionRelationship,Z),yn(v.patchState,z),yn(v.pendingWriteState,N?.syncPendingCloudWrite===!0?"pen
16ding":"not-pending"),yn(v.explicitMoveState,D),yn(v.ownershipClassification,K),yn(v.relationshipClassification,ee),Fe.forEach(ge=>yn(v.protectionCause,ge)),yn(v.budgetLocalShape,J.localShape),yn(v.budgetCloudShape,J.cloudShape),yn(v.budgetComparison,J.comparison),ke&&(yn(v.legacyBudgetLocalClassification,ke.localBudgetClassification),yn(v.legacyBudgetCloudClassification,ke.cloudBudgetClassification),yn(v.legacyBudgetFinalClassification,ke.finalClassification)),yn(v.priceAmountLocalShape,fe.localShape),yn(v.priceAmountCloudShape,fe.cloudShape),yn(v.priceAmountComparison,fe.comparison),We&&(yn(v.legacyPriceParserOutcome,We.parserOutcome),yn(v.legacyPriceCurrencyComparison,We.persistedCurrencyComparison),yn(v.legacyPriceNumericComparison,We.numericComparison),yn(v.legacyPriceFinalClassification,We.finalClassification),yn(v.legacyPriceFailureReason,We.safeFailureReason||"none")),V&&(C+=1,I+=L?1:0,A+=L?0:1),k+=y.action==="protect-local"?1:0,E+=y.action==="skip-cloud-only"?1:0,(y.action==="protect-local"||y.action==="preserve-local-only"||y.action==="skip-cloud-only")&&S.push({recordFingerprint:de,entityType:a,presence:N&&_?"both":N?"local-only":"cloud-only",localRevisionState:B,cloudRevisionState:re,revisionRelationship:Z,decisionAction:y.action,decisionReason:y.reason,patchState:z,differingFields:De,safeValueShapes:{budgetField:J,priceAmountField:fe},relationshipClassification:ee,ownershipClassification:K,pendingCloudWrite:N?.syncPendingCloudWrite===!0,explicitMoveState:D,protectionCauses:Fe,materiallyChanged:L,...ke?{legacyBudgetEquivalence:ke}:{},...We?{legacyPriceEquivalence:We}:{},...ye?{listNormalizationProvenance:ye}:{}})}),{totals:{localRecords:h.size,cloudRecords:b.size,matchedRecords:[...h].filter(y=>b.has(y)).length,localOnlyRecords:[...h].filter(y=>!b.has(y)).length,cloudOnlyRecords:[...b].filter(y=>!h.has(y)).length,acceptedCloudRecords:C,protectedLocalRecords:k,unchangedEquivalentRecords:A,acceptedMaterialChanges:I,acceptedNoMaterialChange:A,rejectedOrInvalidRecords:E},histograms:Object.fromEntries(Object.entries(v).map(([y,N])=>[y,jV(N)])),protectedRecordEvidence:S}},UV=({authenticatedUserId:e="",cloudSnapshot:t={},explicitLocalMoveProductIds:r=[],listNormalizationProvenance:a=null,localSnapshot:s={},mergeResult:o={},privateOwnerScoped:i=!1}={})=>{const c=new Set(r.map(Wo).filter(Boolean)),l=new Set((t.lists||[]).map(wl).filter(Boolean)),u=cF(a),p=new Map(u.records.map(m=>[m.recordFingerprint,m]));return{mergeResultChanged:!!o.changed,listNormalizationProvenance:u,lists:xP({authenticatedUserId:e,cloudRecords:t.lists||[],decisions:o.listDecisions||[],entityType:"list",explicitMoveProductIds:c,availableParentIds:l,listNormalizationProvenanceByFingerprint:p,localRecords:s.lists||[],mergedRecords:o.lists||[],privateOwnerScoped:i}),products:xP({authenticatedUserId:e,cloudRecords:t.products||[],decisions:o.productDecisions||[],entityType:"product",explicitMoveProductIds:c,availableParentIds:l,listNormalizationProvenanceByFingerprint:p,localRecords:s.products||[],mergedRecords:o.products||[],privateOwnerScoped:i}),writesPerformed:0}},Sw="equal-revision-active-conflict",sx="mixed-revision-active-conflict",aR="local-user",sR=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,oR=new Set(["listId","list_id"]),FV=new Set(["cloud-owner-mismatch","cloud-tombstone-evidence-invalid","cloud-tombstone-local-provenance-unproven","inactive-or-tombstoned","local-owner-mismatch","ownership-unproven","shared-or-collaborator-record"]),uo=e=>String(e??"").trim(),rb=(e,t)=>Object.prototype.hasOwnProperty.call(e||{},t),Gb=e=>!!e&&typeof e=="object"&&!Array.isArray(e),Ta=(e={})=>uo(e.id),$i=(e={})=>uo(e.userId||e.user_id),Tn=(e={})=>uo(e.listId||e.list_id),Za=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed),Tm=e=>sR.test(uo(e)),iR=e=>Number.isFinite(Date.parse(e||"")),qb=(e={})=>Gb(e.syncConflictPatch)?Object.keys(e.syncConflictPatch).sort():[],ox=(e={})=>{const t=e.syncConflictPatch;return t!=null&&(!Gb(t)||Object.keys(t).length>0)},nb=(e={})=>!!(e.collaborationId||e.collaboration_id||e.collaboratorId||e.collaborator_id||e.sharedBoardId||e.shared_board_id||e.isCollaborative||e.
16isSharedProjection),_f=(e={})=>e.deleted_at||e.deletedAt||e.cloudDeletedAt||"",cR=(e={})=>e.deletion_id||e.deletionId||e.cloudDeletionId||"",$V=(e={})=>e.updated_at||e.updatedAt||e.cloudUpdatedAt||_f(e)||"",Yb=(e={})=>iR(_f(e))&&sR.test(uo(cR(e)))&&Qn(e.syncRevision??e.revision)!==null,ix=({authenticatedUserId:e,localRecord:t})=>{const r=uo(e),a=$i(t);return a!==r&&a!==aR?!1:Qn(t.syncRevision??t.revision)!==null&&iR(t.cloudUpdatedAt)},cx=({classification:e,localRecord:t,parentTombstone:r=!1})=>t.syncPendingCloudWrite===!0||ox(t)?r?"pending-local-edit-after-board-delete":"pending-local-edit-after-cloud-delete":String(t.syncConflict||"").trim()?r?"unresolved-local-conflict-versus-board-tombstone":"unresolved-local-conflict-versus-cloud-tombstone":e?.reason||(r?"parent-board-tombstone":"cloud-tombstone"),lR=({classification:e,localRecord:t})=>!!(e?.requiresReview||t.syncPendingCloudWrite===!0||ox(t)||String(t.syncConflict||"").trim()),zV=({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:a})=>{if(Za(r)||!Za(t))return null;const s=Ld({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:a});if(s)return{action:"protect-local",reason:s};if(!Yb(t))return{action:"protect-local",reason:"cloud-tombstone-evidence-invalid"};if(!ix({authenticatedUserId:e,localRecord:r}))return{action:"protect-local",reason:"cloud-tombstone-local-provenance-unproven"};const o=Km(r,{...t,deletedAt:_f(t)}),i=lR({classification:o,localRecord:r});return{action:"apply-cloud",authoritativeTombstone:!0,reason:i?cx({classification:o,localRecord:r}):o.reason,requiresReview:i}},VV=({authenticatedUserId:e,availableParentIds:t,cloudRecord:r,explicitMoveProductIds:a,localRecord:s,privateOwnerScoped:o})=>{if(Za(s)||!Za(r))return null;const i=Ld({authenticatedUserId:e,cloudRecord:r,localRecord:s,privateOwnerScoped:o});if(i)return{action:"protect-local",reason:i};const c=Tn(s),l=Tn(r);if(!c||c!==l)return{action:"protect-local",reason:"cloud-tombstone-parent-mismatch"};if(!t.has(l))return{action:"protect-local",reason:"cloud-parent-missing"};const u=r.deleted_at||r.deletedAt||r.cloudDeletedAt||"";if(!Number.isFinite(Date.parse(u)))return{action:"protect-local",reason:"cloud-tombstone-evidence-invalid"};if(String(s.syncConflict||"").trim())return{action:"protect-local",reason:"unresolved-local-conflict"};const p=dR({cloudRecord:r,explicitMoveProductIds:a,localRecord:s});if(p)return{action:"protect-local",reason:p};const m=Km(s,{...r,deletedAt:u});return!m.suppress||m.requiresReview?{action:"protect-local",reason:m.reason}:{action:"apply-cloud",reason:m.reason}},Ld=({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:a})=>{const s=uo(e),o=$i(t),i=$i(r);return!a||!Tm(s)?"ownership-unproven":!Tm(o)||o!==s?"cloud-owner-mismatch":nb(t)||nb(r)?"shared-or-collaborator-record":i&&i!==aR&&(!Tm(i)||i!==o)?"local-owner-mismatch":""},Ef=(e,t)=>t.has(Ta(e))||qb(e).some(r=>oR.has(r)),dR=({cloudRecord:e,entityType:t="",explicitMoveProductIds:r,localRecord:a})=>{if(t&&_N({cloudRecord:e,entityType:t,localRecord:a}))return"";if(a.syncPendingCloudWrite===!0)return"pending-cloud-write";const s=qb(a);if(ox(a))return s.some(l=>oR.has(l))?"pending-local-move":"pending-local-patch";if(Ef(a,r))return"explicit-local-move";const o=String(a.syncConflict||"").trim();if(o&&o!==Sw)return"unresolved-local-conflict";const i=Qn(a.syncRevision??a.revision),c=Qn(e.syncRevision??e.revision);return i===null||c===null?"revision-ambiguous":i>c?"local-revision-newer":""},HV=(e,t)=>{const r=String(e||""),a=String(t||"");return r===a||(!r||Vn(r))&&(!a||Vn(a))},WV=({availableParentIds:e,cloudRecord:t,explicitMoveProductIds:r,localRecord:a})=>{const s=Qn(a.syncRevision??a.revision),o=Qn(t.syncRevision??t.revision),i=Tn(a),c=Tn(t),l=String(a.syncConflict||"").trim(),u=Gb(a.syncConflictPatch)&&qb(a).length===0;if(s!==null||o===null||!u||l&&l!==sx||!i||i!==c||!e.has(c))return!1;const p=rx({cloudRecord:t,explicitMovePending:Ef(a,r),localRecord:a});return p.patchClassification==="empty"&&p.finalClassification==="legacy-price-equivalent"},GV=({authenticatedUserId:e,availableParentIds:t,cloudRecord:r,explicitMoveProductIds:a,localRecord:s,privateOwnerScoped:o})=>{const i=uo(e),c=$i(s),l=$i(r),u=Qn(s.syncRevision??s.revision),p=Qn(r.syncRevision??r.revision),m=Tn(s),f=Tn(r),h=String(s.syncConflict||"").trim(),b=Gb(s.syncConflictPatch)&&qb(s).length===0;return u!==null||p===null||!o||!Tm(i)||c!==i||l!==i||nb(s)||nb(r)||!b||s.syncPendingCloudWrite===!0||Ef(s,a)||h&&h!==sx||!m||m!==f||!t.has(f)?!1:mC({cloudRecord:r,entityType:"product",localRecord:s}).length===0},qV=({authenticatedUserId:e,availableParentIds:t,cloudRecord:r,explicitMoveProductIds:a,localRecord:s,privateOwnerScoped:o})=>{const i=Qn(s.syncRevision??s.revision),c=Qn(r.syncRevision??r.revision);if(i===null||c===null||i!==c)return!1;const l=uo(e),u=$i(s),p=$i(r),m=Tn(s),f=Tn(r),h=[...new Set(Ll({cloudRecord:r,entityType:"product",localRecord:s}).map(v=>v.field))].sort();return Xj({cloudParentExists:t.has(f),cloudRecord:r,explicitMovePending:Ef(s,a),localRecord:s,ownershipClassification:o&&Tm(l)&&u===l&&p===l?"owner-match":"ownership-not-valid",relationshipClassification:m&&m===f?"same-parent":"different-parent",revisionClassification:"equal-valid",semanticDifferenceFields:h}).finalClassification==="equal-revision-legacy-price-equivalent"},YV=({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:a})=>{const s=String(r.syncConflict||"").trim(),o=nR({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:a});return o.finalClassification==="legacy-equal-revision-budget-equivalent"&&s===Sw?{action:"apply-cloud",reason:"legacy-equal-revision-budget-canonicalization"}:(!s||s===sx)&&o.patchState==="empty"&&o.finalClassification==="legacy-budget-equivalent"?{action:"apply-cloud",reason:"legacy-budget-equivalent-transition"}:s===Sw&&o.revisionClassification==="equal-valid"&&o.cloudBudgetClassification==="absent"&&o.localBudgetClassification==="not-numeric"?{action:"protect-local",reason:"legacy-budget-not-proven-equivalent"}:null},KV=({cloudRecord:e,decision:t,inheritRevision:r=!0,localRecord:a})=>{const s=_f(e),o=cR(e),i=$i(e),c=Qn(e.syncRevision??e.revision),l=t?.requiresReview===!0,u={...a,...i?{userId:i}:{},cloudDeletedAt:s,cloudDeletionId:o,cloudDeletionReason:e.cloudDeletionReason||e.deletion_reason||a.cloudDeletionReason||"",cloudPurgeAfter:e.cloudPurgeAfter||e.purge_after||a.cloudPurgeAfter||"",cloudRestoredAt:"",cloudRestoredBy:"",cloudUpdatedAt:$V(e),syncConflict:l?Str
16ing(a.syncConflict||"").trim()||t.reason:"",syncSuppressed:!0};return i&&(rb(a,"user_id")||rb(e,"user_id"))&&(u.user_id=i),r&&c!==null&&!l&&(u.syncRevision=c),l?u.syncConflictAt=a.syncConflictAt||s:(u.syncPendingCloudWrite=!1,delete u.syncConflictAt,delete u.syncConflictPatch),u},$y=({cloudRecord:e,decision:t={},decisionReason:r="",entityType:a,localRecord:s})=>{if(t.authoritativeTombstone===!0)return KV({cloudRecord:e,decision:t,inheritRevision:t.inheritRevision!==!1,localRecord:s});const o={...s,...e};a==="product"&&Object.assign(o,lp(s,e,{isPlaceholder:Vn,preferCurrentImage:t.requiresReview===!0,preferCurrentLocalUpload:!1})),Number.isFinite(Number(s.sortOrder))&&(o.sortOrder=Number(s.sortOrder));const i=a==="product"?Pl(s):null,c=a==="product"?Pl(e):null;return a==="product"&&i.currency===c.currency&&(o.currency=s.currency),a==="product"&&HV(s.imageUrl||s.image,e.imageUrl||e.image)&&(rb(s,"imageUrl")&&(o.imageUrl=s.imageUrl),rb(s,"image")&&(o.image=s.image)),o.syncConflict="",o.syncPendingCloudWrite=!1,delete o.syncConflictAt,delete o.syncConflictPatch,a==="product"&&r==="authoritative-cloud-restore"&&(o.cloudDeletedAt="",o.cloudDeletionId="",o.cloudDeletionReason="",o.cloudPurgeAfter="",o.cloudRestoredAt=e.cloudRestoredAt||e.restored_at||e.restoredAt||"",o.cloudRestoredBy=e.cloudRestoredBy||e.restored_by||e.restoredBy||"",o.syncSuppressed=!1),a==="product"&&r==="cloud-tombstone"&&(o.cloudRestoredAt="",o.cloudRestoredBy=""),o},IP=({authenticatedUserId:e,availableParentIds:t,cloudRecord:r,entityType:a,explicitMoveProductIds:s,localRecord:o,privateOwnerScoped:i})=>{if(a==="product"){const h=Lj({authenticatedUserId:e,availableParentIds:t,cloudRecord:r,explicitMovePending:Ef(o,s),localRecord:o,privateOwnerScoped:i});if(h)return h}if(a==="product"){const h=VV({authenticatedUserId:e,availableParentIds:t,cloudRecord:r,explicitMoveProductIds:s,localRecord:o,privateOwnerScoped:i});if(h)return h}if(a==="list"){const h=zV({authenticatedUserId:e,cloudRecord:r,localRecord:o,privateOwnerScoped:i});if(h)return h}if(Za(o)||Za(r))return{action:"protect-local",reason:"inactive-or-tombstoned"};const c=Ld({authenticatedUserId:e,cloudRecord:r,localRecord:o,privateOwnerScoped:i});if(c)return{action:"protect-local",reason:c};if(a==="list"){const h=YV({authenticatedUserId:e,cloudRecord:r,localRecord:o,privateOwnerScoped:i});if(h)return h}if(a==="product"&&WV({availableParentIds:t,cloudRecord:r,explicitMoveProductIds:s,localRecord:o}))return{action:"apply-cloud",reason:"legacy-price-equivalent-transition"};if(a==="product"&&qV({authenticatedUserId:e,availableParentIds:t,cloudRecord:r,explicitMoveProductIds:s,localRecord:o,privateOwnerScoped:i}))return{action:"apply-cloud",reason:"legacy-equal-revision-price-canonicalization"};if(a==="product"&&GV({authenticatedUserId:e,availableParentIds:t,cloudRecord:r,explicitMoveProductIds:s,localRecord:o,privateOwnerScoped:i}))return{action:"apply-cloud",reason:"mixed-revision-semantic-equivalent-transition",semanticDifferenceFields:[]};const l=dR({cloudRecord:r,entityType:a,explicitMoveProductIds:s,localRecord:o});if(l)return{action:"protect-local",reason:l};const u=Qn(o.syncRevision??o.revision),p=Qn(r.syncRevision??r.revision);if(p>u)return a==="product"&&!t.has(Tn(r))?{action:"protect-local",reason:"cloud-parent-missing"}:{action:"apply-cloud",reason:"cloud-revision-newer"};if(p<u)return{action:"protect-local",reason:"local-revision-newer"};const m=Ll({cloudRecord:r,entityType:a,localRecord:o}),f=[...new Set(m.map(h=>h.field))].sort();return f.length?a==="list"&&f.length===1&&f[0]==="userId"?{action:"apply-cloud",reason:"validated-owner-normalization",semanticDifferenceFields:f}:a==="product"&&f.length===1&&f[0]==="listId"?t.has(Tn(r))?{action:"apply-cloud",reason:"clean-authoritative-cloud-relationship",semanticDifferenceFields:f}:{action:"protect-local",reason:"cloud-parent-missing",semanticDifferenceFields:f}:{action:"protect-local",reason:"unacknowledged-content-difference",semanticDifferenceFields:f}:{action:"apply-cloud",reason:"clean-equal-revision",semanticDifferenceFields:[]}},AP=({authenticatedUserId:e,availableParentIds:t,cloudRecords:r,entityType:a,localIds:s,privateOwnerScoped:o,records:i,decisions:c})=>{r.forEach(l=>{const u=Ta(l);if(!u||s.has(u))return;const p=Ld({authenticatedUserId:e,cloudRecord:l,localRecord:{},privateOwnerScoped:o});if(p){c.push({action:"skip-cloud-only",id:u,reason:p});return}if(a==="product"&&!Za(l)&&!t.has(Tn(l))){c.push({action:"skip-cloud-only",id:u,reason:"cloud-parent-missing"});return}i.push(l),c.push({action:"add-cloud-only",id:u,reason:"cloud-only-record"})})}
16,PP=(e=[],t=[])=>JSON.stringify(e)===JSON.stringify(t),ww=(e={})=>e.action==="protect-local"&&(e.reason==="inactive-or-tombstoned"||String(e.reason||"").startsWith("cloud-restore-")),ku=(e={})=>e.action==="apply-cloud"&&e.requiresReview===!0,XV=(e={})=>ku(e)||e.action==="protect-local"&&e.reason!=="inactive-or-tombstoned",JV=(e={})=>ku(e)||e.action==="protect-local"&&!ww(e),QV=({authenticatedUserId:e,cloudRecord:t,localRecord:r,parentListId:a,privateOwnerScoped:s})=>{if(!Za(t)||Tn(t)!==a||!Yb(t)||Ld({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:s}))return null;const o=Km(r,{...t,deletedAt:_f(t)}),i=lR({classification:o,localRecord:r});return{action:"apply-cloud",authoritativeTombstone:!0,reason:i?cx({classification:o,localRecord:r}):o.reason,requiresReview:i}},ZV=({authenticatedUserId:e,cloudRecord:t,localRecord:r,parentListId:a,privateOwnerScoped:s})=>{if(!ix({authenticatedUserId:e,localRecord:r}))return"local-only-child-versus-board-tombstone";if(!t)return"missing-cloud-child-tombstone";if(Tn(t)!==a)return"cloud-child-parent-mismatch-versus-board-tombstone";if(!Za(t))return"active-cloud-child-versus-board-tombstone";if(!Yb(t))return"malformed-cloud-child-tombstone";const o=Ld({authenticatedUserId:e,cloudRecord:t,localRecord:r,privateOwnerScoped:s});return o?`cloud-child-${o}-versus-board-tombstone`:"unverified-cloud-child-tombstone"},eH=({fallbackReason:e,localRecord:t={}})=>{const r=Date.parse(t.updatedAt||t.updated_at||""),a=Date.parse(t.cloudUpdatedAt||""),o={reason:Number.isFinite(r)&&Number.isFinite(a)&&r>a?"pending-local-edit-after-board-delete":e};return{action:"apply-cloud",authoritativeTombstone:!0,inheritRevision:!1,parentTombstone:!0,reason:cx({classification:o,localRecord:t,parentTombstone:!0}),requiresReview:!0,reviewEvidenceReason:e}},tH=({authenticatedUserId:e="",cloudLists:t=[],cloudProducts:r=[],explicitLocalMoveProductIds:a=[],localLists:s=[],localProducts:o=[],privateOwnerScoped:i=!1}={})=>{const c=new Set(a.map(uo).filter(Boolean)),l=new Map(t.map(N=>[Ta(N),N]).filter(([N])=>N)),u=new Set(s.map(Ta).filter(Boolean)),p=[],m=s.map(N=>{const _=Ta(N),P=l.get(_);if(!P)return p.push({action:"preserve-local-only",id:_,reason:"local-only-record"}),N;const V=IP({authenticatedUserId:e,availableParentIds:new Set,cloudRecord:P,entityType:"list",explicitMoveProductIds:c,localRecord:N,privateOwnerScoped:i});return p.push({...V,id:_}),V.action==="apply-cloud"?$y({cloudRecord:P,decision:V,decisionReason:V.reason,entityType:"list",localRecord:N}):N});AP({authenticatedUserId:e,availableParentIds:new Set,cloudRecords:t,entityType:"list",localIds:u,privateOwnerScoped:i,records:m,decisions:p});const f=new Map(m.map(N=>[Ta(N),N]).filter(([N])=>N)),h=new Map;t.forEach(N=>{const _=Ta(N),P=f.get(_);!_||!P||!Za(N)||!Za(P)||!Yb(N)||!ix({authenticatedUserId:e,localRecord:P})||Ld({authenticatedUserId:e,cloudRecord:N,localRecord:P,privateOwnerScoped:i})||h.set(_,N)});const b=new Map(p.map(N=>[N.id,N])),v=new Set(m.filter(N=>{const _=Ta(N),P=b.get(_);return _&&l.has(_)&&!Za(N)&&!FV.has(P?.reason)}).map(Ta)),S=new Map(r.map(N=>[Ta(N),N]).filter(([N])=>N)),C=new Set(o.map(Ta).filter(Boolean)),I=[],A=new Map,k=new Map,E=o.map(N=>{const _=Ta(N),P=S.get(_),V=Tn(N),L=h.get(V);if(L){const B=P?QV({authenticatedUserId:e,cloudRecord:P,localRecord:N,parentListId:V,privateOwnerScoped:i}):null,re=B?"":ZV({authenticatedUserId:e,cloudRecord:P,localRecord:N,parentListId:V,privateOwnerScoped:i}),Z=B||eH({fallbackReason:re,localRecord:N}),D=B?P:L;return I.push({...Z,cloudParentId:B?Tn(P):V,id:_,localParentId:V}),$y({cloudRecord:D,decision:Z,decisionReason:Z.reason,entityType:"product",localRecord:N})}if(!P)return I.push({action:"preserve-local-only",id:_,reason:"local-only-record"}),N;const z=IP({authenticatedUserId:e,availableParentIds:v,cloudRecord:P,entityType:"product",explicitMoveProductIds:c,localRecord:N,privateOwnerScoped:i});return I.push({...z,cloudParentId:Tn(P),id:_,localParentId:Tn(N)}),z.action!=="apply-cloud"?N:(A.set(_,Tn(P)),z.reason==="authoritative-cloud-restore"&&k.set(_,{ownerId:$i(P),parentId:Tn(P),restoredAt:z.restoredAt,restoredBy:z.restoredBy,revision:z.cloudRevision}),$y({cloudRecord:P,decision:z,decisionReason:z.reason,entityType:"product",localRecord:N}))}),y=E.length;return AP({authenticatedUserId:e,availableParentIds:v,cloudRecords:r,entityType:"product",localIds:C,privateOwnerScoped:i,records:E,decisions:I}
16),E.slice(y).forEach(N=>{Za(N)||A.set(Ta(N),Tn(N))}),{changed:!PP(s,m)||!PP(o,E),expectedCloudParentByProductId:A,expectedCloudRestoreByProductId:k,listDecisions:p,lists:m,localHadRecords:s.length>0||o.length>0,productDecisions:I,products:E,protectedListCount:p.filter(XV).length,protectedProductCount:I.filter(JV).length,reviewRequiredListCount:p.filter(ku).length,reviewRequiredProductCount:I.filter(ku).length,reviewRequiredRecordCount:p.filter(ku).length+I.filter(ku).length,tombstoneProtectedCount:p.filter(ww).length+I.filter(ww).length,writesPerformed:0}},rH=({expectedCloudParentByProductId:e=new Map,expectedCloudRestoreByProductId:t=new Map,snapshot:r={}}={})=>{const a=new Set((r.lists||[]).filter(i=>!Za(i)).map(Ta).filter(Boolean)),s=Array.isArray(r.products)?r.products:[],o=new Map(s.map(i=>[Ta(i),i]).filter(([i])=>i));for(const[i,c]of e.entries()){const l=o.get(i);if(!l||Tn(l)!==c||!a.has(c))return!1}for(const[i,c]of t.entries()){const l=s.filter(p=>Ta(p)===i),u=l[0];if(l.length!==1||Za(u)||$i(u)!==c.ownerId||Tn(u)!==c.parentId||Qn(u.syncRevision??u.revision)!==c.revision||String(u.cloudRestoredAt||"")!==String(c.restoredAt||"")||String(u.cloudRestoredBy||"")!==String(c.restoredBy||""))return!1}return!0},nH=({expectedAccountScopeId:e,expectedGeneration:t,getAccountScopeId:r,getGeneration:a})=>uo(r?.())===uo(e)&&String(a?.()||"")===String(t||""),aH=(e,t)=>{try{e?.(t)}catch{}return t},sH=(e={},t="")=>!!(t&&e?.settled===!0&&e?.foregroundReady===!0&&String(e.sessionKey||"")===String(t)),oH=({applyLiveSnapshot:e,authenticatedUserId:t,cloudSnapshot:r,expectedAccountScopeId:a,expectedGeneration:s,explicitLocalMoveProductIds:o=[],getAccountScopeId:i,getGeneration:c,onPhase:l=()=>{},onTransactionDiagnostic:u=()=>{},persistSnapshot:p,privateOwnerScoped:m=!1,readLocalSnapshot:f,resolveExplicitLocalMoveProductIds:h=()=>o}={})=>{if(typeof e!="function"||typeof i!="function"||typeof c!="function"||typeof p!="function"||typeof f!="function")throw new TypeError("Account hydration transaction is not configured.");const b=[];let v=null,S=!1,C=!1,I=!1,A=!1;const k=L=>{const z=nH({expectedAccountScopeId:a,expectedGeneration:s,getAccountScopeId:i,getGeneration:c});return b.push({checkpoint:L,valid:z}),z},E=L=>aH(u,{terminalReason:L,mergeResultChanged:v?!!v.changed:null,persistenceRequired:!!v?.changed,persistenceStarted:S,persistenceVerified:C,verifiedHydratedSnapshotApplied:A,unchangedLocalSnapshotReapplied:I,foregroundEnabled:!1,generationValidation:[...b],writesPerformed:0});if(!k("before-local-snapshot-read"))return{cancelled:!0,reason:"account-generation-mismatch",transactionDiagnostic:E("superseded-generation"),writesPerformed:0};const y=f();if(!k("after-local-snapshot-read"))return{cancelled:!0,reason:"account-generation-mismatch",transactionDiagnostic:E("superseded-generation"),writesPerformed:0};if(v=tH({authenticatedUserId:t,cloudLists:r?.lists||[],cloudProducts:r?.products||[],explicitLocalMoveProductIds:h(y)||[],localLists:y?.lists||[],localProducts:y?.products||[],privateOwnerScoped:m}),l("hydration-gate-evaluated",{localSnapshot:y,mergeResult:v}),!v.changed){try{e(y,v),I=!0}catch(z){throw E("live-state-application-failed"),z}l("unchanged-local-snapshot-reapplied",{mergeResult:v,snapshot:y});const L=E("unchanged-local-snapshot");return{applied:!1,mergeResult:v,snapshot:y,settled:!0,terminalReason:L.terminalReason,transactionDiagnostic:L,writesPerformed:0}}if(!k("after-merge")){const L=E("superseded-generation");return{cancelled:!0,mergeResult:v,reason:"account-generation-mismatch",transactionDiagnostic:L,writesPerformed:0}}const N={...y,lists:v.lists,products:v.products};l("local-persistence-started",{mergeResult:v,snapshot:N}),S=!0;let _;try{_=p({localSnapshot:y,mergeResult:v,snapshot:N,useCloudAncillaryState:!v.localHadRecords,cloudSnapshot:r})}catch(L){throw E("persistence-failed"),L}const P=_?.verifiedSnapshot;if(!P||!rH({expectedCloudParentByProductId:v.expectedCloudParentByProductId,expectedCloudRestoreByProductId:v.expectedCloudRestoreByProductId,snapshot:P}))throw _?.rollback?.(),E("verification-failed"),new Error("Account hydration persistence verification failed.");
16if(C=!0,l("local-persistence-verified",{mergeResult:v,snapshot:P}),l("verified-snapshot-reread",{mergeResult:v,snapshot:P}),!k("after-persistence-verification")){_?.rollback?.();const L=E("superseded-generation");return{cancelled:!0,mergeResult:v,reason:"account-generation-mismatch",transactionDiagnostic:L,writesPerformed:0}}try{e(P,v),A=!0}catch(L){throw _?.rollback?.(),E("live-state-application-failed"),L}l("verified-hydrated-snapshot-applied",{mergeResult:v,snapshot:P});const V=E("changed-and-persisted");return{applied:!0,mergeResult:v,safetySnapshotSaved:!!_.safetySnapshotSaved,settled:!0,snapshot:P,terminalReason:V.terminalReason,transactionDiagnostic:V,writesPerformed:0}},iH="fnv1a32:79ab3678",kc=Object.freeze({image_background_color:"#fafafa",price:"£12.10",price_amount:12.1}),im=Object.freeze({imageBackgroundColor:"#fbfbfa",price:"£12.00",priceAmount:12}),cH="mixed-revision-active-conflict",uR="missing-opening-revision",_P=Object.freeze(["image_background_color","price","price_amount"]),lH=new Set(["listId","list_id"]),dH=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,up=e=>String(e??"").trim(),uH=e=>!!e&&typeof e=="object"&&!Array.isArray(e),Nu=e=>up(e?.id),ju=(e={})=>up(e.userId||e.user_id),ab=(e={})=>up(e.listId||e.list_id),zy=(e={})=>Br(e.syncRevision??e.revision),pH=e=>dH.test(up(e)),Oh=(e={})=>!!(e.collaborationId||e.collaboration_id||e.collaboratorId||e.collaborator_id||e.sharedBoardId||e.shared_board_id||e.isCollaborative||e.isSharedProjection),pR=(e={})=>!!(e.deleted_at||e.deletedAt||e.cloudDeletedAt||e.syncSuppressed||e.archived_at||e.archivedAt||e.isArchived),EP=(e={})=>!pR(e)&&String(e.status||"active").trim().toLowerCase()==="active",kP=(e={})=>!pR(e),mR=(e={})=>uH(e.syncConflictPatch)?e.syncConflictPatch:null,fR=(e={})=>mR(e)?Object.keys(e.syncConflictPatch).sort():[],mH=(e={})=>{const t=mR(e),r=fR(e);return t!==null&&r.length===_P.length&&r.every((a,s)=>a===_P[s])&&t.price===kc.price&&t.price_amount===kc.price_amount&&t.image_background_color===kc.image_background_color},fH=(e={})=>e.price===kc.price&&e.priceAmount===kc.price_amount&&e.imageBackgroundColor===kc.image_background_color,hH=(e={},t={})=>({...e,imageBackgroundColor:im.imageBackgroundColor,image_background_color:im.imageBackgroundColor,listId:ab(e),list_id:ab(e),price:im.price,priceAmount:im.priceAmount,price_amount:im.priceAmount,revision:1,syncRevision:1,userId:ju(t),user_id:ju(t)}),lx=(e={})=>oo(Nu(e))===iH,gH=({accountScopedStoreIsReady:e=!1,latestProductEditorRecord:t=null,productEditHasUnsavedChanges:r=!1,productEditorSession:a=null,signedInCloudWriteThroughEnabled:s=!1,submissionReason:o=""}={})=>{const i=up(a?.productId);return!!(i&&t&&Nu(t)===i&&!r&&s&&e&&lx(t)&&o===uR)},bH=({authenticatedUserId:e="",cloudParent:t=null,cloudRecord:r=null,explicitMovePending:a=!1,generationIsCurrent:s=!1,localParent:o=null,localRecord:i=null,privateOwnerScoped:c=!1,submissionReason:l=""}={})=>{const u=[],p=up(e),m=Nu(i),f=Nu(r),h=ab(i),b=ab(r),v=ju(i),S=ju(r);l!==uR&&u.push("editor-not-blocked-by-missing-opening-revision"),(!m||m!==f||!lx(i))&&u.push("record-not-allowlisted"),zy(i)!==null&&u.push("local-revision-not-missing"),zy(r)!==1&&u.push("cloud-revision-not-one"),mH(i)||u.push("patch-evidence-changed"),fH(i)||u.push("local-pending-values-changed"),(String(i?.syncConflict||"").trim()!==cH||!Number.isFinite(Date.parse(i?.syncConflictAt||"")))&&u.push("historical-conflict-metadata-missing"),i?.syncPendingCloudWrite===!0&&u.push("pending-cloud-write"),(a||fR(i).some(E=>lH.has(E)))&&u.push("pending-or-explicit-move"),s||u.push("account-generation-superseded"),(!c||!pH(p))&&u.push("private-owner-scope-unproven"),(v!==p||S!==p||Oh(i)||Oh(r))&&u.push("product-owner-mismatch-or-shared"),(!EP(i)||!EP(r))&&u.push("product-inactive-or-tombstoned"),(!h||h!==b||Nu(o)!==h||Nu(t)!==b)&&u.push("parent-mismatch"),(!kP(o)||!kP(t))&&u.push("parent-missing-inactive-or-tombstoned"),(ju(o)!==p||ju(t)!==p||o?.isPublic!==!1||t?.isPublic!==!1||Oh(o)||Oh(t))&&u.push("parent-owner-mismatch-or-shared");let C=[];if(i&&r&&zy(r)===1)try{C=Ll({cloudRecord:r,entityType:"product",localRecord:hH(i,r)}).map(E=>E.field)}catch{u.push("canonical-comparison-failed")}C.length&&u.push("reconstructed-base-does-not-match-cloud");const I=[...new Set(u)];if(I.length)return{eligible:!1,reason:I[0],reasons:I,semanticDifferenceFields:[...new Set(C)].sort()};const A={...r};Number.isFinite(Number(i.sortOrder))&&(A.sortOrder=Number(i.sortOrder));
16const k={...A,imageBackgroundColor:kc.image_background_color,price:kc.price,priceAmount:kc.price_amount};return{cloudOpeningSnapshot:A,eligible:!0,formProduct:k,reason:"verified-missing-opening-revision-recovery",reasons:[],semanticDifferenceFields:[]}},NP=e=>String(e?.id||"").trim(),jP=e=>Qn(e?.syncRevision??e?.revision),RP=(e=[],t=[])=>{const r=new Map((Array.isArray(e)?e:[]).map(o=>[NP(o),o])),a=[];return{records:(Array.isArray(t)?t:[]).map(o=>{const i=NP(o),c=i?r.get(i):null;if(!c)return o;const l=jP(c),u=jP(o);return l!==null&&(u===null||u<l)?(a.push(i),c):o}),regressedIds:a}},to=(e={})=>e.syncSuppressed===!0||!!e.cloudDeletedAt,vH=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,yH=(e={},t="",r="")=>{const a=String(t||"").trim(),s=String(r||"").trim();return vH.test(a)&&a===s?{...e,userId:a}:e},SH=(e,t={},{preserveConflictMetadata:r=!1}={})=>({...e,...r?{}:{syncConflict:"",syncConflictAt:""},syncConflictPatch:{...e.syncPendingCloudWrite||e.syncConflict?e.syncConflictPatch:{},...t},syncPendingCloudWrite:!0,syncPendingWriteRevision:e.syncPendingWriteRevision||e.syncRevision||e.revision||null}),wH=(e,t,{serverRecord:r}={})=>r&&!aC(r,e.syncConflictPatch||{})?e:{...e,...t,syncConflict:"",syncConflictAt:"",syncConflictPatch:void 0,syncPendingCloudWrite:!1,syncPendingWriteRevision:void 0},CH=({attemptedPatch:e={},conflictAt:t=new Date().toISOString(),latestRecord:r=null,product:a,reason:s}={})=>{const o=lp(a,r||{},{isPlaceholder:Vn,preferCurrentImage:!0});return{...a,...r||{},...o,syncConflict:s||"changed-or-unavailable",syncConflictAt:t,syncConflictPatch:{...e,...a.syncConflictPatch||{}},syncPendingCloudWrite:!1}},zu=e=>{const t=Number(e);return Number.isInteger(t)&&t>0?t:null},Cw=(e,t)=>JSON.stringify(Pl(e))===JSON.stringify(Pl(t)),xH=(e=[],t="",r={})=>{const a=String(t||"").trim(),s=zu(r?.revision),o=String(r?.deletedAt||"").trim();if(!a||!s||!o)return Array.isArray(e)?e:[];let i=0;const c=(Array.isArray(e)?e:[]).map(l=>String(l?.id||"")!==a?l:(i+=1,{...l,cloudDeletedAt:o,cloudDeletionId:String(r?.deletionId||""),cloudDeletionReason:"user_trash",cloudPurgeAfter:"",cloudRestoredAt:"",cloudRestoredBy:"",syncConflict:"",syncConflictAt:"",syncConflictPatch:void 0,syncPendingCloudWrite:!1,syncRevision:s,syncSuppressed:!0}));return i===1?c:Array.isArray(e)?e:[]},IH=({acknowledgedProduct:e,currentProducts:t=[],expectedRevision:r,listId:a,ownerId:s,productId:o}={})=>{const i=String(o||"").trim(),c=String(s||"").trim(),l=String(a||"").trim(),u=zu(e?.syncRevision??e?.revision),p=(Array.isArray(t)?t:[]).filter(b=>String(b?.id||"")===i);if(!i||!c||!l||p.length!==1||String(e?.id||"")!==i||String(e?.userId??e?.user_id??"")!==c||String(e?.listId??e?.list_id??"")!==l||String(e?.status||"").toLowerCase()!=="active"||to(e)||!u)return{ok:!1,outcome:"identity-mismatch",products:t};const m=p[0],f=zu(m?.syncRevision??m?.revision);if(String(m?.userId??m?.user_id??"")!==c||String(m?.listId??m?.list_id??"")!==l)return{ok:!1,outcome:"identity-mismatch",products:t};if(to(m)){if(f!==zu(r)||u<f||u===f&&!Cw(m,e))return{ok:!1,outcome:"revision-mismatch",products:t}}else if(f!==u||!Cw(m,e))return{ok:!1,outcome:"canonical-mismatch",products:t};const h=t.map(b=>String(b?.id||"")===i?e:b);return{ok:!0,outcome:to(m)?"applied":"equivalent",product:e,products:h}},AH=({confirmation:e,mode:t,storage:r}={})=>{const a=r.readProducts(t),s=IH({...e,currentProducts:a});if(!s.ok)return s;r.saveProducts(s.products,t,{trackPriceHistory:!1});const o=r.readProducts(t),i=o.filter(l=>String(l?.id||"")===String(e?.productId||"")),c=i[0]||null;return i.length!==1||to(c)||zu(c?.syncRevision??c?.revision)!==zu(e?.acknowledgedProduct?.syncRevision??e?.acknowledgedProduct?.revision)||String(c?.userId??c?.user_id??"")!==String(e?.ownerId||"")||String(c?.listId??c?.list_id??"")!==String(e?.listId||"")||!Cw(c,e?.acknowledgedProduct)?(r.saveProducts(a,t,{trackPriceHistory:!1}),{ok:!1,outcome:"durable-reread-mismatch"}):{ok:!0,outcome:s.outcome,product:c,products:o}},PH=({acknowledgement:e,authenticatedOwnerId:t,currentDefaultList:r,fallbackDefaultList:a,lists:s,mode:o,pe
16ndingOperation:i,products:c,settings:l,storage:u}={})=>{const p=String(u?.getAccountScope?.()||"").trim(),m=u?.readPendingBoardTrashOperation?.(i?.listId);if(!p||p!==String(t||"").trim())return{ok:!1,outcome:"account-scope-mismatch"};const f=!!(m&&m.ownerId===i?.ownerId&&m.listId===i?.listId&&m.expectedRevision===i?.expectedRevision&&m.operationId===i?.operationId),h=!!(m&&!f),b=GD({acknowledgement:e,authenticatedOwnerId:t,currentDefaultList:r,fallbackDefaultList:a,lists:s,pendingOperation:i,products:c});if(!b.ok)return b;const v=h?[{error:new Error("A different pending deletion operation is stored for this board."),label:"pending-operation-read"}]:[],S=(A,k)=>{try{k()}catch(E){v.push({error:E,label:A})}};let C=!1;S("lists",()=>{u.saveLists(b.lists,o);const A=u.readLists(o).filter(E=>String(E?.id||"")===String(i.listId||"")&&String(E?.userId??E?.user_id??"").toLowerCase()===String(t||"").toLowerCase()),k=A[0]||null;if(A.length!==1||k?.syncSuppressed!==!0||String(k?.cloudDeletionId||"")!==String(b.deletionId||"")||Number(k?.syncRevision)!==Number(b.revision))throw new Error("Confirmed board deletion could not be reread from local storage.");C=!0}),S("products",()=>u.saveProducts(b.products,o,{trackPriceHistory:!1}));const I=b.defaultListChanged?{...l||{},defaultList:b.defaultList}:l||{};return b.defaultListChanged&&S("settings",()=>u.saveSettings(I)),C&&f&&S("pending-operation",()=>{if(!u.clearPendingBoardTrashOperation({listId:i.listId,operationId:i.operationId,ownerId:t}))throw new Error("Confirmed board deletion pending metadata was not cleared.")}),{...b,localPersistenceFailed:v.length>0,nextSettings:I,pendingOperationRetained:!C||h,persistenceErrors:v}};function _H({accountScopeId:e="",dashboardList:t,defaultModalList:r,storage:a}){const[s]=d.useState(()=>{const G=a.setAccountScope?.(e)||"",se=G?a.modes.personal:a.readMode(),le=a.readLists(se);return{accountLocalDataNotice:a.getUnscopedPersonalDataNotice?.()||{visible:!1},accountScopeId:G,lists:le,manualStores:a.readManualStores(),mode:se,products:a.readProducts(se),recoveryNotice:a.readRecoveryNotice(),settings:a.readSettings(),activeList:a.resolveSavedActiveList(se,le)}}),[o,i]=d.useState(s.accountScopeId),[c,l]=d.useState(s.accountLocalDataNotice),[u,p]=d.useState(s.mode),[m,f]=d.useState(s.products),[h,b]=d.useState(s.lists),[v,S]=d.useState(s.manualStores),[C,I]=d.useState(s.settings),[A,k]=d.useState(s.recoveryNotice),[E,y]=d.useState(s.activeList),[N,_]=d.useState(a.readGridPreference),[P,V]=d.useState(a.readBoardMode),L=d.useRef(s.accountScopeId),z=d.useRef(""),B=d.useRef(new Set),re=d.useRef(s.lists),Z=d.useRef(s.mode),D=d.useRef(null),K=d.useRef({lists:null,products:null,stores:null}),ee=d.useRef(s.products),J=d.useRef(s.settings);re.current=h,Z.current=u,ee.current=m,J.current=C;const fe=d.useMemo(()=>h.filter(G=>!to(G)),[h]),De=d.useMemo(()=>new Set(h.filter(to).map(G=>String(G?.id||"")).filter(Boolean)),[h]),Be=d.useMemo(()=>m.filter(G=>!to(G)&&!De.has(String(G?.listId||""))),[m,De]),Fe=d.useMemo(()=>m.filter(G=>to(G)&&!!G?.cloudDeletedAt&&!De.has(String(G?.listId||""))),[m,De]),ke=d.useMemo(()=>fe.map(G=>G.name),[fe]),We=d.useMemo(()=>fe.find(G=>G.name===E)||null,[E,fe]),de=d.useMemo(()=>E===t?Be:Be.filter(G=>{const se=String(G?.listId||"").trim();if(se)return se===We?.id;const le=ro(h,G.category||G.listName);return!!(le&&le.id===We?.id)}),[E,We,Be,t,h]),ye=E===t&&ke.includes(C.defaultList)?C.defaultList:E===t?r:E,ge=G=>{try{G();const se=a.readRecoveryNotice();se&&k(se)}catch(se){k(se.message||a.readRecoveryNotice()||"Local changes may not persist in this browser.")}};d.useEffect(()=>{if(K.current.products===m){K.current.products=null;return}const G=D.current;G&&u===a.modes.personal&&(D.current=null,m!==G)||ge(()=>a.saveProducts(m,u))},[o,u,m,a]),d.useEffect(()=>{if(K.current.lists===h){K.current.lists=null;return}ge(()=>a.saveLists(h,u))},[o,h,u,a]),d.useEffect(()=>{if(K.current.stores===v){K.current.stores=null;return}ge(()=>a.saveManualStores(v))},[o,v,a]),d.useEffect(()=>{ge(()=>a.saveMode(u))},[o,u,a]),d.useEffect(()=>{ge(()=>a.saveGridPreference(N))},[o,N,a]),d.useEffect(()=>{ge(()=>a.saveBoardMode(P))},[o,P,a]),d.useEffect(()=>{ge(()=>a.saveSettings(C))},[o,C,a]),d.useEffect(()=>
16{const G=a.setAccountScope?.(e)||"";if(G===o){L.current=G,l(a.getUnscopedPersonalDataNotice?.()||{visible:!1});return}const se=G?a.modes.personal:a.readMode(),le=a.readLists(se);L.current=G,z.current="",B.current.clear(),i(G),p(se),f(a.readProducts(se)),b(le),S(a.readManualStores()),I(a.readSettings()),_(a.readGridPreference()),V(a.readBoardMode()),y(a.resolveSavedActiveList(se,le)),k(a.readRecoveryNotice()),l(a.getUnscopedPersonalDataNotice?.()||{visible:!1})},[e,o,a]),d.useEffect(()=>{if(typeof window>"u")return;const G=(Ne,be)=>{try{return JSON.stringify(Ne)===JSON.stringify(be)}catch{return!1}},se=a.storageKeys||{},le=new Set([se.products,se.demoProducts,se.lists,se.demoLists,se.stores,se.mode].filter(Boolean));if(!le.size)return;const ue=Ne=>{if(Ne.storageArea!==window.localStorage||!le.has(Ne.key))return;const be=a.readMode(),Te=a.readManualStores(),Ve=a.readRecoveryNotice(),at=RP(re.current,a.readLists(be)),yt=RP(ee.current,a.readProducts(be));at.regressedIds.length&&ge(()=>a.saveLists(at.records,be)),yt.regressedIds.length&&ge(()=>a.saveProducts(yt.records,be,{trackPriceHistory:!1}));const tt=at.records,He=yt.records;p(Ge=>Ge===be?Ge:be),f(Ge=>G(Ge,He)?Ge:(K.current.products=He,He)),b(Ge=>G(Ge,tt)?Ge:(K.current.lists=tt,tt)),S(Ge=>G(Ge,Te)?Ge:(K.current.stores=Te,Te)),y(Ge=>Ge===t||tt.some(Xe=>Xe.name===Ge)?Ge:a.resolveSavedActiveList(be,tt)),k(Ge=>Ge===Ve?Ge:Ve)};return window.addEventListener("storage",ue),()=>{window.removeEventListener("storage",ue)}},[o,t,a]),d.useEffect(()=>{f(G=>{let se=!1;const le=G.map(ue=>{const Ne=b1({lists:h,product:ue}),be=Ne.matchingList;return Ac()&&Ec({enabled:!0,listsHydratedBeforeProductNormalization:Ne.sourceParentExists,normalizationDecision:Ne.normalizationDecision,parentExists:Ne.parentExists,parentId:Ne.parentId,phase:"list-category-name-fallback-normalization",productId:ue.id,sourceParentExists:Ne.sourceParentExists}),!be||ue.listId===be.id&&ue.category===be.name&&ue.listName===be.name?ue:(se=!0,{...ue,category:be.name,listName:be.name,listId:be.id})});return se?le:G})},[h]),d.useEffect(()=>{E!==t&&!We&&y(t)},[E,We,t]);const ze=G=>{const se=a.createList(h,G,{authenticatedOwnerId:L.current}),le=new Set(h.map(Ne=>Ne.id)),ue=se.lists.find(Ne=>!le.has(Ne.id))||null;return b(se.lists),y(se.activeList),{...se,createdList:ue}},W=(G,se={})=>{b(le=>le.map(ue=>ue.id===G?{...ue,syncConflict:"",syncConflictAt:"",syncConflictPatch:se,syncPendingCloudWrite:!0}:ue))},Le=(G,se)=>{!G||!se||b(le=>le.map(ue=>ue.id===G?{...ue,...se,syncConflict:"",syncConflictAt:"",syncConflictPatch:void 0,syncPendingCloudWrite:!1}:ue))},et=({attemptedPatch:G={},latestRecord:se=null,listId:le,reason:ue})=>{const Ne=h.find(be=>be.id===le)||null;b(be=>be.map(Te=>Te.id===le?{...Te,...se||{},syncConflict:ue||"changed-or-unavailable",syncConflictAt:new Date().toISOString(),syncConflictPatch:G,syncPendingCloudWrite:!1}:Te)),se?.name&&Ne?.name&&E===Ne.name&&y(se.name)},pt=(G,se)=>{const le=h.find(be=>be.id===G)||null,ue=a.updateList(h,m,G,se,{authenticatedOwnerId:L.current}),Ne=ue.lists.find(be=>be.id===G)||null;return b(ue.lists),f(ue.products),y(ue.activeList),{...ue,previousList:le,updatedList:Ne}},$t=(G,se)=>{const le=a.deleteList(h,m,G,se);b(le.lists),f(le.products),y(le.activeList)},pe=(G,se)=>{const le=a.reorderLists(h,G,se),ue=le.find(Ne=>Ne.id===G)||null;return b(le),{lists:le,updatedList:ue}},Tt=()=>{const G=a.modes.personal,se=a.readLists(G);p(G),f(a.readProducts(G)),b(se),y(a.resolveSavedActiveList(G,se))},F=()=>{const G=a.resetDemo();return u===a.modes.demo&&(f(G.products),b(G.lists),y(t)),G},te=()=>{const G=a.resetPersonal();return u===a.modes.personal&&(f(G.products),b(G.lists),S(G.manualStores),y(t)),G},me=()=>a.exportBackup(),ie=G=>a.importBackup.validate(G),Ae=()=>{a.clearRecoveryNotice(),k("")},Re=(G,se)=>{const le=se==="merge"?a.importBackup.merge(G):a.importBackup.replace(G);return p(a.modes.personal),f(le.products),b(le.lists),S(le.manualStores||a.readManualStores()),y(le.activeList||a.resolveSavedActiveList(a.modes.personal,le.lists)||t),I(a.readSettings()),_(a.readGridPreference()),V(a.readBoardMode()),k(a.readRecoveryNotice()
16),le},ne=d.useCallback((G={})=>{p(a.modes.personal),b(G.lists||[]),f(G.products||[]),S(G.stores||[]),I(G.settings||a.readSettings()),_(G.gridPreference||a.readGridPreference()),V(G.boardMode||a.readBoardMode()),y(a.resolveSavedActiveList(a.modes.personal,G.lists||[])||t),k(a.readRecoveryNotice()),l(a.getUnscopedPersonalDataNotice?.()||{visible:!1})},[t,a]),ht=d.useCallback(({accountScopeId:G,authenticatedUserId:se,currentLiveSnapshot:le,generation:ue,isGenerationCurrent:Ne,uploadedLists:be=[],uploadedLocalBackup:Te,uploadedProducts:Ve=[]}={})=>{const at=String(ue||""),yt=String(G||"").trim(),tt=String(se||"").trim(),He=()=>L.current===yt&&Ne?.()===!0;if(!at||!yt||tt!==yt||typeof Ne!="function"||!He())return{cancelled:!0,reason:"account-generation-mismatch",writesPerformed:0};const Ge=a.readAccountHydrationSnapshot(yt);if(!Ih({currentSnapshot:Ge,uploadedLists:be,uploadedLocalBackup:Te,uploadedProducts:Ve})||!Ih({currentSnapshot:le,uploadedLists:be,uploadedLocalBackup:Te,uploadedProducts:Ve}))return{cancelled:!0,reason:"bootstrap-local-snapshot-changed",writesPerformed:0};const Xe=d1({currentSnapshot:Ge,uploadedLists:be,uploadedProducts:Ve}),Dt=a.commitAccountHydrationSnapshot({accountId:yt,expectedCloudParents:Ve.map(jt=>({parentId:String(jt?.listId||jt?.list_id||"").trim(),productId:String(jt?.id||"").trim()})),localSnapshot:Ge,snapshot:Xe,useCloudAncillaryState:!1});if(!He())return Dt.rollback(),{cancelled:!0,reason:"account-generation-mismatch",writesPerformed:0};try{ne(Dt.verifiedSnapshot)}catch(jt){Dt.rollback();try{ne(Ge)}catch{}throw jt}return{prepared:!0,safetySnapshotSaved:Dt.safetySnapshotSaved,snapshot:Dt.verifiedSnapshot,writesPerformed:0}},[ne,a]),kt=d.useCallback(({accountScopeId:G,authenticatedUserId:se,backup:le,currentLiveSnapshot:ue,generation:Ne,isGenerationCurrent:be,privateOwnerScoped:Te=!1,uploadedLists:Ve=[],uploadedLocalBackup:at,uploadedProducts:yt=[]}={})=>{const tt=String(Ne||""),He=String(G||"").trim(),Ge=String(se||"").trim(),Xe=()=>L.current===He&&be?.()===!0;if(!tt||!He||Ge!==He||Te!==!0||typeof be!="function"||!Xe())return{cancelled:!0,reason:"account-generation-mismatch",writesPerformed:0};const Dt=a.importBackup.validate(le,{authoritativeCloudOwnerScoped:!0});if(xN({authenticatedUserId:Ge,authoritativeBackup:Dt,privateOwnerScoped:!0,uploadedLists:Ve,uploadedProducts:yt}),!Xe())return{cancelled:!0,reason:"account-generation-mismatch",writesPerformed:0};const jt=a.readAccountHydrationSnapshot(He);if(!Ih({currentSnapshot:jt,uploadedLists:Ve,uploadedLocalBackup:at,uploadedProducts:yt})||!Ih({currentSnapshot:ue,uploadedLists:Ve,uploadedLocalBackup:at,uploadedProducts:yt}))return{cancelled:!0,reason:"bootstrap-local-snapshot-changed",writesPerformed:0};const Zt=yt.map(Or=>({parentId:String(Or?.listId||Or?.list_id||"").trim(),productId:String(Or?.id||"").trim()})),xt=a.commitAccountHydrationSnapshot({accountId:He,cloudSnapshot:Dt,expectedCloudParents:Zt,localSnapshot:jt,snapshot:{...jt,lists:Dt.lists,products:Dt.products},useCloudAncillaryState:!1});if(!Xe())return xt.rollback(),{cancelled:!0,reason:"account-generation-mismatch",writesPerformed:0};const Gt=xt.verifiedSnapshot;
16try{ne(Gt)}catch(Or){xt.rollback();try{ne(jt)}catch{}throw Or}return z.current=tt,{safetySnapshotSaved:xt.safetySnapshotSaved,settled:!0,snapshot:Gt,writesPerformed:0}},[ne,a]),Ee=d.useCallback(({accountScopeId:G,authenticatedUserId:se,backup:le,generation:ue,isGenerationCurrent:Ne,privateOwnerScoped:be=!1}={})=>{const Te=String(ue||""),Ve=String(G||"").trim();if(!Te||!Ve||typeof Ne!="function")return{cancelled:!0,reason:"account-generation-mismatch",writesPerformed:0};if(z.current===Te&&L.current===Ve)return{alreadyApplied:!0,settled:!0,snapshot:a.readAccountHydrationSnapshot(Ve),writesPerformed:0};const at=a.importBackup.validate(le,{authoritativeCloudOwnerScoped:be===!0});let yt=null;const He=oH({applyLiveSnapshot:Ge=>{p(a.modes.personal),b(Ge.lists||[]),f(Ge.products||[]),S(Ge.stores||[]),I(Ge.settings||a.readSettings()),_(Ge.gridPreference||a.readGridPreference()),V(Ge.boardMode||a.readBoardMode()),y(a.resolveSavedActiveList(a.modes.personal,Ge.lists||[])||t),k(a.readRecoveryNotice()),l(a.getUnscopedPersonalDataNotice?.()||{visible:!1})},authenticatedUserId:se,cloudSnapshot:at,expectedAccountScopeId:Ve,expectedGeneration:Te,getAccountScopeId:()=>L.current,getGeneration:()=>Ne()?Te:"superseded",onPhase:(Ge,{localSnapshot:Xe=null,mergeResult:Dt=null,snapshot:jt=null}={})=>{if(!Ac())return;if(Ge==="hydration-gate-evaluated"&&Xe&&Dt){const x=(Xe.products||[]).filter($=>B.current.has($.id)).map($=>$.id);try{(Dt.listDecisions||[]).forEach($=>{tp({listId:$.id,phase:"hydration-merge-evidence"})}),yt=UV({authenticatedUserId:se,cloudSnapshot:at,explicitLocalMoveProductIds:x,listNormalizationProvenance:pF(),localSnapshot:Xe,mergeResult:Dt,privateOwnerScoped:be===!0})}catch{yt=null}}const Zt=jt||Xe||{},xt=Zt.lists||[],Gt=Zt.products||[],Or=new Set(xt.map(x=>String(x?.id||"").trim()).filter(Boolean)),Yt=new Map(Gt.map(x=>[String(x?.id||"").trim(),x]).filter(([x])=>x)),er=Ge==="local-persistence-started"?"write-started":Ge==="local-persistence-verified"?"write-verified":Ge==="verified-snapshot-reread"?"verified-reread":Ge==="unchanged-local-snapshot-reapplied"?"unchanged-local-snapshot-reapplied":Ge==="verified-hydrated-snapshot-applied"?"verified-hydrated-snapshot-applied":"none";(Dt?.productDecisions||[]).forEach(x=>{const $=Yt.get(String(x.id||""))||null,O=String($?.listId||(x.action==="apply-cloud"?x.cloudParentId:x.localParentId)||"").trim();Ec({enabled:!0,listsHydratedBeforeProductNormalization:!0,normalizationDecision:"preserved-existing",parentExists:!!(O&&Or.has(O)),parentId:O,phase:Ge,productId:x.id,sourceParentExists:!!(O&&Or.has(O)),storageEvidence:er})})},onTransactionDiagnostic:Ge=>HN({merge:yt,transaction:Ge,writesPerformed:0}),persistSnapshot:({cloudSnapshot:Ge,localSnapshot:Xe,mergeResult:Dt,snapshot:jt,useCloudAncillaryState:Zt})=>a.commitAccountHydrationSnapshot({accountId:Ve,cloudSnapshot:Ge,expectedCloudParents:[...Dt.expectedCloudParentByProductId].map(([xt,Gt])=>({parentId:Gt,productId:xt})),localSnapshot:Xe,snapshot:jt,useCloudAncillaryState:Zt}),privateOwnerScoped:be===!0,readLocalSnapshot:()=>a.readAccountHydrationSnapshot(Ve),resolveExplicitLocalMoveProductIds:Ge=>(Ge.products||[]).filter(Xe=>B.current.has(Xe.id)).map(Xe=>Xe.id)});return He?.settled&&!He?.cancelled&&(z.current=Te),He},[t,a]),xe=d.useCallback(({accountScopeId:G,apply:se=!1,authenticatedUserId:le,backup:ue,generation:Ne,isGenerationCurrent:be,privateOwnerScoped:Te=!1,rawCloudProductEvidence:Ve=[]}={})=>{const at=String(Ne||""),yt=String(G||"").trim();if(!at||!yt||!ue||typeof be!="function")return{applied:!1,mode:se===!0?"apply":"dry-run",reason:"account-context-not-current",status:"blocked",writesPerformed:0};const tt=a.importBackup.validate(ue,{authoritativeCloudOwnerScoped:Te===!0}),He=tF({accountId:yt,apply:se,authenticatedUserId:le,cloudSnapshot:tt,explicitLocalMoveProductIds:[...B.current],getAccountScopeId:()=>L.current,isSessionCurrent:()=>be()&&L.current===yt,privateOwnerScoped:Te===!0,rawCloudProductEvidence:Ve,storage:a});if(He.applied&&He.snapshot){const Xe=He.snapshot;p(a.modes.personal),b(Xe.lists||[]),f(Xe.products||[]),S(Xe.stores||[]),I(Xe.settings||a.readSettings()),_(Xe.gridPreference||a.readGridPreference()),V(Xe.boardMode||a.readBoardMode()),y(a.resolveSavedActiveList(a.modes.personal,Xe.lists||[])||t),k(a.readRecoveryNotice()
16)}const Ge={...He};return delete Ge.snapshot,Ge},[t,a]),Qe=()=>{l(a.getUnscopedPersonalDataNotice?.()||{visible:!1})},Pe=()=>{const G=a.importUnscopedPersonalDataToAccount?.()||{imported:!1},se=G.snapshot||{},le=a.readMode(),ue=se.lists||a.readLists(le);return p(le),f(se.products||a.readProducts(le)),b(ue),S(se.stores||a.readManualStores()),I(a.readSettings()),_(a.readGridPreference()),V(a.readBoardMode()),y(a.resolveSavedActiveList(le,ue)||t),Qe(),G},Ct=()=>{const G=a.keepUnscopedPersonalDataSeparate?.()||{keptSeparate:!0};return Qe(),G},nr=({lists:G=[],products:se=[]}={})=>se.length?!0:G.some(le=>{const ue=String(le?.name||"").trim(),Ne=String(r).trim();return!(!ue||ue===t||ue===Ne)||!!(le?.description||le?.publicDescription||le?.isPublic||le?.coverImage||le?.imageUrl||le?.budget)}),en=({lists:G=[],products:se=[],requiredProductIds:le=null}={})=>{const ue=G.map(tt=>String(tt?.id||"").trim()).filter(Boolean),Ne=se.map(tt=>String(tt?.id||"").trim()).filter(Boolean),be=new Set(ue),Te=new Set(Ne),Ve=le?new Set(le.map(tt=>String(tt||"").trim()).filter(Boolean)):null,yt=(Ve?se.filter(tt=>Ve.has(String(tt?.id||"").trim())):se).every(tt=>be.has(String(tt?.listId||"").trim()));return ue.length===be.size&&Ne.length===Te.size&&yt},st=({lists:G=[],products:se=[]}={})=>{const le=a.readLists(a.modes.personal),ue=a.readProducts(a.modes.personal);if(nr({lists:le,products:ue}))return{blocked:!0,lists:le,message:"Cloud pull is blocked because this browser already has Personal mode data.",products:ue};if(!en({lists:G,products:se}))return{blocked:!0,lists:le,message:"Cloud pull merge needs review before applying changes.",products:ue};a.saveLists(G,a.modes.personal),a.saveProducts(se,a.modes.personal,{trackPriceHistory:!1}),a.saveMode(a.modes.personal);const Ne=a.readLists(a.modes.personal),be=a.readProducts(a.modes.personal);return en({lists:Ne,products:be})?(p(a.modes.personal),b(Ne),f(be),y(a.resolveSavedActiveList(a.modes.personal,Ne)||t),{blocked:!1,lists:Ne,message:`Pulled ${Ne.length} boards and ${be.length} products from cloud.`,products:be}):(a.saveLists(le,a.modes.personal),a.saveProducts(ue,a.modes.personal,{trackPriceHistory:!1}),{blocked:!0,lists:le,message:"Cloud pull merge needs review before applying changes.",products:ue})},gr=({lists:G=[],products:se=[]}={})=>{const le=a.readLists(a.modes.personal),ue=a.readProducts(a.modes.personal),Ne=new Set(le.map(xt=>String(xt?.id||"")).filter(Boolean)),be=new Set(ue.map(xt=>String(xt?.id||"")).filter(Boolean)),Te=new Set,Ve=new Set,at=[],yt=[];G.forEach(xt=>{const Gt=String(xt?.id||"");!Gt||Ne.has(Gt)||Te.has(Gt)||(Te.add(Gt),at.push(xt))});const tt=new Set([...Ne,...Te]);if(se.forEach(xt=>{const Gt=String(xt?.id||""),Or=String(xt?.listId||"");!Gt||be.has(Gt)||Ve.has(Gt)||!tt.has(Or)||(Ve.add(Gt),yt.push(xt))}),!at.length&&!yt.length)return{blocked:!1,boardCount:0,lists:le,message:"No new cloud boards or products to pull.",productCount:0,products:ue,safetySnapshotSaved:!1};const He=a.saveLocalSafetySnapshot("sync-populated-add-only-pull"),Ge=[...le,...at],Xe=[...ue,...yt],Dt=yt.map(xt=>xt.id);if(!en({lists:Ge,products:Xe,requiredProductIds:Dt}))return{blocked:!0,boardCount:0,lists:le,message:"Cloud pull merge needs review before applying changes.",productCount:0,products:ue,safetySnapshotSaved:!1};a.saveLists(Ge,a.modes.personal),a.saveProducts(Xe,a.modes.personal,{trackPriceHistory:!1}),a.saveMode(a.modes.personal);const jt=a.readLists(a.modes.personal),Zt=a.readProducts(a.modes.personal);return en({lists:jt,products:Zt,requiredProductIds:Dt})?(p(a.modes.personal),b(jt),f(Zt),y(a.resolveSavedActiveList(a.modes.personal,jt)||t),{blocked:!1,boardCount:at.length,lists:jt,message:`Pulled ${at.length} new boards and ${yt.length} new products from cloud.`,productCount:yt.length,products:Zt,safetySnapshotSaved:He}):(a.saveLists(le,a.modes.personal),a.saveProducts(ue,a.modes.personal,{trackPriceHistory:!1}),{blocked:!0,boardCount:0,lists:le,message:"Cloud pull merge needs review before applying changes.",productCount:0,products:ue,safetySnapshotSaved:He})},Xt=({listSuppressions:G=[],lists:se=[],productSuppressions:le=[],products:ue=[]}={})=>{const Ne=a.readLists(a.modes.personal),be=a.readProducts(a.modes.personal),Te=$$({currentLists:Ne,currentProducts:be,incomingLists:se,incomingProducts:ue}),Ve=new Map(G.filter(O=>O?.id).map(O=>[String(O.id),O])),at=new Map(le.filter(O=>O?.id).map(O=>[String(O.id),O]));
16if(!Te.boardCount&&!Te.productCount&&!Ve.size&&!at.size)return{blocked:!1,boardCount:0,lists:Ne,message:"No newer cloud board or product updates to apply.",productCount:0,products:be,safetySnapshotSaved:!1,suppressedBoardCount:0,suppressedProductCount:0};if(!Te.valid)return{blocked:!0,boardCount:0,lists:Ne,message:"Cloud update merge needs review before applying changes.",productCount:0,products:be,safetySnapshotSaved:!1};const yt=(O,q)=>({...O,cloudDeletedAt:q.deletedAt||O.cloudDeletedAt||"",cloudDeletionId:q.deletionId||O.cloudDeletionId||"",cloudUpdatedAt:q.updatedAt||O.cloudUpdatedAt||"",syncConflict:q.requiresReview?q.reason:"",...q.revision?{syncRevision:q.revision}:{},syncSuppressed:!0}),tt=(O,q)=>{const X=yt(O,q);return O.syncSuppressed!==!0||String(O.cloudDeletedAt||"")!==String(X.cloudDeletedAt||"")||String(O.syncConflict||"")!==String(X.syncConflict||"")||Number(O.syncRevision||0)!==Number(X.syncRevision||0)};let He=0,Ge=0;const Xe=Te.lists.map(O=>{const q=String(O?.id||""),X=Ve.get(q);return X?(He+=tt(O,X)?1:0,yt(O,X)):O}),Dt=new Map(Xe.map(O=>[String(O?.id||""),String(O?.name||"").trim()]).filter(([O])=>O)),jt=Te.products.map(O=>{const q=String(O?.id||""),X=at.get(q),Se=X?yt(O,X):O;X&&(Ge+=tt(O,X)?1:0);const he=Dt.get(String(Se?.listId||""));return he?{...Se,category:he,listName:he}:Se}),Zt=Xe.map(O=>String(O?.id||"")).filter(Boolean),xt=jt.map(O=>String(O?.id||"")).filter(Boolean),Gt=jt.every(O=>Dt.has(String(O?.listId||"")));if(new Set(Zt).size!==Zt.length||new Set(xt).size!==xt.length||!Gt)return{blocked:!0,boardCount:0,lists:Ne,message:"Cloud update merge needs review before applying changes.",productCount:0,products:be,safetySnapshotSaved:!1};const Or=Te.boardCount||Te.productCount?a.saveLocalSafetySnapshot("sync-cloud-newer-update-pull"):!1;a.saveLists(Xe,a.modes.personal),a.saveProducts(jt,a.modes.personal,{trackPriceHistory:!1}),a.saveMode(a.modes.personal);const Yt=a.readLists(a.modes.personal),er=a.readProducts(a.modes.personal);p(a.modes.personal),b(Yt),f(er);const x=ro(Ne.filter(O=>!to(O)),E)?.id,$=x?Yt.find(O=>String(O.id||"")===String(x))?.name:"";return y(E===t?t:$||a.resolveSavedActiveList(a.modes.personal,Yt)||t),{blocked:!1,boardCount:Te.boardCount,lists:Yt,message:`Updated ${Te.boardCount} boards and ${Te.productCount} products from cloud.`,productCount:Te.productCount,products:er,safetySnapshotSaved:Or,suppressedBoardCount:He,suppressedProductCount:Ge}},fn=G=>{const se=G.category||G.listName||ye||r,le=String(G.listId||"").trim();let ue=h,Ne=le?ue.find(tt=>String(tt.id||"")===le&&!to(tt))||null:(()=>{const tt=ro(ue,se);return tt&&!to(tt)?tt:null})(),be=null;if(!le&&!Ne&&se){const tt=new Set(ue.map(Ge=>Ge.id)),He=a.createList(ue,{name:se},{authenticatedOwnerId:L.current});ue=He.lists,be=ue.find(Ge=>!tt.has(Ge.id))||null,Ne=be||(()=>{const Ge=ro(ue,He.activeList);return Ge&&!to(Ge)?Ge:null})(),b(ue)}if(!Ne)return{createdList:null,createdProduct:null,list:null,lists:ue,products:m};const Te=Ne?yH({...G,category:Ne.name,listName:Ne.name,listId:Ne.id},L.current,a.getAccountScope?.()):G,Ve=a.addProduct(m,Te),at=new Set(m.map(tt=>tt.id)),yt=Ve.find(tt=>!at.has(tt.id))||null;return f(Ve),{createdList:be,createdProduct:yt,list:Ne,lists:ue,products:Ve}},Ke=({activeListName:G="",lists:se=[],products:le=[]}={})=>{if(!Array.isArray(le)||le.length===0)return{importedProducts:[],lists:a.readLists(a.modes.personal),products:a.readProducts(a.modes.personal)};a.saveLists(se,a.modes.personal);const ue=new Set(le.map(at=>String(at?.id||"")).filter(Boolean)),Ne=le.reduce((at,yt)=>at.some(tt=>String(tt?.id||"")===String(yt?.id||""))?at:a.addProduct(at,yt),a.readProducts(a.modes.personal));a.saveProducts(Ne,a.modes.personal);const be=a.readLists(a.modes.personal),Te=a.readProducts(a.modes.personal),Ve=Te.filter(at=>ue.has(String(at?.id||"")));if(Ve.length!==ue.size)throw new Error("Imported items were not visible after saving.");return D.current=Te,p(a.modes.personal),b(be),f(Te),y(be.some(at=>at.name===G)?G:a.resolveSavedActiveList(a.modes.personal,be)||t),{importedProducts:Ve,lists:be,products:Te}},ft=G=>{const se=m.find(Ve=>Ve.id===G.id)||null,le=String(G.listId||"").trim(),ue=le?h.find(Ve=>String(Ve.id||"")===le)||null:ro(h,G.category||G.listName),Ne=ue?{...G,category:ue.name,listName:ue.name,listId:ue.id}:G,be=a.updateProduct(m,Ne),Te=be.find(Ve=>Ve.id===Ne.id)||null;return f(be),{list:ue,previousProduct:se,products:be,updatedProduct:Te}},lr=(G,se={},le={})=>{Object.keys(se||{}).some(ue=>ue==="listId"||ue==="list_id")&&B.current.add(G),f(ue=>ue.map(Ne=>Ne.id===G?SH(Ne,se,le):Ne))},Wr=(G,se,le={})=>{!G||!se||f(ue=>ue.map(Ne=>{if(Ne.id!==G)return Ne;const be=wH(Ne,se,le);return be.syncPendingCloudWrite||B.current.delete(G),be}))},Dr=G=>{const se=String(G?.id||"").trim();se&&f(le=>le.map(ue=>String(ue?.id||"")===se?G:ue))},kr=({attemptedPatch:G={},latestRecord:se=null,productId:le,reason:ue})=>{B.current.delete(le),f(Ne=>Ne.map(be=>be.id===le?CH({attemptedPatch:G,latestRecord:se,product:be,reason:ue}):be))},Gr=d.useCallback((G=[])=>{const se=(Array.isArray(G)?G:[G]).filter(({imageSource:ue,productId:Ne}={})=>!!(Ne&&ue));if(se.length===0)return;const le=new Map(se.map(ue=>[ue.productId,ue]));f(ue=>{let Ne=!1;const be=ue.map(Te=>{const Ve=le.get(Te.id);if(!Ve||AE(Te,{isPlaceholder:Vn})!==Ve.imageSource)return Te;
16const yt=ao(Te),tt=!Ve.expectedImageSettings||["imageFit","imageScale","imagePositionX","imagePositionY"].every(Xe=>String(Te[Xe])===String(Ve.expectedImageSettings[Xe])),He={...Te};return Ve.backgroundColor&&Ve.backgroundMode&&yt.mode==="auto"&&(He.imageBackgroundMode=Ve.backgroundMode,He.imageBackgroundColor=Ku(Ve.backgroundColor,yt.color)),Ve.framing?.ok&&tt&&(He.imageFit=Ve.framing.imageFit,He.imageScale=Ve.framing.imageScale,He.imagePositionX=Ve.framing.imagePositionX,He.imagePositionY=Ve.framing.imagePositionY),Te.imageAutoFramePending===!0&&(He.imageAutoFramePending=!1),["imageBackgroundMode","imageBackgroundColor","imageFit","imageScale","imagePositionX","imagePositionY","imageAutoFramePending"].some(Xe=>String(He[Xe])!==String(Te[Xe]))?(Ne=!0,{...He,updatedAt:Ve.updatedAt||new Date().toISOString()}):Te});return Ne?be:ue})},[]),ar=d.useCallback(G=>Gr([G]),[Gr]),qr=G=>{const se=m.find(be=>be.id===G)||null,le=String(se?.listId||"").trim(),ue=le?h.find(be=>String(be.id||"")===le)||null:ro(h,se?.listName||se?.category),Ne=a.deleteProduct(m,G);return f(Ne),{deletedProduct:se,list:ue,products:Ne}},tn=d.useCallback((G,se)=>{f(le=>{const ue=xH(le,G,se);return ue===le?le:ue})},[]),hn=d.useCallback(G=>{if(L.current!==String(G?.ownerId||"")||a.getAccountScope?.()!==String(G?.ownerId||""))return{ok:!1,outcome:"account-scope-mismatch"};try{const se=AH({confirmation:G,mode:u,storage:a});return se.ok&&f(se.products),se}catch(se){return{error:se,ok:!1,outcome:"local-persistence-failed"}}},[u,a]),Wn=d.useCallback(({acknowledgement:G,pendingOperation:se}={})=>{if(L.current!==String(se?.ownerId||"")||a.getAccountScope?.()!==String(se?.ownerId||""))return{ok:!1,outcome:"account-scope-mismatch"};const le=a.modes?.personal||"personal",ue=Z.current,Ne=ue===le?re.current:a.readLists(le),be=ue===le?ee.current:a.readProducts(le),Te=J.current,Ve=PH({acknowledgement:G,authenticatedOwnerId:se.ownerId,currentDefaultList:Te.defaultList,fallbackDefaultList:r,lists:Ne,mode:le,pendingOperation:se,products:be,settings:Te,storage:a});if(!Ve.ok)return Ve;if(Z.current===le&&(b(Ve.lists),f(Ve.products)),Ve.defaultListChanged&&I(Ve.nextSettings),Z.current===le&&y(at=>at===Ve.list?.name?t:at),Ve.localPersistenceFailed){const at=Ve.persistenceErrors[0]?.error;k(at?.message||a.readRecoveryNotice()||"The board was deleted from your account, but this device could not fully save the refreshed state.")}return Ve},[t,r,a]),br=(G,se)=>{const le=Array.isArray(G)?a.reorderProductsToSequence(m,G,E):a.reorderProducts(m,G,se,E),ue=new Map(m.map(be=>[be.id,be])),Ne=le.filter(be=>{const Te=ue.get(be.id);return!!(Te&&(Te.sortOrder!==be.sortOrder||Te.listId!==be.listId||Te.category!==be.category||Te.listName!==be.listName))});return f(le),{products:le,updatedProducts:Ne}},rn=(G,se)=>{const le=h.find(Te=>Te.id===se),ue=m.find(Te=>Te.id===G);if(!le||!ue||ue.listId===le.id||ue.category===le.name||ue.listName===le.name)return null;const Ne=a.moveProductToList(m,h,G,se),be=Ne.find(Te=>Te.id===G)||null;return be&&B.current.add(G),be&&Ac()&&v1({enabled:!0,productId:G,toParentId:se}),f(Ne),{list:le,previousList:(ue.listId?h.find(Te=>String(Te.id||"")===String(ue.listId||"")):ro(h,ue.listName||ue.category))||null,previousProduct:ue,products:Ne,updatedProduct:be}};return{activeList:E,activeListRecord:We,activeAccountScopeId:o,acknowledgeListCloudWrite:Le,acknowledgeProductCloudWrite:Wr,applyVerifiedLocalProduct:Dr,accountLocalDataNotice:c,addProduct:fn,applyAccountCloudHydration:Ee,applyAuthoritativeBootstrapUpload:kt,applyCloudNewerPersonalCloudPull:Xt,applyConfirmedCloudBoardTrash:Wn,applyConfirmedProductRestore:hn,applyEmptyPersonalCloudPull:st,applyListCloudWriteConflict:et,applyPopulatedPersonalCloudPull:gr,applyProductCloudWriteConflict:kr,boardMode:P,createList:ze,clearRecoveryNotice:Ae,defaultModalList:ye,deleteProduct:qr,deleteList:$t,exportBackup:me,getShareList:G=>a.findListByNameOrSlug(fe,G),hasExplicitLocalProductMove:G=>B.current.has(String(G||"")),gridPreference:N,importPersonalProducts:Ke,importUnscopedPersonalDataToAccount:Pe,keepUnscopedPersonalDataSeparate:Ct,lists:fe,manualStores:v,markListCloudWritePending:W,markProductCloudWritePending:lr,mode:u,modes:a.modes,productLists:ke,products:Be,prepareBootstrapUploadProvenance:ht,recoveryNotice:A,moveProductToList:rn,removeProductAfterConfirmedCloudTrash:tn,reorderProducts:br,reorderList:pe,resetDemo:F,resetPersonal:te,runLegacyQaProductCleanup:xe,setActiveList:y,setBoardMode:V,setGridPreference:_,setManualStores:S,setSettings:I,settings:C,switchMode:Tt,updateProduct:ft,updateProductImageAnalysis:ar,updateProductImageAnalyses:Gr,updateList:pt,validateBackup:ie,visibleProducts:de,trashedProducts:Fe,applyBackup:Re}}const hR=Object.freeze({imageFit:"contain",imageScale:1,imagePositionX:50,imagePositionY:50,imageBackgroun
16dMode:"auto",imageBackgroundColor:"#fafafa"}),cf=Object.freeze({...hR,imageFit:"cover"}),Kb=(e=cf.imageFit)=>({...cf,imageFit:e==="contain"?"contain":"cover",imageAutoFramePending:!0}),EH="mylist.account",kH="local-user",Ii=1,xm=3,NH="incomplete-account-storage",Vy="manual-backup-import",LP="post-completion-sentinel-write",dx=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,gR=["userId","user_id","ownerId","owner_id"],jH=["listId","list_id"],RH=["accessRole","access_role","boardId","board_id","collaborationId","collaboration_id","collaboratorId","collaborator_id","collaborationRole","collaboration_role","publicBoardId","public_board_id","publicationId","publication_id","publishedAt","published_at","publicOnly","publicProjectionId","public_projection_id","role","sharedBoardId","shared_board_id","sharedBy","shared_by","sharedRole","shared_role","isCollaborative","isPublicOnly","isPublicProjection","isSharedProjection"],Jr=e=>String(e??"").trim(),BP=e=>Jr(e).toLowerCase(),Im=e=>!!e&&typeof e=="object"&&!Array.isArray(e),TP=e=>Jr(e).replace(/\s+/g," ").toLowerCase(),ux=e=>{try{return e?JSON.parse(e):null}catch{return null}},bR=(e,t)=>ux(e.getItem(t)),LH=e=>{const t=`${EH}.${e}`;return{backup:`${t}.legacyOwnerRecoveryBackup.v${Ii}`,decision:`${t}.legacyOwnerRecovery.v${Ii}`,handledCaptures:`${t}.handledCaptures`,legacyDecision:`${t}.legacyPersonalDataDecision`,lists:`${t}.lists`,products:`${t}.products`,recoveryNotice:`${t}.recoveryNotice`,safetySnapshot:`${t}.safetySnapshot`}},BH=(e="")=>{const t=Jr(e);return dx.test(t)?LH(t):null},Mh=(e,t,r)=>{const a=e.getItem(t),s=ux(a);return!a||!Im(s)||s.version!==xm||!Array.isArray(s[r])?null:{parsed:s,raw:a,records:s[r]}},wi=(e,t)=>{const r=gR.map(s=>Jr(e?.[s])).filter(Boolean),a=[...new Set(r.map(BP))];return a.length!==1?{classification:"invalid",owners:a}:a[0]===BP(t)?{classification:"account",owners:a}:a[0]===kH?{classification:"sentinel",owners:a}:{classification:"conflict",owners:a}},DP=(e={})=>RH.some(t=>{const r=e?.[t];return r===!0||r!==!1&&!!Jr(r)}),px=(e={})=>{const t=[...new Set(jH.map(r=>Jr(e?.[r])).filter(Boolean))];return t.length===1?t[0]:""},vR=(e,t)=>{const r=TP(t?.name);if(!r)return!1;const a=[e?.listName,e?.category].map(TP).filter(Boolean);return a.length>0&&a.every(s=>s===r)},Hy=(e,t)=>Array.isArray(t)&&t.length===e.length&&t.every((r,a)=>Jr(r)===Jr(e[a]?.id)),TH=({legacyDecision:e,safetySnapshot:t})=>{if(e!=="imported"||!Im(t)||!Array.isArray(t.lists)||!Array.isArray(t.products)||!Array.isArray(t.stores)||!Im(t.settings)||!Im(t.extension)||!Array.isArray(t.extension.handledCaptureIds))return!1;const r=t.metadata,a=t.settings.mode;return t.app==="my-list"&&t.appName==="Saveboard"&&t.schemaVersion===xm&&t.version===xm&&Number.isFinite(Date.parse(t.exportedAt||""))&&Hy(t.lists,t.boardOrder)&&Hy(t.lists,t.listOrder)&&Hy(t.products,t.productOrder)&&["demo","personal"].includes(a)&&Im(r)&&r.source==="pre-import-safety-snapshot"&&r.storage==="localStorage"&&r.mode==="personal"&&r.activeMode===a&&r.reason==="account-scope-legacy-import"&&r.storageVersion===xm&&r.settingsVersion===xm&&r.listCount===t.lists.length&&r.productCount===t.products.length&&r.storeCount===t.stores.length},DH=(e,t)=>{const r=bR(e,t);return new Set((Array.isArray(r)?r:[]).map(Jr).filter(a=>dx.test(a)))},OH=(e,t)=>Array.isArray(e?.priceHistory)&&e.priceHistory.some(r=>Jr(r?.source)==="extension-save")||dx.test(Jr(e?.id))&&t.has(Jr(e.id)),OP=(e={})=>e.syncPendingCloudWrite===!0,MP=(e,t)=>
16{const r={...e,userId:t};for(const a of gR)a!=="userId"&&Object.hasOwn(r,a)&&(r[a]=t);return r},pc=({accountId:e,adoptedListCount:t=0,adoptedProductCount:r=0,automaticAdoptionBlocked:a=!1,evaluatedAt:s,provenance:o=[],status:i,unmatchedListCount:c=0,unmatchedProductCount:l=0})=>({accountId:e,adoptedListCount:t,adoptedProductCount:r,...a?{automaticAdoptionBlocked:!0}:{},evaluatedAt:s,provenance:[...new Set(o)].sort(),status:i,unmatchedListCount:c,unmatchedProductCount:l,version:Ii}),Dm="Some older boards or items saved in this account need ownership recovery before they can be shown. Saveboard kept them hidden because their account provenance was incomplete.",Am=(e,t)=>{const r=Jr(e.getItem(t));r.includes(Dm)||e.setItem(t,r?`${r} ${Dm}`:Dm)},cm=(e,t,r)=>{try{e.setItem(t,JSON.stringify(r))}catch{}return r},Wy=(e,t,r)=>{const a=JSON.stringify(r);try{if(e.setItem(t.decision,a),e.getItem(t.decision)!==a)throw new Error("Owner recovery hold verification failed.");if(r.status==="review-required"&&(Am(e,t.recoveryNotice),!Jr(e.getItem(t.recoveryNotice)).includes(Dm)))throw new Error("Owner recovery notice verification failed.");return r}catch{return{accountId:r.accountId,automaticAdoptionBlocked:!0,provenance:r.provenance,reason:"review-hold-persistence-failed",status:"failed",version:Ii}}},MH=({accountId:e,lists:t,products:r})=>{const a=new Map;for(const o of t){const i=Jr(o?.id),c=wi(o,e);if(!i||a.has(i)||c.classification==="invalid"||c.classification==="conflict"||DP(o))return{ok:!1,reason:"invalid-list-ownership-or-identity"};a.set(i,{owner:c,record:o})}const s=new Set;for(const o of r){const i=Jr(o?.id),c=px(o),l=a.get(c)?.record,u=wi(o,e);if(!i||s.has(i)||!l||u.classification==="invalid"||u.classification==="conflict"||DP(o)||!vR(o,l))return{ok:!1,reason:"invalid-product-ownership-or-parent"};s.add(i)}return{listsById:a,ok:!0}},UH=({accountId:e,adoptedListIds:t,adoptedProductIds:r,lists:a,products:s})=>{const o=new Map(a.map(c=>[Jr(c?.id),c])),i=new Map(s.map(c=>[Jr(c?.id),c]));return[...t].every(c=>wi(o.get(c),e).classification==="account")&&[...r].every(c=>{const l=i.get(c),u=px(l);return wi(l,e).classification==="account"&&o.has(u)&&vR(l,o.get(u))})},FH=({accountId:e="",force:t=!1,now:r=()=>new Date().toISOString(),reviewOnly:a=!1,storage:s}={})=>{const o=BH(e);if(!o||!s||typeof s.getItem!="function"||typeof s.setItem!="function"||typeof s.removeItem!="function")return{status:"not-applicable",version:Ii};const i=s.getItem(o.decision),c=ux(i),l=r(),u=Array.isArray(c?.provenance)?c.provenance.map(Jr).filter(
16Boolean):[],p=!t&&c?.version===Ii&&c.automaticAdoptionBlocked===!0,m=!t&&c?.version===Ii&&["applied","not-needed"].includes(c.status)&&Number(c.unmatchedListCount)===0&&Number(c.unmatchedProductCount)===0,f=s.getItem(o.lists),h=s.getItem(o.products),b=Mh(s,o.lists,"lists"),v=Mh(s,o.products,"products");if(!b||!v){if(f===null&&h===null)return a||p?Wy(s,o,pc({accountId:e,automaticAdoptionBlocked:!0,evaluatedAt:l,provenance:[...u,...a?[Vy]:[]],status:"not-needed"})):cm(s,o.decision,pc({accountId:e,evaluatedAt:l,status:"not-needed"}));const We=(b?.records||[]).filter(ze=>wi(ze,e).classification==="sentinel").length,de=(v?.records||[]).filter(ze=>wi(ze,e).classification==="sentinel").length,ye=m&&!!(We||de),ge=pc({accountId:e,automaticAdoptionBlocked:!0,evaluatedAt:l,provenance:[...u,NH,...a?[Vy]:[],...ye?[LP]:[]],status:"review-required",unmatchedListCount:We,unmatchedProductCount:de});return Wy(s,o,ge)}const S=MH({accountId:e,lists:b.records,products:v.records}),C=b.records.filter(ke=>wi(ke,e).classification==="sentinel").length,I=v.records.filter(ke=>wi(ke,e).classification==="sentinel").length,A=!!(C||I),k=m&&A;if(a||p||k){const ke=A||!S.ok?"review-required":"not-needed",We=pc({accountId:e,automaticAdoptionBlocked:!0,evaluatedAt:l,provenance:[...u,...a?[Vy]:[],...k?[LP]:[]],status:ke,unmatchedListCount:C,unmatchedProductCount:I});return Wy(s,o,We)}if(!t&&c?.version===Ii&&S.ok&&C===0&&I===0&&Number(c.unmatchedListCount)===0&&Number(c.unmatchedProductCount)===0&&["applied","not-needed"].includes(c.status))return c;if(!C&&!I)return cm(s,o.decision,pc({accountId:e,evaluatedAt:l,status:"not-needed"}));if(!S.ok){const ke=pc({accountId:e,evaluatedAt:l,status:"review-required",unmatchedListCount:C,unmatchedProductCount:I});try{Am(s,o.recoveryNotice)}catch{}return cm(s,o.decision,ke)}const N=TH({legacyDecision:Jr(s.getItem(o.legacyDecision)),safetySnapshot:bR(s,o.safetySnapshot)}),_=DH(s,o.handledCaptures),P=new Set(v.records.filter(ke=>OH(ke,_)).map(ke=>Jr(ke.id))),V=new Set(v.records.filter(OP).map(ke=>Jr(ke.id))),L=new Set(b.records.filter(OP).map(ke=>Jr(ke.id))),z=new Set,B=new Set;for(const ke of v.records){const We=wi(ke,e).classification,de=Jr(ke.id);if(!(N||P.has(de)||V.has(de)))continue;We==="sentinel"&&z.add(de);const ge=px(ke),ze=S.listsById.get(ge);(We==="account"||We==="sentinel")&&ze?.owner.classification==="sentinel"&&B.add(ge)}N&&b.records.forEach(ke=>{wi(ke,e).classification==="sentinel"&&B.add(Jr(ke.id))}),L.forEach(ke=>{S.listsById.get(ke)?.owner.classification==="sentinel"&&B.add(ke)});const re=C-B.size,Z=I-z.size,D=[...N?["legacy-account-import"]:[],...P.size?["extension-save"]:[],...L.size||V.size?["pending-cloud-write"]:[]];if(!B.size&&!z.size){const ke=pc({accountId:e,evaluatedAt:l,provenance:D,status:"review-required",unmatchedListCount:re,unmatchedProductCount:Z});try{Am(s,o.recoveryNotice)}catch{}return cm(s,o.decision,ke)}const K=b.records.map(ke=>B.has(Jr(ke.id))?MP(ke,e):ke),ee=v.records.map(ke=>z.has(Jr(ke.id))?MP(ke,e):ke),J={accountId:e,createdAt:l,lists:b.parsed,products:v.parsed,version:Ii},fe=pc({accountId:e,adoptedListCount:B.size,adoptedProductCount:z.size,evaluatedAt:l,provenance:D,status:re||Z?"applied-with-review":"applied",unmatchedListCount:re,unmatchedProductCount:Z}),De=JSON.stringify(J),Be=JSON.stringify(fe),Fe=s.getItem(o.recoveryNotice);try{if(s.setItem(o.backup,De),s.getItem(o.backup)!==De)throw new Error("Legacy owner recovery backup verification failed.");s.setItem(o.lists,JSON.stringify({...b.parsed,lists:K})),s.setItem(o.products,JSON.stringify({...v.parsed,products:ee}));const ke=Mh(s,o.lists,"lists")?.records||[],We=Mh(s,o.products,"products")?.records||[];if(!UH({accountId:e,adoptedListIds:B,adoptedProductIds:z,lists:ke,products:We}))throw new Error("Legacy owner recovery verification failed.");if((re||Z)&&(Am(s,o.recoveryNotice),!Jr(s.getItem(o.recoveryNotice)).includes(Dm)))throw new Error("Legacy owner recovery notice verification failed.");if(s.setItem(o.decision,Be),s.getItem(o.decision)!==Be)throw new Error("Legacy owner recovery decision verification failed.")}
16catch{try{s.setItem(o.lists,b.raw),s.setItem(o.products,v.raw),i===null?s.removeItem(o.decision):s.setItem(o.decision,i),Fe===null?s.removeItem(o.recoveryNotice):s.setItem(o.recoveryNotice,Fe),Am(s,o.recoveryNotice)}catch{}return cm(s,o.decision,pc({accountId:e,evaluatedAt:l,provenance:D,status:"failed",unmatchedListCount:C,unmatchedProductCount:I}))}return fe},Gy=(e={})=>{try{return FH(e)}catch{return{status:"failed",version:Ii}}},vt={products:"mylist.products",demoProducts:"mylist.demoProducts",lists:"mylist.lists",demoLists:"mylist.demoLists",stores:"mylist.stores",legacyCustomLists:"my-list-v3-custom-lists",gridPreference:"mylist.gridPreference",boardMode:"mylist.boardMode",mode:"mylist.mode",settings:"mylist.settings",viewState:"mylist.viewState",pendingCaptures:"mylist.pendingCaptures",handledCaptures:"mylist.handledCaptures",safetySnapshot:"mylist.safetySnapshot",recoveryNotice:"mylist.recoveryNotice",pendingBoardTrash:"mylist.pendingBoardTrash"},yR="mylist.account",$H=new Set([vt.products,vt.lists,vt.stores,vt.viewState,vt.handledCaptures,vt.safetySnapshot,vt.pendingBoardTrash]);let xw=0;const zH=e=>{xw+=1;try{return e()}finally{xw-=1}},og=[],mx=e=>$H.has(e)&&!Sc(Rs)&&xw===0,VH="legacyPersonalDataDecision",HH=new Set([vt.products,vt.lists,vt.stores,vt.gridPreference,vt.boardMode,vt.settings,vt.viewState,vt.handledCaptures,vt.safetySnapshot,vt.recoveryNotice,vt.pendingBoardTrash]),WH={products:"my-list-v3-products",demoProducts:"my-list-v3-demo-products",lists:"my-list-v3-lists",demoLists:"my-list-v3-demo-lists",gridPreference:"my-list-v3-grid-preference",boardMode:"my-list-v3-board-mode",mode:"my-list-v3-mode",settings:"my-list-v3-settings",viewState:"my-list-v3-view-state",handledCaptures:"my-list-handled-capture-ids",recoveryNotice:"my-list-v3-recovery-notice"},lm=3,qy=1,dm=3,Uh="my-list",Fh="Saveboard",UP=new Set(["My·List"]),um=3,$h=1,Es="demo",Wt="personal",GH=new Set(["dashboard","allItems","list","guide","share"]),qH=new Set(["active","purchased","archived","trash"]),SR=["cloudDeletedAt","cloudDeletionId","cloudDeletionReason","cloudPurgeAfter","cloudRestoredAt","cloudRestoredBy","cloudUpdatedAt","syncConflict","syncConflictAt","syncConflictPatch","syncPendingCloudWrite","syncPendingWriteRevision","syncRevision","syncSuppressed"],YH=["budget","budgetCurrency","currency","coverImage","imageUrl","image","coverItemIds","colour","color","emoji","isArchived","archivedAt",...SR],KH="This does not look like a valid Saveboard backup.";let Rs="";const wR=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,XH="00000000-0000-0000-0000-000000000000",JH=new Set(["pending","uncertain"]),mi=(e,t)=>{const r=new Error(e);return r.name="StoragePersistenceError",r.cause=t,r},QH=e=>Object.entries(vt).find(([,t])=>t===e)?.[0]||"",Sc=(e="")=>String(e||"").trim().replace(/[^a-zA-Z0-9_-]/g,""),FP=(e={},t="")=>{const r=String(e?.ownerId||"").trim(),a=String(e?.listId||"").trim(),s=String(e?.operationId||"").trim(),o=Number(e?.expectedRevision),i=Date.parse(e?.requestedAt||""),c=Date.parse(e?.updatedAt||e?.requestedAt||""),l=String(e?.state||"pending").trim().toLowerCase();return!r||r!==String(t||"").trim()||!a||a.length>512||/[\u0000-\u001f\u007f]/.test(a)||!wR.test(s)||s.toLowerCase()===XH||!Number.isSafeInteger(o)||o<=0||!Number.isFinite(i)||!Number.isFinite(c)||!JH.has(l)?null:{expectedRevision:o,listId:a,operationId:s,ownerId:r,requestedAt:new Date(i).toISOString(),state:l,updatedAt:new Date(c).toISOString()}},kl=e=>{const t=Sc(Rs);return!t||!HH.has(e)?e:`${yR}.${t}.${e.replace(/^mylist\./,"")}`},$P=()=>{const e=Sc(Rs);return e?`${yR}.${e}.${VH}`:""},zh=(e,t)=>{const r=Rs;Rs=Sc(e);try{return t()}finally{Rs=r}},lf=e=>{if(typeof window>"u"||mx(e))return null;const t=kl(e),r=window.localStorage.getItem(t);if(r!==null)return r;if(t!==e)return null;const a=WH[QH(e)];if(!a)return null;const s=window.localStorage.getItem(a);if(s!==null)try{window.localStorage.setItem(e,s)}catch{}return s},Su=(e,t)=>{if(typeof window>"u")return;if(mx(e)){og.push({at:Date.now(),key:e}),og.length>50&&og.shift();return}const r=kl(e);try{window.localStorage.setItem(r,t)}catch(a){const s=a?.name==="QuotaExceededError"?"Local storage is full. Export a backup, then remove large pasted images or use image URLs.":"Local storage is unavailable. Changes may not persist in this browser.";try{window.localStorage.setItem(kl(vt.recoveryNotice),s)}catch{}throw mi(s,a)}},Pm=(e,t="Data recovery was needed.")=>{if(!(typeof window>"u"))try{const r=kl(e),a=lf(e);a&&window.localStorage.setItem(`${r}-recovered-${Date.now()}`,a),window.localStorage.setItem(kl(vt.recoveryNotice),t)}catch{}},Sd=e=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`,Xb=()=>Sd("product"),Ye=(e="")=>e.trim().replace(/\s+/g," "),Jb=e=>Ye(e).toLowerCase().replace(/&/g,"and").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""),fx=e=>`list-${Jb(e)||Sd("custom-list")}`,Qs=(e,t=0,r={})=>{const a=Ye(e),s=r.createdAt||new Date().toISOString(),o=r.slug||Jb(a),i=YH.reduce((c,l)=>(Object.hasOwn(r,l)&&r[l]!==void 0&&(c[l]=r[l]),c),{});return{id:r.id||fx(a),userId:r.userId||Mi,name:a,slug:o,description:r.description||"",publicDescription:r.publicDescription||"",sortOrder:Number.isFinite(r.sortOrder)?r.sortOrder:t,isPublic:!!r.isPublic,createdAt:s,updatedAt:r.updatedAt||s,...i}},ZH=(e,t)=>{const r=Ye(t),a=Jb(r);return e.find(s=>
16s.id===t||s.slug===a||s.name.toLowerCase()===r.toLowerCase())},zP=(e,t,r)=>{const a=e.findIndex(c=>c.id===t),s=e.findIndex(c=>c.id===r);if(a===-1||s===-1||a===s)return e;const o=[...e],[i]=o.splice(a,1);return o.splice(s,0,i),o},ui=e=>{if(typeof window>"u")return null;try{const t=lf(e);return t?JSON.parse(t):null}catch{return Pm(e,"Some saved data needed recovery. The original raw data was kept separately."),null}},Js=(e,t)=>{typeof window>"u"||Su(e,JSON.stringify(t))},Do=e=>{if(!(typeof window>"u")&&!mx(e))try{window.localStorage.removeItem(kl(e))}catch{}},eW=()=>{if(typeof window>"u")return"";try{return lf(vt.recoveryNotice)||""}catch{return""}},tW=()=>{if(!(typeof window>"u"))try{window.localStorage.removeItem(kl(vt.recoveryNotice))}catch{}},Iw=e=>{const t=new Set(e.filter(es).map(s=>String(s?.id||"").trim()).filter(Boolean)),r=new Set,a=new Set;return e.filter(s=>{if(!s?.name)return!1;const o=String(s.id||"").trim(),c=`${[s.userId,s.user_id,s.ownerId,s.owner_id].map(u=>String(u||"").trim().toLowerCase()).filter(Boolean).filter((u,p,m)=>m.indexOf(u)===p).sort().join("|")||"ownerless"}:${ji(s.name)}`,l=es(s);return o&&r.has(o)||!l&&o&&t.has(o)||!l&&a.has(c)?!1:(o&&r.add(o),l||a.add(c),!0)})},rW=e=>{const t=new Set;return e.filter(r=>{const a=String(r?.id||"").trim();return!a||t.has(a)?!1:(t.add(a),!0)})},pm=(e={},t={},r=[])=>{const a=String(e.listId??e.list_id??"").trim(),s=String(t.id||"").trim();if(a)return!!(s&&a===s);const o=ro(r,e.category||e.listName);return!!(o&&String(o.id||"").trim()===s)},nW=(e,t,r={})=>{if(r.preserveStoredListIds){const s=new Map,o=new Set;return t.forEach(c=>{if(!c?.name)return;const l=String(c.id||"").trim();if(!l)return;const u=s.get(l);(!u||!es(u)||es(c))&&s.set(l,c),o.add(c.name.toLowerCase())}),[...e.filter(c=>{const l=String(c?.id||"").trim(),u=String(c?.name||"").toLowerCase();return c?.name&&!s.has(l)&&!o.has(u)}),...s.values()].sort((c,l)=>c.sortOrder-l.sortOrder)}const a=new Map(e.map(s=>[s.name.toLowerCase(),s]));return t.forEach(s=>{const o=s.name.toLowerCase(),i=a.get(o);a.set(o,i?Qs(s.name,s.sortOrder,{...i,...s,id:i.id,isPublic:!!(i.isPublic||s.isPublic),slug:i.slug,description:s.description||i.description,publicDescription:s.publicDescription||i.publicDescription}):s)}),Iw([...a.values()].sort((s,o)=>s.sortOrder-o.sortOrder))},Oo=e=>e.map((t,r)=>({...t,sortOrder:r})),VP=e=>[Ye(e.title).toLowerCase(),Ye(e.brand).toLowerCase(),Ye(e.url).toLowerCase(),Ye(e.category||e.listName).toLowerCase()].join("|"),aW=(e,t)=>VP(e)===VP(t),CR=(e=[])=>[...e].sort((t,r)=>String(t.displayName||t.domain||"").localeCompare(String(r.displayName||r.domain||""),void 0,{sensitivity:"base"})||String(t.domain||"").localeCompare(String(r.domain||""))),Om=(e=[])=>{const t=new Map;
16return(Array.isArray(e)?e:[]).forEach(r=>{const a=Cj(r);a&&t.set(a.domain,{...t.get(a.domain)||{},...a})}),CR([...t.values()])},sW=(e=[],t=[])=>{const r=new Map;return Om(t).forEach(a=>{r.set(a.domain,a)}),Om(e).forEach(a=>{r.set(a.domain,a)}),CR([...r.values()])},oW=e=>{const t=new Error(e);return t.name="BackupError",t},Ra=()=>oW(KH),pp=["fog","celadon","eucalyptus","rain","glacier","heather","smoke","juniper","ink","midnight","clay"];function iW({defaultLists:e,demoLists:t,dashboardList:r,defaultGridPreference:a,defaultBoardMode:s,gridPreferences:o,boardModes:i,createInitialProducts:c,normalizeGridPreference:l,normalizeProduct:u}){const p=(x,$,O=null)=>{const q=rA(x),X=tC(q,{isPlaceholder:Vn,previousRecord:O}),Se=bS(q,{isPlaceholder:Vn,previousRecord:O}),he=u(Se,$),$e=X.action==="clear"?{...he,image:"",imageUrl:""}:bS(he,{isPlaceholder:Vn,previousRecord:O});return SR.reduce((Oe,Pt)=>(Object.hasOwn(q||{},Pt)&&q[Pt]!==void 0&&(Oe[Pt]=q[Pt]),Oe),$e)},m=x=>{const $=typeof l=="function"?l(x):x;return Object.hasOwn(o,$)?$:a},f=(x="")=>{if(Rs=Sc(x),Rs&&typeof window<"u")try{Gy({accountId:Rs,storage:window.localStorage})}catch{}return Rs},h=()=>Rs,b=(x="")=>{const $=String(x||"").trim();return wR.test($)&&$===h()?$:""},v=()=>{const x=h();if(!x)return[];const $=ui(vt.pendingBoardTrash);if(!$||$.version!==qy||!Array.isArray($.operations))return[];const O=new Map;return $.operations.forEach(q=>{const X=FP(q,x);X&&!O.has(X.listId)&&O.set(X.listId,X)}),[...O.values()]},S=x=>{const $=String(x||"").trim();return v().find(O=>O.listId===$)||null},C=(x={})=>{const $=h(),O=FP(x,$);if(!O)throw mi("Cloud board deletion could not be prepared safely.");const q=v(),X=q.find(he=>he.listId===O.listId)||null;if(X&&X.operationId!==O.operationId)throw mi("A different deletion attempt is already pending for this board.");const Se=[...q.filter(he=>he.listId!==O.listId),O];return Js(vt.pendingBoardTrash,{operations:Se,version:qy}),O},I=({listId:x,operationId:$,ownerId:O}={})=>{const q=h(),X=String(x||"").trim(),Se=String($||"").trim();if(!q||q!==String(O||"").trim()||!X||!Se)return!1;const he=v();return he.find(Oe=>Oe.listId===X&&Oe.operationId===Se)?(Js(vt.pendingBoardTrash,{operations:he.filter(Oe=>Oe.listId!==X||Oe.operationId!==Se),version:qy}),!0):!1},A=()=>Object.fromEntries(Object.entries(vt).map(([x,$])=>[x,kl($)])),k=(x,$,O="")=>{if(typeof x=="string")return Qs(x,$,O?{createdAt:O}:{});const q=rA(x);return Qs(q?.name||"",$,{...q,createdAt:q?.createdAt||O})},E=(x,$=null)=>{const O=new Map;return(Array.isArray($)?$:ze(x)).forEach(q=>{const X=Ye(q.category||q.listName||""),Se=q.createdAt||"";if(!X||!Se)return;const he=O.get(X);(!he||new Date(Se).getTime()<new Date(he).getTime())&&O.set(X,Se)}),O},y=(x,$,O="")=>{const q=Jb(x)||"list",X=new Set($.filter($e=>$e.id!==O).map($e=>
16$e.slug).filter(Boolean));if(!X.has(q))return q;let Se=2,he=`${q}-${Se}`;for(;X.has(he);)Se+=1,he=`${q}-${Se}`;return he},N=()=>Wt,_=(x=Wt)=>(x===Es?t:e).map(($,O)=>k($,O)),P=typeof e[0]=="string"?e[0]:e[0]?.name||"Wishlist",V={version:um,defaultList:P,defaultImageFit:cf.imageFit,defaultCurrency:wd,gridPreference:a,boardMode:s,theme:"light",minimalBoardMode:!1,lightCardMode:"tonal",boardThemes:{},defaultSortMode:VC,displayQuality:"balanced",customCursorEnabled:!0,monochromeEnabled:!1,onboardingCompleted:{},onboardingDismissed:!1,onboardingForceVisible:!1},L=({lists:x=[],products:$=[]}={})=>$.length?!0:x.some(O=>{const q=String(O?.name||"").trim();return!(!q||q===r||q===P)||!!(O?.description||O?.publicDescription||O?.isPublic||O?.coverImage||O?.imageUrl||O?.budget)}),z=x=>{const $=String(x||"").trim().toLowerCase();return["light","dark","auto","system"].includes($)?$:V.theme},B=x=>["fast","balanced","showcase"].includes(x)?x:V.displayQuality,re=x=>["tonal","panel"].includes(x)?x:V.lightCardMode,Z=x=>{if(!x||typeof x!="object")return{};const $={};for(const[O,q]of Object.entries(x))typeof O=="string"&&O&&pp.includes(q)&&($[O]=q);return $},D=(x={})=>{const $=Ye(x.defaultList||V.defaultList)||V.defaultList,O=Nd(x.defaultCurrency,V.defaultCurrency),q=x.onboardingCompleted&&typeof x.onboardingCompleted=="object"?x.onboardingCompleted:{},Se=x.version===um&&x.defaultImageFit==="contain"?"contain":cf.imageFit;return{...V,defaultList:$,defaultImageFit:Se,defaultCurrency:O,gridPreference:m(x.gridPreference),boardMode:Object.hasOwn(i,x.boardMode)?x.boardMode:V.boardMode,theme:z(x.theme),minimalBoardMode:!!x.minimalBoardMode,lightCardMode:re(x.lightCardMode),boardThemes:Z(x.boardThemes),defaultSortMode:aw(x.defaultSortMode,V.defaultSortMode),displayQuality:B(x.displayQuality),customCursorEnabled:x.customCursorEnabled!==!1,monochromeEnabled:!!x.monochromeEnabled,sidebarListPage:Number.isFinite(x.sidebarListPage)?Math.max(0,Math.floor(x.sidebarListPage)):0,onboardingCompleted:q,onboardingDismissed:!!x.onboardingDismissed,onboardingForceVisible:!!x.onboardingForceVisible,version:um}},K=(x,$=[])=>{const O=Ye(x),q=$.find(X=>ji(X.name)===ji(O)&&US(X));return q?q.name:$.find(X=>X.name&&X.name!==r)?.name||V.defaultList},ee=(x={},$=[])=>{const O=D({...G(),...x});return{...O,defaultList:K(O.defaultList,$),boardMode:Object.hasOwn(i,x.boardMode)?x.boardMode:nn(),gridPreference:Object.hasOwn(x,"gridPreference")?m(x.gridPreference):br(),mode:N(x.mode||Wt)}},J=(x={})=>({version:$h,selectedView:GH.has(x.selectedView)?x.selectedView:"dashboard",selectedListId:typeof x.selectedListId=="string"?x.selectedListId:"",selectedListSlug:typeof x.selectedListSlug=="string"?x.selectedListSlug:"",selectedListName:Ye(x.selectedListName||""),selectedStatusFilter:qH.has(x.selectedStatusFilter)?x.selectedStatusFilter:"active",selectedSort:typeof x.selectedSort=="string"?x.selectedSort:"manual",boardSortModes:lj(x.boardSortModes),allItemsSortMode:aw(x.allItemsSortMode,""),selectedLayoutMode:Object.hasOwn(i,x.selectedLayoutMode)?x.selectedLayoutMode:s,selectedDensity:m(x.selectedDensity),updatedAt:x.updatedAt||new Date().toISOString()}),fe=(x={})=>{const $=x.byMode?.[Wt]||(x.mode===Wt?x:{}),O=x.byMode?.[Es]||(x.mode===Es?x:{});return{version:$h,byMode:{[Wt]:J($),[Es]:J(O)}}},De=(x,$=[])=>$.find(O=>O.id===x.selectedListId)||$.find(O=>x.selectedListSlug&&O.slug===x.selectedListSlug)||ro($,x.selectedListName)||null,Be=(x={},$=[])=>{const O=J(x),q=De(O,$);return O.selectedView!=="list"||!q?{...O,selectedView:O.selectedView==="list"?"dashboard":O.selectedView,selectedListId:"",selectedListSlug:"",selectedListName:""}:{...O,selectedListId:q.id,selectedListSlug:q.slug,selectedListName:q.name}},Fe=(x={},$=[])=>{const O=fe(x);return{version:$h,byMode:{...O.byMode,[Wt]:Be(O.byMode[Wt],$)}}},ke=()=>Wt,We=()=>{},de=x=>vt.products,ye=x=>vt.lists,ge=()=>c(),ze=(x=ke())=>{const $=N();if(typeof window>"u")return $===Es?ge():[];const O=de(),q=ui(O);if(!q)return $===Es?ge():[];const X=Array.isArray(q.products)?q.products:Array.isArray(q)?q:null;return X?Oo(X.filter(Se=>Se&&typeof Se=="object").map((Se,he)=>p(Se,he))):(Pm(O,"Product data needed recovery. The original raw data was kept separately."),Do(O),$===Es?ge():[])},W=()=>{if(typeof window>"u")return[];const x=ui(vt.stores);if(!x)return[];const $=Array.isArray(x?.stores)?x.stores:Array.isArray(x)?x:null;return $?Om($):(Pm(vt.stores,"Store data needed recovery. The original raw data was kept separately."),Do(vt.stores),[])},Le=(x=[])=>{Js(vt.stores,{version:lm,stores:Om(x)})},et=()=>Sd("price-history"),pt=(x,$,O=null)=>{const q=p(x,$,O);return O?_I(O,q,{createId:et}):PI(q,{createId:et,source:x.priceHistorySource||"created"})},$t=(x,$=ke(),O={})=>{const q=N(),X=O.trackPriceHistory!==!1,Se=X?new Map(ze(q).map($e=>
16[$e.id,$e])):new Map,he=Oo(x.filter(Boolean).map(($e,Oe)=>X?pt($e,Oe,Se.get($e.id)||null):p($e,Oe)));Js(de(),{version:lm,products:he})},pe=(x,$=0,O=E(x),q=null)=>{const X=(Array.isArray(q)?q:ze(x)).map(Se=>Ye(Se.category||Se.listName||"")).filter(Boolean).filter(Se=>Se!==r);return[...new Set(X)].map((Se,he)=>Qs(Se,$+he,{createdAt:O.get(Se)}))},Tt=(x=ke(),$={})=>{const O=N(),q=Array.isArray($.products)?$.products:null,X=_(O),Se=ye(),he=ui(Se),$e=E(O,q),Oe=Array.isArray(he?.lists)?he.lists:Array.isArray(he)?he:null;if(Oe){he.version&&he.version!==lm&&Pm(Se,"List data needed recovery. The original raw data was kept separately.");const rt=Oe.map((dr,tr)=>k(dr,tr,$e.get(Ye(dr?.name||"")))),St=new Set(rt.map(dr=>dr.name.toLowerCase())),_t=pe(O,rt.length,$e,q).filter(dr=>!St.has(dr.name.toLowerCase()));return nW(X,[...rt,..._t],{preserveStoredListIds:O===Wt})}he&&(Pm(Se,"List data needed recovery. The original raw data was kept separately."),Do(Se));const Pt=ui(vt.legacyCustomLists),mt=Array.isArray(Pt)?Pt.map(Ye).filter(Boolean).filter(rt=>rt!==r).map((rt,St)=>Qs(rt,X.length+St,{createdAt:$e.get(rt)})):[],Kt=pe(O,X.length+mt.length,$e,q);return Iw([...X,...mt,...Kt])},F=(x,$=ke())=>{Js(ye(),{version:lm,lists:x.map((O,q)=>Qs(O.name,q,{...O,sortOrder:q,updatedAt:O.updatedAt||new Date().toISOString()}))})},te=()=>{const x={lists:_(Es),products:ge()};return $t(x.products,Es,{trackPriceHistory:!1}),F(x.lists,Es),x},me=()=>($t([],Wt,{trackPriceHistory:!1}),F(_(Wt),Wt),Le([]),Do(vt.gridPreference),Do(vt.boardMode),Do(vt.settings),Do(vt.viewState),Do(vt.pendingCaptures),Do(vt.handledCaptures),Do(vt.safetySnapshot),Do(vt.recoveryNotice),{lists:Tt(Wt),manualStores:W(),products:ze(Wt)}),ie=(x=[])=>Array.isArray(x)?x.map($=>String($||"").trim()).filter(Boolean):[],Ae=(x=[],$=[])=>{const O=ie($);if(O.length===0)return x;const q=new Map(x.map(he=>[String(he?.id||""),he]).filter(([he])=>he)),X=O.map(he=>q.get(he)).filter(Boolean),Se=new Set(X.map(he=>String(he.id)));return[...X,...x.filter(he=>!Se.has(String(he?.id||"")))]},Re=(x=[],$=[])=>{const O=ie($);if(O.length===0)return x;const q=new Map;x.forEach(he=>{[he.id,he.slug,he.name].forEach($e=>{const Oe=String($e||"").trim();Oe&&q.set(Oe,he)})});const X=O.map(he=>q.get(he)).filter(Boolean),Se=new Set(X.map(he=>he.id));return[...X,...x.filter(he=>!Se.has(he.id))].map((he,$e)=>Qs(he.name,$e,{...he,sortOrder:$e}))},ne=x=>!!(x&&typeof x=="object"&&!Array.isArray(x)),ht=(x=[],$=[],O=[],{captureListNormalizationProvenance:q=!1,preserveDistinctListIds:X=!1}={})=>{const Se=new Set(x.map(rt=>ji(typeof rt=="string"?rt:rt?.name)).filter(Boolean)),he=X?[]:$.map(rt=>Ye(rt.category||rt.listName||"")).filter(Boolean).filter(rt=>rt!==r),Oe=[...x,...he.filter(rt=>!Se.has(ji(rt))).map(rt=>({name:rt}))].map((rt,St)=>k(rt,St)),Pt=x.map(rt=>typeof rt=="string"?"":String(rt?.id||"").trim());if(q){const rt=new Map,St=new Set;Oe.forEach((_t,dr)=>{const tr=dr<x.length,yr=_t?.id,Sr=Pt[dr]||"";if(X&&Sr&&St.has(Sr))return;tr&&tp({inputPosition:dr,listId:yr,phase:"backup-normalization-input",record:_t});let wr="retained",Mn="";if(!_t?.name||X&&tr&&!Sr)wr="invalid-record-dropped";else if(_t.name===r)wr="reserved-dashboard-dropped";else if(X)St.add(Sr);else{const fr=_t.name.toLowerCase();Mn=rt.get(fr)||"",Mn?wr="duplicate-name-dropped":rt.set(fr,yr)}tr&&tp({inputPosition:dr,listId:yr,normalizationOutcome:wr,phase:"backup-normalization-result",record:_t,retained:wr==="retained",retainedWinnerId:Mn})})}const mt=Oe.filter((rt,St)=>rt.name&&rt.name!==r&&(!X||!!Pt[St])),Kt=X?rW(mt):Iw(mt);return Re(Kt,O)},kt=(x=[],$=[])=>Oo(Ae(x,$).filter(O=>O&&typeof O=="object").map((O,q)=>p(O,q))),Ee=(x=[])=>Om(x),xe=(x=[],$=[])=>{if(!Array.isArray($)||!$.length)return x;const O=new Map;return $.forEach(q=>{const X=String(q?.productId||q?.product_id||"").trim();if(!X)return;const Se=O.get(X)||[];Se.push({id:q.id,price:q.price,currency:q.currency,amount:q.amount,approximate:q.approximate??q.isApproximate,source:q.source==="updated"?"manual-edit":q.source,recordedAt:q.recordedAt||q.recorded_at||q.capturedAt||q.createdAt}),O.set(X,Se)}),x.map(q=>{const X=O.get(q.id)||[];return X.length?p({...q,priceHistory:Rl([...q.priceHistory||[],...X])},q.sortOrder):q})},Qe=(x={},{reason:$="",source:O="manual-export"}={})=>{const q=Array.isArray(x.lists)?x.lists:[],X=Array.isArray(x.stores)?x.stores:[],Se=Array.isArray(x.products)?x.products:[],he=new Date().toISOString();return{app:Uh,appName:Fh,schemaVersion:dm,version:dm,exportedAt:he,lists:q,products:Se,stores:X,boardOrder:q.map($e=>$e.id),listOrder:q.map($e=>$e.id),productOrder:Se.map($e=>$e.id),settings:{boardMode:x.boardMode||s,...x.settings||{},gridPreference:x.gridPreference||a,mode:N(x.mode)},viewState:x.viewState||fe({}),extension:{handledCaptureIds:Array.isArray(x.handledCaptureIds)?x.handledCaptureIds:[]},metadata:{source:O,storage:"localStorage",mode:Wt,activeMode:N(x.mode),productC
16ount:Se.length,listCount:q.length,storeCount:X.length,storageVersion:lm,settingsVersion:um,...$?{reason:$}:{}}}},Pe=()=>{const x=ze(Wt),$=Tt(Wt,{products:x});return{boardMode:nn(),gridPreference:br(),handledCaptureIds:at(),lists:$,mode:ke(),products:x,settings:G(),stores:W(),viewState:le()}},Ct=(x={})=>Qe(Pe(),x),nr=x=>{try{return Js(vt.safetySnapshot,Ct({reason:x,source:"pre-import-safety-snapshot"})),!0}catch{return!1}},en=()=>zH(()=>zh("",Pe)),st=x=>{const $=Sc(x);if(!$)throw mi("Account hydration requires an authenticated account scope.");return zh($,Pe)},gr=(x={},{persistMode:$=!0,persistViewState:O=!0}={})=>{const q=Array.isArray(x.lists)?x.lists:[],X=Array.isArray(x.products)?x.products:[],Se=x.settings||{};F(q,Wt),$t(X,Wt,{trackPriceHistory:!1}),Le(Array.isArray(x.stores)?x.stores:[]),se(Se),Su(vt.gridPreference,m(x.gridPreference)),Su(vt.boardMode,Object.hasOwn(i,x.boardMode)?x.boardMode:s),O&&x.viewState&&Ne(x.viewState,q),yt(x.handledCaptureIds||[]),$&&We(x.mode===Es?Es:Wt)},Xt=({accountId:x,cloudSnapshot:$={},expectedCloudParents:O=[],localSnapshot:q={},snapshot:X={},useCloudAncillaryState:Se=!1}={})=>{const he=Sc(x);if(!he)throw mi("Account hydration requires an authenticated account scope.");return zh(he,()=>{const $e=$.settings||{},Oe=Se?{...X,boardMode:$e.boardMode||X.boardMode,gridPreference:$e.gridPreference||X.gridPreference,handledCaptureIds:$.extension?.handledCaptureIds||X.handledCaptureIds,mode:Wt,settings:$e,stores:Array.isArray($.stores)?$.stores:X.stores,viewState:X.viewState}:{...X,mode:Wt};let Pt=!1,mt=!1;try{Js(vt.safetySnapshot,Qe(q,{reason:"account-cloud-hydration",source:"pre-import-safety-snapshot"})),mt=!0}catch{mt=!1}const Kt=()=>{if(Pt)return;Pt=!0;const rt=Sc(Rs)===he;zh(he,()=>gr(q,{persistMode:rt,persistViewState:!1}))};try{gr(Oe,{persistViewState:!1});
16const rt=Pe(),St=new Set(rt.lists.map(tr=>String(tr?.id||"").trim()).filter(Boolean)),_t=new Map(rt.products.map(tr=>[String(tr?.id||"").trim(),tr]).filter(([tr])=>tr));if(!O.every(({parentId:tr,productId:yr})=>{const Sr=_t.get(String(yr||"").trim()),wr=String(tr||"").trim();return Sr&&String(Sr.listId||"").trim()===wr&&St.has(wr)}))throw Kt(),mi("Account hydration relationships did not survive local persistence.");return{rollback:Kt,safetySnapshotSaved:mt,verifiedSnapshot:rt}}catch(rt){throw Kt(),rt}})},fn=()=>{if(typeof window>"u")return"";const x=$P();if(!x)return"";try{return window.localStorage.getItem(x)||""}catch{return""}},Ke=x=>{if(typeof window>"u")return;const $=$P();if($)try{window.localStorage.setItem($,x)}catch{}},ft=()=>{if(!h())return{visible:!1};const x=fn();if(x)return{decision:x,visible:!1};const $=en(),O=Pe(),q=L($),X=L(O);return{boardCount:$.lists.length,productCount:$.products.length,scopedHasData:X,visible:q&&!X}},lr=()=>{if(!h())return{error:"Sign in before importing local boards.",imported:!1};const x=Pe();if(L(x))return Ke("kept-separate"),{error:"This account already has local boards on this browser.",imported:!1,snapshot:x};const $=en();if(!L($))return Ke("kept-separate"),{error:"",imported:!1,snapshot:x};const O=nr("account-scope-legacy-import");return F($.lists,Wt),$t($.products,Wt,{trackPriceHistory:!1}),Le($.stores),se($.settings),rn($.gridPreference),Pn($.boardMode),Ne($.viewState,$.lists),yt($.handledCaptureIds),Ke("imported"),{error:"",imported:!0,ownerRecovery:Gy({accountId:h(),force:!0,storage:window.localStorage}),safetySnapshotSaved:O,snapshot:Pe()}},Wr=()=>(Ke("kept-separate"),{error:"",keptSeparate:!0}),Dr=(x,{authoritativeCloudOwnerScoped:$=!1}={})=>{if(!ne(x))throw Ra();const O=typeof x.appName=="string"?x.appName.trim():"",q=typeof x.app=="string"?x.app.trim():"",X=x.lists??x.boards,Se=x.products,he=x.settings,$e=O===Fh||UP.has(O)||q===Uh,Oe=Array.isArray(Se)&&Array.isArray(X)&&ne(he);if(O&&O!==Fh&&!UP.has(O)||q&&q!==Uh||!$e&&!Oe)throw Ra();const Pt=Number(x.schemaVersion??x.version??1);if(!Number.isFinite(Pt)||Pt<1||Pt>dm||!Array.isArray(Se)||Se.some(_t=>!ne(_t))||!Array.isArray(X)||X.some(_t=>typeof _t!="string"&&!ne(_t))||!ne(he)||x.productOrder!==void 0&&!Array.isArray(x.productOrder)||x.priceSnapshots!==void 0&&!Array.isArray(x.priceSnapshots)||x.stores!==void 0&&!Array.isArray(x.stores)||x.boardOrder!==void 0&&!Array.isArray(x.boardOrder)||x.listOrder!==void 0&&!Array.isArray(x.listOrder)||x.viewState!==void 0&&!ne(x.viewState)||x.extension!==void 0&&!ne(x.extension)||x.extension?.handledCaptureIds!==void 0&&!Array.isArray(x.extension.handledCaptureIds))throw Ra();const mt=xe(kt(Se,x.productOrder),x.priceSnapshots),Kt=ht(X,mt,x.boardOrder||x.listOrder,{captureListNormalizationProvenance:Ac()&&x.metadata?.source==="cloud-restore",preserveDistinctListIds:$===!0});if(Ac()){const _t=new Map(Se.map(yr=>[String(yr?.id||"").trim(),yr]).filter(([yr])=>yr)),dr=new Set(Kt.map(yr=>String(yr?.id||"").trim()).filter(Boolean)),tr=new Set(X.filter(yr=>yr&&typeof yr=="object").map(yr=>String(yr.id||"").trim()).filter(Boolean));mt.forEach(yr=>{const Sr=_t.get(String(yr?.id||"").trim())||{},wr=String(Sr.listId||Sr.list_id||"").trim(),Mn=String(yr?.listId||yr?.list_id||"").trim();Ec({enabled:!0,listsHydratedBeforeProductNormalization:!1,normalizationDecision:wr===Mn?"preserved-existing":!wr&&Mn?"default-list-fallback":"unknown",parentExists:!!(Mn&&dr.has(Mn)),parentId:Mn,phase:"wishlist-storage-normalization",productId:yr?.id,sourceParentExists:!!(wr&&tr.has(wr))})})}const rt=x.stores===void 0?null:Ee(x.stores),St=ee(he,Kt);return{app:Uh,appName:Fh,exportedAt:x.exportedAt||new Date().toISOString(),lists:Kt,products:mt,stores:rt,boardOrder:Kt.map(_t=>_t.id),listOrder:Kt.map(_t=>_t.id),productOrder:mt.map(_t=>_t.id),settings:St,viewState:Fe(x.viewState||{},Kt),extension:{handledCaptureIds:[...new Set((x.extension?.handledCaptureIds||[]).filter(Boolean))].slice(0,30)},metadata:{...x.metadata&&typeof x.metadata=="object"?x.metadata:{},productCount:mt.length,listCount:Kt.length,storeCount:Array.isArray(rt)?rt.length:0},schemaVersion:dm,version:dm}},kr=()=>Ct(),Gr=()=>{const x=b(h());if(!x||typeof window>"u")return{status:"not-applicable"};try{return Gy({accountId:x,reviewOnly:!0,storage:window.localStorage})}catch{return{accountId:x,automaticAdoptionBlocked:!0,reason:"review-hold-persistence-failed",
16status:"failed"}}},ar=(x,$)=>{if(!b(h()))return x;if(x?.status==="failed"||x?.automaticAdoptionBlocked!==!0)throw mi(`Backup import was stopped because the account ownership review hold could not be persisted ${$}.`);return x},qr=()=>{const x=b(h());if(!x)return{accountId:"",beforeSnapshot:null};const $=Pe();return ar(Gr(),"before importing data"),{accountId:x,beforeSnapshot:$,beforeSnapshotFingerprint:JSON.stringify($)}},tn=(x,$)=>{if(!x?.accountId||!x.beforeSnapshot)throw $;try{gr(x.beforeSnapshot);const O=Pe();if(JSON.stringify(O)!==x.beforeSnapshotFingerprint)throw new Error("The pre-import account snapshot did not survive rollback verification.")}catch(O){throw mi("Backup import failed and the previous account data could not be restored safely.",O)}throw $},hn=x=>{const $=Dr(x),O=qr();try{const q=nr("replace-before-import");$t($.products,Wt,{trackPriceHistory:!1}),F($.lists,Wt),Array.isArray($.stores)&&Le($.stores),rn($.settings.gridPreference),Pn($.settings.boardMode),se($.settings),We(Wt),Ne($.viewState,$.lists),yt($.extension.handledCaptureIds);const X=ar(Gr(),"after importing data"),Se=Tt(Wt),he=ze(Wt);if(Ac()){const $e=new Set(Se.map(Oe=>String(Oe?.id||"").trim()).filter(Boolean));he.forEach(Oe=>{const Pt=String(Oe?.listId||"").trim();Ec({enabled:!0,listsHydratedBeforeProductNormalization:!0,normalizationDecision:"preserved-existing",parentExists:!!(Pt&&$e.has(Pt)),parentId:Pt,phase:"verified-snapshot-reread",productId:Oe?.id,sourceParentExists:!!(Pt&&$e.has(Pt)),storageEvidence:"verified-reread"})})}return{activeList:Ve(Wt,Se),lists:Se,manualStores:W(),products:he,mode:Wt,ownerRecovery:X,safetySnapshotSaved:q,viewState:ue(Wt)}}catch(q){tn(O,q)}},Wn=x=>{const $=Dr(x),O=qr();try{const q=nr("merge-before-import"),X=ze(Wt),Se=Tt(Wt),he=new Set(Se.map(St=>String(St?.id||"").trim()).filter(Boolean)),$e=[...Se];$.lists.forEach(St=>{const _t=String(St?.id||"").trim();if(!_t||he.has(_t)||!es(St)&&yu($e,St.name,{authenticatedOwnerId:h()}))return;const dr=Qs(St.name,$e.length,St);he.add(dr.id),$e.push(dr)});const Oe=new Map(X.map(St=>[St.id,St])),Pt=[...X];$.products.forEach(St=>{const _t=String(St?.listId||St?.list_id||"").trim();if(_t&&!he.has(_t))return;const dr=Oe.get(St.id);if(dr&&aW(dr,St))return;const tr=p({...St,id:dr?Xb():St.id},Pt.length);Oe.set(tr.id,tr),Pt.push(tr)}),F($e,Wt),$t(Pt,Wt,{trackPriceHistory:!1}),Array.isArray($.stores)&&Le(sW(W(),$.stores)),We(Wt);const mt=ar(Gr(),"after importing data"),Kt=Tt(Wt),rt=ze(Wt);if(Ac()){const St=new Set(Kt.map(_t=>String(_t?.id||"").trim()).filter(Boolean));rt.forEach(_t=>{const dr=String(_t?.listId||"").trim();Ec({enabled:!0,listsHydratedBeforeProductNormalization:!0,normalizationDecision:"preserved-existing",parentExists:!!(dr&&St.has(dr)),parentId:dr,phase:"verified-snapshot-reread",productId:_t?.id,sourceParentExists:!!(dr&&St.has(dr)),storageEvidence:"verified-reread"})})}return{activeList:Ve(Wt,Kt),lists:Kt,manualStores:W(),products:rt,mode:Wt,ownerRecovery:mt,safetySnapshotSaved:q,viewState:ue(Wt)}}catch(q){tn(O,q)}},br=()=>{if(typeof window>"u")return a;try{const x=ui(vt.settings)||{},$=lf(vt.gridPreference),O=!!$||Object.hasOwn(x,"gridPreference"),q=$||x.gridPreference,X=m(q);return O&&($!==X&&Su(vt.gridPreference,X),x.gridPreference!==X&&se({...x,gridPreference:X})),X}catch{return a}},rn=x=>{if(!(typeof window>"u"))try{const $=m(x);Su(vt.gridPreference,$),se({...G(),gridPreference:$})}catch($){throw mi($.message||"Grid preference could not be saved.",$)}},nn=()=>{if(typeof window>"u")return s;try{const x=G().boardMode,$=lf(vt.boardMode)||x;return Object.hasOwn(i,$)?$:s}catch{return s}},Pn=x=>{if(!(typeof window>"u"))try{const $=Object.hasOwn(i,x)?x:s;Su(vt.boardMode,$),se({...G(),boardMode:$})}catch($){throw mi($.message||"Board mode could not be saved.",$)}},G=()=>{const x=ui(vt.settings);return x?.version===um?D(x):D(x||{})},se=x=>{Js(vt.settings,D(x))},le=()=>fe(ui(vt.viewState)||{}),ue=(x=ke())=>le().byMode[N()],Ne=(x,$=Tt(Wt))=>{Js(vt.viewState,Fe(x,$))},be=(x,$)=>{const O=N(),q=fe(ui(vt.viewState)||{}),X=J({...q.byMode[O],...$,updatedAt:new Date().toISOString()});Js(vt.viewState,{version:$h,byMode:{...q.byMode,[O]:X}})},Te=(x,$)=>{const O=ue(x);if(O.selectedView==="dashboard"||O.selectedView==="allItems")return null;const q=Array.isArray($)?$:[],X=q.filter(he=>!es(he)),Se=ro(q,O.selectedListName);return X.find(he=>he.id===O.selectedListId)||X.find(he=>O.selectedListSlug&&he.slug===O.selectedListSlug)||(Se&&!es(Se)?Se:null)||null},Ve=(x,$)=>Te(x,$)?.name||r,at=()=>{const x=ui(vt.handledCaptures);
16return Array.isArray(x)?x.filter(Boolean).slice(0,30):[]},yt=(x=[])=>{Js(vt.handledCaptures,[...new Set(x.filter(Boolean))].slice(0,30))};return{addProduct:(x,$)=>Oo([...x,PI(p($,x.length),{createId:et,source:$.priceHistorySource||"created"})]),createList:(x,$,{authenticatedOwnerId:O=""}={})=>{const q=typeof $=="string"?{name:$}:$||{},X=Ye(q.name);if(!X||X===r)return{lists:x,activeList:r};const Se=yu(x,X,{authenticatedOwnerId:O});if(Se)return{lists:x,activeList:Se.name};const he=y(X,x),$e=b(O),Oe=Qs(X,x.length,{...q,id:Sd("list"),isPublic:q.isPublic??!0,slug:he,...$e?{userId:$e}:{}});return{lists:[...x,Oe],activeList:Oe.name}},deleteProduct:(x,$)=>Oo(x.filter(O=>O.id!==$)),deleteList:(x,$,O,q={})=>{const X=x.find(mt=>mt.id===O);if(!X)return{lists:x,products:$,activeList:r};let Se=x.filter(mt=>mt.id!==O);const he=Se.find(mt=>mt.name!==r&&US(mt))||null;let $e=Se.find(mt=>mt.id===q.targetListId)||yu(Se,q.targetListName)||he;const Oe=new Date().toISOString();let Pt=$;if(q.action==="delete")Pt=$.filter(mt=>!pm(mt,X,x));else if(q.action==="archive")Pt=$.map(mt=>pm(mt,X,x)?p({...mt,status:"archived",updatedAt:Oe},mt.sortOrder):mt);else if(q.action==="replacement"||q.action==="autoWishlist"){const mt=Ye(q.action==="autoWishlist"?"Wishlist":q.replacementListName||"Wishlist");$e=yu(Se,mt),$e||($e=Qs(mt||"Wishlist",Se.length,{id:Sd("list"),slug:y(mt||"Wishlist",Se)}),Se=[...Se,$e]),Pt=$.map(Kt=>pm(Kt,X,x)?p({...Kt,category:$e.name,listName:$e.name,listId:$e.id,updatedAt:Oe},Kt.sortOrder):Kt)}else $e&&(Pt=$.map(mt=>pm(mt,X,x)?p({...mt,category:$e.name,listName:$e.name,listId:$e.id,updatedAt:Oe},mt.sortOrder):mt));return{lists:Se,products:Oo(Pt),activeList:r}},exportBackup:kr,findListByNameOrSlug:ZH,importBackup:{merge:Wn,replace:hn,validate:Dr},modes:{demo:Es,personal:Wt},get storageKeys(){return A()},getStorageKeys:A,getAccountScope:h,getRejectedSignedOutWrites:()=>og.slice(),workspaceStorageIsAvailable:()=>!!Sc(Rs),readPendingBoardTrashOperation:S,savePendingBoardTrashOperation:C,clearPendingBoardTrashOperation:I,getUnscopedPersonalDataNotice:ft,importUnscopedPersonalDataToAccount:lr,keepUnscopedPersonalDataSeparate:Wr,commitAccountHydrationSnapshot:Xt,readAccountHydrationSnapshot:st,readBoardMode:nn,readGridPreference:br,readLists:Tt,readManualStores:W,readMode:ke,readProducts:ze,readViewState:ue,captureIdWasHandled:x=>!!(x&&at().includes(x)),readRecoveryNotice:eW,readSettings:G,rememberHandledCaptureId:x=>{x&&Js(vt.handledCaptures,[x,...at().filter($=>$!==x)].slice(0,30))},moveProductToList:(x,$,O,q)=>{const X=$.find(rt=>rt.id===q),Se=x.find(rt=>rt.id===O);if(!X||!Se||Se.listId===X.id&&Se.category===X.name&&Se.listName===X.name)return x;const he=new Date().toISOString(),$e=p({...Se,category:X.name,listName:X.name,listId:X.id,updatedAt:he},x.length),Oe=x.filter(rt=>rt.id!==O),Pt=Oe.reduce((rt,St,_t)=>St.listId===X.id||St.category===X.name||St.listName===X.name?_t:rt,-1),mt=Pt>=0?Pt+1:Oe.length,Kt=[...Oe];return Kt.splice(mt,0,$e),Oo(Kt)},reorderProducts:(x,$,O,q)=>{if(q===r)return Oo(zP(x,$,O));const X=x.filter($e=>$e.category===q||$e.listName===q),Se=zP(X,$,O);if(Se===X)return x;let he=0;return Oo(x.map($e=>{if($e.category!==q&&$e.listName!==q)return $e;const Oe=Se[he];return he+=1,Oe}))},reorderProductsToSequence:(x,$=[],O)=>{if(!Array.isArray($)||$.length<2)return x;const q=[...new Set($)],X=O===r?x.filter(Oe=>q.includes(Oe.id)):x.filter(Oe=>q.includes(Oe.id)&&(Oe.category===O||Oe.listName===O));if(X.length!==q.length||X.map(Oe=>Oe.id).every((Oe,Pt)=>Oe===q[Pt]))return x;const he=new Map(X.map(Oe=>[Oe.id,Oe]));let $e=0;return Oo(x.map(Oe=>{if(!he.has(Oe.id))return Oe;const Pt=he.get(q[$e]);return $e+=1,Pt||Oe}))},reorderLists:(x,$,O)=>{const q=x.findIndex($e=>$e.id===$),X=O==="up"?q-1:q+1;if(q<0||X<0||X>=x.length)return x;const Se=[...x],[he]=Se.splice(q,1);return Se.splice(X,0,he),Se.map(($e,Oe)=>Qs($e.name,Oe,{...$e,sortOrder:Oe}))},resetDemo:te,resetPersonal:me,saveBoardMode:Pn,saveGridPreference:rn,saveLists:F,saveManualStores:Le,saveMode:We,saveProducts:$t,saveSettings:se,saveViewState:be,saveLocalSafetySnapshot:nr,resolveSavedActiveList:Ve,setAccountScope:f,clearRecoveryNotice:tW,updateProduct:(x,$)=>Oo(x.map((O,q)=>{if(O.id!==$.id)return O;const Se=bs($,{isPlaceholder:Vn}).hasConflict?{}:lp(O,$,{isPlaceholder:Vn}),he=p({...O,...$,...Se,updatedAt:new Date().toISOString()},q,O);return _I(O,he,{createId:et,source:$.priceHistorySource||"manual-edit"})})),updateList:(x,$,O,q={},{authenticatedOwnerId:X=""}={})=>{const Se=x.find(St=>St.id===O);if(!Se)return{lists:x,products:$,activeList:r};const he=Ye(q.name??Se.name);if(!he||he===r)return{lists:x,products:$,activeList:Se.name};const $e=yu(x,he,{authenticatedOwnerId:X,excludeListId:O});if($e)return{lists:x,products:$,activeList:$e.name};const Oe=new Date().toISOString(),Pt=y(he,x,O),mt=Qs(he,Se.sortOrder,{...Se,...q,name:he,slug:Pt,updatedAt:Oe}),Kt=x.map(St=>St.id===O?mt:St),rt=$.map(St=>pm(St,Se,x)?p({...St,category:mt.name,listName:mt.name,listId:mt.id,updatedAt:Oe},St.sortOrder):St);return{lists:Kt,products:rt,activeList:mt.name}}}}const Rr=w2(),xR=Rr.priceTrackingEnabled,uu=15e3,rr="Dashboard",cW=[],IR=[],Yy=IR.map(e=>e.name),Ka="Wishlist",HP=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,Vu=6,pu=60,cl=280,lW=new Set(["image/jpeg","image/png","image/webp"]),dW="image/jpeg,image/png,image/webp",uW=10*1024*1024,Mm=Object.freeze({cloudAccountDeleti
16onEnabled:Rr.accountDeletionBetaEnabled,passwordResetEnabled:Rr.passwordResetBetaEnabled,profileAvatarEditingEnabled:!0}),Ns=Object.freeze({accountDeletion:"Account deletion is not available during beta. Contact us to remove a test account.",avatar:"Profile photo editing is paused for beta.",passwordReset:"Password reset is temporarily unavailable during beta. Contact support if you need help accessing your account."}),AR=["image/jpeg","image/png","image/webp"],pW=12*1024*1024,mW=1400,WP=16e5,_m=hR,fW=["archivedAt","priceAmount","purchasedAt"],hW=1e4,gW=12e3,bW=15e3,vW=12,GP="Could not fetch product details. You can still add it manually.",yW="Could not find product details. You can still add it manually.",SW="mylist.imageBackgroundDebug",wW=3,PR=260,CW=220,xW=180,Aw=.5,Pw=4,IW=.01,_w=20,Ew=66,AW=9,PW=13,_W=190,hx=64,EW=32,kW=18,NW=.82,jW=132,RW=.9,LW=.72,BW=140,TW=5,DW=25,OW="mylist.sidebarMenuCollapsed",Ai=()=>{},MW=new Set,_R=[],mu=(e,t,r="Operation timed out.")=>new Promise((a,s)=>{const o=globalThis.setTimeout(()=>{s(new Error(r))},t);Promise.resolve(e).then(i=>{globalThis.clearTimeout(o),a(i)},i=>{globalThis.clearTimeout(o),s(i)})}),UW=(e,t,r)=>{const a=e.indexOf(t),s=e.indexOf(r);if(a<0||s<0||a===s)return e;const o=[...e],[i]=o.splice(a,1);return o.splice(s,0,i),o},FW=(e,t,r)=>{const a=[...new Set(t)].filter(l=>e.includes(l));if(!a.length||!r||a.includes(r))return e;const s=new Set(a),o=e.filter(l=>!s.has(l)),i=o.indexOf(r);if(i<0)return e;const c=[...o.slice(0,i),...a,...o.slice(i)];return c.every((l,u)=>l===e[u])?e:c},$W=(e,t)=>{if(!Array.isArray(t)||t.length===0)return e;const r=new Map(e.map(s=>[s.id,s])),a=t.map(s=>r.get(s)).filter(Boolean);return a.length!==e.length?e:a},qP=e=>typeof CSS<"u"&&CSS.escape?CSS.escape(String(e)):String(e).replace(/\\/g,"\\\\").replace(/"/g,'\\"'),zW=e=>`data:image/svg+xml;utf8,${encodeURIComponent(`
17    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 520" preserveAspectRatio="xMidYMid slice">
18      <rect width="360" height="520" fill="#163A5F"/>
19      ${e}
20    </svg>
21  `)}`,Ja="compact",VW="vertical",sd=5,YP={podWidth:"180px",podAspectRatio:"0.69",columnGap:"34px",rowGap:"34px"},ra={compact:{label:"Compact",...YP},expanded:{label:"Expanded",podWidth:"264px",podAspectRatio:YP.podAspectRatio,columnGap:"36px",rowGap:"36px"}},HW=25/24,WW=14,GW=5,KP=18,qW=WW+KP+GW+KP,ER=e=>(Number.parseFloat(e)||0)*HW+qW,Hu={detailsHeight:55.7/264,bodyPadding:13.2/264,mediaGap:11.7/264},YW=e=>e==="expanded"?"expanded":"compact",sb=1680,XP=900,KW=.86,XW=.9,gx=721,kR=7,JW=6,JP=(e,t=!1)=>{if(t&&e>=sb){if(e>=2680)return 10;if(e>=2360)return 9;if(e>=2040)return 8}return e>=sb?kR:JW},QP={compact:{podWidth:156,columnGap:24,rowGap:26},expanded:{podWidth:228,columnGap:28,rowGap:28}},QW=(e,t,r)=>Math.min(Math.max(e,t),r),$o=e=>`${Math.round(e*10)/10}px`,Ky=(e,t,r=0)=>{const a=Number.parseFloat(e);return Number.isFinite(a)?$o(Math.max(r,a*t)):e},ZP=({viewportWidth:e,viewportHeight:t})=>{if(e<gx)return 1;const r=e>=sb?1:e/sb,a=t>=XP?1:t/XP;return QW(Math.min(r,a),KW,1)},Cl=(e,t)=>{const r=ra[e]??ra[Ja];if(t>=.995)return r;const a=QP[e]??QP[Ja],s=t*XW;return{...r,podWidth:Ky(r.podWidth,t,a.podWidth),columnGap:Ky(r.columnGap,s,a.columnGap),rowGap:Ky(r.rowGap,s,a.rowGap)}},ZW={vertical:"Vertical grid",horizontal:"Horizontal board"},e3={light:"Light",dark:"Dark"},t3=e=>window.SaveBoardThemeResolver?.normalizeThemePreference(e)||"light",r3=()=>typeof window<"u"&&window.matchMedia?.("(prefers-color-scheme: dark)").matches?"dark":"light",n3=()=>{const[e,t]=d.useState(r3);return d.useEffect(()=>{const r=window.matchMedia?.("(prefers-color-scheme: dark)");if(!r)return;const a=()=>t(r.matches?"dark":"light");return r.addEventListener?.("change",a),()=>r.removeEventListener?.("change",a)},[]),e},NR={fast:{label:"Fast",detail:"Prioritises smoother scrolling and quicker interactions."},balanced:{label:"Balanced",badge:"Default",detail:"Keeps Saveboard image quality and motion balanced."},showcase:{label:"Showcase",detail:"Keeps the richest visual treatment for stronger devices."}},kw=e=>Object.prototype.hasOwnProperty.call(NR,e)?e:"balanced",Nl=(e="",t
21=wd)=>{const r=Cb(e);return r?Hm(r):t===""?"":Hm(t)},Qb={active:"Wishlist",purchased:"Purchased",archived:"Archive",trash:"Trash"},a3=new Set(["active","purchased","archived"]),Nw=[{label:"All Items",value:"active"},{label:"Purchased",value:"purchased"},{label:"Archive",value:"archived"},{label:"Trash",value:"trash"}],Zb=[{value:"unknown",label:"Unknown"},{value:"in_stock",label:"In stock"},{value:"low_stock",label:"Low stock"},{value:"out_of_stock",label:"Out of stock"},{value:"unavailable",label:"Unavailable"},{value:"preorder",label:"Preorder"},{value:"discontinued",label:"Discontinued"}],s3=new Set(Zb.map(e=>e.value)),o3=new Set(["manual","imported","checked"]),i3=new Set(["manual","weekly","daily"]),e_=Object.freeze(Zb.reduce((e,t)=>(e[t.value]=t.label,e),{})),va=e=>a3.has(e)?e:"active",fu=e=>Object.hasOwn(Qb,e)?e:"active",Xy=(e,t,r=new Date().toISOString())=>{const a=va(t);return{...e,status:a,archivedAt:a==="archived"?e.archivedAt||r:void 0,purchasedAt:a==="purchased"?e.purchasedAt||r:void 0}},ev=(e="")=>String(e||"").trim().toLowerCase().replace(/[\s-]+/g,"_"),bx=(e="unknown")=>{const t=ev(e);return s3.has(t)?t:"unknown"},c3=(e="")=>{const t=ev(e);return o3.has(t)?t:""},l3=(e="manual")=>{const t=ev(e);return i3.has(t)?t:"manual"},d3=(e="")=>{const t=ev(e).replace(/_/g,"-");return["success","failed","blocked","timeout","low-confidence"].includes(t)?t:""},ob=(e="")=>{const t=new Date(e);return Number.isFinite(t.getTime())?t.toISOString():""},u3=e=>{const t=Number(e);return Number.isFinite(t)?Math.max(0,Math.min(1,t)):null},vx=(e=null)=>{const t=e&&typeof e=="object"&&!Array.isArray(e)?e:{status:e},r=bx(t.status),a=c3(t.source),s=ob(t.checkedAt||t.checked_at),o=ob(t.updatedAt||t.updated_at),i=u3(t.confidence),c=String(t.message||"").trim();return r!=="unknown"||a||s||o||i!==null||c?{status:r,...a?{source:a}:{},...c?{message:c}:{},...s?{checkedAt:s}:{},...o?{updatedAt:o}:{},...i!==null?{confidence:i}:{}}:null},ib=(e={})=>vx(e.availability)||{status:"unknown"},Vh=e=>e===!0||String(e??"").trim().toLowerCase()==="true"||String(e??"").trim()==="1",jR=(e=null)=>{if(!e||typeof e!="object"||Array.isArray(e))return null;const t=Vh(e.enabled),r=Vh(e.alertOnBackInStock??e.alert_on_back_in_stock),a=Vh(e.alertOnLowStock??e.alert_on_low_stock),s=Vh(e.alertOnOutOfStock??e.alert_on_out_of_stock),o=l3(e.cadence),i=ob(e.lastCheckedAt||e.last_checked_at),c=ob(e.nextCheckAt||e.next_check_at),l=d3(e.lastCheckStatus||e.last_check_status),u=Number(e.failCount??e.fail_count),p=Number.isFinite(u)&&u>0?Math.floor(u):0;return t||r||a||s||o!=="manual"||i||c||l||p>0?{enabled:t,...r?{alertOnBackInStock:!0}:{},...a?{alertOnLowStock:!0}:{},...s?{alertOnOutOfStock:!0}:{},...o!=="manual"?{cadence:o}:{},...i?{lastCheckedAt:i}:{},...c?{nextCheckAt:c}:{},...l?{lastCheckStatus:l}:{},...p>0?{failCount:p}:{}}:null},p3=(e,t=null,{recordedAt:r=new Date().toISOString()}={})=>{const a=bx(e);if(a==="unknown")return;const s=vx(t);return s?.status===a?s:{status:a,source:"manual",checkedAt:r,updatedAt:r}},RR=(e="unknown")=>e_[bx(e)]||e_.unknown,t_=[{id:"getting-started",title:"Getting started",copy:"Saveboard is a visual wishlist. Save the things you want to buy, arrange them on boards, and choose whether to share links, invite collaborators or publish. Boards are saved to your account, so you can sign in on any device and pick up where you left off."},{id:"creating-lists",title:"Creating boards",copy:"Use Create in the sidebar, or Create board from the More menu on a phone, to add a board. New boards are private: only you and any collaborators can see them. Open a board to add and arrange items, and use Board actions to rename, sort or delete it. Deleting asks you to confirm first."},{id:"adding-products",title:"Saving items",copy:"Open a board and choose Add item, or press N. Paste a product link and choose Fetch details to fill in the title, price and image, or enter the details yourself. Each item can carry a price, brand, link, image, private notes and an optional public note."},{id:"chrome-extension",title:"Chrome extension",copy:"The Saveboard Chrome extension saves the product page you are looking at straight to a board, without leaving the shop. If Saveboard is not open, the capture waits in the extension until you choose to open Saveboard from it, and is added then."},{id:"editing-products",title:"Editing items",copy:"Open an item to see its details, edit it, move it to another board, mark it purchased or archive it. Items you remove go to Trash, where they can be restored."},{id:"images",title:"Adjusting images",copy:"Upload, paste or drag in an image, or use an image link. Drag the preview to reposition it, use the arrow keys for small nudges, and fine-tune fit, zoom and position with the controls."},{id:"grid-board",title:"Grid and horizontal views",copy:"Each board can be shown as a vertical grid or a horizontal board, at the density you prefer. Drag items to reorder them in Manual order."}
21,{id:"search-sort",title:"Searching and sorting",copy:"Search finds items across your boards. Each board remembers its own sort, and sorting never changes the manual order unless you drag items."},{id:"purchased-archived",title:"Purchased, archived and trashed",copy:"Purchased marks an item as bought. Archive takes an item off the active board but keeps it in Saveboard. Trash holds items you remove so they can be restored."},{id:"backups",title:"Your data",copy:"Boards are saved to your account as you work and follow you to any device you sign in on. Settings › Data can also export a JSON backup of your boards, items, notes and image adjustments, and import one later."},{id:"public-preview",title:"Private, public and sharing",copy:"Boards are private by default. To publish one, choose a username on your Profile, set your profile to Public, then set the board to Public. It appears on your public profile at saveboard.co/u/your-username and never shows private notes. Share board can create a private link. Anyone with the link must sign in to SaveBoard first. The link remains valid until you revoke it; making your profile private does not revoke it. Invite collaborators lets someone edit or view a board with you."},{id:"discover",title:"Profile and Discover",copy:"Profile is your public page: your username, public boards, followers and following. Discover shows public boards picked by Saveboard. Open one to see how a board feels, and follow the people behind it."},{id:"keyboard-shortcuts",title:"Keyboard shortcuts",copy:"Press ? for the shortcuts panel. N adds an item, / focuses search, and Cmd+K or Ctrl+K opens the command palette for actions such as switching boards or opening settings."},{id:"settings",title:"Settings",copy:"Settings is grouped into Appearance, Defaults, Notifications and Data, including light and dark themes."},{id:"troubleshooting",title:"Troubleshooting",copy:"Broken images fall back to a quiet placeholder and can be replaced by editing the item. If a change made on another device has not appeared yet, bring Saveboard to the foreground there: boards refresh when the app regains focus. Signing out only signs out the device you are using."}];function Ol({as:e="span",className:t="",trademark:r=!0,ariaLabel:a="Saveboard",variant:s="auto",...o}){return n.jsxs(e,{className:["saveboardBrand",t].filter(Boolean).join(" "),"aria-label":a,...o,children:[n.jsx(mE,{"aria-hidden":"true",className:"brandGraphic",markOnly:s==="monochrome"}),r?n.jsx("sup",{"aria-hidden":"true",children:"™"}):null]})}function LR({alt:e="Saveboard",className:t="",...r}){const a=r["aria-hidden"]===!0||r["aria-hidden"]==="true"||!e;return n.jsx(mE,{...r,"aria-label":a?void 0:e,"aria-hidden":a||void 0,className:t,markOnly:t.includes("mobileAppLogo")})}const Um={manual:"Manual order",newest:"Recently added",oldest:"Oldest added",priceAsc:"Price low to high",priceDesc:"Price high to low",titleAsc:"A–Z",titleDesc:"Z–A"},bc=e=>Object.hasOwn(Um,e)?e:"manual",jn=zW(`
22  <rect width="360" height="520" fill="#163A5F"/>
23  <style>:root { --font-ui: "Geist"; }</style>
24  <g fill="#fcfcfa" font-family="var(--font-ui)" font-size="31" font-weight="700" letter-spacing="0">
25    <text x="96" y="272">Save</text>
26    <circle cx="181" cy="262" r="7.5"/>
27    <text x="197" y="272">Board</text>
28  </g>
29`),m3=(e="")=>{const t=String(e||"").trim();if(!t.startsWith("data:image/svg+xml"))return"";const r=t.indexOf(",");if(r===-1)return"";let a=t.slice(r+1);if(/;base64/i.test(t.slice(0,r)))try{a=typeof globalThis.atob=="function"?globalThis.atob(a):a}catch{return""}for(let s=0;s<3;s+=1)try{const o=decodeURIComponent(a);if(o===a)break;a=o}catch{break}return a},qo=(e="")=>{const t=String(e||"").trim();if(!t)return!1;if(t===jn)return!0;const r=m3(t);if(!r||!/<svg\b/i.test(r)||/<image\b/i.test(r))return!1;const a=/\bSave\s*board\b/i.test(r)||/\bSave\b/i.test(r)&&/\bBoard\b/i.test(r),s=/<rect\b[^>]*width=["'](?:360|100%)["'][^>]*height=["'](?:520|100%)["']/i.test(r),o=/#(?:163a5f|102f4e|eaf0f6|9f1d35|ef4444|dc2626|b91c1c|b11226|c12632)\b/i.test(r);return a||s&&o},df=(e="")=>{const t=String(e||"").trim();return t&&!qo(t)?t:""},BR=e=>{const t=e.currentTarget.closest(".productImageWindow");t&&(e.currentTarget.classList.add("productImageFallback"),t.classList.add("hasPlaceholderImage")),!e.currentTarget.dataset.fallbackApplied&&(e.currentTarget.dataset.fallbackApplied="true",e.currentTarget.src=jn)},jw=e=>{const t=e?.closest(".listPodCoverTile, .boardCoverItemThumb");t?.classList.remove("hasImage"),t?.classList.add("isPlaceholder"),e?.classList.add("productImageFallback")},Rw=e=>{const t=e.currentTarget.closest(".listPodCoverTile, .boardCoverItemThumb");t?.classList.remove("isPlaceholder"),t?.classList.add("hasImage"),e.currentTarget.classList.remove("productImageFallback")},f3=[],Go=e=>{if(!e)return"Manual entry";try{return new URL(e).hostname.replace(/^www\./,"")}catch{return e.replace(/^https?:\/\//,"").replace(/^www\./,"").split("/")[0]||"Manual entry"}},TR=new Set(["MADE.COM"]),Nc=e=>{const t=Ye(e||"");if(!t)return"";
29try{const r=new URL(/^[a-z][a-z\d+.-]*:\/\//i.test(t)?t:`https://${t}`).hostname.replace(/^www\./i,"");return r.includes(".")?r:t}catch{return t.replace(/^(?:https?:)?\/\//i,"").replace(/^www\./i,"").split(/[/?#]/)[0]||t}},DR=e=>{const t=Ye(e||"");return!t||TR.has(t)?!1:/^(?:(?:https?:)?\/\/|www\.)/i.test(t)||/^[a-z0-9-]+(?:\.[a-z0-9-]+)+(?:[/:?#]|$)/i.test(t)},gd=e=>`/share/${encodeURIComponent(e)}`,ta="/discover",OR="/profile/preview",_d="/privacy",tv="/terms",ig="/search",yc="/stores",Jy="/updates",cg=(e,t)=>`/boards/${encodeURIComponent(String(e||""))}/items/${encodeURIComponent(String(t||""))}`,Qy=(e="")=>{const t=String(e).match(/^\/boards\/([^/]+)\/items\/([^/]+)\/?$/);if(!t)return null;try{const r=decodeURIComponent(t[1]).trim(),a=decodeURIComponent(t[2]).trim();return r&&a?{boardId:r,itemId:a}:null}catch{return null}},r_=e=>`${yc}/${encodeURIComponent(e)}`,h3=e=>{if(!String(e||"").startsWith(`${yc}/`))return null;const t=String(e).slice(yc.length+1);if(!t||t.includes("/"))return null;try{return Tr(decodeURIComponent(t))}catch{return null}},g3=(e="")=>e==="/auth/callback"||e==="/auth/callback]",Di=e=>Ye(e).toLowerCase().replace(/&/g,"and").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"wishlist",b3=e=>{if(!e.startsWith("/share/"))return"";try{return Ye(decodeURIComponent(e.replace("/share/","")))}catch{return""}},MR=e=>String(e||"").match(/^\/u\/([^/]+)(?:\/boards\/([^/]+))?\/?$/),Lw=e=>{const t=MR(e);if(!t)return"";try{return decodeURIComponent(t[1]).trim().replace(/^@+/,"").toLowerCase()}catch{return""}},n_=e=>{const t=MR(e);if(!t?.[2])return"";try{return decodeURIComponent(t[2]).trim()}catch{return""}},ba={captureId:120,title:180,url:1200,image:1600,price:80,currency:12,brand:120,source:120,size:120,colour:120,variant:120,targetListName:120,targetListSlug:120,mode:20,notes:1e3,publicNote:500},a_=["ean_13","ean_8","upc_a","upc_e","code_128"],v3=96,y3="Barcode scanning is not supported in this browser yet. You can still add the product manually.",S3=[{id:"manual",label:"Manual"},{id:"url",label:"From URL"},{id:"barcode",label:"Scan barcode"}],La=(e,t)=>{const r=e.get(t);if(!r)return"";const a=ba[t]||500,s=String(r).trim();return t==="image"||t==="url"?s.length<=a?s:"":s.replace(/\s+/g," ").slice(0,a)},aa=e=>{const t=e.trim();if(!t)return"";try{const r=new URL(t);return["http:","https:"].includes(r.protocol)&&!r.username&&!r.password?r.toString():""}catch{return""}},w3=(e="")=>{const t=String(e||"").trim().toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/g,"");if(!t||t.includes(":")||t==="localhost"||t==="0.0.0.0"||t==="::1"||t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".internal")||t.endsWith(".test"))return!0;const r=t.split(".");if(r.length===4&&r.every(a=>/^\d+$/.test(a)&&Number(a)>=0&&Number(a)<=255)){const[a,s]=r.map(Number);return a===10||a===127||a===0||a===172&&s>=16&&s<=31||a===192&&s===168||a===169&&s===254}return!1},uf=e=>{const t=aa(String(e||""));if(!t)return"";try{const r=new URL(t);return r.hostname&&!w3(r.hostname)?r.toString():""}catch{return""}},UR=(e,t="")=>(Array.isArray(e)?e:[]).filter(r=>xu(r,{authenticatedOwnerId:t})),FR=(e,t,r="")=>{const a=Ye(e?.targetListName||"").toLowerCase(),s=Ye(e?.targetListSlug||""),o=s?Di(s):"";return!a&&!o?null:UR(t,r).find(i=>{const c=Ye(i.name||i);return c.toLowerCase()===a||Di(c)===o})||null},s_=(e,t,r="")=>{const a=Ye(e||"").toLowerCase();return!a||a===rr.toLowerCase()?null:UR(t,r).find(s=>Ye(s.name||s).toLowerCase()===a)||null},Hh=(e,t,r,a="")=>{const s=FR(e,t,a);if(s)return{lists:t,targetList:s,targetListMatched:!0,createdList:!1};const o=s_(r,t,a);if(o)return{lists:t,targetList:o,targetListMatched:!1,createdList:!1};const i=new Set((Array.isArray(t)?t:[]).map(p=>p?.id).filter(Boolean)),l=ct.createList(t,{name:Ka},{authenticatedOwnerId:a}).lists,u=l.find(p=>!i.has(p.id))||s_(Ka,l,a);return{lists:l,targetList:u||null,targetListMatched:!1,createdList:l.length!==t.length}},Zy=(e,t,r,a,s={})=>{const o=new Date().toISOString(),i=df(e.imageUrl||e.image||""),c=Nc(e.source)||Go(e.url),l=Ye(e.title)||Go(e.url)||"Untitled item",u=Hm(r),p=Nl(e.price,e.currency||u);return{id:s.productId||Xb(),...s.ownerId?{userId:s.ownerId}:{},createdAt:o,updatedAt:o,title:l,price:e.price?.trim()||`${u}--`,currency:p,brand:Ye(e.brand),size:Ye(e.size),colour:Ye(e.colour),variant:Ye(e.variant),category:t.name,listName:t.name,listId:t.id,source:c,barcode:xl(e.barcode),privateNotes:e.privateNotes?.trim()||"",publicNotes:e.publicNotes?.trim()||"",priceHistorySource:"extension-save",url:e.url||"",imageUrl:i,image:i||jn,status:"active",...Kb(a)}},o_=e=>ct.captureIdWasHandled(e),mm=e=>ct.rememberHandledCaptureId(e),C3=(e,t,r)=>{const a=new URLSearchParams(e),s=String(a.get("url")||"").trim(),o=String(a.get("image")||"").trim(),i=La(a,"url"),c=La(a,"image"),l=aa(i),u=aa(c),p=La(a,"source"),m=La(a,"brand"),f=La(a,"size"),h=La(a,"colour"),b=La(a,"variant"),v=La(a,"title"),S=La(a,"notes"),C=La(a,"publicNote"),I=La(a,"targetListName"),A=La(a,"targetListSlug"),k=La(a,"mode")==="quick"?"quick":"review",E=La(a,"currency"),y=La(a,"price"),N=[];return s&&(!i||!l)&&N.push("The captured page URL was not usable."),o&&(!c||!u)&&N.push("The captured image URL was not usable."),{draft:{title:v,price:y,currency:Nl(E||y,""),brand:m,size:f,colour:h,variant:b,url:l,imageUrl:u,image:u||"",source:Nc(p)||Go(l),privateNotes:S,publicNotes:C,category:t,captureId:La(a,"captureId"),targetListName:I,targetListSlug:A,targetListMatched:!1,captureMode:k,captureSource:a.get("from")==="edit"?"edit":"chrome",...Kb(r)},message:N.join(" ")}},un=(e,t=500)=>String(e||"").replace(/\s+/g," ").trim().slice(0,t),i_=(e,t)=>{const r=String(e||"").trim();return r.length<=t?r:""},$R=(e,t,r)=>{const a=i_(e?.url,ba.url),s=i_(e?.selectedImage||e?.image,ba.image),o=aa(a),i=aa(s),c=un(e?.title,ba.title)||(o?Go(o):""),l=un(e?.source,ba.source),u=un(e?.note||e?.notes,ba.notes),p=un(e?.publicNotes||e?.publicNote,ba.publicNote),m=un(e?.targetListName,ba.targetListName),f=un(e?.targetListSlug,ba.targetListSlug),h=un(e?.currency,ba.currency),b=un(e?.price,ba.price);return{title:c,price:b,currency:Nl(h||b,""),brand:un(e?.brand,ba.brand),size:un(e?.size,ba.size),colour:un(e?.colour,ba.colour),variant:un(e?.variant,ba.variant),url:o,imageUrl:i,image:i||"",source:Nc(l)||Go(o),privateNotes:u,publicNotes:p,category:t,captureId:un(e?.i
29d||e?.captureId,ba.captureId),targetListName:m,targetListSlug:f,targetListMatched:!1,captureMode:"import",captureSource:"chrome-extension",createdAt:un(e?.createdAt,80),...Kb(r)}},x3=(e,t,r)=>{const a=new URLSearchParams(e),s=a.get("captures");if(!s)return{drafts:[],extensionId:un(a.get("extensionId"),120),message:"No extension saves to import."};try{const o=JSON.parse(s);return{drafts:(Array.isArray(o)?o:[]).slice(0,20).map(c=>$R(c,t,r)),extensionId:un(a.get("extensionId"),120),message:""}}catch{return{drafts:[],extensionId:un(a.get("extensionId"),120),message:"No extension saves to import."}}},I3=(e={})=>({captureId:un(e.captureId||e.id,ba.captureId),title:un(e.title,90),url:un(e.url,180),targetListName:un(e.targetListName||e.category,ba.targetListName),source:un(e.captureSource,80)}),ll=(e,t={})=>{},c_=(e,t={})=>{},l_=(e,t)=>{const r=(Array.isArray(t)?t:[]).filter(Boolean);if(!(!e||!r.length||!window.chrome?.runtime?.sendMessage))try{window.chrome.runtime.sendMessage(e,{type:"MY_LIST_IMPORT_COMPLETE",captureIds:r,importedAt:new Date().toISOString()},()=>{})}catch{}},pf="saveboardNavigationKey",zR=new Map;let Ru="",mf=null,Fm=null,Lu=0,Bw=null,Tw=null,Dw=null;const d_=e=>{Bw=typeof e=="function"?e:null},Bu=()=>String(window.history.state?.[pf]||""),cb=()=>`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,VR=()=>`${window.location.pathname}${window.location.search}${window.location.hash}`,HR=()=>{Ru&&zR.set(Ru,{x:window.scrollX,y:window.scrollY})},Wh=()=>{Fm={at:performance.now(),intent:"replace"}},u_=(e,t=0)=>{window.scrollTo({behavior:"instant",left:t,top:e});let r=window.scrollY,a=24;const s=()=>{a<=0||Math.abs(window.scrollY-e)<=1||Math.abs(window.scrollY-r)>1||(a-=1,window.scrollTo({behavior:"instant",left:t,top:e}),r=window.scrollY,window.requestAnimationFrame(s))};Math.abs(r-e)>1&&window.requestAnimationFrame(s)},Ft=(e,t={})=>{HR(),e===VR()?(mf="replace",window.history.replaceState({...window.history.state||{},...t,[pf]:Bu()||cb()},"",e)):(mf="push",window.history.pushState({...t,[pf]:cb()},"",e)),window.dispatchEvent(new PopStateEvent("popstate"))},ul=(e,t=window.history.state||{})=>{mf="replace",window.history.replaceState({...t,[pf]:Bu()||cb()},"",e),window.dispatchEvent(new PopStateEvent("popstate"))},A3=(e,t)=>
29{const r=new Blob([JSON.stringify(e,null,2)],{type:"application/json"});Ow(r,t)},Ow=(e,t,r="text/plain")=>{const a=e instanceof Blob?e:new Blob([e],{type:r}),s=URL.createObjectURL(a),o=document.createElement("a");o.href=s,o.download=t,document.body.append(o),o.click(),o.remove(),URL.revokeObjectURL(s)},P3=()=>`saveboard-backup-${new Date().toISOString().slice(0,10)}.json`,p_="This does not look like a valid Saveboard backup.",_3=(e,t)=>`saveboard-${Di(`${e}-${Qb[t]||t}`)}-${new Date().toISOString().slice(0,10)}.csv`,E3=(e={})=>`saveboard-${Di(e.name||e.slug||"board")}-qr-code.png`,k3=e=>{const t=eC(e,{isPlaceholder:qo});return uf(t)},xl=(e="")=>String(e).replace(/\s+/g,"").trim().slice(0,v3),N3=async()=>{if(typeof window>"u"||typeof window.BarcodeDetector!="function")return[];if(typeof window.BarcodeDetector.getSupportedFormats!="function")return a_;const e=await window.BarcodeDetector.getSupportedFormats();return a_.filter(t=>e.includes(t))},yx=e=>typeof e=="string"?e.trim():String(e?.url||"").trim(),j3=(e=[],t="")=>{const r=Array.isArray(e)?e:[],a=t?[...r,{url:t,source:"Meta image"}]:r,s=new Set,o=[];return a.forEach(i=>{const c=yx(i);if(!c)return;let l;try{l=new URL(c)}catch{return}if(!["http:","https:"].includes(l.protocol))return;const u=l.toString();s.has(u)||(s.add(u),o.push({url:u,source:Ye(i?.source||"")||"Image"}))}),o.slice(0,vW)},R3=(e={},t=[])=>{const r=!!(e.title||e.brand||e.price||e.description||e.imageUrl||t.length),a=!!(e.imageUrl||t.length);return r?a?!e.title||!e.price?"Fetched what was available. Review before saving.":"Fetched product details. Review before saving.":"Fetched what was available. Add an image manually if needed.":yW},L3=e=>{const t=String(e?.message||"").toLowerCase();return e?.name==="AbortError"||t.includes("too long")||t.includes("timeout")?GP:t.includes("blocked")||t.includes("protected")||t.includes("403")?"This page could not share product details. You can still add it manually.":t.includes("read")||t.includes("html")||t.includes("content-type")?"Could not read product details from that page. You can still add it manually.":GP},eS=(e="")=>e==="no-price-found"||e==="low-confidence"?"Could not find a reliable price.":e==="rate-limited"?"You've reached today's manual check limit.":"Could not check this product right now.",B3=(e
29={},t={})=>{const r=On(e.price),a=Number(e.confidence);if(!e.ok||!ts(r)||!Number.isFinite(a)||a<.75)return null;const s=Us({price:r,currency:e.currency||t.currency});return!Number.isFinite(s.amount)||!s.currency?null:{parsedPrice:s,price:r,priceSource:e.source||"check-price"}},T3=(e={})=>ts(e.price)?On(e.price):"not saved",D3=(e,t)=>{const r=Qb[t]||"Wishlist";return e===rr?r:`${e} — ${r}`},O3=(e={})=>{const t=String(e.price||"").trim();return t&&t!=="$--"?t:""},M3=(e,t)=>{const r=[e,""];return t.forEach((a,s)=>{const o=O3(a);r.push(`${s+1}. ${a.title}${o?` — ${o}`:""}`),a.brand&&a.brand!=="Unlisted"&&r.push(`   ${a.brand}`),a.url&&r.push(`   ${a.url}`),a.publicNotes&&r.push(`   ${a.publicNotes}`),r.push("")}),r.join(`
30`).trim()},WR=e=>e.map(t=>aa(String(t.url||""))).filter(Boolean),U3=e=>WR(e).join(`
31`),F3=e=>{let t=0,r=0;return e.forEach(a=>{try{const s=window.open(a,"_blank");s?(s.opener=null,t+=1):r+=1}catch{r+=1}}),{blockedCount:r,openedCount:t}},$3=(e="")=>{const t=String(e??"");return/[",\n\r]/.test(t)?`"${t.replace(/"/g,'""')}"`:t},z3=e=>{const t=["title","price","currency","brand","url","list","status","createdAt","updatedAt","imageUrl","publicNotes","privateNotes"],r=e.map(a=>[a.title,a.price,a.currency||Nl(a.price,""),a.brand,a.url,a.category,va(a.status),a.createdAt,a.updatedAt,k3(a),a.publicNotes||"",a.privateNotes||""]);return[t,...r].map(a=>a.map($3).join(",")).join(`
32`)},Tu=async e=>{if(navigator.clipboard?.writeText&&window.isSecureContext){await navigator.clipboard.writeText(e);return}const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.opacity="0",document.body.append(t),t.select();const r=document.execCommand("copy");if(t.remove(),!r)throw new Error("clipboard-copy-failed")},Qa=(e="")=>{const t=String(e||"").startsWith("/")?String(e||""):`/${e||""}`;return typeof window>"u"||!window.location?.origin?t:new URL(t,window.location.origin).toString()},m_="Saveboard",f_="Save products to visual boards and track the things you want to come back to.",GR="/saveboard-social-preview.png",lb="Saveboard",lg=(e="",t="")=>String(e||t||"").replace(/\s+/g," ").trim(),qR=(e=[])=>e.map(r=>String(r||"").trim()).find(r=>/^https?:\/\//i.test(r))||Qa(GR),ks=({attribute:e,content:t,key:r})=>{if(typeof document>"u")return()=>{};let a=document.head.querySelector(`meta[${e}="${r}"]`);const s=!!a,o=a?.getAttribute("content")||"";return a||(a=document.createElement("meta"),a.setAttribute(e,r),document.head.append(a)),a.setAttribute("content",lg(t)),()=>{if(s){a.setAttribute("content",o);return}a.remove()}},V3=e=>{if(typeof document>"u")return()=>{};let t=document.head.querySelector('link[rel="canonical"]');const r=!!t,a=t?.getAttribute("href")||"";return t||(t=document.createElement("link"),t.setAttribute("rel","canonical"),document.head.append(t)),t.setAttribute("href",e),()=>{if(r){t.setAttribute("href",a);return}t.remove()}},mp=({description:e=f_,image:t="",imageAlt:r=lb,title:a=m_,type:s="website",url:o=""}={})=>{if(typeof document>"u")return()=>{};const i=lg(a,m_),c=lg(e,f_),l=t||Qa(GR),u=lg(r,lb),p=o||Qa("/"),m=document.title,f=[ks({attribute:"name",key:"description",content:c}),ks({attribute:"property",key:"og:site_name",content:"Saveboard"}),ks({attribute:"property",key:"og:title",content:i}),ks({attribute:"property",key:"og:description",content:c}),ks({attribute:"property",key:"og:type",content:s}),ks({attribute:"property",key:"og:url",content:p}),ks({attribute:"property",key:"og:image",content:l}),ks({attribute:"property",key:"og:image:alt",content:u}),ks({attribute:"name",key:"twitter:card",content:"summary_large_image"}),ks({attribute:"name",key:"twitter:title",content:i}),ks({attribute:"name",key:"twitter:description",content:c}),ks({attribute:"name",key:"twitter:image",content:l}),ks({attribute:"name",key:"twitter:image:alt",content:u}),V3(p)];return document.title=i,()=>{document.title=m,f.forEach(h=>h())}},H3=e=>new Promise((t,r)=>{const a=new FileReader;a.onload=()=>t(a.result),a.onerror=()=>r(new Error("Could not read that image.")),a.readAsDataURL(e)}),W3=e=>new Promise((t,r)=>{const a=new Image;a.onload=()=>t(a),a.onerror=()=>r(new Error("Could not load that image.")),a.src=e}),h_=(e,t,r,a="image/jpeg")=>
32{const s=Math.min(1,t/Math.max(e.naturalWidth,e.naturalHeight)),o=Math.max(1,Math.round(e.naturalWidth*s)),i=Math.max(1,Math.round(e.naturalHeight*s)),c=document.createElement("canvas"),l=c.getContext("2d");return c.width=o,c.height=i,a==="image/jpeg"&&(l.fillStyle="#fcfcfa",l.fillRect(0,0,o,i)),l.drawImage(e,0,0,o,i),a==="image/png"?c.toDataURL(a):c.toDataURL(a,r)},G3=e=>e==="image/png"||e==="image/webp"?e:"image/jpeg",q3=async e=>{if(!e)return"";if(!AR.includes(e.type))throw new Error("Use a JPG, PNG, or WebP image.");if(e.size>pW)throw new Error("Choose an image under 12 MB.");const t=await H3(e),r=await W3(t),a=G3(e.type);let s=h_(r,mW,.82,a);if(s.length>WP&&(s=h_(r,1e3,.72,a==="image/png"?"image/webp":a)),s.length>WP)throw new Error("That image is still too large after compression. Use a smaller file or paste an image URL.");return s},$m=(e,t,r,a)=>{const s=Number(e);return Number.isFinite(s)?Math.min(r,Math.max(t,s)):a},gl=e=>Ku(e,Bs),kn=(e={})=>df(AE(e,{isPlaceholder:qo})),Sx=(e={})=>kn(e)||jn,zi=(e={},t="")=>{const r=String(t||"").trim();return bs(e,{isPlaceholder:qo}).candidates.map(df).filter(a=>a&&a!==r)},Mw=(e="")=>String(e||"").replace(/\s+/g," ").trim(),YR=(e="")=>{let t=String(e||"").trim().toLowerCase();return t?(t=t.replace(/^https?:\/\//,"").replace(/^www\./,""),t=t.split(/[/?#]/)[0],t=t.replace(/\.[a-z]{2,}(?:\.[a-z]{2})?$/i,""),t.replace(/[^a-z0-9]+/g,"")):""},Y3=(e={})=>[e.source,e.store,e.merchant,e.retailer,e.siteName,e.url].reduce((t,r)=>{const a=YR(r);return a&&t.add(a),t},new Set),K3=(e="")=>{const t=Mw(e);return!t||t.length>42||/[,/\\]/.test(t)?!1:t.split(" ").length<=4&&/^[a-z0-9&'.\s-]+$/i.test(t)},X3=(e="",t={})=>{const r=Y3(t),a=e.match(/^(.*?)\s*\|\s*([^|]+)$/);if(a?.[1]&&K3(a[2]))return a[1];const s=e.match(/^(.*?)\s+[—–-]\s+(.+)$/);if(s?.[1]){const o=YR(s[2]);if(o&&r.has(o))return s[1]}return e},KR=(e={})=>{const t=Mw(e.title)||"Untitled product";let r=t.replace(/^go to\s+/i,"");return r=r.replace(/\s+product page$/i,""),r=X3(r,e),r=Mw(r),r||t},Li=(e={})=>{const t=e.imageFit==="cover"?"cover":_m.imageFit,r=ao(e);return{imageFit:t,imageScale:$m(e.imageScale,Aw,Pw,_m.imageScale),imagePositionX:$m(e.imagePositionX,0,100,_m.imagePositionX),imagePositionY:$m(e.imagePositionY,0,100,_m.imagePositionY),imageBackgroundMode:r.mode,imageBackgroundStoredMode:r.storedMode,imageBackgroundDetectorVersion:r.detectorVersion,imageBackgroundConfidenceLevel:r.confidenceLevel,imageBackgroundColor:r.color}},mc=(e=cf.imageFit)=>Kb(e),Ed=(e={})=>{const t=Li(e);return{objectFit:t.imageFit==="cover"&&t.imageScale<1?"contain":t.imageFit,objectPosition:`${t.imagePositionX}% ${t.imagePositionY}%`,transform:`translate3d(0, 0, 0) scale(${t.imageScale})`,transformOrigin:`${t.imagePositionX}% ${t.imagePositionY}%`}},Uw=(e={})=>({...Ed(e),objectFit:"cover",transform:"none"}),kd=(e={})=>({backgroundColor:W0(e).color});function rv({analysisSource:e="",children:t,imageSource:r="",settings:a={},style:s,...o}){const i=d.useRef(null),c=ao(a),[l,u]=d.useState(c.color),[p,m]=d.useState(!1);return d.useEffect(()=>{u(c.color)},[r,c.color,c.storedMode]),d.useEffect(()=>{const f=i.current;if(!f||typeof IntersectionObserver>"u"){m(!0);return}const h=new IntersectionObserver(([b])=>{b.isIntersecting&&(m(!0),h.disconnect())},{rootMargin:"240px"});return h.observe(f),()=>h.disconnect()},[r]),d.useEffect(()=>{if(!r||!p||c.mode!=="auto"||c.detectorVersion===Yu)return;const f=new AbortController,h=()=>{Pg(e||r,{signal:f.signal}).then(v=>{f.signal.aborted||u(v.ok?v.color:Bs)})},b=typeof window.requestIdleCallback=="function"?window.requestIdleCallback(h,{timeout:650}):window.setTimeout(h,PR);return()=>{f.abort(),typeof window.cancelIdleCallback=="function"?window.cancelIdleCallback(b):window.clearTimeout(b)}},[e,r,p,c.detectorVersion,c.mode]),n.jsx("div",{...o,ref:i,style:{...s,...r?{backgroundColor:l}:{}},children:t})}const J3=()=>{if(typeof window>"u")return!1;try{return!!(window.__MYLIST_IMAGE_BACKGROUND_DEBUG__||window.localStorage.getItem(SW)==="true")}catch{return!!window.__MYLIST_IMAGE_BACKGROUND_DEBUG__}},fm=(...e)=>
32{J3()&&console.info("[MyList Image Background]",...e)},hu=new Map,Q3=(e,t,r)=>`${e}|${Number(t).toFixed(4)}|${gl(r)}`,Z3=({imageSource:e,frameAspectRatio:t,backgroundColor:r})=>new Promise(a=>{if(!e||e===jn||!Number.isFinite(t)){a({ok:!1,reason:"missing-image"});return}const s=new Image;let o=!1;const i=c=>{o||(o=!0,a(c))};s.crossOrigin="anonymous",s.onload=()=>{try{const c=Math.max(s.naturalWidth,s.naturalHeight);if(!c){i({ok:!1,reason:"image-dimensions-unavailable"});return}const l=Math.min(1,sM/c),u=Math.max(2,Math.round(s.naturalWidth*l)),p=Math.max(2,Math.round(s.naturalHeight*l)),m=document.createElement("canvas");m.width=u,m.height=p;const f=m.getContext("2d",{willReadFrequently:!0});if(!f){i({ok:!1,reason:"canvas-context-unavailable"});return}f.clearRect(0,0,u,p),f.drawImage(s,0,0,u,p);const h=f.getImageData(0,0,u,p);i(fM({backgroundColor:r,data:h.data,frameAspectRatio:t,height:p,width:u}))}catch(c){i({ok:!1,reason:c?.name==="SecurityError"||String(c?.message||"").toLowerCase().includes("tainted")?"canvas-tainted":"canvas-sampling-error"})}},s.onerror=()=>i({ok:!1,reason:"image-load-failed"}),s.src=e}),Fw=async({imageSource:e,frameAspectRatio:t,backgroundColor:r})=>{const a=Q3(e,t,r);if(hu.has(a))return hu.get(a);const s=await Z3({imageSource:e,frameAspectRatio:t,backgroundColor:r});return hu.set(a,s),hu.size>xW&&hu.delete(hu.keys().next().value),s},$w=(e=ra.compact)=>{const t=Number.parseFloat(e.podWidth)||Number.parseFloat(ra.compact.podWidth),r=Number.parseFloat(e.podAspectRatio)||Number.parseFloat(ra.compact.podAspectRatio),a=t/r,s=Math.max(1,t-_w),o=Math.max(1,a-Ew);return s/o},eG=(e=ra.compact)=>{const t=Number.parseFloat(e.podWidth)||Number.parseFloat(ra.compact.podWidth),r=Number.parseFloat(e.podAspectRatio)||Number.parseFloat(ra.compact.podAspectRatio),a=t/r,s=Number.parseFloat(e.columnGap)||0,o=Number.parseFloat(e.rowGap)||0,i=t*2+s,c=a*2+o,l=$w(e),u=Math.max(1,i-_w)/Math.max(1,a-Ew),p=Math.max(1,i-_w)/Math.max(1,c-Ew);return{[vi(Lr.normal,mn.standard)]:l,[vi(Lr.normal,mn.wide)]:u,[vi(Lr.normal,mn.large)]:p,[vi(Lr.minimal,mn.standard)]:t/a,[vi(Lr.minimal,mn.wide)]:i/a,[vi(Lr.minimal,mn.large)]:i/c}},ff=e=>[e.title,e.brand,e.price,e.size,e.colour,e.variant,e.privateNotes,e.publicNotes,e.notes,e.url,e.
32source,e.category,e.listName].filter(Boolean).join(" ").toLowerCase(),tG=(e={})=>[["Size",e.size],["Colour",e.colour],["Variant",e.variant]].map(([t,r])=>({label:t,value:Ye(String(r||""))})).filter(({value:t})=>t),hs=(e,t)=>{const r=String(e?.listId||"").trim();return r?r===String(t?.id||"").trim():e.category===t.name||e.listName===t.name},XR=e=>[e.name,e.description,e.publicDescription,e.slug].filter(Boolean).join(" ").toLowerCase(),zo=4,hf=(e=[])=>Array.isArray(e)?[...new Set(e.map(t=>String(t||"").trim()).filter(Boolean))].slice(0,zo):[],JR=(e={},t=[])=>{const r=hf(e.coverItemIds);if(!r.length)return t.slice(0,zo);const a=r.map(s=>t.find(o=>o.id===s&&hs(o,e))||null).filter(Boolean);return a.length?a:t.slice(0,zo)},QR=(e={},t=[])=>JR(e,t).map(r=>kn(r)).filter(Boolean).slice(0,zo).map(r=>Il(r,{width:Os.cover})),rG=8,nG=8,aG=8,ZR=48,eL=8,op=()=>typeof window>"u"?{height:900,width:1440}:{height:window.innerHeight,width:window.innerWidth},gf=(e,t,{width:r=1440}={})=>Math.min(t,Math.max(2,Math.ceil(r/e)+1)),tL=(e={},{height:t=900,width:r=1440}={})=>{const a=Number.parseFloat(e.podWidth)||180,s=Number.parseFloat(e.podAspectRatio)||.8,o=r<900,i=Math.max(o?2:1,Math.floor((r-(o?24:96))/(a+16))),c=Math.max(1,Math.ceil(t/(a/s+56))+1);return Math.min(ZR,Math.max(aG,i*c))},rL=e=>{const t=e?kn(e):"";return t?[Il(t,{width:Os.detail})]:[]},db=new Map,wx=e=>{const t=db.get(e?.id);t&&(window.clearTimeout(t),db.delete(e?.id))},nL=e=>{e?.id&&(wx(e),db.set(e.id,window.setTimeout(()=>{db.delete(e.id),k0(rL(e))},140)))},aL=({lists:e,products:t,status:r,query:a})=>{const s=a.trim().toLowerCase();return[...e].sort((o,i)=>o.sortOrder-i.sortOrder).map(o=>{const i=t.filter(p=>hs(p,o)&&va(p.status)===r),c=t.filter(p=>hs(p,o)),l=XR(o).includes(s),u=c.some(p=>ff(p).includes(s));return{list:o,products:i,totalCount:c.length,visibleCount:i.length,matchesSearch:!s||l||u}}).filter(o=>o.matchesSearch)},sL=e=>String(e||"").replace(/,/g,"").match(/\d+(?:\.\d+)?/g)||[],sG=(e={})=>{const t=String(e.price||"").trim();if(!t)return null;const r=sL(t);if(!r.length)return null;const a=Number(r[0]);if(!Number.isFinite(a))return null;const s=Cb(t)||Nd(e.currency,"");if(!s)return null;const o=r.length>1&&/(?:-|–|—|to)/i.test(t),i=/\bfrom\b|\+|approx|estimated|starting/i.test(t)||o;return{currency:s,isApproximate:i,value:a}},Gh=e=>{const t=Number(sL(e)[0]);return Number.isFinite(t)?t:null},Ya=(e,t)=>{const r=new Intl.NumberFormat(void 0,{maximumFractionDigits:2,minimumFractionDigits:Number.isInteger(e)?0:2}).format(e);return`${Hm(t,t)}${r}`},oG=(e=[],t="")=>{const r=e.filter(u=>Number.isFinite(u)).sort((u,p)=>u-p);if(!r.length||!t)return[];const a=r[0],s=r[r.length-1];if(r.length===1||a===s)return[{count:r.length,label:Ya(a,t),percentage:100}];const o=Math.min(4,Math.max(2,r.length)),i=(s-a)/o,c=Array.from({length:o},(u,p)=>{const m=a+i*p,f=p===o-1?s:a+i*(p+1);return{count:0,label:`${Ya(m,t)}-${Ya(f,t)}`,percentage:0}});r.forEach(u=>{const p=Math.min(o-1,Math.floor((u-a)/i));c[p].count+=1});const l=Math.max(...c.map(u=>u.count),1);return c.map(u=>({...u,percentage:Math.max(8,Math.round(u.count/l*100))}))},iG=(e=[])=>{const t=new Map,r=new Map;let a=0,s=!1;e.forEach(S=>{const C=sG(S);C&&(a+=1,s=s||C.isApproximate,t.set(C.currency,(t.get(C.currency)||0)+C.value),r.set(C.currency,[...r.get(C.currency)||[],C.value]))});const o=e.length-a,i=[...t.entries()],c=i.map(([S,C])=>Ya(C,S)).join(" + "),l=i.length>1,u=i.length===1?i[0][0]:"",p=u?r.get(u)||[]:[],m=p.length?Math.min(...p):null,f=p.length?Math.max(...p):null,h=i.length===1?i[0][1]:null,b=i.map(([S,C])=>{const I=r.get(S)||[],A=I.length?Math.min(...I):null,k=I.length?Math.max(...I):null,E=I.length?C/I.length:null;return{averageText:Number.isFinite(E)?Ya(E,S):"",count:I.length,currency:S,highestText:Number.isFinite(k)?Ya(k,S):"",lowestText:Number.isFinite(A)?Ya(A,S):"",totalText:Ya(C,S)}}),v=[a?`${a} priced`:"",o?`${o} without price`:""].filter(Boolean);return{averageText:a&&!l&&Number.isFinite(h)?Ya(h/a,u):a&&l?"Mixed currencies":"",countText:v.join(" · "),currencyBreakdown:b,distributionBuckets:l?[]:oG(p,u),hasMixedCurrencies:l,highestText:!l&&Number.isFinite(f)?Ya(f,u):"",isApproximate:s,lowestText:!l&&Number.isFinite(m)?Ya(m,u):"",pricedCount:a,productC
32ount:e.length,rangeText:!l&&Number.isFinite(m)&&Number.isFinite(f)?`${Ya(m,u)}-${Ya(f,u)}`:a&&l?"See currency rows":"",totalText:c,unpricedCount:o}},Du=e=>{const t=Date.parse(e);return Number.isFinite(t)?t:null},Em=(e,t,r="asc")=>{const a=e===null,s=t===null;return a&&s?0:a?1:s?-1:r==="desc"?t-e:e-t},dg=(e,t)=>t==="manual"?e:e.map((r,a)=>({index:a,product:r})).sort((r,a)=>{let s=0;return t==="newest"?s=Em(Du(r.product.createdAt),Du(a.product.createdAt),"desc"):t==="oldest"?s=Em(Du(r.product.createdAt),Du(a.product.createdAt),"asc"):t==="priceAsc"?s=Em(Gh(r.product.price),Gh(a.product.price),"asc"):t==="priceDesc"?s=Em(Gh(r.product.price),Gh(a.product.price),"desc"):t==="titleAsc"?s=r.product.title.localeCompare(a.product.title,void 0,{sensitivity:"base"}):t==="titleDesc"&&(s=a.product.title.localeCompare(r.product.title,void 0,{sensitivity:"base"})),s||r.index-a.index}).map(({product:r})=>r),vs=e=>{if(!e)return"";const t=new Date(e);return Number.isNaN(t.getTime())?"":t.toLocaleDateString(void 0,{month:"short",day:"numeric",year:"numeric"})},oL=e=>{if(!e)return"";const r=new Date(e).getTime();if(Number.isNaN(r))return"";const a=Math.max(0,Math.floor((Date.now()-r)/1e3));if(a<60)return"Just now";const s=Math.floor(a/60);if(s<60)return`${s}m ago`;const o=Math.floor(s/60);if(o<24)return`${o}h ago`;const i=Math.floor(o/24);return i<7?`${i}d ago`:vs(e)},cG=(e,t)=>Yy.includes(e.category)?e.category:["Tech","Stationery"].includes(e.category)?"Tech":["Beauty","Fashion","Accessories"].includes(e.category)?"Beauty":["Home","Lifestyle"].includes(e.category)?"Home":Yy[t%Yy.length],iL=(e,t=0)=>{const r=e.createdAt||new Date().toISOString(),a=Ye(e.category||e.listName||Ka),s=e.privateNotes??e.notes??"",o=e.publicNotes??"",i=Ye(e.brand||""),c=Ye(e.source||""),l=i==="Unlisted"?"":i,u=!!(l&&!c&&DR(l)),p=c||(u?Nc(l):Go(e.url||"")),m=Nl(e.currency||e.price,e.currency||wd),f=bs(e,{isPlaceholder:qo}),h=f.hasConflict?df(e.imageUrl):f.kind==="external"?f.value:"",b=f.hasConflict?df(e.image)||h||jn:f.kind==="external"||f.kind==="local-path"||f.kind==="local-upload"?f.value:jn,v=xb({targetPrice:e.targetPrice,targetCurrency:e.targetCurrency,currency:m}),S=Ib(e.priceAlert,{hasTargetPrice:!!v.targetPrice}),C=Vo(e.priceAlertEvents),I=Xu(e.priceTracking),A=vx(e.availability),k=vf(e.availabilityHistory),E=Bi(e.availabilityAlertEvents),y=jR(e.availabilityTracking),N=Li(e),_={imageFit:N.imageFit,imageScale:N.imageScale,imagePositionX:N.imagePositionX,imagePositionY:N.imagePositionY,imageBackgroundMode:N.imageBackgroundStoredMode,imageBackgroundColor:N.imageBackgroundColor},P=fW.reduce((V,L)=>(e[L]!==void 0&&(V[L]=e[L]),V),{});return{id:e.id||Xb(),userId:e.userId||Mi,listId:e.listId||fx(a),listName:a,category:a,createdAt:r,updatedAt:e.updatedAt||r,sortOrder:Number.isFinite(e.sortOrder)?e.sortOrder:t,title:e.title||"Untitled",price:e.price||"$--",currency:m,brand:u?"":l,size:Ye(e.size||""),colour:Ye(e.colour||""),variant:Ye(e.variant||""),url:e.url||"",imageUrl:h,image:b,...f.requiresReview?{imageReferenceIssue:f.diagnosticCode}:{},privateNotes:s,publicNotes:o,source:p,barcode:xl(e.barcode),cardSize:zn(e.cardSize??e.card_size),imageFramingOverrides:ya(e.imageFramingOverrides??e.image_framing_overrides),priceHistory:Rl(e.priceHistory),...P,...A?{availability:A}:{},...k.length?{availabilityHistory:k}:{},...E.length?{availabilityAlertEvents:E}:{},...y?{availabilityTracking:y}:{},...v,...S?{priceAlert:S}:{},...C.length?{priceAlertEvents:C}:{},...I?{priceTracking:I}:{},status:va(e.status),...e.imageAutoFramePending===!0?{imageAutoFramePending:!0}:{},..._}},lG=()=>f3.map((e,t)=>iL({...e,category:cG(e,t)},t)),ct=iW({defaultLists:cW,demoLists:IR,dashboardList:rr,defaultGridPreference:Ja,defaultBoardMode:VW,gridPreferences:ra,boardModes:ZW,createInitialProducts:lG,normalizeGridPreference:YW,normalizeProduct:iL}),Ba=(e={})=>({checkedAt:"",error:"",foregroundReady:!1,listCount:0,message:"",productCount:0,sessionKey:"",settled:!1,status:"idle",...e}),qh=()=>({lists:ct.readLists(ct.modes.personal),products:ct.readProducts(ct.modes.personal)}),wu=({lists:e=[],products:t=[]}={})=>Array.isArray(t)&&t.length>0?!0:(Array.isArray(e)?e:[]).some(r=>{const a=Ye(r?.name||"").toLowerCase();return a&&a!==rr.toLowerCase()}),dG=(e={})=>!wu(e),g_=({lists:e=[],products:t=[]}={})=>Array.isArray(t)&&t.length>0?!0:(Array.isArray(e)?e:[]).some(r=>{const a=Ye(r?.name||"");return!(!a||a.toLowerCase()===rr.toLowerCase()||a.toLowerCase()===Ka.toLowerCase())||!!(r?.description||r?.publicDescription||r?.isPublic||r?.coverImage||r?.imageUrl||r?.budget)}),uG="Backup was stopped because Saveboard could not read your current boards and items. Refresh and try again.",pG="Backup was stopped because your boards could not be read. Reload Saveboard, confirm your boards are there, then try again.",mG=(e,t,{alwaysShowAddSlot:r=!1}={})=>{const a=Math.max(1,t),s=e+(r?1:0);if(s===0)return a;const o=s%a,i=o===0?0:a-o;return(r?1:0)+i}
32,fG=({products:e,mode:t,columnCount:r,rowCount:a,alwaysShowAddSlot:s=!1,useDenseCardOccupancy:o=!1})=>{const i=Math.max(1,r),c=Math.max(1,a),l=t==="horizontal"?c:i,u=o?M0(e,i):mG(e.length,l,{alwaysShowAddSlot:s}),p=e.length+u,m=t==="horizontal"?Math.max(p,i*c):p,f=Math.max(u,m-e.length),h=e.map(v=>({type:"product",product:v})),b=Array.from({length:f},(v,S)=>({type:"empty",key:`empty-${e.length}-${S}`}));return[...h,...b]},Cx=(e,t,r)=>{if(t<=hx||e>=t)return t;const a=Math.max(1,r);return Math.min(t,Math.ceil(e/a)*a)},b_=(e,t)=>Cx(hx,e,t),hG=(e,t,r)=>Cx(e+EW,t,r),gG=(e,t)=>{const r=e.deltaMode===1?kW:e.deltaMode===2?t.clientWidth*NW:1,a=e.deltaX*r,s=e.deltaY*r,o=Math.abs(a)>Math.abs(s),i=o?a:s;return Math.abs(i)<.5?0:Math.sign(i)*Math.min(Math.abs(i),jW)*(o?RW:LW)},v_={compact:3,expanded:3},cL=e=>v_[e]??v_.compact,y_={compact:"clamp(18px, 2.4vh, 28px)",expanded:"clamp(18px, 2.4vh, 28px)"},bG=e=>y_[e]??y_.compact;function lL(e){const[t,r]=d.useState(0);return d.useEffect(()=>{const a=e.current;if(!a||typeof window>"u")return;let s=null;const o=()=>{s&&window.cancelAnimationFrame(s),s=window.requestAnimationFrame(()=>{const c=window.innerWidth>=gx&&(a.parentElement?.clientWidth||a.clientWidth)||0;r(l=>l===c?l:c)})};o();const i=typeof ResizeObserver<"u"?new ResizeObserver(o):null;return i?.observe(a),a.parentElement&&i?.observe(a.parentElement),window.addEventListener("resize",o),()=>{s&&window.cancelAnimationFrame(s),i?.disconnect(),window.removeEventListener("resize",o)}},[e]),t}function ug(e,t,r=1/0,a=null){const[s,o]=d.useState(1);return d.useEffect(()=>{const i=e.current;if(!i||typeof window>"u")return;let c=null;const l=()=>{c&&window.cancelAnimationFrame(c),c=window.requestAnimationFrame(()=>{const p=window.getComputedStyle(i),m=ra[t]??ra[Ja],f=window.innerWidth>=gx&&a,h=Number.parseFloat(f?a.podWidth:p.getPropertyValue("--pod-width"))||Number.parseFloat(m.podWidth),b=Number.parseFloat(f?a.columnGap:p.getPropertyValue("--grid-column-gap"))||Number.parseFloat(m.columnGap),v=i.parentElement?.clientWidth||i.clientWidth,S=h>0?Math.floor((v+b)/(h+b)):1;o(C=>{const I=Number.isFinite(r)&&r>0?Math.floor(r):1/0,A=Math.min(Math.max(1,S),I);return C===A?C:A})})};l();const u=typeof ResizeObserver<"u"?new ResizeObserver(l):null;return u?.observe(i),window.addEventListener("resize",l),()=>{c&&window.cancelAnimationFrame(c),u?.disconnect(),window.removeEventListener("resize",l)}},[e,r,a?.columnGap,a?.podWidth,t]),s}const zw="(max-width: 768px), (max-width: 932px) and (max-height: 500px) and (pointer: coarse)";function dL(){const e=zw,[t,r]=d.useState(()=>typeof window<"u"&&window.matchMedia(e).matches);return d.useEffect(()=>{const a=window.matchMedia(e),s=()=>r(a.matches);return s(),a.addEventListener("change",s),()=>a.removeEventListener("change",s)},[]),t}function fp(){const[e,t]=d.useState(()=>typeof window>"u"?1:ZP({viewportHeight:window.visualViewport?.height||window.innerHeight,viewportWidth:window.visualViewport?.width||window.innerWidth}));return d.useEffect(()=>{if(typeof window>"u")return;let r=null;const a=()=>{r&&window.cancelAnimationFrame(r),r=window.requestAnimationFrame(()=>{const s=window.visualViewport?.width||window.innerWidth,o=window.visualViewport?.height||window.innerHeight,i=ZP({viewportWidth:s,viewportHeight:o});t(c=>Math.abs(c-i)<.005?c:i)})};return a(),window.addEventListener("resize",a),window.visualViewport?.addEventListener("resize",a),()=>{r&&window.cancelAnimationFrame(r),window.removeEventListener("resize",a),window.visualViewport?.removeEventListener("resize",a)}},[]),e}function uL(e=!1){const[t,r]=d.useState(()=>typeof window>"u"?kR:JP(window.innerWidth,e));return d.useEffect(()=>{if(typeof window>"u")return;let a=null;const s=()=>{a&&window.cancelAnimationFrame(a),a=window.requestAnimationFrame(()=>{const o=window.visualViewport?.width||window.innerWidth;r(JP(o,e))})};return s(),window.addEventListener("resize",s),window.visualViewport?.addEventListener("resize",s),()=>{a&&window.cancelAnimationFrame(a),window.removeEventListener("resize",s),window.visualViewport?.removeEventListener("resize",s)}},[e]),t}function vG(){const[e,t]=d.useState(()=>typeof window>"u"?{key:"",path:"/",search:""}:{key:Bu(),path:window.location.pathname,search:window.location.search}),[r,a]=d.useState(null);return d.useEffect(()=>{"scrollRestoration"in window.history&&(window.history.scrollRestoration="manual"),Bu()||window.history.replaceState({...window.history.state||{},[pf]:cb()},"",VR()),Ru=Bu(),t(i=>i.key===Ru?i:{...i,key:Ru});const s=()=>{const i=mf||"pop";if(mf=null,!window.dispatchEvent(new Event("saveboard:before-route-change",{cancelable:!0})))return;i==="pop"&&HR();const c=Bu(),l={key:c,path:window.location.pathname,search:window.location.search},u=++Lu;Dw?.();const p=()=>{Ru=c,a(null),t(b=>
32b.key===l.key&&b.path===l.path&&b.search===l.search?b:(Fm={at:performance.now(),intent:i},l))},m=()=>u===Lu,f=()=>{if(!m())return;const b=Bw?Bw(l):[];uE(b,p,{isCurrent:m})||a(l)},h=Tw?.(l,m);h?(a(l),Promise.resolve(h).then(f,f)):f()},o=()=>a(null);return window.addEventListener("saveboard:cancel-pending-route",o),window.addEventListener("popstate",s),()=>{window.removeEventListener("popstate",s),window.removeEventListener("saveboard:cancel-pending-route",o)}},[]),d.useMemo(()=>({...e,pendingPath:r?r.path:""}),[e,r])}function Sn(e){const t=d.useRef(e);return d.useLayoutEffect(()=>{t.current=e}),d.useCallback((...r)=>t.current?.(...r),[])}const yG=e=>e?.matches?.("input, textarea, select, [contenteditable='true'], [contenteditable='']"),SG=["a[href]","button:not([disabled])","input:not([disabled]):not([type='hidden'])","select:not([disabled])","textarea:not([disabled])","summary","[tabindex]:not([tabindex='-1'])"].join(","),pL=e=>{if(!e||e.closest?.("[hidden], [aria-hidden='true'], [inert]"))return!1;const t=window.getComputedStyle(e);return t.display!=="none"&&t.visibility!=="hidden"&&e.getClientRects().length>0},pg=()=>[...document.querySelectorAll("[role='dialog'][aria-modal='true']")].filter(pL).at(-1)||null,S_=e=>[...e.querySelectorAll(SG)].filter(pL),hm=e=>{try{e?.focus?.({preventScroll:!0})}catch{e?.focus?.()}};function wG(){const e=d.useRef(null),t=d.useRef(null);d.useEffect(()=>{if(typeof document>"u")return;const r=c=>{const l=S_(c)[0]||c;hm(l)},a=()=>{const c=pg();if(c&&c!==e.current){e.current||(t.current=document.activeElement),e.current=c,window.requestAnimationFrame(()=>{e.current===c&&!c.contains(document.activeElement)&&r(c)});return}if(!c&&e.current){const l=t.current;e.current=null,t.current=null,window.requestAnimationFrame(()=>{l&&document.contains(l)&&hm(l)})}},s=c=>{if(c.key!=="Tab")return;const l=pg();if(!l)return;const u=S_(l);if(u.length===0){c.preventDefault(),hm(l);return}const p=u.indexOf(document.activeElement),m=c.shiftKey?p-1:p+1;if(!l.contains(document.activeElement)){c.preventDefault(),hm(c.shiftKey?u.at(-1):u[0]);return}(m<0||m>=u.length)&&(c.preventDefault(),hm(m<0?u.at(-1):u[0]))},o=c=>{const l=pg();!l||l.contains(c.target)||(c.stopPropagation(),r(l))},i=new MutationObserver(a);return i.observe(document.body,{childList:!0,subtree:!0}),window.addEventListener("keydown",s,!0),document.addEventListener("focusin",o,!0),a(),()=>{i.disconnect(),window.removeEventListener("keydown",s,!0),document.removeEventListener("focusin",o,!0)}},[])}function CG({disabled:e,searchInputRef:t,searchQuery:r,onSearchQueryChange:a,productModalIsOpen:s,settingsIsOpen:o,shortcutsHelpIsOpen:i,commandPaletteIsOpen:c,deleteModalIsOpen:l,importModalIsOpen:u,onOpenAddProduct:p,onOpenCommandPalette:m,onCloseCommandPalette:f,onCloseProductModal:h,onCloseSettings:b,onOpenShortcutsHelp:v,onCloseShortcutsHelp:S,onCloseDeleteModal:C,onCloseImportModal:I}){d.useEffect(()=>{if(e)return;const A=k=>{const E=k.key,y=k.metaKey||k.ctrlKey||k.altKey,N=yG(k.target);if((k.metaKey||k.ctrlKey)&&E.toLowerCase()==="k"){N||(k.preventDefault(),m());return}if(E==="Escape"){if(c){k.preventDefault(),f();return}if(i){k.preventDefault(),S();return}if(l){k.preventDefault(),C();return}if(u){k.preventDefault(),I();return}if(s){k.preventDefault(),h();return}if(o){k.preventDefault(),b();return}k.target===t.current&&(k.preventDefault(),r?a(""):t.current?.blur());return}if(!(N||y)){if(E==="?"){k.preventDefault(),v();return}if(E==="/"){k.preventDefault(),t.current?.focus();return}E.toLowerCase()==="n"&&!s&&!o&&!i&&!c&&!l&&!u&&(k.preventDefault(),p())}};return window.addEventListener("keydown",A),()=>window.removeEventListener("keydown",A)},[c,l,e,u,C,I,f,h,b,S,p,m,v,a,s,t,r,o,i])}function ub({type:e}){const t={allItems:n.jsxs(n.Fragment,{children:[n.jsx("rect",{x:"5",y:"5",width:"5",height:"5",rx:"1.2"}),n.jsx("rect",{x:"14",y:"5",width:"5",height:"5",rx:"1.2"}),n.jsx("rect",{x:"5",y:"14",width:"5",height:"5",rx:"1.2"}),n.jsx("rect",{x:"14",y:"14",width:"5",height:"5",rx:"1.2"})]}),board:n.jsxs(n.Fragment,{children:[n.jsx("rect",{x:"4.5",y:"5",width:"15",height:"14",rx:"2"}),n.jsx("path",{d:"M8 9h8"}),n.jsx("path",{d:"M8 13h5"})]}),create:n.jsxs(n.Fragment,{children:[n.jsx("circle",{cx:"12",cy:"12",r:"8.5"}),n.jsx("path",{d:"M12 8.2v7.6"}),n.jsx("path",{d:"M8.2 12h7.6"})]}),discover:n.jsxs(n.Fragment,{children:[n.jsx("circle",{cx:"12",cy:"12",r:"8.5"}),n.jsx("path",{d:"m15.5 8.5-2.2 4.8-4.8 2.2 2.2-4.8z"})]}),help:n.jsxs(n.Fragment,{children:[n.jsx("circle",{cx:"12",cy:"12",r:"7.5"}),n.jsx("path",{d:"M9.9 9.4a2.3 2.3 0 0 1 4.2 1.3c0 1.6-1.6 2.1-2.1 3.3"}),n.jsx("path",{d:"M12 17h.01"})]}),home:n.jsxs(n.Fragment,{children:[n.jsx("path",{d:"M3.5 10.5 12 3.5l8.5 7"}),n.jsx("path",{d:"M5.5 9.5V20h13V9.5"})]}),more:n.jsxs(n.Fragment,{children:[n.jsx("path",{d:"M4 7h16"}),n.jsx("path",{d:"M4 12h16"}),n.jsx("path",{d:"M4 17h16"})]}),minimal:n.jsxs(n.Fragment,{children:[n.jsx("rect",{x:"4.5",y:"4.5",width:"15",height:"15",rx:"3"}),n.jsx("path",{d:"m7.5 15 3.2-3.5 2.1 2 1.8-2 2 3.5"}),n.jsx("circle",{cx:"15.2",cy:"8.8",r:"1"})]}),moon:n.jsx("path",{d:"M18.2 15.6A7.5 7.5 0 0 1 8.4 5.8 7.5 7.5 0 1 0 18.2 15.6Z"}),notifications:n.jsxs(n.Fragment,{children:[n.jsx("path",{d:"M6 9a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6"}),n.jsx("path",{d:"M10 19a2 2 0 0 0 4 0"})]}),profile:n.jsxs(n.Fragment,{children:[n.jsx("circle",{cx:"12",cy:"8.5",r:"3.5"}),n.jsx("path",{d:"M5 20a7 7 0 0 1 14 0"})]}),search:n.jsxs(n.Fragment,{children:[n.jsx("circle",{cx:"11",cy:"11",r:"6.5"}),n.jsx("path",{d:"m20 20-4.5-4.5"})]}),stores:n.jsxs(n.Fragment,{children:[n.jsx("path",{d:"M4 4.5h16V9H4z"}),n.jsx("path",{d:"M5.5 9v10.5h13V9"}),n.jsx("path",{d:"M10 13h4"})]}),sun:n.jsxs(n.Fragment,{children:[n.jsx("circle",{cx:"12",cy:"12",r:"4.5"}),n.jsx("path",{d:"M12 2.5V5"}),n.jsx("path",{d:"M12 19v2.5"}),n.jsx("path",{d:"M2.5 12H5"}),n.jsx("path",{d:"M19 12h2.5"}),n.jsx("path",{d:"m5.3 5.3 1.8 1.8"}),n.jsx("path",{d:"m16.9 16.9 1.8 1.8"}),n.jsx("path",{d:"m18.7 5.3-1.8 1.8"}),n.jsx("path",{d:"m7.1 16.9-1.8 1.8"})]})};return n.jsx("span",{className:"sidebarNavIcon","aria-hidden":"true",children:n.jsx("svg",{focusable:"false",viewBox:"0 0 24 24",children:t[e]||t.board})})}const Mo=e=>`sidebar-tooltip-${e.toLowerCase().replace(/\s+/g,"-")}`;function xG({lists:e,activeList:t,activeStatus:r,allItemsIsOpen:a,dashboardOverviewIsOpen:s,discoverIsOpen:o,guideIsOpen:i,accountIsOpen:c,priceTrackingIsOpen:l,searchRouteIsOpen:u,stores
32IsOpen:p,updatesIsOpen:m,signedIn:f,sidebarStyle:h,updatesUnreadCount:b,currentPath:v,draggingProduct:S,activeDropListId:C,onSelectList:I,onSelectStatus:A,onCreateList:k,onOpenHome:E,onOpenDiscover:y,onOpenSearch:N,onOpenStores:_,onOpenUpdates:P,onOpenGuide:V,onNavigate:L,onOpenSettings:z,onOpenShortcutsHelp:B,onSignOut:re,onPrepareDestination:Z,onToggleMinimalMode:D,onToggleTheme:K,minimalMode:ee,theme:J}){const[fe,De]=d.useState(0),Be=Ee=>()=>Z?.(Ee),[Fe,ke]=d.useState(!1),We=d.useRef(null),de=d.useRef(null),ye=!1,ge=Math.max(1,Math.ceil(e.length/sd)),W=Math.min(fe,ge-1)*sd,Le=e.slice(W,W+sd),et=e.findIndex(Ee=>Ee.name===t),pt=et>=0?e[et]:null,$t=pt&&Le.some(Ee=>Ee.id===pt.id);pt&&!$t&&(et<W?[pt,...Le].slice(0,sd):[...Le.slice(0,sd-1)]),e.length>sd;const pe=void 0,Tt=i||c||l||o||u||p||m||!!Lw(v),F=Math.max(0,Math.trunc(Number(b)||0)),te=F>99?"99+":String(F),me=f&&F>0?`Updates, ${te} unread`:"Updates",ie=c||v==="/account",Ae=!Tt&&r==="active";d.useEffect(()=>{De(Ee=>Math.min(Ee,ge-1))},[ge]),d.useEffect(()=>{et>=0&&De(Math.floor(et/sd))},[t,et]),d.useEffect(()=>{if(!Fe)return;const Ee=Qe=>{We.current?.contains(Qe.target)||ke(!1)},xe=Qe=>{Qe.key==="Escape"&&(ke(!1),de.current?.focus())};return document.addEventListener("pointerdown",Ee),window.addEventListener("keydown",xe),()=>{document.removeEventListener("pointerdown",Ee),window.removeEventListener("keydown",xe)}},[Fe]),d.useEffect(()=>{ke(!1)},[r,v]),d.useEffect(()=>{try{window.localStorage.setItem(OW,ye?"true":"false")}catch{}},[ye]);const Re=Ee=>{Ee?.(),ke(!1)},ne=Ee=>{if(L){L(Ee);return}Ft(Ee)},ht=(Ee,xe,Qe=null)=>n.jsxs(n.Fragment,{children:[n.jsx(ub,{type:Ee}),n.jsx("span",{className:"sidebarNavLabel",id:Mo(xe),role:"tooltip",children:xe}),Qe]}),kt=[...Rr.priceTrackingOverviewEnabled?[{isActive:l,label:"Tracking",path:"/price-tracking"}]:[],{isActive:!1,label:"The Edit",path:"/edit",documentNavigation:!0},{isActive:i,label:"Guide",path:"/guide"},{isActive:v==="/",label:"Public homepage",path:"/"}];return n.jsxs("aside",{className:["sidebar","sidebarRedPod","sidebarMinimal",""].filter(Boolean).join(" "),style:h,"aria-label":"Saveboard navigation",children:[n.jsxs("div",{className:"sidebarPodFrame",children:[n.jsx("div",{className:"brandBlock",children:n.jsx("a",{"aria-label":"Saveboard homepage",className:"brand",href:"/",onClick:Ee=>{Ee.preventDefault(),ne("/")},tabIndex:pe,title:"Saveboard homepage",children:n.jsx("img",{alt:"","aria-hidden":"true",className:"appSidebarLogo",decoding:"async",draggable:"false",src:"/brand/saveboard-blue-art-s-logo.png"})})}),n.jsxs("nav",{"aria-hidden":ye,"aria-label":"Main navigation",className:"sidebarTopNav sidebarMenuGroup sidebarMenuGroupTop",id:"sidebar-top-menu",inert:void 0,children:[n.jsx("button",{"aria-current":Ae?"page":void 0,"aria-describedby":Mo("Home"),"aria-label":"Home",className:Ae?"isActive":"",onClick:()=>{if(E){E();return}A("active"),I(rr)},onFocus:Be("home"),onPointerDown:Be("home"),onPointerEnter:Be("home"),style:{"--sidebar-item-index":0},tabIndex:pe,type:"button",children:ht("home","Home")}),n.jsx("button",{"aria-current":o?"page":void 0,"aria-describedby":Mo("Discover"),"aria-label":"Discover",className:o?"isActive":"",onClick:y,onFocus:Be("discover"),onPointerDown:Be("discover"),onPointerEnter:Be("discover"),style:{"--sidebar-item-index":1},tabIndex:pe,type:"button",children:ht("discover","Discover")}),n.jsx("button",{"aria-current":u?"page":void 0,"aria-describedby":Mo("Search"),"aria-label":"Search",className:u?"isActive":"",onClick:N,style:{"--sidebar-item-index":2},tabIndex:pe,type:"button",children:ht("search","Search")}),n.jsx("button",{"aria-current":p?"page":void 0,"aria-describedby":Mo("My Stores"),"aria-label":"My Stores",className:p?"isActive":"",onClick:_,style:{"--sidebar-item-index":3},tabIndex:pe,type:"button",children:ht("stores","My Stores")}),n.jsx("button",{"aria-current":m?"page":void 0,"aria-describedby":Mo("Updates"),"aria-label":me,className:["sidebarUpdatesButton",m?"isActive":""].filter(Boolean).join(" "),onClick:P,style:{"--sidebar-item-index":4},tabIndex:pe,type:"button",children:ht("notifications","Updates",f&&F>0?n.jsx("span",{className:"sidebarUnreadBadge","aria-hidden":"true",children:te}):null)}),n.jsx("button",{"aria-describedby":Mo("Create board"),"aria-label":"Create",onClick:k,style:{"--sidebar-item-index":5},tabIndex:pe,type:"button",children:ht("create","Create board")}),n.jsx("a",{"aria-current":ie?"page":void 0,"aria-describedby":Mo("Profile"),"aria-label":"Profile",className:ie?"isActive":"",href:"/account",onClick:Ee=>{Ee.preventDefault(),ne("/account")},onFocus:Be("account"),onPointerDown:Be("account"),onPointerEnter:Be("account"),style:{"--sidebar-item-index":6},tabIndex:pe,children:ht("profile","Profile")})]}),n.jsxs("div",{"aria-hidden":ye,className:"sidebarBottomNav sidebarMenuGroup sidebarMenuGroupBottom",id:"sidebar-menu-groups",inert:void 0,children:[n.jsxs("button",{"aria-checked":J==="dark","aria-describedby":Mo("Appearance"),"aria-label":J==="dark"?"Enable light mode":"Enable dark mode",className:"sidebarBottomAction sidebarThemeToggle",onClick:K,role:"switch",style:{"--sidebar-item-index":7},tabIndex:pe,type:"button",children:[n.jsx("span",{className:"sidebarThemeIcon","aria-hidden":"true",children:n.jsx(ub,{type:J==="dark"?"moon":"sun"})}),n.jsx("span",{className:"sidebarNavLabel",id:Mo("Appearance"),role:"tooltip",children:"Appearance"})]}),n.jsxs("div",{className:"sidebarMoreMenu",ref:We,children:[n.jsx("button",{"aria-controls":"sidebar-more-menu","aria-describedby":Mo("More"),"aria-expanded":Fe,"aria-haspopup":"menu","aria-label":"More",className:"sidebarMoreTrigger",onClick:()=>ke(Ee=>!Ee),ref:de,style:{"--sidebar-item-index":9},tabIndex:pe,type:"button",children:ht("more","More")}),Fe?n.jsxs("div",{className:"saveboardMenuPanel",id:"sidebar-more-menu",role:"menu",children:[n.jsx("button",{"aria-checked":ee,className:`saveboardMenuRow saveboardMenuToggleRow${ee?" isActive":""}`,onClick:D,role:"menuitemcheckbox",tabIndex:pe,type:"button",children:"Minimal mode"}),Nw.filter(({disabled:Ee,value:xe})=>!Ee&&(xe==="purchased"||xe==="archived"||f&&xe==="trash")).map(({label:Ee,title:xe,value:Qe})=>n.jsx("button",{"aria-label":Ee,className:`saveboardMenuRow${r===Qe?" isActive":""}`,onClick:()=>Re(()=>A(Qe)),role:"menuitem",tabIndex:pe,title:xe||Ee,type:"button",children:Ee},Qe)),kt.filter(Ee=>Ee.label!=="Guide").map(Ee=>n.jsx("a",{className:`saveboardMenuRow${Ee.isActive?" isActive":""}`,href:Ee.path,onClick:xe=>{Ee.documentNavigation||(xe.preventDefault(),Re(()=>ne(Ee.path)))},role:"menuitem",tabIndex:pe,children:Ee.label},Ee.label)),n.jsx("button",{className:"saveboardMenuRow",onClick:()=>{de.current?.focus(),Re(z)},role:"menuitem",tabIndex:pe,type:"button",children:"Settings"}),n.jsx("button",{className:"saveboardMenuRow",onClick:()=>Re(B),role:"menuitem",tabIndex:pe,type:"button",children:"Shortcuts"}),n.jsx("button",{className:`saveboardMenuRow${i?" isActive":""}`,onClick:()=>Re(V),role:"menuitem",tabIndex:pe,type:"button",children:"Help"}),f?n.jsx("button",{className:"saveboardMenuRow accountSignOutRow",onClick:()=>Re(re),role:"menuitem",tabIndex:pe,type:"button",children:"Sign out"}):null]}):null]})]})]}),n.jsxs("details",{className:"mobileUtilityMenu",children:[n.jsx("summary",{children:"More"}),n.jsxs("nav",{"aria-label":"More",children:[Nw.filter(({disabled:Ee,value:xe})=>!Ee&&(xe==="purchased"||xe==="archived"||f&&xe==="trash")).map(({label:Ee,value:xe})=>n.jsx("button",{className:r===xe?"isActive":"",onClick:()=>A(xe),type:"button",children:Ee},xe)),kt.filter(Ee=>Ee.label!=="Guide").map(Ee=>n.jsx("a",{className:Ee.isActive?"isActive":"",href:Ee.path,onClick:xe=>{Ee.documentNavigation||(xe.preventDefault(),ne(Ee.path))},children:Ee.label},Ee.label)),n.jsx("button",{onClick:Ee=>{Ee.currentTarget.closest("details")?.querySelector("summary")?.focus(),z()},type:"button",children:"Settings"}),n.jsx("button",{onClick:B,type:"button",children:"Shortcuts"}),n.jsx("button",{className:i?"isActive":"",onClick:Ee=>{const xe=Ee.currentTarget.closest("details");xe?.querySelector("summary")?.focus(),xe?.removeAttribute("open"),V()},type:"button",children:"Help"})]})]})]})}function IG({activeStatus:e,canAddItems:t=!0,detailIsOpen:r=!1,allItemsIsActive:a,boardsIsActive:s,currentPath:o,discoverIsActive:i,profileIsActive:c,priceTrackingAvailable:l,signedIn:u,title:p,updatesIsActive:m,updatesUnreadCount:f,onCreateBoard:h,onOpenAddProduct:b,onOpenAllItems:v,onOpenBoards:S,onOpenDiscover:C,onOpenGuide:I,onOpenProfile:A,onOpenSearch:k,onOpenSettings:E,onOpenShortcutsHelp:y,onOpenStores:N,onOpenUpdates:_,onPrepareDestination:P,onSelectStatus:V}){const L=d.useRef(r);d.useLayoutEffect(()=>{!r&&!L.current&&window.matchMedia("(max-width: 768px), (max-width: 932px) and (max-height: 500px) and (pointer: coarse)").matches&&window.scrollTo({top:0,left:0,behavior:"instant"}),L.current=r},[o,p,e,r]);const[z,B]=d.useState(!1),re=d.useRef(null),Z=d.useRef(null),D=Math.max(0,Math.trunc(Number(f)||0)),K=D>99?"99+":String(D),ee=u&&D>0?`Updates, ${K} unread`:"Updates";d.useEffect(()=>
32{const De=window.visualViewport;if(!De)return;const Be=()=>{const ke=document.activeElement?.matches("input, textarea, [contenteditable='true']")?Math.max(0,window.innerHeight-De.height-De.offsetTop):0;document.documentElement.style.setProperty("--mobile-keyboard-inset",`${ke}px`),document.documentElement.style.setProperty("--mobile-visual-height",`${De.height}px`),document.documentElement.style.setProperty("--mobile-visual-top",`${De.offsetTop}px`)};return Be(),De.addEventListener("resize",Be),De.addEventListener("scroll",Be),document.addEventListener("focusin",Be),document.addEventListener("focusout",Be),()=>{De.removeEventListener("resize",Be),De.removeEventListener("scroll",Be),document.removeEventListener("focusin",Be),document.removeEventListener("focusout",Be),document.documentElement.style.removeProperty("--mobile-keyboard-inset"),document.documentElement.style.removeProperty("--mobile-visual-height"),document.documentElement.style.removeProperty("--mobile-visual-top")}},[]),d.useEffect(()=>{if(!z)return;const De=Fe=>{re.current?.contains(Fe.target)||B(!1)},Be=Fe=>{Fe.key==="Escape"&&(B(!1),Z.current?.focus())};return document.addEventListener("pointerdown",De),window.addEventListener("keydown",Be),()=>{document.removeEventListener("pointerdown",De),window.removeEventListener("keydown",Be)}},[z]),d.useEffect(()=>{B(!1)},[e,o]);const J=De=>{De?.(),B(!1)},fe=[{isActive:s,label:"Boards",icon:"board",onClick:S,prepare:"home"},{isActive:a,label:"All Items",icon:"allItems",onClick:v},{isActive:i,label:"Discover",icon:"discover",onClick:C,prepare:"discover"},{isActive:c,label:"Profile",icon:"profile",onClick:A,prepare:"account"}];return n.jsxs("div",{className:"mobileAppChrome","aria-label":"Mobile Saveboard navigation",children:[n.jsxs("header",{className:"mobileAppTopBar",children:[n.jsx("button",{className:"mobileAppBrandButton",onClick:S,type:"button","aria-label":"Open boards",children:n.jsx(LR,{alt:"","aria-hidden":"true",className:"appLogoMark mobileAppLogo"})}),n.jsx("div",{className:"mobileAppTitle","aria-live":"polite",children:n.jsx("strong",{children:p})}),n.jsxs("div",{className:"mobileAppActions","aria-label":"Quick actions",children:[n.jsx("button",{className:"mobileAppActionButton",onClick:k,type:"button","aria-label":"Search Saveboard",children:"Search"}),t?n.jsx("button",{className:"mobileAppActionButton mobileAppAddButton",onClick:b,type:"button","aria-label":"Add item",children:"+"}):null,n.jsxs("div",{className:"mobileAppMoreMenu",ref:re,children:[n.jsx("button",{"aria-expanded":z,"aria-haspopup":"menu",className:"mobileAppActionButton",onClick:()=>B(De=>!De),ref:Z,type:"button",children:"More"}),z?n.jsxs("div",{className:"mobileAppMorePanel",role:"menu",children:[u&&h?n.jsx("button",{onClick:()=>J(h),role:"menuitem",type:"button",children:"Create board"}):null,n.jsx("button",{onClick:()=>J(k),role:"menuitem",type:"button",children:"Search Saveboard"}),n.jsx("a",{href:"/edit",role:"menuitem",children:"The Edit"}),n.jsx("button",{onClick:()=>J(N),role:"menuitem",type:"button",children:"Stores"}),n.jsxs("button",{"aria-label":ee,className:m?"isActive":"",onClick:()=>J(_),role:"menuitem",type:"button",children:[n.jsx("span",{children:"Updates"}),u&&D>0?n.jsx("span",{className:"mobileAppMenuBadge","aria-hidden":"true",children:K}):null]}),Nw.filter(({disabled:De,value:Be})=>!De&&(Be==="purchased"||Be==="archived"||u&&Be==="trash")).map(({label:De,value:Be})=>n.jsx("button",{className:e===Be?"isActive":"",onClick:()=>J(()=>V(Be)),role:"menuitem",type:"button",children:De},Be)),l?n.jsx("button",{onClick:()=>J(()=>Ft("/price-tracking")),role:"menuitem",type:"button",children:"Tracking"}):null,n.jsx("button",{onClick:()=>{Z.current?.focus(),J(E)},role:"menuitem",type:"button",children:"Settings"}),n.jsx("button",{className:o==="/guide"?"isActive":"",onClick:()=>J(I),role:"menuitem",type:"button",children:"Help"})]}):null]})]})]}),n.jsx("nav",{className:"mobileBottomNav","aria-label":"Primary mobile navigation",children:fe.map(De=>n.jsxs("button",{"aria-current":De.isActive?"page":void 0,className:De.isActive?"isActive":"",onClick:De.onClick,onPointerDown:De.prepare?()=>P?.(De.prepare):void 0,type:"button",children:[n.jsx(ub,{type:De.icon}),De.label]},De.label))})]})}function AG(){return n.jsxs("svg",{"aria-hidden":"true",focusable:"false",viewBox:"0 0 16 16",children:[n.jsx("path",{d:"M6 4.5H4.5A1.5 1.5 0 0 0 3 6v5.5A1.5 1.5 0 0 0 4.5 13H10a1.5 1.5 0 0 0 1.5-1.5V10"}),n.jsx("path",{d:"M9 3h4v4"}),n.jsx("path",{d:"M8 8l5-5"})]})}function PG(){return n.jsxs("svg",{"aria-hidden":"true",focusable:"false",viewBox:"0 0 16 16",children:[n.jsx("path",{d:"M3.5 4.5h9"}),n.jsx("path",{d:"M6.25 4.5l.45-1h2.6l.45 1"}),n.jsx("path",{d:"M5 4.5l.45 8.5h5.1L11 4.5"}),n.jsx("path",{d:"M7 6.5v4.25"}),n.jsx("path",{d:"M9 6.5v4.25"})]})}function _G(){return n.jsxs("svg",{"aria-hidden":"true",focusable:"false",viewBox:"0 0 16 16",children:[n.jsx("path",{d:"M9.5 3H13v3.5"}),n.jsx("path",{d:"m13 3-4.25 4.25"}),n.jsx("path",{d:"M6.5 13H3V9.5"}),n.jsx("path",{d:"m3 13 4.25-4.25"})]})}function w_(){return n.jsxs("svg",{"aria-hidden":"true",focusable:"false",viewBox:"0 0 16 16",children:[n.jsx("path",{d:"m10.75 3.25 2 2"}),n.jsx("path",{d:"m4.25 11.75.7-2.7 5.8-5.8 2 2-5.8 5.8-2.7.7Z"})]})}const mL=d.memo(function({cardSize:t,interactive:r,product:a}){const s=Sx(a),o=aa(String(a?.url||""));
32ts(a.price)&&On(a.price);const i=qo(s),c=zi(a,s),l=ip(s,c,{width:Os.card}),u=gS(a,{mode:Lr.normal,size:t??a.cardSize}),p=gS(a,{mode:Lr.minimal,size:t??a.cardSize}),m=i?void 0:Ed(u),f=i?void 0:Ed(p),h=i?void 0:{"--product-image-normal-fit":m.objectFit,"--product-image-normal-position":m.objectPosition,"--product-image-normal-transform":m.transform,"--product-image-normal-transform-origin":m.transformOrigin,"--product-image-minimal-fit":f.objectFit,"--product-image-minimal-position":f.objectPosition,"--product-image-minimal-transform":f.transform,"--product-image-minimal-transform-origin":f.transformOrigin},b=i?void 0:kd(a),v=ST(a);return n.jsxs("div",{className:"productPodFace productPodFaceFront",children:[v?n.jsx("span",{className:`productPodSyncChip${v.tone==="rejected"?" isRejected":""}`,"data-sync-chip":v.tone,role:"status",children:v.label}):null,r&&o?n.jsx("a",{"aria-label":`Open ${a.title||"product"} in a new tab`,className:"productPodOpenPill",href:o,onClick:S=>S.stopPropagation(),onPointerDown:S=>S.stopPropagation(),rel:"noopener noreferrer",target:"_blank",children:"Open"}):null,n.jsx("div",{className:`productImageWindow${i?" hasPlaceholderImage":""}`,style:b,children:i?null:n.jsx(Ms,{alternateSources:l.alternateSources,className:"productPodImage",alt:"",decoding:"async",draggable:!1,fallbackSource:jn,loading:"lazy",source:l.source,style:h})})]})});function EG({product:e}){const t=ts(e?.price)?On(e.price):"",r=PL(e);return n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"productPodDetails itemTileCaption",children:n.jsx("h2",{className:"itemTileName",children:e?.title})}),n.jsxs("div",{className:"productPodFooter itemTileMeta",children:[n.jsx("span",{className:"itemTileSource",children:r}),n.jsx("p",{"aria-hidden":t?void 0:"true",className:"productPodPrice itemTilePrice",children:t})]})]})}const Yh=[{color:"#4c8a5a",label:"Active",value:"active"},{color:"#163a5f",label:"Purchased",value:"purchased"},{color:"#a5a19a",label:"Archived",value:"archived"}],C_=["#163a5f","#4c8a5a","#b4553c","#7d6aa8","#c9a54a","#3c7f8c","#a5674b","#6f7f4c"],kG=(e="")=>{const t=String(e||"");let r=0;for(let a=0;a<t.length;a+=1)r=r*31+t.charCodeAt(a)>>>0;return C_[r%C_.length]},x_=()=>n.jsx("svg",{"aria-hidden":"true",className:"productPodBackMetaChevron",viewBox:"0 0 24 24",children:n.jsx("path",{d:"m6 9 6 6 6-6"})}),I_=()=>n.jsx("svg",{"aria-hidden":"true",className:"productPodBackMenuCheck",viewBox:"0 0 24 24",children:n.jsx("path",{d:"m5 12.5 4 4 10-10"})}),gu=6,A_=({direction:e})=>n.jsx("svg",{"aria-hidden":"true",className:"popoverMenuPagerIcon",viewBox:"0 0 24 24",children:n.jsx("path",{d:e==="prev"?"m14 6-6 6 6 6":"m10 6 6 6-6 6"})}),Vw=({activeIndex:e=-1,items:t,itemLabel:r="options",listClassName:a,listProps:s,renderItem:o,rowClassName:i})=>{const c=Math.max(1,Math.ceil(t.length/gu)),l=t.length>gu,[u,p]=d.useState(()=>l&&e>=0?Math.floor(e/gu):0),m=Math.min(Math.max(u,0),c-1),f=l?m*gu:0,h=l?t.slice(f,f+gu):t,b=d.useRef(null),v=d.useRef(!1);d.useEffect(()=>{v.current&&(v.current=!1,b.current?.querySelector('[role="option"], [role="menuitemradio"]')?.focus())},[m]);const S=(I,{moveFocusToRow:A=!1}={})=>{v.current=A,p(Math.max(0,Math.min(c-1,I)))},C=I=>{if(!l||I.key!=="ArrowLeft"&&I.key!=="ArrowRight")return;I.preventDefault();const A=I.target.matches?.('[role="option"], [role="menuitemradio"]');S(m+(I.key==="ArrowRight"?1:-1),{moveFocusToRow:A})};return n.jsxs("div",{className:"popoverMenuPages",onKeyDown:C,ref:b,children:[n.jsxs("div",{className:a,...s,children:[h.map((I,A)=>o(I,f+A)),l?Array.from({length:gu-h.length},(I,A)=>n.jsx("button",{"aria-hidden":"true",className:`${i} popoverMenuPageFiller`,disabled:!0,tabIndex:-1,type:"button",children:" "},`filler-${A}`)):null]}),l?n.jsxs("div",{className:"popoverMenuPager",children:[n.jsx("button",{"aria-label":`Previous page of ${r}`,className:"popoverMenuPagerButton",disabled:m===0,onClick:I=>{I.stopPropagation(),S(m-1)},onPointerDown:I=>I.stopPropagation(),type:"button",children:n.jsx(A_,{direction:"prev"})}),n.jsxs("span",{"aria-live":"polite",className:"popoverMenuPagerStatus",children:[m+1," / ",c]}),n.jsx("button",{"aria-label":`Next page of ${r}`,className:"popoverMenuPagerButton",disabled:m===c-1,onClick:I=>{I.stopPropagation(),S(m+1)},onPointerDown:I=>I.stopPropagation(),type:"button",children:n.jsx(A_,{direction:"next"})})]}):null]})},NG=d.memo(function({capabilities:t=jl,boards:r=[],cardSize:a,isFlipped:s,isRestorePending:o,isTrashView:i,onChangeBoard:c,onChangeStatus:l,onCreateBoard:u,onDelete:p,onExpandProduct:m,onEditProduct:f,onRestoreProduct:h,product:b}
32){const[v,S]=d.useState(null),C=d.useRef(null),I=new Map(tG(b).map(({label:ee,value:J})=>[ee,J])),A=b.brand&&b.brand!=="Unlisted"?b.brand:"",k=String(b.price||"").trim(),E=k&&!/^(?:[$£€¥₹₩₺]|NZ\$|A\$|C\$|HK\$|S\$|MX\$|R\$|CHF|AED|SAR|kr|zł|R)?\s*-+\s*$/i.test(k),y=va(b.status),N=Yh.find(ee=>ee.value===y)||Yh[0],_=i?"Trash":N.label,P=zn(a),V=P!==mn.standard,L=b.category||"",z=!i&&r.length>0,B=!i,re=ee=>{ee.stopPropagation()};d.useEffect(()=>{s||S(null)},[s]),d.useEffect(()=>{if(!v||typeof document>"u")return;const ee=fe=>{C.current?.contains(fe.target)||S(null)},J=fe=>{fe.key==="Escape"&&S(null)};return document.addEventListener("pointerdown",ee,!0),window.addEventListener("keydown",J),()=>{document.removeEventListener("pointerdown",ee,!0),window.removeEventListener("keydown",J)}},[v]);const Z=(ee,J,{control:fe=!1}={})=>n.jsxs("div",{className:`productPodBackMetaRow${fe?" hasControl":""}`,children:[n.jsx("dt",{children:ee}),n.jsx("dd",{children:J})]},ee),D=z?n.jsxs(n.Fragment,{children:[n.jsxs("button",{"aria-expanded":v==="board","aria-haspopup":"menu","aria-label":`Move ${b.title} to another board`,hidden:!t.canMoveItemsBetweenBoards,className:"productPodBackMetaControl",onClick:ee=>{ee.stopPropagation(),S(J=>J==="board"?null:"board")},onDoubleClick:re,onPointerDown:re,tabIndex:s?0:-1,title:"Move to board",type:"button",children:[n.jsx("span",{className:"productPodBackMetaControlValue",children:L}),n.jsx(x_,{})]}),v==="board"?n.jsxs("div",{className:"productPodBackMenu productPodBackMenuBoards",role:"menu",children:[n.jsx("p",{className:"productPodBackMenuLabel",children:"Move to board"}),n.jsx(Vw,{activeIndex:r.findIndex(ee=>ee.name===L),itemLabel:"boards",items:r,listClassName:"productPodBackMenuList",listProps:{role:"none"},renderItem:ee=>{const J=ee.name===L;return n.jsxs("button",{"aria-checked":J,className:"productPodBackMenuRow",onClick:fe=>{fe.stopPropagation(),S(null),J||c?.(b,ee.id)},onDoubleClick:re,onPointerDown:re,role:"menuitemradio",tabIndex:s?0:-1,type:"button",children:[n.jsxs("span",{className:"productPodBackMenuLead",children:[n.jsx("span",{"aria-hidden":"true",className:"productPodBackMenuChip",style:{background:kG(ee.id||ee.name)}}),n.jsx("span",{className:"productPodBackMenuName",children:ee.name})]}),J?n.jsx(I_,{}):null]},ee.id||ee.name)},rowClassName:"productPodBackMenuRow"}),n.jsx("span",{"aria-hidden":"true",className:"productPodBackMenuDivider"}),n.jsxs("button",{className:"productPodBackMenuRow productPodBackMenuNew",onClick:ee=>{ee.stopPropagation(),S(null),u?.(b)},onDoubleClick:re,onPointerDown:re,role:"menuitem",tabIndex:s?0:-1,type:"button",children:[n.jsx("svg",{"aria-hidden":"true",className:"productPodBackMenuPlus",viewBox:"0 0 24 24",children:n.jsx("path",{d:"M12 5v14M5 12h14"})}),n.jsx("span",{className:"productPodBackMenuName",children:"New board…"})]})]}):null]}):L,K=B?n.jsxs(n.Fragment,{children:[n.jsxs("button",{"aria-expanded":v==="status","aria-haspopup":"menu","aria-label":`Set status for ${b.title}`,hidden:!t.canChangeItemStatus,className:"productPodBackMetaControl",onClick:ee=>{ee.stopPropagation(),S(J=>J==="status"?null:"status")},onDoubleClick:re,onPointerDown:re,tabIndex:s?0:-1,title:"Set status",type:"button",children:[n.jsx("span",{"aria-hidden":"true",className:"productPodBackStatusDot",style:{background:N.color}}),n.jsx("span",{className:"productPodBackMetaControlValue",children:_}),n.jsx(x_,{})]}),v==="status"?n.jsxs("div",{className:"productPodBackMenu productPodBackMenuStatus",role:"menu",children:[n.jsx("p",{className:"productPodBackMenuLabel",children:"Set status"}),n.jsx(Vw,{activeIndex:Yh.findIndex(ee=>ee.value===y),itemLabel:"statuses",items:Yh,listClassName:"productPodBackMenuList",listProps:{role:"none"},renderItem:ee=>{const J=ee.value===y;return n.jsxs("button",{"aria-checked":J,className:"productPodBackMenuRow",onClick:fe=>{fe.stopPropagation(),S(null),J||l?.(b,ee.value)},onDoubleClick:re,onPointerDown:re,role:"menuitemradio",tabIndex:s?0:-1,type:"button",children:[n.jsxs("span",{className:"productPodBackMenuLead",children:[n.jsx("span",{"aria-hidden":"true",className:"productPodBackStatusDot",style:{background:ee.color}}),n.jsx("span",{className:"productPodBackMenuName",children:ee.label})]}),J?n.jsx(I_,{}):null]},ee.value)},rowClassName:"productPodBackMenuRow"})]}):null]}):_;return n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"productPodBackHeader",children:[n.jsxs("div",{className:"productPodBackHeading",children:[n.jsx("h3",{children:b.title||"Untitled product"}),E?n.jsx("p",{children:k}):null]}),i?null:n.jsx("button",{"aria-label":"Edit item",className:"productPodBackHeaderEdit",hidden:!t.canEditItems,onClick:ee=>{ee.stopPropagation(),f(b)},onDoubleClick:re,onPointerDown:re,tabIndex:s?0:-1,title:"Edit",type:"button",children:n.jsx(w_,{})})]}),n.jsx("div",{className:"productPodBackContent",children:n.jsxs("dl",{className:`productPodBackMeta is-${P}`,"aria-label":"Product details",ref:C,children:[Z("Board",D,{control:z}),Z("Brand",A||"—"),P===mn.large&&I.get("Size")?Z("Size",I.get("Size")):null,Z("Status",K,{control:B}),P===mn.wide?Z("Colour",I.get("Colour")||"—"):null]})}),n.jsx("div",{className:"productPodActions","aria-label":`Actions for ${b.title}`,children:i?n.jsx("div",{className:"productPodActionRow productPodActionRowPrimary",children:n.jsx("button",{"aria-label":`Restore ${b.title}`,className:"productPodActionText productPodActionPrimary",disabled:o,onClick:ee=>{ee.stopPropagation(),h(b)},onDoubleClick:re,onPointerDown:re,tabIndex:s?0:-1,title:"Restore item",type:"button",children:o?"Restoring...":"Restore"})}):n.jsxs("div",{className:"productPodActionRow productPodActionRowPrimary",children:[b.url?n.jsxs("a",{"aria-label":"Open product",className:"productPodActionText productPodActionPrimary productPodActionOpen",href:b.url,onClick:re,onDoubleClick:re,onPointerDown:re,rel:"noopener noreferrer",tabIndex:s?0:-1,target:"_blank",title:"Open product",children:[n.jsx(AG,{}),n.jsx("span",{children:"Open"})]}):null,n.jsxs("button",{"aria-label":"Edit item",className:"productPodActionText productPodActionPrimary productPodActionEdit",hidden:!t.canEditItems,onClick:ee=>{ee.stopPropagation(),f(b)},onDoubleClick:re,onPointerDown:re,tabIndex:s?0:-1,title:"Edit item",type:"button",children:[n.jsx(w_,{}),V?n.jsx("span",{children:"Edit"}):null]}),n.jsxs("button",{"aria-label":"View item details",className:"productPodActionText productPodActionPrimary productPodActionDetail
32s",onClick:ee=>{ee.stopPropagation(),m(b)},onDoubleClick:re,onPointerDown:re,tabIndex:s?0:-1,title:"View item details",type:"button",children:[n.jsx(_G,{}),V?n.jsx("span",{children:"Details"}):null]}),n.jsx("button",{"aria-label":"Delete product",className:"productPodActionIcon productPodActionDanger",hidden:!t.canDeleteItems,onClick:ee=>{ee.stopPropagation(),p?.(b)},onDoubleClick:re,onPointerDown:re,tabIndex:s?0:-1,title:"Delete product",type:"button",children:n.jsx(PG,{})})]})})]})});function jG({dragSession:e,podHeight:t,preference:r}){if(!e?.product)return null;const a=e.phase||"dragging";return n.jsx("div",{className:"productDragOverlay","data-drag-phase":a,"aria-hidden":"true",style:{width:`${e.width}px`,height:`${e.height}px`,transform:`translate3d(${e.x-e.offsetX}px, ${e.y-e.offsetY}px, 0)`,"--pod-width":r.podWidth,"--pod-aspect-ratio":r.podAspectRatio,"--pod-height":`${t}px`},children:n.jsx("article",{className:"productPod productPodOverlay",children:n.jsxs("div",{className:"productPodMedia",children:[n.jsx("div",{className:"productPodCard",children:n.jsx(mL,{cardSize:e.product.cardSize,product:e.product})}),e.groupSize>1?n.jsxs("span",{className:"productDragGroupBadge",style:{position:"absolute",right:"10px",top:"10px",zIndex:3,display:"inline-flex",alignItems:"center",minHeight:"24px",padding:"0 9px",borderRadius:"999px",background:"rgba(21, 24, 28, 0.82)",color:"#fff",fontSize:"0.72rem",fontWeight:700,letterSpacing:"0",boxShadow:"0 8px 22px rgba(0, 0, 0, 0.22)",backdropFilter:"blur(8px)"},children:[e.groupSize," items"]}):null]})})})}const P_=d.memo(function({product:t,index:r,allowVariableCardSize:a=!1,boards:s=_R,capabilities:o=jl,onChangeBoard:i,onCreateBoard:c,onEmptyClick:l,onExpandProduct:u,onEditProduct:p,onDeleteProduct:m,onRestoreProduct:f,onUpdateProductStatus:h,onDragPointerDown:b,manageMode:v=!1,isSelected:S=!1,onToggleSelection:C,isDragging:I,isDragTarget:A,suppressClick:k,emptySlotMode:E="add",isRestorePending:y=!1,isTrashView:N=!1}){const[_,P]=d.useState(!1),[V,L]=d.useState(!1),[z,B]=d.useState(!1);if(d.useEffect(()=>{v&&_&&(L(!1),P(!1))},[_,v]),t){const re=a?zn(t.cardSize):mn.standard,Z=ts(t.price)?On(t.price):"",D=!!b,K=()=>{z||B(!0),L(!0),P(fe=>!fe)},ee=()=>C?.(t),J=fe=>{fe.stopPropagation()};return n.jsxs("article",{className:`productPod${_?" isFlipped":""}${V?" isFlipAnimating":""}${v?" isManageMode":""}${S?" isSelected":""}${I?" isDraggingPod":""}${A?" isDragTarget":""}`,"aria-label":`${t.title}${Z?`, ${Z}`:""}`,"data-card-size":re,"data-product-id":t.id,children:[n.jsxs("div",{"aria-label":v?`${S?"Deselect":"Select"} ${t.title}`:`${_?"Hide":"Show"} details for ${t.title}`,"aria-pressed":v?S:_,className:"productPodMedia",onPointerEnter:()=>nL(t),onPointerLeave:()=>wx(t),onClick:fe=>{if(k){fe.preventDefault();return}if(v){fe.preventDefault(),ee();return}if(!N&&window.matchMedia(zw).matches){u(t);return}K()},onDoubleClick:fe=>{if(k){fe.preventDefault();return}fe.preventDefault(),!(v||N)&&u(t)},onKeyDown:fe=>{if(fe.target===fe.currentTarget){if(fe.key==="Enter"||fe.key===" "){if(fe.preventDefault(),v){ee();return}if(!N&&window.matchMedia(zw).matches){u(t);return}K();return}if(!v){if(fe.key==="Escape"&&_){fe.preventDefault(),L(!0),P(!1);return}if(!N&&!(fe.metaKey||fe.ctrlKey||fe.altKey)){if(fe.key.toLowerCase()==="e"){fe.preventDefault(),p(t);return}if(fe.key==="Delete"||fe.key==="Backspace"){fe.preventDefault(),m(t);return}if(fe.key.toLowerCase()==="a"&&va(t.status)!=="archived"){fe.preventDefault(),h(t,"archived");return}if(fe.key.toLowerCase()==="p"){fe.preventDefault(),h(t,va(t.status)==="purchased"?"active":"purchased");return}fe.key.toLowerCase()==="o"&&t.url&&(fe.preventDefault(),window.open(t.url,"_blank","noopener,noreferrer"))}}}},onPointerDown:D?fe=>b(t,fe):void 0,role:"button",tabIndex:0,children:[v?n.jsx("button",{"aria-label":`${S?"Deselect":"Select"} product`,"aria-pressed":S,className:`productSelectionControl${S?" isSelected":""}`,onClick:fe=>{fe.stopPropagation(),ee()},onDoubleClick:J,onPointerDown:J,tabIndex:0,type:"button",children:n.jsx("span",{"aria-hidden":"true"})}):null,v&&D?n.jsxs("span",{"aria-hidden":"true",className:"productDragHandle",onClick:J,onDoubleClick:J,onPointerDown:J,children:[n.jsx("span",{}),n.jsx("span",{}),n.jsx("span",{}),n.jsx("span",{})]}):null,n.jsxs("div",{className:"productPodCard",onTransitionEnd:fe=>{fe.target===fe.currentTarget&&fe.propertyName==="transform"&&L(!1)},children:[n.jsx(mL,{cardSize:re,interactive:!0,product:t}),n.jsx("div",{className:"productPodFace productPodFaceBack","aria-hidden":!_,children:z?n.jsx(NG,{boards:s,capabilities:o,cardSize:re,isFlipped:_,isRestorePending:y,isTrashView:N,onChangeBoard:i,onChangeStatus:h,onCreateBoard:c,onDelete:m,onExpandProduct:u,onEditProduct:p,onRestoreProduct:f,product:t}):null})]})]}),n.jsx(EG,{product:t})]})}return E==="filler"?n.jsx("div",{className:"emptyPod emptyPodFiller","aria-hidden":"true"}):n.jsx("button",{className:"emptyPod",type:"button","aria-label":`Add product to slot ${r+1}`,onClick:()=>l(r)})}),fL=Object.fromEntries(pp.map(e=>[e,`v2Cover${e[0].toUpperCase()}${e.slice(1)}`])),__=pp.filter(e=>e!=="ink"&&e!=="midnight"),Hw=new Map,RG=(e={})=>{Hw.clear();for(const[t,r]of Object.entries(e||{}))pp.includes(r)&&Hw.set(t,r)},hL=(e="")=>{const t=String(e||""),r=Hw.get(t);if(r)return r;let a=0;for(let s=0;s<t.length;s+=1)a=(a*31+t.charCodeAt(s))%1e5;return __[a%__.length]},xx=(e="")=>fL[hL(e)];function Bd({coverItemIds:e=[],list:t={},products:r=[]}){const a=JR({...t,coverItemIds:e},r).filter(o=>kn(o)).slice(0,zo),s=a.length?a:[null];return n.jsx("div",{className:`listPodCover ${xx(t?.id||t?.name||"")}`,"aria-hidden":"true","data-tile-count":a.length,children:s.map((o,i)=>{const c=kn(o),l=!!c,u=zi(o,c),p=ip(c,u,{width:Os.cover}),m=l?Uw(o):void 0,f=l?kd(o):void 0;return n.jsx("span",{className:`listPodCoverTile${l?" hasImage":" isPlaceholder"}`,style:f,children:l?n.jsx(Ms,{alt:"",alternateSources:p.alternateSources,decoding:"async",draggable:!1,fallbackSource:jn,loading:"lazy",onFallback:jw,onLoad:Rw,source:p.source,style:m}):null},o?.id||`placeholder-${i}`)})})}const Ix=(e="")=>{const t=String(e||"").trim().replace(/^@+/,"");return t?`@${t}`:""};function gL({list:e}){const t=wT(e||{});return t?n.jsx("span",{className:`productPodSyncChip${t.tone==="rejected"?" isRejected":""}`,"data-board-sync-chip":t.tone,role:"status",children:t.label}):null}function bL({index:e=0,ownerHandle:t="",summary:r,activeDropListId:a,draggingProduct:s,onPrepareList:o,onSelectList:i}){const c=()=>o?.(r.list.name),l=`${r.totalCount} ${r.totalCount===1?"item":"items"}`;return n.jsxs("article",{className:"listPod boardTile",children:[n.jsxs("button",{"aria-label":`Open ${r.list.name} board, ${l}`,className:`listPodSurface boardTileSurface${s?" isListDropTarget":""}${a===r.list.id?" isDragOverList":""}`,"data-list-drop-id":r.list.id,"data-list-drop-name":r.list.name,onClick:()=>i(r.list.name),onFocus:c,onPointerDown:c,onPointerEnter:c,type:"button",children:[n.jsxs("span",{className:"boardTileCover",children:[n.jsx(Bd,{coverItemIds:r.list.coverItemIds,list:r.list,products:r.products}),n.jsx(gL,{list:r.list})]}),n.jsxs("div",{className:"listPodDetails boardTileCaption",children:[n.jsx("span",{"aria-hidden":"true",className:"boardTileIndex",children:Ko(e)}),n.jsx("h2",{className:"boardCardTitle boardTileName",children:r.list.name})]})]}),n.jsxs("div",{className:"boardTileMeta",children:[n.jsx("span",{className:"boardTileOwner",children:t}),n.jsx("span",{className:"boardTileCount",children:l})]})]})}function LG({listSummaries:e,ownerHandle:t="",searchIsActive:r,activeDropListId:a,draggingProduct:s,isSettling:o=!1,onCreateBoard:i,onPrepareList:c,onSelectList:l}){return n.jsxs("section",{className:"dashboardListGrid","aria-label":"Wishlist boards",children:[e.map((u,p)=>n.jsx(bL,{activeDropListId:a,draggingProduct:s,index:p,ownerHandle:t,summary:u,onPrepareList:c,onSelectList:l},u.list.id)),o&&e.length===0?n.jsx(wL,{}):null,!r&&!o&&e.length===0?n.jsxs("div",{className:"mobileBoardsEmptyState",children:[n.jsx("span",{children:"No boards yet"}),n.jsx("p",{children:"Create a board to start saving items in one place."}),i?n.jsx("button",{className:"mobileBoardsEmptyAction",onClick:i,type:"button",children:"Create first board"}):null]}):null]})}function BG({board:e}){const t=String(e?.coverImageUrl||"").trim();return n.jsx(rv,{className:`sharedBoardCover${t?" hasImage":""}`,"aria-hidden":"true",imageSource:t,settings:e,children:t?n.jsx("img",{alt:"",decoding:"async",loading:"lazy",src:t}):n.jsx(Ol,{trademark:!1,variant:"monochrome"})})}const Wu=(e={})=>
32e.displayName||(e.username?`@${e.username}`:"Saveboard user"),pb=(e="")=>String(e||"").trim().replace(/^@+/,"").toLowerCase(),vL=(e={})=>String(e?.status||"").trim().toLowerCase()==="pending",TG=(e={},t="")=>{const r=String(e?.direction||"").trim().toLowerCase();if(r==="received")return!0;if(r==="sent")return!1;const a=pb(e?.invited?.username),s=pb(t);return!!(a&&s&&a===s)},DG=(e={},t="")=>{const r=String(e?.direction||"").trim().toLowerCase();if(r==="sent")return!0;if(r==="received")return!1;const a=pb(e?.owner?.username),s=pb(t);return!!(a&&s&&a===s)};function OG({board:e,index:t=0,onOpen:r}){const a=e?.owner?.username?`@${e.owner.username}`:Wu(e?.owner),s=Number(e?.itemCount)||0,o=`${s} ${s===1?"item":"items"}`;return n.jsxs("article",{className:"sharedBoardCard boardTile",children:[n.jsxs("button",{"aria-label":`Open shared board ${e.boardTitle}`,className:"sharedBoardCardButton boardTileSurface",onClick:()=>r(e),type:"button",children:[n.jsx("span",{className:"boardTileCover",children:n.jsx(BG,{board:e})}),n.jsxs("div",{className:"sharedBoardDetails boardTileCaption",children:[n.jsx("span",{"aria-hidden":"true",className:"boardTileIndex",children:Ko(t)}),n.jsx("h3",{className:"boardCardTitle boardTileName",children:e.boardTitle||"Shared board"})]})]}),n.jsxs("div",{className:"boardTileMeta",children:[n.jsxs("span",{className:"boardTileOwner",children:[yi(e.role).label," · ",a]}),n.jsx("span",{className:"boardTileCount",children:o})]})]})}const mb=(e={})=>`shared:${e.ownerId||""}:${e.boardId||""}`,MG=(e={})=>({boardDescription:"",boardId:e.boardId||"",boardTitle:e.title||"",coverImageUrl:e.coverImageUrl||"",itemCount:Number(e.itemCount)||0,owner:{avatarUrl:e.ownerAvatarUrl||"",displayName:e.ownerDisplayName||"",username:e.ownerUsername||""},ownerId:e.ownerId||"",role:lo(e.role),sharedAt:e.sharedAt||"",updatedAt:e.updatedAt||""}),Ax=(e={})=>`${String(e.boardTitle||"Shared board").trim()} · @${e.owner?.username||"shared"}`,yL=(e={})=>Sb(e.role)&&sC(e),UG=(e=[])=>(Array.isArray(e)?e:[]).filter(yL).map(t=>{const r=Ax(t);return{boardId:t.boardId,id:mb(t),name:r,ownerId:t.ownerId,ownerUsername:t.owner?.username||"",role:t.role,shared:!0,slug:Di(r)}}),FG=/\s·\s@[^\s@]+$/,$G=6e3,zG=new Set(["authentication-unavailable","session-changed"]),E_=(e={})=>FG.test(String(e?.targetListName||"").trim()),tS=(e,t=[])=>{const r=Ye(e?.targetListName||"").toLowerCase(),a=Ye(e?.targetListSlug||""),s=a?Di(a):"";return!r&&!s?null:(Array.isArray(t)?t:[]).filter(yL).find(o=>{const i=Ax(o);return i.toLowerCase()===r||s&&Di(i)===s})||null},Ww="saveboard:collaboration-changed",dd=()=>{typeof window<"u"&&window.dispatchEvent(new Event(Ww))},VG=5e3,Gw=(e,t)=>{const r=d.useRef(0);d.useEffect(()=>{if(!t||typeof window>"u")return;const a=(c=!1)=>{const l=Date.now();!c&&l-r.current<VG||(r.current=l,e())},s=()=>a(!1),o=()=>{document.visibilityState==="visible"&&a(!1)},i=()=>a(!0);return window.addEventListener("focus",s),window.addEventListener("online",s),document.addEventListener("visibilitychange",o),window.addEventListener(Ww,i),()=>{window.removeEventListener("focus",s),window.removeEventListener("online",s),document.removeEventListener("visibilitychange",o),window.removeEventListener(Ww,i)}},[t,e])},HG=12,WG=(e={})=>{const t=String(e.actorUsername||"").trim().replace(/^@+/,"");return t?Oi(t):""}
32,GG=(e={})=>Ye(e.actorName||"")||"Saveboard user",qG=(e={})=>Ye(e.boardTitle||e.metadata?.boardTitle||"")||"a public board",YG=(e={})=>Ye(e.itemTitle||e.metadata?.itemTitle||""),KG=(e={})=>{const t=Number(e.metadata?.itemCount||e.metadata?.item_count||1);return Number.isFinite(t)?Math.max(1,Math.trunc(t)):1},XG=(e={})=>{const t=qG(e);if(e.eventType===_l.BOARD_CREATED_PUBLIC)return{afterBoard:"",beforeBoard:"Created a new public board:",boardTitle:t};if(e.eventType===_l.ITEM_ADDED_TO_PUBLIC_BOARD){const r=KG(e);return{afterBoard:"",beforeBoard:"Added",boardTitle:t,itemCount:r,itemTitle:YG(e),middle:"to"}}return{afterBoard:"public",beforeBoard:"Made",boardTitle:t}};function JG({activity:e}){const t=GG(e),r=WG(e),a=r?`@${r}`:"",s=r?Yo(r):"",o=r&&e.boardId?jc(r,e.boardId):"",i=XG(e),c=oL(e.createdAt),l=e.actorAvatarUrl?n.jsx("img",{alt:"",src:e.actorAvatarUrl}):n.jsx("span",{children:Rf(t,a)}),u=o?n.jsx("a",{href:o,children:i.boardTitle}):n.jsx("span",{children:i.boardTitle}),p=i.itemTitle?n.jsx("span",{children:i.itemTitle}):n.jsx("span",{children:"a public item"}),m=e.eventType===_l.ITEM_ADDED_TO_PUBLIC_BOARD?i.itemCount>1?n.jsxs(n.Fragment,{children:[i.beforeBoard," ",i.itemCount," items ",i.middle," ",u]}):n.jsxs(n.Fragment,{children:[i.beforeBoard," ",p," ",i.middle," ",u]}):n.jsxs(n.Fragment,{children:[i.beforeBoard," ",u,i.afterBoard?` ${i.afterBoard}`:""]});return n.jsxs("article",{className:"followingUpdateRow",children:[s?n.jsx("a",{className:"followingUpdateAvatar",href:s,"aria-label":`View ${t}'s profile`,children:l}):n.jsx("span",{className:"followingUpdateAvatar","aria-hidden":"true",children:l}),n.jsxs("div",{className:"followingUpdateContent",children:[n.jsxs("div",{className:"followingUpdateMeta",children:[s?n.jsx("a",{href:s,children:t}):n.jsx("span",{children:t}),a?n.jsx("span",{children:a}):null,c?n.jsx("time",{dateTime:e.createdAt,children:c}):null]}),n.jsx("p",{children:m})]})]})}function QG({currentProfileUsername:e="",rowLayout:t=!1,signedIn:r=!1}){const[a,s]=d.useState({activities:[],error:"",followingCount:null,isLoading:!1});if(d.useEffect(()=>{let f=!1;return r?(s(h=>({...h,error:"",isLoading:!0})),UM({limit:HG}).then(h=>{f||s(b=>({...b,activities:h?.error?[]:h?.activities||[],error:h?.error?"Could not load following updates.":"",isLoading:!1}))}).catch(()=>{f||s(h=>({...h,activities:[],error:"Could not load following updates.",isLoading:!1}))}),()=>{f=!0}):(s({activities:[],error:"",followingCount:null,isLoading:!1}),()=>{f=!0})},[r]),d.useEffect(()=>{let f=!1;return!r||!e?(s(h=>h.followingCount===null?h:{...h,followingCount:null}),()=>{f=!0}
32):(Ym(e).then(h=>{f||s(b=>({...b,followingCount:h&&!h.error&&Number.isFinite(h.followingCount)?h.followingCount:null}))}).catch(()=>{f||s(h=>({...h,followingCount:null}))}),()=>{f=!0})},[e,r]),!r)return null;const{activities:o,error:i,followingCount:c,isLoading:l}=a,u=o.length>0,p=c===0?"Follow public profiles to see their new boards here.":"No updates yet.",m="New public boards from people you follow will appear here.";return n.jsxs("section",{className:`followingUpdates${t?" hasRowLayout":""}`,"aria-busy":l?"true":"false","aria-label":"Following updates",children:[n.jsxs("header",{className:"followingUpdatesHeader",children:[n.jsx("h2",{children:"Following updates"}),t?null:n.jsx("p",{children:"Quiet public board activity from profiles you follow."})]}),l?n.jsx("div",{className:"followingUpdatesState",role:"status",children:n.jsx("span",{children:"Loading updates..."})}):i?n.jsx("div",{className:"followingUpdatesState",role:"status",children:n.jsx("span",{children:i})}):u?n.jsx("div",{className:t?"homeScrollRow followingUpdatesRowScroll":"followingUpdatesList",children:o.map(f=>n.jsx(JG,{activity:f},f.id||`${f.eventType}-${f.createdAt}`))}):t?n.jsxs("div",{className:"followingUpdatesBanner",children:[n.jsx("span",{children:p}),n.jsx("p",{children:m})]}):n.jsxs("div",{className:"followingUpdatesState",children:[n.jsx("span",{children:p}),n.jsx("p",{children:m})]})]})}const k_=12,SL="mylist.recentBoardOpens",Px=()=>{try{const e=JSON.parse(localStorage.getItem(SL)||"{}");return e&&typeof e=="object"?e:{}}catch{return{}}},N_=e=>{if(e)try{const t=Px();t[String(e)]=Date.now();const r=Object.fromEntries(Object.entries(t).sort((a,s)=>s[1]-a[1]).slice(0,50));localStorage.setItem(SL,JSON.stringify(r))}catch{}},fb=(e={})=>Date.parse(e.createdAt||"")||Date.parse(e.updatedAt||"")||0;function ZG({product:e,onOpenItem:t}){const r=kn(e),a=ip(r,zi(e,r),{width:Os.card}),s=KR(e),o=String(e.price||"").trim(),i=PL(e);return n.jsxs("button",{"aria-label":`Open ${s}
32`,className:"homeRecentItemCard itemTile",onClick:()=>t?.(e),onPointerEnter:()=>nL(e),onPointerLeave:()=>wx(e),type:"button",children:[n.jsx("span",{"aria-hidden":"true",className:"homeRecentItemMedia itemTileCover",children:r?n.jsx(Ms,{alt:"",alternateSources:a.alternateSources,decoding:"async",draggable:!1,fallbackSource:jn,loading:"lazy",source:a.source}):null}),n.jsx("span",{className:"homeRecentItemDetails itemTileCaption",children:n.jsx("strong",{className:"itemTileName",children:s})}),n.jsxs("span",{className:"itemTileMeta",children:[n.jsx("span",{className:"itemTileSource",children:i}),o?n.jsx("span",{className:"homeRecentItemPrice itemTilePrice",children:o}):null]})]})}const e5=({lists:e=[],products:t=[],viewport:r=op()}={})=>{const a=gf(240,rG,r),s=gf(200,nG,r),o=aL({lists:e,products:t,query:"",status:"active"}),i=Px(),c=p=>i[p.list.id]||i[p.list.name]||Date.parse(p.list.updatedAt||p.list.createdAt||"")||0,l=[...o].sort((p,m)=>c(m)-c(p)).slice(0,a).flatMap(p=>QR(p.list,p.products)),u=o.flatMap(p=>p.products).sort((p,m)=>fb(m)-fb(p)).slice(0,s).map(p=>kn(p)).filter(Boolean).map(p=>Il(p,{width:Os.card}));return[...l,...u]};function wL({count:e=4}){return Array.from({length:e},(t,r)=>n.jsxs("article",{"aria-hidden":"true",className:"listPod boardTile isSkeleton",children:[n.jsxs("button",{className:"listPodSurface boardTileSurface",disabled:!0,tabIndex:-1,type:"button",children:[n.jsx("span",{className:"boardTileCover",children:n.jsx("span",{className:"listPodCover"})}),n.jsxs("div",{className:"listPodDetails boardTileCaption",children:[n.jsx("span",{className:"boardTileIndex",children:Ko(r)}),n.jsx("span",{className:"boardTileName skeletonLine"})]})]}),n.jsxs("div",{className:"boardTileMeta",children:[n.jsx("span",{className:"boardTileOwner skeletonLine skeletonLineShort"}),n.jsx("span",{className:"boardTileCount skeletonLine skeletonLineShort"})]})]},r))}function t5({currentProfileUsername:e,isSettling:t=!1,listSummaries:r,searchIsActive:a,signedIn:s,activeDropListId:o,draggingProduct:i,onPrepareList:c,onSelectList:l,onCreateBoard:u,onOpenItem:p,onOpenSharedBoard:m,sharedBoards:f=[]}){const h=Ix(e),b=fp(),v=d.useMemo(()=>Cl(Ja,b),[b]),S=d.useMemo(()=>({"--standard-board-card-aspect-ratio":v.podAspectRatio,"--standard-board-card-width":v.podWidth}),[v]),C=d.useMemo(()=>Px(),[r,f]),I=d.useMemo(()=>{const k=r.map(y=>({key:y.list.id,kind:"owned",openedAt:C[y.list.id]||C[y.list.name]||Date.parse(y.list.updatedAt||y.list.createdAt||"")||0,summary:y})),E=(Array.isArray(f)?f:[]).map(y=>{const N=mb(y);return{board:y,key:N,kind:"shared",openedAt:C[N]||Date.parse(y.sharedAt||y.updatedAt||"")||0}});return[...k,...E].sort((y,N)=>N.openedAt-y.openedAt).slice(0,k_)},[C,r,f]),A=d.useMemo(()=>r.flatMap(k=>k.products).sort((k,E)=>fb(E)-fb(k)).slice(0,k_),[r]);return n.jsxs("div",{className:"dashboardOverview hasHomeSections",style:S,children:[n.jsxs("header",{className:"homePageHeader",children:[n.jsx("h1",{children:"Home"}),n.jsx("span",{className:"homeHeaderDescription",children:"Your boards, recent saves, and updates from people you follow."})]}),n.jsxs("section",{"aria-label":"My boards",className:"homeSection",children:[n.jsx("header",{className:"homeSectionHeader",children:n.jsx("h2",{children:"My boards"})}),t&&!I.length?n.jsx("div",{"aria-busy":"true",className:"homeScrollRow",children:n.jsx(wL,{})}):I.length?n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"homeScrollRow",children:I.map((k,E)=>k.kind==="shared"?n.jsx(OG,{board:k.board,index:E,onOpen:m},k.key):n.jsx(bL,{activeDropListId:o,draggingProduct:i,index:E,ownerHandle:h,summary:k.summary,onPrepareList:c,onSelectList:l},k.key))}),!r.length&&!a?n.jsxs("div",{className:"mobileBoardsEmptyState",children:[n.jsx("span",{children:"No boards of your own yet"}),n.jsx("p",{children:"Boards shared with you are above. Create a board to start saving items of your own."}),u?n.jsx("button",{className:"mobileBoardsEmptyAction",onClick:u,type:"button",children:"Create first board"}):null]}):null]}):n.jsx(LG,{listSummaries:r,ownerHandle:h,searchIsActive:a,activeDropListId:o,draggingProduct:i,isSettling:t,onCreateBoard:u,onPrepareList:c,onSelectList:l})]}),A.length?n.jsxs("section",{"aria-label":"Recent saves",className:"homeSection",children:[n.jsx("header",{className:"homeSectionHeader",children:n.jsx("h2",{children:"Recent saves"})}),n.jsx("div",{className:"homeScrollRow",children:A.map(k=>n.jsx(ZG,{onOpenItem:p,product:k},k.id))})]}):null,n.jsx(QG,{currentProfileUsername:e,rowLayout:!0,signedIn:s})]})}const r5={blocked:"Blocked",failed:"Failed","low-confidence":"Low confidence","no-price":"No price found",success:"Checked",timeout:"Timed out"},n5=e=>
32{if(e.hasMixedCurrencies||!e.canCompareAmount||e.priceHistory.length<2)return"";if(e.amountChange===0)return"No change since saved";const t=Ya(Math.abs(e.amountChange),e.currentParsedPrice.currency);return`${e.amountChange>0?"Up":"Down"} ${t} since saved`},a5=e=>{if(e.hasMixedCurrencies||!e.canCompareAmount)return"";if(e.amountAboveTarget===0)return"Target reached";const t=Ya(Math.abs(e.amountAboveTarget),e.currentParsedPrice.currency);return`${e.isApproximate?"Approx. ":""}${t} ${e.amountAboveTarget>0?"above target":"below target"}`},s5=(e={})=>!e.userId||e.userId===Mi,o5=(e={})=>jR(e.availabilityTracking)||{cadence:"manual",enabled:!1,failCount:0},i5=(e="")=>e==="success"?"Availability checked":e==="low-confidence"||e==="no-availability"||e==="unknown"?"Could not find a reliable availability result":e==="timeout"?"Availability check timed out":e==="blocked"?"Availability check was blocked":e==="failed"?"Availability check failed":"",c5=(e={})=>{if(e.type==="back-in-stock")return"Back in stock";if(e.type==="low-stock")return"Low stock";if(e.type==="sold-out")return"Recently sold out";if(e.type==="now-available")return"Now available";if(e.type==="discontinued")return"Discontinued";const t=RR(e.currentStatus);return t?`Availability changed to ${t}`:"Availability changed"},l5=[{id:"all",label:"All tracked"},{id:"price",label:"Price"},{id:"availability",label:"Availability"},{id:"alerts",label:"Alerts"},{id:"attention",label:"Needs attention"},{id:"manual",label:"Manual / local"}],d5=(e=[])=>Vo(e).sort((t,r)=>{const a=Date.parse(t.createdAt||""),s=Date.parse(r.createdAt||"");return(Number.isFinite(a)?a:0)-(Number.isFinite(s)?s:0)}).slice(-1)[0]||null,u5=(e=null)=>e?e.status==="sent"?"Email sent":e.status==="failed"?"Email not sent":e.type==="target-hit"?e.status==="pending"?"Target reached":"Target saved":e.type==="price-drop"?e.status==="pending"?"Price dropped":"Price drop saved":"Price alert saved":"",p5=(e=null)=>e?e.status==="sent"?"Availability email sent":e.status==="failed"?"Availability email not sent":c5(e):"",m5=(e={})=>{const t=e.lastCheckStatus?r5[e.lastCheckStatus]||"Checked":"",r=e.lastCheckedAt?vs(e.last
32CheckedAt):"";return t&&r?`${t} · ${r}`:t||r||"Not checked yet"},f5=(e={})=>{const t=e.lastCheckStatus?i5(e.lastCheckStatus):"",r=e.lastCheckedAt?vs(e.lastCheckedAt):"";return t&&r?`${t} · ${r}`:t||r||"Not checked yet"},h5=(e={})=>{const t=ek(e),r=KE(e),a=jT(e),s=$T(e),o=d5(e.priceAlertEvents),i=u5(o),c=s5(e),l=!!aa(String(e.url||"")),u=Rr.availabilityTrackingEnabled,p=Rr.restockUiEnabled,m=u?ib(e):{status:"unknown"},f=u?o5(e):{enabled:!1,cadence:"manual"},h=u?vf(e.availabilityHistory):[],b=p?Bi(e.availabilityAlertEvents):[],v=p?fD(b):null,S=p5(v),C=!!(f.alertOnBackInStock||f.alertOnLowStock||f.alertOnOutOfStock),I=!!(o?.type==="price-drop"||a.canCompareAmount&&Number.isFinite(a.amountChange)&&a.amountChange<0),A=!!s?.enabled,k=!!(t.lastCheckStatus&&t.lastCheckStatus!=="success"||t.failCount>0||t.enabled&&!l||o?.status==="failed"),E=!!(u&&(f.lastCheckStatus&&f.lastCheckStatus!=="success"||f.failCount>0||f.enabled&&!l||v?.status==="failed")),y=!!(t.enabled||r.hasTargetPrice||A||Vo(e.priceAlertEvents).length||t.lastCheckStatus),N=!!(u&&(f.enabled||C||m.status!=="unknown"||h.length||b.length||f.lastCheckStatus));return{alertLabel:i,availability:m,availabilityAlertLabel:S,availabilityHistory:h,availabilityLabel:RR(m.status),availabilityTracking:f,canCheckPrice:l,hasAlertRule:A,hasAvailabilitySetup:N,hasPriceDrop:I,hasPricingSetup:y,history:a,isLocalOnly:c,latestEvent:o,latestAvailabilityEvent:v,needsAttention:k||E,product:e,targetReached:!!r.targetReached,targetSummary:r,tracking:t}},j_=(e=[],t="all")=>t==="price"?e.filter(r=>r.hasPricingSetup):t==="availability"?e.filter(r=>r.hasAvailabilitySetup):t==="alerts"?e.filter(r=>r.targetReached||r.hasPriceDrop||r.latestEvent||r.latestAvailabilityEvent):t==="attention"?e.filter(r=>r.needsAttention):t==="manual"?e.filter(r=>r.isLocalOnly||r.tracking.cadence==="manual"||(r.availabilityTracking.cadence||"manual")==="manual"||!r.tracking.enabled&&!r.availabilityTracking.enabled):e,g5=(e="all")=>e==="price"?"No price tracking yet.":e==="availability"?"No availability tracking yet.":e==="alerts"?"No tracking alerts yet.":e==="attention"?"No products need attention.":e==="manual"?"No manual-only or local-only tracking to show.":Rr.availabilityTrackingEnabled?"Track a product to watch prices and availability.":"Track a product to watch price history.",R_=(e="all")=>e==="all"?"Manual checks work locally. Automatic alerts need sign-in and cloud backup.":e==="attention"?"Products with failed checks, missing links, or alert issues will appear here.":e==="price"?"Set target prices or price alert rules on a product to start watching for changes.":e==="availability"?"Use availability settings on a product to watch stock status.":e==="alerts"?Rr.availabilityTrackingEnabled?"Price and availability alerts appear after Saveboard finds a reliable change.":"Price alerts appear after Saveboard finds a reliable change.":"",CL={recent:"Recently saved",count:"Most saved",alpha:"A-Z",favourite:"Favourites first"},b5=e=>Object.hasOwn(CL,e)?e:"recent",Fo="all",_x=(e={})=>{const t=String(e.url||"").trim();return/^https?:\/\//i.test(t)?t:e.domain?`https://${e.domain}`:"#"},v5=(e="")=>{const t=Tr(e);return t?`https://icons.duckduckgo.com/ip3/${encodeURIComponent(t)}.ico`:""},y5=(e="",t="")=>{const a=String(e||t||"").trim().match(/[a-z0-9]/i)?.[0];return a?a.toUpperCase():"S"},bf=(e="")=>String(e||"").toLowerCase().replace(/[’']/g,"").replace(/&/g," and ").replace(/[^a-z0-9]+/g," ").replace(/\s+/g," ").trim(),S5=.82,L_=new Map([["beauty",["skincare","skin care"]],["clothes",["clothing","fashion"]],["clothing",["clothes","fashion"]],["electronics",["tech","technology"]],["fashion",["clothing","clothes"]],["fragrance",["perfume","scent"]],["gift",["gifts"]],["gifts",["gift","gifting"]],["homeware",["home","interiors"]],["interior",["interiors","home"]],["interiors",["interior","home"]],["lamp",["lamps","lighting"]],["lamps",["lamp","lighting"]],["lighting",["lamp","lamps","lights"]],["shoe",["shoes","trainers"]],["shoes",["shoe","trainers"]],["skin care",["skincare","beauty"]],["skincare",["skin care","beauty"]],["tech",["technology","electronics"]],["technology",["tech","electronics"]],["trainer",["trainers","shoes"]],["trainers",["trainer","shoes"]]]),w5=(e="")=>{const t=bf(e);if(!t)return[];const r=t.replace(/\s+/g,""),a=[...L_.get(t)||[],...r!==t?L_.get(r)||[]:[]],s=new Map([[t,1]]);return a.forEach(o=>{const i=bf(o);i&&!s.has(i)&&s.set(i,S5)}),[...s.entries()].map(([o,i])=>({value:o,weight:i}))},C5=(e,t,r)=>{const a=bf(e),s=bf(t);if(!a||!s)return 0;const o=a.replace(/\s+/g,""),i=s.replace(/\s+/g,"");return a===s||i&&o===i?r.exact:a.startsWith(s)||i&&o.startsWith(i)?r.starts:a.includes(s)||i&&o.includes(i)?r.contains:0},bu=(e=[],t=[],r)=>(Array.isArray(e)?e:[e]).reduce((a,s)=>{const o=t.reduce((i,c)=>Math.max(i,Math.round(C5(s,c.value,r)*c.weight)),0);return Math.max(a,o)},0),x5=(e={},t=[])=>{const r=Tr(e.domain||e.url),a=new Set([...Array.isArray(e.itemIds)?e.itemIds:[],...Array.isArray(e.productIds)?e.productIds:[]].map(String));return(Array.isArray(t)?t:[]).filter(s=>{const o=String(s?.id||"");return r&&Af(s)===r||o&&a.has(o)}).flatMap(s=>[s.title,s.name,s.brand,s.source,s.category,s.listName,s.boardName,s.description,s.notes,s.privateNotes,s.publicNotes]).filter(
32Boolean)},I5=(e={},t="",r=[])=>{const a=bf(t);if(!a)return 0;const s=w5(a),o=Array.isArray(e.manualTags)?e.manualTags:[],i=b$(e,{products:r}),c=Array.isArray(e.categories)?e.categories:[],l=x5(e,r);return Math.max(bu([e.displayName,e.domain,e.url],s,{exact:1e3,starts:900,contains:650}),bu(o,s,{exact:850,starts:800,contains:620}),bu(i,s,{exact:720,starts:670,contains:520}),bu(c,s,{exact:700,starts:640,contains:500}),bu(e.notes,s,{exact:360,starts:320,contains:260}),bu(l,s,{exact:300,starts:260,contains:210}))},A5=(e=[],t="",r="recent",a=[])=>Ex(e,r).map((s,o)=>({index:o,score:I5(s,t,a),store:s})).filter(s=>s.score>0).sort((s,o)=>o.score-s.score||s.index-o.index).map(s=>s.store),nv=(e="")=>String(e||"").trim().toLowerCase(),kf=(e={})=>Tl(e.categories),P5=(e=[])=>{const t=new Map;return e.forEach(r=>{kf(r).forEach(a=>{const s=nv(a);if(!s)return;const o=t.get(s);t.set(s,{key:s,label:o?.label||a,count:(o?.count||0)+1})})}),[...t.values()].sort((r,a)=>r.label.localeCompare(a.label,void 0,{sensitivity:"base"}))},_5=(e={},t=Fo)=>!t||t===Fo?!0:kf(e).some(r=>nv(r)===t),mg=(e,t)=>String(e.displayName||e.domain||"").localeCompare(String(t.displayName||t.domain||""),void 0,{sensitivity:"base"})||String(e.domain||"").localeCompare(String(t.domain||"")),Ex=(e=[],t="recent")=>[...e].sort((r,a)=>{const s=Em(Du(r.lastSavedAt||r.updatedAt||r.createdAt),Du(a.lastSavedAt||a.updatedAt||a.createdAt),"desc")||mg(r,a);return t==="count"?(Number(a.savedItemCount)||0)-(Number(r.savedItemCount)||0)||mg(r,a):t==="alpha"?mg(r,a):t==="favourite"&&+!!a.favourite-+!!r.favourite||s}),xL=e=>{const t=Math.max(0,Math.trunc(Number(e)||0));return`${t} saved item${t===1?"":"s"}`},E5=(e=[],t="")=>{const r=Tr(t);return r?(Array.isArray(e)?e:[]).filter(a=>Af(a)===r):[]},k5=(e,t)=>e?.displayName||t||"Store",N5=(e="")=>Tl(String(e).split(",")),j5=(e="")=>zb(String(e).split(",")),Gu=(e=[],t="")=>{const r=Tr(t);return r&&(Array.isArray(e)?e:[]).find(a=>Tr(a.domain||a.url)===r)||null},qw="Cloud stores could not sync. Local stores are still available.",R5="Some cloud stores could not sync. Local stores are still available.",L5="Could not sync store removal. Local stores are still available.",Ou=(e={})=>{const t=Date.parse(e.updatedAt||e.updated_at||e.createdAt||e.created_at||"");return Number.isFinite(t)?t:0},km=(e=[])=>{const t=new Map;
32return(Array.isArray(e)?e:[]).forEach(r=>{const a=Cj(r);if(!a)return;const s=t.get(a.domain);(!s||Ou(a)>=Ou(s))&&t.set(a.domain,a)}),[...t.values()].sort(mg)},B_=(e=[])=>JSON.stringify(km(e).map(t=>({categories:Tl(t.categories),createdAt:t.createdAt||"",displayName:t.displayName||"",domain:t.domain||"",favourite:!!t.favourite,manuallyAdded:!!t.manuallyAdded,notes:t.notes||"",updatedAt:t.updatedAt||"",url:t.url||""}))),rS=(e=[],t=[])=>B_(e)===B_(t),nS=(e=[],t=[])=>{const r=km(e),a=km(t),s=new Map(r.map(c=>[c.domain,c])),o=new Map(a.map(c=>[c.domain,c]));a.forEach(c=>{const l=s.get(c.domain);(!l||Ou(c)>=Ou(l))&&s.set(c.domain,{...c,manualTags:zb(c.manualTags?.length?c.manualTags:l?.manualTags)})});const i=r.filter(c=>{const l=o.get(c.domain);return!l||Ou(c)>Ou(l)});return{mergedStores:km([...s.values()]),storesToUpload:km(i)}},B5=(e={})=>e.status==="syncing"?"Syncing...":e.status==="synced"?"Synced":e.status==="error"?e.message||qw:"",T5=(e={})=>e.manuallyAdded?Number(e.savedItemCount)>0?"Edited locally.":"Added manually.":"";function T_({allStores:e=[],manualStores:t=[],mode:r="add",onCancel:a,onDelete:s=null,onSubmit:o,store:i=null}){const c=r==="edit"&&!!i,l=Tr(i?.domain||i?.url),u=Gu(t,l),p=u||i||{},[m,f]=d.useState(()=>({website:c?_x(p):"",displayName:p.displayName||"",categories:Array.isArray(p.categories)?p.categories.join(", "):"",manualTags:Array.isArray(p.manualTags)?p.manualTags.join(", "):"",notes:p.notes||"",favourite:!!p.favourite})),[h,b]=d.useState(""),v=k=>{const{checked:E,name:y,type:N,value:_}=k.target;f(P=>({...P,[y]:N==="checkbox"?E:_})),b("")},S=k=>{k.preventDefault();const E=Tr(c?l:m.website);if(!E){b("Enter a valid store website or domain.");return}const y=Gu(t,E),N=e.find(z=>Tr(z.domain||z.url)===E)||null,_=N5(m.categories),P=j5(m.manualTags),V=!!(m.displayName.trim()||_.length||P.length||m.notes.trim()||m.favourite);if(!c&&N&&!V){o(y||N,{duplicateDomain:!0,domain:E,skipSave:!0});return}const L=af({...y||{},domain:E,url:`https://${E}`,displayName:m.displayName,categories:_,manualTags:P,notes:m.notes,favourite:m.favourite,manuallyAdded:!0},y);if(!L){b("Enter a valid store website or domain.");return}o(L,{duplicateDomain:!!(!c&&N),domain:E})},C=c?"Edit store":"Add store",I=c?"Save changes":"Save store",A=!!(c&&u&&s);return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"store-modal-title","aria-modal":"true",className:"listModal storeModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"store-modal-title",children:C})}),n.jsxs("form",{autoComplete:"off",className:"listModalForm storeModalForm",onSubmit:S,children:[n.jsxs("label",{children:[n.jsx("span",{children:"Website URL"}),n.jsx("input",{autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",autoFocus:!c,disabled:c,name:"website",onChange:v,placeholder:"https://example.com",required:!c,value:m.website}),c?n.jsx("small",{children:"Store domains stay fixed in this local MVP."}):null,h?n.jsx("em",{children:h}):null]}),n.jsxs("label",{children:[n.jsx("span",{children:"Store name"}),n.jsx("input",{autoComplete:"off",autoCorrect:"off",autoFocus:c,name:"displayName",onChange:v,placeholder:"Derived from domain if blank",value:m.displayName})]}),n.jsxs("label",{children:[n.jsx("span",{children:"Categories"}),n.jsx("input",{autoComplete:"off",name:"categories",onChange:v,placeholder:"Homeware, Gifts",value:m.categories}),n.jsx("small",{children:"Separate categories with commas."})]}),n.jsxs("label",{children:[n.jsx("span",{children:"Search tags"}),n.jsx("input",{autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",name:"manualTags",onChange:v,placeholder:"home, interiors, lamps",spellCheck:!1,value:m.manualTags}),n.jsx("small",{children:"Hidden keywords that help you find this store later, e.g. home, skincare, gifts."})]}),n.jsxs("label",{children:[n.jsx("span",{children:"Notes"}),n.jsx("textarea",{autoComplete:"off",name:"notes",onChange:v,rows:"4",value:m.notes})]}),n.jsxs("label",{className:"storeModalCheckbox",children:[n.jsx("input",{checked:m.favourite,name:"favourite",onCh
32ange:v,type:"checkbox"}),n.jsx("span",{children:"Favourite store"})]}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{type:"submit",children:I}),n.jsx("button",{type:"button",onClick:a,children:"Cancel"}),A?n.jsx("button",{className:"storeModalDeleteButton",onClick:()=>s(p),type:"button",children:"Remove manual details"}):null]})]})]})})}function IL({activeCategory:e=Fo,categories:t=[],label:r="Store categories",maxVisible:a=1/0,onCategorySelect:s=null}){const o=Tl(t);if(!o.length)return null;const i=o.slice(0,a),c=o.length-i.length;return n.jsxs("ul",{className:"storeCategoryList","aria-label":r,children:[i.map(l=>n.jsx("li",{children:s?n.jsx("button",{"aria-pressed":nv(l)===e,className:"storeCategoryButton",onClick:u=>{u.stopPropagation(),s(l)},type:"button",children:l}):l},l)),c>0?n.jsxs("li",{"aria-label":`${c} more categories`,children:["+",c]}):null]})}function AL({domain:e,label:t}){const r=v5(e),a=y5(t,e),[s,o]=d.useState(!1);return d.useEffect(()=>{o(!1)},[r]),n.jsx("span",{className:`storePodIcon${!r||s?" hasFallback":""}`,"aria-hidden":"true",children:r&&!s?n.jsx("img",{alt:"",decoding:"async",loading:"lazy",onError:()=>o(!0),src:r}):n.jsx("span",{children:a})})}function D5(){return n.jsxs("svg",{className:"storePodEditIcon","aria-hidden":"true",focusable:"false",viewBox:"0 0 16 16",children:[n.jsx("path",{d:"M3 11.6V13h1.4l7.4-7.4-1.4-1.4L3 11.6Z"}),n.jsx("path",{d:"m9.7 4.9 1.4 1.4"}),n.jsx("path",{d:"m10.4 4.2.8-.8a1 1 0 0 1 1.4 0 1 1 0 0 1 0 1.4l-.8.8"})]})}function O5(){return n.jsx("svg",{className:"storePodFavouriteIcon","aria-hidden":"true",focusable:"false",viewBox:"0 0 16 16",children:n.jsx("path",{d:"M8 13.25s-5.25-2.9-5.25-6.8A2.9 2.9 0 0 1 8 4.73a2.9 2.9 0 0 1 5.25 1.72C13.25 10.35 8 13.25 8 13.25Z"})})}function M5({activeCategory:e,onCategorySelect:t,onEditStore:r,onOpenStore:a,onToggleFavourite:s,store:o}){const i=kf(o),c=vs(o.lastSavedAt),l=Math.max(0,Math.trunc(Number(o.savedItemCount)||0)),u=o.displayName||o.domain||"Store",p=o.domain||"No domain",m=_x(o),f=!!o.favourite,h=f?"Remove store from favourites":"Add store to favourites",b=()=>a?.(o),v=C=>{C.stopPropagation()},S=!!a;return n.jsxs("article",{"aria-label":`Open ${u} store details`,className:`storePod${S?" isClickable":""}`,onClick:S?b:void 0,onKeyDown:S?C=>{(C.key==="Enter"||C.key===" ")&&(C.preventDefault(),b())}:void 0,role:S?"link":void 0,tabIndex:S?0:void 0,children:[n.jsxs("div",{className:"storePodMain",children:[n.jsx(AL,{domain:o.domain||o.url,label:u}),n.jsxs("div",{className:"storePodIdentity",children:[n.jsx("div",{className:"storePodTitleLine",children:n.jsx("h2",{title:u,children:u})}),n.jsx("p",{title:p,children:p})]})]}),i.length?n.jsx("div",{className:"storePodCategories",children:n.jsx(IL,{activeCategory:e,categories:i,label:`${u} categories`,maxVisible:3,onCategorySelect:t})}):null,n.jsxs("dl",{className:"storePodMeta",children:[n.jsxs("div",{children:[n.jsx("dt",{children:"Saved"}),n.jsx("dd",{children:l})]}),c?n.jsxs("div",{children:[n.jsx("dt",{children:"Last saved"}),n.jsx("dd",{children:c})]}):null]}),n.jsxs("div",{className:"storePodActions",children:[n.jsx("button",{"aria-label":h,"aria-pressed":f,className:`storePodAction storePodActionIcon storePodFavouriteAction${f?" isActive":""}`,onClick:C=>{v(C),s?.(o)},onDoubleClick:v,onPointerDown:v,title:`${h}: ${u}`,type:"button",children:n.jsx(O5,{})}),n.jsx("button",{"aria-label":`Edit store: ${u}`,className:"storePodAction storePodActionIcon",onClick:C=>{v(C),r?.(o)},onDoubleClick:v,onPointerDown:v,title:`Edit ${u}`,type:"button",children:n.jsx(D5,{})}),n.jsx("a",{"aria-label":`Open store: ${u}`,className:"storePodAction storePodActionOpen",href:m,onClick:v,onDoubleClick:v,onPointerDown:v,rel:"noopener noreferrer",target:"_blank",title:`Open ${u} website`,children:"OPEN"})]})]})}function U5({domain:e,gridPreference:t,onBackToStores:r,onDeleteProduct:a,onEditStore:s,onEditProduct:o,onOpenProduct:i,onUpdateProductStatus:c,products:l=[],store:u}){const p=Tr(e),m=k5(u,p),f=u?_x(u):p?`https://${p}`:"",h=d.useMemo(()=>dg(E5(l,p),"newest"),[p,l]),b=vs(u?.lastSavedAt),v=vs(u?.firstSavedAt),S=kf(u),C=String(u?.notes||"").trim(),I=!!(u&&p),A=I?T5(u):"";return I?n.jsxs("main",{className:"storesPage storeDetailPage",children:[n.jsxs("header",{className:"storesHeader storeDetailHeader",children:[n.jsx("button",{onClick:r,type:"button",children:"Back to Stores"}),n.jsx("p",{title:p,children:p}),n.jsx("h1",{title:m,children:m}),A?n.jsx("span",{title:A,children:A}):null,n.jsxs("div",{className:"storeDetailHeaderActions",children:[n.jsx("button",{className:"storeDetailWebsiteLink",onClick:()=>s?.(u),type:"button",children:"Edit details"}),n.jsx("a",{"aria-label":`Open ${m} website`,className:"storeDetailWebsiteLink",href:f,rel:"noopener noreferrer",target:"_blank",children:"Open store"})]})]}),n.jsxs("section",{className:"storeDetailSummary","aria-label":`${m} store summary`,children:[n.jsxs("div",{children:[n.jsx("span",{children:"Saved items"}),n.jsx("strong",{children:u.savedItemCount})]}),b?n.jsxs("div",{children:[n.jsx("span",{children:"Last saved"}),n.jsx("strong",{children:b})]}):null,v?n.jsxs("div",{children:[n.jsx("span",{children:"First saved"}),n.jsx("strong",{children:v})]}):null,n.jsxs("div",{children:[n.jsx("span",{children:"Domain"}),n.jsx("strong",{title:p,children:p})]}),u.favourite?n.jsxs("div",{children:[n.jsx("span",{children:"Favourite"}),n.jsx("strong",{children:"Yes"})]}):null]}),n.jsx(IL,{categories:S,label:`${m} categories`}),C?n.jsxs("section",{className:"storeDetailNotes","aria-label":`${m} private notes`,children:[n.jsx("span",{children:"Private notes"}),n.jsx("p",{children:C})]}):null,n.jsxs("section",{className:"storeDetailItems","aria-label":`Saved items from ${m}`,children:[n.jsxs("div",{className:"storeDetailItemsHeader",children:[n.jsx("p",{children:"Saved items"}),n.jsx("span",{children:xL(h.length)})]}),h.length?n.jsx("div",{className:"storeDetailProductGrid",children:n.jsx($L,{products:h,onEmptyClick:A
32i,onExpandProduct:i,onEditProduct:o,onDeleteProduct:a,onUpdateProductStatus:c,onReorderProducts:Ai,onMoveProductToList:Ai,onDragProductChange:Ai,onDragListTargetChange:Ai,gridPreference:t,boardMode:"vertical",fillEmptySlots:!1,allowReorder:!1,allowMove:!1,renderResetKey:`store:${p}`})}):n.jsxs("div",{className:"storesEmptyState storeDetailEmptyState",children:[n.jsx("p",{children:"No saved items from this store yet."}),n.jsx("span",{children:"Items will appear here when their saved website matches this store domain."})]})]})]}):n.jsxs("main",{className:"storesPage storeDetailPage",children:[n.jsxs("header",{className:"storesHeader storeDetailHeader",children:[n.jsx("button",{onClick:r,type:"button",children:"Back to Stores"}),n.jsx("p",{children:"Store"}),n.jsx("h1",{children:"Store not found"}),n.jsx("span",{children:"This store is not in your saved items."})]}),n.jsxs("section",{className:"storesEmptyState storeDetailEmptyState","aria-live":"polite",children:[n.jsx("p",{children:"Store not found"}),n.jsx("span",{children:"Stores are created from the websites your saved items came from."}),n.jsx("button",{onClick:r,type:"button",children:"Back to Stores"})]})]})}function F5({ariaLabel:e,className:t="",label:r,menuId:a,onChange:s,options:o=[],value:i}){const[c,l]=d.useState(!1),[u,p]=d.useState(0),m=d.useRef(null),f=d.useRef(null),h=Math.max(0,o.findIndex(I=>I.value===i)),b=o[h]||o[0]||{label:""};d.useEffect(()=>{if(!c)return;p(h);const I=A=>{m.current?.contains(A.target)||l(!1)};return window.addEventListener("pointerdown",I),()=>window.removeEventListener("pointerdown",I)},[c,h]);const v=(I=!1)=>{l(!1),I&&window.requestAnimationFrame(()=>f.current?.focus())},S=I=>{const A=o[I];A&&(s(A.value),v(!0))},C=I=>{if(!c&&["ArrowDown","ArrowUp","Enter"," "].includes(I.key)){I.preventDefault(),p(h),l(!0);return}if(c){if(I.key==="Escape"){I.preventDefault(),v(!0);return}if(I.key==="ArrowDown"||I.key==="ArrowUp"){I.preventDefault();const A=I.key==="ArrowDown"?1:-1;p(k=>(k+A+o.length)%o.length);return}if(I.key==="Home"||I.key==="End"){I.preventDefault(),p(I.key==="Home"?0:o.length-1);return}(I.key==="Enter"||I.key===" ")&&(I.preventDefault(),S(u))}};return n.jsxs("div",{className:`customSelectMenu${t?` ${t}`:""}${c?" isOpen":""}`,onBlur:I=>{I.currentTarget.contains(I.relatedTarget)||l(!1)},onKeyDown:C,ref:m,children:[n.jsxs("button",{"aria-controls":c?a:void 0,"aria-expanded":c,"aria-haspopup":"listbox","aria-label":`${e}, current option ${b.label}`,className:"customSelectMenuTrigger",onClick:()=>l(I=>!I),ref:f,type:"button",children:[n.jsx("span",{className:"customSelectMenuLabel",children:r}),n.jsx("span",{className:"customSelectMenuValue",children:b.label}),n.jsx("span",{className:"customSelectMenuChevron","aria-hidden":"true"})]}),c?n.jsx("div",{"aria-label":e,className:"customSelectMenuPanel",id:a,role:"listbox",children:o.map((I,A)=>{const k=I.value===i;return n.jsxs("button",{"aria-selected":k,className:`customSelectMenuOption${k?" isSelected":""}${A===u?" isHighlighted":""}`,onClick:()=>S(A),onFocus:()=>p(A),onMouseEnter:()=>p(A),role:"option",type:"button",children:[n.jsx("span",{children:I.label}),n.jsx("span",{className:"customSelectMenuCheck","aria-hidden":"true",children:n.jsx("svg",{viewBox:"0 0 16 16",children:n.jsx("path",{d:"m3.4 8.3 2.8 2.8 6.4-6.3"})})})]},I.value)})}):null]})}function $5({cloudSyncState:e=null,detailDomain:t=null,detailIsOpen:r=!1,gridPreference:a,manualStores:s=[],onBackToDashboard:o,onBackToStores:i,onDeleteProduct:c,onDeleteManualStore:l,onEditProduct:u,onSaveManualStore:p,onOpenProduct:m,onOpenStore:f,onUpdateProductStatus:h,products:b=[]}){const[v,S]=d.useState(""),[C,I]=d.useState("recent"),[A,k]=d.useState(Fo),[E,y]=d.useState(null),N=d.useMemo(()=>Sj(b),[b]),_=d.useMemo(()=>xj(s,N),[N,s]),P=d.useMemo(()=>P5(_),[_]),V=d.useMemo(()=>new Set(P.map(ge=>ge.key)),[P]),L=d.useMemo(()=>_.find(ge=>ge.domain===t)||null,[t,_]),z=v.trim().toLowerCase(),B=A!==Fo,re=z.length>0,Z=d.useMemo(()=>{const ge=_.filter(ze=>_5(ze,A));return z?A5(ge,z,C,b):Ex(ge,C)},[A,b,C,_,z]),D=_.length>0,K=re&&B?"No stores match your search and filters.":re?"No stores match your search.":"No stores in this category.",ee=re&&B?"Clear the search or choose All categories.":re?"Try another search.":"Choose All or another category.",J=B5(e||{}),fe=e?.status==="error";d.useEffect(()=>{A!==Fo&&!V.has(A)&&k(Fo)},[A,V]);const De=(ge,ze=null)=>{y({mode:ge,store:ze})},Be=()=>{y(null)},Fe=(ge,ze={})=>{const W=ze.skipSave?ge:p?.(ge)||ge;Be(),f?.(W)},ke=ge=>{const ze=l?.(ge),W=E?.store||ge||{};return Be(),r&&Number(W.savedItemCount||0)<=0&&i?.(),ze},We=ge=>{const ze=nv(ge);k(ze||Fo)},de=(ge={})=>{const ze=Tr(ge.domain||ge.url);if(!ze)return;const W=Gu(s,ze),Le=W||ge;p?.({...W||{},domain:ze,url:Le.url||ge.url||`https://${ze}`,displayName:Le.displayName||ge.displayName||"",categories:Array.isArray(Le.categories)?Le.categories:ge.categories||[],manualTags:Object.hasOwn(Le,"manualTags")?Le.manualTags:ge.manualTags||[],notes:Object.hasOwn(Le,"notes")?Le.notes:ge.notes||"",favourite:!ge.favourite,manuallyAdded:!0})},ye=!!E;return r?n.jsxs(n.Fragment,{children:[n.jsx(U5,{domain:t,gridPreference:a,onBackToStores:i,onDeleteProduct:c,onEditProduct:u,onEditStore:ge=>De("edit",ge),onOpenProduct:m,onUpdateProductStatus:h,products:b,store:L}),ye?n.jsx(T_,{allStores:_,manualStores:s,mode:E.mode,onCancel:Be,onDelete:ke,onSubmit:Fe,store:E.store}):null]}):n.jsxs(n.Fragment,{children:[n.jsxs("main",{className:"storesPage",children:[n.jsxs("header",{className:"storesHeader primaryPageHeader contentAlignedPageHeader",children:[n.jsx("h1",{children:"My Stores"}),fe&&J?n.jsx("div",{className:"storesHeaderActions",children:n.jsx("span",{className:"storesSyncStatus isWarning",role:"status",children:J})}):null]}
32),n.jsxs("section",{className:"storesControls","aria-label":"Store controls",children:[n.jsxs("label",{className:"storesSearch",children:[n.jsx("span",{className:"toolbarSrOnly",children:"Search my stores"}),n.jsx("input",{autoComplete:"off",onChange:ge=>S(ge.target.value),placeholder:"Search my stores",type:"search",value:v})]}),n.jsx(F5,{ariaLabel:"Sort stores",className:"storesSort",label:"Sort",menuId:"stores-sort-menu",onChange:ge=>I(b5(ge)),options:Object.entries(CL).map(([ge,ze])=>({label:ze,value:ge})),value:C}),n.jsx("button",{"aria-label":"Add store",className:"toolbarAddButton storesAddButton",onClick:()=>De("add"),title:"Add store",type:"button",children:n.jsx("span",{"aria-hidden":"true"})})]}),P.length?n.jsxs("section",{className:"storesCategoryFilters","aria-label":"Filter stores by category",children:[n.jsxs("button",{"aria-pressed":A===Fo,className:A===Fo?"isActive":"",onClick:()=>k(Fo),type:"button",children:["All",n.jsx("span",{children:_.length})]}),P.map(ge=>n.jsxs("button",{"aria-pressed":A===ge.key,className:A===ge.key?"isActive":"",onClick:()=>k(ge.key),type:"button",children:[ge.label,n.jsx("span",{children:ge.count})]},ge.key))]}):null,D?Z.length?n.jsx("section",{className:"storesList","aria-label":"My Stores",children:Z.map(ge=>n.jsx(M5,{activeCategory:A,onCategorySelect:We,onEditStore:ze=>De("edit",ze),onOpenStore:f,onToggleFavourite:de,store:ge},ge.id||ge.domain))}):n.jsxs("section",{className:"storesEmptyState","aria-live":"polite",children:[n.jsx("p",{children:K}),n.jsx("span",{children:ee})]}):n.jsxs("section",{className:"storesEmptyState","aria-live":"polite",children:[n.jsx("p",{children:"No stores yet"}),n.jsx("span",{children:"Stores will appear here automatically as you save items from websites, or you can add one manually."})]})]}),ye?n.jsx(T_,{allStores:_,manualStores:s,mode:E.mode,onCancel:Be,onDelete:ke,onSubmit:Fe,store:E.store}):null]})}const kx=(e={},t=[])=>t.find(a=>hs(e,a))?.name||Ye(e.listName||e.category||"")||"All Items",Nf=(e={})=>{const t=aa(String(e.url||""));return Ye(e.source||"")||Ye(e.brand||"")||Nc(t)||"Saved item"},z5=new Set(["saved item","manual entry","unlisted"]),PL=(e={})=>{const t=Nf(e);return z5.has(t.trim().toLowerCase())?"":t},Nx=(e={})=>{const t=Af(e);if(t)return t;try{return e.url?Tr(e.url):""}catch{return""}},V5=(e={},t=[])=>[ff(e),kx(e,t),Nf(e),Nx(e)].filter(Boolean).join(" ").toLowerCase(),fg=(e={})=>{const t=Date.parse(e.updatedAt||e.createdAt||"");return Number.isFinite(t)?t:0},hb=8,H5=260,W5=180,D_=e=>`${e} result${e===1?"":"s"}`,O_=(e="",t="")=>t?String(e||"").toLowerCase().includes(t):!0,G5=(e="")=>String(e||"").trim().replace(/\s+/g," ").toLowerCase(),_L=(e={},t="")=>{const r=G5(e.value);if(!r||!t)return Number.POSITIVE_INFINITY;const a=Number.isFinite(e.exactRank)?e.exactRank:0,s=Number.isFinite(e.startsRank)?e.startsRank:12,o=Number.isFinite(e.containsRank)?e.containsRank:36;return r===t?a:r.startsWith(t)?s:r.includes(t)?o:Number.POSITIVE_INFINITY},jf=(e=[],t="")=>e.reduce((r,a)=>Math.min(r,_L(a,t)),Number.POSITIVE_INFINITY),q5=()=>{if(typeof window>"u")return"";try{return String(new URLSearchParams(window.location.search).get("q")||"").trim()}catch{return""}},Y5=(e="")=>{if(!(typeof window>"u"||window.location.pathname!==ig))try{const t=new URL(window.location.href),r=String(e||"").trim();r?t.searchParams.set("q",r):t.searchParams.delete("q"),window.history.replaceState({},"",`${t.pathname}${t.search}${t.hash}`)}catch{}},K5=(e={},t=[])=>[XR(e),...t.filter(r=>hs(r,e)).map(r=>ff(r))].filter(Boolean).join(" ").toLowerCase(),X5=(e={},t=[],r="")=>jf([{value:e.title,exactRank:0,startsRank:10,containsRank:24},{value:Nx(e),exactRank:3,startsRank:12,containsRank:28},{value:e.url,exactRank:5,startsRank:16,containsRank:34},{value:Nf(e),exactRank:7,startsRank:18,containsRank:34},{value:e.brand,exactRank:8,startsRank:20,containsRank:36},{value:kx(e,t),exactRank:14,startsRank:24,containsRank:42},{value:e.description,exactRank:48,startsRank:56,containsRank:70},{value:e.notes,exactRank:50,startsRank:58,containsRank:72},{value:e.privateNotes,exactRank:50,startsRank:58,containsRank:72},{value:e.publicNotes,exactRank:50,startsRank:58,containsRank:72}],r),J5=(e={},t="")=>{const{list:r={},products:a=[]}=e,s=a.reduce((o,i)=>Math.min(o,_L({value:i.title,exactRank:54,startsRank:60,containsRank:74},t)),Number.POSITIVE_INFINITY);return Math.min(jf([{value:r.name,exactRank:0,startsRank:10,containsRank:26},{value:r.description,exactRank:44,startsRank:54,containsRank:68},{value:r.publicDescription,exactRank:44,startsRank:54,containsRank:68}],t),s)},Q5=(e={},t="")=>jf([{value:e.domain,exactRank:0,startsRank:10,containsRank:28},{value:e.displayName,exactRank:2,startsRank:12,containsRank:30},{value:e.url,exactRank:6,startsRank:18,containsRank:36},...Array.isArray(e.categories)?e.categories.map(r=>({value:r,exactRank:36,startsRank:46,containsRank:60})):[],{value:e.notes,exactRank:52,startsRank:60,containsRank:74}],t),M_=(e={},t="")=>jf([{value:e.username,exactRank:0,startsRank:10,containsRank:28},{value:e.displayName,exactRank:4,startsRank:14,containsRank:32}],t),U_=(e={},t="")=>jf([{value:e.title,exactRank:0,startsRank:10,containsRank:26},{value:e.ownerUsername,exactRank:8,startsRank:18,containsRank:34},{value:e.ownerDisplayName,exactRank:12,startsRank:22,containsRank:38},{value:e.description,exactRank:48,startsRank:56,containsRank:70}],t),Z5=(e={},t=[])=>{const r=t.filter(o=>hs(o,e)),a=r.reduce((o,i)=>Math.max(o,fg(i)),0),s=Date.parse(e.updatedAt||e.createdAt||"");return{count:r.length,latestTime:Math.max(Number.isFinite(s)?s:0,a),list:e,products:r,searchText:K5(e,t)}},e4=(e={})=>[e.displayName,e.domain,e.url,e.notes,...Array.isArray(e.categories)?e.categories:[]].filter(
32Boolean).join(" ").toLowerCase(),aS=({fallbackResults:e=[],normalizedQuery:t="",rankSelector:r,recencySelector:a=()=>0,searchTextSelector:s,source:o=[]})=>{if(!t)return{results:e.slice(0,hb),totalCount:e.length};const i=o.map(c=>{const l=r?r(c,t):O_(s(c),t)?100:Number.POSITIVE_INFINITY;return{entry:c,rank:l}}).filter(({entry:c,rank:l})=>Number.isFinite(l)||O_(s(c),t)).sort((c,l)=>{const u=c.rank-l.rank;return u||Number(a(l.entry)||0)-Number(a(c.entry)||0)}).map(({entry:c})=>c);return{results:i.slice(0,hb),totalCount:i.length}};function t4({isSelected:e=!1,lists:t=[],onOpenProduct:r,onSelect:a,product:s,searchResultId:o=""}){const i=t.find(y=>hs(s,y)),c=String(i?.id||"").trim(),l=String(s?.id||"").trim(),u=c&&l?cg(c,l):"",p=kx(s,t),m=Nf(s),f=Nx(s),h=va(s.status),b=vs(s.updatedAt||s.createdAt),v=kn(s)||jn,S=zi(s,v),C=qo(v)?void 0:kd(s),I=s.title||"Untitled item",A=n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"priceOverviewItemImage",style:C,children:n.jsx(Ms,{alt:"",alternateSources:S,decoding:"async",fallbackSource:jn,loading:"lazy",source:v})}),n.jsxs("div",{className:"priceOverviewItemMain",children:[n.jsxs("div",{className:"priceOverviewItemTitle",children:[n.jsx("span",{children:"Item"}),n.jsx("h2",{children:I})]}),n.jsxs("div",{className:"priceOverviewItemMeta",children:[n.jsxs("div",{children:[n.jsx("span",{children:"Board"}),n.jsx("strong",{children:p})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Source"}),n.jsx("strong",{children:m}),f&&f!==m?n.jsx("em",{children:f}):null]}),n.jsxs("div",{children:[n.jsx("span",{children:"Price"}),n.jsx("strong",{children:s.price||"No price saved"})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Status"}),n.jsx("strong",{children:h})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Saved"}),n.jsx("strong",{children:b||"Recently"})]})]})]})]}),k=`priceOverviewItem searchResultItem isItemResult${u?" searchResultItemLink":" isUnavailable"}${e?" isSelected":""}`,E=o?`${o}-row`:void 0;return u?n.jsx("a",{"aria-label":`Open ${I} details`,"aria-selected":e?"true":void 0,className:k,href:u,id:E,onClick:y=>{y.button!==0||y.metaKey||y.ctrlKey||y.shiftKey||y.altKey||(y.preventDefault(),r(s))},onFocus:a,onMouseEnter:a,children:A}):n.jsx("article",{"aria-selected":e?"true":void 0,className:k,id:E,onFocus:a,onMouseEnter:a,children:A})}function r4({isSelected:e=!1,onOpenList:t,onSelect:r,searchResultId:a="",summary:s}){const{count:o=0,list:i={},products:c=[]}=s||{},l=vs(i.updatedAt||i.createdAt),u=i.name||"Untitled board",p=()=>t(i.name);return n.jsxs("article",{"aria-label":`Open board ${u}`,"aria-selected":e?"true":void 0,className:`priceOverviewItem searchResultItem searchResultItemLink${e?" isSelected":""}`,id:a?`${a}-row`:void 0,onClick:p,onFocus:r,onKeyDown:m=>{m.key!=="Enter"&&m.key!==" "||(m.preventDefault(),p())},onMouseEnter:r,role:"button",tabIndex:0,children:[n.jsx("div",{className:"priceOverviewItemImage searchResultBoardImage","aria-hidden":"true",children:n.jsx(Bd,{coverItemIds:i.coverItemIds,list:i,products:c})}),n.jsxs("div",{className:"priceOverviewItemMain",children:[n.jsxs("div",{className:"priceOverviewItemTitle",children:[n.jsx("span",{children:"Board"}),n.jsx("h2",{className:"boardCardTitle",children:u})]}),n.jsxs("div",{className:"priceOverviewItemMeta",children:[n.jsxs("div",{children:[n.jsx("span",{children:"Items"}),n.jsxs("strong",{children:[o," saved item",o===1?"":"s"]})]}),l?n.jsxs("div",{children:[n.jsx("span",{children:"Updated"}),n.jsx("strong",{children:l})]}):null,i.description||i.publicDescription?n.jsxs("div",{children:[n.jsx("span",{children:"Description"}),n.jsx("strong",{children:i.description||i.publicDescription})]}):null]})]})]})}function n4({isSelected:e=!1,onOpenStore:t,onSelect:r,searchResultId:a="",store:s}){const o=s.displayName||s.domain||"Untitled store",i=xL(s.savedItemCount),c=kf(s).join(", "),l=()=>t(s);return n.jsxs("article",{"aria-label":`Open store ${o}`,"aria-selected":e?"true":void 0,className:`priceOverviewItem searchResultItem searchResultItemLink${e?" isSelected":""}`,id:a?`${a}-row`:void 0,onClick:l,onFocus:r,onKeyDown:u=>{u.key!=="Enter"&&u.key!==" "||(u.preventDefault(),l())},onMouseEnter:r,role:"button",tabIndex:0,children:[n.jsx("div",{className:"priceOverviewItemImage searchResultStoreImage","aria-hidden":"true",children:n.jsx(AL,{domain:s.domain||s.url,label:o})}),n.jsxs("div",{className:"priceOverviewItemMain",children:[n.jsxs("div",{className:"priceOverviewItemTitle",children:[n.jsx("span",{children:"Store"}),n.jsx("h2",{children:o})]}),n.jsxs("div",{className:"priceOverviewItemMeta",children:[n.jsxs("div",{children:[n.jsx("span",{children:"Domain"}),n.jsx("strong",{children:s.domain||"No domain"})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Saved"}),n.jsx("strong",{children:i})]}),c?n.jsxs("div",{children:[n.jsx("span",{children:"Categories"}),n.jsx("strong",{children:c})]}):null]})]})]})}function a4({isSelected:e=!1,onOpenProfile:t,onSelect:r,person:a,searchResultId:s=""}){const o=a.displayName||`@${a.username}`,i=vs(a.createdAt);return n.jsxs("article",{"aria-selected":e?"true":void 0,className:`priceOverviewItem searchResultItem${e?" isSelected":""}`,id:s?`${s}-row`:void 0,onFocus:r,onMouseEnter:r,children:[n.jsx("div",{className:"priceOverviewItemImage","aria-hidden":"true",children:n.jsx("img",{alt:"",decoding:"async",loading:"lazy",onError:BR,src:a.avatarUrl||jn})}),n.jsxs("div",{className:"priceOverviewItemMain",children:[n.jsxs("div",{className:"priceOverviewItemTitle",children:[n.jsx("span",{children:"Person"}),n.jsx("h2",{children:o})]}),n.jsxs("div",{className:"priceOverviewItemMeta",children:[n.jsxs("div",{children:[n.jsx("span",{children:"Username"}),n.jsxs("strong",{children:["@",a.username]})]}),i?n.jsxs("div",{children:[n.jsx("span",{children:"Joined"}),n.jsx("strong",{children:i})]}):null]})]}),n.jsx("div",{className:"priceOverviewItemActions",children:n.jsx("button",{onClick:()=>t(a),type:"button",children:"Open profile"})})]})}function s4({board:e,isSelected:t=!1,onOpenPublicBoard:r,onSelect:a,searchResultId:s=""}){const o=e.ownerDisplayName||`@${e.ownerUsername}`,i=vs(e.publishedAt||e.updatedAt);return n.jsxs("article",{"aria-selected":t?"true":void 0,className:`priceOverviewItem searchResultItem${t?" isSelected":""}`,id:s?`${s}-row`:void 0,onFocus:a,onMouseEnter:a,children:[n.jsx("div",{className:"priceOverviewItemImage","aria-hidden":"true",children:n.jsx("img",{alt:"",decoding:"async",loading:"lazy",onError:BR,src:jn})}),n.jsxs("div",{className:"priceOverviewItemMain",children:[n.jsxs("div",{className:"priceOverviewItemTitle",children:[n.jsx("span",{children:"Public board"}),n.jsx("h2",{className:"boardCardTitle",children:e.title||"Untitled board"})]}),n.jsxs("div",{className:"priceOverviewItemMeta",children:[n.jsxs("div",{children:[n.jsx("span",{children:"Owner"}),n.jsxs("strong",{children:[o," · @",e.ownerUsername]})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Items"}),n.jsxs("strong",{children:[e.itemCount," public item",e.itemCount===1?"":"s"]})]}),i?n.jsxs("div",{children:[n.jsx("span",{children:"Published"}),n.jsx("strong",{children:i})]}):null,e.description?n.jsxs("div",{children:[n.jsx("span",{children:"Description"}),n.jsx("strong",{children:e.description})]}):null]})]}),n.jsx("div",{className:"priceOverviewItemActions",children:n.jsx("button",{onClick:()=>r(e),type:"button",children:"Open public board"})})]})}function gm({children:e,count:t,title:r}){if(!t)return null;const a=`search-${r.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}-heading`,s=t>hb?`${D_(t)} · showing top ${hb}`:D_(t);return n.jsxs("section",{"aria-labelledby":a,children:[n.jsxs("div",{className:"priceOverviewLimit",children:[n.jsx("p",{id:a,children:r}),n.jsx("span",{children:s})]}),n.jsx("div",{className:"priceOverviewList",children:e})]})}const o4=(e={})=>`@${Oi(e.ownerUsername||e.username||"")}`,i4=e=>{const t=e.currentTarget;if(!t||Math.abs(e.deltaX)>=Math.abs(e.deltaY))return;const r=t.scrollWidth-t.clientWidth;if(r<=0)return;const a=t.scrollLeft<=0,s=t.scrollLeft>=r-1;e.deltaY<0&&a||e.deltaY>0&&s||(e.preventDefault(),t.scrollLeft+=e.deltaY)},c4=2,l4=e=>{const t=e.currentTarget,r=e.target;if(!t||!r||r===t||!t.contains(r)||typeof r.getBoundingClientRect!="function")return;const a=Math.max(0,t.scrollWidth-t.clientWidth);if(a<=0)return;const s=t.getBoundingClientRect(),o=r.getBoundingClientRect(),i=window.getComputedStyle(r),c=Number.parseFloat(i.outlineWidth)||0,l=Number.parseFloat(i.outlineOffset)||0,u=i.outlineStyle==="none"?0:Math.max(0,c+l),p=c4+u,m=s.left+p,f=s.r
32ight-p;let h=0;if(o.left<m?h=o.left-m:o.right>f&&(h=o.right-f),h===0)return;const b=Math.min(a,Math.max(0,t.scrollLeft+h));Math.abs(b-t.scrollLeft)<.5||t.scrollTo({behavior:"instant",left:b,top:t.scrollTop})},d4=6,F_="Picked by Saveboard",u4=(e="")=>`discover-${String(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")}-heading`,Yw=e=>e.button===0&&!e.metaKey&&!e.ctrlKey&&!e.shiftKey&&!e.altKey,hg=(e={})=>{const t=(Array.isArray(e.images)?e.images:[]).map((r,a)=>({id:`${e.id}-cover-${a}`,imageUrl:r}));return{href:e.href,id:e.id,isPublic:!0,list:{coverItemIds:t.map(r=>r.id),id:e.id,isPublic:!0,name:e.name},name:e.name,ownerHref:e.ownerHref,ownerUsername:e.username,productCount:e.productCount,products:t}},$_=(e=[])=>e.flatMap(t=>(Array.isArray(t?.images)?t.images:[]).slice(0,zo)).map(t=>Il(t,{width:Os.cover})),EL=(e={})=>{const t=op(),r=gf(240,VB,t),a=(e.featured||[]).slice(0,r),s=(e.collections||[]).flatMap(o=>o.boards.slice(0,r));return{collections:$_(s.slice(0,ZR)),featured:$_(a)}},p4=(e={})=>{const t=EL(e);return[...t.featured,...t.collections]},m4=async e=>{const t=EL(e);await iE(t.featured,{budgetMs:pE}),Jh(t.collections)};function bm({anchor:e="",badge:t="",busy:r=!1,children:a,title:s,variant:o=""}){const i=u4(s);return n.jsxs("section",{"aria-busy":r||void 0,"aria-labelledby":i,className:`discoverSection${o?` ${o}`:""}`,id:e?`discover-anchor-${e}`:void 0,children:[n.jsx("div",{className:"discoverSectionHeader",children:n.jsx("div",{className:"discoverSectionTitle",children:n.jsxs("div",{className:"discoverSectionHeading",children:[n.jsx("h2",{id:i,children:s}),t?n.jsx("span",{className:"v2DiscoverBadge",children:t}):null]})})}),n.jsx("div",{className:"discoverCardRow",onFocusCapture:l4,onWheel:i4,children:a})]})}function f4({count:e=d4}){return Array.from({length:e},(t,r)=>n.jsx("article",{"aria-hidden":"true",className:"discoverBoardTile boardTile isSkeleton",children:n.jsxs("span",{className:"discoverBoardTileSurface discoverSkeletonSurface",children:[n.jsx("span",{className:"boardTileCover discoverSkeletonCover"}),n.jsxs("span",{className:"discoverTileDetails discoverBoardDetails boardTileCaption",children:[n.jsx("span",{className:"boardTileIndex",children:Ko(r)}),n.jsx("span",{className:"boardTileName discoverSkeletonLine"})]})]})},r))}function sS({board:e,index:t=0,onOpenProfile:r,onOpenPublicBoard:a}){const s=oa(e.productCount,"item","items"),o=o4(e),i=l=>{!a||!Yw(l)||(l.preventDefault(),a(e))},c=l=>{!r||!Yw(l)||(l.preventDefault(),r({username:e.ownerUsername}))};return n.jsx("article",{className:"discoverBoardTile boardTile isPublic",children:n.jsxs("div",{className:"discoverBoardTileSurface",children:[n.jsxs("a",{"aria-label":`Open ${e.name} board`,className:"discoverBoardTileLink boardTileSurface",href:e.href,onClick:i,children:[n.jsx("span",{className:"boardTileCover",children:n.jsx(Bd,{coverItemIds:e.list.coverItemIds,list:e.list,products:e.products})}),n.jsxs("div",{className:"discoverTileDetails discoverBoardDetails boardTileCaption",children:[n.jsx("span",{"aria-hidden":"true",className:"boardTileIndex",children:Ko(t)}),n.jsx("strong",{className:"boardCardTitle boardTileName",children:e.name})]})]}),n.jsxs("div",{className:"discoverBoardMeta boardTileMeta",children:[n.jsx("a",{"aria-label":`Open ${o} profile`,className:"discoverBoardOwner boardTileOwner",href:e.ownerHref,onClick:c,children:o}),n.jsx("span",{className:"discoverBoardItemCount boardTileCount",children:s})]})]})})}function h4({onOpenProfile:e,profile:t}){const r=`@${t.username}`,a=`${oa(t.boardCount,"Discover board","Discover boards")} · ${oa(t.itemCount,"item","items")}`,s=o=>{!e||!Yw(o)||(o.preventDefault(),e({username:t.username}))};return n.jsx("article",{className:"discoverUserTile",children:n.jsxs("a",{"aria-label":`Open ${r} profile`,className:"discoverUserTileButton",href:t.href,onClick:s,children:[n.jsx("span",{"aria-hidden":"true",className:`discoverUserAvatar ${xx(t.username)}`,children:n.jsx("span",{children:Rf(t.username,r)})}),n.jsx("span",{className:"discoverUserName",children:r}),n.jsx("span",{className:"discoverUserMetaLine",children:a}),t.images.length?n.jsx("span",{"aria-hidden":"true",className:"discoverUserItemsRow",children:t.images.map((o,i)=>{const c=ip(o,[],{width:320});return n.jsx(Ms,{alt:"",alternateSources:c.alternateSources,decoding:"async",loading:"lazy",source:c.source},`${o}-${i}`)})}):null,n.jsx("span",{"aria-hidden":"true",className:"v2FollowPill",children:"View profile"})]})})}function g4({error:e=!1,onOpenAccount:t,onOpenApp:r,onRetry:a,signedIn:s=!1}){return n.jsxs("section",{"aria-labelledby":"discover-intro-heading","aria-live":"polite",className:"discoverIntro",children:[n.jsx("h2",{id:"discover-intro-heading",children:e?"Public boards couldn’t be loaded.":"The first public boards are on their way."}),n.jsx("p",{children:e?"Saveboard couldn’t read its public boards just now. Try again in a moment.":"Public boards appear here when their owners choose to share them with Discover."}),n.jsxs("div",{className:"discoverIntroActions",children:[e&&a?n.jsx("button",{className:"discoverIntroButton",onClick:a,type:"button",children:"Try again"}):null,n.jsxs("button",{className:"discoverIntroButton isPrimary",onClick:s?r:t,type:"button",children:[s?"Open your boards":"Create your account"," ",n.jsx("span",{"aria-hidden":"true",children:"→"})]})]})]})}function b4({lists:e=[],manualStores:t=[],onBackToDashboard:r,onOpenList:a,onOpenProduct:s,onOpenProfile:o,onOpenPublicBoard:i,onOpenStore:c,products:l=[]}){const u=d.useRef(null),[p,m]=d.useState(q5),[f,h]=d.useState(""),[b,v]=d.useState({error:"",isLoading:!1,people:[],publicBoards:[],query:""}),S=p.trim(),C=S.toLowerCase(),I=S.length>
32=Zk,A=b.query===S?b:{error:"",isLoading:I,people:[],publicBoards:[],query:S},k=d.useMemo(()=>xj(t,Sj(l)),[t,l]),E=d.useMemo(()=>e.map(W=>Z5(W,l)).sort((W,Le)=>Le.latestTime-W.latestTime||W.list.name.localeCompare(Le.list.name)),[e,l]),y=d.useMemo(()=>[...l].sort((W,Le)=>fg(Le)-fg(W)),[l]),N=d.useMemo(()=>E.filter(({count:W})=>W>0||!C),[E,C]),_=d.useMemo(()=>Ex(k,"favourite"),[k]),P=d.useMemo(()=>aS({fallbackResults:y,normalizedQuery:C,rankSelector:(W,Le)=>X5(W,e,Le),recencySelector:fg,searchTextSelector:W=>V5(W,e),source:l}),[e,C,l,y]),V=d.useMemo(()=>aS({fallbackResults:N,normalizedQuery:C,rankSelector:J5,recencySelector:W=>W.latestTime,searchTextSelector:W=>W.searchText,source:E}),[E,C,N]),L=d.useMemo(()=>aS({fallbackResults:_,normalizedQuery:C,rankSelector:Q5,recencySelector:W=>Date.parse(W.lastSavedAt||W.updatedAt||W.createdAt||"")||0,searchTextSelector:e4,source:k}),[_,C,k]),z=d.useMemo(()=>C?[...A.people].sort((W,Le)=>{const et=M_(W,C)-M_(Le,C);return et||W.username.localeCompare(Le.username)}):A.people,[C,A.people]),B=d.useMemo(()=>C?[...A.publicBoards].sort((W,Le)=>{const et=U_(W,C)-U_(Le,C);return et||(Date.parse(Le.publishedAt||Le.updatedAt||"")||0)-(Date.parse(W.publishedAt||W.updatedAt||"")||0)||W.title.localeCompare(Le.title)}):A.publicBoards,[C,A.publicBoards]);d.useEffect(()=>{u.current?.focus()},[]),d.useEffect(()=>{const W=window.setTimeout(()=>Y5(S),W5);return()=>window.clearTimeout(W)}
32,[S]),d.useEffect(()=>{if(!I){v({error:"",isLoading:!1,people:[],publicBoards:[],query:S});return}let W=!0;const Le=new AbortController;let et;const pt=window.setTimeout(()=>{v({error:"",isLoading:!0,people:[],publicBoards:[],query:S}),et=window.setTimeout(()=>Le.abort(),15e3),eU(S,void 0,{signal:Le.signal}).then($t=>{W&&v({error:$t.error||"",isLoading:!1,people:$t.people||[],publicBoards:$t.publicBoards||[],query:S})}).catch(()=>{W&&v({error:"Could not load public search results.",isLoading:!1,people:[],publicBoards:[],query:S})}).finally(()=>window.clearTimeout(et))},H5);return()=>{W=!1,Le.abort(),window.clearTimeout(et),window.clearTimeout(pt)}},[I,S]);const re=I&&(A.isLoading||A.query!==S);cE(re);const Z=z.length+B.length,D=P.totalCount+V.totalCount+L.totalCount+Z,K=S?`No results found for "${S}"`:"Search across Saveboard",ee=S?A.error?A.error:re?"Checking public profiles and public boards.":"Try an item title, board name, store domain, public profile, or public board.":"Start typing to search your saved items, boards, stores, people, and public boards. Recent local items, boards, and stores are shown below.",J=d.useCallback(W=>{if(W?.domain){c(W);return}c({})},[c]),fe=D>0||A.isLoading,De=S&&A.error&&fe?A.error:"",Be=d.useMemo(()=>[...P.results.map(W=>({id:`search-item-${W.id}`,open:()=>s(W)})),...V.results.map(W=>({id:`search-board-${W.list.id||W.list.name}`,open:()=>a(W.list.name)})),...L.results.map(W=>({id:`search-store-${W.domain||W.id||W.displayName}`,open:()=>J(W)})),...z.map(W=>({id:`search-person-${W.username}`,open:()=>o(W)})),...B.map(W=>({id:`search-public-board-${W.id}`,open:()=>i(W)}))],[V.results,P.results,a,s,o,i,J,z,B,L.results]),Fe=Be.find(W=>W.id===f)||Be[0]||null;d.useEffect(()=>{h(W=>Be.some(Le=>Le.id===W)?W:Be[0]?.id||"")},[Be]),d.useEffect(()=>{f&&document.getElementById(`${f}-row`)?.scrollIntoView({block:"nearest"})},[f]);const ke=W=>{if(W.key!=="Tab"){if(W.key==="ArrowDown"||W.key==="ArrowUp"){if(!Be.length)return;W.preventDefault();const Le=W.key==="ArrowDown"?1:-1;h(et=>{const pt=Be.findIndex(pe=>pe.id===et),$t=pt===-1?Le>0?0:Be.length-1:(pt+Le+Be.length)%Be.length;return Be[$t]?.id||""});return}if(W.key==="Enter"){if(!Fe)return;W.preventDefault(),Fe.open();return}if(W.key==="Escape"){if(W.preventDefault(),p){m(""),h("");return}if(f){h("");return}u.current?.blur()}}},We=P.results.map(W=>n.jsx(t4,{isSelected:f===`search-item-${W.id}`,lists:e,onOpenProduct:s,onSelect:()=>h(`search-item-${W.id}`),product:W,searchResultId:`search-item-${W.id}`},`item-${W.id}`)),de=V.results.map(W=>n.jsx(r4,{isSelected:f===`search-board-${W.list.id||W.list.name}`,onOpenList:a,onSelect:()=>h(`search-board-${W.list.id||W.list.name}`),searchResultId:`search-board-${W.list.id||W.list.name}`,summary:W},`board-${W.list.id||W.list.name}`)),ye=L.results.map(W=>n.jsx(n4,{isSelected:f===`search-store-${W.domain||W.id||W.displayName}`,onOpenStore:J,onSelect:()=>h(`search-store-${W.domain||W.id||W.displayName}`),searchResultId:`search-store-${W.domain||W.id||W.displayName}`,store:W},`store-${W.domain||W.id||W.displayName}`)),ge=z.map(W=>n.jsx(a4,{isSelected:f===`search-person-${W.username}`,onOpenProfile:o,onSelect:()=>h(`search-person-${W.username}`),person:W,searchResultId:`search-person-${W.username}`},`person-${W.username}`)),ze=B.map(W=>n.jsx(s4,{board:W,isSelected:f===`search-public-board-${W.id}`,onOpenPublicBoard:i,onSelect:()=>h(`search-public-board-${W.id}`),searchResultId:`search-public-board-${W.id}`},`public-board-${W.id}`));return n.jsxs("main",{className:"updatesPage searchPage",children:[n.jsx("header",{className:"updatesHeader primaryPageHeader contentAlignedPageHeader",children:n.jsx("h1",{children:"Search"})}),n.jsx("section",{className:"storesControls","aria-label":"App-wide Saveboard search",children:n.jsxs("label",{className:"storesSearch",children:[n.jsx("span",{className:"toolbarSrOnly",children:"Search Saveboard"}),n.jsx("input",{"aria-activedescendant":f?`${f}-row`:void 0,"aria-controls":"search-results",autoComplete:"off",autoFocus:!0,onKeyDown:ke,onChange:W=>m(W.target.value),placeholder:"Search items, boards, stores, people",ref:u,type:"search",value:p})]})}),!fe||De?n.jsxs("section",{className:"priceOverviewList","aria-label":"Search results","aria-live":"polite",id:"search-results",children:[fe?null:n.jsxs("div",{className:"priceOverviewEmptyState",children:[n.jsx("p",{children:K}),n.jsx("span",{children:ee})]}),De?n.jsx("p",{className:"searchResultNotice",children:De}):null]}):null,fe?n.jsxs(n.Fragment,{children:[n.jsx(gm,{count:P.totalCount,title:"Items",children:We}),n.jsx(gm,{count:V.totalCount,title:"Boards",children:de}),n.jsx(gm,{count:L.totalCount,title:"Stores",children:ye}),n.jsx(gm,{count:A.people.length,title:"People",children:ge}),n.jsx(gm,{count:A.publicBoards.length,title:"Public Boards",children:ze})]}):null]})}const v4="Discover public boards | Saveboard",y4="Explore boards picked by SaveBoard and recently published boards shared by the community.";function z_({content:e,onOpenAccount:t,onOpenApp:r,onOpenProfile:a,onOpenPublicBoard:s,signedIn:o=!1,preview:i=!1}){d.useEffect(()=>{if(!i)return window.location.pathname!==ta&&window.location.pathname.startsWith(`${ta}/`)&&ul(ta),mp({description:y4,title:v4,url:Qa(ta)})},[i]);const c=(e?.featured||[]).map(hg),l=(e?.recent||[]).map(hg),u=(e?.collections||[]).map(h=>({...h,boards:h.boards.map(hg)})),p=e?.profiles||[],m=GB({boards:[...c,...l,...u.flatMap(h=>
32h.boards),...p],status:e?.status}),f=i?"div":"main";return n.jsxs(f,{className:"updatesPage discoverPage",children:[n.jsxs("header",{className:"updatesHeader primaryPageHeader contentAlignedPageHeader discoverHeader",children:[n.jsx("h1",{children:"Discover"}),n.jsx("span",{children:"Boards picked by SaveBoard and new finds from the community."})]}),n.jsx("div",{className:"discoverSectionStack",children:m==="loading"?n.jsx(bm,{anchor:"boards",badge:F_,busy:!0,title:"Featured boards",children:n.jsx(f4,{})}):m==="ready"?n.jsxs(n.Fragment,{children:[c.length?n.jsx(bm,{anchor:"boards",badge:F_,title:"Featured boards",children:c.map((h,b)=>n.jsx(sS,{board:h,index:b,onOpenProfile:a,onOpenPublicBoard:s},`featured-${h.id}`))}):null,l.length?n.jsxs(bm,{anchor:"community",title:"New from the community",children:[l.map((h,b)=>n.jsx(sS,{board:h,index:b,onOpenProfile:a,onOpenPublicBoard:s},`recent-${h.id}`)),e.canLoadMore?n.jsx("button",{className:"discoverSectionAction",onClick:e.loadMore,children:"Load more community boards"}):null]}):null,u.map(h=>n.jsx(bm,{anchor:`collection-${h.slug}`,title:h.title,children:h.boards.map((b,v)=>n.jsx(sS,{board:b,index:v,onOpenProfile:a,onOpenPublicBoard:s},`${h.slug}-${b.id}`))},h.slug)),p.length?n.jsx(bm,{anchor:"savers",title:"Featured savers",variant:"v2FeaturedSavers",children:p.map(h=>n.jsx(h4,{onOpenProfile:a,profile:h},h.username))}):null]}):n.jsx(g4,{error:m==="error",onOpenAccount:t,onOpenApp:r,onRetry:e?.retry,signedIn:o})})]})}function S4({capabilities:e=WC(null),onBackToDashboard:t,onCancelPriceUpdate:r,onCheckPrice:a,onConfirmPriceUpdate:s,onOpenProduct:o,priceCheckState:i={},products:c=[]}){const[l,u]=d.useState("all"),p=d.useMemo(()=>c.map(h5).filter(P=>P.hasPricingSetup||P.hasAvailabilitySetup).sort((P,V)=>{if(P.needsAttention!==V.needsAttention)return P.needsAttention?-1:1;const L=Date.parse(P.latestEvent?.createdAt||""),z=Date.parse(V.latestEvent?.createdAt||"");return Number.isFinite(L)||Number.isFinite(z)?(Number.isFinite(z)?z:0)-(Number.isFinite(L)?L:0):String(P.product.title||"").localeCompare(String(V.product.title||""),void 0,{sensitivity:"base"})}),[c]),m=j_(p,l),f=p.filter(P=>P.tracking.enabled||P.availabilityTracking.enabled),h=p.filter(P=>P.targetReached||P.hasPriceDrop||P.latestEvent).length,b=p.filter(P=>P.latestAvailabilityEvent).length,v=h+b,S=p.filter(P=>P.needsAttention).length,C=p.filter(P=>P.isLocalOnly&&(P.tracking.enabled||P.availabilityTracking.enabled)).length,I=p.filter(P=>(P.tracking.enabled||P.availabilityTracking.enabled)&&!P.canCheckPrice).length,A=Number(e.trackedProductsLimit),k=Number.isFinite(A)&&A>0,E=k&&f.length>A,y=e.plan==="premium"?`Premium: ${f.length} tracked product${f.length===1?"":"s"}.`:k?`Free: ${f.length} of ${A} tracked products.`:`Free: ${f.length} tracked product${f.length===1?"":"s"}.`,N=e.plan==="premium"?"Automatic checks and email alerts still need cloud backup and alert emails to be enabled.":E?"Over Free limit: extra products will not be checked automatically.":k&&f.length===A?"You're at the Free automatic-check limit.":"",_=e.plan==="premium"?"":Rr.billingUiEnabled?"Premium adds more tracked products; email alerts also need alert emails to be enabled.":"Premium billing is not live yet.";return n.jsxs("main",{className:"priceTrackingPage",children:[n.jsxs("header",{className:"priceTrackingHeader",children:[n.jsx("button",{onClick:t,type:"button",children:"Back to dashboard"}),n.jsx("p",{children:"Tracking"}),n.jsx("h1",{children:"Tracking"}),n.jsx("span",{children:"Watch prices, availability, alerts, and checks that need attention."})]}),n.jsxs("section",{className:"priceOverviewSummary","aria-label":"Tracking summary",children:[n.jsxs("div",{children:[n.jsx("span",{children:"Tracked products"}),n.jsx("strong",{children:f.length})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Price alerts"}),n.jsx("strong",{children:h})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Availability alerts"}),n.jsx("strong",{children:b})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Needs attention"}),n.jsx("strong",{children:S})]})]}),n.jsxs("section",{className:"priceOverviewLimit","aria-label":"Tracking limits",children:[n.jsx("p",{children:y}),N?n.jsx("span",{children:N}):null,C?n.jsxs("span",{children:[C," local tracked product",C===1?"":"s"," need sign-in and cloud backup before automatic alerts."]}):null,I?n.jsxs("span",{children:[I," tracked product",I===1?"":"s"," need a link before checks can run."]}):null,!v&&p.length?n.jsx("span",{children:"No tracking alerts yet."}):null,(E||f.length===A)&&_?n.jsx("span",{children:_}):null]}),n.jsx("nav",{className:"priceOverviewFilters","aria-label":"Tracking filters",children:l5.map(P=>{const V=j_(p,P.id).length;return n.jsxs("button",{"aria-pressed":l===P.id,className:l===P.id?"isActive":"",onClick:()=>u(P.id),type:"button",children:[P.label,n.jsx("span",{children:V})]},P.id)})}),n.jsx("section",{className:"priceOverviewList","aria-label":"Tracked products",children:p.length?m.length?m.map(P=>{const V=i.productId===P.product.id?i:{},L=V.status==="checking",z=V.status==="confirming",B=P.targetSummary.hasTargetPrice?a5(P.targetSummary):"",re=Rr.availabilityTrackingEnabled&&P.hasAvailabilitySetup,Z=P.hasPriceDrop&&P.history.canCompareAmou
32nt&&P.history.amountChange?n5(P.history):P.hasPriceDrop?"Price dropped":"",D=kn(P.product)||jn,K=zi(P.product,D);return n.jsxs("article",{className:"priceOverviewItem",children:[n.jsx("div",{className:"priceOverviewItemImage",style:qo(D)?void 0:kd(P.product),children:n.jsx(Ms,{alt:"",alternateSources:K,decoding:"async",fallbackSource:jn,loading:"lazy",source:D})}),n.jsxs("div",{className:"priceOverviewItemMain",children:[n.jsxs("div",{className:"priceOverviewItemTitle",children:[n.jsx("span",{children:P.product.category||P.product.listName||"Wishlist"}),n.jsx("h2",{children:P.product.title})]}),n.jsxs("div",{className:"priceOverviewItemMeta",children:[n.jsxs("div",{children:[n.jsx("span",{children:"Current"}),n.jsx("strong",{children:ts(P.product.price)?P.product.price:"No price saved"})]}),n.jsxs("div",{children:[n.jsx("span",{children:"Target"}),n.jsx("strong",{children:P.targetSummary.hasTargetPrice?P.targetSummary.targetPrice:"Not set"}),B?n.jsx("em",{children:B}):null]}),n.jsxs("div",{children:[n.jsx("span",{children:"Last checked"}),n.jsx("strong",{children:m5(P.tracking)})]}),re?n.jsxs("div",{children:[n.jsx("span",{children:"Availability"}),n.jsx("strong",{children:P.availabilityLabel}),n.jsx("em",{children:f5(P.availabilityTracking)})]}):null,n.jsxs("div",{children:[n.jsx("span",{children:"Next check"}),n.jsx("strong",{children:P.tracking.nextCheckAt||P.availabilityTracking.nextCheckAt?vs(P.tracking.nextCheckAt||P.availabilityTracking.nextCheckAt):"Manual only"})]})]}),n.jsxs("ul",{className:"priceOverviewBadges","aria-label":`Tracking status for ${P.product.title}`,children:[P.tracking.enabled&&P.availabilityTracking.enabled?n.jsx("li",{children:"Tracking price and availability"}):P.tracking.enabled?n.jsx("li",{children:"Tracking price"}):P.availabilityTracking.enabled?n.jsx("li",{children:"Tracking availability"}):n.jsx("li",{children:"Manual only"}),P.isLocalOnly?n.jsx("li",{children:"Saved locally"}):n.jsx("li",{children:"Backed up"}),P.alertLabel?n.jsx("li",{children:P.alertLabel}):null,P.availabilityAlertLabel?n.jsx("li",{children:P.availabilityAlertLabel}):null,Z?n.jsx("li",{children:Z}):null,P.needsAttention?n.jsx("li",{"data-tone":"warning",children:"Needs attention"}):null]}),V.message?n.jsx("p",{className:"priceOverviewRowMessage",children:V.message}):null,z?n.jsxs("div",{className:"priceOverviewConfirm",children:[n.jsx("button",{onClick:()=>s(P.product),type:"button",children:"Update price"}),n.jsx("button",{onClick:()=>r(P.product),type:"button",children:"Keep current"})]}):null]}),n.jsxs("div",{className:"priceOverviewItemActions","aria-label":`Actions for ${P.product.title}`,children:[n.jsx("button",{disabled:!P.canCheckPrice||L||z,onClick:()=>a(P.product),type:"button",children:L?"Checking...":P.canCheckPrice?"Check price":"Needs link"}),n.jsx("button",{onClick:()=>o(P.product),type:"button",children:"Open details"}),n.jsx("button",{onClick:()=>o(P.product),type:"button",children:"Edit tracking"})]})]},P.product.id)}):n.jsxs("div",{className:"priceOverviewEmptyState",children:[n.jsx("p",{children:g5(l)}),R_(l)?n.jsx("span",{children:R_(l)}):null]}):n.jsxs("div",{className:"priceOverviewEmptyState",children:[n.jsx("p",{children:"Track products to watch prices and availability over time."}),n.jsx("span",{children:"Manual checks work locally. Automatic alerts need sign-in and cloud backup."})]})})]})}const V_=30,w4=(e={})=>{const t=String(e.actorUsername||e.metadata?.actorUsername||"").trim().replace(/^@+/,"");return t?Oi(t):""},C4=(e={})=>Ye(e.actorName||e.metadata?.actorDisplayName||"")||"Saveboard user",x4=(e={})=>/^https?:\/\//i.test(String(e.actorAvatarUrl||e.metadata?.actorAvatarUrl||"").trim())?String(e.actorAvatarUrl||e.metadata?.actorAvatarUrl||"").trim():"",I4=(e={})=>Ye(e.boardTitle||e.metadata?.boardTitle||"")||"a public board",A4=(e={})=>{const t=I4(e);return e.type===gc.SOMEONE_FOLLOWED_YOU?{boardTitle:"",textAfterBoard:"",textBeforeBoard:"followed you"}:e.type===gc.FOLLOWED_USER_CREATED_PUBLIC_BOARD?{boardTitle:t,textAfterBoard:"",textBeforeBoard:"created a new public board:"}:e.type===gc.FOLLOWED_USER_MADE_BOARD_PUBLIC?{boardTitle:t,textAfterBoard:"public",textBeforeBoard:"made"}:e.type===gc.PUBLIC_BOARD_LIKED?{boardTitle:t,textAfterBoard:"",textBeforeBoard:"liked your public board:"}:e.type===gc.BOARD_COLLABORATION_INVITE_RECEIVED?{boardTitle:"",textAfterBoard:"",textBeforeBoard:"invited you to collaborate on a board"}:e.type===gc.BOARD_COLLABORATION_INVITE_ACCEPTED?{boardTitle:"",textAfterBoard:"",textBeforeBoard:"accepted y
32our board collaboration invite"}:e.type===gc.BOARD_COLLABORATION_INVITE_DECLINED?{boardTitle:"",textAfterBoard:"",textBeforeBoard:"declined your board collaboration invite"}:{boardTitle:"",textAfterBoard:"",textBeforeBoard:"has a new update"}};function P4({notification:e,onDismiss:t,onMarkRead:r,onOpenPath:a,pendingDismiss:s=!1,pendingRead:o=!1}){const i=C4(e),c=w4(e),l=Oi(String(e.metadata?.boardOwnerUsername||"").trim().replace(/^@+/,"")),u=c?`@${c}`:"",p=c?Yo(c):"",m=e.type===gc.PUBLIC_BOARD_LIKED?l:c,f=m&&e.boardId?jc(m,e.boardId):"",h=A4(e),b=oL(e.createdAt),v=x4(e),S=!e.readAt,C=u||i,I=["updatesRow",S?"isUnread":""].filter(Boolean).join(" "),A=v?n.jsx("img",{alt:"",src:v}):n.jsx("span",{children:Rf(i,u)}),k=h.boardTitle?n.jsx("strong",{children:h.boardTitle}):null,E=o?"Marking...":"Mark read";return n.jsxs("article",{className:I,children:[p?n.jsx("a",{className:"updatesAvatar",href:p,"aria-label":`View ${i}'s profile`,onClick:y=>a(y,p,e),children:A}):n.jsx("span",{className:"updatesAvatar","aria-hidden":"true",children:A}),n.jsxs("div",{className:"updatesRowContent",children:[n.jsxs("button",{className:"updatesRowBodyButton",disabled:!S||o,onClick:()=>r(e),type:"button",children:[n.jsxs("span",{className:"updatesRowMeta",children:[n.jsx("span",{children:i}),u?n.jsx("span",{children:u}):null,b?n.jsx("time",{dateTime:e.createdAt,children:b}):null,S?n.jsx("span",{className:"updatesUnreadText",children:"Unread"}):null]}),n.jsxs("span",{className:"updatesRowCopy",children:[n.jsx("strong",{children:C})," ",h.textBeforeBoard,k?n.jsxs(n.Fragment,{children:[" ",k]}):null,h.textAfterBoard?` ${h.textAfterBoard}`:""]})]}),n.jsxs("div",{className:"updatesRowActions","aria-label":"Update actions",children:[p?n.jsx("a",{href:p,onClick:y=>a(y,p,e),children:"View profile"}):null,f?n.jsx("a",{href:f,onClick:y=>a(y,f,e),children:"View board"}):null,S?n.jsx("button",{disabled:o,onClick:()=>r(e),type:"button",children:E}):null,n.jsx("button",{"aria-label":`Clear update from ${i}`,disabled:s,onClick:()=>t(e),type:"button",children:s?"Clearing...":"Clear"})]})]})]})}function _4({isClearing:e=!1,onCancel:t,onConfirm:r}){return d.useEffect(()=>{const a=s=>{s.key!=="Escape"||e||(s.preventDefault(),s.stopPropagation(),t())};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[e,t]),n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-busy":e?"true":"false","aria-describedby":"updates-clear-all-copy","aria-labelledby":"updates-clear-all-title","aria-modal":"true",className:"deleteProductModal updatesClearAllDialog",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"updates-clear-all-title",children:"Clear all notifications?"})}),n.jsx("p",{id:"updates-clear-all-copy",children:"This will remove all notifications from your updates list."}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{disabled:e,onClick:t,type:"button",children:"Cancel"}),n.jsx("button",{className:"updatesClearAllConfirmButton",disabled:e,onClick:r,type:"button",children:e?"Clearing...":"Clear all"})]})]})})}function E4({currentUsername:e="",signedIn:t}){const[r,a]=d.useState({actionError:"",actionMessage:"",invites:[],isLoading:!1,pendingInviteId:""}),s=d.useCallback(async()=>{if(!t){a({actionError:"",actionMessage:"",invites:[],isLoading:!1,pendingInviteId:""});return}a(i=>({...i,actionError:"",isLoading:!0}));try{const i=await Bk();a(c=>({...c,actionError:i.error||"",invites:i.error?[]:(i.invites||[]).filter(l=>TG(l,e)&&vL(l)),isLoading:!1}))}catch{a(i=>({...i,actionError:"Could not load collaboration invites.",invites:[],isLoading:!1}))}},[e,t]);d.useEffect(()=>{s()},[s]),Gw(s,t);const o=async(i,c)=>{if(!(!i?.id||r.pendingInviteId)){a(l=>({...l,actionError:"",actionMessage:"",pendingInviteId:i.id}));try{const l=c==="accept"?await qO(i.id):await YO(i.id);if(!l.ok){a(u=>({...u,actionError:l.error||"Could not update this invite.",pendingInviteId:""}));return}c==="accept"&&Si(Da.collaborationInviteAccepted,{surface:"updates"}),a(u=>({...u,actionMessage:c==="accept"?`Invite accepted. Find it with your boards on Home. You are ${yi(i.role).label==="Editor"?"an Editor":"a Viewer"}.`:"Invite declined.",invites:u.invites.filter(p=>
32p.id!==i.id),pendingInviteId:""})),dd()}catch{a(l=>({...l,actionError:"Could not update this invite.",pendingInviteId:""}))}}};return!t||!r.isLoading&&!r.actionError&&!r.actionMessage&&r.invites.length===0?null:n.jsxs("section",{className:"collaborationInvitesPanel","aria-busy":r.isLoading?"true":"false","aria-label":"Board collaboration invites",children:[n.jsxs("header",{children:[n.jsx("span",{children:"Collaboration"}),n.jsx("h2",{children:"Board invites"}),n.jsx("button",{disabled:r.isLoading,onClick:s,type:"button",children:"Refresh"})]}),r.isLoading?n.jsx("p",{className:"collaborationInviteMessage",role:"status",children:"Loading invites..."}):r.invites.length?n.jsx("div",{className:"collaborationInviteList",children:r.invites.map(i=>{const c=Wu(i.owner),l=r.pendingInviteId===i.id;return n.jsxs("article",{className:"collaborationInviteCard",children:[n.jsxs("div",{children:[n.jsx("span",{children:c}),n.jsx("strong",{children:i.boardTitle||"Shared board"}),n.jsxs("p",{children:["Wants to share this board with you as ",yi(i.role).label==="Editor"?"an Editor":"a Viewer","."," ",yi(i.role).summary,"."]})]}),n.jsxs("div",{children:[n.jsx("button",{disabled:l,onClick:()=>o(i,"accept"),type:"button",children:l?"Saving...":"Accept"}),n.jsx("button",{disabled:l,onClick:()=>o(i,"decline"),type:"button",children:"Decline"})]})]},i.id)})}):null,r.actionMessage?n.jsx("p",{className:"collaborationInviteMessage",role:"status",children:r.actionMessage}):null,r.actionError?n.jsx("p",{className:"collaborationInviteMessage isError",role:"status",children:r.actionError}):null]})}function k4({profileUsername:e="",signedIn:t,onBackToDashboard:r,onOpenAccount:a,onRefreshUnreadCount:s=Ai}){const[o,i]=d.useState({actionError:"",error:"",hasMore:!1,isLoading:!1,isLoadingMore:!1,notifications:[]}),[c,l]=d.useState(()=>new Set),[u,p]=d.useState(()=>new Set),[m,f]=d.useState(!1),[h,b]=d.useState(!1),[v,S]=d.useState(!1),C=d.useCallback(async({append:B=!1,before:re=null}={})=>{if(!t){i({actionError:"",error:"",hasMore:!1,isLoading:!1,isLoadingMore:!1,notifications:[]});return}i(Z=>({...Z,actionError:"",error:"",isLoading:!B,isLoadingMore:B}));try{const Z=await gU({before:re,includeDismissed:!1,limit:V_});i(D=>({...D,error:Z.error?"Could not load updates.":"",hasMore:!Z.error&&Z.notifications.length===V_,isLoading:!1,isLoadingMore:!1,notifications:Z.error?B?D.notifications:[]:B?[...D.notifications,...Z.notifications]:Z.notifications}))}catch{i(Z=>({...Z,error:"Could not load updates.",hasMore:!1,isLoading:!1,isLoadingMore:!1,notifications:B?Z.notifications:[]}))}},[t]);d.useEffect(()=>{C()},[C]);const I=d.useCallback(async()=>{try{await s()}catch{}},[s]),A=(B,re)=>{l(Z=>{const D=new Set(Z);return re?D.add(B):D.delete(B),D})},k=(B,re)=>{p(Z=>{const D=new Set(Z);return re?D.add(B):D.delete(B),D})},E=d.useCallback(async(B,{quiet:re=!1}={})=>{if(!B?.id||B.readAt)return!0;A(B.id,!0),i(Z=>({...Z,actionError:""}));try{const Z=await vU(B.id);if(!Z.ok)return re||i(K=>({...K,actionError:Z.error||"Could not mark update as read."})),!1;const D=Z.notification?.readAt||new Date().toISOString();return i(K=>({...K,notifications:K.notifications.map(ee=>ee.id===B.id?{...ee,readAt:D}:ee)})),await I(),!0}catch{return re||i(Z=>({...Z,actionError:"Could not mark update as read."})),!1}finally{A(B.id,!1)}},[I]),y=d.useCallback(async B=>{if(B?.id){k(B.id,!0),i(re=>({...re,actionError:""}));try{const re=await QI(B.id);if(!re.ok){i(Z=>({...Z,actionError:re.error||"Could not clear notification."}));return}i(Z=>({...Z,notifications:Z.notifications.filter(D=>D.id!==B.id)})),await I()}catch{i(re=>({...re,actionError:"Could not clear notification."}))}finally{k(B.id,!1)}}},[I]),N=d.useCallback(async()=>{if(h)return;const B=o.notifications.filter(re=>re?.id);if(B.length===0){f(!1);return}b(!0),i(re=>({...re,actionError:""}));try{if((await Promise.all(B.map(K=>QI(K.id)))).find(K=>!K.ok)){i(K=>({...K,actionError:"Could not clear all notifications."})),f(!1);return}const D=new Set(B.map(K=>K.id));i(K=>({...K,actionError:"",hasMore:!1,notifications:K.notifications.filter(ee=>!D.has(ee.id))}
32)),f(!1),await I()}catch{i(re=>({...re,actionError:"Could not clear all notifications."})),f(!1)}finally{b(!1)}},[h,I,o.notifications]),_=d.useCallback(async()=>{S(!0),i(B=>({...B,actionError:""}));try{const B=await yU();if(!B.ok){i(Z=>({...Z,actionError:B.error||"Could not mark updates as read."}));return}const re=new Date().toISOString();i(Z=>({...Z,notifications:Z.notifications.map(D=>D.readAt?D:{...D,readAt:re})})),await I()}catch{i(B=>({...B,actionError:"Could not mark updates as read."}))}finally{S(!1)}},[I]),P=d.useCallback(async(B,re,Z)=>{B.preventDefault(),await E(Z,{quiet:!0}),Ft(re)},[E]),V=()=>{const B=o.notifications[o.notifications.length-1];!B?.createdAt||o.isLoadingMore||C({append:!0,before:B.createdAt})},L=o.notifications.filter(B=>!B.readAt).length,z=o.notifications.length>0;return n.jsxs("main",{className:"updatesPage",children:[n.jsxs("header",{className:"updatesHeader primaryPageHeader",children:[n.jsx("h1",{children:"Updates"}),n.jsx("span",{children:t?"Quiet updates from profiles and public boards you follow.":"Sign in to see updates from follows and public boards."}),t?n.jsxs("div",{className:"updatesHeaderActions","aria-label":"Updates actions",children:[L>0?n.jsx("button",{disabled:v,onClick:_,type:"button",children:v?"Marking...":"Mark all as read"}):null,n.jsx("button",{disabled:o.isLoading,onClick:()=>C(),type:"button",children:"Refresh"}),z?n.jsx("button",{disabled:h||u.size>0||o.isLoading,onClick:()=>{i(B=>({...B,actionError:""})),f(!0)},type:"button",children:"Clear all"}):null]}):null]}),n.jsx(E4,{currentUsername:e,signedIn:t}),t?o.isLoading?n.jsx("section",{className:"updatesList","aria-busy":"true","aria-label":"Updates loading",children:Array.from({length:3},(B,re)=>n.jsxs("div",{className:"updatesRow updatesRowSkeleton",children:[n.jsx("span",{className:"updatesAvatar"}),n.jsx("span",{})]},re))}):o.error?n.jsxs("section",{className:"updatesStateCard","aria-label":"Updates error",children:[n.jsx("p",{children:o.error}),n.jsx("span",{children:"Try again in a moment."}),n.jsx("button",{onClick:()=>C(),type:"button",children:"Retry"})]}):z?n.jsxs(n.Fragment,{children:[o.actionError?n.jsx("div",{className:"updatesActionMessage",role:"status",children:o.actionError}):null,n.jsx("section",{className:"updatesList","aria-label":"Updates",children:o.notifications.map(B=>n.jsx(P4,{notification:B,onDismiss:y,onMarkRead:E,onOpenPath:P,pendingDismiss:h||u.has(B.id),pendingRead:c.has(B.id)},B.id))}),o.hasMore?n.jsx("div",{className:"updatesFooterAction",children:n.jsx("button",{disabled:o.isLoadingMore,onClick:V,type:"button",children:o.isLoadingMore?"Loading...":"Load more"})}):null]}):n.jsxs("section",{className:"updatesStateCard","aria-label":"No updates",children:[n.jsx("p",{children:"No updates yet."}),n.jsx("span",{children:"Follows and public board activity will appear here."})]}):n.jsxs("section",{className:"updatesStateCard","aria-label":"Updates sign in",children:[n.jsx("p",{children:"Sign in to see updates."}),n.jsx("span",{children:"Your sidebar will show Updates once you are signed in."}),n.jsx("button",{onClick:a,type:"button",children:"Go to account"})]}),m?n.jsx(_4,{isClearing:h,onCancel:()=>f(!1),onConfirm:N}):null]})}const H_=(e="")=>{const t=Ye(e||""),r=/(?:https?:\/\/|www\.|\b[a-z0-9-]+(?:\.[a-z0-9-]+)+\b)/i.test(t),a=["manual entry","unlisted"].includes(t.toLowerCase());return t&&!a&&(TR.has(t)||!DR(t)&&!r)?t:""},N4=({brand:e="",cardSize:t=mn.standard,id:r="",imageSettings:a={},imageUrl:s="",note:o="",priceLabel:i="",reportTargetId:c="",sourceLabel:l="",sourceUrl:u="",title:p=""}={})=>{const m=H_(e),f=H_(l),h=Ye(l||"")||Nc(aa(String(u||"")))||m,b=[f,m].filter(
32Boolean).filter((C,I,A)=>A.findIndex(k=>k.toLowerCase()===C.toLowerCase())===I),v=gS(a,{mode:Lr.normal,size:t}),S=Li(v);return{cardSize:zn(t),id:String(r||"").trim(),imageSettings:{...S,imageBackgroundMode:S.imageBackgroundStoredMode},imageUrl:String(s||"").trim(),metadataLabel:b.join(" · "),storeLabel:String(h||"").trim(),note:String(o||"").trim(),priceLabel:String(i||"").trim(),reportTargetId:String(c||"").trim(),sourceUrl:String(u||"").trim(),title:Ye(p||"Untitled item")}},j4=/[\p{Sc}]|\b[A-Z]{3}\b/u,R4=(e="",t="")=>{const r=String(e||"").trim(),a=String(t||"").trim();return r?!a||j4.test(r)?r:`${r} ${a}`:""},L4=(e={},{canReport:t=!1}={})=>{const r=R4(e.priceText,e.currency);return N4({brand:e.brand,cardSize:e.cardSize,id:e.id,imageSettings:e,imageFramingOverrides:e.imageFramingOverrides,imageUrl:uf(e.imageUrl||""),priceLabel:r,reportTargetId:t?e.id:"",sourceLabel:e.sourceLabel,sourceUrl:uf(e.sourceUrl||""),title:e.title})},B4=({description:e="",emptyCopy:t="This board will appear here once items are added.",emptyEyebrow:r="Empty board",emptyTitle:a="No public items yet",itemAriaLabel:s="Public board saved items",items:o=[],owner:i=null,title:c="Untitled board"}={})=>({description:String(e||"").trim(),emptyCopy:String(t||"").trim(),emptyEyebrow:String(r||"").trim(),emptyTitle:String(a||"").trim(),itemAriaLabel:String(s||"").trim(),items:Array.isArray(o)?o:[],owner:i,title:Ye(c||"Untitled board")}),W_=({boardItems:e=[],boards:t=[],publicBoardId:r=""}={})=>r?e.slice(0,tL({},op())).map(a=>uf(a?.imageUrl||"")).filter(Boolean).map(a=>Il(a,{width:Os.card})):t.slice(0,gf(240,eL,op())).flatMap(a=>(Array.isArray(a?.images)?a.images:[]).slice(0,zo)).map(a=>uf(a)).filter(Boolean).map(a=>Il(a,{width:Os.cover})),T4=9e4,D4=12,bl=new Map,O4=({publicBoardId:e="",username:t="",viewerId:r=""}={})=>t?`${r||"anonymous"}|${t}|${e||""}`:"",M4=e=>{const t=e?bl.get(e):null;return t?Date.now()-t.at>T4?(bl.delete(e),null):t.lookup:null},U4=(e,t)=>{if(!(!e||!t||t.error||t.isLoading))for(bl.delete(e),bl.set(e,{at:Date.now(),lookup:t});bl.size>D4;)bl.delete(bl.keys().next().value)},F4=()=>bl.clear(),$4=(e,t)=>{try{return JSON.stringify(e)===JSON.stringify(t)}catch{return!1}};function z4({item:e}){const t=dL(),r=e.imageUrl?Ed(e.imageSettings):void 0,a=ip(e.imageUrl,[],{width:Os.card}),s=`Open ${e.title} in a new tab`,o=t?mn.standard:zn(e.cardSize),i=n.jsx("div",{className:"productPodCard",children:n.jsx("div",{className:"productPodFace productPodFaceFront",children:n.jsx(rv,{analysisSource:a.source,"aria-hidden":"true",className:`productImageWindow publicSharedBoardItemMedia${e.imageUrl?"":" hasPlaceholderImage"}`,imageSource:e.imageUrl,settings:e.imageSettings,children:e.imageUrl?n.jsx(Ms,{alt:"",alternateSources:a.alternateSources,decoding:"async",draggable:!1,fallbackSource:jn,loading:"lazy",referrerPolicy:"no-referrer",source:a.source,style:r}):null})})}),c=n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"productPodDetails publicSharedBoardItemContent itemTileCaption",children:n.jsx("div",{className:"publicSharedBoardItemDetails",children:n.jsx("h2",{className:"itemTileName",children:e.title})})}),n.jsxs("div",{className:"productPodFooter publicSharedBoardItemFooter itemTileMeta",children:[n.jsx("span",{className:"itemTileSource",children:e.storeLabel}),n.jsx("p",{"aria-hidden":e.priceLabel?void 0:"true",className:"productPodPrice publicSharedBoardItemPrice itemTilePrice",children:e.priceLabel})]})]});return n.jsx("article",{"aria-label":e.sourceUrl?void 0:`${e.title}${e.priceLabel?`, ${e.priceLabel}`:""}`,className:`productPod publicProductPod publicSharedBoardItemCard${e.sourceUrl?" isLinked":" isUnavailable"}`,"data-card-size":o,children:e.sourceUrl?n.jsxs("a",{"aria-label":s,className:"publicSharedBoardItemCardBody publicSharedBoardItemCardLink",href:e.sourceUrl,rel:"noopener noreferrer",target:"_blank",children:[n.jsx("span",{className:"productPodMedia",children:i}),c]}):n.jsxs("div",{className:"publicSharedBoardItemCardBody",children:[n.jsx("span",{className:"productPodMedia",children:i}),c]})})}function V4(){return n.jsx("div",{className:"publicSharedBoardBrand",children:n.jsx("a",{"aria-label":"Open SaveBoard homepage",className:"publicSharedBoardBrandLink",href:"/",rel:"noopener noreferrer",target:"_blank",children:n.jsx(LR,{className:"appLogoMark publicSharedBoardBrandLogo"})})})}const gb="expanded",H4=600;function kL(e){const t=fp(),r=uL(!0),a=d.useMemo(()=>
32{const h=Cl(gb,t),b=Number.parseFloat(h.columnGap)*.6;return{...h,columnGap:Number.isFinite(b)?$o(b):h.columnGap}},[t]),s=lL(e),o=ug(e,gb,r,a),i=s>=H4?3:1,c=Math.min(Math.max(i,o),Number.isFinite(r)&&r>0?Math.floor(r):1/0),l=Number.parseFloat(a.podWidth)||0,u=Number.parseFloat(a.columnGap)||0,p=s>0?(s-u*(c-1))/c:0,m=p>l?p:l,f=ER(m);return d.useMemo(()=>({"--pod-width":$o(m),"--pod-aspect-ratio":a.podAspectRatio,"--pod-height":$o(f),"--grid-column-gap":a.columnGap,"--grid-row-gap":a.rowGap,"--board-column-count":c,"--expanded-product-details-height":$o(m*Hu.detailsHeight),"--expanded-product-card-body-padding":$o(m*Hu.bodyPadding),"--expanded-product-card-media-gap":$o(m*Hu.mediaGap)}),[c,f,m,a.columnGap,a.podAspectRatio,a.rowGap])}function W4({itemAriaLabel:e,items:t,title:r}){const a=d.useRef(null),s=kL(a),o=t.some(i=>zn(i.cardSize)!==mn.standard);return n.jsx("div",{className:"publicSharedBoardGallery",children:n.jsx("section",{"aria-label":e,className:`productGrid isVertical isStatic publicSharedBoardGrid${o?" hasVariableCardSizes":""}`,"data-density":gb,ref:a,style:s,children:t.map((i,c)=>n.jsx(z4,{item:i},i.id||`${r}-${i.title}-${c}`))})})}const G4=8;function q4(){const e=d.useRef(null),t=kL(e);return n.jsx("div",{className:"publicSharedBoardGallery",children:n.jsx("section",{"aria-hidden":"true",className:"productGrid isVertical isStatic publicSharedBoardGrid isSkeleton","data-density":gb,ref:e,style:t,children:Array.from({length:G4},(r,a)=>n.jsx("article",{className:"productPod publicProductPod publicSharedBoardItemCard isSkeleton",children:n.jsx("div",{className:"productPodCard",children:n.jsxs("div",{className:"productPodFace productPodFaceFront",children:[n.jsx("div",{className:"productImageWindow publicSharedBoardItemMedia hasPlaceholderImage"}),n.jsx("div",{className:"productPodDetails publicSharedBoardItemContent itemTileCaption",children:n.jsx("span",{className:"skeletonLine"})})]})})},a))})})}function Y4({monochromeEnabled:e,theme:t}){return n.jsxs("main",{"aria-busy":"true",className:`publicSharePage publicSharedBoardPage isLoading${e?" monochromeMode":""}`,"data-theme":t,children:[n.jsxs("header",{className:"publicShareHeader publicSharedBoardHeader publicSharedBoardTopBar",children:[n.jsxs("a",{"aria-label":"Saveboard home",className:"publicSharedBoardHomeLink",href:"/",children:[n.jsx("img",{alt:"",className:"publicSharedBoardHomeMark",src:"/brand/saveboard-blue-art-s-logo.png"}),n.jsx("span",{className:"publicSharedBoardHomeWordmark",children:"SaveBoard"})]}),n.jsxs("h1",{children:[n.jsx("span",{className:"srOnly",children:"Loading board"}),n.jsx("span",{"aria-hidden":"true",className:"skeletonLine skeletonLineTitle"})]}),n.jsxs("div",{"aria-hidden":"true",className:"publicSharedBoardMetadata",children:[n.jsx("span",{className:"publicShareOwnerAvatar isSkeleton"}),n.jsx("span",{className:"skeletonLine skeletonLineShort"})]})]}),n.jsx(q4,{})]})}function K4({authUser:e,headerActions:t=null,headerActionsClassName:r="",headerLeading:a=null,monochromeEnabled:s,onSubmitReport:o,ownerAction:i=null,ownerUsername:c="",theme:l,viewModel:u}){const p=u.items.length;return n.jsxs("main",{className:`publicSharePage publicSharedBoardPage${s?" monochromeMode":""}`,"data-theme":l,children:[n.jsxs("header",{className:"publicShareHeader publicSharedBoardHeader publicSharedBoardTopBar",children:[n.jsxs("a",{"aria-label":"Saveboard home",className:"publicSharedBoardHomeLink",href:"/",title:"Saveboard home",children:[n.jsx("img",{alt:"","aria-hidden":"true",className:"publicSharedBoardHomeMark",decoding:"async",draggable:"false",src:"/brand/saveboard-blue-art-s-logo.png"}),n.jsx("span",{className:"publicSharedBoardHomeWordmark",children:"SaveBoard"})]}),n.jsx("h1",{children:u.title}),n.jsxs("div",{className:"publicSharedBoardMetadata",children:[n.jsx(Z4,{compact:!0,owner:u.owner}),i,n.jsxs("span",{className:"publicSharedBoardCount",children:[p," ",p===1?"item":"items"]})]}),n.jsxs("div",{className:"publicSharedBoardUtilities",children:[t?n.jsx("div",{className:`publicShareActions${r?` ${r}`:""}`,children:t}):null,a]})]}),u.items.length?n.jsx(W4,{itemAriaLabel:u.itemAriaLabel,items:u.items,title:u.title}):n.jsx(jx,{actionHref:"",actionLabel:"",copy:u.emptyCopy,eyebrow:u.emptyEyebrow,title:u.emptyTitle})]})}const X4=(e="")=>{const t=String(e||"").trim();return/^https?:\/\//i.test(t)||/^data:image\/(?:jpeg|png|webp);base64,/i.test(t)?t:""},J4=({avatarUrl:e="",profile:t=null,user:r=null}={})=>{const a=Rx(r),s=vl(t),o=String(t?.display_name||t?.displayName||a.full_name||a.name||a.display_name||"").trim(),i=X4(e)||cp(t),c=t?.profile_visibility||t?.profileVisibility||"",l=s&&yl(c)==="public"?Yo(s):"";return!o&&!s&&!i?null:{avatarUrl:i,avatarFrame:ps(t),displayName:o||(s?`@${s}`:"Saveboard user"),handle:s?`@${s}`:"",profilePath:l,username:s}};function Q4({avatarFrame:e=null,avatarUrl:t="",displayName:r="",handle:a="",profilePath:s=""}
32){const[o,i]=d.useState(!1),c=Rf(r,a),l=!!(t&&!o),u=Bx(e);d.useEffect(()=>{i(!1)},[t]);const p=l?n.jsx("img",{alt:"",decoding:"async",loading:"lazy",onError:()=>i(!0),src:t,style:u}):n.jsx("span",{children:c});return s?n.jsx("a",{"aria-label":`Open ${r||a||"curator"}'s public profile`,className:"publicShareOwnerAvatar publicShareOwnerAvatarLink",href:s,rel:"noopener noreferrer",target:"_blank",children:p}):n.jsx("span",{className:"publicShareOwnerAvatar","aria-hidden":"true",children:p})}function Z4({compact:e=!1,owner:t=null}){return t?n.jsxs("div",{className:"publicShareOwner",children:[n.jsx(Q4,{avatarFrame:t.avatarFrame,avatarUrl:t.avatarUrl,displayName:t.displayName,handle:t.handle,profilePath:t.profilePath}),n.jsxs("span",{children:[e?null:n.jsx("span",{children:"Curated by"}),t.profilePath?n.jsx("a",{className:"publicShareOwnerNameLink",href:t.profilePath,rel:"noopener noreferrer",target:"_blank",children:t.displayName}):n.jsx("strong",{children:t.displayName}),t.handle&&t.displayName!==t.handle?n.jsx("em",{children:t.handle}):null]})]}):null}function jx({actionHref:e="/",actionLabel:t="Back to Saveboard",copy:r,eyebrow:a="",title:s}){return n.jsxs("section",{className:"publicEmptyState publicPageState","aria-label":s,children:[a?n.jsx("span",{className:"publicStateEyebrow",children:a}):null,n.jsx("p",{children:s}),n.jsx("span",{children:r}),e&&t?n.jsx("a",{className:"publicStateAction",href:e,children:t}):null]})}function eq({monochromeEnabled:e=!1,theme:t="light"}){return n.jsxs("div",{className:`appShell workspaceGate${e?" monochromeMode":""}`,"data-app-theme":"v2","data-theme":t,"data-theme-setting":t,children:[n.jsx("aside",{"aria-hidden":"true",className:"workspaceGateRail"}),n.jsx("header",{"aria-hidden":"true",className:"workspaceGateTopBar"}),n.jsxs("main",{"aria-busy":"true",className:"workspaceGateState",role:"status",children:[n.jsx("span",{className:"srOnly",children:"Opening your Saveboard…"}),n.jsx("div",{"aria-hidden":"true",className:"workspaceGateGrid",children:Array.from({length:6},(r,a)=>n.jsx("span",{className:"workspaceGatePod"},a))})]})]})}function zm({actionHref:e="/",actionLabel:t="Back to Saveboard",boardBranding:r=!1,copy:a,eyebrow:s,monochromeEnabled:o,theme:i,title:c}){return n.jsxs("main",{className:`publicSharePage publicStateOnlyPage${o?" monochromeMode":""}`,"data-theme":i,children:[n.jsx("header",{className:`publicShareHeader publicStateHeader${r?" publicSharedBoardStateHeader":""}`,children:r?n.jsx(V4,{}):n.jsxs("div",{className:"publicShareMasthead publicShareMastheadTop",children:[n.jsx("span",{children:s}),n.jsx("a",{"aria-label":"Open Saveboard",className:"publicShareBrandLink",href:"/",rel:"noopener noreferrer",target:"_blank",children:n.jsx(Ol,{className:"publicShareBrand",trademark:!1})})]})}),n.jsx(jx,{actionHref:e,actionLabel:t,copy:a,title:c})]})}function tq(e){return d.useEffect(()=>mp({description:"A visual wishlist for the whole internet. Save the things you love into boards, keep them on every device, and browse featured lists picked by Saveboard.",title:"Saveboard | A home for your saves",url:Qa("/")}),[]),n.jsx($B,{...e,Icon:ub})}function rq({monochromeEnabled:e,theme:t}){return d.useEffect(()=>mp({description:"Saveboard's privacy policy explains what data the web app and Chrome extension collect, store, use, and share.",title:"Privacy Policy | Saveboard",url:Qa(_d)}),[]),n.jsxs("main",{className:`landingPage privacyPage${e?" monochromeMode":""}`,"data-theme":t,children:[n.jsxs("nav",{className:"privacyNav","aria-label":"Saveboard privacy navigation",children:[n.jsx("a",{className:"landingBrand",href:"/","aria-label":"Saveboard home",children:n.jsx(Ol,{trademark:!1})}),n.jsx("a",{className:"privacyNavLink",href:"/",children:"Back to Saveboard"})]}),n.jsxs("header",{className:"privacyHero",children:[n.jsx("span",{className:"privacyEyebrow",children:"Updated: 19 September 2026"}),n.jsx("h1",{children:"Privacy Policy"}),n.jsx("p",{children:"SaveBoard is operated by ZEMBA & ELLIS LTD. This policy explains how SaveBoard handles data in the web app, the Chrome extension, and related backend services."})]}),n.jsxs("div",{className:"privacyLayout",children:[n.jsxs("aside",{className:"privacySummary","aria-label":"Privacy summary",children:[n.jsx("span",{children:"Summary"}),n.jsx("p",{children:"Saveboard needs an account. Your boards and saved items are stored in your Saveboard account and kept on the devices you sign in on. Boards start private. You can publish them, invite collaborators, or share a link that anyone holding it can open after signing in."}),n.jsx("a",{href:"mailto:[email protected]",children:"[email protected]"})]}),n.jsxs("article",{className:"privacyContent",children:[n.jsxs("section",{children:[n.jsx("h2",{children:"Who Saveboard Is"}),n.jsx("p",{children:"Saveboard helps you save product links, organise them into boards, and use the Chrome extension to capture product details while browsing shopping pages. Saveboard requires an account, and your boards are saved to that account."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"What Data Saveboard Collects"}),n.jsx("p",{children:"Depending on the features you use, Saveboard may collect or process:"}),n.jsxs("ul",{children:[n.jsx("li",{children:"Account data such as your email address, account ID, display name, username, profile details, and avatar."}),n.jsx("li",{children:"Saved item data including product URLs, titles, prices, images or image URLs, source/store names, notes, variants, and board/list names."}),n.jsx("li",{children:"Board data such as board names, descriptions, visibility settings, sort order, covers, and timestamps."}),n.jsx("li",{children:"Backup, import, export, settings, view preference, and extension import state data."}),n.jsx("li",{children:"Collaboration invitations, roles and membership; likes, follows, and content reports you submit."}),n.jsx("li",{children:"Public profile, public board, follow, update, and notification data when you choose to use those features."}),n.jsx("li",{children:"Technical error reports and server logs used to operate, secure, and diagnose the service."}),n.jsx("li",{children:"Messages and contact details you send when contacting us for support or privacy requests."})]})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Chrome Extension Page Access"}),n.jsx("p",{children:"The Saveboard Chrome extension can read page content on websites where it runs. It uses this access to detect product pages and provide the extension's save features."}),n.jsx("p",{children:"The extension may read product-oriented page data such as the current page URL, page title, canonical URL, product metadata, visible product images, price text, brand/source information, and selected options such as size, colour, or variant. Saveboard does not use saved browsing or product data for third-party advertising or behavioural ad targeting."}),n.jsx("p",{children:"When you save from the extension, captured product details are sent to the configured Saveboard web app so they can be added to your selected board or queued for import. The extension can load SaveBoard in a hidden page to save using your existing website session. The extension does not store long-lived credentials or refresh tokens in extension storage; the website manages your sign-in session."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Local Storage and Browser Storage"}),n.jsx("p",{children:"Saveboard keeps a copy of your boards, products, settings, view preferences, and recovery data in your browser's local storage so the app works quickly and survives a reload; your account remains the record. The Chrome extension stores pending c
32aptures, extension settings, remembered board/list choices, and the configured Saveboard app URL in Chrome extension storage."}),n.jsx("p",{children:"Some extension settings may use Chrome sync storage when Chrome provides it. Other extension data, such as pending captures and remembered save targets, is stored locally in the extension."}),n.jsx("p",{children:"Local data usually remains on the device and browser profile where it was created. Clearing browser data, uninstalling the extension, or using Saveboard's local clear/reset controls may remove local data."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Cookies and Similar Storage"}),n.jsx("p",{children:"SaveBoard does not currently set app cookies for advertising or behavioural tracking."}),n.jsx("p",{children:"SaveBoard uses browser storage such as localStorage and sessionStorage to provide requested features, including your boards and saved items, settings, recovery state, account/session support, and extension import flows."}),n.jsx("p",{children:"When you sign in, Supabase stores authentication session information in your browser so that your account can remain signed in. This website storage is separate from Chrome extension storage."}),n.jsx("p",{children:"Optional product and usage analytics are disabled. SaveBoard does not load Vercel Web Analytics, send product-usage events, or read or write account-specific analytics milestone flags. Flags left by earlier versions may remain until you clear this site’s browser data. SaveBoard does not use advertising pixels or behavioural advertising scripts."}),n.jsx("p",{children:"If SaveBoard later adds non-essential cookies, advertising pixels, affiliate tracking scripts, or similar technologies, we will update this policy and add consent controls where required."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Cloud Storage and Supabase"}),n.jsx("p",{children:"An account is required for your personal workspace. SaveBoard stores account, profile, board, product, notes, image URL/image data, settings, public sharing, collaboration, store, notification, and backup snapshot data in Supabase."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"How Saveboard Uses Data"}),n.jsx("p",{children:"Saveboard uses data to provide save, organise, sync, backup, account, sharing, and notification features where available or enabled."}),n.jsxs("ul",{children:[n.jsx("li",{children:"To save products and organise boards."}),n.jsx("li",{children:"To import products from the Chrome extension into the web app."}),n.jsx("li",{children:"To support account sign-in, profiles, backup, sync, and restore features."}),n.jsx("li",{children:"To publish public profiles, boards, and selected public board items when you choose to share them."}),n.jsx("li",{children:"To fetch product details and images when you save or edit an item. Saved prices are not live price monitoring."}),n.jsx("li",{children:"To manage board invitations, collaboration, follows, likes, and content reports."}),n.jsx("li",{children:"To maintain, secure, diagnose, and improve Saveboard."})]})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"How Long Saveboard Keeps Data"}),n.jsx("p",{children:"Local browser data remains on your device until you delete it, clear browser data, uninstall the Chrome extension, or use available Saveboard clear/reset controls."}),n.jsx("p",{children:"Account and cloud data is kept while your account is active or as needed to provide the service. Some records may be kept for security, backup, legal, accounting, dispute, or abuse-prevention reasons where necessary."}),n.jsx("p",{children:"Making a profile or board private removes it from public discovery, but does not revoke a previously created private share link. Copies made by other people or third-party link-preview services are separate from the data in your account."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Third-Party Services"}),n.jsx("p",{children:"SaveBoard uses the following services to operate the product:"}),n.jsxs("ul",{children:[n.jsx("li",{children:"Supabase for authentication, account emails, database storage, backups, and profile avatar storage."}),n.jsx("li",{children:"Vercel for hosting, serverless functions, and operational logs. Optional Vercel Web Analytics is disabled."}),n.jsx("li",{children:"Sentry for technical error reporting and diagnosis."}),n.jsx("li",{children:"Google Fonts to load the fonts used on the website; your browser connects to Google to request them."}),n.jsx("li",{children:"Google/Chrome platform services for Chrome Web Store distribution and Chrome extension APIs/storage."}),n.jsx("li",{children:"Google, Apple, or other OAuth providers if those sign-in options are enabled."}),n.jsx("li",{children:"Retailer websites and image hosts when SaveBoard or your browser requests product details or images."})]})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Sharing, Sales, and Advertising"}),n.jsx("p",{children:"SaveBoard does not sell user data to advertisers. SaveBoard does not use saved browsing or product data for third-party advertising or behavioural ad targeting."}),n.jsx("p",{children:"Saveboard shares data with service providers only as needed to provide and operate Saveboard or support features you choose to use. Public publishing, private share links, and collaboration provide different ways for other people to view board information, as explained below."}),n.jsx("p",{children:"The use of information received from Chrome extension APIs will adhere to the Chrome Web Store User Data Policy, including the Limited Use requirements."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Publishing, Private Links and Collaboration"}),n.jsx("p",{children:"Profiles and boards start private. Publishing requires a public profile and a public board. Public pages show your username, display name, avatar, bio, board details, and the item details you share, and may appear in Discover, search results, and link previews. Private item notes are not included in public or shared views."}),n.jsx("p",{children:"Copy private link and Generate QR code create a private link. Anyone with the private link can request access to the board, but must sign in to SaveBoard first. This shares board details and selected item details, plus your username, display name and avatar, even if your profile is private. A private profile’s bio is not included. These links can be forwarded. Making a board or profile private does not revoke an existing link; links do not expire automatically. The link remains valid until the owner revokes it from Share Board; creating a new link afterward does not reactivate the old one. Share a link only with people you want to have this access."}),n.jsx("p",{children:"You can invite an account by username in SaveBoard. We store the invitation, participants, role and status, and show the recipient the board title and inviter’s profile details. After acceptance, Editors can add, edit, reorder and remove items; Viewers can view them. The owner manages access and publishing. Items added to another person’s board remain on that board if you leave or delete your own account."}),n.jsx("p",{children:"Following and liking can generate in-app notifications. On public profiles, signed-in visitors can view follower and following lists containing public profiles. A profile owner can also see private profiles in their own lists. We process content reports and their reasons to review reported content."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Operational Error Reporting"}),n.jsx("p",{children:"Sentry helps us diagnose technical errors. Reports include the softw
32are release, error details, browser and device information, a general screen category, whether someone is signed in, and a short sanitised trail of app steps and network outcomes leading to an error. They are not a product-usage analytics feed. SaveBoard filters account identity, request data, free-text input and identifying URLs from this context. Session replay is disabled. Vercel and Supabase also process operational logs to run the service."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Your Controls"}),n.jsx("p",{children:"You can edit or delete saved items and boards in Saveboard. You can export and import Saveboard JSON backups where those controls are available. You can clear local browser data through Saveboard controls or your browser settings."}),n.jsxs("p",{children:["Use Delete account in the account area to delete your account and the application data you own, including your boards, saved items, account backups and avatar. This is separate from moving an item or board to Trash, where it remains recoverable. You can also contact ",n.jsx("a",{href:"mailto:[email protected]",children:"[email protected]"})," ","for help with deletion or a privacy request."]})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"What Account Deletion Does Not Clear"}),n.jsx("p",{children:"Account deletion is not a complete wipe of every copy. Provider backups and operational logs are managed separately. Reports made by other people may remain with account references removed. Items you added to someone else’s board, downloaded exports, and copies made by others are not removed by deleting your account. The local-clear option resets this browser’s app data; it does not clear extension storage, other devices, or every browser storage key. Use browser and extension settings to clear those local copies."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Your Privacy Rights"}),n.jsx("p",{children:"Depending on where you live and how Saveboard processes your data, you may have rights to access your personal data, correct inaccurate data, delete personal data, restrict or object to certain processing, receive a copy of your data, and withdraw consent where processing is based on consent."}),n.jsxs("p",{children:["To exercise these rights, contact ",n.jsx("a",{href:"mailto:[email protected]",children:"[email protected]"}),"."]}),n.jsx("p",{children:"If you are unhappy with how we handle your personal data, please contact us first so we can try to resolve it. You may also have the right to complain to the UK Information Commissioner's Office."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Extension Permissions"}),n.jsx("p",{children:"The Chrome extension requests permissions to provide product-saving features:"}),n.jsxs("ul",{children:[n.jsxs("li",{children:[n.jsx("code",{children:"activeTab"})," helps Saveboard work with the tab where you use the extension."]}),n.jsxs("li",{children:[n.jsx("code",{children:"storage"})," stores pending captures, settings, remembered boards/lists, and extension preferences."]}),n.jsxs("li",{children:[n.jsx("code",{children:"scripting"})," supports extension capture workflows on product pages."]}),n.jsxs("li",{children:[n.jsx("code",{children:"offscreen"})," lets the extension load a hidden SaveBoard page to save with your website session when no SaveBoard tab is open."]}),n.jsxs("li",{children:[n.jsx("code",{children:"http://*/*"})," and ",n.jsx("code",{children:"https://*/*"})," content-script access lets Saveboard detect and save product information from websites."]}),n.jsx("li",{children:"Saveboard app host permissions support communication between the extension and the Saveboard web app."})]})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Security"}),n.jsx("p",{children:"Saveboard uses HTTPS for deployed web traffic and relies on Supabase access controls for cloud account data. The extension validates Saveboard app origins for app communication. No security measure is perfect, but Saveboard is built to limit access to the data needed for its product-saving features."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Children"}),n.jsx("p",{children:"Saveboard is not directed to children. If you believe a child has provided personal data to Saveboard, contact us so we can review and delete it where appropriate."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Changes to This Policy"}),n.jsx("p",{children:"We may update this policy as Saveboard changes. When we make changes, we will update the effective date on this page."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Contact"}
32),n.jsxs("p",{children:["For privacy questions or deletion requests, contact"," ",n.jsx("a",{href:"mailto:[email protected]",children:"[email protected]"}),"."]}),n.jsx(dE,{})]})]})]})]})}function nq({monochromeEnabled:e,theme:t}){return d.useEffect(()=>mp({description:"SaveBoard's Terms & Conditions explain the rules for using the web app, public boards, Chrome extension, account features, and related services.",title:"Terms & Conditions | Saveboard",url:Qa(tv)}),[]),n.jsxs("main",{className:`landingPage privacyPage${e?" monochromeMode":""}`,"data-theme":t,children:[n.jsxs("nav",{className:"privacyNav","aria-label":"Saveboard terms navigation",children:[n.jsx("a",{className:"landingBrand",href:"/","aria-label":"Saveboard home",children:n.jsx(Ol,{trademark:!1})}),n.jsx("a",{className:"privacyNavLink",href:"/",children:"Back to Saveboard"})]}),n.jsxs("header",{className:"privacyHero",children:[n.jsx("span",{className:"privacyEyebrow",children:"Updated: 19 September 2026"}),n.jsx("h1",{children:"Terms & Conditions"}),n.jsx("p",{children:"SaveBoard is operated by ZEMBA & ELLIS LTD."})]}),n.jsxs("div",{className:"privacyLayout",children:[n.jsxs("aside",{className:"privacySummary","aria-label":"Terms summary",children:[n.jsx("span",{children:"Summary"}),n.jsx("p",{children:"SaveBoard helps you save product links, organise items into visual boards, and share selected boards through publication, private links or collaboration. These Terms explain the rules for using SaveBoard."}),n.jsx("a",{href:"mailto:[email protected]",children:"[email protected]"})]}),n.jsxs("article",{className:"privacyContent",children:[n.jsxs("section",{children:[n.jsx("h2",{children:"Summary"}),n.jsx("p",{children:"SaveBoard helps you save product links, organise items into boards, and share selected boards through publication, private links or collaboration. These Terms explain the rules for using SaveBoard, including the web app, public board pages, Chrome extension, account features, and related services where available."}),n.jsx("p",{children:"These Terms apply to the SaveBoard web app, public board pages, Chrome extension, account features, and related services where available."}),n.jsxs("p",{children:["Please also read our ",n.jsx("a",{href:_d,children:"Privacy Policy"}),", which explains how SaveBoard handles personal data."]})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Who SaveBoard Is"}),n.jsx("p",{children:'SaveBoard is operated by ZEMBA & ELLIS LTD. References to "SaveBoard", "we", "us", or "our" mean ZEMBA & ELLIS LTD and the SaveBoard services we provide.'})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Using SaveBoard"}),n.jsx("p",{children:"You may use SaveBoard to save product links, organise items into boards, add notes and details, and use supported account, backup, sharing, extension, and notification features where available."}),n.jsx("p",{children:"You are responsible for keeping your device, browser, account credentials, and exported backups secure. You must use SaveBoard lawfully and in line with these Terms."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Accounts"}),n.jsx("p",{children:"SaveBoard requires an account, and your boards and saved items are stored in it. A copy is kept in the browser you use so the app works quickly, and that copy may remain on the browser and device where it was created. Backup, profile, public board, and notification features send selected data to SaveBoard services."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Boards, Saved Items and Public Sharing"}),n.jsx("p",{children:"You are responsible for the links, boards, notes, images, descriptions, and other content you save, upload, edit, import, export, or publish. You should only publish boards and content that you have the right to share."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Chrome Extension"}),n.jsx("p",{children:"The SaveBoard Chrome extension helps capture product details from store pages while you browse. Extension capture may not work on every website or every page, and detected product details may need your review before or after saving."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Product Links and Retailer Websites"}),n.jsx("p",{children:"SaveBoard does not sell the products shown in saved items or public boards. Retailer websites, product pages, delivery, returns, pricing, payment, stock, and fulfilment are controlled by third parties. If you choose to buy something, your purchase is with the relevant retailer, not SaveBoard."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Prices, Availability and Product Information"}),n.jsx("p",{children:"Product prices, availability, images, retailer details, and metadata may change and may be inaccurate, incomplete, delayed, or unavailable. You should check the retailer's website before making a purchase."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Saved Prices and Notifications"}),n.jsx("p",{children:"Saved prices reflect details captured or entered when an item is saved or edited. SaveBoard does not provide live price monitoring, restock alerts, or price-alert emails. In-app notifications relate to features such as follows, likes, and collaboration invitations."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"User Content and Acceptable Use"}),n.jsx("p",{children:"You must not save, upload, publish, or share unlawful, infringing, abusive, misleading, malicious, harmful, or privacy-invasive content. You must not misuse SaveBoard, interfere with the service, attempt unauthorised access, or use SaveBoard to distribute malware, spam, or deceptive content."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Public Boards and Visibility"}),n.jsx("p",{children:"Public board details require sign-in; board previews may appear in Discover and link previews without signing in. Anyone with a private link or QR code can request access to the board, but must sign in to SaveBoard first. This does not publish the board. Private links remain valid until revoked; making a board or profile private does not revoke them. After revocation, the owner can create a new link and the old link remains invali
32d. Before sharing, check the board name, description, items and images. Private item notes are excluded."}),n.jsx("p",{children:"Accepted collaborators can view a shared board. Editors can add, edit, reorder and remove items; Viewers can only view. The owner controls access and publishing. Items contributed to someone else’s board remain there if the contributor leaves or deletes their own account."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Backups, Import and Export"}),n.jsx("p",{children:"SaveBoard may provide backup, import, and export tools where supported. You are responsible for storing exported files safely and checking imported data. Imports from old or edited files may not always restore exactly as expected."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Paid Features, Subscriptions and Billing"}),n.jsx("p",{children:"SaveBoard may introduce, change, or remove paid features, subscriptions, or usage limits in future. If paid features are enabled, billing terms shown at checkout or in the account area also apply."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Cancellation and Refunds"}),n.jsx("p",{children:"If paid features or subscriptions are available, cancellation and refund rights will depend on the plan, checkout terms, payment provider rules, and applicable consumer law. We will provide the relevant billing information before purchase where paid features are offered."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Intellectual Property"}),n.jsx("p",{children:"SaveBoard, its design, software, branding, and service materials are owned by or licensed to ZEMBA & ELLIS LTD. You keep your rights in content you add to SaveBoard, but you give us the limited permission needed to host, process, display, back up, sync, share, and operate that content for the features you choose to use."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Beta Features and Service Changes"}),n.jsx("p",{children:"Some features may be experimental, limited, or changed over time. We may add, update, pause, remove, or limit features where needed to improve SaveBoard, protect users, comply with law, or keep the service sustainable."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Availability of the Service"}),n.jsx("p",{children:"We aim to keep SaveBoard useful and available, but we do not guarantee uninterrupted access. The service may be unavailable because of maintenance, outages, third-party service issues, security incidents, browser changes, retailer website changes, or other events outside our control."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Suspension or Removal"}),n.jsx("p",{children:"SaveBoard may remove content or suspend, restrict, or terminate accounts where necessary to protect the service, other users, third parties, or to comply with law. Where practical, we will take a proportionate approach and may contact you about the issue."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Disclaimers"}),n.jsx("p",{children:'SaveBoard is provided on an "as is" and "as available" basis. We do not promise that saved product data, public board data, retailer information, prices, images, availability, metadata, extension capture, or notification features will always be accurate, complete, secure, or available.'})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Limitation of Liability"}),n.jsx("p",{children:"Nothing in these Terms excludes or limits liability that cannot be excluded or limited under applicable law. Subject to that, SaveBoard is not responsible for retailer purchases, third-party websites, loss of local browser data, missed alerts, inaccurate product information, or indirect losses arising from use of the service."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Termination"}),n.jsxs("p",{children:["You can stop using SaveBoard at any time and use Delete account in the account area. Account deletion removes the application data you own. Other people’s boards and copies, provider backups and operational logs are separate. See the ",n.jsx("a",{href:_d,children:"Privacy Policy"}
32)," for deletion scope and local-data controls."]})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Changes to These Terms"}),n.jsx("p",{children:"We may update these Terms as SaveBoard changes. When we make changes, we will update the effective date on this page. If a change is material and you have an account, we may provide additional notice where appropriate."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Governing Law"}),n.jsx("p",{children:"These Terms are governed by the laws of England and Wales. The courts of England and Wales will have jurisdiction, except where applicable consumer law gives you rights to bring a claim elsewhere."})]}),n.jsxs("section",{children:[n.jsx("h2",{children:"Contact"}),n.jsxs("p",{children:["If you have questions about these Terms, contact"," ",n.jsx("a",{href:"mailto:[email protected]",children:"[email protected]"}),"."]}),n.jsx(dE,{})]})]})]})]})}const oS=()=>({canFollow:!1,error:"",followersCount:0,followingCount:0,viewerIsFollowing:!1}),iS=(e=null)=>({canFollow:!!e?.canFollow,error:e?.error||"",followersCount:Number.isFinite(e?.followersCount)?e.followersCount:0,followingCount:Number.isFinite(e?.followingCount)?e.followingCount:0,viewerIsFollowing:!!e?.viewerIsFollowing});function aq({onBackToDashboard:e}){return n.jsxs("main",{className:"guidePage",children:[n.jsxs("header",{className:"guideHeader",children:[n.jsx("button",{onClick:e,type:"button",children:"Back to dashboard"}),n.jsx("p",{children:"Guide"}),n.jsx("h1",{children:"Using Saveboard"}),n.jsx("span",{children:"How Saveboard works, in a few minutes."})]}),n.jsxs("div",{className:"guideLayout",children:[n.jsx("nav",{className:"guideToc","aria-label":"Guide contents",children:t_.map(t=>n.jsx("a",{href:`#${t.id}`,children:t.title},t.id))}),n.jsx("section",{className:"guideSections","aria-label":"Guide sections",children:t_.map(t=>n.jsxs("article",{id:t.id,children:[n.jsx("h2",{children:t.title}),n.jsx("p",{children:t.copy})]},t.id))})]})]})}const G_=e=>Number.isFinite(Number(e)),oa=(e,t,r)=>{const a=Number(e)||0;return`${a} ${a===1?t:r}`},Kw=(e={})=>{const t=G_(e.listCount)?e.listCount:0,r=G_(e.productCount)?e.productCount:0;return`${oa(t,"board","boards")} · ${oa(r,"product","products")}`},Rx=(e={})=>e?.user_metadata||e?.raw_user_meta_data||{},sq=(e="")=>String(e||"").split("@")[0]?.trim()||"",NL=(e={},t=null)=>{const r=String(t?.display_name||t?.displayName||"").trim();if(r)return r;const a=Rx(e);return String(a.full_name||a.name||a.display_name||"").trim()},oq=(e="")=>String(e||"").trim().replace(/[._-]+/g," ").replace(/\s+/g," ").split(" ").filter(Boolean).map(t=>`${t.charAt(0).toUpperCase()}${t.slice(1)}`).join(" "),Lx=(e={},t="",r=null)=>{const a=NL(e,r);return a||oq(sq(t))||"Saveboard user"},Oi=(e="")=>String(e||"").trim().replace(/^@+/,"").toLowerCase().replace(/\s+/g,".").replace(/[^a-z0-9_.]/g,"").replace(/[_.]{2,}/g,".").replace(/^[_.]+|[_.]+$/g,"")||"saveboard-user",vl=(e=null)=>{const t=String(e?.username||"").trim();return t?Oi(t):""},iq=(e={},t=null)=>{const r=vl(t);if(r)return r;const a=Rx(e);return String(a.user_name||a.preferred_username||a.username||a.handle||"").trim().replace(/^@+/,"")},yl=(e="")=>String(e||"").trim().toLowerCase()==="private"?"private":"public",q_="saveboard.profileUsername",cS=3,Vm=30,cq=/^[a-z0-9_.]+$/,jL=(e="")=>String(e||"").trim().toLowerCase().replace(/^@+/,"").replace(/[._-]+/g,""),lq=new Set(Array.from(yb).flatMap(e=>[e,jL(e)])),Sl=(e="")=>String(e||"").trim().replace(/^@+/,"").toLowerCase(),bb=(e="")=>{const r=String(e||"").trim().replace(/^@+/,""),a=Sl(e);return a?r.includes("@")?"Use a username, not an email address.":a.length<cS?`Use ${cS}-${Vm} characters.`:a.length>Vm?`Use ${cS}-${Vm} characters.`:/\s/.test(a)||!cq.test(a)?"Use 3–30 letters, numbers, or simple separators.":/^[_.]|[_.]$/.test(a)?"Do not start or end with a dot or underscore.":/[_.]{2,}/.test(a)?"Use 3–30 letters, numbers, or simple separators.":yb.has(a)||lq.has(jL(a))?"This username is reserved.":"":"Enter a username."},dq=(e={},t=null)=>{const r=vl(t);if(r)return r;const a=Sl(iq(e,null));return a&&!bb(a)?a:""},RL=(e={},t="")=>{const r=String(e?.id||"").trim();if(r)return`${q_}:${r}`;const a=String(t||e?.email||"").trim().toLowerCase();return`${q_}:${a||"local"}`},LL=(e="")=>{if(!e||typeof window>"u")return"";try{const t=Sl(window.localStorage.getItem(e)||"");return bb(t)?"":t}catch{return""}}
32,uq=(e="",t="")=>{if(!e||typeof window>"u")return!1;try{return window.localStorage.setItem(e,Sl(t)),!0}catch{return!1}},Y_="saveboard.profileAvatar",gg="__removed__",BL=/^data:image\/(?:jpeg|png|webp);base64,/i,pq=(e={},t="")=>{const r=String(e?.id||"").trim();if(r)return`${Y_}:${r}`;const a=String(t||e?.email||"").trim().toLowerCase();return`${Y_}:${a||"local"}`},mq=(e="")=>{if(!e||typeof window>"u")return"";try{const t=String(window.localStorage.getItem(e)||"");if(t===gg||BL.test(t))return t}catch{return""}return""},K_=(e="",t="")=>{if(!e||typeof window>"u")return!1;try{return t?(window.localStorage.setItem(e,t),!0):(window.localStorage.removeItem(e),!0)}catch{return!1}},X_=(...e)=>{typeof window>"u"||e.filter(Boolean).forEach(t=>{try{window.localStorage.removeItem(t)}catch{}})},fq=e=>new Promise((t,r)=>{const a=new FileReader;a.addEventListener("load",()=>{const s=String(a.result||"");if(BL.test(s)){t(s);return}r(new Error("invalid-avatar-data-url"))}),a.addEventListener("error",()=>r(a.error||new Error("avatar-read-failed"))),a.readAsDataURL(e)}),Yo=(e="")=>`/u/${encodeURIComponent(Oi(e))}`,jc=(e="",t="")=>`${Yo(e)}/boards/${encodeURIComponent(String(t||"").trim())}`,hq=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,gq=(e="")=>{const t=String(new URLSearchParams(String(e||"")).get("share")||"").trim();return hq.test(t)?t:""},bq=(e="",t="",r="")=>`${jc(e,t)}?share=${encodeURIComponent(String(r||"").trim())}`,Rf=(e="",t="")=>String(e||t||"Saveboard user").replace(/^@/,"").split(/[\s._-]+/).filter(Boolean).slice(0,2).map(s=>s.charAt(0).toUpperCase()).join("")||"SB",lS=(e,t,r,a)=>{const s=Number(e);return Number.isFinite(s)?Math.min(a,Math.max(r,s)):t},ps=(e={})=>({x:lS(e?.avatar_position_x??e?.avatarPositionX??e?.x,50,0,100),y:lS(e?.avatar_position_y??e?.avatarPositionY??e?.y,50,0,100),zoom:lS(e?.avatar_zoom??e?.avatarZoom??e?.zoom,1,1,3)}),Kh=Object.freeze({x:50,y:50,zoom:1}),J_=.1,Q_=2,Bx=(e={})=>{const t=ps(e),r=`${t.x}% ${t.y}%`;return{objectPosition:r,transform:`scale(${t.zoom})`,transformOrigin:r}},vq=e=>e?lW.has(String(e.type||"").toLowerCase())?Number(e.size||0)>uW?"Choose an image under 10 MB.":"":"Choose a JPG, PNG, or WebP image.":"",qu=(e={},t=[])=>t.filter(r=>va(r.status)==="active"&&(r.listId?r.listId===e.id:r.listName===e.name||r.category===e.name)),TL=(e={})=>({boardTitle:Ye(e.name||"Untitled board"),itemCount:Math.max(0,Number(e.productCount||0)||0)}),DL=(e="",t="")=>{const r=String(e||"").trim(),a=String(t||"").trim();return!r||!a?"":`${r}:${a}:${new Date().toISOString().slice(0,10)}`},yq=(e=[],t=[])=>e.filter(r=>r?.isPublic===!0).map(r=>{const a=qu(r,t);return{coverItemIds:r.coverItemIds,description:r.publicDescription?.trim()||"",href:gd(r.slug||r.name),id:r.id||r.slug||r.name,name:r.name,products:a,productCount:a.length}}),Sq=(e=[],t=[])=>e.map(r=>({href:gd(r.slug||r.name),id:r.id,isPublic:r.isPublic===!0,name:r.name,productCount:qu(r,t).length})),wq=(e=0)=>oa(e,"like","likes");function OL({authUser:e,boardId:t="",boardTitle:r="",className:a="",hideWhenZero:s=!1,initialLikeCount:o=0,initialViewerHasLiked:i=!1,labelPrefix:c="",likeStateIsAuthoritative:l=!1}){const u=String(t||"").trim(),p=String(r||"").replace(/\s+/g," ").trim(),m=!!e?.id,[f,h]=d.useState(Math.max(0,Number(o||0)||0)),[b,v]=d.useState(i===!0),[S,C]=d.useState(!1),[I,A]=d.useState(""),k=d.useRef(!1);if(d.useEffect(()=>{let P=!0;return h(Math.max(0,Number(o||0)||0)),v(i===!0),C(!1),A(""),!u||!m||l?()=>{P=!1}:(C(!0),HM(u).then(V=>{P&&V?.ok&&V.state&&(h(V.state.likeCount),v(V.state.viewerHasLiked))}).finally(()=>{P&&C(!1)}),()=>{P=!1})},[e?.id,u,o,i,l,m]),!u)return null;const E=wq(f),y=p||"public board",N=c?`${c} ${E}`:E,_=async P=>{if(P.preventDefault(),P.stopPropagation(),!k.current){if(A(""),!m){A(qM);return}if(!S){k.current=!0,C(!0);try{const V=b?await GM(u):await WM(u);if(!V?.ok){A(V?.error||"Could not update like.");return}V.state&&(h(V.state.likeCount),v(V.state.viewerHasLiked))}catch{A("Could not update like.")}finally{k.current=!1,C(!1)}}}};return s&&f===0&&!I?null:n.jsxs("div",{className:`publicBoardLikeControl${a?` ${a}`:""}`,children:[n.jsxs("button",{"aria-busy":S?"true":void 0,"aria-disabled":S?"true":void 0,"aria-label":`${b?"Unlike":"Like"} ${y}, ${E}`,"aria-pressed":b?"true":"false",className:`publicBoardLikeButton${b?" isLiked":""}`,onClick:_,type:"button",children:[n.jsx("span",{"aria-hidden":"true",children:b?"♥":"♡"}),N]}),I?n.jsx("p",{className:"publicBoardLikeMessage",role:"status",children:I}):null]})}function Cq({authUser:e,board:t,index:r=0,ownerHandle:a="",readOnly:s=!1}){const o=Array.isArray(t.products)?t.products.filter(u=>kn(u)):(Array.isArray(t.images)?t.images:[]).map((u,p)=>({id:`${t.id}-cover-${p}`,imageUrl:u})).filter(u=>kn(u)),i=!s&&t.id?n.jsx(OL,{authUser:e,boardId:t.id,boardTitle:t.name,className:"isCardLike",initialLikeCount:t.likeCount}):null,c=n.jsxs(n.Fragment,{children:[n.jsx("span",{className:"boardTileCover",children:n.jsx(Bd,{coverItemIds:t.coverItemIds,list:t,products:o})}),n.jsxs("div",{className:"listPodDetails publicProfileBoardDetail
32s boardTileCaption",children:[n.jsx("span",{"aria-hidden":"true",className:"boardTileIndex",children:Ko(r)}),n.jsx("h2",{className:"boardCardTitle boardTileName",children:t.name})]})]}),l=n.jsxs("div",{className:"boardTileMeta",children:[n.jsx("span",{className:"boardTileOwner",children:a}),n.jsx("span",{className:"boardTileCount",children:oa(t.productCount,"item","items")})]});return s||!t.href?n.jsxs("article",{className:"listPod publicProfileBoardCard boardTile isReadOnly",children:[n.jsx("div",{className:"listPodSurface publicProfileBoardCardLink boardTileSurface",children:c}),l,i]}):n.jsxs("article",{className:"listPod publicProfileBoardCard boardTile",children:[n.jsx("a",{className:"listPodSurface publicProfileBoardCardLink boardTileSurface",href:t.href,children:c}),l,i]})}const bg=[{label:"Spam",value:"spam"},{label:"Scam or malicious link",value:"scam_or_malicious_link"},{label:"Offensive content",value:"offensive"},{label:"Impersonation",value:"impersonation"},{label:"Privacy concern",value:"privacy"},{label:"Other",value:"other"}],xq=bg.reduce((e,t)=>({...e,[t.value]:t.label}),{}),Iq={actioned:"Actioned",dismissed:"Dismissed",new:"New",reviewed:"Reviewed"},Aq=[{label:"Mark reviewed",value:"reviewed"},{label:"Dismiss",value:"dismissed"},{label:"Mark actioned",value:"actioned"}],Z_={board:{action:"unpublish-board",confirm:"Unpublish this public board? The owner’s private board will not be deleted.",label:"Unpublish board"},item:{action:"hide-item",confirm:"Hide this item from the public board? The owner’s private item will not be deleted.",label:"Hide item"},profile:{action:"set-profile-private",confirm:"Set this public profile private? The user account will not be deleted.",label:"Set profile private"}},Pq=1e3,_q=(e="")=>String(e||"").replace(/[_-]+/g," ").replace(/\s+/g," ").trim().replace(/\b\w/g,t=>t.toUpperCase());function ML({authUser:e,label:t="Report",onSubmitReport:r,targetId:a="",targetOwnerUsername:s="",targetType:o="",variant:i="inline"}){const[c,l]=d.useState(!1),[u,p]=d.useState(bg[0].value),[m,f]=d.useState(""),[h,b]=d.useState(""),[v,S]=d.useState(!1),C=d.useRef(null),I=d.useRef(null),A=d.useRef(!1),k=i==="card"||i==="header",E=k&&(c||!!h);d.useEffect(()=>{k&&(E?I.current?.querySelector("select, textarea, button")?.focus():A.current&&C.current?.focus(),A.current=E)},[k,E]);const y=()=>{l(L=>!L),b(e?.id?"":"Sign in to report this.")},N=()=>{l(!1),b("")},_=async L=>{if(L.preventDefault(),!e?.id){b("Sign in to report this.");return}if(!r){b("Could not send report. Please try again.");return}S(!0),b("");try{const z=await r({details:m,reason:u,targetId:a,targetOwnerUsername:s,targetType:o});if(!z?.ok){b(z?.error||"Could not send report. Please try again.");return}f(""),p(bg[0].value),l(!1),b("Thanks — we’ll review this.")}catch{b("Could not send report. Please try again.")}finally{S(!1)}},P=c&&e?.id?n.jsxs("form",{className:"publicReportForm",onSubmit:_,children:[n.jsxs("label",{children:[n.jsx("span",{children:"Reason"}),n.jsx("select",{disabled:v,onChange:L=>p(L.target.value),value:u,children:bg.map(L=>n.jsx("option",{value:L.value,children:L.label},L.value))})]}),n.jsxs("label",{children:[n.jsx("span",{children:"Details optional"}),n.jsx("textarea",{disabled:v,maxLength:Pq,onChange:L=>f(L.target.value),rows:3,value:m})]}),n.jsx("button",{className:"publicReportSubmit",disabled:v,type:"submit",children:v?"Sending...":"Submit report"})]}):null,V=h?n.jsx("p",{className:"publicReportMessage",role:"status",children:h}):null;return k?n.jsxs("div",{className:`publicReportControl ${i==="header"?"publicReportHeaderControl":"publicReportCardControl"}${E?" isOpen":""}`,children:[n.jsx("button",{"aria-expanded":E?"true":"false","aria-label":t,className:"publicReportToggle publicReportIconToggle",onClick:E?N:y,ref:C,title:t,type:"button",children:n.jsxs("svg",{"aria-hidden":"true",focusable:"false",viewBox:"0 0 16 16",children:[n.jsx("path",{d:"M4 13.5V2.75"}),n.jsx("path",{d:"M4 3.25h7.6l-1.7 2.65 1.7 2.65H4"})]})}),E?n.jsxs("div",{"aria-label":t,className:"publicReportSheet",onKeyDown:L=>{L.key==="Escape"&&(L.stopPropagation(),N())},ref:I,role:"dialog",children:[n.jsxs("div",{className:"publicReportSheetHeader",children:[n.jsx("span",{children:t}),n.jsx("button",{"aria-label":"Close report",className:"publicReportSheetClose",onClick:N,type:"button",children:n.jsx("span",{"aria-hidden":"true",children:"×"})})]}),P,V]}):null]}):n.jsxs("div",{className:"publicReportControl",children:[n.jsx("button",{className:"publicReportToggle",onClick:y,type:"button",children:t}),P,V]})}function Eq({board:e,index:t=0,onOpenBoard:r,onShareBoard:a,onSetVisibility:s,ownerHandle:o=""}){const i=e.isPublic?"Public":"Private",c=e.isPublic?"Private":"Public",l=oa(e.productC
32ount,"item","items");return n.jsxs("article",{className:`accountProfileBoardCard boardTile${e.isPublic?" isPublic":""}`,children:[n.jsxs("button",{"aria-label":`Open ${e.name} board, ${l}`,className:"accountProfileBoardOpenButton boardTileSurface",disabled:!r,onClick:()=>r?.(e),type:"button",children:[n.jsxs("div",{className:"accountProfileBoardCover boardTileCover",children:[n.jsx(Bd,{coverItemIds:e.coverItemIds,list:e,products:e.products}),n.jsx(gL,{list:e})]}),n.jsxs("div",{className:"accountProfileBoardDetails boardTileCaption",children:[n.jsx("span",{"aria-hidden":"true",className:"boardTileIndex",children:Ko(t)}),n.jsx("strong",{className:"boardCardTitle boardTileName",children:e.name})]})]}),n.jsxs("div",{className:"boardTileMeta",children:[n.jsx("span",{className:"boardTileOwner",children:o}),n.jsx("span",{className:"boardTileCount",children:l})]}),n.jsx("button",{"aria-label":`Set ${e.name} ${c.toLowerCase()}`,className:"accountProfileBoardOverlayControl accountProfileBoardVisibilityBadge",onClick:()=>s(e,!e.isPublic),type:"button",children:i}),n.jsx("button",{"aria-label":`Share ${e.name}`,className:"accountProfileBoardOverlayControl accountProfileBoardShareButton",onClick:u=>{u.preventDefault(),u.stopPropagation(),a?.(e)},title:"Share board",type:"button",children:n.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",fill:"none",children:[n.jsx("circle",{cx:"18",cy:"5",r:"3"}),n.jsx("circle",{cx:"6",cy:"12",r:"3"}),n.jsx("circle",{cx:"18",cy:"19",r:"3"}),n.jsx("path",{d:"M8.6 10.6 15.4 6.4M8.6 13.4l6.8 4.2"})]})})]})}function eE({board:e,index:t=0,onOpen:r}){const a=e.role==="editor"?"Editor":"Viewer",s=oa(e.itemCount,"item","items"),o=e.ownerUsername?`@${e.ownerUsername}`:"",i=e.ownerDisplayName||o||"SaveBoard user",c=i.replace(/^@/,"").charAt(0).toUpperCase()||"S";return n.jsxs("article",{"aria-label":`${e.title}, shared by ${i}, ${a}, ${s}`,className:"accountProfileBoardCard collaborativeProfileBoardCard boardTile",children:[n.jsxs("button",{"aria-label":`Open shared board ${e.title}, ${s}`,className:"accountProfileBoardOpenButton boardTileSurface",disabled:!r,onClick:()=>r?.(e),type:"button",children:[n.jsxs(rv,{className:"collaborativeProfileBoardMedia boardTileCover",imageSource:e.coverImageUrl,settings:e,children:[e.coverImageUrl?n.jsx(Ms,{alt:"",loading:"lazy",referrerPolicy:"no-referrer",source:e.coverImageUrl,fallbackSource:jn}):n.jsx("span",{"aria-hidden":"true",className:"collaborativeProfileBoardCoverPlaceholder",children:n.jsxs("svg",{fill:"none",viewBox:"0 0 24 24",children:[n.jsx("rect",{height:"14",rx:"2",width:"16",x:"4",y:"5"}),n.jsx("path",{d:"m6.5 16 3.8-4 2.8 2.8 1.9-2 2.5 3.2"})]})}),n.jsx("span",{className:`collaborativeProfileBoardRoleBadge is${a}`,children:a})]}),n.jsxs("div",{className:"accountProfileBoardDetails collaborativeProfileBoardDetails boardTileCaption",children:[n.jsx("span",{"aria-hidden":"true",className:"boardTileIndex",children:Ko(t)}),n.jsx("strong",{className:"boardCardTitle boardTileName",children:e.title})]})]}),n.jsxs("div",{className:"boardTileMeta",children:[n.jsxs("div",{className:"collaborativeProfileBoardOwner boardTileOwner",children:[n.jsx("span",{"aria-hidden":"true",className:"collaborativeProfileBoardOwnerAvatar",children:e.ownerAvatarUrl?n.jsx("img",{alt:"",loading:"lazy",referrerPolicy:"no-referrer",src:e.ownerAvatarUrl}):c}),n.jsx("span",{children:i})]}),n.jsx("span",{className:"boardTileCount",children:s})]})]})}function UL({kind:e,onClose:t,onFollowStateChange:r,onOpenProfile:a,profileUsername:s}){const o=LE(),i=o?.hydrateProfileRow,c=!!o?.user?.id,l=`profile-social-list-${e}-title`,u=e==="followers",[p,m]=d.useState({error:"",hasMore:!1,nextCursor:"",rows:[],status:"loading"}),[f,h]=d.useState(!1),[b,v]=d.useState(""),[S,C]=d.useState(""),[I,A]=d.useState({}),[k,E]=d.useState({}),y=u?AM:PM;d.useEffect(()=>{let L=!0;return m({error:"",hasMore:!1,nextCursor:"",rows:[],status:"loading"}),y(s).then(z=>{L&&m({error:z.error||"",hasMore:z.hasMore,nextCursor:z.nextCursor,rows:z.rows,status:z.error?"error":"ready"})}),()=>{L=!1}},[e,s]),d.useEffect(()=>{if(typeof i!="function")return;let L=!0;
32const z=p.rows.filter(B=>B.avatarPath&&!B.avatarUrl&&I[B.username]===void 0);if(z.length)return Promise.all(z.map(B=>i({avatar_path:B.avatarPath,avatar_url:""}).then(re=>[B.username,String(re?.avatar_url||"")]).catch(()=>[B.username,""]))).then(B=>{L&&A(re=>({...re,...Object.fromEntries(B)}))}),()=>{L=!1}},[I,i,p.rows]),d.useEffect(()=>{const L=z=>{z.key==="Escape"&&(z.preventDefault(),t())};return window.addEventListener("keydown",L),()=>window.removeEventListener("keydown",L)},[t]);const N=async()=>{if(f||!p.hasMore)return;h(!0);const L=await y(s,{before:p.nextCursor});if(h(!1),L.error){C(L.error);return}m(z=>{const B=new Set(z.rows.map(re=>re.username));return{...z,hasMore:L.hasMore,nextCursor:L.nextCursor||z.nextCursor,rows:[...z.rows,...L.rows.filter(re=>!B.has(re.username))]}})},_=async L=>{if(b||L.isViewer)return;v(L.username),C("");const z=L.viewerIsFollowing?await Vk(L.username):await zk(L.username);if(v(""),z?.error){C(z.error);return}const B=!!(z?.summary?.viewerIsFollowing??!L.viewerIsFollowing);m(re=>({...re,rows:bM(re.rows,L.username,B)})),r?.({username:L.username,viewerIsFollowing:B})},P=u?"Followers":"Following",V=u?"No followers yet.":"Not following anyone yet.";return n.jsx("div",{className:"modalLayer profileSocialLayer",onClick:L=>{L.target===L.currentTarget&&t()},role:"presentation",children:n.jsxs("div",{"aria-labelledby":l,"aria-modal":"true",className:"profileSocialSheet","data-kind":e,role:"dialog",children:[n.jsxs("div",{className:"profileSocialSheetHeader",children:[n.jsx("h2",{id:l,children:P}),n.jsx("button",{"aria-label":"Close",className:"profileSocialClose",onClick:t,type:"button",children:"×"})]}),p.status==="loading"?n.jsx("ul",{"aria-busy":"true","aria-label":`${P} loading`,className:"profileSocialList isSkeleton",children:[0,1,2].map(L=>n.jsxs("li",{className:"profileSocialRow isSkeleton",children:[n.jsx("span",{className:"profileSocialAvatar"}),n.jsxs("span",{className:"profileSocialNames",children:[n.jsx("span",{className:"profileSocialSkeletonLine"}),n.jsx("span",{className:"profileSocialSkeletonLine isShort"})]})]},L))}):p.status==="error"?n.jsx("p",{className:"profileSocialEmpty",role:"status",children:p.error}):p.rows.length===0?n.jsx("p",{className:"profileSocialEmpty",role:"status",children:V}):n.jsx("ul",{"aria-label":P,className:"profileSocialList",children:p.rows.map(L=>{const z=L.avatarUrl||I[L.username]||"",B=!!z&&!k[L.username],re=L.displayName||L.username,Z=c?vM(L,{isPending:b===L.username}):"";return n.jsxs("li",{className:"profileSocialRow",children:[n.jsxs("button",{"aria-label":`Open @${L.username}`,className:"profileSocialPerson",onClick:()=>a(L.username),type:"button",children:[n.jsx("span",{"aria-hidden":"true",className:`profileSocialAvatar ${xx(L.username)}`,children:B?n.jsx("img",{alt:"",decoding:"async",loading:"lazy",onError:()=>E(D=>({...D,[L.username]:!0})),src:z}):n.jsx("span",{children:Rf(L.displayName,L.username)})}),n.jsxs("span",{className:"profileSocialNames",children:[n.jsx("span",{className:"profileSocialName",children:re}),n.jsxs("span",{className:"profileSocialHandle",children:["@",L.username]})]})]}),L.isViewer?n.jsx("span",{className:"profileSocialYou",children:"You"}):Z?n.jsx("button",{"aria-label":`${L.viewerIsFollowing?"Unfollow":"Follow"} @${L.username}`,"aria-pressed":L.viewerIsFollowing,className:`profileSocialFollow${L.viewerIsFollowing?" isFollowing":""}`,disabled:!!b,onClick:()=>_(L),type:"button",children:Z}):null]},L.username)})}),S?n.jsx("p",{className:"profileSocialActionError",role:"alert",children:S}):null,p.status==="ready"&&p.hasMore?n.jsx("button",{className:"profileSocialLoadMore",disabled:f,onClick:N,type:"button",children:f?"Loading…":"Show more"}):null]})})}function tE({authUser:e,isCurrentUserPreview:t,isLocalProfilePreview:r=!1,lists:a,lookupError:s,lookupIsLoading:o,monochromeEnabled:i,onSubmitReport:c,products:l,previewAvatarUrl:u,previewDisplayName:p="",previewUsername:m="",publicBoards:f=[],publicBoardsError:h="",publicProfile:b,profile:v,profileUsername:S,theme:C}
32){const[I,A]=d.useState(oS),[k,E]=d.useState(!1),[y,N]=d.useState(!1),[_,P]=d.useState(""),[V,L]=d.useState(""),[z,B]=d.useState(0),[re,Z]=d.useState("boards"),[D,K]=d.useState(!1),ee=fp(),J=d.useMemo(()=>({"--standard-board-card-width":Cl(Ja,ee).podWidth}),[ee]),fe=!!(r&&t),De=fe&&(e?.email||e?.user_metadata?.email)||"",Be=fe?v:b,Fe=fe?!!(t||Be):!!Be,ke=Fe?fe?p||Lx(e,De,v):Be?.display_name?.trim()||"Saveboard user":"Profile not found",We=Oi(Fe?fe?m:Be?.username||S:S),de=`@${We}`,ye=Fe?fe?u===void 0?cp(v):u:Be?.avatar_url||"":"",ge=Bx(fe?v:Be);fe&&jq(e);const ze=fe?yq(a,l):f,W=fe?ze:ze.map(Ke=>({...Ke,href:jc(We,Ke.id)}));oa(ze.length,"public board","public boards");const Le=Fe?String(Be?.bio||"").trim():"",et=Fe?`${ke} (${de}) on Saveboard`:"Profile on Saveboard",pt=Fe?`Explore public boards curated by ${ke} on Saveboard.`:"Explore public boards on Saveboard.",$t=Qa(r?OR:Yo(We)),pe=fe?`Boards shared by ${ke}. Only boards you mark public appear here.`:Le||`A public Saveboard profile for ${ke}.`,Tt=r?"Boards will appear here when they are made public.":t?"Your public boards will appear here after they are published and your profile is public.":"Public boards will appear here.",F=!!(Fe&&!fe&&We),te=!!e?.id,me=!!(F&&!t&&(!te||k||I.canFollow||I.viewerIsFollowing||I.error));k||oa(I.followersCount,"follower","followers"),k||oa(I.followingCount,"following","following");const ie=te?y||k?"Loading":I.viewerIsFollowing?"Following":"Follow":"Sign in to follow",Ae=!!(te&&(y||k)),Re=ke.split(/\s+/).filter(Boolean).slice(0,2).map(Ke=>Ke.charAt(0).toUpperCase()).join("")||"S",ne=fe?e?.created_at||"":Be?.created_at||"",ht=(()=>{const Ke=new Date(ne);return ne&&!Number.isNaN(Ke.getTime())?String(Ke.getFullYear()):""})(),kt=ze.reduce((Ke,ft)=>Ke+(Number(ft.productCount)||0),0),Ee=d.useMemo(()=>ze.flatMap(Ke=>(Array.isArray(Ke.products)?Ke.products:[]).filter(ft=>kn(ft)).map(ft=>({boardHref:Ke.href||"",boardName:Ke.name,product:ft}))).sort((Ke,ft)=>(Date.parse(ft.product.createdAt||ft.product.updatedAt||"")||0)-(Date.parse(Ke.product.createdAt||Ke.product.updatedAt||"")||0)).slice(0,8),[ze]),xe=F,Qe=k?"—":(Number(I.followersCount)||0).toLocaleString(),Pe=k?"—":(Number(I.followingCount)||0).toLocaleString(),Ct=!!(F&&!k&&!I.error),nr=Ke=>{L(""),Ft(Yo(Ke))},en=async()=>{try{await Tu($t),K(!0),window.setTimeout(()=>K(!1),2e3)}catch{}},st=o?{actionHref:"",actionLabel:"",copy:"One moment while this profile loads.",eyebrow:"Public profile",title:"Loading profile..."}:s?{copy:"We could not load this page. Try again in a moment.",eyebrow:"Public profile",title:"Something went wrong"}:Fe?null:{copy:"This Saveboard profile does not exist or is not available.",eyebrow:"Public profile",title:"Profile not found"};d.useEffect(()=>{let Ke=!0;return F?(E(!0),P(""),Ym(We).then(ft=>{Ke&&A(iS(ft))}).catch(()=>{Ke&&A(oS())}).finally(()=>{Ke&&E(!1)}),()=>{Ke=!1}):(A(oS()),E(!1),P(""),()=>{Ke=!1})},[e?.id,F,z,We]),d.useEffect(()=>mp({description:st?.copy||pt,image:qR([ye]),imageAlt:Fe?`${ke} on Saveboard`:lb,title:st?.title?`${st.title} · Saveboard`:et,type:"profile",url:$t}),[ye,ke,st,Fe,pt,et,$t]);const gr=async()=>{if(!me||y)return;if(P(""),!te){Ft("/account");return}const Ke=I.viewerIsFollowing;N(!0);try{const ft=Ke?await Vk(We):await zk(We);if(!ft.ok){P(ft.error||(Ke?"Could not unfollow this profile.":"Could not follow this profile."));return}if(ft.summary){A(iS(ft.summary));return}E(!0);const lr=await Ym(We);A(iS(lr))}catch{P(Ke?"Could not unfollow this profile.":"Could not follow this profile.")}finally{N(!1),E(!1)}};if(st)return n.jsx(zm,{actionHref:st.actionHref,actionLabel:st.actionLabel,copy:st.copy,eyebrow:st.eyebrow,monochromeEnabled:i,theme:C,title:st.title});const Xt=[de,ht?`Joined ${ht}`:""].filter(Boolean).join(" · "),fn=re==="saves"&&Ee.length>0;return n.jsxs("main",{className:`publicSharePage publicProfilePage${r?" isLocalProfilePreview":""}${i?" monochromeMode":""}`,"data-app-theme":"v2","data-theme":C,children:[r?n.jsx("button",{className:"publicProfileBackLink publicProfileBackButton v2ProfileBackButton",onClick:()=>Ft("/account"),type:"button",children:"Back to profile"}):null,n.jsxs("div",{className:"v2ProfileFrame",children:[n.jsxs("header",{className:"v2ProfileIdentity",children:[n.jsxs("div",{className:"v2ProfileIdentityMain",children:[n.jsx("div",{"aria-hidden":"true",className:`accountProfileAvatar v2ProfileAvatar${ye?" hasPhoto":""}`,children:ye?n.jsx("img",{alt:"",decoding:"async",fetchPriority:"high",loading:"eager",src:ye,style:ge}):n.jsx("span",{className:"v2ProfileAvatarInitials",children:Re})}),n.jsxs("div",{className:"v2ProfileNameBlock",children:[n.jsx("h1",{children:ke}),n.jsx("span",{className:"v2ProfileHandle",children:Xt}),n.jsx("p",{className:"v2ProfileBio",children:pe})]})]}),n.jsxs("div",{className:"v2ProfileActions",children:[n.jsx("button",{className:"v2ProfileShareButton",onClick:en,type:"button",children:D?"Link copied":"Share profile"}),me?n.jsx("button",{className:`v2ProfileFollowButton${I.viewerIsFollowing?" isFollowing":""}`,disabled:Ae,onClick:gr,type:"button",children:ie}):null]})]}),_?n.jsx("p",{className:"v2ProfileFollowMessage",role:"alert",children:_}):null,r?n.jsx("p",{className:"v2ProfilePreviewNote",children:"Preview only — this shows your boards as they would look once published."}):null,n.jsxs("div",{"aria-label":"Profile stats",className:"v2ProfileStats",children:[n.jsxs("span",{className:"v2ProfileStat",children:[n.jsx("strong",{children:kt.toLocaleStr
32ing()}),n.jsx("span",{children:kt===1?"save":"saves"})]}),n.jsxs("span",{className:"v2ProfileStat",children:[n.jsx("strong",{children:ze.length}),n.jsx("span",{children:ze.length===1?"board":"boards"})]}),xe?n.jsxs(n.Fragment,{children:[n.jsxs("button",{"aria-label":`View followers · ${Qe}`,className:"v2ProfileStat v2ProfileStatAction",disabled:!Ct,onClick:()=>L("followers"),type:"button",children:[n.jsx("strong",{children:Qe}),n.jsx("span",{children:!k&&Number(I.followersCount)===1?"follower":"followers"})]}),n.jsxs("button",{"aria-label":`View following · ${Pe}`,className:"v2ProfileStat v2ProfileStatAction",disabled:!Ct,onClick:()=>L("following"),type:"button",children:[n.jsx("strong",{children:Pe}),n.jsx("span",{children:"following"})]})]}):null]}),V?n.jsx(UL,{kind:V,onClose:()=>L(""),onFollowStateChange:()=>B(Ke=>Ke+1),onOpenProfile:nr,profileUsername:We}):null,n.jsxs("div",{"aria-label":"Profile content",className:"v2ProfileTabs",children:[n.jsxs("button",{"aria-pressed":!fn,className:`v2ProfileTab${fn?"":" isActive"}`,onClick:()=>Z("boards"),type:"button",children:["Public boards · ",ze.length]}),Ee.length?n.jsxs("button",{"aria-pressed":fn,className:`v2ProfileTab${fn?" isActive":""}`,onClick:()=>Z("saves"),type:"button",children:["Recent saves · ",Ee.length]}):null]}),fn?n.jsx("div",{className:"v2ProfileSavesGrid",children:Ee.map(({boardHref:Ke,product:ft})=>{const lr=KR(ft),Wr=String(ft.price||"").trim(),Dr=Nf(ft),kr=n.jsxs(n.Fragment,{children:[n.jsx("span",{"aria-hidden":"true",className:"itemTileCover",children:n.jsx(Ms,{alt:"",decoding:"async",loading:"lazy",source:kn(ft),alternateSources:zi(ft,kn(ft)),fallbackSource:jn})}),n.jsx("div",{className:"v2ProfileSaveDetails itemTileCaption",children:n.jsx("span",{className:"v2ProfileSaveTitle itemTileName",children:lr})}),n.jsxs("div",{className:"itemTileMeta",children:[n.jsx("span",{className:"v2ProfileSaveSource itemTileSource",children:Dr}),Wr?n.jsx("span",{className:"v2ProfileSavePrice itemTilePrice",children:Wr}):null]})]});return r||!Ke?n.jsx("article",{className:"v2ProfileSaveCard itemTile",children:kr},ft.id):n.jsx("a",{"aria-label":lr,className:"v2ProfileSaveCard itemTile",href:Ke,children:kr},ft.id)})}):W.length?n.jsx("section",{"aria-label":"Public boards",className:"publicProfileBoards",style:J,children:W.map((Ke,ft)=>n.jsx(Cq,{authUser:e,board:Ke,index:ft,ownerHandle:Ix(We),readOnly:r},Ke.id))}):n.jsx(jx,{actionHref:r?"/account":"",actionLabel:r?"Back to profile":"",copy:h||Tt,eyebrow:"Public boards",title:h?"Public boards unavailable":"No public boards yet."}),Fe&&!fe?n.jsx(ML,{authUser:e,onSubmitReport:c,targetId:We,targetOwnerUsername:We,targetType:"profile"}):null,r?n.jsxs("div",{className:"publicShareMasthead v2ProfileMasthead",children:[n.jsx("span",{children:"Preview only"}),n.jsx(Ol,{className:"publicShareBrand",trademark:!1})]}):null]})]})}function kq({boardId:e,isUnlistedShare:t=!1,lookupError:r,lookupIsLoading:a,monochromeEnabled:s,authUser:o,onSubmitReport:i,publicBoardItems:c=[],publicBoardItemsError:l="",publicBoards:u=[],publicProfile:p,profileUsername:m,theme:f}){const h=Oi(p?.username||m),b=u.find(V=>String(V.id||"")===String(e||""))||null,v=!!(t||b?.isUnlistedShare),S=p?.display_name?.trim()||"Saveboard user",C=`@${h}`,I=Yo(h),A=J4({profile:p}),k=b?.name||"This board is not available.",E=b?.description||`A ${v?"shared":"public"} Saveboard board by ${S}.`,y=c.map(V=>V.imageUrl||V.sourceImage||V.image||"").find(Boolean)||A?.avatarUrl||"";c.length;const N=a?{copy:"One moment while this board loads.",title:"Loading board..."}:r?{copy:"We could not load this board. Try again in a moment.",title:"Something went wrong"}:!p||!b?{copy:"This board is not available.",title:"This board is not available."}:null;if(d.useEffect(()=>mp({description:N?.copy||E,image:qR([y]),imageAlt:lb,title:N?.title?`${N.title} · Saveboard`:`${k} (${C}) · Saveboard`,type:"profile",url:Qa(jc(h,e))}),[E,e,k,C,y,N,h]),a)return n.jsx(Y4,{monochromeEnabled:s,theme:f});if(N)return n.jsx(zm,{actionHref:v?"/":I,actionLabel:v?"Open Saveboard":"Back to profile",boardBranding:!0,copy:N.copy,monochromeEnabled:s,theme:f,title:N.title});
32const P=B4({description:E,emptyCopy:l||(v?"No shared items yet.":"No public items yet."),emptyEyebrow:l?"Saved items":"Empty board",emptyTitle:l?"Saved items unavailable":v?"No shared items yet":"No public items yet",itemAriaLabel:v?"Shared board saved items":"Public board saved items",items:c.map(V=>L4(V,{canReport:!v})),owner:A,title:k});return n.jsx(K4,{authUser:o,headerActions:v?null:n.jsxs(n.Fragment,{children:[n.jsx(OL,{hideWhenZero:!0,authUser:o,boardId:b.id,boardTitle:k,initialLikeCount:b.likeCount,labelPrefix:""}),n.jsx(ML,{label:"Report board",variant:"header",authUser:o,onSubmitReport:i,targetId:b.id,targetOwnerUsername:h,targetType:"board"})]}),headerLeading:v?null:n.jsx("a",{"aria-label":`Back to ${C}`,className:"publicProfileBackLink",href:I,children:"← Profile"}),monochromeEnabled:s,onSubmitReport:i,ownerUsername:h,theme:f,viewModel:P})}function Nq({auth:e}){const[t,r]=d.useState("checking"),[a,s]=d.useState([]),[o,i]=d.useState(""),[c,l]=d.useState(""),[u,p]=d.useState(""),[m,f]=d.useState(""),[h,b]=d.useState(""),v=!!e.user?.id,S=d.useCallback(async()=>{if(i(""),l(""),!v){r("signed-out"),s([]);return}if(r("checking"),!(await e.checkReportAdminAccess?.())?.isAdmin){r("denied"),s([]);return}r("admin");const k=await e.fetchContentReports?.();if(k?.error){s([]),i(k.error);return}s(Array.isArray(k?.reports)?k.reports:[])},[e,v]);d.useEffect(()=>{let A=!0;return(async()=>await S())(),()=>{A=!1}},[S]);const C=async(A,k)=>{i(""),l(""),p(""),b(A);const E=await e.updateContentReportStatus?.({reportId:A,status:k});if(b(""),E?.error){i(E.error);return}E?.report?s(y=>y.map(N=>N.id===E.report.id?E.report:N)):await S(),l("Report status updated.")},I=async(A,{confirmed:k=!1}={})=>{const E=Z_[A?.targetType]||null;if(!A?.id||!E){i("Could not apply moderation action.");return}if(!k){i(""),l(""),p(A.id);return}i(""),l(""),p(""),f(A.id);const y=await e.applyContentReportModerationAction?.({action:E.action,reportId:A.id});if(f(""),y?.error){i(y.error);return}y?.report?s(N=>N.map(_=>_.id===y.report.id?y.report:_)):await S(),l("Moderation action applied.")};return t==="signed-out"?n.jsx("main",{className:"adminReportsPage",children:n.jsxs("header",{className:"accountHeader",children:[n.jsx("button",{onClick:()=>Ft("/account"),type:"button",children:"Go to Account"}),n.jsx("p",{children:"Admin"}),n.jsx("h1",{children:"Sign in required"}),n.jsx("span",{children:"Sign in with an admin account to review reports."})]})}):t==="denied"?n.jsx("main",{className:"adminReportsPage",children:n.jsxs("header",{className:"accountHeader",children:[n.jsx("button",{onClick:()=>Ft("/"),type:"button",children:"Back to Saveboard"}),n.jsx("p",{children:"Admin"}),n.jsx("h1",{children:"Not available"}),n.jsx("span",{children:"You do not have access to this page."})]})}):n.jsxs("main",{className:"adminReportsPage",children:[n.jsxs("header",{className:"accountHeader",children:[n.jsx("button",{onClick:()=>Ft("/"),type:"button",children:"Back to Saveboard"}),n.jsx("p",{children:"Admin"}),n.jsx("h1",{children:"Content reports"}),t==="admin"?n.jsx("a",{href:"/admin/discover",children:"Manage Discover"}):null,n.jsx("span",{children:"Review public profile, board, and item reports."})]}),t==="checking"?n.jsx("section",{className:"adminReportsState","aria-label":"Reports loading",children:n.jsx("p",{children:"Checking access..."})}):o?n.jsxs("section",{className:"adminReportsState","aria-label":"Reports unavailable",children:[n.jsx("p",{children:o}),n.jsx("button",{onClick:S,type:"button",children:"Try again"})]}):n.jsxs("section",{className:"adminReportsPanel","aria-label":"Submitted reports",children:[n.jsxs("div",{className:"adminReportsToolbar",children:[n.jsx("span",{children:oa(a.length,"report","reports")}),n.jsx("button",{onClick:S,type:"button",children:"Refresh"})]}),c?n.jsx("p",{className:"adminReportsMessage",role:"status",children:c}):null,a.length?n.jsx("div",{className:"adminReportsList",children:a.map(A=>{const k=vs(A.createdAt)||"Recently",E=xq[A.reason]||"Other",y=Iq[A.status]||A.status||"New",N=_q(A.targetType||"report"),_=A.targetOwnerUsername?`@${A.targetOwnerUsername}`:"No owner username",P=Z_[A.targetType]||null,V=u===A.id;return n.jsxs("article",{className:"adminReportCard",children:[n.jsxs("div",{className:"adminReportMeta",children:[n.jsx("span",{children:k}),n.jsx("span",{children:N}),n.jsx("span",{children:y})]}),n.jsx("h2",{children:E}),n.jsxs("dl",{children:[n.jsxs("div",{children:[n.jsx("dt",{children:"Target"}),n.jsx("dd",{children:A.targetId||"Unknown"})]}),n.jsxs("div",{children:[n.jsx("dt",{children:"Owner"}),n.jsx("dd",{children:_})]}),n.jsxs("div",{children:[n.jsx("dt",{children:"Details"}),n.jsx("dd",{children:A.details||"No details provided."})]})]}),P?n.jsx("div",{className:"adminReportActions adminReportModerationActions",children:V?n.jsxs(n.Fragment,{children:[n.jsx("span",{children:P.confirm}),n.jsx("button",{disabled:m===A.id,onClick:()=>I(A,{confirmed:!0}),type:"button",children:"Confirm"}),n.jsx("button",{disabled:m===A.id,onClick:()=>p(""),type:"button",children:"Cancel"})]}):n.jsx("button",{disabled:m===A.id||A.status==="actioned",onClick:()=>I(A),type:"button",children:m===A.id?"Applying...":P.label})}):null,n.jsx("div",{className:"adminReportActions",children:Aq.map(L=>n.jsx("button",{disabled:h===A.id||m===A.id||A.status===L.value,onClick:()=>C(A.id,L.value),type:"button",children:h===A.id?"Updating...":L.label},L.value))})]},A.id)})}):n.jsx("div",{className:"adminReportsState","aria-label":"No reports",children:n.jsx("p",{children:"No reports yet."})})]})]})}const jq=(e={})=>{const t=e?.created_at||e?.createdAt||"",r=new Date(t);return!t||Number.isNaN(r.getTime())?"Joined recently":`Joined ${r.toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"})}`},rE=(e,t,r)=>{const a=Pc(e);return a?`${t} ${a}`:r},FL=(e="")=>e==="pre_restore_safety"?"Safety backup":e==="imported"?"Imported backup":e==="legacy"?"Legacy backup":"Manual backup",Rq=(e={})=>e.snapshotType==="pre_restore_safety"?"Delete this safety backup?":"Delete this account backup?",Lq=(e={})=>e.snapshotType==="pre_restore_safety"?"This only removes the saved recovery copy. Your current boards are unchanged.":"Deleting this account backup does not delete boards on this browser. This removes only the selected cloud backup.",Bq=(e="")=>e==="older-schema"?"This backup was created with an older data format. Saveboard will add safe defaults where possible.":e==="newer-schema"?"This backup was created with a newer data format and cannot be restored here.":e==="empty-backup"?"This backup has no products.":e==="missing-lists"||e==="missing-products"||e==="missing-settings"||e==="missing-board-data"?"This backup looks incomplete.":e==="invalid-payload"||e==="unknown-schema"?"This backup could not be read.":"",Tq=(e="")=>{const t=new URLSearchParams(e||""),r=t.get("checkout"),a=t.get("billing");return r==="success"?{tone:"success",text:"Checkout completed. Your plan will update once payment is confirmed."}:r==="cancelled"?{tone:"neutral",text:"Checkout cancelled. Your plan was not changed."}:a==="returned"?{tone:"neutral",text:"Returned from billing. Your plan will update once Stripe confirms any changes."}:null},Dq=({billingProfile:e,isLoading:t=!1})=>{if(t)return"Checking plan...";if(!e)return"Free limits are shown until Premium is confirmed.";const r=nf(e.subscription_status||e.subscriptionStatus),a=e.current_period_end||e.currentPeriodEnd,s=Pc(a);return $b(e)?e.cancel_at_period_end||e.cancelAtPeriodEnd?s?`Premium active until ${s}.`:"Premium remains active until the current billing period ends.":r===na.TRIALING?"Trial active.":"Premium active.":r===na.PAST_DUE||r===na.UNPAID||r===na.INCOMPLETE||r===na.INCOMPLETE_EXPIRED?"Billing needs attention. Local price history is still available.":r===na.CANCELED?"Subscription ended. Free limits are shown.":"Free limits are shown until Premium is confirmed."}
32,Oq=({billingProfile:e,isLoading:t=!1})=>{if(t)return"Checking";if($b(e))return"Premium";const r=nf(e?.subscription_status||e?.subscriptionStatus);return r===na.PAST_DUE||r===na.UNPAID||r===na.INCOMPLETE||r===na.INCOMPLETE_EXPIRED?"Attention":"Free"},Mq=e=>{const t=nf(e?.subscription_status||e?.subscriptionStatus);return t===na.PAST_DUE||t===na.UNPAID||t===na.INCOMPLETE||t===na.INCOMPLETE_EXPIRED};function Uq({isRestoring:e,onCancel:t,onConfirm:r}){return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"cloud-restore-title","aria-modal":"true",className:"deleteProductModal accountCloudRestoreModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"cloud-restore-title",children:"Restore from account?"})}),n.jsx("p",{children:"This replaces the Saveboard data currently saved in this browser with your saved account backup. Before restoring, Saveboard will save a safety backup of this browser so you can recover it later."}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{disabled:e,onClick:r,type:"button",children:e?"Restoring...":"Restore from account"}),n.jsx("button",{disabled:e,onClick:t,type:"button",children:"Cancel"})]})]})})}function Fq({isDeleting:e,onCancel:t,onConfirm:r,snapshot:a}){if(!a)return null;const s=Pc(a.updatedAt||a.createdAt),o=`${oa(a.productCount,"product","products")} · ${oa(a.listCount,"board","boards")}`;return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"account-snapshot-delete-title","aria-modal":"true",className:"deleteProductModal accountSnapshotDeleteModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"account-snapshot-delete-title",children:Rq(a)})}),n.jsx("p",{children:Lq(a)}),n.jsxs("p",{children:[a.deviceLabel||"This browser"," · ",FL(a.snapshotType),s?` · ${s}`:""," · ",o]}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{disabled:e,onClick:r,type:"button",children:e?"Deleting...":"Delete backup"}),n.jsx("button",{disabled:e,onClick:t,type:"button",children:"Cancel"})]})]})})}function $q({currentSummary:e,isRestoring:t,onCancel:r,onConfirm:a,preview:s}){if(!s?.snapshot||!s?.summary)return null;const{snapshot:o,summary:i,validationError:c=""}=s,l=Pc(i.backedUpAt||i.exportedAt||o.updatedAt||o.createdAt),u=`${oa(i.listCount,"board","boards")} · ${oa(i.productCount,"product","products")}`,p=Kw(e),m=i.productWithPricesCount>0||i.productWithTrackingCount>0,f=i.productWithAvailabilityCount>0,h=[...new Set(i.warnings||[])].map(Bq).filter(Boolean),b=t||!i.isValid||!!c||h.includes("This backup could not be read.");return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"account-snapshot-restore-title","aria-modal":"true",className:"deleteProductModal accountSnapshotRestoreModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"account-snapshot-restore-title",children:"Restore this backup?"})}),n.jsxs("div",{className:"accountRestorePreview",children:[n.jsxs("section",{"aria-label":"Selected backup",children:[n.jsx("span",{children:"Backup"}),n.jsx("strong",{children:o.deviceLabel||"This browser"}),n.jsxs("p",{children:[FL(o.snapshotType),l?` · ${l}`:""," · ",u]})]}),n.jsxs("section",{"aria-label":"Backup contents",children:[n.jsx("span",{children:"Contains"}),n.jsxs("p",{children:[i.hasSettings?"Includes settings":"Settings missing"," ·"," ",m?"Includes price history/tracking data":"No price tracking data detected"]}),n.jsx("p",{children:f?"Includes availability data":"No availability data detected"}),n.jsxs("p",{children:[oa(i.archivedCount,"archived product","archived products")," ·"," ",oa(i.purchasedCount,"purchased product","purchased products")]})]}),n.jsxs("section",{"aria-label":"Current browser",children:[n.jsx("span",{children:"This will replace"}),n.jsx("p",{children:"The boards and products on this browser."}),n.jsxs("p",{children:["Current browser: ",p]})]}),n.jsxs("section",{"aria-label":"Restore safety",children:[n.jsx("span",{children:"Safety"}),n.jsx("p",{children:"Saveboard will create a safety backup of this browser before restoring."}),n.jsx("p",{children:"This does not turn on automatic sync."})]}),c||h.length?n.jsxs("div",{className:"accountRestoreWarnings","aria-label":"Backup warnings",children:[c?n.jsx("p",{children:c}
32):null,h.map(v=>n.jsx("p",{children:v},v))]}):null]}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{disabled:b,onClick:a,type:"button",children:t?"Restoring...":"Restore this backup"}),n.jsx("button",{disabled:t,onClick:r,type:"button",children:"Cancel"})]})]})})}function zq({intent:e="visibility",isSaving:t=!1,nextVisibility:r="",onCancel:a,onConfirm:s}){const i=yl(r)==="public",c=e==="deactivation"&&!i,l=c?"Deactivate public profile?":i?"Make profile public?":"Make profile private?",u=c?"Your public profile and public board pages will be hidden. Existing private share links and collaborator access will still work. Your saved items and account will not be deleted.":i?"People will be able to view your username, display name, avatar, bio and public boards. Public pages may appear in Discover, search results and link previews. Private boards are not listed; existing private share links and collaborator access are separate.":"Your public profile and public board pages will be hidden. Existing private share links and collaborator access will still work. You can make your profile public again later.",p=i?"Keep private":"Keep public",m=t?"Saving...":c?"Deactivate profile":i?"Make public":"Make private";return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"profile-visibility-confirm-title","aria-modal":"true",className:"deleteProductModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"profile-visibility-confirm-title",children:l})}),n.jsx("p",{children:u}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{disabled:t,onClick:a,type:"button",children:p}),n.jsx("button",{disabled:t,onClick:s,type:"button",children:m})]})]})})}function Vq({clearLocalData:e=!1,confirmationValue:t="",error:r="",isDeleting:a=!1,onCancel:s,onClearLocalDataChange:o,onConfirm:i,onConfirmationChange:c}){const l=t==="DELETE";return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"account-cloud-delete-title","aria-modal":"true",className:"deleteProductModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"account-cloud-delete-title",children:"Delete cloud account?"})}),n.jsx("p",{children:"This will permanently delete your SaveBoard account and the application data you own, including your boards, saved items, account backups and avatar. Your profile and board links will stop working. This cannot be undone."}),n.jsxs("p",{children:["Items you contributed to someone else’s board, copies made by others, and provider backups and operational logs are separate. Local app data is kept unless you choose to reset it below. Extension storage and other devices are not cleared. Export first if you want a copy. See our ",n.jsx("a",{href:_d,children:"Privacy Policy"}),"."]}),n.jsxs("div",{className:"accountDeletionModalFields",children:[n.jsxs("label",{children:[n.jsx("span",{children:"Type DELETE to confirm"}),n.jsx("input",{autoComplete:"off",disabled:a,onChange:u=>c(u.target.value),spellCheck:"false",type:"text",value:t})]}),n.jsxs("label",{className:"accountDeletionCheckbox",children:[n.jsx("input",{checked:e,disabled:a,onChange:u=>o(u.target.checked),type:"checkbox"}),n.jsx("span",{children:"Also reset this browser’s local SaveBoard app data after account deletion succeeds."})]})]}),r?n.jsx("p",{className:"accountStatusMessage isError",children:r}):null,n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{className:"accountDangerButton",disabled:!l||a,onClick:i,type:"button",children:a?"Deleting...":"Delete account"}),n.jsx("button",{disabled:a,onClick:s,type:"button",children:"Cancel"})]})]})})}const Hq=({authIsUnavailable:e=!1,browserIsOffline:t=!1,currentMode:r="",enabled:a=!1,lastSyncedAt:s=null,signedInEmail:o="",syncDescription:i="",syncHasError:c=!1,syncIsRunning:l=!1,syncIsSynced:u=!1,syncNeedsAttention:p=!1}={})=>a?o?t?{badge:"Offline",canSync:!1,description:i||"Offline — changes are saved on this device.",label:"Offline",lastSyncedAt:null,reason:"offline",state:"offline",tone
32:"warning"}:e?{badge:"Unavailable",canSync:!1,description:i||"Sync is not available in this app configuration.",label:"Sync unavailable",lastSyncedAt:null,reason:"auth-unavailable",state:"error",tone:"warning"}:r!=="personal"?{badge:"Local",canSync:!1,description:i||"This browser is in local-only mode.",label:"Local-only mode",lastSyncedAt:null,reason:"local-only",state:"local-only",tone:"neutral"}:l?{badge:"Syncing",canSync:!1,description:i||"Syncing...",label:"Syncing",lastSyncedAt:null,reason:"syncing",state:"syncing",tone:"active"}:c?{badge:"Retry",canSync:!0,description:i||"Sync could not complete. Your local changes are still saved.",label:"Sync needs a retry",lastSyncedAt:null,reason:"error",state:"error",tone:"warning"}:p?{badge:"Review",canSync:!0,description:i||"Some changes need attention. Your data was not overwritten.",label:"Needs attention",lastSyncedAt:null,reason:"needs-attention",state:"needs-attention",tone:"warning"}:u?{badge:"Synced",canSync:!0,description:i||"Synced just now.",label:"Synced",lastSyncedAt:s,reason:"recent-sync",state:"synced",tone:"success"}:{badge:"Ready",canSync:!0,description:"Ready to sync across signed-in devices.",label:"Ready to sync",lastSyncedAt:null,reason:"idle",state:"idle",tone:"neutral"}:{badge:"Off",canSync:!1,description:i||"Sign in to sync boards across devices.",label:"Sign in to sync",lastSyncedAt:null,reason:"signed-out",state:"signed-out",tone:"neutral"}:null,fc=Object.freeze({conflict:"Some changes need review before they can sync safely.",deletedItems:"Some deleted items need review. Your data was not overwritten.",error:"Sync could not complete. Your local changes are still saved.",needsAttention:"Some changes need attention. Your data was not overwritten.",noChanges:"Synced just now. No new changes found.",offline:"Offline — changes are saved on this device.",partial:"Some changes synced. A few still need review.",pulledChanges:"Synced just now. Pulled new changes from your account.",reviewBoards:"Some board changes need review. Your data was not overwritten."}),Wq=e=>{const t=Number(e);return Number.isFinite(t)&&t>0?t:0},dl=(...e)=>e.reduce((t,r)=>t+Wq(r),0),dS=(e=[],t=[])=>e.some(r=>{const a=String(r||"").toLowerCase();return t.some(s=>a.includes(s))}),uS=({offline:e=!1,result:t=null,thrown:r=!1}={})=>{if(e)return{message:fc.offline,state:"offline"};if(r||!t)return{message:fc.error,state:"error"};const a=t.warnings||[],s=t.finalDryRun||{},o=t.preview||{},i=t.conflicts||{},c=dl(t.added?.boards,t.added?.products,t.boardCount,t.productCount),l=dl(t.updated?.boards,t.updated?.products),u=c+l,p=dl(t.ignoredBoardTombstones,t.cloud?.boardTombstones,s.cloud?.boardTombstones,o.boards?.cloudTombstones),m=dl(t.ignoredProductTombstones,t.cloud?.productTombstones,s.cloud?.productTombstones,o.products?.cloudTombstones),f=dl(s.tombstoneConflicts?.localBoardsConflictingWithCloudTombstones,s.tombstoneConflicts?.localProductsConflictingWithCloudTombstones,o.boards?.localMatchingCloudTombstones,o.products?.localSuppressedByCloudTombstones),h=dl(s.relationships?.mismatches,s.status?.mismatches,s.visibility?.mismatches,s.ordering?.mismatches,o.relationships?.missingBoardIssues),b=dl(i.equalTimestampConflicts,i.missingTimestampConflicts),v=dl(i.missingBoardProductUpdates,t.skippedProductsMissingBoard),S=dS(a,["tombstone","deleted","delete"]),C=dS(a,["board tombstone","board changes"]),I=dS(a,["timestamp","relationship","missing board","need review","conflict"]);return!!t.blocked||a.length>0||p>0||m>0||f>0||h>0||b>0||v>0?u>0?{message:fc.partial,state:"needs-attention"}:m>0||f>0||S?{message:fc.deletedItems,state:"needs-attention"}:p>0||C?{message:fc.reviewBoards,state:"needs-attention"}:h>0||b>0||v>0||I?{message:fc.conflict,state:"needs-attention"}:{message:fc.needsAttention,state:"needs-attention"}:{message:u>0?fc.pulledChanges:fc.noChanges,state:"synced"}};function Gq({publicItemPublishStateByBoardId:e,setPublicItemPublishStateByBoardId:t,setPublicItemPublishStateForBoard:r,accountLocalDataNotice:a=null,auth:s,backupError:o,backupMessage:i,cloudBackupState:c,cloudHydrationState:l,locationSearch:u,lists:p,localDataSummary:m,mode:f,onBackToDashboard:h,onClearLocalData:b,onCloudBackup:v,onCloudBootstrapUpload:S,onExportBackup:C,onImportBackup:I,onImportLocalBoardsToAccount:A,onSelectList:k,onOpenSharedBoard:E,onBoardPublished:y,onKeepLocalBoardsSeparate:N,onCloudRestore:_,onShareBoard:P,onSnapshotRestore:V,onSyncCloudNewerPull:L,onSyncDryRun:z,onSyncPopulatedPull:B,onToggleBoardVisibility:re,onValidateSnapshotBackup:Z,products:D,onRefreshCloudStatus:K,trueSyncBoardPilotState:ee=null,trueSyncBoardWriteThroughEnabled:J=!1,trueSyncCloudNewerPullEnabled:fe=!1,trueSyncDryRunEnabled:De=!1,trueSyncEmptyPullEnabled:Be=!1,trueSyncManualBetaEnabled:Fe=!1,trueSyncNowQaEnabled:ke=!1,trueSyncPopulatedPullEnabled:We=!1,trueSyncPullMergePreviewEnabled:de=!1,trueSyncProductPilotState:ye=null,trueSyncProductTomb
32stoneEnabled:ge=!1,trueSyncProductWriteThroughEnabled:ze=!1,trueSyncStatusModelEnabled:W=!1,onSyncEmptyPull:Le,onSyncNow:et,onSyncPullMergePreview:pt}){const[$t,pe]=d.useState("create"),Tt=fp(),F=d.useMemo(()=>({"--standard-board-card-width":Cl(Ja,Tt).podWidth}),[Tt]),[te,me]=d.useState(""),[ie,Ae]=d.useState(""),[Re,ne]=d.useState(!1),[ht,kt]=d.useState(!1),[Ee,xe]=d.useState(""),[Qe,Pe]=d.useState(""),[Ct,nr]=d.useState(""),[en,st]=d.useState(""),[gr,Xt]=d.useState(!1),[fn,Ke]=d.useState(!1),[ft,lr]=d.useState(!1),[Wr,Dr]=d.useState(""),[kr,Gr]=d.useState(""),[ar,qr]=d.useState(""),[tn,hn]=d.useState("private"),[Wn,br]=d.useState(""),[rn,nn]=d.useState("visibility"),[Pn,G]=d.useState(""),[se,le]=d.useState(""),[ue,Ne]=d.useState(""),[be,Te]=d.useState({status:"idle",message:""}),[Ve,at]=d.useState(""),[yt,tt]=d.useState(""),[He,Ge]=d.useState(!1),[Xe,Dt]=d.useState(!1),[jt,Zt]=d.useState(()=>ps(Kh)),[xt,Gt]=d.useState(!1),[Or,Yt]=d.useState(!1),[er,x]=d.useState(!1),[$,O]=d.useState(!1),[q,X]=d.useState(""),[Se,he]=d.useState(""),[$e,Oe]=d.useState(!1),[Pt,mt]=d.useState(""),[Kt,rt]=d.useState(""),[St,_t]=d.useState(!1),[dr,tr]=d.useState(!1),[yr,Sr]=d.useState(!1),[wr,Mn]=d.useState(null),[fr,Cr]=d.useState(""),[po,ca]=d.useState(""),[mo,rs]=d.useState(""),[$s,ce]=d.useState(null),[oe,gt]=d.useState(!1),[wt,It]=d.useState(null),[or,Yr]=d.useState(""),[qt,Ir]=d.useState(""),[Fr,gn]=d.useState(!1),[Vt,fo]=d.useState(null),[Dc,Oc]=d.useState(""),[ho,Ua]=d.useState(""),[Gn,Vi]=d.useState(!1),[Ze,H]=d.useState(null),[ve,Je]=d.useState(""),[lt,Et]=d.useState(""),[ur,on]=d.useState(!1),[Lt,Sa]=d.useState(null),[Fa,qn]=d.useState(""),[_n,go]=d.useState(""),[bo,ys]=d.useState(!1),[an,ns]=d.useState(null),[Zn,Hi]=d.useState(""),[as,Td]=d.useState(""),[zs,hp]=d.useState(!1),[wn,Wi]=d.useState(null),[vo,la]=d.useState(""),[ea,yo]=d.useState(""),[$a,da]=d.useState(""),[Mc,bn]=d.useState(""),[Gi,gp]=d.useState(!1),[Dd,bp]=d.useState(!1),[Od,Uc]=d.useState(!1),[vp,Xo]=d.use
32State(!1),[Jo,So]=d.useState(""),[Ml,Fc]=d.useState(""),[Vs,Hs]=d.useState(!1),[$c,wo]=d.useState(""),[wa,qi]=d.useState(!1),[zc,Ws]=d.useState(!1),[av,Cn]=d.useState(""),[sv,Yi]=d.useState([]),[ov,Un]=d.useState(!1),[Lf,Co]=d.useState(!1),[Md,ua]=d.useState(""),[xo,Gs]=d.useState(""),[Ki,Vc]=d.useState(""),[Hc,Ud]=d.useState(""),[Ul,iv]=d.useState(!1),[Xi,Fd]=d.useState(null),[Fl,Yn]=d.useState(!1),[At,Ji]=d.useState(null),[yp,$l]=d.useState(""),[Ca,$d]=d.useState(!1),[Ss,zl]=d.useState("boards"),[$r,pa]=d.useState(()=>({boards:[],viewerId:""})),[qs,Wc]=d.useState(!1),[Nr,cn]=d.useState(""),[Qi,Gc]=d.useState(()=>({followersCount:0,followingCount:0})),[Io,ss]=d.useState(!1),[Bf,zd]=d.useState(""),[cv,Ao]=d.useState(0),[ws,Vl]=d.useState(null),[Tf,Qo]=d.useState(!1),[Zo,Zi]=d.useState(!1),[Sp,wp]=d.useState(""),[Df,os]=d.useState(""),[Po,Of]=d.useState(""),[Tx,Ie]=d.useState(!1),[Ea,lv]=d.useState(!1),Hl=d.useRef(null),qc=d.useRef(null),ei=d.useRef(null),Jt=d.useRef(null),jr=d.useRef(null),Kr=d.useRef(0),Vd=d.useRef(0),ec=d.useRef(null),vr=s.user?.email||s.user?.user_metadata?.email||"",Qt=s.user?.id||"",ma=$r.viewerId===Qt?$r.boards:[],En=d.useMemo(()=>RL(s.user,vr),[s.user?.email,s.user?.id,vr]),tc=d.useMemo(()=>pq(s.user,vr),[s.user?.email,s.user?.id,vr]),_o=s.profile||null,ln=dq(s.user,_o),is=ln||Ve||"",Wl=NL(s.user,_o),Yc=Lx(s.user,vr,_o),Cs=ln?`@${ln}`:Yc,Cp=ln?Yc:"Choose your username",ti=String(_o?.bio||"").trim(),Kn=yl(_o?.profile_visibility||_o?.profileVisibility),xp=Kn==="public"?"Public profile":"Private profile",Eo=Kn==="public"?"private":"public",Mf=Kn==="public"?"Change profile to private":"Change profile to public",Ys=!s.isConfigured,ko=!!(!Ys&&s.user?.id),xa=!!(Kn==="public"&&ln),Ip=ln?Yo(ln):"",Kc=Kn!=="public"?"Set your profile to Public to share it.":ln?"Your public profile is live. Only public boards appear there.":"Choose a username before sharing your profile.";ko&&s.fetchOwnerPublicBoardItems&&s.syncPublicBoardItemMetadata&&s.syncPublicBoardMetadata;const Uf=cp(_o),cs=ko?Uf:yt===gg?"":yt||Uf,za=ps(_o),uv=Bx(xt?jt:za),rc=!!(Mm.profileAvatarEditingEnabled&&cs),ls=s.user?.created_at||s.user?.createdAt||"",Ap=new Date(ls),Va=ls&&!Number.isNaN(Ap.getTime())?`Joined ${Ap.getFullYear()}`:"Joined recently",pr=s.loading||s.profileLoading,No=Qe||s.authError;s.socialProviders?.google,s.socialProviders?.apple;const Gl=Rr.billingUiEnabled;Gl&&Tq(u),WC(ws||null);const Pp=$b(ws||null),vn=Mq(ws);Pp||ws?.plan,Dq({billingProfile:ws,isLoading:Tf||vr&&!Zo}),Oq({billingProfile:ws,isLoading:Tf||vr&&!Zo}),ws?.stripe_customer_id||ws?.stripeCustomerId;const ri=Mm.cloudAccountDeletionEnabled,Ia=Mm.profileAvatarEditingEnabled,ds=r2({local:m,cloud:c||{}}),_p=Pc(ds.cloud.latestUpdatedAt||c?.lastBackedUpAt),Ff=Pc(c?.lastRestoredAt),nc=Pc(c?.checkedAt),Aa=`Local browser: ${Kw(ds.local)} · ${rE(ds.local.latestUpdatedAt,"updated","no local updates yet")}`,$f=ds.cloud.known?ds.cloud.exists?`Cloud backup: ${Kw(ds.cloud)} · ${rE(ds.cloud.latestUpdatedAt,"backed up","backup time unknown")}`:"Cloud backup: No cloud backup yet.":"Cloud backup: Not checked yet.",Hd=ds.cloud.known?"Backup and restore are manual actions. Nothing changes unless you choose an action.":"Refresh status to compare this browser with cloud backup.",zf=l?.status==="empty"&&ds.cloud.exists?"":l?.message||l?.error||"",jo=["blocked","error"].includes(l?.status),fa=f==="personal",ni=fa&&l?.status==="local-upload-ready",Fn=fa&&l?.status==="cloud-and-local",ai=!!(yr||Fr||Gn||bo||oe||zs||ur||ee?.status==="syncing"||ye?.status==="syncing"),Xc=!!(po||$s?.state==="error"||ho||lt||as||qt||ea||_n||ee?.status==="error"||ye?.status==="error"),Rn=!!($s?.state==="needs-attention"||wr?.blocked||Lt?.blocked||wn?.blocked||an?.blocked||wt?.blocked||Lt?.warnings?.length||wn?.warnings?.length||an?.warnings?.length||wt?.warnings?.length),Vf=!!($s?.state==="synced"&&mo||Lt&&!Lt.blocked||wt&&!wt.blocked||an&&!an.blocked||Ze&&!Ze.blocked),si=Hq({authIsUnavailable:Ys,browserIsOffline:typeof navigator<"u"&&navigator.onLine===!1,currentMode:f,enabled:W,lastSyncedAt:mo||null,signedInEmail:vr,syncDescription:yr?"Syncing...":po||fr,syncHasError:Xc,syncIsRunning:ai,syncIsSynced:Vf,syncNeedsAttention:Rn}),Ep=si?.lastSyncedAt?`Last synced ${Pc(si.lastSyncedAt)}. Backup is a separate recovery copy.`:"Sync keeps signed-in devices up to date. Backup is a separate recovery copy.",kp=Vt?[`Local ${Vt.local.boards} boards / ${Vt.local.products} products`,`Cloud ${Vt.cloud.boards} boards / ${Vt.cloud.products} products`,`Cloud tombstones ${Vt.cloud.boardTombstones}
32 boards / ${Vt.cloud.productTombstones} products`,`Would create ${Vt.wouldCreate.boards} boards / ${Vt.wouldCreate.products} products`,`Would update ${Vt.wouldUpdate.boards} boards / ${Vt.wouldUpdate.products} products`,`Would tombstone later ${Vt.wouldTombstone.boards} boards / ${Vt.wouldTombstone.products} products`,`Tombstone conflicts ${Vt.tombstoneConflicts?.localBoardsConflictingWithCloudTombstones||0} boards / ${Vt.tombstoneConflicts?.localProductsConflictingWithCloudTombstones||0} products`,`${Vt.relationships.mismatches} relationship mismatches`,`${Vt.status.mismatches} status mismatches`,`${Vt.visibility.mismatches} visibility mismatches`,`${Vt.ordering.mismatches} ordering mismatches`,`Writes performed: ${Vt.writesPerformed}`]:[],Np=Ze?[`Pulled ${Ze.boardCount} boards / ${Ze.productCount} products`,`Ignored tombstones ${Ze.ignoredBoardTombstones} boards / ${Ze.ignoredProductTombstones} products`,`Skipped missing-board products ${Ze.skippedProductsMissingBoard}`,`Supabase writes performed: ${Ze.supabaseWritesPerformed}`]:[],Wd=an?[`Pulled ${an.boardCount} new boards / ${an.productCount} new products`,`Ignored tombstones ${an.ignoredBoardTombstones} boards / ${an.ignoredProductTombstones} products`,`Skipped missing-board products ${an.skippedProductsMissingBoard}`,`Safety snapshot saved: ${an.safetySnapshotSaved?"yes":"no"}`,`Supabase writes performed: ${an.supabaseWritesPerformed}`]:[],jp=wt?[`Updated ${wt.boardCount} boards / ${wt.productCount} products`,`Ignored tombstones ${wt.ignoredBoardTombstones} boards / ${wt.ignoredProductTombstones} products`,`Equal timestamp conflicts ${wt.conflicts?.equalTimestampConflicts||0}`,`Missing timestamp conflicts ${wt.conflicts?.missingTimestampConflicts||0}`,`Missing-board product updates ${wt.conflicts?.missingBoardProductUpdates||0}`,`Safety snapshot saved: ${wt.safetySnapshotSaved?"yes":"no"}`,`Supabase writes performed: ${wt.supabaseWritesPerformed}`]:[],Hf=wn?[`Local ${wn.boards.local} boards / ${wn.products.local} products`,`Cloud active ${wn.boards.cloudActive} boards / ${wn.products.cloudActive} products`,`Cloud tombstones ${wn.boards.cloudTombstones} boards / ${wn.products.cloudTombstones} products`,`Would add from cloud ${wn.boards.wouldAddFromCloud} boards / ${wn.products.wouldAddFromCloud} products`,`Would update from cloud ${wn.boards.wouldUpdateFromCloud} boards / ${wn.products.wouldUpdateFromCloud} products`,`Would keep local ${wn.boards.wouldKeepLocal} boards / ${wn.products.wouldKeepLocal} products`,`Would suppress local products ${wn.products.localSuppressedByCloudTombstones}`,`Board tombstones report-only ${wn.boards.localMatchingCloudTombstones}`,`Missing board relationship issues ${wn.relationships.missingBoardIssues}`,`Writes performed: ${wn.writesPerformed}`]:[],Gd=Lt?[`Preview would add ${Lt.preview?.boards?.wouldAddFromCloud||0} boards / ${Lt.preview?.products?.wouldAddFromCloud||0} products`,`Preview would update ${Lt.preview?.boards?.wouldUpdateFromCloud||0} boards / ${Lt.preview?.products?.wouldUpdateFromCloud||0} products`,`Added ${Lt.added?.boards||0} boards / ${Lt.added?.products||0} products`,`Updated ${Lt.updated?.boards||0} boards / ${Lt.updated?.products||0} products`,`Final would create ${Lt.finalDryRun?.wouldCreate?.boards||0} boards / ${Lt.finalDryRun?.wouldCreate?.products||0} products`,`Final would update ${Lt.finalDryRun?.wouldUpdate?.boards||0} boards / ${Lt.finalDryRun?.wouldUpdate?.products||0} products`,`Final mismatches ${Lt.finalDryRun?.relationships?.mismatches||0} relationships / ${Lt.finalDryRun?.status?.mismatches||0} status / ${Lt.finalDryRun?.visibility?.mismatches||0} visibility / ${Lt.finalDryRun?.ordering?.mismatches||0} ordering`,`Tombstone conflicts ${Lt.finalDryRun?.tombstoneConflicts?.localBoardsConflictingWithCloudTombstones||0} boards / ${Lt.finalDryRun?.tombstoneConflicts?.localProductsConflictingWithCloudTombstones||0} products`,`Safety snapshots saved add/update ${Lt.safetySnapshots?.addOnly?"yes":"no"} / ${Lt.safetySnapshots?.cloudNewer?"yes":"no"}`,`Supabase writes performed: ${Lt.supabaseWritesPerformed||0}`]:[],Rp=Sq(p,D),ql=Rp.filter(R=>R.isPublic).length,Lp=Math.max(0,Rp.length-ql),oi=Io?"—":Qi.followersCount,Wf=Io?"—":Qi.followingCount,Bp=p.map((R,_e)=>{const bt=qu(R,D),ir=R.id||R.slug||R.name,Ln=e[ir]||{},ka=String(Ln.publicBoardId||"").trim(),lc=R.isPublic===!0&&xa&&ka?jc(ln,ka):"",Kp=R.isPublic!==!0?"":ln?Kn!=="public"?"Set your profile to Public to share this board.":"Public link will appear once publishing completes.":"Choose a username before sharing this board.";return{description:R.publicDescription?.trim()||R.description?.trim()||"",href:gd(R.slug||R.name),id:ir,
32isPublic:R.isPublic===!0,name:R.name,syncConflict:R.syncConflict||"",syncPendingCloudWrite:R.syncPendingCloudWrite===!0,syncRevision:R.syncRevision,userId:R.userId,coverItemIds:hf(R.coverItemIds),productCount:bt.length,products:bt,publicPath:lc,publicPathLabel:lc,publicShareCopy:Kp,publicDescription:R.publicDescription?.trim()||"",sortOrder:Number.isFinite(R.sortOrder)?R.sortOrder:_e}}),Tp=D.filter(R=>va(R.status)==="active").length,Gf=[{id:"boards",label:"Boards",count:Bp.length+ma.length},{id:"public",label:"Public",count:ql},{id:"private",label:"Private",count:Lp},{id:"collaborative",label:"Collaborative",count:ma.length}],Dp=Bp.filter(R=>Ss==="public"?R.isPublic:Ss==="private"?!R.isPublic:!0),ac=Ss==="collaborative",Op=Ss==="boards"?ma:[],pv=!ac&&(Dp.length>0||Op.length>0),Mp=R=>{R?.boardId&&E&&E(MG(R))},Ha=ac&&ma.length>0,Up=Gf.find(R=>R.id===Ss)?.label||"Boards",qf=Ss==="public"?"No public boards yet.":Ss==="private"?"No private boards yet.":"No boards yet.",Fp=Ss==="boards"?"Create your first board to start shaping this profile.":"Change a board's visibility to make it appear here.",mv=R=>{R?.name&&k&&k(R.name)},qd=Wr.trim().replace(/\s+/g," "),ha=Wl.trim().replace(/\s+/g," "),fv=qd!==ha,Jc=!qd||qd.length>pu,Qc=kr.trim().replace(/\s+/g," "),Yd=ti.replace(/\s+/g," "),Yf=Qc!==Yd,Ar=Qc.length>cl,Ro=!!(vr&&!ln&&!gr),Kd=gr||Ro,xs=Sl(ar),Kf=is,Zc=xs!==Kf||!Kf&&!!xs,Xd=Kd?bb(ar):"",Yl=ue||(Zc?Xd:""),$p=be.status||"idle",ii=Yl||!xs?"":be.message||"",sc=yl(tn||Kn),Xf=!!(He||pr||!fv&&!Yf&&!(sc!==Kn)||Jc||Ar),Ks=!!(He||pr||!Zc||Xd||ko&&Zc&&$p!=="available"),hv=ln||Ve?"Update username":"Claim username",gv=$c==="DELETE",Kl=d.useCallback(async()=>{const R=Vd.current+1;if(Vd.current=R,!Qt){pa({boards:[],viewerId:""}),cn(""),Wc(!1);return}pa(bt=>bt.viewerId===Qt?bt:{boards:[],viewerId:Qt}),cn(""),Wc(!0);const _e=await MO({client:ae,isConfigured:s.isConfigured,userId:Qt});Vd.current===R&&(_e.ok?(pa(bt=>({boards:OO(bt.viewerId===Qt?bt.boards:[],_e),viewerId:Qt})),cn("")):cn(_e.error),Wc(!1))},[s.isConfigured,Qt]),Jf=R=>{zl(R),R==="collaborative"&&Qt&&!qs&&Kl()},zp=(R,_e)=>{nr(R),st(_e),ec.current&&window.clearTimeout(ec.current),ec.current=window.setTimeout(()=>{nr(""),st(""),ec.current=null},1800)};d.useEffect(()=>()=>{ec.current&&window.clearTimeout(ec.current)},[]),d.useEffect(()=>(Kl(),()=>{Vd.current+=1}),[Kl]),d.useEffect(()=>{if(!vr&&!s.user?.id){at("");return}at(LL(En))},[s.user?.id,En,vr]),d.useEffect(()=>{if(!vr&&!s.user?.id){tt("");return}tt(mq(tc))},[s.user?.id,tc,vr]),d.useEffect(()=>{xt||Zt(za)},[za.x,za.y,za.zoom,xt]),d.useEffect(()=>{if(!$)return;const R=bt=>{qc.current?.contains(bt.target)||O(!1)},_e=bt=>{bt.key==="Escape"&&O(!1)};return document.addEventListener("pointerdown",R),document.addEventListener("keydown",_e),()=>{document.removeEventListener("pointerdown",R),document.removeEventListener("keydown",_e)}},[$]),d.useEffect(()=>{if(!ft)return;const R=bt=>{Jt.current?.contains(bt.target)||lr(!1)},_e=bt=>{bt.key==="Escape"&&(lr(!1),jr.current?.focus())};return document.addEventListener("pointerdown",R),window.addEventListener("keydown",_e),()=>{document.removeEventListener("pointerdown",R),window.removeEventListener("keydown",_e)}},[ft]),d.useEffect(()=>{let R=!1;return!vr||!s.user?.id||!ln?(Gc({followersCount:0,followingCount:0}),ss(!1),()=>{R=!0}):(ss(!0),Ym(ln).then(_e=>{if(!R){if(_e?.error){Gc({followersCount:0,followingCount:0});return}Gc({followersCount:Number.isFinite(_e?.followersCount)?_e.followersCount:0,followingCount:Number.isFinite(_e?.followingCount)?_e.followingCount:0})}}).catch(()=>{R||Gc({followersCount:0,followingCount:0})}).finally(()=>{R||ss(!1)}),()=>{R=!0})},[ln,cv,s.user?.id,vr]),d.useEffect(()=>{const R=Kr.current+1;if(Kr.current=R,!Kd){Te({status:"idle",message:""});return}if(!xs){Te({status:"idle",message:""});return}if(Xd){Te({status:"idle",message:""});return}if(!Zc){Te({status:"current",message:"Current username."});return}if(!ko){Te({status:"available",message:"This username can be saved on this device."});return}if(!s.checkUsernameAvailability){Te({status:"error",message:"Could not check username availability."});return}Te({status:"checking",message:"Checking availability..."});const _e=window.setTimeout(()=>{s.checkUsernameAvailability(xs).then(bt=>{if(Kr.current===R){if(bt?.available){Te({status:"available",message:"That username is available."});return}Te({status:"taken",message:bt?.error||"That username is already taken."})}}).catch(()=>{Kr.current===R&&Te({status:"error",message:"Could not check username availability."})})},350);return()=>{window.clearTimeout(_e)}},[s.checkUsernameAvailability,xs,ko,Kd,Zc,Xd]);const el=()=>{xe(""),Pe(""),nr(""),st(""),s.clearAuthError()},Vp=()=>{el();const R=A?.();
32if(R?.error){Pe(R.error);return}xe(R?.imported?"Local boards were imported into this account on this browser.":"No local boards were imported.")},bv=()=>{el(),N?.(),xe("Local boards will stay separate from this account.")},oc=()=>{G(""),le(""),Ne(""),Te({status:"idle",message:""}),xe(""),Pe(""),s.clearAuthError()},Qf=()=>{Dr(Wl||Yc),Gr(ti),qr(is),hn(Kn),Xt(!0),oc()},vv=()=>{He||(Xt(!1),Dr(Wl||Yc),Gr(ti),qr(is),hn(Kn),G(""),le(""),Ne(""),Te({status:"idle",message:""}))},Hp=()=>{pr||He||Xe||gr||(oc(),nn("visibility"),br(Eo))},yv=()=>{pr||He||Xe||gr||Kn!=="public"||(oc(),nn("deactivation"),br("private"))},Sv=()=>{He||(nn("visibility"),br(""))},Zf=async()=>{const R=yl(Wn);if(!Wn||R===Kn){nn("visibility"),br("");return}const _e=rn==="deactivation"&&R==="private";oc(),Ge(!0);const bt=await s.updateUserDisplayName({bio:ti,displayName:Wl||Yc,profileVisibility:R});if(Ge(!1),bt.error){s.clearAuthError(),nn("visibility"),br(""),Pe("Could not update profile visibility. Please try again.");return}nn("visibility"),br(""),hn(yl(bt.profile?.profile_visibility||R)),xe(_e?"Your profile is now private.":`Profile is now ${R}.`)},eh=async R=>{R.preventDefault(),oc();const _e=Wr.trim().replace(/\s+/g," ");if(!_e){G("Enter a name.");return}if(_e.length>pu){G(`Use ${pu} characters or fewer.`);return}const bt=Qc;if(bt.length>cl){le(`Use ${cl} characters or fewer.`);return}Ge(!0);const ir=sc,Ln=await s.updateUserDisplayName({bio:bt,displayName:_e,profileVisibility:ir});
32if(Ge(!1),Ln.error){Pe(Ln.error);return}Xt(!1),Dr(_e),Gr(Ln.profile?.bio||bt),qr(is),hn(yl(Ln.profile?.profile_visibility||ir)),xe("Profile updated.")},Wp=async()=>{oc();const R=Sl(ar),_e=bb(R);if(_e){Ne(_e);return}if(gr&&Ar){le(`Use ${cl} characters or fewer.`);return}const bt=gr?Qc:ti;if(ko){if($p==="checking"){Ne("Wait for the username availability check to finish.");return}if($p!=="available"){Ne(be.message||"Could not check username availability.");return}Ge(!0);const Ln=await s.updateUserProfile({bio:bt,displayName:Wl||Yc,profileVisibility:_o?Kn:"private",username:R});if(Ge(!1),Ln.error){Ne(Ln.error),String(Ln.error).toLowerCase().includes("taken")?Te({status:"taken",message:"That username is already taken."}):Te({status:"error",message:""});return}at(""),Gr(Ln.profile?.bio||bt),qr(R),Te({status:"current",message:"Current username."}),xe(ln?"Username updated.":"Username claimed.");return}if(!uq(En,R)){Ne("Could not save username on this device.");return}at(R),qr(R),Te({status:"current",message:"Current username."}),xe(Ve?"Username updated.":"Username claimed.")},ci=R=>{Zt(ps(R))},th=()=>{if(!Ia){xe(Ns.avatar),Pe(""),s.clearAuthError();return}Xe||er||pr||He||(xe(""),Pe(""),s.clearAuthError(),O(R=>!R))},rh=()=>{!rc||Xe||er||pr||He||(O(!1),Zt(za),Gt(!0),Yt(!1),xe(""),Pe(""),s.clearAuthError())},Gp=()=>{Zt(za),Gt(!1),Yt(!1),ei.current=null,Pe("")},Xl=()=>{ci(Kh),xe(""),Pe("")},Pa=R=>{Zt(_e=>{const bt=ps(_e);return ps({...bt,zoom:Math.round((bt.zoom+R)*10)/10})}),xe(""),Pe("")},nh=async()=>{if(!rc||!s.updateProfileAvatarFrame||er)return;x(!0),xe(""),Pe(""),s.clearAuthError();const R=ps(jt),_e=await s.updateProfileAvatarFrame(R);if(x(!1),_e.error){Pe(_e.error);return}const bt=ps(_e.profile||R);Zt(bt),Gt(!1),Yt(!1),ei.current=null,xe("Profile photo framing saved.")},Jd=R=>{if(!xt||!cs||er||Xe||R.button!==void 0&&R.button!==0)return;R.preventDefault();const _e=R.currentTarget.getBoundingClientRect();ei.current={height:_e.height||1,pointerId:R.pointerId,startFrame:ps(jt),startX:R.clientX,startY:R.clientY,width:_e.width||1},Yt(!0),R.currentTarget.setPointerCapture?.(R.pointerId)},tl=R=>{const _e=ei.current;if(!_e||_e.pointerId!==R.pointerId)return;R.preventDefault();const bt=(R.clientX-_e.startX)/_e.width*100,ir=(R.clientY-_e.startY)/_e.height*100;ci({x:_e.startFrame.x-bt,y:_e.startFrame.y-ir,zoom:_e.startFrame.zoom})},Qd=R=>{const _e=ei.current;!_e||_e.pointerId!==R.pointerId||(ei.current=null,Yt(!1),R.currentTarget.releasePointerCapture?.(R.pointerId))},rl=R=>{if(!xt||er||Xe)return;if(R.key==="Escape"){R.preventDefault(),Gp();return}const _e=ps(jt),bt=R.shiftKey?Q_*3:Q_,ir={..._e};if(R.key==="ArrowLeft")ir.x+=bt;else if(R.key==="ArrowRight")ir.x-=bt;else if(R.key==="ArrowUp")ir.y+=bt;else if(R.key==="ArrowDown")ir.y-=bt;else return;R.preventDefault(),ci(ir)},wv=R=>{R.key==="Escape"&&(R.preventDefault(),Gp())},ah=()=>{if(!Ia){O(!1),xe(Ns.avatar),Pe(""),s.clearAuthError();return}Xe||pr||He||(Gt(!1),Yt(!1),O(!1),xe(""),Pe(""),s.clearAuthError(),Hl.current?.click())},sn=async R=>{const _e=R.target.files?.[0]||null;if(R.target.value="",xe(""),Pe(""),s.clearAuthError(),!Ia){xe(Ns.avatar);return}if(!_e)return;const bt=vq(_e);if(bt){Pe(bt);return}if(Dt(!0),ko){const ka=await s.uploadProfileAvatar(_e);if(Dt(!1),ka.error){Pe(ka.error);return}tt(""),Zt(ps(ka.profile||za)),Gt(!1),Yt(!1),xe("Profile photo updated.");return}let ir="";try{ir=await fq(_e)}catch{Dt(!1),Pe("Could not read that image. Try another JPG, PNG, or WebP file.");return}const Ln=K_(tc,ir);if(Dt(!1),!Ln){Pe("Could not save profile photo on this device. Try a smaller image.");return}tt(ir),Zt(za),Gt(!1),Yt(!1),xe("Profile photo updated on this device.")},sh=async()=>{if(!Ia){O(!1),xe(Ns.avatar),Pe(""),s.clearAuthError();return}if(Xe||pr||He||!cs)return;if(xe(""),Pe(""),O(!1),s.clearAuthError(),ko){Dt(!0);const _e=await s.removeProfileAvatar();if(Dt(!1),_e.error){Pe(_e.error);return}tt(""),Zt(ps(Kh)),Gt(!1),Yt(!1),xe("Profile photo removed.");return}if(!K_(tc,gg)){Pe("Could not remove profile photo on this device.");return}tt(gg),Zt(ps(Kh)),Gt(!1),Yt(!1),xe("Profile photo removed.")},ic=async(R,_e)=>{const bt=R?.isPublic===!0;if(!R?.id||!re)return;const ir=!!_e;if(R.isPublic===ir)return;Pe(""),xe("Saving board visibility…");const Ln=await re(R.id,ir);if(!Ln?.ok){xe("Board visibility could not be confirmed in cloud. Review the sync status and try again.");return}if(Ln.localOnly){xe(`${R.name} is now ${ir?"public":"private"} on this device. Sign in to publish it.`);return}const ka=await s.syncPublicBoardMetadata({localBoardId:R.id,title:R.name,visibility:ir?"public":"private"});if(ka.error||!ka.board){xe("Visibility was saved, but the public view could not be refreshed. Please try again.");return}if(ir&&!bt&&ka.board.visibility==="public"&&y?.(),ir&&ka.board.visibility!=="public"){xe("This board is restricted from public publication.");return}const lc=ir?ka.board.id:"",Kp=lc,zv=[];r(R.id,al=>({...al,error:"",isLoaded:!1,isLoading:!1,items:ir?zv:al.items,publicBoardId:Kp,savingItemId:""})),xe(`${R.name} is now ${ir?"public":"private"}.`),ir&&lc&&(await Kk({boardId:lc,dedupeKey:DL(_l.BOARD_MADE_PUBLIC,lc),eventType:_l.BOARD_MADE_PUBLIC,metadata:TL(R)})).error},Jl=async()=>
32{if(!(!xa||!Ip)){Pe(""),xe("");try{await Tu(Qa(Ip)),zp("Copied","profile")}catch{zp("Could not copy link.","profile")}}},Cv=async()=>{xe(""),Pe(""),os(""),Of("");const{error:R}=await s.signOut();if(R){Pe(R);return}xe("Signed out on this device. Your boards stay in your account.")},oh=R=>{lr(!1),R?.()},xv=R=>{if(!["ArrowDown","ArrowUp","Home","End"].includes(R.key))return;const _e=[...Jt.current?.querySelectorAll('[role="menuitem"]:not(:disabled)')||[]];if(_e.length===0)return;R.preventDefault();const bt=_e.indexOf(document.activeElement),ir=R.key==="Home"?0:R.key==="End"?_e.length-1:R.key==="ArrowDown"?(bt+1+_e.length)%_e.length:(bt-1+_e.length)%_e.length;_e[ir]?.focus()},Iv=R=>{["ArrowDown","ArrowUp"].includes(R.key)&&(R.preventDefault(),lr(!0),window.requestAnimationFrame(()=>{const _e=[...Jt.current?.querySelectorAll('[role="menuitem"]:not(:disabled)')||[]],bt=R.key==="ArrowUp"?_e.length-1:0;_e[bt]?.focus()}))},nl=d.useCallback(async({quiet:R=!1}={})=>{if(!vr||Ys)return Yi([]),Co(!1),Un(!1),[];R||ua(""),Gs(""),Un(!0);try{const _e=await PA({user:s.user});return Yi(_e),Co(!0),_e}catch{return Gs("Could not load account backups."),Co(!0),[]}finally{Un(!1)}},[s.user,Ys,vr]),Av=()=>{Fl||Fd(null)},Pv=()=>{Ca||Ji(null)},qp=async()=>{if(!(!At?.backup||!At?.summary?.isValid||At.validationError)){$d(!0),ua(""),Gs(""),da(""),bn("");try{const R=await V({backup:At.backup,snapshot:At.snapshot});Ji(null),da(`Restore complete. Restored ${R.listCount} boards and ${R.productCount} products.${R.safetySnapshotSaved?" A safety backup of the previous browser data was saved.":""}`),X("Cloud status updated."),await nl({quiet:!0})}catch(R){const _e=R.message||"";bn(_e.startsWith("Restore stopped")?_e:"Could not restore this backup. Your local data was not changed.")}finally{$d(!1)}}},_v=async()=>{if(Xi){Yn(!0),ua(""),Gs("");try{await ZF({snapshotId:Xi.id,user:s.user}),Yi(R=>R.filter(_e=>_e.id!==Xi.id)),At?.snapshot?.id===Xi.id&&Ji(null),Fd(null),ua("Account backup deleted. Local browser data was not changed.")}catch{Fd(null),Gs("Could not delete this backup.")}finally{Yn(!1)}}},Ev=async()=>{X(""),he(""),Oe(!0);try{const R=await K();X(R.hasCloudData?"Cloud backup found.":"No cloud backup yet.")}catch{he("Could not check cloud backup right now.")}finally{Oe(!1)}},kv=async()=>{mt(""),rt(""),X(""),he(""),_t(!0);try{const R=await v();if(R?.cancelled){if(R.blocked){rt(R.message||"Cloud backup stopped to protect existing cloud boards.");return}mt("Cloud backup cancelled.");return}mt(`Backup complete. Backed up ${R.listCount} boards and ${R.productCount} products.`),X("Cloud status updated.")}catch(R){rt(R.message||"Could not back up right now. Your local data was not changed.")}finally{_t(!1)}},ih=async()=>{if(S){mt(""),rt(""),X(""),he(""),tr(!0);try{const R=await S();if(R?.blocked){rt(R.message||"Cloud setup needs review before uploading from this browser.");return}mt(`Uploaded ${R.listCount} boards and ${R.productCount} products to cloud.`),X("Cloud status updated.")}catch{rt("Could not upload this browser's boards. Nothing was deleted or overwritten.")}finally{tr(!1)}}},Nv=async()=>{if(!(!De||!z)){Ua(""),Oc(""),fo(null),gn(!0);try{const R=await z();if(R?.blocked){Ua(R.message||"Sync dry-run is only available for signed-in Personal mode.");return}fo(R),Oc("Sync dry-run complete. No changes were made.")}catch{Ua("Could not run sync dry-run right now.")}finally{gn(!1)}}},cc=async()=>{if(!(!Be||!Le)){Et(""),Je(""),H(null),Vi(!0);try{const R=await Le();if(R?.blocked){Et(R.message||"Cloud pull is blocked because this browser already has Personal mode data.");return}H(R),Je(R.message||"Cloud data was pulled into this empty browser.")}catch{Et("Could not pull cloud data into this browser right now.")}finally{Vi(!1)}}},jv=async()=>{if(!(!We||!B)){Td(""),Hi(""),ns(null),ys(!0);try{const R=await B();if(R?.blocked){Td(R.message||"Cloud pull merge needs review before applying changes.");return}ns(R),Hi(R.message||"No new cloud boards or products to pull.")}catch{Td("Could not pull missing cloud rows right now.")}finally{ys(!1)}}},Rv=async()=>
32{if(!(!fe||!L)){Ir(""),Yr(""),It(null),gt(!0);try{const R=await L();if(R?.blocked){It(R),Ir(R.message||"Cloud update merge needs review before applying changes.");return}It(R),Yr(R.message||"No newer cloud board or product updates to apply.")}catch{Ir("Could not apply newer cloud updates. Please try again.")}finally{gt(!1)}}},Lv=async()=>{if(!(!ke||!et)){go(""),qn("Checking cloud changes..."),Sa(null),on(!0);try{const R=await et({onStatus:_e=>{qn(_e)}});if(Sa(R),R?.blocked){go(R.message||"Sync now needs review before applying changes.");return}qn(R?.message||"Sync now complete. No new cloud changes to apply.")}catch{go("Sync now could not complete. Please try again."),qn("")}finally{on(!1)}}},Bv=async()=>{if(!(!Fe||!et)){if(ca(""),Mn(null),ce(null),typeof navigator<"u"&&navigator.onLine===!1){const R=uS({offline:!0});ce(R),Cr(R.message);return}Cr("Syncing..."),Sr(!0);try{const R=await et({blockedMessage:"Sync is available when you are signed in and using Personal mode.",enabled:Fe,onStatus:()=>{Cr("Syncing...")}});Mn(R);const _e=uS({result:R});if(ce(_e),Cr(_e.message),_e.state!=="synced")return;rs(new Date().toISOString())}catch{const R=uS({thrown:!0});ce(R),Cr(""),ca(R.message)}finally{Sr(!1)}}},Tv=async()=>{if(!(!de||!pt)){yo(""),la(""),Wi(null),hp(!0);try{const R=await pt();if(R?.blocked){yo(R.message||"Sync merge preview is only available for signed-in Personal mode.");return}Wi(R),la(R.message||"Cloud pull merge preview only. No changes were made.")}catch{yo("Could not preview cloud pull merge right now.")}finally{hp(!1)}}},Dv=async()=>{if(da(""),bn(""),X(""),he(""),!K){Uc(!0);return}gp(!0);try{const R=await K();if(X(R.hasCloudData?"Account backup found.":"No account backup found yet."),!R.hasCloudData){bn("No account backup found yet.");return}Uc(!0)}catch{bn("Could not check account backup right now.")}finally{gp(!1)}},Ov=()=>{Dd||Uc(!1)},Mv=async()=>{da(""),bn(""),bp(!0);try{const R=await _();Uc(!1),da(`Restore complete. Restored ${R.listCount} boards and ${R.productCount} products.${R.safetySnapshotSaved?" A safety backup of the previous browser data was saved.":""}`),X("Cloud status updated."),await nl({quiet:!0})}catch(R){const _e=R.message||"";bn(_e==="No cloud backup found yet."||_e.startsWith("Restore stopped")?_e:"Could not restore from account. Your local data was not changed.")}finally{bp(!1)}},ch=()=>{xe(""),Pe(""),So(""),Fc(""),Xo(!0)},Ql=()=>{So(""),Fc(""),Xo(!1)},Uv=()=>{xe(""),Pe(""),So(""),Fc("");try{if(!b){Fc("Local browser data clearing is not available right now.");return}const R=b?.({quiet:!0});if(R?.ok===!1){Fc(R.error||"Local browser data could not be cleared.");return}X_(En,tc),at(""),tt(""),zl("boards"),t({}),Xo(!1),So("Local browser data cleared. Your cloud account, cloud backups, and data on other devices were not deleted.")}catch(R){Fc(R?.message||"Local browser data could not be cleared.")}},Fv=()=>{if(!ri){xe(Ns.accountDeletion),Pe(""),Cn(""),Hs(!1);return}xe(""),Pe(""),Cn(""),wo(""),qi(!1),Xo(!1),Hs(!0)},$v=()=>{zc||(Hs(!1),wo(""),qi(!1),Cn(""))},Yp=async()=>{if(!ri){Hs(!1),xe(Ns.accountDeletion);return}if(!gv||zc)return;xe(""),Pe(""),Cn("");const R=s.session?.access_token||"";if(!R){Cn("Sign in again before deleting your cloud account.");return}Ws(!0);try{const _e=wa,bt=await fetch("/api/account/delete-account",{body:JSON.stringify({confirm:"DELETE",dryRun:!1}),headers:{Authorization:`Bearer ${R}`,"Content-Type":"application/json"},method:"POST"});let ir=null;try{ir=await bt.json()}catch{ir=null}if(!bt.ok||ir?.ok!==!0||ir?.deleted!==!0)throw new Error("account-deletion-failed");let Ln=!1;if(_e)try{const ka=b?.({quiet:!0});!b||ka?.ok===!1?Ln=!0:(X_(En,tc),at(""),tt(""),zl("boards"),t({}))}catch{Ln=!0}await s.clearLocalSession?.(),Hs(!1),wo(""),qi(!1),Ae(""),me(""),pe("signin"),xe(Ln?"Your cloud account has been deleted. Local browser data could not be cleared from this device.":_e?"Your account has been deleted and this browser’s SaveBoard app data was reset.":"Your account has been deleted. Local browser data was kept on this device.")}catch{Cn("Could not delete your account. Please try again.")}finally{Ws(!1)}};return d.useEffect(()=>{if(!vr||Ys||!K)return;let R=!0;return Oe(!0),K().catch(()=>null).finally(()=>{R&&Oe(!1)}),()=>{R=!1}},[Ys,K,vr]),d.useEffect(()=>{if(!vr||Ys){Yi([]),Co(!1),Un(!1),ua(""),Gs(""),Vc(""),Ud(""),Fd(null),Ji(null),$l(""),$d(!1),Hs(!1),wo(""),qi(!1),Ws(!1),Cn("");return}let R=!0;return Un(!0),Gs(""),PA({user:s.user}).then(_e=>{R&&(Yi(_e),Co(!0))}).catch(()=>{R&&(Gs("Could not load account backups."),Co(!0))}).finally(()=>{R&&Un(!1)}),()=>{R=!1}},[s.user,Ys,vr]),d.useEffect(()=>{if(!Gl||!vr||Ys){Vl(null),wp(""),Qo(!1),Zi(!!Gl);return}let R=!0;return Qo(!0),Zi(!1),wp(""),nj({user:s.user}).then(_e=>{R&&Vl(_e)}).catch(()=>{R&&(Vl(null),wp("Could not confirm billing status. Free limits are shown."))}).finally(()=>{R&&(Qo(!1),Zi(!0))}),()=>{R=!1}},[s.user?.id,Ys,Gl,vr]),n.jsxs(n.Fragment,{children:[n.jsxs("main",{className:`accountPage${vr?" accountProfilePage":""}`,children:[vr?n.jsxs("section",{className:"accountProfileShell","aria-label":"Saveboard profile",children:[n.jsxs("div",{className:"accountProfileHero",children:[n.jsxs("div",{className:"accountProfileIdentityCluster",children:[n.jsxs("div",{className:"accountProfileAvatarStack",ref:qc,children:[n.jsxs("div",{className:`accountProfileAvatarEditor${$?" isOpen":""}`,children:[n.jsxs("button",{"aria-expanded":Ia&&!xt?$:void 0,"aria-haspopup":Ia&&!xt?"menu":void 0,"aria-label":Ia?xt?"Drag to adjust profile photo":Xe?"Saving profile photo":"Edit profile photo":"Profile photo editing is paused for beta",className:`accountProfileAvatarEditButton${xt?" isAdjusting":""}${Or?" isDragging":""}`,disabled:!Ia||pr||He||Xe||er,onClick:Ia&&!xt?th:void 0,onKeyDown:rl,onPointerCancel:Qd,onPointerDown:Jd,onPointerMove:tl,onPointerUp:Qd,type:"button",children:[n.jsx("span",{className:`accountProfileAvatar${cs?" hasPhoto":" hasBrandFallback"}`,"data-avatar-state":cs?"resolved":s.profileLoading?"loading":"default","aria-hidden":"true",children:cs?n.jsx("img",{alt:"",decoding:"async",fetchPriority:"high",loading:"eager",src:cs,style:uv}):n.jsx(Ol,{ariaLabel:null,className:"accountProfileAvatarBrand",trademark:!1,variant:"monochrome"})}),Ia?n.jsx("span",{className:"accountProfileAvatarEditIcon","aria-hidden":"true"}):null]}),Ia&&$&&!xt?n.jsxs("div",{className:"accountAvatarControls","aria-label":"Profile photo actions",children:[n.jsx("button",{className:"accountAvatarButton",disabled:pr||He||Xe||er,onClick:ah,type:"button",children:cs?"Change photo":"Add photo"}),cs?n.jsxs(n.Fragment,{children:[n.jsx("button",{className:"accountAvatarButton",disabled:pr||He||Xe||er,onClick:rh,type:"button",children:"Adjust photo"}),n.jsx("button",{className:"accountAvatarButton accountAvatarRemoveButton",disabled:pr||He||Xe||er,onClick:sh,type:"button",children:"Remove photo"})]}):null]}):null]}),Ia?n.jsx("input",{accept:dW,className:"accountAvatarInput",disabled:Xe,onChange:sn,ref:Hl,type:"file"}):n.jsx("p",{className:"accountFinePrint",children:Ns.avatar}),xt&&cs?n.jsxs("div",{className:"accountAvatarAdjustPanel","aria-label":"Adjust profile photo",onKeyDown:wv,children:[n.jsx("p",{children:"Drag p
32hoto to reposition."}),n.jsxs("div",{className:"accountAvatarZoomControls","aria-label":"Zoom controls",children:[n.jsx("button",{"aria-label":"Zoom out",className:"accountAvatarIconButton",disabled:er||jt.zoom<=1,onClick:()=>Pa(-J_),type:"button",children:"-"}),n.jsxs("span",{children:[jt.zoom.toFixed(1),"x"]}),n.jsx("button",{"aria-label":"Zoom in",className:"accountAvatarIconButton",disabled:er||jt.zoom>=3,onClick:()=>Pa(J_),type:"button",children:"+"})]}),n.jsxs("div",{className:"accountAvatarAdjustActions",children:[n.jsx("button",{disabled:er,onClick:Xl,type:"button",children:"Reset"}),n.jsx("button",{disabled:er,onClick:Gp,type:"button",children:"Cancel"}),n.jsx("button",{className:"accountPrimaryAction",disabled:er,onClick:nh,type:"button",children:er?"Saving...":"Save"})]})]}):null]}),n.jsxs("div",{className:"accountProfileIdentity",children:[n.jsxs("div",{className:"accountProfileHandleRow",children:[n.jsx("h2",{children:Cs}),Pp?n.jsx("span",{className:"accountProfilePremiumBadge","aria-label":"Premium plan",children:"Premium"}):null]}),n.jsx("strong",{children:Cp}),n.jsx("span",{children:`· ${Va}`}),n.jsx("button",{"aria-label":Mf,className:`accountProfileVisibilityBadge ${Kn==="public"?"isPublic":"isPrivate"}`,disabled:pr||He||Xe||gr,onClick:Hp,title:Mf,type:"button",children:xp}),xa?null:n.jsx("p",{className:"accountProfileInlineStatus","aria-label":"Profile sharing status",children:Kc}),ti?n.jsx("p",{className:"accountProfileBio",children:ti}):null]})]}),n.jsxs("div",{className:"accountProfileActions accountProfileTopActions","aria-label":"Profile actions",children:[n.jsx("button",{className:"accountPrimaryAction",disabled:pr||He||Xe||gr,onClick:Qf,type:"button",children:"Edit profile"}),n.jsx("button",{disabled:pr||He||Xe||!xa,onClick:Jl,title:xa?"Copy public profile link":Kc,type:"button",children:"Share profile"}),n.jsxs("div",{className:"accountProfileActionsOverflow",ref:Jt,children:[n.jsx("button",{"aria-expanded":ft,"aria-haspopup":"menu","aria-label":"More profile actions",className:"accountProfileActionsOverflowTrigger",disabled:pr||He||Xe,onClick:()=>lr(R=>!R),onKeyDown:Iv,ref:jr,title:"More profile actions",type:"button",children:n.jsxs("svg",{"aria-hidden":"true",focusable:"false",viewBox:"0 0 24 24",children:[n.jsx("circle",{cx:"5",cy:"12",r:"1.6"}),n.jsx("circle",{cx:"12",cy:"12",r:"1.6"}),n.jsx("circle",{cx:"19",cy:"12",r:"1.6"})]})}),ft?n.jsxs("div",{"aria-label":"More profile actions",className:"accountProfileActionsMenu saveboardMenuPanel",onKeyDown:xv,role:"menu",children:[n.jsx("button",{className:"saveboardMenuRow",disabled:gr,onClick:()=>oh(()=>Ke(!0)),role:"menuitem",type:"button",children:"Data & backup"}),n.jsx("div",{className:"accountProfileActionsMenuDivider",role:"separator"}),n.jsx("button",{className:"saveboardMenuRow accountSignOutRow",onClick:()=>oh(Cv),role:"menuitem",type:"button",children:pr?"Signing out...":"Sign out"})]}):null]})]})]}),n.jsxs("div",{className:"accountProfileMain",children:[n.jsxs("dl",{className:"accountProfileStats","aria-label":"Profile summary",children:[n.jsxs("div",{children:[n.jsx("dt",{children:Tp.toLocaleString()}),n.jsx("dd",{children:Tp===1?"save":"saves"})]}),n.jsxs("div",{children:[n.jsx("dt",{children:ql+Lp}),n.jsx("dd",{children:ql+Lp===1?"board":"boards"})]}),n.jsxs("div",{className:"accountProfileStatInteractive",children:[n.jsx("dt",{children:oi}),n.jsx("dd",{children:n.jsx("button",{"aria-label":`View followers · ${oi}`,className:"accountProfileStatButton",disabled:!ln||Io,onClick:()=>zd("followers"),type:"button",children:"followers"})})]}),n.jsxs("div",{className:"accountProfileStatInteractive",children:[n.jsx("dt",{children:Wf}),n.jsx("dd",{children:n.jsx("button",{"aria-label":`View following · ${Wf}`,className:"accountProfileStatButton",disabled:!ln||Io,onClick:()=>zd("following"),type:"button",children:"following"})})]})]}),Bf?n.jsx(UL,{kind:Bf,onClose:()=>zd(""),onFollowStateChange:()=>Ao(R=>R+1),onOpenProfile:R=>{zd(""),Ft(Yo(R))},profileUsername:ln}):null,Ro?n.jsxs("section",{className:"accountProfileSetupCard","aria-label":"Username setup",children:[n.jsxs("div",{className:"accountProfileSetupIntro",children:[n.jsx("strong",{children:"Choose your username"}),n.jsx("p",{children:"Your public profile link will use this username. You can keep your profile private until you are ready to share."})]}),n.jsxs("label",{className:"accountProfileSetupField",children:[n.jsx("span",{children:"Username"}),n.jsxs("div",{className:"accountUsernameControl",children:[n.jsx("span",{"aria-hidden":"true",children:"@"}),n.jsx("input",{autoComplete:"username",disabled:He,maxLength:Vm+1,onChange:R=>{const _e=Sl(R.target.value);qr(_e),Ne(""),Te({status:"idle",message:""}),xe(""),Pe("")},placeholder:"username",type:"text",value:ar})]})]}),Yl?n.jsx("p",{className:"accountProfileFieldError",children:Yl}):null,ii?n.jsx("p",{className:"accountProfileFieldHint",children:ii}):null,n.jsxs("div",{className:"accountActionRow accountProfileSetupActions",children:[n.jsx("button",{className:"accountPrimaryAction",disabled:Ks,onClick:Wp,type:"button",children:"Claim username"}),n.jsx("button",{disabled:He,onClick:Qf,type:"button",children:"More profile settings"})]})]}):null,Ct&&en==="profile"?n.jsx("p",{className:"accountStatusMessage",children:Ct}):null,Ee?n.jsx("p",{className:"accountStatusMessage",children:Ee}):null,No?n.jsx("p",{className:"accountStatusMessage isError",children:No}):null]}),gr?n.jsxs("form",{className:"accountEmailForm accountProfileEditForm accountProfileEditPanel",noValidate:!0,onSubmit:eh,children:[n.jsxs("label",{children:[n.jsx("span",{children:"Name"}),n.jsx("input",{autoComplete:"name",disabled:He,maxLength:pu+1,onChange:R=>{const _e=R.target.value,bt=_e.trim().replace(/\s+/g," ");Dr(_e),bt?bt.length>pu?G(`Use ${pu} characters or fewer.`):G(""):G("Enter a name."),xe(""),Pe("")},placeholder:"Your name",type:"text",value:Wr})]}),Pn?n.jsx("p",{className:"accountProfileFieldError",children:Pn}):null,n.jsxs("label",{children:[n.jsx("span",{children:"Bio"}),n.jsx("textarea",{disabled:He,maxLength:cl+1,onChange:R=>{const _e=R.target.value,bt=_e.trim().replace(/\s+/g," ");Gr(_e),bt.length>cl?le(`Use ${cl} characters or fewer.`):le(""),xe(""),Pe("")},placeholder:"Add a short note about your taste, style, or what you save.",rows:3,value:kr})]}),n.jsxs("p",{className:"accountFinePrint",children:["Shown on your public profile when your profile is public. ",Qc.length,"/",cl]}),se?n.jsx("p",{className:"accountProfileFieldError",children:se}):null,n.jsxs("label",{children:[n.jsx("span",{children:"Username"}),n.jsxs("div",{className:"accountUsernameControl",children:[n.jsx("span",{"aria-hidden":"true",children:"@"}),n.jsx("input",{autoComplete:"username",disabled:He,maxLength:Vm+1,onChange:R=>{const _e=Sl(R.target.value);qr(_e),Ne(""),Te({status:"idle",message:""}),xe(""),Pe("")},placeholder:"username",type:"text",value:ar})]})]}),Yl?n.jsx("p",{className:"accountProfileFieldError",children:Yl}):null,ii?n.jsx("p",{className:"accountProfileFieldHint",children:ii}):null,n.jsx("p",{className:"accountFinePrint",children:ko?"Use 3-30 lowercase letters, numbers, underscores, or dots. Changing it updates public profile and board links.":"Username is saved on this device until public profiles are connected."}),n.jsxs("div",{className:"accountProfileVisibilityField",children:[n.jsxs("div",{className:"accountProfileVisibilityFieldHeader",children:[n.jsx("span",{children:"Profile visibility"}),n.jsx("em",{children:sc==="public"?"Public":"Private"})]}),n.jsxs("div",{className:"accountProfileVisibilityControl",role:"group","aria-label":"Profile visibility",children:[n.jsx("button",{"aria-pressed":sc==="private",className:sc==="private"?"isActive":"",disabled:He,onClick:()=>{hn("private"),xe(""),Pe("")},type:"button",children:"Private"}),n.jsx("button",{"aria-pressed":sc==="public",className:sc==="public"?"isActive":"",disabled:He,onClick:()=>{hn("public"),xe(""),Pe("")},type:"button",children:"Public"})]}),n.jsx("p",{className:"accountFinePrint",children:"This hides public profile and board pages. Existing private share links and collaborator access are separate."})]}),n.jsx("div",{className:"accountActionRow accountProfileEditActions",children:n.jsx("button",{disabled:Ks,onClick:Wp,type:"button",children:hv})}),n.jsxs("div",{className:"accountActionRow accountProfileEditActions",children:[n.jsx("button",{className:"accountPrimaryAction",disabled:Xf,type:"submit",children:He?"Saving...":"Save changes"}),n.jsx("button",{disabled:He,onClick:vv,type:"button",children:"Cancel"})]})]}):null,n.jsx("div",{className:"accountProfileTabs","aria-label":"Profile board filters",children:Gf.map(R=>n.jsxs("button",{"aria-pressed":Ss===R.id,className:Ss===R.id?"isActive":"",onClick:()=>Jf(R.id),type:"button",children:[n.jsx("span",{children:R.label}),n.jsx("em",{children:`· ${R.count}`})]},R.id))}),Ct&&en==="board"?n.jsx("p",{className:"accountStatusMessage",children:Ct}):null,ac&&Ha&&qs?n.jsx("p",{className:"collaborativeProfileStatus",role:"status",children:"Refreshing collaborative boards..."}):null,ac&&Ha&&Nr?n.jsxs("div",{className:"collaborativeProfileStatus isError",role:"alert",children:[n.jsx("span",{children:Nr}),n.jsx("button",{disabled:qs,onClick:Kl,type:"button",children:"Try again"})]}):null,Ha?n.jsx("div",{className:"accountProfileBoardGrid","aria-label":"Collaborative boards",style:F,children:ma.map((R,_e)=>n.jsx(eE,{board:R,index:_e,onOpen:Mp},R.compositeKey))}):pv?n.jsxs("div",{className:"accountProfileBoardGrid","aria-label":`${Up} boards`,style:F,children:[Dp.map((R,_e)=>n.jsx(Eq,{board:R,index:_e,onOpenBoard:mv,ownerHandle:Ix(ln),onShareBoard:P,onSetVisibility:ic},R.id)),Op.map((R,_e)=>n.jsx(eE,{board:R,index:Dp.length+_e,onOpen:Mp},R.compositeKey))]}):ac?n.jsx("div",{className:"accountProfileEmptyBoards collaborativeProfileEmptyBoards",children:qs?n.jsxs(n.Fragment,{children:[n.jsx("strong",{children:"Loading collaborative boards..."}),n.jsx("span",{children:"Checking boards shared with your account."})]}):Nr?n.jsxs(n.Fragment,{children:[n.jsx("strong",{children:"Collaborative boards could not load."}),n.jsx("span",{children:Nr}),n.jsx("button",{onClick:Kl,type:"button",children:"Try again"})]}):n.jsxs(n.Fragment,{children:[n.jsx("strong",{children:"No collaborative boards yet."}),n.jsx("span",{children:"Boards shared with you will appear here."})]})}):n.jsxs("div",{className:"accountProfileEmptyBoards",children:[n.jsx("strong",{children:qf}),n.jsx("span",{children:Fp})]})]}):null,vr&&fn?n.jsx("div",{className:"modalLayer accountProfileDataLayer",onMouseDown:R=>{R.target===R.currentTarget&&Ke(!1)},role:"presentation",children:n.jsxs("section",{"aria-labelledby":"account-data-backup-title","aria-modal":"true",className:"accountProfileUtilityCard accountProfileDataModal",role:"dialog",children:[n.jsxs("header",{className:"accountProfileDataHeader",children:[n.jsxs("div",{children:[n.jsx("p",{id:"account-data-backup-title",children:"Data & backup"}),n.jsx("span",{children:"Your boards live in your account. Export a copy whenever you want one."})]}),n.jsx("button",{onClick:()=>Ke(!1),type:"button",children:"Close"})]}),n.jsxs("div",{className:"accountProfileUtilitySummary",children:[n.jsx("span",{children:Aa}),n.jsx("span",{children:$f}),n.jsx("span",{children:Hd}),zf?n.jsx("span",{className:jo?"isError":"",children:zf}):null,nc?n.jsxs("span",{children:["Backup status checked ",nc]}):null,_p?n.jsxs("span",{children:["Last account backup ",_p]}):null,Ff?n.jsxs("span",{children:["Last restored ",Ff]}):null]}),si?n.jsxs("div",{className:`accountSyncStatusCard is-${si.tone}`,children:[n.jsxs("div",{className:"accountSyncStatusHeader",children:[n.jsx("strong",{children:si.label}),n.jsx("span",{children:si.badge})]}),n.jsx("p",{children:si.description}),n.jsxs("div",{className:"accountSyncStatusFooter",children:[n.jsx("small",{children:Ep}),Fe?n.jsx("button",{disabled:yr,onClick:Bv,type:"button",children:yr?"Syncing...":"Sync now"}):null]})]}):null,a?.visible?n.jsxs("div",{className:"accountPrivacyControl",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Local boards foun
32d on this browser"}),n.jsx("span",{children:"These boards were saved on this device before this account was selected. Choose whether to import them into this account or keep them separate."})]}),n.jsxs("div",{className:"accountActionRow accountLocalActions",children:[n.jsx("button",{onClick:Vp,type:"button",children:"Import to this account"}),n.jsx("button",{onClick:bv,type:"button",children:"Keep separate"})]})]}):null,ni?n.jsxs("div",{className:"accountPrivacyControl",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Upload this device's boards to cloud"}),n.jsx("span",{children:"This account has no cloud boards yet. Uploading is add/update only, so Saveboard will not delete cloud data from another device."})]}),n.jsx("button",{disabled:dr,onClick:ih,type:"button",children:dr?"Uploading...":"Upload to cloud"})]}):null,Fn?n.jsx("div",{className:"accountPrivacyControl",children:n.jsxs("div",{children:[n.jsx("strong",{children:"Cloud setup needs review"}),n.jsx("span",{children:"This browser has local boards and this account already has cloud boards. Nothing was overwritten. Use a sync review flow before combining them."})]})}):null,n.jsxs("div",{className:"accountPrivacyControls","aria-label":"Privacy and data controls",children:[n.jsxs("div",{className:"accountPrivacyControl",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Export and backup"}),n.jsx("span",{children:"Export before destructive actions. Cloud backup is separate from local browser clearing."})]}),n.jsxs("div",{className:"accountActionRow accountLocalActions","aria-label":"Export and backup actions",children:[n.jsx("button",{onClick:C,type:"button",children:"Export backup"}),n.jsx("button",{onClick:I,type:"button",children:"Import backup"}),n.jsx("button",{disabled:St,onClick:kv,type:"button",children:St?"Backing up...":"Back up now"}),n.jsx("button",{disabled:Gi||Dd,onClick:Dv,type:"button",children:Gi||Dd?"Checking...":"Restore"}),n.jsx("button",{disabled:$e,onClick:Ev,type:"button",children:$e?"Checking...":"Refresh status"}),De?n.jsx("button",{disabled:Fr,onClick:Nv,type:"button",children:Fr?"Comparing...":"Run sync dry-run"}):null,de?n.jsx("button",{disabled:zs,onClick:Tv,type:"button",children:zs?"Previewing...":"Preview cloud pull merge"}):null,Be?n.jsx("button",{disabled:Gn,onClick:cc,type:"button",children:Gn?"Pulling...":"Pull cloud data into empty browser"}):null,We?n.jsx("button",{disabled:bo,onClick:jv,type:"button",children:bo?"Pulling...":"Pull missing cloud rows"}):null,fe?n.jsx("button",{disabled:oe,onClick:Rv,type:"button",children:oe?"Updating...":"Apply newer cloud updates"}):null,ke?n.jsx("button",{disabled:ur,onClick:Lv,type:"button",children:ur?"Syncing...":"Sync now"}):null]}),De&&kp.length?n.jsxs("div",{className:"accountProfileUtilitySummary","aria-label":"Sync dry-run summary",children:[kp.map(R=>n.jsx("span",{children:R},R)),Vt.warnings.map(R=>n.jsx("span",{className:"isError",children:R},R))]}):null,de&&Hf.length?n.jsxs("div",{className:"accountProfileUtilitySummary","aria-label":"Sync pull merge preview summary",children:[Hf.map(R=>n.jsx("span",{children:R},R)),wn.warnings.map(R=>n.jsx("span",{className:"isError",children:R},R))]}):null,Be&&Np.length?n.jsxs("div",{className:"accountProfileUtilitySummary","aria-label":"Sync empty-browser pull summary",children:[Np.map(R=>n.jsx("span",{children:R},R)),Ze.warnings.map(R=>n.jsx("span",{className:"isError",children:R},R))]}):null,We&&Wd.length?n.jsxs("div",{className:"accountProfileUtilitySummary","aria-label":"Sync populated pull summary",children:[Wd.map(R=>n.jsx("span",{children:R},R)),(an.warnings||[]).map(R=>n.jsx("span",{className:"isError",children:R},R))]}):null,fe&&jp.length?n.jsxs("div",{className:"accountProfileUtilitySummary","aria-label":"Sync cloud-newer update summary",children:[jp.map(R=>n.jsx("span",{children:R},R)),(wt.warnings||[]).map(R=>n.jsx("span",{className:"isError",children:R},R))]}):null,ke&&Gd.length?n.jsxs("div",{className:"accountProfileUtilitySummary","aria-label":"Sync now summary",children:[Gd.map(R=>n.jsx("span",{children:R},R)),(Lt.warnings||[]).map(R=>n.jsx("span",{className:"isError",children:R},R))]}):null]}),n.jsxs("div",{className:"accountPrivacyControl",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Clear local browser data"}),n.jsx("span",{children:"Clears boards, items, manual stores, local settings, and local profile fallbacks from this browser only."})]}),n.jsx("button",{className:"accountDangerButton",onClick:ch,type:"button",children:"Clear local data"}),vp?n.jsxs("div",{className:"accountPrivacyConfirm",role:"alert",children:[n.jsx("p",{children:"This clears local boards, items, manual stores, and settings from this browser. It does not delete your cloud account, cloud backups, or data stored on other devices. Export first if you want a copy."}),n.jsxs("div",{className:"accountActionRow",children:[n.jsx("button",{className:"accountDangerButton",onClick:Uv,type:"button",children:"Confirm clear"}),n.jsx("button",{onClick:Ql,type:"button",children:"Cancel"})]})]}):null]}),n.jsxs("div",{className:"accountPrivacyControl",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Deactivate public profile"}),n.jsx("span",{children:Kn==="public"?"Makes your profile private and removes your public boards from public view. Your account and saved items are not deleted.":"Your public profile is hidden. Existing private share links and collaborator access still work."})]}),n.jsx("button",{className:Kn==="public"?"accountDangerButton":"",disabled:pr||He||Xe||gr||Kn!=="public",onClick:yv,type:"button",children:Kn==="public"?"Deactivate profile":"Already private"})]}),n.jsxs("div",{className:"accountPrivacyControl",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Delete cloud account"}),n.jsx("span",{children:ri?"Permanently deletes your account and the application data you own. Other 
32copies and provider logs/backups are separate; review the confirmation before deleting.":Ns.accountDeletion})]}),n.jsx("button",{className:"accountDangerButton",disabled:!ri||pr||zc,onClick:ri?Fv:void 0,type:"button",children:ri?"Delete account":"Unavailable in beta"})]})]}),o?n.jsx("p",{className:"accountStatusMessage",children:o}):null,i?n.jsx("p",{className:"accountStatusMessage",children:i}):null,Jo?n.jsx("p",{className:"accountStatusMessage",children:Jo}):null,Ml?n.jsx("p",{className:"accountStatusMessage isError",children:Ml}):null,q?n.jsx("p",{className:"accountStatusMessage",children:q}):null,Se?n.jsx("p",{className:"accountStatusMessage isError",children:Se}):null,Pt?n.jsx("p",{className:"accountStatusMessage",children:Pt}):null,Kt?n.jsx("p",{className:"accountStatusMessage isError",children:Kt}):null,Dc?n.jsx("p",{className:"accountStatusMessage",children:Dc}):null,ho?n.jsx("p",{className:"accountStatusMessage isError",children:ho}):null,ve?n.jsx("p",{className:"accountStatusMessage",children:ve}):null,lt?n.jsx("p",{className:"accountStatusMessage isError",children:lt}):null,Zn?n.jsx("p",{className:"accountStatusMessage",children:Zn}):null,as?n.jsx("p",{className:"accountStatusMessage isError",children:as}):null,or?n.jsx("p",{className:"accountStatusMessage",children:or}):null,qt?n.jsx("p",{className:"accountStatusMessage isError",children:qt}):null,vo?n.jsx("p",{className:"accountStatusMessage",children:vo}):null,ea?n.jsx("p",{className:"accountStatusMessage isError",children:ea}):null,Fa?n.jsx("p",{className:"accountStatusMessage",children:Fa}):null,_n?n.jsx("p",{className:"accountStatusMessage isError",children:_n}):null,J&&ee?.message?n.jsx("p",{className:`accountStatusMessage${ee.status==="error"?" isError":""}`,children:ee.message}):null,(ze||ge)&&ye?.message?n.jsx("p",{className:`accountStatusMessage${ye.status==="error"?" isError":""}`,children:ye.message}):null,$a?n.jsx("p",{className:"accountStatusMessage",children:$a}):null,Mc?n.jsx("p",{className:"accountStatusMessage isError",children:Mc}):null]})}):null]}),Od?n.jsx(Uq,{isRestoring:Dd,onCancel:Ov,onConfirm:Mv}):null,At?n.jsx($q,{currentSummary:m,isRestoring:Ca,onCancel:Pv,onConfirm:qp,preview:At}):null,Xi?n.jsx(Fq,{isDeleting:Fl,onCancel:Av,onConfirm:_v,snapshot:Xi}):null,Wn?n.jsx(zq,{intent:rn,isSaving:He,nextVisibility:Wn,onCancel:Sv,onConfirm:Zf}):null,ri&&Vs?n.jsx(Vq,{clearLocalData:wa,confirmationValue:$c,error:av,isDeleting:zc,onCancel:$v,onClearLocalDataChange:qi,onConfirm:Yp,onConfirmationChange:wo}):null]})}function vb({children:e,eyebrow:t="Saveboard",headline:r,monochromeEnabled:a=!1,onToggleTheme:s,supporting:o,theme:i="light",withIntro:c=!0}){return n.jsxs("main",{className:`authPage${a?" monochromeMode":""}`,"data-theme":i,children:[n.jsxs("header",{className:"authPageBar",children:[n.jsx("a",{"aria-label":"Saveboard home",className:"authPageBrand",href:"/",children:n.jsx(Ol,{trademark:!1})}),n.jsxs("div",{className:"authPageBarActions",children:[s?n.jsx("button",{"aria-label":i==="dark"?"Switch to light mode":"Switch to dark mode",className:"authPageThemeToggle",onClick:s,title:i==="dark"?"Switch to light mode":"Switch to dark mode",type:"button",children:i==="dark"?"Light":"Dark"}):null,n.jsx("a",{className:"authPageBarLink",href:"/",children:"Back to Saveboard"})]})]}),n.jsxs("div",{className:`authPageLayout${c?"":" isSingleColumn"}`,children:[c?n.jsxs("section",{className:"authPageIntro","aria-label":"About Saveboard",children:[n.jsx("p",{className:"authPageEyebrow",children:t}),n.jsx("p",{className:"authPageTagline",children:"Good finds. All in one place."}),n.jsxs("ul",{className:"authPagePoints",children:[n.jsx("li",{children:"Save products you find while browsing."}),n.jsx("li",{children:"Arrange it into boards that look the way you think."}),n.jsx("li",{children:"Private by default. Share or publish when you choose."})]})]}):null,n.jsxs("section",{className:"authPanel","aria-label":"Sign in to Saveboard",children:[n.jsxs("header",{className:"authPanelHeader",children:[n.jsx("h1",{className:"authPanelHeadline",children:r}),o?n.jsx("p",{className:"authPanelSupporting",children:o}):null]}),e]})]}),n.jsxs("footer",{className:"authPageFooter",children:[n.jsxs("span",{children:["© ",new Date().getFullYear()," Saveboard"]}),n.jsxs("span",{className:"authPageFooterLinks",children:[n.jsx("a",{href:tv,children:"Terms"}),n.jsx("a",{href:_d,children:"Privacy"})]})]})]})}const nE=Object.freeze({confirm:{headline:"Check your email.",supporting:"One link, and 
32your account is ready."},create:{headline:"Start your collection.",supporting:"An account keeps your boards with you on every device."},reset:{headline:"Reset your password.",supporting:"We'll email you a link to choose a new one."},signin:{headline:"Welcome back.",supporting:"Your boards are where you left them."}});function qq({auth:e,monochromeEnabled:t=!1,onToggleTheme:r,theme:a="light"}){const[s,o]=d.useState("create");d.useEffect(()=>{Si(Da.signupStarted),lE("auth form shown")},[]);const[i,c]=d.useState(""),[l,u]=d.useState(""),[p,m]=d.useState(!1),[f,h]=d.useState(""),[b,v]=d.useState(!1),[S,C]=d.useState(""),[I,A]=d.useState(""),k=d.useRef(!1),E=!e.isConfigured,y=e.loading||e.profileLoading,N=S||e.authError,_=!!e.socialProviders?.google,P=!!e.socialProviders?.apple,V=!E&&(_||P),L=Mm.passwordResetEnabled,{headline:z,supporting:B}=nE[s]||nE.signin,re=y?s==="create"?"Creating account...":"Signing in...":s==="create"?"Create account":"Sign in",Z=b?"Opening Google...":s==="create"?"Sign up with Google":"Sign in with Google",D=y?"Sending...":"Send reset link",K=()=>{A(""),C(""),e.clearAuthError()},ee=de=>{o(de),u(""),h(""),K()},J=()=>{if(!L){A(Ns.passwordReset),C(""),e.clearAuthError();return}o("reset"),u(""),h(""),K()},fe=()=>{o("signin"),f&&c(f),u(""),h(""),K()},De=async de=>{de.preventDefault(),K();const ye=i.trim().toLowerCase();if(E){C("Account sign-in is not configured yet.");return}if(!ye){C("Enter your email.");return}if(!HP.test(ye)){C("Enter a valid email address.");return}if(!l){C(s==="create"?"Enter a password.":"Enter your password.");return}if(s==="create"&&l.length<Vu){C(`Use at least ${Vu} characters for your password.`);return}const ge=s==="create"?await e.signUpWithPassword({email:i,password:l}):await e.signInWithPassword({email:i,password:l});if(ge.error){C(ge.error);return}if(u(""),s==="create"&&ge.needsConfirmation){h(ye),o("confirm");return}Si(Da.accountAuthenticated),A(s==="create"?"Account created. Opening Saveboard...":"Signed in. Opening Saveboard...")},Be=async de=>{if(de.preventDefault(),K(),!L){A(Ns.passwordReset);return}const ye=i.trim().toLowerCase();if(E){C("Account sign-in is not configured yet.");return}if(!ye){C("Enter your email address.");return}if(!HP.test(ye)){C("Enter a valid email address.");return}const ge=await e.requestPasswordReset(ye);if(ge.error){C(ge.error);return}A("If an account exists for that email, we'll send a password reset link.")},Fe=async()=>{if(!(k.current||y)){K(),k.current=!0,v(!0);try{const{error:de}=await e.signInWithGoogle();de&&C(de)}finally{k.current=!1,v(!1)}}},ke=async()=>{K();const{error:de}=await e.signInWithApple();de&&C(de)},We=de=>{c(de.target.value),K()};return n.jsxs(vb,{headline:z,monochromeEnabled:t,onToggleTheme:r,supp
32orting:B,theme:a,children:[E?n.jsx("p",{className:"authNotice",role:"status",children:"Account sign-in is not configured in this environment. Add the Supabase public URL and anon key, then redeploy."}):null,s==="confirm"?n.jsxs("div",{className:"authConfirmState",children:[n.jsx("p",{className:"authConfirmLead",children:"We sent a confirmation link to"}),n.jsx("strong",{className:"authConfirmEmail",children:f}),n.jsx("p",{className:"authConfirmBody",children:"Open it to confirm your address, then come back here and sign in."}),n.jsx("button",{className:"authPrimaryAction",onClick:fe,type:"button",children:"Back to sign in"})]}):s==="reset"?L?n.jsxs("form",{className:"authForm",noValidate:!0,onSubmit:Be,children:[n.jsxs("label",{className:"authField",children:[n.jsx("span",{children:"Email"}),n.jsx("input",{autoComplete:"email",disabled:E||y,enterKeyHint:"send",inputMode:"email",name:"reset-email",onChange:We,placeholder:"[email protected]",type:"email",value:i})]}),N?n.jsx("p",{className:"authFieldError",role:"alert",children:N}):null,I?n.jsx("p",{className:"authFieldMessage",role:"status",children:I}):null,n.jsx("button",{className:"authPrimaryAction",disabled:E||y,type:"submit",children:D}),n.jsx("button",{className:"authTextButton",disabled:y,onClick:fe,type:"button",children:"Back to sign in"})]}):n.jsxs("div",{className:"authConfirmState",children:[n.jsx("p",{className:"authConfirmBody",children:Ns.passwordReset}),n.jsx("button",{className:"authPrimaryAction",disabled:y,onClick:fe,type:"button",children:"Back to sign in"})]}):n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"authModeTabs","aria-label":"Account mode",children:[n.jsx("button",{"aria-pressed":s==="create",className:s==="create"?"isActive":"",onClick:()=>ee("create"),type:"button",children:"Create account"}),n.jsx("button",{"aria-pressed":s==="signin",className:s==="signin"?"isActive":"",onClick:()=>ee("signin"),type:"button",children:"Sign in"})]}),n.jsxs("form",{className:"authForm",noValidate:!0,onSubmit:De,children:[n.jsxs("label",{className:"authField",children:[n.jsx("span",{children:"Email"}),n.jsx("input",{autoComplete:"email",disabled:E||y,enterKeyHint:"next",inputMode:"email",name:"email",onChange:We,placeholder:"[email protected]",type:"email",value:i})]}),n.jsxs("label",{className:"authField",children:[n.jsx("span",{children:"Password"}),n.jsxs("div",{className:"authPasswordControl",children:[n.jsx("input",{autoComplete:s==="create"?"new-password":"current-password",disabled:E||y,enterKeyHint:"go",name:"password",onChange:de=>{u(de.target.value),K()},placeholder:s==="create"?`At least ${Vu} characters`:"Your password",type:p?"text":"password",value:l}),n.jsx("button",{"aria-label":p?"Hide password":"Show password",disabled:E||y||!l,onClick:()=>m(de=>!de),type:"button",children:p?"Hide":"Show"})]})]}),N?n.jsx("p",{className:"authFieldError",role:"alert",children:N}):null,I?n.jsx("p",{className:"authFieldMessage",role:"status",children:I}):null,n.jsx("button",{className:"authPrimaryAction",disabled:E||y,type:"submit",children:re}),s==="signin"?L?n.jsx("button",{className:"authTextButton",disabled:E||y,onClick:J,type:"button",children:"Forgot password?"}):n.jsx("p",{className:"authFinePrint",children:Ns.passwordReset}):null]}),V?n.jsxs("div",{className:"authSocial","aria-label":"Other ways to continue",children:[n.jsx("div",{className:"authDivider",children:n.jsx("span",{children:"or"})}),_?n.jsxs("button",{"aria-busy":b?"true":"false",className:"authGoogleButton",disabled:y||b,onClick:Fe,type:"button",children:[n.jsx("img",{alt:"","aria-hidden":"true",className:"authGoogleLogo",src:CT}),n.jsx("span",{children:Z})]}):null,P?n.jsx("button",{className:"authGoogleButton",disabled:y,onClick:ke,type:"button",children:n.jsx("span",{children:"Continue with Apple"})}):null]}):null,s==="create"?n.jsxs("p",{className:"authFinePrint",children:["By creating an account you agree to the ",n.jsx("a",{href:tv,children:"Terms"}),". Our"," ",n.jsx("a",{href:_d,children:"Privacy Policy"})," explains how we use your data. Boards start private; you choose whether to publish, invite collaborators, or share a link."]}):null]})]})}function aE({completeAuthCallback:e,monochromeEnabled:t=!1,onToggleTheme:r,theme:a="light"}
32){const[s,o]=d.useState("Finishing sign-in..."),[i,c]=d.useState("");return d.useEffect(()=>{let l=!0;return(async()=>{const p=await e();if(l){if(p.error){c(p.error),o(p.recovery?"Password reset link could not be completed.":"Sign-in could not be completed.");return}if(p.recovery){o("Choose a new password."),window.setTimeout(()=>Ft("/account/reset-password"),500);return}Si(Da.accountAuthenticated),o("Signed in. Returning to Account..."),window.setTimeout(()=>Ft("/account"),500)}})(),()=>{l=!1}},[e]),n.jsx(vb,{headline:i?"Sign-in could not be completed.":s,monochromeEnabled:t,onToggleTheme:r,supporting:i?"Return to sign in and try again.":"One moment while we finish signing you in.",theme:a,withIntro:!1,children:i?n.jsxs("div",{className:"authConfirmState",children:[n.jsx("p",{className:"authFieldError",role:"alert",children:i}),n.jsx("button",{className:"authPrimaryAction",onClick:()=>Ft("/account"),type:"button",children:"Back to sign in"})]}):n.jsxs("p",{className:"authPendingState",role:"status",children:[n.jsx("span",{className:"authPendingDot","aria-hidden":"true"}),s]})})}function sE({auth:e,monochromeEnabled:t=!1,onToggleTheme:r,theme:a="light"}){const[s,o]=d.useState(""),[i,c]=d.useState(""),[l,u]=d.useState(!1),[p,m]=d.useState(""),[f,h]=d.useState(""),[b,v]=d.useState(!1),S=!!(e.passwordRecoveryIsActive&&e.user?.id),C=!e.loading&&!S&&!b,I=e.loading;if(!Mm.passwordResetEnabled)return n.jsx(vb,{headline:"Password reset unavailable",monochromeEnabled:t,onToggleTheme:r,supp
32orting:Ns.passwordReset,theme:a,withIntro:!1,children:n.jsx("div",{className:"authConfirmState",children:n.jsx("button",{className:"authPrimaryAction",onClick:()=>Ft("/account"),type:"button",children:"Back to sign in"})})});const A=()=>{m(""),h(""),e.clearAuthError()},k=()=>{e.clearPasswordRecovery?.(),Ft("/account")},E=async y=>{if(y.preventDefault(),A(),!s){h("Enter a new password.");return}if(s.length<Vu){h(`Use at least ${Vu} characters for your password.`);return}if(s!==i){h("Passwords do not match.");return}const N=await e.completePasswordReset(s);if(N.error){h(N.error);return}o(""),c(""),u(!1),v(!0),m("Password updated. You can now sign in with your new password.")};return n.jsx(vb,{headline:b?"Password updated.":e.loading?"Checking your link.":C?"That link has expired.":"Choose a new password.",monochromeEnabled:t,onToggleTheme:r,supporting:b?"You can sign in with it now.":e.loading?"One moment while Saveboard verifies this reset link.":C?"Request a new reset link and try again.":"Pick something only you would use.",theme:a,withIntro:!1,children:e.loading&&!b?n.jsxs("p",{className:"authPendingState",role:"status",children:[n.jsx("span",{className:"authPendingDot","aria-hidden":"true"}),"Checking reset link"]}):C?n.jsx("div",{className:"authConfirmState",children:n.jsx("button",{className:"authPrimaryAction",onClick:k,type:"button",children:"Back to sign in"})}):b?n.jsx("div",{className:"authConfirmState",children:n.jsx("button",{className:"authPrimaryAction",onClick:k,type:"button",children:"Continue to Saveboard"})}):n.jsxs("form",{className:"authForm",noValidate:!0,onSubmit:E,children:[n.jsxs("label",{className:"authField",children:[n.jsx("span",{children:"New password"}),n.jsxs("div",{className:"authPasswordControl",children:[n.jsx("input",{autoComplete:"new-password",disabled:I,enterKeyHint:"next",name:"new-password",onChange:y=>{o(y.target.value),A()},placeholder:`At least ${Vu} characters`,type:l?"text":"password",value:s}),n.jsx("button",{"aria-label":l?"Hide password":"Show password",disabled:I||!s,onClick:()=>u(y=>!y),type:"button",children:l?"Hide":"Show"})]})]}),n.jsxs("label",{className:"authField",children:[n.jsx("span",{children:"Confirm new password"}),n.jsx("input",{autoComplete:"new-password",disabled:I,enterKeyHint:"go",name:"confirm-new-password",onChange:y=>{c(y.target.value),A()},placeholder:"Repeat your new password",type:l?"text":"password",value:i})]}),f||e.authError?n.jsx("p",{className:"authFieldError",role:"alert",children:f||e.authError}):null,p?n.jsx("p",{className:"authFieldMessage",role:"status",children:p}):null,n.jsx("button",{className:"authPrimaryAction",disabled:I,type:"submit",children:I?"Updating...":"Update password"}),n.jsx("button",{className:"authTextButton",disabled:I,onClick:k,type:"button",children:"Back to sign in"})]})})}function Yq({className:e=""}){return n.jsxs("svg",{"aria-hidden":"true",className:e,fill:"none",focu
32sable:"false",viewBox:"0 0 24 24",children:[n.jsx("rect",{height:"16",rx:"4.5",stroke:"currentColor",strokeWidth:"1.6",width:"16",x:"4",y:"4"}),n.jsx("path",{d:"m8.5 12 2.5 2.5 4.5-5",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"1.6"})]})}function Kq({className:e=""}){return n.jsx("svg",{"aria-hidden":"true",className:e,fill:"none",focusable:"false",viewBox:"0 0 24 24",children:n.jsx("path",{d:"M8 4v14M8 4 5 7M8 4l3 3M16 20V6M16 20l-3-3M16 20l3-3",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"1.6"})})}function Xq({className:e=""}){return n.jsxs("svg",{"aria-hidden":"true",className:e,fill:"none",focusable:"false",viewBox:"0 0 24 24",children:[n.jsx("circle",{cx:"11",cy:"11",r:"6.5",stroke:"currentColor",strokeWidth:"1.7"}),n.jsx("path",{d:"m20 20-4.5-4.5",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"1.7"})]})}function Jq({className:e=""}){return n.jsx("svg",{"aria-hidden":"true",className:e,fill:"none",focusable:"false",viewBox:"0 0 24 24",children:n.jsx("path",{d:"M12 5v14M5 12h14",stroke:"currentColor",strokeLinecap:"round",strokeWidth:"1.9"})})}function Qq({capabilities:e=jl,contextLabel:t="",shareList:r,onPreviewShare:a,activeListRecord:s,onEditList:o,onEditBoardCover:i,onDeleteList:c,onMoveList:l,canDeleteList:u,onCopyWishlistText:p,onCopyProductLinks:m,onOpenProductLinks:f,onExportCsv:h,listActionMessage:b,onEnterManage:v,onAddProduct:S}){const C=d.useRef(null),I=d.useRef(null);d.useEffect(()=>{const k=()=>{C.current?.open&&(C.current.open=!1)},E=N=>{C.current?.open&&!C.current.contains(N.target)&&k()},y=N=>{N.key!=="Escape"||!C.current?.open||pg()||(N.preventDefault(),k(),I.current?.focus())};return document.addEventListener("pointerdown",E),window.addEventListener("keydown",y),()=>{document.removeEventListener("pointerdown",E),window.removeEventListener("keydown",y)}},[]);const A=e.canReorderItems||e.canDeleteItems||e.canMoveItemsBetweenBoards;return n.jsxs("div",{className:"listToolbarActions","aria-label":"Board actions",children:[t?n.jsx("span",{className:"boardContextLabel",children:t}):null,A?n.jsxs("button",{"aria-label":"Select items",className:"manageModeButton toolbarIconButton",onClick:v,title:"Select items",type:"button",children:[n.jsx(Yq,{className:"toolbarManageIcon"}),n.jsx("span",{className:"toolbarSrOnly",children:"Select items"})]}):null,r&&e.canManageBoard?n.jsxs("button",{"aria-label":"Share board",className:"sharePreviewButton toolbarIconButton",onClick:()=>a(r),title:"Share board",type:"button",children:[n.jsxs("svg",{className:"toolbarShareIcon","aria-hidden":"true",viewBox:"0 0 24 24",fill:"none",children:[n.jsx("circle",{cx:"6",cy:"12",r:"2.4"}),n.jsx("circle",{cx:"17",cy:"6",r:"2.4"}),n.jsx("circle",{cx:"17",cy:"18",r:"2.4"}),n.jsx("path",{d:"m8.2 10.9 6.6-3.8M8.2 13.1l6.6 3.8"})]}),n.jsx("span",{className:"toolbarSrOnly",children:"Share board"})]}):null,n.jsxs("details",{className:"listActionsMenu",ref:C,children:[n.jsxs("summary",{"aria-label":"Board settings",ref:I,title:"Board settings",children:[n.jsxs("svg",{className:"toolbarGearIcon","aria-hidden":"true",viewBox:"0 0 24 24",fill:"none",children:[n.jsx("path",{d:"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"}),n.jsx("circle",{cx:"12",cy:"12",r:"3.2"})]}),n.jsx("span",{className:"toolbarSrOnly",children:"Board settings"})]}),n.jsxs("div",{"aria-label":"Board settings",className:"saveboardMenuPanel",role:"menu",children:[n.jsx("button",{"aria-label":"Close board settings",className:"phonePopoverClose",onClick:()=>{C.current&&(C.current.open=!1)},type:"button",children:"Close"}),s&&e.canManageBoard?n.jsxs(n.Fragment,{children:[n.jsx("button",{className:"saveboardMenuRow",onClick:()=>o(s),role:"menuitem",type:"button",children:"Edit board"}),n.jsx("button",{className:"saveboardMenuRow",onClick:()=>i(s),role:"menuitem",type:"button",children:"Edit board cover"}),n.jsx("button",{className:"saveboardMenuRow",onClick:()=>l(s,"up"),role:"menuitem",type:"button",children:"Move up"}),n.jsx("button",{className:"saveboardMenuRow",onClick:()=>l(s,"down"),role:"menuitem",type:"button",children:"Move down"}),u?n.jsx("button",{className:"saveboardMenuRow saveboardMenuDangerRow",onClick:()=>c(s),role:"menuitem",type:"button",children:"Delete board"}):null]}):null,n.jsx("button",{className:"saveboardMenuRow",onClick:p,role:"menuitem",type:"button",children:"Copy wishlist text"}),n.jsx("button",{className:"saveboardMenuRow",onClick:m,role:"menuitem",type:"button",children:"Copy product links"}),n.jsx("button",{className:"saveboardMenuRow",onClick:f,role:"menuitem",type:"button",children:"Open all product links"}),n.jsx("button",{className:"saveboardMenuRow",onClick:h,role:"menuitem",type:"button",children:"Export CSV"})]}),b?n.jsx("p",{children:b}):null]}),e.canAddItems?n.jsx("button",{"aria-label":"Add item",className:"toolbarAddButton",onClick:S,title:"Add item",type:"button",children:n.jsx(Jq,{className:"toolbarAddIcon"})}):null]})}function Zq({capabilities:e=jl,selectedCount:t,totalCount:r,lists:a,activeListRecord:s,onDone:o,onMove:i,onFitImages:c,fitImagesIsPending:l,onMarkPurchased:u,onArchive:p,onDelete:m,onSelectAll:f,onClearSelection:h}){const b=t>0,v=a.filter(C=>C.id!==s?.id),S=l||!b;return n.jsxs("div",{"aria-busy":l?"true":void 0,className:"manageToolbar","aria-label":"Manage products",children:[n.jsxs("div",{className:"manageToolbarPrimary",children:[n.jsx("button",{className:"manageDoneButton",disabled:l,onClick:o,type:"button",children:"Done"}),n.jsx("span",{className:"manageSelectedCount","aria-live":"polite",children:b?`${t} selected`:"Select products"})]}),n.jsxs("div",{className:"manageToolbarActions",children:[e.canMoveItemsBetweenBoards?n.jsxs("details",{className:`manageMoveMenu${!S&&v.length?"":" isDisabled"}`,children:[n.jsx("summary",{"aria-disabled":S||v.length===0,onClick:C=>{(S||v.length===0)&&C.preventDefault()},children:"Move"}),n.jsx("div",{children:v.map(C=>n.jsx("button",{disabled:l,onClick:I=>{I.currentTarget.closest("details")?.removeAttribute("open"),i(C.id)},type:"button",children:C.name},C.id))})]}):null,n.jsx("button",{"aria-label":"Fit selected images","aria-busy":l?"true":void 0,disabled:S,onClick:c,type:"button",children:l?"Fitting images...":"Fit images"}),n.jsx("button",{disabled:S,onClick:u,type:"button",children:"Mark purchased"}),n.jsx("button",{disabled:S,onClick:p,type:"button",children:"Archive"}),n.jsx("button",{className:"manageDangerAction",disabled:S,onClick:m,type:"button",children:"Delete"}),n.jsx("button",{disabled:l||r===0||t===r,onClick:f,type:"button",children:"Select all"}),n.jsx("button",{disabled:S,onClick:h,type:"button",children:"Clear"})]})]})}function eY({query:e,onQueryChange:t,inputRef:r}){return n.jsxs("label",{className:"dashboardSearch",children:[n.jsx("span",{className:"toolbarSrOnly",children:"Search items"}),n.jsx(Xq,{className:"dashboardSearchIcon"}),n.jsx("input",{"aria-label":"Search items",onChange:a=>t(a.target.value),onKeyDown:a=>{a.key==="Escape"&&(a.preventDefault(),e?t(""):a.currentTarget.blur())},placeholder:"Search",ref:r,value:e})]})}function tY({panelId:e,summary:t,onClose:r}){const a=!!t?.pricedCount,s=a?`${t.isApproximate?"Approx. ":""}${t.totalText}`:"No prices yet",o=[{label:"Average",value:t?.averageText||"No prices"},{label:"Priced items",value:String(t?.pricedCount||0)},{label:"Unpriced items",value:String(t?.unpricedCount||0)},{label:"Range",value:t?.rangeText||"No range"}];return n.jsxs("div",{className:"priceSummaryPanel",id:e,role:"dialog","aria-label":"Pricing summary",children:[n.jsx("button",{className:"phonePopoverClose","aria-label":"Close pricing summary",onClick:r,type:"button",children:"Close"}),n.jsxs("div",{className:"priceSummaryPanelHeader",children:[n.jsx("span",{children:"Pricing summary"}),n.jsx("strong",{children:s}),n.jsx("p",{children:a?t.hasMixedCurrencies?"Totals are grouped by currency.":"Current saved item prices.":"Items with prices will appear in this summary."})]}),a?n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"priceSummaryMetricGrid","aria-label":"Board value metrics",children:o.map(i=>n.jsxs("div",{children:[n.jsx("span",{children:i.label}),n.jsx("strong",{children:i.value})]},i.label))}),n.jsxs("section",{className:"priceSummaryBreakdown","aria-label":"Currency breakdown",children:[n.jsxs("div",{className:"priceSummarySectionHeader",children:[n.jsx("h3",{children:"Currency breakdown"}),t.hasMixedCurrencies?n.jsx("span",{children:"Mixed currencies"}):null]}),n.jsx("div",{className:"priceSummaryCurrencyRows",children:t.currencyBreakdown.map(i=>n.jsxs("div",{className:"priceSummaryCurrencyRow",children:[n.jsx("span",{children:i.currency}),n.jsx("strong",{children:i.totalText}),n.jsxs("em",{children:[i.count," ",i.count===1?"item":"items"," · avg ",i.averageText,i.lowestText&&i.highestText?` · ${i.lowestText}-${i.highestText}`:""]})]},i.currency))})]})]}):n.jsxs("div",{className:"priceSummaryEmpty",children:[n.jsx("strong",{children:"No prices yet"}),n.jsx("p",{children:"Items with prices will appear in this summary."})]}),n.jsxs("section",{className:"priceSummaryChart","aria-label":"Price graph",children:[n.jsxs("div",{className:"priceSummarySectionHeader",children:[n.jsx("h3",{children:"Price distribution"}),t?.distributionBuckets?.length?n.jsx("span",{children:"Current prices"}):null]}),t?.distributionBuckets?.length?n.jsx("div",{className:"priceDistributionBars",children:t.distributionBuckets.map(i=>n.jsxs("div",{className:"priceDistributionBucket",children:[n.jsx("span",{"aria-label":`${i.label}: ${i.count} ${i.count===1?"item":"items"}`,style:{"--bar-size":`${i.percentage}%`}}),n.jsx("strong",{children:i.count}),n.jsx("em",{children:i.label})]},i.label))}):n.jsxs("div",{className:"priceSummaryChartPlaceholder",children:[n.jsx("strong",{children:"Items with a price show their spread here."}),t?.hasMixedCurrencies?n.jsx("p",{children:"Current distribution is hidden for mixed currencies."}):null]})]})]})}
32function rY({value:e,onChange:t,priceSummary:r}){const[a,s]=d.useState(!1),[o,i]=d.useState(!1),[c,l]=d.useState(0),u=d.useRef(null),p="list-price-summary-panel",m=Object.entries(Um),f=Math.max(0,m.findIndex(([C])=>C===e)),h=Um[e]||Um.manual;d.useEffect(()=>{if(!a&&!o)return;a&&l(f);const C=I=>{u.current?.contains(I.target)||(s(!1),i(!1))};return window.addEventListener("pointerdown",C),()=>window.removeEventListener("pointerdown",C)},[a,o,f]);const b=C=>{t(C),s(!1)},v=C=>{if(!a&&["ArrowDown","ArrowUp","Enter"," "].includes(C.key)){C.preventDefault(),i(!1),s(!0);return}if(a){if(C.key==="Escape"){C.preventDefault(),s(!1);return}if(C.key==="ArrowDown"||C.key==="ArrowUp"){C.preventDefault(),l(I=>{const A=C.key==="ArrowDown"?1:-1;return(I+A+m.length)%m.length});return}(C.key==="Enter"||C.key===" ")&&(C.preventDefault(),b(m[c]?.[0]||e))}},S=C=>{C.key==="Escape"&&(a||o)&&(C.preventDefault(),s(!1),i(!1))};return n.jsxs("div",{className:"sortControl",onKeyDown:S,ref:u,children:[n.jsxs("button",{"aria-expanded":a,"aria-haspopup":"listbox","aria-label":`Sort products, current option ${h}`,className:"sortTrigger",onClick:()=>{i(!1),s(C=>!C)},onKeyDown:v,title:h,type:"button",children:[n.jsx(Kq,{className:"toolbarSortIcon"}),n.jsx("span",{className:"toolbarSrOnly",children:h})]}),n.jsxs("div",{className:"priceSummaryControl",children:[n.jsx("button",{"aria-controls":o?p:void 0,"aria-expanded":o,"aria-haspopup":"dialog","aria-label":"Show pricing summary",className:`sortQuickButton sortQuickButton-price${o?" isActive":""}`,onClick:()=>{s(!1),i(C=>!C)},title:"Show pricing summary",type:"button",children:n.jsx("span",{children:"£"})}),o?n.jsx(tY,{panelId:p,summary:r,onClose:()=>{i(!1),u.current?.querySelector(".sortQuickButton-price")?.focus()}}):null]}),a?n.jsx("div",{className:"sortMenu",role:"listbox","aria-label":"Sort products",children:m.map(([C,I],A)=>n.jsx("button",{"aria-selected":e===C,className:`${e===C?"isActive":""}${A===c?" isHighlighted":""}`,onClick:()=>b(C),onMouseEnter:()=>l(A),role:"option",type:"button",children:I},C))}):null]})}function od({message:e,monochromeEnabled:t=!1,onDismiss:r}){return e?n.jsxs("div",{className:`systemNotice${t?" monochromeMode":""}`,role:"status",children:[n.jsx("span",{children:e}),n.jsx("button",{type:"button",onClick:r,children:"Dismiss"})]}):null}function vm({title:e,subtitle:t,actionLabel:r,onAction:a,variant:s="default"}){return n.jsxs("div",{className:`dashboardEmptyState ${s==="search"?"searchEmptyState":"firstUseEmptyState"}`,children:[n.jsx("p",{children:e}),t?n.jsx("span",{children:t}):null,r?n.jsx("button",{onClick:a,type:"button",children:r}):null]})}function id({enabled:e}){const t=d.useRef(null);return d.useEffect(()=>{const r=t.current;if(!r||typeof window>"u")return;const a=window.matchMedia("(pointer: fine)"),s=window.matchMedia("(prefers-reduced-motion: reduce)");let o=0,i=!1,c=0,l=0,u=null;const p=()=>{i=!!(e&&a.matches&&!s.matches),document.documentElement.classList.toggle("myListCustomCursor",i),r.style.opacity="0",u=null},m=()=>{o=0,r.style.transform=`translate3d(${c-4}px, ${l-4}px, 0) scale(var(--cursor-scale, 1))`},f=S=>{if(!i)return;u=S;const C=!!S?.closest?.("textarea, input:not([type]), input[type='text'], input[type='search'], input[type='url'], input[type='email'], input[type='tel'], input[type='password'], input[type='number'], [contenteditable='true'], [contenteditable='']"),I=!!S?.closest?.("a, button, summary, select, input[type='range'], input[type='file'], [role='button'], .emptyPod, .productPod, .productPodMedia, .modalLayer, .modalImageInput, .listPodSurface, .gridPreferenceControl, .sortControl, .listActionsMenu, .settingsPanel, .settingsButtonGroup, .settingsActionGrid, .settingsActionRow, .commandPaletteList button");r.classList.toggle("isHidden",C),r.classList.toggle("isInteractive",!C&&I)},h=S=>{if(!i||S.pointerType&&S.pointerType!=="mouse")return;c=S.clientX,l=S.clientY,S.target!==u&&f(S.target);const C=r.classList.contains("isHidden")?"0":"1";r.style.opacity!==C&&(r.style.opacity=C),o||(o=window.requestAnimationFrame(m))},b=S=>{f(S.target)},v=()=>{r.style.opacity="0"};return p(),window.addEventListener("pointermove",h,{passive:!0}),window.addEventListener("pointerover",b,{passive:!0}),window.addEventListener("pointerout",b,{passive:!0}),window.addEventListener("blur",v),document.documentElement.addEventListener("mouseleave",v),a.addEventListener("change",p),s.addEventListener("change",p),()=>{window.cancelAnimationFrame(o),document.documentElement.classList.remove("myListCustomCursor"),window.removeEventListener("pointermove",h),window.removeEventListener("pointerover",b),window.removeEventListener("pointerout",b),window.removeEventListener("blur",v),document.documentElement.removeEventListener("mouseleave",v),a.removeEventListener("change",p),s.removeEventListener("change",p)}},[e]),e?n.jsx("span",{className:"customCursorDot",ref:t,"aria-hidden":"true"}):null}function nY({contextLabel:e="",createdAt:t,listName:r,priceSummary:a,productC
32ount:s}){return[r,e,`${s} ${s===1?"item":"items"}`,a?.totalText?`${a.isApproximate?"Approx. ":"Total "}${a.totalText}`:"",t?`Created ${t}`:""].filter(Boolean)}function aY({items:e}){return n.jsx("div",{className:"listEditorialMetadata",children:e.map(t=>n.jsx("span",{children:t},t))})}function sY({contextLabel:e="",createdAt:t,listName:r,priceSummary:a,productCount:s}){const o=nY({contextLabel:e,createdAt:t,listName:r,priceSummary:a,productCount:s});return o.length===0?null:n.jsx("div",{className:"listEditorialFooter","aria-label":"Board information",children:n.jsx(aY,{items:o})})}function oY({authenticatedOwnerId:e="",authenticatedUsername:t="",list:r,existingLists:a=[],protectedName:s=!1,boardTheme:o="",showBoardTheme:i=!1,onBoardThemeChange:c,onSubmit:l,onCancel:u,onDirtyChange:p}){const m=!!r,[f,h]=d.useState({name:r?.name??"",description:r?.description??"",publicDescription:r?.publicDescription??"",isPrivate:r?!r.isPublic:!0}),[b,v]=d.useState(""),[S,C]=d.useState(!1),[I,A]=d.useState([]),[k,E]=d.useState(!1),[y,N]=d.useState(!1),[_,P]=d.useState(""),V=d.useRef(f);d.useEffect(()=>{p?.(JSON.stringify(f)!==JSON.stringify(V.current))},[f,p]),d.useEffect(()=>()=>p?.(!1),[p]);const L=D=>{const{name:K,value:ee}=D.target;h(J=>({...J,[K]:ee})),K==="name"&&v("")},z=D=>{!D?.userId&&D?.kind!=="exact"||D.userId===e||D.username===t||(A(K=>K.some(ee=>D.userId&&ee.userId===D.userId||ee.username===D.username)?K:[...K,D]),v(""),P(""))},B=!!Ye(f.name),re=k||y||!m&&!B,Z=async D=>{if(D.preventDefault(),k||y)return;const K=Ye(f.name);if(!K){v("Board name is required.");return}if(!!yu(a,K,{authenticatedOwnerId:e,excludeListId:r?.id})){v("You already have an active board with this name.");return}const J=!m&&S?I:[];v(""),P(""),E(!0);try{const De=(await l({name:K,description:f.description.trim(),...m?{}:{isPublic:!f.isPrivate},publicDescription:f.publicDescription.trim()},{waitForCloud:J.length>0}))?.createdList||null;if(!m&&J.length>0){if(!De?.id){N(!0),P("Board was created, but invites could not be sent. Open Share later to invite collaborators.");return}const Be=[];for(const Fe of J){const ke=Fe.kind==="exact"?await Lk(De.id,Fe.username):await GO(De.id,Fe.userId);ke.ok||Be.push(ke.error||`Could not invite @${Fe.username}.`)}if(Be.length>0){N(!0),P(`Board was created, but ${Be.length===1?"one invite failed":"some invites failed"}. ${Be[0]}`);return}}u()}catch{v(m?"Could not save this board.":"Could not create this board.")}finally{E(!1)}};return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"list-modal-title","aria-modal":"true",className:`listModal${m?"":" createBoardModal"}`,role:"dialog",children:[n.jsxs("div",{className:`modalHeader${m?"":" createBoardModalHeader"}`,children:[n.jsx("h2",{id:"list-modal-title",children:m?"Edit Board":"Create a board"}),m?null:n.jsx("button",{"aria-label":"Close Create Board",className:"createBoardCloseButton",onClick:u,type:"button",children:n.jsx("span",{"aria-hidden":"true",children:"X"})})]}),n.jsxs("form",{autoComplete:"off",className:"listModalForm",onSubmit:Z,children:[n.jsxs("label",{className:m?"":"createBoardNameField",children:[n.jsx("span",{children:"Board name"}),n.jsx("input",{autoComplete:"off",autoCorrect:"off",autoFocus:!0,disabled:s,name:"name",onChange:L,placeholder:m?"":"Name your board",required:!0,value:f.name}),s?n.jsx("small",{children:"Default board names are protected in this local prototype."}):null,b?n.jsx("em",{children:b}):null]}),m?n.jsxs(n.Fragment,{children:[n.jsxs("label",{children:[n.jsx("span",{children:"Description"}),n.jsx("small",{children:"Private note for this board."}),n.jsx("textarea",{autoComplete:"off",name:"description",onChange:L,rows:"3",value:f.description})]}),n.jsxs("label",{children:[n.jsx("span",{children:"Public description"}),n.jsx("small",{children:"May appear on the share preview."}),n.jsx("textarea",{autoComplete:"off",name:"publicDescription",onChange:L,rows:"3",value:f.publicDescription})]}),i?n.jsxs("div",{className:"listModalBoardColour",children:[n.jsx("span",{children:"Theme"}),n.jsx("small",{children:"The artwork behind this board's cover. Saved on this device only, so it may not sync between devices."}),n.jsx("div",{"aria-label":"Board theme",className:"boardThemeGroup",role:"radiogroup",children:pp.map(D=>{const K=o===D,ee=`${D[0].toUpperCase()}${D.slice(1)}`;return n.jsxs("button",{"aria-checked":K,className:`boardThemeButton${K?" isActive":""}`,onClick:()=>c?.(D),role:"radio",type:"button",children:[n.jsx("span",{"aria-hidden":"true",className:`boardThemeSwatch ${fL[D]}`}),n.jsx("span",{className:"boardThemeName",children:ee})]},D)})})]}):null]}):n.jsxs("section",{className:"createBoardPrivacyRow","aria-label":"Board privacy",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Private board"}),n.jsx("p",{children:"New boards start private. Invite collaborators, share a link that anyone holding it can open after signing in, or publish the board on your public profile."})]}),n.jsx("button",{"aria-checked":f.isPrivate,"aria-label":"Private board",className:"createBoardPrivacySwitch",onClick:()=>h(D=>({...D,isPrivate:!D.isPrivate})),role:"switch",type:"button",children:n.jsx("span",{"aria-hidden":"true"})})]}),m?null:n.jsxs("section",{className:`createBoardGroupFlow${S?" isOpen":""}`,"aria-label":"Group board",children:[n.jsxs("button",{"aria-expanded":S,className:"createBoardGroupToggle",onClick:()=>{C(D=>!D),v(""),P("")},type:"button",children:[n.jsxs("span",{children:[n.jsx("strong",{children:"Group board"}),n.jsx("small",{children:"Build this board with other people"})]}),n.jsx("span",{className:"createBoardGroupIcon","aria-hidden":"true",children:n.jsxs("svg",{viewBox:"0 0 24 24",focusable:"false",children:[n.jsx("circle",{cx:"10",cy:"7",r:"3.2"}),n.jsx("path",{d:"M4.5 19.5c.45-3.4 2.55-5.1 6.3-5.1 1.55 0 2.85.3 3.9.9"}),n.jsx("path",{d:"M17.5 12.5v7"}),n.jsx("path",{d:"M14 16h7"})]})})]}),S?n.jsxs("div",{className:"createBoardInvitePanel",children:[n.jsx("span",{children:"Invite collaborators"}),n.jsx(aM,{currentUserId:e,currentUsername:t,addedUsers:I,disabled:k||y,onAdd:z}),I.length>0?n.jsx("div",{className:"createBoardInviteChips","aria-label":"Collaborators to invite",children:I.map(D=>n.jsxs("button",{"aria-label":`Remove @${D.username}`,disabled:k||y,onClick:()=>A(K=>K.filter(ee=>ee!==D)),type:"button",children:[D.kind==="exact"?n.jsxs("span",{className:"collaboratorIdentity",children:[n.jsxs("strong",{children:["@",D.username]}),n.jsx("small",{children:"Exact username · not verified"})]}):n.jsx(TS,{person:D}),n.jsx("span",{className:"collaboratorContext",children:D.kind==="exact"?"Queued":"Added"}),n.jsx("span",{"aria-hidden":"true",children:"×"})]},D.userId||`exact:${D.username}`))}):null]}):null]}),_?n.jsx("p",{className:"createBoardFlowMessage isError",role:"status",children:_}):null,n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{className:m?"":"createBoardSubmitButton",disabled:re,type:"submit",children:k?m?"Saving...":"Creating...":m?"Save board":"Create"}),m?n.jsx("button",{type:"button",onClick:u,children:"Cancel"}):null]})]})]})})}function iY({board:e,currentUserId:t="",currentUsername:r="",isSaving:a=!1,manualShareUrl:s="",message:o="",onCancel:i,onCopyBoardLink:c,onCopyQrPng:l,onDownloadQrPng:u,onGenerateQrCode:p,onRevokePrivateLink:m,hasPrivateLink:f=!1,onMakePublicAndCopy:h,onOpenProfile:b,onViewPublicBoard:v,publishPrerequisiteMessage:S="",publicUrl:C="",qrCodeDataUrl:I="",qrError:A="",qrIsLoading:k=!1}
32){const E=String(e?.id||"").trim(),[y,N]=d.useState(!1),_="Collaborators are available after this board is synced.",[P,V]=d.useState(!1),[L,z]=d.useState(""),[B,re]=d.useState("editor"),[Z,D]=d.useState(""),[K,ee]=d.useState({actionError:"",actionMessage:"",collaborationIsAvailable:null,collaborators:[],invites:[],isLoading:!1,pendingAction:""});d.useEffect(()=>{V(!1),z(""),re("editor"),D(""),ee({actionError:"",actionMessage:"",collaborationIsAvailable:null,collaborators:[],invites:[],isLoading:!1,pendingAction:""})},[E]);const J=d.useCallback(async()=>{if(!E)return!1;const W=await ZO(E);return W.available?(ee(Le=>({...Le,actionError:"",collaborationIsAvailable:!0})),!0):(ee(Le=>({...Le,actionError:W.ok?"":W.error||"Could not check board collaboration.",actionMessage:"",collaborationIsAvailable:!1,collaborators:[],invites:[],isLoading:!1,pendingAction:""})),!1)},[E,_]),fe=d.useCallback(async()=>{if(E){ee(W=>({...W,actionError:"",isLoading:!0}));try{if(!await J())return;const[Le,et]=await Promise.all([JO(E,t),Bk()]),pt=(et.invites||[]).filter(pe=>DG(pe,r)&&pe.boardId===E&&vL(pe)),$t=(Le.collaborators||[]).filter(pe=>pe.status==="active");ee(pe=>({...pe,actionError:Le.error||et.error||"",collaborators:$t,invites:pt,isLoading:!1}))}catch{ee(W=>({...W,actionError:"Could not load collaborators.",isLoading:!1}))}}},[E,t,r,J]);if(!e)return null;const De=e.isPublic===!0,Be=K.collaborationIsAvailable!==!1,Fe=K.collaborators.length>0,ke=K.invites.length>0,We=()=>{V(!0),fe()},de=async W=>{if(W.preventDefault(),!(!E||K.pendingAction)){ee(Le=>({...Le,actionError:"",actionMessage:"",pendingAction:"invite"}));try{if(!await J())return;const et=await Lk(E,L,B);if(!et.ok){ee(pt=>({...pt,actionError:et.error||"Could not send this invite.",pendingAction:""}));return}z(""),ee(pt=>({...pt,actionMessage:`Invited as ${yi(B).label}. They will see it in Saveboard.`,pendingAction:""})),await fe()}catch{ee(Le=>({...Le,actionError:"Could not send this invite.",pendingAction:""}))}}},ye=async(W,Le)=>{if(!(!W?.collaboratorUserId||K.pendingAction||W.role===Le)){D(""),ee(et=>({...et,actionError:"",actionMessage:"",pendingAction:W.collaboratorUserId}));try{if(!await J())return;const pt=await QO(E,W.collaboratorUserId,Le);if(!pt.ok){ee($t=>({...$t,actionError:pt.error||"Could not change this collaborator's role.",pendingAction:""}));return}ee($t=>({...$t,actionMessage:`${Wu(W.profile)} is now ${yi(Le).label==="Editor"?"an Editor":"a Viewer"}.`,pendingAction:""})),await fe()}catch{ee(et=>({...et,actionError:"Could not change this collaborator's role.",pendingAction:""}))}}},ge=async W=>{if(!(!W?.id||K.pendingAction)){if(Z!==W.id){D(W.id);return}D(""),ee(Le=>({...Le,actionError:"",actionMessage:"",pendingAction:W.id}));try{if(!await J())return;const et=await KO(W.id);if(!et.ok){ee(pt=>({...pt,actionError:et.error||"Could not revoke this invite.",pendingAction:""}));return}ee(pt=>({...pt,actionMessage:"Invite revoked.",pendingAction:""})),await fe()}catch{ee(Le=>({...Le,actionError:"Could not revoke this invite.",pendingAction:""}))}}},ze=async W=>{if(!(!W?.collaboratorUserId||K.pendingAction)){if(Z!==W.collaboratorUserId){D(W.collaboratorUserId);return}D(""),ee(Le=>({...Le,actionError:"",actionMessage:"",pendingAction:W.collaboratorUserId}));try{if(!await J())return;const et=await XO(E,W.collaboratorUserId);if(!et.ok){ee(pt=>({...pt,actionError:et.error||"Could not remove this collaborator.",pendingAction:""}));return}ee(pt=>({...pt,actionMessage:"Collaborator removed.",pendingAction:""})),await fe()}catch{ee(Le=>({...Le,actionError:"Could not remove this collaborator.",pendingAction:""}))}}};return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"board-share-title","aria-modal":"true",className:"listModal boardShareModal",role:"dialog",children:[n.jsxs("div",{className:"modalHeader boardShareModalHeader",children:[n.jsx("h2",{id:"board-share-title",children:"Share Board"}),n.jsx("button",{"aria-label":"Close Share Board",className:"boardShareCloseButton",disabled:a,onClick:i,type:"button",children:n.jsx("span",{"aria-hidden":"true",children:"X"})})]}),De&&S?n.jsxs("p",{className:"boardShareMessage boardSharePrerequisite",children:["This board is set to public, but it has no public link yet. ",S]}):null,De?null:n.jsx("p",{className:"boardShareMessage",children:"Anyone with the private link or its QR code can request access to this board, but must sign in to SaveBoard first. They can see your username, display name and avatar. Links can be forwarded and remain active when your profile is private. There is no automatic link expiry: the link remains valid until you revoke it here. You can create a new link afterward. Private notes are not shared."}),n.jsx("div",{className:"boardShareActions",children:De&&S?n.jsx("button",{className:"boardSharePrimaryAction",disabled:a,onClick:b,type:"button",children:"Open profile"}):De?n.jsxs(n.Fragment,{children:[n.jsx("button",{className:"boardSharePrimaryAction",disabled:a,onClick:c,type:"button",children:"Copy link"}),n.jsx("button",{disabled:a,onClick:v,type:"button",children:"View public board"})]}):n.jsx(n.Fragment,{children:n.jsx("button",{className:"boardSharePrimaryAction",disabled:a,onClick:c,type:"button",children:a?"Creating link...":"Copy private link"})})}),f?n.jsx("div",{className:"boardShareMessage",children:y?n.jsxs(n.Fragment,{children:[n.jsx("p",{children:"Anyone using the current private link will lose access. You can create a new link afterward."}),n.jsx("button",{disabled:a,onClick:async()=>{await m(),N(!1)},type:"button",children:"Confirm revoke link"}),n.jsx("button",{disabled:a,onClick:()=>N(!1),type:"button",children:"Cancel"})]}):n.jsx("button",{disabled:a,onClick:()=>N(!0),type:"button",children:"Revoke link"})}):null,!De&&s?n.jsx("input",{"aria-label":"Private board share link",className:"boardShareQrUrl",onFocus:W=>W.currentTarget.select(),readOnly:!0,value:s}):null,n.jsx(XB,{boardId:E,isPublic:De}),n.jsxs("section",{className:"boardShareQrPanel","aria-label":"Board QR code",children:[n.jsx("button",{className:"boardShareQrGenerateButton",disabled:a||k,onClick:p,type:"button",children:k?"Generating QR code...":"Generate QR code"}),A?n.jsx("p",{className:"boardShareQrMessage",children:A}):null,I?n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"boardShareQrCode",children:n.jsx("img",{alt:`QR code for ${e.name}`,src:I})}),n.jsxs("div",{className:"boardShareQrActions",children:[n.jsx("button",{disabled:a||!I,onClick:l,type:"button",children:"Copy QR PNG"}),n.jsx("button",{disabled:a||!I,onClick:u,type:"button",children:"Download QR PNG"})]})]}):null]}),n.jsxs("section",{className:`boardCollaborationPanel${P?" isOpen":""}`,"aria-busy":K.isLoading?"true":"false","aria-label":"Board collaborators",children:[n.jsxs("button",{"aria-expanded":P,className:"boardCollaborationToggle createBoardGroupToggle",onClick:We,type:"button",children:[n.jsxs("span",{children:[n.jsx("strong",{children:"Invite collaborators"}),n.jsx("small",{children:"Build this board with other people"})]}),n.jsx("span",{className:"createBoardGroupIcon","aria-hidden":"true",children:n.jsxs("svg",{viewBox:"0 0 24 24",focusable:"false",children:[n.jsx("circle",{cx:"10",cy:"7",r:"3.2"}),n.jsx("path",{d:"M4.5 19.5c.45-3.4 2.55-5.1 6.3-5.1 1.55 0 2.85.3 3.9.9"}),n.jsx("path",{d:"M17.5 12.5v7"}),n.jsx("path",{d:"M14 16h7"})]})})]}),P?n.jsxs("div",{className:"boardCollaborationDrawer createBoardInvitePanel",children:[n.jsxs("div",{className:"boardCollaborationHeader",children:[n.jsx("span",{children:"Invite collaborators"}),n.jsx("button",{disabled:K.isLoading,onClick:fe,type:"button",children:"Refresh"})]}),K.isLoading?n.jsx("p",{className:"boardCollaborationMessage",role:"status",children:"Loading collaborators..."}):Be?n.jsxs(n.Fragment,{children:[n.jsxs("form",{className:"boardCollaborationForm createBoardInviteEntry hasRole",onSubmit:de,children:[n.jsx("input",{"aria-label":"Collaborator username",autoCapitalize:"none",autoComplete:"off",onChange:W=>
32z(W.target.value),placeholder:"Username, e.g. @jane",value:L}),n.jsx("select",{"aria-label":"Collaborator role",className:"boardCollaborationRoleSelect",onChange:W=>re(W.target.value),value:B,children:wI.map(W=>n.jsx("option",{value:W,children:yi(W).label},W))}),n.jsx("button",{disabled:a||K.pendingAction==="invite"||!L.trim(),type:"submit",children:K.pendingAction==="invite"?"Inviting...":"Invite"})]}),n.jsx("p",{className:"boardCollaborationHint",children:"Editors can add, edit, reorder and remove items. Viewers can only look. Only you can publish, rename or delete the board. Invites show your profile details and board title to the recipient. Private notes are not shared."}),n.jsxs("div",{className:"boardCollaborationList","aria-label":"Accepted collaborators",children:[n.jsx("span",{children:"Collaborators"}),Fe?K.collaborators.map(W=>{const Le=Wu(W.profile),et=K.pendingAction===W.collaboratorUserId,pt=Z===W.collaboratorUserId,$t=yi(W.role);return n.jsxs("article",{className:"boardCollaborationRow",children:[n.jsxs("div",{children:[n.jsx("strong",{children:Le}),n.jsx("small",{children:pt?`Remove ${Le} from this board?`:`${$t.label} · ${$t.summary}`})]}),n.jsx("div",{className:"boardCollaborationRowActions",children:pt?n.jsxs(n.Fragment,{children:[n.jsx("button",{disabled:et,onClick:()=>ze(W),type:"button",children:et?"Removing...":"Confirm removal"}),n.jsx("button",{disabled:et,onClick:()=>D(""),type:"button",children:"Keep"})]}):n.jsxs(n.Fragment,{children:[n.jsx("select",{"aria-label":`Role for ${Le}`,className:"boardCollaborationRoleSelect",disabled:et,onChange:pe=>ye(W,pe.target.value),value:W.role,children:wI.map(pe=>n.jsx("option",{value:pe,children:yi(pe).label},pe))}),n.jsx("button",{"aria-label":`Remove ${Le}`,disabled:et,onClick:()=>ze(W),type:"button",children:et?"Saving...":"Remove"})]})})]},W.collaboratorUserId)}):n.jsx("p",{children:"No collaborators yet."})]}),n.jsxs("div",{className:"boardCollaborationList","aria-label":"Pending collaborator invites",children:[n.jsx("span",{children:"Invited"}),ke?K.invites.map(W=>{const Le=Wu(W.invited),et=K.pendingAction===W.id,pt=Z===W.id,$t=Number.isFinite(Date.parse(W.expiresAt))?new Date(W.expiresAt).toLocaleDateString(void 0,{day:"numeric",month:"short"}):"";return n.jsxs("article",{className:"boardCollaborationRow",children:[n.jsxs("div",{children:[n.jsx("strong",{children:Le}),n.jsx("small",{children:pt?`Revoke the invite for ${Le}?`:`${yi(W.role).label} invite pending${$t?` · expires ${$t}`:""}`})]}),n.jsx("div",{className:"boardCollaborationRowActions",children:pt?n.jsxs(n.Fragment,{children:[n.jsx("button",{disabled:et,onClick:()=>ge(W),type:"button",children:et?"Revoking...":"Confirm revoke"}),n.jsx("button",{disabled:et,onClick:()=>D(""),type:"button",children:"Keep"})]}):n.jsx("button",{"aria-label":`Revoke invite for ${Le}`,disabled:et,onClick:()=>ge(W),type:"button",children:"Revoke"})})]},W.id)}):n.jsx("p",{children:"No invites pending."})]})]}):n.jsx("p",{className:"boardCollaborationMessage",role:"status",children:_}),K.actionMessage?n.jsx("p",{className:"boardCollaborationMessage",role:"status",children:K.actionMessage}):null,K.actionError?n.jsx("p",{className:"boardCollaborationMessage isError",role:"status",children:K.actionError}):null]}):null]}),o?n.jsx("p",{className:"boardShareMessage","aria-live":"polite",children:o}):null]})})}function cY({list:e,listOptions:t,onConfirm:r,onCancel:a}){const s=t.filter(C=>C.id!==e?.id),o=s.length>0,[i,c]=d.useState(o?"move":"replacement"),[l,u]=d.useState(s[0]?.id||""),[p,m]=d.useState("Wishlist"),[f,h]=d.useState("");if(d.useEffect(()=>{if(!e)return;const C=t.filter(I=>I.id!==e.id);c(C.length>0?"move":"replacement"),u(C[0]?.id||""),m("Wishlist"),h("")},[e?.id,t]),!e)return null;const b=f.trim().toUpperCase()==="DELETE",v=Ye(p).length>0,S=i==="move"&&!l||i==="replacement"&&!v||i==="delete"&&!b;return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"delete-list-title","aria-modal":"true",className:"deleteProductModal listDeleteModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"delete-list-title",children:"Delete Board"})}),n.jsxs("p",{children:["Choose what should happen to products in ",e.name,". Products will never be deleted silently."]}),n.jsxs("label",{children:[n.jsx("span",{children:"Products"}),n.jsxs("select",{onChange:C=>c(C.target.value),value:i,children:[o?n.jsx("option",{value:"move",children:"Move to another board"}):null,n.jsx("option",{value:"replacement",children:"Create replacement board"}),n.jsx("option",{value:"autoWishlist",children:"Move to Wishlist"}),n.jsx("option",{value:"archive",children:"Archive products"}),n.jsx("option",{value:"delete",children:"Delete products"})]})]}),i==="move"?n.jsxs("label",{children:[n.jsx("span",{children:"Move to"}),n.jsx("select",{onChange:C=>u(C.target.value),value:l,children:s.map(C=>n.jsx("option",{value:C.id,children:C.name},C.id))})]}):null,i==="replacement"?n.jsxs("label",{children:[n.jsx("span",{children:"Replacement board"}),n.jsx("input",{onChange:C=>m(C.target.value),value:p}),n.jsxs("small",{children:["Products from ",e.name," will move into this new board."]})]}):null,i==="autoWishlist"?n.jsxs("p",{children:["Products from ",e.name," will move into a Wishlist board."]}):null,i==="delete"?n.jsxs("label",{children:[n.jsx("span",{children:"Confirm delete products"}),n.jsx("input",{onChange:C=>h(C.target.value),placeholder:"Type DELETE",value:f}),n.jsx("small",{children:"This permanently deletes the board and its products."})]}):null,n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{onClick:()=>r({action:i,targetListId:l,replacementListName:Ye(p)}),disabled:S,type:"button",children:"Delete board"}),n.jsx("button",{onClick:a,type:"button",children:"Cancel"})]})]})})}function lY({itemCount:e=0,list:t,onCancel:r,onConfirm:a,state:s={}}
32){const[o,i]=d.useState(""),c=String(s.operation?.operationId||"");if(d.useEffect(()=>{i("")},[t?.id,c]),!t)return null;const l=e>0,u=!l||o.trim().toUpperCase()==="DELETE",p=s.status==="pending",m=s.status==="uncertain",f=s.status==="blocked",h=`${e} ${e===1?"item":"items"}`;return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"cloud-delete-list-title","aria-modal":"true",className:"deleteProductModal listDeleteModal cloudListDeleteModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"cloud-delete-list-title",children:"Delete Board"})}),n.jsxs("p",{children:["Delete ",n.jsx("strong",{children:t.name})," and its ",h," from your account?"]}),n.jsx("p",{children:"Public links and shared access to this board will stop. This action cannot currently be undone in SaveBoard."}),l?n.jsxs("label",{children:[n.jsx("span",{children:"Type DELETE to confirm"}),n.jsx("input",{autoComplete:"off",disabled:p,onChange:b=>i(b.target.value),placeholder:"DELETE",value:o})]}):null,s.message?n.jsx("p",{className:`cloudBoardDeleteMessage${s.status==="error"||m?" isError":""}`,role:s.status==="error"||m?"alert":"status",children:s.message}):null,n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{className:"cloudBoardDeleteConfirmButton",disabled:!u||p||f,onClick:a,type:"button",children:p?"Deleting…":m?"Retry delete":f?"Delete unavailable":"Delete board"}),n.jsx("button",{disabled:p,onClick:r,type:"button",children:"Cancel"})]})]})})}function dY({list:e,products:t=[],onSubmit:r,onCancel:a}){const s=d.useMemo(()=>t.filter(y=>hs(y,e)&&va(y.status)==="active").sort((y,N)=>{const _=Number.isFinite(y.sortOrder)?y.sortOrder:0,P=Number.isFinite(N.sortOrder)?N.sortOrder:0;return _-P}),[e?.id,e?.name,t]),o=d.useMemo(()=>new Set(s.map(y=>y.id)),[s]),i=d.useMemo(()=>hf(e?.coverItemIds).filter(y=>o.has(y)),[e?.coverItemIds,o]),[c,l]=d.useState(i),[u,p]=d.useState("");d.useEffect(()=>{l(i),p("")},[i]);const m=c.length,f=m>=zo,h=c.map(y=>s.find(N=>N.id===y)||null),b=Array.from({length:zo},(y,N)=>h[N]||null),v=s.some(y=>kn(y)),S=u||(f?"Remove an item to choose another.":""),C=y=>{l(N=>N.includes(y)?(p(""),N.filter(_=>_!==y)):N.length>=zo?(p("Deselect an item before adding another."),N):(p(""),[...N,y]))},I=y=>{l(N=>N.filter(_=>_!==y)),p("")},A=(y,N)=>{l(_=>{const P=_.indexOf(y),V=P+N;if(P===-1||V<0||V>=_.length)return _;const L=[..._];return[L[P],L[V]]=[L[V],L[P]],L}),p("")},k=()=>{r(c)},E=()=>{r([])};return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"board-cover-title","aria-modal":"true",className:"boardCoverModal",role:"dialog",children:[n.jsxs("div",{className:"modalHeader boardCoverHeader",children:[n.jsxs("div",{children:[n.jsx("h2",{id:"board-cover-title",children:"Board cover"}),n.jsx("p",{children:"Choose up to 4 items from this board to appear on the board cover."})]}),n.jsx("button",{"aria-label":"Close board cover picker",onClick:a,type:"button",children:"Close"})]}),n.jsxs("div",{className:"boardCoverEditor",children:[n.jsxs("section",{className:"boardCoverPreviewPanel","aria-label":"Cover preview",children:[n.jsx("span",{children:"Preview"}),n.jsx(Bd,{coverItemIds:c,list:e,products:s}),n.jsxs("p",{children:[m," / ",zo," selected"]}),S?n.jsx("em",{children:S}):null]}),n.jsxs("section",{className:"boardCoverSelectedPanel","aria-label":"Selected cover order",children:[n.jsxs("div",{className:"boardCoverSelectedHeader",children:[n.jsx("span",{children:"Selected order"}),n.jsx("p",{children:"1 top-left · 2 top-right · 3 bottom-left · 4 bottom-right"})]}),n.jsx("div",{className:"boardCoverSelectedSlots",children:b.map((y,N)=>{const _=kn(y),P=zi(y,_),V=y?.title||`Slot ${N+1}`,L=N===0?"Top-left":N===1?"Top-right":N===2?"Bottom-left":"Bottom-right",z=_?Uw(y):void 0,B=_?kd(y):void 0;return n.jsxs("article",{className:`boardCoverSelectedSlot${y?" hasProduct":" isEmpty"}`,children:[n.jsxs("span",{className:`boardCoverItemThumb${_?" hasImage":" isPlaceholder"}`,"aria-hidden":"true",style:B,children:[_?n.jsx(Ms,{alt:"",alternateSources:P,decoding:"async",draggable:!1,fallbackSource:jn,loading:"lazy",onFallback:jw,onLoad:Rw,source:_,style:z}):null,n.jsx("span",{className:"boardCoverSelectionBadge",children:N+1})]}
32),n.jsxs("div",{className:"boardCoverSelectedDetails",children:[n.jsx("strong",{children:y?V:"Empty slot"}),n.jsx("span",{children:L})]}),y?n.jsxs("div",{className:"boardCoverSlotControls",children:[n.jsx("button",{"aria-label":`Move ${V} earlier`,disabled:N===0,onClick:()=>A(y.id,-1),type:"button",children:"Earlier"}),n.jsx("button",{"aria-label":`Move ${V} later`,disabled:N===m-1,onClick:()=>A(y.id,1),type:"button",children:"Later"}),n.jsx("button",{"aria-label":`Remove ${V}`,onClick:()=>I(y.id),type:"button",children:"Remove"})]}):null]},y?.id||`slot-${N}`)})})]}),n.jsx("section",{className:"boardCoverPickerPanel","aria-label":`${e?.name||"Board"} items`,children:s.length?n.jsxs(n.Fragment,{children:[v?null:n.jsx("p",{className:"boardCoverPickerNotice",children:"No item images available yet."}),n.jsx("div",{className:"boardCoverItemGrid",children:s.map(y=>{const N=kn(y),_=zi(y,N),P=c.indexOf(y.id),V=P!==-1,L=f&&!V,z=N?Uw(y):void 0,B=N?kd(y):void 0;return n.jsxs("button",{"aria-disabled":L,"aria-pressed":V,className:`boardCoverItemOption${V?" isSelected":""}${L?" isLocked":""}`,disabled:L,onClick:()=>C(y.id),type:"button",children:[n.jsxs("span",{className:`boardCoverItemThumb${N?" hasImage":" isPlaceholder"}`,"aria-hidden":"true",style:B,children:[N?n.jsx(Ms,{alt:"",alternateSources:_,decoding:"async",draggable:!1,fallbackSource:jn,loading:"lazy",onFallback:jw,onLoad:Rw,source:N,style:z}):null,V?n.jsx("span",{className:"boardCoverSelectionBadge",children:P+1}):null]}),n.jsx("span",{children:y.title||"Untitled item"}),N?null:n.jsx("small",{children:"No image"})]},y.id)})})]}):n.jsxs("div",{className:"boardCoverEmptyState",children:[n.jsx("strong",{children:"Add items to this board before choosing a cover."}),n.jsx("p",{children:"The automatic Saveboard placeholder will stay in place until this board has items."})]})})]}),n.jsxs("div",{className:"modalActions boardCoverActions",children:[n.jsx("button",{onClick:k,type:"button",children:"Save cover"}),n.jsx("button",{onClick:E,type:"button",children:"Reset to automatic"}),n.jsx("button",{onClick:a,type:"button",children:"Cancel"})]})]})})}const pS=[{description:"Theme and viewing preferences",key:"appearance",label:"Appearance"},{description:"Starting values for new items",key:"defaults",label:"Defaults"},{description:"Choose which updates you receive",key:"notifications",label:"Notifications"},{description:"Backups and local data controls",key:"data",label:"Data"}];function uY({activeTheme:e,settings:t,lists:r,mode:a,modes:s,signedIn:o=!1,onSettingsChange:i,onModeChange:c,onExportBackup:l,onImportBackup:u,onResetPersonal:p,backupError:m,backupMessage:f,onClose:h}){const b=d.useRef(null),v=d.useRef({}),S=d.useRef(null),C=d.useRef({}),I=d.useRef(null),[A,k]=d.useState("appearance"),[E,y]=d.useState(!1),[N,_]=d.useState("social"),[P,V]=d.useState(!1),[L,z]=d.useState(()=>({...Ei})),[B,re]=d.useState(""),[Z,D]=d.useState(!1),[K,ee]=d.useState(""),[J,fe]=d.useState(""),[De,Be]=d.useState(!1),Fe=r.length===0?[Ka]:r.includes(t.defaultList)?r:[...r,t.defaultList].filter(Boolean),ke=Fe.includes(t.defaultList)?t.defaultList:Ka,We=GE(t.defaultCurrency),de=pS.find(F=>F.key===A)||pS[0],ye=F=>{i(te=>({...te,...F}))},ge=F=>{k(F),y(!0),V(!1),window.matchMedia("(max-width: 720px)").matches&&window.requestAnimationFrame(()=>S.current?.focus())},ze=()=>{y(!1),V(!1),window.requestAnimationFrame(()=>v.current[A]?.focus())};d.useEffect(()=>{let F=!0;if(!o){z({...Ei}),re(""),D(!1),ee(""),fe("");return}return D(!0),re(""),fe(""),pN().then(te=>{F&&(z(te.preferences||{...Ei}),re(te.ok?"":"Could not load Updates preferences."))}).catch(()=>{F&&(z({...Ei}),re("Could not load Updates preferences."))}).finally(()=>{F&&D(!1)}),()=>{F=!1}},[o]);const W=async(F,te)=>{if(!o||K||!!L[F]===te)return;const ie={...L,[F]:te};z(ie),re(""),ee(F),fe("Saving...");try{const Ae=await EU({[F]:te});if(!Ae.ok){z(L),re("Could not update Updates preferences."),fe("");return}z(Ae.preferences||ie),fe("Saved.")}catch{z(L),re("Could not update Updates preferences."),fe("")}finally{ee("")}},et=[{description:"Profile interactions and public-board appreciation.",key:"social",label:"Social",options:[{help:"When someone follows your profile.",key:hr.SOMEONE_FOLLOWED_YOU,label:"Someone follows you"}
32,{help:"When someone likes one of your public boards.",key:hr.PUBLIC_BOARD_LIKED,label:"Someone likes your public board"},{future:!0,help:"Public item likes and saves are not available yet.",key:hr.ITEM_LIKED_PUBLIC,label:"Public likes and saves"}]},{description:"Public-board activity from profiles you follow.",key:"following",label:"Following",options:[{help:"When a followed profile creates a public board.",key:hr.FOLLOWED_USER_CREATED_PUBLIC_BOARD,label:"New public boards from profiles you follow"},{help:"When a followed profile makes a board public.",key:hr.FOLLOWED_USER_MADE_BOARD_PUBLIC,label:"Boards made public by profiles you follow"},{future:!0,help:"Quieter batched updates for new public-board items.",key:hr.FOLLOWED_USER_ADDED_ITEMS_TO_PUBLIC_BOARD,label:"Items added to public boards"}]},{description:"Board invitations and collaboration responses.",key:"collaboration",label:"Collaboration",options:[{help:"Invites and responses for collaborative boards.",key:hr.BOARD_COLLABORATION_UPDATES,label:"Board collaboration invites"}]},{description:"Future delivery options beyond in-app updates.",key:"delivery",label:"Delivery",options:[{future:!0,help:"Email delivery is not available yet.",key:hr.EMAIL_UPDATES,label:"Email updates"},{future:!0,help:"Push and browser delivery are not available yet.",key:hr.PUSH_UPDATES,label:"Push or browser updates"}]}].map(F=>({...F,options:F.options.filter(te=>!te.future)})).filter(F=>F.options.length),pt=et.find(F=>F.key===N)||et[0],$t=F=>{_(F),V(!0),window.matchMedia("(max-width: 720px)").matches&&window.requestAnimationFrame(()=>I.current?.focus())},pe=()=>{V(!1),window.requestAnimationFrame(()=>C.current[N]?.focus())},Tt=({future:F=!1,help:te,key:me,label:ie})=>{const Ae=!!L[me],Re=K===me,ne=F||Z||!!K||!o;return n.jsxs("div",{className:`updatesPreferenceRow${F?" isFuture":""}`,children:[n.jsxs("div",{className:"updatesPreferenceCopy",children:[n.jsxs("span",{children:[ie,F?n.jsx("em",{children:"Coming later"}):null]}),n.jsx("p",{children:te})]}),n.jsxs("div",{"aria-label":ie,className:"settingsButtonGroup settingsSegmentedControl updatesPreferenceToggle",role:"group",children:[n.jsx("button",{"aria-pressed":Ae,className:Ae?"isActive":"",disabled:ne||Re,onClick:()=>W(me,!0),type:"button",children:"On"}),n.jsx("button",{"aria-pressed":!Ae,className:Ae?"":"isActive",disabled:ne||Re,onClick:()=>W(me,!1),type:"button",children:"Off"})]})]},me)};return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("aside",{"aria-labelledby":"settings-title","aria-modal":"true",className:"settingsPanel",role:"dialog",children:[n.jsxs("div",{className:"modalHeader settingsHeader",children:[n.jsx("h2",{id:"settings-title",children:"Settings"}),n.jsx("button",{"aria-label":"Close settings",onClick:h,type:"button",children:"Close"})]}),n.jsxs("div",{className:`settingsWorkspace${E?" isMobileCategoryOpen":""}${P?" isMobileNotificationGroupOpen":""}`,children:[n.jsx("nav",{"aria-label":"Settings categories",className:"settingsCategoryNav",children:pS.map(F=>n.jsxs("button",{"aria-controls":"settings-category-detail","aria-current":A===F.key?"page":void 0,className:A===F.key?"isActive":"",onClick:()=>ge(F.key),ref:te=>{v.current[F.key]=te},type:"button",children:[n.jsxs("span",{className:"settingsCategoryNavCopy",children:[n.jsx("strong",{children:F.label}),n.jsx("small",{children:F.description})]}),n.jsx("span",{"aria-hidden":"true",className:"settingsCategoryArrow",children:"›"})]},F.key))}),n.jsxs("div",{"aria-labelledby":"settings-category-title",className:"settingsCategoryDetail",id:"settings-category-detail",role:"region",children:[n.jsxs("button",{"aria-label":"Back to settings categories",className:"settingsCategoryBack",onClick:ze,ref:S,type:"button",children:[n.jsx("span",{"aria-hidden":"true",children:"←"}),"Back"]}),A==="appearance"?n.jsxs("section",{className:"settingsSection settingsAppearanceSection",children:[n.jsx("div",{className:"settingsSectionIntro",children:n.jsx("h3",{id:"settings-category-title",children:de.label})}),n.jsxs("div",{className:"settingsControlGroups",children:[n.jsxs("section",{className:"settingsControlGroup settingsThemeGroup",children:[n.jsx("h4",{children:"Theme"}),n.jsx("div",{className:"settingsButtonGroup settingsSegmentedControl","aria-label":"Theme",role:"group",children:Object.entries(e3).map(([F,te])=>n.jsx("button",{"aria-pressed":e===F,className:e===F?"isActive":"",onClick:()=>ye({theme:F}),type:"button",children:te},F))})]}),n.jsxs("section",{className:"settingsControlGroup settingsViewingGroup",children:[n.jsx("h4",{children:"Viewing"}),n.jsxs("div",{className:"settingsControlGrid",children:[n.jsxs("div",{className:"settingsRow settingsRowFull",children:[n.jsx("span",{children:"Default board sort"}),n.jsx("select",{"aria-label":"Default board sort",onChange:F=>ye({defaultSortMode:bc(F.target.value)}),value:bc(t.defaultSortMode),children:Object.entries(Um).map(([F,te])=>n.jsx("option",{value:F,children:te},F))})]}),n.jsx("p",{className:"settingsRowNote",children:"Boards you have sorted keep their own choice. Sorting and item order are saved on this browser."}),n.jsxs("div",{className:"settingsRow settingsRowFull",children:[n.jsx("span",{children:"Display quality"}),n.jsx("div",{className:"settingsButtonGroup displayQualityGroup","aria-label":"Display quality",role:"group",children:Object.entries(NR).map(([F,te])=>n.jsxs("button",{"aria-pressed":kw(t.displayQuality)===F,className:`displayQualityButton${kw(t.displayQuality)===F?" isActive":""}`,onClick:()=>ye({displayQuality:F}),type:"button",children:[n.jsx("span",{children:te.label}),te.badge?n.jsx("em",{children:te.badge}):null,n.jsx("small",{children:te.detail})]},F))})]}),n.jsxs("div",{className:"settingsRow",children:[n.jsx("span",{children:"Card style"}),n.jsx("div",{className:"settingsButtonGroup settingsSegmentedControl","aria-label":"Card style",role:"group",children:[["tonal","Tonal"],["panel","Panel"]].map(([F,te])=>{const me=(t.lightCardMode==="panel"?"panel":"tonal")===F;return n.jsx("button",{"aria-pressed":me,className:me?"isActive":"",onClick:()=>ye({lightCardMode:F}),type:"button",children:te},F)})})]})]})]}),n.jsxs("section",{className:"settingsControlGroup settingsInterfaceGroup",children:[n.jsx("h4",{children:"Interface"}),n.jsxs("div",{className:"settingsControlGrid",children:[n.jsxs("div",{className:"settingsRow",children:[n.jsx("span",{children:"Custom cursor"}),n.jsx("div",{className:"settingsButtonGroup settingsSegmentedControl","aria-label":"Custom cursor",role:"group",children:[["on","On"],["off","Off"]].map(([F,te])=>{const me=t.customCursorEnabled!==!1;return n.jsx("button",{"aria-pressed":F==="on"===me,className:F==="on"===me?"isActive":"",onClick:()=>ye({customCursorEnabled:F==="on"}),type:"button",children:te},F)})})]}),n.jsxs("div",{className:"settingsRow",children:[n.jsx("span",{children:"Monochrome mode"}),n.jsx("div",{className:"settingsButtonGroup settingsSegmentedControl","aria-label":"Monochrome mode",role:"group",children:[["on","On"],["off","Off"]].map(([F,te])=>{const me=!!t.monochromeEnabled;return n.jsx("button",{"aria-pressed":F==="on"===me,className:F==="on"===me?"isActive":"",onClick:()=>ye({monochromeEnabled:F==="on"}),type:"button",children:te},F)})})]})]})]})]})]}):null,A==="defaults"?n.jsxs("section",{className:"settingsSection settingsDefaultsSection",children:[n.jsx("div",{className:"settingsSectionIntro",children:n.jsx("h3",{id:"settings-category-title",children:de.label})}),n.jsxs("div",{className:"settingsDefaultsForm",children:[n.jsxs("label",{className:"settingsRow settingsFormRow",children:[n.jsx("span",{children:"Default board"}),n.jsx("select",{onChange:F=>ye({defaultList:F.target.value}),value:ke,children:Fe.map(F=>n.jsx("option",{value:F,children:F},F))})]}),n.jsxs("label",{className:"settingsRow settingsFormRow",children:[n.jsx("span",{children:"Default currency"}),n.jsx("select",{"aria-label":"Default currency",onChange:F=>ye({defaultCurrency:Nd(F.target.value)}),value:We.code,children:wb.map(F=>n.jsxs("option",{value:F.code,children:[F.display," — ",F.label]}
32,F.code))})]}),n.jsxs("div",{className:"settingsRow settingsFormRow",children:[n.jsx("span",{children:"Default image fit"}),n.jsx("div",{className:"settingsButtonGroup settingsSegmentedControl","aria-label":"Default image fit",role:"group",children:["contain","cover"].map(F=>n.jsx("button",{"aria-pressed":t.defaultImageFit===F,className:t.defaultImageFit===F?"isActive":"",onClick:()=>ye({defaultImageFit:F}),type:"button",children:F},F))})]})]})]}):null,A==="notifications"?n.jsxs("section",{className:"settingsSection settingsNotificationsSection",children:[n.jsx("div",{className:"settingsSectionIntro",children:n.jsx("h3",{id:"settings-category-title",children:de.label})}),n.jsxs("div",{className:`notificationSettingsLayout${P?" isMobileGroupOpen":""}`,children:[n.jsx("nav",{"aria-label":"Notification categories",className:"notificationGroupNav",children:et.map(F=>n.jsxs("button",{"aria-controls":"notification-group-detail","aria-current":N===F.key?"page":void 0,className:N===F.key?"isActive":"",onClick:()=>$t(F.key),ref:te=>{C.current[F.key]=te},type:"button",children:[n.jsx("span",{children:F.label}),n.jsx("span",{"aria-hidden":"true",className:"notificationGroupArrow",children:"›"})]},F.key))}),n.jsxs("div",{"aria-labelledby":"notification-group-title",className:"notificationGroupDetail",id:"notification-group-detail",role:"region",children:[n.jsxs("button",{"aria-label":"Back to notification categories",className:"notificationGroupBack",onClick:pe,ref:I,type:"button",children:[n.jsx("span",{"aria-hidden":"true",children:"←"}),"Notifications"]}),n.jsxs("div",{className:"notificationGroupHeader",children:[n.jsx("h4",{id:"notification-group-title",children:pt.label}),n.jsx("p",{children:pt.description})]}),o?n.jsxs("div",{className:"updatesPreferencesPanel",children:[Z?n.jsx("p",{className:"settingsFieldHelp",children:"Loading preferences..."}):null,n.jsx("div",{className:"updatesPreferencesList",children:pt.options.map(F=>Tt(F))}),B?n.jsx("p",{className:"settingsMessage",children:B}):null,J?n.jsx("p",{className:"settingsMessage",role:"status",children:J}):null]}):n.jsxs("div",{className:"settingsLocalNote updatesPreferencesNotice",children:[n.jsx("strong",{children:"Sign in"}),n.jsx("span",{children:"Sign in to manage notification preferences."})]})]})]})]}):null,A==="data"?n.jsxs("section",{className:"settingsSection",children:[n.jsx("div",{className:"settingsSectionIntro",children:n.jsx("h3",{id:"settings-category-title",children:de.label})}),n.jsxs("div",{className:"settingsRows",children:[n.jsxs("div",{className:"settingsLocalNote",children:[n.jsx("strong",{children:"Backups"}),n.jsx("span",{children:"A backup is a file you keep yourself, separate from your account. It includes personal boards, products, stores, notes, statuses, order, visual details, and settings."})]}),n.jsxs("div",{className:"settingsActionGrid",children:[n.jsxs("div",{className:"settingsBackupAction",children:[n.jsx("button",{onClick:l,type:"button",children:"Export backup"}),n.jsx("p",{children:"Download a local backup of your boards, products, stores, and settings."})]}),n.jsxs("div",{className:"settingsBackupAction",children:[n.jsx("button",{onClick:()=>b.current?.click(),type:"button",children:"Import backup"}),n.jsx("p",{children:"Choose a Saveboard JSON backup to restore or merge."})]}),n.jsx("button",{onClick:()=>Be(!0),type:"button",children:"Reset personal data"}),n.jsx("input",{accept:"application/json,.json",className:"backupFileInput",onChange:F=>{u(F.target.files?.[0]),F.target.value=""},ref:b,type:"file"})]}),m?n.jsx("p",{className:"settingsMessage",children:m}):null,f?n.jsx("p",{className:"settingsMessage",children:f}):null,De?n.jsxs("div",{className:"settingsConfirm",children:[n.jsx("p",{children:"This clears the copy of your boards and items held in this browser. Your account is not changed."}),n.jsxs("div",{children:[n.jsx("button",{onClick:()=>{p(),Be(!1)},type:"button",children:"Confirm reset"}),n.jsx("button",{onClick:()=>Be(!1),type:"button",children:"Cancel"})]})]}):null]})]}):null]})]})]})})}const $L=d.memo(function({products:t,boards:r=_R,capabilities:a=jl,onCreateBoard:s,onEmptyClick:o,onExpandProduct:i,onEditProduct:c,onDeleteProduct:l,onRestoreProduct:u,onUpdateProductStatus:p,onReorderProducts:m,onMoveProductToList:f,onDragProductChange:h,onDragListTargetChange:b,gridPreference:v,boardMode:S,fillEmptySlots:C=!0,alwaysShowAddSlot:I=!1,emptySlotMode:A="add",allowReorder:k=!0,allowMove:E=!0,manageMode:y=!1,selectedProductIds:N=MW,onToggleProductSelection:_=Ai,onRailWidthChange:P=Ai,maxColumnCount:V=1/0,renderResetKey:L="",allowVariableCardSizes:z=!1,minimalMode:B=!1,restorePendingProductId:re="",trashView:Z=!1}){const D=d.useRef(null),K=d.useRef(null),ee=d.useRef(null),J=d.useRef(new Map),fe=d.useRef(null),De=d.useRef(null),Be=d.useRef(null),Fe=d.useRef(0),ke=d.useRef(null),We=d.useRef(null),[de,ye]=d.useState(null),[ge,ze]=d.useState(null),[W,Le]=d.useState(null),[et,pt]=d.useState(null),[$t,pe]=d.useState(hx),[Tt,F]=d.useState(null),te=k||E,me=Sn(o),ie=Sn(i),Ae=Sn(c),Re=Sn(l),ne=Sn(u),ht=Sn(p),kt=Sn(m),Ee=Sn(f),xe=Sn((ce,oe)=>
32{!ce?.id||!oe||Ee(ce.id,oe)}),Qe=Sn(h),Pe=Sn(b),Ct=Sn(_),nr=S==="horizontal"?Ja:v,st=!dL()&&z&&S==="vertical",gr=Number.isFinite(V)&&V>0,Xt=cL(nr),fn=fp(),Ke=d.useCallback(ce=>{const oe=Number.parseFloat(ce.columnGap)*.6;return{...ce,columnGap:Number.isFinite(oe)?$o(oe):ce.columnGap}},[]),ft=d.useMemo(()=>Ke(Cl(nr,fn)),[fn,nr,Ke]),lr=d.useMemo(()=>Ke(Cl(Ja,fn)),[fn,Ke]),Wr=d.useMemo(()=>Ke(Cl("expanded",fn)),[fn,Ke]),Dr=lL(D),kr=ug(D,nr,V,ft),Gr=ug(D,Ja,V,lr),ar=ug(D,"expanded",V,Wr),qr=d.useMemo(()=>$W(t,W),[W,t]),tn=S==="horizontal"?Xt:kr,hn=d.useMemo(()=>Cx($t,qr.length,tn),[tn,qr.length,$t]),Wn=d.useMemo(()=>qr.slice(0,hn),[hn,qr]),br=Wn.length<qr.length,rn=d.useMemo(()=>C?fG({products:Wn,mode:S,columnCount:kr,rowCount:Xt,alwaysShowAddSlot:br?!1:I,useDenseCardOccupancy:st}):Wn.map(ce=>({type:"product",product:ce})),[Wn,S,kr,C,br,Xt,I,st]),nn=d.useMemo(()=>{const ce=Math.max(1,kr),oe=Math.max(1,Xt);return S==="horizontal"?rn.length>0&&rn.length<oe:Math.ceil(rn.length/ce)<oe},[S,kr,Xt,rn.length]),Pn=ft.rowGap,G=Number.parseFloat(ft.podWidth)||0,se=Number.parseFloat(ft.columnGap)||0,le=Number.parseFloat(lr.podWidth)||0,ue=Number.parseFloat(lr.columnGap)||0,Ne=le*Math.max(1,Gr)+ue*Math.max(0,Gr-1),be=Number.parseFloat(Wr.podWidth)||0,Te=Number.parseFloat(Wr.columnGap)||0,Ve=be*Math.max(1,ar)+Te*Math.max(0,ar-1),at=gr&&S==="vertical",yt=G*Math.max(1,kr)+se*Math.max(0,kr-1),tt=at&&Dr>0?Dr:0,He=Math.max(Ne,Ve,yt,tt),Ge=at&&He>yt+.5,Xe=(He-se*Math.max(0,kr-1))/Math.max(1,kr),Dt=Ge&&Xe>0?Xe:G,jt=ER(Dt),Zt=Dt*Math.max(1,kr)+se*Math.max(0,kr-1),xt=at?Math.max(Ne,Ve,Zt):Zt,Gt=Number.parseFloat(Pn)||0,Or=jt*Xt+Gt*Math.max(0,Xt-1),Yt=$o(Dt*Hu.detailsHeight),er=$o(Dt*Hu.bodyPadding),x=$o(Dt*Hu.mediaGap),$=d.useMemo(()=>({"--pod-width":`${Dt}px`,"--pod-aspect-ratio":ft.podAspectRatio,"--pod-height":`${jt}px`,"--grid-column-gap":ft.columnGap,"--grid-row-gap":Pn,"--board-row-count":Xt,"--board-column-count":kr,"--visible-grid-height":`${Or}px`,"--grid-rail-width":`${xt}px`,...Ge&&nr==="expanded"?{"--expanded-product-details-height":Yt,"--expanded-product-card-body-padding":er,"--expanded-product-card-media-gap":x}:{}}),[er,Yt,x,Ge,Pn,nr,jt,Dt,ft.columnGap,ft.podAspectRatio,xt,Xt,kr,Or]);d.useEffect(()=>{!Number.isFinite(xt)||xt<=0||P(Math.round(xt*10)/10)},[P,xt]),d.useEffect(()=>{pe(b_(t.length,tn))},[tn,L]),d.useEffect(()=>{pe(ce=>Math.min(Math.max(ce,b_(t.length,tn)),t.length))},[tn,t.length]),d.useEffect(()=>{if(!br||de||typeof IntersectionObserver>"u")return;const ce=K.current;if(!ce)return;const oe=new IntersectionObserver(gt=>{gt.some(wt=>wt.isIntersecting)&&d.startTransition(()=>{pe(wt=>hG(wt,qr.length,tn))})},{root:D.current,rootMargin:S==="horizontal"?"0px 960px 0px 0px":"960px 0px",threshold:.01});return oe.observe(ce),()=>oe.disconnect()},[S,de,tn,br,qr.length]),d.useEffect(()=>{typeof IntersectionObserver<"u"||!br||pe(qr.length)},[br,qr.length]);const O=(ce,oe)=>document.elementFromPoint(ce,oe)?.closest(".productPod[data-product-id]")?.dataset.productId??null,q=(ce,oe)=>{const gt=document.elementFromPoint(ce,oe)?.closest("[data-list-drop-id]");return gt?.dataset.listDropId?{id:gt.dataset.listDropId,name:gt.dataset.listDropName||""}:null},X=ce=>D.current?D.current.querySelector(`.productPod[data-product-id="${qP(ce)}"]`)?.getBoundingClientRect()??null:null,Se=ce=>document.querySelector(`[data-list-drop-id="${qP(ce)}"]`)?.getBoundingClientRect()??null,he=ce=>!y||!N.has(ce.id)||N.size<2?[ce.id]:t.map(oe=>oe.id).filter(oe=>N.has(oe)),$e=ce=>{const oe=new Map(t.map(gt=>[gt.id,gt]));return ce.map(gt=>oe.get(gt)).filter(Boolean)},Oe=(ce,oe,gt="")=>!!(ce&&oe&&(ce.listId===oe||gt&&(ce.category===gt||ce.listName===gt))),Pt=(ce,oe,gt="")=>!!(ce?.products?.length&&ce.products.every(wt=>Oe(wt,oe,gt))),mt=()=>{const ce=D.current;if(!ce){J.current=new Map;return}const oe=new Map;ce.querySelectorAll(".productPod[data-product-id]").forEach(gt=>{oe.set(gt.dataset.productId,gt.getBoundingClientRect())}),J.current=oe},Kt=ce=>({left:ce.originPageLeft-window.scrollX,top:ce.originPageTop-window.scrollY}),rt=(ce,oe,gt,wt)=>({left:Math.min(Math.max(ce,8),Math.max(8,window.innerWidth-gt-8)),top:Math.min(Math.max(oe,8),Math.max(8,window.innerHeight-wt-8))}),St=ce=>{!ce||typeof window>"u"||(ce.classList.add("isWheelScrolling"),window.clearTimeout(We.current),We.current=window.setTimeout(()=>{ce.classList.remove("isWheelScrolling"),We.current=null},BW))},_t=(ce,oe)=>
32{if(!D.current)return;const It=D.current.getBoundingClientRect();if(oe<It.top||oe>It.bottom){oe<52?window.scrollBy({top:-14,left:0,behavior:"auto"}):oe>window.innerHeight-52&&window.scrollBy({top:14,left:0,behavior:"auto"});return}S==="horizontal"&&ce<It.left+52?D.current.scrollBy({left:-14,top:0,behavior:"auto"}):S==="horizontal"&&ce>It.right-52?D.current.scrollBy({left:14,top:0,behavior:"auto"}):S==="vertical"&&oe<It.top+52?D.current.scrollBy({left:0,top:-14,behavior:"auto"}):S==="vertical"&&oe>It.bottom-52&&D.current.scrollBy({left:0,top:14,behavior:"auto"})},dr=()=>{ke.current=null;const ce=D.current,oe=Fe.current;if(Fe.current=0,!ce||Math.abs(oe)<.5)return;const gt=ce.scrollWidth-ce.clientWidth;if(gt<=0)return;const wt=Math.min(Math.max(ce.scrollLeft+oe,0),gt);Math.abs(wt-ce.scrollLeft)>=.5&&(ce.scrollLeft=wt)},tr=ce=>{if(S!=="horizontal"||!D.current)return;const oe=D.current,gt=oe.scrollWidth-oe.clientWidth;if(gt<=0)return;const wt=gG(ce,oe);if(Math.abs(wt)<.5)return;const It=Fe.current+wt,or=Math.min(Math.max(oe.scrollLeft+It,0),gt);Math.abs(or-oe.scrollLeft)<.5||(ce.preventDefault(),St(oe),Fe.current=It,ke.current||(ke.current=window.requestAnimationFrame(dr)))},yr=ce=>{!ce?.sourceElement||ce.pointerId===void 0||ce.sourceElement.hasPointerCapture?.(ce.pointerId)&&ce.sourceElement.releasePointerCapture?.(ce.pointerId)},Sr=(ce,oe)=>{if(typeof window>"u"||typeof window.requestAnimationFrame!="function"){pt(gt=>gt&&{...gt,x:ce,y:oe});return}De.current&&window.cancelAnimationFrame(De.current),De.current=window.requestAnimationFrame(()=>{De.current=null,pt(gt=>gt&&{...gt,x:ce,y:oe})})},wr=({suppressClick:ce=!1}={})=>{const oe=ee.current;oe?.removeWindowListeners?.(),yr(oe),De.current&&(window.cancelAnimationFrame(De.current),De.current=null),window.clearTimeout(Be.current),Be.current=null,ce&&oe?.id&&(F(oe.id),window.clearTimeout(fe.current),fe.current=window.setTimeout(()=>F(null),180)),ee.current=null,ye(null),ze(null),Le(null),pt(null),Qe(null),Pe("")},Mn=({left:ce,top:oe,beforeSettle:gt,afterSettle:wt,suppressClick:It=!0})=>{const or=ee.current;if(!or)return;or.removeWindowListeners?.(),yr(or),De.current&&(window.cancelAnimationFrame(De.current),De.current=null),gt?.(or);const Yr=rt(ce,oe,or.width,or.height);pt(qt=>qt&&{...qt,phase:"settling",x:Yr.left+qt.offsetX,y:Yr.top+qt.offsetY}),window.clearTimeout(Be.current),Be.current=window.setTimeout(()=>{Be.current=null,wt?.(or),wr({suppressClick:It})},_W)},fr=()=>{const ce=ee.current;if(!ce?.isDragging){wr({suppressClick:!!ce?.id});return}const oe=Kt(ce);Mn({left:oe.left,top:oe.top,beforeSettle:()=>{Le(ce.originalOrderIds),ze(null),ce.currentOrderIds=ce.originalOrderIds,ce.overListId="",ce.overListName="",Pe("")},suppressClick:!0})},Cr=(ce,oe)=>{if(!te||oe.button!==void 0&&oe.button!==0||oe.target.closest("a, button, input, select, textarea"))return;const wt=(oe.currentTarget.closest(".productPod")||oe.currentTarget).getBoundingClientRect(),It=t.map(Fr=>Fr.id),or=he(ce),Yr=$e(or),qt=Fr=>po(Fr),Ir=Fr=>ca(Fr);ee.current={id:ce.id,ids:or,product:ce,products:Yr.length?Yr:[ce],groupSize:or.length,pointerId:oe.pointerId,startX:oe.clientX,startY:oe.clientY,offsetX:oe.clientX-wt.left,offsetY:oe.clientY-wt.top,originPageLeft:wt.left+window.scrollX,originPageTop:wt.top+window.scrollY,width:wt.width,height:wt.height,isDragging:!1,lastOverId:ce.id,currentOrderIds:It,originalOrderIds:It,overListId:"",overListName:"",sourceElement:oe.currentTarget,threshold:oe.pointerType==="touch"?PW:AW,removeWindowListeners:()=>{window.removeEventListener("pointermove",qt),window.removeEventListener("pointerup",Ir),window.removeEventListener("pointercancel",Ir)}},window.addEventListener("pointermove",qt,{passive:!1}),window.addEventListener("pointerup",Ir),window.addEventListener("pointercancel",Ir),oe.currentTarget.setPointerCapture?.(oe.pointerId)},po=ce=>{const oe=ee.current;if(!oe||oe.pointerId!==ce.pointerId)return;const gt=ce.clientX-oe.startX,wt=ce.clientY-oe.startY,It=Math.hypot(gt,wt);if(!oe.isDragging&&It<oe.threshold)return;oe.isDragging||(mt(),oe.isDragging=!0,ye(oe.id),Le(oe.currentOrderIds),pt({product:oe.product,x:ce.clientX,y:ce.clientY,offsetX:oe.offsetX,offsetY:oe.offsetY,width:oe.width,height:oe.height,groupSize:oe.groupSize,phase:"dragging"}),Qe(oe.product)),ce.preventDefault(),_t(ce.clientX,ce.clientY),Sr(ce.clientX,ce.clientY);
32const or=E?q(ce.clientX,ce.clientY):null,Yr=or&&Pt(oe,or.id,or.name),qt=or&&!Yr?or.id:"",Ir=qt?or.name:"";if(qt!==oe.overListId?(oe.overListId=qt,oe.overListName=Ir,Pe(qt)):Ir!==oe.overListName&&(oe.overListName=Ir),qt){ze(null);return}if(!k)return;const Fr=O(ce.clientX,ce.clientY);if(!Fr||oe.ids.includes(Fr)||Fr===oe.lastOverId)return;oe.lastOverId=Fr,ze(Fr);const gn=oe.ids.length>1?FW(oe.currentOrderIds,oe.ids,Fr):UW(oe.currentOrderIds,oe.id,Fr);gn!==oe.currentOrderIds&&(oe.currentOrderIds=gn,Le(gn))},ca=ce=>{const oe=ee.current;if(!(!oe||oe.pointerId!==ce.pointerId)){if(oe.isDragging){if(ce.preventDefault(),ce.type==="pointercancel"){fr();return}const gt=E?q(ce.clientX,ce.clientY):null,wt=gt?.id||oe.overListId,It=gt?.name||oe.overListName,or=wt&&Pt(oe,wt,It);if(wt&&!or){const gn=Se(wt);if(gn){Mn({left:gn.left+gn.width/2-oe.width/2,top:gn.top+gn.height/2-oe.height/2,beforeSettle:()=>{Le(oe.originalOrderIds),ze(null),oe.overListId=wt,oe.overListName=It},afterSettle:()=>Ee(oe.ids,wt),suppressClick:!0});return}}const Yr=k&&oe.currentOrderIds?.length&&!oe.currentOrderIds.every((gn,Vt)=>gn===oe.originalOrderIds[Vt]),qt=document.elementFromPoint(ce.clientX,ce.clientY),Ir=!!(D.current&&qt&&D.current.contains(qt)),Fr=!!qt?.closest(".emptyPod");if(Yr&&Ir&&!Fr){const gn=X(oe.id)||Kt(oe);Mn({left:gn.left,top:gn.top,beforeSettle:()=>{ze(null),oe.overListId="",oe.overListName="",Pe("")},afterSettle:()=>kt(oe.currentOrderIds),suppressClick:!0});return}fr();return}wr()}};d.useLayoutEffect(()=>{const ce=D.current;if(!ce||!W){de||(J.current=new Map);return}const oe=J.current,gt=new Map;[...ce.querySelectorAll(".productPod[data-product-id]")].forEach(It=>{const or=It.dataset.productId,Yr=It.getBoundingClientRect();gt.set(or,Yr);const qt=oe.get(or);if(!qt||or===de)return;const Ir=qt.left-Yr.left,Fr=qt.top-Yr.top;if(!(Math.abs(Ir)<.5&&Math.abs(Fr)<.5)){if(It.getAnimations?.().forEach(gn=>gn.cancel()),It.style.transition="",It.style.transform="",typeof It.animate=="function"){const gn=It.animate([{transform:`translate3d(${Ir}px, ${Fr}px, 0)`},{transform:"translate3d(0, 0, 0)"}],{duration:220,easing:"cubic-bezier(0.19, 0.72, 0.24, 1)",fill:"none"});window.setTimeout(()=>gn.cancel(),280);return}It.style.transition="none",It.style.transform=`translate3d(${Ir}px, ${Fr}px, 0)`,It.getBoundingClientRect(),window.setTimeout(()=>{It.style.transition="transform 220ms var(--ease-out)",It.style.transform="",window.setTimeout(()=>{It.style.transition="",It.style.transform=""},260)},16)}}),J.current=gt},[W,de]),d.useEffect(()=>{if(!(!de||typeof document>"u"))return document.documentElement.classList.add("myListProductDragging"),()=>document.documentElement.classList.remove("myListProductDragging")},[de]),d.useEffect(()=>{if(!de)return;const ce=oe=>
32{oe.key==="Escape"&&(oe.preventDefault(),fr())};return window.addEventListener("keydown",ce),()=>window.removeEventListener("keydown",ce)},[de]),d.useEffect(()=>{S!=="horizontal"&&(ke.current&&(window.cancelAnimationFrame(ke.current),ke.current=null),Fe.current=0,window.clearTimeout(We.current),We.current=null,D.current?.classList.remove("isWheelScrolling"))},[S]),d.useEffect(()=>()=>{ee.current?.removeWindowListeners?.(),De.current&&window.cancelAnimationFrame(De.current),ke.current&&window.cancelAnimationFrame(ke.current),window.clearTimeout(We.current),D.current?.classList.remove("isWheelScrolling"),window.clearTimeout(Be.current),window.clearTimeout(fe.current),document.documentElement.classList.remove("myListProductDragging")},[]);const mo=d.useCallback(ce=>{if(!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(ce.key))return;const oe=[...D.current.querySelectorAll(".productPodMedia, .emptyPod:not(.emptyPodFiller)")],gt=oe.indexOf(ce.target);if(gt===-1)return;const wt=S==="horizontal"?1:kr,It=S==="horizontal"?Xt:1,or=ce.key==="ArrowRight"?gt+It:ce.key==="ArrowLeft"?gt-It:ce.key==="ArrowDown"?gt+wt:gt-wt,Yr=oe[Math.max(0,Math.min(oe.length-1,or))];Yr&&Yr!==ce.target&&(ce.preventDefault(),Yr.focus(),Yr.scrollIntoView({block:"nearest",inline:"nearest"}))},[S,kr,Xt]),rs=Sn(Cr),$s=te?rs:null;return n.jsxs("section",{className:`productGrid boardScrollbarHidden ${S==="horizontal"?"isHorizontal":"isVertical"}${te?"":" isStatic"}${gr?" isColumnCapped":""}${de?" isDraggingProducts":""}${nn?" isShortGrid":""}${st?" hasVariableCardSizes":""}`,"aria-label":"Wishlist product grid","data-density":v,"data-minimal-mode":B?"true":"false",onKeyDown:mo,onWheel:S==="horizontal"?tr:void 0,ref:D,style:$,children:[rn.map((ce,oe)=>ce.type==="product"?n.jsx(P_,{index:oe,product:ce.product,allowVariableCardSize:st,boards:r,capabilities:a,onChangeBoard:xe,onCreateBoard:s,onEmptyClick:me,onExpandProduct:ie,onEditProduct:Ae,onDeleteProduct:Re,onRestoreProduct:ne,onUpdateProductStatus:ht,onDragPointerDown:$s,manageMode:y,isSelected:N.has(ce.product.id),onToggleSelection:Ct,isDragging:de===ce.product.id,isDragTarget:ge===ce.product.id,suppressClick:Tt===ce.product.id,isRestorePending:re===ce.product.id,isTrashView:Z},ce.product.id):n.jsx(P_,{product:null,index:oe,onEmptyClick:me,onExpandProduct:ie,onEditProduct:Ae,onDeleteProduct:Re,onRestoreProduct:ne,onUpdateProductStatus:ht,onDragPointerDown:null,manageMode:!1,isSelected:!1,onToggleSelection:Ai,isDragging:!1,isDragTarget:!1,suppressClick:!1,emptySlotMode:A,isTrashView:Z},ce.key)),br?n.jsx("div",{className:"productGridLoadSentinel",ref:K,"aria-hidden":"true",children:n.jsx("span",{children:"Loading more"})}):null,n.jsx(jG,{dragSession:et,podHeight:jt,preference:ft})]})});function pY({onBarcodeDetected:e,onCancel:t}){const r=d.useRef(null),a=d.useRef(null),s=d.useRef(0),o=d.useRef(null),i=d.useRef(!1),[c,l]=d.useState("starting"),[u,p]=d.useState("Use your camera to scan a product barcode."),[m,f]=d.useState(""),h=d.useCallback(()=>{i.current=!1,s.current&&(window.cancelAnimationFrame(s.current),s.current=0),a.current?.getTracks().forEach(A=>A.stop()),a.current=null,r.current&&(r.current.srcObject=null)},[]),b=d.useCallback(A=>{const k=xl(A);k&&(h(),l("detected"),p(`Barcode found: ${k}`),e(k))},[e,h]),v=d.useCallback(async()=>{if(!(!i.current||!o.current||!r.current)){try{if(r.current.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA){const k=(await o.current.detect(r.current)).find(E=>xl(E.rawValue));if(k){b(k.rawValue);return}}}catch{p("Could not read the barcode yet. You can also enter it manually.")}i.current&&(s.current=window.requestAnimationFrame(v))}},[b]),S=d.useCallback(async()=>{l("starting"),p("Use your camera to scan a product barcode.");try{const A=await N3();if(!A.length||!navigator.mediaDevices?.getUserMedia){l("unsupported"),p(y3);return}try{o.current=new window.BarcodeDetector({formats:A})}catch{o.current=new window.BarcodeDetector}const k=await navigator.mediaDevices.getUserMedia({audio:!1,video:{facingMode:{ideal:"environment"}}});if(a.current=k,i.current=!0,!r.current)throw new Error("camera-preview-unavailable");r.current.srcObject=k,await r.current.play(),l("scanning"),p("Scanning for a retail barcode..."),s.current=window.requestAnimationFrame(v)}catch(A){if(h(),A?.name==="NotAllowedError"||A?.name==="SecurityError"){l("denied"),p("Camera access was denied. You can enter the barcode manually or add the product manually.");return}l("error"),p("Could not start barcode scanning. You can enter the barcode manually.")}},[v,h]);d.useEffect(()=>(S(),h),[S,h]);const C=xl(m),I=c==="starting"||c==="scanning";return n.jsxs("section",{className:"barcodeScannerPanel","aria-label":"Barcode scanner",children:[n.jsxs("div",{className:"barcodeScannerPreview",children:[n.jsx("video",{"aria-hidden":"true",className:"barcodeScannerVideo",muted:!0,playsInl
32ine:!0,ref:r}),I?null:n.jsx("div",{className:"barcodeScannerPlaceholder",children:c==="detected"?"Barcode captured":"Manual entry available"})]}),n.jsxs("div",{className:"barcodeScannerCopy",children:[n.jsx("span",{children:"Scan barcode"}),n.jsx("p",{children:"Use your camera to scan a product barcode."}),n.jsx("p",{className:"barcodeScannerStatus","aria-live":"polite",children:u}),n.jsxs("div",{className:"barcodeManualEntry",children:[n.jsxs("label",{children:[n.jsx("span",{children:"Enter barcode manually"}),n.jsx("input",{autoComplete:"off",inputMode:"numeric",onChange:A=>f(A.target.value),value:m})]}),n.jsx("button",{disabled:!C,onClick:A=>{A.preventDefault(),A.stopPropagation(),b(m)},type:"button",children:"Use barcode"})]}),n.jsx("div",{className:"barcodeScannerActions",children:n.jsx("button",{type:"button",onClick:()=>{h(),t()},children:"Cancel"})})]})]})}function mY({candidates:e,selectedUrl:t,brokenUrls:r,onSelect:a,onImageError:s}){return e.length<2?null:n.jsxs("div",{className:"metadataImagePicker","aria-label":"Detected product images",children:[n.jsx("span",{children:"Choose image"}),n.jsx("div",{className:"metadataImageCandidateGrid",children:e.map((o,i)=>{const c=yx(o),l=t===c,u=r.has(c),p=o.source||"Image";return n.jsxs("button",{"aria-label":`Use ${p.toLowerCase()} ${i+1}`,"aria-pressed":l,className:`metadataImageCandidate${l?" isSelected":""}${u?" hasImageError":""}`,onClick:()=>a(o),type:"button",children:[n.jsx(rv,{className:"metadataImageThumb",imageSource:u?"":c,children:u?n.jsx("span",{children:"Unavailable"}):n.jsx("img",{alt:"",loading:"lazy",onError:()=>s(c),src:c})}),n.jsx("span",{children:p})]},c)})})]})}function oE({product:e,initialProduct:t=null,presentation:r="modal",formId:a,listRecords:s=[],listOptions:o,defaultList:i,defaultImageFit:c,defaultCurrency:l,imagePreviewAspectRatio:u,imagePreviewAspectRatios:p={},initialFramingMode:m=Lr.normal,onSubmit:f,onCancel:h,onBack:b,onCreateBoard:v,onDelete:S,onDirtyChange:C,onRecoverMissingRevision:I,onSubmissionStateChange:A}){const k=!!e,E=r==="page",y=d.useRef(null),N=d.useRef(null),_=d.useRef(null),P=d.useRef(0),V=d.useRef(null),L=d.useRef(null),z=d.useRef(null),B=d.useRef(null),re=d.useRef(!1),Z=d.useRef(!1),D=d.useRef(null),K=d.useRef(0),ee=d.useRef(!1),J=e||t,fe=d.useRef(eC(J,{isPlaceholder:qo})),De=m===Lr.minimal?Lr.minimal:Lr.normal,Be=zn(J?.cardSize??J?.card_size),Fe=J?Zw(J):em(mc(c)),ke=ya(J?.imageFramingOverrides??J?.image_framing_overrides),We=Nm({base:Fe,mode:De,overrides:ke,size:Be}),de=Hm(l),ye=!k&&["chrome","edit"].includes(t?.captureSource),ge=!k&&!ye,[ze,W]=d.useState("url"),Le=ge&&ze==="url",et=ge&&ze==="barcode",pt=ye&&t?.targetListName&&!t?.targetListMatched?`Suggested board "${t.targetListName}" is not in Saveboard yet. Choose a board before saving.`:"",$t=J?.image?.startsWith("data:image/")&&!J.image.startsWith("data:image/svg+xml"),[pe,Tt]=d.useState({title:J?.title??"",price:J?.price??"",currency:J?.currency??Nl(J?.price,de),targetPrice:J?.targetPrice??"",brand:J?.brand??"",size:J?.size??"",colour:J?.colour??"",variant:J?.variant??"",availabilityStatus:ib(J||{}).status,source:J?.source??"",url:J?.url??"",barcode:J?.barcode??"",imageUrl:J?.imageUrl??"",imageData:$t?J.image:"",...J?Li(J):mc(c),imageBackgroundMode:J?.imageBackgroundMode??_m.imageBackgroundMode,imageBackgroundColor:gl(J?.imageBackgroundColor),...hc(We),imageFramingBase:Fe,imageFramingOverrides:ke,privateNotes:J?.privateNotes??J?.notes??"",publicNotes:J?.publicNotes??"",category:J?.category??i,cardSize:zn(J?.cardSize??J?.card_size)}),[F,te]=d.useState(De),[me,ie]=d.useState(Be),[Ae,Re]=d.useState(!1),ne=d.useRef(null),ht=d.useRef(null),kt=d.useRef(null),Ee=d.useRef(pe);d.useLayoutEffect(()=>{C?.(JSON.stringify(pe)!==JSON.stringify(Ee.current))},[pe,C]),d.useEffect(()=>()=>C?.(!1),[C]),d.useEffect(()=>{if(!Ae)return;const H=Et=>{ne.current?.contains(Et.target)||Re(!1)},ve=Et=>{Et.key==="Escape"&&(Re(!1),kt.current?.focus())};document.addEventListener("pointerdown",H,!0),window.addEventListener("keydown",ve),ht.current?.scrollIntoView({block:"nearest"});const Je=ht.current?.querySelectorAll('[role="option"]');
32return(ht.current?.querySelector('[role="option"][aria-selected="true"]')||Je?.[0])?.focus({preventScroll:!0}),()=>{document.removeEventListener("pointerdown",H,!0),window.removeEventListener("keydown",ve)}},[Ae]),d.useEffect(()=>()=>{ee.current=!1,A?.(!1)},[A]);const[xe,Qe]=d.useState(()=>{const H=Li(J||{}),ve=H.imageBackgroundMode==="manual"||H.imageBackgroundDetectorVersion!==null;return sa({color:H.imageBackgroundColor,confidenceLevel:H.imageBackgroundConfidenceLevel,ok:ve,reason:ve?H.imageBackgroundMode==="manual"?"saved-manual-color":"saved-automatic-color":"not-yet-sampled"})}),[Pe,Ct]=d.useState({active:!1,color:"",message:""}),[nr,en]=d.useState(()=>gl(J?.imageBackgroundColor)),[st,gr]=d.useState(""),[Xt,fn]=d.useState(!1),[Ke,ft]=d.useState(()=>!String(J?.privateNotes||J?.notes||"").trim()&&String(J?.publicNotes||"").trim()?"public":"private"),[lr,Wr]=d.useState(""),[Dr,kr]=d.useState(!1),[Gr,ar]=d.useState(""),[qr,tn]=d.useState(!1),[hn,Wn]=d.useState(!1),[br,rn]=d.useState({width:0,height:0}),[nn,Pn]=d.useState(""),[G,se]=d.useState(""),[le,ue]=d.useState(""),[Ne,be]=d.useState(""),[Te,Ve]=d.useState(!1),[at,yt]=d.useState(!1),[tt,He]=d.useState(!1),[Ge,Xe]=d.useState([]),[Dt,jt]=d.useState(()=>new Set),Zt=o.includes(pe.category)?o:[...o,pe.category],xt=E?"div":d.Fragment,Gt=E?{className:"modalImageStage"}:{},Or=vi(F,me),Yt=Number(p[Or])||u,er=Number(p[vi(Lr.normal,mn.standard)])||u,x=pe.imageData||pe.imageUrl.trim()||Sx(J),$=zi(J,x),O=Li(pe),q=Pe.active?{...Ed(O),objectFit:"contain",objectPosition:"50% 50%",transform:"none",transformOrigin:"50% 50%"}:Ed(O),X=Pe.color||O.imageBackgroundColor,Se=JSON.stringify(pe)!==JSON.stringify(Ee.current),he=ya(pe.imageFramingOverrides),$e=Object.prototype.hasOwnProperty.call(he,Or),Oe=aa(pe.url.trim()),Pt=pe.url.trim();let mt="";if(Oe)try{mt=new URL(Oe).hostname.replace(/^www\./,"")}catch{mt=""}const Kt=Nc(pe.source||Oe||pe.url)||"Saved item",rt=J?.category||i,St=pe.price!==Ee.current.price,_t={"--modal-image-preview-aspect-ratio":Number.isFinite(Yt)?Yt.toFixed(4):void 0,backgroundColor:X},dr=O.imageBackgroundMode==="manual"?`Manual background: ${O.imageBackgroundColor}`:xe.reason==="detecting"?"Detecting background...":xe.ok?`${xe.confidenceLevel==="low"?"Low confidence":"Detected"}: ${xe.color}`:xe.transparent?"Transparent image · neutral stage":"Low confidence · neutral stage",tr=(H,ve,Je={})=>{const lt=H===Lr.minimal?Lr.minimal:Lr.normal,Et=zn(ve);P.current+=1,te(lt),ie(Et),Tt(ur=>({...ur,...hc(Nm({base:ur.imageFramingBase,mode:lt,overrides:ur.imageFramingOverrides,size:Et})),...Je}))},yr=H=>{const ve=zn(H);tr(F,ve,{cardSize:ve})},Sr=(H,ve)=>{const Je=em({...H,...ve});return{...H,...hc(Je),imageFramingOverrides:wE(H.imageFramingOverrides,Or,Je)}},wr=(H,ve)=>{const Je=em(ve),lt=ao(H);return{...H,...hc(Je),...lt.mode==="auto"?{imageBackgroundMode:"auto",imageBackgroundColor:Bs}:{},imageFramingBase:Je,imageFramingOverrides:{}}},Mn=H=>{if(!["ArrowDown","ArrowUp","Home","End"].includes(H.key))return;const ve=[...ht.current?.querySelectorAll(".productEditorBoardMenuRow:not(.popoverMenuPageFiller)")||[]];if(!ve.length)return;H.preventDefault();const Je=ve.indexOf(document.activeElement),lt=ve.length-1,Et=H.key==="Home"?0:H.key==="End"?lt:H.key==="ArrowDown"?Je<0?0:(Je+1)%ve.length:Je<0?lt:(Je-1+ve.length)%ve.length;ve[Et]?.focus()},fr=H=>{const{name:ve,value:Je}=H.target,lt=ve==="barcode"?xl(Je):Je;if(["imageScale","imagePositionX","imagePositionY"].includes(ve)&&(re.current=!0),ve==="imageUrl"&&lt!==pe.imageUrl&&(Z.current=!0,re.current=!1,fe.current=lt),ve==="cardSize"){tr(F,lt,{cardSize:zn(lt)});return}Tt(Et=>ve==="imageUrl"&&lt!==Et.imageUrl?{...wr(Et,mc(Et.imageFit)),imageData:"",imageUrl:lt}:{...Et,[ve]:lt}),ve==="url"&&(K.current+=1,D.current?.abort(),D.current=null,yt(!1),se(""),Pn(""),Xe([]),jt(new Set))},Cr=H=>{const ve=yx(H);ve&&(ar(""),Z.current=!0,re.current=!1,fe.current=ve,Tt(Je=>({...wr(Je,mc(Je.imageFit)),imageData:"",imageUrl:ve})))},po=H=>{jt(ve=>new Set([...ve,H]))};d.useEffect(()=>()=>{K.current+=1,D.current?.abort(),V.current?.abort(),z.current?.abort()},[]);const ca=d.useCallback(H=>{const ve=xl(H);ve&&(se(""),Pn(""),ar(""),Tt(Je=>
32({...wr(Je,mc(c)),title:"",price:"",targetPrice:"",brand:"",size:"",colour:"",variant:"",availabilityStatus:"unknown",source:"Barcode scan",url:"",imageUrl:"",imageData:"",barcode:ve,privateNotes:"",publicNotes:""})),W("manual"))},[c]),mo=H=>$m(H,0,100,50),rs=()=>{const ve=N.current?.getBoundingClientRect();if(!ve?.width||!ve?.height||!br.width||!br.height)return{x:1,y:1};const Je=ve.width/ve.height,lt=br.width/br.height,ur=O.imageFit==="cover"?lt<Je:lt>Je,on=ur?ve.width:ve.height*lt,Lt=ur?ve.width/lt:ve.height,Sa=O.imageScale;return{x:on*Sa>ve.width+1?-1:1,y:Lt*Sa>ve.height+1?-1:1}},$s=H=>{re.current=!0,Tt(ve=>Sr(ve,{imagePositionX:mo(H.imagePositionX??ve.imagePositionX),imagePositionY:mo(H.imagePositionY??ve.imagePositionY)}))},ce=H=>{re.current=!0,Tt(ve=>{const Je=Li(ve).imageScale,lt=$m(Je+H*IW,Aw,Pw,Je);return lt===Je?ve:Sr(ve,{imageScale:Number(lt.toFixed(2))})})},oe=()=>{re.current=!0,Tt(H=>Sr(H,hc(SE(em(H)))))},gt=H=>{if(Pe.active||H.button!==void 0&&H.button!==0)return;const ve=N.current?.getBoundingClientRect();if(!(!ve?.width||!ve?.height)){H.preventDefault(),N.current?.focus();try{H.currentTarget.setPointerCapture?.(H.pointerId)}catch{}_.current={pointerId:H.pointerId,startX:H.clientX,startY:H.clientY,startPositionX:mo(pe.imagePositionX),startPositionY:mo(pe.imagePositionY),frameWidth:ve.width,frameHeight:ve.height,direction:rs()},Wn(!0)}},wt=H=>{const ve=_.current;if(!ve||ve.pointerId!==H.pointerId)return;H.preventDefault();const Je=(H.clientX-ve.startX)/ve.frameWidth*100*ve.direction.x,lt=(H.clientY-ve.startY)/ve.frameHeight*100*ve.direction.y;$s({imagePositionX:ve.startPositionX+Je,imagePositionY:ve.startPositionY+lt})},It=H=>{_.current?.pointerId===H.pointerId&&(H.currentTarget.hasPointerCapture?.(H.pointerId)&&H.currentTarget.releasePointerCapture?.(H.pointerId),_.current=null,Wn(!1))};d.useEffect(()=>{if(!hn)return;const H=ve=>{const Je=_.current;if(!Je||ve?.pointerId!==void 0&&ve.pointerId!==Je.pointerId)return;const lt=N.current;lt?.hasPointerCapture?.(Je.pointerId)&&lt.releasePointerCapture?.(Je.pointerId),_.current=null,Wn(!1)};return window.addEventListener("pointerup",H),window.addEventListener("pointercancel",H),window.addEventListener("blur",H),()=>{window.removeEventListener("pointerup",H),window.removeEventListener("pointercancel",H),window.removeEventListener("blur",H)}},[hn]);const or=async({forceAuto:H=!1,frameContent:ve=!1}={})=>{const Je=P.current+1;P.current=Je,V.current?.abort();const lt=new AbortController;V.current=lt,H&&(Tt(ur=>({...ur,imageBackgroundMode:"auto",imageBackgroundColor:Bs})),gr(""),Ct({active:!1,color:"",message:""}),rO(x)),Qe(sa({color:H?Bs:pe.imageBackgroundColor,reason:"detecting"}));const Et=await Pg(x,{force:H,signal:lt.signal});if(!(Et.reason==="aborted"||P.current!==Je)){if(Qe(Et),Tt(ur=>ao(ur).mode!=="auto"?ur:{...ur,imageBackgroundMode:fS(Et),imageBackgroundColor:Et.ok?gl(Et.color):Bs}),ve&&Et.ok){const ur=await Fw({backgroundColor:Et.color,frameAspectRatio:Yt,imageSource:x});if(P.current!==Je||!ur.ok||re.current)return;Tt(on=>Sr(on,ur))}V.current===lt&&(V.current=null)}};d.useEffect(()=>{const H=ao(pe);
32if(H.mode==="manual"){V.current?.abort(),Qe(sa({color:H.color,confidence:1,ok:!0,reason:"saved-manual-color"}));return}if(!hS(pe)){Qe(sa({color:H.color,confidenceLevel:H.confidenceLevel,confidence:H.confidenceLevel==="high"?.9:H.confidenceLevel==="medium"?.67:.3,ok:!0,reason:"saved-automatic-color"}));return}const ve=P.current+1;P.current=ve,V.current?.abort();const Je=new AbortController;return V.current=Je,Qe(sa({color:H.color,reason:"detecting"})),Pg(x,{signal:Je.signal}).then(async lt=>{if(Je.signal.aborted||lt.reason==="aborted"||P.current!==ve||(Qe(lt),Tt(on=>ao(on).mode!=="auto"?on:{...on,imageBackgroundMode:fS(lt),imageBackgroundColor:lt.ok?gl(lt.color):Bs}),!(lt.ok&&(!k||Z.current)&&!re.current)))return;const ur=await Fw({backgroundColor:lt.color,frameAspectRatio:er,imageSource:x});Je.signal.aborted||P.current!==ve||re.current||!ur.ok||Tt(on=>{const Lt=em(ur);return{...on,...hc(Lt),imageFramingBase:Lt,imageFramingOverrides:{}}})}),()=>{Je.abort()}},[er,k,x]),d.useEffect(()=>{z.current?.abort(),Ct({active:!1,color:"",message:""})},[x]);const Yr=()=>{z.current?.abort(),z.current=null,Ct({active:!1,color:"",message:""}),window.setTimeout(()=>{E&&L.current?.setAttribute("open",""),B.current?.focus()},0)},qt=()=>{V.current?.abort(),Ct({active:!0,color:"",message:"Click or tap a colour on the product image."}),E&&window.requestAnimationFrame(()=>L.current?.removeAttribute("open"))},Ir=async H=>{if(!Pe.active)return;H.preventDefault();const ve=N.current?.querySelector("img")?.getBoundingClientRect(),Je=Z0({containerHeight:ve?.height,containerLeft:ve?.left,containerTop:ve?.top,containerWidth:ve?.width,naturalHeight:br.height,naturalWidth:br.width,pointX:H.clientX,pointY:H.clientY});if(!Je.inside){Ct(ur=>({...ur,color:"",message:"Choose a point inside the image, not the surrounding stage."}));return}z.current?.abort();const lt=new AbortController;z.current=lt,Ct(ur=>({...ur,message:"Sampling colour..."}));const Et=await tO(x,{signal:lt.signal,x:Je.x,y:Je.y});lt.signal.aborted||Et.reason==="aborted"||(Ct(ur=>({...ur,color:Et.ok?Et.color:"",message:Et.ok?`Selected ${Et.color}.`:Et.reason==="transparent-neighbourhood"?"That point is transparent. Choose a visible colour.":"This image cannot be sampled. Use a custom colour instead."})),E&&window.requestAnimationFrame(()=>L.current?.setAttribute("open","")))},Fr=()=>{Pe.color&&(Tt(H=>({...H,imageBackgroundMode:ym,imageBackgroundColor:Pe.color})),en(Pe.color),gr(""),Ct({active:!1,color:"",message:""}),window.setTimeout(()=>B.current?.focus(),0))};d.useEffect(()=>{if(!Pe.active)return;const H=ve=>{ve.key==="Escape"&&(ve.preventDefault(),Yr())};return window.addEventListener("keydown",H),()=>window.removeEventListener("keydown",H)},[Pe.active]);const gn=()=>{V.current?.abort(),Ct({active:!1,color:"",message:""}),en(O.imageBackgroundColor),gr(""),Tt(H=>({...H,imageBackgroundMode:ym,imageBackgroundColor:gl(H.imageBackgroundColor)}))},Vt=H=>{en(H);const ve=Ku(H);if(!ve){gr("Enter a colour as #RRGGBB, RRGGBB, or #RGB.");return}gr(""),Tt(Je=>({...Je,imageBackgroundMode:ym,imageBackgroundColor:ve}))},fo=H=>{if(Pe.active)return;const Je={ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1],ArrowDown:[0,1]}[H.key];if(!Je)return;H.preventDefault();const lt=H.shiftKey?5:1,Et=rs();$s({imagePositionX:Number(pe.imagePositionX)+Je[0]*lt*Et.x,imagePositionY:Number(pe.imagePositionY)+Je[1]*lt*Et.y})},Dc=async H=>{if(H)try{ar("");const ve=await q3(H);Z.current=!0,re.current=!1,Tt(Je=>{const lt=String(Je.imageUrl||"").trim();return lt&&(fe.current=lt),{...wr(Je,mc(Je.imageFit)),imageData:ve,imageUrl:""}})}catch(ve){ar(ve.message||"Could not use that image.")}},Oc=()=>{const H=aa(lr.trim());if(!H){ar("Enter a valid image URL.");return}fr({target:{name:"imageUrl",value:H}}),Wr(""),kr(!1),ar("")};d.useEffect(()=>{const H=ve=>{const Je=[...ve.clipboardData?.files??[]].find(lt=>lt.type.startsWith("image/"));Je&&(ve.preventDefault(),Dc(Je))};return window.addEventListener("paste",H),()=>window.removeEventListener("paste",H)},[]);const ho=async()=>{const H=pe.url.trim(),ve=aa(H);if(!ve){D.current?.abort(),D.current=null,K.current+=1,yt(!1),se("Enter a valid product URL."),Pn("");return}D.current?.abort();const Je=K.current+1;K.current=Je,yt(!0),se(""),Pn("Fetching product details…");const lt=new AbortController;D.current=lt;const Et=window.setTimeout(()=>lt.abort(),hW);try{const ur=await fetch("/api/metadata",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({url:ve}),signal:lt.signal}),on=await ur.json().catch(()=>({}));if(!ur.ok)throw new Error(on.error||"metadata-fetch-failed");if(K.current!==Je)return;const Lt=on.metadata||{},Sa=j3(Lt.imageCandidates,Lt.imageUrl);Xe(Sa),jt(new Set),Tt(Fa=>{const qn=aa(String(Lt.canonicalUrl||"")),_n={...Fa,url:qn||Fa.url.trim()||ve},go=Nc(Lt.source||qn||ve)||Go(ve),bo=Sa[0]?.url||Lt.imageUrl,ys=(an,ns)=>
32{const Zn=typeof ns=="string"?ns.trim():ns;!_n[an]&&Zn&&(an==="imageUrl"&&(Z.current=!0,re.current=!1,Object.assign(_n,wr(_n,mc(_n.imageFit)))),_n[an]=Zn)};return ys("title",Lt.title),ys("brand",Lt.brand),ys("source",Nc(Lt.source)||go),ys("price",Lt.price),ys("imageUrl",bo),_n}),Pn(R3(Lt,Sa))}catch(ur){if(K.current!==Je)return;Tt(on=>({...on,url:on.url.trim()||ve,source:on.source.trim()?on.source:Go(ve)})),se(L3(ur)),Pn("")}finally{window.clearTimeout(Et),K.current===Je&&(D.current=null,yt(!1))}},Ua=async H=>{if(H.preventDefault(),ee.current)return;ue(""),be("");const ve=pe.title.trim();if(!ve){ue("Add a product title before saving."),be("validation-missing-title");return}const Je=pe.url.trim(),lt=Z.current?pe.imageData?{image:pe.imageData,imageUrl:""}:{image:pe.imageUrl.trim(),imageUrl:pe.imageUrl.trim()}:{image:J?.image??pe.imageData??pe.imageUrl.trim(),imageUrl:J?.imageUrl??pe.imageUrl.trim()},Et=bs(lt,{isPlaceholder:qo});if(Et.kind==="local-path"&&Z.current){ue("Choose a fully qualified product image URL before saving."),be("invalid-image-reference");return}if(Et.requiresReview||Et.hasConflict){ue("Choose a valid product image before saving."),be(Et.diagnosticCode||"invalid-image-reference");return}const ur=Et.kind==="local-upload"?{image:Et.value,imageUrl:""}:Et.kind==="external"?{image:Et.value,imageUrl:Et.value}:Et.kind==="local-path"?{image:Et.value,imageUrl:""}:{image:"",imageUrl:""},on=e?.id??Xb(),Lt=new Date().toISOString(),Sa=p3(pe.availabilityStatus,e?.availability,{recordedAt:Lt}),Fa=ib(e||{}),qn=Sa||{status:"unknown",source:"manual",checkedAt:Lt},_n=nD(e?.availabilityHistory,Fa,qn,{checkedAt:Lt,source:"manual"}),go={...e||{},id:on},bo=_n.changed?pD(go,Fa,qn,{checkedAt:Lt,createId:()=>Sd("availability-alert-event"),source:"manual",transition:_n.transition}):null,ys=bo?mD(go,[bo]):go,an=hc(pe.imageFramingBase);ee.current=!0,He(!0),A?.(!0);try{const ns=Ye(pe.category)||i,Zn=ro(s,ns),Hi=await f({id:on,createdAt:e?.createdAt??new Date().toISOString(),title:ve,price:pe.price.trim()||`${de}--`,currency:Nl(pe.price,pe.currency||de),targetPrice:pe.targetPrice.trim(),brand:pe.brand.trim(),size:pe.size.trim(),colour:pe.colour.trim(),variant:pe.variant.trim(),availability:Sa,..._n.changed?{availabilityHistory:_n.history}:{},...ys.availabilityAlertEvents?{availabilityAlertEvents:ys.availabilityAlertEvents}:{},category:ns,...Zn?.id?{listId:Zn.id}:{},cardSize:zn(pe.cardSize),source:pe.source.trim()||Go(Je),barcode:xl(pe.barcode),privateNotes:pe.privateNotes.trim(),publicNotes:pe.publicNotes.trim(),...k?{}:{priceHistorySource:ye?"extension-save":Le?"url-import":"created"},url:Je,...ur,imageAutoFramePending:(!k||Z.current)&&!re.current,...an,imageBackgroundMode:ao(pe).mode==="manual"?ym:pe.imageBackgroundMode,imageBackgroundColor:gl(pe.imageBackgroundColor),imageFramingOverrides:ya(pe.imageFramingOverrides)},{imageCropWasManuallyChanged:re.current,imageWasReplaced:Z.current});Hi?.ok===!1&&(ue(Hi.message||"Could not save this item. Review it and try again."),be(Hi.reason||"submission-blocked"))}catch(ns){ue(ns?.message||"Could not save this item. Try again."),be("submission-error")}finally{ee.current=!1,He(!1),A?.(!1)}},Gn=async()=>{if(!(!I||Te)){ue(""),be(""),Ve(!0);try{const H=await I();H?.ok||(ue(H?.message||Fu),be(H?.reason||"missing-revision-recovery-blocked"))}catch{ue(Fu),be("missing-revision-recovery-failed")}finally{Ve(!1)}}},Vi=n.jsxs("div",{className:"metadataFeedback","aria-live":"polite",children:[G?n.jsxs("span",{className:"metadataFeedbackLine",children:[n.jsx("em",{children:G}),aa(pe.url.trim())&&!at?n.jsx("button",{onClick:ho,type:"button",children:"Try again"}):null]}):null,nn?n.jsx("em",{children:nn}):null]}),Ze=pe.imageData?"":pe.imageUrl.trim();return n.jsx("div",{className:E?"itemDetailEditorSurface":"modalLayer",role:E?void 0:"presentation",children:n.jsx("div",{"aria-labelledby":E?void 0:"add-product-title","aria-modal":E?void 0:"true",className:`${E?"itemDetailEditorCard":"addProductModal"} productEditorModal`,role:E?void 0:"dialog",children:n.jsxs("form",{"aria-busy":tt?"true":"false",autoComplete:"off",className:"addProductForm productEditorForm",id:a,onKeyDown:H=>{E&&(H.metaKey||H.ctrlKey)&&H.key.toLowerCase()==="s"&&(H.preventDefault(),Se&&!tt&&H.currentTarget.requestSubmit())},onSubmit:Ua,children:[E?n.jsxs("header",{className:"productEditorEditorialHeader",children:[n.jsxs("button",{"aria-label":`Back to ${rt}`,className:"productEditorEditorialBack",disabled:tt,onClick:b,type:"button",children:[n.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:n.jsx("path",{d:"M15 5 8 12l7 7"})}),n.jsxs("span",{children:["Back to ",rt]})]}),n.jsxs("div",{className:"productEditorEditorialHeading",children:[n.jsx("span",{children:"Edit item"}),n.jsxs("label",{className:"productEditorEditorialTitleField",children:[n.jsx("span",{className:"srOnly",children:"Product title"}),n.jsx("input",{"aria-label":"Product title",autoComplete:"off",maxLength:140,name:"title",onCh
32ange:fr,placeholder:"Untitled item",spellCheck:!1,value:pe.title})]})]}),n.jsxs("div",{className:"productEditorEditorialActions","aria-label":"Edit item actions",children:[n.jsxs("span",{"aria-live":"polite",className:"productEditorSaveStatus","data-state":tt?"saving":le?"error":Se?"unsaved":"saved",children:[n.jsx("i",{"aria-hidden":"true"}),tt?"Saving…":le?"Couldn’t save":Se?"Unsaved changes":"Saved"]}),n.jsx("button",{className:"productEditorEditorialCancel",disabled:tt,onClick:h,type:"button",children:"Cancel"}),n.jsx("button",{className:"productEditorEditorialSave",disabled:!Se||tt,type:"submit",children:tt?"Saving…":"Save changes"}),n.jsxs("details",{className:"productEditorEditorialMore",children:[n.jsx("summary",{"aria-label":"More item actions",title:"More item actions",children:n.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[n.jsx("circle",{cx:"5",cy:"12",r:"1.5"}),n.jsx("circle",{cx:"12",cy:"12",r:"1.5"}),n.jsx("circle",{cx:"19",cy:"12",r:"1.5"})]})}),n.jsx("div",{"aria-label":"Item actions",className:"saveboardMenuPanel",role:"menu",children:n.jsx("button",{className:"saveboardMenuRow saveboardMenuDangerRow",disabled:tt,onClick:()=>S(e),role:"menuitem",type:"button",children:"Delete product"})})]})]})]}):null,E?null:n.jsxs("header",{className:"modalHeader productEditorHeader",children:[n.jsxs("div",{children:[n.jsx("p",{className:"productEditorKicker",children:k?"Edit product":"Add product"}),n.jsx("h2",{id:"add-product-title",children:k?"Edit Product":"Add Product"})]}),ye?n.jsx("p",{className:"captureModalSource",children:t?.captureSource==="edit"?"Captured from The Edit":"Captured from Chrome"}):null]}),pt||le?n.jsxs("div",{className:"productEditorNoticeStack",children:[pt?n.jsx("div",{className:"duplicateCaptureNotice captureTargetNotice",children:n.jsx("span",{children:pt})}):null,le?n.jsx("div",{"aria-live":"assertive",className:"duplicateCaptureNotice","data-submission-reason":Ne||"submission-error",role:"alert",children:n.jsx("span",{children:le})}):null]}):null,ge?n.jsx("section",{className:"productEntryOptions","aria-label":"Add product options",children:S3.map(H=>n.jsx("button",{className:ze===H.id?"isActive":"",onClick:()=>W(H.id),type:"button",children:H.label},H.id))}):null,Le?n.jsxs("section",{className:"productEditorUrlImport","aria-label":"Add from URL",children:[n.jsx("span",{className:"productEditorUrlImportTitle",children:"Add from URL"}),n.jsxs("label",{className:"urlField productEditorUrlField",children:[n.jsxs("span",{children:["Paste product URL",n.jsx("button",{"aria-label":"Fetch product details",disabled:at,onClick:ho,type:"button",children:at?"Fetching…":"Fetch details"})]}),n.jsx("input",{autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",autoFocus:!0,name:"url",onChange:fr,placeholder:"https://",type:"url",value:pe.url}),Vi]})]}):null,et?n.jsx(pY,{onBarcodeDetected:ca,onCancel:()=>W("manual")}):null,pe.barcode?n.jsxs("div",{className:"barcodeDraftNotice","aria-live":"polite",children:[n.jsx("span",{children:"Barcode"}),n.jsx("strong",{children:pe.barcode}),ge?n.jsx("button",{type:"button",onClick:()=>W("barcode"),children:"Scan again"}):null]}):null,n.jsxs("div",{className:`productEditorMain${E?" isEditorial":""}`,children:[n.jsx("section",{className:"productEditorImagePanel","aria-label":"Product image",children:n.jsxs("div",{className:`modalImageInput${qr?" isDragging":""}`,onDragEnter:H=>{H.preventDefault(),tn(!0)},onDragLeave:H=>{H.preventDefault(),tn(!1)},onDragOver:H=>{H.preventDefault()},onDrop:H=>{H.preventDefault(),tn(!1),Dc(H.dataTransfer.files?.[0])},children:[n.jsx("input",{accept:AR.join(","),className:"imageFileInput",onChange:H=>{Dc(H.target.files?.[0]),H.target.value=""},ref:y,type:"file"}),n.jsxs("div",{className:"imageFramingContextControl","data-framing-context":Or,children:[n.jsxs("span",{children:["Framing: ",n.jsxs("strong",{children:[F===Lr.minimal?"Minimal":"Normal"," · ",me[0].toUpperCase()+me.slice(1)]})]}),n.jsxs("div",{className:"imageFramingContextOptions",children:[n.jsx("div",{"aria-label":"Framing mode",className:"fitModeControl imageFramingModeControl",role:"group",children:[[Lr.normal,"Normal"],[Lr.minimal,"Minimal"]].map(([H,ve])=>n.jsx("button",{"aria-pressed":F===H,className:F===H?"isActive":"",onClick:()=>tr(H,me),type:"button",children:ve},H))}),n.jsx("span",{"aria-hidden":"true",className:"imageFramingContextDivider"}),n.jsx("div",{"aria-label":"Card format",className:"fitModeControl imageCardSizeControl",role:"group",children:Object.values(mn).map(H=>n.jsxs("button",{"aria-pressed":me===H,className:me===H?"isActive":"",onClick:()=>E?yr(H):tr(F,H),type:"button",children:[E?n.jsx("span",{"aria-hidden":"true",className:"imageCardSizeSegIcon",children:H===mn.standard?n.jsx("svg",{viewBox:"0 0 24 24",children:n.jsx("rect",{x:"6.5",y:"6.5",width:"11",height:"11",rx:"2.5"})}):H===mn.wide?n.jsx("svg",{viewBox:"0 0 24 24",children:n.jsx("rect",{x:"3.5",y:"8",width:"17",height:"8.5",rx:"2.5"})}):n.jsxs("svg",{viewBox:"0 0 24 24",children:[n.jsx("rect",{x:"4.5",y:"4.5",width:"6.4",height:"6.4",rx:"1.6"}),n.jsx("rect",{x:"13.1",y:"4.5",width:"6.4",height:"6.4",rx:"1.6"}),n.jsx("rect",{x:"4.5",y:"13.1",width:"6.4",height:"6.4",rx:"1.6"}),n.jsx("rect",{x:"13.1",y:"13.1",width:"6.4",height:"6.4",rx:"1.6"})]})}):null,H[0].toUpperCase()+H.slice(1)]},H))})]})]}),n.jsxs(xt,{...Gt,children:[n.jsxs("div",{"aria-describedby":Pe.active?"image-colour-picker-status":void 0,"aria-label":Pe.active?"Choose a background colour from the product image. Press Escape to cancel.":"Drag image to reposition. Use arrow keys for small nudges.",className:`modalImagePreview${hn?" isRepositioning":""}${Pe.active?" isPickingColour":""}`,onKeyDown:fo,onPointerCancel:It,onPointerDown:H=>{if(Pe.active){H.preventDefault();return}gt(H)},onLostPointerCapture:It,onPointerMove:wt,onPointerUp:H=>{if(Pe.active){Ir(H);return}It(H)},ref:N,role:"group",style:_t,tabIndex:0,children:[n.jsx(Ms,{alt:"",alternateSources:$,decoding:"async",draggable:!1,fallbackSource:jn,loading:"eager",source:x,style:q,onLoad:H=>
32{rn({width:H.currentTarget.naturalWidth,height:H.currentTarget.naturalHeight})}}),Pe.active?n.jsx("div",{"aria-hidden":"true",className:"imageColourPickerReticle",children:"Pick from image"}):n.jsxs(n.Fragment,{children:[n.jsxs("div",{"aria-label":"Image zoom controls",className:"imageZoomControls",onPointerDown:H=>H.stopPropagation(),role:"group",children:[n.jsx("button",{"aria-label":"Zoom in",disabled:O.imageScale>=Pw,onClick:()=>ce(1),type:"button",children:n.jsx("span",{"aria-hidden":"true",children:"+"})}),n.jsx("button",{"aria-label":"Zoom out",disabled:O.imageScale<=Aw,onClick:()=>ce(-1),type:"button",children:n.jsx("span",{"aria-hidden":"true",children:"−"})})]}),n.jsx("div",{className:"imageFitControl",onPointerDown:H=>H.stopPropagation(),children:n.jsx("button",{"aria-label":"Fit image to frame",onClick:oe,title:"Fit image to frame",type:"button",children:"Fit"})})]})]}),n.jsxs("div",{className:"modalImageCopy",children:[n.jsx("span",{children:"Drop image, paste, upload, or use URL. Drag preview to position."}),n.jsxs("div",{className:"modalImageActions",children:[n.jsxs("button",{type:"button",onClick:()=>y.current?.click(),children:[E?n.jsxs("svg",{"aria-hidden":"true",className:"modalImageActionIcon",viewBox:"0 0 24 24",children:[n.jsx("path",{d:"M12 15V4"}),n.jsx("path",{d:"m7.5 8.5 4.5-4.5 4.5 4.5"}),n.jsx("path",{d:"M5 15v3.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V15"})]}):null,E?"Replace image":"Upload"]}),pe.imageData?n.jsx("button",{type:"button",onClick:()=>{Z.current=!0,re.current=!1,Tt(H=>({...wr(H,mc(H.imageFit)),imageData:"",imageUrl:fe.current})),ar("")},children:"Use URL"}):null]}),Gr?n.jsx("p",{children:Gr}):null]}),Le?n.jsx(mY,{brokenUrls:Dt,candidates:Ge,onImageError:po,onSelect:Cr,selectedUrl:Ze}):null,E?null:n.jsxs("label",{className:"productEditorImageUrlField",children:[n.jsx("span",{children:"Image URL"}),n.jsx("input",{autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",name:"imageUrl",onChange:fr,type:"url",value:pe.imageUrl})]}),n.jsxs("details",{className:"imageBackgroundMenu",open:E?void 0:!0,ref:L,children:[E?n.jsxs("summary",{"aria-label":"Image background settings",children:[n.jsx("span",{"aria-hidden":"true",className:"imageBackgroundSwatch",style:{backgroundColor:X}}),n.jsx("span",{className:"imageBackgroundMenuHex",children:X}),n.jsx("span",{children:Pe.active?"Pick from image":O.imageBackgroundMode==="manual"?"Custom colour":"Auto"}),n.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:n.jsx("path",{d:"m6 9 6 6 6-6"})})]}):null,n.jsxs("div",{className:"imageEditingControls",children:[n.jsx("div",{className:"fitModeControl","aria-label":"Image fit mode",children:["contain","cover"].map(H=>n.jsx("button",{className:O.imageFit===H?"isActive":"",onClick:()=>{re.current=!0,Tt(ve=>{const Je=mc(H);return{...Sr(ve,Je),imageBackgroundMode:ve.imageBackgroundMode,imageBackgroundColor:ve.imageBackgroundColor}})},type:"button",children:H},H))}),n.jsxs("div",{className:"imageBackgroundControl",children:[n.jsx("span",{children:"Backgroun
32d"}),n.jsxs("div",{"aria-label":"Image background mode",className:"imageBackgroundModeControl",role:"group",children:[n.jsx("button",{"aria-pressed":O.imageBackgroundMode==="auto"&&!Pe.active,className:O.imageBackgroundMode==="auto"&&!Pe.active?"isActive":"",onClick:()=>{re.current=!1,or({forceAuto:!0,frameContent:!0})},type:"button",children:"Auto"}),n.jsx("button",{"aria-pressed":Pe.active,className:Pe.active?"isActive":"",disabled:!x,onClick:qt,ref:B,type:"button",children:"Pick from image"}),n.jsx("button",{"aria-pressed":O.imageBackgroundMode==="manual"&&!Pe.active,className:O.imageBackgroundMode==="manual"&&!Pe.active?"isActive":"",onClick:gn,type:"button",children:"Custom colour"})]})]}),Pe.active?n.jsxs("div",{className:"imageColourPickerPanel",children:[n.jsxs("div",{"aria-live":"polite",className:"imageBackgroundDebug",id:"image-colour-picker-status",children:[n.jsx("span",{"aria-hidden":"true",className:"imageBackgroundSwatch",style:{backgroundColor:Pe.color||O.imageBackgroundColor}}),n.jsx("span",{children:Pe.message})]}),n.jsxs("div",{className:"imageColourPickerActions",children:[n.jsx("button",{onClick:Yr,type:"button",children:"Cancel"}),n.jsxs("button",{disabled:!Pe.color,onClick:Fr,type:"button",children:["Use ",Pe.color||"colour"]})]})]}):O.imageBackgroundMode==="manual"?n.jsxs("div",{className:"customImageBackgroundEditor",children:[n.jsxs("label",{className:"customImageBackgroundVisualInput",children:[n.jsx("span",{children:"Visual colour"}),n.jsx("input",{"aria-label":"Visual background colour",onChange:H=>Vt(H.target.value),type:"color",value:O.imageBackgroundColor})]}),n.jsxs("label",{className:"customImageBackgroundHexInput",children:[n.jsx("span",{children:"Hex colour"}),n.jsx("input",{"aria-describedby":st?"image-background-colour-error":void 0,"aria-invalid":!!st,autoCapitalize:"off",autoComplete:"off",onChange:H=>Vt(H.target.value),spellCheck:!1,type:"text",value:nr})]}),st?n.jsx("span",{className:"customImageBackgroundError",id:"image-background-colour-error",role:"alert",children:st}):null]}):n.jsxs("div",{className:"imageBackgroundDebug","aria-live":"polite",children:[n.jsx("span",{"aria-hidden":"true",className:"imageBackgroundSwatch",style:{backgroundColor:xe.color}}),n.jsx("span",{children:dr}),n.jsx("button",{className:"redetectImageBackgroundButton",onClick:()=>{re.current=!1,or({forceAuto:!0,frameContent:!0})},type:"button",children:"Re-detect"})]}),E?n.jsx("div",{className:"imageUrlReplacementControl",children:Dr?n.jsxs(n.Fragment,{children:[n.jsxs("label",{children:[n.jsx("span",{children:"Replacement image URL"}),n.jsx("input",{"aria-label":"Image URL",autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",onChange:H=>Wr(H.target.value),placeholder:"https://",type:"url",value:lr})]}),n.jsxs("div",{children:[n.jsx("button",{onClick:()=>kr(!1),type:"button",children:"Cancel"}),n.jsx("button",{disabled:!aa(lr.trim()),onClick:Oc,type:"button",children:"Use URL"})]})]}):n.jsx("button",{onClick:()=>kr(!0),type:"button",children:"Replace from URL"})}):null,!E||$e?n.jsx("button",{className:"resetImageButton",onClick:()=>{re.current=!1,Tt(H=>{const ve=rB(H.imageFramingOverrides,Or);return{...H,...hc(Nm({base:H.imageFramingBase,mode:F,overrides:ve,size:me})),imageFramingOverrides:ve}})},type:"button",children:"Reset framing for this view"}):null]})]})]})]})}),n.jsxs("section",{className:"productEditorDetails","aria-label":"Product details",children:[E?n.jsxs("div",{className:"productEditorSourceContext",children:[n.jsx("i",{"aria-hidden":"true"}),n.jsxs("span",{children:["Saved from ",Kt]})]}):n.jsxs("label",{className:"productEditorTitleField",children:[n.jsx("span",{children:"Product title"}),n.jsx("input",{autoComplete:"off",autoFocus:!Le&&!et,name:"title",onChange:fr,required:!0,value:pe.title})]}),n.jsxs("div",{className:"productEditorInlineGrid",children:[n.jsxs("label",{className:"productEditorCurrentPriceField",children:[n.jsx("span",{children:E?"Current price":"Price"}),E?n.jsxs("div",{className:"productEditorPriceControl",children:[n.jsx("select",{"aria-label":"Currency",name:"currency",onChange:fr,value:Nd(pe.currency),children:wb.map(H=>n.jsx("option",{value:H.code,children:H.code},H.code))}),n.jsx("input",{"aria-label":"Price",autoComplete:"off",inputMode:"decimal",name:"price",onChange:fr,placeholder:"0.00",value:pe.price}),n.jsx("small",{children:St?"Manual":"Detected"})]}):n.jsx("input",{autoComplete:"off",inputMode:"decimal",name:"price",onChange:fr,placeholder:de,value:pe.price})]}),xR?n.jsxs("label",{className:"productEditorTargetPriceField",children:[n.jsx("span",{children:"Target price"}),E?n.jsxs("div",{className:"productEditorTargetPriceControl",children:[n.jsx("span",{"aria-hidden":"true",children:"+"}),n.jsx("input",{"aria-label":"Target price",autoComplete:"off",inputMode:"decimal",name:"targetPrice",onChange:fr,placeholder:"Set target price",value:pe.targetPrice})]}):n.jsx("input",{autoComplete:"off",inputMode:"decimal",name:"targetPrice",onChange:fr,placeholder:`${de}99`,value:pe.targetPrice})]}):null,E?n.jsxs("div",{className:"productEditorBoardField",children:[n.jsx("span",{children:"Board"}),n.jsxs("div",{className:"productEditorBoardControl",ref:ne,children:[n.jsxs("button",{"aria-expanded":Ae,"aria-haspopup":"listbox","aria-label":"Board",className:"productEditorBoardTrigger",onClick:()=>Re(H=>!H),ref:kt,type:"button",children:[n.jsx("span",{className:"productEditorBoardValue",children:pe.category||"Select a board"}),n.jsx("svg",{"aria-hidden":"true",className:"productEditorBoardChevron",viewBox:"0 0 24 24",children:n.jsx("path",{d:"m6 9.5 6 6 6-6"})})]}),Ae?n.jsxs("div",{className:"productEditorBoardMenu",onKeyDown:Mn,ref:ht,children:[n.jsx("p",{className:"productEditorBoardMenuLabel",id:"product-editor-board-menu-label",children:"Move to board"}),n.jsx(Vw,{activeIndex:Zt.indexOf(pe.category),itemLabel:"boards",items:Zt,listClassName:"productEditorBoardMenuList",listProps:{"aria-labelledby":"product-editor-board-menu-label",role:"listbox"},renderItem:H=>{const ve=H===pe.category;return n.jsxs("button",{"aria-selected":ve,className:"productEditorBoardMenuRow",onClick:()=>{Re(!1),kt.current?.focus(),ve||fr({target:{name:"category",value:H}})},role:"option",type:"button",children:[n.jsx("span",{className:"productEditorBoardMenuName",children:H}),ve?n.jsx("svg",{"aria-hidden":"true",className:"productEditorBoardMenuCheck",viewBox:"0 0 24 24",children:n.jsx("path",{d:"m5 12.5 4 4 10-10"})}):null]},H)},rowClassName:"productEditorBoardMenuRow"}),v?n.jsxs(n.Fragment,{children:[n.jsx("span",{"aria-hidden":"true",className:"productEditorBoardMenuDivider"}),n.jsxs("button",{className:"productEditorBoardMenuRow productEditorBoardMenuNew",onClick:()=>{Re(!1),v()},type:"button",children:[n.jsx("svg",{"aria-hidden":"true",className:"productEditorBoardMenuPlus",viewBox:"0 0 24 24",children:n.jsx("path",{d:"M12 5v14M5 12h14"})}),n.jsx("span",{className:"productEditorBoardMenuName",children:"New board…"})]})]}):null]}):null]})]}):n.jsxs("label",{className:"productEditorBoardField",children:[n.jsx("span",{children:"Board/category"}),n.jsx("select",{"aria-label":"Board/category",name:"category",onChange:fr,value:pe.category,children:Zt.map(H=>n.jsx("option",{value:H,children:H},H))})]})]}),E?null:n.jsxs("fieldset",{className:"productEditorCardSizeFieldset",children:[n.jsx("legend",{children:"Card size"}),n.jsx("div",{className:"productEditorCardSizeOptions",children:[{label:"Standard",size:mn.standard},{label:"Wide",size:mn.wide},{label:"Large",size:mn.large}].map(H=>n.jsxs("label",{className:pe.cardSize===H.size?"isSelected":"",children:[n.jsx("input",{"aria-label":`${H.label}
32 item size`,checked:pe.cardSize===H.size,name:"cardSize",onChange:fr,type:"radio",value:H.size}),n.jsx("span",{"aria-hidden":"true",className:`itemCardSizeIcon is-${H.size}`,children:n.jsx("i",{})}),n.jsx("span",{children:H.label})]},H.size))})]}),n.jsxs("details",{className:"productEditorDisclosure productEditorDetailsDisclosure",open:!0,children:[n.jsxs("summary",{children:[n.jsx("span",{children:"Details"}),n.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:n.jsx("path",{d:"m6 9 6 6 6-6"})})]}),n.jsxs("div",{className:"productEditorDisclosureBody",children:[n.jsxs("div",{className:"productEditorMetaGrid",children:[n.jsxs("label",{children:[n.jsx("span",{children:"Brand"}),n.jsx("input",{autoComplete:"off",name:"brand",onChange:fr,value:pe.brand})]}),n.jsxs("label",{children:[n.jsx("span",{children:"Source"}),n.jsx("input",{autoComplete:"off",name:"source",onChange:fr,placeholder:"Website or store",value:pe.source})]}),Rr.availabilityTrackingEnabled?n.jsxs("label",{children:[n.jsx("span",{children:"Availability"}),n.jsx("select",{name:"availabilityStatus",onChange:fr,value:pe.availabilityStatus,children:Zb.map(H=>n.jsx("option",{value:H.value,children:H.label},H.value))})]}):null]}),n.jsxs("div",{className:"productEditorVariantGrid",children:[n.jsxs("label",{children:[n.jsx("span",{children:"Size"}),n.jsx("input",{autoComplete:"off",name:"size",onChange:fr,placeholder:"M / UK 8 / 42",value:pe.size})]}),n.jsxs("label",{children:[n.jsx("span",{children:"Colour"}),n.jsx("input",{autoComplete:"off",name:"colour",onChange:fr,placeholder:"Black / Cream / Walnut",value:pe.colour})]}),n.jsxs("label",{children:[n.jsx("span",{children:"Variant"}),n.jsx("input",{autoComplete:"off",name:"variant",onChange:fr,placeholder:"128GB / Left-facing / Set of 2",value:pe.variant})]})]}),pe.barcode?n.jsxs("label",{className:"barcodeField",children:[n.jsx("span",{children:"Barcode"}),n.jsx("input",{autoComplete:"off",inputMode:"numeric",name:"barcode",onChange:fr,value:pe.barcode})]}):null]})]}),Le?null:n.jsxs("label",{className:"urlField productEditorUrlField",children:[n.jsxs("span",{children:[E?"Product link":"URL",E?null:n.jsx("button",{"aria-label":"Fetch product details",disabled:at,onClick:ho,type:"button",children:at?"Fetching…":"Fetch details"})]}),n.jsxs("div",{className:"productEditorUrlControl",children:[n.jsx("input",{"aria-invalid":!!(pe.url.trim()&&!Oe),autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",name:"url",onChange:fr,type:"url",value:pe.url}),E?n.jsxs(n.Fragment,{children:[n.jsx("button",{"aria-label":"Copy product link",disabled:!Oe,onClick:async()=>{if(Oe)try{await navigator.clipboard.writeText(Oe),fn(!0),window.setTimeout(()=>fn(!1),1400)}catch{se("Could not copy the product link.")}},title:Xt?"Copied":"Copy product link",type:"button",children:Xt?n.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:n.jsx("path",{d:"m5 12 4 4 10-10"})}):n.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[n.jsx("rect",{x:"9",y:"9",width:"11",height:"11",rx:"2.5"}),n.jsx("path",{d:"M5 15V5.5A1.5 1.5 0 0 1 6.5 4H15"})]})}),n.jsx("a",{"aria-label":"Open product link","aria-disabled":!Oe,href:Oe||void 0,rel:"noopener noreferrer",tabIndex:Oe?0:-1,target:"_blank",title:"Open product link",children:n.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[n.jsx("path",{d:"M14 4h6v6"}),n.jsx("path",{d:"M20 4 10 14"}),n.jsx("path",{d:"M18 13v5.5A1.5 1.5 0 0 1 16.5 20h-11A1.5 1.5 0 0 1 4 18.5v-11A1.5 1.5 0 0 1 5.5 6H11"})]})})]}):null]}),E?n.jsxs("div",{className:"productEditorUrlFooter",children:[n.jsx("span",{className:"productEditorUrlHint","data-state":Pt===""?"empty":Oe?"valid":"invalid",children:Pt===""?"":Oe?`Valid product link · ${mt}`:"That doesn’t look like a valid URL."}),n.jsxs("button",{"aria-label":"Refresh details",className:"productEditorUrlRefresh",disabled:at,onClick:ho,type:"button",children:[n.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[n.jsx("path",{d:"M20 11a8 8 0 1 0-.9 4.5"}),n.jsx("path",{d:"M20 5v6h-6"})]}),at?"Refreshing…":"Refresh details"]})]}):null,Vi]}),n.jsxs("details",{className:"productEditorDisclosure productEditorNotesDisclosure",open:E?void 0:!0,children:[n.jsxs("summary",{children:[n.jsx("span",{children:"Notes"}),n.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:n.jsx("path",{d:"m6 9 6 6 6-6"})})]}),E?n.jsxs("div",{className:"productEditorDisclosureBody productEditorNotesGrid",children:[n.jsxs("label",{className:"notesField",children:[n.jsx("span",{className:"srOnly",children:Ke==="public"?"Public note":"Private notes"}),n.jsx("textarea",{"aria-label":Ke==="public"?"Public note":"Private notes",autoComplete:"off",name:Ke==="public"?"publicNotes":"privateNotes",onChange:fr,placeholder:"Add a note…",rows:"3",value:Ke==="public"?pe.publicNotes:pe.privateNotes})]}),n.jsxs("div",{className:"productEditorNoteVisibility",children:[n.jsx("span",{className:"productEditorNoteVisibilityLabel",children:"Note visibility"}),n.jsxs("div",{"aria-label":"Note visibility",className:"fitModeControl productEditorNoteVisibilityControl",role:"group",children:[n.jsxs("button",{"aria-pressed":Ke==="private",className:Ke==="private"?"isActive":"",onClick:()=>ft("private"),type:"button",children:[n.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[n.jsx("rect",{x:"5",y:"11",width:"14",height:"9",rx:"2"}),n.jsx("path",{d:"M8 11V8a4 4 0 0 1 8 0v3"})]}),"Private"]}),n.jsxs("button",{"aria-pressed":Ke==="public",className:Ke==="public"?"isActive":"",onClick:()=>ft("public"),type:"button",children:[n.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[n.jsx("circle",{cx:"12",cy:"12",r:"8.5"}),n.jsx("circle",{cx:"12",cy:"12",r:"3"})]}),"Public"]})]}),n.jsx("span",{className:"productEditorNoteVisibilityHint",children:Ke==="public"?"Shown in shared and exported views.":"Only you can see this note."})]})]}):n.jsxs("div",{className:"productEditorDisclosureBody productEditorNotesGrid",children:[n.jsxs("label",{className:"notesField",children:[n.jsx("span",{children:"Private notes"}),n.jsx("small",{children:"Private notes are only visible to you."}),n.jsx("textarea",{autoComplete:"off",name:"privateNotes",onChange:fr,rows:"4",value:pe.privateNotes})]}),n.jsxs("label",{className:"notesField",children:[n.jsx("span",{children:"Public note"}),n.jsx("small",{children:"Public note may appear in preview/export."}),n.jsx("textarea",{autoComplete:"off",name:"publicNotes",onChange:fr,rows:"3",value:pe.publicNotes})]})]})]})]})]}),!E||I?n.jsxs("div",{className:"modalActions productEditorActions",children:[I?n.jsx("button",{disabled:Te,onClick:Gn,type:"button",children:Te?"Verifying…":"Verify pending change"}):null,E?null:n.jsxs(n.Fragment,{children:[n.jsx("button",{disabled:tt,type:"submit",children:k?"S
32ave changes":"Save product"}),n.jsx("button",{disabled:tt,type:"button",onClick:h,children:"Cancel"}),k?n.jsx("button",{className:"modalDeleteAction",disabled:tt,type:"button",onClick:()=>S(e),children:"Delete product"}):null]})]}):null]})})})}const Uo=e=>String(e??"").trim();function Xh({children:e,title:t}){return e?n.jsxs("section",{className:"itemDetailSection",children:[n.jsx("h2",{children:t}),e]}):null}function mS({rows:e}){const t=e.filter(r=>Uo(r.value));return t.length?n.jsx("dl",{className:"itemDetailDefinitionList",children:t.map(r=>n.jsxs("div",{children:[n.jsx("dt",{children:r.label}),n.jsx("dd",{children:r.value})]},r.label))}):null}function fY({board:e,product:t}){const r=Sx(t),a=qo(r),s=zi(t,r),o=ip(r,s,{width:Os.detail}),i=a?void 0:Ed(t),c=a?void 0:kd(t),l=aa(Uo(t.url)),u=Uo(t.brand),p=Uo(t.source),m=Uo(t.privateNotes||t.notes),f=Uo(t.publicNotes),h=va(t.status),b=ib(t).status,v=Rr.availabilityTrackingEnabled&&b!=="unknown"?Zb.find(k=>k.value===b)?.label||b:"",S=[{label:"Size",value:t.size},{label:"Colour",value:t.colour},{label:"Variant",value:t.variant},{label:"Status",value:h!=="active"?h:""},{label:"Availability",value:v}],C=S.some(k=>Uo(k.value)),I=ek(t),A=Rr.priceTrackingOverviewEnabled&&I.enabled?[{label:"Tracking",value:"Price tracking on"},{label:"Last checked",value:I.lastCheckedAt?vs(I.lastCheckedAt):""}]:[];return n.jsxs("div",{className:"itemDetailReadLayout",children:[n.jsx("section",{className:"itemDetailMedia","aria-label":"Product image",children:n.jsx("div",{className:`itemDetailImageStage productImageWindow${a?" hasPlaceholderImage":""}`,style:c,children:a?n.jsx(Ol,{trademark:!1,variant:"monochrome"}):n.jsx(Ms,{alt:Uo(t.title),alternateSources:o.alternateSources,decoding:"async",draggable:!1,fallbackSource:jn,loading:"eager",source:o.source,style:i})})}),n.jsxs("div",{className:"itemDetailInformation",children:[n.jsxs("section",{className:"itemDetailOverview","aria-label":"Overview",children:[Uo(t.price)?n.jsx("p",{className:"itemDetailPrice",children:t.price}):null,xR&&Uo(t.targetPrice)?n.jsxs("p",{className:"itemDetailTargetPrice",children:[n.jsx("span",{children:"Target price"}),t.targetPrice]}):null,n.jsx(mS,{rows:[{label:"Brand",value:u},{label:"Store",value:p&&p!==u?p:""},{label:"Board",value:e?.name}]})]}),C?n.jsx(Xh,{title:"Product details",children:n.jsx(mS,{rows:S})}):null,m||f?n.jsx(Xh,{title:"Notes",children:n.jsxs("div",{className:"itemDetailNotes",children:[m?n.jsxs("div",{className:"itemDetailNote isPrivate",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Private note"}),n.jsx("span",{children:"Only visible to you"})]}),n.jsx("p",{children:m})]}):null,f?n.jsxs("div",{className:"itemDetailNote",children:[n.jsxs("div",{children:[n.jsx("strong",{children:"Public note"}),n.jsx("span",{children:"May appear in shared views"})]}),n.jsx("p",{children:f})]}):null]})}):null,p||l?n.jsx(Xh,{title:"Source",children:n.jsxs("div",{className:"itemDetailSource",children:[p?n.jsx("strong",{children:p}):null,l?n.jsx("a",{href:l,rel:"noopener noreferrer",target:"_blank",children:"Open product page"}):null]})}):null,A.length?n.jsx(Xh,{title:"Tracking",children:n.jsx(mS,{rows:A})}):null]})]})}function hY({board:e,capabilities:t=jl,children:r,isEditing:a,isLoading:s,isSaving:o,onBack:i,onCancelEdit:c,onDelete:l,onEdit:u,onRetryCloudSave:p,onResolveCloudConflict:m,pendingChangeDescriptions:f=[],retryingCloudSave:h,product:b}){const v=e?.name||"board",S=d.useRef(null),C=d.useRef(null),I=aa(Uo(b?.url)),A=b?.title||"Untitled item";d.useEffect(()=>{const E=({restoreFocus:_=!1}={})=>{S.current?.open&&(S.current.open=!1,_&&C.current?.focus())},y=_=>{S.current?.open&&!S.current.contains(_.target)&&E()},N=_=>{_.key==="Escape"&&S.current?.open&&(_.preventDefault(),E({restoreFocus:!0}))};return document.addEventListener("pointerdown",y),window.addEventListener("keydown",N),()=>{document.removeEventListener("pointerdown",y),window.removeEventListener("keydown",N)}},[]);const k=E=>{S.current&&(S.current.open=!1),E?.()};return n.jsxs("main",{className:"itemDetailPage","data-mode":a?"edit":"detail",children:[!a&&(b?.syncPendingCloudWrite||b?.syncConflict)?n.jsxs("aside",{className:"itemDetailSyncNotice",role:"status",children:[n.jsx("span",{children:b.syncConflict===tg?"This item could not be saved to your account. It is kept in this browser;
32 you can try again.":b.syncPendingCloudWrite&&!Br(b.syncRevision)?"This item is saved in this browser but not yet in your account. Saveboard retries when you return; you can also retry now.":"Cloud save is unconfirmed. Keep this browser's data until your changes are confirmed."}),m?n.jsxs("div",{children:[n.jsx("p",{children:"This item changed in another session. Review the changes saved in this browser before applying them."}),n.jsx("dl",{children:f.map(({label:E,value:y})=>n.jsxs(d.Fragment,{children:[n.jsx("dt",{children:E}),n.jsx("dd",{children:y})]},E))}),n.jsx("button",{disabled:h,onClick:m,type:"button",children:h?"Saving…":"Use my saved changes"})]}):p?n.jsx("button",{disabled:h,onClick:p,type:"button",children:h?"Retrying…":"Retry cloud save"}):null]}):null,a?null:n.jsxs("header",{className:"itemDetailPageHeader",children:[n.jsxs("button",{"aria-label":`Back to ${v}`,className:"itemDetailBackButton",onClick:i,type:"button",children:[n.jsx("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:n.jsx("path",{d:"M15 5 8 12l7 7"})}),n.jsxs("span",{children:["Back to ",v]})]}),e&&b?n.jsxs("div",{className:"itemDetailHeadingRow",children:[n.jsxs("div",{className:"itemDetailHeading",children:[n.jsx("p",{children:a?"Edit item":"Item details"}),n.jsx("h1",{title:A,children:A})]}),n.jsxs("div",{className:"itemDetailHeaderActions","aria-label":"Item actions",children:[a?n.jsxs(n.Fragment,{children:[n.jsx("button",{className:"itemDetailPrimaryAction",disabled:o,form:"item-detail-editor-form",type:"submit",children:o?"Saving…":"Save changes"}),n.jsx("button",{className:"itemDetailSecondaryAction",disabled:o,onClick:c,type:"button",children:"Cancel"})]}):n.jsxs(n.Fragment,{children:[I?n.jsx("a",{className:"itemDetailPrimaryAction",href:I,rel:"noopener noreferrer",target:"_blank",children:"Visit product"}):null,t.canEditItems?n.jsx("button",{className:"itemDetailSecondaryAction",disabled:!!b.syncPendingCloudWrite,onClick:u,type:"button",children:"Edit product"}):null]}),n.jsxs("details",{className:"itemDetailActionsMenu",hidden:!t.canDeleteItems,ref:S,children:[n.jsx("summary",{"aria-disabled":o?"true":void 0,"aria-label":"More item actions",onClick:E=>{o&&E.preventDefault()},ref:C,role:"button",title:"More item actions",children:n.jsxs("svg",{"aria-hidden":"true",viewBox:"0 0 24 24",children:[n.jsx("circle",{cx:"5",cy:"12",r:"1.5"}),n.jsx("circle",{cx:"12",cy:"12",r:"1.5"}),n.jsx("circle",{cx:"19",cy:"12",r:"1.5"})]})}),n.jsx("div",{"aria-label":"Item actions",className:"saveboardMenuPanel",role:"menu",children:n.jsx("button",{className:"saveboardMenuRow saveboardMenuDangerRow",disabled:o,onClick:()=>k(()=>l(b)),role:"menuitem",type:"button",children:"Delete product"})})]})]})]}):null]}),s?n.jsx("section",{"aria-live":"polite",className:"itemDetailState",children:n.jsx("p",{children:"Loading item…"})}):e&&b?a?r:n.jsx(fY,{board:e,product:b}):n.jsxs("section",{className:"itemDetailState",children:[n.jsx("h1",{children:"Item unavailable"}),n.jsx("p",{children:"This item is not available in this board."}),n.jsx("button",{onClick:i,type:"button",children:"Back to board"})]})]})}function gY({error:e="",isCloudTrash:t=!1,isPending:r=!1,product:a,onArchive:s,onConfirm:o,onCancel:i}){if(!a)return null;const l=!cd(a)&&va(a.status)!=="archived";return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"delete-product-title","aria-modal":"true",className:"deleteProductModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"delete-product-title",children:t?"Move item to Trash":"Delete Product"})}),t?n.jsxs("p",{children:["Move ",a.title," to Trash? It will leave active boards after Saveboard confirms the change."]}):n.jsxs("p",{children:["Delete ",a.title," permanently? Archive keeps the item in Saveboard without showing it in the active wishlist."]}),e?n.jsx("p",{role:"alert",children:e}):null,n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{disabled:r,type:"button",onClick:()=>o(a.id),children:r?"Moving to Trash...":t?"Move to Trash":"Delete permanently"}),l?n.jsx("button",{disabled:r,type:"button",onClick:()=>s(a),children:"Archive instead"}):null,n.jsx("button",{disabled:r,type:"button",onClick:i,children:"Cancel"})]})]})})}function bY({count:e,onConfirm:t,onCancel:r}){return e?n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"bulk-delete-product-title","aria-modal":"true",className:"deleteProductModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"bulk-delete-product-title",children:"Delete Products"})}),n.jsxs("p",{children:["Delete ",e," selected product",e===1?"":"s"," permanently? Archive keeps items in Saveboard without showing them in the active wishlist."]}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{type:"button",onClick:t,children:"Delete permanently"}),n.jsx("button",{type:"button",onClick:r,children:"Cancel"})]})]})}):null}function vY({request:e,onConfirm:t,onCancel:r}){if(d.useEffect(()=>{if(!e)return;const i=c=>{c.key==="Escape"&&(c.preventDefault(),r())};return window.addEventListener("keydown",i),()=>window.removeEventListener("keydown",i)},[r,e]),!e)return null;const a=e.links.length,s=e.totalCount>a,o=s?`Open first ${a} product links?`:`Open ${a} product link${a===1?"":"s"}?`;return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"open-product-links-title","aria-modal":"true",className:"deleteProductModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"open-product-links-title",children:o})}),s?n.jsxs("p",{children:["This board has ",e.totalCount," links. For safety, Saveboard can open the first ",a," at once."]}):n.jsx("p",{children:"This will open each product in a new browser tab."}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{autoFocus:!0,t
32ype:"button",onClick:t,children:s?`Open first ${a}`:"Open links"}),n.jsx("button",{type:"button",onClick:r,children:"Cancel"})]})]})})}function yY({backup:e,onReplace:t,onMerge:r,onCancel:a}){if(!e)return null;const s=e.exportedAt?formatDate(e.exportedAt):"",o=e.schemaVersion||e.version||1;return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("div",{"aria-labelledby":"import-backup-title","aria-modal":"true",className:"deleteProductModal importBackupModal",role:"dialog",children:[n.jsx("div",{className:"modalHeader",children:n.jsx("h2",{id:"import-backup-title",children:"Import backup?"})}),n.jsxs("div",{className:"importBackupSummary",children:[n.jsxs("p",{children:["This Saveboard backup contains ",e.products.length," products and ",e.lists.length," boards",s?`, exported ${s}`:"","."]}),n.jsxs("span",{children:["Schema v",o]})]}),n.jsx("p",{className:"importBackupWarning",children:"Import backup replaces your current local Saveboard data. Merge backup adds boards and item records that are not already present by ID. Saveboard keeps a local safety snapshot before either action."}),n.jsxs("div",{className:"modalActions",children:[n.jsx("button",{type:"button",onClick:t,children:"Import backup"}),n.jsx("button",{type:"button",onClick:r,children:"Merge backup"}),n.jsx("button",{type:"button",onClick:a,children:"Cancel"})]})]})})}function SY({onClose:e}){const t=[{title:"General",shortcuts:[["N","Add product"],["/","Search"],["?","Keyboard shortcuts"],["Esc","Close or clear"]]},{title:"Focused product",shortcuts:[["Enter","Flip card"],["E","Edit"],["P","Mark purchased"],["A","Archive"],["O","Open link"],["Delete","Delete"]]},{title:"Grid",shortcuts:[["← ↑ ↓ →","Move focus"]]}];return n.jsx("div",{className:"modalLayer",role:"presentation",children:n.jsxs("section",{"aria-labelledby":"shortcuts-title","aria-modal":"true",className:"shortcutsPanel",role:"dialog",children:[n.jsxs("div",{className:"modalHeader shortcutsHeader",children:[n.jsx("h2",{id:"shortcuts-title",children:"Keyboard Shortcuts"}),n.jsx("button",{"aria-label":"Close keyboard shortcuts",onClick:e,type:"button",children:"Close"})]}),n.jsx("div",{className:"shortcutsGrid",children:t.map(r=>n.jsxs("section",{className:"shortcutsGroup",children:[n.jsx("h3",{children:r.title}),n.jsx("dl",{children:r.shortcuts.map(([a,s])=>n.jsxs("div",{children:[n.jsx("dt",{children:a}),n.jsx("dd",{children:s})]},a))})]},r.title))})]})})}function wY({commands:e,onClose:t}){const[r,a]=d.useState(""),[s,o]=d.useState(0),i=d.useRef(null),c=d.useMemo(()=>{const p=r.trim().toLowerCase();return p?e.filter(m=>[m.label,m.detail,m.keywords].filter(Boolean).join(" ").toLowerCase().includes(p)):e},[e,r]),l=c[s];d.useEffect(()=>{i.current?.focus()},[]),d.useEffect(()=>{o(0)},[r]),d.useEffect(()=>{s>c.length-1&&o(Math.max(0,c.length-1))},[c.length,s]);const u=p=>{!p||p.disabled||(t(),window.setTimeout(()=>p.action(),0))};return n.jsx("div",{className:"modalLayer commandPaletteLayer",role:"presentation",children:n.jsxs("section",{"aria-label":"Command palette","aria-modal":"true",className:"commandPalette",role:"dialog",children:[n.jsx("input",{"aria-label":"Search commands",autoComplete:"off",onChange:p=>a(p.target.value),onKeyDown:p=>{if(p.key==="Escape"){p.preventDefault(),t();return}if(p.key==="ArrowDown"){if(p.preventDefault(),c.length===0)return;o(m=>Math.min(c.length-1,m+1));return}if(p.key==="ArrowUp"){if(p.preventDefault(),c.length===0)return;o(m=>Math.max(0,m-1));return}p.key==="Enter"&&(p.preventDefault(),u(l))},placeholder:"Type a command",ref:i,value:r}),n.jsx("div",{className:"commandPaletteList",role:"listbox",children:c.length>0?c.map((p,m)=>n.jsxs("button",{"aria-disabled":p.disabled?"true":void 0,className:`${m===s?"isSelected":""}${p.disabled?" isDisabled":""}`,onClick:()=>u(p),onMouseEnter:()=>o(m),"aria-selected":m===s,role:"option",type:"button",children:[n.jsx("span",{children:p.label}),p.detail?n.jsx("em",{children:p.disabled&&p.disabledReason||p.detail}):null]},p.id)):n.jsx("p",{children:"No commands found."})})]})})}function CY(){const e=LE(),t=n3(),{activeList:r,activeListRecord:a,activeAccountScopeId:s,acknowledgeListCloudWrite:o,acknowledgeProductCloudWrite:i,applyConfirmedCloudBoardTrash:c,applyVerifiedLocalProduct:l,accountLocalDataNotice:u,addProduct:p,applyListCloudWriteConflict:m,applyProductCloudWriteConflict:f,applyConfirmedProductRestore:h,createList:b,defaultModalList:v,deleteProduct:S,deleteList:C,exportBackup:I,getShareList:A,hasExplicitLocalProductMove:k,importPersonalProducts:E,importUnscopedPersonalDataToAccount:y,keepUnscopedPersonalDataSeparate:N,lists:_,manualStores:P,markListCloudWritePending:V,markProductCloudWritePending:L,mode:z,modes:B,moveProductToList:re,productLists:Z,products:D,recoveryNotice:K,removeProductAfterConfirmedCloudTrash:ee,reorderProducts:J,reorderList:fe,resetPersonal:De,runLegacyQaProductCleanup:Be,setActiveList:Fe,setManualStores:ke,setSettings:We,settings:de,switchMode:ye,trashedProducts:ge,updateProduct:ze,updateProductImageAnalyses:W,updateList:Le,validateBackup:et,visibleProducts:pt,applyAccountCloudHydration:$t,applyAuthoritativeBootstrapUpload:pe,applyCloudNewerPersonalCloudPull:Tt,applyEmptyPersonalCloudPull:F,applyPopulatedPersonalCloudPull:te,applyBackup:me,clearRecoveryNotice:ie,prepareBootstrapUploadProvenance:Ae}=_H({accountScopeId:e.user?.id||"",dashboardList:rr,defaultModalList:Ka,storage:ct}),Re="vertical",ne=Ja,[ht,kt]=d.useState(null),[Ee,xe]=d.useState(()=>hi(e.user?.id)),[Qe,Pe]=d.useState(()=>Ba()),[Ct,nr]=d.useState({message:"",status:"idle"}),[en,st]=d.useState({message:"",status:"idle"}),[gr,Xt]=d.useState({message:"",status:"local"}),[fn,Ke]=d.useState(null),[ft,lr]=d.useState(null),[Wr,Dr]=d.useState(!1),[kr,Gr]=d.useState(!1),[ar,qr]=d.useState(null),[tn,hn]=d.useState(!1),[Wn,br]=d.useState(!1),[rn,nn]=d.useState(null),[Pn,G]=d.useState({message:"",productId:"",status:"idle"}),[se,le]=d.useState({message:"",productId:"",status:"idle"}),[ue,Ne]=d.useState(null),[be,Te]=d.useState(null),[Ve,at]=d.useState(!1),[yt,tt]=d.useState(!1),[He,Ge]=d.useState(null),[Xe,Dt]=d.useState(null),[jt,Zt]=d.useState(""),[xt,Gt]=d.useState({message:"",operation:null,status:"idle"}),[Or,Yt]=d.useState(""),[er,x]=d.useState(()=>bc(ct.readViewState(z).selectedSort)),[$,O]=d.useState(()=>ct.readViewState(z).boardSortModes||{}
32),[q,X]=d.useState(()=>ct.readViewState(z).allItemsSortMode||""),[Se,he]=d.useState(()=>fu(ct.readViewState(z).selectedStatusFilter)),[$e,Oe]=d.useState(()=>ct.readViewState(z).selectedView==="allItems"?"allItems":"overview"),[Pt,mt]=d.useState(null),[Kt,rt]=d.useState(null),[St,_t]=d.useState(""),[dr,tr]=d.useState(""),[yr,Sr]=d.useState(""),[wr,Mn]=d.useState(""),[fr,Cr]=d.useState(""),[po,ca]=d.useState(!1),[mo,rs]=d.useState(""),[$s,ce]=d.useState(null),[oe,gt]=d.useState({}),[wt,It]=d.useState({dataUrl:"",error:"",status:"idle",url:""}),[or,Yr]=d.useState(null),[qt,Ir]=d.useState({productId:"",status:"idle",message:""}),[Fr,gn]=d.useState({productId:"",status:"idle",message:""}),[Vt,fo]=d.useState({boardItems:[],boardItemsError:"",boards:[],boardsError:"",error:"",isUnlistedShare:!1,isLoading:!1,profile:null,username:""}),[Dc,Oc]=d.useState({}),ho=(g,w)=>{Oc(j=>{const T=j[g]||{},U=typeof w=="function"?w(T):{...T,...w};return{...j,[g]:U}})};d.useEffect(()=>{Oc({})},[e.user?.id]);const[Ua,Gn]=d.useState(null),[Vi,Ze]=d.useState(""),[H,ve]=d.useState(""),[Je,lt]=d.useState(null),[Et,ur]=d.useState(null),[on,Lt]=d.useState(""),[Sa,Fa]=d.useState(!1),[qn,_n]=d.useState(()=>new Set),[go,bo]=d.useState(!1),[ys,an]=d.useState(!1),[ns,Zn]=d.useState(!1),[Hi,as]=d.useState(!1),[Td,zs]=d.useState(!1),[hp,wn]=d.useState(0),[Wi,vo]=d.useState(null),[la,ea]=d.useState({accessLost:!1,error:"",isLoading:!1,isSaving:!1,items:[],role:""}),yo=!!(r===rr&&$e==="shared"&&Wi?.boardId),$a=d.useMemo(()=>Wi?{...Wi,role:lo(la.role||Wi.role)}:null,[Wi,la.role]),da=d.useMemo(()=>iT($a),[$a]),Mc=d.useMemo(()=>lT(la.items,$a),[$a,la.items]),bn=d.useMemo(()=>oT({isShared:yo,role:$a?.role}),[$a?.role,yo]),Gi=d.useCallback(async()=>{const g=Od.current;if(!(!g?.boardId||!sC(g))){ea(w=>({...w,error:"",isLoading:!0}));try{const[w,j]=await Promise.all([eM(g),YI()]);if(Od.current?.boardId!==g.boardId)return;let T=my(w.error),U="";if(j.ok){const M=(j.boards||[]).find(Y=>Y.ownerId===g.ownerId&&Y.boardId===g.boardId);M?U=lo(M.role):w.error||(T=!0)}ea(M=>({accessLost:T,error:T?w.error||"This board is no longer shared with you.":w.error||"",isLoading:!1,isSaving:!1,items:T?[]:w.error?M.items:w.items||[],role:U||M.role}))}catch{ea(w=>({...w,error:"Could not load this board.",isLoading:!1}))}}},[]),gp=fp(),Dd=uL(!0),bp=d.useRef(Date.now()),Od=d.useRef(null);Od.current=Wi;const Uc=d.useRef(null),vp=d.useRef(null),Xo=d.useRef(null),Jo=d.useRef(null),So=d.useRef(0),Ml=d.useRef(null),Fc=d.useRef(0),Vs=d.useRef(P),Hs=d.useRef(0),$c=d.useRef(e.user?.id||""),wo=d.useRef(0),wa=d.useRef(""),qi=d.useRef(Promise.resolve()),zc=d.useRef(""),Ws=d.useRef(""),av=d.useRef(0),Cn=d.useRef(new Set),sv=d.useRef(new Map),Yi=d.useRef(r),ov=d.useRef(""),Un=d.useRef(null),Lf=d.useRef(0),Co=d.useRef(null),Md=d.useRef(!1),ua=d.useRef(D),xo=d.useRef(_),Gs=d.useRef(new Set),Ki=d.useRef(new Set),Vc=d.useRef(new Map),Hc=d.useRef(new Map),Ud=d.useRef(new Map),Ul=d.useRef(null),iv=d.useRef(null),Xi=d.useRef(Promise.resolve()),Fd=d.useRef(kO()),Fl=d.useMemo(()=>WC(ht||null),[ht]),Yn=vG(),At=Yn.path,[Ji,yp]=d.useState(""),$l=Yn.pendingPath||"",Ca=!!($l||Ji),$d=$l===ta||$l.startsWith(`${ta}/`),Ss=$l==="/account",zl=Ji===rr,$r=Qy(At),pa=!!$r,qs=Ac(),Wc=b3(At),Nr=Lw(At),cn=n_(At),Qi=gq(Yn.search),Gc=!!(Nr&&(Vt.isLoading||Vt.username!==Nr||String(Vt.boardId||"")!==String(cn||""))),Io=At==="/guide",ss=At==="/account",Bf=At===_d,zd=At===tv,cv=At===OR,Ao=At===ta||At.startsWith(`${ta}/`),ws=At===ig,Vl=At.startsWith(`${yc}/`),Tf=h3(At),Qo=At===yc||Vl,Zo=At===Jy,Zi=At==="/price-tracking",Sp=Zi&&Rr.priceTrackingOverviewEnabled,wp=At==="/admin/reports",Df=At==="/admin/discover",os=g3(At),Po=At==="/account/reset-password";A(Wc);const Of=vl(e.profile),Tx=!!(e.user&&Nr&&Nr===Of),Ie=e.user?.id||"",Ea=!!Ie,[lv,Hl]=d.useState({boards:[],error:"",isLoading:!1}),qc=d.useRef([]);qc.current=lv.boards;const ei=d.useCallback(async()=>{if(!Ie||!e.isConfigured){Hl({boards:[],error:"",isLoading:!1});return}Hl(g=>({...g,error:"",isLoading:!0}));try{const g=await YI();Hl(w=>({boards:g.error?w.boards:g.boards||[],error:g.error||"",isLoading:!1}))}catch{Hl(g=>({...g,error:"Could not load shared boards.",isLoading:!1}))}},[e.isConfigured,Ie]);d.useEffect(()=>{ei()},[ei]),Gw(ei,!!(Ie&&e.isConfigured)),Gw(Gi,yo),d.useEffect(()=>{!yo||!la.accessLost||(Ze("This board is no longer shared with you."),vo(null),ea({accessLost:!1,error:"",isLoading:!1,isSaving:!1,items:[],role:""}),Oe("overview"),Fe(rr))},[Fe,la.accessLost,yo]);const Jt=UO(e.session);wa.current=Jt,Yi.current=r,ov.current=At,ua.current=D,xo.current=_;
32const jr=!!(Ie&&String(s||"")===Ie),Kr=sH(Qe,Jt),[Vd,ec]=d.useState(!1);d.useEffect(()=>{if(Kr||!Ie){ec(!1);return}const g=window.setTimeout(()=>ec(!0),6e3);return()=>window.clearTimeout(g)},[Kr,Ie]);const vr=!!(Ie&&e.isConfigured);vr&&e.fetchOwnerPublicBoardItems&&e.syncPublicBoardItemMetadata&&e.syncPublicBoardMetadata;const Qt=!!(vr&&z===B.personal),ma=$r?_.find(g=>String(g?.id||"")===$r.boardId)||(da?.id===$r.boardId?da:null):null,En=ma&&(ma.isSharedBoard?Mc:D).find(g=>String(g?.id||"")===$r.itemId&&hs(g,ma))||null,tc=!!(pa&&!En&&(e.loading||Ea&&(!jr||!Kr))),_o=Rr.trueSyncTombstoneProductsEnabled,ln=At==="/"&&!Ua&&!Vi;d.useEffect(()=>{ln&&Si(Da.landingViewed)},[ln]),d.useEffect(()=>{Ao&&Si(Da.discoverViewed)},[Ao]),d.useEffect(()=>{e.loading||N0(!!e.user?.id)},[e.loading,e.user?.id]);const is=SS({enabled:(ln||Ao)&&!e.loading,surfaceKey:At,prepare:m4}),Wl=d.useMemo(()=>is.status==="ready"?p4(is):[],[is]),Yc=(is.featured||[]).slice(0,zB).map(hg),Cs="/app";d.useEffect(()=>{Zi&&!Sp&&ul("/app")},[Sp,Zi]);const Cp=!1,ti=gy({authenticatedUserId:Ie,board:a,isProtected:Cp}),Kn=!!(a&&(ti.eligibility===Bn.local||ti.eligibility===Bn.cloud&&Qt&&jr&&Kr));d.useEffect(()=>{const g=String(xt.operation?.ownerId||"");jt!=="cloud"||!g||g===Ie||(Ws.current="",Dt(null),Zt(""),Gt({message:"",operation:null,status:"idle"}))},[xt.operation?.ownerId,jt,Ie]);const xp=t3(de.theme),Eo=window.SaveBoardThemeResolver?.resolveApplicationTheme({systemTheme:t,themePreference:de.theme})||"light",Mf=!e.loading&&(!Ea||String(s||"")===Ie),Ys=document.documentElement.dataset.theme==="dark"?"dark":"light",ko=Mf?window.SaveBoardThemeResolver?.resolveLandingTheme({systemTheme:t,themePreference:de.theme})||"light":Ys,xa=ln?ko:Eo,Ip=xp,Kc=!!de.minimalBoardMode;RG(de.boardThemes);const Uf=de.lightCardMode==="panel"?"panel":"tonal",dv=xa==="dark"?"dark":Uf,cs=kw(de.displayQuality),za=d.useCallback(()=>{We(g=>{const w=window.SaveBoardThemeResolver?.resolveApplicationTheme({systemTheme:t,themePreference:g.theme})||"light";return{...g,theme:w==="dark"?"light":"dark"}})},[We,t]),uv=d.useCallback(()=>{We(g=>({...g,minimalBoardMode:!g.minimalBoardMode}))},[We]),rc=Or.trim(),ls=rc.length>0,Ap=r===rr,Va=Ap&&$e==="allItems",pr=yo,No=Ap&&$e==="overview",Gl=z===B.personal&&Ie||Mi,Pp=d.useMemo(()=>xz({activeListRecord:a,allItemsIsSelected:Va,ownerId:Gl,products:[...D,...ge],requestedStatus:Se,signedIn:Ea}),[a,Se,Va,Gl,D,Ea,ge]),vn=Pp.status,ri=vn==="active"?"All Items":Qb[vn]||"All Items",Ia=pr?da?.name||"Shared board":Va?ri:r,ds=d.useMemo(()=>Cl(ne,gp),[ne,gp]),_p=d.useMemo(()=>{const g=cL(ne),w=Number.parseFloat(ds.podWidth),j=Number.parseFloat(ds.podAspectRatio),T=Number.parseFloat(ds.rowGap)||0,U=Number.isFinite(w)&&w>0&&Number.isFinite(j)&&j>0?w/j*g+T*Math.max(0,g-1):0;return U>0?{"--sidebar-visible-grid-height":`${Math.round(U*10)/10}px`,"--sidebar-toolbar-grid-gap":bG(ne)}:void 0},[ne,ds]),Ff=Pt?{"--list-content-rail-width":`${Pt}px`}:void 0,nc=d.useCallback(g=>{Un.current=g,qr(g)},[]),Aa=d.useCallback(()=>{Un.current=null,qr(null)},[]),$f=d.useCallback(g=>{const w=!!g;hn(w);const j=Un.current,T=mA(j,w);T!==j&&(Un.current=T,qr(T))},[]),Hd=d.useCallback(g=>{const w=Un.current,j=fA(w,g);return!j||j===w?j:(nc(j),j.needsReview?(br(!0),Ze(Fu),j):(lr(j.openingSnapshot),hn(!1),br(!1),j))},[nc]);d.useLayoutEffect(()=>{const g=Un.current;if(!g?.productId)return;const w=D.find(j=>String(j?.id||"")===g.productId);w&&Hd(w)},[ar,D,Hd]);const zf=d.useCallback(g=>{const w=Number.parseFloat(g);!Number.isFinite(w)||w<=0||mt(j=>j&&Math.abs(j-w)<.5?j:w)},[]),jo=d.useCallback(g=>{zc.current=Jt;const w=qi.current.then(g,g);return qi.current=w.catch(()=>{}),w},[Jt]),fa=d.useCallback((g,w)=>`${Ie}:${g}:${String(w||"")}`,[Ie]);d.useEffect(()=>{if(!qs)return;const g=ar;if(!g?.productId)return;const w=D.find(Y=>String(Y?.id||"")===g.productId)||null,j=(Je?.diagnostics?.products||[]).find(Y=>Y.recordId===g.productId)||null,T=j?.parentBoardId||w?.listId||w?.list_id||"",U=(Je?.diagnostics?.lists||[]).find(Y=>Y.recordId===String(T||""))||null,M=fa("product",g.productId);SA(RF({aggregateConflicts:Je?.aggregateConflicts||{},editorNeedsReview:Wn,editorSession:g,parentBoardDiagnostic:U,productDiagnostic:j,queueState:{conflictRegistryContainsRecord:Cn.current.has(M),queueSessionMatches:zc.current===Jt,recordPendingCloudWrite:w?.syncPendingCloudWrite===!0},storeRecord:w}),"editor")},[Jt,fa,Wn,ar,D,qs,Je]);const ni=d.useCallback((g,w)=>{const j=Br(w?.syncRevision??w?.revision),T=Br(sv.current.get(fa(g,w?.id)));return j&&T?Math.max(j,T):T||j},[fa]),Fn=d.useCallback((g,w)=>{const j=Br(w?.revision??w?.syncRevision);j&&w?.id&&sv.current.set(fa(g,w.id),j)},[fa]),ai=d.useCallback(async(g,w={})=>
32{if(!Qt||!g?.id)return{ok:!1,skipped:!0};const j=w.operation==="create"?"create":"update",T=j==="update"?pP({currentList:g,previousList:w.previousList,user:e.user}):{};if(j==="update"&&!Object.keys(T).length&&w.previousList)return{ok:!0,reason:"no-cloud-field-change",skipped:!0};const U=fa("list",g.id);w.previousList?.syncConflict&&Cn.current.delete(U),V(g.id,T),nr({message:"Saving 1 board to cloud...",status:"syncing"});try{const M=await jo(async()=>{const we=await(j==="create"?Fy({list:g,user:e.user}):Vz({expectedRevision:Cn.current.has(U)?null:ni("list",w.previousList),list:g,patch:T,user:e.user}));return Fn("list",we?.row||we?.latest),we?.conflict?Cn.current.add(U):we?.ok&&Cn.current.delete(U),we});if(M?.conflict){const Q=M.latest?sm(M.latest,g):null;m({attemptedPatch:M.attemptedPatch||T,latestRecord:Q,listId:g.id,reason:M.reason}),Fn("list",M.latest);const we=Q?"This board changed on another device. Review your change.":"This board changed or is no longer available.";return nr({message:we,status:"error"}),Ze(we),M}if(!M?.ok||!M.row)throw new Error("Board cloud write was skipped.");const Y=sm(M.row,g);if(M.contentDiverged){m({attemptedPatch:pP({currentList:g,previousList:Y,user:e.user}),latestRecord:Y,listId:g.id,reason:"changed-or-unavailable"}),Fn("list",M.row);const Q="This board was already saved to your account and has changed since. Review your change.";return nr({message:Q,status:"error"}),Ze(Q),M}return o(g.id,Y),Fn("list",M.row),nr({message:"Saved 1 board to cloud.",status:"synced"}),M}
32catch(M){if(j==="create"&&HE(M)==="rejected"){m({attemptedPatch:{},latestRecord:null,listId:g.id,reason:Cu});const Q="This board could not be saved to your account. It is kept in this browser.";return nr({message:Q,status:"error"}),Ze(Q),{ok:!1,reason:Cu,skipped:!1}}const Y=j==="create"?"This board is saved in this browser and will be saved to your account when you return.":"This board was saved on this browser, but cloud sync did not finish.";return nr({message:Y,status:"error"}),Ze(Y),Cn.current.add(U),{ok:!1,skipped:!1}}},[o,m,e.user,ni,fa,V,jo,Fn,Qt]),Xc=d.useCallback((g,w=_)=>{if(!g)return null;const j=String(g.listId||"").trim();return j?w.find(T=>String(T.id||"")===j)||null:w.find(T=>T.name===g.listName||T.name===g.category)||null},[_]),Rn=d.useCallback(async(g,w={})=>{const j=()=>{try{return w.isSessionCurrent?.()!==!1}catch{return!1}};if(!vr||z!==B.personal&&w.personalMutation!==!0)return{ok:!1,skipped:!0};const T=(Array.isArray(g)?g:[g]).filter(Me=>Me?.id);if(!T.length)return{ok:!1,skipped:!0};if(!j())return{ok:!1,reason:"session-changed",skipped:!1};const U=w.operation==="create"?"create":"update",M=Br(w.expectedRevision);if(U==="update"&&T.length!==1)return{ok:!1,reason:"multi-record-cas-deferred",skipped:!0};const Y=Array.isArray(w.lists)?w.lists:_,Q=T.map(Me=>({list:w.list?.id?w.list:Xc(Me,Y),product:Me})).filter(Me=>Me.list?.id&&Me.product?.id),we=T.length-Q.length,Ce=new Set((Array.isArray(w.createListIds)?w.createListIds:[]).map(Me=>String(Me||"")));w.createList===!0&&w.list?.id&&Ce.add(String(w.list.id)),Q.forEach(({list:Me})=>{Me.userId===e.user.id&&Me.syncPendingCloudWrite&&!Br(Me.syncRevision)&&!Me.cloudDeletedAt&&!Me.syncSuppressed&&Ce.add(String(Me.id))});const je=w.retryPatch||(U==="update"?mP({currentList:Q[0]?.list,currentProduct:Q[0]?.product,previousList:w.previousList,previousProduct:w.previousProductForPatch||w.previousProduct,user:e.user}):{});if(U==="update"&&!Object.keys(je).length&&w.previousProduct)return{ok:!0,reason:"no-cloud-field-change",skipped:!0};const qe=fa("product",Q[0]?.product?.id);if(w.previousProduct?.syncConflict&&Cn.current.delete(qe),!Q.length)return st({message:"This item was saved on this browser, but its cloud board could not be resolved.",status:"error"}),Ze("This item was saved on this browser, but cloud sync did not finish."),{ok:!1,skipped:!0};st({message:`Saving ${Q.length===1?"1 item":`${Q.length} items`} to cloud...`,status:"syncing"}),w.trackPendingMetadata!==!1&&Q.forEach(Me=>L(Me.product.id,je,{preserveConflictMetadata:w.preserveConflictUntilAcknowledged===!0})),w.trackPendingMetadata!==!1&&Q.filter(Me=>Ce.has(String(Me.list.id||""))).forEach(Me=>V(Me.list.id));try{const Me=await jo(async()=>{if(!j())throw new Error("Cloud write session changed.");const ut=new Set,it=[];for(const Rt of Q){if(!j())throw new Error("Cloud write session changed.");const Mr=String(Rt.list.id||"");if(Ce.has(Mr)&&!ut.has(Mr)){const Pr=await Fy({list:Rt.list,user:e.user});if(!Pr?.ok||!Pr.row)throw new Error("Cloud board insert did not return a server record.");if(!j())throw new Error("Cloud write session changed.");const Lo=sm(Pr.row,Rt.list);o(Rt.list.id,Lo),Fn("list",Pr.row),ut.add(Mr)}const sr=U==="create"?await zz({list:Rt.list,product:Rt.product,user:e.user}):await fP({acceptAlreadyApplied:!!w.retryPatch,expectedRevision:M||(Cn.current.has(qe)?null:ni("product",w.previousProduct)),patch:je,product:Rt.product,user:e.user});if(!j())throw new Error("Cloud write session changed.");Fn("product",sr?.row||sr?.latest),sr?.conflict&&!w.automaticAnalysis?Cn.current.add(qe):sr?.ok&&Cn.current.delete(qe),it.push(sr)}return it});if(!j())return{ok:!1,reason:"session-changed",skipped:!1};const Ue=Me.find(ut=>ut?.conflict);if(Ue){if(w.automaticAnalysis)return Ue;const ut=Q[0],it=Y.find(sr=>String(sr.id||"")===String(Ue.latest?.list_id||"")),Rt=Ue.latest?om({fallback:ut.product,listName:it?.name||"",row:Ue.latest}):null;f({attemptedPatch:Ue.attemptedPatch||je,latestRecord:Rt,productId:ut.product.id,reason:Ue.reason}),Fn("product",Ue.latest);const Mr=Rt?"This item changed on another device. Review your change.":"This record changed or is no longer available.";return st({message:Mr,status:"error"}),Ze(Mr),Ue}const dt=[],ot=[];for(const[ut,it]of Me.entries()){const Rt=Q[ut];
32if(!it?.ok||!it.row||!Rt)throw new Error("Cloud item write did not return a server record.");if(w.automaticAnalysis){const Pr=ua.current.find(Lo=>Lo.id===Rt.product.id);if(!Pr||Pr.syncPendingCloudWrite||Pr.syncConflict||Pr.syncRevision!==w.previousProduct?.syncRevision||Un.current?.productId===Pr.id)return{ok:!1,reason:"automatic-analysis-superseded",skipped:!0}}const Mr=om({attemptedPatch:U==="update"?je:void 0,fallback:Rt.product,listName:Rt.list.name,row:it.row});let sr=null;if(w.extensionImportAcknowledgement===!0){let Pr=null;try{Pr=ct.readAccountHydrationSnapshot(w.expectedOwnerId).products.find(sl=>String(sl?.id||"")===String(Rt.product.id))}catch{Pr=null}const Lo=ua.current.find(sl=>String(sl?.id||"")===String(Rt.product.id));if(sr=mz({acknowledgedProduct:Mr,durableProduct:Pr,expectedListId:Rt.list.id,expectedOwnerId:w.expectedOwnerId,expectedProductId:Rt.product.id,liveProduct:Lo}),!sr.ok)return{ok:!1,reason:sr.reason,skipped:!1}}if(!j())return{ok:!1,reason:"session-changed",skipped:!1};(!sr||sr.action==="apply")&&i(Rt.product.id,Mr,{serverRecord:it.row}),Fn("product",it.row),dt.push(Mr),U==="create"&&Si(Da.firstItemSaved,{surface:"workspace"},{accountId:e.user?.id||""}),sr&&ot.push(sr)}return st({message:`Saved ${Q.length===1?"1 item":`${Q.length} items`} to cloud.${we?` ${we} item${we===1?" was":"s were"} skipped because its board could not be resolved.`:""}`,status:"synced"}),{acknowledgementDecisions:ot,acknowledgedProducts:dt,ok:!0,results:Me,skipped:!1}}catch(Me){if(!j())return{ok:!1,reason:"session-changed",skipped:!1};if(w.automaticAnalysis)return{ok:!1,skipped:!1};if(U==="create"&&yT(Me)==="rejected"){Q.forEach(ot=>f({attemptedPatch:{},latestRecord:null,productId:ot.product.id,reason:tg}));const dt="This item could not be saved to your account. It is kept in this browser.";return st({message:dt,status:"error"}),Ze(dt),{ok:!1,reason:tg,skipped:!1}}const Ue=U==="create"?"This item is saved in this browser and will be saved to your account when you return.":"This item was saved on this browser, but cloud sync did not finish.";return st({message:Ue,status:"error"}),Ze(Ue),Cn.current.add(qe),{ok:!1,skipped:!1}}},[e.user,o,i,f,Xc,ni,fa,_,V,L,z,B.personal,jo,Fn,vr]),Vf=g=>!!g?.id&&g.userId===Ie&&(oC(g,{userId:Ie})||g.syncConflict===tg),si=async(g,w=!1)=>{if(H||!Qt)return;if(!w&&Vf(g)){const M=Xc(g);if(!M){Ze("The destination board is unavailable. Your item is still kept in this browser.");return}const Y=Ie,Q=Jt;ve(g.id);try{(await Rn(g,{isSessionCurrent:()=>wa.current===Q&&ct.getAccountScope?.()===Y,list:M,operation:"create"}))?.ok&&Ze("Your item is now saved to your account.")}finally{ve("")}return}if(g?.userId!==Ie||!g?.syncPendingWriteRevision||!Object.keys(g.syncConflictPatch||{}).length||w&&!SI(g))return;const j=Ie,T=Jt,U=g.syncConflictPatch.list_id?_.find(M=>M.id===g.syncConflictPatch.list_id):Xc(g);if(!U){Ze("The destination board is unavailable. Your saved changes are still kept in this browser.");return}ve(g.id);try{(await Rn(g,{operation:"update",expectedRevision:w?g.syncRevision:g.syncPendingWriteRevision,retryPatch:g.syncConflictPatch,previousProduct:g,list:U,isSessionCurrent:()=>wa.current===T&&ct.getAccountScope?.()===j}))?.ok&&Ze("Your changes are confirmed in cloud.")}finally{ve("")}},Ep=d.useRef(new Set),kp=d.useCallback(async()=>{if(!Qt||!Ie||z!==B.personal)return{acknowledged:0,attempted:0};const g=mT(xo.current,{inFlightIds:Ep.current,userId:Ie});let w=0;for(const j of g){const T=String(j.id);Ep.current.add(T);try{(await ai(j,{operation:"create"}))?.ok&&II(j,bp.current)&&(w+=1)}catch{}finally{Ep.current.delete(T)}}return w>0&&Ze(w===1?"Your board is now saved to your account.":`${w} boards are now saved to your account.`),{acknowledged:w,attempted:g.length}},[z,B.personal,Qt,Ie,ai]),Np=d.useRef(kp);Np.current=kp;const[Wd,jp]=d.useState("");d.useCallback(g=>!!g?.id&&(Sg(g,{userId:Ie})||g.syncConflict===Cu),[Ie]);const Hf=async g=>{if(!(!g?.id||Wd||!Qt)){jp(String(g.id));try{const w=await ai(g,{operation:"create"});w?.ok&&!w.contentDiverged&&Ze("Your board is now saved to your account.")}finally{jp("")}}},Gd=d.useRef(new Set),Rp=d.useCallback(async()=>
32{if(!Qt||!Ie||z!==B.personal)return{acknowledged:0,attempted:0};const g=Ie,w=Jt,j=hT(ua.current,xo.current,{inFlightIds:Gd.current,userId:g});let T=0;for(const U of j){const M=String(U.product.id);Gd.current.add(M);try{(await Rn(U.product,{isSessionCurrent:()=>wa.current===w&&ct.getAccountScope?.()===g,list:U.list,lists:xo.current,operation:"create"}))?.ok&&II(U.product,bp.current)&&(T+=1)}catch{}finally{Gd.current.delete(M)}}return T>0&&Ze(T===1?"Your item is now saved to your account.":`${T} items are now saved to your account.`),{acknowledged:T,attempted:j.length}},[Jt,z,B.personal,Qt,Ie,Rn]),ql=d.useRef(Rp);ql.current=Rp;const Lp=d.useCallback(g=>{const w=p(g);return Rn(w?.createdProduct,{createList:!!w?.createdList,list:w?.list,lists:w?.lists,operation:"create"}),w},[p,Rn]),oi=d.useCallback((g,w={})=>{const j=ze(g);return w.sync!==!1&&Rn(j?.updatedProduct,{expectedRevision:w.expectedRevision,list:j?.list,operation:"update",preserveConflictUntilAcknowledged:w.preserveConflictUntilAcknowledged,previousProduct:j?.previousProduct,previousProductForPatch:w.previousProductForPatch}),j},[Rn,ze]),Wf=d.useCallback((g,w)=>{const j=J(g,w);return Qt&&j?.updatedProducts?.length&&st({message:"Item order is saved on this browser. Cloud ordering is not synced yet.",status:"idle"}),j},[J,Qt]),Bp=d.useCallback((g,w,j={})=>{const T=re(g,w);return j.sync!==!1&&Rn(T?.updatedProduct,{list:T?.list,operation:"update",previousList:T?.previousList,previousProduct:T?.previousProduct}),T},[re,Rn]),Tp=d.useCallback(g=>S(g),[S]),Gf=d.useCallback(async g=>{const w=Ie,j=Jt,T=ni("product",g),U=fa("product",g?.id);G({message:"",productId:String(g?.id||""),status:"pending"}),st({message:"Moving 1 item to Trash...",status:"syncing"});const M=await Rz({expectedOwnerId:w,expectedRevision:T,expectedSessionGenerationKey:j,isSessionCurrent:()=>wa.current===j&&ct.getAccountScope?.()===w,product:g,removeConfirmedProduct:ee,requestTrash:({expectedRevision:Q,product:we})=>jo(()=>Hz({expectedRevision:Q,product:we,user:e.user}))});if(M.ok&&M.removed)return Cn.current.delete(U),Fn("product",{id:g.id,revision:M.revision}),G({message:"",productId:"",status:"idle"}),st({message:"Moved 1 item to Trash.",status:"synced"}),Ze("Moved to Trash."),M;let Y="This item is still visible because Saveboard could not confirm Trash.";return M.conflict||M.outcome==="revision-conflict"?(Cn.current.add(U),f({attemptedPatch:{deleted_at:"trash"},latestRecord:null,productId:g.id,reason:M.outcome}),Fn("product",{id:g.id,revision:M.revision}),Y="This item changed on another device. Review it before moving it to Trash."):M.outcome==="not-active"?Y="Only active items can be moved to Trash.":["authentication-unavailable","session-changed"].includes(M.outcome)&&(Y="Trash is unavailable until account sync is ready."),G({message:Y,productId:String(g?.id||""),status:"error"}),st({message:Y,status:"error"}),Ze(Y),M},[f,e.user,Jt,fa,ni,jo,Fn,ee,Ie]),Dp=d.useCallback(async g=>{const w=Ie,j=Jt,T=ni("product",g),U=fa("product",g?.id),M=String(g?.id||"");le({message:"",productId:M,status:"pending"}),st({message:"Restoring 1 item...",status:"syncing"});const Y=await Ez({applyConfirmedProduct:h,expectedOwnerId:w,expectedRevision:T,expectedSessionGenerationKey:j,isSessionCurrent:()=>wa.current===j&&ct.getAccountScope?.()===w,mapAcknowledgedProduct:(we,Ce)=>{const je=xo.current.find(qe=>String(qe?.id||"")===String(we?.list_id||Ce?.listId||""));return om({attemptedPatch:{deleted_at:null},fallback:Ce,listName:je?.name||Ce?.listName||Ce?.category||"Wishlist",row:we})},product:g,requestRestore:({expectedRevision:we,product:Ce})=>jo(()=>Wz({expectedRevision:we,product:Ce,user:e.user}))});if(Y.ok&&Y.restored)return Cn.current.delete(U),Fn("product",{id:g.id,revision:Y.revision}),le({message:"",productId:"",status:"idle"}),st({message:"Restored 1 item.",status:"synced"}),Ze(`Restored to ${Y.product?.listName||g.listName||"its board"}.`),Y;let Q="This item remains in Trash because Saveboard could not confirm Restore.";return Y.conflict||Y.outcome==="revision-conflict"?(Cn.current.add(U),f({attemptedPatch:{deleted_at:null},latestRecord:null,productId:g.id,reason:Y.outcome}),Fn("product",{id:g.id,revision:Y.revision}),Q="This item changed on another device. Review it before restoring."):Y.outcome==="parent-unavailable"?Q="This item cannot be restored because its original board is unavailable.":["authentication-unavailable","session-changed"].includes(Y.outcome)&&(Q="Restore is unavailable until account sync is ready."),le({message:Q,productId:M,status:"error"}),st({message:Q,status:"error"}),Ze(Q),Y},[h,f,e.user,Jt,fa,ni,jo,Fn,Ie]);d.useEffect(()=>{xe(hi(e.user?.id))},[e.user?.id]),d.useEffect(()=>{if(!Ie||!e.isConfigured||!Jt){wo.current+=1,Pe(Ba());return}if(!jr){wo.current+=1,Pe(Ba({message:"Preparing account data...",sessionKey:Jt,status:"checking"}));return}let g=!0;const w=wo.current+1,j=Jt;wo.current=w,Pe(Ba({message:"Checking cloud boards...",sessionKey:j,status:"checking"}));const T=()=>g&&wo.current===w&&wa.current===j&&ct.getAccountScope?.()===Ie;return(async()=>{try{const M=await ew({user:{id:Ie}});if(!T())return;const Y=new Date().toISOString(),Q=hi(Ie)||{},we=ad(Ie,{...Q,checkedAt:Y,hasCloudData:M.hasCloudData,lastBackedUpAt:M.cloudBackedUpAt||Q.lastBackedUpAt,latestUpdatedAt:M.cloudBackedUpAt||Q.latestUpdatedAt,listCount:M.listCount,productC
32ount:M.productCount});if(xe(we),!M.hasCloudData||!M.backup){const ut=qh(),it=wu(ut);qs&&HN({merge:null,transaction:{terminalReason:"no-cloud-data",mergeResultChanged:null,persistenceRequired:!1,persistenceStarted:!1,persistenceVerified:!1,verifiedHydratedSnapshotApplied:!1,unchangedLocalSnapshotReapplied:!1,foregroundEnabled:!1,generationValidation:[{checkpoint:"after-cloud-candidate-fetch",valid:!0}],writesPerformed:0},writesPerformed:0}),Pe(Ba({checkedAt:Y,message:it?"This browser has local boards and this account has no cloud boards yet. You can upload this device's boards to cloud from Data & backup.":"No cloud boards found for this account yet.",foregroundReady:!0,sessionKey:j,settled:!0,status:it?"local-upload-ready":"empty"}));return}const Ce=wu(qh()),je=$t({accountScopeId:Ie,authenticatedUserId:Ie,backup:M.backup,generation:j,isGenerationCurrent:T,privateOwnerScoped:M.privateOwnerScoped===!0});if(je?.cancelled||!T())return;const qe=ct.readViewState(B.personal),Me=new Date().toISOString(),Ue=Number(je?.mergeResult?.protectedListCount||0)+Number(je?.mergeResult?.protectedProductCount||0),dt=ad(Ie,{...we,checkedAt:Me,hasCloudData:!0,lastHydratedAt:Me,latestUpdatedAt:M.cloudBackedUpAt||we.latestUpdatedAt,listCount:M.listCount,productCount:M.productCount});xe(dt),he(fu(qe.selectedStatusFilter)),x(bc(qe.selectedSort)),O(qe.boardSortModes||{}),X(qe.allItemsSortMode||""),Yt(""),_t("");const ot=!Ce&&(Number(M.listCount)>0||Number(M.productCount)>0);Ue?tr(`Cloud boards refreshed. ${Ue} local record${Ue===1?"":"s"} remain protected for review.`):je?.applied&&ot&&(tr(`Cloud boards restored to this browser. Restored ${M.listCount} boards and ${M.productCount} items.`),Ze("Cloud boards restored to this browser.")),Pe(Ba({checkedAt:Me,listCount:M.listCount,message:Ue?`Cloud boards refreshed. ${Ue} local record${Ue===1?"":"s"} need review.`:`Cloud boards restored to this browser. ${M.listCount} boards and ${M.productCount} items are now local here.`,productCount:M.productCount,foregroundReady:!0,sessionKey:j,settled:!0,status:Ue?"cloud-and-local":"hydrated"}))}catch{if(!T())return;const M=new Date().toISOString();Pe(Ba({checkedAt:M,error:"Could not load cloud boards. Your local browser data was left unchanged.",message:"Could not load cloud boards. Your local browser data was left unchanged.",sessionKey:j,settled:!0,status:"error"}))}})(),()=>{g=!1}},[jr,$t,e.isConfigured,Jt,B.personal,Ie,qs]),d.useEffect(()=>{},[Kr,jr,e.isConfigured,Jt,Yn.search,be,ft,Ve,z,B.personal,tn,ar,Be,Ie]),d.useEffect(()=>{Vs.current=P},[P]),d.useEffect(()=>{$c.current=Ie},[Ie]),d.useEffect(()=>{if(!Ie){Hs.current+=1,Xt({message:"",status:"local"});return}let g=!0;const w=Hs.current+1;return Hs.current=w,Xt({message:"Syncing...",status:"syncing"}),(async()=>{const T=await A$();if(!g||Hs.current!==w||$c.current!==Ie)return;if(!T.ok){Xt({message:qw,status:"error"});return}const{mergedStores:U,storesToUpload:M}=nS(Vs.current,T.stores);if(rS(Vs.current,U)||(Vs.current=U,ke(U)),M.length){const Y=await E$(M);if(!g||Hs.current!==w||$c.current!==Ie)return;if(Y.stores?.length){const{mergedStores:Q}=nS(Vs.current,Y.stores);rS(Vs.current,Q)||(Vs.current=Q,ke(Q))}if(!Y.ok){Xt({message:R5,status:"error"});return}}Xt({message:"Synced",status:"synced"})})(),()=>{g=!1}},[ke,Ie]);const ac=d.useCallback(async()=>{if(!e.user?.id)return wn(0),0;try{const g=await bU(),w=g.ok?g.count:0;return wn(w),w}catch{return wn(0),0}},[e.user?.id]);d.useEffect(()=>{ac()},[ac]),d.useEffect(()=>{if(!Nr){fo({boardItems:[],boardItemsError:"",boards:[],boardsError:"",error:"",isUnlistedShare:!1,isLoading:!1,profile:null,username:Nr||""});return}if(e.loading||!e.user)return;let g=!0;const w=Qi?"":O4({publicBoardId:cn,username:Nr,viewerId:e.user?.id||""}),j=M4(w);if(fo(j||{boardItems:[],boardItemsError:"",boards:[],boardsError:"",error:"",isUnlistedShare:!!(Qi&&cn),isLoading:!0,profile:null,username:Nr,boardId:cn}),Qi&&cn){let Q=0;const we=()=>fo({boardItems:[],boardItemsError:"",boards:[],boardsError:"",error:"",isUnlistedShare:!0,isLoading:!0,profile:null,username:Nr,boardId:cn}),Ce=async()=>{const qe=++Q;we();let Me=null,Ue=null,dt="",ot=[],ut="";if(!e.fetchPrivateBoardByShareToken||!e.fetchPrivateBoardItemsByShareToken)dt="This board is not available.";else try{const it=await e.fetchPrivateBoardByShareToken({publicBoardId:cn,shareToken:Qi,username:Nr});if(Me=it.board||null,Ue=it.profile||null,dt=it.error||"",Me?.id){const Rt=await e.fetchPrivateBoardItemsByShareToken({publicBoardId:cn,shareToken:Qi});ot=Rt.items||[],ut=Rt.error||""}}catch{dt="This board is not available."}!g||qe!==Q||fo({boardItems:ot,boardItemsError:ut,boards:Me?[Me]:[],boardsError:"",error:dt,isUnlistedShare:!0,isLoading:!1,profile:Ue,username:Nr,boardId:cn})},je=()=>{document.visibilityState==="hidden"?(++Q,we()):Ce()};return Ce(),window.addEventListener("focus",Ce),window.addEventListener("pageshow",Ce),window.addEventListener("online",Ce),document.addEventListener("visibilitychange",je),()=>{g=!1,window.removeEventListener("focus",Ce),window.removeEventListener("pageshow",Ce),window.removeEventListener("online",Ce),document.removeEventListener("visibilitychange",je)}}const T=(Q,we)=>Q.then(Ce=>Ce??we).catch(()=>we),U=e.fetchPublicProfileByUsername(Nr),M=e.fetchPublicBoardsByUsername?T(e.fetchPublicBoardsByUsername(Nr),{boards:[],error:"Public boards could not load."}):Promise.resolve({boards:[],error:""}),Y=cn&&e.fetchPublicBoardItemsByBoardId?T(e.fetchPublicBoardItemsByBoardId(cn),{error:"Public items could not load.",items:[]}):Promise.resolve({error:"",items:[]});return U.then(async Q=>{if(!g)return;let we=[],Ce="",je=[],qe="";if(Q.profile){const dt=await M;we=dt.boards||[],Ce=dt.error||""}let Me=!!(cn&&we.some(dt=>String(dt.id||"")===String(cn)));if(Q.profile&&cn&&!Me&&e.fetchPublicBoardByUsernameAndId)try{const dt=await e.fetchPublicBoardByUsernameAndId({publicBoardId:cn,username:Nr});dt.board?.id?(we=[dt.board,...we.filter(ot=>String(ot.id||"")!==String(dt.board.id))],Me=!0):dt.error&&(Ce=Ce||dt.error)}catch{Ce=Ce||"Public boards could not load."}if(Me){const dt=await Y;je=dt.items||[],qe=dt.error||""}if(!g)return;const Ue={boardItems:je,boardItemsError:qe,boards:we,boardsError:Ce,error:Q.error||"",isUnlistedShare:!1,isLoading:!1,profile:Q.profile||null,username:Nr,boardId:cn};U4(w,Ue),!(j&&$4(j,Ue))&&(await iE(W_({boardItems:je,boards:we,publicBoardId:cn}),{budgetMs:pE}),g&&fo(Ue))}).catch(()=>{g&&fo({boardItems:[],boardItemsError:"",boards:[],boardsError:"",error:"Could not load this profile.",isUnlistedShare:!1,isLoading:!1,profile:null,username:Nr,boardId:cn})}),()=>{g=!1}},[e.loading,e.user?.id,e.fetchPrivateBoardByShareToken,e.fetchPrivateBoardItemsByShareToken,e.fetchPublicProfileByUsername,e.fetchPublicBoardsByUsername,e.fetchPublicBoardItemsByBoardId,e.fetchPublicBoardByUsernameAndId,Qi,cn,Nr]);const Op=d.useCallback(({backgroundResult:g,expectedImageSettings:w=null,framing:j=null,imageSource:T,productId:U})=>{if(!U||!T)return null;try{const Y=ct.readProducts(B.personal).find(qe=>qe.id===U);if(!Y||kn(Y)!==T)return null;const Q=Li(Y),we={...Y};
32g&&Q.imageBackgroundMode==="auto"&&(we.imageBackgroundMode=fS(g),we.imageBackgroundColor=g.ok?gl(g.color):Bs);const Ce=!w||["imageFit","imageScale","imagePositionX","imagePositionY"].every(qe=>String(Q[qe])===String(w[qe]));return j?.ok&&Ce&&(we.imageFit=j.imageFit,we.imageScale=j.imageScale,we.imagePositionX=j.imagePositionX,we.imagePositionY=j.imagePositionY),Y.imageAutoFramePending===!0&&(we.imageAutoFramePending=!1),["imageBackgroundMode","imageBackgroundColor","imageFit","imageScale","imagePositionX","imagePositionY","imageAutoFramePending"].some(qe=>String(we[qe])!==String(Y[qe]))?{previousProduct:Y,updatedProduct:{...we,updatedAt:new Date().toISOString()}}:null}catch(M){return fm("storage image analysis update failed",{productId:U,imageSource:T,reason:M?.message||"unknown"}),null}},[B.personal]),pv=d.useCallback(()=>{Ul.current=null;const g=[...Ud.current.values()];if(Ud.current.clear(),g.length===0)return;const w=new Map(ua.current.map(U=>[U.id,U])),j=g.filter(({storePayload:U})=>{const M=w.get(U.productId);return!M||kn(M)!==U.imageSource||vr&&(M.userId!==Ie||!Br(M.syncRevision)||M.syncPendingCloudWrite||M.syncConflict||Un.current?.productId===M.id)?!1:!U.backgroundMode||ao(M).mode==="auto"});if(j.length===0)return;if(!vr){W(j.map(({storePayload:U})=>U));return}const T=j.map(({storePayload:U})=>{const M=w.get(U.productId),Y=!U.expectedImageSettings||["imageFit","imageScale","imagePositionX","imagePositionY"].every(Q=>String(M[Q])===String(U.expectedImageSettings[Q]));return{previousProduct:M,updatedProduct:{...M,...U.backgroundMode?{imageBackgroundMode:U.backgroundMode,imageBackgroundColor:U.backgroundColor}:{},...U.framing?.ok&&Y?{imageFit:U.framing.imageFit,imageScale:U.framing.imageScale,imagePositionX:U.framing.imagePositionX,imagePositionY:U.framing.imagePositionY}:{},imageAutoFramePending:!1,updatedAt:U.updatedAt}}});Xi.current=Xi.current.catch(()=>{}).then(async()=>{for(const U of T)await Rn(U.updatedProduct,{operation:"update",previousProduct:U.previousProduct,trackPendingMetadata:!1,automaticAnalysis:!0,isSessionCurrent:()=>wa.current===Jt&&ct.getAccountScope?.()===Ie})})},[Jt,vr,Ie,Rn,W]);iv.current=pv;const Mp=d.useCallback(g=>{g?.mutation?.updatedProduct?.id&&(Ud.current.set(g.mutation.updatedProduct.id,g),Ul.current===null&&(Ul.current=window.setTimeout(()=>iv.current?.(),180)))},[]),Ha=d.useCallback((g,{autoFrame:w=!1,delay:j=0,reason:T="product-save"}={})=>{if(typeof window>"u")return;(Array.isArray(g)?g:[g]).filter(Boolean).forEach((M,Y)=>{const Q=kn(M),we=Il(Q,{width:Os.card}),Ce=Li(M),je=`${M.id||""}|${Q}`,qe=hS(M),Me=w||M.imageAutoFramePending===!0;if(!M.id||!Q||!qe&&!Me||Gs.current.has(je)||Ki.current.has(je))return;Ki.current.add(je);for(const[ut,it]of Vc.current)ut.startsWith(`${M.id||""}|`)&&ut!==je&&(window.clearTimeout(it),Vc.current.delete(ut),Ki.current.delete(ut));for(const[ut,it]of Hc.current)ut.startsWith(`${M.id||""}|`)&&ut!==je&&(it.abort(),Hc.current.delete(ut),Ki.current.delete(ut));const Ue=async()=>{Vc.current.delete(je);const ut=new AbortController;Hc.current.set(je,ut),fm("queued product detection",{productId:M.id,imageSource:Q,reason:T});try{performance.mark("saveboard:analysis",{detail:{productId:M.id,reason:T}})}catch{}const it=qe?await Pg(we,{signal:ut.signal}):sa({color:Ce.imageBackgroundColor,confidenceLevel:Ce.imageBackgroundConfidenceLevel,ok:!0,reason:"saved-automatic-color"});if(ut.signal.aborted||it.reason==="aborted"){Ki.current.delete(je),Hc.current.delete(je);return}const Rt=Me?await Fw({backgroundColor:it.color,frameAspectRatio:$w(ra[ne]??ra[Ja]),imageSource:we}):null;fm("content framing",{autoFrame:Me,productId:M.id,imageSource:Q,result:Rt}),Ki.current.delete(je),Hc.current.delete(je),Gs.current.add(je);try{performance.mark("saveboard:analysed",{detail:{ok:it.ok,productId:M.id,reason:it.reason}})}catch{}it.ok||fm("product detection fallback",{productId:M.id,imageSource:Q,reason:it.reason});const Mr={backgroundResult:qe?it:null,expectedImageSettings:Me?Ce:null,framing:Rt,productId:M.id,imageSource:Q},sr=Op(Mr);sr&&(Mp({mutation:sr,storePayload:{backgroundMode:qe?sr.updatedProduct.imageBackgroun
32dMode:null,backgroundColor:sr.updatedProduct.imageBackgroundColor,expectedImageSettings:Mr.expectedImageSettings,framing:Rt,imageSource:Q,productId:M.id,updatedAt:sr.updatedProduct.updatedAt}}),fm("background runtime",nO()))},dt=()=>{T==="lazy-visible-products"&&typeof window.requestIdleCallback=="function"?window.requestIdleCallback(()=>Ue(),{timeout:2e3}):Ue()},ot=window.setTimeout(dt,j+Y*CW);Vc.current.set(je,ot)})},[Op,ne,Mp]),Up=Pp.products;d.useEffect(()=>{!Ea&&Se==="trash"&&he("active")},[Se,Ea]),d.useEffect(()=>{a?.id&&Se!=="active"&&he("active")},[a?.id,Se]);const qf=d.useMemo(()=>No?aL({lists:_,products:D,query:"",status:"active"}):[],[No,_,D]),Fp=He?_.find(g=>g.id===He.id)||He:null,mv=Xe&&jt==="cloud"?$D({listId:Xe.id,ownerId:xt.operation?.ownerId,products:D}):0;d.useEffect(()=>()=>{typeof window>"u"||(Vc.current.forEach(g=>window.clearTimeout(g)),Vc.current.clear(),Hc.current.forEach(g=>g.abort()),Hc.current.clear(),Ki.current.clear(),Ul.current!==null&&(window.clearTimeout(Ul.current),Ul.current=null),Ud.current.clear())},[]),d.useEffect(()=>{if(!e.user?.id||!e.isConfigured){kt(null);return}let g=!0;return nj({user:e.user}).then(w=>{g&&kt(w)}).catch(()=>{g&&kt(null)}),()=>{g=!1}},[e.isConfigured,e.user?.id]),d.useEffect(()=>{if(typeof window>"u"||z!==B.personal)return;const g=new Set(pt.map(T=>T.id)),w=new Map;[...pt,...D].forEach(T=>{T?.id&&!w.has(T.id)&&w.set(T.id,T)});const j=[...w.values()].map(T=>{const U=kn(T),M=Li(T),Y=`${T.id}|${U}`;return{product:T,imageSource:U,imageSettings:M,key:Y}}).filter(({product:T,imageSource:U,imageSettings:M,key:Y})=>!U||!hS(T)?!1:!Gs.current.has(Y)&&!Ki.current.has(Y)).sort((T,U)=>{const M=g.has(T.product.id),Y=g.has(U.product.id);return M!==Y?M?-1:1:new Date(U.product.updatedAt||U.product.createdAt||0)-new Date(T.product.updatedAt||T.product.createdAt||0)}).slice(0,wW);j.length!==0&&Ha(j.map(({product:T})=>T),{delay:PR,reason:"lazy-visible-products"})},[z,B.personal,D,Ha,pt]),d.useLayoutEffect(()=>{if(typeof document>"u")return;const g=document.documentElement;g.dataset.theme=xa,g.dataset.themeSetting=Ip,g.dataset.displayQuality=cs,g.dataset.cardSurface=dv,g.style.colorScheme=xa},[xa,Ip,cs,dv]);const qd=d.useMemo(()=>{if(!ls)return Up;const g=rc.toLowerCase();return Up.filter(w=>ff(w).includes(g))},[ls,Up,rc]),ha=d.useMemo(()=>dg(qd,er),[qd,er]),fv=d.useMemo(()=>{const g=ls?Mc.filter(w=>ff(w).includes(rc.toLowerCase())):Mc;return dg(g,er)},[ls,Mc,er,rc]),Jc=pr?fv:ha,Qc=d.useMemo(()=>pr||!a?.id?null:a.syncConflict===Cu?{message:"This board could not be saved to your account. It is kept in this browser; you can try again."}:Sg(a,{userId:Ie})?{message:"This board is saved in this browser but not yet in your account. Saveboard retries when you return; you can also retry now."}:null,[a,pr,Ie]),Yd=pr?da:a,Yf=d.useMemo(()=>iG(Jc),[Jc]),Ar=d.useMemo(()=>wr&&_.find(g=>g.id===wr)||null,[_,wr]);d.useEffect(()=>{if(!Ar?.id||!e.user?.id||po)return;let g=!0,w=0;const j=async()=>{const T=++w,U=await e.getOwnerPrivateBoardShareLink(Ar.id);!g||T!==w||(ce(U.error?null:U),U.error&&Cr(U.error),rs(M=>U.shareToken&&M.includes(`share=${U.shareToken}`)?M:""),It(M=>M.url.includes("?share=")&&(!U.shareToken||!M.url.includes(`share=${U.shareToken}`))?{dataUrl:"",error:"",status:"idle",url:""}:M))};return j(),window.addEventListener("focus",j),window.addEventListener("pageshow",j),()=>{g=!1,window.removeEventListener("focus",j),window.removeEventListener("pageshow",j)}},[Ar?.id,e.user?.id,e.getOwnerPrivateBoardShareLink,po]);const Ro=vl(e.profile),Kd=yl(e.profile?.profile_visibility||e.profile?.profileVisibility)==="public",xs=!!(e.user?.id&&e.isConfigured),Kf=xs&&!Ro?"Choose a username before sharing this board publicly.":xs&&!Kd?"Make your profile public before sharing public boards.":"",Zc=Ar?String(oe[Ar.id]||"").trim():"",Xd=Ar&&Ro&&Zc?Qa(jc(Ro,Zc)):"",Yl=Ar?Qa(gd(Ar.slug||Ar.name)):"",$p=xs?Xd:Yl,ii=wt.status==="ready"?wt.dataUrl:"",sc=d.useMemo(()=>t2({lists:_,products:D,settings:de}),[_,D,de]),ga=d.useMemo(()=>ha.filter(g=>qn.has(g.id)),[qn,ha]),Xf=ga.length,Ks=d.useCallback(()=>{_n(new Set)},[]),hv=d.useCallback(()=>{Fa(!1),_n(new Set),an(!1)},[]),gv=d.useCallback(g=>{const w=typeof g=="string"?g:g?.id;if(!w)return;const j=qn.size===1&&qn.has(w);_n(T=>{const U=new Set(T);return U.has(w)?U.delete(w):U.add(w),U}),j&&(Fa(!1),an(!1))},[qn]),Kl=d.useCallback(()=>{_n(new Set(ha.map(g=>g.id)))},[ha]),Jf=d.useMemo(()=>$w(ra[ne]??ra[Ja]),[ne]),zp=d.useMemo(()=>eG(ra[ne]??ra[Ja]),[ne]),el=Va?ri:D3(r,vn),Vp=!!Nr||Df||pa||Io||ss||os||Po||Zi||Ao||ws||Qo||Zo,bv=Nr?"Public profile":Df?"Discover admin":pa?"Item details":os?"Signing in":Po?"Reset password":ss?Ea?"Profile":"Account":Io?"Guide":ws?"Search":Ao?"Discover":Zo?"Updates":Qo?Vl?"Store":"My Stores":Zi?"Tracking":No?"Boards":Ia,oc=!ls&&er==="manual",Qf=oc&&vn==="active"&&!Va,vv=oc,Hp=!!(Ea&&e.isConfigured&&!Vd&&(!jr||!Kr)&&D.length===0&&_.length===0),yv=Va&&vn==="active"&&!Hp&&!ls&&ha.length===0,Sv=Va&&vn==="trash"&&!ls&&ha.length===0,Zf=ls&&ha.length===0&&(!No||qf.length===0);d.useEffect(()=>{Sr("")},[r,Se,Or,er]),d.useEffect(()=>{Fa(!1),_n(new Set),an(!1)},[r,Se,z]),d.useEffect(()=>{if(!qn.size)return;const g=new Set(ha.map(w=>w.id));_n(w=>{let j=!1;const T=new Set;
32return w.forEach(U=>{g.has(U)?T.add(U):j=!0}),j?T:w})},[qn.size,ha]);const eh=`${s}|${z}`,Wp=d.useRef(null);if(Wp.current!==eh){Wp.current=eh;const g=ct.readViewState(z);he(fu(g.selectedStatusFilter)),x(bc(g.selectedSort)),O(g.boardSortModes||{}),X(g.allItemsSortMode||""),Oe(g.selectedView==="allItems"?"allItems":"overview")}const ci=Va?nw:a?.id||"",th=P2({allItemsSortMode:q,boardKey:ci,boardSortModes:$,defaultSortMode:de.defaultSortMode});d.useEffect(()=>{ci&&x(th)},[ci,th]);const rh=!!(_.length&&(!Ie||jr));d.useEffect(()=>{rh&&O(g=>_2(g,_.map(w=>w?.id)))},[rh,_]);const Gp=g=>{const w=bc(g);x(w),ci&&(ci===nw?X(w):O(j=>({...j,[ci]:w})),Qt&&st({message:"Sorting and item order are saved on this browser.",status:"idle"}))};d.useEffect(()=>{if(At==="/capture"||At==="/capture/import")return;const g=Io?"guide":ss||Po?"account":os?"auth":Zo?"updates":Qo?"dashboard":Nr||Wc?"share":Va?"allItems":r===rr||!a?"dashboard":"list";if(!(Ie&&String(s||"")!==Ie))try{ct.saveViewState(z,{selectedView:g,selectedListId:a?.id||"",selectedListSlug:a?.slug||"",selectedListName:a?.name||"",selectedStatusFilter:vn,selectedSort:er,boardSortModes:$,allItemsSortMode:q,selectedLayoutMode:Re,selectedDensity:ne})}catch{}},[r,a,Se,Va,q,ss,os,Re,$,At,ne,Io,z,Po,Nr,Wc,er,Qo,Zo,vn]),d.useEffect(()=>{const g="MY_LIST_EXTENSION_IMPORT_CAPTURE",w="MY_LIST_EXTENSION_IMPORT_CAPTURE_RESULT",j="MY_LIST_EXTENSION_MOVE_PRODUCT",T="MY_LIST_EXTENSION_MOVE_PRODUCT_RESULT",U="MY_LIST_EXTENSION_GET_LISTS",M="MY_LIST_EXTENSION_GET_LISTS_RESULT",Y="MY_LIST_EXTENSION_CREATE_BOARD",Q="MY_LIST_EXTENSION_CREATE_BOARD_RESULT",we="MY_LIST_EXTENSION_DEBUG_TRACE_EVENT",Ce=new Set,je=(Nt,nt,Ht={})=>{const Ut=un(Nt,160),cr=un(nt,120);!Ut||!cr||(window.postMessage({type:we,traceId:Ut,source:"app",event:cr,details:Ht},window.location.origin),console.log(`[Saveboard Create List Trace] ${Ut} ${cr}`,Ht))},qe=(Nt,nt,Ht)=>{window.postMessage({type:Nt,requestId:nt,result:Ht},window.location.origin)},Me=(Nt,nt)=>qe(w,Nt,nt),Ue=(Nt,nt)=>qe(T,Nt,nt),dt=(Nt,nt)=>qe(M,Nt,nt),ot=(Nt,nt)=>qe(Q,Nt,nt),ut=(Nt=[])=>Nt.filter(nt=>xu(nt,{authenticatedOwnerId:Ie})).map(nt=>{const Ht=Ye(nt?.name||nt);return!Ht||Ht===rr?null:{id:nt?.id||fx(Ht),name:Ht,slug:nt?.slug||Di(Ht)}}).filter(Boolean),it=()=>{const Nt=z===B.personal?_:ct.readLists(B.personal);return[...ut(Nt),...UG(qc.current)]},Rt=(Nt,nt)=>{const Ht=Ye(nt).toLowerCase();return Nt.find(Ut=>Ye(Ut.name).toLowerCase()===Ht)||Nt.find(Ut=>Ye(Ut.name).toLowerCase()===Ka.toLowerCase())||Nt[0]||null},Mr=(Nt,nt)=>{if(!nt)return null;const Ht=Ye(nt.name||"");return Nt.find(Ut=>Ut.id===nt.id&&xu(Ut,{authenticatedOwnerId:Ie}))||Nt.find(Ut=>Ye(Ut.name).toLowerCase()===Ht.toLowerCase()&&xu(Ut,{authenticatedOwnerId:Ie}))||null},sr=({product:Nt,list:nt,message:Ht})=>({ok:!0,status:"imported",persisted:!0,visible:va(Nt.status)==="active",visibleAfterRefresh:!0,message:Ht,
32itemId:Nt.id,productId:Nt.id,listId:nt.id,listName:nt.name}),Pr=Nt=>{if(Nt.source!==window||Nt.origin!==window.location.origin)return;const nt=Nt.data;if(!nt||nt.type!==U||typeof nt.requestId!="string")return;const Ht=de.defaultList||v||Ka,Ut=it(),cr=Rt(Ut,Ht);c_("sending list response",{requestId:nt.requestId,origin:Nt.origin,listCount:Ut.length,lists:Ut.map(_r=>_r.name),selectedListName:cr?.name||""}),dt(nt.requestId,{ok:!0,status:"lists",lists:Ut,selectedListName:cr?.name||"",defaultListName:cr?.name||Ye(Ht)||Ka})},Lo=Nt=>{if(Nt.source!==window||Nt.origin!==window.location.origin)return;const nt=Nt.data;if(!nt||nt.type!==Y||typeof nt.requestId!="string")return;const Ht=Ye(nt.boardName||"").slice(0,60),Ut=Ht.toLowerCase(),cr=un(nt.traceId,160),_r=zr=>{je(cr,"app handler returned create-list response",{requestId:nt.requestId,ok:!!zr?.ok,status:zr?.status||"",message:zr?.message||"",listName:zr?.listName||zr?.selectedListName||"",listCount:Array.isArray(zr?.lists)?zr.lists.length:0}),ot(nt.requestId,{traceId:cr,...zr})};if(!e.loading&&!e.user?.id){_r({ok:!1,status:"auth-required",message:"Sign in to SaveBoard to create boards."});return}if(je(cr,"app handler received create-list request",{requestId:nt.requestId,boardName:Ht,hasAuthUser:!!e.user?.id,authConfigured:!!e.isConfigured}),!Ht||Ht===rr){je(cr,"app create-list validation failed",{reason:"empty-or-dashboard-name"}),_r({ok:!1,status:"invalid",message:"Enter a board name."});return}if(Ce.has(Ut)){je(cr,"app create-list validation failed",{reason:"duplicate-in-flight",boardName:Ht}),_r({ok:!1,status:"busy",message:"Creating that board already."});return}Ce.add(Ut),(async()=>{try{const zr=ct.readLists(B.personal);je(cr,"app local list create attempted",{boardName:Ht,existingListCount:zr.length});const Ur=zr.find(dn=>Ye(dn.name).toLowerCase()===Ut&&xu(dn,{authenticatedOwnerId:Ie}));if(Ur){ye(B.personal),Fe(Ur.name),je(cr,"app local list already existed",{listId:Ur.id,listName:Ur.name}),_r({ok:!0,status:"exists",message:`${Ur.name} already exists.`,board:{id:Ur.id,name:Ur.name,slug:Ur.slug||Di(Ur.name)},listId:Ur.id,listName:Ur.name,lists:ut(zr),selectedListName:Ur.name,defaultListName:Ur.name});return}const Wa=ct.createList(zr,{name:Ht},{authenticatedOwnerId:Ie}),Is=Wa.lists.find(dn=>!zr.some(ol=>ol.id===dn.id))||Wa.lists.find(dn=>Ye(dn.name).toLowerCase()===Ut);if(!Is||zr.some(dn=>dn.id===Is.id)){je(cr,"app local list create failed",{reason:"no-new-list-record",boardName:Ht}),_r({ok:!1,status:"failed",message:"Could not create that board."});return}ct.saveLists(Wa.lists,B.personal);const Na=ct.readLists(B.personal),Er=Na.find(dn=>dn.id===Is.id)||Na.find(dn=>Ye(dn.name).toLowerCase()===Ut);if(!Er){je(cr,"app local list create failed",{reason:"local-confirmation-missing",boardName:Ht}),_r({ok:!1,status:"failed",message:"Could not confirm that board locally."});return}ye(B.personal),Fe(Er.name),Ze(`Created ${Er.name}
32.`),je(cr,"app local list create succeeded",{listId:Er.id,listName:Er.name,listCount:Na.length});let As=e.isConfigured&&e.user?.id?"synced":"local-only",Ps="";if(e.isConfigured&&e.user?.id)try{je(cr,"app cloud list create attempted",{listId:Er.id,listName:Er.name});const dn=await Fy({list:Er,user:e.user});if(!dn?.ok||!dn.row)throw new Error("Cloud board insert did not return a server record.");const ol=sm(dn.row,Er),xn=ct.readLists(B.personal);ct.saveLists(xn.map(dc=>dc.id===Er.id?ol:dc),B.personal),Fn("list",dn.row),ye(B.personal),je(cr,"app cloud list create succeeded",{listId:Er.id,listName:Er.name})}catch(dn){As="failed",Ps="Created locally. Cloud sync did not finish.",je(cr,"app cloud list create failed",{listId:Er.id,listName:Er.name,message:dn?.message||"unknown"}),c_("cloud list create failed after local create",{listId:Er.id,listName:Er.name,message:dn?.message||"unknown"})}else je(cr,"app cloud list create skipped",{reason:e.isConfigured?"signed-out-local-only":"auth-not-configured"});_r({ok:!0,status:"created",message:Ps||`Created ${Er.name}.`,board:{id:Er.id,name:Er.name,slug:Er.slug||Di(Er.name)}
32,listId:Er.id,listName:Er.name,lists:ut(Na),selectedListName:Er.name,defaultListName:Er.name,persistedLocal:!0,cloudSyncStatus:As,syncWarning:Ps})}catch(zr){je(cr,"app create-list catch path",{message:zr?.message||"unknown"}),_r({ok:!1,status:"failed",message:zr?.message||"Could not create that board. Try again in Saveboard."})}finally{Ce.delete(Ut)}})()},sl=async(Nt,nt,Ht,Ut)=>{ll("resolved shared board target",{boardId:Nt.boardId,ownerId:Nt.ownerId,role:Nt.role});try{const cr=await by(Nt,{brand:nt.brand,imageUrl:nt.imageUrl||nt.image||"",price:nt.price,source:nt.source,title:nt.title||Go(nt.url)||"Untitled item",url:nt.url});if(!cr.ok||!cr.item?.id){Ut({ok:!1,status:"failed",persisted:!1,message:cr.error||"Could not save to this shared board."});return}dd(),Ut({ok:!0,status:"imported",persisted:!0,visible:!0,visibleAfterRefresh:!0,message:`Saved to ${Nt.boardTitle}.`,itemId:cr.item.id,productId:cr.item.id,listId:mb(Nt),listName:Ax(Nt)})}catch{Ut({ok:!1,status:"failed",persisted:!1,message:"Could not save to this shared board."})}},uh=Nt=>{if(Nt.source!==window||Nt.origin!==window.location.origin)return;const nt=Nt.data;if(!nt||nt.type!==g||typeof nt.requestId!="string")return;const Ht=de.defaultList||v||Ka,Ut=$R(nt.capture,Ht,de.defaultImageFit),cr=Ut.captureId;ll("received import request",{requestId:nt.requestId,origin:Nt.origin,draft:I3(Ut)});const _r=xn=>{ll("sending import response",{requestId:nt.requestId,status:xn?.status||"",ok:!!xn?.ok,persisted:!!xn?.persisted,productId:xn?.productId||"",listId:xn?.listId||"",listName:xn?.listName||"",message:xn?.message||""}),Me(nt.requestId,{captureId:cr,...xn})};if(!Ut.title&&!Ut.url){_r({ok:!1,status:"queued",message:"Review needed before saving."});return}const zr=tS(Ut,qc.current);if(!zr&&E_(Ut)){(async()=>{const xn=Date.now()+$G;let dc=null;for(;!dc&&Date.now()<xn;)await new Promise(tu=>setTimeout(tu,150)),dc=tS(Ut,qc.current);if(dc){sl(dc,Ut,cr,_r);return}ll("shared board destination unavailable",{targetListName:Ut.targetListName}),_r({ok:!1,status:"board-unavailable",persisted:!1,message:"That shared board is not available to you any more. Choose another board."})})();return}if(zr){if(!e.loading&&!Ie){_r({ok:!1,status:"auth-required",persisted:!1,message:"Sign in to SaveBoard to save this item."});return}sl(zr,Ut,cr,_r);return}let Ur=ct.readLists(B.personal);const Wa=ct.readProducts(B.personal),Is=Hh(Ut,Ur,Ht,Ie);Ur=Is.lists;const Na=Is.targetList;if(ll("resolved target list",{targetListName:Na?.name||"",matched:!!Is.targetListMatched,createdList:!!Is.createdList,personalListCount:Ur.length,personalProductCount:Wa.length}),!Na){_r({ok:!1,status:"queued",message:"Saved to queue. Open Saveboard to choose a board."});return}const Er={...Ut,category:Na.name,targetListMatched:Is.targetListMatched};if(!e.loading&&!Ie&&z===B.personal&&String(ct.getAccountScope?.()||"")===""){_r({ok:!1,status:"auth-required",persisted:!1,message:"Sign in to SaveBoard to save this item."});return}const Ps=Ie,dn=Jt,ol=()=>!!(Ps&&dn&&wa.current===dn&&ct.getAccountScope?.()===Ps);(async()=>{try{const xn=await hz({captureId:cr,expectedOwnerId:Ps,expectedSessionGenerationKey:dn,isSessionCurrent:ol,markCaptureHandled:mm,readCanonicalProduct:ru=>ct.readAccountHydrationSnapshot(Ps).products.find(Xs=>String(Xs?.id||"")===String(ru))||null,resolveLocalProduct:({productId:ru})=>{const Xs=Wa.find(ed=>String(ed?.id||"")===String(ru));if(Xs){const ed=Mr(Ur,Na);if(!ed||!hs(Xs,ed)||va(Xs.status)!=="active"||Xs.syncSuppressed===!0||Xs.cloudDeletedAt||Xs.deletedAt||Xs.deleted_at)throw new Error("Existing extension item is not an active item in the target board.");return{created:!1,list:ed,lists:Ur,product:Xs,products:Wa}}const nu=Zy(Er,Na,de.defaultCurrency,de.defaultImageFit,{ownerId:Ps,productId:ru}),Jp=E({activeListName:Na.name,lists:Ur,products:[nu]}),Qp=Jp.importedProducts.find(ed=>ed.id===nu.id),Zp=Mr(Jp.lists,Na);if(!Qp||!Zp||!hs(Qp,Zp)||va(Qp.status)!=="active")throw new Error("Save was not visible in the target list.");return ll("import persisted",{captureId:cr,productId:nu.id,listId:Zp.id,listName:Zp.name,productC
32ountBefore:Wa.length,productCountAfter:Jp.products.length}),Ha(Qp,{autoFrame:!0,reason:"extension-bridge-save"}),{created:!0,list:Zp,lists:Jp.lists,product:Qp,products:Jp.products}},syncProductWriteThrough:(ru,Xs,nu)=>Rn(ru,{createList:nu.created&&!!Is.createdList,expectedOwnerId:Ps,extensionImportAcknowledgement:!0,isSessionCurrent:ol,list:Xs,lists:nu.lists,operation:"create",personalMutation:!0,trackPendingMetadata:!1})});if(!xn.verifiedFinalSuccess){if(ll("import acknowledgement queued",{captureId:cr,reason:xn.reason||"unconfirmed"}),zG.has(String(xn.reason||""))){_r({ok:!1,status:"auth-required",persisted:!1,message:"Sign in to SaveBoard to save this item."});return}_r({ok:!1,status:"queued",persisted:!1,message:"Saveboard did not confirm the save."});return}const dc=xn.durableProduct,tu=xn.durableList;ye(B.personal),Fe(tu.name),Gn(null),Ke(null),lr(null),Aa(),nn(null),Zn(!1),zs(!1),as(!1),he("active"),Yt(""),Ze(`Saved to ${tu.name}.`),_r(sr({product:dc,list:tu,message:`Saved to ${tu.name}.`}))}catch(xn){ll("import persistence failed",{message:xn?.message||"unknown"}),_r({ok:!1,status:"queued",persisted:!1,message:"Saveboard did not confirm the save."})}})()},eI=Nt=>{if(Nt.source!==window||Nt.origin!==window.location.origin)return;const nt=Nt.data;if(!nt||nt.type!==j||typeof nt.requestId!="string")return;const Ht=String(nt.productId||"").trim(),Ut=Ye(nt.targetListName||""),cr=Ye(nt.targetListSlug||""),_r=un(nt.traceId,160),zr=Ur=>{je(_r,"app handler returned item move response",{requestId:nt.requestId,productId:Ht,captureId:String(nt.captureId||"").trim(),ok:!!Ur?.ok,status:Ur?.status||"",message:Ur?.message||"",listName:Ur?.listName||""}),Ue(nt.requestId,{traceId:_r,productId:Ht,captureId:String(nt.captureId||"").trim(),...Ur})};if(!e.loading&&!e.user?.id){zr({ok:!1,status:"auth-required",message:"Sign in to SaveBoard to move items."});return}if(je(_r,"app handler received item move request",{requestId:nt.requestId,productId:Ht,captureId:String(nt.captureId||"").trim(),targetListName:Ut}),!Ht||!Ut){je(_r,"app item move validation failed",{reason:"missing-product-or-target"}),zr({ok:!1,status:"failed",message:"Could not move. Open Saveboard to edit."});return}try{je(_r,"app item move attempted",{productId:Ht,targetListName:Ut});const Ur=de.defaultList||v||Ka;let Wa=ct.readLists(B.personal);const Is=ct.readProducts(B.personal),Na=Is.find(xn=>xn.id===Ht);if(!Na){je(_r,"app item move failed",{reason:"product-not-found",productId:Ht}),zr({ok:!1,status:"failed",message:"Could not move. Open Saveboard to edit."});return}const Er=Hh({targetListName:Ut,targetListSlug:cr},Wa,Ur,Ie);Wa=Er.lists;const As=Er.targetList;if(!As){je(_r,"app item move failed",{reason:"target-list-not-found",targetListName:Ut}),zr({ok:!1,status:"failed",message:"Could not move. Open Saveboard to edit."});return}Er.createdList&&ct.saveLists(Wa,B.personal);const Ps=ct.moveProductToList(Is,Wa,Ht,As.id);ct.saveProducts(Ps,B.personal);const dn=Ps.find(xn=>xn.id===Ht)||null,ol=Xc(Na,Wa);Rn(dn,{createList:!!Er.createdList,list:As,lists:Wa,operation:"update",personalMutation:!0,previousList:ol,previousProduct:Na}),ye(B.personal),Fe(As.name),Ze(`Moved to ${As.name}.`),je(_r,"app item move succeeded",{productId:Ht,listId:As.id,listName:As.name}),zr({ok:!0,status:"moved",message:`Moved to ${As.name}.`,productId:Ht,listName:As.name})}catch(Ur){je(_r,"app item move catch path",{message:Ur?.message||"unknown"}),zr({ok:!1,status:"failed",message:"Could not move. Open Saveboard to edit."})}};return window.addEventListener("message",Pr),window.addEventListener("message",Lo),window.addEventListener("message",uh),window.addEventListener("message",eI),()=>{window.removeEventListener("message",Pr),window.removeEventListener("message",Lo),window.removeEventListener("message",uh),window.removeEventListener("message",eI)}},[e.isConfigured,e.loading,Jt,e.user,Aa,v,Xc,E,_,z,B.personal,Ha,Fn,Fe,Ie,de.defaultCurrency,de.defaultImageFit,de.defaultList,ye,Rn]),d.useEffect(()=>{At!=="/capture"&&At!=="/capture/import"&&(Xo.current=null)},[At]),d.useEffect(()=>{if(e.loading||!e.user||!jr||!Kr||At!=="/capture/import")return;const g=Yn.search||"",w=`import:${g}`;if(Xo.current===w)return;Xo.current=w;const j=()=>{window.history.replaceState({},"","/"),window.dispatchEvent(new PopStateEvent("popstate"))},T=de.defaultList||v||Ka,{drafts:U,extensionId:M,message:Y}=x3(g,T,de.defaultImageFit);if(!U.length){Ze(Y||"No extension saves to import."),j();return}let Q=z===B.personal?_:ct.readLists(B.personal),we=Q,Ce=0,je=0,qe="";const Me=[],Ue=[],dt=[];
32if(U.forEach(ot=>{if(ot.captureId&&o_(ot.captureId)){je+=1;return}const ut=lw(ot.captureId);if(Ie&&!ut){je+=1;return}if(E_(ot)){dt.push(ot);return}const it=Hh(ot,we,T,Ie);we=it.lists;const Rt=it.targetList;if(!Rt||!ot.title&&!ot.url){je+=1;return}const Mr={...ot,category:Rt.name,targetListMatched:it.targetListMatched},sr=Zy(Mr,Rt,de.defaultCurrency,de.defaultImageFit,{ownerId:Ie||void 0,productId:ut||void 0});Me.push(sr),Ce+=1,qe=Rt.name,ot.captureId&&Ue.push(ot.captureId)}),dt.length&&(async()=>{const ot=[];let ut=0;for(const it of dt){const Rt=tS(it,qc.current);if(!Rt){ut+=1;continue}try{const Mr=await by(Rt,{brand:it.brand,imageUrl:it.imageUrl||it.image||"",price:it.price,source:it.source,title:it.title||Go(it.url)||"Untitled item",url:it.url});Mr.ok&&Mr.item?.id?it.captureId&&(ot.push(it.captureId),mm(it.captureId)):ut+=1}catch{ut+=1}}ot.length&&(dd(),l_(M,ot)),ut?Ze(`${ut} save${ut===1?"":"s"} could not be added to a shared board. It may no longer be shared with you.`):ot.length&&Ze(`Added ${ot.length} save${ot.length===1?"":"s"} to a shared board.`)})(),Ce>0){(async()=>{try{const ot=new Set(Q.map(sr=>String(sr.id||""))),ut=we.filter(sr=>!ot.has(String(sr.id||""))).map(sr=>sr.id),it=E({activeListName:qe,lists:we,products:Me}),Rt=it.importedProducts,Mr=await Rn(Rt,{createListIds:ut,lists:it.lists,operation:"create",personalMutation:!0});if(Ie&&!Mr?.ok){Ze("Imported on this browser, but cloud confirmation is still pending."),j();return}Ue.forEach(mm),Ha(Rt,{autoFrame:!0,reason:"extension-batch-import"}),l_(M,Ue),qe&&Fe(qe),Gn(null),Ke(null),lr(null),Aa(),nn(null),Zn(!1),zs(!1),as(!1),he("active"),Yt(""),Ze([`Imported ${Ce} extension save${Ce===1?"":"s"}.`,je?`${je} skipped because they need review or already exist.`:"",Y].filter(Boolean).join(" ")),j()}catch{Ze("Review needed before saving."),j()}})();return}Ze([Ce?`Imported ${Ce} extension save${Ce===1?"":"s"}.`:dt.length?"Adding to a shared board...":"No extension saves to import.",je?`${je} skipped because they need review or already exist.`:"",Y].filter(Boolean).join(" ")),j()},[e.loading,e.user,jr,Kr,Yn.search,At,Aa,v,E,_,z,B.personal,D,Ha,Fe,de.defaultCurrency,de.defaultImageFit,de.defaultList,Ie,ye,Rn]),d.useEffect(()=>{if(e.loading||!e.user||!jr||!Kr||At!=="/capture")return;const g=Yn.search||"";if(Xo.current===g)return;Xo.current=g;const w=()=>{window.history.replaceState({},"","/"),window.dispatchEvent(new PopStateEvent("popstate"))};if(!g){Gn(null),Ke(null),lr(null),Aa(),nn(null),Ze("Capture route is ready. Open the extension from a product page to send item details."),w();return}const j=de.defaultList||v||Ka,{draft:T,message:U}=C3(g,j,de.defaultImageFit);if(o_(T.captureId)){Ze("Capture already opened."),w();return}const M=lw(T.captureId),Y=z===B.personal?_:ct.readLists(B.personal),Q=Hh(T,Y,j,Ie),we=FR(T,Y,Ie),Ce=Q.targetList,je={...T,category:Ce?.name||j,targetListMatched:Q.targetListMatched},qe=T.targetListName&&!we?`Suggested board "${T.targetListName}" is not in Saveboard yet. Choose a board before saving.`:"",Me=Q.targetList;if(T.captureMode==="quick"&&Me&&(je.title||je.url)&&!U&&(!Ie||M)){const Ue=Zy(je,Me,de.defaultCurrency,de.defaultImageFit,{ownerId:Ie||void 0,productId:M||void 0});if(Ie){(async()=>{try{const dt=E({activeListName:Me.name,lists:Q.lists,products:[Ue]}),ot=dt.importedProducts.find(it=>it.id===Ue.id);if(!ot)throw new Error("Save did not persist.");if(!(await Rn(ot,{createList:!!Q.createdList,expectedOwnerId:Ie,list:Me,lists:dt.lists,operation:"create",personalMutation:!0}))?.ok){Ze("Saved on this browser, but cloud confirmation is still pending."),w();return}mm(T.captureId),Ha(ot,{autoFrame:!0,reason:"extension-quick-save"}),Fe(Me.name),Gn(null),Ke(null),lr(null),Aa(),nn(null),Zn(!1),zs(!1),as(!1),he("active"),Yt(""),Ze(`Saved to ${Me.name}.`),w()}catch{Gn(je),Ze("Review needed before saving.")}})();return}try{const dt=E({activeListName:Me.name,lists:Q.lists,products:[Ue]}),ot=dt.importedProducts.find(ut=>ut.id===Ue.id);if(!ot)throw new Error("Save did not persist.");mm(T.captureId),Rn(ot,{createList:!!Q.createdList,list:Me,lists:dt.lists,operation:"create",personalMutation:!0}),Ha(ot,{autoFrame:!0,reason:"extension-quick-save"}),ye(B.personal),Fe(Me.name),Gn(null),Ke(null),lr(null),Aa(),nn(null),Zn(!1),zs(!1),as(!1),he("active"),Yt(""),Ze(`Saved to ${Me.name}.`),w();return}catch{}}z!==B.personal&&ye(B.personal),Gn(je),Ke(null),lr(null),Aa(),nn(null),Zn(!1),zs(!1),as(!1),he("active"),Yt(""),Ze([T.captureMode==="quick"?"Review needed before saving.":"",U,qe].filter(
32Boolean).join(" ")||(!je.title&&!je.url&&!je.imageUrl?"Capture opened. Add details manually.":"Review captured item before saving.")),w()},[e.loading,e.user,jr,Kr,Aa,Yn.search,At,v,E,_,z,B.personal,Ha,Fe,de.defaultCurrency,de.defaultImageFit,de.defaultList,Ie,ye,Rn]),d.useEffect(()=>{!qt.productId||String($r?.itemId||"")===qt.productId||(Jo.current?.abort(),Jo.current=null,So.current+=1,Ir({productId:"",status:"idle",message:""}))},[$r?.itemId,qt.productId]),d.useEffect(()=>()=>{Jo.current?.abort(),Jo.current=null},[]),d.useEffect(()=>{!Fr.productId||String($r?.itemId||"")===Fr.productId||(Ml.current?.abort(),Ml.current=null,Fc.current+=1,gn({productId:"",status:"idle",message:""}))},[Fr.productId,$r?.itemId]),d.useEffect(()=>()=>{Ml.current?.abort(),Ml.current=null},[]);const Xl=g=>{Gn(null),lr(null),Aa(),hn(!1),br(!1),Ke(g)},Pa=()=>{Gn(null),Ke(null),lr(null),Aa(),hn(!1),br(!1)},nh=g=>{const w=cd(g),j=fF({product:g,products:w?Mc:D});Gn(null),Ke(null),lr(j),nc(MC(j,{requiresExpectedRevision:!w&&Qt&&z===B.personal})),hn(!1),br(!1)},Jd=g=>cd(g)&&da?.id===String(g?.listId||"")?da:_.find(w=>String(w?.id||"")===String(g?.listId||""))||_.find(w=>hs(g,w))||null,tl=(g,{startEditing:w=!1}={})=>{const j=Jd(g);if(!j?.id||!g?.id){Ze("This item is not available in a board.");return}Co.current={activeList:r,activeStatus:vn,boardId:String(j.id),boardName:j.name,boardMode:Re,dashboardViewMode:$e,gridPreference:ne,gridScrollLeft:document.querySelector(".productGrid")?.scrollLeft||0,restoreBoardScroll:At===Cs,searchQuery:Or,sortMode:er,windowScrollY:window.scrollY},Dr(w),Gr(!1),Pa(),Ft(cg(j.id,g.id),{saveboardItemDetail:{boardId:String(j.id),itemId:String(g.id),sourcePath:At,startEditing:w}})},Qd=()=>!Wr||!tn||window.confirm("Discard your unsaved changes?"),rl=()=>{if(!Qd())return;const g=Wr,w=Co.current,j=ma||_.find(T=>String(T?.id||"")===String(w?.boardId||""))||Jd(ft||En);if(Pa(),Dr(!1),Gr(!1),j?.isSharedBoard)he("active"),Fe(rr),Oe("shared");else if(vo(null),j){const T=du({dashboardList:rr,listName:j.name});he(T.status),Fe(T.activeList),Oe(T.dashboardViewMode)}g&&(Md.current=!0),Ft(Cs)};d.useEffect(()=>{!$r||!ma||!En||(ma.isSharedBoard||(vo(null),Fe(ma.name),Oe("list"),he("active")),Wr&&String(Un.current?.productId||"")!==$r.itemId&&nh(En))},[ma,Wr,En,$r?.boardId,$r?.itemId]),d.useEffect(()=>{Dr(!!window.history.state?.saveboardItemDetail?.startEditing),Gr(!1)},[$r?.boardId,$r?.itemId]),d.useEffect(()=>{pa||!ft||Pa()},[pa]),d.useLayoutEffect(()=>{const g=Co.current;if(At!==Cs||!g?.restoreBoardScroll)return;Fm=null,u_(g.windowScrollY||0);const w=document.querySelector(".productGrid");w&&(w.scrollLeft=g.gridScrollLeft||0),Co.current=null},[At]),d.useLayoutEffect(()=>{const g=Fm;if(g&&(Fm=null,!(performance.now()-g.at>800))){if(g.intent==="pop"){const w=zR.get(Yn.key);u_(w?.y||0,w?.x||0);return}window.scrollTo({behavior:"instant",left:0,top:0})}},[r,Yn.key,At,$e,vn]);const wv=()=>{En&&(nh(En),Gr(!1),Dr(!0))},ah=()=>{Qd()&&(Pa(),Dr(!1),Gr(!1))},sn=g=>Qd()?(Wr&&(Pa(),Dr(!1),Gr(!1),Md.current=!0),g?.(),!0):!1;d.useEffect(()=>{if(!Wr||!tn||!$r)return;const g=cg($r.boardId,$r.itemId),w=window.history.state,j=U=>{U.preventDefault(),U.returnValue=""},T=()=>{if(Md.current){Md.current=!1;return}if(window.location.pathname!==g){if(window.confirm("Discard your unsaved changes?")){Pa(),Dr(!1),Gr(!1);return}window.history.pushState(w,"",g),window.dispatchEvent(new PopStateEvent("popstate",{state:w}))}};return window.addEventListener("beforeunload",j),window.addEventListener("popstate",T),()=>{window.removeEventListener("beforeunload",j),window.removeEventListener("popstate",T)}},[Wr,$r?.boardId,$r?.itemId,tn]);const sh=d.useCallback(async()=>{const g=Un.current,w=String(g?.productId||""),j=ua.current.find(Ce=>String(Ce?.id||"")===w)||null,T=Tg({latestRecord:j,session:g}),U=Ie,M=Jt,Y=Lf.current+1;Lf.current=Y;const Q=()=>Y===Lf.current&&wa.current===M&&ct.getAccountScope?.()===U&&Un.current===g,we=Ce=>({message:Fu,ok:!1,reason:Ce});if(!g||T.reason!==pi.missingOpeningRevision||!j||!lx(j)||tn||!Qt||!jr||!U||!M||!Q())return we("missing-revision-recovery-unavailable");try{const Ce=await $z({productId:w,user:e.user});if(!Ce?.ok||!Ce.row||!Ce.parentRow||!Q())return we(Ce?.reason||"missing-revision-recovery-read-blocked");const je=ua.current.find(it=>String(it?.id||"")===w)||null,qe=String(je?.listId||je?.list_id||""),Me=xo.current.find(it=>String(it?.id||"")===qe)||null,Ue=sm(Ce.parentRow,{}),dt=om({fallback:{id:w},listName:Ue.name,row:Ce.row}),ot=bH({authenticatedUserId:U,cloudParent:Ue,cloudRecord:dt,explicitMovePending:k(w),generationIsCurrent:Q(),localParent:Me,localRecord:je,privateOwnerScoped:Ce.privateOwnerScoped===!0,submissionReason:T.reason});if(!ot.eligible||!Q())return we(ot.reason||"missing-revision-recovery-evidence-changed");const ut=hF({cloudOpeningSnapshot:ot.cloudOpeningSnapshot,formGeneration:(Number(g.formGeneration)||0)+1,protectedLocalRecord:je});return Q()?(lr(ot.formProduct),nc(ut),hn(!1),br(!1),{ok:!0,reason:ot.reason}):we("missing-revision-recovery-generation-superseded")}catch{return we("missing-revision-recovery-read-failed")}},[jr,e.user,Jt,nc,k,tn,Qt,Ie]),ic=()=>{nn(null),G({message:"",productId:"",status:"idle"})},Jl=g=>{if(cd(g)){if(!bn.canDeleteItems){Ze("You can only view this board.");return}Gn(null),Ke(null),G({message:"",productId:String(g?.id||""),status:"idle"}),nn(g);return}if(Ie&&z===B.personal&&va(g?.status)!=="active"){Ze("Only active items can be moved to Trash.");return}Gn(null),Ke(null),pa||(lr(null),Aa()),G({message:"",productId:String(g?.id||""),status:"idle"}),nn(g)},Cv=d.useCallback(async g=>{const w=Ie;if(!w||!g)return;Xt({message:"Syncing...",status:"syncing"});const j=await P$(g);
32if($c.current===w){if(!j.ok){Xt({message:qw,status:"error"});return}if(j.store){const{mergedStores:T}=nS(Vs.current,[j.store]);rS(Vs.current,T)||(Vs.current=T,ke(T))}Xt({message:"Synced",status:"synced"})}},[ke,Ie]),oh=d.useCallback(async g=>{const w=Tr(g),j=Ie;if(!j||!w)return;Xt({message:"Syncing...",status:"syncing"});const T=await _$(w);if($c.current===j){if(!T.ok){Xt({message:L5,status:"error"});return}Xt({message:"Synced",status:"synced"})}},[Ie]),xv=(g={})=>{const w=Tr(g.domain||g.url);if(!w)return null;const j=Gu(P,w),T=af(g,j);return T?(ke(U=>{const M=Gu(U,w),Y=af(T,M)||T;return[...U.filter(we=>Tr(we.domain||we.url)!==w),Y]}),Cv(T),T):null},Iv=(g={})=>{const w=Tr(g.domain||g.url);if(!w)return null;const j=Gu(P,w);return j?(ke(T=>T.filter(U=>Tr(U.domain||U.url)!==w)),oh(w),j):null},nl=()=>{Te(null),at(!1),tt(!1),Ne("create")},Av=g=>{Te(g),at(!1),tt(!1),Ne("edit")},Pv=g=>{Ge(g)},qp=()=>{Te(null),at(!1),tt(!1),Ne(null)},_v=(g,w)=>{!g||!pp.includes(w)||We(j=>({...j,boardThemes:{...j?.boardThemes||{},[g]:w}}))},Ev=async(g,w={})=>{if(be){if(yt)throw Ze("This board changed on another device. Close and reopen it before saving your changes."),new Error("board-editor-base-changed");const U=Le(be.id,g),M=ai(U?.updatedList,{operation:"update",previousList:U?.previousList});if(w.waitForCloud&&!(await M)?.ok)throw new Error("Board cloud update did not finish.");return U}const j=b(g);if(!j?.createdList?.id)throw new Error("Board creation did not produce a new identity.");lE("board created locally");const T=Promise.resolve(ai(j?.createdList,{operation:"create"})).then(U=>(U?.ok&&KL(Da.firstBoardCreated),U));if(w.waitForCloud&&!(await T)?.ok)throw new Error("Board cloud insert did not finish.");return j},kv=g=>{if(!He)return;const w=hf(g),j=hf((Fp||He).coverItemIds);if(!(w.length===j.length&&w.every((U,M)=>U===j[M]))){const U=Le(He.id,{coverItemIds:w});ai(U?.updatedList,{operation:"update",previousList:U?.previousList})}Ge(null)},ih=async(g,w)=>{const j=Le(g,{isPublic:!!w});return Qt?await ai(j?.updatedList,{operation:"update",previousList:j?.previousList}):{ok:!Ie,localOnly:!Ie}},Nv=(g,w)=>{const j=fe(g,w);Qt&&j?.lists?.length&&nr({message:"Board order is saved on this browser. Cloud ordering is not synced yet.",status:"idle"})},cc=()=>{xt.status!=="pending"&&(Ws.current="",Dt(null),Zt(""),Gt({message:"",operation:null,status:"idle"}))},jv=g=>{const w=gy({authenticatedUserId:Ie,board:g,isProtected:Cp});if(w.eligibility===Bn.local&&BI(g)){Zt("local"),Gt({message:"",operation:null,status:"idle"}),Dt(g);return}if(w.eligibility!==Bn.cloud||!Qt||!jr||!Kr)return;const j=ct.readPendingBoardTrashOperation?.(w.boardId)||null,T=VD({authenticatedOwnerId:w.ownerId,existingOperation:j,expectedRevision:w.expectedRevision,listId:w.boardId});if(!T){Ze("Cloud board deletion could not be prepared safely. Refresh and try again.");return}Zt("cloud"),Gt({message:T.recovered?"SaveBoard could not confirm the earlier request. Retry uses the same protected request.":"",operation:T,status:T.recovered?"uncertain":"idle"}),Dt(g)},Rv=g=>{if(jt!=="local"||!BI(Xe)){cc();return}C(Xe.id,g),cc()},Lv=async()=>
32{const g=xt.operation,w=String(Xe?.id||""),j=String(g?.ownerId||""),T=`${j}:${w}:${g?.operationId||""}`;if(jt!=="cloud"||!g||!T||Ws.current||Ie!==j||s!==j||!Qt||!jr||!Kr){Ws.current||cc();return}const U=gy({authenticatedUserId:Ie,board:Xe,isProtected:Cp});if(U.eligibility!==Bn.cloud||U.ownerId!==j){cc();return}const M={...g,recovered:void 0,state:"pending",updatedAt:new Date().toISOString()};try{ct.savePendingBoardTrashOperation(M)}catch(Ue){Gt({message:Ue?.message||"Cloud board deletion could not be prepared safely. Nothing was sent.",operation:g,status:"error"});return}const Y=`${T}:${++av.current}`;Ws.current=Y,Gt({message:"Deleting…",operation:M,status:"pending"});const Q=Jt,we=await HD({request:()=>OD({client:ae,expectedRevision:M.expectedRevision,listId:M.listId,operationId:M.operationId})}),Ce=Ws.current===Y;if(Ce&&(Ws.current=""),!Ce||ct.getAccountScope?.()!==j||wa.current!==Q)return;const je=Ue=>{const dt={...M,state:"uncertain",updatedAt:new Date().toISOString()};try{ct.savePendingBoardTrashOperation(dt)}catch{}Gt({message:Ue,operation:dt,status:"uncertain"}),Xp.requestRefresh()};if(we.kind==="timeout"){je("SaveBoard could not confirm whether deletion completed. Keep this board open and retry when you are online.");return}if(we.kind==="failure"){je("SaveBoard could not confirm whether deletion completed. Retry uses the same protected request.");return}const qe=we.result;if(qe?.ok===!0){const Ue=Qy(ov.current),dt=xo.current.filter(Pr=>Ye(Pr?.name).toLowerCase()===Ye(Xe?.name).toLowerCase()),ot=Ue?.boardId===w||Yi.current===Xe?.name&&dt.length===1&&String(dt[0]?.id||"")===w,ut=Pr=>{if(!Pr)return!1;const Lo=String(Pr.listId??Pr.list_id??"");if(Lo)return Lo===w;const sl=[Pr.category,Pr.listName,Pr.targetListName].map(uh=>Ye(uh).toLowerCase()).filter(Boolean);return dt.length===1&&String(dt[0]?.id||"")===w&&sl.includes(Ye(Xe?.name).toLowerCase())},it=!!(ut(ft)||ar?.openingSnapshot?.listId===w),Rt=!!ut(rn),Mr=ut(Ua),sr=c({acknowledgement:qe,pendingOperation:M});if(!sr?.ok){je("The cloud confirmed deletion, but this device could not apply the refreshed board state. SaveBoard is refreshing now.");return}if(ot){const Pr=du({dashboardList:rr,listName:rr});vo(null),ul(Cs),he(Pr.status),Oe(Pr.dashboardViewMode),Fe(Pr.activeList),Yt("")}be?.id===w&&qp(),He?.id===w&&Ge(null),wr===w&&Zd(),it&&(lr(null),Dr(!1),Aa()),Rt&&nn(null),ot&&Ke(null),Mr&&Gn(null),Dt(null),Zt(""),Gt({message:"",operation:null,status:"idle"}),Xp.requestRefresh(),Ze(sr.localPersistenceFailed?"Board deleted. This device could not fully save the refreshed state, so SaveBoard is refreshing it now.":sr.defaultListChanged?"Board deleted. Your default save board was updated on this device.":"Board deleted.");return}const Me=qe?.classification;if(Me===In.transport||Me===In.malformed||Me===In.unknown){je(Me===In.malformed?"SaveBoard received an incomplete confirmation. The board is still shown while cloud state refreshes; retry uses the same request.":"SaveBoard could not confirm whether deletion completed. Retry uses the same protected request.");return}try{ct.clearPendingBoardTrashOperation({listId:w,operationId:M.operationId,ownerId:j})}catch{}Xp.requestRefresh(),Gt({message:Me===In.stale?"This board changed elsewhere. SaveBoard is refreshing it; close and review it before trying again.":Me===In.permission?"Your account no longer has owner permission to delete this board. SaveBoard is refreshing access.":"This board is not in an active state that can be deleted. SaveBoard is refreshing it.",operation:M,status:"blocked"})},Bv=async g=>{const w=$a;if(!w||!bn.canAddItems)return{ok:!1,message:"You can only view this board."};const j=xI(g);if(!j.title)return{ok:!1,message:"Add a title before saving this item."};ea(M=>({...M,isSaving:!0}));const T=await by(w,j);if(ea(M=>({...M,isSaving:!1})),!T.ok||!T.item?.id)return my(T.error)&&await Gi(),{ok:!1,message:T.error||"Could not add this item to the shared board."};ea(M=>({...M,items:[...M.items,T.item]})),dd();const U=uT(g);return Ze(U.length?`Item added to ${w.boardTitle}. Notes and sizing are not kept on shared boards.`:`Item added to ${w.boardTitle}.`),Pa(),{ok:!0}},Tv=async g=>{const w=$a,j=la.items.find(U=>String(U.id)===String(g?.id||""));if(!w||!bn.canEditItems||!j)return{ok:!1,message:"You can only view this board."};ea(U=>({...U,isSaving:!0}));const T=await tM(w,j,xI(g));return ea(U=>({...U,isSaving:!1})),T.ok?(ea(U=>({...U,items:U.items.map(M=>String(M.id)===String(g.id)?T.item:M)})),dd(),Pa(),Dr(!1),Ze("Item updated."),{ok:!0}):(T.conflict&&T.item?(ea(U=>
32({...U,items:U.items.map(M=>String(M.id)===String(T.item.id)?T.item:M)})),hn(!1),Pa(),Dr(!1),Ze("This item changed elsewhere. It has been refreshed.")):my(T.error)&&await Gi(),{ok:!1,message:T.error||"Could not update this item."})},Dv=async g=>{const w=$a,j=la.items.find(U=>String(U.id)===String(g?.id||""));if(!w||!bn.canDeleteItems||!j){G({message:"You can only view this board.",productId:String(g?.id||""),status:"error"});return}G({message:"",productId:String(g.id),status:"pending"});const T=await rM(w,j);if(!T.ok){T.conflict&&T.item&&ea(U=>({...U,items:U.items.map(M=>String(M.id)===String(T.item.id)?T.item:M)})),G({message:T.error||"Could not remove this item.",productId:String(g.id),status:"error"});return}ea(U=>({...U,items:U.items.filter(M=>String(M.id)!==String(g.id))})),dd(),G({message:"",productId:"",status:"idle"}),ic(),pa&&rl(),Ze(`Item moved to ${Wu(w.owner)}'s Trash. Only the owner can restore it.`)},Ov=async(g,w)=>{const j=$a;if(!j||!bn.canReorderItems)return;const T=pT(la.items,g,w);if(!T)return;ea(M=>({...M,items:T}));const U=await nM(j,T.map(M=>M.id));if(!U.ok){Ze(U.error||"Could not save the new order."),await Gi();return}dd()},Mv=(g,w={})=>{if(pr)return Bv(g);const j=Lp(g);if(!j?.createdProduct?.id)return{ok:!1,message:"Choose an active board before saving this item."};const T=j.createdProduct;return Ha(T,{autoFrame:w.imageCropWasManuallyChanged!==!0,reason:Ua?"capture-review-save":"manual-add"}),Pa(),{ok:!0}},ch=(g,w={})=>{if(cd(g)||pr&&la.items.some(Q=>String(Q.id)===String(g?.id||"")))return Tv(g);const j=Un.current,T=D.find(Q=>String(Q?.id||"")===String(g?.id||""))||null,U=j?.requiresExpectedRevision?gF({latestRecord:T,session:j,submit:({expectedRevision:Q,openingSnapshot:we})=>oi(g,{expectedRevision:Q,preserveConflictUntilAcknowledged:Zm(j),previousProductForPatch:we})}):{ok:!0,result:oi(g),submitted:!0};if(!U.ok){const Q=T?fA(mA(j,!0),T):j;return Q&&nc(Q),br(!0),Ze(U.message||Fu),U}const M=U.result?.updatedProduct||g,Y=U.result?.list||Jd(M)||ma;return Ha(M,{autoFrame:w.imageWasReplaced===!0&&w.imageCropWasManuallyChanged!==!0,reason:"product-update"}),pa?(Pa(),Dr(!1),Y?.id&&String(Y.id)!==$r?.boardId&&(Md.current=!0,ul(cg(Y.id,M.id)))):Pa(),U},Ql=(g,w,j=new Date().toISOString())=>{const T=String(g?.id||"");if(!T)return g;const U=D.find(Q=>Q.id===T)||g,M=jI(U.priceTracking,{status:w,checkedAt:j}),Y={...U,priceTracking:M};return oi(Y),Y},Uv=async g=>{const w=String(g?.id||"");if(!w)return;const j=aa(String(g?.url||""));if(!j){Ir({productId:w,status:"unavailable",message:"Add a product link to check price."});return}Jo.current?.abort();const T=So.current+1;So.current=T;const U=new AbortController;Jo.current=U;const M=window.setTimeout(()=>U.abort(),gW);Ir({productId:w,status:"checking",message:"Checking..."});try{const Y=await fetch("/api/check-price",{method:"POST",headers:{"Content-Type":"application/json",...e.session?.access_token?{Authorization:`Bearer ${e.session.access_token}`}:{}},body:JSON.stringify({url:j}),signal:U.signal}),Q=await Y.json().catch(()=>({}));if(So.current!==T)return;if(Q?.ok===!1){if(Q.reason==="rate-limited"){Ir({productId:w,status:"failed",message:eS(Q.reason,{isPremium:Fl.plan==="premium",signedIn:!!e.user})});return}Ql(g,eD(Q.reason),Q.checkedAt||new Date().toISOString()),Ir({productId:w,status:"failed",message:eS(Q.reason,{isPremium:Fl.plan==="premium",signedIn:!!e.user})});return}if(!Y.ok)throw new Error(Q.reason||Q.error||"price-check-failed");const we=D.find(Me=>Me.id===w)||g,Ce=B3(Q,we),je=Q.checkedAt||new Date().toISOString();if(!Ce){Ql(we,"low-confidence",je),Ir({productId:w,status:"failed",message:eS("low-confidence",{isPremium:Fl.plan==="premium",signedIn:!!e.user})});return}Ql(we,"success",je);const qe={price:Ce.price,currency:Ce.parsedPrice.currency};if(wg(we,qe)){Ir({productId:w,status:"unchanged",message:"Price unchanged"});return}Ir({productId:w,status:"confirming",message:`Update price from ${T3(we)} to ${Ce.price}?`,fetchedPrice:Ce.price,fetchedCurrency:Ce.parsedPrice.currency,checkedAt:je})}catch(Y){if(So.current!==T)return;Ql(g,Y?.name==="AbortError"?"timeout":"failed"),Ir({productId:w,status:"failed",message:"Could not check this product right now."})}
32finally{window.clearTimeout(M),So.current===T&&(Jo.current=null)}},Fv=g=>{const w=String(g?.id||"");if(!w||qt.productId!==w||!ts(qt.fetchedPrice))return;const j=D.find(je=>je.id===w)||g,T={price:qt.fetchedPrice,currency:qt.fetchedCurrency};if(wg(j,T)){Ql(j,"success",qt.checkedAt||new Date().toISOString()),Ir({productId:w,status:"unchanged",message:"Price unchanged"});return}const U=qt.checkedAt||new Date().toISOString(),M=Nl(qt.fetchedPrice,qt.fetchedCurrency||j.currency||de.defaultCurrency),Y={...j,price:qt.fetchedPrice,currency:M,priceHistorySource:"manual-check",priceTracking:jI(j.priceTracking,{status:"success",checkedAt:U})},Q=WT(Y,j,{price:qt.fetchedPrice,currency:M},{checkedAt:U,createId:()=>Sd("price-alert-event"),source:"manual-check"}),we=GT(Y,Q);oi(we);const Ce=VT(Q);Ir({productId:w,status:"updated",message:Ce?`Price updated. ${Ce}`:"Price updated"})},$v=g=>{const w=String(g?.id||"");!w||qt.productId!==w||Ir({productId:w,status:"idle",message:"Kept current price"})},Yp=(g,w)=>{oi(Xy(g,w))},R=(g,w)=>{const j=Array.isArray(g)?[...new Set(g)]:[g],T=_.find(Y=>Y.id===w),U=j.length>1;let M=0;j.forEach(Y=>{Bp(Y,w,{sync:!U})&&(M+=1)}),!(!T||!M)&&(Ze(U&&Qt?`Moved ${M} products locally. Cloud bulk move is not synced yet.`:M===1?`Moved to ${T.name}.`:`Moved ${M} products to ${T.name}.`),j.some(Y=>qn.has(Y))&&Ks())},_e=g=>{if(!ga.length)return;const w=_.find(T=>T.id===g),j=ga.length>1;ga.forEach(T=>Bp(T.id,g,{sync:!j})),w&&Ze(j&&Qt?`Moved ${ga.length} products locally. Cloud bulk move is not synced yet.`:`Moved ${ga.length} product${ga.length===1?"":"s"} to ${w.name}.`),Ks()},bt=async()=>await Fd.current.run(async()=>{if(!ga.length)return null;bo(!0);const w=Kc?Lr.minimal:Lr.normal,j=!!(Ie&&z===B.personal),T=Jt;try{const U=await EO({products:ga,mode:w,resolveProduct:Y=>ua.current.find(Q=>String(Q?.id||"")===String(Y?.id||""))||Y,hasUsableImage:Y=>!!kn(Y),persistChange:async Y=>{const Q=Y.product,we=Jd(Q);if(!we?.id)return{ok:!1,reason:"missing-board"};if(!j){const dt=ct.readProducts(z),ot=dt.filter(ut=>String(ut?.id||"")===String(Q.id||""));if(ot.length!==1||!hC(ot[0],Q))return{ok:!1,reason:"local-record-changed"};try{const ut=ct.updateProduct(dt,Y.candidate);ct.saveProducts(ut,z,{trackPriceHistory:!1});const Rt=ct.readProducts(z).filter(sr=>String(sr?.id||"")===String(Q.id||"")),Mr=Rt[0]||null;return Rt.length!==1||!PO({candidate:Y.candidate,contextKey:Y.contextKey,durableProduct:Mr})?(ct.saveProducts(dt,z,{trackPriceHistory:!1}),{ok:!1,reason:"local-reread-mismatch"}):(l(Mr),{ok:!0,product:Mr})}catch{return{ok:!1,reason:"local-persistence-failed"}}}if(!vr||wa.current!==T||!IO({product:Q,userId:Ie}))return{ok:!1,reason:"cloud-identity-needs-review"};const Ce=fa("product",Q.id);if(Cn.current.has(Ce))return{ok:!1,reason:"existing-cloud-conflict"};const je=Br(Q.syncRevision??Q.revision),qe=mP({currentList:we,currentProduct:Y.candidate,previousList:we,previousProduct:Q,user:e.user});if(Object.keys(qe).length!==1||!Object.hasOwn(qe,"image_framing_overrides"))return{ok:!1,reason:"unexpected-cloud-patch"};const Me=await _O(()=>jo(()=>fP({expectedRevision:je,patch:qe,product:Y.candidate,user:e.user})),bW);if(Me?.stop)return Me;if(wa.current!==T||!Me?.ok||!Me.row)return{ok:!1,reason:Me?.conflict?"revision-conflict":Me?.reason||"cloud-write-failed"};const Ue=om({attemptedPatch:qe,fallback:Y.candidate,listName:we.name,row:Me.row});return AO({acknowledgedProduct:Ue,candidate:Y.candidate,contextKey:Y.contextKey,expectedRevision:je,userId:Ie})?(i(Q.id,Ue),Fn("product",Me.row),{ok:!0,product:Ue}):{ok:!1,reason:"malformed-cloud-acknowledgement"}}}),M=new Set(U.needsReview.map(Y=>String(Y.product?.id||"")).filter(Boolean));return M.size?_n(M):Ks(),Ze(NO(U)),U}finally{bo(!1)}}),ir=()=>{if(!ga.length)return;const g=ga.length>1;ga.forEach(w=>oi(Xy(w,"purchased"),{sync:!g})),g&&Qt&&Ze("Purchased status was updated locally. Cloud bulk update is not synced yet."),Ks()},Ln=()=>{if(!ga.length)return;const g=ga.length>1;ga.forEach(w=>oi(Xy(w,"archived"),{sync:!g})),g&&Qt&&Ze("Items were archived locally. Cloud bulk update is not synced yet."),Ks()},ka=()=>
32{if(Ie&&z===B.personal){Ze("Bulk Trash is not available yet. Move items one at a time.");return}ga.length&&an(!0)},lc=()=>{if(Ie&&z===B.personal){an(!1),Ze("Bulk Trash is not available yet. Move items one at a time.");return}ga.forEach(g=>Tp(g.id)),an(!1),Ks()},Kp=async g=>{if(rn&&cd(rn)){await Dv(rn);return}const w=ua.current.find(U=>String(U?.id||"")===String(g||""));if(!!!(Ie&&z===B.personal)){if(e.loading){G({message:"Trash is unavailable while account access is loading.",productId:String(g||""),status:"error"});return}Tp(g),ic(),pa&&rl();return}if(!w||!Qt||!jr||!Kr){const U="Trash is unavailable until account sync is ready.";G({message:U,productId:String(g||""),status:"error"}),Ze(U);return}const T=await Gf(w);!T.ok||!T.removed||(ic(),pa&&rl())},zv=g=>{Yp(g,"archived"),ic(),pa&&rl()},al=g=>{const w=A(g);if(!w?.id){Ft(gd(w?.slug||g));return}ce(null),Mn(w.id),Cr(""),rs(""),It({dataUrl:"",error:"",status:"idle",url:""})},Zd=()=>{Mn(""),Cr(""),ca(!1),rs(""),It({dataUrl:"",error:"",status:"idle",url:""})},lh=async g=>{if(!g?.id)return{error:"Could not make this board public. Please try again.",url:""};if(!xs){if(g.isPublic!==!0){const Y=Le(g.id,{isPublic:!0});ai(Y?.updatedList,{operation:"update",previousList:Y?.previousList})}return{error:"",localOnly:!0,url:Qa(gd(g.slug||g.name))}}if(!Ro)return{error:"Choose a username before sharing this board publicly.",url:""};if(!Kd)return{error:"Make your profile public before sharing public boards.",url:""};if(!e.syncPublicBoardMetadata)return{error:"Could not make this board public. Please try again.",url:""};const w=g.isPublic===!0,j=qu(g,D);if(!w){const Y=await ih(g.id,!0);if(!Y?.ok||Y.localOnly)return{error:"Could not confirm public visibility in cloud. Review the sync status and try again.",url:""}}const T=await e.syncPublicBoardMetadata({description:g.publicDescription||"",itemCount:j.length,localBoardId:g.id,sortOrder:g.sortOrder,title:g.name,visibility:"public"}),U=String(T.board?.id||"").trim();if(T.error||!U)return{error:"Could not make this board public. Please try again.",url:""};if(w||Si(Da.boardPublished),T.board.visibility!=="public")return{error:"This board is restricted from public publication.",url:""};const M=[];gt(Y=>({...Y,[g.id]:U}));try{ho(g.id,Y=>({...Y,error:"",isLoaded:!1,isLoading:!1,items:M,publicBoardId:U,savingItemId:""}))}catch{}return w||(await Kk({boardId:U,dedupeKey:DL(_l.BOARD_MADE_PUBLIC,U),eventType:_l.BOARD_MADE_PUBLIC,metadata:TL({...g,productCount:j.length})})).error,{error:"",publicBoardId:U,url:Qa(jc(Ro,U))}},Dx=async g=>{if(!g?.id)return{error:"Could not create a private board link.",url:""};if(!xs)return{error:"Sign in to create a private board link.",url:""};if(!Ro)return{error:"Choose a username before sharing this board.",url:""};if(!e.syncPublicBoardMetadata||!e.createPrivateBoardShareLink)return{error:"Could not create a private board link.",url:""};const w=qu(g,D),j=await e.syncPublicBoardMetadata({description:g.publicDescription||"",itemCount:w.length,localBoardId:g.id,sortOrder:g.sortOrder,title:g.name,visibility:"private"}),T=String(j.board?.id||"").trim();if(j.error||!T)return{error:j.error||"Could not create a private board link.",url:""};const U=await e.createPrivateBoardShareLink(T);return U.error||!U.shareToken?{error:U.error||"Could not create a private board link.",url:""}:(ce(U),gt(M=>({...M,[g.id]:T})),{error:"",publicBoardId:T,url:Qa(bq(Ro,T,U.shareToken))})},zL=async()=>{if(!(!$s?.publicBoardId||po)){ca(!0);try{const g=await e.revokePrivateBoardShareLink($s.publicBoardId);if(g.error){Cr(g.error);return}ce(null),rs(""),It({dataUrl:"",error:"",status:"idle",url:""}),Cr("Private link revoked. You can create a new link.")}finally{ca(!1)}}},VL=async()=>{if(!Ar){Cr("Could not create a board link.");return}ca(!0),rs("");try{const g=Ar.isPublic===!0?await lh(Ar):await Dx(Ar);if(g.error||!g.url){Cr(g.error||"Could not create a board link.");return}rs(g.url),await Tu(g.url),Cr(Ar.isPublic===!0?"Link copied.":"Private link copied.")}catch{Cr("Could not copy automatically. Select and copy the link manually.")}finally{ca(!1)}},HL=async()=>
32{if(!Ar){Cr("Could not create a board link.");return}ca(!0),Cr(""),It({dataUrl:"",error:"",status:"loading",url:""});try{const g=Ar.isPublic===!0?await lh(Ar):await Dx(Ar);if(g.error||!g.url){It({dataUrl:"",error:g.error||"Could not generate QR code.",status:"error",url:""});return}rs(g.url);const w=await B0.toDataURL(g.url,{color:{dark:"#102f4e",light:"#ffffff"},errorCorrectionLevel:"M",margin:2,scale:8});It({dataUrl:w,error:"",status:"ready",url:g.url})}catch{It({dataUrl:"",error:"Could not generate QR code.",status:"error",url:""})}finally{ca(!1)}},WL=async()=>{if(!ii){Cr("QR code is not ready yet.");return}if(!navigator.clipboard?.write||typeof window.ClipboardItem!="function"){Cr("Copying QR images is not supported in this browser.");return}try{const w=await(await fetch(ii)).blob();await navigator.clipboard.write([new window.ClipboardItem({[w.type||"image/png"]:w})]),Cr("QR code copied.")}catch{Cr("Could not copy QR code.")}},GL=async()=>{if(!Ar||!ii){Cr("QR code is not ready yet.");return}try{const w=await(await fetch(ii)).blob();Ow(w,E3(Ar)),Cr("QR code downloaded.")}catch{Cr("Could not download QR code.")}},qL=async()=>{if(Ar?.id){ca(!0);try{const g=await lh(Ar);if(g.error||!g.url){Cr(g.error||"Could not make this board public. Please try again.");return}try{await Tu(g.url),Cr(g.localOnly?"Board is public on this browser and local link copied.":"Board is public and link copied.")}catch{Cr("Board is public. Copy the link manually below.")}}catch{Cr("Could not make this board public. Please try again.")}finally{ca(!1)}}},YL=async()=>{if(Ar){ca(!0);try{const g=await lh(Ar);if(g.error||!g.url){Cr(g.error||"Could not make this board public. Please try again.");return}const w=xs?new URL(g.url).pathname:gd(Ar.slug||Ar.name);Zd(),Ft(w)}catch{Cr("Could not open the public board.")}finally{ca(!1)}}},Vv=()=>{Ft("/guide")},li=()=>{const g=du({dashboardList:rr,listName:rr});vo(null),Wh(),Ft(Cs),he(g.status),Oe(g.dashboardViewMode),Fe(g.activeList),Yt("")},Hv=g=>{if(g===rr)return e5({lists:_,products:D});const w=_.find(U=>U.name===g);if(!w)return[];const j=D.filter(U=>hs(U,w)&&va(U.status)==="active"),T=tL(ra[ne]??ra[Ja],op());return dg(j,er).slice(0,T).map(U=>kn(U)).filter(Boolean).map(U=>Il(U,{width:Os.card}))},Wv=({path:g=""}={})=>{if(g===ta||g.startsWith(`${ta}/`))return Wl;if(g==="/account")return _.slice(0,gf(240,eL,op())).flatMap(T=>QR(T,qu(T,D)));const w=Qy(g);if(w){const T=_.find(M=>String(M?.id||"")===w.boardId)||null,U=T&&D.find(M=>String(M?.id||"")===w.itemId&&hs(M,T))||null;return rL(U)}const j=Lw(g);return j&&Vt.username===j&&!Vt.isLoading?W_({boardItems:Vt.boardItems,boards:Vt.boards,publicBoardId:n_(g)}):[]},Ox=d.useRef(Wv);Ox.current=Wv;const Mx=d.useRef(null);Mx.current=(g,w)=>g.path===ta||g.path.startsWith(`${ta}/`)?is.prepareNavigation(g.path,w):null,d.useEffect(()=>(d_(g=>Ox.current(g)),Tw=(g,w)=>Mx.current(g,w),Dw=()=>yp(""),()=>{++Lu,d_(null),Tw=null,Dw=null}),[]),d.useLayoutEffect(()=>{++Lu,yp(""),window.dispatchEvent(new Event("saveboard:cancel-pending-route")),$l&&ul(`${At}${Yn.search||""}`)},[Ie]),d.useEffect(()=>{F4()},[_,Ie]);const Gv=At===Cs&&!pa?No?rr:r:"";d.useEffect(()=>{if(!Gv||typeof window>"u")return;const g=()=>Jh(Hv(Gv));typeof window.requestIdleCallback=="function"?window.requestIdleCallback(g,{timeout:1500}):window.setTimeout(g,300)},[Gv]);const Ux=g=>Jh(Hv(g)),Fx=g=>g==="home"?Ux(rr):Jh(Wv({path:g==="discover"?ta:g==="account"?"/account":""})),$x=(g,w)=>{const j=++Lu;window.dispatchEvent(new Event("saveboard:cancel-pending-route")),uE(Hv(g),()=>{yp(""),w()},{isCurrent:()=>j===Lu})||yp(g)},zx=g=>{const w=du({dashboardList:rr,listName:g});vo(null),Wh(),Ft(Cs),w.activeList===rr&&Yt(""),he(w.status),Oe(w.dashboardViewMode),Fe(w.activeList)},Zl=g=>{N_(_.find(j=>j.name===g)?.id||g);const w=du({dashboardList:rr,listName:g});$x(w.activeList,()=>zx(g))},eu=g=>{if(g==="trash"&&!Ea)return;const w=Iz({dashboardList:rr,status:g});vo(null),Wh(),Ft(Cs),he(w.status),Oe(w.dashboardViewMode),Fe(w.activeList),g==="trash"&&(Fa(!1),Ks())},KL=d.useCallback((g,w={})=>Si(),[Ie]),Vx=g=>{N_(mb(g)),Od.current=g,vo(g),ea({accessLost:!1,error:"",isLoading:!0,isSaving:!1,items:[],role:lo(g?.role)}),Fa(!1),Ks(),Wh(),Ft(Cs),Oe("shared"),Fe(rr),he("active"),Yt(""),Gi()},qv=async()=>
32{if(ha.length===0){Sr("Nothing to copy.");return}try{await Tu(M3(el,ha)),Sr("Wishlist text copied.")}catch{Sr("Could not copy.")}},Yv=async()=>{const g=U3(ha);if(!g){Sr("No links to copy.");return}try{await Tu(g),Sr("Product links copied.")}catch{Sr("Could not copy.")}},Hx=g=>{const{blockedCount:w,openedCount:j}=F3(g);if(w>0){Sr("Some tabs may have been blocked by your browser. Allow pop-ups for Saveboard and try again.");return}Sr(`Opened ${j} product link${j===1?"":"s"}.`)},XL=()=>{const g=WR(ha);if(!g.length){Sr("No product links to open.");return}const w={links:g.slice(0,DW),totalCount:g.length};if(g.length>=TW){Yr(w);return}Hx(w.links)},JL=()=>{or&&(Hx(or.links),Yr(null))},QL=()=>{Yr(null)},Kv=()=>{if(ha.length===0){Sr("Nothing to export.");return}Ow(z3(ha),_3(r,vn),"text/csv"),Sr("CSV exported.")},dh=()=>{const g=I();A3(g,P3()),_t(""),tr("Personal backup exported.")},ZL=d.useCallback(async()=>{const g=e.user?.id?{id:e.user.id}:e.user,w=await ZS({user:g}),j=hi(e.user?.id)||{},T=ad(e.user?.id,{...j,checkedAt:w.checkedAt,hasCloudData:w.hasCloudData,lastBackedUpAt:w.lastBackedUpAt||j.lastBackedUpAt,latestUpdatedAt:w.latestUpdatedAt||w.lastBackedUpAt||j.latestUpdatedAt,listCount:w.listCount,productCount:w.productCount});return xe(T),w},[e.user?.id]),e0=async()=>{const w=wu({lists:_,products:D});if(z!==B.personal&&w)return{blocked:!0,cancelled:!0,message:pG};const j=qh();if(dG(j)){let M=null;try{const Y=e.user?.id?{id:e.user.id}:e.user;M=await ZS({user:Y});const Q=hi(e.user?.id)||{},we=ad(e.user?.id,{...Q,checkedAt:M.checkedAt,hasCloudData:M.hasCloudData,lastBackedUpAt:M.lastBackedUpAt||Q.lastBackedUpAt,latestUpdatedAt:M.latestUpdatedAt||M.lastBackedUpAt||Q.latestUpdatedAt,listCount:M.listCount,productCount:M.productCount});xe(we)}catch{const Y="Cloud backup stopped because Saveboard could not confirm whether cloud boards already exist.";return Pe(Ba({error:Y,message:Y,status:"error"})),{blocked:!0,cancelled:!0,message:Y}}if(M?.hasCloudData){const Y="Cloud already has boards for this account. Restore cloud boards to this browser before backing up from an empty browser.";return Pe(Ba({checkedAt:M.checkedAt,error:Y,listCount:M.listCount,message:Y,productCount:M.productCount,status:"blocked"})),{blocked:!0,cancelled:!0,existingSummary:M,message:Y}}}const T=I();if(!wu(T)&&w)return{blocked:!0,cancelled:!0,message:uG};const U=await l2({backup:T,user:e.user,confirmBackup:M=>{const Y=M.hasCloudData?`Replace cloud backup?
33
34This will replace the backup saved to your account with this browser's current Saveboard data, including price tracking settings for tracked products. Your local data stays on this browser.`:`Back up this browser's Saveboard data?
35
36This uploads your local boards and products to your account, including price tracking settings for tracked products. Your local data stays on this browser.`;return window.confirm(Y)}});return U?.state&&xe(U.state),U},t0=async()=>{if(!Ie||!e.isConfigured||z!==B.personal)return{blocked:!0,message:"Cloud setup is only available for signed-in Personal mode."};const g=I(),w=Ie,j=Jt,T=()=>!!(j&&wa.current===j&&ct.getAccountScope?.()===w);if(!wu(g)){const M=new Date().toISOString();return Pe(Ba({checkedAt:M,message:"No local boards or items need uploading.",status:"empty"})),{blocked:!0,message:"No local boards or items need uploading."}}Pe(Ba({message:"Checking cloud before upload...",status:"checking"}));let U=!1;try{const M=await ew({user:e.user});if(!T())return{cancelled:!0,reason:"account-generation-mismatch"};const Y=new Date().toISOString(),Q=hi(Ie)||{},we=ad(Ie,{...Q,checkedAt:Y,hasCloudData:M.hasCloudData,latestUpdatedAt:M.cloudBackedUpAt||Q.latestUpdatedAt,listCount:M.listCount,productCount:M.productCount});if(xe(we),M.hasCloudData){const qe="Cloud already has boards for this account. Nothing was uploaded so you can review both sides before combining them.";return Pe(Ba({checkedAt:Y,listCount:M.listCount,message:qe,productCount:M.productCount,status:"cloud-and-local"})),{blocked:!0,message:qe}}Pe(Ba({message:"Uploading this browser's boards to cloud...",status:"uploading-local"}));const Ce=await c2({backup:g,prepareLocalUpload:({uploadedLists:qe,uploadedProducts:Me})=>{const Ue=Ae({accountScopeId:w,authenticatedUserId:w,currentLiveSnapshot:{lists:xo.current,products:ua.current},generation:j,isGenerationCurrent:T,uploadedLists:qe,uploadedLocalBackup:g,uploadedProducts:Me});return Ue?.prepared&&(U=!0,xo.current=Ue.snapshot.lists||[],ua.current=Ue.snapshot.products||[]),Ue},user:e.user});if(Ce?.cancelled&&!U){const qe="Local boards changed while cloud upload was being prepared. Nothing was uploaded; review the changes and try again.";return Pe(Ba({checkedAt:new Date().toISOString(),foregroundReady:!0,message:qe,sessionKey:j,settled:!0,status:"local-upload-ready"})),{...Ce,blocked:!0,message:qe}}if(!T())return{cancelled:!0,reason:"account-generation-mismatch"};const je=pe({accountScopeId:w,authenticatedUserId:w,backup:Ce.authoritativeBackup,currentLiveSnapshot:{lists:xo.current,products:ua.current},generation:j,isGenerationCurrent:T,privateOwnerScoped:Ce.privateOwnerScoped===!0,uploadedLists:Ce.uploadedLists,uploadedLocalBackup:Ce.preparation?.snapshot,uploadedProducts:Ce.uploadedProducts});if(je?.cancelled||!je?.settled||!T())throw new Error("Authoritative cloud provenance could not be persisted locally.");return Ce?.state&&xe(Ce.state),Pe(Ba({checkedAt:Ce.uploadedAt,foregroundReady:!0,listCount:Ce.listCount,message:`Uploaded ${Ce.listCount}
36 boards and ${Ce.productCount} products to cloud. Other devices can now load them.`,productCount:Ce.productCount,sessionKey:j,settled:!0,status:"uploaded-local"})),Ce}catch{if(!T())return{cancelled:!0,reason:"account-generation-mismatch"};const M=U?"Cloud setup could not be confirmed. Your boards and items were kept intact, but some records may already be in cloud and are marked for review. Refresh cloud status before retrying.":"Cloud setup could not be started. Your boards and items were kept intact.";throw Pe(Ba({checkedAt:new Date().toISOString(),error:U?"":M,foregroundReady:U,message:M,sessionKey:U?j:"",settled:U,status:U?"cloud-and-local":"error"})),new Error(M)}},r0=async()=>{const g=await s2({user:e.user}),w=I(),j=await AA({backup:w,user:e.user}),T=me(g.backup,"replace"),U=T?.viewState||ct.readViewState(B.personal),M=new Date().toISOString(),Y=j?.id?" A safety backup of the previous browser data was saved to your account.":T?.safetySnapshotSaved?" A local safety snapshot was kept before restore.":"";he(fu(U.selectedStatusFilter)),x(bc(U.selectedSort)),O(U.boardSortModes||{}),X(U.allItemsSortMode||""),Yt(""),_t(""),tr(`Cloud backup restored to this browser.${Y}`),Ze(`Cloud backup restored to this browser.${Y}`);const Q=hi(e.user?.id)||{},we=ad(e.user?.id,{...Q,checkedAt:M,hasCloudData:!0,lastBackedUpAt:g.cloudBackedUpAt||Q.lastBackedUpAt,lastRestoredAt:M,latestUpdatedAt:g.cloudBackedUpAt||Q.latestUpdatedAt,listCount:g.listCount,productCount:g.productCount});return xe(we),li(),{...g,restoredAt:M,safetySnapshotId:j?.id||"",safetySnapshotSaved:!!(j?.id||T?.safetySnapshotSaved)}},n0=async()=>!Rr.trueSyncDryRunEnabled||!Ie||!e.isConfigured||z!==B.personal?{blocked:!0,message:"Sync dry-run is only available for signed-in Personal mode."}:UA({localLists:_,localProducts:D,user:e.user}),a0=async()=>!Rr.trueSyncPullMergePreviewEnabled||!Ie||!e.isConfigured||z!==B.personal?{blocked:!0,message:"Sync merge preview is only available for signed-in Personal mode."}:Bh({localLists:_,localProducts:D,user:e.user}),s0=async()=>{if(!Rr.trueSyncEmptyPullEnabled||!Ie||!e.isConfigured||z!==B.personal)return{blocked:!0,message:"Sync empty-browser pull is only available for signed-in Personal mode."};const g=qh();if(g_({lists:_,products:D})||g_(g))return{blocked:!0,message:"Cloud pull is blocked because this browser already has Personal mode data."};const w=await iz({user:e.user});if(w?.blocked)return w;const j=F({lists:w.lists,products:w.products});return j?.blocked?j:{...w,boardCount:j.lists?.length||w.boardCount||0,message:j.message||w.message,productCount:j.products?.length||w.productC
36ount||0}},o0=async()=>{if(!Rr.trueSyncPopulatedPullEnabled||!Ie||!e.isConfigured||z!==B.personal)return{blocked:!0,message:"Sync populated pull is only available for signed-in Personal mode."};if((await Bh({localLists:_,localProducts:D,user:e.user}))?.blocked)return{blocked:!0,message:"Cloud pull merge needs review before applying changes."};const w=await Dy({localLists:_,localProducts:D,user:e.user});if(w?.blocked||!w.lists?.length&&!w.products?.length)return w;const j=te({lists:w.lists,products:w.products});return j?.blocked?j:{...w,boardCount:j.boardCount??w.boardCount??0,message:j.message||w.message,productCount:j.productCount??w.productCount??0,safetySnapshotSaved:!!j.safetySnapshotSaved}},i0=async()=>{if(!Rr.trueSyncCloudNewerPullEnabled||!Ie||!e.isConfigured||z!==B.personal)return{blocked:!0,message:"Sync cloud update pull is only available for signed-in Personal mode."};if((await mu(Bh({localLists:_,localProducts:D,user:e.user}),uu,"cloud-newer-preview-timeout"))?.blocked)return{blocked:!0,message:"Cloud update merge needs review before applying changes."};const w=await mu(Oy({localLists:_,localProducts:D,user:e.user}),uu,"cloud-newer-prepare-timeout");if(w?.blocked||!w.lists?.length&&!w.products?.length)return w;const j=Tt({lists:w.lists,products:w.products});return j?.blocked?{...w,...j,blocked:!0,message:j.message||"Cloud update merge needs review before applying changes.",supabaseWritesPerformed:0}:{...w,boardCount:j.boardCount??w.boardCount??0,message:j.message||w.message,productCount:j.productCount??w.productCount??0,safetySnapshotSaved:!!j.safetySnapshotSaved,supabaseWritesPerformed:0}},c0=async({blockedMessage:g="Sync now is only available for signed-in Personal mode.",enabled:w=Rr.trueSyncNowQaEnabled,onStatus:j=Ai}={})=>{if(!w||!Ie||!e.isConfigured||z!==B.personal)return{blocked:!0,message:g};const T=()=>({lists:ct.readLists(B.personal),products:ct.readProducts(B.personal)}),U=(...sr)=>[...new Set(sr.flatMap(Pr=>Pr?.warnings||[]))];j("Checking cloud changes...");const M=T(),Y=await mu(Bh({localLists:M.lists,localProducts:M.products,user:e.user}),uu,"sync-now-preview-timeout");if(Y?.blocked)return{blocked:!0,message:"Sync now needs review before applying changes.",preview:Y,supabaseWritesPerformed:0,warnings:Y.warnings||[]};j("Pulling missing cloud rows...");const Q=T(),we=await mu(Dy({localLists:Q.lists,localProducts:Q.products,user:e.user}),uu,"sync-now-add-only-timeout");if(we?.blocked)return{...we,blocked:!0,message:we.message||"Sync now needs review before applying changes.",preview:Y,supabaseWritesPerformed:0,warnings:U(Y,we)};let Ce={boardCount:0,productCount:0,safetySnapshotSaved:!1};if((we.lists?.length||we.products?.length)&&(Ce=te({lists:we.lists,products:we.products}),Ce?.blocked))return{...we,...Ce,blocked:!0,message:Ce.message||"Sync now needs review before applying changes.",preview:Y,supabaseWritesPerformed:0,warnings:U(Y,we,Ce)};j("Applying newer cloud updates...");const je=T(),qe=await mu(Oy({localLists:je.lists,localProducts:je.products,user:e.user}),uu,"sync-now-cloud-newer-timeout");if(qe?.blocked)return{blocked:!0,message:Ce.boardCount||Ce.productCount?"Sync now pulled missing rows, but newer cloud updates need review.":"Sync now needs review before applying changes.",preview:Y,added:{boards:Ce.boardCount??we.boardCount??0,products:Ce.productCount??we.productCount??0},safetySnapshots:{addOnly:!!Ce.safetySnapshotSaved,cloudNewer:!1},supabaseWritesPerformed:0,updated:{boards:0,products:0},warnings:U(Y,we,qe)};let Me={boardCount:0,productCount:0,safetySnapshotSaved:!1};if((qe.lists?.length||qe.products?.length)&&(Me=Tt({lists:qe.lists,products:qe.products}),Me?.blocked))return{...qe,...Me,blocked:!0,message:Ce.boardCount||Ce.productCount?"Sync now pulled missing rows, but newer cloud updates need review.":"Sync now needs review before applying changes.",preview:Y,added:{boards:Ce.boardCount??we.boardCount??0,products:Ce.productCount??we.productCount??0},safetySnapshots:{addOnly:!!Ce.safetySnapshotSaved,cloudNewer:!1},supabaseWritesPerformed:0,updated:{boards:0,products:0},warnings:U(Y,we,qe,Me)};j("Checking final sync state...");const Ue=T(),dt=await mu(UA({localLists:Ue.lists,localProducts:Ue.products,user:e.user}),uu,"sync-now-final-dry-run-timeout"),ot=Ce.boardCount??we.boardCount??0,ut=Ce.productC
36ount??we.productCount??0,it=Me.boardCount??qe.boardCount??0,Rt=Me.productCount??qe.productCount??0;return{added:{boards:ot,products:ut},blocked:!1,finalDryRun:dt,message:ot||ut||it||Rt?`Sync now complete. Added ${ot} boards / ${ut} products. Updated ${it} boards / ${Rt} products.`:"Sync now complete. No new cloud changes to apply.",preview:Y,safetySnapshots:{addOnly:!!Ce.safetySnapshotSaved,cloudNewer:!!Me.safetySnapshotSaved},supabaseWritesPerformed:0,updated:{boards:it,products:Rt},warnings:U(Y,we,qe,dt)}},l0=d.useCallback(async({signal:g,sessionKey:w}={})=>{if(hl(g),!Qt||!e.user?.id||!Jt||w!==Jt||!jr||!Kr||z!==B.personal)return{cancelled:!0,reason:"session-or-account-store-not-ready",signedOut:!e.user?.id||!Jt};if(zc.current===Jt&&await fw(qi.current,{signal:g}),hl(g),w!==Jt||!jr)throw new tx;const j=(Q,we,Ce)=>!we?.id||!Ce?Q:Q.map(je=>je.id===we.id?{...je,syncConflictPatch:je.syncConflictPatch||{},syncPendingCloudWrite:!0}:je),T=()=>{const Q=Un.current;return{lists:j(ct.readLists(B.personal),be,Ve),products:j(ct.readProducts(B.personal),Q?.openingSnapshot,Q?.dirty)}},U=Q=>{const we=Tt(Q);if(we?.blocked)return we;const Ce=z$({editorRecord:be,hasUnsavedChanges:Ve,refreshedRecords:we?.lists||[]}),je=Un.current,qe=je?.productId&&(we?.products||[]).find(Ue=>String(Ue?.id||"")===je.productId)||null,Me=qe?Hd(qe):je;return Ce.baseChanged&&(Ce.requiresReview&&Ve?tt(!0):(Te(Ce.record),tt(!1))),Ce.baseChanged&&Ce.requiresReview&&Ve&&!Me?.needsReview&&Ze("This board changed on another device. Review your open edit before saving."),we};let M=null;const Y=await lV({applyAddOnlyPull:te,applyCloudNewerPull:U,prepareAddOnlyPull:Q=>Dy({localLists:Q.lists,localProducts:Q.products,user:e.user}),prepareCloudNewerPull:async Q=>{const we=await Oy({includeDiagnostics:qs,localLists:Q.lists,localProducts:Q.products,user:e.user});return M=we?.diagnostics||null,we},readLocalRows:T,signal:g});if(qs){const Q={aggregateConflicts:Y?.conflicts||{},diagnostics:M||{lists:[],products:[]}};lt(Q),SA(TF(Q),"foreground")}return Y},[jr,Kr,Jt,Tt,te,e.user,be,Ve,z,B.personal,Hd,Qt,qs]),Xp=hV({enabled:!!(Qt&&Jt&&jr&&Kr&&!e.loading&&!["checking","uploading-local"].includes(Qe?.status)),refresh:l0,sessionKey:Jt});d.useEffect(()=>{!Ie||!jr||!Kr||!Qe?.settled||(async()=>(await Np.current?.(),await ql.current?.()))()},[Kr,jr,Qe?.checkedAt,Qe?.settled,Xp?.checkedAt,Ie]),d.useEffect(()=>{if(!Ie||!jr||!Kr||z!==B.personal)return;const g=mk({authenticatedOwnerId:Ie,currentDefaultList:de.defaultList,fallbackDefaultList:Ka,lists:_});g.changed&&We(w=>({...w,defaultList:g.defaultList}))},[Kr,jr,_,z,B.personal,We,de.defaultList,Ie]),d.useEffect(()=>{if(!Ie||!jr||!Kr||z!==B.personal)return;const g=ct.readLists(B.personal),w=g.filter(Ue=>String(Ue?.userId??Ue?.user_id??"").toLowerCase()===Ie.toLowerCase()&&Ue?.syncSuppressed===!0&&!!String(Ue?.cloudDeletedAt||"").trim());if(!w.length)return;const j=new Map(w.map(Ue=>[String(Ue.id||""),Ue]));w.forEach(Ue=>{const dt=String(Ue?.id||""),ot=ct.readPendingBoardTrashOperation?.(dt);if(!(!ot||String(ot.ownerId||"").toLowerCase()!==Ie.toLowerCase()||String(ot.listId||"")!==dt))try{ct.clearPendingBoardTrashOperation({listId:dt,operationId:ot.operationId,ownerId:ot.ownerId})}catch{}});const T=Ue=>{if(!Ue)return!1;const dt=String(Ue.listId??Ue.list_id??"");return dt?j.has(dt):[Ue.category,Ue.listName,Ue.targetListName].map(ut=>Ye(ut).toLowerCase()).filter(Boolean).some(ut=>{const it=g.filter(Rt=>Ye(Rt?.name).toLowerCase()===ut);return it.length===1&&j.has(String(it[0]?.id||""))})},U=Ue=>Ue?T(Ue):!1,M=xt.operation,Y=!!(jt==="cloud"&&M?.listId&&String(M.ownerId||"").toLowerCase()===Ie.toLowerCase()&&j.has(String(M.listId)));if(Y){try{ct.clearPendingBoardTrashOperation({listId:M.listId,operationId:M.operationId,ownerId:M.ownerId})}catch{}Ws.current="",Dt(null),Zt(""),Gt({message:"",operation:null,status:"idle"})}else Xe&&j.has(String(Xe.id||""))&&(Dt(null),Zt(""),Gt({message:"",operation:null,status:"idle"}));const Q=g.filter(Ue=>Ye(Ue?.name)===Ye(Yi.current)),we=!!(Q.length===1&&j.has(String(Q[0]?.id||""))),Ce=!!($r?.boardId&&j.has(String($r.boardId)));if(we||Ce){const Ue=du({dashboardList:rr,listName:rr});ul(Cs),he(Ue.status),Oe(Ue.dashboardViewMode),Fe(Ue.activeList),Yt(""),Ke(null)}const je=!!(be?.id&&j.has(String(be.id)));
36je&&(Ne(null),Te(null),at(!1),tt(!1)),He?.id&&j.has(String(He.id))&&Ge(null),wr&&j.has(String(wr))&&Zd();const qe=!!(T(ft)||ar?.openingSnapshot?.listId&&j.has(String(ar.openingSnapshot.listId)));qe&&(lr(null),Dr(!1),Aa()),T(rn)&&ic();const Me=U(Ua);Me&&Gn(Ue=>Ue&&{...Ue,category:"",listId:"",listName:"",targetListMatched:!1,targetListName:"",targetListSlug:""}),(Y||we||Ce||je||qe||Me)&&Ze(Y?"Board deleted.":Me?"That board was deleted on another device. Choose another board before saving.":"That board was deleted on another device.")},[Kr,jr,r,Ua,Aa,xt.operation,He,Cs,Xe,rn,be,ft,$r?.boardId,jt,_,z,B.personal,ar?.openingSnapshot?.listId,Fe,wr,Ie]);const d0=async({backup:g,snapshot:w}={})=>{const j=et(g),T=I(),U=await AA({backup:T,user:e.user}),M=me(j,"replace"),Y=M?.viewState||ct.readViewState(B.personal),Q=new Date().toISOString(),we=w?.updatedAt||w?.createdAt||j.backedUpAt||j.exportedAt||"",Ce=U?.id?" A safety backup of the previous browser data was saved to your account.":M?.safetySnapshotSaved?" A local safety snapshot was kept before restore.":"";he(fu(Y.selectedStatusFilter)),x(bc(Y.selectedSort)),O(Y.boardSortModes||{}),X(Y.allItemsSortMode||""),Yt(""),_t(""),tr(`Account backup restored to this browser.${Ce}`),Ze(`Account backup restored to this browser.${Ce}`);const je=hi(e.user?.id)||{},qe=ad(e.user?.id,{...je,checkedAt:Q,hasCloudData:!0,lastBackedUpAt:we||je.lastBackedUpAt,lastRestoredAt:Q,latestUpdatedAt:we||je.latestUpdatedAt,listCount:j.lists.length,productCount:j.products.length});return xe(qe),li(),{backup:j,listCount:j.lists.length,productCount:j.products.length,restoredAt:Q,safetySnapshotId:U?.id||"",safetySnapshotSaved:!!(U?.id||M?.safetySnapshotSaved)}},Wx=async g=>{if(g){_t(""),tr("");try{const w=g.name?.toLowerCase()||"",j=g.type?.toLowerCase()||"";if(!(w.endsWith(".json")||j==="application/json"||j==="text/json"))throw new Error(p_);const U=JSON.parse(await g.text());rt(et(U))}catch{rt(null),_t(p_)}}},Gx=()=>{rt(null)},qx=g=>{if(Kt)try{const w=me(Kt,g),j=w?.safetySnapshotSaved?" A local safety snapshot was kept before import.":" Your backup file remains unchanged if you need to restore again.",T=w?.viewState||ct.readViewState(B.personal);he(fu(T.selectedStatusFilter)),x(bc(T.selectedSort)),O(T.boardSortModes||{}),X(T.allItemsSortMode||""),Yt(""),_t(""),tr(`${g==="merge"?"Personal backup merged.":"Personal backup restored."}${j}`),rt(null)}catch(w){_t(w.message||"That backup could not be imported."),rt(null)}},Yx=({quiet:g=!1}={})=>{try{const w=De();return he("active"),x("manual"),O({}),X(""),Yt(""),_t(""),tr(g?"":"Personal data reset."),{ok:!0,...w}}catch(w){return _t(w.message||"Personal data could not be reset."),tr(""),{error:w.message||"Personal data could not be reset.",ok:!1}}},u0=d.useMemo(()=>{const g=[rr,...Z].map(w=>({id:`list-${w}`,label:`Switch to ${w}`,detail:"Board",keywords:`go ${w}`,action:()=>Zl(w)}));return[{id:"add-item",label:"Add new item",detail:"Create a product pod",keywords:"new product",action:()=>Xl(0)},{id:"focus-search",label:"Focus search",detail:"Search items",keywords:"find filter",action:()=>Uc.current?.focus()},{id:"all-items",label:"Open All Items",detail:"All saved items",keywords:"all products saved items",action:()=>eu("active")},{id:"settings",label:"Open settings",detail:"Local preferences",keywords:"preferences options",action:()=>Zn(!0)},...g,{id:"public-preview",label:"Open share preview",detail:r===rr?"Choose a board first":r,disabled:r===rr,disabledReason:"Choose a board first",keywords:"share view public",action:()=>al(r)},{id:"copy-wishlist",label:"Copy wishlist text",detail:el,keywords:"clipboard text",action:qv},{id:"copy-links",label:"Copy product links",detail:el,keywords:"urls clipboard",action:Yv},{id:"export-csv",label:"Export CSV",detail:el,keywords:"download spreadsheet",action:Kv},{id:"export-backup",label:"Export backup",detail:"Personal data",keywords:"download json",action:dh},{id:"import-backup",label:"Import backup",detail:"Personal data",keywords:"upload json",action:()=>vp.current?.click()}]},[r,Yv,qv,dh,Kv,el,B.demo,B.personal,al,Z,Zl,eu,ye]),Kx=fn!==null||Ua,Xv=ar?.productId&&D.find(g=>String(g?.id||"")===ar.productId)||null,p0=ar&&Xv?Tg({latestRecord:Xv,session:ar}):null,Xx=gH({accountScopedStoreIsReady:jr,latestProductEditorRecord:Xv,productEditHasUnsavedChanges:tn,productEditorSession:ar,signedInCloudWriteThroughEnabled:Qt,submissionReason:p0?.reason}),m0=!!ue,f0=!!Ar,h0=Sn(Xl),g0=Sn(nl),b0=Sn(tl),Jx=Sn(g=>tl(g,{startEditing:!0})),v0=Sn(Jl),y0=Sn(g=>{if(vn!=="trash"||!Qt||!jr||!Kr){Ze("Restore is unavailable until account sync is ready.");return}se.status!=="pending"&&Dp(g)}),S0=Sn((g,w)=>{if(cd(g)){Ze("Purchased and archived are the board owner's to set.");return}return Yp(g,w)}),w0=Sn((g,w)=>{if(pr){Ov(g,w);return}return Wf(g,w)}),C0=Sn(R),x0=Sn(ur),I0=Sn(Lt),A0=Sn(gv);wG(),CG({disabled:!!(Wc||Nr),searchInputRef:Uc,searchQuery:Or,onSearchQueryChange:Yt,productModalIsOpen:!!(Kx||m0||f0),settingsIsOpen:ns,shortcutsHelpIsOpen:Hi,commandPaletteIsOpen:Td,deleteModalIsOpen:!!(rn||Xe),importModalIsOpen:!!Kt,onOpenAddProduct:()=>Xl(0),onOpenCommandPalette:()=>zs(!0),onCloseCommandPalette:()=>zs(!1),onCloseProductModal:()=>{Pa(),qp(),Zd()},onCloseSettings:()=>Zn(!1),onOpenShortcutsHelp:()=>as(!0),onCloseShortcutsHelp:()=>as(!1),onCloseDeleteModal:()=>{ic(),cc()},onCloseImportModal:Gx}),cE(!!(Ca||e.loading||ss&&e.profileLoading||!Vp&&Hp||Ao&&is.status==="loading"||Gc||yo&&la.isLoading||tc));const Jv=oj(At),Qv=Jv===xi.gated,Zv=Jv===xi.auth,Qx=Qv&&e.isConfigured&&!e.loading&&!e.user;d.useEffect(()=>{if(!Qx)return;const g=`${At}${Yn.search||""}`;EA(g),ul(x2(g))},[Yn.search,At,Qx]);const ey=ss?ij(Yn.search):"";d.useEffect(()=>{ey&&EA(ey)},[ey]);const Zx=Zv&&!Po&&(os||ss);if(d.useEffect(()=>{if(e.loading||!e.user||!Zx)return;const g=I2({fallback:os?"/app":"",search:Yn.search});g&&ul(g)},[e.loading,e.user?.id,os,Yn.search,Zx]),Qv&&!e.isConfigured)return n.jsx(zm,{actionHref:"/",actionLabel:"Back to Saveboard",copy:"SaveBoard needs its account service to open your boards, and it is not available in this deployment. Nothing has been lost. Please try again later.",eyebrow:"Account",monochromeEnabled:de.monochromeEnabled,theme:xa,title:"Sign-in is unavailable"});if(Qv&&(e.loading||!e.user)||Zv&&e.loading)return n.jsx(eq,{monochromeEnabled:de.monochromeEnabled,theme:xa});if(Zv&&(os||Po||!e.user))return os?n.jsx(aE,{completeAuthCallback:e.completeAuthCallback,monochromeEnabled:de.monochromeEnabled,onToggleTheme:za,theme:xa}):Po?n.jsx(sE,{auth:e,monochromeEnabled:de.monochromeEnabled,onToggleTheme:za,theme:xa}):n.jsx(qq,{auth:e,monochromeEnabled:de.monochromeEnabled,onToggleTheme:za,theme:xa});if(Jv===xi.retired)return n.jsx(zm,{actionHref:"/",actionLabel:"Back to Saveboard",copy:"Boards are now shared from a Saveboard account. Ask for a new link, or sign in to share one of your own.",eyebrow:"Shared board",monochromeEnabled:de.monochromeEnabled,theme:xa,title:"This link is no longer available"});if(Bf)return n.jsxs(n.Fragment,{children:[n.jsx(id,{enabled:de.customCursorEnabled!==!1}),n.jsx(od,{message:K,monochromeEnabled:de.monochromeEnabled,onDismiss:ie}),n.jsx(rq,{monochromeEnabled:de.monochromeEnabled,theme:Eo})]});if(zd)return n.jsxs(n.Fragment,{children:[n.jsx(id,{enabled:de.customCursorEnabled!==!1}),n.jsx(od,{message:K,monochromeEnabled:de.monochromeEnabled,onDismiss:ie}),n.jsx(nq,{monochromeEnabled:de.monochromeEnabled,theme:Eo})]});if(cv){const g=e.user?.email||e.user?.user_metadata?.email||"",w=LL(RL(e.user,g)),j=cp(e.profile);return e.user?n.jsxs(n.Fragment,{children:[n.jsx(id,{enabled:de.customCursorEnabled!==!1}),n.jsx(od,{message:K,monochromeEnabled:de.monochromeEnabled,onDismiss:ie}),n.jsx(tE,{authUser:e.user,isCurrentUserPreview:!0,isLocalProfilePreview:!0,lists:_,lookupError:"",lookupIsLoading:!1,monochromeEnabled:de.monochromeEnabled,onSubmitReport:e.submitContentReport,previewAvatarUrl:j,previewDisplayName:Lx(e.user,g,e.profile),previewUsername:vl(e.profile)||w,products:D,profile:e.profile,publicProfile:null,profileUsername:"",theme:Eo})]}):n.jsxs(n.Fragment,{children:[n.jsx(id,{enabled:de.customCursorEnabled!==!1}),n.jsx(od,{message:K,monochromeEnabled:de.monochromeEnabled,onDismiss:ie}),n.jsx(zm,{actionHref:"/account",actionLabel:"Go to account",copy:"Sign in to preview how y
36our public Saveboard profile will look.",eyebrow:"Profile preview",monochromeEnabled:de.monochromeEnabled,theme:Eo,title:"Preview your profile"})]})}return Nr&&cn?n.jsxs(n.Fragment,{children:[n.jsx(id,{enabled:de.customCursorEnabled!==!1}),n.jsx(od,{message:K,monochromeEnabled:de.monochromeEnabled,onDismiss:ie}),n.jsx(kq,{boardId:cn,isUnlistedShare:Vt.isUnlistedShare,lookupError:Vt.error||Vt.boardsError,lookupIsLoading:Gc,monochromeEnabled:de.monochromeEnabled,authUser:e.user,onSubmitReport:e.submitContentReport,publicBoardItems:Vt.boardItems,publicBoardItemsError:Vt.boardItemsError,publicBoards:Vt.boards,publicProfile:Vt.profile,profileUsername:Nr,theme:Eo})]}):ln?n.jsxs(n.Fragment,{children:[n.jsx(id,{enabled:de.customCursorEnabled!==!1}),n.jsx(od,{message:K,monochromeEnabled:de.monochromeEnabled,onDismiss:ie}),n.jsx(tq,{BoardCover:Bd,featuredBoards:Yc,featuredEnabled:!0,featuredLoading:is.status==="loading"||is.status==="idle",monochromeEnabled:de.monochromeEnabled,onOpenAccount:()=>Ft("/account"),onOpenApp:li,onOpenDiscover:()=>Ft(ta),onOpenGuide:Vv,onOpenProfile:g=>Ft(g?.ownerHref||ta),onOpenPublicBoard:g=>Ft(g?.href||ta),onToggleTheme:za,theme:xa})]}):n.jsxs(n.Fragment,{children:[n.jsx(id,{enabled:de.customCursorEnabled!==!1}),n.jsxs("div",{className:`appShell${de.monochromeEnabled?" monochromeMode":""}`,"data-app-theme":"v2","data-display-quality":cs,"data-theme":Eo,"data-theme-setting":xp,style:_p,children:[n.jsx(od,{message:Vi||K,onDismiss:Vi?()=>Ze(""):ie}),n.jsx(vV,{state:Xp}),n.jsx(IG,{detailIsOpen:pa,activeStatus:vn,allItemsIsActive:!Vp&&Va&&vn==="active"&&!Ca,boardsIsActive:!Vp&&!Va&&!Ca||zl,currentPath:At,discoverIsActive:Ao&&!Ca||$d,profileIsActive:(ss||os||Po)&&!Ca||Ss,priceTrackingAvailable:Rr.priceTrackingOverviewEnabled,signedIn:Ea,title:bv,updatesIsActive:Zo,updatesUnreadCount:hp,onCreateBoard:()=>sn(nl),canAddItems:bn.canAddItems,onOpenAddProduct:()=>sn(()=>Xl(0)),onOpenAllItems:()=>sn(()=>eu("active")),onOpenBoards:()=>sn(()=>Zl(rr)),onOpenDiscover:()=>sn(()=>Ft(ta)),onOpenGuide:()=>sn(Vv),onOpenProfile:()=>sn(()=>Ft("/account")),onOpenSearch:()=>sn(()=>Ft(ig)),onOpenSettings:()=>sn(()=>Zn(!0)),onOpenShortcutsHelp:()=>sn(()=>as(!0)),onOpenStores:()=>sn(()=>Ft(yc)),onOpenUpdates:()=>sn(()=>Ft(Jy)),onPrepareDestination:Fx,onSelectStatus:g=>sn(()=>eu(g))}),n.jsx(xG,{lists:_,activeList:Ji&&!zl?Ji:r,activeStatus:vn,allItemsIsOpen:Va&&vn==="active"&&!Ca,dashboardOverviewIsOpen:No&&!Ca||zl,discoverIsOpen:Ao&&!Ca||$d,guideIsOpen:Io&&!Ca,accountIsOpen:(ss||os||Po)&&!Ca||Ss,priceTrackingIsOpen:Sp&&!Ca,searchRouteIsOpen:ws&&!Ca,storesIsOpen:Qo&&!Ca,updatesIsOpen:Zo&&!Ca,signedIn:Ea,sidebarStyle:_p,updatesUnreadCount:hp,currentPath:At,draggingProduct:Et,activeDropListId:on,onSelectList:g=>sn(()=>Zl(g)),onSelectStatus:g=>sn(()=>eu(g)),onCreateList:()=>sn(nl),onOpenHome:()=>sn(()=>$x(rr,()=>{eu("active"),zx(rr)})),onOpenDiscover:()=>sn(()=>Ft(ta)),onOpenSearch:()=>sn(()=>Ft(ig)),onOpenStores:()=>sn(()=>Ft(yc)),onOpenUpdates:()=>sn(()=>Ft(Jy)),onOpenGuide:()=>sn(Vv),onNavigate:g=>sn(()=>Ft(g)),onOpenSettings:()=>sn(()=>Zn(!0)),onOpenShortcutsHelp:()=>sn(()=>as(!0)),onSignOut:e.signOut,onPrepareDestination:Fx,onToggleMinimalMode:uv,onToggleTheme:za,minimalMode:Kc,theme:Eo}),Nr?n.jsx("div",{className:"publicProfileRoute",children:n.jsx(tE,{authUser:e.user,isCurrentUserPreview:Tx,lists:[],lookupError:Vt.error,lookupIsLoading:Gc,monochromeEnabled:de.monochromeEnabled,onSubmitReport:e.submitContentReport,products:[],publicBoards:Vt.boards,publicBoardsError:Vt.boardsError,profile:e.profile,publicProfile:Vt.profile,profileUsername:Nr,theme:Eo})}):pa?n.jsx(hY,{board:ma,capabilities:ma?.isSharedBoard?bn:jl,isEditing:Wr,isSaving:kr,isLoading:tc||!!(Wr&&En&&(String(ft?.id||"")!==$r?.itemId||String(ar?.productId||"")!==$r?.itemId)),onBack:rl,onCancelEdit:ah,onDelete:Jl,onEdit:wv,onRetryCloudSave:Vf(En)||En?.syncPendingWriteRevision&&Object.keys(En.syncConflictPatch||{}).length?()=>si(En):null,onResolveCloudConflict:SI(En||{})?()=>si(En,!0):null,pendingChangeDescriptions:rT(En?.syncConflictPatch||{},_),retryingCloudSave:H===En?.id,product:En,children:Wr?n.jsx(oE,{product:ft,presentation:"page",formId:"item-detail-editor-form",listRecords:_,listOptions:Z,defaultList:ma?.name||v,defaultImageFit:de.defaultImageFit,defaultCurrency:de.defaultCurrency,imagePreviewAspectRatio:Jf,imagePreviewAspectRatios:zp,initialFramingMode:Kc?Lr.minimal:Lr.normal,onBack:rl,onSubmit:ch,onCancel:ah,onCreateBoard:nl,onDelete:Jl,onDirtyChange:$f,onRecoverMissingRevision:Xx?sh:null,onSubmissionStateChange:Gr},pA(ar)):null}):Io?n.jsx(aq,{onBackToDashboard:li}):os?n.jsx(aE,{completeAuthCallback:e.completeAuthCallback}):Po?n.jsx(sE,{auth:e}):Df?n.jsx(KB,{auth:e,renderPreview:g=>n.jsx(z_,{content:g,signedIn:!0,preview:!0})}):wp?n.jsx(Nq,{auth:e}):ss?n.jsx(Gq,{publicItemPublishStateByBoardId:Dc,setPublicItemPublishStateByBoardId:Oc,setPublicItemPublishStateForBoard:ho,accountLocalDataNotice:u,auth:e,backupError:St,backupMessage:dr,cloudBackupState:Ee,cloudHydrationState:Qe,lists:_,locationSearch:Yn.search,localDataSummary:sc,mode:z,onBackToDashboard:li,onClearLocalData:Yx,onCloudBackup:e0,onCloudBootstrapUpload:t0,onCloudRestore:r0,onExportBackup:dh,onImportBackup:()=>vp.current?.click(),onImportLocalBoardsToAccount:y,onKeepLocalBoardsSeparate:N,onRefreshCloudStatus:ZL,onSelectList:Zl,onOpenSharedBoard:Vx,onBoardPublished:()=>Si(Da.boardPublished),onShareBoard:g=>al(g?.name||""),onSnapshotRestore:d0,onSyncCloudNewerPull:i0,onSyncEmptyPull:s0,onSyncDryRun:n0,onSyncNow:c0,onSyncPopulatedPull:o0,onSyncPullMergePreview:a0,onToggleBoardVisibility:ih,onValidateSnapshotBackup:et,products:D,trueSyncBoardPilotState:Ct,trueSyncBoardWriteThroughEnabled:Qt,trueSyncCloudNewerPullEnabled:Rr.trueSyncCloudNewerPullEnabled,trueSyncDryRunEnabled:Rr.trueSyncDryRunEnabled,trueSyncEmptyPullEnabled:Rr.trueSyncEmptyPullEnabled,trueSyncManualBetaEnabled:Rr.trueSyncManualBetaEnabled,trueSyncNowQaEnabled:Rr.trueSyncNowQaEnabled,trueSyncPopulatedPullEnabled:Rr.trueSyncPopulatedPullEnabled,trueSyncPullMergePreviewEnabled:Rr.trueSyncPullMergePreviewEnabled,trueSyncProductPilotState:en,trueSyncProductTomb
36stoneEnabled:_o,trueSyncProductWriteThroughEnabled:Qt,trueSyncStatusModelEnabled:Rr.trueSyncStatusModelEnabled}):ws?n.jsx(b4,{lists:_,manualStores:P,onBackToDashboard:li,onOpenList:Zl,onOpenProduct:tl,onOpenProfile:g=>Ft(Yo(g?.username||"")),onOpenPublicBoard:g=>Ft(jc(g?.ownerUsername||"",g?.id||"")),onOpenStore:g=>Ft(g?.domain?r_(g.domain):yc),products:D}):Ao?n.jsx(z_,{content:is,onOpenAccount:()=>Ft("/account"),onOpenApp:li,onOpenProfile:g=>Ft(Yo(g?.username||"")),onOpenPublicBoard:g=>Ft(g?.href||ta),signedIn:Ea}):Zo?n.jsx(k4,{profileUsername:vl(e.profile),signedIn:Ea,onBackToDashboard:li,onOpenAccount:()=>Ft("/account"),onRefreshUnreadCount:ac}):Qo?n.jsx($5,{cloudSyncState:gr,detailDomain:Tf,detailIsOpen:Vl,gridPreference:ne,manualStores:P,onBackToDashboard:li,onBackToStores:()=>Ft(yc),onDeleteManualStore:Iv,onDeleteProduct:Jl,onEditProduct:Jx,onOpenProduct:tl,onOpenStore:g=>Ft(r_(g.domain)),onSaveManualStore:xv,onUpdateProductStatus:Yp,products:D}):Sp?n.jsx(S4,{capabilities:Fl,onBackToDashboard:li,onCancelPriceUpdate:$v,onCheckPrice:Uv,onConfirmPriceUpdate:Fv,onOpenProduct:tl,priceCheckState:qt,products:D}):n.jsx("main",{className:`dashboard${No?" isDashboardOverview":""}`,children:No?n.jsxs(n.Fragment,{children:[Zf?n.jsx(vm,{title:"No items found.",subtitle:"Try a different search.",variant:"search"}):null,n.jsx(t5,{currentProfileUsername:vl(e.profile),isSettling:Hp,listSummaries:qf,searchIsActive:ls,signedIn:Ea,activeDropListId:on,draggingProduct:Et,onPrepareList:Ux,onSelectList:Zl,onCreateBoard:nl,onOpenItem:tl,onOpenSharedBoard:Vx,sharedBoards:lv.boards})]}):n.jsxs("div",{className:"listPageContent",style:Ff,children:[n.jsx("section",{className:"listEditorialFrame","aria-label":`${Ia} board tools`,children:n.jsx("div",{className:"productListToolbar","aria-label":"Board product toolbar",children:Sa?n.jsx(Zq,{capabilities:bn,fitImagesIsPending:go,selectedCount:Xf,totalCount:Jc.length,lists:pr?[]:_,activeListRecord:Yd,onDone:hv,onMove:_e,onFitImages:bt,onMarkPurchased:ir,onArchive:Ln,onDelete:ka,onSelectAll:Kl,onClearSelection:Ks}):n.jsxs(n.Fragment,{children:[n.jsx("div",{className:"toolbarPrimaryControls",children:n.jsx(eY,{query:Or,onQueryChange:Yt,inputRef:Uc})}),n.jsx(rY,{value:er,onChange:Gp,priceSummary:Yf}),vn!=="trash"?n.jsx(Qq,{capabilities:bn,contextLabel:pr?CI($a):"",shareList:r===rr?"":r,onPreviewShare:al,activeListRecord:pr||r===rr?null:a,onEditList:Av,onEditBoardCover:Pv,onDeleteList:jv,onMoveList:(g,w)=>Nv(g.id,w),canDeleteList:Kn,onCopyWishlistText:qv,onExportCsv:Kv,onCopyProductLinks:Yv,onOpenProductLinks:XL,listActionMessage:yr,onEnterManage:()=>Fa(!0),onAddProduct:()=>Xl(0)}):null]})})}),Qc?n.jsxs("div",{className:"sharedBoardNotice boardCreateNotice",role:"status",children:[n.jsx("span",{children:Qc.message}),n.jsx("button",{disabled:Wd===String(a?.id||""),onClick:()=>Hf(a),type:"button",children:Wd===String(a?.id||"")?"Saving…":"Save to account"})]}):null,Zf?n.jsx(vm,{title:"No items found.",subtitle:"Try a different search.",variant:"search"}):null,yv?n.jsx(vm,{title:"No saved items yet.",subtitle:"",variant:"search"}):null,Sv?n.jsx(vm,{title:"Trash is empty.",subtitle:"",variant:"search"}):null,pr&&la.error?n.jsxs("div",{className:"sharedBoardNotice",role:"status",children:[n.jsx("span",{children:la.error}),n.jsx("button",{onClick:()=>{Gi()},type:"button",children:"Try again"})]}):null,pr&&!la.isLoading&&!la.error&&!Jc.length&&!ls?n.jsx(vm,{title:(bn.canAddItems,"Nothing on this board yet."),subtitle:bn.canAddItems?"Add the first item to this shared board.":"Items the owner and editors add will appear here.",variant:"search"}):null,n.jsx($L,{allowVariableCardSizes:!!(Yd?.id&&r!==rr),capabilities:bn,products:Jc,boards:bn.canMoveItemsBetweenBoards?_:[],onCreateBoard:bn.canManageBoard?g0:null,onEmptyClick:h0,onExpandProduct:b0,onEditProduct:Jx,onDeleteProduct:v0,onRestoreProduct:y0,onUpdateProductStatus:S0,onReorderProducts:w0,onMoveProductToList:C0,onDragProductChange:x0,onDragListTargetChange:I0,gridPreference:ne,boardMode:Re,fillEmptySlots:!ls&&vn!=="trash",emptySlotMode:vn==="active"&&bn.canAddItems?"add":"filler",allowReorder:Sa&&Qf&&bn.canReorderItems,allowMove:Sa&&vv&&vn!=="trash"&&bn.canMoveItemsBetweenBoards,manageMode:Sa&&vn!=="trash",selectedProductIds:qn,onToggleProductSelection:A0,onRailWidthChange:zf,maxColumnCount:Dd,minimalMode:Kc&&!!(Yd?.id&&r!==rr),restorePendingProductId:se.status==="pending"?se.productId:"",trashView:vn==="trash",renderResetKey:`${z}:${Ia}:${vn}:${er}:${rc}:${Re}:${ne}`}),n.jsx(sY,{contextLabel:pr?CI($a):"",createdAt:vs(Yd?.createdAt),listName:Ia,priceSummary:Yf,productC
36ount:Jc.length})]})}),Kx?n.jsx(oE,{product:ft,initialProduct:Ua,listRecords:pr&&da?[da]:_,listOptions:pr&&da?[da.name]:Z,defaultList:pr&&da?da.name:v,defaultImageFit:de.defaultImageFit,defaultCurrency:de.defaultCurrency,imagePreviewAspectRatio:Jf,imagePreviewAspectRatios:zp,initialFramingMode:Kc?Lr.minimal:Lr.normal,onSubmit:ft?ch:Mv,onCancel:Pa,onDelete:Jl,onDirtyChange:$f,onRecoverMissingRevision:Xx?sh:null},ft?.id?pA(ar)||`shared-${ft.id}`:Ua?.url??Ua?.title??`add-${v}`):null,ns?n.jsx(uY,{activeTheme:xp,settings:de,lists:Z,mode:z,modes:B,signedIn:Ea,onSettingsChange:We,onModeChange:ye,onExportBackup:dh,onImportBackup:Wx,onResetPersonal:Yx,backupError:St,backupMessage:dr,onClose:()=>Zn(!1)}):null,ue?n.jsx(oY,{authenticatedOwnerId:Ie,authenticatedUsername:Of,list:be,existingLists:_,protectedName:!1,boardTheme:be?hL(be.id):"",showBoardTheme:!!be,onBoardThemeChange:g=>_v(be?.id,g),onSubmit:Ev,onCancel:qp,onDirtyChange:at},be?.id?`${be.id}:${be.syncRevision||be.cloudUpdatedAt||"local"}`:"create-list"):null,Ar?n.jsx(iY,{board:Ar,currentUserId:e.user?.id||"",currentUsername:Ro,isSaving:po,manualShareUrl:mo,message:fr,onCancel:Zd,onCopyBoardLink:VL,onCopyQrPng:WL,onDownloadQrPng:GL,onGenerateQrCode:HL,hasPrivateLink:!!$s?.shareToken,onRevokePrivateLink:zL,onMakePublicAndCopy:qL,onOpenProfile:()=>{Zd(),Ft("/account")},onViewPublicBoard:YL,publishPrerequisiteMessage:Kf,publicUrl:$p,qrCodeDataUrl:ii,qrError:wt.error,qrIsLoading:wt.status==="loading"}):null,jt==="cloud"?n.jsx(lY,{itemCount:mv,list:Xe,onConfirm:Lv,onCancel:cc,state:xt}):n.jsx(cY,{list:jt==="local"?Xe:null,listOptions:_,onConfirm:Rv,onCancel:cc}),Fp?n.jsx(dY,{list:Fp,products:D,onSubmit:kv,onCancel:()=>Ge(null)}):null,n.jsx(gY,{error:Pn.productId===rn?.id?Pn.message:"",isCloudTrash:!!(Ie&&z===B.personal),isPending:Pn.productId===rn?.id&&Pn.status==="pending",product:rn,onArchive:zv,onConfirm:Kp,onCancel:ic}),n.jsx(bY,{count:ys?Xf:0,onConfirm:lc,onCancel:()=>an(!1)}),n.jsx(vY,{request:or,onConfirm:JL,onCancel:QL}),n.jsx(yY,{backup:Kt,onReplace:()=>qx("replace"),onMerge:()=>qx("merge"),onCancel:Gx}),Hi?n.jsx(SY,{onClose:()=>as(!1)}):null,Td?n.jsx(wY,{commands:u0,onClose:()=>zs(!1)}):null,n.jsx("input",{accept:"application/json,.json",className:"backupFileInput",onChange:g=>{Wx(g.target.files?.[0]),g.target.value=""},ref:vp,type:"file"})]})]})}j0.createRoot(document.getElementById("root"),{onCaughtError:ty(),onRecoverableError:ty(),onUncaughtError:ty()}).render(n.jsxs(d.StrictMode,{children:[n.jsxs(BB,{children:[n.jsx(CY,{}),n.jsx(R0,{})]}),null,n.jsx(bV,{})]}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.