@mblinkov/whats-missing 20.0.30 → 20.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("react"),Se=window.origin+"/cloud/speakid/games/whatsmissing/",Z=(r,m)=>r.map(([l,s])=>({src:`${Se}${m}/${s.replace(/\s/g,"%20")}.png`,name:s})),Ce=[["apple","apple"],["banana","banana"],["bread","bread"],["burger","burger"],["cake","cake"],["carrot","carrot"],["cheese","cheese"],["chicken","chicken"],["chocolate","chocolate"],["corn","corn"],["donut","donut"],["fish","fish"],["fries","fries"],["grapes","grapes"],["ice_cream","ice cream"],["milk","milk"],["orange","orange"],["pear","pear"],["pizza","pizza"],["rice","rice"],["sandwich","sandwich"],["soup","soup"],["strawberry","strawberry"],["tomato","tomato"],["watermelon","watermelon"]],ke=[["bear","bear"],["cat","cat"],["crocodile","crocodile"],["dolphin","dolphin"],["elephant","elephant"],["fox","fox"],["giraffe","giraffe"],["horse","horse"],["kangaroo","kangaroo"],["lion","lion"],["monkey","monkey"],["owl","owl"],["panda","panda"],["penguin","penguin"],["squirrel","squirrel"],["tiger","tiger"],["tortoise","tortoise"],["wolf","wolf"],["zebra","zebra"]],ze=[["ball","ball"],["balloon","balloon"],["blocks","blocks"],["car","car"],["doll","doll"],["drum","drum"],["guitar","guitar"],["jump_rope","jump rope"],["kite","kite"],["paints","paints"],["plane","plane"],["puzzle","puzzle"],["rocket","rocket"],["scooter","scooter"],["skateboard","skateboard"],["slide","slide"],["teddy_bear","teddy bear"],["yo-yo","yo-yo"],["crayons","crayons"]],_={food:Z(Ce,"food"),animals:Z(ke,"animals"),toys:Z(ze,"toys")},Me=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),s=require("react"),he=window.origin+"/cloud/speakid/games/whatsmissing/",Y=(a,m)=>a.map(([r,i])=>({src:`${he}${m}/${i.replace(/\s/g,"%20")}.png`,name:i})),fe=[["apple","apple"],["banana","banana"],["bread","bread"],["burger","burger"],["cake","cake"],["carrot","carrot"],["cheese","cheese"],["chicken","chicken"],["chocolate","chocolate"],["corn","corn"],["donut","donut"],["fish","fish"],["fries","fries"],["grapes","grapes"],["ice_cream","ice cream"],["milk","milk"],["orange","orange"],["pear","pear"],["pizza","pizza"],["rice","rice"],["sandwich","sandwich"],["soup","soup"],["strawberry","strawberry"],["tomato","tomato"],["watermelon","watermelon"]],pe=[["bear","bear"],["cat","cat"],["crocodile","crocodile"],["dolphin","dolphin"],["elephant","elephant"],["fox","fox"],["giraffe","giraffe"],["horse","horse"],["kangaroo","kangaroo"],["lion","lion"],["monkey","monkey"],["owl","owl"],["panda","panda"],["penguin","penguin"],["squirrel","squirrel"],["tiger","tiger"],["tortoise","tortoise"],["wolf","wolf"],["zebra","zebra"]],ye=[["ball","ball"],["balloon","balloon"],["blocks","blocks"],["car","car"],["doll","doll"],["drum","drum"],["guitar","guitar"],["jump_rope","jump rope"],["kite","kite"],["paints","paints"],["plane","plane"],["puzzle","puzzle"],["rocket","rocket"],["scooter","scooter"],["skateboard","skateboard"],["slide","slide"],["teddy_bear","teddy bear"],["yo-yo","yo-yo"],["crayons","crayons"]],P={food:Y(fe,"food"),animals:Y(pe,"animals"),toys:Y(ye,"toys")},xe=`
2
2
  @keyframes spin {
3
3
  from { transform: rotate(0deg); }
4
4
  to { transform: rotate(360deg); }
5
5
  }
6
- `;if(typeof document<"u"&&!document.getElementById("spin-keyframes")){const r=document.createElement("style");r.id="spin-keyframes",r.innerHTML=Me,document.head.appendChild(r)}const Re={animation:"spin 1.4s linear infinite"},n={gmCenterScreen:{position:"relative",zIndex:1,minHeight:"100%",width:"100%",display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",textAlign:"center",color:"#1f2937",padding:"24px 16px",boxSizing:"border-box",transform:"translateY(20px)"},gmHeadline1:{fontWeight:700,fontSize:"clamp(28px, 4vw, 40px)",lineHeight:"110%"},gmHeadline3:{fontWeight:600,fontSize:"18px",lineHeight:"130%"},gmBodyM:{fontWeight:400,fontSize:"16px",lineHeight:"140%"},gmBodyS:{fontWeight:400,fontSize:"14px",lineHeight:"140%",color:"#6b7280"},gmButton:{fontFamily:'"Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, "Noto Sans"',fontWeight:600,fontSize:"16px",padding:"10px 16px",borderRadius:"12px",border:"1px solid #e5e7eb",background:"#ec4c44",color:"#ffffff",cursor:"pointer",boxShadow:"0 6px 18px rgba(236, 76, 68, .18)",transition:"transform .06s ease, box-shadow .2s ease, background .2s ease, opacity .2s ease"},gmButtonActive:{background:"#333",color:"#fff"},gmGameLayout:{position:"relative",width:"100%",maxWidth:"none",minHeight:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",color:"#1f2937",padding:"16px 8px",margin:"0 auto"},gmGrid:{width:"100%",maxWidth:"none",margin:"0 auto",display:"grid",gridTemplateColumns:"repeat(3, 210px)",gridAutoRows:"210px",gap:"20px",justifyContent:"center"},gmCard:{border:"1px solid #e5e7eb",borderRadius:"16px",background:"#f9f9f9",aspectRatio:"1 / 1",display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",transition:"transform .2s ease, box-shadow .2s ease, border-color .2s ease"},gmCorrect:{border:"2px solid #10b981",boxShadow:"0 0 18px rgba(16,185,129,.45)",background:"#ecfdf5"},gmWrong:{border:"2px solid #ec4c44",boxShadow:"0 0 18px rgba(236,76,68,.35)",background:"#fef2f2"},gmInput:{padding:"6px 10px",borderRadius:"6px",border:"1px solid #ccc",fontSize:"16px",fontFamily:'"Geist", system-ui',width:"160px"},gmTable:{marginTop:"20px",marginBottom:"32px",borderCollapse:"collapse",width:"100%",maxWidth:"520px",tableLayout:"fixed",textAlign:"center"},gmTableCell:{padding:"8px 12px",borderBottom:"1px solid #e5e7eb",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},gmLogoFixed:{position:"absolute",top:"16px",left:"24px",width:"120px",zIndex:10,pointerEvents:"none",background:"transparent",transform:"none",willChange:"auto"},gmLogoImg:{height:"clamp(28px, 5vw, 40px)",width:"auto",background:"transparent",objectFit:"contain",imageRendering:"auto",transform:"translateZ(0)",backfaceVisibility:"hidden",WebkitFontSmoothing:"antialiased"},gmHourglass:{fontSize:"42px",...Re}},Te=()=>{const r=document.createElement("style");r.textContent=`
6
+ `;if(typeof document<"u"&&!document.getElementById("spin-keyframes")){const a=document.createElement("style");a.id="spin-keyframes",a.innerHTML=xe,document.head.appendChild(a)}const be={animation:"spin 1.4s linear infinite"},n={gmCenterScreen:{position:"relative",zIndex:1,minHeight:"100%",width:"100%",display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",textAlign:"center",color:"#1f2937",padding:"24px 16px",boxSizing:"border-box",transform:"translateY(20px)"},gmHeadline1:{fontWeight:700,fontSize:"clamp(28px, 4vw, 40px)",lineHeight:"110%"},gmHeadline3:{fontWeight:600,fontSize:"18px",lineHeight:"130%"},gmBodyM:{fontWeight:400,fontSize:"16px",lineHeight:"140%"},gmBodyS:{fontWeight:400,fontSize:"14px",lineHeight:"140%",color:"#6b7280"},gmButton:{fontFamily:'"Geist", system-ui, -apple-system, "Segoe UI", Roboto, Arial, "Noto Sans"',fontWeight:600,fontSize:"16px",padding:"10px 16px",borderRadius:"12px",border:"1px solid #e5e7eb",background:"#ec4c44",color:"#ffffff",cursor:"pointer",boxShadow:"0 6px 18px rgba(236, 76, 68, .18)",transition:"transform .06s ease, box-shadow .2s ease, background .2s ease, opacity .2s ease"},gmButtonActive:{background:"#333",color:"#fff"},gmGameLayout:{position:"relative",width:"100%",maxWidth:"none",minHeight:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",textAlign:"center",color:"#1f2937",padding:"16px 8px",margin:"0 auto"},gmGrid:{width:"100%",maxWidth:"none",margin:"0 auto",display:"grid",gridTemplateColumns:"repeat(3, 210px)",gridAutoRows:"210px",gap:"20px",justifyContent:"center"},gmCard:{border:"1px solid #e5e7eb",borderRadius:"16px",background:"#f9f9f9",aspectRatio:"1 / 1",display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",transition:"transform .2s ease, box-shadow .2s ease, border-color .2s ease"},gmCorrect:{border:"2px solid #10b981",boxShadow:"0 0 18px rgba(16,185,129,.45)",background:"#ecfdf5"},gmWrong:{border:"2px solid #ec4c44",boxShadow:"0 0 18px rgba(236,76,68,.35)",background:"#fef2f2"},gmInput:{padding:"6px 10px",borderRadius:"6px",border:"1px solid #ccc",fontSize:"16px",fontFamily:'"Geist", system-ui',width:"160px"},gmTable:{marginTop:"20px",marginBottom:"32px",borderCollapse:"collapse",width:"100%",maxWidth:"520px",tableLayout:"fixed",textAlign:"center"},gmTableCell:{padding:"8px 12px",borderBottom:"1px solid #e5e7eb",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},gmLogoFixed:{position:"absolute",top:"16px",left:"24px",width:"120px",zIndex:10,pointerEvents:"none",background:"transparent",transform:"none",willChange:"auto"},gmLogoImg:{height:"clamp(28px, 5vw, 40px)",width:"auto",background:"transparent",objectFit:"contain",imageRendering:"auto",transform:"translateZ(0)",backfaceVisibility:"hidden",WebkitFontSmoothing:"antialiased"},gmHourglass:{fontSize:"42px",...be}},we=()=>{const a=document.createElement("style");a.textContent=`
7
7
  #whats-missing-root, #whats-missing-root * { box-sizing: border-box; }
8
8
  #whats-missing-root img { max-width:100%; height:auto; display:block; user-select:none; }
9
- `,document.head.appendChild(r)},Ie=(r,m)=>{const l=Array.from({length:r.length+1},()=>Array(m.length+1).fill(0));for(let s=0;s<=r.length;s++)l[s][0]=s;for(let s=0;s<=m.length;s++)l[0][s]=s;for(let s=1;s<=r.length;s++)for(let d=1;d<=m.length;d++)l[s][d]=r[s-1]===m[d-1]?l[s-1][d-1]:Math.min(l[s-1][d-1],l[s][d-1],l[s-1][d])+1;return l[r.length][m.length]};function He(r,m={minDesktopWidth:1200,forceResize:!1}){const l=o.useRef(null),s=m.minDesktopWidth??1200,d=!!m.forceResize;o.useLayoutEffect(()=>{if(typeof window>"u"||!r||!r.current)return;const c=r.current,T=()=>{try{const a=document.body,g=getComputedStyle(a),C=parseFloat(a.style&&a.style.zoom||"");if(C&&!isNaN(C)&&C>0)return C;const w=parseFloat(g.zoom||"");if(w&&!isNaN(w)&&w>0)return w;const h=document.createElement("div");h.style.position="absolute",h.style.left="0",h.style.top="0",h.style.width="100px",h.style.height="1px",h.style.visibility="hidden",document.documentElement.appendChild(h);const p=h.getBoundingClientRect();if(document.documentElement.removeChild(h),p&&p.width>0){const I=p.width/100;if(!isNaN(I)&&I>0)return I}}catch{}return 1},j=()=>{if(s&&window.innerWidth<s){M();return}const a=T();if(!a||a===1){M();return}l.current||(l.current={transform:c.style.transform||null,transformOrigin:c.style.transformOrigin||null,width:c.style.width||null,height:c.style.height||null,willChange:c.style.willChange||null});const g=1/a;d&&(c.style.width=`${a*100}%`,c.style.height=`${a*100}%`),c.style.transformOrigin="50% 50%",c.style.transform=`scale(${g})`,c.style.willChange="transform"},M=()=>{if(!l.current)return;const a=l.current;c.style.transform=a.transform??"",c.style.transformOrigin=a.transformOrigin??"",c.style.width=a.width??"",c.style.height=a.height??"",c.style.willChange=a.willChange??"",l.current=null};let b=0;const v=()=>{cancelAnimationFrame(b),b=requestAnimationFrame(j)},S=new MutationObserver(a=>{for(const g of a)if(g.type==="attributes"&&(g.attributeName==="style"||g.attributeName==="class")){v();break}});return S.observe(document.body,{attributes:!0,attributeFilter:["style","class"]}),window.addEventListener("resize",v),v(),()=>{cancelAnimationFrame(b),S.disconnect(),window.removeEventListener("resize",v),M()}},[r,s,d])}function Be({gameCubeSize:r,screenHeight:m,screenWidth:l}){const s=o.useRef(null),d=o.useRef(null),[c,T]=o.useState(null);He(s,{minDesktopWidth:1200,forceResize:!1}),o.useEffect(()=>(Te(),()=>{document.body.style.overflow=""}),[]);const[j,M]=o.useState(null),[b,v]=o.useState([]),[S,a]=o.useState(4),[g,C]=o.useState(!1),[w,h]=o.useState(1),[p,I]=o.useState(null),[y,A]=o.useState("ready"),[K,J]=o.useState(3),[$,G]=o.useState(10),[N,Q]=o.useState(20),[ce,O]=o.useState(0),[E,D]=o.useState(!1),[W,X]=o.useState(""),[R,q]=o.useState(!1),[Y,ee]=o.useState(!1),[te,H]=o.useState(null),[me,P]=o.useState([]),[ue,ne]=o.useState([]),[k,ge]=o.useState(!1);o.useEffect(()=>{if(typeof window>"u")return;const t=()=>{const i=l??window.innerWidth;ge(i<=768)};return t(),window.addEventListener("resize",t),window.addEventListener("orientationchange",t),()=>{window.removeEventListener("resize",t),window.removeEventListener("orientationchange",t)}},[l]),o.useLayoutEffect(()=>{const t=d.current;if(!t||typeof window>"u")return;let i=null;try{i=new ResizeObserver(f=>{for(const u of f){const x=u.contentRect;T(Math.round(Math.min(x.width,x.height)))}}),i.observe(t),T(Math.round(Math.min(t.clientWidth,t.clientHeight)))}catch{T(Math.round(Math.min(t.clientWidth,t.clientHeight)))}return()=>i?.disconnect()},[k]);const oe=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),se=()=>{if(!j)return;const t=oe(_[j]);v(t),C(!0),D(!1),h(1),O(0),P([]),ne([]),ie(t,[],!0)},ie=(t=b,i=ue,f=!1)=>{const u=oe(t.length?t:_[j]);let x=Math.floor(Math.random()*u.length),z=u[x].name,B=0;for(;i.includes(z)&&B<20;)x=Math.floor(Math.random()*u.length),z=u[x].name,B++;v(u),I(x),ne([...i,z]),q(!1),X(""),Q(20),H(null),f?(A("ready"),J(3),G(10)):(A("memorize"),G(10))};o.useEffect(()=>{if(!(!g||E||R)){if(y==="ready")if(K<=0)A("memorize");else{const t=setTimeout(()=>J(i=>i-1),1e3);return()=>clearTimeout(t)}if(y==="memorize")if($<=0)A("guess");else{const t=setTimeout(()=>G(i=>i-1),1e3);return()=>clearTimeout(t)}if(y==="guess"){if(N<=0){q(!0),H("wrong");const i=b[p].name;P(f=>[...f,{round:w,answer:W,correct:i,result:"wrong"}]);return}const t=setTimeout(()=>Q(i=>i-1),1e3);return()=>clearTimeout(t)}}},[y,K,$,N,g,E,R,b,p,w,W]);const he=()=>{if(p===null||Y)return;const t=b[p].name,i=W.toLowerCase().trim();let f="wrong";i===t?(O(u=>u+1),H("correct"),f="correct"):Ie(i,t)===1?(O(u=>u+.5),H("almost"),f="almost"):(H("wrong"),f="wrong"),P(u=>[...u,{round:w,answer:i,correct:t,result:f}]),ee(!0),setTimeout(()=>{ee(!1),q(!0)},600)},fe=()=>w<S?(h(t=>t+1),ie()):D(!0),pe=()=>{C(!1),D(!1),M(null)},ye=o.useMemo(()=>e.jsx("div",{style:{...n.gmLogoFixed,position:"absolute",top:16,left:16,zIndex:30},children:e.jsxs("picture",{children:[e.jsx("source",{srcSet:window.origin+"/cloud/speakid/games/whatsmissing/logo.svg",type:"image/svg+xml"}),e.jsx("img",{src:window.origin+"/cloud/speakid/games/whatsmissing/logo.png",alt:"SPEAKID Logo",style:n.gmLogoImg,loading:"lazy"})]})}),[]),re=1440,le=900,xe=d.current?.clientWidth??l??(typeof window<"u"?window.innerWidth:re),be=d.current?.clientHeight??m??(typeof window<"u"?window.innerHeight:le),U=Math.min(xe/re,be/le);return e.jsx("div",{ref:s,style:{position:"fixed",inset:0,display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",overflow:"hidden",zIndex:1},children:e.jsx("div",{ref:d,style:{width:k?"100%":`${Math.min(r??1e3,l??1e3,m??1e3)}px`,height:k?"100%":`${Math.min(r??1e3,l??1e3,m??1e3)}px`,borderRadius:k?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",position:"relative",overflow:"hidden",boxShadow:k?"none":"0 0 40px rgba(0,0,0,0.08)",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",style:{transform:`scale(${U})`,transformOrigin:"center center",width:`${100/U}%`,height:`${100/U}%`,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[!k&&ye,!j&&!g&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:n.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:n.gmButton,onClick:()=>M(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:n.gmBodyS,children:"Choose number of rounds:"}),e.jsx("div",{style:{display:"flex",gap:12,marginTop:8},children:[3,4,5].map(t=>e.jsx("button",{style:{...n.gmButton,...S===t?n.gmButtonActive:{}},onClick:()=>a(t),children:t},t))})]})]}),j&&!g&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsxs("h1",{style:n.gmHeadline1,children:["Theme selected: ",j]}),e.jsxs("p",{style:n.gmBodyM,children:["Rounds: ",S]}),e.jsx("button",{style:n.gmButton,onClick:se,children:"▶ Start game"})]}),E&&e.jsxs("div",{style:n.gmCenterScreen,children:[e.jsx("h1",{style:n.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:n.gmHeadline3,children:["Your score: ",ce," / ",S]}),e.jsx("p",{style:{...n.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:n.gmTable,children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Round"}),e.jsx("th",{children:"Your Answer"}),e.jsx("th",{children:"Correct"}),e.jsx("th",{children:"Result"})]})}),e.jsx("tbody",{children:me.map((t,i)=>e.jsxs("tr",{children:[e.jsx("td",{style:n.gmTableCell,children:t.round}),e.jsx("td",{style:n.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:n.gmTableCell,children:t.correct}),e.jsx("td",{style:n.gmTableCell,children:t.result==="correct"?"✔ Correct":t.result==="almost"?"◐ Almost (0.5)":"✘ Wrong"})]},i))})]}),e.jsxs("div",{style:{display:"flex",gap:12,marginTop:24},children:[e.jsx("button",{style:n.gmButton,onClick:se,children:"🔁 Play again"}),e.jsx("button",{style:n.gmButton,onClick:pe,children:"⬅️ Choose theme"})]})]}),g&&!E&&e.jsxs("div",{style:n.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[y==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...n.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:n.gmHourglass,children:"⏳"})]}),y==="memorize"&&e.jsxs("p",{style:{...n.gmBodyM,color:"#10b981"},children:["MEMORIZE (",$,")"]}),y==="guess"&&!R&&e.jsxs("p",{style:n.gmBodyM,children:["⏳ Time left: ",N,"s"]})]}),y!=="ready"&&(()=>{const t=k?12:20,i=32,f=d.current?.clientWidth??Math.min(r??1e3,l??1e3),u=d.current?.clientHeight??Math.min(r??1e3,m??1e3),x=Math.min(f,u),z=typeof window<"u"?window.innerWidth:l??1e3,B=z<600?110:z<900?130:z<1280?150:180,we=4,ae=2,V=Math.max(ae,Math.min(we,Math.floor((x-i+t)/(B+t))||ae)),je=Math.floor((x-i-t*(V-1))/V),L=Math.max(B,je);return e.jsx("div",{style:{...n.gmGrid,gridTemplateColumns:`repeat(${V}, ${L}px)`,gridAutoRows:`${L}px`,gap:`${t}px`,justifyContent:"center",justifyItems:"center",padding:8,boxSizing:"border-box"},children:b.map((de,F)=>{const ve=p===F&&y==="guess"&&!R;return e.jsx("div",{style:{...n.gmCard,width:`${L}px`,height:`${L}px`,padding:L>=160?10:8,boxSizing:"border-box",...te==="correct"&&p===F?n.gmCorrect:{},...te==="wrong"&&p===F?n.gmWrong:{}},children:!ve&&e.jsx("img",{src:de.src,alt:de.name,style:{width:"100%",height:"100%",objectFit:"cover",display:"block"}})},F)})})})(),e.jsxs("div",{style:{marginTop:16,height:80},children:[y==="guess"&&!R&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:W,onChange:t=>X(t.target.value),style:n.gmInput}),e.jsx("button",{style:{...n.gmButton,marginLeft:8},onClick:he,disabled:Y,children:Y?"...":"Check"})]}),R&&e.jsx("button",{type:"button",style:n.gmButton,onClick:fe,children:"Next round"})]})]})]})})})}exports.Game=Be;exports.themes=_;
9
+ `,document.head.appendChild(a)},je=(a,m)=>{const r=Array.from({length:a.length+1},()=>Array(m.length+1).fill(0));for(let i=0;i<=a.length;i++)r[i][0]=i;for(let i=0;i<=m.length;i++)r[0][i]=i;for(let i=1;i<=a.length;i++)for(let u=1;u<=m.length;u++)r[i][u]=a[i-1]===m[u-1]?r[i-1][u-1]:Math.min(r[i-1][u-1],r[i][u-1],r[i-1][u])+1;return r[a.length][m.length]};function Se(a,m={minDesktopWidth:1200,forceResize:!1}){const r=s.useRef(null),i=m.minDesktopWidth??1200,u=!!m.forceResize;s.useLayoutEffect(()=>{if(typeof window>"u"||!a||!a.current)return;const d=a.current,R=()=>{try{const l=document.body,j=getComputedStyle(l),b=parseFloat(l.style&&l.style.zoom||"");if(b&&!isNaN(b)&&b>0)return b;const S=parseFloat(j.zoom||"");if(S&&!isNaN(S)&&S>0)return S;const g=document.createElement("div");g.style.position="absolute",g.style.left="0",g.style.top="0",g.style.width="100px",g.style.height="1px",g.style.visibility="hidden",document.documentElement.appendChild(g);const k=g.getBoundingClientRect();if(document.documentElement.removeChild(g),k&&k.width>0){const p=k.width/100;if(!isNaN(p)&&p>0)return p}}catch{}return 1},I=()=>{if(i&&window.innerWidth<i){y();return}const l=R();if(!l||l===1){y();return}r.current||(r.current={transform:d.style.transform||null,transformOrigin:d.style.transformOrigin||null,width:d.style.width||null,height:d.style.height||null,willChange:d.style.willChange||null});const j=1/l;u&&(d.style.width=`${l*100}%`,d.style.height=`${l*100}%`),d.style.transformOrigin="50% 50%",d.style.transform=`scale(${j})`,d.style.willChange="transform"},y=()=>{if(!r.current)return;const l=r.current;d.style.transform=l.transform??"",d.style.transformOrigin=l.transformOrigin??"",d.style.width=l.width??"",d.style.height=l.height??"",d.style.willChange=l.willChange??"",r.current=null};let C=0;const x=()=>{cancelAnimationFrame(C),C=requestAnimationFrame(I)},T=new MutationObserver(l=>{for(const j of l)if(j.type==="attributes"&&(j.attributeName==="style"||j.attributeName==="class")){x();break}});return T.observe(document.body,{attributes:!0,attributeFilter:["style","class"]}),window.addEventListener("resize",x),x(),()=>{cancelAnimationFrame(C),T.disconnect(),window.removeEventListener("resize",x),y()}},[a,i,u])}function ve({gameCubeSize:a,screenHeight:m,screenWidth:r}){const i=s.useRef(null),u=s.useRef(null),[d,R]=s.useState(null);Se(i,{minDesktopWidth:1024,forceResize:!1});const I=s.useMemo(()=>{const e=a??Math.min(r??1e3,m??1e3),o=r??(typeof window<"u"?window.innerWidth:1e3);return e<600&&o>768?600:o<=768?Math.min(e,o-20):e},[a,r,m]);s.useEffect(()=>(we(),()=>{document.body.style.overflow=""}),[]);const[y,C]=s.useState(null),[x,T]=s.useState([]),[l,j]=s.useState(4),[b,S]=s.useState(!1),[g,k]=s.useState(1),[p,ie]=s.useState(null),[w,H]=s.useState("ready"),[U,V]=s.useState(3),[E,A]=s.useState(10),[W,Z]=s.useState(20),[re,F]=s.useState(0),[B,G]=s.useState(!1),[L,_]=s.useState(""),[z,$]=s.useState(!1),[N,K]=s.useState(!1),[J,M]=s.useState(null),[ae,O]=s.useState([]),[le,Q]=s.useState([]),[h,de]=s.useState(!1);s.useEffect(()=>{if(typeof window>"u")return;const e=()=>{const o=r??window.innerWidth,c=window.matchMedia&&window.matchMedia("(pointer: coarse)").matches;de(o<=768||c)};return e(),window.addEventListener("resize",e),window.addEventListener("orientationchange",e),()=>{window.removeEventListener("resize",e),window.removeEventListener("orientationchange",e)}},[r]),s.useLayoutEffect(()=>{const e=u.current;if(!e||typeof window>"u")return;let o=null;try{o=new ResizeObserver(c=>{for(const f of c){const v=f.contentRect;R(Math.round(Math.min(v.width,v.height)))}}),o.observe(e),R(Math.round(Math.min(e.clientWidth,e.clientHeight)))}catch{R(Math.round(Math.min(e.clientWidth,e.clientHeight)))}return()=>o?.disconnect()},[h]);const X=e=>[...e].sort(()=>Math.random()-.5).slice(0,6),ee=()=>{if(!y)return;const e=X(P[y]);T(e),S(!0),G(!1),k(1),F(0),O([]),Q([]),te(e,[],!0)},te=(e=x,o=le,c=!1)=>{const f=X(e.length?e:P[y]);let v=Math.floor(Math.random()*f.length),q=f[v].name,se=0;for(;o.includes(q)&&se<20;)v=Math.floor(Math.random()*f.length),q=f[v].name,se++;T(f),ie(v),Q([...o,q]),$(!1),_(""),Z(20),M(null),c?(H("ready"),V(3),A(10)):(H("memorize"),A(10))};s.useEffect(()=>{if(!(!b||B||z)){if(w==="ready")if(U<=0)H("memorize");else{const e=setTimeout(()=>V(o=>o-1),1e3);return()=>clearTimeout(e)}if(w==="memorize")if(E<=0)H("guess");else{const e=setTimeout(()=>A(o=>o-1),1e3);return()=>clearTimeout(e)}if(w==="guess"){if(W<=0){$(!0),M("wrong");const o=x[p].name;O(c=>[...c,{round:g,answer:L,correct:o,result:"wrong"}]);return}const e=setTimeout(()=>Z(o=>o-1),1e3);return()=>clearTimeout(e)}}},[w,U,E,W,b,B,z,x,p,g,L]);const ce=()=>{if(p===null||N)return;const e=x[p].name,o=L.toLowerCase().trim();let c="wrong";o===e?(F(f=>f+1),M("correct"),c="correct"):je(o,e)===1?(F(f=>f+.5),M("almost"),c="almost"):(M("wrong"),c="wrong"),O(f=>[...f,{round:g,answer:o,correct:e,result:c}]),K(!0),setTimeout(()=>{K(!1),$(!0)},600)},me=()=>g<l?(k(e=>e+1),te()):G(!0),ue=()=>{S(!1),G(!1),C(null)},ge=s.useMemo(()=>t.jsx("div",{style:{...n.gmLogoFixed,position:"absolute",top:16,left:16,zIndex:30},children:t.jsxs("picture",{children:[t.jsx("source",{srcSet:window.origin+"/cloud/speakid/games/whatsmissing/logo.svg",type:"image/svg+xml"}),t.jsx("img",{src:window.origin+"/cloud/speakid/games/whatsmissing/logo.png",alt:"SPEAKID Logo",style:n.gmLogoImg,loading:"lazy"})]})}),[]),ne=1200,oe=700,D=s.useMemo(()=>{const e=r??(typeof window<"u"?window.innerWidth:ne),o=m??(typeof window<"u"?window.innerHeight:oe),c=Math.min(e/ne,o/oe);return Math.min(1.15,Math.max(.92,c))},[r,m,h]);return t.jsx("div",{ref:i,style:{position:"fixed",inset:0,display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",overflow:"hidden",zIndex:1},children:t.jsx("div",{ref:u,style:{width:h?"100%":`${I}px`,height:h?"100%":`${I}px`,borderRadius:h?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",position:"relative",overflow:"hidden",boxShadow:h?"none":"0 0 40px rgba(0,0,0,0.08)",display:"flex",justifyContent:"center",alignItems:"center"},children:t.jsxs("div",{id:"whats-missing-root",style:{transform:`scale(${D})`,transformOrigin:"center center",transition:"transform 0.2s ease-out",width:`${100/D}%`,height:`${100/D}%`,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[!h&&ge,!y&&!b&&t.jsxs("div",{style:n.gmCenterScreen,children:[t.jsx("h1",{style:n.gmHeadline1,children:"WHAT'S MISSING?"}),t.jsx("p",{style:n.gmBodyM,children:"Select a theme:"}),t.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(e=>t.jsx("button",{style:n.gmButton,onClick:()=>C(e),children:e==="animals"?"🐶 Animals":e==="food"?"🍎 Food":"🧸 Toys"},e))}),t.jsxs("div",{style:{marginTop:24},children:[t.jsx("p",{style:n.gmBodyS,children:"Choose number of rounds:"}),t.jsx("div",{style:{display:"flex",gap:12,marginTop:8},children:[3,4,5].map(e=>t.jsx("button",{style:{...n.gmButton,...l===e?n.gmButtonActive:{}},onClick:()=>j(e),children:e},e))})]})]}),y&&!b&&t.jsxs("div",{style:n.gmCenterScreen,children:[t.jsxs("h1",{style:n.gmHeadline1,children:["Theme selected: ",y]}),t.jsxs("p",{style:n.gmBodyM,children:["Rounds: ",l]}),t.jsx("button",{style:n.gmButton,onClick:ee,children:"▶ Start game"})]}),B&&t.jsxs("div",{style:n.gmCenterScreen,children:[t.jsx("h1",{style:n.gmHeadline1,children:"Results"}),t.jsxs("h2",{style:n.gmHeadline3,children:["Your score: ",re," / ",l]}),t.jsx("p",{style:{...n.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),t.jsxs("table",{style:n.gmTable,children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Round"}),t.jsx("th",{children:"Your Answer"}),t.jsx("th",{children:"Correct"}),t.jsx("th",{children:"Result"})]})}),t.jsx("tbody",{children:ae.map((e,o)=>t.jsxs("tr",{children:[t.jsx("td",{style:n.gmTableCell,children:e.round}),t.jsx("td",{style:n.gmTableCell,children:e.answer||"—"}),t.jsx("td",{style:n.gmTableCell,children:e.correct}),t.jsx("td",{style:n.gmTableCell,children:e.result==="correct"?"✔ Correct":e.result==="almost"?"◐ Almost (0.5)":"✘ Wrong"})]},o))})]}),t.jsxs("div",{style:{display:"flex",gap:12,marginTop:24},children:[t.jsx("button",{style:n.gmButton,onClick:ee,children:"🔁 Play again"}),t.jsx("button",{style:n.gmButton,onClick:ue,children:"⬅️ Choose theme"})]})]}),b&&!B&&t.jsxs("div",{style:n.gmGameLayout,children:[t.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[w==="ready"&&t.jsxs(t.Fragment,{children:[t.jsx("h1",{style:{...n.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),t.jsx("div",{style:n.gmHourglass,children:"⏳"})]}),w==="memorize"&&t.jsxs("p",{style:{...n.gmBodyM,color:"#10b981"},children:["MEMORIZE (",E,")"]}),w==="guess"&&!z&&t.jsxs("p",{style:n.gmBodyM,children:["⏳ Time left: ",W,"s"]})]}),w!=="ready"&&t.jsx("div",{style:{...n.gmGrid,display:"grid",gridTemplateColumns:`repeat(${h?2:3}, 1fr)`,gridTemplateRows:`repeat(${h?3:2}, 1fr)`,gap:h?12:20,justifyContent:"center",alignContent:"center",padding:h?8:16,width:"100%",height:"100%",maxWidth:h?"100%":600,maxHeight:h?"100%":400,boxSizing:"border-box"},children:x.map((e,o)=>{const c=p===o&&w==="guess"&&!z;return t.jsx("div",{style:{...n.gmCard,width:"100%",height:"100%",...J==="correct"&&p===o?n.gmCorrect:{},...J==="wrong"&&p===o?n.gmWrong:{}},children:!c&&t.jsx("img",{src:e.src,alt:e.name,style:{width:"100%",height:"100%",objectFit:"cover",display:"block"}})},o)})}),t.jsxs("div",{style:{marginTop:16,height:80},children:[w==="guess"&&!z&&t.jsxs("div",{children:[t.jsx("input",{type:"text",placeholder:"Type the missing word",value:L,onChange:e=>_(e.target.value),style:n.gmInput}),t.jsx("button",{style:{...n.gmButton,marginLeft:8},onClick:ce,disabled:N,children:N?"...":"Check"})]}),z&&t.jsx("button",{type:"button",style:n.gmButton,onClick:me,children:"Next round"})]})]})]})})})}exports.Game=ve;exports.themes=P;
@@ -1,9 +1,9 @@
1
- import { jsx as n, jsxs as l, Fragment as Te } from "react/jsx-runtime";
2
- import { useRef as J, useState as a, useEffect as _, useLayoutEffect as ge, useMemo as Re } from "react";
3
- const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r.map(([s, o]) => ({
4
- src: `${Ie}${u}/${o.replace(/\s/g, "%20")}.png`,
5
- name: o
6
- })), He = [
1
+ import { jsx as n, jsxs as a, Fragment as be } from "react/jsx-runtime";
2
+ import { useRef as Z, useState as d, useMemo as P, useEffect as U, useLayoutEffect as de } from "react";
3
+ const xe = window.origin + "/cloud/speakid/games/whatsmissing/", V = (s, u) => s.map(([r, i]) => ({
4
+ src: `${xe}${u}/${i.replace(/\s/g, "%20")}.png`,
5
+ name: i
6
+ })), ve = [
7
7
  ["apple", "apple"],
8
8
  ["banana", "banana"],
9
9
  ["bread", "bread"],
@@ -29,7 +29,7 @@ const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r
29
29
  ["strawberry", "strawberry"],
30
30
  ["tomato", "tomato"],
31
31
  ["watermelon", "watermelon"]
32
- ], Be = [
32
+ ], Ce = [
33
33
  ["bear", "bear"],
34
34
  ["cat", "cat"],
35
35
  ["crocodile", "crocodile"],
@@ -49,7 +49,7 @@ const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r
49
49
  ["tortoise", "tortoise"],
50
50
  ["wolf", "wolf"],
51
51
  ["zebra", "zebra"]
52
- ], Ae = [
52
+ ], ke = [
53
53
  ["ball", "ball"],
54
54
  ["balloon", "balloon"],
55
55
  ["blocks", "blocks"],
@@ -69,21 +69,21 @@ const Ie = window.origin + "/cloud/speakid/games/whatsmissing/", K = (r, u) => r
69
69
  ["teddy_bear", "teddy bear"],
70
70
  ["yo-yo", "yo-yo"],
71
71
  ["crayons", "crayons"]
72
- ], ue = {
73
- food: K(He, "food"),
74
- animals: K(Be, "animals"),
75
- toys: K(Ae, "toys")
76
- }, Le = `
72
+ ], ae = {
73
+ food: V(ve, "food"),
74
+ animals: V(Ce, "animals"),
75
+ toys: V(ke, "toys")
76
+ }, ze = `
77
77
  @keyframes spin {
78
78
  from { transform: rotate(0deg); }
79
79
  to { transform: rotate(360deg); }
80
80
  }
81
81
  `;
82
82
  if (typeof document < "u" && !document.getElementById("spin-keyframes")) {
83
- const r = document.createElement("style");
84
- r.id = "spin-keyframes", r.innerHTML = Le, document.head.appendChild(r);
83
+ const s = document.createElement("style");
84
+ s.id = "spin-keyframes", s.innerHTML = ze, document.head.appendChild(s);
85
85
  }
86
- const We = {
86
+ const Se = {
87
87
  animation: "spin 1.4s linear infinite"
88
88
  }, t = {
89
89
  gmCenterScreen: {
@@ -239,168 +239,173 @@ const We = {
239
239
  },
240
240
  gmHourglass: {
241
241
  fontSize: "42px",
242
- ...We
242
+ ...Se
243
243
  }
244
- }, Ee = () => {
245
- const r = document.createElement("style");
246
- r.textContent = `
244
+ }, Te = () => {
245
+ const s = document.createElement("style");
246
+ s.textContent = `
247
247
  #whats-missing-root, #whats-missing-root * { box-sizing: border-box; }
248
248
  #whats-missing-root img { max-width:100%; height:auto; display:block; user-select:none; }
249
- `, document.head.appendChild(r);
250
- }, je = (r, u) => {
251
- const s = Array.from({ length: r.length + 1 }, () => Array(u.length + 1).fill(0));
252
- for (let o = 0; o <= r.length; o++) s[o][0] = o;
253
- for (let o = 0; o <= u.length; o++) s[0][o] = o;
254
- for (let o = 1; o <= r.length; o++)
255
- for (let c = 1; c <= u.length; c++)
256
- s[o][c] = r[o - 1] === u[c - 1] ? s[o - 1][c - 1] : Math.min(s[o - 1][c - 1], s[o][c - 1], s[o - 1][c]) + 1;
257
- return s[r.length][u.length];
249
+ `, document.head.appendChild(s);
250
+ }, Re = (s, u) => {
251
+ const r = Array.from({ length: s.length + 1 }, () => Array(u.length + 1).fill(0));
252
+ for (let i = 0; i <= s.length; i++) r[i][0] = i;
253
+ for (let i = 0; i <= u.length; i++) r[0][i] = i;
254
+ for (let i = 1; i <= s.length; i++)
255
+ for (let g = 1; g <= u.length; g++)
256
+ r[i][g] = s[i - 1] === u[g - 1] ? r[i - 1][g - 1] : Math.min(r[i - 1][g - 1], r[i][g - 1], r[i - 1][g]) + 1;
257
+ return r[s.length][u.length];
258
258
  };
259
- function Fe(r, u = { minDesktopWidth: 1200, forceResize: !1 }) {
260
- const s = J(null), o = u.minDesktopWidth ?? 1200, c = !!u.forceResize;
261
- ge(() => {
262
- if (typeof window > "u" || !r || !r.current) return;
263
- const m = r.current, H = () => {
259
+ function Me(s, u = { minDesktopWidth: 1200, forceResize: !1 }) {
260
+ const r = Z(null), i = u.minDesktopWidth ?? 1200, g = !!u.forceResize;
261
+ de(() => {
262
+ if (typeof window > "u" || !s || !s.current) return;
263
+ const c = s.current, M = () => {
264
264
  try {
265
- const d = document.body, h = getComputedStyle(d), M = parseFloat(d.style && d.style.zoom || "");
266
- if (M && !isNaN(M) && M > 0) return M;
267
- const v = parseFloat(h.zoom || "");
268
- if (v && !isNaN(v) && v > 0) return v;
269
- const f = document.createElement("div");
270
- f.style.position = "absolute", f.style.left = "0", f.style.top = "0", f.style.width = "100px", f.style.height = "1px", f.style.visibility = "hidden", document.documentElement.appendChild(f);
271
- const y = f.getBoundingClientRect();
272
- if (document.documentElement.removeChild(f), y && y.width > 0) {
273
- const B = y.width / 100;
274
- if (!isNaN(B) && B > 0) return B;
265
+ const l = document.body, C = getComputedStyle(l), x = parseFloat(l.style && l.style.zoom || "");
266
+ if (x && !isNaN(x) && x > 0) return x;
267
+ const k = parseFloat(C.zoom || "");
268
+ if (k && !isNaN(k) && k > 0) return k;
269
+ const h = document.createElement("div");
270
+ h.style.position = "absolute", h.style.left = "0", h.style.top = "0", h.style.width = "100px", h.style.height = "1px", h.style.visibility = "hidden", document.documentElement.appendChild(h);
271
+ const T = h.getBoundingClientRect();
272
+ if (document.documentElement.removeChild(h), T && T.width > 0) {
273
+ const y = T.width / 100;
274
+ if (!isNaN(y) && y > 0) return y;
275
275
  }
276
276
  } catch {
277
277
  }
278
278
  return 1;
279
- }, C = () => {
280
- if (o && window.innerWidth < o) {
281
- R();
279
+ }, B = () => {
280
+ if (i && window.innerWidth < i) {
281
+ w();
282
282
  return;
283
283
  }
284
- const d = H();
285
- if (!d || d === 1) {
286
- R();
284
+ const l = M();
285
+ if (!l || l === 1) {
286
+ w();
287
287
  return;
288
288
  }
289
- s.current || (s.current = {
290
- transform: m.style.transform || null,
291
- transformOrigin: m.style.transformOrigin || null,
292
- width: m.style.width || null,
293
- height: m.style.height || null,
294
- willChange: m.style.willChange || null
289
+ r.current || (r.current = {
290
+ transform: c.style.transform || null,
291
+ transformOrigin: c.style.transformOrigin || null,
292
+ width: c.style.width || null,
293
+ height: c.style.height || null,
294
+ willChange: c.style.willChange || null
295
295
  });
296
- const h = 1 / d;
297
- c && (m.style.width = `${d * 100}%`, m.style.height = `${d * 100}%`), m.style.transformOrigin = "50% 50%", m.style.transform = `scale(${h})`, m.style.willChange = "transform";
298
- }, R = () => {
299
- if (!s.current) return;
300
- const d = s.current;
301
- m.style.transform = d.transform ?? "", m.style.transformOrigin = d.transformOrigin ?? "", m.style.width = d.width ?? "", m.style.height = d.height ?? "", m.style.willChange = d.willChange ?? "", s.current = null;
296
+ const C = 1 / l;
297
+ g && (c.style.width = `${l * 100}%`, c.style.height = `${l * 100}%`), c.style.transformOrigin = "50% 50%", c.style.transform = `scale(${C})`, c.style.willChange = "transform";
298
+ }, w = () => {
299
+ if (!r.current) return;
300
+ const l = r.current;
301
+ c.style.transform = l.transform ?? "", c.style.transformOrigin = l.transformOrigin ?? "", c.style.width = l.width ?? "", c.style.height = l.height ?? "", c.style.willChange = l.willChange ?? "", r.current = null;
302
302
  };
303
- let x = 0;
304
- const k = () => {
305
- cancelAnimationFrame(x), x = requestAnimationFrame(C);
306
- }, z = new MutationObserver((d) => {
307
- for (const h of d)
308
- if (h.type === "attributes" && (h.attributeName === "style" || h.attributeName === "class")) {
309
- k();
303
+ let S = 0;
304
+ const b = () => {
305
+ cancelAnimationFrame(S), S = requestAnimationFrame(B);
306
+ }, I = new MutationObserver((l) => {
307
+ for (const C of l)
308
+ if (C.type === "attributes" && (C.attributeName === "style" || C.attributeName === "class")) {
309
+ b();
310
310
  break;
311
311
  }
312
312
  });
313
- return z.observe(document.body, { attributes: !0, attributeFilter: ["style", "class"] }), window.addEventListener("resize", k), k(), () => {
314
- cancelAnimationFrame(x), z.disconnect(), window.removeEventListener("resize", k), R();
313
+ return I.observe(document.body, { attributes: !0, attributeFilter: ["style", "class"] }), window.addEventListener("resize", b), b(), () => {
314
+ cancelAnimationFrame(S), I.disconnect(), window.removeEventListener("resize", b), w();
315
315
  };
316
- }, [r, o, c]);
316
+ }, [s, i, g]);
317
317
  }
318
- function De({
319
- gameCubeSize: r,
318
+ function Be({
319
+ gameCubeSize: s,
320
320
  screenHeight: u,
321
- screenWidth: s
321
+ screenWidth: r
322
322
  }) {
323
- const o = J(null), c = J(null), [m, H] = a(null);
324
- Fe(o, { minDesktopWidth: 1200, forceResize: !1 }), _(() => (Ee(), () => {
323
+ const i = Z(null), g = Z(null), [c, M] = d(null);
324
+ Me(i, { minDesktopWidth: 1024, forceResize: !1 });
325
+ const B = P(() => {
326
+ const e = s ?? Math.min(r ?? 1e3, u ?? 1e3), o = r ?? (typeof window < "u" ? window.innerWidth : 1e3);
327
+ return e < 600 && o > 768 ? 600 : o <= 768 ? Math.min(e, o - 20) : e;
328
+ }, [s, r, u]);
329
+ U(() => (Te(), () => {
325
330
  document.body.style.overflow = "";
326
331
  }), []);
327
- const [C, R] = a(null), [x, k] = a([]), [z, d] = a(4), [h, M] = a(!1), [v, f] = a(1), [y, B] = a(null), [b, E] = a("ready"), [Q, X] = a(3), [G, N] = a(10), [D, ee] = a(20), [he, O] = a(0), [j, q] = a(!1), [F, te] = a(""), [I, Y] = a(!1), [P, ne] = a(!1), [oe, A] = a(null), [fe, U] = a([]), [pe, ie] = a([]), [S, ye] = a(!1);
328
- _(() => {
332
+ const [w, S] = d(null), [b, I] = d([]), [l, C] = d(4), [x, k] = d(!1), [h, T] = d(1), [y, ce] = d(null), [v, L] = d("ready"), [_, K] = d(3), [E, j] = d(10), [F, J] = d(20), [me, $] = d(0), [A, G] = d(!1), [W, Q] = d(""), [R, N] = d(!1), [D, X] = d(!1), [ee, H] = d(null), [ue, O] = d([]), [ge, te] = d([]), [f, he] = d(!1);
333
+ U(() => {
329
334
  if (typeof window > "u") return;
330
335
  const e = () => {
331
- const i = s ?? window.innerWidth;
332
- ye(i <= 768);
336
+ const o = r ?? window.innerWidth, m = window.matchMedia && window.matchMedia("(pointer: coarse)").matches;
337
+ he(o <= 768 || m);
333
338
  };
334
339
  return e(), window.addEventListener("resize", e), window.addEventListener("orientationchange", e), () => {
335
340
  window.removeEventListener("resize", e), window.removeEventListener("orientationchange", e);
336
341
  };
337
- }, [s]), ge(() => {
338
- const e = c.current;
342
+ }, [r]), de(() => {
343
+ const e = g.current;
339
344
  if (!e || typeof window > "u") return;
340
- let i = null;
345
+ let o = null;
341
346
  try {
342
- i = new ResizeObserver((p) => {
343
- for (const g of p) {
344
- const w = g.contentRect;
345
- H(Math.round(Math.min(w.width, w.height)));
347
+ o = new ResizeObserver((m) => {
348
+ for (const p of m) {
349
+ const z = p.contentRect;
350
+ M(Math.round(Math.min(z.width, z.height)));
346
351
  }
347
- }), i.observe(e), H(Math.round(Math.min(e.clientWidth, e.clientHeight)));
352
+ }), o.observe(e), M(Math.round(Math.min(e.clientWidth, e.clientHeight)));
348
353
  } catch {
349
- H(Math.round(Math.min(e.clientWidth, e.clientHeight)));
354
+ M(Math.round(Math.min(e.clientWidth, e.clientHeight)));
350
355
  }
351
- return () => i?.disconnect();
352
- }, [S]);
353
- const re = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), se = () => {
354
- if (!C) return;
355
- const e = re(ue[C]);
356
- k(e), M(!0), q(!1), f(1), O(0), U([]), ie([]), le(e, [], !0);
357
- }, le = (e = x, i = pe, p = !1) => {
358
- const g = re(e.length ? e : ue[C]);
359
- let w = Math.floor(Math.random() * g.length), T = g[w].name, L = 0;
360
- for (; i.includes(T) && L < 20; )
361
- w = Math.floor(Math.random() * g.length), T = g[w].name, L++;
362
- k(g), B(w), ie([...i, T]), Y(!1), te(""), ee(20), A(null), p ? (E("ready"), X(3), N(10)) : (E("memorize"), N(10));
356
+ return () => o?.disconnect();
357
+ }, [f]);
358
+ const ne = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), oe = () => {
359
+ if (!w) return;
360
+ const e = ne(ae[w]);
361
+ I(e), k(!0), G(!1), T(1), $(0), O([]), te([]), ie(e, [], !0);
362
+ }, ie = (e = b, o = ge, m = !1) => {
363
+ const p = ne(e.length ? e : ae[w]);
364
+ let z = Math.floor(Math.random() * p.length), Y = p[z].name, le = 0;
365
+ for (; o.includes(Y) && le < 20; )
366
+ z = Math.floor(Math.random() * p.length), Y = p[z].name, le++;
367
+ I(p), ce(z), te([...o, Y]), N(!1), Q(""), J(20), H(null), m ? (L("ready"), K(3), j(10)) : (L("memorize"), j(10));
363
368
  };
364
- _(() => {
365
- if (!(!h || j || I)) {
366
- if (b === "ready")
367
- if (Q <= 0) E("memorize");
369
+ U(() => {
370
+ if (!(!x || A || R)) {
371
+ if (v === "ready")
372
+ if (_ <= 0) L("memorize");
368
373
  else {
369
- const e = setTimeout(() => X((i) => i - 1), 1e3);
374
+ const e = setTimeout(() => K((o) => o - 1), 1e3);
370
375
  return () => clearTimeout(e);
371
376
  }
372
- if (b === "memorize")
373
- if (G <= 0) E("guess");
377
+ if (v === "memorize")
378
+ if (E <= 0) L("guess");
374
379
  else {
375
- const e = setTimeout(() => N((i) => i - 1), 1e3);
380
+ const e = setTimeout(() => j((o) => o - 1), 1e3);
376
381
  return () => clearTimeout(e);
377
382
  }
378
- if (b === "guess") {
379
- if (D <= 0) {
380
- Y(!0), A("wrong");
381
- const i = x[y].name;
382
- U((p) => [
383
- ...p,
384
- { round: v, answer: F, correct: i, result: "wrong" }
383
+ if (v === "guess") {
384
+ if (F <= 0) {
385
+ N(!0), H("wrong");
386
+ const o = b[y].name;
387
+ O((m) => [
388
+ ...m,
389
+ { round: h, answer: W, correct: o, result: "wrong" }
385
390
  ]);
386
391
  return;
387
392
  }
388
- const e = setTimeout(() => ee((i) => i - 1), 1e3);
393
+ const e = setTimeout(() => J((o) => o - 1), 1e3);
389
394
  return () => clearTimeout(e);
390
395
  }
391
396
  }
392
- }, [b, Q, G, D, h, j, I, x, y, v, F]);
393
- const be = () => {
394
- if (y === null || P) return;
395
- const e = x[y].name, i = F.toLowerCase().trim();
396
- let p = "wrong";
397
- i === e ? (O((g) => g + 1), A("correct"), p = "correct") : je(i, e) === 1 ? (O((g) => g + 0.5), A("almost"), p = "almost") : (A("wrong"), p = "wrong"), U((g) => [...g, { round: v, answer: i, correct: e, result: p }]), ne(!0), setTimeout(() => {
398
- ne(!1), Y(!0);
397
+ }, [v, _, E, F, x, A, R, b, y, h, W]);
398
+ const fe = () => {
399
+ if (y === null || D) return;
400
+ const e = b[y].name, o = W.toLowerCase().trim();
401
+ let m = "wrong";
402
+ o === e ? ($((p) => p + 1), H("correct"), m = "correct") : Re(o, e) === 1 ? ($((p) => p + 0.5), H("almost"), m = "almost") : (H("wrong"), m = "wrong"), O((p) => [...p, { round: h, answer: o, correct: e, result: m }]), X(!0), setTimeout(() => {
403
+ X(!1), N(!0);
399
404
  }, 600);
400
- }, we = () => v < z ? (f((e) => e + 1), le()) : q(!0), xe = () => {
401
- M(!1), q(!1), R(null);
402
- }, ve = Re(
403
- () => /* @__PURE__ */ n("div", { style: { ...t.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }, children: /* @__PURE__ */ l("picture", { children: [
405
+ }, pe = () => h < l ? (T((e) => e + 1), ie()) : G(!0), ye = () => {
406
+ k(!1), G(!1), S(null);
407
+ }, we = P(
408
+ () => /* @__PURE__ */ n("div", { style: { ...t.gmLogoFixed, position: "absolute", top: 16, left: 16, zIndex: 30 }, children: /* @__PURE__ */ a("picture", { children: [
404
409
  /* @__PURE__ */ n(
405
410
  "source",
406
411
  {
@@ -419,11 +424,14 @@ function De({
419
424
  )
420
425
  ] }) }),
421
426
  []
422
- ), ae = 1440, de = 900, Ce = c.current?.clientWidth ?? s ?? (typeof window < "u" ? window.innerWidth : ae), ke = c.current?.clientHeight ?? u ?? (typeof window < "u" ? window.innerHeight : de), V = Math.min(Ce / ae, ke / de);
427
+ ), re = 1200, se = 700, q = P(() => {
428
+ const e = r ?? (typeof window < "u" ? window.innerWidth : re), o = u ?? (typeof window < "u" ? window.innerHeight : se), m = Math.min(e / re, o / se);
429
+ return Math.min(1.15, Math.max(0.92, m));
430
+ }, [r, u, f]);
423
431
  return /* @__PURE__ */ n(
424
432
  "div",
425
433
  {
426
- ref: o,
434
+ ref: i,
427
435
  style: {
428
436
  position: "fixed",
429
437
  inset: 0,
@@ -437,96 +445,97 @@ function De({
437
445
  children: /* @__PURE__ */ n(
438
446
  "div",
439
447
  {
440
- ref: c,
448
+ ref: g,
441
449
  style: {
442
- width: S ? "100%" : `${Math.min(r ?? 1e3, s ?? 1e3, u ?? 1e3)}px`,
443
- height: S ? "100%" : `${Math.min(r ?? 1e3, s ?? 1e3, u ?? 1e3)}px`,
444
- borderRadius: S ? 0 : "20px",
450
+ width: f ? "100%" : `${B}px`,
451
+ height: f ? "100%" : `${B}px`,
452
+ borderRadius: f ? 0 : "20px",
445
453
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
446
454
  position: "relative",
447
455
  overflow: "hidden",
448
- boxShadow: S ? "none" : "0 0 40px rgba(0,0,0,0.08)",
456
+ boxShadow: f ? "none" : "0 0 40px rgba(0,0,0,0.08)",
449
457
  display: "flex",
450
458
  justifyContent: "center",
451
459
  alignItems: "center"
452
460
  },
453
- children: /* @__PURE__ */ l(
461
+ children: /* @__PURE__ */ a(
454
462
  "div",
455
463
  {
456
464
  id: "whats-missing-root",
457
465
  style: {
458
- transform: `scale(${V})`,
466
+ transform: `scale(${q})`,
459
467
  transformOrigin: "center center",
460
- width: `${100 / V}%`,
461
- height: `${100 / V}%`,
468
+ transition: "transform 0.2s ease-out",
469
+ width: `${100 / q}%`,
470
+ height: `${100 / q}%`,
462
471
  display: "flex",
463
472
  flexDirection: "column",
464
473
  justifyContent: "center",
465
474
  alignItems: "center"
466
475
  },
467
476
  children: [
468
- !S && ve,
469
- !C && !h && /* @__PURE__ */ l("div", { style: t.gmCenterScreen, children: [
477
+ !f && we,
478
+ !w && !x && /* @__PURE__ */ a("div", { style: t.gmCenterScreen, children: [
470
479
  /* @__PURE__ */ n("h1", { style: t.gmHeadline1, children: "WHAT'S MISSING?" }),
471
480
  /* @__PURE__ */ n("p", { style: t.gmBodyM, children: "Select a theme:" }),
472
- /* @__PURE__ */ n("div", { style: { display: "flex", gap: 16 }, children: ["animals", "food", "toys"].map((e) => /* @__PURE__ */ n("button", { style: t.gmButton, onClick: () => R(e), children: e === "animals" ? "🐶 Animals" : e === "food" ? "🍎 Food" : "🧸 Toys" }, e)) }),
473
- /* @__PURE__ */ l("div", { style: { marginTop: 24 }, children: [
481
+ /* @__PURE__ */ n("div", { style: { display: "flex", gap: 16 }, children: ["animals", "food", "toys"].map((e) => /* @__PURE__ */ n("button", { style: t.gmButton, onClick: () => S(e), children: e === "animals" ? "🐶 Animals" : e === "food" ? "🍎 Food" : "🧸 Toys" }, e)) }),
482
+ /* @__PURE__ */ a("div", { style: { marginTop: 24 }, children: [
474
483
  /* @__PURE__ */ n("p", { style: t.gmBodyS, children: "Choose number of rounds:" }),
475
484
  /* @__PURE__ */ n("div", { style: { display: "flex", gap: 12, marginTop: 8 }, children: [3, 4, 5].map((e) => /* @__PURE__ */ n(
476
485
  "button",
477
486
  {
478
487
  style: {
479
488
  ...t.gmButton,
480
- ...z === e ? t.gmButtonActive : {}
489
+ ...l === e ? t.gmButtonActive : {}
481
490
  },
482
- onClick: () => d(e),
491
+ onClick: () => C(e),
483
492
  children: e
484
493
  },
485
494
  e
486
495
  )) })
487
496
  ] })
488
497
  ] }),
489
- C && !h && /* @__PURE__ */ l("div", { style: t.gmCenterScreen, children: [
490
- /* @__PURE__ */ l("h1", { style: t.gmHeadline1, children: [
498
+ w && !x && /* @__PURE__ */ a("div", { style: t.gmCenterScreen, children: [
499
+ /* @__PURE__ */ a("h1", { style: t.gmHeadline1, children: [
491
500
  "Theme selected: ",
492
- C
501
+ w
493
502
  ] }),
494
- /* @__PURE__ */ l("p", { style: t.gmBodyM, children: [
503
+ /* @__PURE__ */ a("p", { style: t.gmBodyM, children: [
495
504
  "Rounds: ",
496
- z
505
+ l
497
506
  ] }),
498
- /* @__PURE__ */ n("button", { style: t.gmButton, onClick: se, children: "▶ Start game" })
507
+ /* @__PURE__ */ n("button", { style: t.gmButton, onClick: oe, children: "▶ Start game" })
499
508
  ] }),
500
- j && /* @__PURE__ */ l("div", { style: t.gmCenterScreen, children: [
509
+ A && /* @__PURE__ */ a("div", { style: t.gmCenterScreen, children: [
501
510
  /* @__PURE__ */ n("h1", { style: t.gmHeadline1, children: "Results" }),
502
- /* @__PURE__ */ l("h2", { style: t.gmHeadline3, children: [
511
+ /* @__PURE__ */ a("h2", { style: t.gmHeadline3, children: [
503
512
  "Your score: ",
504
- he,
513
+ me,
505
514
  " / ",
506
- z
515
+ l
507
516
  ] }),
508
517
  /* @__PURE__ */ n("p", { style: { ...t.gmBodyM, color: "#10b981", marginTop: 12 }, children: "Yahoo! You did it! 🍬✨" }),
509
- /* @__PURE__ */ l("table", { style: t.gmTable, children: [
510
- /* @__PURE__ */ n("thead", { children: /* @__PURE__ */ l("tr", { children: [
518
+ /* @__PURE__ */ a("table", { style: t.gmTable, children: [
519
+ /* @__PURE__ */ n("thead", { children: /* @__PURE__ */ a("tr", { children: [
511
520
  /* @__PURE__ */ n("th", { children: "Round" }),
512
521
  /* @__PURE__ */ n("th", { children: "Your Answer" }),
513
522
  /* @__PURE__ */ n("th", { children: "Correct" }),
514
523
  /* @__PURE__ */ n("th", { children: "Result" })
515
524
  ] }) }),
516
- /* @__PURE__ */ n("tbody", { children: fe.map((e, i) => /* @__PURE__ */ l("tr", { children: [
525
+ /* @__PURE__ */ n("tbody", { children: ue.map((e, o) => /* @__PURE__ */ a("tr", { children: [
517
526
  /* @__PURE__ */ n("td", { style: t.gmTableCell, children: e.round }),
518
527
  /* @__PURE__ */ n("td", { style: t.gmTableCell, children: e.answer || "—" }),
519
528
  /* @__PURE__ */ n("td", { style: t.gmTableCell, children: e.correct }),
520
529
  /* @__PURE__ */ n("td", { style: t.gmTableCell, children: e.result === "correct" ? "✔ Correct" : e.result === "almost" ? "◐ Almost (0.5)" : "✘ Wrong" })
521
- ] }, i)) })
530
+ ] }, o)) })
522
531
  ] }),
523
- /* @__PURE__ */ l("div", { style: { display: "flex", gap: 12, marginTop: 24 }, children: [
524
- /* @__PURE__ */ n("button", { style: t.gmButton, onClick: se, children: "🔁 Play again" }),
525
- /* @__PURE__ */ n("button", { style: t.gmButton, onClick: xe, children: "⬅️ Choose theme" })
532
+ /* @__PURE__ */ a("div", { style: { display: "flex", gap: 12, marginTop: 24 }, children: [
533
+ /* @__PURE__ */ n("button", { style: t.gmButton, onClick: oe, children: "🔁 Play again" }),
534
+ /* @__PURE__ */ n("button", { style: t.gmButton, onClick: ye, children: "⬅️ Choose theme" })
526
535
  ] })
527
536
  ] }),
528
- h && !j && /* @__PURE__ */ l("div", { style: t.gmGameLayout, children: [
529
- /* @__PURE__ */ l(
537
+ x && !A && /* @__PURE__ */ a("div", { style: t.gmGameLayout, children: [
538
+ /* @__PURE__ */ a(
530
539
  "div",
531
540
  {
532
541
  style: {
@@ -537,87 +546,81 @@ function De({
537
546
  alignItems: "center"
538
547
  },
539
548
  children: [
540
- b === "ready" && /* @__PURE__ */ l(Te, { children: [
549
+ v === "ready" && /* @__PURE__ */ a(be, { children: [
541
550
  /* @__PURE__ */ n("h1", { style: { ...t.gmHeadline1, color: "#ec4c44" }, children: "GET READY" }),
542
551
  /* @__PURE__ */ n("div", { style: t.gmHourglass, children: "⏳" })
543
552
  ] }),
544
- b === "memorize" && /* @__PURE__ */ l("p", { style: { ...t.gmBodyM, color: "#10b981" }, children: [
553
+ v === "memorize" && /* @__PURE__ */ a("p", { style: { ...t.gmBodyM, color: "#10b981" }, children: [
545
554
  "MEMORIZE (",
546
- G,
555
+ E,
547
556
  ")"
548
557
  ] }),
549
- b === "guess" && !I && /* @__PURE__ */ l("p", { style: t.gmBodyM, children: [
558
+ v === "guess" && !R && /* @__PURE__ */ a("p", { style: t.gmBodyM, children: [
550
559
  "⏳ Time left: ",
551
- D,
560
+ F,
552
561
  "s"
553
562
  ] })
554
563
  ]
555
564
  }
556
565
  ),
557
- b !== "ready" && (() => {
558
- const e = S ? 12 : 20, i = 32, p = c.current?.clientWidth ?? Math.min(r ?? 1e3, s ?? 1e3), g = c.current?.clientHeight ?? Math.min(r ?? 1e3, u ?? 1e3), w = Math.min(p, g), T = typeof window < "u" ? window.innerWidth : s ?? 1e3, L = T < 600 ? 110 : T < 900 ? 130 : T < 1280 ? 150 : 180, ze = 4, ce = 2, Z = Math.max(
559
- ce,
560
- Math.min(
561
- ze,
562
- Math.floor((w - i + e) / (L + e)) || ce
563
- )
564
- ), Me = Math.floor((w - i - e * (Z - 1)) / Z), W = Math.max(L, Me);
565
- return /* @__PURE__ */ n(
566
- "div",
567
- {
568
- style: {
569
- ...t.gmGrid,
570
- gridTemplateColumns: `repeat(${Z}, ${W}px)`,
571
- gridAutoRows: `${W}px`,
572
- gap: `${e}px`,
573
- justifyContent: "center",
574
- justifyItems: "center",
575
- padding: 8,
576
- boxSizing: "border-box"
577
- },
578
- children: x.map((me, $) => {
579
- const Se = y === $ && b === "guess" && !I;
580
- return /* @__PURE__ */ n(
581
- "div",
582
- {
583
- style: {
584
- ...t.gmCard,
585
- width: `${W}px`,
586
- height: `${W}px`,
587
- padding: W >= 160 ? 10 : 8,
588
- boxSizing: "border-box",
589
- ...oe === "correct" && y === $ ? t.gmCorrect : {},
590
- ...oe === "wrong" && y === $ ? t.gmWrong : {}
591
- },
592
- children: !Se && /* @__PURE__ */ n(
593
- "img",
594
- {
595
- src: me.src,
596
- alt: me.name,
597
- style: {
598
- width: "100%",
599
- height: "100%",
600
- objectFit: "cover",
601
- display: "block"
602
- }
603
- }
604
- )
566
+ v !== "ready" && /* @__PURE__ */ n(
567
+ "div",
568
+ {
569
+ style: {
570
+ ...t.gmGrid,
571
+ display: "grid",
572
+ gridTemplateColumns: `repeat(${f ? 2 : 3}, 1fr)`,
573
+ gridTemplateRows: `repeat(${f ? 3 : 2}, 1fr)`,
574
+ gap: f ? 12 : 20,
575
+ justifyContent: "center",
576
+ alignContent: "center",
577
+ padding: f ? 8 : 16,
578
+ width: "100%",
579
+ height: "100%",
580
+ maxWidth: f ? "100%" : 600,
581
+ maxHeight: f ? "100%" : 400,
582
+ boxSizing: "border-box"
583
+ },
584
+ children: b.map((e, o) => {
585
+ const m = y === o && v === "guess" && !R;
586
+ return /* @__PURE__ */ n(
587
+ "div",
588
+ {
589
+ style: {
590
+ ...t.gmCard,
591
+ width: "100%",
592
+ height: "100%",
593
+ ...ee === "correct" && y === o ? t.gmCorrect : {},
594
+ ...ee === "wrong" && y === o ? t.gmWrong : {}
605
595
  },
606
- $
607
- );
608
- })
609
- }
610
- );
611
- })(),
612
- /* @__PURE__ */ l("div", { style: { marginTop: 16, height: 80 }, children: [
613
- b === "guess" && !I && /* @__PURE__ */ l("div", { children: [
596
+ children: !m && /* @__PURE__ */ n(
597
+ "img",
598
+ {
599
+ src: e.src,
600
+ alt: e.name,
601
+ style: {
602
+ width: "100%",
603
+ height: "100%",
604
+ objectFit: "cover",
605
+ display: "block"
606
+ }
607
+ }
608
+ )
609
+ },
610
+ o
611
+ );
612
+ })
613
+ }
614
+ ),
615
+ /* @__PURE__ */ a("div", { style: { marginTop: 16, height: 80 }, children: [
616
+ v === "guess" && !R && /* @__PURE__ */ a("div", { children: [
614
617
  /* @__PURE__ */ n(
615
618
  "input",
616
619
  {
617
620
  type: "text",
618
621
  placeholder: "Type the missing word",
619
- value: F,
620
- onChange: (e) => te(e.target.value),
622
+ value: W,
623
+ onChange: (e) => Q(e.target.value),
621
624
  style: t.gmInput
622
625
  }
623
626
  ),
@@ -625,13 +628,13 @@ function De({
625
628
  "button",
626
629
  {
627
630
  style: { ...t.gmButton, marginLeft: 8 },
628
- onClick: be,
629
- disabled: P,
630
- children: P ? "..." : "Check"
631
+ onClick: fe,
632
+ disabled: D,
633
+ children: D ? "..." : "Check"
631
634
  }
632
635
  )
633
636
  ] }),
634
- I && /* @__PURE__ */ n("button", { type: "button", style: t.gmButton, onClick: we, children: "Next round" })
637
+ R && /* @__PURE__ */ n("button", { type: "button", style: t.gmButton, onClick: pe, children: "Next round" })
635
638
  ] })
636
639
  ] })
637
640
  ]
@@ -643,6 +646,6 @@ function De({
643
646
  );
644
647
  }
645
648
  export {
646
- De as Game,
647
- ue as themes
649
+ Be as Game,
650
+ ae as themes
648
651
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mblinkov/whats-missing",
3
- "version": "20.0.30",
3
+ "version": "20.0.32",
4
4
  "main": "dist/whats-missing.umd.js",
5
5
  "module": "dist/whats-missing.es.js",
6
6
  "types": "dist/index.d.ts",
package/src/Game.tsx CHANGED
@@ -157,7 +157,25 @@ export default function Game({
157
157
  const containerRef = useRef<HTMLDivElement | null>(null);
158
158
  const squareRef = useRef<HTMLDivElement | null>(null);
159
159
  const [squareSize, setSquareSize] = useState<number | null>(null);
160
- useNeutralizeBodyZoom(containerRef, { minDesktopWidth: 1200, forceResize: false });
160
+ useNeutralizeBodyZoom(containerRef, { minDesktopWidth: 1024, forceResize: false });
161
+
162
+ // ✅ защита от слишком маленьких размеров игры
163
+ const effectiveGameCubeSize = useMemo(() => {
164
+ const baseSize = gameCubeSize ?? Math.min(screenWidth ?? 1000, screenHeight ?? 1000);
165
+ const currentWidth = screenWidth ?? (typeof window !== "undefined" ? window.innerWidth : 1000);
166
+
167
+ // минимальный предел для десктопа и планшета
168
+ if (baseSize < 600 && currentWidth > 768) {
169
+ return 600;
170
+ }
171
+
172
+ // для мобилок в портретной ориентации пусть остаётся адаптивным
173
+ if (currentWidth <= 768) {
174
+ return Math.min(baseSize, currentWidth - 20);
175
+ }
176
+
177
+ return baseSize;
178
+ }, [gameCubeSize, screenWidth, screenHeight]);
161
179
 
162
180
  useEffect(() => {
163
181
  globalReset();
@@ -191,7 +209,8 @@ export default function Game({
191
209
  if (typeof window === "undefined") return;
192
210
  const update = () => {
193
211
  const w = screenWidth ?? window.innerWidth;
194
- setIsMobile(w <= 768);
212
+ const hasCoarsePointer = window.matchMedia && window.matchMedia('(pointer: coarse)').matches;
213
+ setIsMobile(w <= 768 || hasCoarsePointer);
195
214
  };
196
215
  update();
197
216
  window.addEventListener("resize", update);
@@ -349,13 +368,17 @@ export default function Game({
349
368
  []
350
369
  );
351
370
 
352
- // ✅ масштаб интерфейса под доступный размер контейнера не всей вкладки)
353
- // это устраняет резкие перепады масштаба при открытии DevTools или панелей браузера
354
- const baseWidth = 1440;
355
- const baseHeight = 900;
356
- const effectiveWidth = squareRef.current?.clientWidth ?? (screenWidth ?? (typeof window !== "undefined" ? window.innerWidth : baseWidth));
357
- const effectiveHeight = squareRef.current?.clientHeight ?? (screenHeight ?? (typeof window !== "undefined" ? window.innerHeight : baseHeight));
358
- const scale = Math.min(effectiveWidth / baseWidth, effectiveHeight / baseHeight);
371
+ // ✅ масштаб интерфейса под размеры окна с мягкими лимитами и кэшированием
372
+ // оптимизированные базовые размеры для лучшего покрытия экрана на десктопах
373
+ const baseWidth = 1200;
374
+ const baseHeight = 700;
375
+ const scale = useMemo(() => {
376
+ const effectiveWidth = screenWidth ?? (typeof window !== "undefined" ? window.innerWidth : baseWidth);
377
+ const effectiveHeight = screenHeight ?? (typeof window !== "undefined" ? window.innerHeight : baseHeight);
378
+ const rawScale = Math.min(effectiveWidth / baseWidth, effectiveHeight / baseHeight);
379
+ // мягкие границы роста/сжатия
380
+ return Math.min(1.15, Math.max(0.92, rawScale));
381
+ }, [screenWidth, screenHeight, isMobile]);
359
382
 
360
383
  return (
361
384
  <div
@@ -376,10 +399,10 @@ export default function Game({
376
399
  style={{
377
400
  width: isMobile
378
401
  ? "100%"
379
- : `${Math.min(gameCubeSize ?? 1000, screenWidth ?? 1000, screenHeight ?? 1000)}px`,
402
+ : `${effectiveGameCubeSize}px`,
380
403
  height: isMobile
381
404
  ? "100%"
382
- : `${Math.min(gameCubeSize ?? 1000, screenWidth ?? 1000, screenHeight ?? 1000)}px`,
405
+ : `${effectiveGameCubeSize}px`,
383
406
  borderRadius: isMobile ? 0 : "20px",
384
407
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
385
408
  position: "relative",
@@ -395,6 +418,7 @@ export default function Game({
395
418
  style={{
396
419
  transform: `scale(${scale})`,
397
420
  transformOrigin: "center center",
421
+ transition: "transform 0.2s ease-out",
398
422
  width: `${100 / scale}%`,
399
423
  height: `${100 / scale}%`,
400
424
  display: "flex",
@@ -523,85 +547,55 @@ export default function Game({
523
547
  )}
524
548
  </div>
525
549
 
526
- {/* Сетка карточек */}
527
- {phase !== "ready" && (() => {
528
- const gap = isMobile ? 12 : 20;
529
- const innerGutters = 32; // total padding inside the grid wrapper
530
- const effW = squareRef.current?.clientWidth ?? Math.min(gameCubeSize ?? 1000, screenWidth ?? 1000);
531
- const effH = squareRef.current?.clientHeight ?? Math.min(gameCubeSize ?? 1000, screenHeight ?? 1000);
532
- const effective = Math.min(effW, effH);
533
-
534
- // choose a comfortable minimum card size per breakpoint
535
- const vw = typeof window !== "undefined" ? window.innerWidth : (screenWidth ?? 1000);
536
- // Tune breakpoints so common laptop sizes (e.g., 1366×768) keep a 3×3 grid
537
- // by allowing a slightly smaller minimum card size when width < 1280.
538
- const minCardBase = vw < 600 ? 110 : vw < 900 ? 130 : vw < 1280 ? 150 : 180;
539
-
540
- // compute columns to best fill available space without going below minCardBase
541
- const maxColumns = 4;
542
- const minColumns = 2;
543
- const possibleColumns = Math.max(
544
- minColumns,
545
- Math.min(
546
- maxColumns,
547
- Math.floor((effective - innerGutters + gap) / (minCardBase + gap)) || minColumns
548
- )
549
- );
550
-
551
- const columns = possibleColumns;
552
- const computed = Math.floor((effective - innerGutters - gap * (columns - 1)) / columns);
553
- const cardSize = Math.max(minCardBase, computed);
554
-
555
- return (
556
- <div
557
- style={{
558
- ...styles.gmGrid,
559
- gridTemplateColumns: `repeat(${columns}, ${cardSize}px)`,
560
- gridAutoRows: `${cardSize}px`,
561
- gap: `${gap}px`,
562
- justifyContent: "center",
563
- justifyItems: "center",
564
- padding: 8,
565
- boxSizing: "border-box",
566
- }}
567
- >
568
- {files.map((file, i) => {
569
- const isHidden = hiddenIndex === i && phase === "guess" && !answered;
570
- return (
571
- <div
572
- key={i}
573
- style={{
574
- ...styles.gmCard,
575
- width: `${cardSize}px`,
576
- height: `${cardSize}px`,
577
- padding: cardSize >= 160 ? 10 : 8,
578
- boxSizing: "border-box",
579
- ...(result === "correct" && hiddenIndex === i
580
- ? styles.gmCorrect
581
- : {}),
582
- ...(result === "wrong" && hiddenIndex === i
583
- ? styles.gmWrong
584
- : {}),
585
- }}
586
- >
587
- {!isHidden && (
588
- <img
589
- src={file.src}
590
- alt={file.name}
591
- style={{
592
- width: "100%",
593
- height: "100%",
594
- objectFit: "cover",
595
- display: "block",
596
- }}
597
- />
598
- )}
599
- </div>
600
- );
601
- })}
602
- </div>
603
- );
604
- })()}
550
+ {/* ===== Сетка карточек (фикс 3×2 на десктопе, 2×3 на мобилках) ===== */}
551
+ {phase !== "ready" && (
552
+ <div
553
+ style={{
554
+ ...styles.gmGrid,
555
+ display: "grid",
556
+ gridTemplateColumns: `repeat(${isMobile ? 2 : 3}, 1fr)`,
557
+ gridTemplateRows: `repeat(${isMobile ? 3 : 2}, 1fr)`,
558
+ gap: isMobile ? 12 : 20,
559
+ justifyContent: "center",
560
+ alignContent: "center",
561
+ padding: isMobile ? 8 : 16,
562
+ width: "100%",
563
+ height: "100%",
564
+ maxWidth: isMobile ? "100%" : 600,
565
+ maxHeight: isMobile ? "100%" : 400,
566
+ boxSizing: "border-box",
567
+ }}
568
+ >
569
+ {files.map((file, i) => {
570
+ const isHidden = hiddenIndex === i && phase === "guess" && !answered;
571
+ return (
572
+ <div
573
+ key={i}
574
+ style={{
575
+ ...styles.gmCard,
576
+ width: "100%",
577
+ height: "100%",
578
+ ...(result === "correct" && hiddenIndex === i ? styles.gmCorrect : {}),
579
+ ...(result === "wrong" && hiddenIndex === i ? styles.gmWrong : {}),
580
+ }}
581
+ >
582
+ {!isHidden && (
583
+ <img
584
+ src={file.src}
585
+ alt={file.name}
586
+ style={{
587
+ width: "100%",
588
+ height: "100%",
589
+ objectFit: "cover",
590
+ display: "block",
591
+ }}
592
+ />
593
+ )}
594
+ </div>
595
+ );
596
+ })}
597
+ </div>
598
+ )}
605
599
 
606
600
  {/* Инпут и кнопки */}
607
601
  <div style={{ marginTop: 16, height: 80 }}>