script-engine-lib 1.0.2 → 1.0.3

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.
package/dist/index.js CHANGED
@@ -14,8 +14,8 @@
14
14
  with (vars) {
15
15
  return String(\`${e}\`);
16
16
  }
17
- `)(this.šau);}catch(i){return this.šak(i),""}return Reflect.defineMetadata(d,false,this.functions),t}duplicate(){let e=helpersLib.JsonHelper.deepCopy(this.variables),t=helpersLib.JsonHelper.deepCopy(this.functions);return new l(t,e,this.globalNameSpace)}šas(e,t){v.forEach(i=>{if(Object.hasOwn(t,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a variable.`);if(Object.hasOwn(e,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a function.`)}),Object.getOwnPropertyNames(e).forEach(i=>{if(Object.hasOwn(t,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a variable.`)});}šak(e){throw e instanceof Error?(e.message=e.message.replace(/^.*Error: /,""),e):new Error(`${e}`.replace(/^.*Error: /,""))}};var E="actionsBeforeTesting";function j(){return function(l,e,t){let i=t.value;p.setAsJSEngineFunction(i),t.value=function(...n){if(Reflect.getOwnMetadata(E,this))return i.apply(this,n);throw new Error(`"${String(e)}(...)" can only be called at "actions before testing".`)},helpersLib.MetaDataHelper.carryMetaDataOfFunction(i,t.value);}}var h=class extends Error{constructor(e,t){super(e),this.location=t;}},S=class extends Error{constructor(e,t){super(e),this.actionIndex=t;}},x=class extends Error{constructor(e,t,i){super(e),this.actionIndex=t,this.location=i;}};var b=class{},D=(r=>(r[r.Idle=1]="Idle",r[r.Running=2]="Running",r[r.WaitingForPlayerChoice=3]="WaitingForPlayerChoice",r[r.WaitingForManualChoice=4]="WaitingForManualChoice",r[r.WaitingForDialog=5]="WaitingForDialog",r))(D||{}),B=class{constructor(e,t,i,n){this.šaq=new helpersLib.Stack;this.šaw=false;this.šaa=false;this.šac=new actionsLib.Action;this.onManualBranching=this.šac.notifier;this.šad=new actionsLib.Action;this.šat(t),this.šaa=!!n?.manualTestingMode,this.šap=e,this.šx=new p(t,i);}get variables(){return this.šx.variables}get state(){return this.šaw?5:this.šz?4:this.šaf?3:this.šan?2:1}get šan(){return !this.šaq.isEmpty}run(e){if(this.state!==1)throw new Error("ScriptEngine: Existing script haven't been concluded yet.");this.šy(e);let t=this.šad.toSingleEvent().destroyIfNotAttached();return this.šaj(),t}continue(){let e=this.state;if(e!==5){if(this.šaq.isEmpty)throw new Error("ScriptEngine: There is no active script to iterate.");if(e!==2)throw new Error(`ScriptEngine: The engine is not in running state. Next action cannot be executed. State: ${D[this.state]}`)}this.šaw=false,this.šaj();}playerChoice(e){if(!this.šaf)throw new Error("ScriptEngine: No player branching choices available.");let t=this.šaf[e];if(!t)throw new Error("ScriptEngine: Invalid player choice.");this.šv(t),this.šaf=void 0,this.šaj();}manualBranchingChoice(e){if(!this.šz)throw new Error("ScriptEngine: No manual branching choices available.");let t=this.šz[e];if(!t)throw new Error("ScriptEngine: Invalid manual choice.");this.šv(t),this.šz=void 0,this.šaj();}šaj(){for(;this.state===2;)this.šab();this.state===1&&this.šad.trigger();}šab(){let e=this.šaq.pop();this.ši(e);}šy(e){let t=this.šap[e];if(!t)throw new Error(`ScriptEngine: Script definition not found: ${e}`);this.šv(t.actions);}ši(e){switch(e.type){case "command":this.šx.execute(e.value);break;case "dialog":{let t=e.value;this.šaw=true,this.šx.functions.onDialog(this.šx.string(t.text),t.speaker);break}case "jumpTo":{this.šy(e.value),this.šan&&this.šab();break}case "branchByCondition":{let i=e.value.find(n=>n.condition?this.šx.boolean(n.condition):true);i&&this.šv(i.actions),this.šan&&this.šab();break}case "branchByChance":{let t=e.value.filter(i=>i.condition?this.šx.boolean(i.condition):true);if(t.length===0)throw new Error("ScriptEngine: No branch is fulfilled the condition in branchByChance action.");if(this.šaa)this.šz=t.map(i=>i.actions),this.šac.trigger(t.map((i,n)=>i.label??`Anonymous ${n}`));else {let i=helpersLib.Random.pickRandomElementWithWeight(t.map(n=>({value:n.actions,weight:helpersLib.Comparator.isString(n.weight)?this.šx.number(n.weight):n.weight})));this.šv(i),this.šan&&this.šab();}break}case "branchByPlayerChoice":{let t=e.value.filter(i=>i.condition?this.šx.boolean(i.condition):true);if(t.length===0)throw new Error("ScriptEngine: No branch is fulfilled the condition in branchByPlayerChoice action.");this.šaf=t.map(i=>i.actions),this.šx.functions.onPlayerChoice(t.map(i=>this.šx.string(i.text)));break}default:throw new Error(`ScriptEngine: Unknown action type: ${e.type}`)}}šv(e){this.šaq.add(...e);}šat(e){if(p.isJSEngineFunction(e.onPlayerChoice))throw new Error("ScriptEngine: onPlayerChoice function shall not be decorated as a JSEngineFunction.")}};var y=class{static isValid(e,t){try{return this.validate(e,t),!0}catch{return false}}static validate(e,t){let i=[],n=0;for(;n<e.length;){let r=e.indexOf("<",n);if(r===-1)break;let a=e[r+1]==="/",o=r+(a?2:1),s=e.indexOf(">",r);if(s===-1)throw new Error(`Malformed tag at position ${r}: missing closing bracket '>'`);let c=e.substring(o,s);if(c.trim()==="")throw new Error(`Empty tag name found at position ${r}`);if(/\s/.test(c))throw new Error(`Invalid tag name '${c}' at position ${r}: contains whitespace`);if(t&&!a&&!t.has(c))throw new Error(`Unknown tag '${c}' at position ${r}. Only these tags are allowed: ${[...t].join(", ")}`);if(a){if(i.length===0)throw new Error(`Closing tag '${c}' at position ${r} has no matching opening tag`);let u=i.pop();if(u!==c)throw new Error(`Mismatched tags: expected closing tag for '${u}', but found '${c}' at position ${r}`)}else i.push(c);n=s+1;}if(i.length>0)throw new Error(`Unclosed tag${i.length>1?"s":""}: ${i.join(", ")}`)}};var C=class{static process(e,t){y.validate(e,t);let i=this.šai(e,[]);return this.šf(i)}static šf(e){if(e.length<=1)return e;let t=[],i=e[0];for(let n=1;n<e.length;n++){let r=e[n];i.tags.length===r.tags.length&&i.tags.every((o,s)=>o===r.tags[s])?i={text:i.text+r.text,tags:i.tags}:(t.push(i),i=r);}return t.push(i),t}static šai(e,t){let i=[],n=0;if(e==="")return [{text:"",tags:[]}];for(;n<e.length;){let r=e.indexOf("<",n);if(r===-1){if(n<e.length){let g=e.substring(n);g.length>0&&i.push({text:g,tags:[...t]});}break}if(r>n){let g=e.substring(n,r);g.length>0&&i.push({text:g,tags:[...t]});}let a=e.indexOf(">",r),o=e.substring(r+1,a),s=this.šs(e,o,a+1),c=e.substring(a+1,s);if(c.length===0){n=s+o.length+3;continue}let u=[...t,o],f=this.šai(c,u);i.push(...f),n=s+o.length+3;}return i}static šs(e,t,i){let n=i,r=1;for(;n<e.length&&r>0;){let a=e.indexOf("<"+t,n),o=e.indexOf("</"+t+">",n);if(a!==-1&&a<o)r++,n=a+1;else {if(r--,r===0)return o;n=o+1;}}return e.length}};var m=class l{constructor(){this.šh=[];}addEntry(e){return this.šh.push(e),this}toString(){return this.šh.join(`
18
- `)}duplicate(){let e=new l;return e.šh=[...this.šh],e}};var w=class{constructor(e){this.šu=new Map;this.šar=new Set;this.šc=new Map;this.ša=new Map;e.forEach(t=>{this.šu.set(t.id,t),this.šal(t,1,t.id,void 0,[]);});}getScript(e){let t=this.šu.get(e);if(!t)throw new Error(`Script with id ${e} not found.`);return t}getRootBranchLocation(e){let t=this.šc.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:[]}}getBranchLocation(e){let t=this.šc.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:t.path}}getActionLocation(e){let t=this.ša.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:t.path}}setVisited(e){this.šar.delete(e);}getUnvisitedBranchLocations(){return Array.from(this.šar).map(e=>this.šc.get(e)).filter(e=>!e.parentBranchInfo||!this.šar.has(e.parentBranchInfo.branch)).map(e=>({scriptId:e.rootScriptId,path:e.path}))}šal(e,t,i,n,r){let a={branch:e,type:t,parentBranchInfo:n,rootScriptId:i,path:r};this.šar.add(e),this.šc.set(e,a),this.še(e.actions,i,a,r);}še(e,t,i,n){e.forEach((r,a)=>{let o=[...n,"actions",`${a}`],s={action:r,rootScriptId:t,path:o};this.ša.set(r,s),r.type==="branchByCondition"?r.value.forEach((u,f)=>{let g=[...o,"branchByCondition",`${f}`];this.šal(u,2,t,i,g);}):r.type==="branchByPlayerChoice"?r.value.forEach((u,f)=>{let g=[...o,"branchByPlayerChoice",`${f}`];this.šal(u,3,t,i,g);}):r.type==="branchByChance"&&r.value.forEach((u,f)=>{let g=[...o,"branchByChance",`${f}`];this.šal(u,4,t,i,g);});});}};var T=class{},R=100,A=class{constructor(e,t={prscriptTypeChanges:true,richTextTags:void 0}){this.šap=e;this.šae=t;this.šav=new Map;this.šao=new w(this.šap),this.šae.prscriptTypeChanges&&(this.št=new Map);}simulateScript(e,t,i){this.šae.prscriptTypeChanges&&(t.globalNameSpace=this.št);let r=[{executionHistory:new m,stack:new helpersLib.Stack,jsEngine:t,depth:0,lastExecutedAction:void 0}];this.šah(i,r),this.šav.clear(),this.šr(e,r),this.šav.clear();}getUnvisitedBranchLocations(){return this.šao.getUnvisitedBranchLocations()}šah(e,t){e.forEach((i,n)=>{switch(i.type){case "command":this.šj(i,t,n);break;case "runScript":this.šb(i,t,n);break;default:throw new Error(`Unknown action before testing type: ${i.type}`)}});}šj(e,t,i){try{t.forEach(n=>{Reflect.defineMetadata(E,!0,n.jsEngine.functions),n.jsEngine.execute(e.value);});}catch(n){let r=this.šag(`${n}`,t[0].executionHistory);throw new S(r,i)}}šb(e,t,i){let n=[],r=this.šao.getScript(e.value);if(!r)throw new Error(`Target script is not found: ${e.value}`);try{this.šav.clear(),t.forEach(o=>{o.executionHistory.addEntry(`Branching out from script: ${e.value}`),o.depth=0,Reflect.defineMetadata(E,!1,o.jsEngine.functions);let s=this.šp(r,o,!1);if(!s.exitFound){let c=this.šag(`All possible paths are creating infinite loops, no exit found while executing: ${e.value}`,o.executionHistory);throw new h(c,this.šao.getRootBranchLocation(r))}s.allEndings.forEach(c=>{n.push(c);});});let a=this.šam(n);t.length=0,t.push(...a),t.forEach(o=>{if(o.executionHistory.addEntry(`${a.length} unique ending${a.length>1?"s":""} generated.`).addEntry(""),o.lastExecutedAction)try{o.jsEngine.functions.onScriptBranchingEnd();}catch(s){let c=this.šao.getActionLocation(o.lastExecutedAction),u=this.šag(`${s}`,o.executionHistory);throw new h(u,c)}else throw new Error("Script execution is ended without executing any command!")});}catch(a){throw a instanceof h?new x(`${a.message}`,i,a.location):a}}šr(e,t){t.forEach(i=>{i.executionHistory.addEntry(`Running script: ${e.id}`),i.depth=0,Reflect.defineMetadata(E,false,i.jsEngine.functions);let n=this.šp(e,i,true);if(!n.exitFound){let r=this.šag(`All possible paths are creating infinite loops, no exit found while executing: ${e.id}`,i.executionHistory);throw new h(r,this.šao.getRootBranchLocation(e))}n.allEndings.forEach(r=>{if(r.lastExecutedAction)try{r.jsEngine.functions.onEnd();}catch(a){let o=this.šao.getActionLocation(r.lastExecutedAction),s=this.šag(`${a}`,r.executionHistory);throw new h(s,o)}else throw new Error("Script execution is ended without executing any command!")});});}šp(e,t,i){if(!this.šw(e,t))return {allEndings:[],exitFound:false};let n=[],r=true;if(i&&this.šao.setVisited(e),t.depth++,t.depth>R){let a=this.šag(`Maximum depth "${R}" is reached. Try to reduce the script branching tree or check infinite loops with trivial state changes.`,t.executionHistory);throw new h(a,this.šao.getRootBranchLocation(e))}for(t.stack.add(...e.actions);!t.stack.isEmpty;){let a=t.stack.pop(),o=this.ši(a,t,i);r=o.exitFound&&r,t.stack.isEmpty&&n.push(...o.allEndings);}return n=n.length>0?this.šam(n):[],{allEndings:n,exitFound:r}}ši(e,t,i){switch(t.lastExecutedAction=e,e.type){case "command":return this.šn(e,t);case "dialog":return this.šq(e,t);case "jumpTo":return this.šo(e,t,i);case "branchByCondition":return this.šl(e,t,i);case "branchByChance":return this.šk(e,t,i);case "branchByPlayerChoice":return this.šm(e,t,i);default:throw new Error(`Unknown action type: ${e.type}`)}}šn(e,t){try{t.jsEngine.execute(e.value);}catch(i){let n=this.šao.getActionLocation(e),r=this.šag(`${i}`,t.executionHistory);throw new h(r,n)}return {allEndings:[t],exitFound:true}}šq(e,t){let i=e.value,n;try{n=t.jsEngine.string(i.text),this.šae.richTextTags&&y.validate(n,this.šae.richTextTags),t.jsEngine.functions.onDialog(n,i.speaker);}catch(r){let a=this.šao.getActionLocation(e),o=this.šag(`${r}`,t.executionHistory);throw new h(o,a)}return {allEndings:[t],exitFound:true}}šo(e,t,i){let n=this.šao.getScript(e.value);return t.executionHistory.addEntry(`Jumping to script: ${e.value}`),this.šp(n,t,i)}šl(e,t,i){let r=e.value.find(a=>this.šd(a,t));return r?(t.executionHistory.addEntry(`Branching by condition: ${r.condition?r.condition:"default"}`),this.šp(r,t,i)):{allEndings:[],exitFound:true}}šk(e,t,i){let r=e.value.map((o,s)=>({index:s,subBranch:o})).filter(o=>this.šd(o.subBranch,t));if(r.length===0){let o=this.šao.getActionLocation(e),s=this.šag("No option is fulfilled the condition during branching.",t.executionHistory);throw new h(s,o)}let a=r.map(o=>{try{let c=helpersLib.Comparator.isString(o.subBranch.weight)?t.jsEngine.number(o.subBranch.weight):o.subBranch.weight;if(!helpersLib.Comparator.isNumber(c)||c<0)throw new Error(`Weight of branch ${o.index} is not a valid number: "${o.subBranch.weight}" -> ${c}.`)}catch(c){let u=this.šao.getActionLocation(e),f=this.šag(`${c}`,t.executionHistory);throw new h(f,u)}let s=this.šg(t);return s.executionHistory.addEntry(`Branching by chance: ${o.index}`),this.šp(o.subBranch,s,i)});return {allEndings:a.flatMap(o=>o.allEndings),exitFound:a.some(o=>o.exitFound)}}šm(e,t,i){let r=e.value.filter(o=>this.šd(o,t));if(r.length===0){let o=this.šao.getActionLocation(e),s=this.šag("No option is fulfilled the condition during branching.",t.executionHistory);throw new h(s,o)}try{t.jsEngine.functions.onPlayerChoice(r.map(o=>t.jsEngine.string(o.text)));}catch(o){let s=this.šao.getActionLocation(e),c=this.šag(`${o}`,t.executionHistory);throw new h(c,s)}let a=r.map(o=>{let s=this.šg(t);return s.executionHistory.addEntry(`Player choice: ${o.text}`),this.šp(o,s,i)});return {allEndings:a.flatMap(o=>o.allEndings),exitFound:a.some(o=>o.exitFound)}}šd(e,t){if(e.condition)try{return t.jsEngine.boolean(e.condition)}catch(i){let n=this.šao.getBranchLocation(e),r=this.šag(`${i}`,t.executionHistory);throw new h(r,n)}else return true}šam(e){let t=[];return e.map(n=>({ending:n,variablesString:JSON.stringify(n.jsEngine.variables),functionsString:JSON.stringify(n.jsEngine.functions)})).forEach(n=>{t.every(a=>n.functionsString!==a.functionsString||n.variablesString!==a.variablesString)&&t.push({ending:n.ending,variablesString:n.variablesString,functionsString:n.functionsString});}),t.map(n=>n.ending)}šw(e,t){let i=JSON.stringify(t.jsEngine.variables)+JSON.stringify(t.jsEngine.functions),n=this.šav.get(e);return n||(n=new Set,this.šav.set(e,n)),n.has(i)?false:(n.add(i),true)}šg(e){return {executionHistory:e.executionHistory.duplicate(),stack:e.stack.duplicate(),jsEngine:e.jsEngine.duplicate(),depth:e.depth,lastExecutedAction:e.lastExecutedAction}}šag(e,t){return `${e}
17
+ `)(this.šau);}catch(i){return this.šak(i),""}return Reflect.defineMetadata(d,false,this.functions),t}duplicate(){let e=helpersLib.JsonHelper.deepCopy(this.variables),t=helpersLib.JsonHelper.deepCopy(this.functions);return new l(t,e,this.globalNameSpace)}šas(e,t){v.forEach(i=>{if(Object.hasOwn(t,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a variable.`);if(Object.hasOwn(e,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a function.`)}),Object.getOwnPropertyNames(e).forEach(i=>{if(Object.hasOwn(t,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a variable.`)});}šak(e){throw e instanceof Error?(e.message=e.message.replace(/^.*Error: /,""),e):new Error(`${e}`.replace(/^.*Error: /,""))}};var E="actionsBeforeTesting";function L(){return function(l,e,t){let i=t.value;p.setAsJSEngineFunction(i),t.value=function(...n){if(Reflect.getOwnMetadata(E,this))return i.apply(this,n);throw new Error(`"${String(e)}(...)" can only be called at "actions before testing".`)},helpersLib.MetaDataHelper.carryMetaDataOfFunction(i,t.value);}}var h=class extends Error{constructor(e,t){super(e),this.location=t;}},S=class extends Error{constructor(e,t){super(e),this.actionIndex=t;}},x=class extends Error{constructor(e,t,i){super(e),this.actionIndex=t,this.location=i;}};var b=class{},D=(r=>(r[r.Idle=1]="Idle",r[r.Running=2]="Running",r[r.WaitingForPlayerChoice=3]="WaitingForPlayerChoice",r[r.WaitingForManualChoice=4]="WaitingForManualChoice",r[r.WaitingForDialog=5]="WaitingForDialog",r))(D||{}),B=class{constructor(e,t,i,n){this.šaq=new helpersLib.Stack;this.šaw=false;this.šaa=false;this.šac=new actionsLib.Action;this.onManualBranching=this.šac.notifier;this.šad=new actionsLib.Action;this.šat(t),this.šaa=!!n?.manualTestingMode,this.šap=e,this.šx=new p(t,i);}get variables(){return this.šx.variables}get state(){return this.šaw?5:this.šz?4:this.šaf?3:this.šan?2:1}get šan(){return !this.šaq.isEmpty}run(e){if(this.state!==1)throw new Error("ScriptEngine: Existing script haven't been concluded yet.");this.šy(e);let t=this.šad.toSingleEvent().destroyIfNotAttached();return this.šaj(),t}continue(){let e=this.state;if(e!==5){if(this.šaq.isEmpty)throw new Error("ScriptEngine: There is no active script to iterate.");if(e!==2)throw new Error(`ScriptEngine: The engine is not in running state. Next action cannot be executed. State: ${D[this.state]}`)}this.šaw=false,this.šaj();}playerChoice(e){if(!this.šaf)throw new Error("ScriptEngine: No player branching choices available.");let t=this.šaf[e];if(!t)throw new Error("ScriptEngine: Invalid player choice.");this.šv(t),this.šaf=void 0,this.šaj();}manualBranchingChoice(e){if(!this.šz)throw new Error("ScriptEngine: No manual branching choices available.");let t=this.šz[e];if(!t)throw new Error("ScriptEngine: Invalid manual choice.");this.šv(t),this.šz=void 0,this.šaj();}šaj(){for(;this.state===2;)this.šab();this.state===1&&this.šad.trigger();}šab(){let e=this.šaq.pop();this.ši(e);}šy(e){let t=this.šap[e];if(!t)throw new Error(`ScriptEngine: Script definition not found: ${e}`);this.šv(t.actions);}ši(e){switch(e.type){case "command":this.šx.execute(e.value);break;case "dialog":{let t=e.value;this.šaw=true,this.šx.functions.onDialog(this.šx.string(t.text),t.speaker);break}case "jumpTo":{this.šy(e.value),this.šan&&this.šab();break}case "branchByCondition":{let i=e.value.find(n=>n.condition?this.šx.boolean(n.condition):true);i&&this.šv(i.actions),this.šan&&this.šab();break}case "branchByChance":{let t=e.value.filter(i=>i.condition?this.šx.boolean(i.condition):true);if(t.length===0)throw new Error("ScriptEngine: No branch is fulfilled the condition in branchByChance action.");if(this.šaa)this.šz=t.map(i=>i.actions),this.šac.trigger(t.map((i,n)=>i.label??`Anonymous ${n}`));else {let i=helpersLib.Random.pickRandomElementWithWeight(t.map(n=>({value:n.actions,weight:helpersLib.Comparator.isString(n.weight)?this.šx.number(n.weight):n.weight})));this.šv(i),this.šan&&this.šab();}break}case "branchByPlayerChoice":{let t=e.value.filter(i=>i.condition?this.šx.boolean(i.condition):true);if(t.length===0)throw new Error("ScriptEngine: No branch is fulfilled the condition in branchByPlayerChoice action.");this.šaf=t.map(i=>i.actions),this.šx.functions.onPlayerChoice(t.map(i=>this.šx.string(i.text)));break}default:throw new Error(`ScriptEngine: Unknown action type: ${e.type}`)}}šv(e){this.šaq.add(...e);}šat(e){if(p.isJSEngineFunction(e.onPlayerChoice))throw new Error("ScriptEngine: onPlayerChoice function shall not be decorated as a JSEngineFunction.")}};var y=class{static isValid(e,t){try{return this.validate(e,t),!0}catch{return false}}static validate(e,t){let i=[],n=0;for(;n<e.length;){let r=e.indexOf("<",n);if(r===-1)break;let a=e[r+1]==="/",o=r+(a?2:1),s=e.indexOf(">",r);if(s===-1)throw new Error(`Malformed tag at position ${r}: missing closing bracket '>'`);let c=e.substring(o,s);if(c.trim()==="")throw new Error(`Empty tag name found at position ${r}`);if(/\s/.test(c))throw new Error(`Invalid tag name '${c}' at position ${r}: contains whitespace`);if(t&&!a&&!t.has(c))throw new Error(`Unknown tag '${c}' at position ${r}. Only these tags are allowed: ${[...t].join(", ")}`);if(a){if(i.length===0)throw new Error(`Closing tag '${c}' at position ${r} has no matching opening tag`);let u=i.pop();if(u!==c)throw new Error(`Mismatched tags: expected closing tag for '${u}', but found '${c}' at position ${r}`)}else i.push(c);n=s+1;}if(i.length>0)throw new Error(`Unclosed tag${i.length>1?"s":""}: ${i.join(", ")}`)}};var C=class{static process(e,t){y.validate(e,t);let i=this.šai(e,[]);return this.šf(i)}static šf(e){if(e.length<=1)return e;let t=[],i=e[0];for(let n=1;n<e.length;n++){let r=e[n];i.tags.length===r.tags.length&&i.tags.every((o,s)=>o===r.tags[s])?i={text:i.text+r.text,tags:i.tags}:(t.push(i),i=r);}return t.push(i),t}static šai(e,t){let i=[],n=0;if(e==="")return [{text:"",tags:[]}];for(;n<e.length;){let r=e.indexOf("<",n);if(r===-1){if(n<e.length){let g=e.substring(n);g.length>0&&i.push({text:g,tags:[...t]});}break}if(r>n){let g=e.substring(n,r);g.length>0&&i.push({text:g,tags:[...t]});}let a=e.indexOf(">",r),o=e.substring(r+1,a),s=this.šs(e,o,a+1),c=e.substring(a+1,s);if(c.length===0){n=s+o.length+3;continue}let u=[...t,o],f=this.šai(c,u);i.push(...f),n=s+o.length+3;}return i}static šs(e,t,i){let n=i,r=1;for(;n<e.length&&r>0;){let a=e.indexOf("<"+t,n),o=e.indexOf("</"+t+">",n);if(a!==-1&&a<o)r++,n=a+1;else {if(r--,r===0)return o;n=o+1;}}return e.length}};var m=class l{constructor(){this.šh=[];}addEntry(e){return this.šh.push(e),this}toString(){return this.šh.join(`
18
+ `)}duplicate(){let e=new l;return e.šh=[...this.šh],e}};var w=class{constructor(e){this.šu=new Map;this.šar=new Set;this.šc=new Map;this.ša=new Map;e.forEach(t=>{this.šu.set(t.id,t),this.šal(t,1,t.id,void 0,[]);});}getScript(e){let t=this.šu.get(e);if(!t)throw new Error(`Script with id ${e} not found.`);return t}getRootBranchLocation(e){let t=this.šc.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:[]}}getBranchLocation(e){let t=this.šc.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:t.path}}getActionLocation(e){let t=this.ša.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:t.path}}setVisited(e){this.šar.delete(e);}getUnvisitedBranchLocations(){return Array.from(this.šar).map(e=>this.šc.get(e)).filter(e=>!e.parentBranchInfo||!this.šar.has(e.parentBranchInfo.branch)).map(e=>({scriptId:e.rootScriptId,path:e.path}))}šal(e,t,i,n,r){let a={branch:e,type:t,parentBranchInfo:n,rootScriptId:i,path:r};this.šar.add(e),this.šc.set(e,a),this.še(e.actions,i,a,r);}še(e,t,i,n){e.forEach((r,a)=>{let o=[...n,"actions",`${a}`],s={action:r,rootScriptId:t,path:o};this.ša.set(r,s),r.type==="branchByCondition"?r.value.forEach((u,f)=>{let g=[...o,"branchByCondition",`${f}`];this.šal(u,2,t,i,g);}):r.type==="branchByPlayerChoice"?r.value.forEach((u,f)=>{let g=[...o,"branchByPlayerChoice",`${f}`];this.šal(u,3,t,i,g);}):r.type==="branchByChance"&&r.value.forEach((u,f)=>{let g=[...o,"branchByChance",`${f}`];this.šal(u,4,t,i,g);});});}};var T=class{},R=100,A=class{constructor(e,t={prscriptTypeChanges:true,richTextTags:void 0}){this.šap=e;this.šae=t;this.šav=new Map;this.šao=new w(this.šap),this.šae.prscriptTypeChanges&&(this.št=new Map);}simulateScript(e,t,i){this.šae.prscriptTypeChanges&&(t.globalNameSpace=this.št);let r=[{executionHistory:new m,stack:new helpersLib.Stack,jsEngine:t,depth:0,lastExecutedAction:void 0}];this.šah(i,r),this.šav.clear(),this.šr(e,r),this.šav.clear();}getUnvisitedBranchLocations(){return this.šao.getUnvisitedBranchLocations()}šah(e,t){e.forEach((i,n)=>{switch(i.type){case "command":this.šj(i,t,n);break;case "runScript":this.šb(i,t,n);break;default:throw new Error(`Unknown action before testing type: ${i.type}`)}});}šj(e,t,i){try{t.forEach(n=>{Reflect.defineMetadata(E,!0,n.jsEngine.functions),n.jsEngine.execute(e.value);});}catch(n){let r=this.šag(`${n}`,t[0].executionHistory);throw new S(r,i)}}šb(e,t,i){let n=[],r=this.šao.getScript(e.value);if(!r)throw new Error(`Target script is not found: ${e.value}`);try{this.šav.clear(),t.forEach(o=>{o.executionHistory.addEntry(`Branching out from script: ${e.value}`),o.depth=0,Reflect.defineMetadata(E,!1,o.jsEngine.functions);let s=this.šp(r,o,!1);if(!s.exitFound){let c=this.šag(`All possible paths are creating infinite loops, no exit found while executing: ${e.value}`,o.executionHistory);throw new h(c,this.šao.getRootBranchLocation(r))}s.allEndings.forEach(c=>{n.push(c);});});let a=this.šam(n);t.length=0,t.push(...a),t.forEach(o=>{if(o.executionHistory.addEntry(`${a.length} unique ending${a.length>1?"s":""} generated.`).addEntry(""),o.lastExecutedAction)try{o.jsEngine.functions.onScriptBranchingEnd();}catch(s){let c=this.šao.getActionLocation(o.lastExecutedAction),u=this.šag(`${s}`,o.executionHistory);throw new h(u,c)}else throw new Error("Script execution is ended without executing any command!")});}catch(a){throw a instanceof h?new x(`${a.message}`,i,a.location):a}}šr(e,t){t.forEach(i=>{i.executionHistory.addEntry(`Running script: ${e.id}`),i.depth=0,Reflect.defineMetadata(E,false,i.jsEngine.functions);let n=this.šp(e,i,true);if(!n.exitFound){let r=this.šag(`All possible paths are creating infinite loops, no exit found while executing: ${e.id}`,i.executionHistory);throw new h(r,this.šao.getRootBranchLocation(e))}n.allEndings.forEach(r=>{try{r.jsEngine.functions.onEnd();}catch(a){let o=r.lastExecutedAction?this.šao.getActionLocation(r.lastExecutedAction):this.šao.getRootBranchLocation(e),s=this.šag(`${a}`,r.executionHistory);throw new h(s,o)}});});}šp(e,t,i){if(!this.šw(e,t))return {allEndings:[],exitFound:false};let n=[],r=true;if(i&&this.šao.setVisited(e),t.depth++,t.depth>R){let a=this.šag(`Maximum depth "${R}" is reached. Try to reduce the script branching tree or check infinite loops with trivial state changes.`,t.executionHistory);throw new h(a,this.šao.getRootBranchLocation(e))}for(t.stack.add(...e.actions);!t.stack.isEmpty;){let a=t.stack.pop(),o=this.ši(a,t,i);r=o.exitFound&&r,t.stack.isEmpty&&n.push(...o.allEndings);}return n.length>0?n=this.šam(n):r&&n.push(t),{allEndings:n,exitFound:r}}ši(e,t,i){switch(t.lastExecutedAction=e,e.type){case "command":return this.šn(e,t);case "dialog":return this.šq(e,t);case "jumpTo":return this.šo(e,t,i);case "branchByCondition":return this.šl(e,t,i);case "branchByChance":return this.šk(e,t,i);case "branchByPlayerChoice":return this.šm(e,t,i);default:throw new Error(`Unknown action type: ${e.type}`)}}šn(e,t){try{t.jsEngine.execute(e.value);}catch(i){let n=this.šao.getActionLocation(e),r=this.šag(`${i}`,t.executionHistory);throw new h(r,n)}return {allEndings:[t],exitFound:true}}šq(e,t){let i=e.value,n;try{n=t.jsEngine.string(i.text),this.šae.richTextTags&&y.validate(n,this.šae.richTextTags),t.jsEngine.functions.onDialog(n,i.speaker);}catch(r){let a=this.šao.getActionLocation(e),o=this.šag(`${r}`,t.executionHistory);throw new h(o,a)}return {allEndings:[t],exitFound:true}}šo(e,t,i){let n=this.šao.getScript(e.value);return t.executionHistory.addEntry(`Jumping to script: ${e.value}`),this.šp(n,t,i)}šl(e,t,i){let r=e.value.find(a=>this.šd(a,t));return r?(t.executionHistory.addEntry(`Branching by condition: ${r.condition?r.condition:"default"}`),this.šp(r,t,i)):{allEndings:[],exitFound:true}}šk(e,t,i){let r=e.value.map((o,s)=>({index:s,subBranch:o})).filter(o=>this.šd(o.subBranch,t));if(r.length===0){let o=this.šao.getActionLocation(e),s=this.šag("No option is fulfilled the condition during branching.",t.executionHistory);throw new h(s,o)}let a=r.map(o=>{try{let c=helpersLib.Comparator.isString(o.subBranch.weight)?t.jsEngine.number(o.subBranch.weight):o.subBranch.weight;if(!helpersLib.Comparator.isNumber(c)||c<0)throw new Error(`Weight of branch ${o.index} is not a valid number: "${o.subBranch.weight}" -> ${c}.`)}catch(c){let u=this.šao.getActionLocation(e),f=this.šag(`${c}`,t.executionHistory);throw new h(f,u)}let s=this.šg(t);return s.executionHistory.addEntry(`Branching by chance: ${o.index}`),this.šp(o.subBranch,s,i)});return {allEndings:a.flatMap(o=>o.allEndings),exitFound:a.some(o=>o.exitFound)}}šm(e,t,i){let r=e.value.filter(o=>this.šd(o,t));if(r.length===0){let o=this.šao.getActionLocation(e),s=this.šag("No option is fulfilled the condition during branching.",t.executionHistory);throw new h(s,o)}try{t.jsEngine.functions.onPlayerChoice(r.map(o=>t.jsEngine.string(o.text)));}catch(o){let s=this.šao.getActionLocation(e),c=this.šag(`${o}`,t.executionHistory);throw new h(c,s)}let a=r.map(o=>{let s=this.šg(t);return s.executionHistory.addEntry(`Player choice: ${o.text}`),this.šp(o,s,i)});return {allEndings:a.flatMap(o=>o.allEndings),exitFound:a.some(o=>o.exitFound)}}šd(e,t){if(e.condition)try{return t.jsEngine.boolean(e.condition)}catch(i){let n=this.šao.getBranchLocation(e),r=this.šag(`${i}`,t.executionHistory);throw new h(r,n)}else return true}šam(e){let t=[];return e.map(n=>({ending:n,variablesString:JSON.stringify(n.jsEngine.variables),functionsString:JSON.stringify(n.jsEngine.functions)})).forEach(n=>{t.every(a=>n.functionsString!==a.functionsString||n.variablesString!==a.variablesString)&&t.push({ending:n.ending,variablesString:n.variablesString,functionsString:n.functionsString});}),t.map(n=>n.ending)}šw(e,t){let i=JSON.stringify(t.jsEngine.variables)+JSON.stringify(t.jsEngine.functions),n=this.šav.get(e);return n||(n=new Set,this.šav.set(e,n)),n.has(i)?false:(n.add(i),true)}šg(e){return {executionHistory:e.executionHistory.duplicate(),stack:e.stack.duplicate(),jsEngine:e.jsEngine.duplicate(),depth:e.depth,lastExecutedAction:e.lastExecutedAction}}šag(e,t){return `${e}
19
19
 
20
20
  ----Execution history----
21
- ${t.toString()}`}};exports.ActionBeforeTesting=j;exports.ActionsBeforeTestingError=S;exports.BranchingBeforeTestingError=x;exports.JSEngine=p;exports.JSEngineFunction=O;exports.RichTextSeparator=C;exports.RichTextValidator=y;exports.ScriptEngine=B;exports.ScriptEngineFunctions=b;exports.ScriptEngineSimulatorFunctions=T;exports.ScriptEngineState=D;exports.ScriptTestSimulator=A;exports.SimulationError=h;
21
+ ${t.toString()}`}};exports.ActionBeforeTesting=L;exports.ActionsBeforeTestingError=S;exports.BranchingBeforeTestingError=x;exports.JSEngine=p;exports.JSEngineFunction=O;exports.RichTextSeparator=C;exports.RichTextValidator=y;exports.ScriptEngine=B;exports.ScriptEngineFunctions=b;exports.ScriptEngineSimulatorFunctions=T;exports.ScriptEngineState=D;exports.ScriptTestSimulator=A;exports.SimulationError=h;
package/dist/index.mjs CHANGED
@@ -14,8 +14,8 @@ import {MetaDataHelper,Comparator,JsonHelper,Stack,Random}from'helpers-lib';impo
14
14
  with (vars) {
15
15
  return String(\`${e}\`);
16
16
  }
17
- `)(this.šau);}catch(i){return this.šak(i),""}return Reflect.defineMetadata(d,false,this.functions),t}duplicate(){let e=JsonHelper.deepCopy(this.variables),t=JsonHelper.deepCopy(this.functions);return new l(t,e,this.globalNameSpace)}šas(e,t){v.forEach(i=>{if(Object.hasOwn(t,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a variable.`);if(Object.hasOwn(e,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a function.`)}),Object.getOwnPropertyNames(e).forEach(i=>{if(Object.hasOwn(t,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a variable.`)});}šak(e){throw e instanceof Error?(e.message=e.message.replace(/^.*Error: /,""),e):new Error(`${e}`.replace(/^.*Error: /,""))}};var E="actionsBeforeTesting";function j(){return function(l,e,t){let i=t.value;p.setAsJSEngineFunction(i),t.value=function(...n){if(Reflect.getOwnMetadata(E,this))return i.apply(this,n);throw new Error(`"${String(e)}(...)" can only be called at "actions before testing".`)},MetaDataHelper.carryMetaDataOfFunction(i,t.value);}}var h=class extends Error{constructor(e,t){super(e),this.location=t;}},S=class extends Error{constructor(e,t){super(e),this.actionIndex=t;}},x=class extends Error{constructor(e,t,i){super(e),this.actionIndex=t,this.location=i;}};var b=class{},D=(r=>(r[r.Idle=1]="Idle",r[r.Running=2]="Running",r[r.WaitingForPlayerChoice=3]="WaitingForPlayerChoice",r[r.WaitingForManualChoice=4]="WaitingForManualChoice",r[r.WaitingForDialog=5]="WaitingForDialog",r))(D||{}),B=class{constructor(e,t,i,n){this.šaq=new Stack;this.šaw=false;this.šaa=false;this.šac=new Action;this.onManualBranching=this.šac.notifier;this.šad=new Action;this.šat(t),this.šaa=!!n?.manualTestingMode,this.šap=e,this.šx=new p(t,i);}get variables(){return this.šx.variables}get state(){return this.šaw?5:this.šz?4:this.šaf?3:this.šan?2:1}get šan(){return !this.šaq.isEmpty}run(e){if(this.state!==1)throw new Error("ScriptEngine: Existing script haven't been concluded yet.");this.šy(e);let t=this.šad.toSingleEvent().destroyIfNotAttached();return this.šaj(),t}continue(){let e=this.state;if(e!==5){if(this.šaq.isEmpty)throw new Error("ScriptEngine: There is no active script to iterate.");if(e!==2)throw new Error(`ScriptEngine: The engine is not in running state. Next action cannot be executed. State: ${D[this.state]}`)}this.šaw=false,this.šaj();}playerChoice(e){if(!this.šaf)throw new Error("ScriptEngine: No player branching choices available.");let t=this.šaf[e];if(!t)throw new Error("ScriptEngine: Invalid player choice.");this.šv(t),this.šaf=void 0,this.šaj();}manualBranchingChoice(e){if(!this.šz)throw new Error("ScriptEngine: No manual branching choices available.");let t=this.šz[e];if(!t)throw new Error("ScriptEngine: Invalid manual choice.");this.šv(t),this.šz=void 0,this.šaj();}šaj(){for(;this.state===2;)this.šab();this.state===1&&this.šad.trigger();}šab(){let e=this.šaq.pop();this.ši(e);}šy(e){let t=this.šap[e];if(!t)throw new Error(`ScriptEngine: Script definition not found: ${e}`);this.šv(t.actions);}ši(e){switch(e.type){case "command":this.šx.execute(e.value);break;case "dialog":{let t=e.value;this.šaw=true,this.šx.functions.onDialog(this.šx.string(t.text),t.speaker);break}case "jumpTo":{this.šy(e.value),this.šan&&this.šab();break}case "branchByCondition":{let i=e.value.find(n=>n.condition?this.šx.boolean(n.condition):true);i&&this.šv(i.actions),this.šan&&this.šab();break}case "branchByChance":{let t=e.value.filter(i=>i.condition?this.šx.boolean(i.condition):true);if(t.length===0)throw new Error("ScriptEngine: No branch is fulfilled the condition in branchByChance action.");if(this.šaa)this.šz=t.map(i=>i.actions),this.šac.trigger(t.map((i,n)=>i.label??`Anonymous ${n}`));else {let i=Random.pickRandomElementWithWeight(t.map(n=>({value:n.actions,weight:Comparator.isString(n.weight)?this.šx.number(n.weight):n.weight})));this.šv(i),this.šan&&this.šab();}break}case "branchByPlayerChoice":{let t=e.value.filter(i=>i.condition?this.šx.boolean(i.condition):true);if(t.length===0)throw new Error("ScriptEngine: No branch is fulfilled the condition in branchByPlayerChoice action.");this.šaf=t.map(i=>i.actions),this.šx.functions.onPlayerChoice(t.map(i=>this.šx.string(i.text)));break}default:throw new Error(`ScriptEngine: Unknown action type: ${e.type}`)}}šv(e){this.šaq.add(...e);}šat(e){if(p.isJSEngineFunction(e.onPlayerChoice))throw new Error("ScriptEngine: onPlayerChoice function shall not be decorated as a JSEngineFunction.")}};var y=class{static isValid(e,t){try{return this.validate(e,t),!0}catch{return false}}static validate(e,t){let i=[],n=0;for(;n<e.length;){let r=e.indexOf("<",n);if(r===-1)break;let a=e[r+1]==="/",o=r+(a?2:1),s=e.indexOf(">",r);if(s===-1)throw new Error(`Malformed tag at position ${r}: missing closing bracket '>'`);let c=e.substring(o,s);if(c.trim()==="")throw new Error(`Empty tag name found at position ${r}`);if(/\s/.test(c))throw new Error(`Invalid tag name '${c}' at position ${r}: contains whitespace`);if(t&&!a&&!t.has(c))throw new Error(`Unknown tag '${c}' at position ${r}. Only these tags are allowed: ${[...t].join(", ")}`);if(a){if(i.length===0)throw new Error(`Closing tag '${c}' at position ${r} has no matching opening tag`);let u=i.pop();if(u!==c)throw new Error(`Mismatched tags: expected closing tag for '${u}', but found '${c}' at position ${r}`)}else i.push(c);n=s+1;}if(i.length>0)throw new Error(`Unclosed tag${i.length>1?"s":""}: ${i.join(", ")}`)}};var C=class{static process(e,t){y.validate(e,t);let i=this.šai(e,[]);return this.šf(i)}static šf(e){if(e.length<=1)return e;let t=[],i=e[0];for(let n=1;n<e.length;n++){let r=e[n];i.tags.length===r.tags.length&&i.tags.every((o,s)=>o===r.tags[s])?i={text:i.text+r.text,tags:i.tags}:(t.push(i),i=r);}return t.push(i),t}static šai(e,t){let i=[],n=0;if(e==="")return [{text:"",tags:[]}];for(;n<e.length;){let r=e.indexOf("<",n);if(r===-1){if(n<e.length){let g=e.substring(n);g.length>0&&i.push({text:g,tags:[...t]});}break}if(r>n){let g=e.substring(n,r);g.length>0&&i.push({text:g,tags:[...t]});}let a=e.indexOf(">",r),o=e.substring(r+1,a),s=this.šs(e,o,a+1),c=e.substring(a+1,s);if(c.length===0){n=s+o.length+3;continue}let u=[...t,o],f=this.šai(c,u);i.push(...f),n=s+o.length+3;}return i}static šs(e,t,i){let n=i,r=1;for(;n<e.length&&r>0;){let a=e.indexOf("<"+t,n),o=e.indexOf("</"+t+">",n);if(a!==-1&&a<o)r++,n=a+1;else {if(r--,r===0)return o;n=o+1;}}return e.length}};var m=class l{constructor(){this.šh=[];}addEntry(e){return this.šh.push(e),this}toString(){return this.šh.join(`
18
- `)}duplicate(){let e=new l;return e.šh=[...this.šh],e}};var w=class{constructor(e){this.šu=new Map;this.šar=new Set;this.šc=new Map;this.ša=new Map;e.forEach(t=>{this.šu.set(t.id,t),this.šal(t,1,t.id,void 0,[]);});}getScript(e){let t=this.šu.get(e);if(!t)throw new Error(`Script with id ${e} not found.`);return t}getRootBranchLocation(e){let t=this.šc.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:[]}}getBranchLocation(e){let t=this.šc.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:t.path}}getActionLocation(e){let t=this.ša.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:t.path}}setVisited(e){this.šar.delete(e);}getUnvisitedBranchLocations(){return Array.from(this.šar).map(e=>this.šc.get(e)).filter(e=>!e.parentBranchInfo||!this.šar.has(e.parentBranchInfo.branch)).map(e=>({scriptId:e.rootScriptId,path:e.path}))}šal(e,t,i,n,r){let a={branch:e,type:t,parentBranchInfo:n,rootScriptId:i,path:r};this.šar.add(e),this.šc.set(e,a),this.še(e.actions,i,a,r);}še(e,t,i,n){e.forEach((r,a)=>{let o=[...n,"actions",`${a}`],s={action:r,rootScriptId:t,path:o};this.ša.set(r,s),r.type==="branchByCondition"?r.value.forEach((u,f)=>{let g=[...o,"branchByCondition",`${f}`];this.šal(u,2,t,i,g);}):r.type==="branchByPlayerChoice"?r.value.forEach((u,f)=>{let g=[...o,"branchByPlayerChoice",`${f}`];this.šal(u,3,t,i,g);}):r.type==="branchByChance"&&r.value.forEach((u,f)=>{let g=[...o,"branchByChance",`${f}`];this.šal(u,4,t,i,g);});});}};var T=class{},R=100,A=class{constructor(e,t={prscriptTypeChanges:true,richTextTags:void 0}){this.šap=e;this.šae=t;this.šav=new Map;this.šao=new w(this.šap),this.šae.prscriptTypeChanges&&(this.št=new Map);}simulateScript(e,t,i){this.šae.prscriptTypeChanges&&(t.globalNameSpace=this.št);let r=[{executionHistory:new m,stack:new Stack,jsEngine:t,depth:0,lastExecutedAction:void 0}];this.šah(i,r),this.šav.clear(),this.šr(e,r),this.šav.clear();}getUnvisitedBranchLocations(){return this.šao.getUnvisitedBranchLocations()}šah(e,t){e.forEach((i,n)=>{switch(i.type){case "command":this.šj(i,t,n);break;case "runScript":this.šb(i,t,n);break;default:throw new Error(`Unknown action before testing type: ${i.type}`)}});}šj(e,t,i){try{t.forEach(n=>{Reflect.defineMetadata(E,!0,n.jsEngine.functions),n.jsEngine.execute(e.value);});}catch(n){let r=this.šag(`${n}`,t[0].executionHistory);throw new S(r,i)}}šb(e,t,i){let n=[],r=this.šao.getScript(e.value);if(!r)throw new Error(`Target script is not found: ${e.value}`);try{this.šav.clear(),t.forEach(o=>{o.executionHistory.addEntry(`Branching out from script: ${e.value}`),o.depth=0,Reflect.defineMetadata(E,!1,o.jsEngine.functions);let s=this.šp(r,o,!1);if(!s.exitFound){let c=this.šag(`All possible paths are creating infinite loops, no exit found while executing: ${e.value}`,o.executionHistory);throw new h(c,this.šao.getRootBranchLocation(r))}s.allEndings.forEach(c=>{n.push(c);});});let a=this.šam(n);t.length=0,t.push(...a),t.forEach(o=>{if(o.executionHistory.addEntry(`${a.length} unique ending${a.length>1?"s":""} generated.`).addEntry(""),o.lastExecutedAction)try{o.jsEngine.functions.onScriptBranchingEnd();}catch(s){let c=this.šao.getActionLocation(o.lastExecutedAction),u=this.šag(`${s}`,o.executionHistory);throw new h(u,c)}else throw new Error("Script execution is ended without executing any command!")});}catch(a){throw a instanceof h?new x(`${a.message}`,i,a.location):a}}šr(e,t){t.forEach(i=>{i.executionHistory.addEntry(`Running script: ${e.id}`),i.depth=0,Reflect.defineMetadata(E,false,i.jsEngine.functions);let n=this.šp(e,i,true);if(!n.exitFound){let r=this.šag(`All possible paths are creating infinite loops, no exit found while executing: ${e.id}`,i.executionHistory);throw new h(r,this.šao.getRootBranchLocation(e))}n.allEndings.forEach(r=>{if(r.lastExecutedAction)try{r.jsEngine.functions.onEnd();}catch(a){let o=this.šao.getActionLocation(r.lastExecutedAction),s=this.šag(`${a}`,r.executionHistory);throw new h(s,o)}else throw new Error("Script execution is ended without executing any command!")});});}šp(e,t,i){if(!this.šw(e,t))return {allEndings:[],exitFound:false};let n=[],r=true;if(i&&this.šao.setVisited(e),t.depth++,t.depth>R){let a=this.šag(`Maximum depth "${R}" is reached. Try to reduce the script branching tree or check infinite loops with trivial state changes.`,t.executionHistory);throw new h(a,this.šao.getRootBranchLocation(e))}for(t.stack.add(...e.actions);!t.stack.isEmpty;){let a=t.stack.pop(),o=this.ši(a,t,i);r=o.exitFound&&r,t.stack.isEmpty&&n.push(...o.allEndings);}return n=n.length>0?this.šam(n):[],{allEndings:n,exitFound:r}}ši(e,t,i){switch(t.lastExecutedAction=e,e.type){case "command":return this.šn(e,t);case "dialog":return this.šq(e,t);case "jumpTo":return this.šo(e,t,i);case "branchByCondition":return this.šl(e,t,i);case "branchByChance":return this.šk(e,t,i);case "branchByPlayerChoice":return this.šm(e,t,i);default:throw new Error(`Unknown action type: ${e.type}`)}}šn(e,t){try{t.jsEngine.execute(e.value);}catch(i){let n=this.šao.getActionLocation(e),r=this.šag(`${i}`,t.executionHistory);throw new h(r,n)}return {allEndings:[t],exitFound:true}}šq(e,t){let i=e.value,n;try{n=t.jsEngine.string(i.text),this.šae.richTextTags&&y.validate(n,this.šae.richTextTags),t.jsEngine.functions.onDialog(n,i.speaker);}catch(r){let a=this.šao.getActionLocation(e),o=this.šag(`${r}`,t.executionHistory);throw new h(o,a)}return {allEndings:[t],exitFound:true}}šo(e,t,i){let n=this.šao.getScript(e.value);return t.executionHistory.addEntry(`Jumping to script: ${e.value}`),this.šp(n,t,i)}šl(e,t,i){let r=e.value.find(a=>this.šd(a,t));return r?(t.executionHistory.addEntry(`Branching by condition: ${r.condition?r.condition:"default"}`),this.šp(r,t,i)):{allEndings:[],exitFound:true}}šk(e,t,i){let r=e.value.map((o,s)=>({index:s,subBranch:o})).filter(o=>this.šd(o.subBranch,t));if(r.length===0){let o=this.šao.getActionLocation(e),s=this.šag("No option is fulfilled the condition during branching.",t.executionHistory);throw new h(s,o)}let a=r.map(o=>{try{let c=Comparator.isString(o.subBranch.weight)?t.jsEngine.number(o.subBranch.weight):o.subBranch.weight;if(!Comparator.isNumber(c)||c<0)throw new Error(`Weight of branch ${o.index} is not a valid number: "${o.subBranch.weight}" -> ${c}.`)}catch(c){let u=this.šao.getActionLocation(e),f=this.šag(`${c}`,t.executionHistory);throw new h(f,u)}let s=this.šg(t);return s.executionHistory.addEntry(`Branching by chance: ${o.index}`),this.šp(o.subBranch,s,i)});return {allEndings:a.flatMap(o=>o.allEndings),exitFound:a.some(o=>o.exitFound)}}šm(e,t,i){let r=e.value.filter(o=>this.šd(o,t));if(r.length===0){let o=this.šao.getActionLocation(e),s=this.šag("No option is fulfilled the condition during branching.",t.executionHistory);throw new h(s,o)}try{t.jsEngine.functions.onPlayerChoice(r.map(o=>t.jsEngine.string(o.text)));}catch(o){let s=this.šao.getActionLocation(e),c=this.šag(`${o}`,t.executionHistory);throw new h(c,s)}let a=r.map(o=>{let s=this.šg(t);return s.executionHistory.addEntry(`Player choice: ${o.text}`),this.šp(o,s,i)});return {allEndings:a.flatMap(o=>o.allEndings),exitFound:a.some(o=>o.exitFound)}}šd(e,t){if(e.condition)try{return t.jsEngine.boolean(e.condition)}catch(i){let n=this.šao.getBranchLocation(e),r=this.šag(`${i}`,t.executionHistory);throw new h(r,n)}else return true}šam(e){let t=[];return e.map(n=>({ending:n,variablesString:JSON.stringify(n.jsEngine.variables),functionsString:JSON.stringify(n.jsEngine.functions)})).forEach(n=>{t.every(a=>n.functionsString!==a.functionsString||n.variablesString!==a.variablesString)&&t.push({ending:n.ending,variablesString:n.variablesString,functionsString:n.functionsString});}),t.map(n=>n.ending)}šw(e,t){let i=JSON.stringify(t.jsEngine.variables)+JSON.stringify(t.jsEngine.functions),n=this.šav.get(e);return n||(n=new Set,this.šav.set(e,n)),n.has(i)?false:(n.add(i),true)}šg(e){return {executionHistory:e.executionHistory.duplicate(),stack:e.stack.duplicate(),jsEngine:e.jsEngine.duplicate(),depth:e.depth,lastExecutedAction:e.lastExecutedAction}}šag(e,t){return `${e}
17
+ `)(this.šau);}catch(i){return this.šak(i),""}return Reflect.defineMetadata(d,false,this.functions),t}duplicate(){let e=JsonHelper.deepCopy(this.variables),t=JsonHelper.deepCopy(this.functions);return new l(t,e,this.globalNameSpace)}šas(e,t){v.forEach(i=>{if(Object.hasOwn(t,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a variable.`);if(Object.hasOwn(e,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a function.`)}),Object.getOwnPropertyNames(e).forEach(i=>{if(Object.hasOwn(t,i))throw new Error(`JSEngine: Reserved word "${i}" cannot be used as a variable.`)});}šak(e){throw e instanceof Error?(e.message=e.message.replace(/^.*Error: /,""),e):new Error(`${e}`.replace(/^.*Error: /,""))}};var E="actionsBeforeTesting";function L(){return function(l,e,t){let i=t.value;p.setAsJSEngineFunction(i),t.value=function(...n){if(Reflect.getOwnMetadata(E,this))return i.apply(this,n);throw new Error(`"${String(e)}(...)" can only be called at "actions before testing".`)},MetaDataHelper.carryMetaDataOfFunction(i,t.value);}}var h=class extends Error{constructor(e,t){super(e),this.location=t;}},S=class extends Error{constructor(e,t){super(e),this.actionIndex=t;}},x=class extends Error{constructor(e,t,i){super(e),this.actionIndex=t,this.location=i;}};var b=class{},D=(r=>(r[r.Idle=1]="Idle",r[r.Running=2]="Running",r[r.WaitingForPlayerChoice=3]="WaitingForPlayerChoice",r[r.WaitingForManualChoice=4]="WaitingForManualChoice",r[r.WaitingForDialog=5]="WaitingForDialog",r))(D||{}),B=class{constructor(e,t,i,n){this.šaq=new Stack;this.šaw=false;this.šaa=false;this.šac=new Action;this.onManualBranching=this.šac.notifier;this.šad=new Action;this.šat(t),this.šaa=!!n?.manualTestingMode,this.šap=e,this.šx=new p(t,i);}get variables(){return this.šx.variables}get state(){return this.šaw?5:this.šz?4:this.šaf?3:this.šan?2:1}get šan(){return !this.šaq.isEmpty}run(e){if(this.state!==1)throw new Error("ScriptEngine: Existing script haven't been concluded yet.");this.šy(e);let t=this.šad.toSingleEvent().destroyIfNotAttached();return this.šaj(),t}continue(){let e=this.state;if(e!==5){if(this.šaq.isEmpty)throw new Error("ScriptEngine: There is no active script to iterate.");if(e!==2)throw new Error(`ScriptEngine: The engine is not in running state. Next action cannot be executed. State: ${D[this.state]}`)}this.šaw=false,this.šaj();}playerChoice(e){if(!this.šaf)throw new Error("ScriptEngine: No player branching choices available.");let t=this.šaf[e];if(!t)throw new Error("ScriptEngine: Invalid player choice.");this.šv(t),this.šaf=void 0,this.šaj();}manualBranchingChoice(e){if(!this.šz)throw new Error("ScriptEngine: No manual branching choices available.");let t=this.šz[e];if(!t)throw new Error("ScriptEngine: Invalid manual choice.");this.šv(t),this.šz=void 0,this.šaj();}šaj(){for(;this.state===2;)this.šab();this.state===1&&this.šad.trigger();}šab(){let e=this.šaq.pop();this.ši(e);}šy(e){let t=this.šap[e];if(!t)throw new Error(`ScriptEngine: Script definition not found: ${e}`);this.šv(t.actions);}ši(e){switch(e.type){case "command":this.šx.execute(e.value);break;case "dialog":{let t=e.value;this.šaw=true,this.šx.functions.onDialog(this.šx.string(t.text),t.speaker);break}case "jumpTo":{this.šy(e.value),this.šan&&this.šab();break}case "branchByCondition":{let i=e.value.find(n=>n.condition?this.šx.boolean(n.condition):true);i&&this.šv(i.actions),this.šan&&this.šab();break}case "branchByChance":{let t=e.value.filter(i=>i.condition?this.šx.boolean(i.condition):true);if(t.length===0)throw new Error("ScriptEngine: No branch is fulfilled the condition in branchByChance action.");if(this.šaa)this.šz=t.map(i=>i.actions),this.šac.trigger(t.map((i,n)=>i.label??`Anonymous ${n}`));else {let i=Random.pickRandomElementWithWeight(t.map(n=>({value:n.actions,weight:Comparator.isString(n.weight)?this.šx.number(n.weight):n.weight})));this.šv(i),this.šan&&this.šab();}break}case "branchByPlayerChoice":{let t=e.value.filter(i=>i.condition?this.šx.boolean(i.condition):true);if(t.length===0)throw new Error("ScriptEngine: No branch is fulfilled the condition in branchByPlayerChoice action.");this.šaf=t.map(i=>i.actions),this.šx.functions.onPlayerChoice(t.map(i=>this.šx.string(i.text)));break}default:throw new Error(`ScriptEngine: Unknown action type: ${e.type}`)}}šv(e){this.šaq.add(...e);}šat(e){if(p.isJSEngineFunction(e.onPlayerChoice))throw new Error("ScriptEngine: onPlayerChoice function shall not be decorated as a JSEngineFunction.")}};var y=class{static isValid(e,t){try{return this.validate(e,t),!0}catch{return false}}static validate(e,t){let i=[],n=0;for(;n<e.length;){let r=e.indexOf("<",n);if(r===-1)break;let a=e[r+1]==="/",o=r+(a?2:1),s=e.indexOf(">",r);if(s===-1)throw new Error(`Malformed tag at position ${r}: missing closing bracket '>'`);let c=e.substring(o,s);if(c.trim()==="")throw new Error(`Empty tag name found at position ${r}`);if(/\s/.test(c))throw new Error(`Invalid tag name '${c}' at position ${r}: contains whitespace`);if(t&&!a&&!t.has(c))throw new Error(`Unknown tag '${c}' at position ${r}. Only these tags are allowed: ${[...t].join(", ")}`);if(a){if(i.length===0)throw new Error(`Closing tag '${c}' at position ${r} has no matching opening tag`);let u=i.pop();if(u!==c)throw new Error(`Mismatched tags: expected closing tag for '${u}', but found '${c}' at position ${r}`)}else i.push(c);n=s+1;}if(i.length>0)throw new Error(`Unclosed tag${i.length>1?"s":""}: ${i.join(", ")}`)}};var C=class{static process(e,t){y.validate(e,t);let i=this.šai(e,[]);return this.šf(i)}static šf(e){if(e.length<=1)return e;let t=[],i=e[0];for(let n=1;n<e.length;n++){let r=e[n];i.tags.length===r.tags.length&&i.tags.every((o,s)=>o===r.tags[s])?i={text:i.text+r.text,tags:i.tags}:(t.push(i),i=r);}return t.push(i),t}static šai(e,t){let i=[],n=0;if(e==="")return [{text:"",tags:[]}];for(;n<e.length;){let r=e.indexOf("<",n);if(r===-1){if(n<e.length){let g=e.substring(n);g.length>0&&i.push({text:g,tags:[...t]});}break}if(r>n){let g=e.substring(n,r);g.length>0&&i.push({text:g,tags:[...t]});}let a=e.indexOf(">",r),o=e.substring(r+1,a),s=this.šs(e,o,a+1),c=e.substring(a+1,s);if(c.length===0){n=s+o.length+3;continue}let u=[...t,o],f=this.šai(c,u);i.push(...f),n=s+o.length+3;}return i}static šs(e,t,i){let n=i,r=1;for(;n<e.length&&r>0;){let a=e.indexOf("<"+t,n),o=e.indexOf("</"+t+">",n);if(a!==-1&&a<o)r++,n=a+1;else {if(r--,r===0)return o;n=o+1;}}return e.length}};var m=class l{constructor(){this.šh=[];}addEntry(e){return this.šh.push(e),this}toString(){return this.šh.join(`
18
+ `)}duplicate(){let e=new l;return e.šh=[...this.šh],e}};var w=class{constructor(e){this.šu=new Map;this.šar=new Set;this.šc=new Map;this.ša=new Map;e.forEach(t=>{this.šu.set(t.id,t),this.šal(t,1,t.id,void 0,[]);});}getScript(e){let t=this.šu.get(e);if(!t)throw new Error(`Script with id ${e} not found.`);return t}getRootBranchLocation(e){let t=this.šc.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:[]}}getBranchLocation(e){let t=this.šc.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:t.path}}getActionLocation(e){let t=this.ša.get(e);if(!t)throw new Error("Branch not found.");return {scriptId:t.rootScriptId,path:t.path}}setVisited(e){this.šar.delete(e);}getUnvisitedBranchLocations(){return Array.from(this.šar).map(e=>this.šc.get(e)).filter(e=>!e.parentBranchInfo||!this.šar.has(e.parentBranchInfo.branch)).map(e=>({scriptId:e.rootScriptId,path:e.path}))}šal(e,t,i,n,r){let a={branch:e,type:t,parentBranchInfo:n,rootScriptId:i,path:r};this.šar.add(e),this.šc.set(e,a),this.še(e.actions,i,a,r);}še(e,t,i,n){e.forEach((r,a)=>{let o=[...n,"actions",`${a}`],s={action:r,rootScriptId:t,path:o};this.ša.set(r,s),r.type==="branchByCondition"?r.value.forEach((u,f)=>{let g=[...o,"branchByCondition",`${f}`];this.šal(u,2,t,i,g);}):r.type==="branchByPlayerChoice"?r.value.forEach((u,f)=>{let g=[...o,"branchByPlayerChoice",`${f}`];this.šal(u,3,t,i,g);}):r.type==="branchByChance"&&r.value.forEach((u,f)=>{let g=[...o,"branchByChance",`${f}`];this.šal(u,4,t,i,g);});});}};var T=class{},R=100,A=class{constructor(e,t={prscriptTypeChanges:true,richTextTags:void 0}){this.šap=e;this.šae=t;this.šav=new Map;this.šao=new w(this.šap),this.šae.prscriptTypeChanges&&(this.št=new Map);}simulateScript(e,t,i){this.šae.prscriptTypeChanges&&(t.globalNameSpace=this.št);let r=[{executionHistory:new m,stack:new Stack,jsEngine:t,depth:0,lastExecutedAction:void 0}];this.šah(i,r),this.šav.clear(),this.šr(e,r),this.šav.clear();}getUnvisitedBranchLocations(){return this.šao.getUnvisitedBranchLocations()}šah(e,t){e.forEach((i,n)=>{switch(i.type){case "command":this.šj(i,t,n);break;case "runScript":this.šb(i,t,n);break;default:throw new Error(`Unknown action before testing type: ${i.type}`)}});}šj(e,t,i){try{t.forEach(n=>{Reflect.defineMetadata(E,!0,n.jsEngine.functions),n.jsEngine.execute(e.value);});}catch(n){let r=this.šag(`${n}`,t[0].executionHistory);throw new S(r,i)}}šb(e,t,i){let n=[],r=this.šao.getScript(e.value);if(!r)throw new Error(`Target script is not found: ${e.value}`);try{this.šav.clear(),t.forEach(o=>{o.executionHistory.addEntry(`Branching out from script: ${e.value}`),o.depth=0,Reflect.defineMetadata(E,!1,o.jsEngine.functions);let s=this.šp(r,o,!1);if(!s.exitFound){let c=this.šag(`All possible paths are creating infinite loops, no exit found while executing: ${e.value}`,o.executionHistory);throw new h(c,this.šao.getRootBranchLocation(r))}s.allEndings.forEach(c=>{n.push(c);});});let a=this.šam(n);t.length=0,t.push(...a),t.forEach(o=>{if(o.executionHistory.addEntry(`${a.length} unique ending${a.length>1?"s":""} generated.`).addEntry(""),o.lastExecutedAction)try{o.jsEngine.functions.onScriptBranchingEnd();}catch(s){let c=this.šao.getActionLocation(o.lastExecutedAction),u=this.šag(`${s}`,o.executionHistory);throw new h(u,c)}else throw new Error("Script execution is ended without executing any command!")});}catch(a){throw a instanceof h?new x(`${a.message}`,i,a.location):a}}šr(e,t){t.forEach(i=>{i.executionHistory.addEntry(`Running script: ${e.id}`),i.depth=0,Reflect.defineMetadata(E,false,i.jsEngine.functions);let n=this.šp(e,i,true);if(!n.exitFound){let r=this.šag(`All possible paths are creating infinite loops, no exit found while executing: ${e.id}`,i.executionHistory);throw new h(r,this.šao.getRootBranchLocation(e))}n.allEndings.forEach(r=>{try{r.jsEngine.functions.onEnd();}catch(a){let o=r.lastExecutedAction?this.šao.getActionLocation(r.lastExecutedAction):this.šao.getRootBranchLocation(e),s=this.šag(`${a}`,r.executionHistory);throw new h(s,o)}});});}šp(e,t,i){if(!this.šw(e,t))return {allEndings:[],exitFound:false};let n=[],r=true;if(i&&this.šao.setVisited(e),t.depth++,t.depth>R){let a=this.šag(`Maximum depth "${R}" is reached. Try to reduce the script branching tree or check infinite loops with trivial state changes.`,t.executionHistory);throw new h(a,this.šao.getRootBranchLocation(e))}for(t.stack.add(...e.actions);!t.stack.isEmpty;){let a=t.stack.pop(),o=this.ši(a,t,i);r=o.exitFound&&r,t.stack.isEmpty&&n.push(...o.allEndings);}return n.length>0?n=this.šam(n):r&&n.push(t),{allEndings:n,exitFound:r}}ši(e,t,i){switch(t.lastExecutedAction=e,e.type){case "command":return this.šn(e,t);case "dialog":return this.šq(e,t);case "jumpTo":return this.šo(e,t,i);case "branchByCondition":return this.šl(e,t,i);case "branchByChance":return this.šk(e,t,i);case "branchByPlayerChoice":return this.šm(e,t,i);default:throw new Error(`Unknown action type: ${e.type}`)}}šn(e,t){try{t.jsEngine.execute(e.value);}catch(i){let n=this.šao.getActionLocation(e),r=this.šag(`${i}`,t.executionHistory);throw new h(r,n)}return {allEndings:[t],exitFound:true}}šq(e,t){let i=e.value,n;try{n=t.jsEngine.string(i.text),this.šae.richTextTags&&y.validate(n,this.šae.richTextTags),t.jsEngine.functions.onDialog(n,i.speaker);}catch(r){let a=this.šao.getActionLocation(e),o=this.šag(`${r}`,t.executionHistory);throw new h(o,a)}return {allEndings:[t],exitFound:true}}šo(e,t,i){let n=this.šao.getScript(e.value);return t.executionHistory.addEntry(`Jumping to script: ${e.value}`),this.šp(n,t,i)}šl(e,t,i){let r=e.value.find(a=>this.šd(a,t));return r?(t.executionHistory.addEntry(`Branching by condition: ${r.condition?r.condition:"default"}`),this.šp(r,t,i)):{allEndings:[],exitFound:true}}šk(e,t,i){let r=e.value.map((o,s)=>({index:s,subBranch:o})).filter(o=>this.šd(o.subBranch,t));if(r.length===0){let o=this.šao.getActionLocation(e),s=this.šag("No option is fulfilled the condition during branching.",t.executionHistory);throw new h(s,o)}let a=r.map(o=>{try{let c=Comparator.isString(o.subBranch.weight)?t.jsEngine.number(o.subBranch.weight):o.subBranch.weight;if(!Comparator.isNumber(c)||c<0)throw new Error(`Weight of branch ${o.index} is not a valid number: "${o.subBranch.weight}" -> ${c}.`)}catch(c){let u=this.šao.getActionLocation(e),f=this.šag(`${c}`,t.executionHistory);throw new h(f,u)}let s=this.šg(t);return s.executionHistory.addEntry(`Branching by chance: ${o.index}`),this.šp(o.subBranch,s,i)});return {allEndings:a.flatMap(o=>o.allEndings),exitFound:a.some(o=>o.exitFound)}}šm(e,t,i){let r=e.value.filter(o=>this.šd(o,t));if(r.length===0){let o=this.šao.getActionLocation(e),s=this.šag("No option is fulfilled the condition during branching.",t.executionHistory);throw new h(s,o)}try{t.jsEngine.functions.onPlayerChoice(r.map(o=>t.jsEngine.string(o.text)));}catch(o){let s=this.šao.getActionLocation(e),c=this.šag(`${o}`,t.executionHistory);throw new h(c,s)}let a=r.map(o=>{let s=this.šg(t);return s.executionHistory.addEntry(`Player choice: ${o.text}`),this.šp(o,s,i)});return {allEndings:a.flatMap(o=>o.allEndings),exitFound:a.some(o=>o.exitFound)}}šd(e,t){if(e.condition)try{return t.jsEngine.boolean(e.condition)}catch(i){let n=this.šao.getBranchLocation(e),r=this.šag(`${i}`,t.executionHistory);throw new h(r,n)}else return true}šam(e){let t=[];return e.map(n=>({ending:n,variablesString:JSON.stringify(n.jsEngine.variables),functionsString:JSON.stringify(n.jsEngine.functions)})).forEach(n=>{t.every(a=>n.functionsString!==a.functionsString||n.variablesString!==a.variablesString)&&t.push({ending:n.ending,variablesString:n.variablesString,functionsString:n.functionsString});}),t.map(n=>n.ending)}šw(e,t){let i=JSON.stringify(t.jsEngine.variables)+JSON.stringify(t.jsEngine.functions),n=this.šav.get(e);return n||(n=new Set,this.šav.set(e,n)),n.has(i)?false:(n.add(i),true)}šg(e){return {executionHistory:e.executionHistory.duplicate(),stack:e.stack.duplicate(),jsEngine:e.jsEngine.duplicate(),depth:e.depth,lastExecutedAction:e.lastExecutedAction}}šag(e,t){return `${e}
19
19
 
20
20
  ----Execution history----
21
- ${t.toString()}`}};export{j as ActionBeforeTesting,S as ActionsBeforeTestingError,x as BranchingBeforeTestingError,p as JSEngine,O as JSEngineFunction,C as RichTextSeparator,y as RichTextValidator,B as ScriptEngine,b as ScriptEngineFunctions,T as ScriptEngineSimulatorFunctions,D as ScriptEngineState,A as ScriptTestSimulator,h as SimulationError};
21
+ ${t.toString()}`}};export{L as ActionBeforeTesting,S as ActionsBeforeTestingError,x as BranchingBeforeTestingError,p as JSEngine,O as JSEngineFunction,C as RichTextSeparator,y as RichTextValidator,B as ScriptEngine,b as ScriptEngineFunctions,T as ScriptEngineSimulatorFunctions,D as ScriptEngineState,A as ScriptTestSimulator,h as SimulationError};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "script-engine-lib",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Script Engine",
5
5
  "main": "dist/index.js",
6
6
  "publishConfig": {