diff --git a/dist/assets/index-9fEuiyFj.js b/dist/assets/index-9fEuiyFj.js new file mode 100644 index 0000000..5d67c22 --- /dev/null +++ b/dist/assets/index-9fEuiyFj.js @@ -0,0 +1,35 @@ +var Bt=Object.defineProperty;var Gt=(f,t,e)=>t in f?Bt(f,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):f[t]=e;var y=(f,t,e)=>Gt(f,typeof t!="symbol"?t+"":t,e);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))n(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const g of i.addedNodes)g.tagName==="LINK"&&g.rel==="modulepreload"&&n(g)}).observe(document,{childList:!0,subtree:!0});function e(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(s){if(s.ep)return;s.ep=!0;const i=e(s);fetch(s.href,i)}})();var x=(f=>(f.L="L",f.R="R",f.U="U",f.D="D",f))(x||{});class dt{constructor(t,e){this.key=t,this.value=e}getKey(){return this.key}getValue(){return this.value}static from(t,e){return new dt(t,e)}toString(){return"["+this.getKey()+", "+this.getValue()+"]"}}const mt=class mt{static makeMove(t,e){const s=t.indexOf(-1),i=this.getXY(s);let g=i.getKey(),l=i.getValue();e===x.L&&(g-=1),e===x.R&&(g+=1),e===x.U&&(l-=1),e===x.D&&(l+=1);const p=this.getIndex(g,l);if(p>15)throw console.log(t),console.log(e),mt.logBoardState(t),new Error("i1 > 15");const A=[...t],k=A[p];return A[s]=k,A[p]=-1,A}static getXY(t){const e=t%4,n=Math.floor(t/4);return dt.from(e,n)}static getIndex(t,e){return e*4+t}static _getValidMoves(t){const e=this.getXY(t);let n=Object.values(x).slice();return e.getKey()===0&&(n=n.filter(s=>s!==x.L)),e.getKey()===3&&(n=n.filter(s=>s!==x.R)),e.getValue()===0&&(n=n.filter(s=>s!==x.U)),e.getValue()===3&&(n=n.filter(s=>s!==x.D)),n}static getValidMoves(t,e){let n=this._getValidMoves(t);const s=this.getXY(t);return this.contains(e,s.getKey()-1,s.getValue())&&(n=n.filter(i=>i!=x.L)),this.contains(e,s.getKey()+1,s.getValue())&&(n=n.filter(i=>i!=x.R)),this.contains(e,s.getKey(),s.getValue()-1)&&(n=n.filter(i=>i!=x.U)),this.contains(e,s.getKey(),s.getValue()+1)&&(n=n.filter(i=>i!=x.D)),n}static contains(t,e,n){const s=this.getIndex(e,n);return t.includes(s)}static getStateAsString(t){let e=t.getBoardState(),n=t.getGoals();return this.zenGardenOn?this.getStateAsZenStoneGarden(e,n):this.__getStateAsString(e,n)}static logBoardState(t){const e=Array.from({length:16},(n,s)=>{let i;return i=t[s].toString(),i+=" ",s!==0&&(s+1)%4===0&&(i+=` +`),i}).join("");console.log(e)}static __getStateAsString(t,e){return Array.from({length:16},(n,s)=>{let i;const g=t[s];return g===-1?i=B.blue("*"):e.includes(g)?i=B.red(g.toString()):e.includes(s+1)?i=B.green(g.toString()):i=g.toString(),i+=" ",s!==0&&(s+1)%4===0&&(i+=` +`),i}).join("")}static getStateAsZenStoneGarden(t,e){return Array.from({length:16},(n,s)=>{let i;const g=t[s];return e.includes(g)?i="o":e.includes(s+1)?i="O":i="",i+=" ",s!==0&&(s+1)%4===0&&(i+=` +`),i}).join("")}static prntState(t){let e=this.getStateAsString(t);B.prnt(e)}static prntStateV0(t){let e=this.getStateAsString(t);B.prntAtSomeElement("shadowTester",e)}static getReverseAction(t){return t===x.D?x.U:t===x.U?x.D:t===x.L?x.R:t===x.R?x.L:null}static getAction(t,e,n){const s=e.getHashCodeV2();if(t.has(s)){let i=t.get(s);if(i===void 0)throw new Error("qTable.has(hash) == true, but get(..) returned row == undefined");return i.getActionWithMaxValue(n)}else return this.getFirstPossibleAction(e,n)}static getRandomAction(t){return t.length===0&&B.prntErrorMsg("Check lessons configuration, for logic errors: The getPossibleActions function returned no action."),t.length>0?t[Math.floor(Math.random()*t.length)]:x.D}static getFirstPossibleAction(t,e){const n=this.getPossibleActions(t);if(n.length===1)return B.prntErrorMsg("Check lessons configuration, for logic errors: The getPossibleActions function returned only one action: "+n[0]),n[0];const s=n.filter(i=>i!==e);return s.length===0?(B.prntErrorMsg("Check lessons configuration, for logic errors: The getPossibleActions function returned no action."),x.D):s[0]}static getPossibleActions(t){const e=t.getBoardState().indexOf(-1),n=t.getFixedElements().map(s=>s-1);return mt.getValidMoves(e,n)}};y(mt,"zenGardenOn",!1);let T=mt;class B{static blue(t){return''+t+""}static green(t){return''+t+""}static red(t){return''+t+""}static clearScreen(){const t=document.getElementById("console");t&&(t.innerHTML="")}static prntTestStep(t){this.addElementToConsoleDiv("testGameStep",t)}static prntAtSomeElement(t,e){this.addElementToConsoleDiv(t,e)}static prntStatsInfo(t){const e=document.getElementById("statsInfo");e&&(e.setAttribute("class","console-text"),e.textContent=` +`+t.toLowerCase().replace(", "," | "))}static prntErrorMsg(t){if(T.zenGardenOn)return;const e=document.getElementById("statsInfo");e&&(e.setAttribute("class","console-error-msg"),e.textContent=` +`+t)}static addElementToConsoleDiv(t,e){const n=document.getElementById(t);n?n.innerHTML=e:this.prnt(e,"color:black;",t)}static prnt(t,e="color:black;",n=null){const s=document.getElementById("console");if(s){const i=document.createElement("div");i.innerHTML=t,e&&(i.style.cssText=e),n!==null&&(i.id=n),s.appendChild(i),s.scrollTop=s.scrollHeight}}static warn(t){this.prnt(t,"color: orange;")}}const kt=class kt{static prnt(t,e="color: black;"){B.prnt(t,e)}static str(t,e){const n=t.toString();if(n.length>=e)return n;const s=e-n.length;return n+kt.emptyString.substring(0,s)}static sum(t){return!t||(t=t.filter(e=>e!==0),t.length===0)?0:t.reduce((e,n)=>e+n,0)}static toString(t){return`[${Array.from(t).map(String).join(", ")}]`}static px(){return(t,e)=>t}static equalArrays(t,e){if(t.length!==e.length)return!1;for(let n=0;nMath.random()-.5)}static _sleep(t){return new Promise(e=>setTimeout(e,t))}static async sleep(t){await this._sleep(t)}};y(kt,"emptyString"," ");let z=kt;class zt{constructor(t){y(this,"state");y(this,"qValues");this.state=t,this.qValues=new Map}setValue(t,e){const n=T.getPossibleActions(this.state);this.qValues.size===0&&n.forEach(s=>this.qValues.set(s,0)),n.includes(t)&&this.qValues.set(t,e)}getState(){return this.state}getValue(t){return this.qValues.get(t)||0}getActionWithMaxValue(t){const e=t===null?null:this.getAction(t);if(e==null){let n=T.getPossibleActions(this.state);if(n=n.filter(s=>s!==t),n.length===0)throw console.log("reverseAction",t),T.logBoardState(this.state.boardState),B.prntErrorMsg("possibleActions.length === 0, there allways must be some action to go around.. need to debug."),new Error("possibleActions.length === 0, there allways must be some action to go around.. need to debug.");return n[0]}else return e}getAction(t){const n=Array.from(this.qValues.entries()).filter(([s])=>s!==t).reduce((s,i)=>i[1]>s[1]?i:s,[t,-1/0]);return n[1]>-1/0?n[0]:void 0}getMaxValue(){return this.qValues.size===0?0:Math.max(...Array.from(this.qValues.values()))}}class $t{static updateQTable(t,e,n,s,i,g,l,p){let A;if(g)A=i;else{const k=this.getQValue(t,e,n),P=this.getMaxQValue(t,s);A=this.calcQValue(i,k,P,p,l)}this.addStateWithZeroValuesToQTableIfStateNotExist(t,e),this.updateQTableEntry(t,e.getHashCodeV2(),n,A)}static updateQTableEntry(t,e,n,s){var i;(i=t.get(e))==null||i.setValue(n,s)}static getMaxQValue(t,e){var s;const n=e.getHashCodeV2();return this.addStateWithZeroValuesToQTableIfStateNotExist(t,e),((s=t.get(n))==null?void 0:s.getMaxValue())??0}static getQValue(t,e,n){var i;const s=e.getHashCodeV2();return this.addStateWithZeroValuesToQTableIfStateNotExist(t,e),((i=t.get(s))==null?void 0:i.getValue(n))??0}static addStateWithZeroValuesToQTableIfStateNotExist(t,e){t.has(e.getHashCodeV2())||this.addStateWithZeroValuesToQTable(t,e)}static addStateWithZeroValuesToQTable(t,e){const n=e.getHashCodeV2(),s=new zt(e);t.set(n,s)}static calcQValue(t,e,n,s,i){return e+i*(t+s*n-e)}}class j{constructor(t,e){y(this,"boardState");y(this,"goals");y(this,"fixedElements");"boardState"in t&&"goals"in t&&"fixedElements"in t?(this.boardState=[...t.boardState],this.goals=[...t.goals],this.fixedElements=[...t.fixedElements]):t instanceof j?(this.boardState=[...t.getBoardState()],this.goals=[...t.getGoals()],this.fixedElements=[...t.getFixedElements()]):(this.boardState=[...t],this.goals=[...(e==null?void 0:e.getGoals())??[]],this.fixedElements=[...(e==null?void 0:e.getLockedStateElements())??[]])}static getTestCase(){let t={boardState:[1,2,3,4,5,6,7,8,9,10,11,-1,14,15,12,13],goals:[12],fixedElements:[1,2,3,4,5,6,7,8,9,10,11,13,14,15]};return new j(t)}getBoardState(){return this.boardState}setBoardState(t){this.boardState=t}getGoals(){return this.goals}setGoals(t){this.goals=t}getFixedElements(){return this.fixedElements}setFixedElements(t){this.fixedElements=t}getHashCodeV2(){const t=this.getHashCodeV3__();return this.hashString(t)}getHashCodeV3__(){return Array.from({length:16},(t,e)=>{let n;const s=this.boardState[e];return s===-1?n="*":this.goals.includes(s)?n=String(s):this.goals.includes(e+1)?n="o":n=" ",n=n+" ",e!==0&&(e+1)%4===0&&(n=n+` +`),n}).join("")}getHashCode(){const t=this.boardState.map(String).join(",");return this.hashString(t)}hashString(t){let e=0;for(let n=0;n8&&this.circleAction.shift(),(z.equalArrays(this.circleAction,this.bigCircleAction1)||z.equalArrays(this.circleAction,this.bigCircleAction2)||z.equalArrays(this.circleAction,this.smallCircleAction1)||z.equalArrays(this.circleAction,this.smallCircleAction2))&&(i=!0);const l=this.state.getBoardState().indexOf(-1);return G.lessonProducer.isLockedIndex(l)&&(i=!0,g=-1),isNaN(g)&&(g=this.getReward(n,this.goals)),new Ht(s,e,g,i)}static _isTerminalSuccess(t,e){return e.filter(s=>t[s-1]===s).length===e.length}prntInfo(){z.prnt(` + +------------------------------------------------------------------ +`);const t=this.state.getBoardState(),e=t.indexOf(-1),n=T.getXY(e);z.prnt(n.getKey()+" - "+n.getValue());const s=T.getIndex(n.getKey(),n.getValue());z.prnt(`${e} - ${s}`);const i=T._getValidMoves(e);z.prnt(i);const g=this.getReward(t,this.goals);z.prnt("reward: "+g),z.prnt(` +`),T.prntState(this.state)}getReward(t,e){const n=t.indexOf(-1),s=T.getXY(n),g=e.map(p=>this.getDistance(T.getXY(t.indexOf(p)),T.getXY(p-1))).reduce((p,A)=>p+A,0);if(g===0)return 100.5;const l=e.reduce((p,A)=>p+this.getDistance(T.getXY(t.indexOf(A)),s),0);return 1/(g+l)}getDistance(t,e){const n=Math.pow(e.getKey()-t.getKey(),2),s=Math.pow(e.getValue()-t.getValue(),2);return Math.sqrt(n+s)}};y(G,"lessonProducer");let ht=G;class bt{static shuffle(t,e,n){const s=e.map(i=>i-1);for(let i=0;il+1).filter(g=>!t.includes(g)),n=[...e].sort(()=>Math.random()-.5),s=e.map((g,l)=>dt.from(g,n[l]));return Array.from({length:16},(g,l)=>this.zip(s,l)).map(g=>g.getValue()===16?-1:g.getValue())}static zip(t,e){const n=t.find(s=>s.getKey()===e+1);return n===void 0?dt.from(e,e+1):dt.from(e,n.getValue())}}class ft{static async getFile(t){let e="";try{const n=await fetch(t);if(!n.ok)throw new Error(`HTTP error! Status: ${n.status}`);e=await n.text()}catch(n){console.error("Error reading file: "+t,n)}finally{return e}}}class Lt{static async getQTableActionMap(){const t="dist/qTableActions.csv",e="/public/qTableActions.csv";let n=await ft.getFile(t);n=n===""?await ft.getFile(e):n;const s=n.trim().split(` +`),i=new Map;return s.forEach(g=>{const[l,p]=g.trim().split(",");i.set(l,x[p])}),i}static getStateActionKey(t){const e=t.getBoardState(),n=t.getGoals();return Array.from({length:16},(i,g)=>{let l;const p=e[g];return p===-1?l="*":n.includes(p)?l=`${p}`:n.includes(g+1)?l="o":l=" ",l+="_",g!==0&&(g+1)%4===0&&(l+="|"),l}).join("").trim()}}const yt=class yt{static async getConfiguration(){var e;if(this.configuration!==void 0)return this.configuration;let t=await this.getConfigurationJson();try{return this.configuration=JSON.parse(t),this.configuration.lessons=(e=this.configuration.lessons)==null?void 0:e.sort((n,s)=>n.lesson-s.lesson),this.configuration}catch(n){return console.error("Invalid JSON string:",n),this.configuration={}}}static async getConfigurationJson(){if(this.configurationJson!==void 0)return this.configurationJson;const t="dist/configuration.json",e="/public/configuration.json";return this.configurationJson=await ft.getFile(t),this.configurationJson===""?await ft.getFile(e):this.configurationJson}static async updateConfigurationJson(t){var e;try{let n=JSON.parse(t);return this.configuration.lessons=(e=this.configuration.lessons)==null?void 0:e.sort((s,i)=>s.lesson-i.lesson),this.configurationJson=t,this.configuration=n,await yt.updateTester(),await W.restartTrainerIfIsRunning(),{success:!0,messgae:"Configuration updated successfully."}}catch(n){return console.error("Invalid JSON string:",n),{success:!1,messgae:"Invalid JSON string: "+n}}}static async updateTester(){const t=this.configuration.usePretrainedDataWhileTesting;Tt.usePreloadedActions!==t&&await W.restartTesterIfIsRunning()}};y(yt,"configurationJson"),y(yt,"configuration");let ot=yt;const ut=class ut{constructor(t){y(this,"boardState");y(this,"episodesToTrain");y(this,"lesson");this.boardState=[],this.lesson=t,this.episodesToTrain=0}getState(){return this.boardState}getGoals(){return this.lesson.goals}getLockedStateElements(){return this.lesson.lockedElements??[]}getEpisodesToTrain(){return this.episodesToTrain}static async getLessonProducersFromJson(){var n;let t=await ot.getConfiguration();if(t.lessons===void 0)return[];const e=((n=t.basicTrainerConfig)==null?void 0:n.lessonsToGenerate)??100;return t.lessons.sort((s,i)=>s.lesson-i.lesson).map(s=>ut.from(s,e))}static from(t,e){const n=new ut(t);return n.lesson=t,n.episodesToTrain=t.lessonsToGenerate!==void 0?t.lessonsToGenerate:e,n.shuffleBoardState(),n}static shuffleFreeCellStarPosition(t,e){const n=z.shuffleArray(e)[0],s=t.boardState.indexOf(-1),i=t.boardState[n];return t.boardState[n]=-1,t.boardState[s]=i,t}isLockedIndex(t){return this.getLockedStateElements().includes(t+1)}shuffleBoardState(){var e;const t=this.getLockedStateElements();this.boardState=bt.shuffleForTraining(t),((e=this.lesson)==null?void 0:e.startPositions)!==void 0&&ut.shuffleFreeCellStarPosition(this,this.lesson.startPositions.map(n=>n-1))}};y(ut,"stateDone",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-1]);let lt=ut;const at=class at{async test(t){this.stop();const e=new Tt;await e.init(t),e.makeMove(),at.testerIntervalId=setInterval(()=>e.makeMove(),500)}stop(){at.testerIntervalId!==null&&(clearInterval(at.testerIntervalId),at.testerIntervalId=null)}};y(at,"testerIntervalId",null);let Et=at;class Jt{constructor(t){y(this,"lessonNo",0);y(this,"lessons");y(this,"lessonCount");y(this,"stateProducer");y(this,"state");y(this,"goals");y(this,"gameOver",!1);y(this,"step",0);y(this,"reverseAction",null);this.lessons=t,this.lessonCount=t.length,this.stateProducer=t[this.lessonNo];let e=bt.shuffle(lt.stateDone,[],1e3);this.state=new j(e,this.stateProducer),this.goals=this.stateProducer.getGoals()}resetIfGameIsOver(){if(!this.gameOver)return;this.lessonNo=0,this.stateProducer=this.lessons[this.lessonNo];let t=bt.shuffle(lt.stateDone,[],1e3);this.state=new j(t,this.stateProducer),this.goals=this.stateProducer.getGoals(),this.gameOver=!1,this.step=0,this.reverseAction=null}}const _=class _{constructor(){y(this,"ctx",null);y(this,"maxEpisodeSteps",200)}async init(t){const e=await lt.getLessonProducersFromJson();this.ctx=new Jt(e),await this.loadedActionMap(t)}async loadedActionMap(t){const e=await ot.getConfiguration();_.usePreloadedActions=t??e.usePretrainedDataWhileTesting??!0,_.usePreloadedActions&&_.actionMap===null&&(_.actionMap=await Lt.getQTableActionMap())}makeMove(){if(this.ctx===null)return;this.ctx.gameOver=this.isGameDone(this.ctx.state),this.ctx.resetIfGameIsOver(),this.ctx.step++;let t=this.getAction(this.ctx.state,this.ctx.reverseAction);this.ctx.reverseAction=T.getReverseAction(t);const e=T.makeMove(this.ctx.state.getBoardState(),t),n=ht._isTerminalSuccess(e,this.ctx.goals);if(this.ctx.state=new j(e,this.ctx.stateProducer),this.ctx.gameOver=this.isGameDone(this.ctx.state),this.ctx.gameOver=this.ctx.step>this.maxEpisodeSteps,this.prntState(this.ctx.state,this.ctx.step),n&&!this.ctx.gameOver&&this.ctx.lessonNoc!==l.reverseAction);if(C.length===0)throw T.logBoardState(p.boardState),C=T.getPossibleActions(p),console.log("environment.reverseAction",l.reverseAction),console.log("possibleActions 1",C),C=C.filter(c=>c!==l.reverseAction),console.log("possibleActions 2",C),new Error("possibleActions.length === 0");Math.random()this.maxExperienceSize&&et.experience.clear();const M=`QTable size: ${g.size}, experience size: ${et.experience.size}`;let $=` +`+s+` +`+M;B.prntAtSomeElement("episodeTrainer",$),B.prntStatsInfo(M+` +it will start to show some intelligence when the qtable size is around 8500 .. ;)`),await z.sleep(0)}static replayExperience(t,e,n,s,i){Array.from(t).sort(()=>Math.random()-.5).slice(0,i).forEach(l=>{$t.updateQTable(e,l.getState(),l.getAction(),l.getNewState(),l.getReward(),l.isDone(),n,s)})}};y(et,"experience",new Set);let Ct=et;const gt=class gt{constructor(){y(this,"episodeTrainer",new Ct);y(this,"semaphoreId",null);y(this,"tester",null)}async train(){if(this.semaphoreId=gt.semaphore.enable(),!gt.semaphore.goodToGo(this.semaphoreId))return;await this.runTester(),Ct.experience.clear();const e=(await ot.getConfiguration()).basicTrainerConfig,n=(e==null?void 0:e.discount)??.9,s=(e==null?void 0:e.learningRate)??.1,i=(e==null?void 0:e.trainingBachCount)??10,g=await lt.getLessonProducersFromJson(),l=async(A,k)=>await this.episodeTrainer.train(A,n,s,k,this.semaphoreId),p=async(A,k,P)=>{let M=A.getEpisodesToTrain();for(let $=0;${},P;f.setAttribute("contenteditable","plaintext-only"),f.setAttribute("spellcheck",n.spellcheck?"true":"false"),f.style.outline="none",f.style.overflowWrap="break-word",f.style.overflowY="auto",f.style.whiteSpace="pre-wrap";const M=(a,u)=>{t(a,u)};let $=!1;f.contentEditable!=="plaintext-only"&&($=!0),$&&f.setAttribute("contenteditable","true");const H=St(()=>{const a=r();M(f,a),c(a)},30);let C=!1;const E=a=>!L(a)&&!J(a)&&a.key!=="Meta"&&a.key!=="Control"&&a.key!=="Alt"&&!a.key.startsWith("Arrow"),D=St(a=>{E(a)&&(X(),C=!1)},300),o=(a,u)=>{g.push([a,u]),f.addEventListener(a,u)};o("keydown",a=>{a.defaultPrevented||(P=U(),n.preserveIdent?S(a):b(a),n.catchTab&&R(a),n.addClosing&&I(a),n.history&&(Z(a),E(a)&&!C&&(X(),C=!0)),$&&!st(a)&&c(r()))}),o("keyup",a=>{a.defaultPrevented||a.isComposing||(P!==U()&&H(),D(a),k(U()))}),o("focus",a=>{A=!0}),o("blur",a=>{A=!1}),o("paste",a=>{X(),xt(a),X(),k(U())}),o("cut",a=>{X(),Ot(a),X(),k(U())});function r(){const a=K(),u={start:0,end:0,dir:void 0};let{anchorNode:m,anchorOffset:w,focusNode:F,focusOffset:O}=a;if(!m||!F)throw"error1";if(m===f&&F===f)return u.start=w>0&&f.textContent?f.textContent.length:0,u.end=O>0&&f.textContent?f.textContent.length:0,u.dir=O>=w?"->":"<-",u;if(m.nodeType===Node.ELEMENT_NODE){const V=i.createTextNode("");m.insertBefore(V,m.childNodes[w]),m=V,w=0}if(F.nodeType===Node.ELEMENT_NODE){const V=i.createTextNode("");F.insertBefore(V,F.childNodes[O]),F=V,O=0}return At(f,V=>{if(V===m&&V===F)return u.start+=w,u.end+=O,u.dir=w<=O?"->":"<-","stop";if(V===m)if(u.start+=w,!u.dir)u.dir="->";else return"stop";else if(V===F)if(u.end+=O,!u.dir)u.dir="<-";else return"stop";V.nodeType===Node.TEXT_NODE&&(u.dir!="->"&&(u.start+=V.nodeValue.length),u.dir!="<-"&&(u.end+=V.nodeValue.length))}),f.normalize(),u}function c(a){var Mt,Dt;const u=K();let m,w=0,F,O=0;if(a.dir||(a.dir="->"),a.start<0&&(a.start=0),a.end<0&&(a.end=0),a.dir=="<-"){const{start:Y,end:tt}=a;a.start=tt,a.end=Y}let V=0;At(f,Y=>{if(Y.nodeType!==Node.TEXT_NODE)return;const tt=(Y.nodeValue||"").length;if(V+tt>a.start&&(m||(m=Y,w=a.start-V),V+tt>a.end))return F=Y,O=a.end-V,"stop";V+=tt}),m||(m=f,w=f.childNodes.length),F||(F=f,O=f.childNodes.length),a.dir=="<-"&&([m,w,F,O]=[F,O,m,w]);{const Y=d(m);if(Y){const pt=i.createTextNode("");(Mt=Y.parentNode)==null||Mt.insertBefore(pt,Y),m=pt,w=0}const tt=d(F);if(tt){const pt=i.createTextNode("");(Dt=tt.parentNode)==null||Dt.insertBefore(pt,tt),F=pt,O=0}}u.setBaseAndExtent(m,w,F,O),f.normalize()}function d(a){for(;a&&a!==f;){if(a.nodeType===Node.ELEMENT_NODE){const u=a;if(u.getAttribute("contenteditable")=="false")return u}a=a.parentNode}}function h(){const u=K().getRangeAt(0),m=i.createRange();return m.selectNodeContents(f),m.setEnd(u.startContainer,u.startOffset),m.toString()}function v(){const u=K().getRangeAt(0),m=i.createRange();return m.selectNodeContents(f),m.setStart(u.endContainer,u.endOffset),m.toString()}function S(a){if(a.key==="Enter"){const u=h(),m=v();let[w]=Q(u),F=w;if(n.indentOn.test(u)&&(F+=n.tab),F.length>0?(q(a),a.stopPropagation(),N(` +`+F)):b(a),F!==w&&n.moveToNewLine.test(m)){const O=r();N(` +`+w),c(O)}}}function b(a){if($&&a.key==="Enter")if(q(a),a.stopPropagation(),v()==""){N(` + `);const u=r();u.start=--u.end,c(u)}else N(` +`)}function I(a){const u=`([{'"`,m=`)]}'"`;if(u.includes(a.key)){q(a);const w=r(),F=w.start==w.end?"":K().toString(),O=a.key+F+m[u.indexOf(a.key)];N(O),w.start++,w.end++,c(w)}}function R(a){if(a.key==="Tab")if(q(a),a.shiftKey){const u=h();let[m,w]=Q(u);if(m.length>0){const F=r(),O=Math.min(n.tab.length,m.length);c({start:w,end:w+O}),i.execCommand("delete"),F.start-=O,F.end-=O,c(F)}}else N(n.tab)}function Z(a){if(L(a)){q(a),p--;const u=l[p];u&&(f.innerHTML=u.html,c(u.pos)),p<0&&(p=0)}if(J(a)){q(a),p++;const u=l[p];u&&(f.innerHTML=u.html,c(u.pos)),p>=l.length&&p--}}function X(){if(!A)return;const a=f.innerHTML,u=r(),m=l[p];if(m&&m.html===a&&m.pos.start===u.start&&m.pos.end===u.end)return;p++,l[p]={html:a,pos:u},l.splice(p+1);const w=300;p>w&&(p=w,l.splice(0,1))}function xt(a){if(a.defaultPrevented)return;q(a);const m=(a.originalEvent??a).clipboardData.getData("text/plain").replace(/\r\n?/g,` +`),w=r();N(m),M(f),c({start:Math.min(w.start,w.end)+m.length,end:Math.min(w.start,w.end)+m.length,dir:"<-"})}function Ot(a){const u=r(),m=K();(a.originalEvent??a).clipboardData.setData("text/plain",m.toString()),i.execCommand("delete"),M(f),c({start:Math.min(u.start,u.end),end:Math.min(u.start,u.end),dir:"<-"}),q(a)}function At(a,u){const m=[];a.firstChild&&m.push(a.firstChild);let w=m.pop();for(;w&&u(w)!=="stop";)w.nextSibling&&m.push(w.nextSibling),w.firstChild&&m.push(w.firstChild),w=m.pop()}function ct(a){return a.metaKey||a.ctrlKey}function L(a){return ct(a)&&!a.shiftKey&&it(a)==="Z"}function J(a){return ct(a)&&a.shiftKey&&it(a)==="Z"}function st(a){return ct(a)&&it(a)==="C"}function it(a){let u=a.key||a.keyCode||a.which;if(u)return(typeof u=="string"?u:String.fromCharCode(u)).toUpperCase()}function N(a){a=a.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'"),i.execCommand("insertHTML",!1,a)}function St(a,u){let m=0;return(...w)=>{clearTimeout(m),m=s.setTimeout(()=>a(...w),u)}}function Q(a){let u=a.length-1;for(;u>=0&&a[u]!==` +`;)u--;u++;let m=u;for(;m + * @author Lea Verou + * @namespace + * @public + */var e=function(n){var s=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,i=0,g={},l={manual:n.Prism&&n.Prism.manual,disableWorkerMessageHandler:n.Prism&&n.Prism.disableWorkerMessageHandler,util:{encode:function o(r){return r instanceof p?new p(r.type,o(r.content),r.alias):Array.isArray(r)?r.map(o):r.replace(/&/g,"&").replace(/"u")return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(d){var o=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(d.stack)||[])[1];if(o){var r=document.getElementsByTagName("script");for(var c in r)if(r[c].src==o)return r[c]}return null}},isActive:function(o,r,c){for(var d="no-"+r;o;){var h=o.classList;if(h.contains(r))return!0;if(h.contains(d))return!1;o=o.parentElement}return!!c}},languages:{plain:g,plaintext:g,text:g,txt:g,extend:function(o,r){var c=l.util.clone(l.languages[o]);for(var d in r)c[d]=r[d];return c},insertBefore:function(o,r,c,d){d=d||l.languages;var h=d[o],v={};for(var S in h)if(h.hasOwnProperty(S)){if(S==r)for(var b in c)c.hasOwnProperty(b)&&(v[b]=c[b]);c.hasOwnProperty(S)||(v[S]=h[S])}var I=d[o];return d[o]=v,l.languages.DFS(l.languages,function(R,Z){Z===I&&R!=o&&(this[R]=v)}),v},DFS:function o(r,c,d,h){h=h||{};var v=l.util.objId;for(var S in r)if(r.hasOwnProperty(S)){c.call(r,S,r[S],d||S);var b=r[S],I=l.util.type(b);I==="Object"&&!h[v(b)]?(h[v(b)]=!0,o(b,c,null,h)):I==="Array"&&!h[v(b)]&&(h[v(b)]=!0,o(b,c,S,h))}}},plugins:{},highlightAll:function(o,r){l.highlightAllUnder(document,o,r)},highlightAllUnder:function(o,r,c){var d={callback:c,container:o,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};l.hooks.run("before-highlightall",d),d.elements=Array.prototype.slice.apply(d.container.querySelectorAll(d.selector)),l.hooks.run("before-all-elements-highlight",d);for(var h=0,v;v=d.elements[h++];)l.highlightElement(v,r===!0,d.callback)},highlightElement:function(o,r,c){var d=l.util.getLanguage(o),h=l.languages[d];l.util.setLanguage(o,d);var v=o.parentElement;v&&v.nodeName.toLowerCase()==="pre"&&l.util.setLanguage(v,d);var S=o.textContent,b={element:o,language:d,grammar:h,code:S};function I(Z){b.highlightedCode=Z,l.hooks.run("before-insert",b),b.element.innerHTML=b.highlightedCode,l.hooks.run("after-highlight",b),l.hooks.run("complete",b),c&&c.call(b.element)}if(l.hooks.run("before-sanity-check",b),v=b.element.parentElement,v&&v.nodeName.toLowerCase()==="pre"&&!v.hasAttribute("tabindex")&&v.setAttribute("tabindex","0"),!b.code){l.hooks.run("complete",b),c&&c.call(b.element);return}if(l.hooks.run("before-highlight",b),!b.grammar){I(l.util.encode(b.code));return}if(r&&n.Worker){var R=new Worker(l.filename);R.onmessage=function(Z){I(Z.data)},R.postMessage(JSON.stringify({language:b.language,code:b.code,immediateClose:!0}))}else I(l.highlight(b.code,b.grammar,b.language))},highlight:function(o,r,c){var d={code:o,grammar:r,language:c};if(l.hooks.run("before-tokenize",d),!d.grammar)throw new Error('The language "'+d.language+'" has no grammar.');return d.tokens=l.tokenize(d.code,d.grammar),l.hooks.run("after-tokenize",d),p.stringify(l.util.encode(d.tokens),d.language)},tokenize:function(o,r){var c=r.rest;if(c){for(var d in c)r[d]=c[d];delete r.rest}var h=new P;return M(h,h.head,o),k(o,h,r,h.head,0),H(h)},hooks:{all:{},add:function(o,r){var c=l.hooks.all;c[o]=c[o]||[],c[o].push(r)},run:function(o,r){var c=l.hooks.all[o];if(!(!c||!c.length))for(var d=0,h;h=c[d++];)h(r)}},Token:p};n.Prism=l;function p(o,r,c,d){this.type=o,this.content=r,this.alias=c,this.length=(d||"").length|0}p.stringify=function o(r,c){if(typeof r=="string")return r;if(Array.isArray(r)){var d="";return r.forEach(function(I){d+=o(I,c)}),d}var h={type:r.type,content:o(r.content,c),tag:"span",classes:["token",r.type],attributes:{},language:c},v=r.alias;v&&(Array.isArray(v)?Array.prototype.push.apply(h.classes,v):h.classes.push(v)),l.hooks.run("wrap",h);var S="";for(var b in h.attributes)S+=" "+b+'="'+(h.attributes[b]||"").replace(/"/g,""")+'"';return"<"+h.tag+' class="'+h.classes.join(" ")+'"'+S+">"+h.content+""};function A(o,r,c,d){o.lastIndex=r;var h=o.exec(c);if(h&&d&&h[1]){var v=h[1].length;h.index+=v,h[0]=h[0].slice(v)}return h}function k(o,r,c,d,h,v){for(var S in c)if(!(!c.hasOwnProperty(S)||!c[S])){var b=c[S];b=Array.isArray(b)?b:[b];for(var I=0;I=v.reach);J+=L.value.length,L=L.next){var st=L.value;if(r.length>o.length)return;if(!(st instanceof p)){var it=1,N;if(xt){if(N=A(ct,J,o,X),!N||N.index>=o.length)break;var q=N.index,St=N.index+N[0].length,Q=J;for(Q+=L.value.length;q>=Q;)L=L.next,Q+=L.value.length;if(Q-=L.value.length,J=Q,L.value instanceof p)continue;for(var U=L;U!==r.tail&&(Qv.reach&&(v.reach=m);var w=L.prev;a&&(w=M(r,w,a),J+=a.length),$(r,w,it);var F=new p(S,Z?l.tokenize(K,Z):K,Ot,K);if(L=M(r,w,F),u&&M(r,L,u),it>1){var O={cause:S+","+I,reach:m};k(o,r,c,L.prev,J,O),v&&O.reach>v.reach&&(v.reach=O.reach)}}}}}}function P(){var o={value:null,prev:null,next:null},r={value:null,prev:o,next:null};o.next=r,this.head=o,this.tail=r,this.length=0}function M(o,r,c){var d=r.next,h={value:c,prev:r,next:d};return r.next=h,d.prev=h,o.length++,h}function $(o,r,c){for(var d=r.next,h=0;h/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},e.languages.markup.tag.inside["attr-value"].inside.entity=e.languages.markup.entity,e.languages.markup.doctype.inside["internal-subset"].inside=e.languages.markup,e.hooks.add("wrap",function(n){n.type==="entity"&&(n.attributes.title=n.content.replace(/&/,"&"))}),Object.defineProperty(e.languages.markup.tag,"addInlined",{value:function(s,i){var g={};g["language-"+i]={pattern:/(^$)/i,lookbehind:!0,inside:e.languages[i]},g.cdata=/^$/i;var l={"included-cdata":{pattern://i,inside:g}};l["language-"+i]={pattern:/[\s\S]+/,inside:e.languages[i]};var p={};p[s]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return s}),"i"),lookbehind:!0,greedy:!0,inside:l},e.languages.insertBefore("markup","cdata",p)}}),Object.defineProperty(e.languages.markup.tag,"addAttribute",{value:function(n,s){e.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+n+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[s,"language-"+s],inside:e.languages[s]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),e.languages.html=e.languages.markup,e.languages.mathml=e.languages.markup,e.languages.svg=e.languages.markup,e.languages.xml=e.languages.extend("markup",{}),e.languages.ssml=e.languages.xml,e.languages.atom=e.languages.xml,e.languages.rss=e.languages.xml,function(n){var s=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;n.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+s.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+s.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+s.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+s.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:s,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},n.languages.css.atrule.inside.rest=n.languages.css;var i=n.languages.markup;i&&(i.tag.addInlined("style","css"),i.tag.addAttribute("style","css"))}(e),e.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},e.languages.javascript=e.languages.extend("clike",{"class-name":[e.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+(/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source)+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),e.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,e.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:e.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:e.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:e.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:e.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:e.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),e.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:e.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),e.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),e.languages.markup&&(e.languages.markup.tag.addInlined("script","javascript"),e.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),e.languages.js=e.languages.javascript,function(){if(typeof e>"u"||typeof document>"u")return;Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var n="Loading…",s=function(C,E){return"✖ Error "+C+" while fetching file: "+E},i="✖ Error: File does not exist or is empty",g={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},l="data-src-status",p="loading",A="loaded",k="failed",P="pre[data-src]:not(["+l+'="'+A+'"]):not(['+l+'="'+p+'"])';function M(C,E,D){var o=new XMLHttpRequest;o.open("GET",C,!0),o.onreadystatechange=function(){o.readyState==4&&(o.status<400&&o.responseText?E(o.responseText):o.status>=400?D(s(o.status,o.statusText)):D(i))},o.send(null)}function $(C){var E=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(C||"");if(E){var D=Number(E[1]),o=E[2],r=E[3];return o?r?[D,Number(r)]:[D,void 0]:[D,D]}}e.hooks.add("before-highlightall",function(C){C.selector+=", "+P}),e.hooks.add("before-sanity-check",function(C){var E=C.element;if(E.matches(P)){C.code="",E.setAttribute(l,p);var D=E.appendChild(document.createElement("CODE"));D.textContent=n;var o=E.getAttribute("data-src"),r=C.language;if(r==="none"){var c=(/\.(\w+)$/.exec(o)||[,"none"])[1];r=g[c]||c}e.util.setLanguage(D,r),e.util.setLanguage(E,r);var d=e.plugins.autoloader;d&&d.loadLanguages(r),M(o,function(h){E.setAttribute(l,A);var v=$(E.getAttribute("data-range"));if(v){var S=h.split(/\r\n?|\n/g),b=v[0],I=v[1]==null?S.length:v[1];b<0&&(b+=S.length),b=Math.max(0,Math.min(b-1,S.length)),I<0&&(I+=S.length),I=Math.max(0,Math.min(I,S.length)),h=S.slice(b,I).join(` +`),E.hasAttribute("data-start")||E.setAttribute("data-start",String(b+1))}D.textContent=h,e.highlightElement(D)},function(h){E.setAttribute(l,k),D.textContent=h})}}),e.plugins.fileHighlight={highlight:function(E){for(var D=(E||document).querySelectorAll(P),o=0,r;r=D[o++];)e.highlightElement(r)}};var H=!1;e.fileHighlight=function(){H||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),H=!0),e.plugins.fileHighlight.highlight.apply(this,arguments)}}()})(Rt);var Vt=Rt.exports;class wt{static close(){var t;(t=document.getElementById("jsonEditor"))==null||t.remove()}static show(t,e,n=!0){var M;const s=document.getElementById("tools");if(!s)return;(M=document.getElementById("jsonEditor"))==null||M.remove();const i=document.createElement("div"),g=document.createElement("div"),l=document.createElement("div"),p=document.createElement("div"),A=document.createElement("div");s.appendChild(i),i.appendChild(g),i.appendChild(A),i.appendChild(p),i.appendChild(l),i.id="jsonEditor",A.setAttribute("class","console-text"),g.textContent=this.divLine,l.textContent=this.divLine,Ut(p,async $=>this.update(t,$,A,e,n)).updateCode(t)}static async update(t,e,n,s,i){if(e.textContent===null)return;let g=i?e.textContent:t;if(e.innerHTML=Vt.highlight(g,Vt.languages.js,"js"),g===t)return;let l=await s(g);n.textContent=l.messgae}}y(wt,"divLine","--------------------------------------------------------------------------------------------------");const rt=class rt{static async toggleConfigurationDisplay(t){if(t){const e=await rt.getAboutJson();wt.show(e,async n=>rt.updateStatus,!1)}else wt.close()}static async getAbout(){if(this.about!==void 0)return this.about;let t=await this.getAboutJson();try{return JSON.parse(t)}catch(e){const n="Invalid JSON string: "+e;return console.error(n),this.about=[]}}static async getAboutJson(){if(this.aboutJson!==void 0)return this.aboutJson;const t="dist/about.json",e="/public/about.json";return this.aboutJson=await ft.getFile(t),this.aboutJson===""?await ft.getFile(e):this.aboutJson}};y(rt,"aboutJson"),y(rt,"about"),y(rt,"updateStatus",{success:!1,messgae:"Not editable."});let Ft=rt;class Pt{static async toggleLessonsDisplay(t){if(t){const e=await ot.getConfigurationJson();let n=async s=>ot.updateConfigurationJson(s);await wt.show(e,n)}else wt.close()}}class nt{static setupTools(){var t,e,n,s,i;(t=document.getElementById("startTrainingBtn"))==null||t.addEventListener("click",()=>nt.startTraining().then()),(e=document.getElementById("startTestingBtn"))==null||e.addEventListener("click",()=>nt.startTesting().then()),(n=document.getElementById("zenGardenBtn"))==null||n.addEventListener("click",()=>nt.zenGardenOnOff().then()),(s=document.getElementById("configurationBtn"))==null||s.addEventListener("click",()=>nt.configurationOnOff().then()),(i=document.getElementById("aboutBtn"))==null||i.addEventListener("click",()=>nt.configOnOff().then())}static async startTraining(){W.stopTester(),B.clearScreen(),await W.train(),await nt.startTesting()}static async startTesting(){W.stopTrainer(),B.clearScreen(),await W.test()}static async configOnOff(){this.btnOff("configurationBtn","configuration",t=>Pt.toggleLessonsDisplay(t)),this.btnOnOff("aboutBtn","about",t=>Ft.toggleConfigurationDisplay(t))}static async configurationOnOff(){this.btnOff("aboutBtn","about",t=>Ft.toggleConfigurationDisplay(t)),this.btnOnOff("configurationBtn","configuration",t=>Pt.toggleLessonsDisplay(t))}static async zenGardenOnOff(){this.btnOnOff("zenGardenBtn","zen garden",t=>T.zenGardenOn=t)}static async btnOff(t,e,n){let s=document.getElementById(t);s==null||s.setAttribute("value",e+" off"),n(!1)}static async btnOnOff(t,e,n){let s=document.getElementById(t);(s==null?void 0:s.getAttribute("value"))!==e+" off"?(s==null||s.setAttribute("value",e+" off"),n(!1)):(s==null||s.setAttribute("value",e+" on"),n(!0))}}nt.setupTools();nt.startTesting().then(); diff --git a/dist/assets/index-DJqDn2it.js b/dist/assets/index-DJqDn2it.js deleted file mode 100644 index 8343614..0000000 --- a/dist/assets/index-DJqDn2it.js +++ /dev/null @@ -1,34 +0,0 @@ -var Re=Object.defineProperty;var Be=(p,t,e)=>t in p?Re(p,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):p[t]=e;var m=(p,t,e)=>Be(p,typeof t!="symbol"?t+"":t,e);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const n of document.querySelectorAll('link[rel="modulepreload"]'))s(n);new MutationObserver(n=>{for(const a of n)if(a.type==="childList")for(const f of a.addedNodes)f.tagName==="LINK"&&f.rel==="modulepreload"&&s(f)}).observe(document,{childList:!0,subtree:!0});function e(n){const a={};return n.integrity&&(a.integrity=n.integrity),n.referrerPolicy&&(a.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?a.credentials="include":n.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function s(n){if(n.ep)return;n.ep=!0;const a=e(n);fetch(n.href,a)}})();var x=(p=>(p.L="L",p.R="R",p.U="U",p.D="D",p))(x||{});class fe{constructor(t,e){this.key=t,this.value=e}getKey(){return this.key}getValue(){return this.value}static from(t,e){return new fe(t,e)}toString(){return"["+this.getKey()+", "+this.getValue()+"]"}}const Ce=class Ce{static makeMove(t,e){const n=t.indexOf(-1),a=this.getXY(n);let f=a.getKey(),l=a.getValue();e===x.L&&(f-=1),e===x.R&&(f+=1),e===x.U&&(l-=1),e===x.D&&(l+=1);const S=this.getIndex(f,l);if(S>15)throw console.log(t),console.log(e),new Error("i1 > 15");const A=[...t],k=A[S];return A[n]=k,A[S]=-1,A}static getXY(t){const e=t%4,s=Math.floor(t/4);return fe.from(e,s)}static getIndex(t,e){return e*4+t}static _getValidMoves(t){const e=this.getXY(t);let s=Object.values(x).slice();return e.getKey()===0&&(s=s.filter(n=>n!==x.L)),e.getKey()===3&&(s=s.filter(n=>n!==x.R)),e.getValue()===0&&(s=s.filter(n=>n!==x.U)),e.getValue()===3&&(s=s.filter(n=>n!==x.D)),s}static getValidMoves(t,e){let s=this._getValidMoves(t);const n=this.getXY(t);return this.contains(e,n.getKey()-1,n.getValue())&&(s=s.filter(a=>a!=x.L)),this.contains(e,n.getKey()+1,n.getValue())&&(s=s.filter(a=>a!=x.R)),this.contains(e,n.getKey(),n.getValue()-1)&&(s=s.filter(a=>a!=x.U)),this.contains(e,n.getKey(),n.getValue()+1)&&(s=s.filter(a=>a!=x.D)),s}static contains(t,e,s){return t.includes(this.getIndex(e,s))}static getStateAsString(t){let e=t.getBoardState(),s=t.getGoals();return this.zenGardenOn?this.getStateAsZenStoneGarden(e,s):this.__getStateAsString(e,s)}static __getStateAsString(t,e){return Array.from({length:16},(s,n)=>{let a;const f=t[n];return f===-1?a=B.blue("*"):e.includes(f)?a=B.red(f.toString()):e.includes(n+1)?a=B.green(f.toString()):a=f.toString(),a+=" ",n!==0&&(n+1)%4===0&&(a+=` -`),a}).join("")}static getStateAsZenStoneGarden(t,e){return Array.from({length:16},(s,n)=>{let a;const f=t[n];return e.includes(f)?a="o":e.includes(n+1)?a="O":a="",a+=" ",n!==0&&(n+1)%4===0&&(a+=` -`),a}).join("")}static prntState(t){let e=this.getStateAsString(t);B.prnt(e)}static prntStateV0(t){let e=this.getStateAsString(t);B.prntAtSomeElement("shadowTester",e)}static getReverseAction(t){return t===x.D?x.U:t===x.U?x.D:t===x.L?x.R:t===x.R?x.L:null}static getAction(t,e,s){const n=e.getHashCodeV2();if(t.has(n)){let a=t.get(n);if(a===void 0)throw new Error("qTable.has(hash) == true, but get(..) returned row == undefined");return a.getActionWithMaxValue(s)}else return this.getFirstPossibleAction(e,s)}static getRandomAction(t){return t.length===0&&B.prntErrorMsg("Check lessons configuration, for logic errors: The getPossibleActions function returned no action."),t.length>0?t[Math.floor(Math.random()*t.length)]:x.D}static getFirstPossibleAction(t,e){const s=this.getPossibleActions(t);if(s.length===1)return B.prntErrorMsg("Check lessons configuration, for logic errors: The getPossibleActions function returned only one action: "+s[0]),s[0];const n=s.filter(a=>a!==e);return n.length===0?(B.prntErrorMsg("Check lessons configuration, for logic errors: The getPossibleActions function returned no action."),x.D):n[0]}static getPossibleActions(t){const e=t.getBoardState().indexOf(-1),s=t.getFixedElements().map(n=>n-1);return Ce.getValidMoves(e,s)}};m(Ce,"zenGardenOn",!1);let C=Ce;class B{static blue(t){return''+t+""}static green(t){return''+t+""}static red(t){return''+t+""}static clearScreen(){const t=document.getElementById("console");t&&(t.innerHTML="")}static prntTestStep(t){this.addElementToConsoleDiv("testGameStep",t)}static prntAtSomeElement(t,e){this.addElementToConsoleDiv(t,e)}static prntStatsInfo(t){const e=document.getElementById("statsInfo");e&&(e.setAttribute("class","console-text"),e.textContent=` -`+t.toLowerCase().replace(", "," | "))}static prntErrorMsg(t){if(C.zenGardenOn)return;const e=document.getElementById("statsInfo");e&&(e.setAttribute("class","console-error-msg"),e.textContent=` -`+t)}static addElementToConsoleDiv(t,e){const s=document.getElementById(t);s?s.innerHTML=e:this.prnt(e,"color:black;",t)}static prnt(t,e="color:black;",s=null){const n=document.getElementById("console");if(n){const a=document.createElement("div");a.innerHTML=t,e&&(a.style.cssText=e),s!==null&&(a.id=s),n.appendChild(a),n.scrollTop=n.scrollHeight}}static warn(t){this.prnt(t,"color: orange;")}}const ke=class ke{static prnt(t,e="color: black;"){B.prnt(t,e)}static str(t,e){const s=t.toString();if(s.length>=e)return s;const n=e-s.length;return s+ke.emptyString.substring(0,n)}static sum(t){return!t||(t=t.filter(e=>e!==0),t.length===0)?0:t.reduce((e,s)=>e+s,0)}static toString(t){return`[${Array.from(t).map(String).join(", ")}]`}static px(){return(t,e)=>t}static equalArrays(t,e){if(t.length!==e.length)return!1;for(let s=0;sMath.random()-.5)}static _sleep(t){return new Promise(e=>setTimeout(e,t))}static async sleep(t){await this._sleep(t)}};m(ke,"emptyString"," ");let H=ke;class ze{constructor(t){m(this,"state");m(this,"qValues");this.state=t,this.qValues=new Map}setValue(t,e){const s=C.getPossibleActions(this.state);this.qValues.size===0&&s.forEach(n=>this.qValues.set(n,0)),s.includes(t)&&this.qValues.set(t,e)}getState(){return this.state}getValue(t){return this.qValues.get(t)||0}getActionWithMaxValue(t){const e=t===null?null:this.getAction(t);if(e==null){let s=C.getPossibleActions(this.state);if(s=s.filter(n=>n!==t),s.length===0)throw B.prntErrorMsg("possibleActions.length === 0, there allways must be some action to go around.. need to debug."),new Error("possibleActions.length === 0, there allways must be some action to go around.. need to debug.");return s[0]}else return e}getAction(t){const s=Array.from(this.qValues.entries()).filter(([n])=>n!==t).reduce((n,a)=>a[1]>n[1]?a:n,[t,-1/0]);return s[1]>-1/0?s[0]:void 0}getMaxValue(){return this.qValues.size===0?0:Math.max(...Array.from(this.qValues.values()))}}class Ge{static updateQTable(t,e,s,n,a,f,l,S){let A;if(f)A=a;else{const k=this.getQValue(t,e,s),G=this.getMaxQValue(t,n);A=this.calcQValue(a,k,G,S,l)}this.addStateWithZeroValuesToQTableIfStateNotExist(t,e),this.updateQTableEntry(t,e.getHashCodeV2(),s,A)}static updateQTableEntry(t,e,s,n){var a;(a=t.get(e))==null||a.setValue(s,n)}static getMaxQValue(t,e){var n;const s=e.getHashCodeV2();return this.addStateWithZeroValuesToQTableIfStateNotExist(t,e),((n=t.get(s))==null?void 0:n.getMaxValue())??0}static getQValue(t,e,s){var a;const n=e.getHashCodeV2();return this.addStateWithZeroValuesToQTableIfStateNotExist(t,e),((a=t.get(n))==null?void 0:a.getValue(s))??0}static addStateWithZeroValuesToQTableIfStateNotExist(t,e){t.has(e.getHashCodeV2())||this.addStateWithZeroValuesToQTable(t,e)}static addStateWithZeroValuesToQTable(t,e){const s=e.getHashCodeV2(),n=new ze(e);t.set(s,n)}static calcQValue(t,e,s,n,a){return e+a*(t+n*s-e)}}class le{static shuffle(t,e,s){const n=e.map(a=>a-1);for(let a=0;al+1).filter(f=>!t.includes(f)),s=[...e].sort(()=>Math.random()-.5),n=e.map((f,l)=>fe.from(f,s[l]));return Array.from({length:16},(f,l)=>this.zip(n,l)).map(f=>f.getValue()===16?-1:f.getValue())}static zip(t,e){const s=t.find(n=>n.getKey()===e+1);return s===void 0?fe.from(e,e+1):fe.from(e,s.getValue())}}class U{constructor(t,e){m(this,"boardState");m(this,"goals");m(this,"fixedElements");"boardState"in t&&"goals"in t&&"fixedElements"in t?(this.boardState=[...t.boardState],this.goals=[...t.goals],this.fixedElements=[...t.fixedElements]):t instanceof U?(this.boardState=[...t.getBoardState()],this.goals=[...t.getGoals()],this.fixedElements=[...t.getFixedElements()]):(this.boardState=[...t],this.goals=[...(e==null?void 0:e.getGoals())??[]],this.fixedElements=[...(e==null?void 0:e.getLockedStateElements())??[]])}static getTestCase(){let t={boardState:[1,2,3,4,5,6,7,8,9,10,11,-1,14,15,12,13],goals:[12],fixedElements:[1,2,3,4,5,6,7,8,9,10,11,13,14,15]};return new U(t)}getBoardState(){return this.boardState}setBoardState(t){this.boardState=t}getGoals(){return this.goals}setGoals(t){this.goals=t}getFixedElements(){return this.fixedElements}setFixedElements(t){this.fixedElements=t}getHashCodeV2(){const t=this.getHashCodeV3__();return this.hashString(t)}getHashCodeV3__(){return Array.from({length:16},(t,e)=>{let s;const n=this.boardState[e];return n===-1?s="*":this.goals.includes(n)?s=String(n):this.goals.includes(e+1)?s="o":s=" ",s=s+" ",e!==0&&(e+1)%4===0&&(s=s+` -`),s}).join("")}getHashCode(){const t=this.boardState.map(String).join(",");return this.hashString(t)}hashString(t){let e=0;for(let s=0;s8&&this.circleAction.shift(),(H.equalArrays(this.circleAction,this.bigCircleAction1)||H.equalArrays(this.circleAction,this.bigCircleAction2)||H.equalArrays(this.circleAction,this.smallCircleAction1)||H.equalArrays(this.circleAction,this.smallCircleAction2))&&(a=!0);const l=this.state.getBoardState().indexOf(-1);return z.stateProducer.isLockedIndex(l)&&(a=!0,f=-1),isNaN(f)&&(f=this.getReward(s,this.goals)),new He(n,e,f,a)}static _isTerminalSuccess(t,e){return e.filter(n=>t[n-1]===n).length===e.length}prntInfo(){H.prnt(` - ------------------------------------------------------------------- -`);const t=this.state.getBoardState(),e=t.indexOf(-1),s=C.getXY(e);H.prnt(s.getKey()+" - "+s.getValue());const n=C.getIndex(s.getKey(),s.getValue());H.prnt(`${e} - ${n}`);const a=C._getValidMoves(e);H.prnt(a);const f=this.getReward(t,this.goals);H.prnt("reward: "+f),H.prnt(` -`),C.prntState(this.state)}getReward(t,e){const s=t.indexOf(-1),n=C.getXY(s),f=e.map(S=>this.getDistance(C.getXY(t.indexOf(S)),C.getXY(S-1))).reduce((S,A)=>S+A,0);if(f===0)return 100.5;const l=e.reduce((S,A)=>S+this.getDistance(C.getXY(t.indexOf(A)),n),0);return 1/(f+l)}getDistance(t,e){const s=Math.pow(e.getKey()-t.getKey(),2),n=Math.pow(e.getValue()-t.getValue(),2);return Math.sqrt(s+n)}};m(z,"stateProducer");let he=z;class pe{static async getFile(t){let e="";try{const s=await fetch(t);if(!s.ok)throw new Error(`HTTP error! Status: ${s.status}`);e=await s.text()}catch(s){console.error("Error reading file: "+t,s)}finally{return e}}}const ye=class ye{static async getConfiguration(){var e;if(this.configuration!==void 0)return this.configuration;let t=await this.getConfigurationJson();try{return this.configuration=JSON.parse(t),this.configuration.lessons=(e=this.configuration.lessons)==null?void 0:e.sort((s,n)=>s.lesson-n.lesson),this.configuration}catch(s){return console.error("Invalid JSON string:",s),this.configuration={}}}static async getConfigurationJson(){if(this.configurationJson!==void 0)return this.configurationJson;const t="dist/configuration.json",e="/public/configuration.json";return this.configurationJson=await pe.getFile(t),this.configurationJson===""?await pe.getFile(e):this.configurationJson}static async updateConfigurationJson(t){var e;try{let s=JSON.parse(t);return this.configuration.lessons=(e=this.configuration.lessons)==null?void 0:e.sort((n,a)=>n.lesson-a.lesson),this.configurationJson=t,this.configuration=s,await ye.updateTester(),await Z.restartTrainerIfIsRunning(),{success:!0,messgae:"Configuration updated successfully."}}catch(s){return console.error("Invalid JSON string:",s),{success:!1,messgae:"Invalid JSON string: "+s}}}static async updateTester(){const t=this.configuration.usePretrainedDataWhileTesting;Ee.usePreloadedActions!==t&&await Z.restartTesterIfIsRunning()}};m(ye,"configurationJson"),m(ye,"configuration");let ce=ye;const g=class g{constructor(t){m(this,"goals");m(this,"lockedStateElements");m(this,"state");m(this,"episodesToTrain");m(this,"lessonNb");this.lessonNb=t,this.goals=[],this.lockedStateElements=[],this.state=[],this.episodesToTrain=0}getState(){return this.state}getGoals(){return this.goals}getLockedStateElements(){return this.lockedStateElements}getEpisodesToTrain(){return this.episodesToTrain}static async getLessonProducersFromJson(){var s;let t=await ce.getConfiguration();if(t.lessons===void 0)return[];const e=((s=t.basicTrainerConfig)==null?void 0:s.lessonsToGenerate)??100;return t.lessons.map((n,a)=>g.from(n,a,e))}static from(t,e,s){const n=new g(e);return n.goals=t.goals,n.lockedStateElements=t.lockedElements!==void 0?t.lockedElements:[],n.episodesToTrain=t.lessonsToGenerate!==void 0?t.lessonsToGenerate:s,n.state=le.shuffleForTraining(n.lockedStateElements),t.startPositions===void 0?n:g.shuffleFreeCellStarPosition(n,t.startPositions.map(a=>a-1))}static generateLessons0(){return[g.state1(0),g.shuffleFreeCellStarPosition(g.createStateProducer(2,1),[1,4]),g.shuffleFreeCellStarPosition(g.createStateProducer(3,2),[2,5]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_3_4(3),[3,6]),g.shuffleFreeCellStarPosition(g.createStateProducer(5,4),[6,7]),g.shuffleFreeCellStarPosition(g.createStateProducer(6,5),[5,8]),g.shuffleFreeCellStarPosition(g.createStateProducer(7,6),[6,9]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_7_8(7),[8,11]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_9_13(8),[10,11]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_10__15(9),[9,13]),g.state12(10)]}static generateLessonsV1(){return[g.createStateProducerForGoals_1_2(0),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_3_4(1),[2,3,4]),g.shuffleFreeCellStarPosition(g.createStateProducer(5,2),[6,7]),g.shuffleFreeCellStarPosition(g.createStateProducer(6,3),[5,8]),g.shuffleFreeCellStarPosition(g.createStateProducer(7,4),[6,9]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_7_8(5),[8,11]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_9_13(6),[10,11]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_10__15(7),[9,13]),g.state12(8)]}static generateLessons(){return[g.createStateProducerForGoals_1_2(0),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_3_4(1),[2,3,4]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_5_6(2),[6,7]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_7_8(3),[8,9,6]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_9_13(4),[10,11]),g.shuffleFreeCellStarPosition(g.createStateProducerForGoals_10__15(5),[9,13]),g.state12(6)]}static createStateProducerForGoals_1_2(t){const e=new g(t);return e.goals=[1,2],e.lockedStateElements=[],e.state=[...g.stateDone],e.episodesToTrain=100,g.shuffle(e,e.lockedStateElements),e}static state1(t){return g.createStateProducer(1,t)}static createStateProducerForGoals_3_4(t){const e=new g(t);return e.goals=[3,4],e.lockedStateElements=[1,2],e.state=[...g.stateDone],e.episodesToTrain=100,g.shuffle(e,[1,2,3]),e}static createStateProducerForGoals_5_6(t){const e=new g(t);return e.goals=[5,6],e.lockedStateElements=[1,2,3,4],e.state=[...g.stateDone],e.episodesToTrain=100,g.shuffle(e,e.lockedStateElements),e}static createStateProducer(t,e){const s=new g(e);return s.goals=[t],s.lockedStateElements=Array.from({length:t-1},(n,a)=>a+1),s.state=[...g.stateDone],s.episodesToTrain=100,g.shuffle(s,s.lockedStateElements),s}static shuffleFreeCellStarPosition(t,e){const s=H.shuffleArray(e)[0],n=t.state.indexOf(-1),a=t.state[s];return t.state[s]=-1,t.state[n]=a,t}static createStateProducerForGoals_7_8(t){const e=new g(t);return e.goals=[7,8],e.lockedStateElements=[1,2,3,4,5,6],e.state=[...g.stateDone],e.episodesToTrain=100,g.shuffle(e,[1,2,3,4,5,6,7]),e}static createStateProducerForGoals_9_13(t){const e=new g(t);return e.goals=[9,13],e.lockedStateElements=[1,2,3,4,5,6,7,8],e.state=[...g.stateDone],e.episodesToTrain=100,g.shuffle(e,e.lockedStateElements),e}static createStateProducerForGoals_10__15(t){const e=new g(t);return e.goals=[10,11,14,15],e.lockedStateElements=[1,2,3,4,5,6,7,8,9,13],e.state=le.shuffle([...g.stateDone],e.lockedStateElements,this.shufleSteps),e.episodesToTrain=100,e}static state12(t){const e=new g(t);return e.goals=[12],e.lockedStateElements=[1,2,3,4,5,6,7,8,9,10,11,13,14,15],e.state=le.shuffle([...g.stateDone],e.lockedStateElements,this.shufleSteps),e.episodesToTrain=10,e}isLockedIndex(t){return this.lockedStateElements.includes(t+1)}static shuffle(t,e){let s=t.state.filter(n=>!e.includes(n));s=H.shuffleArray(s),t.state=[...e,...s]}resetStateV0(){const t=g.generateLessons()[this.lessonNb];this.goals=[...t.goals],this.lockedStateElements=[...t.lockedStateElements],this.state=[...t.state]}async resetState(){const e=(await g.getLessonProducersFromJson())[this.lessonNb];this.goals=[...e.goals],this.lockedStateElements=[...e.lockedStateElements],this.state=[...e.state]}};m(g,"stateDone",[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,-1]),m(g,"shufleSteps",100);let ue=g;class De{static async getQTableActionMap(){const t="dist/qTableActions.csv",e="/public/qTableActions.csv";let s=await pe.getFile(t);s=s===""?await pe.getFile(e):s;const n=s.trim().split(` -`),a=new Map;return n.forEach(f=>{const[l,S]=f.trim().split(",");a.set(l,x[S])}),a}static getStateActionKey(t){const e=t.getBoardState(),s=t.getGoals();return Array.from({length:16},(a,f)=>{let l;const S=e[f];return S===-1?l="*":s.includes(S)?l=`${S}`:s.includes(f+1)?l="o":l=" ",l+="_",f!==0&&(f+1)%4===0&&(l+="|"),l}).join("").trim()}}const ie=class ie{async test(t){this.stop();const e=new Ee;await e.init(t),e.makeMove(),ie.testerIntervalId=setInterval(()=>e.makeMove(),500)}stop(){ie.testerIntervalId!==null&&(clearInterval(ie.testerIntervalId),ie.testerIntervalId=null)}};m(ie,"testerIntervalId",null);let Ae=ie;class Je{constructor(t){m(this,"lessonNo",0);m(this,"lessons");m(this,"lessonCount");m(this,"stateProducer");m(this,"state");m(this,"goals");m(this,"gameOver",!1);m(this,"step",0);m(this,"reverseAction",null);this.lessons=t,this.lessonCount=t.length,this.stateProducer=t[this.lessonNo];let e=le.shuffle(ue.stateDone,[],1e3);this.state=new U(e,this.stateProducer),this.goals=this.stateProducer.getGoals()}resetIfGameIsOver(){if(!this.gameOver)return;this.lessonNo=0,this.stateProducer=this.lessons[this.lessonNo];let t=le.shuffle(ue.stateDone,[],1e3);this.state=new U(t,this.stateProducer),this.goals=this.stateProducer.getGoals(),this.gameOver=!1,this.step=0,this.reverseAction=null}}const ee=class ee{constructor(){m(this,"ctx",null);m(this,"maxEpisodeSteps",200)}async init(t){const e=await ue.getLessonProducersFromJson();this.ctx=new Je(e),await this.loadedActionMap(t)}async loadedActionMap(t){const e=await ce.getConfiguration();ee.usePreloadedActions=t??e.usePretrainedDataWhileTesting??!0,ee.usePreloadedActions&&ee.actionMap===null&&(ee.actionMap=await De.getQTableActionMap())}makeMove(){if(this.ctx===null)return;this.ctx.gameOver=this.isGameDone(this.ctx.state),this.ctx.resetIfGameIsOver(),this.ctx.step++;let t=this.getAction(this.ctx.state,this.ctx.reverseAction);this.ctx.reverseAction=C.getReverseAction(t);const e=C.makeMove(this.ctx.state.getBoardState(),t),s=he._isTerminalSuccess(e,this.ctx.goals);if(this.ctx.state=new U(e,this.ctx.stateProducer),this.ctx.gameOver=this.isGameDone(this.ctx.state),this.ctx.gameOver=this.ctx.step>this.maxEpisodeSteps,this.prntState(this.ctx.state,this.ctx.step),s&&!this.ctx.gameOver&&this.ctx.lessonNothis.maxExperienceSize&&se.experience.clear();const M=`QTable size: ${f.size}, experience size: ${se.experience.size}`;let $=` -`+n+` -`+M;B.prntAtSomeElement("episodeTrainer",$),B.prntStatsInfo(M+` -it will start to show some intelligence when the qtable size is around 8500 .. ;)`),await H.sleep(0)}static replayExperience(t,e,s,n,a){Array.from(t).sort(()=>Math.random()-.5).slice(0,a).forEach(l=>{Ge.updateQTable(e,l.getState(),l.getAction(),l.getNewState(),l.getReward(),l.isDone(),s,n)})}};m(se,"experience",new Set);let Fe=se;const de=class de{constructor(){m(this,"episodeTrainer",new Fe);m(this,"semaphoreId",null);m(this,"tester",null)}async train(){if(this.semaphoreId=de.semaphore.enable(),!de.semaphore.goodToGo(this.semaphoreId))return;await this.runTester(),Fe.experience.clear();const e=(await ce.getConfiguration()).basicTrainerConfig,s=(e==null?void 0:e.discount)??.9,n=(e==null?void 0:e.learningRate)??.1,a=(e==null?void 0:e.trainingBachCount)??10,f=await ue.getLessonProducersFromJson(),l=async(A,k)=>await this.episodeTrainer.train(A,s,n,k,this.semaphoreId),S=async(A,k,G)=>{let M=A.getEpisodesToTrain();for(let $=0;${},G;p.setAttribute("contenteditable","plaintext-only"),p.setAttribute("spellcheck",s.spellcheck?"true":"false"),p.style.outline="none",p.style.overflowWrap="break-word",p.style.overflowY="auto",p.style.whiteSpace="pre-wrap";const M=(r,u)=>{t(r,u)};let $=!1;p.contentEditable!=="plaintext-only"&&($=!0),$&&p.setAttribute("contenteditable","true");const J=xe(()=>{const r=i();M(p,r),c(r)},30);let P=!1;const F=r=>!L(r)&&!q(r)&&r.key!=="Meta"&&r.key!=="Control"&&r.key!=="Alt"&&!r.key.startsWith("Arrow"),D=xe(r=>{F(r)&&(Y(),P=!1)},300),o=(r,u)=>{f.push([r,u]),p.addEventListener(r,u)};o("keydown",r=>{r.defaultPrevented||(G=Q(),s.preserveIdent?E(r):v(r),s.catchTab&&R(r),s.addClosing&&I(r),s.history&&(X(r),F(r)&&!P&&(Y(),P=!0)),$&&!ae(r)&&c(i()))}),o("keyup",r=>{r.defaultPrevented||r.isComposing||(G!==Q()&&J(),D(r),k(Q()))}),o("focus",r=>{A=!0}),o("blur",r=>{A=!1}),o("paste",r=>{Y(),be(r),Y(),k(Q())}),o("cut",r=>{Y(),Pe(r),Y(),k(Q())});function i(){const r=W(),u={start:0,end:0,dir:void 0};let{anchorNode:y,anchorOffset:w,focusNode:T,focusOffset:O}=r;if(!y||!T)throw"error1";if(y===p&&T===p)return u.start=w>0&&p.textContent?p.textContent.length:0,u.end=O>0&&p.textContent?p.textContent.length:0,u.dir=O>=w?"->":"<-",u;if(y.nodeType===Node.ELEMENT_NODE){const V=a.createTextNode("");y.insertBefore(V,y.childNodes[w]),y=V,w=0}if(T.nodeType===Node.ELEMENT_NODE){const V=a.createTextNode("");T.insertBefore(V,T.childNodes[O]),T=V,O=0}return we(p,V=>{if(V===y&&V===T)return u.start+=w,u.end+=O,u.dir=w<=O?"->":"<-","stop";if(V===y)if(u.start+=w,!u.dir)u.dir="->";else return"stop";else if(V===T)if(u.end+=O,!u.dir)u.dir="<-";else return"stop";V.nodeType===Node.TEXT_NODE&&(u.dir!="->"&&(u.start+=V.nodeValue.length),u.dir!="<-"&&(u.end+=V.nodeValue.length))}),p.normalize(),u}function c(r){var Ie,Me;const u=W();let y,w=0,T,O=0;if(r.dir||(r.dir="->"),r.start<0&&(r.start=0),r.end<0&&(r.end=0),r.dir=="<-"){const{start:_,end:te}=r;r.start=te,r.end=_}let V=0;we(p,_=>{if(_.nodeType!==Node.TEXT_NODE)return;const te=(_.nodeValue||"").length;if(V+te>r.start&&(y||(y=_,w=r.start-V),V+te>r.end))return T=_,O=r.end-V,"stop";V+=te}),y||(y=p,w=p.childNodes.length),T||(T=p,O=p.childNodes.length),r.dir=="<-"&&([y,w,T,O]=[T,O,y,w]);{const _=d(y);if(_){const me=a.createTextNode("");(Ie=_.parentNode)==null||Ie.insertBefore(me,_),y=me,w=0}const te=d(T);if(te){const me=a.createTextNode("");(Me=te.parentNode)==null||Me.insertBefore(me,te),T=me,O=0}}u.setBaseAndExtent(y,w,T,O),p.normalize()}function d(r){for(;r&&r!==p;){if(r.nodeType===Node.ELEMENT_NODE){const u=r;if(u.getAttribute("contenteditable")=="false")return u}r=r.parentNode}}function h(){const u=W().getRangeAt(0),y=a.createRange();return y.selectNodeContents(p),y.setEnd(u.startContainer,u.startOffset),y.toString()}function b(){const u=W().getRangeAt(0),y=a.createRange();return y.selectNodeContents(p),y.setStart(u.endContainer,u.endOffset),y.toString()}function E(r){if(r.key==="Enter"){const u=h(),y=b();let[w]=K(u),T=w;if(s.indentOn.test(u)&&(T+=s.tab),T.length>0?(j(r),r.stopPropagation(),N(` -`+T)):v(r),T!==w&&s.moveToNewLine.test(y)){const O=i();N(` -`+w),c(O)}}}function v(r){if($&&r.key==="Enter")if(j(r),r.stopPropagation(),b()==""){N(` - `);const u=i();u.start=--u.end,c(u)}else N(` -`)}function I(r){const u=`([{'"`,y=`)]}'"`;if(u.includes(r.key)){j(r);const w=i(),T=w.start==w.end?"":W().toString(),O=r.key+T+y[u.indexOf(r.key)];N(O),w.start++,w.end++,c(w)}}function R(r){if(r.key==="Tab")if(j(r),r.shiftKey){const u=h();let[y,w]=K(u);if(y.length>0){const T=i(),O=Math.min(s.tab.length,y.length);c({start:w,end:w+O}),a.execCommand("delete"),T.start-=O,T.end-=O,c(T)}}else N(s.tab)}function X(r){if(L(r)){j(r),S--;const u=l[S];u&&(p.innerHTML=u.html,c(u.pos)),S<0&&(S=0)}if(q(r)){j(r),S++;const u=l[S];u&&(p.innerHTML=u.html,c(u.pos)),S>=l.length&&S--}}function Y(){if(!A)return;const r=p.innerHTML,u=i(),y=l[S];if(y&&y.html===r&&y.pos.start===u.start&&y.pos.end===u.end)return;S++,l[S]={html:r,pos:u},l.splice(S+1);const w=300;S>w&&(S=w,l.splice(0,1))}function be(r){if(r.defaultPrevented)return;j(r);const y=(r.originalEvent??r).clipboardData.getData("text/plain").replace(/\r\n?/g,` -`),w=i();N(y),M(p),c({start:Math.min(w.start,w.end)+y.length,end:Math.min(w.start,w.end)+y.length,dir:"<-"})}function Pe(r){const u=i(),y=W();(r.originalEvent??r).clipboardData.setData("text/plain",y.toString()),a.execCommand("delete"),M(p),c({start:Math.min(u.start,u.end),end:Math.min(u.start,u.end),dir:"<-"}),j(r)}function we(r,u){const y=[];r.firstChild&&y.push(r.firstChild);let w=y.pop();for(;w&&u(w)!=="stop";)w.nextSibling&&y.push(w.nextSibling),w.firstChild&&y.push(w.firstChild),w=y.pop()}function ge(r){return r.metaKey||r.ctrlKey}function L(r){return ge(r)&&!r.shiftKey&&re(r)==="Z"}function q(r){return ge(r)&&r.shiftKey&&re(r)==="Z"}function ae(r){return ge(r)&&re(r)==="C"}function re(r){let u=r.key||r.keyCode||r.which;if(u)return(typeof u=="string"?u:String.fromCharCode(u)).toUpperCase()}function N(r){r=r.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'"),a.execCommand("insertHTML",!1,r)}function xe(r,u){let y=0;return(...w)=>{clearTimeout(y),y=n.setTimeout(()=>r(...w),u)}}function K(r){let u=r.length-1;for(;u>=0&&r[u]!==` -`;)u--;u++;let y=u;for(;y - * @author Lea Verou - * @namespace - * @public - */var e=function(s){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,a=0,f={},l={manual:s.Prism&&s.Prism.manual,disableWorkerMessageHandler:s.Prism&&s.Prism.disableWorkerMessageHandler,util:{encode:function o(i){return i instanceof S?new S(i.type,o(i.content),i.alias):Array.isArray(i)?i.map(o):i.replace(/&/g,"&").replace(/"u")return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(d){var o=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(d.stack)||[])[1];if(o){var i=document.getElementsByTagName("script");for(var c in i)if(i[c].src==o)return i[c]}return null}},isActive:function(o,i,c){for(var d="no-"+i;o;){var h=o.classList;if(h.contains(i))return!0;if(h.contains(d))return!1;o=o.parentElement}return!!c}},languages:{plain:f,plaintext:f,text:f,txt:f,extend:function(o,i){var c=l.util.clone(l.languages[o]);for(var d in i)c[d]=i[d];return c},insertBefore:function(o,i,c,d){d=d||l.languages;var h=d[o],b={};for(var E in h)if(h.hasOwnProperty(E)){if(E==i)for(var v in c)c.hasOwnProperty(v)&&(b[v]=c[v]);c.hasOwnProperty(E)||(b[E]=h[E])}var I=d[o];return d[o]=b,l.languages.DFS(l.languages,function(R,X){X===I&&R!=o&&(this[R]=b)}),b},DFS:function o(i,c,d,h){h=h||{};var b=l.util.objId;for(var E in i)if(i.hasOwnProperty(E)){c.call(i,E,i[E],d||E);var v=i[E],I=l.util.type(v);I==="Object"&&!h[b(v)]?(h[b(v)]=!0,o(v,c,null,h)):I==="Array"&&!h[b(v)]&&(h[b(v)]=!0,o(v,c,E,h))}}},plugins:{},highlightAll:function(o,i){l.highlightAllUnder(document,o,i)},highlightAllUnder:function(o,i,c){var d={callback:c,container:o,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};l.hooks.run("before-highlightall",d),d.elements=Array.prototype.slice.apply(d.container.querySelectorAll(d.selector)),l.hooks.run("before-all-elements-highlight",d);for(var h=0,b;b=d.elements[h++];)l.highlightElement(b,i===!0,d.callback)},highlightElement:function(o,i,c){var d=l.util.getLanguage(o),h=l.languages[d];l.util.setLanguage(o,d);var b=o.parentElement;b&&b.nodeName.toLowerCase()==="pre"&&l.util.setLanguage(b,d);var E=o.textContent,v={element:o,language:d,grammar:h,code:E};function I(X){v.highlightedCode=X,l.hooks.run("before-insert",v),v.element.innerHTML=v.highlightedCode,l.hooks.run("after-highlight",v),l.hooks.run("complete",v),c&&c.call(v.element)}if(l.hooks.run("before-sanity-check",v),b=v.element.parentElement,b&&b.nodeName.toLowerCase()==="pre"&&!b.hasAttribute("tabindex")&&b.setAttribute("tabindex","0"),!v.code){l.hooks.run("complete",v),c&&c.call(v.element);return}if(l.hooks.run("before-highlight",v),!v.grammar){I(l.util.encode(v.code));return}if(i&&s.Worker){var R=new Worker(l.filename);R.onmessage=function(X){I(X.data)},R.postMessage(JSON.stringify({language:v.language,code:v.code,immediateClose:!0}))}else I(l.highlight(v.code,v.grammar,v.language))},highlight:function(o,i,c){var d={code:o,grammar:i,language:c};if(l.hooks.run("before-tokenize",d),!d.grammar)throw new Error('The language "'+d.language+'" has no grammar.');return d.tokens=l.tokenize(d.code,d.grammar),l.hooks.run("after-tokenize",d),S.stringify(l.util.encode(d.tokens),d.language)},tokenize:function(o,i){var c=i.rest;if(c){for(var d in c)i[d]=c[d];delete i.rest}var h=new G;return M(h,h.head,o),k(o,h,i,h.head,0),J(h)},hooks:{all:{},add:function(o,i){var c=l.hooks.all;c[o]=c[o]||[],c[o].push(i)},run:function(o,i){var c=l.hooks.all[o];if(!(!c||!c.length))for(var d=0,h;h=c[d++];)h(i)}},Token:S};s.Prism=l;function S(o,i,c,d){this.type=o,this.content=i,this.alias=c,this.length=(d||"").length|0}S.stringify=function o(i,c){if(typeof i=="string")return i;if(Array.isArray(i)){var d="";return i.forEach(function(I){d+=o(I,c)}),d}var h={type:i.type,content:o(i.content,c),tag:"span",classes:["token",i.type],attributes:{},language:c},b=i.alias;b&&(Array.isArray(b)?Array.prototype.push.apply(h.classes,b):h.classes.push(b)),l.hooks.run("wrap",h);var E="";for(var v in h.attributes)E+=" "+v+'="'+(h.attributes[v]||"").replace(/"/g,""")+'"';return"<"+h.tag+' class="'+h.classes.join(" ")+'"'+E+">"+h.content+""};function A(o,i,c,d){o.lastIndex=i;var h=o.exec(c);if(h&&d&&h[1]){var b=h[1].length;h.index+=b,h[0]=h[0].slice(b)}return h}function k(o,i,c,d,h,b){for(var E in c)if(!(!c.hasOwnProperty(E)||!c[E])){var v=c[E];v=Array.isArray(v)?v:[v];for(var I=0;I=b.reach);q+=L.value.length,L=L.next){var ae=L.value;if(i.length>o.length)return;if(!(ae instanceof S)){var re=1,N;if(be){if(N=A(ge,q,o,Y),!N||N.index>=o.length)break;var j=N.index,xe=N.index+N[0].length,K=q;for(K+=L.value.length;j>=K;)L=L.next,K+=L.value.length;if(K-=L.value.length,q=K,L.value instanceof S)continue;for(var Q=L;Q!==i.tail&&(Kb.reach&&(b.reach=y);var w=L.prev;r&&(w=M(i,w,r),q+=r.length),$(i,w,re);var T=new S(E,X?l.tokenize(W,X):W,Pe,W);if(L=M(i,w,T),u&&M(i,L,u),re>1){var O={cause:E+","+I,reach:y};k(o,i,c,L.prev,q,O),b&&O.reach>b.reach&&(b.reach=O.reach)}}}}}}function G(){var o={value:null,prev:null,next:null},i={value:null,prev:o,next:null};o.next=i,this.head=o,this.tail=i,this.length=0}function M(o,i,c){var d=i.next,h={value:c,prev:i,next:d};return i.next=h,d.prev=h,o.length++,h}function $(o,i,c){for(var d=i.next,h=0;h/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},e.languages.markup.tag.inside["attr-value"].inside.entity=e.languages.markup.entity,e.languages.markup.doctype.inside["internal-subset"].inside=e.languages.markup,e.hooks.add("wrap",function(s){s.type==="entity"&&(s.attributes.title=s.content.replace(/&/,"&"))}),Object.defineProperty(e.languages.markup.tag,"addInlined",{value:function(n,a){var f={};f["language-"+a]={pattern:/(^$)/i,lookbehind:!0,inside:e.languages[a]},f.cdata=/^$/i;var l={"included-cdata":{pattern://i,inside:f}};l["language-"+a]={pattern:/[\s\S]+/,inside:e.languages[a]};var S={};S[n]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return n}),"i"),lookbehind:!0,greedy:!0,inside:l},e.languages.insertBefore("markup","cdata",S)}}),Object.defineProperty(e.languages.markup.tag,"addAttribute",{value:function(s,n){e.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+s+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:e.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),e.languages.html=e.languages.markup,e.languages.mathml=e.languages.markup,e.languages.svg=e.languages.markup,e.languages.xml=e.languages.extend("markup",{}),e.languages.ssml=e.languages.xml,e.languages.atom=e.languages.xml,e.languages.rss=e.languages.xml,function(s){var n=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+n.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+n.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+n.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+n.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:n,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var a=s.languages.markup;a&&(a.tag.addInlined("style","css"),a.tag.addAttribute("style","css"))}(e),e.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},e.languages.javascript=e.languages.extend("clike",{"class-name":[e.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+(/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source)+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),e.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,e.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:e.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:e.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:e.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:e.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:e.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),e.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:e.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),e.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),e.languages.markup&&(e.languages.markup.tag.addInlined("script","javascript"),e.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),e.languages.js=e.languages.javascript,function(){if(typeof e>"u"||typeof document>"u")return;Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var s="Loading…",n=function(P,F){return"✖ Error "+P+" while fetching file: "+F},a="✖ Error: File does not exist or is empty",f={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},l="data-src-status",S="loading",A="loaded",k="failed",G="pre[data-src]:not(["+l+'="'+A+'"]):not(['+l+'="'+S+'"])';function M(P,F,D){var o=new XMLHttpRequest;o.open("GET",P,!0),o.onreadystatechange=function(){o.readyState==4&&(o.status<400&&o.responseText?F(o.responseText):o.status>=400?D(n(o.status,o.statusText)):D(a))},o.send(null)}function $(P){var F=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(P||"");if(F){var D=Number(F[1]),o=F[2],i=F[3];return o?i?[D,Number(i)]:[D,void 0]:[D,D]}}e.hooks.add("before-highlightall",function(P){P.selector+=", "+G}),e.hooks.add("before-sanity-check",function(P){var F=P.element;if(F.matches(G)){P.code="",F.setAttribute(l,S);var D=F.appendChild(document.createElement("CODE"));D.textContent=s;var o=F.getAttribute("data-src"),i=P.language;if(i==="none"){var c=(/\.(\w+)$/.exec(o)||[,"none"])[1];i=f[c]||c}e.util.setLanguage(D,i),e.util.setLanguage(F,i);var d=e.plugins.autoloader;d&&d.loadLanguages(i),M(o,function(h){F.setAttribute(l,A);var b=$(F.getAttribute("data-range"));if(b){var E=h.split(/\r\n?|\n/g),v=b[0],I=b[1]==null?E.length:b[1];v<0&&(v+=E.length),v=Math.max(0,Math.min(v-1,E.length)),I<0&&(I+=E.length),I=Math.max(0,Math.min(I,E.length)),h=E.slice(v,I).join(` -`),F.hasAttribute("data-start")||F.setAttribute("data-start",String(v+1))}D.textContent=h,e.highlightElement(D)},function(h){F.setAttribute(l,k),D.textContent=h})}}),e.plugins.fileHighlight={highlight:function(F){for(var D=(F||document).querySelectorAll(G),o=0,i;i=D[o++];)e.highlightElement(i)}};var J=!1;e.fileHighlight=function(){J||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),J=!0),e.plugins.fileHighlight.highlight.apply(this,arguments)}}()})($e);var Ne=$e.exports;class ve{static close(){var t;(t=document.getElementById("jsonEditor"))==null||t.remove()}static show(t,e,s=!0){var M;const n=document.getElementById("tools");if(!n)return;(M=document.getElementById("jsonEditor"))==null||M.remove();const a=document.createElement("div"),f=document.createElement("div"),l=document.createElement("div"),S=document.createElement("div"),A=document.createElement("div");n.appendChild(a),a.appendChild(f),a.appendChild(A),a.appendChild(S),a.appendChild(l),a.id="jsonEditor",A.setAttribute("class","console-text"),f.textContent=this.divLine,l.textContent=this.divLine,Ue(S,async $=>this.update(t,$,A,e,s)).updateCode(t)}static async update(t,e,s,n,a){if(e.textContent===null)return;let f=a?e.textContent:t;if(e.innerHTML=Ne.highlight(f,Ne.languages.js,"js"),f===t)return;let l=await n(f);s.textContent=l.messgae}}m(ve,"divLine","--------------------------------------------------------------------------------------------------");const oe=class oe{static async toggleConfigurationDisplay(t){if(t){const e=await oe.getAboutJson();ve.show(e,async s=>oe.updateStatus,!1)}else ve.close()}static async getAbout(){if(this.about!==void 0)return this.about;let t=await this.getAboutJson();try{return JSON.parse(t)}catch(e){const s="Invalid JSON string: "+e;return console.error(s),this.about=[]}}static async getAboutJson(){if(this.aboutJson!==void 0)return this.aboutJson;const t="dist/about.json",e="/public/about.json";return this.aboutJson=await pe.getFile(t),this.aboutJson===""?await pe.getFile(e):this.aboutJson}};m(oe,"aboutJson"),m(oe,"about"),m(oe,"updateStatus",{success:!1,messgae:"Not editable."});let Te=oe;class Ve{static async toggleLessonsDisplay(t){if(t){const e=await ce.getConfigurationJson();let s=async n=>ce.updateConfigurationJson(n);await ve.show(e,s)}else ve.close()}}class ne{static setupTools(){var t,e,s,n,a;(t=document.getElementById("startTrainingBtn"))==null||t.addEventListener("click",()=>ne.startTraining().then()),(e=document.getElementById("startTestingBtn"))==null||e.addEventListener("click",()=>ne.startTesting().then()),(s=document.getElementById("zenGardenBtn"))==null||s.addEventListener("click",()=>ne.zenGardenOnOff().then()),(n=document.getElementById("configurationBtn"))==null||n.addEventListener("click",()=>ne.configurationOnOff().then()),(a=document.getElementById("aboutBtn"))==null||a.addEventListener("click",()=>ne.configOnOff().then())}static async startTraining(){Z.stopTester(),B.clearScreen(),await Z.train(),await ne.startTesting()}static async startTesting(){Z.stopTrainer(),B.clearScreen(),await Z.test()}static async configOnOff(){this.btnOff("configurationBtn","configuration",t=>Ve.toggleLessonsDisplay(t)),this.btnOnOff("aboutBtn","about",t=>Te.toggleConfigurationDisplay(t))}static async configurationOnOff(){this.btnOff("aboutBtn","about",t=>Te.toggleConfigurationDisplay(t)),this.btnOnOff("configurationBtn","configuration",t=>Ve.toggleLessonsDisplay(t))}static async zenGardenOnOff(){this.btnOnOff("zenGardenBtn","zen garden",t=>C.zenGardenOn=t)}static async btnOff(t,e,s){let n=document.getElementById(t);n==null||n.setAttribute("value",e+" off"),s(!1)}static async btnOnOff(t,e,s){let n=document.getElementById(t);(n==null?void 0:n.getAttribute("value"))!==e+" off"?(n==null||n.setAttribute("value",e+" off"),s(!1)):(n==null||n.setAttribute("value",e+" on"),s(!0))}}ne.setupTools();ne.startTesting().then(); diff --git a/dist/configuration_1.json b/dist/configuration_1.json new file mode 100644 index 0000000..b624603 --- /dev/null +++ b/dist/configuration_1.json @@ -0,0 +1,57 @@ +{ + "info":[ + "This configuration is editable.", + "The explanation of this file properties can be found in the 'about' section." + ], + "usePretrainedDataWhileTesting": true, + "basicTrainerConfig":{ + "learningRate": 0.1, + "discount": 0.9, + "trainingBachCount": 10, + "lessonsToGenerate": 100 + }, +"lessons": [ + { + "lesson": 1, + "goals": [1, 4], + "lessonsToGenerate": 200 + }, + { + "lesson": 2, + "goals": [2, 3], + "startPositions": [2, 5, 3,6], + "lockedElements": [1, 4], + "lessonsToGenerate": 200 + }, + { + "lesson": 3, + "goals": [5, 8], + "startPositions": [6, 7], + "lockedElements": [1, 2, 3, 4] + }, + { + "lesson": 4, + "goals": [6, 7], + "startPositions": [6, 9, 7, 12], + "lockedElements": + [1, 2, 3, 4, + 5, 8] + }, + { + "lesson": 5, + "goals": [9, 10, 13, 14], + "lockedElements": + [1, 2, 3, 4, + 5, 6, 7, 8] + }, + { + "lesson": 6, + "goals": [11, 15, 12], + "lockedElements": + [1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, + 13, 14 ] + } + ] +} \ No newline at end of file diff --git a/dist/index.html b/dist/index.html index bb77e96..f9283c8 100644 --- a/dist/index.html +++ b/dist/index.html @@ -5,7 +5,7 @@ puzzle 15 ml - + diff --git a/index.html b/index.html index 786139c..d041c8a 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ puzzle 15 ml - + diff --git a/public/configuration_1.json b/public/configuration_1.json new file mode 100644 index 0000000..b624603 --- /dev/null +++ b/public/configuration_1.json @@ -0,0 +1,57 @@ +{ + "info":[ + "This configuration is editable.", + "The explanation of this file properties can be found in the 'about' section." + ], + "usePretrainedDataWhileTesting": true, + "basicTrainerConfig":{ + "learningRate": 0.1, + "discount": 0.9, + "trainingBachCount": 10, + "lessonsToGenerate": 100 + }, +"lessons": [ + { + "lesson": 1, + "goals": [1, 4], + "lessonsToGenerate": 200 + }, + { + "lesson": 2, + "goals": [2, 3], + "startPositions": [2, 5, 3,6], + "lockedElements": [1, 4], + "lessonsToGenerate": 200 + }, + { + "lesson": 3, + "goals": [5, 8], + "startPositions": [6, 7], + "lockedElements": [1, 2, 3, 4] + }, + { + "lesson": 4, + "goals": [6, 7], + "startPositions": [6, 9, 7, 12], + "lockedElements": + [1, 2, 3, 4, + 5, 8] + }, + { + "lesson": 5, + "goals": [9, 10, 13, 14], + "lockedElements": + [1, 2, 3, 4, + 5, 6, 7, 8] + }, + { + "lesson": 6, + "goals": [11, 15, 12], + "lockedElements": + [1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, + 13, 14 ] + } + ] +} \ No newline at end of file diff --git a/src/game-15-reconstruction/configuration/LessonProducer.ts b/src/game-15-reconstruction/configuration/LessonProducer.ts deleted file mode 100644 index af19917..0000000 --- a/src/game-15-reconstruction/configuration/LessonProducer.ts +++ /dev/null @@ -1,253 +0,0 @@ -import { Utils } from '../utils/Utils'; -import { StateShuffle } from './StateShuffle'; -import { Lesson, ConfigurationLoader } from './ConfigLoader'; - -export class LessonProducer { - private goals: number[]; - private lockedStateElements: number[]; - private state: number[]; - private episodesToTrain: number; - private readonly lessonNb: number; - - public static readonly stateDone: number[] = [ - 1, 2, 3, 4, - 5, 6, 7, 8, - 9, 10, 11, 12, - 13, 14, 15, -1 - ]; - - private constructor(lessonNb: number) { - this.lessonNb = lessonNb; - this.goals = []; - this.lockedStateElements = []; - this.state = []; - this.episodesToTrain = 0; - } - - public getState() { - return this.state; - } - - public getGoals() { - return this.goals; - } - - public getLockedStateElements() { - return this.lockedStateElements; - } - - public getEpisodesToTrain() { - return this.episodesToTrain; - } - - public static async getLessonProducersFromJson(): Promise { - let config = await ConfigurationLoader.getConfiguration(); - if (config.lessons === undefined) return []; - const defaultEpisdeCount = config.basicTrainerConfig?.lessonsToGenerate ?? 100; - return config.lessons.map((e, i) => LessonProducer.from(e, i, defaultEpisdeCount)); - } - - private static from(lesson: Lesson, lessonNb: number, defaultEpisdeCount: number): LessonProducer { - const stateProducer = new LessonProducer(lessonNb); - stateProducer.goals = lesson.goals; - stateProducer.lockedStateElements = lesson.lockedElements !== undefined ? lesson.lockedElements : []; - stateProducer.episodesToTrain = lesson.lessonsToGenerate !== undefined ? lesson.lessonsToGenerate : defaultEpisdeCount; - stateProducer.state = StateShuffle.shuffleForTraining(stateProducer.lockedStateElements); - if (lesson.startPositions === undefined) return stateProducer; - return LessonProducer.shuffleFreeCellStarPosition(stateProducer, lesson.startPositions.map(e => e - 1)); - } - - public static generateLessons0(): LessonProducer[] { - return [ - LessonProducer.state1(0), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducer(2, 1), [1, 4]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducer(3, 2), [2, 5]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_3_4(3), [3, 6]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducer(5, 4), [6, 7]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducer(6, 5), [5, 8]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducer(7, 6), [6, 9]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_7_8(7), [8, 11]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_9_13(8), [10, 11]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_10__15(9), [9, 13]), - LessonProducer.state12(10) - ]; - } - - public static generateLessonsV1(): LessonProducer[] { - return [ - LessonProducer.createStateProducerForGoals_1_2(0), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_3_4(1), [2, 3, 4]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducer(5, 2), [6, 7]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducer(6, 3), [5, 8]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducer(7, 4), [6, 9]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_7_8(5), [8, 11]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_9_13(6), [10, 11]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_10__15(7), [9, 13]), - LessonProducer.state12(8) - ]; - } - - public static generateLessons(): LessonProducer[] { - return [ - LessonProducer.createStateProducerForGoals_1_2(0), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_3_4(1), [2, 3, 4]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_5_6(2), [6, 7]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_7_8(3), [8, 9, 6]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_9_13(4), [10, 11]), - LessonProducer.shuffleFreeCellStarPosition(LessonProducer.createStateProducerForGoals_10__15(5), [9, 13]), - LessonProducer.state12(6) - ]; - } - - private static createStateProducerForGoals_1_2(lessonNb: number): LessonProducer { - const o = new LessonProducer(lessonNb); - o.goals = [1, 2]; - o.lockedStateElements = []; - o.state = [...LessonProducer.stateDone]; - o.episodesToTrain = 100; - LessonProducer.shuffle(o, o.lockedStateElements); - return o; - } - - private static state1(lessonNb: number): LessonProducer { - return LessonProducer.createStateProducer(1, lessonNb); - } - - private static createStateProducerForGoals_3_4(lessonNb: number): LessonProducer { - const o = new LessonProducer(lessonNb); - o.goals = [3, 4]; - o.lockedStateElements = [1, 2]; - o.state = [...LessonProducer.stateDone]; - o.episodesToTrain = 100; - LessonProducer.shuffle(o, [1, 2, 3]); - return o; - } - - private static createStateProducerForGoals_5_6(lessonNb: number): LessonProducer { - const o = new LessonProducer(lessonNb); - o.goals = [5, 6]; - o.lockedStateElements = [1, 2, 3, 4]; - o.state = [...LessonProducer.stateDone]; - o.episodesToTrain = 100; - LessonProducer.shuffle(o, o.lockedStateElements); - return o; - } - - private static createStateProducer(goal: number, lessonNb: number): LessonProducer { - const o = new LessonProducer(lessonNb); - o.goals = [goal]; - o.lockedStateElements = Array.from({ length: goal - 1 }, (_, i) => i + 1); - o.state = [...LessonProducer.stateDone]; - o.episodesToTrain = 100; - LessonProducer.shuffle(o, o.lockedStateElements); - return o; - } - - private static shuffleFreeCellStarPosition(stateProducer: LessonProducer, availableFreeCellIndexes: number[]): LessonProducer { - const newFreeCellIndex = Utils.shuffleArray(availableFreeCellIndexes)[0] - const oldFreeCellIndex = stateProducer.state.indexOf(-1); - const v = stateProducer.state[newFreeCellIndex]; - stateProducer.state[newFreeCellIndex] = -1; - stateProducer.state[oldFreeCellIndex] = v; - return stateProducer; - } - - private static createStateProducerForGoals_7_8(lessonNb: number): LessonProducer { - const o = new LessonProducer(lessonNb); - o.goals = [7, 8]; - o.lockedStateElements = [1, 2, 3, 4, 5, 6]; - o.state = [...LessonProducer.stateDone]; - o.episodesToTrain = 100; - LessonProducer.shuffle(o, [1, 2, 3, 4, 5, 6, 7]); - return o; - } - - private static createStateProducerForGoals_9_13(lessonNb: number): LessonProducer { - const o = new LessonProducer(lessonNb); - o.goals = [9, 13]; - o.lockedStateElements = [1, 2, 3, 4, 5, 6, 7, 8]; - o.state = [...LessonProducer.stateDone]; - o.episodesToTrain = 100; - LessonProducer.shuffle(o, o.lockedStateElements); - return o; - } - - private static shufleSteps = 100; - - private static createStateProducerForGoals_10__15(lessonNb: number): LessonProducer { - const o = new LessonProducer(lessonNb); - o.goals = [10, 11, 14, 15]; - o.lockedStateElements = [ - 1, 2, 3, 4, - 5, 6, 7, 8, - 9, - 13 - ]; - o.state = StateShuffle.shuffle([...LessonProducer.stateDone], o.lockedStateElements, this.shufleSteps); - o.episodesToTrain = 100; - return o; - } - - private static state12(lessonNb: number): LessonProducer { - const o = new LessonProducer(lessonNb); - o.goals = [12]; - o.lockedStateElements = [ - 1, 2, 3, 4, - 5, 6, 7, 8, - 9, 10, 11, - 13, 14, 15 - ]; - o.state = StateShuffle.shuffle([...LessonProducer.stateDone], o.lockedStateElements, this.shufleSteps); - o.episodesToTrain = 10; - return o; - } - - public isLockedIndex(index: number): boolean { - return this.lockedStateElements.includes(index + 1); - } - - private static shuffle(o: LessonProducer, lockedStateElements: number[]): void { - let v0 = o.state.filter(e => !lockedStateElements.includes(e)); - v0 = Utils.shuffleArray(v0); - o.state = [...lockedStateElements, ...v0]; - } - - // private static shuffle_vx(lessonProducer: LessonProducer): void { - // // lessonProducer.getLockedStateElements(); - - // /* - // const boardStateTerminal= - // [1, 2, 3, 4, - // 5, 6, 7, 8, - // 9, 10, 11, 12 - // 13, 14, 15 -1] - - // */ - - // let lockedStateElements = lessonProducer.getLockedStateElements(); - - // LessonProducer.stateDone.filter(e => lockedStateElements.findIndex(x => x === e) != -1) - // const fixedStateIndexes = lessonProducer.getLockedStateElements().map(e => e - 1); - - // let v0 = lessonProducer.state.filter(e => !lockedStateElements.includes(e)); - // v0 = Utils.shuffleArray(v0); - // lessonProducer.state = [...lockedStateElements, ...v0]; - // } - - //old .. biski nesamone kad .. generuoju auksciau .. o poto environment'e vel is naujo ta pati darau - public resetStateV0(): void { - const o = LessonProducer.generateLessons()[this.lessonNb]; - this.goals = [...o.goals]; - this.lockedStateElements = [...o.lockedStateElements]; - this.state = [...o.state]; - } - - // ~ .. biski nesamone kad .. generuoju auksciau .. o poto environment'e vel is naujo ta pati darau - public async resetState(): Promise { - const stateProducers = await LessonProducer.getLessonProducersFromJson(); - const o = stateProducers[this.lessonNb]; - this.goals = [...o.goals]; - this.lockedStateElements = [...o.lockedStateElements]; - this.state = [...o.state]; - } -} diff --git a/src/game-15-reconstruction/environment/Environment.ts b/src/game-15-reconstruction/environment/Environment.ts index 137f430..0973037 100644 --- a/src/game-15-reconstruction/environment/Environment.ts +++ b/src/game-15-reconstruction/environment/Environment.ts @@ -2,13 +2,13 @@ import { Action } from './Action'; import { Pair } from '../utils/Pair'; import { Utils } from '../utils/Utils'; import { GameUtils } from './GameUtils'; +import { LessonProducer } from './LessonProducer'; import { EnvironmentState } from './EnvironmentState'; -import { LessonProducer } from '../configuration/LessonProducer'; import { EnvironmentActionResult } from './EnvironmentActionResult'; export class Environment { private state: EnvironmentState; - private static stateProducer: LessonProducer; + private static lessonProducer: LessonProducer; private goals: number[]; public reverseAction: Action | null = null; @@ -18,13 +18,12 @@ export class Environment { private smallCircleAction2: Action[] = []; private circleAction: Action[] = []; - constructor(stateProducer: LessonProducer) { - Environment.stateProducer = stateProducer; - - Environment.stateProducer.resetState().then(); - const state = Environment.stateProducer.getState(); - this.goals = Environment.stateProducer.getGoals(); - this.state = new EnvironmentState(state, Environment.stateProducer); + constructor(lessonProducer: LessonProducer) { + Environment.lessonProducer = lessonProducer; + Environment.lessonProducer.shuffleBoardState(); + const state = Environment.lessonProducer.getState(); + this.goals = Environment.lessonProducer.getGoals(); + this.state = new EnvironmentState(state, Environment.lessonProducer); } public static isTerminalSuccess(state: EnvironmentState): boolean { @@ -47,19 +46,19 @@ export class Environment { } public getInitState(): EnvironmentState { - Environment.stateProducer.resetState(); - const state = Environment.stateProducer.getState(); - this.goals = Environment.stateProducer.getGoals(); - this.state = new EnvironmentState(state, Environment.stateProducer); + Environment.lessonProducer.shuffleBoardState(); + const state = Environment.lessonProducer.getState(); + this.goals = Environment.lessonProducer.getGoals(); + this.state = new EnvironmentState(state, Environment.lessonProducer); return this.state; } public executeAction(state0: EnvironmentState, action: Action): EnvironmentActionResult { const newState = GameUtils.makeMove(state0.getBoardState(), action); - const environmentState = new EnvironmentState(newState, Environment.stateProducer); + const environmentState = new EnvironmentState(newState, Environment.lessonProducer); let isTerminal = Environment._isTerminalSuccess(newState, this.goals); - this.state = new EnvironmentState(newState, Environment.stateProducer); + this.state = new EnvironmentState(newState, Environment.lessonProducer); let r: number = NaN; @@ -75,7 +74,7 @@ export class Environment { } const io = this.state.getBoardState().indexOf(-1); - if (Environment.stateProducer.isLockedIndex(io)) { + if (Environment.lessonProducer.isLockedIndex(io)) { isTerminal = true; r = -1; } diff --git a/src/game-15-reconstruction/environment/EnvironmentState.ts b/src/game-15-reconstruction/environment/EnvironmentState.ts index 0e5e7f6..18d73c2 100644 --- a/src/game-15-reconstruction/environment/EnvironmentState.ts +++ b/src/game-15-reconstruction/environment/EnvironmentState.ts @@ -1,4 +1,4 @@ -import { LessonProducer } from '../configuration/LessonProducer'; +import { LessonProducer } from './LessonProducer'; export interface EnvironmentStateI { boardState: number[]; diff --git a/src/game-15-reconstruction/environment/GameUtils.ts b/src/game-15-reconstruction/environment/GameUtils.ts index 8988b4e..71ef4ce 100644 --- a/src/game-15-reconstruction/environment/GameUtils.ts +++ b/src/game-15-reconstruction/environment/GameUtils.ts @@ -24,6 +24,7 @@ export class GameUtils { if (i1 > 15) { console.log(state) console.log(action) + GameUtils.logBoardState(state); throw new Error('i1 > 15'); } @@ -71,7 +72,8 @@ export class GameUtils { } private static contains(fixedStateIndexes: number[], x: number, y: number): boolean { - return fixedStateIndexes.includes(this.getIndex(x, y)); + const index = this.getIndex(x, y); + return fixedStateIndexes.includes(index); } @@ -82,6 +84,22 @@ export class GameUtils { else return this.__getStateAsString(boardState, goals); } + public static logBoardState(boardState: number[]) { + const state = Array.from({ length: 16 }, (_, e) => { + let v: string; + const o = boardState[e]; + v = o.toString(); + v += "\t"; + if (e !== 0 && (e + 1) % 4 === 0) { + v += "\n"; + } + return v; + }).join('') + + console.log(state); + + } + private static __getStateAsString(state: number[], goals: number[]): string { return Array.from({ length: 16 }, (_, e) => { let v: string; diff --git a/src/game-15-reconstruction/environment/LessonProducer.ts b/src/game-15-reconstruction/environment/LessonProducer.ts new file mode 100644 index 0000000..e4fe51c --- /dev/null +++ b/src/game-15-reconstruction/environment/LessonProducer.ts @@ -0,0 +1,83 @@ +import { Utils } from '../utils/Utils'; +import { StateShuffle } from './StateShuffle'; +import { Lesson, ConfigurationLoader } from '../configuration/ConfigLoader'; + +export class LessonProducer { + // private goals: number[]; + // private lockedStateElements: number[]; + private boardState: number[]; + private episodesToTrain: number; + private lesson: Lesson; + + public static readonly stateDone: number[] = [ + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, -1 + ]; + + private constructor(lesson: Lesson) { + // this.goals = []; + this.boardState = []; + // this.lockedStateElements = []; + this.lesson = lesson; + this.episodesToTrain = 0; + } + + public getState() { + return this.boardState; + } + + public getGoals() { + return this.lesson.goals; + } + + public getLockedStateElements(): number[] { + return this.lesson.lockedElements ?? []; + } + + public getEpisodesToTrain() { + return this.episodesToTrain; + } + + public static async getLessonProducersFromJson(): Promise { + let config = await ConfigurationLoader.getConfiguration(); + if (config.lessons === undefined) return []; + const defaultEpisdeCount = config.basicTrainerConfig?.lessonsToGenerate ?? 100; + return config.lessons + .sort((o1, o2) => o1.lesson - o2.lesson) + .map(e => LessonProducer.from(e, defaultEpisdeCount)); + } + + private static from(lesson: Lesson, defaultEpisdeCount: number): LessonProducer { + const lessonProducer = new LessonProducer(lesson); + lessonProducer.lesson = lesson; + + // lessonProducer.goals = lesson.goals; + // lessonProducer.lockedStateElements = lesson.lockedElements !== undefined ? lesson.lockedElements : []; + lessonProducer.episodesToTrain = lesson.lessonsToGenerate !== undefined ? lesson.lessonsToGenerate : defaultEpisdeCount; + + lessonProducer.shuffleBoardState(); + return lessonProducer; + } + + private static shuffleFreeCellStarPosition(stateProducer: LessonProducer, availableFreeCellIndexes: number[]): LessonProducer { + const newFreeCellIndex = Utils.shuffleArray(availableFreeCellIndexes)[0] + const oldFreeCellIndex = stateProducer.boardState.indexOf(-1); + const v = stateProducer.boardState[newFreeCellIndex]; + stateProducer.boardState[newFreeCellIndex] = -1; + stateProducer.boardState[oldFreeCellIndex] = v; + return stateProducer; + } + + public isLockedIndex(index: number): boolean { + return this.getLockedStateElements().includes(index + 1); + } + + public shuffleBoardState(): void { + const lockedElements = this.getLockedStateElements(); + this.boardState = StateShuffle.shuffleForTraining(lockedElements); + if (this.lesson?.startPositions === undefined) return; + LessonProducer.shuffleFreeCellStarPosition(this, this.lesson.startPositions.map(e => e - 1)); + } +} diff --git a/src/game-15-reconstruction/configuration/StateShuffle.ts b/src/game-15-reconstruction/environment/StateShuffle.ts similarity index 100% rename from src/game-15-reconstruction/configuration/StateShuffle.ts rename to src/game-15-reconstruction/environment/StateShuffle.ts diff --git a/src/game-15-reconstruction/qtable/EpisodeTrainer.ts b/src/game-15-reconstruction/qtable/EpisodeTrainer.ts index e04dc9c..4bdef04 100644 --- a/src/game-15-reconstruction/qtable/EpisodeTrainer.ts +++ b/src/game-15-reconstruction/qtable/EpisodeTrainer.ts @@ -8,14 +8,14 @@ import { GameUtils } from '../environment/GameUtils'; import { ConsoleUtils } from '../utils/ConsoleUtils'; import { ExperienceRecord } from './ExperienceRecord'; import { Environment } from '../environment/Environment'; -import { LessonProducer } from '../configuration/LessonProducer'; +import { LessonProducer } from '../environment/LessonProducer'; export class EpisodeRunner { public static experience: Set = new Set(); private maxExperienceSize = 2000; public async train( - stateProducer: LessonProducer, + lessonProducer: LessonProducer, discount: number, learningRate: number, trainerInfo: string, @@ -26,7 +26,7 @@ export class EpisodeRunner { // //---------------------------------- const qTable = EntryPoint.qTable; - const environment = new Environment(stateProducer); + const environment = new Environment(lessonProducer); environment.reset(); let state0 = environment.getInitState(); @@ -42,10 +42,16 @@ export class EpisodeRunner { step++; if (Environment._isTerminalSuccess(state0.getBoardState(), state0.getGoals())) break; let action: Action; - const possibleActions = GameUtils.getPossibleActions(state0); - if (environment.reverseAction !== null) { - const index = possibleActions.indexOf(environment.reverseAction); - possibleActions.splice(index, 1); // Remove reverse action + let possibleActions = GameUtils.getPossibleActions(state0).filter(e => e !== environment.reverseAction); + + if (possibleActions.length === 0) { + GameUtils.logBoardState(state0.boardState); + possibleActions = GameUtils.getPossibleActions(state0) + console.log('environment.reverseAction', environment.reverseAction); + console.log('possibleActions 1', possibleActions); + possibleActions = possibleActions.filter(e => e !== environment.reverseAction); + console.log('possibleActions 2', possibleActions); + throw new Error('possibleActions.length === 0'); } if (Math.random() < epsilon) { // Explore diff --git a/src/game-15-reconstruction/qtable/QTableRow.ts b/src/game-15-reconstruction/qtable/QTableRow.ts index d4d8fe3..432b3e1 100644 --- a/src/game-15-reconstruction/qtable/QTableRow.ts +++ b/src/game-15-reconstruction/qtable/QTableRow.ts @@ -38,6 +38,10 @@ export class QTableRow { let possibleActions = GameUtils.getPossibleActions(this.state); possibleActions = possibleActions.filter(action => action !== reverseAction); if (possibleActions.length === 0) { + + console.log('reverseAction', reverseAction) + GameUtils.logBoardState(this.state.boardState); + ConsoleUtils.prntErrorMsg('possibleActions.length === 0, there allways must be some action to go around.. need to debug.') throw new Error('possibleActions.length === 0, there allways must be some action to go around.. need to debug.'); } diff --git a/src/game-15-reconstruction/qtable/Tester.ts b/src/game-15-reconstruction/qtable/Tester.ts index 247a56b..55674d7 100644 --- a/src/game-15-reconstruction/qtable/Tester.ts +++ b/src/game-15-reconstruction/qtable/Tester.ts @@ -2,12 +2,12 @@ import { Utils } from '../utils/Utils'; import { EntryPoint } from './EntryPoint'; import { Action } from '../environment/Action'; import { QTableUpdater } from './QTableUpdater'; -import { GameUtils } from '../environment/GameUtils'; import { ConsoleUtils } from '../utils/ConsoleUtils'; -import { StateShuffle } from '../configuration/StateShuffle'; +import { GameUtils } from '../environment/GameUtils'; import { Environment } from '../environment/Environment'; -import { LessonProducer } from '../configuration/LessonProducer'; +import { StateShuffle } from '../environment/StateShuffle'; import { PretrainedDataLoader } from './QTableActionsLoader'; +import { LessonProducer } from '../environment/LessonProducer'; import { EnvironmentState } from '../environment/EnvironmentState'; import { ConfigurationLoader } from '../configuration/ConfigLoader'; diff --git a/src/game-15-reconstruction/qtable/Trainer.ts b/src/game-15-reconstruction/qtable/Trainer.ts index e7af34a..8014659 100644 --- a/src/game-15-reconstruction/qtable/Trainer.ts +++ b/src/game-15-reconstruction/qtable/Trainer.ts @@ -1,6 +1,6 @@ import { TesterEntryPoint } from './Tester'; import { Semaphore } from '../utils/Semaphore'; -import { LessonProducer } from '../configuration/LessonProducer'; +import { LessonProducer } from '../environment/LessonProducer'; import { EpisodeRunner as EpisodeTrainer } from './EpisodeTrainer'; import { ConfigurationLoader } from '../configuration/ConfigLoader';