@puzzmo/sdk 1.0.23 → 1.0.25

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.
@@ -24,7 +24,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
24
24
  <div class="simulator-row">
25
25
  <button class="simulator-btn danger" id="simulator-retry" disabled>Retry</button>
26
26
  </div>
27
- `},bind(e){let t=e.getElement(`#simulator-start`),n=e.getElement(`#simulator-pause`),r=e.getElement(`#simulator-retry`),i=e.getElement(`#simulator-fixtures-container`);if(console.log(`Simulator: CtrlView.bind called`,{hasFixtures:!!e.fixtures,categories:e.fixtureCategories,selectedCategory:e.state.selectedCategory,selectedPuzzle:e.state.selectedPuzzle}),e.fixtures&&e.fixtureCategories.length>0&&i){i.innerHTML=y(e.fixtureCategories,e.state.selectedCategory);let t=e.getElement(`#simulator-fixture-category`),n=e.getElement(`#simulator-fixture-puzzle`);if(t&&n&&e.state.selectedCategory){e.state.selectedPuzzle=b(n,e.fixtures,e.state.selectedCategory,e.state.selectedPuzzle);let r=x(e.fixtures,e.state.selectedCategory,e.state.selectedPuzzle);console.log(`Simulator: Loading fixture puzzle`,{category:e.state.selectedCategory,puzzle:e.state.selectedPuzzle,hasPuzzleData:!!r}),r&&(e.state.puzzleData=r,e.state.originalPuzzle=JSON.stringify(r,null,2),e.state.selectedCategory&&p(e.state.selectedCategory),e.state.selectedPuzzle&&m(e.state.selectedPuzzle)),t.addEventListener(`change`,()=>{console.log(`Simulator: Category changed, reloading...`,t.value),p(t.value),h(),window.location.reload()}),n.addEventListener(`change`,()=>{console.log(`Simulator: Puzzle changed, reloading...`,n.value),m(n.value),window.location.reload()})}}t==null||t.addEventListener(`click`,()=>{e.state.isPaused?(e.sendToGame(`RESUME_GAME`,{}),e.state.isPaused=!1,n&&(n.textContent=`Pause`),e.updateStatus(`Running`,`ready`)):(e.sendToGame(`START_GAME`,void 0),e.state.hasStarted=!0,n&&(n.disabled=!1),t&&(t.textContent=`Resume`),e.updateStatus(`Running`,`ready`))}),n==null||n.addEventListener(`click`,()=>{e.state.isPaused?(e.sendToGame(`RESUME_GAME`,{}),e.state.isPaused=!1,n.textContent=`Pause`,e.updateStatus(`Running`,`ready`)):(e.sendToGame(`PAUSE_GAME`,{}),e.state.isPaused=!0,n.textContent=`Resume`,e.updateStatus(`Paused`,`paused`))}),r==null||r.addEventListener(`click`,()=>{e.sendToGame(`RETRY_PUZZLE`,{}),e.state.hasStarted=!1,e.state.isPaused=!1,n&&(n.disabled=!0,n.textContent=`Pause`),t&&(t.textContent=`Start`),e.updateStatus(`Ready to retry`,`ready`)})},onMessage(e,t,n){let r=n.getElement(`#simulator-start`),i=n.getElement(`#simulator-pause`),a=n.getElement(`#simulator-retry`);e===`READY_GAME_LOADED`&&(r&&(r.disabled=!1),a&&(a.disabled=!1),n.updateStatus(`Ready`,`ready`)),e===`GAME_COMPLETED`&&(n.state.hasStarted=!1,i&&(i.disabled=!0),r&&(r.disabled=!0),n.updateStatus(`Completed!`,`ready`))}}}var S=`simulator-saved-states`;function C(){let e=globalThis;for(let t of Object.keys(e))if(t.endsWith(`Thumbnail`)&&typeof e[t]==`function`)return{name:t,fn:e[t]};return null}function w(e,t){let n=C();if(!n)return``;try{let r=e.state.puzzleData?JSON.stringify(e.state.puzzleData):``,i={viewerIsOwner:!0,theme:e.state.selectedTheme,strict:!0,renderHost:`game`};return n.fn(r,t,i)}catch(e){return``}}var T=[];function E(e,t=8){let n=14*t+8+4;e.style.height=`auto`;let r=Math.min(Math.max(e.scrollHeight,40),n);e.style.height=`${r}px`}function ie(){let e=``,t=``;return{id:`data`,label:`Data`,render(){return`
27
+ `},bind(e){let t=e.getElement(`#simulator-start`),n=e.getElement(`#simulator-pause`),r=e.getElement(`#simulator-retry`),i=e.getElement(`#simulator-fixtures-container`);if(console.log(`Simulator: CtrlView.bind called`,{hasFixtures:!!e.fixtures,categories:e.fixtureCategories,selectedCategory:e.state.selectedCategory,selectedPuzzle:e.state.selectedPuzzle}),e.fixtures&&e.fixtureCategories.length>0&&i){i.innerHTML=y(e.fixtureCategories,e.state.selectedCategory);let t=e.getElement(`#simulator-fixture-category`),n=e.getElement(`#simulator-fixture-puzzle`);if(t&&n&&e.state.selectedCategory){e.state.selectedPuzzle=b(n,e.fixtures,e.state.selectedCategory,e.state.selectedPuzzle);let r=x(e.fixtures,e.state.selectedCategory,e.state.selectedPuzzle);console.log(`Simulator: Loading fixture puzzle`,{category:e.state.selectedCategory,puzzle:e.state.selectedPuzzle,hasPuzzleData:!!r}),r&&(e.state.puzzleData=r,e.state.originalPuzzle=JSON.stringify(r,null,2),e.state.selectedCategory&&p(e.state.selectedCategory),e.state.selectedPuzzle&&m(e.state.selectedPuzzle)),t.addEventListener(`change`,()=>{console.log(`Simulator: Category changed, reloading...`,t.value),p(t.value),h(),window.location.reload()}),n.addEventListener(`change`,()=>{console.log(`Simulator: Puzzle changed, reloading...`,n.value),m(n.value),window.location.reload()})}}t==null||t.addEventListener(`click`,()=>{e.state.isPaused?(e.sendToGame(`RESUME_GAME`,{}),e.state.isPaused=!1,n&&(n.textContent=`Pause`),e.updateStatus(`Running`,`ready`)):(e.sendToGame(`START_GAME`,void 0),e.state.hasStarted=!0,n&&(n.disabled=!1),t&&(t.textContent=`Resume`),e.updateStatus(`Running`,`ready`))}),n==null||n.addEventListener(`click`,()=>{e.state.isPaused?(e.sendToGame(`RESUME_GAME`,{}),e.state.isPaused=!1,n.textContent=`Pause`,e.updateStatus(`Running`,`ready`)):(e.sendToGame(`PAUSE_GAME`,{}),e.state.isPaused=!0,n.textContent=`Resume`,e.updateStatus(`Paused`,`paused`))}),r==null||r.addEventListener(`click`,()=>{e.sendToGame(`RETRY_PUZZLE`,{}),e.state.hasStarted=!1,e.state.isPaused=!1,n&&(n.disabled=!0,n.textContent=`Pause`),t&&(t.textContent=`Start`),e.updateStatus(`Ready to retry`,`ready`)})},onMessage(e,t,n){let r=n.getElement(`#simulator-start`),i=n.getElement(`#simulator-pause`),a=n.getElement(`#simulator-retry`);e===`READY_GAME_LOADED`&&(r&&(r.disabled=!1),a&&(a.disabled=!1),n.updateStatus(`Ready`,`ready`)),e===`GAME_COMPLETED`&&(n.state.hasStarted=!1,i&&(i.disabled=!0),r&&(r.disabled=!0),n.updateStatus(`Completed!`,`complete`))}}}var S=`simulator-saved-states`;function C(){let e=globalThis;for(let t of Object.keys(e))if(t.endsWith(`Thumbnail`)&&typeof e[t]==`function`)return{name:t,fn:e[t]};return null}function w(e,t){let n=C();if(!n)return``;try{let r=e.state.puzzleData?JSON.stringify(e.state.puzzleData):``,i={viewerIsOwner:!0,theme:e.state.selectedTheme,strict:!0,renderHost:`game`};return n.fn(r,t,i)}catch(e){return``}}var T=[];function E(e,t=8){let n=14*t+8+4;e.style.height=`auto`;let r=Math.min(Math.max(e.scrollHeight,40),n);e.style.height=`${r}px`}function ie(){let e=``,t=``;return{id:`data`,label:`Data`,render(){return`
28
28
  <div class="data-view-container">
29
29
  <div class="data-subtabs">
30
30
  <button class="data-subtab active" data-subtab="edit">Edit</button>
@@ -133,10 +133,10 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
133
133
  <textarea class="simulator-textarea" id="simulator-done-raw" rows="4" readonly></textarea>
134
134
  </div>
135
135
  </div>
136
- `},bind(e){},onMessage(e,t,n){var r,i;if(e!==`GAME_COMPLETED`)return;n.state.completionData=t;let a=n.getElement(`#simulator-done-empty`),o=n.getElement(`#simulator-done-content`),s=n.getElement(`#simulator-done-text`),c=n.getElement(`#simulator-done-input`),l=n.getElement(`#simulator-done-deeds`),u=n.getElement(`#simulator-done-raw`);a&&(a.style.display=`none`),o&&(o.style.display=`block`);let d=((r=t.input)==null?void 0:r.completionText)||t.completionText||`(no completion text)`;s&&(s.textContent=d);let f=((i=t.input)==null?void 0:i.boardState)||t.boardState||n.state.currentInputStr||``;if(c&&(c.value=f),l){var p;l.innerHTML=``;let e=((p=t.config)==null?void 0:p.deeds)||t.deeds;e&&Array.isArray(e)?e.forEach(e=>{let t=document.createElement(`div`);t.className=`simulator-deed`,t.innerHTML=`
136
+ `},bind(e){},onMessage(e,t,n){var r,i;if(e===`SHOW_GAME_COMPLETE_SCREEN`){n.setCollapsed(!1),n.switchTab(`done`);return}if(e!==`GAME_COMPLETED`)return;n.state.completionData=t;let a=n.getElement(`#simulator-done-empty`),o=n.getElement(`#simulator-done-content`),s=n.getElement(`#simulator-done-text`),c=n.getElement(`#simulator-done-input`),l=n.getElement(`#simulator-done-deeds`),u=n.getElement(`#simulator-done-raw`);a&&(a.style.display=`none`),o&&(o.style.display=`block`);let d=((r=t.input)==null?void 0:r.completionText)||t.completionText||`(no completion text)`;s&&(s.textContent=d);let f=((i=t.input)==null?void 0:i.boardState)||t.boardState||n.state.currentInputStr||``;if(c&&(c.value=f),l){var p;l.innerHTML=``;let e=((p=t.config)==null?void 0:p.deeds)||t.deeds;e&&Array.isArray(e)?e.forEach(e=>{let t=document.createElement(`div`);t.className=`simulator-deed`,t.innerHTML=`
137
137
  <span class="simulator-deed-name">${e.id}</span>
138
138
  <span class="simulator-deed-value">${e.value}</span>
139
- `,l.appendChild(t)}):l.innerHTML=`<div class="simulator-empty">No deeds</div>`}u&&(u.value=JSON.stringify(t,null,2)),n.setCollapsed(!1),n.switchTab(`done`)}}}function se(){let e=[],t=()=>new Date().toLocaleTimeString(`en-US`,{hour12:!1}),n=e=>{let{checkpointName:t,augConfig:n,time:r}=e,i=n==null?void 0:n.deeds;return`
139
+ `,l.appendChild(t)}):l.innerHTML=`<div class="simulator-empty">No deeds</div>`}u&&(u.value=JSON.stringify(t,null,2))}}}function se(){let e=[],t=()=>new Date().toLocaleTimeString(`en-US`,{hour12:!1}),n=e=>{let{checkpointName:t,augConfig:n,time:r}=e,i=n==null?void 0:n.deeds;return`
140
140
  <div class="checkpoint-item">
141
141
  <div class="checkpoint-header">
142
142
  <span class="checkpoint-name">${t}</span>
@@ -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 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`
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`,ue=e=>localStorage.setItem(W,e),de=e=>localStorage.setItem(G,e),K=()=>{let e=localStorage.getItem(W);return e&&`${e.substring(0,20)}`,e},q=()=>localStorage.getItem(G),J=()=>{localStorage.removeItem(W),localStorage.removeItem(G)},fe=()=>{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()},pe=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}},me=function(){var t=e.t(function*(){let e=q();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;ue(a);let o=i.refresh_token||i.refreshToken;return o&&de(o),!0}catch(e){return!1}});return function(){return t.apply(this,arguments)}}(),he=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)}}(),ge=function(){var t=e.t(function*(e,t={}){let n=H(),r=K();if(!r)throw Error(`Not authenticated`);if(pe(r))if(yield me()){if(r=K(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw J(),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)}}(),_e=e=>{try{let t=e.split(`.`);return t.length,t.length===3?JSON.parse(atob(t[1])):null}catch(e){return null}};function ve(){let t=!1;return{id:`auth`,label:`Auth`,render(){let e=K(),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=_e(e),n=t!=null&&t.exp?new Date(t.exp*1e3).toLocaleString():`Unknown`,a=!!q(),o=a?_e(q()):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>
@@ -241,7 +241,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
241
241
  </div>
242
242
  <div id="auth-error" class="auth-error"></div>
243
243
  </div>
244
- `},bind(n){let r=n.getElement(`#auth-login`),i=n.getElement(`#auth-logout`),a=n.getElement(`#auth-refresh`),o=n.getElement(`#auth-test-api`),s=n.getElement(`#auth-api-result`),c=n.getElement(`#auth-dev-toggle`);t?B&&c&&(c.style.display=``,R()===`dev`&&c.classList.add(`active`)):(t=!0,V().then(e=>{e&&c&&(c.style.display=``,R()===`dev`&&c.classList.add(`active`))})),c==null||c.addEventListener(`click`,()=>{z(R()===`dev`?`prod`:`dev`),Y(),window.location.reload()}),r==null||r.addEventListener(`click`,()=>{de()}),i==null||i.addEventListener(`click`,()=>{Y(),window.location.reload()}),a==null||a.addEventListener(`click`,e.t(function*(){a.disabled=!0,a.textContent=`Refreshing...`,(yield pe())?window.location.reload():(a.textContent=`Refresh Failed`,a.disabled=!1)})),o==null||o.addEventListener(`click`,e.t(function*(){if(s){s.innerHTML=`<div class="loading">Loading...</div>`;try{let t=yield he(`
244
+ `},bind(n){let r=n.getElement(`#auth-login`),i=n.getElement(`#auth-logout`),a=n.getElement(`#auth-refresh`),o=n.getElement(`#auth-test-api`),s=n.getElement(`#auth-api-result`),c=n.getElement(`#auth-dev-toggle`);t?B&&c&&(c.style.display=``,R()===`dev`&&c.classList.add(`active`)):(t=!0,V().then(e=>{e&&c&&(c.style.display=``,R()===`dev`&&c.classList.add(`active`))})),c==null||c.addEventListener(`click`,()=>{z(R()===`dev`?`prod`:`dev`),J(),window.location.reload()}),r==null||r.addEventListener(`click`,()=>{fe()}),i==null||i.addEventListener(`click`,()=>{J(),window.location.reload()}),a==null||a.addEventListener(`click`,e.t(function*(){a.disabled=!0,a.textContent=`Refreshing...`,(yield me())?window.location.reload():(a.textContent=`Refresh Failed`,a.disabled=!1)})),o==null||o.addEventListener(`click`,e.t(function*(){if(s){s.innerHTML=`<div class="loading">Loading...</div>`;try{let t=yield ge(`
245
245
  query {
246
246
  currentUser {
247
247
  id
@@ -250,7 +250,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
250
250
  name
251
251
  }
252
252
  }
253
- `);if(t.errors){var e;s.innerHTML=`<div class="error">Error: ${((e=t.errors[0])==null?void 0:e.message)||`Unknown error`}</div>`}else s.innerHTML=`<pre>${JSON.stringify(t.data,null,2)}</pre>`}catch(e){s.innerHTML=`<div class="error">Error: ${e instanceof Error?e.message:`Unknown error`}</div>`}}}))},onActivate(t){return e.t(function*(){let e=new URLSearchParams(window.location.search),n=e.get(`code`),r=e.get(`state`),i=e.get(`error`);if(i){let e=t.getElement(`#auth-error`);e&&(e.innerHTML=`<div class="error">OAuth error: ${i}</div>`),window.history.replaceState({},``,window.location.pathname);return}if(n&&r){let e=t.getElement(`#auth-status`);e&&(e.innerHTML=`<span class="indicator waiting"></span><span>Exchanging code...</span>`);let i=yield me(n,r);if(window.history.replaceState({},``,window.location.pathname),i){let e=i.access_token||i.accessToken;if(e){K(e);let t=i.refresh_token||i.refreshToken;t&&ue(t)}window.location.reload()}else{let e=t.getElement(`#auth-error`);e&&(e.innerHTML=`<div class="error">Failed to exchange code for token</div>`)}}})()}}}var ve=`puzzmo_sim_api_mode`,ye=`http://localhost:8911`,be=`https://api.puzzmo.com`,X=`puzzmo_sim_oauth_token`,Z=`puzzmo_sim_oauth_refresh_token`,xe=()=>localStorage.getItem(ve)===`dev`?`dev`:`prod`,Q=()=>localStorage.getItem(X),Se=()=>localStorage.getItem(Z),Ce=e=>localStorage.setItem(X,e),we=e=>localStorage.setItem(Z,e),Te=()=>{localStorage.removeItem(X),localStorage.removeItem(Z)},Ee=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}},De=function(){var t=e.t(function*(){let e=Se();if(!e)return!1;let t=xe()===`dev`?ye:be;try{let n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:`protosdk:oauthclient`}),r=yield fetch(`${t}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:n.toString()});if(!r.ok)return!1;let i=yield r.json(),a=i.access_token||i.accessToken;if(!a)return!1;Ce(a);let o=i.refresh_token||i.refreshToken;return o&&we(o),!0}catch(e){return!1}});return function(){return t.apply(this,arguments)}}(),Oe=function(){var t=e.t(function*(e,t={}){let n=xe()===`dev`?ye:be,r=Q();if(!r)throw Error(`Not authenticated`);if(Ee(r))if(yield De()){if(r=Q(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw Te(),Error(`Session expired. Please log in again.`);let i=yield fetch(`${n}/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)}}(),ke=`
253
+ `);if(t.errors){var e;s.innerHTML=`<div class="error">Error: ${((e=t.errors[0])==null?void 0:e.message)||`Unknown error`}</div>`}else s.innerHTML=`<pre>${JSON.stringify(t.data,null,2)}</pre>`}catch(e){s.innerHTML=`<div class="error">Error: ${e instanceof Error?e.message:`Unknown error`}</div>`}}}))},onActivate(t){return e.t(function*(){let e=new URLSearchParams(window.location.search),n=e.get(`code`),r=e.get(`state`),i=e.get(`error`);if(i){let e=t.getElement(`#auth-error`);e&&(e.innerHTML=`<div class="error">OAuth error: ${i}</div>`),window.history.replaceState({},``,window.location.pathname);return}if(n&&r){let e=t.getElement(`#auth-status`);e&&(e.innerHTML=`<span class="indicator waiting"></span><span>Exchanging code...</span>`);let i=yield he(n,r);if(window.history.replaceState({},``,window.location.pathname),i){let e=i.access_token||i.accessToken;if(e){ue(e);let t=i.refresh_token||i.refreshToken;t&&de(t)}window.location.reload()}else{let e=t.getElement(`#auth-error`);e&&(e.innerHTML=`<div class="error">Failed to exchange code for token</div>`)}}})()}}}var ye=`puzzmo_sim_api_mode`,be=`http://localhost:8911`,xe=`https://api.puzzmo.com`,Y=`puzzmo_sim_oauth_token`,X=`puzzmo_sim_oauth_refresh_token`,Se=()=>localStorage.getItem(ye)===`dev`?`dev`:`prod`,Z=()=>localStorage.getItem(Y),Ce=()=>localStorage.getItem(X),we=e=>localStorage.setItem(Y,e),Te=e=>localStorage.setItem(X,e),Ee=()=>{localStorage.removeItem(Y),localStorage.removeItem(X)},De=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}},Oe=function(){var t=e.t(function*(){let e=Ce();if(!e)return!1;let t=Se()===`dev`?be:xe;try{let n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:`protosdk:oauthclient`}),r=yield fetch(`${t}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:n.toString()});if(!r.ok)return!1;let i=yield r.json(),a=i.access_token||i.accessToken;if(!a)return!1;we(a);let o=i.refresh_token||i.refreshToken;return o&&Te(o),!0}catch(e){return!1}});return function(){return t.apply(this,arguments)}}(),ke=function(){var t=e.t(function*(e,t={}){let n=Se()===`dev`?be:xe,r=Z();if(!r)throw Error(`Not authenticated`);if(De(r))if(yield Oe()){if(r=Z(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw Ee(),Error(`Session expired. Please log in again.`);let i=yield fetch(`${n}/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)}}(),Ae=`
254
254
  query GameFeaturesQuery($slug: ID!) {
255
255
  game(id: $slug) {
256
256
  id
@@ -268,7 +268,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
268
268
  }
269
269
  }
270
270
  }
271
- `,Ae=`
271
+ `,je=`
272
272
  mutation ToggleFeatureMutation($gameSlug: ID!, $input: UpdateGameInput!) {
273
273
  updateGame(id: $gameSlug, input: $input) {
274
274
  id
@@ -284,7 +284,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
284
284
  }
285
285
  }
286
286
  }
287
- `,je=(e,t)=>{let n=t-1,r=Math.floor(n/31),i=n%31,a=[...e];for(;a.length<=r;)a.push(0);return a[r]=a[r]^1<<i,a};const Me=()=>!!Q();function Ne(){let n=null,r=!1,i=null,a=function(){var t=e.t(function*(e){r=!0,i=null;try{var t;let r=yield Oe(ke,{slug:e});if(r.errors){var a;i=((a=r.errors[0])==null?void 0:a.message)||`Unknown error`,n=null}else (t=r.data)!=null&&t.game?n=r.data.game:(i=`Game not found`,n=null)}catch(e){i=e instanceof Error?e.message:`Unknown error`,n=null}finally{r=!1}});return function(e){return t.apply(this,arguments)}}(),o=function(){var r=e.t(function*(e){if(!n)return;let r=je(n.featuresArr,e);try{var i;let e=yield Oe(Ae,{gameSlug:n.slug,input:{featuresArr:r}});if(e.errors){var a;console.error(`Failed to toggle feature:`,(a=e.errors[0])==null?void 0:a.message)}else (i=e.data)!=null&&i.updateGame&&(n=t.t(t.t({},n),{},{featuresArr:e.data.updateGame.featuresArr,gameFeatures:e.data.updateGame.gameFeatures}))}catch(e){console.error(`Failed to toggle feature:`,e)}});return function(e){return r.apply(this,arguments)}}(),s=()=>{if(r)return`<div class="features-loading">Loading features...</div>`;if(i)return`<div class="features-error">${i}</div>`;if(!n)return`<div class="features-empty">Enter your game slug above to load features</div>`;let e=n.gameFeatures.map(e=>{let t=e.features.map(e=>{let t=e.isEnabled?`enabled`:`disabled`,n=e.isEnabled?`✓`:`✗`;return`
287
+ `,Me=(e,t)=>{let n=t-1,r=Math.floor(n/31),i=n%31,a=[...e];for(;a.length<=r;)a.push(0);return a[r]=a[r]^1<<i,a};const Ne=()=>!!Z();function Pe(){let n=null,r=!1,i=null,a=function(){var t=e.t(function*(e){r=!0,i=null;try{var t;let r=yield ke(Ae,{slug:e});if(r.errors){var a;i=((a=r.errors[0])==null?void 0:a.message)||`Unknown error`,n=null}else (t=r.data)!=null&&t.game?n=r.data.game:(i=`Game not found`,n=null)}catch(e){i=e instanceof Error?e.message:`Unknown error`,n=null}finally{r=!1}});return function(e){return t.apply(this,arguments)}}(),o=function(){var r=e.t(function*(e){if(!n)return;let r=Me(n.featuresArr,e);try{var i;let e=yield ke(je,{gameSlug:n.slug,input:{featuresArr:r}});if(e.errors){var a;console.error(`Failed to toggle feature:`,(a=e.errors[0])==null?void 0:a.message)}else (i=e.data)!=null&&i.updateGame&&(n=t.t(t.t({},n),{},{featuresArr:e.data.updateGame.featuresArr,gameFeatures:e.data.updateGame.gameFeatures}))}catch(e){console.error(`Failed to toggle feature:`,e)}});return function(e){return r.apply(this,arguments)}}(),s=()=>{if(r)return`<div class="features-loading">Loading features...</div>`;if(i)return`<div class="features-error">${i}</div>`;if(!n)return`<div class="features-empty">Enter your game slug above to load features</div>`;let e=n.gameFeatures.map(e=>{let t=e.features.map(e=>{let t=e.isEnabled?`enabled`:`disabled`,n=e.isEnabled?`✓`:`✗`;return`
288
288
  <div class="feature-item ${t}" data-feature-id="${e.featureID}">
289
289
  <span class="feature-status">${n}</span>
290
290
  <span class="feature-title">${e.title}</span>
@@ -297,7 +297,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
297
297
  `}).join(``);return`
298
298
  <div class="features-game-name">${n.displayName}</div>
299
299
  ${e}
300
- `};return{id:`features`,label:`Features`,render(){return Me()?`
300
+ `};return{id:`features`,label:`Features`,render(){return Ne()?`
301
301
  <div class="features-view-container">
302
302
  <div class="simulator-section">
303
303
  <div class="simulator-section-title">Game Features</div>
@@ -321,13 +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 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`
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,Ne()&&!n&&d(t.gameSlug)),u()},onActivate(e){let t=e.getElement(`#simulator-tab-features`);t&&(t.innerHTML=this.render(),this.bind(e))}}}var Fe=(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>`},Ie=e=>`<div class="sim-kb">${e.layout.filter(e=>e!=null).map(t=>`<div class="sim-kb-row">${[...t].map(t=>Fe(t,e)).join(``)}</div>`).join(``)}</div>`;function Le(){let e=null,t=()=>e?Ie(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
325
  <div class="keyboard-view-container">
326
326
  <div id="sim-kb-content">
327
327
  ${t()}
328
328
  </div>
329
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=`
330
+ `},bind(e){Q(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(),Q(i)),i.updateBadge(`kbd`,void 0)}}}function Q(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(),ve(),Pe(),Le()],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=`
331
331
  <style>
332
332
  :root {
333
333
  --sim-bg: #1a1a2e;
@@ -449,6 +449,16 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
449
449
  background: var(--sim-error);
450
450
  box-shadow: 0 0 4px var(--sim-error);
451
451
  }
452
+ #simulator-header-indicator.complete {
453
+ background: transparent;
454
+ box-shadow: none;
455
+ color: var(--sim-success);
456
+ width: auto;
457
+ height: auto;
458
+ font-size: 11px;
459
+ line-height: 1;
460
+ font-weight: bold;
461
+ }
452
462
  #simulator-timer {
453
463
  font-size: 11px;
454
464
  color: var(--sim-text);
@@ -638,6 +648,16 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
638
648
  background: var(--sim-error);
639
649
  box-shadow: 0 0 6px var(--sim-error);
640
650
  }
651
+ #simulator-status .indicator.complete {
652
+ background: transparent;
653
+ box-shadow: none;
654
+ color: var(--sim-success);
655
+ width: auto;
656
+ height: auto;
657
+ font-size: 12px;
658
+ line-height: 1;
659
+ font-weight: bold;
660
+ }
641
661
  .simulator-row {
642
662
  display: flex;
643
663
  gap: 4px;
@@ -1505,5 +1525,5 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
1505
1525
  </div>
1506
1526
  </div>
1507
1527
  </div>
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
1528
+ `,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`),i=t===`complete`?`✓`:``;n&&(n.textContent=e),r&&(r.className=`indicator ${t}`,r.textContent=i),b.className=t,b.textContent=i,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===`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!`,`complete`))},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}});
1529
+ //# sourceMappingURL=createSimulator-BVMKhHqV.cjs.map