From a73cc00c3307906541d5374637f1a79b53aae684 Mon Sep 17 00:00:00 2001 From: Eric Woodward Date: Fri, 6 Jun 2025 02:48:29 -0400 Subject: [PATCH] add maze of the minotaur --- package-lock.json | 8 ++- package.json | 2 +- site.config.json5 | 7 ++- .../webtoys/maze/assets/index-BwJAUWNN.css | 1 + .../webtoys/maze/assets/index-DsLgZhNW.js | 3 ++ src/assets/_root/webtoys/maze/index.html | 51 +++++++++++++++++++ src/assets/_root/webtoys/maze/vite.svg | 1 + src/assets/styles/styles.css | 7 +++ src/layouts/partials/bottom.ejs | 2 +- src/layouts/partials/top.ejs | 6 ++- src/pages/webtoys/index.md | 2 + .../journal/2024/04-27-one-night-on-wpm.md | 4 +- src/support/manifest.json.ejs | 2 +- 13 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 src/assets/_root/webtoys/maze/assets/index-BwJAUWNN.css create mode 100644 src/assets/_root/webtoys/maze/assets/index-DsLgZhNW.js create mode 100644 src/assets/_root/webtoys/maze/index.html create mode 100644 src/assets/_root/webtoys/maze/vite.svg diff --git a/package-lock.json b/package-lock.json index b6462cd..d8a62fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,19 @@ { "name": "iew-site", - "version": "0.11.0", + "version": "0.14.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "iew-site", - "version": "0.11.0", + "version": "0.14.0", "license": "MIT", "devDependencies": { "web-weevr": "git+ssh://git@git.itsericwoodward.com:eric/web-weevr.git" + }, + "engines": { + "node": ">=18", + "npm": ">=9" } }, "../../../Src/markdown-it-implicit-figures-video": { diff --git a/package.json b/package.json index eb3ae83..6ebcd4a 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iew-site", - "version": "0.13.0", + "version": "0.14.0", "description": "", "main": "index.js", "scripts": {}, diff --git a/site.config.json5 b/site.config.json5 index 900454c..9f9dc37 100644 --- a/site.config.json5 +++ b/site.config.json5 @@ -14,9 +14,11 @@ }, base_uri: "", + // csp: "default-src 'self' data: https://v8.js-dos.com 'unsafe-inline'; img-src 'self' https://*; media-src 'self' https://* data:; script-src 'self' https://v8.js-dos.com 'wasm-eval' 'unsafe-eval' 'unsafe-inline'; style-src 'self' https://v8.js-dos.com 'unsafe-inline'; worker-src 'self' blob:;", + csp: "default-src 'self' data: ; img-src 'self' https://*; media-src 'self' https://* data:;", robots: "index,follow", language: "en-us", - copyright: "Copyright 2014-2023 Eric Woodward, licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.", + copyright: "Copyright 2014-2025 Eric Woodward, licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.", basePath: "", uri: "https://www.itsericwoodward.com", comment_insert: "\n\ @@ -46,8 +48,11 @@ journalsPerPage: 5, srcPath: "src", outputPath: "out", + publishPath: "public", }, serve: { + authTypeUI: "basic", + handleStatic: true, port: 4997, shortCodeLink: "/q/", static404: "./public/errors/404.html", diff --git a/src/assets/_root/webtoys/maze/assets/index-BwJAUWNN.css b/src/assets/_root/webtoys/maze/assets/index-BwJAUWNN.css new file mode 100644 index 0000000..c9d22bc --- /dev/null +++ b/src/assets/_root/webtoys/maze/assets/index-BwJAUWNN.css @@ -0,0 +1 @@ +:root{font-family:system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:#ffffffde;background-color:#242424;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}body{margin:0;display:flex;place-items:center;min-width:320px;min-height:100vh;font-size:16px}h1{font-size:3.2em;line-height:1.1}h4,h5{margin:1rem 0}#app{align-items:center;display:flex;flex-direction:column;flex-wrap:wrap;justify-content:center;margin:0 auto;max-width:800px;position:relative;text-align:center;width:100%}#app-controls-window{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;grid-gap:.5rem;margin-top:.5rem}#app-controls-window>button{grid-column:span 2}#app-controls-window>button:first-child,#app-controls-window>button:last-child{grid-column:2 / span 2}#app-interface-window{display:flex;flex-basis:40%;flex-direction:column;font-size:16px;order:3}#app-inventory-controls{display:flex;flex-direction:row;gap:.5rem;width:100%}#app-inventory-controls select{font-size:16px;width:15rem}#app-maze-window{flex-basis:60%;order:1}#app-modal{background-color:#1b1e1fde;border-radius:4px;left:50%;position:fixed;top:50%;transform:translate(-50%,-50%);visibility:hidden;width:20rem}#app-modal.show{transition:visibility .5s cubic-bezier(.075,.82,.165,1);visibility:visible}#app-modal-button{margin:3rem auto 1rem}#app-text-output{flex-basis:100%;order:2;padding:.5rem;width:95%}#mazeOutput{margin:0}.logo{height:6em;padding:1.5em;will-change:filter;transition:filter .3s}.logo:hover{filter:drop-shadow(0 0 2em #646cffaa)}.logo.vanilla:hover{filter:drop-shadow(0 0 2em #3178c6aa)}.card{padding:2em}.read-the-docs{color:#888}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#363c3e;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}@media (min-width: 30em) and (orientation: landscape){#app{align-items:start;flex-direction:row;justify-content:space-around}#app-interface-window{order:2}#app-text-output{order:3}} diff --git a/src/assets/_root/webtoys/maze/assets/index-DsLgZhNW.js b/src/assets/_root/webtoys/maze/assets/index-DsLgZhNW.js new file mode 100644 index 0000000..bf952df --- /dev/null +++ b/src/assets/_root/webtoys/maze/assets/index-DsLgZhNW.js @@ -0,0 +1,3 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))s(o);new MutationObserver(o=>{for(const l of o)if(l.type==="childList")for(const u of l.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&s(u)}).observe(document,{childList:!0,subtree:!0});function n(o){const l={};return o.integrity&&(l.integrity=o.integrity),o.referrerPolicy&&(l.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?l.credentials="include":o.crossOrigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function s(o){if(o.ep)return;o.ep=!0;const l=n(o);fetch(o.href,l)}})();var i=(e=>(e[e.North=0]="North",e[e.South=1]="South",e[e.East=2]="East",e[e.West=3]="West",e))(i||{}),x=(e=>(e.Key="KEY",e.Weapon="WEAPON",e))(x||{});const p="@",P="p",S="m",q="P",le="M",y=" ",v="H",ue="X",J=[{id:"mouthpiece",name:"Horn Mouthpiece",isCarried:!1,row:-1,col:-1,type:x.Key,areaToUse:v,useFailText:"You blow a raspberry into the mouthpiece.",useSuccessText:"The sound of the horn reverberates around the maze. The Minotaur is loosed!"},{id:"axe",name:"Magic Pickaxe",isCarried:!1,row:-1,col:-1,type:x.Weapon,useFailText:"You swing wildly in the air.",useSuccessText:"As the Minotaur lunges at you, you swing at him with the pickaxe. It strikes him and explodes as it hits him, stunning him."},{id:"spear",name:"Magic Spear",isCarried:!1,row:-1,col:-1,type:x.Weapon,useFailText:"You stab wildly at the air.",useSuccessText:"As the Minotaur lunges at you, you stab at him with the spear. It strikes him and explodes as it hits him, stunning him."}];let r,I,g,Y=!1,E,d,a,U,m="Welcome to Maze of the Minotaur!";const K=()=>m;let R="";const fe=()=>R,k=(e,t,n=1)=>{const s=n+1;return Math.abs(((a==null?void 0:a.row)??s)-e){r=Array.from({length:e},()=>Array.from({length:t},()=>p)),I=r.map(n=>n.map(s=>s===q||s===P)),g=r.map(n=>n.map(()=>!1)),E=Array.from(J)},Q=(e=0,t=0,n=!1)=>{let s=0;const o=[[0,0],[0,0],[0,0]],l=(c,z)=>{o[z][0]=c},u=c=>o[c][0],f=(c,z)=>o[z][1]=c,h=c=>o[c][1];for(;s=0,e>2&&r[e-2][t]===p&&(l(e-2,s),f(t,s),s++),e2&&r[e][t-2]===p&&(l(e,s),f(t-2,s),s++),t{if(!e||t===s&&n===o)return;const l=Math.floor((s-t)/2)+t,u=Math.floor((o-n)/2)+n;if(r[l][u]===p&&r[l+1][u]===y&&r[l][u-1]===p&&r[l][u+1]===p){r[l][u]=e;return}let f=u;do{let h=l-1;for(;h!==l;){if(r[h][f]===p&&r[h+1][f]===y&&r[h][f-1]===p&&r[h][f+1]===p){r[h][f]=e;return}h===t?h=Math.min(s,r.length-2):h=h-1}f===n?f=Math.min(o,r[l].length-2):f=f-1}while(f!==u)},de=()=>r.reduce((e,t,n)=>e.concat(t.map((s,o)=>s===y?{row:n,col:o}:null).filter(s=>s!==null)),[]),H=[y,q,v],A=(e,t)=>e>0&&(H.includes(r[e-1][t])||d.hasBeenSummoned&&r[e-1][t]===S),W=(e,t)=>ett>0&&H.includes(r[e][t-1]),pe=()=>{const{row:e,col:t}=d??{},n=Math.random()*2;if(k(e,t,2)||n>1){if(ea.row&&r[e-1][t]===y)return i.North;if(ta.col&&r[e][t-1]===y)return i.West}const s=[null];return A(e,t)&&s.push(i.North),W(e,t)&&s.push(i.South),L(e,t)&&s.push(i.East),T(e,t)&&s.push(i.West),s[Math.floor(Math.random()*s.length)]},me=e=>{if(e===null||!d.hasBeenSummoned)return;const{row:t,col:n}=d??{};if(typeof t>"u"||typeof n>"u")return;let s=t,o=n;if(e===i.North&&A(t,n)&&(s=t-1),e===i.South&&W(t,n)&&(s=t+1),e===i.East&&L(t,n)&&(o=n+1),e===i.West&&T(t,n)&&(o=n-1),s===t&&o===n)return;d.row=s,d.col=o;const l=k(s,o),u=k(s,o,3);l?m="The Minotaur lunges after you.":u&&(m="You hear the Minotaur's heavy steps and breathing.")},Z=e=>{if(typeof e>"u")return;const{row:t,col:n}=a??{};if(typeof t>"u"||typeof n>"u")return;let s=t,o=n;e===i.North&&A(t,n)&&(s=t-1),e===i.South&&W(t,n)&&(s=t+1),e===i.East&&L(t,n)&&(o=n+1),e===i.West&&T(t,n)&&(o=n-1),!(s===t&&o===n)&&(a.row=s,a.col=o,a.lastDirection=e)},ye=()=>{const{row:e,col:t}=a??{};I[e][t]=!0,e>0&&t>0&&(g[e-1][t-1]=!0,g[e-1][t]=!0,g[e][t-1]=!0,g[e][t]=!0,e{E=structuredClone(E).map(e=>!e.isCarried&&e.row===a.row&&e.col===a.col?(m=`You picked up a ${e.name}!`,{...e,isCarried:!0}):e),a.items=structuredClone(E).filter(({hasBeenUsed:e=!1,isCarried:t})=>t&&!e).map(({row:e,col:t,...n})=>({...n,row:a.row,col:a.col}))},V=()=>{if(!(a.row===d.row&&a.col===d.col))return;const e=a.items.filter(({type:t})=>t===x.Weapon);if(e.length){const t=e[0];m=t.useSuccessText,a.items=a.items.filter(({id:u})=>u!==t.id);const n=E.findIndex(({id:u})=>u===t.id);E[n].hasBeenUsed=!0;const{row:s,col:o,lastDirection:l}=a??{};for(let u=0;u<3;u++){let f=[];u===0?(l!==i.North&&A(s,o)&&f.push(i.North),l!==i.South&&W(s,o)&&f.push(i.South),l!==i.East&&L(s,o)&&f.push(i.East),l!==i.West&&T(s,o)&&f.push(i.West)):(l===i.North&&A(s,o)&&f.push(i.North),l===i.South&&W(s,o)&&f.push(i.South),l===i.East&&L(s,o)&&f.push(i.East),l===i.West&&T(s,o)&&f.push(i.West),l!==i.South&&A(s,o)&&f.push(i.North),l!==i.North&&W(s,o)&&f.push(i.South),l!==i.West&&L(s,o)&&f.push(i.East),l!==i.East&&T(s,o)&&f.push(i.West)),f.length&&Z(f[Math.floor(Math.random()*f.length)])}}else Y=!1,m="The Minotaur gored you. YOU HAVE DIED!",R="You Have Died!"},Ee=()=>{const{row:e,col:t}=a??{};r[e][t]===S&&d.hasBeenSummoned&&(Y=!1,m=`You escaped the Minotaur in ${U} turns. YOU HAVE WON!`,R="You Have Won!")},Se=()=>{U++,Ee(),V(),ye(),ge(),me(pe()),V()},F=e=>{Y&&(Z(e),Se())},ee=()=>F(i.North),te=()=>F(i.South),se=()=>F(i.East),oe=()=>F(i.West),Me=()=>{let e=de();E=Array.from(J).map(t=>{const n=Math.floor(Math.random()*e.length),{row:s,col:o}=e[n];return e=e.filter((l,u)=>u!==n),{...t,col:o,row:s}})},xe=(e=0,t=0)=>{ce(e*2+1,t*2+1);const n=Math.floor(Math.random()*(t*2-4))+2;let s=Math.floor(Math.random()*(t*2-1)+1);if(r[0][n]=S,d={hasBeenSummoned:!1,row:0,col:n},r[e*2][s]=P,a={items:[],row:e*2,col:s},Q(1,n,!0),he(v,e<4?0:e-4,t<4?0:t-4,e+5,t+5),Me(),r[e*2-1][s]!==y){for(r[e*2][s]=p;r[e*2-1][s]!==y;)s<2?s=r[0].length-3:s=s-1;r[e*2][s]=P,a={items:[],row:e*2,col:s}}return U=0,R="",m="Welcome to Maze of the Minotaur!",Y=!0,r},N=(e,t)=>`${e}`,ne=()=>r.map((e,t)=>e.map((n,s)=>{let o=n;const l=k(t,s);if(t===a.row&&s===a.col)return N(U%2?"🯅":"🯆","yellow");if(E.forEach(u=>{!u.isCarried&&u.row===t&&u.col===s&&(u.id==="spear"?o="↗":u.id==="axe"?o="⛏":u.id==="mouthpiece"?o="v":o="/",k(t,s)&&(m=`A ${u.name.toLocaleLowerCase()} lays on the ground nearby!`))}),n===v&&!d.hasBeenSummoned){let u;t===a.row&&s===a.col?m="You're in an empty room with a large horn. It appears to be missing its mouthpiece.":l&&(ta.row?u="south":s0&&(r[t-1][s]===p||r[t-1][s]===S&&!d.hasBeenSummoned)&&(u=!0),t0&&(r[t][s-1]===p||r[t][s-1]===S&&!d.hasBeenSummoned)&&(c=!0),(se.join("")).join(` +`),re=()=>((a==null?void 0:a.items)??[]).length===0?'':a.items.map(({id:e,name:t})=>``).join(` +`),ie=(e="")=>{if(!e)return!1;const t=a.items.find(({id:n})=>e===n);if(!t)return!1;if((t==null?void 0:t.type)===x.Key){if(r[a.row][a.col]===t.areaToUse)return m=t.useSuccessText,t.areaToUse===v&&(d.hasBeenSummoned=!0,a.items=a.items.filter(({id:n})=>n!=="mouthpiece"),E[E.findIndex(({id:n})=>n==="mouthpiece")].hasBeenUsed=!0),!0}else m=(t==null?void 0:t.useFailText)??"";return!1},Ae=document.body,b=document.getElementById("mazeOutput"),B=document.getElementById("app-text-output"),M=document.getElementById("inventoryOutput"),O=document.getElementById("inventory-useButton"),w=document.getElementById("app-modal"),_=document.getElementById("app-modal-result"),ae=()=>{xe(5,16),w==null||w.classList.remove("show"),b&&(b.innerHTML=ne()),B&&(B.innerText=K()),M&&(M.innerHTML=re())};ae();const C=()=>{b&&(b.innerHTML=ne()),B&&(B.innerText=K()),M&&(M.innerHTML=re());const e=fe();w&&_&&e&&(_.innerText=e,w.classList.add("show"))};O&&(O==null||O.addEventListener("click",()=>{M&&(ie((M==null?void 0:M.value)??"")?C():B&&(B.innerText=K()))}));Ae.addEventListener("keydown",e=>{e.key==="ArrowUp"||e.key.toLocaleUpperCase()==="N"?ee():e.key==="ArrowDown"||e.key.toLocaleUpperCase()==="S"?te():e.key==="ArrowLeft"||e.key.toLocaleUpperCase()==="W"?oe():e.key==="ArrowRight"||e.key.toLocaleUpperCase()==="E"?se():e.key.toLocaleUpperCase()==="H"&&ie("mouthpiece"),C()});var $;($=document.getElementById("goNorthButton"))==null||$.addEventListener("click",()=>{ee(),C()});var j;(j=document.getElementById("goSouthButton"))==null||j.addEventListener("click",()=>{te(),C()});var G;(G=document.getElementById("goWestButton"))==null||G.addEventListener("click",()=>{oe(),C()});var D;(D=document.getElementById("goEastButton"))==null||D.addEventListener("click",()=>{se(),C()});var X;(X=document.getElementById("app-modal-button"))==null||X.addEventListener("click",()=>{ae()}); diff --git a/src/assets/_root/webtoys/maze/index.html b/src/assets/_root/webtoys/maze/index.html new file mode 100644 index 0000000..2ed347c --- /dev/null +++ b/src/assets/_root/webtoys/maze/index.html @@ -0,0 +1,51 @@ + + + + + + + Maze of the Minotaur + + + + +
+
+

The Maze of the Minotaur

+

+			
+
+
Inventory
+
+ + +
+
+ + + + +
+
+
+
+

You Died!

+
+ +
+
+
+ + diff --git a/src/assets/_root/webtoys/maze/vite.svg b/src/assets/_root/webtoys/maze/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/src/assets/_root/webtoys/maze/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/styles/styles.css b/src/assets/styles/styles.css index acd888f..888476e 100644 --- a/src/assets/styles/styles.css +++ b/src/assets/styles/styles.css @@ -829,6 +829,13 @@ samp { padding: 0.25em 0.5em; } +.llmFun { + visibility: hidden; + position: fixed; + left: -999em; + max-height: 1px; +} + .magicDeck { display: grid; grid-template-columns: 1fr; diff --git a/src/layouts/partials/bottom.ejs b/src/layouts/partials/bottom.ejs index 22e04d9..1b93b3f 100644 --- a/src/layouts/partials/bottom.ejs +++ b/src/layouts/partials/bottom.ejs @@ -20,7 +20,7 @@ -