@mblinkov/whats-missing 20.0.16 → 20.0.17

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,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("react"),re=window.origin+"/cloud/speakid/games/whatsmissing/",B=(r,a)=>r.map(([l,n])=>({src:`${re}${a}/${n.replace(/\s/g,"%20")}.png`,name:n})),ae=[["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"]],le=[["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"]],de=[["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"]],L={food:B(ae,"food"),animals:B(le,"animals"),toys:B(de,"toys")},ce=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("react"),re=window.origin+"/cloud/speakid/games/whatsmissing/",B=(r,a)=>r.map(([d,n])=>({src:`${re}${a}/${n.replace(/\s/g,"%20")}.png`,name:n})),ae=[["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"]],le=[["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"]],de=[["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"]],W={food:B(ae,"food"),animals:B(le,"animals"),toys:B(de,"toys")},ce=`
2
2
  @keyframes spin {
3
3
  from { transform: rotate(0deg); }
4
4
  to { transform: rotate(360deg); }
@@ -14,5 +14,9 @@
14
14
  display: block;
15
15
  user-select: none;
16
16
  }
17
- html, body { margin: 0; padding: 0; }
18
- `,document.head.appendChild(r)},ue=(r,a)=>{const l=Array.from({length:r.length+1},()=>Array(a.length+1).fill(0));for(let n=0;n<=r.length;n++)l[n][0]=n;for(let n=0;n<=a.length;n++)l[0][n]=n;for(let n=1;n<=r.length;n++)for(let c=1;c<=a.length;c++)l[n][c]=r[n-1]===a[c-1]?l[n-1][c-1]:Math.min(l[n-1][c-1],l[n][c-1],l[n-1][c])+1;return l[r.length][a.length]};function he(){const r=o.useRef(null);o.useEffect(()=>(ge(),()=>{document.body.style.overflow=""}),[]);const[a,l]=o.useState(null),[n,c]=o.useState([]),[b,K]=o.useState(4),[x,W]=o.useState(!1),[w,E]=o.useState(1),[h,Z]=o.useState(null),[g,j]=o.useState("ready"),[G,F]=o.useState(3),[v,C]=o.useState(10),[T,Y]=o.useState(20),[J,z]=o.useState(0),[S,R]=o.useState(!1),[k,D]=o.useState(""),[p,I]=o.useState(!1),[H,q]=o.useState(!1),[O,y]=o.useState(null),[Q,M]=o.useState([]),[X,P]=o.useState([]),[u,ee]=o.useState(!1),[te,U]=o.useState(1);o.useEffect(()=>{const t=()=>{const i=window.innerWidth<768;if(ee(i),i)U(1);else{const f=Math.min(window.innerWidth/1440,window.innerHeight/768);U(f)}};return t(),window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[]);const $=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),N=()=>{if(!a)return;const t=$(L[a]);c(t),W(!0),R(!1),E(1),z(0),M([]),P([]),V(t,[],!0)},V=(t=n,i=X,m=!1)=>{const d=$(t.length?t:L[a]);let f=Math.floor(Math.random()*d.length),A=d[f].name,_=0;for(;i.includes(A)&&_<20;)f=Math.floor(Math.random()*d.length),A=d[f].name,_++;c(d),Z(f),P([...i,A]),I(!1),D(""),Y(20),y(null),m?(j("ready"),F(3),C(10)):(j("memorize"),C(10))};o.useEffect(()=>{if(!(!x||S||p)){if(g==="ready")if(G<=0)j("memorize");else{const t=setTimeout(()=>F(i=>i-1),1e3);return()=>clearTimeout(t)}if(g==="memorize")if(v<=0)j("guess");else{const t=setTimeout(()=>C(i=>i-1),1e3);return()=>clearTimeout(t)}if(g==="guess"){if(T<=0){I(!0),y("wrong");const i=n[h].name;M(m=>[...m,{round:w,answer:k,correct:i,result:"wrong"}]);return}const t=setTimeout(()=>Y(i=>i-1),1e3);return()=>clearTimeout(t)}}},[g,G,v,T,x,S,p,n,h,w,k]);const se=()=>{if(h===null||H)return;const t=n[h].name,i=k.toLowerCase().trim();let m="wrong";i===t?(z(d=>d+1),y("correct"),m="correct"):ue(i,t)===1?(z(d=>d+.5),y("almost"),m="almost"):(y("wrong"),m="wrong"),M(d=>[...d,{round:w,answer:i,correct:t,result:m}]),q(!0),setTimeout(()=>{q(!1),I(!0)},600)},ne=()=>w<b?(E(t=>t+1),V()):R(!0),oe=()=>{W(!1),R(!1),l(null)},ie=o.useMemo(()=>e.jsx("div",{style:s.gmLogoFixed,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:s.gmLogoImg,loading:"lazy"})]})}),[]);return e.jsx("div",{ref:r,style:{width:"100%",height:"100vh",display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",transition:"background 0.3s ease"},children:e.jsx("div",{style:{width:u?"100%":1440,height:u?"100%":768,display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",borderRadius:u?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",boxShadow:u?"none":"0 0 40px rgba(0,0,0,0.1)",margin:u?"0 auto":"unset"},children:e.jsx("div",{style:{transform:u?"none":`scale(${te})`,transformOrigin:"center center",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",children:[!u&&ie,!a&&!x&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsx("h1",{style:s.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:s.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:s.gmButton,onClick:()=>l(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:s.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:{...s.gmButton,...b===t?s.gmButtonActive:{}},onClick:()=>K(t),children:t},t))})]})]}),a&&!x&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsxs("h1",{style:s.gmHeadline1,children:["Theme selected: ",a]}),e.jsxs("p",{style:s.gmBodyM,children:["Rounds: ",b]}),e.jsx("button",{style:s.gmButton,onClick:N,children:"▶ Start game"})]}),S&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsx("h1",{style:s.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:s.gmHeadline3,children:["Your score: ",J," / ",b]}),e.jsx("p",{style:{...s.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:s.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:Q.map((t,i)=>e.jsxs("tr",{children:[e.jsx("td",{style:s.gmTableCell,children:t.round}),e.jsx("td",{style:s.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:s.gmTableCell,children:t.correct}),e.jsx("td",{style:s.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:s.gmButton,onClick:N,children:"🔁 Play again"}),e.jsx("button",{style:s.gmButton,onClick:oe,children:"⬅️ Choose theme"})]})]}),x&&!S&&e.jsxs("div",{style:s.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[g==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...s.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:s.gmHourglass,children:"⏳"})]}),g==="memorize"&&e.jsxs("p",{style:{...s.gmBodyM,color:"#10b981"},children:["MEMORIZE (",v,")"]}),g==="guess"&&!p&&e.jsxs("p",{style:s.gmBodyM,children:["⏳ Time left: ",T,"s"]})]}),g!=="ready"&&e.jsx("div",{style:{...s.gmGrid,gridTemplateColumns:u?"repeat(2, 1fr)":"repeat(3, 210px)",gridAutoRows:u?"150px":"210px",gap:u?"12px":"20px",justifyItems:"center"},children:n.map((t,i)=>{const m=h===i&&g==="guess"&&!p;return e.jsx("div",{style:{...s.gmCard,...O==="correct"&&h===i?s.gmCorrect:{},...O==="wrong"&&h===i?s.gmWrong:{}},children:!m&&e.jsx("img",{src:t.src,alt:t.name,style:{width:"100%",height:"100%",objectFit:"cover"}})},i)})}),e.jsxs("div",{style:{marginTop:16,height:80},children:[g==="guess"&&!p&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:k,onChange:t=>D(t.target.value),style:s.gmInput}),e.jsx("button",{style:{...s.gmButton,marginLeft:8},onClick:se,disabled:H,children:H?"...":"Check"})]}),p&&e.jsx("button",{style:s.gmButton,onClick:ne,children:"Next round"})]})]})]})})})})}exports.Game=he;exports.themes=L;
17
+ html, body {
18
+ margin: 0;
19
+ padding: 0;
20
+ zoom: 1 !important; /* ✅ защита от подзума */
21
+ }
22
+ `,document.head.appendChild(r)},ue=(r,a)=>{const d=Array.from({length:r.length+1},()=>Array(a.length+1).fill(0));for(let n=0;n<=r.length;n++)d[n][0]=n;for(let n=0;n<=a.length;n++)d[0][n]=n;for(let n=1;n<=r.length;n++)for(let m=1;m<=a.length;m++)d[n][m]=r[n-1]===a[m-1]?d[n-1][m-1]:Math.min(d[n-1][m-1],d[n][m-1],d[n-1][m])+1;return d[r.length][a.length]};function he(){const r=o.useRef(null);o.useEffect(()=>(ge(),()=>{document.body.style.overflow=""}),[]);const[a,d]=o.useState(null),[n,m]=o.useState([]),[w,K]=o.useState(4),[f,L]=o.useState(!1),[j,E]=o.useState(1),[h,Z]=o.useState(null),[g,S]=o.useState("ready"),[G,F]=o.useState(3),[C,T]=o.useState(10),[z,Y]=o.useState(20),[X,R]=o.useState(0),[k,I]=o.useState(!1),[v,D]=o.useState(""),[p,H]=o.useState(!1),[M,q]=o.useState(!1),[O,x]=o.useState(null),[J,A]=o.useState([]),[Q,P]=o.useState([]),[u,ee]=o.useState(!1),[te,U]=o.useState(1);o.useEffect(()=>{const t=()=>{const i=window.innerWidth<768,l=window.innerWidth>=768&&window.innerWidth<1200;if(ee(i||l),!i&&!l){const b=Math.min(window.innerWidth/1440,window.innerHeight/768)*.97;U(b)}else U(1)};return t(),window.addEventListener("resize",t),()=>window.removeEventListener("resize",t)},[]);const $=t=>[...t].sort(()=>Math.random()-.5).slice(0,6),N=()=>{if(!a)return;const t=$(W[a]);m(t),L(!0),I(!1),E(1),R(0),A([]),P([]),V(t,[],!0)},V=(t=n,i=Q,l=!1)=>{const c=$(t.length?t:W[a]);let y=Math.floor(Math.random()*c.length),b=c[y].name,_=0;for(;i.includes(b)&&_<20;)y=Math.floor(Math.random()*c.length),b=c[y].name,_++;m(c),Z(y),P([...i,b]),H(!1),D(""),Y(20),x(null),l?(S("ready"),F(3),T(10)):(S("memorize"),T(10))};o.useEffect(()=>{if(!(!f||k||p)){if(g==="ready")if(G<=0)S("memorize");else{const t=setTimeout(()=>F(i=>i-1),1e3);return()=>clearTimeout(t)}if(g==="memorize")if(C<=0)S("guess");else{const t=setTimeout(()=>T(i=>i-1),1e3);return()=>clearTimeout(t)}if(g==="guess"){if(z<=0){H(!0),x("wrong");const i=n[h].name;A(l=>[...l,{round:j,answer:v,correct:i,result:"wrong"}]);return}const t=setTimeout(()=>Y(i=>i-1),1e3);return()=>clearTimeout(t)}}},[g,G,C,z,f,k,p,n,h,j,v]);const se=()=>{if(h===null||M)return;const t=n[h].name,i=v.toLowerCase().trim();let l="wrong";i===t?(R(c=>c+1),x("correct"),l="correct"):ue(i,t)===1?(R(c=>c+.5),x("almost"),l="almost"):(x("wrong"),l="wrong"),A(c=>[...c,{round:j,answer:i,correct:t,result:l}]),q(!0),setTimeout(()=>{q(!1),H(!0)},600)},ne=()=>j<w?(E(t=>t+1),V()):I(!0),oe=()=>{L(!1),I(!1),d(null)},ie=o.useMemo(()=>e.jsx("div",{style:s.gmLogoFixed,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:s.gmLogoImg,loading:"lazy"})]})}),[]);return e.jsx("div",{ref:r,style:{width:"100%",height:"100vh",display:"flex",justifyContent:"center",alignItems:"center",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",transition:"background 0.3s ease",overflowX:"clip"},children:e.jsx("div",{style:{width:u?"100%":1440,height:u?"100%":768,display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",borderRadius:u?0:"20px",background:"linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",boxShadow:u?"none":"0 0 40px rgba(0,0,0,0.1)",margin:u?"0 auto":"unset"},children:e.jsx("div",{style:{transform:u?"none":`scale(${te})`,transformOrigin:"top center",width:"100%",height:"100%",display:"flex",justifyContent:"center",alignItems:"center"},children:e.jsxs("div",{id:"whats-missing-root",children:[!u&&ie,!a&&!f&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsx("h1",{style:s.gmHeadline1,children:"WHAT'S MISSING?"}),e.jsx("p",{style:s.gmBodyM,children:"Select a theme:"}),e.jsx("div",{style:{display:"flex",gap:16},children:["animals","food","toys"].map(t=>e.jsx("button",{style:s.gmButton,onClick:()=>d(t),children:t==="animals"?"🐶 Animals":t==="food"?"🍎 Food":"🧸 Toys"},t))}),e.jsxs("div",{style:{marginTop:24},children:[e.jsx("p",{style:s.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:{...s.gmButton,...w===t?s.gmButtonActive:{}},onClick:()=>K(t),children:t},t))})]})]}),a&&!f&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsxs("h1",{style:s.gmHeadline1,children:["Theme selected: ",a]}),e.jsxs("p",{style:s.gmBodyM,children:["Rounds: ",w]}),e.jsx("button",{style:s.gmButton,onClick:N,children:"▶ Start game"})]}),k&&e.jsxs("div",{style:s.gmCenterScreen,children:[e.jsx("h1",{style:s.gmHeadline1,children:"Results"}),e.jsxs("h2",{style:s.gmHeadline3,children:["Your score: ",X," / ",w]}),e.jsx("p",{style:{...s.gmBodyM,color:"#10b981",marginTop:12},children:"Yahoo! You did it! 🍬✨"}),e.jsxs("table",{style:s.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:J.map((t,i)=>e.jsxs("tr",{children:[e.jsx("td",{style:s.gmTableCell,children:t.round}),e.jsx("td",{style:s.gmTableCell,children:t.answer||"—"}),e.jsx("td",{style:s.gmTableCell,children:t.correct}),e.jsx("td",{style:s.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:s.gmButton,onClick:N,children:"🔁 Play again"}),e.jsx("button",{style:s.gmButton,onClick:oe,children:"⬅️ Choose theme"})]})]}),f&&!k&&e.jsxs("div",{style:s.gmGameLayout,children:[e.jsxs("div",{style:{minHeight:160,display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center"},children:[g==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("h1",{style:{...s.gmHeadline1,color:"#ec4c44"},children:"GET READY"}),e.jsx("div",{style:s.gmHourglass,children:"⏳"})]}),g==="memorize"&&e.jsxs("p",{style:{...s.gmBodyM,color:"#10b981"},children:["MEMORIZE (",C,")"]}),g==="guess"&&!p&&e.jsxs("p",{style:s.gmBodyM,children:["⏳ Time left: ",z,"s"]})]}),g!=="ready"&&e.jsx("div",{style:{...s.gmGrid,gridTemplateColumns:u?"repeat(2, 1fr)":"repeat(3, 210px)",gridAutoRows:u?"150px":"210px",gap:u?"12px":"20px",justifyItems:"center"},children:n.map((t,i)=>{const l=h===i&&g==="guess"&&!p;return e.jsx("div",{style:{...s.gmCard,...O==="correct"&&h===i?s.gmCorrect:{},...O==="wrong"&&h===i?s.gmWrong:{}},children:!l&&e.jsx("img",{src:t.src,alt:t.name,style:{width:"100%",height:"100%",objectFit:"cover"}})},i)})}),e.jsxs("div",{style:{marginTop:16,height:80},children:[g==="guess"&&!p&&e.jsxs("div",{children:[e.jsx("input",{type:"text",placeholder:"Type the missing word",value:v,onChange:t=>D(t.target.value),style:s.gmInput}),e.jsx("button",{style:{...s.gmButton,marginLeft:8},onClick:se,disabled:M,children:M?"...":"Check"})]}),p&&e.jsx("button",{style:s.gmButton,onClick:ne,children:"Next round"})]})]})]})})})})}exports.Game=he;exports.themes=W;
@@ -1,6 +1,6 @@
1
1
  import { jsx as t, jsxs as r, Fragment as ae } from "react/jsx-runtime";
2
- import { useRef as de, useEffect as j, useState as s, useMemo as ce } from "react";
3
- const me = window.origin + "/cloud/speakid/games/whatsmissing/", W = (l, a) => l.map(([d, o]) => ({
2
+ import { useRef as de, useEffect as L, useState as s, useMemo as ce } from "react";
3
+ const me = window.origin + "/cloud/speakid/games/whatsmissing/", j = (l, a) => l.map(([c, o]) => ({
4
4
  src: `${me}${a}/${o.replace(/\s/g, "%20")}.png`,
5
5
  name: o
6
6
  })), ge = [
@@ -70,9 +70,9 @@ const me = window.origin + "/cloud/speakid/games/whatsmissing/", W = (l, a) => l
70
70
  ["yo-yo", "yo-yo"],
71
71
  ["crayons", "crayons"]
72
72
  ], Z = {
73
- food: W(ge, "food"),
74
- animals: W(he, "animals"),
75
- toys: W(pe, "toys")
73
+ food: j(ge, "food"),
74
+ animals: j(he, "animals"),
75
+ toys: j(pe, "toys")
76
76
  }, ue = `
77
77
  @keyframes spin {
78
78
  from { transform: rotate(0deg); }
@@ -248,67 +248,70 @@ const fe = {
248
248
  display: block;
249
249
  user-select: none;
250
250
  }
251
- html, body { margin: 0; padding: 0; }
251
+ html, body {
252
+ margin: 0;
253
+ padding: 0;
254
+ zoom: 1 !important; /* ✅ защита от подзума */
255
+ }
252
256
  `, document.head.appendChild(l);
253
257
  }, be = (l, a) => {
254
- const d = Array.from({ length: l.length + 1 }, () => Array(a.length + 1).fill(0));
255
- for (let o = 0; o <= l.length; o++) d[o][0] = o;
256
- for (let o = 0; o <= a.length; o++) d[0][o] = o;
258
+ const c = Array.from({ length: l.length + 1 }, () => Array(a.length + 1).fill(0));
259
+ for (let o = 0; o <= l.length; o++) c[o][0] = o;
260
+ for (let o = 0; o <= a.length; o++) c[0][o] = o;
257
261
  for (let o = 1; o <= l.length; o++)
258
- for (let m = 1; m <= a.length; m++)
259
- d[o][m] = l[o - 1] === a[m - 1] ? d[o - 1][m - 1] : Math.min(d[o - 1][m - 1], d[o][m - 1], d[o - 1][m]) + 1;
260
- return d[l.length][a.length];
262
+ for (let g = 1; g <= a.length; g++)
263
+ c[o][g] = l[o - 1] === a[g - 1] ? c[o - 1][g - 1] : Math.min(c[o - 1][g - 1], c[o][g - 1], c[o - 1][g]) + 1;
264
+ return c[l.length][a.length];
261
265
  };
262
266
  function ke() {
263
267
  const l = de(null);
264
- j(() => (ye(), () => {
268
+ L(() => (ye(), () => {
265
269
  document.body.style.overflow = "";
266
270
  }), []);
267
- const [a, d] = s(null), [o, m] = s([]), [w, J] = s(4), [b, E] = s(!1), [k, G] = s(1), [u, Q] = s(null), [h, v] = s("ready"), [F, Y] = s(3), [S, z] = s(10), [R, D] = s(20), [X, I] = s(0), [C, H] = s(!1), [T, U] = s(""), [f, M] = s(!1), [A, $] = s(!1), [N, x] = s(null), [ee, B] = s([]), [te, O] = s([]), [p, ne] = s(!1), [oe, P] = s(1);
268
- j(() => {
271
+ const [a, c] = s(null), [o, g] = s([]), [k, X] = s(4), [y, E] = s(!1), [v, G] = s(1), [u, J] = s(null), [h, C] = s("ready"), [F, Y] = s(3), [z, R] = s(10), [I, D] = s(20), [Q, H] = s(0), [T, M] = s(!1), [S, U] = s(""), [f, A] = s(!1), [B, $] = s(!1), [N, b] = s(null), [ee, W] = s([]), [te, O] = s([]), [p, ne] = s(!1), [oe, P] = s(1);
272
+ L(() => {
269
273
  const e = () => {
270
- const i = window.innerWidth < 768;
271
- if (ne(i), i)
274
+ const i = window.innerWidth < 768, d = window.innerWidth >= 768 && window.innerWidth < 1200;
275
+ if (ne(i || d), !i && !d) {
276
+ const w = Math.min(window.innerWidth / 1440, window.innerHeight / 768) * 0.97;
277
+ P(w);
278
+ } else
272
279
  P(1);
273
- else {
274
- const y = Math.min(window.innerWidth / 1440, window.innerHeight / 768);
275
- P(y);
276
- }
277
280
  };
278
281
  return e(), window.addEventListener("resize", e), () => window.removeEventListener("resize", e);
279
282
  }, []);
280
283
  const V = (e) => [...e].sort(() => Math.random() - 0.5).slice(0, 6), _ = () => {
281
284
  if (!a) return;
282
285
  const e = V(Z[a]);
283
- m(e), E(!0), H(!1), G(1), I(0), B([]), O([]), q(e, [], !0);
284
- }, q = (e = o, i = te, g = !1) => {
285
- const c = V(e.length ? e : Z[a]);
286
- let y = Math.floor(Math.random() * c.length), L = c[y].name, K = 0;
287
- for (; i.includes(L) && K < 20; )
288
- y = Math.floor(Math.random() * c.length), L = c[y].name, K++;
289
- m(c), Q(y), O([...i, L]), M(!1), U(""), D(20), x(null), g ? (v("ready"), Y(3), z(10)) : (v("memorize"), z(10));
286
+ g(e), E(!0), M(!1), G(1), H(0), W([]), O([]), q(e, [], !0);
287
+ }, q = (e = o, i = te, d = !1) => {
288
+ const m = V(e.length ? e : Z[a]);
289
+ let x = Math.floor(Math.random() * m.length), w = m[x].name, K = 0;
290
+ for (; i.includes(w) && K < 20; )
291
+ x = Math.floor(Math.random() * m.length), w = m[x].name, K++;
292
+ g(m), J(x), O([...i, w]), A(!1), U(""), D(20), b(null), d ? (C("ready"), Y(3), R(10)) : (C("memorize"), R(10));
290
293
  };
291
- j(() => {
292
- if (!(!b || C || f)) {
294
+ L(() => {
295
+ if (!(!y || T || f)) {
293
296
  if (h === "ready")
294
- if (F <= 0) v("memorize");
297
+ if (F <= 0) C("memorize");
295
298
  else {
296
299
  const e = setTimeout(() => Y((i) => i - 1), 1e3);
297
300
  return () => clearTimeout(e);
298
301
  }
299
302
  if (h === "memorize")
300
- if (S <= 0) v("guess");
303
+ if (z <= 0) C("guess");
301
304
  else {
302
- const e = setTimeout(() => z((i) => i - 1), 1e3);
305
+ const e = setTimeout(() => R((i) => i - 1), 1e3);
303
306
  return () => clearTimeout(e);
304
307
  }
305
308
  if (h === "guess") {
306
- if (R <= 0) {
307
- M(!0), x("wrong");
309
+ if (I <= 0) {
310
+ A(!0), b("wrong");
308
311
  const i = o[u].name;
309
- B((g) => [
310
- ...g,
311
- { round: k, answer: T, correct: i, result: "wrong" }
312
+ W((d) => [
313
+ ...d,
314
+ { round: v, answer: S, correct: i, result: "wrong" }
312
315
  ]);
313
316
  return;
314
317
  }
@@ -316,16 +319,16 @@ function ke() {
316
319
  return () => clearTimeout(e);
317
320
  }
318
321
  }
319
- }, [h, F, S, R, b, C, f, o, u, k, T]);
322
+ }, [h, F, z, I, y, T, f, o, u, v, S]);
320
323
  const ie = () => {
321
- if (u === null || A) return;
322
- const e = o[u].name, i = T.toLowerCase().trim();
323
- let g = "wrong";
324
- i === e ? (I((c) => c + 1), x("correct"), g = "correct") : be(i, e) === 1 ? (I((c) => c + 0.5), x("almost"), g = "almost") : (x("wrong"), g = "wrong"), B((c) => [...c, { round: k, answer: i, correct: e, result: g }]), $(!0), setTimeout(() => {
325
- $(!1), M(!0);
324
+ if (u === null || B) return;
325
+ const e = o[u].name, i = S.toLowerCase().trim();
326
+ let d = "wrong";
327
+ i === e ? (H((m) => m + 1), b("correct"), d = "correct") : be(i, e) === 1 ? (H((m) => m + 0.5), b("almost"), d = "almost") : (b("wrong"), d = "wrong"), W((m) => [...m, { round: v, answer: i, correct: e, result: d }]), $(!0), setTimeout(() => {
328
+ $(!1), A(!0);
326
329
  }, 600);
327
- }, re = () => k < w ? (G((e) => e + 1), q()) : H(!0), se = () => {
328
- E(!1), H(!1), d(null);
330
+ }, re = () => v < k ? (G((e) => e + 1), q()) : M(!0), se = () => {
331
+ E(!1), M(!1), c(null);
329
332
  }, le = ce(
330
333
  () => /* @__PURE__ */ t("div", { style: n.gmLogoFixed, children: /* @__PURE__ */ r("picture", { children: [
331
334
  /* @__PURE__ */ t("source", { srcSet: window.origin + "/cloud/speakid/games/whatsmissing/logo.svg", type: "image/svg+xml" }),
@@ -344,7 +347,8 @@ function ke() {
344
347
  justifyContent: "center",
345
348
  alignItems: "center",
346
349
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
347
- transition: "background 0.3s ease"
350
+ transition: "background 0.3s ease",
351
+ overflowX: "clip"
348
352
  },
349
353
  children: /* @__PURE__ */ t(
350
354
  "div",
@@ -366,7 +370,8 @@ function ke() {
366
370
  {
367
371
  style: {
368
372
  transform: p ? "none" : `scale(${oe})`,
369
- transformOrigin: "center center",
373
+ transformOrigin: "top center",
374
+ // ✅ фикс вертикального смещения
370
375
  width: "100%",
371
376
  height: "100%",
372
377
  display: "flex",
@@ -375,10 +380,10 @@ function ke() {
375
380
  },
376
381
  children: /* @__PURE__ */ r("div", { id: "whats-missing-root", children: [
377
382
  !p && le,
378
- !a && !b && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
383
+ !a && !y && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
379
384
  /* @__PURE__ */ t("h1", { style: n.gmHeadline1, children: "WHAT'S MISSING?" }),
380
385
  /* @__PURE__ */ t("p", { style: n.gmBodyM, children: "Select a theme:" }),
381
- /* @__PURE__ */ t("div", { style: { display: "flex", gap: 16 }, children: ["animals", "food", "toys"].map((e) => /* @__PURE__ */ t("button", { style: n.gmButton, onClick: () => d(e), children: e === "animals" ? "🐶 Animals" : e === "food" ? "🍎 Food" : "🧸 Toys" }, e)) }),
386
+ /* @__PURE__ */ t("div", { style: { display: "flex", gap: 16 }, children: ["animals", "food", "toys"].map((e) => /* @__PURE__ */ t("button", { style: n.gmButton, onClick: () => c(e), children: e === "animals" ? "🐶 Animals" : e === "food" ? "🍎 Food" : "🧸 Toys" }, e)) }),
382
387
  /* @__PURE__ */ r("div", { style: { marginTop: 24 }, children: [
383
388
  /* @__PURE__ */ t("p", { style: n.gmBodyS, children: "Choose number of rounds:" }),
384
389
  /* @__PURE__ */ t("div", { style: { display: "flex", gap: 12, marginTop: 8 }, children: [3, 4, 5].map((e) => /* @__PURE__ */ t(
@@ -386,33 +391,33 @@ function ke() {
386
391
  {
387
392
  style: {
388
393
  ...n.gmButton,
389
- ...w === e ? n.gmButtonActive : {}
394
+ ...k === e ? n.gmButtonActive : {}
390
395
  },
391
- onClick: () => J(e),
396
+ onClick: () => X(e),
392
397
  children: e
393
398
  },
394
399
  e
395
400
  )) })
396
401
  ] })
397
402
  ] }),
398
- a && !b && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
403
+ a && !y && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
399
404
  /* @__PURE__ */ r("h1", { style: n.gmHeadline1, children: [
400
405
  "Theme selected: ",
401
406
  a
402
407
  ] }),
403
408
  /* @__PURE__ */ r("p", { style: n.gmBodyM, children: [
404
409
  "Rounds: ",
405
- w
410
+ k
406
411
  ] }),
407
412
  /* @__PURE__ */ t("button", { style: n.gmButton, onClick: _, children: "▶ Start game" })
408
413
  ] }),
409
- C && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
414
+ T && /* @__PURE__ */ r("div", { style: n.gmCenterScreen, children: [
410
415
  /* @__PURE__ */ t("h1", { style: n.gmHeadline1, children: "Results" }),
411
416
  /* @__PURE__ */ r("h2", { style: n.gmHeadline3, children: [
412
417
  "Your score: ",
413
- X,
418
+ Q,
414
419
  " / ",
415
- w
420
+ k
416
421
  ] }),
417
422
  /* @__PURE__ */ t("p", { style: { ...n.gmBodyM, color: "#10b981", marginTop: 12 }, children: "Yahoo! You did it! 🍬✨" }),
418
423
  /* @__PURE__ */ r("table", { style: n.gmTable, children: [
@@ -434,7 +439,7 @@ function ke() {
434
439
  /* @__PURE__ */ t("button", { style: n.gmButton, onClick: se, children: "⬅️ Choose theme" })
435
440
  ] })
436
441
  ] }),
437
- b && !C && /* @__PURE__ */ r("div", { style: n.gmGameLayout, children: [
442
+ y && !T && /* @__PURE__ */ r("div", { style: n.gmGameLayout, children: [
438
443
  /* @__PURE__ */ r(
439
444
  "div",
440
445
  {
@@ -452,12 +457,12 @@ function ke() {
452
457
  ] }),
453
458
  h === "memorize" && /* @__PURE__ */ r("p", { style: { ...n.gmBodyM, color: "#10b981" }, children: [
454
459
  "MEMORIZE (",
455
- S,
460
+ z,
456
461
  ")"
457
462
  ] }),
458
463
  h === "guess" && !f && /* @__PURE__ */ r("p", { style: n.gmBodyM, children: [
459
464
  "⏳ Time left: ",
460
- R,
465
+ I,
461
466
  "s"
462
467
  ] })
463
468
  ]
@@ -474,7 +479,7 @@ function ke() {
474
479
  justifyItems: "center"
475
480
  },
476
481
  children: o.map((e, i) => {
477
- const g = u === i && h === "guess" && !f;
482
+ const d = u === i && h === "guess" && !f;
478
483
  return /* @__PURE__ */ t(
479
484
  "div",
480
485
  {
@@ -483,7 +488,7 @@ function ke() {
483
488
  ...N === "correct" && u === i ? n.gmCorrect : {},
484
489
  ...N === "wrong" && u === i ? n.gmWrong : {}
485
490
  },
486
- children: !g && /* @__PURE__ */ t(
491
+ children: !d && /* @__PURE__ */ t(
487
492
  "img",
488
493
  {
489
494
  src: e.src,
@@ -508,12 +513,20 @@ function ke() {
508
513
  {
509
514
  type: "text",
510
515
  placeholder: "Type the missing word",
511
- value: T,
516
+ value: S,
512
517
  onChange: (e) => U(e.target.value),
513
518
  style: n.gmInput
514
519
  }
515
520
  ),
516
- /* @__PURE__ */ t("button", { style: { ...n.gmButton, marginLeft: 8 }, onClick: ie, disabled: A, children: A ? "..." : "Check" })
521
+ /* @__PURE__ */ t(
522
+ "button",
523
+ {
524
+ style: { ...n.gmButton, marginLeft: 8 },
525
+ onClick: ie,
526
+ disabled: B,
527
+ children: B ? "..." : "Check"
528
+ }
529
+ )
517
530
  ] }),
518
531
  f && /* @__PURE__ */ t("button", { style: n.gmButton, onClick: re, children: "Next round" })
519
532
  ] })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mblinkov/whats-missing",
3
- "version": "20.0.16",
3
+ "version": "20.0.17",
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
@@ -25,7 +25,11 @@ const globalReset = () => {
25
25
  display: block;
26
26
  user-select: none;
27
27
  }
28
- html, body { margin: 0; padding: 0; }
28
+ html, body {
29
+ margin: 0;
30
+ padding: 0;
31
+ zoom: 1 !important; /* ✅ защита от подзума */
32
+ }
29
33
  `;
30
34
  document.head.appendChild(style);
31
35
  };
@@ -77,17 +81,19 @@ export default function Game() {
77
81
  const [isMobile, setIsMobile] = useState(false);
78
82
  const [scale, setScale] = useState(1);
79
83
 
80
- // ✅ адаптив под мобилки и десктоп
84
+ // ✅ адаптив под мобилки, планшеты и десктоп
81
85
  useEffect(() => {
82
86
  const resize = () => {
83
87
  const mobile = window.innerWidth < 768;
84
- setIsMobile(mobile);
88
+ const tablet = window.innerWidth >= 768 && window.innerWidth < 1200;
89
+
90
+ setIsMobile(mobile || tablet);
85
91
 
86
- if (!mobile) {
87
- // виртуальный размер игры (1440x768)
92
+ if (!mobile && !tablet) {
88
93
  const baseW = 1440;
89
94
  const baseH = 768;
90
- const ratio = Math.min(window.innerWidth / baseW, window.innerHeight / baseH);
95
+ // коэффициент безопасности, чтобы кнопка не обрезалась
96
+ const ratio = Math.min(window.innerWidth / baseW, window.innerHeight / baseH) * 0.97;
91
97
  setScale(ratio);
92
98
  } else {
93
99
  setScale(1);
@@ -219,9 +225,6 @@ export default function Game() {
219
225
  []
220
226
  );
221
227
 
222
- // =============================
223
- // RENDER
224
- // =============================
225
228
  return (
226
229
  <div
227
230
  ref={containerRef}
@@ -233,6 +236,7 @@ export default function Game() {
233
236
  alignItems: "center",
234
237
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
235
238
  transition: "background 0.3s ease",
239
+ overflowX: "clip"
236
240
  }}
237
241
  >
238
242
  <div
@@ -246,14 +250,13 @@ export default function Game() {
246
250
  borderRadius: isMobile ? 0 : "20px",
247
251
  background: "linear-gradient(to bottom, #fff8f8 0%, #f9fafb 100%)",
248
252
  boxShadow: isMobile ? "none" : "0 0 40px rgba(0,0,0,0.1)",
249
- margin: isMobile ? "0 auto" : "unset",
253
+ margin: isMobile ? "0 auto" : "unset",
250
254
  }}
251
255
  >
252
- {/* ✅ добавленный блок для правильного масштабирования и центрирования */}
253
256
  <div
254
257
  style={{
255
258
  transform: isMobile ? "none" : `scale(${scale})`,
256
- transformOrigin: "center center",
259
+ transformOrigin: "top center", // ✅ фикс вертикального смещения
257
260
  width: "100%",
258
261
  height: "100%",
259
262
  display: "flex",
@@ -263,7 +266,6 @@ export default function Game() {
263
266
  >
264
267
  <div id="whats-missing-root">
265
268
  {!isMobile && MemoizedLogo}
266
-
267
269
  {/* ====== ИГРОВАЯ ЛОГИКА ====== */}
268
270
  {!theme && !started && (
269
271
  <div style={styles.gmCenterScreen}>
@@ -295,7 +297,6 @@ export default function Game() {
295
297
  </div>
296
298
  </div>
297
299
  )}
298
-
299
300
  {theme && !started && (
300
301
  <div style={styles.gmCenterScreen}>
301
302
  <h1 style={styles.gmHeadline1}>Theme selected: {theme}</h1>
@@ -305,7 +306,6 @@ export default function Game() {
305
306
  </button>
306
307
  </div>
307
308
  )}
308
-
309
309
  {finished && (
310
310
  <div style={styles.gmCenterScreen}>
311
311
  <h1 style={styles.gmHeadline1}>Results</h1>
@@ -349,7 +349,6 @@ export default function Game() {
349
349
  </div>
350
350
  </div>
351
351
  )}
352
-
353
352
  {started && !finished && (
354
353
  <div style={styles.gmGameLayout}>
355
354
  <div
@@ -367,29 +366,41 @@ export default function Game() {
367
366
  <div style={styles.gmHourglass}>⏳</div>
368
367
  </>
369
368
  )}
370
- {phase === "memorize" && <p style={{ ...styles.gmBodyM, color: "#10b981" }}>MEMORIZE ({memorizeTime})</p>}
371
- {phase === "guess" && !answered && <p style={styles.gmBodyM}>⏳ Time left: {timeLeft}s</p>}
369
+ {phase === "memorize" && (
370
+ <p style={{ ...styles.gmBodyM, color: "#10b981" }}>
371
+ MEMORIZE ({memorizeTime})
372
+ </p>
373
+ )}
374
+ {phase === "guess" && !answered && (
375
+ <p style={styles.gmBodyM}>⏳ Time left: {timeLeft}s</p>
376
+ )}
372
377
  </div>
373
-
374
378
  {phase !== "ready" && (
375
379
  <div
376
380
  style={{
377
381
  ...styles.gmGrid,
378
- gridTemplateColumns: isMobile ? "repeat(2, 1fr)" : "repeat(3, 210px)",
382
+ gridTemplateColumns: isMobile
383
+ ? "repeat(2, 1fr)"
384
+ : "repeat(3, 210px)",
379
385
  gridAutoRows: isMobile ? "150px" : "210px",
380
386
  gap: isMobile ? "12px" : "20px",
381
387
  justifyItems: "center",
382
388
  }}
383
389
  >
384
390
  {files.map((file, i) => {
385
- const isHidden = hiddenIndex === i && phase === "guess" && !answered;
391
+ const isHidden =
392
+ hiddenIndex === i && phase === "guess" && !answered;
386
393
  return (
387
394
  <div
388
395
  key={i}
389
396
  style={{
390
397
  ...styles.gmCard,
391
- ...(result === "correct" && hiddenIndex === i ? styles.gmCorrect : {}),
392
- ...(result === "wrong" && hiddenIndex === i ? styles.gmWrong : {}),
398
+ ...(result === "correct" && hiddenIndex === i
399
+ ? styles.gmCorrect
400
+ : {}),
401
+ ...(result === "wrong" && hiddenIndex === i
402
+ ? styles.gmWrong
403
+ : {}),
393
404
  }}
394
405
  >
395
406
  {!isHidden && (
@@ -408,7 +419,6 @@ export default function Game() {
408
419
  })}
409
420
  </div>
410
421
  )}
411
-
412
422
  <div style={{ marginTop: 16, height: 80 }}>
413
423
  {phase === "guess" && !answered && (
414
424
  <div>
@@ -419,12 +429,20 @@ export default function Game() {
419
429
  onChange={(e) => setInputValue(e.target.value)}
420
430
  style={styles.gmInput}
421
431
  />
422
- <button style={{ ...styles.gmButton, marginLeft: 8 }} onClick={checkAnswer} disabled={animating}>
432
+ <button
433
+ style={{ ...styles.gmButton, marginLeft: 8 }}
434
+ onClick={checkAnswer}
435
+ disabled={animating}
436
+ >
423
437
  {animating ? "..." : "Check"}
424
438
  </button>
425
439
  </div>
426
440
  )}
427
- {answered && <button style={styles.gmButton} onClick={nextRound}>Next round</button>}
441
+ {answered && (
442
+ <button style={styles.gmButton} onClick={nextRound}>
443
+ Next round
444
+ </button>
445
+ )}
428
446
  </div>
429
447
  </div>
430
448
  )}