@puzzmo/sdk 1.0.16 → 1.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.
@@ -196,7 +196,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
196
196
  ${P(n)}
197
197
  <div class="simulator-theme-name">${n.name}</div>
198
198
  <div class="simulator-theme-type">${n.type}</div>
199
- `,r.addEventListener(`click`,()=>{console.log(`Simulator: Theme changed, reloading...`,n.name),f(n.name),window.location.reload()}),t.appendChild(r)})}}}var F=`puzzmo_sim_api_mode`,I=`http://localhost:8911`,L=`https://api.puzzmo.com`,R=()=>localStorage.getItem(F)===`dev`?`dev`:`prod`,z=e=>{localStorage.setItem(F,e)},B=null,V=function(){var t=e.t(function*(){if(B!==null)return B;try{let e=new AbortController,t=setTimeout(()=>e.abort(),1e3),n=yield fetch(`${I}/healthz`,{signal:e.signal});return clearTimeout(t),B=n.ok,B}catch(e){return B=!1,!1}});return function(){return t.apply(this,arguments)}}(),H=()=>({apiURL:R()===`dev`?I:L,clientID:`protosdk:oauthclient`,redirectUri:`${window.location.origin}/oauth/callback`}),U=()=>{let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)},W=`puzzmo_sim_oauth_token`,G=`puzzmo_sim_oauth_refresh_token`,K=e=>localStorage.setItem(W,e),ue=e=>localStorage.setItem(G,e),q=()=>{let e=localStorage.getItem(W);return console.log(`[AuthView] getAccessToken:`,{TOKEN_KEY:W,token:e?`${e.substring(0,20)}...`:null}),e},J=()=>localStorage.getItem(G),Y=()=>{localStorage.removeItem(W),localStorage.removeItem(G)},de=()=>{let e=H(),t=U();sessionStorage.setItem(`oauth_state`,t),sessionStorage.setItem(`oauth_return_url`,window.location.href);let n=new URL(`${e.apiURL}/oauth/auth`);n.searchParams.set(`client_id`,e.clientID),n.searchParams.set(`response_type`,`code`),n.searchParams.set(`redirect_uri`,e.redirectUri),n.searchParams.set(`state`,t),window.location.href=n.toString()},fe=e=>{try{let t=e.split(`.`);if(t.length!==3)return!0;let n=JSON.parse(atob(t[1])).exp;return n?Date.now()>=n*1e3-300*1e3:!0}catch(e){return!0}},pe=function(){var t=e.t(function*(){let e=J();if(!e)return console.log(`[AuthView] No refresh token available`),!1;let t=H();try{let n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:t.clientID}),r=yield fetch(`${t.apiURL}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:n.toString()});if(!r.ok)return console.error(`[AuthView] Failed to refresh token:`,r.statusText),!1;let i=yield r.json(),a=i.access_token||i.accessToken;if(!a)return console.error(`[AuthView] No access token in refresh response`),!1;K(a);let o=i.refresh_token||i.refreshToken;return o&&ue(o),console.log(`[AuthView] Successfully refreshed access token`),!0}catch(e){return console.error(`[AuthView] Error refreshing token:`,e),!1}});return function(){return t.apply(this,arguments)}}(),me=function(){var t=e.t(function*(e,t){let n=H(),r=sessionStorage.getItem(`oauth_state`);if(!r||r!==t)return console.error(`OAuth state mismatch - possible CSRF attack`),null;sessionStorage.removeItem(`oauth_state`);try{let t=new URLSearchParams({grant_type:`authorization_code`,code:e,client_id:n.clientID,redirect_uri:n.redirectUri}),r=yield fetch(`${n.apiURL}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:t.toString()});return r.ok?yield r.json():(console.error(`Failed to exchange code for token:`,r.statusText),null)}catch(e){return console.error(`Error exchanging code for token:`,e),null}});return function(e,n){return t.apply(this,arguments)}}(),he=function(){var t=e.t(function*(e,t={}){let n=H(),r=q();if(!r)throw Error(`Not authenticated`);if(fe(r))if(console.log(`[AuthView] Access token expired, attempting refresh...`),yield pe()){if(r=q(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw Y(),Error(`Session expired. Please log in again.`);let i=yield fetch(`${n.apiURL}/graphql`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`,"auth-provider":`custom`},body:JSON.stringify({query:e,variables:t})});if(!i.ok)throw Error(`API request failed: ${i.statusText}`);return i.json()});return function(e){return t.apply(this,arguments)}}(),ge=e=>{try{console.log(`[AuthView] decodeJWT input:`,e);let t=e.split(`.`);if(console.log(`[AuthView] JWT parts:`,t.length),t.length!==3)return null;let n=JSON.parse(atob(t[1]));return console.log(`[AuthView] JWT payload:`,n),n}catch(e){return console.error(`[AuthView] decodeJWT error:`,e),null}};function _e(){let t=!1;return{id:`auth`,label:`Auth`,render(){let e=q(),t=!!e,n=R(),r=n===`dev`?I:L,i=`<button class="simulator-btn tiny" id="auth-dev-toggle" style="display: none;">${n===`dev`?`Using Dev`:`Dev`}</button>`;if(t){let t=ge(e),n=t!=null&&t.exp?new Date(t.exp*1e3).toLocaleString():`Unknown`,a=!!J(),o=a?ge(J()):null,s=o!=null&&o.exp?new Date(o.exp*1e3).toLocaleString():null;return console.log({decoded:t}),`
199
+ `,r.addEventListener(`click`,()=>{console.log(`Simulator: Theme changed, reloading...`,n.name),f(n.name),window.location.reload()}),t.appendChild(r)})}}}var F=`puzzmo_sim_api_mode`,I=`http://localhost:8911`,L=`https://api.puzzmo.com`,R=()=>localStorage.getItem(F)===`dev`?`dev`:`prod`,z=e=>{localStorage.setItem(F,e)},B=null,V=function(){var t=e.t(function*(){if(B!==null)return B;try{let e=new AbortController,t=setTimeout(()=>e.abort(),1e3),n=yield fetch(`${I}/healthz`,{signal:e.signal});return clearTimeout(t),B=n.ok,B}catch(e){return B=!1,!1}});return function(){return t.apply(this,arguments)}}(),H=()=>({apiURL:R()===`dev`?I:L,clientID:`protosdk:oauthclient`,redirectUri:`${window.location.origin}/oauth/callback`}),U=()=>{let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)},W=`puzzmo_sim_oauth_token`,G=`puzzmo_sim_oauth_refresh_token`,K=e=>localStorage.setItem(W,e),ue=e=>localStorage.setItem(G,e),q=()=>{let e=localStorage.getItem(W);return e&&`${e.substring(0,20)}`,e},J=()=>localStorage.getItem(G),Y=()=>{localStorage.removeItem(W),localStorage.removeItem(G)},de=()=>{let e=H(),t=U();sessionStorage.setItem(`oauth_state`,t),sessionStorage.setItem(`oauth_return_url`,window.location.href);let n=new URL(`${e.apiURL}/oauth/auth`);n.searchParams.set(`client_id`,e.clientID),n.searchParams.set(`response_type`,`code`),n.searchParams.set(`redirect_uri`,e.redirectUri),n.searchParams.set(`state`,t),window.location.href=n.toString()},fe=e=>{try{let t=e.split(`.`);if(t.length!==3)return!0;let n=JSON.parse(atob(t[1])).exp;return n?Date.now()>=n*1e3-300*1e3:!0}catch(e){return!0}},pe=function(){var t=e.t(function*(){let e=J();if(!e)return!1;let t=H();try{let n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:t.clientID}),r=yield fetch(`${t.apiURL}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:n.toString()});if(!r.ok)return r.statusText,!1;let i=yield r.json(),a=i.access_token||i.accessToken;if(!a)return!1;K(a);let o=i.refresh_token||i.refreshToken;return o&&ue(o),!0}catch(e){return!1}});return function(){return t.apply(this,arguments)}}(),me=function(){var t=e.t(function*(e,t){let n=H(),r=sessionStorage.getItem(`oauth_state`);if(!r||r!==t)return null;sessionStorage.removeItem(`oauth_state`);try{let t=new URLSearchParams({grant_type:`authorization_code`,code:e,client_id:n.clientID,redirect_uri:n.redirectUri}),r=yield fetch(`${n.apiURL}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:t.toString()});return r.ok?yield r.json():(r.statusText,null)}catch(e){return null}});return function(e,n){return t.apply(this,arguments)}}(),he=function(){var t=e.t(function*(e,t={}){let n=H(),r=q();if(!r)throw Error(`Not authenticated`);if(fe(r))if(yield pe()){if(r=q(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw Y(),Error(`Session expired. Please log in again.`);let i=yield fetch(`${n.apiURL}/graphql`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`,"auth-provider":`custom`},body:JSON.stringify({query:e,variables:t})});if(!i.ok)throw Error(`API request failed: ${i.statusText}`);return i.json()});return function(e){return t.apply(this,arguments)}}(),ge=e=>{try{let t=e.split(`.`);return t.length,t.length===3?JSON.parse(atob(t[1])):null}catch(e){return null}};function _e(){let t=!1;return{id:`auth`,label:`Auth`,render(){let e=q(),t=!!e,n=R(),r=n===`dev`?I:L,i=`<button class="simulator-btn tiny" id="auth-dev-toggle" style="display: none;">${n===`dev`?`Using Dev`:`Dev`}</button>`;if(t){let t=ge(e),n=t!=null&&t.exp?new Date(t.exp*1e3).toLocaleString():`Unknown`,a=!!J(),o=a?ge(J()):null,s=o!=null&&o.exp?new Date(o.exp*1e3).toLocaleString():null;return`
200
200
  <div class="simulator-section">
201
201
  <div class="simulator-section-title auth-title-row">
202
202
  <span>Puzzmo Authentication</span>
@@ -321,7 +321,13 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
321
321
  </div>
322
322
  </div>
323
323
  </div>
324
- `},bind(t){let r=t.getElement(`#features-load-btn`),i=t.getElement(`#features-game-slug`),c=t.getElement(`#features-content`),l=()=>{c&&(c.innerHTML=s(),u())},u=()=>{var n;let r=(n=t.getElement(`#features-content`))==null?void 0:n.querySelectorAll(`.feature-item`);r==null||r.forEach(t=>{t.addEventListener(`click`,e.t(function*(){let e=parseInt(t.getAttribute(`data-feature-id`)||`0`);e>0&&(t.classList.add(`updating`),yield o(e),l())}))})},d=function(){var t=e.t(function*(e){e&&(r&&(r.disabled=!0,r.textContent=`Loading...`),yield a(e),l(),r&&(r.disabled=!1,r.textContent=`Load`))});return function(e){return t.apply(this,arguments)}}();r==null||r.addEventListener(`click`,e.t(function*(){let e=i==null?void 0:i.value.trim();e&&(yield d(e))})),i==null||i.addEventListener(`keypress`,e=>{e.key===`Enter`&&(r==null||r.click())}),console.log(`[FeaturesView] bind called, ctx.gameSlug:`,t.gameSlug,`slugInput:`,i),t.gameSlug&&i&&(i.value=t.gameSlug,Me()&&!n&&d(t.gameSlug)),u()},onActivate(e){let t=e.getElement(`#simulator-tab-features`);t&&(t.innerHTML=this.render(),this.bind(e))}}}var $=null;function Pe(t={}){var n,r;if(console.log(`[Simulator] createSimulator called with config:`,{slug:t.slug,hasFixtures:!!t.fixtures}),$)return t.fixtures&&(console.log(`[Simulator] Instance already exists, updating fixtures`),$.updateFixtures(t.fixtures)),$;let i=(n=t.autoStart)==null?!0:n,a=t.fixtures?v(t.fixtures):null,o=a?Array.from(a.keys()).sort():[],s=ae(),c=ce(),f=[re(),ie(),s,oe(),se(),c,le(),_e(),Ne()],p=f.map(e=>e.id),m=l(t,o,p),h={pause:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect x="1" y="1" width="3" height="8"/><rect x="6" y="1" width="3" height="8"/></svg>`,play:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><polygon points="2,1 9,5 2,9"/></svg>`,retry:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M5 1C2.8 1 1 2.8 1 5s1.8 4 4 4c1.8 0 3.3-1.2 3.8-2.8H7.5c-.4.9-1.3 1.5-2.5 1.5-1.5 0-2.7-1.2-2.7-2.7S3.5 2.3 5 2.3c.7 0 1.4.3 1.9.8L5.5 4.5H9V1L7.6 2.4C6.9 1.5 5.9 1 5 1z"/></svg>`,cog:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M9.5 5.8l-.8-.5c0-.2.1-.5.1-.8s0-.5-.1-.8l.8-.5c.1-.1.2-.2.1-.4l-.8-1.4c-.1-.1-.2-.2-.4-.1l-1 .3c-.3-.3-.7-.5-1.1-.6L6.1.2C6.1.1 6 0 5.8 0H4.2c-.2 0-.3.1-.3.2l-.2 1c-.4.1-.7.3-1.1.6l-1-.3c-.2 0-.3 0-.4.1l-.8 1.4c-.1.2 0 .3.1.4l.8.5c0 .2-.1.5-.1.8s0 .5.1.8l-.8.5c-.1.1-.2.2-.1.4l.8 1.4c.1.1.2.2.4.1l1-.3c.3.3.7.5 1.1.6l.2 1c0 .1.1.2.3.2h1.6c.2 0 .3-.1.3-.2l.2-1c.4-.1.7-.3 1.1-.6l1 .3c.2 0 .3 0 .4-.1l.8-1.4c.1-.2 0-.3-.1-.4zM5 6.5c-.8 0-1.5-.7-1.5-1.5S4.2 3.5 5 3.5 6.5 4.2 6.5 5 5.8 6.5 5 6.5z"/></svg>`,minimize:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect x="1" y="4" width="8" height="2"/></svg>`,expand:`<svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor"><polygon points="1,1 7,4 1,7"/></svg>`},g=document.createElement(`div`);g.id=`simulator`,g.innerHTML=`
324
+ `},bind(t){let r=t.getElement(`#features-load-btn`),i=t.getElement(`#features-game-slug`),c=t.getElement(`#features-content`),l=()=>{c&&(c.innerHTML=s(),u())},u=()=>{var n;let r=(n=t.getElement(`#features-content`))==null?void 0:n.querySelectorAll(`.feature-item`);r==null||r.forEach(t=>{t.addEventListener(`click`,e.t(function*(){let e=parseInt(t.getAttribute(`data-feature-id`)||`0`);e>0&&(t.classList.add(`updating`),yield o(e),l())}))})},d=function(){var t=e.t(function*(e){e&&(r&&(r.disabled=!0,r.textContent=`Loading...`),yield a(e),l(),r&&(r.disabled=!1,r.textContent=`Load`))});return function(e){return t.apply(this,arguments)}}();r==null||r.addEventListener(`click`,e.t(function*(){let e=i==null?void 0:i.value.trim();e&&(yield d(e))})),i==null||i.addEventListener(`keypress`,e=>{e.key===`Enter`&&(r==null||r.click())}),console.log(`[FeaturesView] bind called, ctx.gameSlug:`,t.gameSlug,`slugInput:`,i),t.gameSlug&&i&&(i.value=t.gameSlug,Me()&&!n&&d(t.gameSlug)),u()},onActivate(e){let t=e.getElement(`#simulator-tab-features`);t&&(t.innerHTML=this.render(),this.bind(e))}}}var Pe=(e,t)=>{var n,r;let i=(n=t.symbols[e])==null?e:n,a=t.disabled.includes(e),o=t.highlight.includes(e),s=t.xl.includes(e),c=t.l.includes(e),l=(r=t.flexGrowSymbols)==null?void 0:r.includes(e);return`<button class="${[`sim-kb-key`,a?`disabled`:``,o?`highlight`:``,s?`xl`:``,c?`l`:``,l?`grow`:``].filter(Boolean).join(` `)}" data-key="${e}" ${a?`disabled`:``}>${i}</button>`},Fe=e=>`<div class="sim-kb">${e.layout.filter(e=>e!=null).map(t=>`<div class="sim-kb-row">${[...t].map(t=>Pe(t,e)).join(``)}</div>`).join(``)}</div>`;function Ie(){let e=null,t=()=>e?Fe(e):`<div class="sim-kb-empty">No keyboard config received from game yet.<br>The game calls <code>sdk.keyboard.show(config)</code> to display a keyboard.</div>`;return{id:`kbd`,label:`Kbd`,render(){return`
325
+ <div class="keyboard-view-container">
326
+ <div id="sim-kb-content">
327
+ ${t()}
328
+ </div>
329
+ </div>
330
+ `},bind(e){Le(e)},onMessage(n,r,i){var a;if(n!==`KEYBOARD_UPDATE_CONFIG`)return;e=!(!(r==null||(a=r.layout)==null)&&a.length)||r.layout.every(e=>!e)?null:r;let o=i.getElement(`#sim-kb-content`);o&&(o.innerHTML=t(),Le(i)),i.updateBadge(`kbd`,void 0)}}}function Le(e){var t;let n=(t=e.getElement(`#sim-kb-content`))==null?void 0:t.querySelectorAll(`.sim-kb-key`);n==null||n.forEach(t=>{t.addEventListener(`click`,()=>{let n=t.getAttribute(`data-key`);n&&e.sendToGame(`KEYBOARD_KEY_PRESS`,{key:n})})})}var $=null;function Re(t={}){var n,r;if(console.log(`[Simulator] createSimulator called with config:`,{slug:t.slug,hasFixtures:!!t.fixtures}),$)return t.fixtures&&(console.log(`[Simulator] Instance already exists, updating fixtures`),$.updateFixtures(t.fixtures)),$;let i=(n=t.autoStart)==null?!0:n,a=t.fixtures?v(t.fixtures):null,o=a?Array.from(a.keys()).sort():[],s=ae(),c=ce(),f=[re(),ie(),s,oe(),se(),c,le(),_e(),Ne(),Ie()],p=f.map(e=>e.id),m=l(t,o,p),h={pause:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect x="1" y="1" width="3" height="8"/><rect x="6" y="1" width="3" height="8"/></svg>`,play:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><polygon points="2,1 9,5 2,9"/></svg>`,retry:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M5 1C2.8 1 1 2.8 1 5s1.8 4 4 4c1.8 0 3.3-1.2 3.8-2.8H7.5c-.4.9-1.3 1.5-2.5 1.5-1.5 0-2.7-1.2-2.7-2.7S3.5 2.3 5 2.3c.7 0 1.4.3 1.9.8L5.5 4.5H9V1L7.6 2.4C6.9 1.5 5.9 1 5 1z"/></svg>`,cog:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M9.5 5.8l-.8-.5c0-.2.1-.5.1-.8s0-.5-.1-.8l.8-.5c.1-.1.2-.2.1-.4l-.8-1.4c-.1-.1-.2-.2-.4-.1l-1 .3c-.3-.3-.7-.5-1.1-.6L6.1.2C6.1.1 6 0 5.8 0H4.2c-.2 0-.3.1-.3.2l-.2 1c-.4.1-.7.3-1.1.6l-1-.3c-.2 0-.3 0-.4.1l-.8 1.4c-.1.2 0 .3.1.4l.8.5c0 .2-.1.5-.1.8s0 .5.1.8l-.8.5c-.1.1-.2.2-.1.4l.8 1.4c.1.1.2.2.4.1l1-.3c.3.3.7.5 1.1.6l.2 1c0 .1.1.2.3.2h1.6c.2 0 .3-.1.3-.2l.2-1c.4-.1.7-.3 1.1-.6l1 .3c.2 0 .3 0 .4-.1l.8-1.4c.1-.2 0-.3-.1-.4zM5 6.5c-.8 0-1.5-.7-1.5-1.5S4.2 3.5 5 3.5 6.5 4.2 6.5 5 5.8 6.5 5 6.5z"/></svg>`,minimize:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect x="1" y="4" width="8" height="2"/></svg>`,expand:`<svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor"><polygon points="1,1 7,4 1,7"/></svg>`},g=document.createElement(`div`);g.id=`simulator`,g.innerHTML=`
325
331
  <style>
326
332
  :root {
327
333
  --sim-bg: #1a1a2e;
@@ -352,6 +358,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
352
358
  border-radius: 4px;
353
359
  color: var(--sim-text);
354
360
  width: 420px;
361
+ max-width: calc(100vw - 8px);
355
362
  box-shadow: 4px 4px 0 rgba(0,0,0,0.5);
356
363
  }
357
364
  #simulator-panel.collapsed {
@@ -1395,6 +1402,80 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
1395
1402
  color: var(--sim-text-dim);
1396
1403
  font-size: 9px;
1397
1404
  }
1405
+ /* Keyboard view styles */
1406
+ .keyboard-view-container {
1407
+ padding: 4px;
1408
+ }
1409
+ .sim-kb-empty {
1410
+ color: var(--sim-text-dim);
1411
+ text-align: center;
1412
+ padding: 16px 8px;
1413
+ font-size: 10px;
1414
+ line-height: 1.6;
1415
+ }
1416
+ .sim-kb-empty code {
1417
+ background: var(--sim-bg);
1418
+ padding: 1px 4px;
1419
+ border-radius: 2px;
1420
+ font-size: 10px;
1421
+ }
1422
+ .sim-kb {
1423
+ display: flex;
1424
+ flex-direction: column;
1425
+ gap: 4px;
1426
+ }
1427
+ .sim-kb-row {
1428
+ display: flex;
1429
+ justify-content: center;
1430
+ gap: 3px;
1431
+ }
1432
+ .sim-kb-key {
1433
+ min-width: 28px;
1434
+ height: 30px;
1435
+ padding: 0 4px;
1436
+ border: 1px solid var(--sim-border);
1437
+ border-radius: 3px;
1438
+ background: var(--sim-bg);
1439
+ color: var(--sim-text);
1440
+ font: inherit;
1441
+ font-size: 11px;
1442
+ text-transform: uppercase;
1443
+ cursor: pointer;
1444
+ display: flex;
1445
+ align-items: center;
1446
+ justify-content: center;
1447
+ }
1448
+ .sim-kb-key:hover {
1449
+ background: var(--sim-bg-alt);
1450
+ border-color: var(--sim-border-light);
1451
+ }
1452
+ .sim-kb-key:active {
1453
+ background: var(--sim-accent);
1454
+ color: var(--sim-panel);
1455
+ }
1456
+ .sim-kb-key.highlight {
1457
+ background: var(--sim-bg-alt);
1458
+ border-color: var(--sim-accent);
1459
+ color: var(--sim-accent);
1460
+ font-size: 9px;
1461
+ }
1462
+ .sim-kb-key.highlight:active {
1463
+ background: var(--sim-accent);
1464
+ color: var(--sim-panel);
1465
+ }
1466
+ .sim-kb-key.l {
1467
+ min-width: 40px;
1468
+ }
1469
+ .sim-kb-key.xl {
1470
+ min-width: 52px;
1471
+ }
1472
+ .sim-kb-key.grow {
1473
+ flex: 1;
1474
+ }
1475
+ .sim-kb-key.disabled {
1476
+ opacity: 0.3;
1477
+ cursor: default;
1478
+ }
1398
1479
  </style>
1399
1480
  <div id="simulator-panel" class="${m.isCollapsed?`collapsed`:``}">
1400
1481
  <div id="simulator-header">
@@ -1424,5 +1505,5 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
1424
1505
  </div>
1425
1506
  </div>
1426
1507
  </div>
1427
- `,document.body.appendChild(g);let _=g.querySelector(`#simulator-panel`),y=g.querySelector(`#simulator-header`),b=g.querySelector(`#simulator-header-indicator`),x=g.querySelector(`#simulator-header-status-text`),S=g.querySelector(`#simulator-header-pause`),C=g.querySelector(`#simulator-header-retry`),w=g.querySelector(`#simulator-header-settings`),T=g.querySelector(`#simulator-toggle`),E=g.querySelector(`#simulator-timer`),D=g.querySelector(`#simulator-tabs`),O=g.querySelector(`#simulator-content`),k=e=>g.querySelector(e),A=e=>{S.innerHTML=e?h.play:h.pause,S.title=e?`Resume`:`Pause`},j=(e,t)=>{let n=k(`#simulator-status .text`),r=k(`#simulator-status .indicator`);n&&(n.textContent=e),r&&(r.className=`indicator ${t}`),b.className=t,x.textContent=e},M=(e,t)=>{t&&t!==`0`?E.innerHTML=`${e}<span class="penalty">+${t}</span>`:E.textContent=e},N=e=>{var t;m.activeTab=e,O.classList.remove(`hidden`),d(e),D.querySelectorAll(`.simulator-tab`).forEach(t=>{t.classList.toggle(`active`,t.getAttribute(`data-tab`)===e)}),g.querySelectorAll(`.simulator-tab-content`).forEach(t=>{t.classList.toggle(`active`,t.id===`simulator-tab-${e}`)}),w.classList.toggle(`active`,e===`auth`);let n=f.find(t=>t.id===e);n==null||(t=n.onActivate)==null||t.call(n,B)},P=e=>{m.isCollapsed=e,_.classList.toggle(`collapsed`,e),u(e),e?(O.classList.add(`hidden`),D.querySelectorAll(`.simulator-tab`).forEach(e=>e.classList.remove(`active`))):N(m.activeTab)},F=()=>{c.updatePreview(B)},I=function(){var t=e.t(function*(){var e,t;if(m.puzzleData)return m.puzzleData;if(!a||a.size===0)throw Error(`No fixtures configured. Add puzzle JSON files to a fixtures directory and pass fixturesGlob to the simulator.`);let n=(e=m.selectedCategory)==null?o[0]:e,r=n?a.get(n):void 0;if(!r||r.size===0)throw Error(`No puzzles found in fixture category "${n}"`);let i=(t=m.selectedPuzzle)==null?r.keys().next().value:t,s=i?r.get(i):void 0;if(!s)throw Error(`Puzzle "${i}" not found in category "${n}"`);m.puzzleData=s,console.log(`Simulator: Puzzle loaded from fixtures`,{category:n,puzzle:i}),m.originalPuzzle=JSON.stringify(m.puzzleData,null,2);let c=k(`#simulator-puzzle`);return c&&(c.value=m.originalPuzzle),m.activeTab===`thumb`&&F(),m.puzzleData});return function(){return t.apply(this,arguments)}}(),L=ee(e=>{s.addLogEntry(e,B)}),R=(e,t)=>{te(e,t,L)},z=(e,t)=>{let n=g.querySelector(`[data-badge="${e}"]`);n&&(n.textContent=t&&t>0?String(t):``)},B={state:m,getElement:k,sendToGame:R,logMessage:L.log,loadPuzzle:I,updateStatus:j,updateTimer:M,setCollapsed:P,switchTab:N,updateThumbnail:F,updateBadge:z,fixtures:a,fixtureCategories:o,gameSlug:(r=t.slug)==null?null:r};console.log(`[Simulator] Context created with gameSlug:`,B.gameSlug),f.forEach(e=>e.bind(B)),D.querySelectorAll(`.simulator-tab`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-tab`);N(t),z(t,0)})}),T.addEventListener(`click`,e=>{e.stopPropagation(),P(!0)}),S.addEventListener(`click`,e=>{e.stopPropagation(),m.isPaused?(R(`RESUME_GAME`,{}),m.isPaused=!1,A(!1),j(`Running`,`ready`)):(R(`PAUSE_GAME`,{}),m.isPaused=!0,A(!0),j(`Paused`,`paused`));let t=k(`#simulator-pause`);t&&(t.textContent=m.isPaused?`Resume`:`Pause`)}),C.addEventListener(`click`,e=>{e.stopPropagation(),R(`RETRY_PUZZLE`,{}),m.hasStarted=!1,m.isPaused=!1,A(!1),S.disabled=!0,j(`Ready to retry`,`ready`);let t=k(`#simulator-pause`),n=k(`#simulator-start`);t&&(t.disabled=!0,t.textContent=`Pause`),n&&(n.textContent=`Start`)}),w.addEventListener(`click`,e=>{e.stopPropagation(),m.isCollapsed&&P(!1),N(`auth`)}),y.addEventListener(`click`,e=>{m.isCollapsed&&e.target!==T&&P(!1)}),m.isCollapsed||N(m.activeTab);let V=new URLSearchParams(window.location.search);(V.has(`code`)||V.has(`error`))&&(P(!1),N(`auth`));let H=e=>({userState:{gameSettings:{},id:`simulator-user`,nakamaLogin:`simulator`,ownerID:`simulator-owner`},currentUser:null,startOrFindGameplay:{gamePlayed:{additionalTimeAddedSecs:0,boardState:m.currentInputStr,cheatsUsed:0,combinedTimeSecs:0,completed:!1,createdAt:new Date().toISOString(),elapsedTimeSecs:0,hintsUsed:0,id:`simulator-gameplay-${Date.now()}`,ownerID:`simulator-owner`,pointsAwarded:0,resetsUsed:0,slug:`simulator-game`,viewerOwnsPuzzle:!0,puzzle:{id:`simulator-puzzle`,name:`Proto Jig Puzzle`,puzzle:JSON.stringify(e),seriesNumber:1,game:{assetsPath:`./assets/`,assetsSha:``,displayName:`Proto Game`,exposedGlobalFunction:`startGame`,jsPath:``,slug:`proto-game`}}}},theme:m.selectedTheme,hostFlags:[],hostContext:[],appRuntimeContract:`1.0`}),U=function(){var t=e.t(function*(){j(`Loading puzzle...`,`waiting`);try{let e=H(yield I());j(`Sending READY_DATA...`,`waiting`),R(`READY_DATA`,e),j(`Waiting for game to load...`,`waiting`)}catch(e){j(`Error: ${e}`,`paused`)}});return function(){return t.apply(this,arguments)}}(),W=()=>{console.log(`Simulator: Game loaded, ready to start`),C.disabled=!1,f.forEach(e=>{var t;return(t=e.onMessage)==null?void 0:t.call(e,`READY_GAME_LOADED`,void 0,B)}),i&&!m.hasStarted&&setTimeout(()=>{let e=k(`#simulator-start`);e==null||e.click(),S.disabled=!1,m.hasStarted=!0,j(`Running`,`ready`)},100)};return ne((e,t)=>{var n,r;if(e===`READY`){console.log(`Simulator: Received READY from game`),U();return}if(e===`INITIALIZE_SETTINGS`){console.log(`Simulator: Game initialized settings`,t);return}if(e===`READY_GAME_LOADED`){W();return}if(e===`TIMER_TICK`){if(t!=null&&t.display){let[e,n]=t.display;M(e,n)}return}if(e===`TIMER_SYNC`)return;if(e===`SHOW_GAME_COMPLETE_SCREEN`){console.log(`Simulator: Show completion screen`,t);return}if(e===`SIDEBAR_UPDATE`){console.log(`Simulator: Sidebar update`,t);return}f.forEach(n=>{var r;return(r=n.onMessage)==null?void 0:r.call(n,e,t,B)});let i=(n=t==null||(r=t.input)==null?void 0:r.boardState)==null?t==null?void 0:t.boardState:n;e===`UPLOAD_NEW_GAME_STATE`&&i&&(m.currentInputStr=i,m.activeTab===`thumb`&&F(),console.log(`Simulator: Game state uploaded`,t)),e===`GAME_COMPLETED`&&(console.log(`Simulator: Game completed!`,t),S.disabled=!0,m.hasStarted=!1,j(`Completed!`,`ready`))},L),console.log(`Simulator initialized`),$={updateFixtures:e=>{a=v(e),o=Array.from(a.keys()).sort(),B.fixtures=a,B.fixtureCategories=o;let t=localStorage.getItem(`simulator-fixture-category`);if(!m.selectedCategory||!o.includes(m.selectedCategory)){var n;m.selectedCategory=t&&o.includes(t)?t:(n=o[0])==null?null:n}let r=f.find(e=>e.id===`ctrl`);r==null||r.bind(B),console.log(`Simulator: Fixtures updated`,{categories:o,selectedCategory:m.selectedCategory})},sendToGame:R,loadPuzzle:I},$}Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Pe}});
1428
- //# sourceMappingURL=createSimulator-CGTMmToi.cjs.map
1508
+ `,document.body.appendChild(g);let _=g.querySelector(`#simulator-panel`),y=g.querySelector(`#simulator-header`),b=g.querySelector(`#simulator-header-indicator`),x=g.querySelector(`#simulator-header-status-text`),S=g.querySelector(`#simulator-header-pause`),C=g.querySelector(`#simulator-header-retry`),w=g.querySelector(`#simulator-header-settings`),T=g.querySelector(`#simulator-toggle`),E=g.querySelector(`#simulator-timer`),D=g.querySelector(`#simulator-tabs`),O=g.querySelector(`#simulator-content`),k=e=>g.querySelector(e),A=e=>{S.innerHTML=e?h.play:h.pause,S.title=e?`Resume`:`Pause`},j=(e,t)=>{let n=k(`#simulator-status .text`),r=k(`#simulator-status .indicator`);n&&(n.textContent=e),r&&(r.className=`indicator ${t}`),b.className=t,x.textContent=e},M=(e,t)=>{t&&t!==`0`?E.innerHTML=`${e}<span class="penalty">+${t}</span>`:E.textContent=e},N=e=>{var t;m.activeTab=e,O.classList.remove(`hidden`),d(e),D.querySelectorAll(`.simulator-tab`).forEach(t=>{t.classList.toggle(`active`,t.getAttribute(`data-tab`)===e)}),g.querySelectorAll(`.simulator-tab-content`).forEach(t=>{t.classList.toggle(`active`,t.id===`simulator-tab-${e}`)}),w.classList.toggle(`active`,e===`auth`);let n=f.find(t=>t.id===e);n==null||(t=n.onActivate)==null||t.call(n,B)},P=e=>{m.isCollapsed=e,_.classList.toggle(`collapsed`,e),u(e),e?(O.classList.add(`hidden`),D.querySelectorAll(`.simulator-tab`).forEach(e=>e.classList.remove(`active`))):N(m.activeTab)},F=()=>{c.updatePreview(B)},I=function(){var t=e.t(function*(){var e,t;if(m.puzzleData)return m.puzzleData;if(!a||a.size===0)throw Error(`No fixtures configured. Add puzzle JSON files to a fixtures directory and pass fixturesGlob to the simulator.`);let n=(e=m.selectedCategory)==null?o[0]:e,r=n?a.get(n):void 0;if(!r||r.size===0)throw Error(`No puzzles found in fixture category "${n}"`);let i=(t=m.selectedPuzzle)==null?r.keys().next().value:t,s=i?r.get(i):void 0;if(!s)throw Error(`Puzzle "${i}" not found in category "${n}"`);m.puzzleData=s,console.log(`Simulator: Puzzle loaded from fixtures`,{category:n,puzzle:i}),m.originalPuzzle=JSON.stringify(m.puzzleData,null,2);let c=k(`#simulator-puzzle`);return c&&(c.value=m.originalPuzzle),m.activeTab===`thumb`&&F(),m.puzzleData});return function(){return t.apply(this,arguments)}}(),L=ee(e=>{s.addLogEntry(e,B)}),R=(e,t)=>{te(e,t,L)},z=(e,t)=>{let n=g.querySelector(`[data-badge="${e}"]`);n&&(n.textContent=t&&t>0?String(t):``)},B={state:m,getElement:k,sendToGame:R,logMessage:L.log,loadPuzzle:I,updateStatus:j,updateTimer:M,setCollapsed:P,switchTab:N,updateThumbnail:F,updateBadge:z,fixtures:a,fixtureCategories:o,gameSlug:(r=t.slug)==null?null:r};console.log(`[Simulator] Context created with gameSlug:`,B.gameSlug),f.forEach(e=>e.bind(B)),D.querySelectorAll(`.simulator-tab`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-tab`);N(t),z(t,0)})}),T.addEventListener(`click`,e=>{e.stopPropagation(),P(!0)}),S.addEventListener(`click`,e=>{e.stopPropagation(),m.isPaused?(R(`RESUME_GAME`,{}),m.isPaused=!1,A(!1),j(`Running`,`ready`)):(R(`PAUSE_GAME`,{}),m.isPaused=!0,A(!0),j(`Paused`,`paused`));let t=k(`#simulator-pause`);t&&(t.textContent=m.isPaused?`Resume`:`Pause`)}),C.addEventListener(`click`,e=>{e.stopPropagation(),R(`RETRY_PUZZLE`,{}),m.hasStarted=!1,m.isPaused=!1,A(!1),S.disabled=!0,j(`Ready to retry`,`ready`);let t=k(`#simulator-pause`),n=k(`#simulator-start`);t&&(t.disabled=!0,t.textContent=`Pause`),n&&(n.textContent=`Start`)}),w.addEventListener(`click`,e=>{e.stopPropagation(),m.isCollapsed&&P(!1),N(`auth`)}),y.addEventListener(`click`,e=>{m.isCollapsed&&e.target!==T&&P(!1)}),m.isCollapsed||N(m.activeTab);let V=new URLSearchParams(window.location.search);(V.has(`code`)||V.has(`error`))&&(P(!1),N(`auth`));let H=e=>({userState:{gameSettings:{},id:`simulator-user`,nakamaLogin:`simulator`,ownerID:`simulator-owner`},currentUser:null,startOrFindGameplay:{gamePlayed:{additionalTimeAddedSecs:0,boardState:m.currentInputStr,cheatsUsed:0,combinedTimeSecs:0,completed:!1,createdAt:new Date().toISOString(),elapsedTimeSecs:0,hintsUsed:0,id:`simulator-gameplay-${Date.now()}`,ownerID:`simulator-owner`,pointsAwarded:0,resetsUsed:0,slug:`simulator-game`,viewerOwnsPuzzle:!0,puzzle:{id:`simulator-puzzle`,name:`Proto Jig Puzzle`,puzzle:JSON.stringify(e),seriesNumber:1,game:{assetsPath:`./assets/`,assetsSha:``,displayName:`Proto Game`,exposedGlobalFunction:`startGame`,jsPath:``,slug:`proto-game`}}}},theme:m.selectedTheme,hostFlags:[],hostContext:[],appRuntimeContract:`1.0`}),U=function(){var t=e.t(function*(){j(`Loading puzzle...`,`waiting`);try{let e=H(yield I());j(`Sending READY_DATA...`,`waiting`),R(`READY_DATA`,e),j(`Waiting for game to load...`,`waiting`)}catch(e){j(`Error: ${e}`,`paused`)}});return function(){return t.apply(this,arguments)}}(),W=()=>{console.log(`Simulator: Game loaded, ready to start`),C.disabled=!1,f.forEach(e=>{var t;return(t=e.onMessage)==null?void 0:t.call(e,`READY_GAME_LOADED`,void 0,B)}),i&&!m.hasStarted&&setTimeout(()=>{let e=k(`#simulator-start`);e==null||e.click(),S.disabled=!1,m.hasStarted=!0,j(`Running`,`ready`)},100)};return ne((e,t)=>{var n,r;if(e===`READY`){console.log(`Simulator: Received READY from game`),U();return}if(e===`INITIALIZE_SETTINGS`){console.log(`Simulator: Game initialized settings`,t);return}if(e===`READY_GAME_LOADED`){W();return}if(e===`TIMER_TICK`){if(t!=null&&t.display){let[e,n]=t.display;M(e,n)}return}if(e===`TIMER_SYNC`)return;if(e===`SHOW_GAME_COMPLETE_SCREEN`){console.log(`Simulator: Show completion screen`,t);return}if(e===`SIDEBAR_UPDATE`){console.log(`Simulator: Sidebar update`,t);return}f.forEach(n=>{var r;return(r=n.onMessage)==null?void 0:r.call(n,e,t,B)});let i=(n=t==null||(r=t.input)==null?void 0:r.boardState)==null?t==null?void 0:t.boardState:n;e===`UPLOAD_NEW_GAME_STATE`&&i&&(m.currentInputStr=i,m.activeTab===`thumb`&&F(),console.log(`Simulator: Game state uploaded`,t)),e===`GAME_COMPLETED`&&(console.log(`Simulator: Game completed!`,t),S.disabled=!0,m.hasStarted=!1,j(`Completed!`,`ready`))},L),console.log(`Simulator initialized`),$={updateFixtures:e=>{a=v(e),o=Array.from(a.keys()).sort(),B.fixtures=a,B.fixtureCategories=o;let t=localStorage.getItem(`simulator-fixture-category`);if(!m.selectedCategory||!o.includes(m.selectedCategory)){var n;m.selectedCategory=t&&o.includes(t)?t:(n=o[0])==null?null:n}let r=f.find(e=>e.id===`ctrl`);r==null||r.bind(B),console.log(`Simulator: Fixtures updated`,{categories:o,selectedCategory:m.selectedCategory})},sendToGame:R,loadPuzzle:I},$}Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Re}});
1509
+ //# sourceMappingURL=createSimulator-HQPoM1pd.cjs.map