narraleaf-react 0.4.3 → 0.4.4

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.
@@ -92,6 +92,7 @@ export declare class GameState {
92
92
  exposedState: Map<Values<ExposedKeys>, object>;
93
93
  guard: GameStateGuard;
94
94
  timelines: Timelines;
95
+ preloadingScene: Scene | null;
95
96
  readonly notificationMgr: NotificationManager;
96
97
  readonly events: EventDispatcher<GameStateEvents>;
97
98
  readonly logger: Logger;
@@ -108,6 +109,8 @@ export declare class GameState {
108
109
  findElementByScene(scene: Scene): PlayerStateElement | null;
109
110
  findElementByDisplayable(displayable: LogicAction.DisplayableElements, layer?: Layer | null): PlayerStateElement | null;
110
111
  removeElement(element: PlayerStateElement): this;
112
+ preloadScene(scene: Scene): this;
113
+ getPreloadingScene(): Scene | null;
111
114
  addElement(element: PlayerStateElement): this;
112
115
  addScene(scene: Scene): this;
113
116
  flush(): this;
package/dist/main.js CHANGED
@@ -48,21 +48,21 @@ Use video.show() to add the video to the game`);let r=this.callee,i=new b,s=t.ge
48
48
  NarraLeaf cannot find the element with the id from the saved game`);this.soundFromData(s,i)}),this}soundFromData(t,n){let r=this.getState(t);r.group.playing(r.token)&&r.group.stop(r.token);let i=this.initSound(t);this.state.set(t,i),i.group.seek(n.position,i.token),t.state.paused?i.group.pause(i.token):n.isPlaying||i.group.stop(i.token)}isManaged(t){return this.state.has(t)}reset(){this.state.forEach(t=>{t.group.stop(t.token)}),this.state.clear(),this.tasks.forEach(t=>{t.awaitable.abort()}),this.tasks.clear()}initSound(t){if(this.state.has(t))return this.state.get(t);let n=this,[r,i]=this.wrapTask(),[s,c]=this.wrapTask(),u=Reflect.construct(this.gameState.getHowl(),[this.getHowlConfig(t,{onend(){s.resolve()},onplay(){r.resolve()},onloaderror(f,a){let l=a,m={1:"The fetching process for the media resource was aborted by the user agent at the user's request.",2:"A network error of some description caused the user agent to stop fetching the media resource, after the resource was established to be usable.",3:"An error of some description occurred while decoding the media resource, after the resource was established to be usable.",4:"The media resource indicated by the src attribute or assigned media provider object was not suitable."};n.gameState.logger.error("AudioManager",`Failed to load sound (src: "${t.config.src}")
49
49
  ${m[l]}
50
50
  For more information, see https://github.com/goldfire/howler.js?tab=readme-ov-file#onloaderror-function`)}})]),p=u.play();return this.state.set(t,{group:u,token:p}),u.seek(t.config.seek,p).volume(t.state.volume,p).rate(t.state.rate,p),t.state.paused&&u.pause(p),{group:u,token:p,onPlayTask:i,onEndTask:c}}pushTask(t,n){return this.tasks.set(t,{awaitable:n}),n}getState(t){if(!this.state.has(t))throw new M(`Sound not initialized (src: "${t.config.src}")`);return this.state.get(t)}abortTask(t){let n=this.tasks.get(t);n&&(n.awaitable.abort(),this.tasks.delete(t))}fadeTo(t,n,r){let i,s,c=r.start??t.volume(),u=r.end??t.volume(),p=r.duration,f=new K(()=>{t.volume(u,n),i()});return[l=>{t.volume(c,n),t.fade(c,u,p,n),i=()=>{l.isSolved()||(s&&(s(),s=void 0),l.resolve())},s=this.gameState.schedule(()=>{s=void 0,i()},p)},f]}stopSound(t,n){return[()=>{t.stop(n)}]}pauseSound(t,n){return[()=>{t.pause(n)}]}resumeSound(t,n){return[()=>{t.play(n)}]}getHowlConfig(t,n={}){return{src:t.config.src,volume:t.state.volume,loop:t.config.loop,rate:t.state.rate,html5:t.config.streaming,...n}}createTask(t){return[n=>{t(n.resolve.bind(n))}]}wrapTask(){let t=new b;return[t,[n=>{t.isSolved()?n.resolve():t.then(()=>{n.resolve()})}]]}};var Hc={};Ud(Hc,{getFontEmbedCSS:()=>KT,toBlob:()=>UT,toCanvas:()=>Fr,toJpeg:()=>HT,toPixelData:()=>FT,toPng:()=>OT,toSvg:()=>Ff});function vf(o,t){if(o.match(/^[a-z]+:\/\//i))return o;if(o.match(/^\/\//))return window.location.protocol+o;if(o.match(/^[a-z]+:/i))return o;let n=document.implementation.createHTMLDocument(),r=n.createElement("base"),i=n.createElement("a");return n.head.appendChild(r),n.body.appendChild(i),t&&(r.href=t),i.href=o,i.href}var Sf=(()=>{let o=0,t=()=>`0000${(Math.random()*36**4<<0).toString(36)}`.slice(-4);return()=>(o+=1,`u${t()}${o}`)})();function Tt(o){let t=[];for(let n=0,r=o.length;n<r;n++)t.push(o[n]);return t}var zo=null;function Ws(o={}){return zo||(o.includeStyleProperties?(zo=o.includeStyleProperties,zo):(zo=Tt(window.getComputedStyle(document.documentElement)),zo))}function Bs(o,t){let r=(o.ownerDocument.defaultView||window).getComputedStyle(o).getPropertyValue(t);return r?parseFloat(r.replace("px","")):0}function rT(o){let t=Bs(o,"border-left-width"),n=Bs(o,"border-right-width");return o.clientWidth+t+n}function iT(o){let t=Bs(o,"border-top-width"),n=Bs(o,"border-bottom-width");return o.clientHeight+t+n}function js(o,t={}){let n=t.width||rT(o),r=t.height||iT(o);return{width:n,height:r}}function xf(){let o,t;try{t=process}catch{}let n=t&&t.env?t.env.devicePixelRatio:null;return n&&(o=parseInt(n,10),Number.isNaN(o)&&(o=1)),o||window.devicePixelRatio||1}var nt=16384;function bf(o){(o.width>nt||o.height>nt)&&(o.width>nt&&o.height>nt?o.width>o.height?(o.height*=nt/o.width,o.width=nt):(o.width*=nt/o.height,o.height=nt):o.width>nt?(o.height*=nt/o.width,o.width=nt):(o.width*=nt/o.height,o.height=nt))}function Af(o,t={}){return o.toBlob?new Promise(n=>{o.toBlob(n,t.type?t.type:"image/png",t.quality?t.quality:1)}):new Promise(n=>{let r=window.atob(o.toDataURL(t.type?t.type:void 0,t.quality?t.quality:void 0).split(",")[1]),i=r.length,s=new Uint8Array(i);for(let c=0;c<i;c+=1)s[c]=r.charCodeAt(c);n(new Blob([s],{type:t.type?t.type:"image/png"}))})}function qo(o){return new Promise((t,n)=>{let r=new Image;r.onload=()=>{r.decode().then(()=>{requestAnimationFrame(()=>t(r))})},r.onerror=n,r.crossOrigin="anonymous",r.decoding="async",r.src=o})}async function sT(o){return Promise.resolve().then(()=>new XMLSerializer().serializeToString(o)).then(encodeURIComponent).then(t=>`data:image/svg+xml;charset=utf-8,${t}`)}async function Cf(o,t,n){let r="http://www.w3.org/2000/svg",i=document.createElementNS(r,"svg"),s=document.createElementNS(r,"foreignObject");return i.setAttribute("width",`${t}`),i.setAttribute("height",`${n}`),i.setAttribute("viewBox",`0 0 ${t} ${n}`),s.setAttribute("width","100%"),s.setAttribute("height","100%"),s.setAttribute("x","0"),s.setAttribute("y","0"),s.setAttribute("externalResourcesRequired","true"),i.appendChild(s),s.appendChild(o),sT(i)}var Ge=(o,t)=>{if(o instanceof t)return!0;let n=Object.getPrototypeOf(o);return n===null?!1:n.constructor.name===t.name||Ge(n,t)};function aT(o){let t=o.getPropertyValue("content");return`${o.cssText} content: '${t.replace(/'|"/g,"")}';`}function cT(o,t){return Ws(t).map(n=>{let r=o.getPropertyValue(n),i=o.getPropertyPriority(n);return`${n}: ${r}${i?" !important":""};`}).join(" ")}function lT(o,t,n,r){let i=`.${o}:${t}`,s=n.cssText?aT(n):cT(n,r);return document.createTextNode(`${i}{${s}}`)}function wf(o,t,n,r){let i=window.getComputedStyle(o,n),s=i.getPropertyValue("content");if(s===""||s==="none")return;let c=Sf();try{t.className=`${t.className} ${c}`}catch{return}let u=document.createElement("style");u.appendChild(lT(c,n,i,r)),t.appendChild(u)}function Pf(o,t,n){wf(o,t,":before",n),wf(o,t,":after",n)}var Ef="application/font-woff",kf="image/jpeg",uT={woff:Ef,woff2:Ef,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:kf,jpeg:kf,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml",webp:"image/webp"};function pT(o){let t=/\.([^./]*?)$/g.exec(o);return t?t[1]:""}function Xo(o){let t=pT(o).toLowerCase();return uT[t]||""}function mT(o){return o.split(/,/)[1]}function Nr(o){return o.search(/^(data:)/)!==-1}function Vc(o,t){return`data:${t};base64,${o}`}async function Nc(o,t,n){let r=await fetch(o,t);if(r.status===404)throw new Error(`Resource "${r.url}" not found`);let i=await r.blob();return new Promise((s,c)=>{let u=new FileReader;u.onerror=c,u.onloadend=()=>{try{s(n({res:r,result:u.result}))}catch(p){c(p)}},u.readAsDataURL(i)})}var Mc={};function fT(o,t,n){let r=o.replace(/\?.*/,"");return n&&(r=o),/ttf|otf|eot|woff2?/i.test(r)&&(r=r.replace(/.*\//,"")),t?`[${t}]${r}`:r}async function Yo(o,t,n){let r=fT(o,t,n.includeQueryParams);if(Mc[r]!=null)return Mc[r];n.cacheBust&&(o+=(/\?/.test(o)?"&":"?")+new Date().getTime());let i;try{let s=await Nc(o,n.fetchRequestInit,({res:c,result:u})=>(t||(t=c.headers.get("Content-Type")||""),mT(u)));i=Vc(s,t)}catch(s){i=n.imagePlaceholder||"";let c=`Failed to fetch resource: ${o}`;s&&(c=typeof s=="string"?s:s.message),c&&console.warn(c)}return Mc[r]=i,i}async function dT(o){let t=o.toDataURL();return t==="data:,"?o.cloneNode(!1):qo(t)}async function hT(o,t){if(o.currentSrc){let s=document.createElement("canvas"),c=s.getContext("2d");s.width=o.clientWidth,s.height=o.clientHeight,c?.drawImage(o,0,0,s.width,s.height);let u=s.toDataURL();return qo(u)}let n=o.poster,r=Xo(n),i=await Yo(n,r,t);return qo(i)}async function gT(o,t){var n;try{if(!((n=o?.contentDocument)===null||n===void 0)&&n.body)return await Gr(o.contentDocument.body,t,!0)}catch{}return o.cloneNode(!1)}async function yT(o,t){return Ge(o,HTMLCanvasElement)?dT(o):Ge(o,HTMLVideoElement)?hT(o,t):Ge(o,HTMLIFrameElement)?gT(o,t):o.cloneNode(Df(o))}var TT=o=>o.tagName!=null&&o.tagName.toUpperCase()==="SLOT",Df=o=>o.tagName!=null&&o.tagName.toUpperCase()==="SVG";async function vT(o,t,n){var r,i;if(Df(t))return t;let s=[];return TT(o)&&o.assignedNodes?s=Tt(o.assignedNodes()):Ge(o,HTMLIFrameElement)&&(!((r=o.contentDocument)===null||r===void 0)&&r.body)?s=Tt(o.contentDocument.body.childNodes):s=Tt(((i=o.shadowRoot)!==null&&i!==void 0?i:o).childNodes),s.length===0||Ge(o,HTMLVideoElement)||await s.reduce((c,u)=>c.then(()=>Gr(u,n)).then(p=>{p&&t.appendChild(p)}),Promise.resolve()),t}function ST(o,t,n){let r=t.style;if(!r)return;let i=window.getComputedStyle(o);i.cssText?(r.cssText=i.cssText,r.transformOrigin=i.transformOrigin):Ws(n).forEach(s=>{let c=i.getPropertyValue(s);s==="font-size"&&c.endsWith("px")&&(c=`${Math.floor(parseFloat(c.substring(0,c.length-2)))-.1}px`),Ge(o,HTMLIFrameElement)&&s==="display"&&c==="inline"&&(c="block"),s==="d"&&t.getAttribute("d")&&(c=`path(${t.getAttribute("d")})`),r.setProperty(s,c,i.getPropertyPriority(s))})}function xT(o,t){Ge(o,HTMLTextAreaElement)&&(t.innerHTML=o.value),Ge(o,HTMLInputElement)&&t.setAttribute("value",o.value)}function bT(o,t){if(Ge(o,HTMLSelectElement)){let n=t,r=Array.from(n.children).find(i=>o.value===i.getAttribute("value"));r&&r.setAttribute("selected","")}}function AT(o,t,n){return Ge(t,Element)&&(ST(o,t,n),Pf(o,t,n),xT(o,t),bT(o,t)),t}async function CT(o,t){let n=o.querySelectorAll?o.querySelectorAll("use"):[];if(n.length===0)return o;let r={};for(let s=0;s<n.length;s++){let u=n[s].getAttribute("xlink:href");if(u){let p=o.querySelector(u),f=document.querySelector(u);!p&&f&&!r[u]&&(r[u]=await Gr(f,t,!0))}}let i=Object.values(r);if(i.length){let s="http://www.w3.org/1999/xhtml",c=document.createElementNS(s,"svg");c.setAttribute("xmlns",s),c.style.position="absolute",c.style.width="0",c.style.height="0",c.style.overflow="hidden",c.style.display="none";let u=document.createElementNS(s,"defs");c.appendChild(u);for(let p=0;p<i.length;p++)u.appendChild(i[p]);o.appendChild(c)}return o}async function Gr(o,t,n){return!n&&t.filter&&!t.filter(o)?null:Promise.resolve(o).then(r=>yT(r,t)).then(r=>vT(o,r,t)).then(r=>AT(o,r,t)).then(r=>CT(r,t))}var Rf=/url\((['"]?)([^'"]+?)\1\)/g,wT=/url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g,PT=/src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;function ET(o){let t=o.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1");return new RegExp(`(url\\(['"]?)(${t})(['"]?\\))`,"g")}function kT(o){let t=[];return o.replace(Rf,(n,r,i)=>(t.push(i),n)),t.filter(n=>!Nr(n))}async function DT(o,t,n,r,i){try{let s=n?vf(t,n):t,c=Xo(t),u;if(i){let p=await i(s);u=Vc(p,c)}else u=await Yo(s,c,r);return o.replace(ET(t),`$1${u}$3`)}catch{}return o}function RT(o,{preferredFontFormat:t}){return t?o.replace(PT,n=>{for(;;){let[r,,i]=wT.exec(n)||[];if(!i)return"";if(i===t)return`src: ${r};`}}):o}function Gc(o){return o.search(Rf)!==-1}async function $s(o,t,n){if(!Gc(o))return o;let r=RT(o,n);return kT(r).reduce((s,c)=>s.then(u=>DT(u,c,t,n)),Promise.resolve(r))}async function Zo(o,t,n){var r;let i=(r=t.style)===null||r===void 0?void 0:r.getPropertyValue(o);if(i){let s=await $s(i,null,n);return t.style.setProperty(o,s,t.style.getPropertyPriority(o)),!0}return!1}async function IT(o,t){await Zo("background",o,t)||await Zo("background-image",o,t),await Zo("mask",o,t)||await Zo("-webkit-mask",o,t)||await Zo("mask-image",o,t)||await Zo("-webkit-mask-image",o,t)}async function LT(o,t){let n=Ge(o,HTMLImageElement);if(!(n&&!Nr(o.src))&&!(Ge(o,SVGImageElement)&&!Nr(o.href.baseVal)))return;let r=n?o.src:o.href.baseVal,i=await Yo(r,Xo(r),t);await new Promise((s,c)=>{o.onload=s,o.onerror=t.onImageErrorHandler?(...p)=>{try{s(t.onImageErrorHandler(...p))}catch(f){c(f)}}:c;let u=o;u.decode&&(u.decode=s),u.loading==="lazy"&&(u.loading="eager"),n?(o.srcset="",o.src=i):o.href.baseVal=i})}async function _T(o,t){let r=Tt(o.childNodes).map(i=>Fc(i,t));await Promise.all(r).then(()=>o)}async function Fc(o,t){Ge(o,Element)&&(await IT(o,t),await LT(o,t),await _T(o,t))}function If(o,t){let{style:n}=o;t.backgroundColor&&(n.backgroundColor=t.backgroundColor),t.width&&(n.width=`${t.width}px`),t.height&&(n.height=`${t.height}px`);let r=t.style;return r!=null&&Object.keys(r).forEach(i=>{n[i]=r[i]}),o}var Lf={};async function _f(o){let t=Lf[o];if(t!=null)return t;let r=await(await fetch(o)).text();return t={url:o,cssText:r},Lf[o]=t,t}async function Mf(o,t){let n=o.cssText,r=/url\(["']?([^"')]+)["']?\)/g,s=(n.match(/url\([^)]+\)/g)||[]).map(async c=>{let u=c.replace(r,"$1");return u.startsWith("https://")||(u=new URL(u,o.url).href),Nc(u,t.fetchRequestInit,({result:p})=>(n=n.replace(c,`url(${p})`),[c,p]))});return Promise.all(s).then(()=>n)}function Vf(o){if(o==null)return[];let t=[],n=/(\/\*[\s\S]*?\*\/)/gi,r=o.replace(n,""),i=new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})","gi");for(;;){let p=i.exec(r);if(p===null)break;t.push(p[0])}r=r.replace(i,"");let s=/@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi,c="((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})",u=new RegExp(c,"gi");for(;;){let p=s.exec(r);if(p===null){if(p=u.exec(r),p===null)break;s.lastIndex=u.lastIndex}else u.lastIndex=s.lastIndex;t.push(p[0])}return t}async function MT(o,t){let n=[],r=[];return o.forEach(i=>{if("cssRules"in i)try{Tt(i.cssRules||[]).forEach((s,c)=>{if(s.type===CSSRule.IMPORT_RULE){let u=c+1,p=s.href,f=_f(p).then(a=>Mf(a,t)).then(a=>Vf(a).forEach(l=>{try{i.insertRule(l,l.startsWith("@import")?u+=1:i.cssRules.length)}catch(m){console.error("Error inserting rule from remote css",{rule:l,error:m})}})).catch(a=>{console.error("Error loading remote css",a.toString())});r.push(f)}})}catch(s){let c=o.find(u=>u.href==null)||document.styleSheets[0];i.href!=null&&r.push(_f(i.href).then(u=>Mf(u,t)).then(u=>Vf(u).forEach(p=>{c.insertRule(p,c.cssRules.length)})).catch(u=>{console.error("Error loading remote stylesheet",u)})),console.error("Error inlining remote css file",s)}}),Promise.all(r).then(()=>(o.forEach(i=>{if("cssRules"in i)try{Tt(i.cssRules||[]).forEach(s=>{n.push(s)})}catch(s){console.error(`Error while reading CSS rules from ${i.href}`,s)}}),n))}function VT(o){return o.filter(t=>t.type===CSSRule.FONT_FACE_RULE).filter(t=>Gc(t.style.getPropertyValue("src")))}async function NT(o,t){if(o.ownerDocument==null)throw new Error("Provided element is not within a Document");let n=Tt(o.ownerDocument.styleSheets),r=await MT(n,t);return VT(r)}function Nf(o){return o.trim().replace(/["']/g,"")}function GT(o){let t=new Set;function n(r){(r.style.fontFamily||getComputedStyle(r).fontFamily).split(",").forEach(s=>{t.add(Nf(s))}),Array.from(r.children).forEach(s=>{s instanceof HTMLElement&&n(s)})}return n(o),t}async function Oc(o,t){let n=await NT(o,t),r=GT(o);return(await Promise.all(n.filter(s=>r.has(Nf(s.style.fontFamily))).map(s=>{let c=s.parentStyleSheet?s.parentStyleSheet.href:null;return $s(s.cssText,c,t)}))).join(`
51
- `)}async function Gf(o,t){let n=t.fontEmbedCSS!=null?t.fontEmbedCSS:t.skipFonts?null:await Oc(o,t);if(n){let r=document.createElement("style"),i=document.createTextNode(n);r.appendChild(i),o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r)}}async function Ff(o,t={}){let{width:n,height:r}=js(o,t),i=await Gr(o,t,!0);return await Gf(i,t),await Fc(i,t),If(i,t),await Cf(i,n,r)}async function Fr(o,t={}){let{width:n,height:r}=js(o,t),i=await Ff(o,t),s=await qo(i),c=document.createElement("canvas"),u=c.getContext("2d"),p=t.pixelRatio||xf(),f=t.canvasWidth||n,a=t.canvasHeight||r;return c.width=f*p,c.height=a*p,t.skipAutoScale||bf(c),c.style.width=`${f}`,c.style.height=`${a}`,t.backgroundColor&&(u.fillStyle=t.backgroundColor,u.fillRect(0,0,c.width,c.height)),u.drawImage(s,0,0,c.width,c.height),c}async function FT(o,t={}){let{width:n,height:r}=js(o,t);return(await Fr(o,t)).getContext("2d").getImageData(0,0,n,r).data}async function OT(o,t={}){return(await Fr(o,t)).toDataURL()}async function HT(o,t={}){return(await Fr(o,t)).toDataURL("image/jpeg",t.quality||1)}async function UT(o,t={}){let n=await Fr(o,t);return await Af(n)}async function KT(o,t={}){return Oc(o,t)}var zs=class{constructor(t,n){this.gameState=t;this.notifications=n;this.events=new re}addNotification(t){this.notifications.push(t),this.flush()}removeNotification(t){this.notifications=this.notifications.filter(n=>n!==t),this.flush()}clearNotifications(){this.notifications=[],this.flush()}consume(t){let n=new b,r=new ne(n);return n.registerSkipController(new K(()=>{this.removeNotification(t)})),this.addNotification(t),this.gameState.schedule(()=>{n.resolve(),this.removeNotification(t)},t.duration),this.gameState.timelines.attachTimeline(r),n}onFlush(t){return this.events.on("event:notifications.flush",t)}toArray(){return[...this.notifications]}flush(){this.events.emit("event:notifications.flush")}};var qs=class{constructor(t=100){this.history=[];this.hooks={onUndo:[],onHistoryLimit:[]};this.maxHistorySize=t}push(t,n,r,i){let s=Nl(6);if(this.history.push({action:t,id:s,args:r,undo:n,timeline:i}),this.history.length>this.maxHistorySize){let c=this.history.splice(0,this.history.length-this.maxHistorySize);this.hooks.onHistoryLimit.forEach(u=>u(c))}return{id:s}}undoUntil(t){let n=-1;for(let i=this.history.length-1;i>=0;i--)if(this.history[i].id===t){n=i;break}if(n===-1)return null;let r=[];for(let i=this.history.length-1;i>=n;i--)this.history[i].timeline&&!this.history[i].timeline.isSettled&&this.history[i].timeline.abort(),this.history[i].undo?.(...this.history[i].args||[]),r.push(this.history[i]);return this.history.splice(n),this.hooks.onUndo.forEach(i=>i(r)),r[r.length-1]?.action||null}undo(){let t=this.history.pop();return t?(t.timeline&&!t.timeline.isSettled&&t.timeline.abort(),t.undo?.(...t.args),this.hooks.onUndo.forEach(n=>n([t])),t.action):null}onUndo(t){return this.hooks.onUndo.push(t),{cancel:()=>this.offUndo(t)}}offUndo(t){this.hooks.onUndo=this.hooks.onUndo.filter(n=>n!==t)}getHistory(){return this.history}onHistoryLimit(t){return this.hooks.onHistoryLimit.push(t),{cancel:()=>this.offHistoryLimit(t)}}offHistoryLimit(t){this.hooks.onHistoryLimit=this.hooks.onHistoryLimit.filter(n=>n!==t)}reset(){this.history=[]}};var Xs=class{constructor(t){this.history=[];this.actionHistoryMgr=t,this.actionHistoryMgr.onUndo(n=>{this.crossFilter(n)}),this.actionHistoryMgr.onHistoryLimit(n=>{this.crossFilter(n)})}push(t){return this.history.push(t),this}getHistory(){return this.history}reset(){this.history=[]}crossFilter(t){let n=new Set(t.map(r=>r.id));this.history=this.history.filter(r=>!n.has(r.token))}};var Or=class Or{constructor(t,n){this.state={sounds:[],videos:[],srcManagers:[],elements:[]};this.currentHandling=null;this.playerCurrent=null;this.mainContentNode=null;this.exposedState=new Map;this.htmlToImage=Hc;this.stage=n,this.game=t,this.events=new re,this.logger=new Us(t,"NarraLeaf-React"),this.audioManager=new Ks(this),this.guard=new ks(t.config.app.guard).observe(this),this.timelines=new Ds(this.guard),this.notificationMgr=new zs(this,[]),this.idManager=new Xr,this.actionHistory=new qs,this.gameHistory=new Xs(this.actionHistory)}addVideo(t){return this.state.videos.push(t),this}removeVideo(t){let n=this.state.videos.indexOf(t);return n===-1?(this.logger.weakWarn("Video not found when removing",t.getId()),this):(this.state.videos.splice(n,1),this)}isVideoAdded(t){return this.state.videos.includes(t)}getVideos(){return this.state.videos}findElementByScene(t){return this.state.elements.find(n=>n.scene===t)||null}findElementByDisplayable(t,n=null){return this.state.elements.find(r=>{if(n)return r.layers.get(n)?.includes(t)||!1;for(let i of r.layers.values())if(i.includes(t))return!0;return!1})||null}removeElement(t){let n=this.state.elements.indexOf(t);return n===-1?(this.logger.weakWarn("Element not found when removing",t.scene.getId()),this):(this.state.elements.splice(n,1),this)}addElement(t){return this.state.elements.push(t),this}addScene(t){return this.sceneExists(t)?this:(this.state.elements.unshift({scene:t,texts:[],menus:[],layers:new Map(t.config.layers.map(n=>[n,[]]))}),this)}flush(){return this.stage.update(),this}popScene(){let t=this.state.elements.pop();return t?(this.removeElements(t.scene),this):this}removeScene(t){return this.removeElements(t),this}getSceneElements(){return this.state.elements}getLastScene(){return this.state.elements[this.state.elements.length-1]?.scene||null}sceneExists(t){return t?this.state.elements.some(n=>n.scene===t):!!this.getLastScene()}isSceneActive(t){for(let{scene:n}of this.state.elements)if(n===t)return!0;return!1}wait(t){return new Promise(n=>setTimeout(n,t))}schedule(t,n){let r=setTimeout(()=>{t({retry:()=>{this.schedule(t,0)}})},n);return()=>clearTimeout(r)}notify(t){this.notificationMgr.addNotification(t)}handle(t){if(this.currentHandling===t)return this;switch(this.currentHandling=t,t.type){case"condition:action":break}return this}createDialog(t,n,r,i){let s=this.findElementByScene(this.getLastSceneIfNot(i))?.texts;if(!s)throw this.sceneNotFound();let c=n.evaluate(ut.getCtx({gameState:this}));this.game.getLiveGame().events.emit(Cn.EventTypes["event:character.prompt"],{character:n.config.character,sentence:n,text:Z.getText(c)});let u=this.createWaitableAction({character:n.config.character,sentence:n,id:t,words:c},()=>{s.splice(s.indexOf(u),1),r&&r()});return s.push(u),{cancel:()=>{let p=s.indexOf(u);p!==-1&&s.splice(p,1)},text:Z.getText(c)}}createMenu(t,n,r){if(!t.choices.length)throw new Error("Menu must have at least one choice");let i=this.findElementByScene(this.getLastSceneIfNot(r))?.menus;if(!i)throw this.sceneNotFound();let s=t.prompt?.evaluate(ut.getCtx({gameState:this}))||null,c=this.createWaitableAction({...t,words:s},u=>{i.splice(i.indexOf(c),1),n&&n(u),this.game.getLiveGame().events.emit(Cn.EventTypes["event:menu.choose"],{sentence:u.prompt,text:u.evaluated})});return i.push(c),{cancel:()=>{let u=i.indexOf(c);u!==-1&&i.splice(u,1)},prompt:s?Z.getText(s):null}}createDisplayable(t,n=null,r=null){let i=this.getLastSceneIfNot(n),s=this.findElementByScene(i);if(!s)throw this.sceneNotFound();let c=s.layers.get(r||i.config.defaultDisplayableLayer);if(!c)throw this.layerNotFound();return c.push(t),this}disposeDisplayable(t,n=null,r=null){let i=this.getLastSceneIfNot(n),s=this.findElementByScene(i)?.layers.get(r||i.config.defaultDisplayableLayer);if(!s)throw this.layerNotFound();let c=s.indexOf(t);if(c===-1)throw new M(`Displayables not found when disposing. (disposing: ${t.getId()})`);return s.splice(c,1),this}forceReset(){this.state.elements.forEach(({scene:t})=>{this.offSrcManager(t.srcManager),this.removeScene(t),t.events.clear()}),this.state.elements=[],this.state.srcManagers=[],this.state.videos=[],this.audioManager.reset(),this.timelines.abortAll(),this.gameHistory.reset(),this.actionHistory.reset()}getHowl(){return Of.Howl}registerSrcManager(t){return this.state.srcManagers.push(t),this}offSrcManager(t){return this.state.srcManagers=this.state.srcManagers.filter(n=>n!==t),this}getStorable(){return this.game.getLiveGame().getStorable()}getSceneByName(t){return this.game.getLiveGame().story?.getScene(t)||null}getStory(){if(!this.game.getLiveGame().story)throw new M("Story not loaded");return this.game.getLiveGame().story}setInterval(t,n){return setInterval(t,n)}clearInterval(t){clearInterval(t)}setTimeout(t,n){return setTimeout(t,n)}clearTimeout(t){clearTimeout(t)}forceAnimation(){let[t,n]=ne.proxy(b.nothing),r=[];return Array.from(this.exposedState.keys()).forEach(i=>{i instanceof Pt&&r.push(i)}),r.forEach(i=>{let c=this.getExposedStateForce(i).applyTransform(ce.immediate({}),()=>{});n.attachChild(c)}),this.timelines.attachTimeline(n),t}mountState(t,n){if(this.exposedState.has(t))throw new Dr("State already mounted");if(!t)throw new Dr("Invalid state key");return this.exposedState.set(t,n),this.events.emit(Or.EventTypes["event.state.onExpose"],t,n),{unMount:()=>{this.unMountState(t)}}}unMountState(t){return this.exposedState.has(t)||this.guard.warn("invalidExposedStateUnmounting","State not found when unmounting"),this.exposedState.delete(t),this}initVideo(t){return this.state.videos.push(t),this}isStateMounted(t){return this.exposedState.has(t)}getExposedState(t){return this.exposedState.get(t)||null}getExposedStateForce(t){let n=this.getExposedState(t);if(!n)throw new M("State not found, key: "+t);return n}getExposedStateAsync(t,n){let r=this.getExposedState(t);if(r)return{cancel:this.schedule(()=>{n(r)},0)};{let i=this.events.on(Or.EventTypes["event.state.onExpose"],(s,c)=>{s===t&&(n(c),i.cancel())});return i}}dispose(){this.forceReset()}toData(){return{scenes:this.state.elements.map(t=>({sceneId:t.scene.getId(),elements:{layers:Object.fromEntries(Array.from(t.layers.entries()).map(([n,r])=>[n.getId(),r.map(i=>i.getId())]))}})),audio:this.audioManager.toData(),videos:this.state.videos.map(t=>[t.getId(),t.toData()])}}loadData(t,n){if(this.state.elements=[],!this.game.getLiveGame().story)throw new Error("No story loaded");let{scenes:i,audio:s,videos:c}=t;i.forEach(({sceneId:u,elements:p})=>{this.logger.debug("Loading scene: "+u);let f=n.get(u);if(!f)throw new M("Scene not found, id: "+u+`
51
+ `)}async function Gf(o,t){let n=t.fontEmbedCSS!=null?t.fontEmbedCSS:t.skipFonts?null:await Oc(o,t);if(n){let r=document.createElement("style"),i=document.createTextNode(n);r.appendChild(i),o.firstChild?o.insertBefore(r,o.firstChild):o.appendChild(r)}}async function Ff(o,t={}){let{width:n,height:r}=js(o,t),i=await Gr(o,t,!0);return await Gf(i,t),await Fc(i,t),If(i,t),await Cf(i,n,r)}async function Fr(o,t={}){let{width:n,height:r}=js(o,t),i=await Ff(o,t),s=await qo(i),c=document.createElement("canvas"),u=c.getContext("2d"),p=t.pixelRatio||xf(),f=t.canvasWidth||n,a=t.canvasHeight||r;return c.width=f*p,c.height=a*p,t.skipAutoScale||bf(c),c.style.width=`${f}`,c.style.height=`${a}`,t.backgroundColor&&(u.fillStyle=t.backgroundColor,u.fillRect(0,0,c.width,c.height)),u.drawImage(s,0,0,c.width,c.height),c}async function FT(o,t={}){let{width:n,height:r}=js(o,t);return(await Fr(o,t)).getContext("2d").getImageData(0,0,n,r).data}async function OT(o,t={}){return(await Fr(o,t)).toDataURL()}async function HT(o,t={}){return(await Fr(o,t)).toDataURL("image/jpeg",t.quality||1)}async function UT(o,t={}){let n=await Fr(o,t);return await Af(n)}async function KT(o,t={}){return Oc(o,t)}var zs=class{constructor(t,n){this.gameState=t;this.notifications=n;this.events=new re}addNotification(t){this.notifications.push(t),this.flush()}removeNotification(t){this.notifications=this.notifications.filter(n=>n!==t),this.flush()}clearNotifications(){this.notifications=[],this.flush()}consume(t){let n=new b,r=new ne(n);return n.registerSkipController(new K(()=>{this.removeNotification(t)})),this.addNotification(t),this.gameState.schedule(()=>{n.resolve(),this.removeNotification(t)},t.duration),this.gameState.timelines.attachTimeline(r),n}onFlush(t){return this.events.on("event:notifications.flush",t)}toArray(){return[...this.notifications]}flush(){this.events.emit("event:notifications.flush")}};var qs=class{constructor(t=100){this.history=[];this.hooks={onUndo:[],onHistoryLimit:[]};this.maxHistorySize=t}push(t,n,r,i){let s=Nl(6);if(this.history.push({action:t,id:s,args:r,undo:n,timeline:i}),this.history.length>this.maxHistorySize){let c=this.history.splice(0,this.history.length-this.maxHistorySize);this.hooks.onHistoryLimit.forEach(u=>u(c))}return{id:s}}undoUntil(t){let n=-1;for(let i=this.history.length-1;i>=0;i--)if(this.history[i].id===t){n=i;break}if(n===-1)return null;let r=[];for(let i=this.history.length-1;i>=n;i--)this.history[i].timeline&&!this.history[i].timeline.isSettled&&this.history[i].timeline.abort(),this.history[i].undo?.(...this.history[i].args||[]),r.push(this.history[i]);return this.history.splice(n),this.hooks.onUndo.forEach(i=>i(r)),r[r.length-1]?.action||null}undo(){let t=this.history.pop();return t?(t.timeline&&!t.timeline.isSettled&&t.timeline.abort(),t.undo?.(...t.args),this.hooks.onUndo.forEach(n=>n([t])),t.action):null}onUndo(t){return this.hooks.onUndo.push(t),{cancel:()=>this.offUndo(t)}}offUndo(t){this.hooks.onUndo=this.hooks.onUndo.filter(n=>n!==t)}getHistory(){return this.history}onHistoryLimit(t){return this.hooks.onHistoryLimit.push(t),{cancel:()=>this.offHistoryLimit(t)}}offHistoryLimit(t){this.hooks.onHistoryLimit=this.hooks.onHistoryLimit.filter(n=>n!==t)}reset(){this.history=[]}};var Xs=class{constructor(t){this.history=[];this.actionHistoryMgr=t,this.actionHistoryMgr.onUndo(n=>{this.crossFilter(n)}),this.actionHistoryMgr.onHistoryLimit(n=>{this.crossFilter(n)})}push(t){return this.history.push(t),this}getHistory(){return this.history}reset(){this.history=[]}crossFilter(t){let n=new Set(t.map(r=>r.id));this.history=this.history.filter(r=>!n.has(r.token))}};var Or=class Or{constructor(t,n){this.state={sounds:[],videos:[],srcManagers:[],elements:[]};this.currentHandling=null;this.playerCurrent=null;this.mainContentNode=null;this.exposedState=new Map;this.preloadingScene=null;this.htmlToImage=Hc;this.stage=n,this.game=t,this.events=new re,this.logger=new Us(t,"NarraLeaf-React"),this.audioManager=new Ks(this),this.guard=new ks(t.config.app.guard).observe(this),this.timelines=new Ds(this.guard),this.notificationMgr=new zs(this,[]),this.idManager=new Xr,this.actionHistory=new qs,this.gameHistory=new Xs(this.actionHistory)}addVideo(t){return this.state.videos.push(t),this}removeVideo(t){let n=this.state.videos.indexOf(t);return n===-1?(this.logger.weakWarn("Video not found when removing",t.getId()),this):(this.state.videos.splice(n,1),this)}isVideoAdded(t){return this.state.videos.includes(t)}getVideos(){return this.state.videos}findElementByScene(t){return this.state.elements.find(n=>n.scene===t)||null}findElementByDisplayable(t,n=null){return this.state.elements.find(r=>{if(n)return r.layers.get(n)?.includes(t)||!1;for(let i of r.layers.values())if(i.includes(t))return!0;return!1})||null}removeElement(t){let n=this.state.elements.indexOf(t);return n===-1?(this.logger.weakWarn("Element not found when removing",t.scene.getId()),this):(this.state.elements.splice(n,1),this)}preloadScene(t){return this.preloadingScene=t,this}getPreloadingScene(){return this.preloadingScene}addElement(t){return this.state.elements.push(t),this}addScene(t){return this.sceneExists(t)?this:(this.state.elements.unshift({scene:t,texts:[],menus:[],layers:new Map(t.config.layers.map(n=>[n,[]]))}),this)}flush(){return this.stage.update(),this}popScene(){let t=this.state.elements.pop();return t?(this.removeElements(t.scene),this):this}removeScene(t){return this.removeElements(t),this}getSceneElements(){return this.state.elements}getLastScene(){return this.state.elements[this.state.elements.length-1]?.scene||null}sceneExists(t){return t?this.state.elements.some(n=>n.scene===t):!!this.getLastScene()}isSceneActive(t){for(let{scene:n}of this.state.elements)if(n===t)return!0;return!1}wait(t){return new Promise(n=>setTimeout(n,t))}schedule(t,n){let r=setTimeout(()=>{t({retry:()=>{this.schedule(t,0)}})},n);return()=>clearTimeout(r)}notify(t){this.notificationMgr.addNotification(t)}handle(t){if(this.currentHandling===t)return this;switch(this.currentHandling=t,t.type){case"condition:action":break}return this}createDialog(t,n,r,i){let s=this.findElementByScene(this.getLastSceneIfNot(i))?.texts;if(!s)throw this.sceneNotFound();let c=n.evaluate(ut.getCtx({gameState:this}));this.game.getLiveGame().events.emit(Cn.EventTypes["event:character.prompt"],{character:n.config.character,sentence:n,text:Z.getText(c)});let u=this.createWaitableAction({character:n.config.character,sentence:n,id:t,words:c},()=>{s.splice(s.indexOf(u),1),r&&r()});return s.push(u),{cancel:()=>{let p=s.indexOf(u);p!==-1&&s.splice(p,1)},text:Z.getText(c)}}createMenu(t,n,r){if(!t.choices.length)throw new Error("Menu must have at least one choice");let i=this.findElementByScene(this.getLastSceneIfNot(r))?.menus;if(!i)throw this.sceneNotFound();let s=t.prompt?.evaluate(ut.getCtx({gameState:this}))||null,c=this.createWaitableAction({...t,words:s},u=>{i.splice(i.indexOf(c),1),n&&n(u),this.game.getLiveGame().events.emit(Cn.EventTypes["event:menu.choose"],{sentence:u.prompt,text:u.evaluated})});return i.push(c),{cancel:()=>{let u=i.indexOf(c);u!==-1&&i.splice(u,1)},prompt:s?Z.getText(s):null}}createDisplayable(t,n=null,r=null){let i=this.getLastSceneIfNot(n),s=this.findElementByScene(i);if(!s)throw this.sceneNotFound();let c=s.layers.get(r||i.config.defaultDisplayableLayer);if(!c)throw this.layerNotFound();return c.push(t),this}disposeDisplayable(t,n=null,r=null){let i=this.getLastSceneIfNot(n),s=this.findElementByScene(i)?.layers.get(r||i.config.defaultDisplayableLayer);if(!s)throw this.layerNotFound();let c=s.indexOf(t);if(c===-1)throw new M(`Displayables not found when disposing. (disposing: ${t.getId()})`);return s.splice(c,1),this}forceReset(){this.state.elements.forEach(({scene:t})=>{this.offSrcManager(t.srcManager),this.removeScene(t),t.events.clear()}),this.state.elements=[],this.state.srcManagers=[],this.state.videos=[],this.audioManager.reset(),this.timelines.abortAll(),this.gameHistory.reset(),this.actionHistory.reset()}getHowl(){return Of.Howl}registerSrcManager(t){return this.state.srcManagers.push(t),this}offSrcManager(t){return this.state.srcManagers=this.state.srcManagers.filter(n=>n!==t),this}getStorable(){return this.game.getLiveGame().getStorable()}getSceneByName(t){return this.game.getLiveGame().story?.getScene(t)||null}getStory(){if(!this.game.getLiveGame().story)throw new M("Story not loaded");return this.game.getLiveGame().story}setInterval(t,n){return setInterval(t,n)}clearInterval(t){clearInterval(t)}setTimeout(t,n){return setTimeout(t,n)}clearTimeout(t){clearTimeout(t)}forceAnimation(){let[t,n]=ne.proxy(b.nothing),r=[];return Array.from(this.exposedState.keys()).forEach(i=>{i instanceof Pt&&r.push(i)}),r.forEach(i=>{let c=this.getExposedStateForce(i).applyTransform(ce.immediate({}),()=>{});n.attachChild(c)}),this.timelines.attachTimeline(n),t}mountState(t,n){if(this.exposedState.has(t))throw new Dr("State already mounted");if(!t)throw new Dr("Invalid state key");return this.exposedState.set(t,n),this.events.emit(Or.EventTypes["event.state.onExpose"],t,n),{unMount:()=>{this.unMountState(t)}}}unMountState(t){return this.exposedState.has(t)||this.guard.warn("invalidExposedStateUnmounting","State not found when unmounting"),this.exposedState.delete(t),this}initVideo(t){return this.state.videos.push(t),this}isStateMounted(t){return this.exposedState.has(t)}getExposedState(t){return this.exposedState.get(t)||null}getExposedStateForce(t){let n=this.getExposedState(t);if(!n)throw new M("State not found, key: "+t);return n}getExposedStateAsync(t,n){let r=this.getExposedState(t);if(r)return{cancel:this.schedule(()=>{n(r)},0)};{let i=this.events.on(Or.EventTypes["event.state.onExpose"],(s,c)=>{s===t&&(n(c),i.cancel())});return i}}dispose(){this.forceReset()}toData(){return{scenes:this.state.elements.map(t=>({sceneId:t.scene.getId(),elements:{layers:Object.fromEntries(Array.from(t.layers.entries()).map(([n,r])=>[n.getId(),r.map(i=>i.getId())]))}})),audio:this.audioManager.toData(),videos:this.state.videos.map(t=>[t.getId(),t.toData()])}}loadData(t,n){if(this.state.elements=[],!this.game.getLiveGame().story)throw new Error("No story loaded");let{scenes:i,audio:s,videos:c}=t;i.forEach(({sceneId:u,elements:p})=>{this.logger.debug("Loading scene: "+u);let f=n.get(u);if(!f)throw new M("Scene not found, id: "+u+`
52
52
  NarraLeaf cannot find the element with the id from the saved game`);let a={scene:f,layers:this.constructLayerMap(p.layers,n),menus:[],texts:[]};this.state.elements.push(a),this.registerSrcManager(f.srcManager),this.getExposedStateAsync(f,l=>{xe.initBackgroundMusic(f,l)})}),this.audioManager.fromData(s,n),this.state.videos=c.map(([u,p])=>{let f=n.get(u);if(!f)throw new M("Video not found, id: "+u+`
53
53
  NarraLeaf cannot find the element with the id from the saved game`);return f.fromData(p),f})}getLastSceneIfNot(t){let n=t||this.getLastScene();if(!n||!this.sceneExists(n))throw new M('Scene not found, please call "scene.activate()" first.');return n}createElementSnapshot(t){return{scene:t.scene,layers:new Map(Array.from(t.layers.entries()).map(([n,r])=>[n,r.map(i=>[i,i.toData()])]))}}fromElementSnapshot(t){return{scene:t.scene,layers:new Map(Array.from(t.layers.entries()).map(([n,r])=>[n,r.map(([i,s])=>(i.fromData(s),i))])),texts:[],menus:[]}}removeElements(t){let n=this.state.elements.findIndex(r=>r.scene===t);return n===-1?(this.logger.weakWarn("Scene not found when removing elements",t.getId()),this):(this.resetLayers(this.state.elements[n].layers),this.state.elements.splice(n,1),this)}resetLayers(t){t.forEach(n=>{n.forEach(r=>{r.reset()})})}createWaitableAction(t,n){return{action:t,onClick:i=>{n&&n(i)}}}sceneNotFound(){return new M("Scene not found, target scene may not be activated. This is an internal error, please report this to the developer.")}layerNotFound(){return new M("Layer not found, target layer may not be activated. You may forget to add the layer to the scene config")}constructLayerMap(t,n){return new Map(Object.entries(t).map(([r,i])=>{let s=n.get(r);if(!s)throw new M("Layer not found, id: "+r+`
54
54
  NarraLeaf cannot find the element with the id from the saved game`);return[s,i.map(c=>{if(!n.has(c))throw new M("Displayable not found, id: "+c+`
55
55
  NarraLeaf cannot find the element with the id from the saved game
56
56
  This may be caused by the damage of the saved game file or the change of the story file`);return n.get(c)})]}))}};Or.EventTypes={"event:state.end":"event:state.end","event:state.player.skip":"event:state.player.skip","event:state.player.requestFlush":"event:state.player.requestFlush","event.state.onExpose":"event.state.onExpose","event:state.onRender":"event:state.onRender"};var ie=Or;var Xt=class Xt{constructor(t){this.gameLock=new Xn;this.events=new re;this.story=null;this.currentSavedGame=null;this.lockedAwaiting=null;this.gameState=void 0;this._lockedCount=0;this.currentAction=null;this.game=t,this.storable=new _r,this.initNamespaces()}initNamespaces(){return this.storable.clear().addNamespace(new $t(Xt.GameSpacesKey.game,Xt.DefaultNamespaces.game)),this.story&&this.story.initPersistent(this.storable),this}getStorable(){return this.storable}loadStory(t){return this.story=t.constructStory(),this}serialize(){this.assertGameState();let t=this.gameState,n=this.story;if(!n)throw new Error("No story loaded");if(!this.currentSavedGame)throw new Error("Failed when trying to serialize the game: The game has not started");let r=this.storable.toData(),i=t.toData(),s=this.getCurrentAction()?.getId()||null,c=n.getAllElementStates();return{name:this.currentSavedGame.name,meta:{created:this.currentSavedGame.meta.created,updated:Date.now(),id:this.currentSavedGame.meta.id},game:{store:r,stage:i,currentAction:s,elementStates:c,services:n.serializeServices()}}}deserialize(t){this.assertGameState();let n=this.gameState,r=this.story;if(!r)throw new Error("No story loaded");this.reset({gameState:n}),n.stage.forceRemount();let i=new Map,s=new Map,{game:{store:c,stage:u,elementStates:p,currentAction:f,services:a}}=t;if(r.forEachChild(r,r.entryScene?.getSceneRoot()||[],l=>{i.set(l.getId(),l),s.set(l.callee.getId(),l.callee)},{allowFutureScene:!0}),this.storable.clear().load(c),p.forEach(({id:l,data:m})=>{n.logger.debug("restore element",l);let d=s.get(l);if(!d)throw new Error("Element not found, id: "+l+`
57
57
  NarraLeaf cannot find the element with the id from the saved game`);d.reset(),d.fromData(m)}),this.currentSavedGame=t,n.loadData(u,s),f){let l=i.get(f);if(!l)throw new Error("Action not found, id: "+f+`
58
- NarraLeaf cannot find the action with the id from the saved game`);this.currentAction=l}r.deserializeServices(a),n.stage.forceUpdate(),n.events.once(ie.EventTypes["event:state.onRender"],()=>{n.schedule(()=>{n.stage.next()},0)})}getHistory(){return this.assertGameState(),this.gameState.gameHistory.getHistory()}undo(t){this.assertGameState(),this.lockedAwaiting&&(this.lockedAwaiting.abort(),this.lockedAwaiting=null);let n=this.currentAction;t?n=this.gameState.actionHistory.undoUntil(t):n=this.gameState.actionHistory.undo(),n?this.currentAction=n:this.gameState.logger.warn("LiveGame.undo","No action found"),this.gameState.logger.info("LiveGame.undo","Undo until",t,"currentAction",this.currentAction,"action",n),this.gameState.stage.forceUpdate(),this.gameState.stage.next(),this.gameState.schedule(()=>{this.gameState&&this.gameState.forceAnimation()},0)}dispose(){this.events.clear(),this.gameState?.dispose()}notify(t,n=3e3){this.assertGameState();let r=this.gameState.idManager.generateId();this.gameState.notificationMgr.consume({id:r,message:t,duration:n})}assertScreenshot(){this.assertGameState(),this.assertPlayerElement()}capturePng(){return this.assertScreenshot(),this.gameState.htmlToImage.toPng(this.gameState.mainContentNode,this.getScreenshotOptions())}captureJpeg(){return this.assertScreenshot(),this.gameState.htmlToImage.toJpeg(this.gameState.mainContentNode,this.getScreenshotOptions())}captureSvg(){return this.assertScreenshot(),this.gameState.htmlToImage.toSvg(this.gameState.mainContentNode,this.getScreenshotOptions())}capturePngBlob(){return this.assertScreenshot(),this.assertGameState(),this.assertPlayerElement(),this.gameState.htmlToImage.toBlob(this.gameState.mainContentNode,this.getScreenshotOptions())}onCharacterPrompt(t){return this.events.on(Xt.EventTypes["event:character.prompt"],t)}onMenuChoose(t){return this.events.on(Xt.EventTypes["event:menu.choose"],t)}newGame(){this.assertGameState();let t=this.gameState,n=t.logger.group("LiveGame (newGame)",!0);this.reset({gameState:t}),this.initNamespaces();let r=this.getNewSavedGame();r.name="NewGame-"+Date.now(),this.currentSavedGame=r,this.currentAction=this.story?.entryScene?.getSceneRoot()||null;let i=this.story?.getAllElementMap(this.story,this.story?.entryScene?.getSceneRoot()||[]);return i?i.forEach(s=>{t.logger.debug("reset element",s),s.reset()}):t.logger.warn("No elements found"),t.stage.forceUpdate(),t.stage.next(),n.end(),this}requestFullScreen(t){this.assertGameState();let n="LiveGame.requestFullScreen";try{let r=this.gameState.playerCurrent;if(!r){this.gameState.logger.warn(n,"No player element found");return}if(r.requestFullscreen)return r.requestFullscreen(t);this.gameState.logger.warn(n,"Fullscreen is not supported")}catch(r){this.gameState.logger.error(n,r)}}exitFullScreen(){this.assertGameState();let t="LiveGame.exitFullScreen";try{if(document.exitFullscreen)return document.exitFullscreen();this.gameState.logger.warn(t,"Fullscreen is not supported")}catch(n){this.gameState.logger.error(t,n)}}getScreenshotOptions(){return{quality:this.game.config.screenshotQuality}}onPlayerEvent(t,n,r){this.assertPlayerElement();let i=this.gameState.playerCurrent;return i?(i.addEventListener(t,n,r),{cancel:()=>i.removeEventListener(t,n,r)}):(this.gameState.logger.warn("LiveGame.onEvent","No player element found"),{cancel:()=>{}})}reset({gameState:t}){this.lockedAwaiting&&this.lockedAwaiting.abort(),this.currentAction=null,this.lockedAwaiting=null,this.currentSavedGame=null,t.forceReset()}getCurrentAction(){return this.currentAction}setCurrentAction(t){return this.currentAction=t,this}next(t){if(this.gameLock.isLocked())return this.gameLock;if(!this.story)throw new Error("No story loaded");if(this.lockedAwaiting){if(!this.lockedAwaiting.solved){if(this._lockedCount++,this._lockedCount>1e3)throw new Error(`LiveGame locked: dead cycle detected
59
- Please refresh the page`);return this.lockedAwaiting}let r=this.lockedAwaiting.result;return this.currentAction=r?.node?.action||null,this.lockedAwaiting=null,this.currentAction||t.events.emit(ie.EventTypes["event:state.end"]),t.logger.debug("next action (lockedAwaiting)",r),r||null}if(!this.currentAction)return t.logger.weakWarn("LiveGame","No current action"),null;let n=this.currentAction.executeAction(t);return b.isAwaitable(n)?(this.lockedAwaiting=n,n):(t.logger.debug("next action",n),this._lockedCount=0,this.currentAction=n.node?.action||null,n)}isPlaying(){return!!this.currentAction}abortAwaiting(){if(this.lockedAwaiting){let t=this.lockedAwaiting.abort();this.currentAction=t?.node?.action||null,this.lockedAwaiting=null}}executeAction(t,n){let r=n.executeAction(t);return b.isAwaitable(r)?r:r?.node?.action||null}executeActionRaw(t,n){return n.executeAction(t)}setGameState(t){return this.gameState=t,this}getGameState(){return this.gameState}getAllPredictableActions(t,n,r){let i=n?.contentNode||null,s=[],c=[],u=new Set;for(;(i||c.length)&&!(r&&s.length>=r);){if(i||(i=c.pop().contentNode),[bn].some(p=>i?.action&&i.action instanceof p)){i=null;continue}if(i.action&&i.action.is(xe,ge.jumpTo)){let[p]=i.action.contentNode.getContent(),f=t.getScene(p);if(!f)throw i.action._sceneNotFoundError(i.action.getSceneName(p));if(u.has(f)){i=null;continue}u.add(f),i=f.getSceneRoot()?.contentNode||null;continue}else if(i.action&&i.action.is(he,ft.do)){let[p]=i.action.contentNode.getContent();i.getChild()?.action&&c.push(i.getChild().action),i=p[0]?.contentNode||null}i.action&&s.push(i.action),i=i.getChild()}return s}getNewSavedGame(){return{name:"",meta:{created:Date.now(),updated:Date.now(),id:Gl()},game:{store:{},stage:{scenes:[],audio:{sounds:[]},videos:[]},elementStates:[],currentAction:this.story?.entryScene?.getSceneRoot().getId()||null,services:{}}}}assertGameState(){if(!this.gameState)throw new M("No game state found, make sure you call this method in effect hooks or event handlers")}assertPlayerElement(){if(this.assertGameState(),!this.gameState.playerCurrent)throw new M("Player Element Not Mounted")}};Xt.DefaultNamespaces={game:{}},Xt.GameSpacesKey={game:"game"},Xt.EventTypes={"event:character.prompt":"event:character.prompt","event:menu.choose":"event:menu.choose"};var Cn=Xt;var Hr=class Hr{constructor(t){this.settings=t;this.events=new re;this.events.setMaxListeners(64)}setPreference(t,n){this.settings[t]=n,this.events.emit(Hr.EventTypes["event:game.preference.change"],t,n)}getPreference(t){return this.settings[t]}getPreferences(){return this.settings}onPreferenceChange(t,n){return this.events.on(Hr.EventTypes["event:game.preference.change"],(r,i)=>{typeof t=="string"?t===r&&n&&n(i):t(r,i)})}importPreferences(t){for(let n in t)Object.prototype.hasOwnProperty.call(t,n)&&this.setPreference(n,t[n])}exportPreferences(){let t={};for(let n in this.settings)Object.prototype.hasOwnProperty.call(this.settings,n)&&(t[n]=this.settings[n]);return t}togglePreference(t){this.setPreference(t,!this.getPreference(t))}};Hr.EventTypes={"event:game.preference.change":"event:game.preference.change"};var Ys=Hr;function Hf(o){var t,n,r="";if(typeof o=="string"||typeof o=="number")r+=o;else if(typeof o=="object")if(Array.isArray(o)){var i=o.length;for(t=0;t<i;t++)o[t]&&(n=Hf(o[t]))&&(r&&(r+=" "),r+=n)}else for(n in o)o[n]&&(r&&(r+=" "),r+=n);return r}function BT(){for(var o,t,n=0,r="",i=arguments.length;n<i;n++)(o=arguments[n])&&(t=Hf(o))&&(r&&(r+=" "),r+=t);return r}var q=BT;import{flushSync as Ad}from"react-dom";import Bf,{useEffect as YT,useRef as ZT,useState as Wf}from"react";import Kf from"react";import WT,{createContext as jT,useContext as $T,useEffect as zT,useReducer as qT,useState as XT}from"react";var Yt=class Yt{constructor(){this.state={width:0,height:0,minWidth:800,minHeight:450,paused:!1,scale:0};this.events=new re().setMaxListeners(1/0);this.lockers=[];this.updater=null}update(t,n,r){this.state.width=t,this.state.height=n,this.state.scale=r,this.events.emit(Yt.EventTypes["event:aspectRatio.update"],t,n)}updateMin(t,n){this.state.minWidth=t,this.state.minHeight=n}lock(){let t=Symbol();return this.lockers.push(t),t}unlock(t){if(t&&!this.lockers.includes(t))throw new Error("Locker not found");return this.lockers=this.lockers.filter(n=>n!==t),this.triggerUpdate(),null}isLocked(){return!!this.lockers.length}getStyle(){return{width:`${this.state.width}px`,height:`${this.state.height}px`}}setUpdate(t){this.updater=t}pause(){this.state.paused=!0,this.events.emit(Yt.EventTypes["event:aspectRatio.pause"])}resume(){this.state.paused=!1,this.events.emit(Yt.EventTypes["event:aspectRatio.resume"])}onUpdate(t){return this.events.on(Yt.EventTypes["event:aspectRatio.update"],t).cancel}requestUpdate(){this.events.emit(Yt.EventTypes["event:aspectRatio.requestUpdate"])}onRequestedUpdate(t){return this.events.on(Yt.EventTypes["event:aspectRatio.requestUpdate"],t).cancel}triggerUpdate(){this.updater&&this.updater()}};Yt.EventTypes={"event:aspectRatio.update":"event:aspectRatio.update","event:aspectRatio.pause":"event:aspectRatio.pause","event:aspectRatio.resume":"event:aspectRatio.resume","event:aspectRatio.requestUpdate":"event:aspectRatio.requestUpdate"};var Uc=Yt,Kc=jT(null);function Uf({children:o}){"use client";let[t]=XT(()=>new Uc);return WT.createElement(Kc,{value:{ratio:t}},o)}function be(){let o=$T(Kc),[,t]=qT(r=>r+1,0);if(!Kc||!o)throw new Error("useRatio must be used within a RatioProvider");let{ratio:n}=o;return zT(()=>n.onUpdate(()=>{t()}),[]),o}function Dt({children:o,className:t,style:n,ref:r,...i}){let{ratio:s}=be(),c=s.getStyle();return Kf.createElement("div",{className:q("inset-0",t),style:{width:"100%",height:"100%",minWidth:`${s.state.minWidth}px`,minHeight:`${s.state.minHeight}px`},...i},Kf.createElement("div",{style:{...c,position:"relative",...n||{}},...i||{},ref:r},o))}function Bc({src:o,width:t,height:n}){let[r,i]=Wf({x:0,y:0}),[s,c]=Wf(!1),u=ZT(null),{ratio:p}=be();return YT(()=>{let f=a=>{if(u.current){let l=u.current.getBoundingClientRect(),m=a.clientX-l.left,d=a.clientY-l.top;i({x:m,y:d}),s||c(!0)}};return window.addEventListener("mousemove",f),()=>{window.removeEventListener("mousemove",f)}},[s]),Bf.createElement(Dt,{ref:u,className:"overflow-hidden absolute"},Bf.createElement("img",{src:o,style:{position:"absolute",left:r.x,top:r.y,width:t,height:n,pointerEvents:"none",zIndex:1001,display:s?"block":"none",cursor:"none",transform:`scale(${p.state.scale})`},alt:""}))}var Kn=class Kn{constructor(){this.preloaded=[];this.events=new re}add(t){let n=this.getSrc(t);return n&&this.has(n)?this:(this.preloaded.push(t),this.events.emit(Kn.EventTypes["event:preloaded.add"],t),this.events.emit(Kn.EventTypes["event:preloaded.change"]),this)}get(t){return this.preloaded.find(n=>this.getSrc(n)===t)}has(t){return Array.isArray(t)?t.every(n=>this.has(n)):this.preloaded.some(n=>this.getSrc(n)===t)}remove(t){if(Array.isArray(t)){let r=t.map(i=>this.getSrc(i));return this.preloaded=this.preloaded.filter(i=>!r.includes(this.getSrc(i))),this}let n=this.getSrc(t);return this.preloaded=this.preloaded.filter(r=>this.getSrc(r)!==n),this.events.emit(Kn.EventTypes["event:preloaded.remove"],t),this.events.emit(Kn.EventTypes["event:preloaded.change"]),this}clear(){return this.preloaded=[],this}getSrc(t){return Ne.getSrc(t)}};Kn.EventTypes={"event:preloaded.add":"event:preloaded.add","event:preloaded.remove":"event:preloaded.remove","event:preloaded.change":"event:preloaded.change","event:preloaded.mount":"event:preloaded.mount","event:preloaded.ready":"event:preloaded.ready","event:preloaded.unmount":"event:preloaded.unmount"};var ot=Kn;import qf,{useEffect as Xf,useState as nv}from"react";import jf,{useContext as JT,useState as QT}from"react";var $f=jf.createContext(null);function zf({children:o,game:t}){"use client";let n=new de({}),[r]=QT(t||n);return jf.createElement($f,{value:r},o)}function N(){let o=JT($f);if(!o)throw new Error("useGame must be used within a GameProvider");return o}import{useEffect as ev,useState as tv}from"react";function Ye(o){let[t,n]=tv(0);ev(()=>{r()},o??[]);function r(){n(i=>i+1)}return[r,t]}function Wc({children:o,className:t,gameState:n}){let[r,i]=nv({}),{ratio:s}=be(),c=N(),[u]=Ye(),p=c.config.minWidth,f=c.config.minHeight;return Xf(()=>{n.logger.debug("AspectRatio","mount, using interval",c.config.ratioUpdateInterval);let a=()=>{if(s.isLocked()){n.logger.weakWarn("Ratio is locked, skipping update");return}let h=document.getElementById(c.config.contentContainerId);if(h){let g=h.clientWidth,y=h.clientHeight,T=c.config.aspectRatio,v,S;g/y>T?(v=y*T,S=y):(v=g,S=g/T),v<p&&(v=p),S<f&&(S=f),i({width:`${v}px`,height:`${S}px`,margin:"auto",position:"absolute",top:"0",bottom:"0",left:"0",right:"0",display:"flex",alignItems:"center",justifyContent:"center"});let C=v/c.config.width;s.update(v,S,C),s.updateMin(p,f),u()}};s.setUpdate(a);let m=Rl(()=>{a()},c.config.ratioUpdateInterval);m(),window.addEventListener("resize",m);let d=s.onRequestedUpdate(m);return()=>{window.removeEventListener("resize",m),d()}},[s,c.config.ratioUpdateInterval]),Xf(()=>n.events.on(ie.EventTypes["event:state.player.requestFlush"],u).cancel,[n]),qf.createElement("div",{id:c.config.contentContainerId,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"}},qf.createElement("div",{className:q(t),style:r},o))}import Yf from"react";import Zt from"react";function jc({error:o,errorInfo:t}){let n=N();return n.config.onError&&n.config.onError(o),n.config.app.debug?Zt.createElement("div",{className:"text-left"},Zt.createElement("h1",null,"NarraLeaf-React cannot initialize the player correctly. (development mode)"),Zt.createElement("p",{className:"text-red-700"},"Message: ",o.message),Zt.createElement("pre",null,"Error Stack: ",o?.stack),Zt.createElement("pre",null,"Component Stack: ",t?.componentStack),Zt.createElement("pre",null,"Digest: ",t?.digest)):Zt.createElement("div",{className:"bg-white w-full h-full"},Zt.createElement("h1",null,"NarraLeaf-React crashed due to an unknown error."),Zt.createElement("p",null,"Please contact the game developer for further assistance."))}var Zs=class extends Yf.Component{constructor(){super(...arguments);this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(n){return{hasError:!0,error:n,errorInfo:null}}componentDidCatch(n,r){this.setState({error:n,errorInfo:r}),console.error(n,r)}render(){return this.state.hasError?Yf.createElement(jc,{error:this.state.error,errorInfo:this.state.errorInfo}):this.props.children}};import $c,{createContext as ov,useContext as rv,useState as Zf}from"react";var Js=class o{constructor(t){this.game=t;this.src=new Map;this.preloadTasks=new Map;this.game.addSideEffect(()=>{this.abortAll(),this.src.clear()})}static getImage(t,n,r){return Ll(t,{...r,signal:n})}has(t){return this.src.has(t)}add(t,n){return this.src.set(t,n),this}remove(t){return this.src.delete(t),this}get(t){return this.src.get(t)}clear(){return this.src.clear(),this}size(){return this.src.size}isPreloading(t){return this.preloadTasks.has(t)}preload(t,n){if(this.src.has(n)||this.preloadTasks.has(n)){let l={abort:()=>{},onFinished:()=>l,onErrored:()=>l};return l}let r=n,i={};this.game.hooks.rawTrigger("preloadImage",()=>[r,(l,m)=>{r=l,i={...i,...m}}]);let s=new AbortController,c=s.signal,u=[],f={promise:o.getImage(r,c,i).then(l=>{this.preloadTasks.delete(n),l&&this.add(n,l)}).catch(l=>{t.logger.error("ImageCacheManager",`Failed to preload image: ${n}`,`Reason: ${l}`),u.forEach(m=>m(l))}),controller:s};this.preloadTasks.set(n,f);let a={abort:()=>{s.abort(),this.preloadTasks.delete(n)},onFinished:l=>(f.promise.then(l),a),onErrored:l=>(u.push(l),a)};return a}abortAll(){this.preloadTasks.forEach(t=>{t.controller.abort()}),this.preloadTasks.clear()}abort(t){let n=this.preloadTasks.get(t);n&&(n.controller.abort(),this.preloadTasks.delete(t))}preloadedSrc(){return Array.from(this.src.values())}filter(t){for(let n of this.src.keys())t.includes(n)||this.src.delete(n);return this}};var zc=ov(null);function Jf({children:o}){let t=N(),[n]=Zf(()=>new ot),[r]=Zf(()=>new Js(t));return $c.createElement($c.Fragment,null,$c.createElement(zc,{value:{preloaded:n,cacheManager:r}},o))}function Jo(){if(!zc)throw new Error("usePreloaded must be used within a PreloadedProvider");return rv(zc)}import{useEffect as qc,useRef as iv}from"react";function Qf({state:o}){let{preloaded:t,cacheManager:n}=Jo(),r=N(),i=iv(new Set),s="Preload",c=o.getLastScene(),u=r.getLiveGame().getCurrentAction(),p=r.getLiveGame().story;function f(){o.logger.debug(s,"Preload unmounted"),t.events.emit(ot.EventTypes["event:preloaded.unmount"])}return qc(()=>{if(typeof fetch>"u")return t.events.emit(ot.EventTypes["event:preloaded.ready"]),o.logger.warn(s,"Fetch is not supported in this environment, skipping preload"),f;if(!r.config.preloadAllImages)return t.events.emit(ot.EventTypes["event:preloaded.ready"]),o.logger.debug(s,"Preload all images is disabled, skipping preload"),f;if(r.config.forceClearCache&&(n.clear(),o.logger.weakWarn(s,"Cache cleared")),!p||!c)return o.logger.weakWarn(s,"Story/Scene not found, skipping preload"),f;let a=performance.now(),l=Ne.catSrc([...c.srcManager?.src||[],...c.srcManager?.getFutureSrc()||[]]),m=new ir(r.config.preloadConcurrency,r.config.preloadDelay),d=[],h=o.logger.group(s,!0),g=[];o.logger.debug(s,"preloading:",l,c);for(let y of l.image){let T=Ne.getSrc(y);if(T){if(d.push(T),n.has(T)||n.isPreloading(T)||g.includes(T)){o.logger.debug(s,`Image already loaded (${l.image.indexOf(y)+1}/${l.image.length})`,T),g.push(T);continue}g.push(T),m.addTask(()=>new Promise(v=>{n.preload(o,T).onFinished(()=>{o.logger.debug(s,`Image loaded (${l.image.indexOf(y)+1}/${l.image.length})`,T),v()}).onErrored(()=>{o.logger.weakError(s,`Failed to preload image (${l.image.indexOf(y)+1}/${l.image.length})`,T),v()})}))}}return h.end(),m.start().then(()=>{o.logger.info(s,"Image preload",`loaded ${n.size()} images in ${performance.now()-a}ms`),r.config.waitForPreload&&t.events.emit(ot.EventTypes["event:preloaded.ready"]),n.filter(d)}),r.config.waitForPreload||t.events.emit(ot.EventTypes["event:preloaded.ready"]),t.events.emit(ot.EventTypes["event:preloaded.mount"]),f},[c,p]),qc(()=>{i.current.clear()},[c]),qc(()=>{if(typeof fetch>"u"||r.config.preloadAllImages)return;if(!p){o.logger.weakWarn(s,"Story not found, skipping preload");return}let a=performance.now(),l=r.getLiveGame().getAllPredictableActions(p,u,r.config.maxPreloadActions).map(T=>Ne.getPreloadableSrc(p,T)).filter(function(T){return T!==null});l.filter(function(T){return T?.activeType==="scene"}).forEach(T=>{i.current.has(T)||i.current.add(T)});let d=Ne.catSrc([...i.current,...l]),h=new ir(r.config.preloadConcurrency,r.config.preloadDelay),g=[],y=o.logger.group(s);o.logger.debug(s,"preloading:",d);for(let T of d.image){let v=Ne.getSrc(T);if(v){if(g.push(v),n.has(v)||n.isPreloading(v)){o.logger.debug(s,`Image already loaded (${d.image.indexOf(T)+1}/${d.image.length})`,v);continue}h.addTask(()=>new Promise(S=>{n.preload(o,v).onFinished(()=>{o.logger.debug(s,`Image loaded (${d.image.indexOf(T)+1}/${d.image.length})`,v),S()}).onErrored(()=>{o.logger.weakError(s,`Failed to preload image (${d.image.indexOf(T)+1}/${d.image.length})`,v),S()})}))}}y.end(),h.start().then(()=>{o.logger.info(s,"Image preload (quick reload)",`loaded ${n.size()} images in ${performance.now()-a}ms`),n.filter(g)})},[u,p]),null}import Ae,{useEffect as fa,useReducer as Cd,useState as Sl}from"react";import Qo,{useEffect as cv}from"react";import ed from"react";import Qs from"react";function ea({children:o,className:t,style:n,...r}){let{ratio:i}=be(),s=N();return Qs.createElement(Dt,{className:q("absolute pointer-events-none w-full h-full"),style:{transform:`scale(${i.state.scale})`,transformOrigin:"left top",width:s.config.width,height:s.config.height,pointerEvents:"none"},"data-element-type":"full",...r},Qs.createElement("div",{className:"absolute inset-0 w-full h-full"},Qs.createElement("div",{className:"inset-0 w-full h-full"},Qs.createElement("div",{className:q("pointer-events-auto-rest",t),style:n},o))))}function Xc({id:o,children:t,className:n,style:r,...i}){return ed.createElement(Kt.div,{className:q("w-full h-full"),key:o,...i},ed.createElement(ea,{className:n,style:r},t))}import Yc,{createContext as sv,useContext as td,useState as av}from"react";var Zc=class{constructor(t,n){this.events=new re;this.current=null;this.history=[];this.historyIndex=-1;this.game=t,n&&(this.current=n,this.history.push(n),this.historyIndex=0)}getCurrentId(){return this.current}push(t){return this.historyIndex<this.history.length-1&&(this.history=this.history.slice(0,this.historyIndex+1)),this.history.push(t),this.history.length>this.game.config.maxRouterHistory&&(this.history.shift(),this.historyIndex--),this.historyIndex++,this.current=t,this.emitOnChange(),this}back(){return this.historyIndex>0?(this.historyIndex--,this.current=this.history[this.historyIndex],this.emitOnChange()):(this.current=null,this.emitOnChange()),this}forward(){return this.historyIndex<this.history.length-1&&(this.historyIndex++,this.current=this.history[this.historyIndex],this.emitOnChange()),this}clear(){return this.current=null,this.history=[],this.historyIndex=-1,this.emitOnChange(),this}cleanHistory(){return this.history=this.current?[this.current]:[],this.historyIndex=this.current?0:-1,this}isActive(){return this.current!==null}emitOnChange(){this.events.emit("event:router.onChange")}},Jc=sv(null);function nd({children:o}){"use client";let t=N(),[n]=av(()=>new Zc(t));return Yc.createElement(Yc.Fragment,null,Yc.createElement(Jc,{value:{router:n}},o))}function Ur(){if(!td(Jc))throw new Error("usePreloaded must be used within a PreloadedProvider");return td(Jc).router}import Qc from"react";function el({children:o,className:t,style:n}){return Qc.createElement(Qc.Fragment,null,Qc.createElement(ea,{style:n,className:t,"data-element-type":"stage","data-code-source":"Stage.tsx"},o))}function od({children:o}){let[t]=Ye(),n=Ur(),r=N();if(cv(()=>{if(n)return n.events.on("event:router.onChange",t).cancel},[]),!n)return null;let i=Qo.Children.toArray([...r.config.stage?[r.config.stage]:[],...o?[o]:[]]),s=Xc,u=i.filter(function(l){return Qo.isValidElement(l)&&l.type===s}).find(l=>l.props.id===n.getCurrentId()),p=el,f=i.find(function(l){return Qo.isValidElement(l)&&l.type===p});return Qo.createElement(Qo.Fragment,null,f,Qo.createElement(cr,{mode:"wait"},u))}import jn,{useEffect as hl,useRef as _v}from"react";import ta,{useEffect as uv}from"react";import tl,{useEffect as Kr,useRef as rd,useState as nl}from"react";function er({element:o,state:t,skipTransform:n,skipTransition:r,overwriteDefinition:i,onTransform:s,transitionsProps:c=[],propOverwrite:u}){let[p,f]=nl(null),[a,l]=nl(null),m=tl.useRef(null),[d]=nl(()=>new qr("displayable.refGroup")),h=rd(d.next()),g=rd(V()),T=N().getLiveGame().getGameState(),v=typeof c=="function"?c(p):c,[S]=Ye([a,p,g]);Kr(()=>T.events.depends([T.events.on(ie.EventTypes["event:state.player.skip"],P)]).cancel,[a,p,g]),Kr(()=>{if(!p)return;if(g.current.some(([oe])=>!oe.current))throw new M("Displayable: Trying to access transition groups before they are mounted");let{controller:I,task:W}=p;return I.onUpdate(oe=>{g.current.forEach(([Fe],O)=>{let F=W.resolve[O],ae=typeof F=="function"?F:F.resolver;if(!ae)throw new M(`Displayable: Trying to resolve element props but found no resolver. (reading: transitionTask.task.resolve[${O}])`);let H=ae(...oe),j=U(v[O]||v[v.length-1]||{},H);x(Fe,u?u(j):j)})}).cancel},[p]),Kr(()=>{if(!g.current||!g.current.length)throw new M("Displayable: Transition group refs are not initialized correctly");if(g.current.some(([I])=>!I.current))throw new M("Displayable: Trying to access transition groups before they are mounted");g.current.forEach(([I],W)=>{if(!I.current)throw new M("Displayable: Trying to assign properties to unmounted element");x(I,v[W]||v[v.length-1]||{})})},[p]),Kr(()=>{if(!m.current)throw new Error(`Scope not ready. Using element: ${o.constructor.name}`)},[]),Kr(()=>{let I=t.toStyle(T,i);Object.assign(m.current.style,I),T.logger.debug("Displayable","Initial style applied",m.current,I)},[]);function C(I){T.logger.debug("Displayable","Transform applied",t.toStyle(T,i),m.current),S(),s?.(I)}function x(I,W){if(!I.current)throw new M("Displayable: Trying to assign properties to unmounted element");let se=I.current,oe={},Fe={};Object.keys(W).forEach(F=>{let ae=F;ae==="style"&&W.style?Object.assign(oe,W.style):W[ae]!==void 0&&ae!=="key"&&(Fe[ae]=W[ae])}),Object.keys(oe).length>0&&Object.assign(se.style,oe);let O=u?u(Fe):Fe;for(let[F,ae]of Object.entries(O))se.getAttribute(F)!==ae&&se.setAttribute(F,ae)}function w(I,W){a&&(a.abort(),l(null));let se=I.animate(t,{gameState:T,ref:m,overwrites:i}),oe=new ne(se);return T.timelines.attachTimeline(oe),se.onSkipControllerRegister(Fe=>{Fe.onAbort(()=>{oe.abort()})}),l(se),se.then(()=>{l(null),C(I),W()}),oe}function _(I,W){p&&p.controller.complete();let se=I.createTask(T),oe=I.requestAnimations(se.animations),Fe=new b().registerSkipController(new K(oe.cancel)),O=new ne(Fe);Fe.skipController.onAbort(()=>{oe.cancel()}),oe.onCanceled(()=>{O.abort()}),T.timelines.attachTimeline(O),f({task:se,controller:oe,transition:I,resolve:W});let F;if(g.current=se.resolve.map(ae=>{let H=tl.createRef(),j=typeof ae=="function"?void 0:ae.key;if(!j)return[H,d.next()];if(j==="target")return F=d.next(),[H,F];if(j==="current")return[H,h.current];throw new M("Displayable: Invalid key type")}),!F)throw new M("Displayable: No target key found");return h.current=F,oe.start(),oe.onComplete(()=>{J(),f(null),W(),Fe.resolve()}),O}function A(I){return T.logger.debug("initDisplayable",o),w(ce.immediate(t.get()),I)}function P(){n&&a&&(a.abort(),l(null),T.logger.debug("transform skipped")),r&&p&&(p.controller.complete(),T.logger.debug("transition skipped"))}function V(){return[[tl.createRef(),h.current]]}function J(){g.current.forEach(([I])=>{I.current=null}),g.current=V()}return{transformRef:m,transitionRefs:g.current,isTransforming:!!a,transitionTask:p,initDisplayable:A,applyTransform:w,applyTransition:_,deps:[a,p,g]}}import{useEffect as lv}from"react";function wn(o,t,n=[]){let i=N().getLiveGame().getGameState();return lv(()=>{let s=typeof t=="function"?t():t;return i.mountState(o,s).unMount},[...n]),[]}function id({state:o,layer:t,children:n}){let{transformRef:r,transitionRefs:i,initDisplayable:s,applyTransition:c,applyTransform:u,deps:p}=er({element:t,state:t.transformState,skipTransform:o.game.config.allowSkipLayersTransform,skipTransition:!1,transitionsProps:[{style:{width:"100%",height:"100%",transformOrigin:"center"}}]});return wn(t,{initDisplayable:s,applyTransition:c,applyTransform:u},[...p]),uv(()=>(o.logger.debug("Layer","Layer mounted",t.getId()),()=>{o.logger.debug("Layer","Layer unmounted",t.getId())}),[]),ta.createElement(ta.Fragment,null,ta.createElement(Kt.div,{layout:!0,className:"absolute w-full h-full",ref:r,"data-element-type":"layer","data-layer-id":t.getId(),key:`layer-${t.getId()}`},i.map(([f,a])=>ta.createElement("div",{className:"relative w-full h-full",ref:f,key:a},n))))}import ia from"react";import oa from"react";import pt,{useState as sd}from"react";function na({children:o,border:t="solid",color:n="red",tag:r,borderWidth:i=1,as:s="div",ref:c,...u}){let p=N(),[f,a]=sd(!1);if(!p.config.app.inspector)return pt.createElement(s,{...u,ref:c},o);let l={...u,onMouseEnter:()=>a(!0),onMouseLeave:()=>a(!1),style:{...u.style||{},outline:`${i}px ${t} ${n}`,zIndex:f?1e3:"auto"}};return pt.createElement(s,{...l,ref:c},r&&f&&pt.createElement("span",{className:"absolute top-0 left-0 bg-white text-black border-2 border-black text-sm"},r),o)}function pv({border:o="solid",color:t="red",tag:n,borderWidth:r=1,as:i="img",...s}){let c=N(),[u,p]=sd(!1);if(!c.config.app.inspector)return pt.createElement(i,{...s});let f={...s,onMouseEnter:()=>p(!0),onMouseLeave:()=>p(!1),style:{...s.style||{},outline:`${o} ${r}px ${t}`,zIndex:u?1e3:"auto"}};return pt.createElement("div",null,pt.createElement(i,{...f}),n&&u&&pt.createElement("span",{className:"absolute top-0 left-0 bg-white text-black border-2 border-black"},n))}function mv(o){return pt.createElement(na,{...o,as:"div"})}function fv(o){return pt.createElement(na,{...o,as:"span"})}function dv(o){return pt.createElement(pv,{...o,as:"img"})}function hv(o){return pt.createElement(na,{...o,as:"button"})}function gv(o){return pt.createElement(na,{...o,as:Kt.div,ref:o.ref,layout:o.layout})}var yv={Div:mv,Span:fv,Button:hv,Img:dv,mDiv:gv},Bn=yv;function ol({state:o,text:t}){let{ratio:n}=be(),[r]=Ye(),{transformRef:i,transitionRefs:s,initDisplayable:c,applyTransform:u,applyTransition:p,deps:f,isTransforming:a}=er({element:t,state:t.transformState,skipTransform:o.game.config.allowSkipTextTransform,skipTransition:o.game.config.allowSkipTextTransition,overwriteDefinition:{overwrite:l=>({width:"fit-content",transform:ce.propToCSSTransform(o,l,{translate:[t.config.alignX==="left"?"0%":t.config.alignX==="right"?"-100%":void 0,t.config.alignY==="top"?"100%":t.config.alignY==="bottom"?"0%":void 0]})})},transitionsProps:[{style:{width:"fit-content",whiteSpace:"nowrap",transform:`scale(${n.state.scale})`,transformOrigin:`${t.config.alignX} ${t.config.alignY}`,fontSize:`${t.state.fontSize}px`}}]});return wn(t,{initDisplayable:c,applyTransform:u,applyTransition:p,flush:r},[...f]),oa.createElement(Bn.Div,{"data-element-type":"text"},oa.createElement(Bn.mDiv,{tag:"text.container",color:"green",border:"dashed",layout:a,ref:i,className:"absolute"},s.map(([l,m])=>oa.createElement("span",{key:m,ref:l,className:t.config.className},oa.createElement("span",null,t.state.text)))))}import tr,{useRef as cd,useState as ld}from"react";import rl,{useEffect as ad,useRef as Tv}from"react";function il({ref:o,onSizeChanged:t,onLoad:n,autoFit:r=!1}){let i=Tv(null),{ratio:s}=be(),[c,u]=rl.useState(()=>s.state.width),[p,f]=rl.useState(()=>s.state.height),a=N();ad(()=>(l(),s.onUpdate(l)),[o]),ad(()=>{let d=new MutationObserver(h=>{h.forEach(g=>{g.type==="attributes"&&g.attributeName==="src"&&i.current&&l()})});return i.current&&d.observe(i.current,{attributes:!0}),()=>{d.disconnect()}},[]);function l(){let d=o||i;if(d.current&&d.current.naturalWidth)if(d.current.naturalWidth*d.current.naturalHeight===1){let h=s.state.width,g=s.state.height,y=`${h} / ${g}`;u(h),f(g),d.current.style.aspectRatio=y,t&&t(h,g)}else{let h=r?a.config.width/d.current.naturalWidth:1,g=d.current.naturalWidth*s.state.scale*h,y=d.current.naturalHeight*s.state.scale*h;u(g),f(y),t&&t(g,y)}}function m(){l(),n&&n()}return rl.createElement("img",{ref:o||i,onLoad:m,width:c,height:p,alt:"image"})}function ra({image:o,state:t}){let[n]=ld(()=>new re),[r,i]=ld([]),{cacheManager:s}=Jo(),c=cd([]),u=cd(null),{transformRef:p,transitionRefs:f,isTransforming:a,initDisplayable:l,applyTransition:m,applyTransform:d,deps:h}=er({element:o,state:o.transformState,skipTransform:t.game.config.allowSkipImageTransform,skipTransition:t.game.config.allowSkipImageTransition,transitionsProps:T=>{let v=T?T.transition._getCurrentSrc():o.state.currentSrc;return[{style:{position:"absolute",transformOrigin:"center",backgroundColor:k.isColor(v)?k.colorToString(v):void 0,transform:"none",top:"auto",left:"auto",right:"auto",bottom:"auto"},src:k.isImageSrc(v)?k.srcToURL(v):B.DefaultImagePlaceholder},{style:{position:"absolute",transformOrigin:"center",transform:"translate(-50%, -50%)",top:"50%",left:"50%",right:"auto",bottom:"auto",maxWidth:"none",maxHeight:"none"}}]},propOverwrite:T=>T.src?(!k.isDataURI(T.src)&&!s.has(T.src)&&!s.isPreloading(T.src)&&!c.current.includes(T.src)&&(t.game.getLiveGame().getGameState()?.logger.warn("Image",`Image not preloaded: "${T.src}".
58
+ NarraLeaf cannot find the action with the id from the saved game`);this.currentAction=l}r.deserializeServices(a),n.stage.forceUpdate(),n.events.once(ie.EventTypes["event:state.onRender"],()=>{n.schedule(()=>{n.stage.next()},0)})}getHistory(){return this.assertGameState(),this.gameState.gameHistory.getHistory()}undo(t){this.assertGameState(),this.lockedAwaiting&&(this.lockedAwaiting.abort(),this.lockedAwaiting=null);let n=this.currentAction;t?n=this.gameState.actionHistory.undoUntil(t):n=this.gameState.actionHistory.undo(),n?this.currentAction=n:this.gameState.logger.warn("LiveGame.undo","No action found"),this.gameState.logger.info("LiveGame.undo","Undo until",t,"currentAction",this.currentAction,"action",n),this.gameState.stage.forceUpdate(),this.gameState.stage.next(),this.gameState.schedule(()=>{this.gameState&&this.gameState.forceAnimation()},0)}dispose(){this.events.clear(),this.gameState?.dispose()}notify(t,n=3e3){this.assertGameState();let r=this.gameState.idManager.generateId();this.gameState.notificationMgr.consume({id:r,message:t,duration:n})}assertScreenshot(){this.assertGameState(),this.assertPlayerElement()}capturePng(){return this.assertScreenshot(),this.gameState.htmlToImage.toPng(this.gameState.mainContentNode,this.getScreenshotOptions())}captureJpeg(){return this.assertScreenshot(),this.gameState.htmlToImage.toJpeg(this.gameState.mainContentNode,this.getScreenshotOptions())}captureSvg(){return this.assertScreenshot(),this.gameState.htmlToImage.toSvg(this.gameState.mainContentNode,this.getScreenshotOptions())}capturePngBlob(){return this.assertScreenshot(),this.assertGameState(),this.assertPlayerElement(),this.gameState.htmlToImage.toBlob(this.gameState.mainContentNode,this.getScreenshotOptions())}onCharacterPrompt(t){return this.events.on(Xt.EventTypes["event:character.prompt"],t)}onMenuChoose(t){return this.events.on(Xt.EventTypes["event:menu.choose"],t)}newGame(){this.assertGameState();let t=this.gameState,n=t.logger.group("LiveGame (newGame)",!0);this.reset({gameState:t}),this.initNamespaces();let r=this.getNewSavedGame();r.name="NewGame-"+Date.now(),this.currentSavedGame=r,this.currentAction=this.story?.entryScene?.getSceneRoot()||null;let i=this.story?.getAllElementMap(this.story,this.story?.entryScene?.getSceneRoot()||[]);return i?i.forEach(s=>{t.logger.debug("reset element",s),s.reset()}):t.logger.warn("No elements found"),t.stage.forceUpdate(),t.stage.next(),n.end(),this}requestFullScreen(t){this.assertGameState();let n="LiveGame.requestFullScreen";try{let r=this.gameState.playerCurrent;if(!r){this.gameState.logger.warn(n,"No player element found");return}if(r.requestFullscreen)return r.requestFullscreen(t);this.gameState.logger.warn(n,"Fullscreen is not supported")}catch(r){this.gameState.logger.error(n,r)}}exitFullScreen(){this.assertGameState();let t="LiveGame.exitFullScreen";try{if(document.exitFullscreen)return document.exitFullscreen();this.gameState.logger.warn(t,"Fullscreen is not supported")}catch(n){this.gameState.logger.error(t,n)}}getScreenshotOptions(){return{quality:this.game.config.screenshotQuality}}onPlayerEvent(t,n,r){this.assertPlayerElement();let i=this.gameState.playerCurrent;return i?(i.addEventListener(t,n,r),{cancel:()=>i.removeEventListener(t,n,r)}):(this.gameState.logger.warn("LiveGame.onEvent","No player element found"),{cancel:()=>{}})}reset({gameState:t}){this.lockedAwaiting&&this.lockedAwaiting.abort(),this.currentAction=null,this.lockedAwaiting=null,this.currentSavedGame=null,t.forceReset()}getCurrentAction(){return this.currentAction}setCurrentAction(t){return this.currentAction=t,this}next(t){if(this.gameLock.isLocked())return this.gameLock;if(!this.story)throw new Error("No story loaded");if(this.lockedAwaiting){if(!this.lockedAwaiting.isSettled()){if(this._lockedCount++,this._lockedCount>1e3)throw new Error(`LiveGame locked: dead cycle detected
59
+ Please refresh the page`);return this.lockedAwaiting}let r=this.lockedAwaiting.result;return this.currentAction=r?.node?.action||null,this.lockedAwaiting=null,this.currentAction||t.events.emit(ie.EventTypes["event:state.end"]),this._lockedCount=0,t.logger.debug("next action (lockedAwaiting)",r),r||null}if(!this.currentAction)return t.logger.weakWarn("LiveGame","No current action"),null;let n=this.currentAction.executeAction(t);return b.isAwaitable(n)?(this.lockedAwaiting=n,this._lockedCount=0,n):(t.logger.debug("next action",n),this._lockedCount=0,this.currentAction=n.node?.action||null,n)}isPlaying(){return!!this.currentAction}abortAwaiting(){if(this.lockedAwaiting){let t=this.lockedAwaiting.abort();this.currentAction=t?.node?.action||null,this.lockedAwaiting=null}}executeAction(t,n){let r=n.executeAction(t);return b.isAwaitable(r)?r:r?.node?.action||null}executeActionRaw(t,n){return n.executeAction(t)}setGameState(t){return this.gameState=t,this}getGameState(){return this.gameState}getAllPredictableActions(t,n,r){let i=n?.contentNode||null,s=[],c=[],u=new Set;for(;(i||c.length)&&!(r&&s.length>=r);){if(i||(i=c.pop().contentNode),[bn].some(p=>i?.action&&i.action instanceof p)){i=null;continue}if(i.action&&i.action.is(xe,ge.jumpTo)){let[p]=i.action.contentNode.getContent(),f=t.getScene(p);if(!f)throw i.action._sceneNotFoundError(i.action.getSceneName(p));if(u.has(f)){i=null;continue}u.add(f),i=f.getSceneRoot()?.contentNode||null;continue}else if(i.action&&i.action.is(he,ft.do)){let[p]=i.action.contentNode.getContent();i.getChild()?.action&&c.push(i.getChild().action),i=p[0]?.contentNode||null}i.action&&s.push(i.action),i=i.getChild()}return s}getNewSavedGame(){return{name:"",meta:{created:Date.now(),updated:Date.now(),id:Gl()},game:{store:{},stage:{scenes:[],audio:{sounds:[]},videos:[]},elementStates:[],currentAction:this.story?.entryScene?.getSceneRoot().getId()||null,services:{}}}}assertGameState(){if(!this.gameState)throw new M("No game state found, make sure you call this method in effect hooks or event handlers")}assertPlayerElement(){if(this.assertGameState(),!this.gameState.playerCurrent)throw new M("Player Element Not Mounted")}};Xt.DefaultNamespaces={game:{}},Xt.GameSpacesKey={game:"game"},Xt.EventTypes={"event:character.prompt":"event:character.prompt","event:menu.choose":"event:menu.choose"};var Cn=Xt;var Hr=class Hr{constructor(t){this.settings=t;this.events=new re;this.events.setMaxListeners(64)}setPreference(t,n){this.settings[t]=n,this.events.emit(Hr.EventTypes["event:game.preference.change"],t,n)}getPreference(t){return this.settings[t]}getPreferences(){return this.settings}onPreferenceChange(t,n){return this.events.on(Hr.EventTypes["event:game.preference.change"],(r,i)=>{typeof t=="string"?t===r&&n&&n(i):t(r,i)})}importPreferences(t){for(let n in t)Object.prototype.hasOwnProperty.call(t,n)&&this.setPreference(n,t[n])}exportPreferences(){let t={};for(let n in this.settings)Object.prototype.hasOwnProperty.call(this.settings,n)&&(t[n]=this.settings[n]);return t}togglePreference(t){this.setPreference(t,!this.getPreference(t))}};Hr.EventTypes={"event:game.preference.change":"event:game.preference.change"};var Ys=Hr;function Hf(o){var t,n,r="";if(typeof o=="string"||typeof o=="number")r+=o;else if(typeof o=="object")if(Array.isArray(o)){var i=o.length;for(t=0;t<i;t++)o[t]&&(n=Hf(o[t]))&&(r&&(r+=" "),r+=n)}else for(n in o)o[n]&&(r&&(r+=" "),r+=n);return r}function BT(){for(var o,t,n=0,r="",i=arguments.length;n<i;n++)(o=arguments[n])&&(t=Hf(o))&&(r&&(r+=" "),r+=t);return r}var q=BT;import{flushSync as Ad}from"react-dom";import Bf,{useEffect as YT,useRef as ZT,useState as Wf}from"react";import Kf from"react";import WT,{createContext as jT,useContext as $T,useEffect as zT,useReducer as qT,useState as XT}from"react";var Yt=class Yt{constructor(){this.state={width:0,height:0,minWidth:800,minHeight:450,paused:!1,scale:0};this.events=new re().setMaxListeners(1/0);this.lockers=[];this.updater=null}update(t,n,r){this.state.width=t,this.state.height=n,this.state.scale=r,this.events.emit(Yt.EventTypes["event:aspectRatio.update"],t,n)}updateMin(t,n){this.state.minWidth=t,this.state.minHeight=n}lock(){let t=Symbol();return this.lockers.push(t),t}unlock(t){if(t&&!this.lockers.includes(t))throw new Error("Locker not found");return this.lockers=this.lockers.filter(n=>n!==t),this.triggerUpdate(),null}isLocked(){return!!this.lockers.length}getStyle(){return{width:`${this.state.width}px`,height:`${this.state.height}px`}}setUpdate(t){this.updater=t}pause(){this.state.paused=!0,this.events.emit(Yt.EventTypes["event:aspectRatio.pause"])}resume(){this.state.paused=!1,this.events.emit(Yt.EventTypes["event:aspectRatio.resume"])}onUpdate(t){return this.events.on(Yt.EventTypes["event:aspectRatio.update"],t).cancel}requestUpdate(){this.events.emit(Yt.EventTypes["event:aspectRatio.requestUpdate"])}onRequestedUpdate(t){return this.events.on(Yt.EventTypes["event:aspectRatio.requestUpdate"],t).cancel}triggerUpdate(){this.updater&&this.updater()}};Yt.EventTypes={"event:aspectRatio.update":"event:aspectRatio.update","event:aspectRatio.pause":"event:aspectRatio.pause","event:aspectRatio.resume":"event:aspectRatio.resume","event:aspectRatio.requestUpdate":"event:aspectRatio.requestUpdate"};var Uc=Yt,Kc=jT(null);function Uf({children:o}){"use client";let[t]=XT(()=>new Uc);return WT.createElement(Kc,{value:{ratio:t}},o)}function be(){let o=$T(Kc),[,t]=qT(r=>r+1,0);if(!Kc||!o)throw new Error("useRatio must be used within a RatioProvider");let{ratio:n}=o;return zT(()=>n.onUpdate(()=>{t()}),[]),o}function Dt({children:o,className:t,style:n,ref:r,...i}){let{ratio:s}=be(),c=s.getStyle();return Kf.createElement("div",{className:q("inset-0",t),style:{width:"100%",height:"100%",minWidth:`${s.state.minWidth}px`,minHeight:`${s.state.minHeight}px`},...i},Kf.createElement("div",{style:{...c,position:"relative",...n||{}},...i||{},ref:r},o))}function Bc({src:o,width:t,height:n}){let[r,i]=Wf({x:0,y:0}),[s,c]=Wf(!1),u=ZT(null),{ratio:p}=be();return YT(()=>{let f=a=>{if(u.current){let l=u.current.getBoundingClientRect(),m=a.clientX-l.left,d=a.clientY-l.top;i({x:m,y:d}),s||c(!0)}};return window.addEventListener("mousemove",f),()=>{window.removeEventListener("mousemove",f)}},[s]),Bf.createElement(Dt,{ref:u,className:"overflow-hidden absolute"},Bf.createElement("img",{src:o,style:{position:"absolute",left:r.x,top:r.y,width:t,height:n,pointerEvents:"none",zIndex:1001,display:s?"block":"none",cursor:"none",transform:`scale(${p.state.scale})`},alt:""}))}var Kn=class Kn{constructor(){this.preloaded=[];this.events=new re}add(t){let n=this.getSrc(t);return n&&this.has(n)?this:(this.preloaded.push(t),this.events.emit(Kn.EventTypes["event:preloaded.add"],t),this.events.emit(Kn.EventTypes["event:preloaded.change"]),this)}get(t){return this.preloaded.find(n=>this.getSrc(n)===t)}has(t){return Array.isArray(t)?t.every(n=>this.has(n)):this.preloaded.some(n=>this.getSrc(n)===t)}remove(t){if(Array.isArray(t)){let r=t.map(i=>this.getSrc(i));return this.preloaded=this.preloaded.filter(i=>!r.includes(this.getSrc(i))),this}let n=this.getSrc(t);return this.preloaded=this.preloaded.filter(r=>this.getSrc(r)!==n),this.events.emit(Kn.EventTypes["event:preloaded.remove"],t),this.events.emit(Kn.EventTypes["event:preloaded.change"]),this}clear(){return this.preloaded=[],this}getSrc(t){return Ne.getSrc(t)}};Kn.EventTypes={"event:preloaded.add":"event:preloaded.add","event:preloaded.remove":"event:preloaded.remove","event:preloaded.change":"event:preloaded.change","event:preloaded.mount":"event:preloaded.mount","event:preloaded.ready":"event:preloaded.ready","event:preloaded.unmount":"event:preloaded.unmount"};var ot=Kn;import qf,{useEffect as Xf,useState as nv}from"react";import jf,{useContext as JT,useState as QT}from"react";var $f=jf.createContext(null);function zf({children:o,game:t}){"use client";let n=new de({}),[r]=QT(t||n);return jf.createElement($f,{value:r},o)}function N(){let o=JT($f);if(!o)throw new Error("useGame must be used within a GameProvider");return o}import{useEffect as ev,useState as tv}from"react";function Ye(o){let[t,n]=tv(0);ev(()=>{r()},o??[]);function r(){n(i=>i+1)}return[r,t]}function Wc({children:o,className:t,gameState:n}){let[r,i]=nv({}),{ratio:s}=be(),c=N(),[u]=Ye(),p=c.config.minWidth,f=c.config.minHeight;return Xf(()=>{n.logger.debug("AspectRatio","mount, using interval",c.config.ratioUpdateInterval);let a=()=>{if(s.isLocked()){n.logger.weakWarn("Ratio is locked, skipping update");return}let h=document.getElementById(c.config.contentContainerId);if(h){let g=h.clientWidth,y=h.clientHeight,T=c.config.aspectRatio,v,S;g/y>T?(v=y*T,S=y):(v=g,S=g/T),v<p&&(v=p),S<f&&(S=f),i({width:`${v}px`,height:`${S}px`,margin:"auto",position:"absolute",top:"0",bottom:"0",left:"0",right:"0",display:"flex",alignItems:"center",justifyContent:"center"});let C=v/c.config.width;s.update(v,S,C),s.updateMin(p,f),u()}};s.setUpdate(a);let m=Rl(()=>{a()},c.config.ratioUpdateInterval);m(),window.addEventListener("resize",m);let d=s.onRequestedUpdate(m);return()=>{window.removeEventListener("resize",m),d()}},[s,c.config.ratioUpdateInterval]),Xf(()=>n.events.on(ie.EventTypes["event:state.player.requestFlush"],u).cancel,[n]),qf.createElement("div",{id:c.config.contentContainerId,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"}},qf.createElement("div",{className:q(t),style:r},o))}import Yf from"react";import Zt from"react";function jc({error:o,errorInfo:t}){let n=N();return n.config.onError&&n.config.onError(o),n.config.app.debug?Zt.createElement("div",{className:"text-left"},Zt.createElement("h1",null,"NarraLeaf-React cannot initialize the player correctly. (development mode)"),Zt.createElement("p",{className:"text-red-700"},"Message: ",o.message),Zt.createElement("pre",null,"Error Stack: ",o?.stack),Zt.createElement("pre",null,"Component Stack: ",t?.componentStack),Zt.createElement("pre",null,"Digest: ",t?.digest)):Zt.createElement("div",{className:"bg-white w-full h-full"},Zt.createElement("h1",null,"NarraLeaf-React crashed due to an unknown error."),Zt.createElement("p",null,"Please contact the game developer for further assistance."))}var Zs=class extends Yf.Component{constructor(){super(...arguments);this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(n){return{hasError:!0,error:n,errorInfo:null}}componentDidCatch(n,r){this.setState({error:n,errorInfo:r}),console.error(n,r)}render(){return this.state.hasError?Yf.createElement(jc,{error:this.state.error,errorInfo:this.state.errorInfo}):this.props.children}};import $c,{createContext as ov,useContext as rv,useState as Zf}from"react";var Js=class o{constructor(t){this.game=t;this.src=new Map;this.preloadTasks=new Map;this.game.addSideEffect(()=>{this.abortAll(),this.src.clear()})}static getImage(t,n,r){return Ll(t,{...r,signal:n})}has(t){return this.src.has(t)}add(t,n){return this.src.set(t,n),this}remove(t){return this.src.delete(t),this}get(t){return this.src.get(t)}clear(){return this.src.clear(),this}size(){return this.src.size}isPreloading(t){return this.preloadTasks.has(t)}preload(t,n){if(this.src.has(n)||this.preloadTasks.has(n)){let l={abort:()=>{},onFinished:()=>l,onErrored:()=>l};return l}let r=n,i={};this.game.hooks.rawTrigger("preloadImage",()=>[r,(l,m)=>{r=l,i={...i,...m}}]);let s=new AbortController,c=s.signal,u=[],f={promise:o.getImage(r,c,i).then(l=>{this.preloadTasks.delete(n),l&&this.add(n,l)}).catch(l=>{t.logger.error("ImageCacheManager",`Failed to preload image: ${n}`,`Reason: ${l}`),u.forEach(m=>m(l))}),controller:s};this.preloadTasks.set(n,f);let a={abort:()=>{s.abort(),this.preloadTasks.delete(n)},onFinished:l=>(f.promise.then(l),a),onErrored:l=>(u.push(l),a)};return a}abortAll(){this.preloadTasks.forEach(t=>{t.controller.abort()}),this.preloadTasks.clear()}abort(t){let n=this.preloadTasks.get(t);n&&(n.controller.abort(),this.preloadTasks.delete(t))}preloadedSrc(){return Array.from(this.src.values())}filter(t){for(let n of this.src.keys())t.includes(n)||this.src.delete(n);return this}};var zc=ov(null);function Jf({children:o}){let t=N(),[n]=Zf(()=>new ot),[r]=Zf(()=>new Js(t));return $c.createElement($c.Fragment,null,$c.createElement(zc,{value:{preloaded:n,cacheManager:r}},o))}function Jo(){if(!zc)throw new Error("usePreloaded must be used within a PreloadedProvider");return rv(zc)}import{useEffect as qc,useRef as iv}from"react";function Qf({state:o}){let{preloaded:t,cacheManager:n}=Jo(),r=N(),i=iv(new Set),s="Preload",c=o.getLastScene()||o.getPreloadingScene(),u=r.getLiveGame().getCurrentAction(),p=r.getLiveGame().story;function f(){o.logger.debug(s,"Preload unmounted"),t.events.emit(ot.EventTypes["event:preloaded.unmount"])}return qc(()=>{if(typeof fetch>"u")return t.events.emit(ot.EventTypes["event:preloaded.ready"]),o.logger.warn(s,"Fetch is not supported in this environment, skipping preload"),f;if(!r.config.preloadAllImages)return t.events.emit(ot.EventTypes["event:preloaded.ready"]),o.logger.debug(s,"Preload all images is disabled, skipping preload"),f;if(r.config.forceClearCache&&(n.clear(),o.logger.weakWarn(s,"Cache cleared")),!p||!c)return o.logger.weakWarn(s,"Story/Scene not found, skipping preload"),f;let a=performance.now(),l=Ne.catSrc([...c.srcManager?.src||[],...c.srcManager?.getFutureSrc()||[]]),m=new ir(r.config.preloadConcurrency,r.config.preloadDelay),d=[],h=o.logger.group(s,!0),g=[];o.logger.debug(s,"preloading:",l,c);for(let y of l.image){let T=Ne.getSrc(y);if(T){if(d.push(T),n.has(T)||n.isPreloading(T)||g.includes(T)){o.logger.debug(s,`Image already loaded (${l.image.indexOf(y)+1}/${l.image.length})`,T),g.push(T);continue}g.push(T),m.addTask(()=>new Promise(v=>{n.preload(o,T).onFinished(()=>{o.logger.debug(s,`Image loaded (${l.image.indexOf(y)+1}/${l.image.length})`,T),v()}).onErrored(()=>{o.logger.weakError(s,`Failed to preload image (${l.image.indexOf(y)+1}/${l.image.length})`,T),v()})}))}}return h.end(),m.start().then(()=>{o.logger.info(s,"Image preload",`loaded ${n.size()} images in ${performance.now()-a}ms`),r.config.waitForPreload&&t.events.emit(ot.EventTypes["event:preloaded.ready"]),n.filter(d)}),r.config.waitForPreload||t.events.emit(ot.EventTypes["event:preloaded.ready"]),t.events.emit(ot.EventTypes["event:preloaded.mount"]),f},[c,p]),qc(()=>{i.current.clear()},[c]),qc(()=>{if(typeof fetch>"u"||r.config.preloadAllImages)return;if(!p){o.logger.weakWarn(s,"Story not found, skipping preload");return}let a=performance.now(),l=r.getLiveGame().getAllPredictableActions(p,u,r.config.maxPreloadActions).map(T=>Ne.getPreloadableSrc(p,T)).filter(function(T){return T!==null});l.filter(function(T){return T?.activeType==="scene"}).forEach(T=>{i.current.has(T)||i.current.add(T)});let d=Ne.catSrc([...i.current,...l]),h=new ir(r.config.preloadConcurrency,r.config.preloadDelay),g=[],y=o.logger.group(s);o.logger.debug(s,"preloading:",d);for(let T of d.image){let v=Ne.getSrc(T);if(v){if(g.push(v),n.has(v)||n.isPreloading(v)){o.logger.debug(s,`Image already loaded (${d.image.indexOf(T)+1}/${d.image.length})`,v);continue}h.addTask(()=>new Promise(S=>{n.preload(o,v).onFinished(()=>{o.logger.debug(s,`Image loaded (${d.image.indexOf(T)+1}/${d.image.length})`,v),S()}).onErrored(()=>{o.logger.weakError(s,`Failed to preload image (${d.image.indexOf(T)+1}/${d.image.length})`,v),S()})}))}}y.end(),h.start().then(()=>{o.logger.info(s,"Image preload (quick reload)",`loaded ${n.size()} images in ${performance.now()-a}ms`),n.filter(g)})},[u,p]),null}import Ae,{useEffect as fa,useReducer as Cd,useState as Sl}from"react";import Qo,{useEffect as cv}from"react";import ed from"react";import Qs from"react";function ea({children:o,className:t,style:n,...r}){let{ratio:i}=be(),s=N();return Qs.createElement(Dt,{className:q("absolute pointer-events-none w-full h-full"),style:{transform:`scale(${i.state.scale})`,transformOrigin:"left top",width:s.config.width,height:s.config.height,pointerEvents:"none"},"data-element-type":"full",...r},Qs.createElement("div",{className:"absolute inset-0 w-full h-full"},Qs.createElement("div",{className:"inset-0 w-full h-full"},Qs.createElement("div",{className:q("pointer-events-auto-rest",t),style:n},o))))}function Xc({id:o,children:t,className:n,style:r,...i}){return ed.createElement(Kt.div,{className:q("w-full h-full"),key:o,...i},ed.createElement(ea,{className:n,style:r},t))}import Yc,{createContext as sv,useContext as td,useState as av}from"react";var Zc=class{constructor(t,n){this.events=new re;this.current=null;this.history=[];this.historyIndex=-1;this.game=t,n&&(this.current=n,this.history.push(n),this.historyIndex=0)}getCurrentId(){return this.current}push(t){return this.historyIndex<this.history.length-1&&(this.history=this.history.slice(0,this.historyIndex+1)),this.history.push(t),this.history.length>this.game.config.maxRouterHistory&&(this.history.shift(),this.historyIndex--),this.historyIndex++,this.current=t,this.emitOnChange(),this}back(){return this.historyIndex>0?(this.historyIndex--,this.current=this.history[this.historyIndex],this.emitOnChange()):(this.current=null,this.emitOnChange()),this}forward(){return this.historyIndex<this.history.length-1&&(this.historyIndex++,this.current=this.history[this.historyIndex],this.emitOnChange()),this}clear(){return this.current=null,this.history=[],this.historyIndex=-1,this.emitOnChange(),this}cleanHistory(){return this.history=this.current?[this.current]:[],this.historyIndex=this.current?0:-1,this}isActive(){return this.current!==null}emitOnChange(){this.events.emit("event:router.onChange")}},Jc=sv(null);function nd({children:o}){"use client";let t=N(),[n]=av(()=>new Zc(t));return Yc.createElement(Yc.Fragment,null,Yc.createElement(Jc,{value:{router:n}},o))}function Ur(){if(!td(Jc))throw new Error("usePreloaded must be used within a PreloadedProvider");return td(Jc).router}import Qc from"react";function el({children:o,className:t,style:n}){return Qc.createElement(Qc.Fragment,null,Qc.createElement(ea,{style:n,className:t,"data-element-type":"stage","data-code-source":"Stage.tsx"},o))}function od({children:o}){let[t]=Ye(),n=Ur(),r=N();if(cv(()=>{if(n)return n.events.on("event:router.onChange",t).cancel},[]),!n)return null;let i=Qo.Children.toArray([...r.config.stage?[r.config.stage]:[],...o?[o]:[]]),s=Xc,u=i.filter(function(l){return Qo.isValidElement(l)&&l.type===s}).find(l=>l.props.id===n.getCurrentId()),p=el,f=i.find(function(l){return Qo.isValidElement(l)&&l.type===p});return Qo.createElement(Qo.Fragment,null,f,Qo.createElement(cr,{mode:"wait"},u))}import jn,{useEffect as hl,useRef as _v}from"react";import ta,{useEffect as uv}from"react";import tl,{useEffect as Kr,useRef as rd,useState as nl}from"react";function er({element:o,state:t,skipTransform:n,skipTransition:r,overwriteDefinition:i,onTransform:s,transitionsProps:c=[],propOverwrite:u}){let[p,f]=nl(null),[a,l]=nl(null),m=tl.useRef(null),[d]=nl(()=>new qr("displayable.refGroup")),h=rd(d.next()),g=rd(V()),T=N().getLiveGame().getGameState(),v=typeof c=="function"?c(p):c,[S]=Ye([a,p,g]);Kr(()=>T.events.depends([T.events.on(ie.EventTypes["event:state.player.skip"],P)]).cancel,[a,p,g]),Kr(()=>{if(!p)return;if(g.current.some(([oe])=>!oe.current))throw new M("Displayable: Trying to access transition groups before they are mounted");let{controller:I,task:W}=p;return I.onUpdate(oe=>{g.current.forEach(([Fe],O)=>{let F=W.resolve[O],ae=typeof F=="function"?F:F.resolver;if(!ae)throw new M(`Displayable: Trying to resolve element props but found no resolver. (reading: transitionTask.task.resolve[${O}])`);let H=ae(...oe),j=U(v[O]||v[v.length-1]||{},H);x(Fe,u?u(j):j)})}).cancel},[p]),Kr(()=>{if(!g.current||!g.current.length)throw new M("Displayable: Transition group refs are not initialized correctly");if(g.current.some(([I])=>!I.current))throw new M("Displayable: Trying to access transition groups before they are mounted");g.current.forEach(([I],W)=>{if(!I.current)throw new M("Displayable: Trying to assign properties to unmounted element");x(I,v[W]||v[v.length-1]||{})})},[p]),Kr(()=>{if(!m.current)throw new Error(`Scope not ready. Using element: ${o.constructor.name}`)},[]),Kr(()=>{let I=t.toStyle(T,i);Object.assign(m.current.style,I),T.logger.debug("Displayable","Initial style applied",m.current,I)},[]);function C(I){T.logger.debug("Displayable","Transform applied",t.toStyle(T,i),m.current),S(),s?.(I)}function x(I,W){if(!I.current)throw new M("Displayable: Trying to assign properties to unmounted element");let se=I.current,oe={},Fe={};Object.keys(W).forEach(F=>{let ae=F;ae==="style"&&W.style?Object.assign(oe,W.style):W[ae]!==void 0&&ae!=="key"&&(Fe[ae]=W[ae])}),Object.keys(oe).length>0&&Object.assign(se.style,oe);let O=u?u(Fe):Fe;for(let[F,ae]of Object.entries(O))se.getAttribute(F)!==ae&&se.setAttribute(F,ae)}function w(I,W){a&&(a.abort(),l(null));let se=I.animate(t,{gameState:T,ref:m,overwrites:i}),oe=new ne(se);return T.timelines.attachTimeline(oe),se.onSkipControllerRegister(Fe=>{Fe.onAbort(()=>{oe.abort()})}),l(se),se.then(()=>{l(null),C(I),W()}),oe}function _(I,W){p&&p.controller.complete();let se=I.createTask(T),oe=I.requestAnimations(se.animations),Fe=new b().registerSkipController(new K(oe.cancel)),O=new ne(Fe);Fe.skipController.onAbort(()=>{oe.cancel()}),oe.onCanceled(()=>{O.abort()}),T.timelines.attachTimeline(O),f({task:se,controller:oe,transition:I,resolve:W});let F;if(g.current=se.resolve.map(ae=>{let H=tl.createRef(),j=typeof ae=="function"?void 0:ae.key;if(!j)return[H,d.next()];if(j==="target")return F=d.next(),[H,F];if(j==="current")return[H,h.current];throw new M("Displayable: Invalid key type")}),!F)throw new M("Displayable: No target key found");return h.current=F,oe.start(),oe.onComplete(()=>{J(),f(null),W(),Fe.resolve()}),O}function A(I){return T.logger.debug("initDisplayable",o),w(ce.immediate(t.get()),I)}function P(){n&&a&&(a.abort(),l(null),T.logger.debug("transform skipped")),r&&p&&(p.controller.complete(),T.logger.debug("transition skipped"))}function V(){return[[tl.createRef(),h.current]]}function J(){g.current.forEach(([I])=>{I.current=null}),g.current=V()}return{transformRef:m,transitionRefs:g.current,isTransforming:!!a,transitionTask:p,initDisplayable:A,applyTransform:w,applyTransition:_,deps:[a,p,g]}}import{useEffect as lv}from"react";function wn(o,t,n=[]){let i=N().getLiveGame().getGameState();return lv(()=>{let s=typeof t=="function"?t():t;return i.mountState(o,s).unMount},[...n]),[]}function id({state:o,layer:t,children:n}){let{transformRef:r,transitionRefs:i,initDisplayable:s,applyTransition:c,applyTransform:u,deps:p}=er({element:t,state:t.transformState,skipTransform:o.game.config.allowSkipLayersTransform,skipTransition:!1,transitionsProps:[{style:{width:"100%",height:"100%",transformOrigin:"center"}}]});return wn(t,{initDisplayable:s,applyTransition:c,applyTransform:u},[...p]),uv(()=>(o.logger.debug("Layer","Layer mounted",t.getId()),()=>{o.logger.debug("Layer","Layer unmounted",t.getId())}),[]),ta.createElement(ta.Fragment,null,ta.createElement(Kt.div,{layout:!0,className:"absolute w-full h-full",ref:r,"data-element-type":"layer","data-layer-id":t.getId(),key:`layer-${t.getId()}`},i.map(([f,a])=>ta.createElement("div",{className:"relative w-full h-full",ref:f,key:a},n))))}import ia from"react";import oa from"react";import pt,{useState as sd}from"react";function na({children:o,border:t="solid",color:n="red",tag:r,borderWidth:i=1,as:s="div",ref:c,...u}){let p=N(),[f,a]=sd(!1);if(!p.config.app.inspector)return pt.createElement(s,{...u,ref:c},o);let l={...u,onMouseEnter:()=>a(!0),onMouseLeave:()=>a(!1),style:{...u.style||{},outline:`${i}px ${t} ${n}`,zIndex:f?1e3:"auto"}};return pt.createElement(s,{...l,ref:c},r&&f&&pt.createElement("span",{className:"absolute top-0 left-0 bg-white text-black border-2 border-black text-sm"},r),o)}function pv({border:o="solid",color:t="red",tag:n,borderWidth:r=1,as:i="img",...s}){let c=N(),[u,p]=sd(!1);if(!c.config.app.inspector)return pt.createElement(i,{...s});let f={...s,onMouseEnter:()=>p(!0),onMouseLeave:()=>p(!1),style:{...s.style||{},outline:`${o} ${r}px ${t}`,zIndex:u?1e3:"auto"}};return pt.createElement("div",null,pt.createElement(i,{...f}),n&&u&&pt.createElement("span",{className:"absolute top-0 left-0 bg-white text-black border-2 border-black"},n))}function mv(o){return pt.createElement(na,{...o,as:"div"})}function fv(o){return pt.createElement(na,{...o,as:"span"})}function dv(o){return pt.createElement(pv,{...o,as:"img"})}function hv(o){return pt.createElement(na,{...o,as:"button"})}function gv(o){return pt.createElement(na,{...o,as:Kt.div,ref:o.ref,layout:o.layout})}var yv={Div:mv,Span:fv,Button:hv,Img:dv,mDiv:gv},Bn=yv;function ol({state:o,text:t}){let{ratio:n}=be(),[r]=Ye(),{transformRef:i,transitionRefs:s,initDisplayable:c,applyTransform:u,applyTransition:p,deps:f,isTransforming:a}=er({element:t,state:t.transformState,skipTransform:o.game.config.allowSkipTextTransform,skipTransition:o.game.config.allowSkipTextTransition,overwriteDefinition:{overwrite:l=>({width:"fit-content",transform:ce.propToCSSTransform(o,l,{translate:[t.config.alignX==="left"?"0%":t.config.alignX==="right"?"-100%":void 0,t.config.alignY==="top"?"100%":t.config.alignY==="bottom"?"0%":void 0]})})},transitionsProps:[{style:{width:"fit-content",whiteSpace:"nowrap",transform:`scale(${n.state.scale})`,transformOrigin:`${t.config.alignX} ${t.config.alignY}`,fontSize:`${t.state.fontSize}px`}}]});return wn(t,{initDisplayable:c,applyTransform:u,applyTransition:p,flush:r},[...f]),oa.createElement(Bn.Div,{"data-element-type":"text"},oa.createElement(Bn.mDiv,{tag:"text.container",color:"green",border:"dashed",layout:a,ref:i,className:"absolute"},s.map(([l,m])=>oa.createElement("span",{key:m,ref:l,className:t.config.className},oa.createElement("span",null,t.state.text)))))}import tr,{useRef as cd,useState as ld}from"react";import rl,{useEffect as ad,useRef as Tv}from"react";function il({ref:o,onSizeChanged:t,onLoad:n,autoFit:r=!1}){let i=Tv(null),{ratio:s}=be(),[c,u]=rl.useState(()=>s.state.width),[p,f]=rl.useState(()=>s.state.height),a=N();ad(()=>(l(),s.onUpdate(l)),[o]),ad(()=>{let d=new MutationObserver(h=>{h.forEach(g=>{g.type==="attributes"&&g.attributeName==="src"&&i.current&&l()})});return i.current&&d.observe(i.current,{attributes:!0}),()=>{d.disconnect()}},[]);function l(){let d=o||i;if(d.current&&d.current.naturalWidth)if(d.current.naturalWidth*d.current.naturalHeight===1){let h=s.state.width,g=s.state.height,y=`${h} / ${g}`;u(h),f(g),d.current.style.aspectRatio=y,t&&t(h,g)}else{let h=r?a.config.width/d.current.naturalWidth:1,g=d.current.naturalWidth*s.state.scale*h,y=d.current.naturalHeight*s.state.scale*h;u(g),f(y),t&&t(g,y)}}function m(){l(),n&&n()}return rl.createElement("img",{ref:o||i,onLoad:m,width:c,height:p,alt:""})}function ra({image:o,state:t}){let[n]=ld(()=>new re),[r,i]=ld([]),{cacheManager:s}=Jo(),c=cd([]),u=cd(null),{transformRef:p,transitionRefs:f,isTransforming:a,initDisplayable:l,applyTransition:m,applyTransform:d,deps:h}=er({element:o,state:o.transformState,skipTransform:t.game.config.allowSkipImageTransform,skipTransition:t.game.config.allowSkipImageTransition,transitionsProps:T=>{let v=T?T.transition._getCurrentSrc():o.state.currentSrc;return[{style:{position:"absolute",transformOrigin:"center",backgroundColor:k.isColor(v)?k.colorToString(v):void 0,transform:"none",top:"auto",left:"auto",right:"auto",bottom:"auto"},src:k.isImageSrc(v)?k.srcToURL(v):B.DefaultImagePlaceholder},{style:{position:"absolute",transformOrigin:"center",transform:"translate(-50%, -50%)",top:"50%",left:"50%",right:"auto",bottom:"auto",maxWidth:"none",maxHeight:"none"}}]},propOverwrite:T=>T.src?(!k.isDataURI(T.src)&&!s.has(T.src)&&!s.isPreloading(T.src)&&!c.current.includes(T.src)&&(t.game.getLiveGame().getGameState()?.logger.warn("Image",`Image not preloaded: "${T.src}".
60
60
  This may be caused by complicated image action behavior that cannot be predicted.
61
- To fix this issue, you can manually register the image using scene.preloadImage(YourImageSrc). `),c.current.push(T.src)),{...T,src:s.get(T.src)||T.src}):T});wn(o,{createWearable:T=>{i(v=>[...v,T])},disposeWearable:T=>{i(v=>v.filter(S=>S.getId()!==T.getId()))},initDisplayable:l,applyTransform:d,applyTransition:m,events:n},[...h]);function g(T,v){u.current&&(n.emit("event:image.onLoad"),Object.assign(u.current.style,{width:`${T}px`,height:`${v}px`}))}function y(){n.emit("event:image.onLoad")}return tr.createElement(Kt.div,{layout:a,ref:p,className:"absolute w-max h-max","data-element-type":"image"},tr.createElement("div",{className:"relative h-full w-full",ref:u,"data-image-id":o.getId()},f.map(([T,v],S)=>tr.createElement(il,{key:v,ref:T,autoFit:o.config.autoFit,onSizeChanged:S===0?g:void 0,onLoad:S===0?y:void 0})),tr.createElement("div",{className:q("w-full h-full top-0 left-0 absolute")},r.map(T=>tr.createElement("div",{className:q("w-full h-full relative"),key:"wearable-"+T.getId()},tr.createElement(ra,{image:T,state:t}))))))}function sl({state:o,displayable:t}){return ia.createElement(ia.Fragment,null,t.map(n=>{if(n instanceof Un)return ia.createElement(ol,{state:o,text:n,key:"text-"+n.getId()});if(n instanceof B)return ia.createElement(ra,{state:o,image:n,key:"image-"+n.getId()});throw new Error("Unsupported displayable type: "+(n?.constructor?.name||n))}))}import It,{useMemo as Rv,useCallback as ml,useRef as Iv}from"react";import sa from"react";var al=sa.createContext(null);function ud(){let o=sa.useContext(al);if(!o)throw new Error("useUIMenuContext must be used within a UIMenuContext");return o}var cl=sa.createContext(null);function pd(){let o=sa.useContext(cl);if(!o)throw new Error("useUIListContext must be used within a UIListContext");return o}import md from"react";function aa({className:o,children:t,...n}){let{ratio:r}=be();return md.createElement("div",{style:{transform:`scale(${r.state.scale})`,transformOrigin:"left top"},className:q("w-full h-full")},md.createElement("div",{className:q("z-20",o),...n},t))}import la,{useEffect as Pv,useLayoutEffect as Ev,useRef as kv,useState as Dv}from"react";import Wn,{useEffect as ul,useRef as Av,useState as Cv}from"react";import fd from"react";var ll=fd.createContext(null);function Jt(){let o=fd.useContext(ll);if(!o)throw new Error("useDialogContext must be used within a DialogContext");return o}import ca,{useEffect as vv,useLayoutEffect as Sv,useMemo as xv,useState as bv}from"react";var Rt=class Rt{constructor(t){this.events=new re;this._forceSkipped=!1;this._idle=!1;this.config=t,this._state="pending",this.autoForwardScheduler=new zr,this._count=0}get state(){return this._state}get deps(){return[this._count]}isIdle(){return this._idle}setIdle(t){this._idle=t}requestComplete(){this.state==="ended"?this.events.emit(Rt.Events.complete):this.events.emit(Rt.Events.requestComplete)}forceSkip(){this.state==="ended"?this.emitComplete():(this._forceSkipped=!0,this.events.emit(Rt.Events.forceSkip))}dispatchComplete(){if(this.state==="ended")return;let t=this.config.gameState.game.preference;return this._state="ended",t.getPreference(de.Preferences.autoForward)&&this.scheduleAutoForward(),this.emitComplete(),this}emitComplete(){return this.events.emit(Rt.Events.complete),this.emitFlush(),this}isEnded(){return this.state==="ended"}setPause(t){this.isEnded()||(t?this._state="paused":this._state="pending")}isForceSkipped(){return this._forceSkipped}tryScheduleAutoForward(){this.isEnded()&&this.scheduleAutoForward()}cancelAutoForward(){this.autoForwardScheduler.cancelTask()}emitFlush(){return this._count++,this.events.emit(Rt.Events.onFlush),this}onFlush(t){return this.events.on(Rt.Events.onFlush,t)}scheduleAutoForward(){let t=this.config.gameState.game.preference;!t.getPreference(de.Preferences.autoForward)||this.state!=="ended"||this.autoForwardScheduler.cancelTask().scheduleTask(()=>{this.events.emit(Rt.Events.complete)},this.config.gameState.game.config.autoForwardDelay/t.getPreference(de.Preferences.gameSpeed))}};Rt.Events={requestComplete:"event:dialog.requestComplete",complete:"event:dialog.complete",forceSkip:"event:dialog.forceSkip",onFlush:"event:dialog.onFlush"};var vt=Rt;function Br({action:o,onFinished:t,useTypeEffect:n=!0,gameState:r}){let i=xv(()=>o.sentence?.evaluate(ut.getCtx({gameState:r})),[o.sentence,r]),[s]=bv(()=>new vt({useTypeEffect:n,action:o,evaluatedWords:i||[],gameState:r})),c=r.game.config.dialog;return Sv(()=>s.events.depends([s.events.on(vt.Events.complete,()=>{r.logger.log("NarraLeaf-React: Say","Complete",s.isIdle()),s.isIdle()?t?.(!1):s.setIdle(!0)})]).cancel,[]),vv(()=>r.events.on(ie.EventTypes["event:state.player.skip"],()=>{r.logger.log("NarraLeaf-React: Say","Skipped",s.isIdle()),s.isIdle()?t?.(!0):s.forceSkip()}).cancel,[s]),ca.createElement(ca.Fragment,null,ca.createElement(ll,{value:s,key:o.id},ca.createElement(c,null)))}function*dd(o){let t=[...o];for(let n=0;n<t.length;n++){let r=t[n];if(Ke.isPause(r.text)){yield Ke.from(r.text);continue}for(let i=0;i<r.text.length;i++){let s=r.text[i];s===`
61
+ To fix this issue, you can manually register the image using scene.preloadImage(YourImageSrc). `),c.current.push(T.src)),{...T,src:s.get(T.src)||T.src}):T});wn(o,{createWearable:T=>{i(v=>[...v,T])},disposeWearable:T=>{i(v=>v.filter(S=>S.getId()!==T.getId()))},initDisplayable:l,applyTransform:d,applyTransition:m,events:n},[...h]);function g(T,v){u.current&&(n.emit("event:image.onLoad"),Object.assign(u.current.style,{width:`${T}px`,height:`${v}px`}))}function y(){n.emit("event:image.onLoad")}return tr.createElement(Kt.div,{layout:a,ref:p,className:"absolute w-max h-max","data-element-type":"image"},tr.createElement("div",{className:"relative h-full w-full",ref:u,"data-image-id":o.getId()},f.map(([T,v],S)=>tr.createElement(il,{key:v,ref:T,autoFit:o.config.autoFit,onSizeChanged:S===0?g:void 0,onLoad:S===0?y:void 0})),tr.createElement("div",{className:q("w-full h-full top-0 left-0 absolute")},r.map(T=>tr.createElement("div",{className:q("w-full h-full relative"),key:"wearable-"+T.getId()},tr.createElement(ra,{image:T,state:t}))))))}function sl({state:o,displayable:t}){return ia.createElement(ia.Fragment,null,t.map(n=>{if(n instanceof Un)return ia.createElement(ol,{state:o,text:n,key:"text-"+n.getId()});if(n instanceof B)return ia.createElement(ra,{state:o,image:n,key:"image-"+n.getId()});throw new Error("Unsupported displayable type: "+(n?.constructor?.name||n))}))}import It,{useMemo as Rv,useCallback as ml,useRef as Iv}from"react";import sa from"react";var al=sa.createContext(null);function ud(){let o=sa.useContext(al);if(!o)throw new Error("useUIMenuContext must be used within a UIMenuContext");return o}var cl=sa.createContext(null);function pd(){let o=sa.useContext(cl);if(!o)throw new Error("useUIListContext must be used within a UIListContext");return o}import md from"react";function aa({className:o,children:t,...n}){let{ratio:r}=be();return md.createElement("div",{style:{transform:`scale(${r.state.scale})`,transformOrigin:"left top"},className:q("w-full h-full")},md.createElement("div",{className:q("z-20",o),...n},t))}import la,{useEffect as Pv,useLayoutEffect as Ev,useRef as kv,useState as Dv}from"react";import Wn,{useEffect as ul,useRef as Av,useState as Cv}from"react";import fd from"react";var ll=fd.createContext(null);function Jt(){let o=fd.useContext(ll);if(!o)throw new Error("useDialogContext must be used within a DialogContext");return o}import ca,{useEffect as vv,useLayoutEffect as Sv,useMemo as xv,useState as bv}from"react";var Rt=class Rt{constructor(t){this.events=new re;this._forceSkipped=!1;this._idle=!1;this.config=t,this._state="pending",this.autoForwardScheduler=new zr,this._count=0}get state(){return this._state}get deps(){return[this._count]}isIdle(){return this._idle}setIdle(t){this._idle=t}requestComplete(){this.state==="ended"?this.events.emit(Rt.Events.complete):this.events.emit(Rt.Events.requestComplete)}forceSkip(){this.state==="ended"?this.emitComplete():(this._forceSkipped=!0,this.events.emit(Rt.Events.forceSkip))}dispatchComplete(){if(this.state==="ended")return;let t=this.config.gameState.game.preference;return this._state="ended",t.getPreference(de.Preferences.autoForward)&&this.scheduleAutoForward(),this.emitComplete(),this}emitComplete(){return this.events.emit(Rt.Events.complete),this.emitFlush(),this}isEnded(){return this.state==="ended"}setPause(t){this.isEnded()||(t?this._state="paused":this._state="pending")}isForceSkipped(){return this._forceSkipped}tryScheduleAutoForward(){this.isEnded()&&this.scheduleAutoForward()}cancelAutoForward(){this.autoForwardScheduler.cancelTask()}emitFlush(){return this._count++,this.events.emit(Rt.Events.onFlush),this}onFlush(t){return this.events.on(Rt.Events.onFlush,t)}scheduleAutoForward(){let t=this.config.gameState.game.preference;!t.getPreference(de.Preferences.autoForward)||this.state!=="ended"||this.autoForwardScheduler.cancelTask().scheduleTask(()=>{this.events.emit(Rt.Events.complete)},this.config.gameState.game.config.autoForwardDelay/t.getPreference(de.Preferences.gameSpeed))}};Rt.Events={requestComplete:"event:dialog.requestComplete",complete:"event:dialog.complete",forceSkip:"event:dialog.forceSkip",onFlush:"event:dialog.onFlush"};var vt=Rt;function Br({action:o,onFinished:t,useTypeEffect:n=!0,gameState:r}){let i=xv(()=>o.sentence?.evaluate(ut.getCtx({gameState:r})),[o.sentence,r]),[s]=bv(()=>new vt({useTypeEffect:n,action:o,evaluatedWords:i||[],gameState:r})),c=r.game.config.dialog;return Sv(()=>s.events.depends([s.events.on(vt.Events.complete,()=>{r.logger.log("NarraLeaf-React: Say","Complete",s.isIdle()),s.isIdle()?t?.(!1):s.setIdle(!0)})]).cancel,[]),vv(()=>r.events.on(ie.EventTypes["event:state.player.skip"],()=>{s.isIdle()?t?.(!0):s.forceSkip()}).cancel,[s]),ca.createElement(ca.Fragment,null,ca.createElement(ll,{value:s,key:o.id},ca.createElement(c,null)))}function*dd(o){let t=[...o];for(let n=0;n<t.length;n++){let r=t[n];if(Ke.isPause(r.text)){yield Ke.from(r.text);continue}for(let i=0;i<r.text.length;i++){let s=r.text[i];s===`
62
62
  `?yield`
63
- `:yield{text:s,config:r.config,tag:n,tag2:i,cps:r.config.cps}}}}function hd({defaultColor:o,className:t,style:n,dialog:r,...i}){let s=N(),c=s.getLiveGame().getGameState(),u=Av(null),[p,f]=Cv(()=>r&&!r.config.useTypeEffect?d(r.config.evaluatedWords):[]),[a,l]=Ye();if(!r)throw new Error("Dialog state is required");ul(()=>{if(!(!r.config.action.sentence||u.current)){if(c.logger.info("Initializing the sentence",r,u.current),!r.config.useTypeEffect){r.dispatchComplete();return}f([]),u.current=m(),a(),u.current.onComplete(()=>{r.dispatchComplete()})}},[r]),ul(()=>r.events.depends([r.events.on(vt.Events.requestComplete,()=>{c.logger.debug("Sentence.tsx","requestComplete"),u.current?.interact()}),r.events.on(vt.Events.forceSkip,()=>{c.logger.debug("Sentence.tsx","forceSkip"),r.isEnded()||u.current?.forceSkip()})]).cancel,[r,l]),ul(()=>{s.preference.onPreferenceChange(de.Preferences.gameSpeed,()=>{u.current?.update()}),s.preference.onPreferenceChange(de.Preferences.autoForward,()=>{u.current?.update()})},[]);function m(){let v=new b,S=new ne(v).setGuard(c.guard),C=new Set,x=new Set,w=new Set,_=dd(r.config.evaluatedWords),A=null,P=[],V=[],J=()=>{P.forEach(H=>H()),P.length=0},I=()=>{if(V.length!==0)return{done:!1,value:V.shift()};let{done:H,value:j}=_.next();return{done:H,value:j}},W=H=>{let j=Ie=>{H(Ie),x.delete(j)};return x.add(j),{cancel:()=>{x.delete(j)}}},se=H=>{f(j=>{let Ie=j[j.length-1];return Ie&&Ie!==`
63
+ `:yield{text:s,config:r.config,tag:n,tag2:i,cps:r.config.cps}}}}function hd({defaultColor:o,className:t,style:n,dialog:r,...i}){let s=N(),c=s.getLiveGame().getGameState(),u=Av(null),[p,f]=Cv(()=>r&&!r.config.useTypeEffect?d(r.config.evaluatedWords):[]),[a,l]=Ye();if(!r)throw new Error("Dialog state is required");ul(()=>{if(!(!r.config.action.sentence||u.current)){if(c.logger.info("Initializing the sentence",r,u.current),!r.config.useTypeEffect){r.dispatchComplete();return}f([]),u.current=m(),a(),u.current.onComplete(()=>{r.dispatchComplete()})}},[r]),ul(()=>r.events.depends([r.events.on(vt.Events.requestComplete,()=>{u.current?.interact()}),r.events.on(vt.Events.forceSkip,()=>{r.isEnded()||u.current?.forceSkip()})]).cancel,[r,l]),ul(()=>s.preference.events.depends([s.preference.onPreferenceChange(de.Preferences.gameSpeed,()=>{u.current?.update()}),s.preference.onPreferenceChange(de.Preferences.autoForward,()=>{u.current?.update()})]).cancel,[]);function m(){let v=new b,S=new ne(v).setGuard(c.guard),C=new Set,x=new Set,w=new Set,_=dd(r.config.evaluatedWords),A=null,P=[],V=[],J=()=>{P.forEach(H=>H()),P.length=0},I=()=>{if(V.length!==0)return{done:!1,value:V.shift()};let{done:H,value:j}=_.next();return{done:H,value:j}},W=H=>{let j=Ie=>{H(Ie),x.delete(j)};return x.add(j),{cancel:()=>{x.delete(j)}}},se=H=>{f(j=>{let Ie=j[j.length-1];return Ie&&Ie!==`
64
64
  `&&H!==`
65
- `&&Ie.tag===H.tag?[...j.slice(0,-1),{...H,text:Ie.text+H.text,config:H.config}]:[...j,H]})},oe=(H=!1)=>{c.logger.debug("Sentence.tsx","skipToEnd");let j=!1;for(;!j;){let{done:Ie,value:Le}=I();if(Ie){j=!0;break}if(Ke.isPause(Le)){if(H)continue;j=!0,V.push(Le);break}else Le===`
65
+ `&&Ie.tag===H.tag?[...j.slice(0,-1),{...H,text:Ie.text+H.text,config:H.config}]:[...j,H]})},oe=(H=!1)=>{let j=!1;for(;!j;){let{done:Ie,value:Le}=I();if(Ie){j=!0;break}if(Ke.isPause(Le)){if(H)continue;j=!0,V.push(Le);break}else Le===`
66
66
  `?f(Oe=>[...Oe,Le]):typeof Le=="object"&&"text"in Le&&!C.has(Le)&&(C.add(Le),se(Le))}A&&!A.isSettled()?A.abort():(w.forEach(Ie=>Ie()),v.resolve())};return c.schedule(async H=>{let j=!1,Ie=!1;for(;!j;){let{done:Le,value:Oe}=I();if(Le){j=Ie=!0;break}let St=new b;if(c.timelines.attachTimeline(St),St.registerSkipController(new K(()=>{J(),j=!0,H.retry()})),St.onSettled(()=>{J()}),A=St,Ke.isPause(Oe)){let Lt=Ke.from(Oe),en=s.preference.getPreference(de.Preferences.gameSpeed);if(Lt.config.duration){let mt=Lt.config.duration/en;await Jr(mt)}else{let mt=s.preference.getPreference(de.Preferences.autoForward),tn=b.race([b.create(Id=>{let Ld=W(_d=>{_d(),Id.resolve()});P.push(()=>Ld.cancel())}),...mt?[b.delay(s.config.autoForwardDefaultPause/en)]:[]]);c.timelines.attachTimeline(tn),await b.wait(tn)}}else{if(Oe!==`
67
67
  `&&C.has(Oe))continue;C.add(Oe),se(Oe);let Lt=s.preference.getPreference(de.Preferences.gameSpeed),mt=1e3/((typeof Oe=="object"&&"cps"in Oe&&Oe.cps!==void 0?Oe.cps:s.config.cps)*Lt);await Jr(mt)}}Ie&&(w.forEach(Le=>Le()),v.resolve())},0),{getToken:()=>v,interact:()=>{let H=!1;x.forEach(j=>j(()=>H=!0)),!H&&oe()},update:()=>{A&&A.abort()},forceSkip:()=>{oe(!0)},timeline:S,onComplete:H=>(w.add(H),{cancel:()=>{w.delete(H)}})}}function d(v){let S=dd(v),C=[];for(let x of S)Ke.isPause(x)||C.push(x);return C}let h=r.config.action.sentence;if(!h)return null;let g={fontWeight:h.config.bold?s.config.fontWeightBold:s.config.fontWeight,fontSize:h.config.fontSize??s.config.fontSize,color:Pn(h.config.color??s.config.defaultTextColor),fontFamily:h.config.fontFamily??s.config.fontFamily,fontStyle:h.config.italic?"italic":void 0},y=v=>({fontWeight:v.config.bold||h.config.bold?s.config.fontWeightBold:s.config.fontWeight,fontSize:v.config.fontSize??h.config.fontSize??s.config.fontSize,color:Pn(v.config.color??h.config.color??o??s.config.defaultTextColor),fontFamily:v.config.fontFamily??h.config.fontFamily??s.config.fontFamily,fontStyle:v.config.italic??h.config.italic?"italic":void 0}),T=(v,S)=>v===`
68
68
  `?Wn.createElement("br",{key:S}):Wn.createElement(Bn.Span,{tag:`say.word.${S}`,key:S,style:{...y(v),...Qr(s.config.app.debug,{outline:"1px dashed red"})},className:q("inline-block break-all",v.config.className)},v.config.ruby?Wn.createElement("ruby",{className:"align-bottom inline-block"},Wn.createElement("rt",{className:"block text-center"},v.config.ruby),v.text):v.text);return Wn.createElement("div",{...i,className:q("whitespace-pre-wrap",t),style:{...n,...g}},p.map(T))}function gd(o){return Wn.createElement(hd,{...o,key:o.dialog?.config.action.id})}function pl(o){let t=Jt();return Wn.createElement(hd,{...o,dialog:t,key:t.config.action.id})}var wv=pl;function ua({className:o,style:t,bindKey:n}){let r=kv(null),{register:i,unregister:s,getIndex:c}=pd(),[u,p]=Dv(-1),{choose:f,evaluated:a,gameState:l}=ud(),m=u===-1?null:a[u];Ev(()=>{if(!r.current)return;let h=r;i(h);let g=c(h);return p(g),r.current.dataset.index=g.toString(),()=>s(h)},[i,s,c]),Pv(()=>{if(!n)return;let h=g=>{g.key.toLowerCase()===n.toLowerCase()&&!g.ctrlKey&&!g.metaKey&&(g.preventDefault(),g.stopPropagation(),d())};return window.addEventListener("keydown",h,!0),()=>{window.removeEventListener("keydown",h,!0)}},[n]);function d(){if(u===-1||!a[u])return;let h=a[u];f({...h,evaluated:Z.getText(h.words||[])})}return la.createElement(la.Fragment,null,la.createElement("button",{className:q(o),style:t,onClick:d,ref:r},m&&la.createElement(gd,{dialog:new vt({useTypeEffect:!1,action:{sentence:m.prompt,words:m.words,character:null},gameState:l,evaluatedWords:m.words})})))}function fl({prompt:o,choices:t,afterChoose:n,state:r,words:i}){let s=N(),c=Iv([]),u=ml(d=>(c.current.push(d),c.current.indexOf(d)),[]),p=ml(d=>{let h=c.current.indexOf(d);h!==-1&&c.current.splice(h,1)},[]),f=ml(d=>c.current.indexOf(d),[]),a=s.config.menu,l=Rv(()=>t.map(d=>({...d,words:d.prompt.evaluate(ut.getCtx({gameState:r}))})),[]);function m(d){n(d)}return It.createElement(It.Fragment,null,It.createElement(al,{value:{evaluated:l,choose:m,gameState:r}},It.createElement(cl,{value:{register:u,unregister:p,getIndex:f}},It.createElement(Dt,{className:"absolute"},o&&It.createElement(Br,{gameState:r,action:{sentence:o,words:i,character:null},useTypeEffect:!1})),It.createElement(Bn.Div,{color:"green",border:"dashed",className:q("absolute"),style:{width:`${s.config.width}px`,height:`${s.config.height}px`}},It.createElement(a,{items:l.map((d,h)=>h)})))))}function yd({items:o}){return It.createElement(aa,{className:"absolute flex flex-col items-center justify-center min-w-full w-full h-full"},o.map(t=>It.createElement(ua,{key:t,className:"bg-white text-black p-2 mt-2 w-1/2"})))}import Wr,{useEffect as Lv}from"react";import pa from"react";function ma({children:o,...t}){let n=cr;return pa.createElement(pa.Fragment,null,pa.createElement("div",{...t},pa.createElement(n,null,o)))}function dl({gameState:o}){let[t]=Ye(),n=o.notificationMgr;Lv(()=>n.onFlush(()=>{t()}).cancel,[]);let r=o.game.config.notification;return Wr.createElement("div",{className:"absolute top-0 left-0 w-full h-full pointer-events-none","data-element-type":"notification"},Wr.createElement(r,{notifications:n.toArray()}))}function Td({notifications:o}){return Wr.createElement(ma,{className:"absolute top-0 left-0 w-full h-full"},o.map(({id:t,message:n})=>Wr.createElement("div",{key:t,className:"absolute top-0 left-0 w-[100px] h-[80px]"},Wr.createElement("span",{className:"text-white text-2xl font-bold"},n))))}function gl({state:o,className:t,elements:n}){let{scene:r,layers:i,texts:s,menus:c}=n,u=_v(!1);return hl(()=>r.events.depends([r.events.on(yt.EventTypes["event:scene.preUnmount"],()=>{if(r.state.backgroundMusic)return o.audioManager.stop(r.state.backgroundMusic).then(()=>{r.state.backgroundMusic=null})})]).cancel,[]),hl(()=>(r.events.emit(yt.EventTypes["event:scene.mount"]),o.logger.debug("Scene","Scene mounted",r.getId()),()=>{r.events.emit(yt.EventTypes["event:scene.unmount"]),o.logger.debug("Scene","Scene unmounted",r.getId())}),[]),wn(r,{setBackgroundMusic(p,f){return new Promise(a=>{r.state.backgroundMusic&&o.audioManager.stop(r.state.backgroundMusic,f).then(()=>{r.state.backgroundMusic=null,p&&o.audioManager.play(p,{end:p.state.volume,duration:f}).then(a)})})}}),hl(()=>{o.events.emit(ie.EventTypes["event:state.onRender"])},[]),jn.createElement("div",{className:q(t,"w-full h-full absolute")},[...i.entries()].sort(([p],[f])=>p.config.zIndex-f.config.zIndex).map(([p,f])=>jn.createElement(id,{state:o,layer:p,key:p.getId()},jn.createElement(sl,{state:o,displayable:f}))),s.map(({action:p,onClick:f})=>jn.createElement(Br,{gameState:o,key:"say-"+p.id,action:p,onFinished:a=>{a!==void 0&&(u.current=a),f(),o.stage.next(),setTimeout(()=>{u.current=!1},0)},useTypeEffect:!u.current})),c.map(({action:p,onClick:f},a)=>jn.createElement("div",{key:"menu-"+a,"data-element-type":"menu"},jn.createElement(fl,{state:o,prompt:p.prompt,choices:p.choices,afterChoose:l=>{f(l),o.stage.next()},words:p.words}))),jn.createElement(dl,{gameState:o}))}import vd,{useEffect as Mv}from"react";function Sd({state:o}){let t=N(),n=Ur();return Mv(()=>{if(!t.getLiveGame().gameState.playerCurrent){o.logger.warn("KeyEventAnnouncer","Failed to listen to playerElement events");return}let i=Dl(s=>{t.config.skipKey.includes(s.key)&&t.preference.getPreference(de.Preferences.skip)&&(!n||!n.isActive())&&(o.logger.verbose("KeyEventAnnouncer","Emitted event: state.player.skip"),o.events.emit(ie.EventTypes["event:state.player.skip"]))},t.config.skipInterval);return t.getLiveGame().onPlayerEvent("keydown",i).cancel},[n]),vd.createElement(vd.Fragment,null)}import{useEffect as Vv}from"react";function yl({ref:o}){let{ratio:t}=be();return Vv(()=>{let n=o.current;if(!n)return;let r=new ResizeObserver(()=>{t.requestUpdate()});return r.observe(n),()=>{r.disconnect()}},[o.current]),null}import Nv from"react";import{useEffect as Tl,useRef as Gv}from"react";import{useCallback as xd}from"react";function bd(o){let t=xd(()=>{if(!o.current)return;let r=o.current;r.style.opacity="1",r.style.pointerEvents="auto",r.style.visibility="visible"},[o]),n=xd(()=>{if(!o.current)return;let r=o.current;r.style.opacity="0",r.style.pointerEvents="none",r.style.visibility="hidden"},[o]);return{show:t,hide:n}}function vl({gameState:o,video:t}){let n=Gv(null),{show:r,hide:i}=bd(n);Tl(()=>o.events.depends([o.events.on(ie.EventTypes["event:state.player.skip"],()=>{o.game.config.allowSkipVideo&&(s(),o.logger.log("NarraLeaf-React: Video","Skipped"))})]).cancel,[]),Tl(()=>{i(),t.state.display&&r()},[]),Tl(()=>{if(!n.current)return;let c=n.current,u=!1,p=()=>new M(`Failed to add event listener, ref is not available
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "narraleaf-react",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "A React visual novel player framework",
5
5
  "main": "./dist/main.js",
6
6
  "types": "./dist/index.d.ts",