diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100755 index 0000000..dd36290 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1 @@ +(function(qr){"use strict";function jr(r,e,n){return n.a=r,n.f=e,n}function c(r){return jr(2,r,function(e){return function(n){return r(e,n)}})}function D(r){return jr(3,r,function(e){return function(n){return function(t){return r(e,n,t)}}})}function W(r){return jr(4,r,function(e){return function(n){return function(t){return function(a){return r(e,n,t,a)}}}})}function ar(r){return jr(5,r,function(e){return function(n){return function(t){return function(a){return function($){return r(e,n,t,a,$)}}}}})}function je(r){return jr(6,r,function(e){return function(n){return function(t){return function(a){return function($){return function(o){return r(e,n,t,a,$,o)}}}}}})}function pt(r){return jr(7,r,function(e){return function(n){return function(t){return function(a){return function($){return function(o){return function(i){return r(e,n,t,a,$,o,i)}}}}}}})}function ht(r){return jr(8,r,function(e){return function(n){return function(t){return function(a){return function($){return function(o){return function(i){return function(s){return r(e,n,t,a,$,o,i,s)}}}}}}}})}function dt(r){return jr(9,r,function(e){return function(n){return function(t){return function(a){return function($){return function(o){return function(i){return function(s){return function(f){return r(e,n,t,a,$,o,i,s,f)}}}}}}}}})}function u(r,e,n){return r.a===2?r.f(e,n):r(e)(n)}function v(r,e,n,t){return r.a===3?r.f(e,n,t):r(e)(n)(t)}function U(r,e,n,t,a){return r.a===4?r.f(e,n,t,a):r(e)(n)(t)(a)}function L(r,e,n,t,a,$){return r.a===5?r.f(e,n,t,a,$):r(e)(n)(t)(a)($)}function $n(r,e,n,t,a,$,o){return r.a===6?r.f(e,n,t,a,$,o):r(e)(n)(t)(a)($)(o)}function Su(r,e,n,t,a,$,o,i){return r.a===7?r.f(e,n,t,a,$,o,i):r(e)(n)(t)(a)($)(o)(i)}function gu(r,e,n,t,a,$,o,i,s){return r.a===8?r.f(e,n,t,a,$,o,i,s):r(e)(n)(t)(a)($)(o)(i)(s)}function tv(r,e,n,t,a,$,o,i,s,f){return r.a===9?r.f(e,n,t,a,$,o,i,s,f):r(e)(n)(t)(a)($)(o)(i)(s)(f)}function oe(r,e){for(var n,t=[],a=on(r,e,0,t);a&&(n=t.pop());a=on(n.a,n.b,0,t));return a}function on(r,e,n,t){if(r===e)return!0;if(typeof r!="object"||r===null||e===null)return typeof r=="function"&&fr(5),!1;if(n>100)return t.push(l(r,e)),!0;r.$<0&&(r=Oe(r),e=Oe(e));for(var a in r)if(!on(r[a],e[a],n+1,t))return!1;return!0}var wu=c(oe),Du=c(function(r,e){return!oe(r,e)});function rr(r,e,n){if(typeof r!="object")return r===e?0:r0}),av=c(function(r,e){return rr(r,e)>=0}),Bu=c(function(r,e){var n=rr(r,e);return n<0?Nt:n?Wo:Kt}),Jr=0,uv={$:"#0"};function l(r,e){return{a:r,b:e}}function $v(r,e){return{$:"#2",a:r,b:e}}function ov(r,e,n){return{a:r,b:e,c:n}}function iv(r,e,n){return{$:"#3",a:r,b:e,c:n}}function cv(r){return r}function sv(r){return new String(r)}function y(r,e){var n={};for(var t in r)n[t]=r[t];for(var t in e)n[t]=e[t];return n}var Eu=c(C);function C(r,e){if(typeof r=="string")return r+e;if(!r.b)return e;var n=Sr(r.a,e);r=r.b;for(var t=n;r.b;r=r.b)t=t.b=Sr(r.a,e);return n}var d={$:0},fv={$:"[]"};function Sr(r,e){return{$:1,a:r,b:e}}function vv(r,e){return{$:"::",a:r,b:e}}var ju=c(Sr);function _(r){for(var e=d,n=r.length;n--;)e=Sr(r[n],e);return e}function Pe(r){for(var e=[];r.b;r=r.b)e.push(r.a);return e}var Pu=D(function(r,e,n){for(var t=[];e.b&&n.b;e=e.b,n=n.b)t.push(u(r,e.a,n.a));return _(t)}),lv=W(function(r,e,n,t){for(var a=[];e.b&&n.b&&t.b;e=e.b,n=n.b,t=t.b)a.push(v(r,e.a,n.a,t.a));return _(a)}),mv=ar(function(r,e,n,t,a){for(var $=[];e.b&&n.b&&t.b&&a.b;e=e.b,n=n.b,t=t.b,a=a.b)$.push(U(r,e.a,n.a,t.a,a.a));return _($)}),_v=je(function(r,e,n,t,a,$){for(var o=[];e.b&&n.b&&t.b&&a.b&&$.b;e=e.b,n=n.b,t=t.b,a=a.b,$=$.b)o.push(L(r,e.a,n.a,t.a,a.a,$.a));return _(o)}),bv=c(function(r,e){return _(Pe(e).sort(function(n,t){return rr(r(n),r(t))}))}),pv=c(function(r,e){return _(Pe(e).sort(function(n,t){var a=u(r,n,t);return a===Kt?0:a===Nt?-1:1}))}),Au=[];function hv(r){return[r]}function Mu(r){return r.length}var Fu=D(function(r,e,n){for(var t=new Array(r),a=0;a=0;t--)e=u(r,n[t],e);return e}),Dv=c(function(r,e){for(var n=e.length,t=new Array(n),a=0;an.length&&(a=n.length);for(var $=t+a,o=new Array($),i=0;i"}function Av(r){return Cr(!1,r)}function Cr(r,e){if(typeof e=="function")return Me(r,"");if(typeof e=="boolean")return ie(r,e?"True":"False");if(typeof e=="number")return Ju(r,e+"");if(e instanceof String)return Uu(r,"'"+gt(e,!0)+"'");if(typeof e=="string")return wt(r,'"'+gt(e,!1)+'"');if(typeof e=="object"&&"$"in e){var n=e.$;if(typeof n=="number")return Me(r,"");if(n[0]==="#"){var a=[];for(var t in e)t!=="$"&&a.push(Cr(r,e[t]));return"("+a.join(",")+")"}if(n==="Set_elm_builtin")return ie(r,"Set")+Ae(r,".fromList")+" "+Cr(r,Yo(e));if(n==="RBNode_elm_builtin"||n==="RBEmpty_elm_builtin")return ie(r,"Dict")+Ae(r,".fromList")+" "+Cr(r,Oe(e));if(n==="Array_elm_builtin")return ie(r,"Array")+Ae(r,".fromList")+" "+Cr(r,Qo(e));if(n==="::"||n==="[]"){var a="[";for(e.b&&(a+=Cr(r,e.a),e=e.b);e.b;e=e.b)a+=","+Cr(r,e.a);return a+"]"}var a="";for(var $ in e)if($!=="$"){var o=Cr(r,e[$]),i=o[0],s=i==="{"||i==="("||i==="["||i==="<"||i==='"'||o.indexOf(" ")<0;a+=" "+(s?o:"("+o+")")}return ie(r,n)+a}if(typeof DataView=="function"&&e instanceof DataView)return wt(r,"<"+e.byteLength+" bytes>");if(typeof File!="undefined"&&e instanceof File)return Me(r,"<"+e.name+">");if(typeof e=="object"){var a=[];for(var f in e){var m=f[0]==="_"?f.slice(1):f;a.push(Ae(r,m)+" = "+Cr(r,e[f]))}return a.length===0?"{}":"{ "+a.join(", ")+" }"}return Me(r,"")}function gt(r,e){var n=r.replace(/\\/g,"\\\\").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/\v/g,"\\v").replace(/\0/g,"\\0");return e?n.replace(/\'/g,"\\'"):n.replace(/\"/g,'\\"')}function ie(r,e){return r?"\x1B[96m"+e+"\x1B[0m":e}function Ju(r,e){return r?"\x1B[95m"+e+"\x1B[0m":e}function wt(r,e){return r?"\x1B[93m"+e+"\x1B[0m":e}function Uu(r,e){return r?"\x1B[92m"+e+"\x1B[0m":e}function Ae(r,e){return r?"\x1B[37m"+e+"\x1B[0m":e}function Me(r,e){return r?"\x1B[36m"+e+"\x1B[0m":e}function Mv(r){return String.fromCharCode(r<10?48+r:55+r)}function fr(r){throw new Error("https://github.com/elm/core/blob/1.0.0/hints/"+r+".md")}function Fv(r,e,n,t,a){switch(r){case 0:throw new Error('What node should I take over? In JavaScript I need something like:\n\n Elm.Main.init({\n node: document.getElementById("elm-node")\n })\n\nYou need to do this with any Browser.sandbox or Browser.element program.');case 1:throw new Error("Browser.application programs cannot handle URLs like this:\n\n "+document.location.href+"\n\nWhat is the root? The root of your file system? Try looking at this program with `elm reactor` or some other server.");case 2:var $=e;throw new Error("Problem with the flags given to your Elm program on initialization.\n\n"+$);case 3:var o=e;throw new Error("There can only be one port named `"+o+"`, but your program has multiple.");case 4:var o=e,i=n;throw new Error("Trying to send an unexpected type of value through port `"+o+"`:\n"+i);case 5:throw new Error('Trying to use `(==)` on functions.\nThere is no way to know if functions are "the same" in the Elm sense.\nRead more about this at https://package.elm-lang.org/packages/elm/core/latest/Basics#== which describes why it is this way and what the better version will look like.');case 6:var s=e;throw new Error("Your page is loading multiple Elm scripts with a module named "+s+". Maybe a duplicate script is getting loaded accidentally? If not, rename one of them so I know which is which!");case 8:var s=e,f=n,b=t;throw new Error("TODO in module `"+s+"` "+Dt(f)+"\n\n"+b);case 9:var s=e,f=n,m=t,b=a;throw new Error("TODO in module `"+s+"` from the `case` expression "+Dt(f)+"\n\nIt received the following value:\n\n "+St(m).replace("\n","\n ")+"\n\nBut the branch that handles it says:\n\n "+b.replace("\n","\n "));case 10:throw new Error("Bug in https://github.com/elm/virtual-dom/issues");case 11:throw new Error("Cannot perform mod 0. Division by zero error.")}}function Dt(r){return r.bl.aE===r.bH.aE?"on line "+r.bl.aE:"on lines "+r.bl.aE+" through "+r.bH.aE}var Lu=c(function(r,e){return r+e}),Ou=c(function(r,e){return r-e}),Hu=c(function(r,e){return r*e}),Ru=c(function(r,e){return r/e}),Gu=c(function(r,e){return r/e|0}),Iu=c(Math.pow),zu=c(function(r,e){return e%r}),Wu=c(function(r,e){var n=e%r;return r===0?fr(11):n>0&&r<0||n<0&&r>0?n+r:n}),Vv=Math.PI,kv=Math.E,Jv=Math.cos,Uv=Math.sin,Lv=Math.tan,Ov=Math.acos,Hv=Math.asin,Rv=Math.atan,Gv=c(Math.atan2);function qu(r){return r}function Iv(r){return r|0}function zv(r){return r===1/0||r===-1/0}var Yu=Math.ceil,Zu=Math.floor,Wv=Math.round,qv=Math.sqrt,Ct=Math.log,Yv=isNaN;function Qu(r){return!r}var Xu=c(function(r,e){return r&&e}),Ku=c(function(r,e){return r||e}),Zv=c(function(r,e){return r!==e}),Nu=c(function(r,e){return r+e});function xu(r){var e=r.charCodeAt(0);return isNaN(e)?M:G(55296<=e&&e<=56319?l(r[0]+r[1],r.slice(2)):l(r[0],r.slice(1)))}var r$=c(function(r,e){return r+e});function e$(r){return r.length}var Qv=c(function(r,e){for(var n=e.length,t=new Array(n),a=0;a-1}),f$=c(function(r,e){return e.indexOf(r)===0}),v$=c(function(r,e){return e.length>=r.length&&e.lastIndexOf(r)===e.length-r.length}),l$=c(function(r,e){var n=r.length;if(n<1)return d;for(var t=0,a=[];(t=e.indexOf(r,t))>-1;)a.push(t),t=t+n;return _(a)});function yt(r){return r+""}function m$(r){for(var e=0,n=r.charCodeAt(0),t=n==43||n==45?1:0,a=t;a=e.length)return $r("a LONGER array. Need index "+t+" but only see "+e.length+" entries",e);var f=ur(r.b,e[t]);return br(f)?f:z(u(ra,t,f.a));case 8:if(typeof e!="object"||e===null||Fe(e))return $r("an OBJECT",e);var a=d;for(var $ in e)if(e.hasOwnProperty($)){var f=ur(r.b,e[$]);if(!br(f))return z(u(xt,$,f.a));a=Sr(l($,f.a),a)}return J(R(a));case 9:for(var o=r.f,i=r.g,s=0;s=0&&e.splice(i,1)}return{subscribe:a,unsubscribe:$}}function N$(r,e){return Ft(r),er[r]={f:x$,u:e,a:ro},bn(r)}var x$=c(function(r,e){return function(n){return r(e(n))}});function ro(r,e){var n=d,t=er[r].u,a=vr(null);er[r].b=a,er[r].c=D(function(o,i,s){return n=i,a});function $(o){var i=u(cn,t,o);br(i)||fr(4,r,i.a);for(var s=i.a,f=n;f.b;f=f.b)e(f.a(s))}return{send:$}}function eo(r){qr.Elm?kt(qr.Elm,r):qr.Elm=r}function kt(r,e){for(var n in e)n in r?n=="init"?fr(6):kt(r[n],e[n]):r[n]=e[n]}function Ml(r){qr.Elm?Jt("Elm",qr.Elm,r):qr.Elm=r}function Jt(r,e,n){for(var t in n)t in e?t=="init"?fr(6,r):Jt(r+"."+t,e[t],n[t]):e[t]=n[t]}var ke,nr=typeof document!="undefined"?document:{};function hn(r,e){r.appendChild(e)}var Fl=W(function(r,e,n,t){var a=t.node;return a.parentNode.replaceChild(Mr(r,function(){}),a),{}});function dn(r){return{$:0,a:r}}var Ut=c(function(r,e){return c(function(n,t){for(var a=[],$=0;t.b;t=t.b){var o=t.a;$+=o.b||0,a.push(o)}return $+=a.length,{$:1,c:e,d:gn(n),e:a,f:r,b:$}})}),Sn=Ut(void 0),Lt=c(function(r,e){return c(function(n,t){for(var a=[],$=0;t.b;t=t.b){var o=t.a;$+=o.b.b||0,a.push(o)}return $+=a.length,{$:2,c:e,d:gn(n),e:a,f:r,b:$}})}),no=Lt(void 0);function Vl(r,e,n,t){return{$:3,d:gn(r),g:e,h:n,i:t}}var kl=c(function(r,e){return{$:4,j:r,k:e,b:1+(e.b||0)}});function Ar(r,e){return{$:5,l:r,m:e,k:void 0}}var Jl=c(function(r,e){return Ar([r,e],function(){return r(e)})}),Ul=D(function(r,e,n){return Ar([r,e,n],function(){return u(r,e,n)})}),Ll=W(function(r,e,n,t){return Ar([r,e,n,t],function(){return v(r,e,n,t)})}),Ol=ar(function(r,e,n,t,a){return Ar([r,e,n,t,a],function(){return U(r,e,n,t,a)})}),Hl=je(function(r,e,n,t,a,$){return Ar([r,e,n,t,a,$],function(){return L(r,e,n,t,a,$)})}),Rl=pt(function(r,e,n,t,a,$,o){return Ar([r,e,n,t,a,$,o],function(){return $n(r,e,n,t,a,$,o)})}),Gl=ht(function(r,e,n,t,a,$,o,i){return Ar([r,e,n,t,a,$,o,i],function(){return Su(r,e,n,t,a,$,o,i)})}),Il=dt(function(r,e,n,t,a,$,o,i,s){return Ar([r,e,n,t,a,$,o,i,s],function(){return gu(r,e,n,t,a,$,o,i,s)})}),Ot=c(function(r,e){return{$:"a0",n:r,o:e}}),zl=c(function(r,e){return{$:"a1",n:r,o:e}}),to=c(function(r,e){return{$:"a2",n:r,o:e}}),Ht=c(function(r,e){return{$:"a3",n:r,o:e}}),Wl=D(function(r,e,n){return{$:"a4",n:e,o:{f:r,o:n}}}),ao=/^script$/i,uo=/^(on|formAction$)/i,$o=/^\s*j\s*a\s*v\s*a\s*s\s*c\s*r\s*i\s*p\s*t\s*:/i,Rt=/^\s*(j\s*a\s*v\s*a\s*s\s*c\s*r\s*i\s*p\s*t\s*:|d\s*a\s*t\s*a\s*:\s*t\s*e\s*x\s*t\s*\/\s*h\s*t\s*m\s*l\s*(,|;))/i;function Je(r){return ao.test(r)?"p":r}function oo(r){return uo.test(r)?"data-"+r:r}function io(r){return r=="innerHTML"||r=="formAction"?"data-"+r:r}function ql(r){return $o.test(r)?"":r}function co(r){return Rt.test(r)?"":r}function so(r){return typeof r=="string"&&Rt.test(r)?"":r}var Yl=c(function(r,e){return e.$==="a0"?u(Ot,e.n,fo(r,e.o)):e});function fo(r,e){var n=Fn(e);return{$:e.$,a:n?v(sa,n<3?vo:lo,me(r),e.a):u(Mn,r,e.a)}}var vo=c(function(r,e){return l(r(e.a),e.b)}),lo=c(function(r,e){return{L:r(e.L),bm:e.bm,bh:e.bh}});function gn(r){for(var e={};r.b;r=r.b){var n=r.a,t=n.$,a=n.n,$=n.o;if(t==="a2"){a==="className"?Gt(e,a,$):e[a]=$;continue}var o=e[t]||(e[t]={});t==="a3"&&a==="class"?Gt(o,a,$):o[a]=$}return e}function Gt(r,e,n){var t=r[e];r[e]=t?t+" "+n:n}function Mr(r,e){var n=r.$;if(n===5)return Mr(r.k||(r.k=r.m()),e);if(n===0)return nr.createTextNode(r.a);if(n===4){for(var t=r.k,a=r.j;t.$===4;)typeof a!="object"?a=[a,t.j]:a.push(t.j),t=t.k;var $={j:a,p:e},o=Mr(t,$);return o.elm_event_node_ref=$,o}if(n===3){var o=r.h(r.g);return wn(o,e,r.d),o}var o=r.f?nr.createElementNS(r.f,r.c):nr.createElement(r.c);ke&&r.c=="a"&&o.addEventListener("click",ke(o)),wn(o,e,r.d);for(var i=r.e,s=0;s0&&K(n,1,t,m);return;case 4:for(var b=r.j,h=e.j,p=!1,g=r.k;g.$===4;)p=!0,typeof b!="object"?b=[b,g.j]:b.push(g.j),g=g.k;for(var w=e.k;w.$===4;)p=!0,typeof h!="object"?h=[h,w.j]:h.push(w.j),w=w.k;if(p&&b.length!==h.length){K(n,0,t,e);return}(p?!go(b,h):b!==h)&&K(n,2,t,h),lr(g,w,n,t+1);return;case 0:r.a!==e.a&&K(n,3,t,e.a);return;case 1:zt(r,e,n,t,wo);return;case 2:zt(r,e,n,t,Do);return;case 3:if(r.h!==e.h){K(n,0,t,e);return}var T=Cn(r.d,e.d);T&&K(n,4,t,T);var A=e.i(r.g,e.g);A&&K(n,5,t,A);return}}}function go(r,e){for(var n=0;ni?K(n,6,t,{v:i,i:o-i}):o0||o.length>0||dr)&&K(n,8,t,{w:a,x:o,y:dr})}var Wt="_elmW6BL";function se(r,e,n,t,a,$){var o=r[n];if(!o){o={c:0,z:t,r:a,s:void 0},$.push({r:a,A:o}),r[n]=o;return}if(o.c===1){$.push({r:a,A:o}),o.c=2;var i=[];lr(o.z,t,i,o.r),o.r=a,o.s.s={w:i,A:o};return}se(r,e,n+Wt,t,a,$)}function fe(r,e,n,t,a){var $=r[n];if(!$){var o=K(e,9,a,void 0);r[n]={c:1,z:t,r:a,s:o};return}if($.c===0){$.c=2;var i=[];lr(t,$.z,i,a),K(e,9,a,{w:i,A:$});return}fe(r,e,n+Wt,t,a)}function qt(r,e,n,t){ve(r,e,n,0,0,e.b,t)}function ve(r,e,n,t,a,$,o){for(var i=n[t],s=i.r;s===a;){var f=i.$;if(f===1)qt(r,e.k,i.s,o);else if(f===8){i.t=r,i.u=o;var m=i.s.w;m.length>0&&ve(r,e,m,0,a,$,o)}else if(f===9){i.t=r,i.u=o;var b=i.s;if(b){b.A.s=r;var m=b.w;m.length>0&&ve(r,e,m,0,a,$,o)}}else i.t=r,i.u=o;if(t++,!(i=n[t])||(s=i.r)>$)return t}var h=e.$;if(h===4){for(var p=e.k;p.$===4;)p=p.k;return ve(r,p,n,t,a+1,$,r.elm_event_node_ref)}for(var g=e.e,w=r.childNodes,T=0;T$))return t;a=B}return t}function Yt(r,e,n,t){return n.length===0?r:(qt(r,e,n,t),Ue(r,n))}function Ue(r,e){for(var n=0;n>r}),Go=c(function(r,e){return e>>>r}),Io=function(r){return{$:0,a:r}},zo=function(r){return{$:1,a:r}},Kt=1,Wo=2,Nt=0,S=ju,Bn=D(function(r,e,n){r:for(;;){if(n.$===-2)return e;var t=n.b,a=n.c,$=n.d,o=n.e,i=r,s=v(r,t,a,v(Bn,r,e,o)),f=$;r=i,e=s,n=f;continue r}}),Oe=function(r){return v(Bn,D(function(e,n,t){return u(S,l(e,n),t)}),d,r)},qo=function(r){return v(Bn,D(function(e,n,t){return u(S,e,t)}),d,r)},Yo=function(r){var e=r;return qo(e)},He=ku,Zo=D(function(r,e,n){var t=n.c,a=n.d,$=c(function(o,i){if(o.$){var f=o.a;return v(He,r,i,f)}else{var s=o.a;return v(He,$,i,s)}});return v(He,$,v(He,r,e,a),t)}),Qo=function(r){return v(Zo,S,d,r)},z=function(r){return{$:1,a:r}},En=c(function(r,e){return{$:3,a:r,b:e}}),xt=c(function(r,e){return{$:0,a:r,b:e}}),ra=c(function(r,e){return{$:1,a:r,b:e}}),J=function(r){return{$:0,a:r}},Xo=function(r){return{$:2,a:r}},sm=1,fm=Lu,G=function(r){return{$:0,a:r}},M={$:1},Ko=c$,vm=Xu,No=Eu,xo=j$,Qr=yt,mr=c(function(r,e){return u(u$,r,Pe(e))}),Re=c(function(r,e){return _(u(a$,r,e))}),ea=function(r){return u(mr,"\n ",u(Re,"\n",r))},V=D(function(r,e,n){r:for(;;)if(n.b){var t=n.a,a=n.b,$=r,o=u(r,t,e),i=a;r=$,e=o,n=i;continue r}else return e}),Ur=function(r){return v(V,c(function(e,n){return n+1}),0,r)},ri=Pu,lm=yu,mm=Ou,ei=D(function(r,e,n){r:for(;;)if(rr(r,e)<1){var t=r,a=e-1,$=u(S,e,n);r=t,e=a,n=$;continue r}else return n}),ni=c(function(r,e){return v(ei,r,e,d)}),ti=c(function(r,e){return v(ri,r,u(ni,0,Ur(e)-1),e)}),Ge=p$,na=function(r){var e=Ge(r);return 97<=e&&e<=122},ta=function(r){var e=Ge(r);return e<=90&&65<=e},_m=Ku,ai=function(r){return na(r)||ta(r)},ui=function(r){var e=Ge(r);return e<=57&&48<=e},$i=function(r){return na(r)||ta(r)||ui(r)},R=function(r){return v(V,S,d,r)},oi=xu,ii=c(function(r,e){return"\n\n("+(Qr(r+1)+(") "+ea(aa(e))))}),aa=function(r){return u(ci,r,d)},ci=c(function(r,e){r:for(;;)switch(r.$){case 0:var n=r.a,o=r.b,t=function(){var w=oi(n);if(w.$===1)return!1;var T=w.a,A=T.a,B=T.b;return ai(A)&&u(Ko,$i,B)}(),a=t?"."+n:"['"+(n+"']"),s=o,f=u(S,a,e);r=s,e=f;continue r;case 1:var $=r.a,o=r.b,i="["+(Qr($)+"]"),s=o,f=u(S,i,e);r=s,e=f;continue r;case 2:var m=r.a;if(m.b)if(m.b.b){var b=function(){return e.b?"The Json.Decode.oneOf at json"+u(mr,"",R(e)):"Json.Decode.oneOf"}(),g=b+(" failed in the following "+(Qr(Ur(m))+" ways:"));return u(mr,"\n\n",u(S,g,u(ti,ii,m)))}else{var o=m.a,s=o,f=e;r=s,e=f;continue r}else return"Ran into a Json.Decode.oneOf with no possibilities"+function(){return e.b?" at json"+u(mr,"",R(e)):"!"}();default:var h=r.a,p=r.b,g=function(){return e.b?"Problem with the value at json"+(u(mr,"",R(e))+":\n\n "):"Problem with the given value:\n\n"}();return g+(ea(u(xo,4,p))+("\n\n"+h))}}),_r=32,jn=W(function(r,e,n,t){return{$:0,a:r,b:e,c:n,d:t}}),Pn=Au,ua=Yu,bm=Ru,$a=c(function(r,e){return Ct(e)/Ct(r)}),pm=qu,An=ua(u($a,2,_r)),si=U(jn,0,An,Pn,Pn),oa=Fu,fi=function(r){return{$:1,a:r}},hm=c(function(r,e){return r(e)}),vi=c(function(r,e){return e(r)}),dm=wu,li=Zu,ia=Mu,Sm=Tu,mi=c(function(r,e){return rr(r,e)>0?r:e}),gm=Hu,_i=function(r){return{$:0,a:r}},ca=Vu,bi=c(function(r,e){r:for(;;){var n=u(ca,_r,r),t=n.a,a=n.b,$=u(S,_i(t),e);if(a.b){var o=a,i=$;r=o,e=i;continue r}else return R($)}}),wm=function(r){var e=r.a;return e},pi=c(function(r,e){r:for(;;){var n=ua(e/_r);if(n===1)return u(ca,_r,r).a;var t=u(bi,r,d),a=n;r=t,e=a;continue r}}),hi=c(function(r,e){if(e.l){var n=e.l*_r,t=li(u($a,_r,n-1)),a=r?R(e.o):e.o,$=u(pi,a,e.l);return U(jn,ia(e.n)+n,u(mi,5,t*An),$,e.n)}else return U(jn,ia(e.n),An,Pn,e.n)}),Dm=Gu,Cm=Cu,di=ar(function(r,e,n,t,a){r:for(;;){if(e<0)return u(hi,!1,{o:t,l:n/_r|0,n:a});var $=fi(v(oa,_r,e,r)),o=r,i=e-_r,s=n,f=u(S,$,t),m=a;r=o,e=i,n=s,t=f,a=m;continue r}}),ym=zu,Si=c(function(r,e){if(r<=0)return si;var n=r%_r,t=v(oa,n,r-n,e),a=r-n-_r;return L(di,e,a,r,d,t)}),Tm=0,br=function(r){return!r.$},Mn=T$,sa=B$,me=h$,Fn=function(r){switch(r.$){case 0:return 0;case 1:return 1;case 2:return 2;default:return 3}},gi=function(r){return{$:1,a:r}},wi=function(r){return{$:0,a:r}},Xr=function(r){return r},Di=Xr,Bm=0,Em=1,fa=je(function(r,e,n,t,a,$){return{bN:$,bR:e,b0:t,b2:n,b6:r,b7:a}}),Ci=s$,va=e$,la=$$,Lr=c(function(r,e){return r<1?e:v(la,r,va(e),e)}),Ie=l$,Kr=function(r){return r===""},ze=c(function(r,e){return r<1?"":v(la,0,r,e)}),yi=m$,ma=ar(function(r,e,n,t,a){if(Kr(a)||u(Ci,"@",a))return M;var $=u(Ie,":",a);if($.b){if($.b.b)return M;var o=$.a,i=yi(u(Lr,o+1,a));if(i.$===1)return M;var s=i;return G($n(fa,r,u(ze,o,a),s,e,n,t))}else return G($n(fa,r,a,M,e,n,t))}),_a=W(function(r,e,n,t){if(Kr(t))return M;var a=u(Ie,"/",t);if(a.b){var $=a.a;return L(ma,r,u(Lr,$,t),e,n,u(ze,$,t))}else return L(ma,r,"/",e,n,t)}),ba=D(function(r,e,n){if(Kr(n))return M;var t=u(Ie,"?",n);if(t.b){var a=t.a;return U(_a,r,G(u(Lr,a+1,n)),e,u(ze,a,n))}else return U(_a,r,M,e,n)}),pa=c(function(r,e){if(Kr(e))return M;var n=u(Ie,"#",e);if(n.b){var t=n.a;return v(ba,r,G(u(Lr,t+1,e)),u(ze,t,e))}else return v(ba,r,M,e)}),_e=f$,ha=function(r){return u(_e,"http://",r)?u(pa,0,u(Lr,7,r)):u(_e,"https://",r)?u(pa,1,u(Lr,8,r)):M},be=function(r){r:for(;;){var e=r,n=e;r=n;continue r}},jm=Xr,Or=vr,Ti=Or(0),da=W(function(r,e,n,t){if(t.b){var a=t.a,$=t.b;if($.b){var o=$.a,i=$.b;if(i.b){var s=i.a,f=i.b;if(f.b){var m=f.a,b=f.b,h=n>500?v(V,r,e,R(b)):U(da,r,e,n+1,b);return u(r,a,u(r,o,u(r,s,u(r,m,h))))}else return u(r,a,u(r,o,u(r,s,e)))}else return u(r,a,u(r,o,e))}else return u(r,a,e)}else return e}),Hr=D(function(r,e,n){return U(da,r,e,0,n)}),F=c(function(r,e){return v(Hr,c(function(n,t){return u(S,r(n),t)}),d,e)}),pe=fn,Vn=c(function(r,e){return u(pe,function(n){return Or(r(n))},e)}),Bi=D(function(r,e,n){return u(pe,function(t){return u(pe,function(a){return Or(u(r,t,a))},n)},e)}),Ei=function(r){return v(Hr,Bi(S),Or(d),r)},ji=W$,Pi=c(function(r,e){var n=e;return Et(u(pe,ji(r),n))}),Ai=D(function(r,e,n){return u(Vn,function(t){return 0},Ei(u(F,Pi(r),e)))}),Mi=D(function(r,e,n){return Or(0)}),Fi=c(function(r,e){var n=e;return u(Vn,r,n)});er.Task=I$(Ti,Ai,Mi,Fi);var Sa=bn("Task"),he=c(function(r,e){return Sa(u(Vn,r,e))}),Vi=Fo,ki={$:3},Nr=D(function(r,e,n){return r(e(n))}),Ji=k$,Ui=c(function(r,e){return Sa(u(Ji,u(Nr,u(Nr,Or,r),z),u(pe,u(Nr,u(Nr,Or,r),J),e)))}),Li=D(function(r,e,n){return{cT:r,cU:e,cV:n}}),kn=S$,Oi=sa(vi),gr=C$,de=D(function(r,e,n){return u(Oi,u(gr,r,e),n)}),Hi=v(de,"keepTheme",kn,v(de,"keepPrompt",kn,v(de,"keepFont",kn,me(Li)))),Ri=function(r){return{cM:r}},Gi=g$,ga=v(de,"fontSize",Gi,me(Ri)),Ii=function(r){return{c1:r}},We=D$,wa=v(de,"prompt",We,me(Ii)),zi=y$,Wi=d$,qi=c(function(r,e){var n=r(e);if(n.$)return Wi("Constructor not matched");var t=n.a;return me(t)}),Yi=function(r){return u(zi,qi(r),We)},Pm=1,Am=0,Mm=2,Fm=3,Zi=function(r){switch(r){case"Pit":return G(0);case"Dim":return G(1);case"Sky":return G(2);case"Sun":return G(3);default:return M}},Da=Yi(Zi),Fr=cn,qe={r:{cT:!0,cU:!0,cV:!0},p:{cM:20},c1:{c1:">"},F:1},Qi=Jo("focus"),Xi=function(r){return{$:4,a:r}},Ca=dn,Ki=function(r){return Xi(Ca(r))},k=Ki,Ni=D(function(r,e,n){var t=function(){var s=u(Fr,u(gr,"Theme",Da),r);if(s.$)return qe.F;var f=s.a;return f}(),a=function(){var s=u(Fr,u(gr,"Prompt",wa),r);if(s.$)return qe.c1;var f=s.a;return f}(),$=_([k("Welcome to my website! Pardon the alpha quality for the time being"),k("\nRun `help` to get started")]),o=function(){var s=u(Fr,u(gr,"Font",ga),r);if(s.$)return qe.p;var f=s.a;return f}(),i=function(){var s=u(Fr,u(gr,"CookiesKept",Hi),r);if(s.$)return qe.r;var f=s.a;return f}();return l({ay:"",a:$,r:i,p:o,bb:n,c1:a,F:t,bo:e},u(Ui,function(s){return ki},Qi("init-focus")))}),xi=function(r){return{$:4,a:r}},ya=w$,rc=N$("receiveStorageFromJS",ya),ec=function(r){return rc(xi)},Vm=10,km=0,Ta=function(r){return{$:0,a:r}},Jm=Xr,Ye=c(function(r,e){return Ta(r+(":"+e))}),xr=function(r){return u(Ye,"background-color",r.G)},Y=c(function(r,e){return u(Ye,r,e.G)}),Ze=Y("border-width"),Se=function(r){return u(Ye,"color",r.G)},re=Y("margin"),ee=Y("padding"),Um=0,Lm=0,Jn=yt,Qe=D(function(r,e,n){return{bp:0,bA:0,af:0,cM:0,aD:0,ai:0,K:0,aj:0,ak:0,S:0,T:0,D:0,al:0,M:n,aq:0,as:e,aM:r,G:C(Jn(n),e)}}),H=u(Qe,0,"px"),nc=D(function(r,e,n){return{$:0,a:r,b:e,c:n}}),tc=nc,Un=tc,Xe=Un("span"),Ln=D(function(r,e,n){return{$:0,a:r,b:e,c:n}}),ne=c(function(r,e){return u(Ht,oo(r),co(e))}),ac=c(function(r,e){r:for(;;)if(e.b){var n=e.a,t=e.b;if(r(n))return!0;var a=r,$=t;r=a,e=$;continue r}else return!1}),uc=Qu,Ba=c(function(r,e){return!u(ac,u(Nr,uc,r),e)}),Om=1,or=ar(function(r,e,n,t,a){return{$:-1,a:r,b:e,c:n,d:t,e:a}}),On={$:-2},Hm=0,Ea=ar(function(r,e,n,t,a){if(a.$===-1&&!a.a){var $=a.a,o=a.b,i=a.c,s=a.d,f=a.e;if(t.$===-1&&!t.a){var m=t.a,b=t.b,h=t.c,p=t.d,g=t.e;return L(or,0,e,n,L(or,1,b,h,p,g),L(or,1,o,i,s,f))}else return L(or,r,o,i,L(or,0,e,n,t,s),f)}else if(t.$===-1&&!t.a&&t.d.$===-1&&!t.d.a){var w=t.a,b=t.b,h=t.c,T=t.d,A=T.a,B=T.b,Z=T.c,I=T.d,O=T.e,g=t.e;return L(or,0,b,h,L(or,1,B,Z,I,O),L(or,1,e,n,g,a))}else return L(or,r,e,n,t,a)}),ja=Bu,Hn=D(function(r,e,n){if(n.$===-2)return L(or,0,r,e,On,On);var t=n.a,a=n.b,$=n.c,o=n.d,i=n.e,s=u(ja,r,a);switch(s){case 0:return L(Ea,t,a,$,v(Hn,r,e,o),i);case 1:return L(or,t,a,e,o,i);default:return L(Ea,t,a,$,o,v(Hn,r,e,i))}}),Pa=D(function(r,e,n){var t=v(Hn,r,e,n);if(t.$===-1&&!t.a){var a=t.a,$=t.b,o=t.c,i=t.d,s=t.e;return L(or,1,$,o,i,s)}else{var f=t;return f}}),Tr=function(r){return!r.b},$c=c(function(r,e){var n=e.a,t=e.b;switch(r.$){case 0:var a=r.a,s=a.c;return Tr(s)?l(n,t):l(n,u(S,r,t));case 1:var $=r.b;return u(Ba,function(m){var b=m.c;return Tr(b)},$)?l(n,t):l(n,u(S,r,t));case 2:var o=r.b;return Tr(o)?l(n,t):l(n,u(S,r,t));case 3:return l(n,u(S,r,t));case 4:var s=r.a;return Tr(s)?l(n,t):l(n,u(S,r,t));case 5:var s=r.a;return Tr(s)?l(n,t):l(n,u(S,r,t));case 6:var i=r.a;return Kr(i.cH)?l(n,t):l(v(Pa,i.cY,i.cH,n),t);case 7:var s=r.a;return Tr(s)?l(n,t):l(n,u(S,r,t));case 8:var s=r.a;return Tr(s)?l(n,t):l(n,u(S,r,t));default:var f=r.a;return u(Ba,function(m){var b=m.b;return Tr(b)},f)?l(n,t):l(n,u(S,r,t))}}),ge=On,Aa=function(r){return{$:6,a:r}},Rn=c(function(r,e){return e.b?v(Hr,S,e,r):r}),oc=c(function(r,e){return u(Rn,u(F,function(n){var t=n.a,a=n.b;return Aa({cH:a,cY:t})},Oe(r)),e)}),ic=function(r){var e=v(Hr,$c,l(ge,d),r),n=e.a,t=e.b;return u(oc,n,t)},cc=function(r){var e=r.cI,n=r.bZ,t=r.bS,a=r.bD;return{bD:a,cI:ic(e),bS:t,bZ:n}},Ke=c(function(r,e){if(e.$)return M;var n=e.a;return G(r(n))}),pr=c(function(r,e){if(e.$)return r;var n=e.a;return n}),sc=function(r){return u(pr,"",u(Ke,function(e){return'@charset "'+(e+'"')},r))},fc=W(function(r,e,n,t){r:for(;;)if(n.b)if(n.b.b){var a=n.a,$=n.b,o=r,i=e,s=$,f=t+(r(a)+(e+""));r=o,e=i,n=s,t=f;continue r}else{var a=n.a;return t+(r(a)+"")}else return t}),ir=D(function(r,e,n){return U(fc,r,e,n,"")}),Ma=function(r){return"("+(r.bK+(u(pr,"",u(Ke,No(": "),r.G))+")"))},vc=function(r){switch(r){case 0:return"print";case 1:return"screen";default:return"speech"}},Fa=function(r){var e=D(function($,o,i){return $+(" "+u(mr," and ",u(S,vc(o),u(F,Ma,i))))});switch(r.$){case 0:var t=r.a;return v(ir,Ma," and ",t);case 1:var n=r.a,t=r.b;return v(e,"only",n,t);case 2:var n=r.a,t=r.b;return v(e,"not",n,t);default:var a=r.a;return a}},lc=c(function(r,e){return'@import "'+(r+(Fa(e)+'"'))}),mc=function(r){var e=r.a,n=r.b;return v(ir,lc(e),"\n",n)},_c=function(r){var e=r.a,n=r.b;return"@namespace "+(e+('"'+(n+'"')))},bc=function(r){return v(ir,function(e){var n=e;return n+";"},"",r)},pc=r$,hc=function(r){var e=r;return"::"+e},dc=function(r){switch(r){case 0:return"+";case 1:return"~";case 2:return">";default:return""}},Gn=function(r){switch(r.$){case 0:var e=r.a;return"."+e;case 1:var e=r.a;return"#"+e;case 2:var e=r.a;return":"+e;default:var e=r.a;return"["+(e+"]")}},Va=function(r){switch(r.$){case 0:var e=r.a,n=r.b;return C(e,v(ir,Gn,"",n));case 1:var n=r.a;return Tr(n)?"*":v(ir,Gn,"",n);default:var e=r.a,n=r.b;return C(e,v(ir,Gn,"",n))}},Sc=function(r){var e=r.a,n=r.b;return dc(e)+(" "+Va(n))},gc=function(r){var e=r.a,n=r.b,t=r.c,a=u(S,Va(e),u(F,Sc,n)),$=u(pr,"",u(Ke,hc,t));return u(pc,u(mr," ",a),$)},ka=function(r){var e=r.a,n=r.b,t=r.c,a=v(ir,gc,",",u(S,e,n));return a+("{"+(bc(t)+"}"))},wc=function(r){switch(r.$){case 0:var e=r.a;return ka(e);case 1:var n=r.a,t=r.b,a=v(ir,Fa,", ",n),$=v(ir,ka,"\n",t);return"@media "+(a+("{"+($+"}")));case 2:return"TODO";case 3:return"TODO";case 4:return"TODO";case 5:return"TODO";case 6:var o=r.a.cH,i=r.a.cY;return"@keyframes "+(i+("{"+(o+"}")));case 7:return"TODO";case 8:return"TODO";default:return"TODO"}},Dc=function(r){var e=r.cI,n=r.bZ,t=r.bS,a=r.bD;return sc(a)+(v(ir,mc,"\n",t)+(v(ir,_c,"\n",n)+(v(ir,wc,"\n",e)+"")))},In=function(r){return v(Hr,Rn,d,r)},we=c(function(r,e){return In(u(F,r,e))}),Ja=function(r){return{$:8,a:r}},Ua=function(r){return{$:5,a:r}},La=function(r){return{$:4,a:r}},De=D(function(r,e,n){return{$:0,a:r,b:e,c:n}}),Vr=D(function(r,e,n){return{$:0,a:r,b:e,c:n}}),Ce=function(r){return{$:0,a:r}},zn=c(function(r,e){return{$:2,a:r,b:e}}),Oa=function(r){return{$:7,a:r}},Rr=c(function(r,e){return{$:1,a:r,b:e}}),Wn=c(function(r,e){if(e.b)if(e.b.b){var t=e.a,a=e.b;return u(S,t,u(Wn,r,a))}else{var n=e.a;return _([r(n)])}else return e}),Ha=c(function(r,e){var n=e.a,t=e.b,a=e.c;return v(Vr,n,t,C(a,_([r])))}),qn=c(function(r,e){if(e.b)if(e.b.b){var o=e.a,i=e.b;return u(S,o,u(qn,r,i))}else switch(e.a.$){case 0:var n=e.a.a;return _([Ce(u(Ha,r,n))]);case 1:var t=e.a,a=t.a,$=t.b;return _([u(Rr,a,u(Wn,Ha(r),$))]);default:return e}else return e}),Ra=c(function(r,e){if(e.b.b){var a=e.a,$=e.b,t=e.c,o=u(F,r,$),i=r(a);return _([v(Vr,a,$,t),v(Vr,i,o,d)])}else{var n=e.a,t=e.c;return _([v(Vr,n,d,t),v(Vr,r(n),d,d)])}}),Cc=c(function(r,e){var n=e.a,t=e.b;return v(De,n,t,G(r))}),yc=c(function(r,e){return u(Ra,Cc(r),e)}),Tc=c(function(r,e){return{$:2,a:r,b:e}}),Bc=c(function(r,e){return{$:0,a:r,b:e}}),Ga=function(r){return{$:1,a:r}},Ia=c(function(r,e){switch(e.$){case 0:var n=e.a,a=e.b;return u(Bc,n,C(a,_([r])));case 1:var a=e.a;return Ga(C(a,_([r])));default:var t=e.a,a=e.b;return u(Tc,t,C(a,_([r])))}}),za=c(function(r,e){if(e.b)if(e.b.b){var $=e.a,o=e.b;return u(S,$,u(za,r,o))}else{var n=e.a,t=n.a,a=n.b;return _([l(t,u(Ia,r,a))])}else return d}),Ec=c(function(r,e){if(e.b.b){var a=e.a,$=e.b,t=e.c;return v(De,a,u(za,r,$),t)}else{var n=e.a,t=e.c;return v(De,u(Ia,r,n),d,t)}}),jc=c(function(r,e){return u(Ra,Ec(r),e)}),Yn=function(r){r:for(;;)if(r.b)if(r.a.$){var a=r.b,$=a;r=$;continue r}else{var e=r.a.a,n=e.a,t=e.b,a=r.b;return C(u(S,n,t),Yn(a))}else return d},Zn=ar(function(r,e,n,t,a){return{$:3,a:r,b:e,c:n,d:t,e:a}}),Ne=c(function(r,e){r:for(;;)if(e.b){if(e.b.b)break r;switch(e.a.$){case 0:var I=e.a.a;return u(F,Ce,r(I));case 1:if(e.a.b.b)if(e.a.b.b.b){var $=e.a,t=$.a,o=$.b,O=o.a,E=o.b,i=u(Ne,r,_([u(Rr,t,E)]));if(i.b&&i.a.$===1&&!i.b.b){var s=i.a,f=s.a,m=s.b;return _([u(Rr,f,u(S,O,m))])}else{var b=i;return b}}else{var n=e.a,t=n.a,a=n.b,I=a.a;return _([u(Rr,t,r(I))])}else break r;case 2:var h=e.a,p=h.a,g=h.b;return _([u(zn,p,u(Ne,r,g))]);case 3:var w=e.a,T=w.a,A=w.b,B=w.c,Z=w.d,I=w.e;return u(F,U(Zn,T,A,B,Z),r(I));case 4:return e;case 5:return e;case 6:return e;case 7:return e;case 8:return e;default:return e}}else return e;var O=e.a,E=e.b;return u(S,O,u(Ne,r,E))}),Qn=Nu,Pc=W(function(r,e,n,t){return{ac:t,ah:n,W:e,an:r}}),Wa=3432918353,qa=461845907,Rm=Lo,Gm=Ro,Im=Go,Gr=c(function(r,e){return(e&65535)*r+(((e>>>16)*r&65535)<<16)}),Ac=Du,zm=Oo,Xn=c(function(r,e){return e<>>32-r}),Wm=Ho,Mc=function(r){var e=r.ah?r.W^u(Gr,qa,u(Xn,15,u(Gr,Wa,r.ah))):r.W,n=e^r.ac,t=u(Gr,2246822507,n^n>>>16),a=u(Gr,3266489909,t^t>>>13);return(a^a>>>16)>>>0},Fc=n$,Vc=c(function(r,e){return u(Gr,5,u(Xn,13,r^u(Gr,qa,u(Xn,15,u(Gr,Wa,e)))))+3864292196}),kc=c(function(r,e){var n=e.ah|(255&Ge(r))<1e3?u(S,B,u(S,o,u(S,m,u(S,w,u(qc,e-4,T))))):u(S,B,u(S,o,u(S,m,u(S,w,v(xa,r+1,e-4,T)))))}else break e}else{if(t.a===1)break r;break e}else return n;return n}var A=t.b,B=A.a;return _([B])}),Yc=c(function(r,e){return v(xa,0,r,e)}),ru=ar(function(r,e,n,t,a){if(a.$)return a;var $=a.a;return L(Zn,r,e,n,t,$)}),eu=c(function(r,e){switch(e.$){case 0:var m=e.a;return u(Rr,r,_([m]));case 1:var n=e.a,t=e.b;return u(Rr,C(r,n),t);case 2:var a=e.a,$=e.b;return u(zn,a,u(F,eu(r),$));case 3:var o=e.a,i=e.b,s=e.c,f=e.d,m=e.e;return L(Zn,o,i,s,f,m);case 4:return e;case 5:return e;case 6:return e;case 7:return e;case 8:return e;default:return e}}),Nn=function(r){var e=r;return e},nu=W(function(r,e,n,t){var a=function(f){return u(pr,d,Ir(f))},$=u(wr,e,u(pr,d,Ka(t))),o=function(){var f=l(N($),Rc(t));if(!f.a.$&&!f.b.$){var m=f.a.a,b=f.b.a;return C(u(Yc,Ur(t)-1,t),_([oe(b,m)?b:m]))}else return t}(),i=function(f){return In(u(Wn,wr(r),u(F,Kn,u(Ne,n,f))))},s=u(pr,d,u(Ke,i,Ka(t)));return C(o,C(a(s),a($)))}),wr=c(function(r,e){if(r.b)switch(r.a.$){case 0:var n=r.a.a,O=r.b;return u(wr,O,u(qn,n,e));case 1:var t=r.a,a=t.a,B=t.b,O=r.b;return U(nu,B,O,jc(a),e);case 2:var $=r.a,o=$.a,i=$.b,O=r.b,s=c(function(E,Q){var hr=E.a,tr=E.b,Er=E.c,sr=Q.a,dr=Q.b,Ee=Q.c;return v(De,hr,C(tr,u(S,l(o,sr),dr)),Gc(_([Ee,Er])))}),f=function(E){switch(E.$){case 0:var Q=E.a,hr=Q.a,tr=Q.b,Er=Q.c,sr=u(we,function(bt){return u(F,s(bt),u(S,hr,tr))},Yn(e)),dr=function(){if(sr.b){var bt=sr.a,nv=sr.b;return _([Ce(v(Vr,bt,nv,d))])}else return d}();return u(wr,Er,dr);case 1:var Ee=E.a,mt=E.b;return u(tu,Ee,mt);case 2:var _t=E.a,Qf=E.b;return u(au,_t,Qf);case 3:var Xf=E.a,Kf=E.b,Nf=E.c,xf=E.d,rv=E.e;return u(F,U(ru,Xf,Kf,Nf,xf),xe(rv));case 4:var Wr=E.a;return _([La(Wr)]);case 5:var Wr=E.a;return _([Ua(Wr)]);case 6:var Wr=E.a;return _([Oa(Wr)]);case 7:var Wr=E.a;return _([Ja(Wr)]);default:var ev=E.a;return Na(ev)}};return In(C(_([u(wr,O,e)]),u(F,f,u(we,Nn,i))));case 3:var m=r.a,b=m.a,B=m.b,O=r.b;return U(nu,B,O,yc(b),e);case 5:var h=r.a.a,O=r.b,p=Xa(h),g="animation-name:"+p,w=u(wr,O,u(qn,g,e));return u(Rn,w,_([Aa({cH:h,cY:p})]));case 4:var T=r.a,A=T.a,B=T.b,O=r.b,Z=function(){var E=Yn(e);if(E.b){var Q=E.a,hr=E.b;return u(F,zc(A),u(wr,B,Kn(Ce(v(Vr,Q,hr,d)))))}else return d}();return C(u(wr,O,e),Z);default:var I=r.a.a,O=r.b;return u(wr,C(I,O),e)}else return e}),xe=function(r){var e=r.a,n=r.b,t=r.c;return u(wr,t,_([Ce(v(Vr,e,n,d))]))},xn=function(r){if(r.b){var e=r.a,n=r.b;return C(Zc(e),xn(n))}else return d},tu=c(function(r,e){var n=function(t){return u(F,eu(r),xe(t))};return u(we,n,e)}),au=c(function(r,e){var n=xn(u(we,Nn,e));return _([u(zn,r,n)])}),Zc=function(r){switch(r.$){case 0:var f=r.a;return xe(f);case 1:var e=r.a,n=r.b;return u(tu,e,n);case 2:var t=r.a,a=r.b;return u(au,t,a);case 3:var $=r.a,o=r.b,i=r.c,s=r.d,f=r.e;return u(F,U(ru,$,o,i,s),xe(f));case 4:var m=r.a;return _([La(m)]);case 5:var m=r.a;return _([Ua(m)]);case 6:var m=r.a;return _([Oa(m)]);case 7:var m=r.a;return _([Ja(m)]);default:var b=r.a;return Na(b)}},Qc=function(r){var e=r.ci,n=r.bZ,t=r.bS,a=r.bD,$=xn(u(we,Nn,e));return{bD:a,cI:$,bS:t,bZ:n}},Xc=function(r){return Dc(cc(Qc(r)))},qm=Xr,Kc=D(function(r,e,n){return{$:0,a:r,b:e,c:n}}),Nc=function(r){return{$:0,a:r}},xc=c(function(r,e){var n=v(De,e,d,M);return _([Nc(v(Kc,n,d,r))])}),rs=function(r){return{bD:M,bS:d,bZ:d,ci:r}},es=function(r){return{$:0,a:r}},rt="\x07",ns=Ga(_([es(rt)])),ts=function(r){if(r.b){var e=r;return Xc(rs(_([u(xc,r,ns)])))}else return""},as=function(r){var e=ts(r),n=u(ne,"","");return v(Ln,n,!0,e)},te=W(function(r,e,n,t){return u(r,u(S,as(e),n),t)}),us=D(function(r,e,n){return U(te,Xe,_([Se(r),xr(e),ee(H(0)),re(H(0)),Ze(H(0))]),d,_([k(n)]))}),$s=c(function(r,e){return r+("("+(u(mr,",",e)+")"))}),os=W(function(r,e,n,t){return{av:t,ax:n,C:0,aC:e,aH:r,G:u($s,"rgba",C(u(F,Qr,_([r,e,n])),_([Jn(t)])))}}),ye=c(function(r,e){return v(us,r,U(os,0,0,0,0),e)}),uu=function(r){return u(_e,"#",r)?r:u(Qn,"#",r)},$u=function(r){return{av:1,ax:0,C:0,aC:0,aH:0,G:uu(r)}},is=t$,et=function(r){return v(is,S,d,r)},ou=D(function(r,e,n){return e(r(n))}),cs=function(r){return u(Qn,r,"")},x=Iu,iu=D(function(r,e,n){r:for(;;)if(e.b){var t=e.a,a=e.b;switch(t){case"0":var $=r-1,o=a,i=n;r=$,e=o,n=i;continue r;case"1":var $=r-1,o=a,i=n+u(x,16,r);r=$,e=o,n=i;continue r;case"2":var $=r-1,o=a,i=n+2*u(x,16,r);r=$,e=o,n=i;continue r;case"3":var $=r-1,o=a,i=n+3*u(x,16,r);r=$,e=o,n=i;continue r;case"4":var $=r-1,o=a,i=n+4*u(x,16,r);r=$,e=o,n=i;continue r;case"5":var $=r-1,o=a,i=n+5*u(x,16,r);r=$,e=o,n=i;continue r;case"6":var $=r-1,o=a,i=n+6*u(x,16,r);r=$,e=o,n=i;continue r;case"7":var $=r-1,o=a,i=n+7*u(x,16,r);r=$,e=o,n=i;continue r;case"8":var $=r-1,o=a,i=n+8*u(x,16,r);r=$,e=o,n=i;continue r;case"9":var $=r-1,o=a,i=n+9*u(x,16,r);r=$,e=o,n=i;continue r;case"a":var $=r-1,o=a,i=n+10*u(x,16,r);r=$,e=o,n=i;continue r;case"b":var $=r-1,o=a,i=n+11*u(x,16,r);r=$,e=o,n=i;continue r;case"c":var $=r-1,o=a,i=n+12*u(x,16,r);r=$,e=o,n=i;continue r;case"d":var $=r-1,o=a,i=n+13*u(x,16,r);r=$,e=o,n=i;continue r;case"e":var $=r-1,o=a,i=n+14*u(x,16,r);r=$,e=o,n=i;continue r;case"f":var $=r-1,o=a,i=n+15*u(x,16,r);r=$,e=o,n=i;continue r;default:var s=t;return z(cs(s)+" is not a valid hexadecimal character.")}}else return J(n)}),ss=c(function(r,e){if(e.$){var t=e.a;return z(t)}else{var n=e.a;return J(r(n))}}),fs=c(function(r,e){if(e.$){var t=e.a;return z(r(t))}else{var n=e.a;return J(n)}}),vs=function(r){if(Kr(r))return z("Empty strings are not valid hexadecimal strings.");var e=function(){if(u(_e,"-",r)){var t=u(pr,d,Ir(et(r)));return u(ss,Lc,v(iu,Ur(t)-1,t,0))}else return v(iu,va(r)-1,et(r),0)}(),n=function(t){return u(mr," ",_(['"'+(r+'"'),"is not a valid hexadecimal string because",t]))};return u(fs,n,e)},ls=i$,rn=ar(function(r,e,n,t,a){var $=e.a,o=e.b,i=n.a,s=n.b,f=t.a,m=t.b,b=a.a,h=a.b,p=u(ou,Ya,u(ou,ls,vs)),g=l(l(p(_([$,o])),p(_([i,s]))),l(p(_([f,m])),p(_([b,h]))));if(!g.a.a.$&&!g.a.b.$&&!g.b.a.$&&!g.b.b.$){var w=g.a,T=w.a.a,A=w.b.a,B=g.b,Z=B.a.a,I=B.b.a;return{av:I/255,ax:Z,C:0,aC:A,aH:T,G:uu(r)}}else return $u(r)}),j=function(r){var e=u(_e,"#",r)?u(Lr,1,r):r,n=et(e);r:for(;;)if(n.b&&n.b.b&&n.b.b.b)if(n.b.b.b.b)if(n.b.b.b.b.b)if(n.b.b.b.b.b.b)if(n.b.b.b.b.b.b.b)if(n.b.b.b.b.b.b.b.b&&!n.b.b.b.b.b.b.b.b.b){var h=n.a,Q=n.b,g=Q.a,hr=Q.b,T=hr.a,tr=hr.b,B=tr.a,Er=tr.b,I=Er.a,sr=Er.b,E=sr.a,dr=sr.b,Ee=dr.a,mt=dr.b,_t=mt.a;return L(rn,r,l(h,g),l(T,B),l(I,E),l(Ee,_t))}else break r;else{var h=n.a,p=n.b,g=p.a,w=p.b,T=w.a,A=w.b,B=A.a,Z=A.b,I=Z.a,O=Z.b,E=O.a;return L(rn,r,l(h,g),l(T,B),l(I,E),l("f","f"))}else break r;else{var t=n.a,s=n.b,$=s.a,f=s.b,i=f.a,m=f.b,b=m.a;return L(rn,r,l(t,t),l($,$),l(i,i),l(b,b))}else{var t=n.a,a=n.b,$=a.a,o=a.b,i=o.a;return L(rn,r,l(t,t),l($,$),l(i,i),l("f","f"))}else break r;return $u(r)},Te=function(r){switch(r){case 0:return j("e14433");case 1:return j("#359b54");case 2:return j("#a08016");case 3:return j("#5a77f2");case 4:return j("#cf2ec8");case 5:return j("1894a5");case 6:return j("#f36552");case 7:return j("#3db361");case 8:return j("#b9941a");case 9:return j("#7491f8");case 10:return j("#e54ede");default:return j("#1eabbf")}},ms=q$,P=ms(d),en=c(function(r,e){return l(y(r,{a:C(r.a,_([u(ye,Te(0),"\n"+aa(e))]))}),P)}),_s=c(function(r,e){var n=u(Fr,u(gr,"name",We),e);if(n.$){var $=n.a;return u(en,r,$)}else switch(n.a){case"Theme":var t=u(Fr,u(gr,"data",Da),e);if(t.$){var $=t.a;return u(en,r,$)}else{var a=t.a;return l(y(r,{F:a}),P)}case"Prompt":var o=u(Fr,u(gr,"data",wa),e);if(o.$){var $=o.a;return u(en,r,$)}else{var i=o.a;return l(y(r,{c1:i}),P)}case"Font":var s=u(Fr,u(gr,"data",ga),e);if(s.$){var $=s.a;return u(en,r,$)}else{var f=s.a;return l(y(r,{p:f}),P)}default:return l(y(r,{a:C(r.a,_([k("expecting field `name` to contain type while applyJSONData")]))}),P)}}),bs=v$,ps=Uo,Ym=0,Zm=1,Qm=2,Xm=3,Km=4,Nm=5,xm=6,r_=7,e_=8,n_=9,hs=c(function(r,e){return v(Hr,c(function(n,t){return r(n)?u(S,n,t):t}),d,e)}),cu=o$,ds=function(r){var e=u(F,cu,u(Re," ",r)),n=function(){var i=N(e);if(i.$)return z("error in parseInput parsing tokens");switch(i.a){case"help":return J(6);case"clear":return J(0);case"colors":return J(1);case"cookies":return J(2);case"debug":return J(3);case"font":return J(4);case"hello":return J(5);case"prompt":return J(7);case"theme":return J(8);case"todo":return J(9);default:var s=i.a;return z(s)}}(),t=function(){var i=Ir(e);if(i.$)return z("error in parseInput parsing tokens");var s=i.a;return J(u(hs,Ac(""),s))}();if(t.$){var o=t.a;return z(o)}else{var a=t.a;if(n.$){var o=n.a;return z(o)}else{var $=n.a;return J({cB:a,cF:$})}}},Ss=Vo,gs=function(r){return"["+(u(mr,",",r)+"]")},q=D(function(r,e,n){var t=function(){switch(r){case 6:return"help";case 0:return"clear";case 1:return"colors";case 2:return"cookies";case 3:return"debug";case 4:return"font";case 5:return"hello";case 7:return"prompt";case 8:return"theme";default:return"todo"}}();return _([k((rr(e,Ur(n))>0?"\nToo few arguments for "+t:rr(e,Ur(n))<0?"\nToo many arguments for "+t:"\nUnexpected arguments "+gs(n))+(". Run `help "+(t+"` for usage")))])}),ws=c(function(r,e){return l(function(){var n=N(e);if(n.$===1)return y(r,{a:d});var t=n.a;return y(r,{a:C(r.a,v(q,0,0,e))})}(),P)}),Ds=c(function(r,e){var n=N(e);return n.$===1?l(y(r,{a:C(r.a,v(q,1,1,e))}),P):n.a==="test"?l(y(r,{a:C(r.a,_([u(ye,Te(0),"Red")]))}),P):l(y(r,{a:C(r.a,v(q,1,1,e))}),P)}),nt=function(r){return r?"True":"False"},Cs=function(r){return"{ keepFont = "+(nt(r.cT)+("\n, keepPrompt = "+(nt(r.cU)+("\n, keepTheme = "+(nt(r.cV)+"\n}")))))},tt=sn,at=function(r){return v(V,c(function(e,n){var t=e.a,a=e.b;return v(M$,t,a,n)}),A$(0),r)},Dr=sn,ys=function(r){return at(_([l("tag",Dr("CookiesKept")),l("keepFont",tt(r.cT)),l("keepPrompt",tt(r.cU)),l("keepTheme",tt(r.cV))]))},Ts=c(function(r,e){return v(V,F$(r),P$(0),e)}),nn=Vt("setStorage",function(r){var e=r.a,n=r.b;return u(Ts,Xr,_([Dr(e),Xr(n)]))}),ae=function(r){return l(r,nn(l("CookiesKept",ys(r.r))))},Bs=c(function(r,e){var n=N(e);if(n.$===1)return l(y(r,{a:C(r.a,_([k("\n"+Cs(r.r))]))}),P);if(n.a==="set"){var t=function(){var i=Ir(e);if(i.$)return"";var s=i.a,f=Ir(s);if(f.$)return"";var m=f.a;return u(pr,"",N(m))}(),a=function(){var i=Ir(e);if(i.$)return"";var s=i.a;return u(pr,"",N(s))}(),$=r.r;if(t==="")return l(y(r,{a:C(r.a,v(q,2,3,e))}),P);switch(a){case"":return l(y(r,{a:C(r.a,v(q,2,2,e))}),P);case"keepFont":switch(t){case"true":return ae(y(r,{r:y($,{cT:!0})}));case"false":return ae(y(r,{r:y($,{cT:!1})}));default:return l(y(r,{a:C(r.a,v(q,2,3,e))}),P)}case"keepTheme":switch(t){case"true":return ae(y(r,{r:y($,{cV:!0})}));case"false":return ae(y(r,{r:y($,{cV:!1})}));default:return l(y(r,{a:C(r.a,v(q,2,3,e))}),P)}case"keepPrompt":switch(t){case"true":return ae(y(r,{r:y($,{cU:!0})}));case"false":return ae(y(r,{r:y($,{cU:!1})}));default:return l(y(r,{a:C(r.a,v(q,2,3,e))}),P)}default:return l(y(r,{a:C(r.a,v(q,2,2,e))}),P)}}else{var o=n.a;return l(y(r,{a:C(r.a,v(q,2,1,e))}),P)}}),Es=Vt("getStorage",Dr),js=c(function(r,e){return l(r,Es("Theme"))}),Ps=sn,As=function(r){return at(_([l("tag",Dr("Font")),l("fontSize",Ps(r.cM))]))},ut=function(r){return l(r,nn(l("Font",As(r.p))))},Ms=_$,Fs=c(function(r,e){var n=N(e);if(n.$===1)return l(y(r,{a:C(r.a,v(q,4,1,e))}),P);switch(n.a){case"size":var o=function(){var i=Ir(e);if(i.$)return"";var s=i.a;return u(pr,"",N(s))}(),t=Ms(o);if(t.$)switch(o){case"":return l(y(r,{a:C(r.a,_([k("\nfontSize is "+(Jn(r.p.cM)+"px"))]))}),P);case"reset":var $=y(r,{a:C(r.a,_([k("\nfontSize reset to 20px")])),p:{cM:20}});return ut($);default:return l(y(r,{a:C(r.a,_([k("\nfontSize "+(o+" not recognised; font size expected"))]))}),P)}else{var a=t.a;if(a>0){var $=y(r,{a:C(r.a,_([k("\nfontSize successfully set to "+(o+"px"))])),p:{cM:a}});return ut($)}else return l(y(r,{a:C(r.a,_([k("\nPlease enter a valid fontSize, a Float greater than 0")]))}),P)}case"reset":var $=y(r,{a:C(r.a,_([k("\nfontSize reset to 20px")])),p:{cM:20}});return ut($);default:var o=n.a;return l(y(r,{a:C(r.a,v(q,4,1,e))}),P)}}),Vs=c(function(r,e){var n=N(e);return n.$===1?l(y(r,{a:C(r.a,_([k("\nHello World!")]))}),P):l(y(r,{a:C(r.a,v(q,5,0,e))}),P)}),t_=11,ks=c(function(r,e){return l(y(r,{a:C(r.a,function(){if(Ur(e)<2){var n=N(e);if(n.$===1)return _([k("\n+--------------------------------------------------+\n|help prints this message |\n|help prints more information about |\n+--------------------------------------------------+\nclear clears the screen\ncookies [UNSTABLE] manages cookies\nhello prints hello world message\nfont manages font\nprompt [UNFINISHED] manages prompt\ntheme manages theme\ntodo prints aspirations for the site")]);switch(n.a){case"help":return _([k("\nhelp lists available commands with a short summary\nhelp prints more information about ")]);case"clear":return _([k("\nclear clears the screen")]);case"colors":return _([k("\ncolors "),u(ye,Te(11),"[UNIMPLEMENTED]")]);case"cookies":return _([k("\ncookies prints info about the current cookie settings\ncookies set [true|false] sets whether to store a certain cookie\noptions for are:\n keepFont - whether to store fontSize. Default fontSize is 20\n keepPrompt - whether to store prompt. Default prompt is >\n keepTheme - whether to store theme. Default theme is pit")]);case"hello":return _([k("\nhello prints `Hello World!`")]);case"font":return _([k("\nfont size prints info about the current font size\nfont size changes fontSize to if is >0\nfont reset changes fontSize to the default of 20px")]);case"prompt":return _([k("\nprompt prints info about the current prompt\nprompt set sets prompt text to \n is specified in quotes\nprompt color sets prompt color to \n run `colors` to list available colors")]);case"theme":return _([k("\ntheme sets the current theme according to \nOptions for are:\n sun - a theme blinding like the sun\n sky - a toned-down light theme\n dim - a deep and colorful dark theme\n pit - nearly black like the bottom of a pit")]);case"todo":return _([k("\ntodo prints aspirations for the site")]);default:var t=n.a;return v(q,6,1,e)}}else return v(q,6,1,e)}())}),P)}),Js=function(r){return at(_([l("tag",Dr("Prompt")),l("prompt",Dr(r.c1))]))},Us=function(r){return l(r,nn(l("Prompt",Js(r.c1))))},Ls=c(function(r,e){var n=N(e);if(n.$===1)return l(y(r,{a:C(r.a,_([k("\ncurrent prompt is "+r.c1.c1)]))}),P);var t=n.a,a=r.c1;return Us(y(r,{c1:y(a,{c1:t})}))}),Os=function(r){switch(r){case 0:return"Pit";case 1:return"Dim";case 2:return"Sky";default:return"Sun"}},Hs=u(Nr,Dr,Os),Rs=function(r){return l(r,nn(l("Theme",Hs(r.F))))},tn=c(function(r,e){var n=y(r,{F:e});return Rs(n)}),Gs=c(function(r,e){var n=N(e);if(n.$===1)return l(y(r,{a:C(r.a,_([k("\nThe current theme is "+function(){var a=r.F;switch(a){case 3:return"sun";case 2:return"sky";case 1:return"dim";default:return"pit"}}())]))}),P);switch(n.a){case"sun":return u(tn,r,3);case"sky":return u(tn,r,2);case"dim":return u(tn,r,1);case"pit":return u(tn,r,0);default:var t=n.a;return l(y(r,{a:C(r.a,v(q,8,1,e))}),P)}}),Is=c(function(r,e){return l(function(){var n=N(e);return n.$===1?y(r,{a:C(r.a,_([k("\nIn no particular order:\n- Implement colors throughout existing methods\n- Something like Neofetch\n- Collect and store feedback in a database\n- Create a style guide for programs involving console colors\n- Modularise the code (to have something more elegant than a single 2k line file)\n- Figure out a better way to parse commands\n- Add cache headers")]))}):y(r,{a:C(r.a,v(q,9,0,e))})}(),P)}),zs=c(function(r,e){if(e.$){if(e.a==="")return l(r,P);var a=e.a;return l(y(r,{a:C(r.a,_([k("\ncommand "+(a+" not recognised. Run `help` to find a valid command"))]))}),P)}else{var n=e.a.cB,t=e.a.cF;return u(function(){switch(t){case 6:return ks;case 0:return ws;case 1:return Ds;case 2:return Bs;case 3:return js;case 4:return Fs;case 5:return Vs;case 7:return Ls;case 8:return Gs;default:return Is}}(),r,n)}}),Ws=c(function(r,e){if(r.$===1)return e;var n=r.a;return e+(":"+Qr(n))}),su=D(function(r,e,n){if(e.$===1)return n;var t=e.a;return C(n,C(r,t))}),qs=function(r){var e=function(){var n=r.b6;return n?"https://":"http://"}();return v(su,"#",r.bN,v(su,"?",r.b7,C(u(Ws,r.b2,C(e,r.bR)),r.b0)))},Ys=c(function(r,e){switch(r.$){case 0:var n=r.a;if(n.$){var t=n.a;return l(e,ps(t))}else{var a=n.a;return l(e,u(Ss,e.bb,qs(a)))}case 1:var a=r.a;return l(y(e,{bo:a}),P);case 2:var $=r.a;return u(bs,"\n",$)?u(zs,y(e,{ay:"",a:C(e.a,_([k(oe(e.a,d)?"":"\n"),u(ye,Te(10),e.c1.c1),k(cu($))]))}),ds($)):l(y(e,{ay:$}),P);case 3:return l(e,P);default:var o=r.a;return u(_s,e,o)}}),Zs=c(function(r,e){return{cD:e,db:r}}),an=function(r){return{$:0,a:r}},$t=c(function(r,e){r:for(;;){if(e.$===-2)return M;var n=e.b,t=e.c,a=e.d,$=e.e,o=u(ja,r,n);switch(o){case 0:var i=r,s=a;r=i,e=s;continue r;case 1:return G(t);default:var i=r,s=$;r=i,e=s;continue r}}}),cr=c(function(r,e){var n=r.b,t=r.c;if(n){var a=u($t,t,e);return a.$?v(Pa,t,Xa(t),e):e}else return e}),ot=c(function(r,e){return u(to,io(r),so(e))}),kr=c(function(r,e){var n=e.a,t=e.b,a=e.c;if(t){var $=u($t,a,r);if($.$)return u(ot,"className",Dr("_unstyled"));var o=$.a;return u(ot,"className",Dr(o))}else return n}),un=c(function(r,e){var n=e.a,t=e.b,a=e.c;if(t){var $=u($t,a,r);if($.$)return u(ne,"class","_unstyled");var o=$.a;return u(ne,"class",o)}else return n}),it=function(r){return no(Je(r))},ct=c(function(r,e){return u(Lt,r,Je(e))}),Be=function(r){return Sn(Je(r))},st=c(function(r,e){return u(Ut,r,Je(e))}),ue=c(function(r,e){var n=r.a,t=r.b,a=e.a,$=e.b;switch(t.$){case 4:var A=t.a;return l(u(S,l(n,A),a),$);case 0:var m=t.a,b=t.b,h=t.c,p=v(V,cr,$,b),o=v(V,$e,l(d,p),h),w=o.a,T=o.b,A=v(Be,m,u(F,kr(T),b),R(w));return l(u(S,l(n,A),a),T);case 1:var f=t.a,m=t.b,b=t.c,h=t.d,p=v(V,cr,$,b),i=v(V,$e,l(d,p),h),w=i.a,T=i.b,A=U(st,f,m,u(F,kr(T),b),R(w));return l(u(S,l(n,A),a),T);case 2:var m=t.a,b=t.b,h=t.c,p=v(V,cr,$,b),s=v(V,ue,l(d,p),h),w=s.a,T=s.b,A=v(it,m,u(F,kr(T),b),R(w));return l(u(S,l(n,A),a),T);default:var f=t.a,m=t.b,b=t.c,h=t.d,p=v(V,cr,$,b),g=v(V,ue,l(d,p),h),w=g.a,T=g.b,A=U(ct,f,m,u(F,kr(T),b),R(w));return l(u(S,l(n,A),a),T)}}),$e=c(function(r,e){var n=e.a,t=e.b;switch(r.$){case 4:var w=r.a;return l(u(S,w,n),t);case 0:var s=r.a,f=r.b,m=r.c,b=v(V,cr,t,f),a=v(V,$e,l(d,b),m),p=a.a,g=a.b,w=v(Be,s,u(F,kr(g),f),R(p));return l(u(S,w,n),g);case 1:var i=r.a,s=r.b,f=r.c,m=r.d,b=v(V,cr,t,f),$=v(V,$e,l(d,b),m),p=$.a,g=$.b,w=U(st,i,s,u(F,un(g),f),R(p));return l(u(S,w,n),g);case 2:var s=r.a,f=r.b,m=r.c,b=v(V,cr,t,f),o=v(V,ue,l(d,b),m),p=o.a,g=o.b,w=v(it,s,u(F,kr(g),f),R(p));return l(u(S,w,n),g);default:var i=r.a,s=r.b,f=r.c,m=r.d,b=v(V,cr,t,f),h=v(V,ue,l(d,b),m),p=h.a,g=h.b,w=U(ct,i,s,u(F,un(g),f),R(p));return l(u(S,w,n),g)}}),ft=D(function(r,e,n){r:for(;;){if(n.$===-2)return e;var t=n.b,a=n.c,$=n.d,o=n.e,i=r,s=v(r,t,a,v(ft,r,e,$)),f=o;r=i,e=s,n=f;continue r}}),fu=D(function(r,e,n){return u(mr,e,u(Re,r,n))}),Qs=D(function(r,e,n){return n+("\n"+v(fu,rt,e,r))}),Xs=function(r){return v(ft,Qs,"",r)},vu=c(function(r,e){return v(ft,D(function(n,t,a){return a+("\n"+v(fu,"."+rt,"#"+(r+("."+t)),n))}),"",e)}),vt=c(function(r,e){var n=function(){if(e.$){var a=e.a,$=e.b,o=e.c;return u(vu,a,$)+("\n"+u(vu,a+" ",o))}else{var t=e.a;return Xs(t)}}();return v(Be,"span",_([u(ne,"style","display: none;"),u(ne,"class","elm-css-style-wrapper")]),_([v(Be,"style",function(){if(r.$)return d;var t=r.a;return _([u(ne,"nonce",t)])}(),Kn(Ca(n)))]))}),Ks=W(function(r,e,n,t){var a=v(V,cr,ge,n),$=v(V,$e,l(d,a),t),o=$.a,i=$.b,s=u(vt,r,an(i)),f=u(F,kr(i),n);return v(Be,e,f,u(S,s,R(o)))}),Ns=c(function(r,e){r:for(;;)if(e.b){var n=e.a,t=n.a,a=e.b;if(oe(r,t))return!0;var $=r,o=a;r=$,e=o;continue r}else return!1}),xs=c(function(r,e){r:for(;;)if(e.b){var n=e.a,t=n.a,a=e.b,$="_"+t;if(u(Ns,$,a)){var o=$,i=a;r=o,e=i;continue r}else return $}else return r}),lu=D(function(r,e,n){var t=u(xs,"_",n),a=u(vt,r,e);return l(t,a)}),rf=W(function(r,e,n,t){var a=v(V,cr,ge,n),$=v(V,ue,l(d,a),t),o=$.a,i=$.b,s=v(lu,r,an(i),o),f=u(F,kr(i),n);return v(it,e,f,u(S,s,R(o)))}),ef=ar(function(r,e,n,t,a){var $=v(V,cr,ge,t),o=v(V,ue,l(d,$),a),i=o.a,s=o.b,f=v(lu,r,an(s),i),m=u(F,un(s),t);return U(ct,e,n,m,u(S,f,R(i)))}),nf=ar(function(r,e,n,t,a){var $=v(V,cr,ge,t),o=v(V,$e,l(d,$),a),i=o.a,s=o.b,f=u(vt,r,an(s)),m=u(F,un(s),t);return U(st,e,n,m,u(S,f,R(i)))}),tf=function(r){switch(r.$){case 4:var e=r.a;return e;case 0:var t=r.a,a=r.b,$=r.c;return U(Ks,M,t,a,$);case 1:var n=r.a,t=r.b,a=r.c,$=r.d;return L(nf,M,n,t,a,$);case 2:var t=r.a,a=r.b,$=r.c;return U(rf,M,t,a,$);default:var n=r.a,t=r.b,a=r.c,$=r.d;return L(ef,M,n,t,a,$)}},af=tf,uf=function(r){return{$:2,a:r}},$f=c(function(r,e){return v(Ln,u(ot,r,e),!1,"")}),mu=c(function(r,e){return u($f,r,Dr(e))}),of=mu("id"),cf=function(r){return l(r,!0)},sf=function(r){return{$:1,a:r}},ff=Ot,vf=c(function(r,e){return v(Ln,u(ff,r,e),!1,"")}),lf=c(function(r,e){return u(vf,r,sf(e))}),mf=c(function(r,e){return v(Hr,gr,e,r)}),_f=u(mf,_(["target","value"]),We),bf=function(r){return u(lf,"input",u(Mn,cf,u(Mn,r,_f)))},a_=0,u_=1,pf=Un("main"),hf=Y("min-height"),$_=4,Br=c(function(r,e){r:for(;;){var n=r.F;switch(n){case 0:switch(e){case 0:return j("#120211");case 1:return j("#f3d9f0");case 2:var t=r,a=4;r=t,e=a;continue r;case 3:return j("#380e36");case 4:return j("#e29edc");case 5:return j("#7c2b77");default:return j("#f9ecf7")}case 1:switch(e){case 0:return j("#380e36");case 1:return j("#f7e5f4");case 2:var t=r,a=4;r=t,e=a;continue r;case 3:return j("#5e1c56");case 4:return j("#e8b2e2");case 5:return j("#9d3c98");default:return j("#fbf4fa")}case 2:switch(e){case 0:return j("#f3d9f0");case 1:return j("#380e36");case 2:var t=r,a=4;r=t,e=a;continue r;case 3:return j("#eec6e9");case 4:return j("#7c2b77");case 5:return j("#d575cd");default:return j("#120211")}default:switch(e){case 0:return j("#f9ecf7");case 1:return j("#5a1c56");case 2:var t=r,a=4;r=t,e=a;continue r;case 3:return j("#f3d9f0");case 4:return j("#9d3c98");case 5:return j("#dc8ed5");default:return j("#380e36")}}}}),o_=0,df=u(Qe,0,"vh"),i_=0,_u=u(Qe,0,"vw"),bu=Y("width"),Sf=function(r){return u(te,pf,_([xr(u(Br,r,0)),Se(u(Br,r,1)),hf(df(100)),bu(_u(100)),re(H(0)),ee(H(0))]))},gf=u(Ye,"display","flex"),wf=Y("flex-direction"),Df=Y("flex-start"),Cf=Y("flex-wrap"),yf=function(r){return{$:6,a:r}},zr=c(function(r,e){return Ta(r+(":"+e))}),Tf=D(function(r,e,n){r:for(;;)switch(n.$){case 0:var t=n.a,a=u(pr,"",N(u(Re,":",t)));return u(zr,e,a);case 1:var $=n.a;return u(zr,e,"elm-css-error-cannot-apply-"+(r+"-with-inapplicable-Style-for-selector"));case 2:var o=n.a;return u(zr,e,"elm-css-error-cannot-apply-"+(r+"-with-inapplicable-Style-for-combinator"));case 3:var i=n.a;return u(zr,e,"elm-css-error-cannot-apply-"+(r+"-with-inapplicable-Style-for-pseudo-element setter"));case 4:return u(zr,e,"elm-css-error-cannot-apply-"+(r+"-with-inapplicable-Style-for-media-query"));case 5:return u(zr,e,"elm-css-error-cannot-apply-"+(r+"-with-inapplicable-Style-for-keyframes"));default:if(n.a.b)if(n.a.b.b){var p=n.a,g=p.a,w=p.b,m=r,b=e,h=yf(w);r=m,e=b,n=h;continue r}else{var s=n.a,f=s.a,m=r,b=e,h=f;r=m,e=b,n=h;continue r}else return u(zr,e,"elm-css-error-cannot-apply-"+(r+"-with-empty-Style"))}}),c_=0,Bf=v(Qe,0,"",0),Ef=function(r){return v(Tf,"justifyContent","justify-content",r(Bf))},jf={az:0,aS:0,G:"nowrap",_:0},Pf={a9:0,az:0,G:"row"},Af=function(r){return u(te,Xe,_([xr(u(Br,r,0)),ee(H(0)),re(H(0)),gf,wf(Pf),Cf(jf),Ef(Df)]))},Mf=Y("flex-grow"),lt=Y("font-size"),pu=Y("height"),Ff={t:0,am:0,G:"hidden",aO:0},s_=0,Vf=function(r){return{Q:0,aT:0,T:0,D:0,aF:0,aV:0,M:r,as:"",aM:0,G:Qr(r)}},kf={aa:0,by:0,t:0,d:0,k:0,cO:0,bT:0,bc:0,ak:0,S:0,D:0,f:0,e:0,bf:0,aX:0,c0:0,A:0,aY:0,c4:0,ap:0,Y:0,w:0,j:0,dd:0,G:"none"},Jf=Y("outline-width"),Uf=Y("overflow"),Lf=Y("resize"),Of=Un("textarea"),Hf=function(r){return u(te,Of,_([Se(u(Br,r,1)),lt(H(r.p.cM)),ee(H(0)),re(H(0)),xr(u(Br,r,0)),Ze(H(0)),Jf(H(0)),pu(H(r.p.cM)),Lf(kf),Uf(Ff),Mf(Vf(100))]))},hu=Y("font-family"),du={P:0,G:"monospace"},Rf={G:"pre-wrap",_:0},Gf=Y("white-space"),If=function(r){return u(te,Xe,_([Se(u(Br,r,1)),lt(H(r.p.cM)),ee(H(0)),re(H(0)),xr(u(Br,r,0)),Ze(H(0)),bu(_u(100)),Gf(Rf),hu(du)]))},zf=function(r){return u(te,Xe,_([Se(u(Br,r,1)),lt(H(r.p.cM)),ee(H(0)),re(H(0)),xr(u(Br,r,0)),Ze(H(0)),pu(H(r.p.cM)),hu(du)]))},Wf=mu("value"),qf=function(r){return v(Sf,r,d,_([v(If,r,d,r.a),v(Af,r,d,_([v(zf,r,d,_([u(ye,Te(10),r.c1.c1)])),v(Hf,r,_([bf(uf),Wf(r.ay),of("init-focus")]),d)]))]))},Yf=function(r){return u(Zs,"elmskell",_([af(qf(r))]))},Zf=Vi({cQ:Ni,cZ:zo,c_:Io,c9:ec,dc:Ys,de:Yf});eo({Main:{init:Zf(ya)(0)}})})(this); diff --git a/assets/json/init.json b/assets/json/init.json new file mode 100755 index 0000000..2c63c08 --- /dev/null +++ b/assets/json/init.json @@ -0,0 +1,2 @@ +{ +} diff --git a/assets/json/test.json b/assets/json/test.json new file mode 100755 index 0000000..da132be --- /dev/null +++ b/assets/json/test.json @@ -0,0 +1,4 @@ +{ + "message0": "Hello World!", + "message1": "This is another message. Hello World!" +} diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100755 index 0000000..c368d45 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,2 @@ +.stack-work/ +*~ \ No newline at end of file diff --git a/backend/CHANGELOG.md b/backend/CHANGELOG.md new file mode 100755 index 0000000..1e535cd --- /dev/null +++ b/backend/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog for `hs-server` + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to the +[Haskell Package Versioning Policy](https://pvp.haskell.org/). + +## Unreleased + +## 0.1.0.0 - YYYY-MM-DD diff --git a/backend/LICENSE b/backend/LICENSE new file mode 100755 index 0000000..4810e24 --- /dev/null +++ b/backend/LICENSE @@ -0,0 +1,26 @@ +Copyright 2025 Author name here + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/backend/README.md b/backend/README.md new file mode 100755 index 0000000..de045bf --- /dev/null +++ b/backend/README.md @@ -0,0 +1,2 @@ +# hs-server +this is a custom-built single-purpose server infrastructure based on Scorry, Warp, and Wai. It holds up MTGmonkey's personal website diff --git a/backend/Setup.hs b/backend/Setup.hs new file mode 100755 index 0000000..9a994af --- /dev/null +++ b/backend/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/backend/app/Main.hs b/backend/app/Main.hs new file mode 100755 index 0000000..e2b879a --- /dev/null +++ b/backend/app/Main.hs @@ -0,0 +1,108 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE OverloadedStrings #-} +module Main (main) where + +import ElmskellTypes +import Data.Text.Lazy (Text) +import Network.Wai.Handler.Warp (Port) +import Network.Wai.Middleware.RequestLogger (logStdoutDev) +import Text.Blaze ((!)) +import Text.Blaze.Html.Renderer.Text (renderHtml) + +import Network.HTTP.Types +import Network.Wai.Middleware.Gzip +import Web.Scotty as S + +import qualified Control.Exception as E +import qualified Text.Blaze.Html5 as H +import qualified Text.Blaze.Html5.Attributes as A + +-- HTML +index :: H.Html -> Text +index compiledElmApp = renderHtml $ do + H.docTypeHtml $ do + H.head $ do + H.title "TESTING Scotty+Elm" + H.meta ! A.charset "utf-8" + H.style "body{margin:0px;}" + (H.body ! A.id "body") $ do + embedJs compiledElmApp + +-- CONF +port :: Port +port = 8080 + +adminContact :: String +adminContact = "[Matrix] @mtgmonkey:calitabby.net" + +compiledElmAppFile :: AssetPath +compiledElmAppFile = "/js/main.js" + +boilerplateJsFile :: AssetPath +boilerplateJsFile = "/js/init.js" + +assetsFolder :: FilePath +assetsFolder = "/home/mtgmonkey/elmskell/assets" + +-- MAIN +main :: IO () +main = do + + generateElmskellTypes + + compiledElmAppOrExc <- E.try $ readFile $ assetsFolder ++ compiledElmAppFile :: IO (Either E.IOException String) + let compiledElmApp = case compiledElmAppOrExc of + Left e -> serverErrorReadFile e + Right contents -> H.toHtml $ contents + + boilerplateJsOrExc <- E.try $ readFile $ assetsFolder ++ boilerplateJsFile :: IO (Either E.IOException String) + let boilerplateJs = case boilerplateJsOrExc of + Left e -> serverErrorReadFile e + Right contents -> H.toHtml $ contents + + let anyRoute = regex "^.*$" + scotty port $ do + + middleware $ gzip $ def { gzipFiles = GzipCompress } + middleware logStdoutDev + + -- GET requests + get "/" $ do + shortCache + status ok200 + S.html $ index $ do + compiledElmApp + boilerplateJs + + get "/favicon.ico/" $ do + shortCache + status notFound404 + S.html $ "you want a favi-whatnow!?" + + -- ERR + notFound $ do + noCache + status methodNotAllowed405 + S.text "Verb disallowed; OR, route doesn't exist :(" + + +-- FUNC +serverErrorReadFile :: E.IOException -> Js +serverErrorReadFile e = H.toHtml $ "document.getElementById('body').innerHTML='Server-side error occurred: " + ++ (show e) + ++ "; report this to a site administrator: " + ++ adminContact + ++ "';" + +shortCache :: ActionM () +shortCache = addHeader "Cache-Control" "max-age=21600" + +noCache :: ActionM () +noCache = addHeader "Cache-Control" "no-cache" + +embedJs :: Js -> H.Html +embedJs js = H.script $ js + + -- TYPES +type AssetPath = FilePath +type Js = H.Html diff --git a/backend/hs-server.cabal b/backend/hs-server.cabal new file mode 100755 index 0000000..3d73eab --- /dev/null +++ b/backend/hs-server.cabal @@ -0,0 +1,91 @@ +cabal-version: 2.2 + +-- This file has been generated from package.yaml by hpack version 0.37.0. +-- +-- see: https://github.com/sol/hpack + +name: hs-server +version: 0.1.0.0 +description: Please see README.md +author: mtgmonkey +maintainer: mtgmonkey +copyright: 2025 mtgmonkey +license: BSD-3-Clause +license-file: LICENSE +build-type: Simple +extra-source-files: + README.md + CHANGELOG.md + +library + exposed-modules: + ElmskellTypes + other-modules: + Paths_hs_server + autogen-modules: + Paths_hs_server + hs-source-dirs: + src + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints + build-depends: + aeson >=2.2.3 && <2.3 + , base >=4.19.2 && <4.20 + , blaze-html >=0.9.2 && <0.10 + , blaze-markup >=0.8.3 && <0.9 + , directory >=1.3.8 && <1.4 + , elm-street >=0.2.2 && <0.3 + , http-types >=0.12.4 && <0.13 + , scotty ==0.22.* + , text >=2.1.1 && <2.2 + , wai-extra >=3.1.16 && <3.2 + , warp >=3.4.7 && <3.5 + default-language: Haskell2010 + +executable hs-server-exe + main-is: Main.hs + other-modules: + Paths_hs_server + autogen-modules: + Paths_hs_server + hs-source-dirs: + app + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N + build-depends: + aeson >=2.2.3 && <2.3 + , base >=4.19.2 && <4.20 + , blaze-html >=0.9.2 && <0.10 + , blaze-markup >=0.8.3 && <0.9 + , directory >=1.3.8 && <1.4 + , elm-street >=0.2.2 && <0.3 + , hs-server + , http-types >=0.12.4 && <0.13 + , scotty ==0.22.* + , text >=2.1.1 && <2.2 + , wai-extra >=3.1.16 && <3.2 + , warp >=3.4.7 && <3.5 + default-language: Haskell2010 + +test-suite hs-server-test + type: exitcode-stdio-1.0 + main-is: Spec.hs + other-modules: + Paths_hs_server + autogen-modules: + Paths_hs_server + hs-source-dirs: + test + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N + build-depends: + aeson >=2.2.3 && <2.3 + , base >=4.19.2 && <4.20 + , blaze-html >=0.9.2 && <0.10 + , blaze-markup >=0.8.3 && <0.9 + , directory >=1.3.8 && <1.4 + , elm-street >=0.2.2 && <0.3 + , hs-server + , http-types >=0.12.4 && <0.13 + , scotty ==0.22.* + , text >=2.1.1 && <2.2 + , wai-extra >=3.1.16 && <3.2 + , warp >=3.4.7 && <3.5 + default-language: Haskell2010 diff --git a/backend/package.yaml b/backend/package.yaml new file mode 100755 index 0000000..6fecc4f --- /dev/null +++ b/backend/package.yaml @@ -0,0 +1,68 @@ +name: hs-server +version: 0.1.0.0 +license: BSD-3-Clause +author: "mtgmonkey" +maintainer: "mtgmonkey" +copyright: "2025 mtgmonkey" + +extra-source-files: +- README.md +- CHANGELOG.md + +# Metadata used when publishing your package +# synopsis: Short description of your package +# category: Web + +# To avoid duplicated efforts in documentation and dealing with the +# complications of embedding Haddock markup inside cabal files, it is +# common to point users to the README.md file. +description: Please see README.md + +dependencies: +- aeson >= 2.2.3 && < 2.3 +- base >= 4.19.2 && < 4.20 +- blaze-html >= 0.9.2 && < 0.10 +- blaze-markup >= 0.8.3 && < 0.9 +- directory >= 1.3.8 && < 1.4 +- elm-street >= 0.2.2 && < 0.3 +- http-types >= 0.12.4 && < 0.13 +- scotty >= 0.22 && < 0.23 +- text >= 2.1.1 && < 2.2 +- wai-extra >= 3.1.16 && < 3.2 +- warp >= 3.4.7 && < 3.5 + +ghc-options: +- -Wall +- -Wcompat +- -Widentities +- -Wincomplete-record-updates +- -Wincomplete-uni-patterns +- -Wmissing-export-lists +- -Wmissing-home-modules +- -Wpartial-fields +- -Wredundant-constraints + +library: + source-dirs: src + +executables: + hs-server-exe: + main: Main.hs + source-dirs: app + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - hs-server + +tests: + hs-server-test: + main: Spec.hs + source-dirs: test + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - hs-server diff --git a/backend/stack.yaml b/backend/stack.yaml new file mode 100755 index 0000000..e4f847c --- /dev/null +++ b/backend/stack.yaml @@ -0,0 +1,74 @@ +# This file was automatically generated by 'stack init' +# +# Some commonly used options have been documented as comments in this file. +# For advanced use and comprehensive documentation of the format, please see: +# https://docs.haskellstack.org/en/stable/yaml_configuration/ + +# A 'specific' Stackage snapshot or a compiler version. +# A snapshot resolver dictates the compiler version and the set of packages +# to be used for project dependencies. For example: +# +# snapshot: lts-22.28 +# snapshot: nightly-2024-07-05 +# snapshot: ghc-9.6.6 +# +# The location of a snapshot can be provided as a file or url. Stack assumes +# a snapshot provided as a file might change, whereas a url resource does not. +# +# snapshot: ./custom-snapshot.yaml +# snapshot: https://example.com/snapshots/2024-01-01.yaml +snapshot: + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/19.yaml + +# User packages to be built. +# Various formats can be used as shown in the example below. +# +# packages: +# - some-directory +# - https://example.com/foo/bar/baz-0.0.2.tar.gz +# subdirs: +# - auto-update +# - wai +# +# packages is represented in package.yaml +packages: +- . + +nix: + enable: true + packages: [zlib] + +# Dependency packages to be pulled from upstream that are not in the snapshot. +# These entries can reference officially published versions as well as +# forks / in-progress versions pinned to a git hash. For example: +# +# extra-deps: +# - acme-missiles-0.3 +# - git: https://github.com/commercialhaskell/stack.git +# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a +# +# extra-deps: [] + +# Override default flag values for project packages and extra-deps +# flags: {} + +# Extra package databases containing global packages +# extra-package-dbs: [] + +# Control whether we use the GHC we find on the path +# system-ghc: true +# +# Require a specific version of Stack, using version ranges +# require-stack-version: -any # Default +# require-stack-version: ">=3.1" +# +# Override the architecture used by Stack, especially useful on Windows +# arch: i386 +# arch: x86_64 +# +# Extra directories used by Stack for building +# extra-include-dirs: [/path/to/dir] +# extra-lib-dirs: [/path/to/dir] +# +# Allow a newer minor version of GHC than the snapshot specifies +# compiler-check: newer-minor diff --git a/backend/stack.yaml.lock b/backend/stack.yaml.lock new file mode 100755 index 0000000..e0ca7a4 --- /dev/null +++ b/backend/stack.yaml.lock @@ -0,0 +1,13 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: [] +snapshots: +- completed: + sha256: 296a7960c37efa382432ab497161a092684191815eb92a608c5d6ea5f894ace3 + size: 683835 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/19.yaml + original: + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/23/19.yaml diff --git a/flake.lock b/flake.lock index 190eaf7..1a2b6d9 100644 --- a/flake.lock +++ b/flake.lock @@ -2,6 +2,7 @@ "nodes": { "nixpkgs": { "locked": { +<<<<<<< HEAD "lastModified": 1748708770, "narHash": "sha256-q8jG2HJWgooWa9H0iatZqBPF3bp0504e05MevFmnFLY=", "owner": "NixOS", @@ -13,6 +14,20 @@ "id": "nixpkgs", "ref": "nixos-25.05", "type": "indirect" +======= + "lastModified": 1747958103, + "narHash": "sha256-qmmFCrfBwSHoWw7cVK4Aj+fns+c54EBP8cGqp/yK410=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "fe51d34885f7b5e3e7b59572796e1bcb427eccb1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" +>>>>>>> master } }, "root": { diff --git a/flake.nix b/flake.nix index 957e8e0..e6a7b17 100644 --- a/flake.nix +++ b/flake.nix @@ -1,4 +1,5 @@ { +<<<<<<< HEAD inputs = { nixpkgs.url = "nixpkgs/nixos-25.05"; }; @@ -9,6 +10,37 @@ packages.${system} = { default = pkgs.callPackage ./package.nix {}; frontend = pkgs.callPackage ./elmskell-frontend.nix {}; +======= + description = "elmskell"; + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + }; + outputs = inputs @ {...}: let + utilities = [ + pkgs.httpie + ]; + deps = [ + pkgs.cowsay + pkgs.just + pkgs.elmPackages.elm + pkgs.elmPackages.elm-format + pkgs.esbuild + pkgs.stack + ]; + pkgs = import inputs.nixpkgs { + system = "x86_64-linux"; + }; + in { + devShell.x86_64-linux = pkgs.mkShell { + packages = [ + utilities + deps + ]; + shellHook = '' + export PS1='\h@\[\e[30;48;5;202;1m\]elmskell\[\e[0m\]|\w\\$ ' && + cowsay "Welcome to elmskell! Run 'just' to build!" + ''; +>>>>>>> master }; }; } diff --git a/frontend/elm-stuff/0.19.1/d.dat b/frontend/elm-stuff/0.19.1/d.dat new file mode 100644 index 0000000..c440da6 Binary files /dev/null and b/frontend/elm-stuff/0.19.1/d.dat differ diff --git a/frontend/elm-stuff/0.19.1/i.dat b/frontend/elm-stuff/0.19.1/i.dat new file mode 100644 index 0000000..0571e15 Binary files /dev/null and b/frontend/elm-stuff/0.19.1/i.dat differ diff --git a/frontend/elm-stuff/0.19.1/lock b/frontend/elm-stuff/0.19.1/lock new file mode 100644 index 0000000..e69de29 diff --git a/frontend/elm-stuff/0.19.1/o.dat b/frontend/elm-stuff/0.19.1/o.dat new file mode 100644 index 0000000..f6bb556 Binary files /dev/null and b/frontend/elm-stuff/0.19.1/o.dat differ diff --git a/frontend/shell.nix b/frontend/shell.nix new file mode 100755 index 0000000..20dc38c --- /dev/null +++ b/frontend/shell.nix @@ -0,0 +1,9 @@ +{pkgs ? import {}}: +pkgs.mkShell { + nativeBuildInputs = [ + pkgs.elmPackages.elm + pkgs.elmPackages.elm-format + pkgs.uglify-js + pkgs.ungoogled-chromium + ]; +} diff --git a/frontend/src/ElmskellTypes/Generated/Decoder.elm b/frontend/src/ElmskellTypes/Generated/Decoder.elm new file mode 100755 index 0000000..2992128 --- /dev/null +++ b/frontend/src/ElmskellTypes/Generated/Decoder.elm @@ -0,0 +1,40 @@ +module ElmskellTypes.Generated.Decoder exposing (..) + +import Iso8601 as Iso +import Json.Decode as D exposing (..) +import Json.Decode.Pipeline as D exposing (required) + +import ElmskellTypes.Generated.ElmStreet exposing (..) +import ElmskellTypes.Generated.Types as T + + +decodeCommand : Decoder T.Command +decodeCommand = elmStreetDecodeEnum T.readCommand + +decodeCookiesKept : Decoder T.CookiesKept +decodeCookiesKept = D.succeed T.CookiesKept + |> required "keepFont" D.bool + |> required "keepPrompt" D.bool + |> required "keepTheme" D.bool + +decodeCoreColor : Decoder T.CoreColor +decodeCoreColor = elmStreetDecodeEnum T.readCoreColor + +decodeFont : Decoder T.Font +decodeFont = D.succeed T.Font + |> required "fontSize" D.float + +decodeInput : Decoder T.Input +decodeInput = D.succeed T.Input + |> required "command" decodeCommand + |> required "args" (D.list D.string) + +decodePrompt : Decoder T.Prompt +decodePrompt = D.succeed T.Prompt + |> required "prompt" D.string + +decodeTheme : Decoder T.Theme +decodeTheme = elmStreetDecodeEnum T.readTheme + +decodeThemeColor : Decoder T.ThemeColor +decodeThemeColor = elmStreetDecodeEnum T.readThemeColor diff --git a/frontend/src/ElmskellTypes/Generated/ElmStreet.elm b/frontend/src/ElmskellTypes/Generated/ElmStreet.elm new file mode 100755 index 0000000..129371a --- /dev/null +++ b/frontend/src/ElmskellTypes/Generated/ElmStreet.elm @@ -0,0 +1,52 @@ +module ElmskellTypes.Generated.ElmStreet exposing (..) + +import Json.Encode as E exposing (Value) +import Json.Decode as D exposing (Decoder) +import Json.Decode.Pipeline as D exposing (..) + + +elmStreetEncodeMaybe : (a -> Value) -> Maybe a -> Value +elmStreetEncodeMaybe enc = Maybe.withDefault E.null << Maybe.map enc + +elmStreetEncodeEither : (a -> Value) -> (b -> Value) -> Result a b -> Value +elmStreetEncodeEither encA encB res = E.object <| case res of + Err a -> [("Left", encA a)] + Ok b -> [("Right", encB b)] + +elmStreetEncodePair : (a -> Value) -> (b -> Value) -> (a, b) -> Value +elmStreetEncodePair encA encB (a, b) = E.list identity [encA a, encB b] + +elmStreetEncodeTriple : (a -> Value) -> (b -> Value) -> (c -> Value) -> (a, b, c) -> Value +elmStreetEncodeTriple encA encB encC (a, b, c) = E.list identity [encA a, encB b, encC c] + +elmStreetEncodeNonEmpty : (a -> Value) -> (a, List a) -> Value +elmStreetEncodeNonEmpty encA (a, xs) = E.list encA <| a :: xs + +decodeStr : (String -> Maybe a) -> String -> Decoder a +decodeStr readX x = case readX x of + Just a -> D.succeed a + Nothing -> D.fail "Constructor not matched" + +elmStreetDecodeEnum : (String -> Maybe a) -> Decoder a +elmStreetDecodeEnum r = D.andThen (decodeStr r) D.string + +elmStreetDecodeChar : Decoder Char +elmStreetDecodeChar = D.andThen (decodeStr (Maybe.map Tuple.first << String.uncons)) D.string + +elmStreetDecodeEither : Decoder a -> Decoder b -> Decoder (Result a b) +elmStreetDecodeEither decA decB = D.oneOf + [ D.field "Left" (D.map Err decA) + , D.field "Right" (D.map Ok decB) + ] + +elmStreetDecodePair : Decoder a -> Decoder b -> Decoder (a, b) +elmStreetDecodePair decA decB = D.map2 Tuple.pair (D.index 0 decA) (D.index 1 decB) + +elmStreetDecodeTriple : Decoder a -> Decoder b -> Decoder c -> Decoder (a, b, c) +elmStreetDecodeTriple decA decB decC = D.map3 (\a b c -> (a,b,c)) (D.index 0 decA) (D.index 1 decB) (D.index 2 decC) + +elmStreetDecodeNonEmpty : Decoder a -> Decoder (a, List a) +elmStreetDecodeNonEmpty decA = D.list decA |> D.andThen (\xs -> case xs of + h::t -> D.succeed (h, t) + _ -> D.fail "Expecting non-empty array") + diff --git a/frontend/src/ElmskellTypes/Generated/Encoder.elm b/frontend/src/ElmskellTypes/Generated/Encoder.elm new file mode 100755 index 0000000..3ae7cbd --- /dev/null +++ b/frontend/src/ElmskellTypes/Generated/Encoder.elm @@ -0,0 +1,47 @@ +module ElmskellTypes.Generated.Encoder exposing (..) + +import Iso8601 as Iso +import Json.Encode as E exposing (..) + +import ElmskellTypes.Generated.ElmStreet exposing (..) +import ElmskellTypes.Generated.Types as T + + +encodeCommand : T.Command -> Value +encodeCommand = E.string << T.showCommand + +encodeCookiesKept : T.CookiesKept -> Value +encodeCookiesKept x = E.object + [ ("tag", E.string "CookiesKept") + , ("keepFont", E.bool x.keepFont) + , ("keepPrompt", E.bool x.keepPrompt) + , ("keepTheme", E.bool x.keepTheme) + ] + +encodeCoreColor : T.CoreColor -> Value +encodeCoreColor = E.string << T.showCoreColor + +encodeFont : T.Font -> Value +encodeFont x = E.object + [ ("tag", E.string "Font") + , ("fontSize", E.float x.fontSize) + ] + +encodeInput : T.Input -> Value +encodeInput x = E.object + [ ("tag", E.string "Input") + , ("command", encodeCommand x.command) + , ("args", (E.list E.string) x.args) + ] + +encodePrompt : T.Prompt -> Value +encodePrompt x = E.object + [ ("tag", E.string "Prompt") + , ("prompt", E.string x.prompt) + ] + +encodeTheme : T.Theme -> Value +encodeTheme = E.string << T.showTheme + +encodeThemeColor : T.ThemeColor -> Value +encodeThemeColor = E.string << T.showThemeColor diff --git a/frontend/src/ElmskellTypes/Generated/Types.elm b/frontend/src/ElmskellTypes/Generated/Types.elm new file mode 100755 index 0000000..9086a31 --- /dev/null +++ b/frontend/src/ElmskellTypes/Generated/Types.elm @@ -0,0 +1,197 @@ +module ElmskellTypes.Generated.Types exposing (..) + +import Time exposing (Posix) +import Json.Decode exposing (Value) + + +type Command + = ClearCommand + | ColorsCommand + | CookiesCommand + | DebugCommand + | FontCommand + | HelloCommand + | HelpCommand + | PromptCommand + | ThemeCommand + | TodoCommand + +showCommand : Command -> String +showCommand x = case x of + ClearCommand -> "ClearCommand" + ColorsCommand -> "ColorsCommand" + CookiesCommand -> "CookiesCommand" + DebugCommand -> "DebugCommand" + FontCommand -> "FontCommand" + HelloCommand -> "HelloCommand" + HelpCommand -> "HelpCommand" + PromptCommand -> "PromptCommand" + ThemeCommand -> "ThemeCommand" + TodoCommand -> "TodoCommand" + +readCommand : String -> Maybe Command +readCommand x = case x of + "ClearCommand" -> Just ClearCommand + "ColorsCommand" -> Just ColorsCommand + "CookiesCommand" -> Just CookiesCommand + "DebugCommand" -> Just DebugCommand + "FontCommand" -> Just FontCommand + "HelloCommand" -> Just HelloCommand + "HelpCommand" -> Just HelpCommand + "PromptCommand" -> Just PromptCommand + "ThemeCommand" -> Just ThemeCommand + "TodoCommand" -> Just TodoCommand + _ -> Nothing + +universeCommand : List Command +universeCommand = [ ClearCommand + , ColorsCommand + , CookiesCommand + , DebugCommand + , FontCommand + , HelloCommand + , HelpCommand + , PromptCommand + , ThemeCommand + , TodoCommand ] + +type alias CookiesKept = + { keepFont : Bool + , keepPrompt : Bool + , keepTheme : Bool + } + +type CoreColor + = Red + | Green + | Yellow + | Blue + | Magenta + | Cyan + | BrightRed + | BrightGreen + | BrightYellow + | BrightBlue + | BrightMagenta + | BrightCyan + +showCoreColor : CoreColor -> String +showCoreColor x = case x of + Red -> "Red" + Green -> "Green" + Yellow -> "Yellow" + Blue -> "Blue" + Magenta -> "Magenta" + Cyan -> "Cyan" + BrightRed -> "BrightRed" + BrightGreen -> "BrightGreen" + BrightYellow -> "BrightYellow" + BrightBlue -> "BrightBlue" + BrightMagenta -> "BrightMagenta" + BrightCyan -> "BrightCyan" + +readCoreColor : String -> Maybe CoreColor +readCoreColor x = case x of + "Red" -> Just Red + "Green" -> Just Green + "Yellow" -> Just Yellow + "Blue" -> Just Blue + "Magenta" -> Just Magenta + "Cyan" -> Just Cyan + "BrightRed" -> Just BrightRed + "BrightGreen" -> Just BrightGreen + "BrightYellow" -> Just BrightYellow + "BrightBlue" -> Just BrightBlue + "BrightMagenta" -> Just BrightMagenta + "BrightCyan" -> Just BrightCyan + _ -> Nothing + +universeCoreColor : List CoreColor +universeCoreColor = [ Red + , Green + , Yellow + , Blue + , Magenta + , Cyan + , BrightRed + , BrightGreen + , BrightYellow + , BrightBlue + , BrightMagenta + , BrightCyan ] + +type alias Font = + { fontSize : Float + } + +type alias Input = + { command : Command + , args : List String + } + +type alias Prompt = + { prompt : String + } + +type Theme + = Pit + | Dim + | Sky + | Sun + +showTheme : Theme -> String +showTheme x = case x of + Pit -> "Pit" + Dim -> "Dim" + Sky -> "Sky" + Sun -> "Sun" + +readTheme : String -> Maybe Theme +readTheme x = case x of + "Pit" -> Just Pit + "Dim" -> Just Dim + "Sky" -> Just Sky + "Sun" -> Just Sun + _ -> Nothing + +universeTheme : List Theme +universeTheme = [Pit, Dim, Sky, Sun] + +type ThemeColor + = Background + | Foreground + | Cursor + | Black + | White + | BrightBlack + | BrightWhite + +showThemeColor : ThemeColor -> String +showThemeColor x = case x of + Background -> "Background" + Foreground -> "Foreground" + Cursor -> "Cursor" + Black -> "Black" + White -> "White" + BrightBlack -> "BrightBlack" + BrightWhite -> "BrightWhite" + +readThemeColor : String -> Maybe ThemeColor +readThemeColor x = case x of + "Background" -> Just Background + "Foreground" -> Just Foreground + "Cursor" -> Just Cursor + "Black" -> Just Black + "White" -> Just White + "BrightBlack" -> Just BrightBlack + "BrightWhite" -> Just BrightWhite + _ -> Nothing + +universeThemeColor : List ThemeColor +universeThemeColor = [ Background + , Foreground + , Cursor + , Black + , White + , BrightBlack + , BrightWhite ] diff --git a/frontend/src/Main.elm b/frontend/src/Main.elm new file mode 100755 index 0000000..7ef05a4 --- /dev/null +++ b/frontend/src/Main.elm @@ -0,0 +1,1173 @@ +port module Main exposing (..) + +import Browser +import Browser.Dom as Dom +import Browser.Navigation as Nav +import Css exposing (..) +import ElmskellTypes.Generated.Decoder exposing (..) +import ElmskellTypes.Generated.ElmStreet exposing (..) +import ElmskellTypes.Generated.Encoder exposing (..) +import ElmskellTypes.Generated.Types exposing (..) +import Html.Styled exposing (Attribute, Html, styled, text, toUnstyled) +import Html.Styled.Attributes exposing (id, value) +import Html.Styled.Events exposing (onInput) +import Json.Decode as D +import Json.Encode as E +import Task +import Url + + + +-- MAIN + + +main : Program E.Value Model Msg +main = + Browser.application + { init = init + , view = view + , update = update + , subscriptions = subscriptions + , onUrlChange = UrlChanged + , onUrlRequest = LinkClicked + } + + + +-- MODEL + + +type alias Model = + { key : Nav.Key + , url : Url.Url + , theme : Theme + , font : Font + , cookiesKept : CookiesKept + , prompt : Prompt + , content : List (Html Msg) + , cliContent : String + } + + +defaultCookies : + { cookiesKept : CookiesKept + , font : Font + , prompt : Prompt + , theme : Theme + } +defaultCookies = + { font = { fontSize = 20.0 } + , cookiesKept = + { keepTheme = True + , keepFont = True + , keepPrompt = True + } + , theme = Dim + , prompt = { prompt = ">" } + } + + +init : E.Value -> Url.Url -> Nav.Key -> ( Model, Cmd Msg ) +init flags url key = + let + initContent = + [ text "Welcome to my website! Pardon the alpha quality for the time being" + , text "\nRun `help` to get started" + ] + + th = + case D.decodeValue (D.field "Theme" decodeTheme) flags of + Ok val -> + val + + Err _ -> + defaultCookies.theme + + pr = + case D.decodeValue (D.field "Prompt" decodePrompt) flags of + Ok val -> + val + + Err _ -> + defaultCookies.prompt + + cK = + case D.decodeValue (D.field "CookiesKept" decodeCookiesKept) flags of + Ok val -> + val + + Err _ -> + defaultCookies.cookiesKept + + fo = + case D.decodeValue (D.field "Font" decodeFont) flags of + Ok val -> + val + + Err _ -> + defaultCookies.font + in + ( { key = key + , url = url + , theme = th + , font = fo + , cookiesKept = cK + , prompt = pr + , content = initContent + , cliContent = "" + } + , Task.attempt (\_ -> NoInitFocus) (Dom.focus "init-focus") + ) + + + +-- UPDATE + + +type Msg + = LinkClicked Browser.UrlRequest + | UrlChanged Url.Url + | TakeInput String + | NoInitFocus + | ReceivedStorage E.Value + + +update : Msg -> Model -> ( Model, Cmd Msg ) +update msg model = + case msg of + LinkClicked urlRequest -> + case urlRequest of + Browser.Internal url -> + ( model, Nav.pushUrl model.key (Url.toString url) ) + + Browser.External href -> + ( model, Nav.load href ) + + UrlChanged url -> + ( { model | url = url } + , Cmd.none + ) + + TakeInput string -> + if String.endsWith "\n" string then + runCommand + { model + | cliContent = "" + , content = + model.content + ++ [ text + (if model.content /= [] then + "\n" + + else + "" + ) + , coloredText (coreColor BrightMagenta) model.prompt.prompt + , text <| String.trim string + ] + } + (parseInput string) + + else + ( { model | cliContent = string }, Cmd.none ) + + NoInitFocus -> + ( model, Cmd.none ) + + ReceivedStorage value -> + applyJSONData model value + + +applyJSONData : Model -> E.Value -> ( Model, Cmd Msg ) +applyJSONData model data = + case D.decodeValue (D.field "name" D.string) data of + Ok "Theme" -> + case D.decodeValue (D.field "data" decodeTheme) data of + Ok th -> + ( { model | theme = th }, Cmd.none ) + + Err e -> + errApplyingJSON model e + + Ok "Prompt" -> + case D.decodeValue (D.field "data" decodePrompt) data of + Ok pr -> + ( { model | prompt = pr }, Cmd.none ) + + Err e -> + errApplyingJSON model e + + Ok "Font" -> + case D.decodeValue (D.field "data" decodeFont) data of + Ok fo -> + ( { model | font = fo }, Cmd.none ) + + Err e -> + errApplyingJSON model e + + Ok _ -> + ( { model | content = model.content ++ [ text "expecting field `name` to contain type while applyJSONData" ] }, Cmd.none ) + + Err e -> + errApplyingJSON model e + + +errApplyingJSON : Model -> D.Error -> ( Model, Cmd Msg ) +errApplyingJSON model e = + ( { model | content = model.content ++ [ coloredText (coreColor Red) <| "\n" ++ D.errorToString e ] }, Cmd.none ) + + +isOK : Result x a -> Bool +isOK res = + case res of + Ok _ -> + True + + Err _ -> + False + + + +-- COMMANDS + + +parseInput : String -> Result String Input +parseInput input = + let + tokens = + List.map String.trim (String.split " " input) + + command = + case List.head tokens of + Just "help" -> + Ok HelpCommand + + Just "clear" -> + Ok ClearCommand + + Just "colors" -> + Ok ColorsCommand + + Just "cookies" -> + Ok CookiesCommand + + Just "debug" -> + Ok DebugCommand + + Just "font" -> + Ok FontCommand + + Just "hello" -> + Ok HelloCommand + + Just "prompt" -> + Ok PromptCommand + + Just "theme" -> + Ok ThemeCommand + + Just "todo" -> + Ok TodoCommand + + Just trimput -> + Err trimput + + _ -> + Err "error in parseInput parsing tokens" + + args = + case List.tail tokens of + Just tail -> + Ok <| List.filter ((/=) "") tail + + _ -> + Err "error in parseInput parsing tokens" + in + case args of + Ok arguments -> + case command of + Ok cmd -> + Ok { command = cmd, args = arguments } + + Err err -> + Err err + + Err err -> + Err err + + +runCommand : Model -> Result String Input -> ( Model, Cmd Msg ) +runCommand model input = + case input of + Ok { command, args } -> + (case command of + HelpCommand -> + runHelp + + ClearCommand -> + runClear + + ColorsCommand -> + runColors + + CookiesCommand -> + runCookies + + DebugCommand -> + runDebug + + FontCommand -> + runFont + + HelloCommand -> + runHello + + PromptCommand -> + runPrompt + + ThemeCommand -> + runTheme + + TodoCommand -> + runTodo + ) + model + args + + Err "" -> + ( model, Cmd.none ) + + Err string -> + ( { model + | content = model.content ++ [ text <| "\ncommand " ++ string ++ " not recognised. Run `help` to find a valid command" ] + } + , Cmd.none + ) + + +type alias CommandRunner = + Model -> List String -> ( Model, Cmd Msg ) + + +runHelp : CommandRunner +runHelp model args = + ( { model + | content = + model.content + ++ (if List.length args < 2 then + case List.head args of + Nothing -> + [ text <| + "\n+--------------------------------------------------+" + ++ "\n|help prints this message |" + ++ "\n|help prints more information about |" + ++ "\n+--------------------------------------------------+" + ++ "\nclear clears the screen" + ++ "\ncookies [UNSTABLE] manages cookies" + ++ "\nhello prints hello world message" + ++ "\nfont manages font" + ++ "\nprompt [UNFINISHED] manages prompt" + ++ "\ntheme manages theme" + ++ "\ntodo prints aspirations for the site" + ] + + Just "help" -> + [ text <| + "\nhelp lists available commands with a short summary" + ++ "\nhelp prints more information about " + ] + + Just "clear" -> + [ text <| "\nclear clears the screen" + ] + + Just "colors" -> + [ text "\ncolors ", coloredText (coreColor BrightCyan) "[UNIMPLEMENTED]" ] + + Just "cookies" -> + [ text <| + "\ncookies prints info about the current cookie settings" + ++ "\ncookies set [true|false] sets whether to store a certain cookie" + ++ "\noptions for are:" + ++ "\n keepFont - whether to store fontSize. Default fontSize is 20" + ++ "\n keepPrompt - whether to store prompt. Default prompt is >" + ++ "\n keepTheme - whether to store theme. Default theme is pit" + ] + + Just "hello" -> + [ text <| "\nhello prints `Hello World!`" + ] + + Just "font" -> + [ text <| + "\nfont size prints info about the current font size" + ++ "\nfont size changes fontSize to if is >0" + ++ "\nfont reset changes fontSize to the default of 20px" + ] + + Just "prompt" -> + [ text <| + "\nprompt prints info about the current prompt" + ++ "\nprompt set sets prompt text to " + ++ "\n is specified in quotes" + ++ "\nprompt color sets prompt color to " + ++ "\n run `colors` to list available colors" + ] + + Just "theme" -> + [ text <| + "\ntheme sets the current theme according to " + ++ "\nOptions for are:" + ++ "\n sun - a theme blinding like the sun" + ++ "\n sky - a toned-down light theme" + ++ "\n dim - a deep and colorful dark theme" + ++ "\n pit - nearly black like the bottom of a pit" + ] + + Just "todo" -> + [ text "\ntodo prints aspirations for the site" ] + + Just string -> + wrongArgs HelpCommand 1 args + + else + wrongArgs HelpCommand 1 args + ) + } + , Cmd.none + ) + + +runClear : CommandRunner +runClear model args = + ( case List.head args of + Nothing -> + { model | content = [] } + + Just string -> + { model | content = model.content ++ wrongArgs ClearCommand 0 args } + , Cmd.none + ) + + +runColors : CommandRunner +runColors model args = + case List.head args of + Nothing -> + ( { model | content = model.content ++ wrongArgs ColorsCommand 1 args }, Cmd.none ) + + Just "test" -> + ( { model + | content = + model.content + ++ [ coloredText (coreColor Red) "Red" ] + } + , Cmd.none + ) + + Just _ -> + ( { model | content = model.content ++ wrongArgs ColorsCommand 1 args }, Cmd.none ) + + +runCookies : CommandRunner +runCookies model args = + case List.head args of + Nothing -> + ( { model | content = model.content ++ [ text <| "\n" ++ cookiesKeptToString model.cookiesKept ] }, Cmd.none ) + + Just "set" -> + let + cookiesKept = + model.cookiesKept + + second = + case List.tail args of + Just tail -> + Maybe.withDefault "" (List.head tail) + + Nothing -> + "" + + third = + case List.tail args of + Just tail -> + case List.tail tail of + Just tail2 -> + Maybe.withDefault "" (List.head tail2) + + Nothing -> + "" + + Nothing -> + "" + in + if third == "" then + ( { model | content = model.content ++ wrongArgs CookiesCommand 3 args }, Cmd.none ) + + else + case second of + "" -> + ( { model | content = model.content ++ wrongArgs CookiesCommand 2 args }, Cmd.none ) + + "keepFont" -> + case third of + "true" -> + saveCookiesKept { model | cookiesKept = { cookiesKept | keepFont = True } } + + "false" -> + saveCookiesKept { model | cookiesKept = { cookiesKept | keepFont = False } } + + _ -> + ( { model | content = model.content ++ wrongArgs CookiesCommand 3 args }, Cmd.none ) + + "keepTheme" -> + case third of + "true" -> + saveCookiesKept { model | cookiesKept = { cookiesKept | keepTheme = True } } + + "false" -> + saveCookiesKept { model | cookiesKept = { cookiesKept | keepTheme = False } } + + _ -> + ( { model | content = model.content ++ wrongArgs CookiesCommand 3 args }, Cmd.none ) + + "keepPrompt" -> + case third of + "true" -> + saveCookiesKept { model | cookiesKept = { cookiesKept | keepPrompt = True } } + + "false" -> + saveCookiesKept { model | cookiesKept = { cookiesKept | keepPrompt = False } } + + _ -> + ( { model | content = model.content ++ wrongArgs CookiesCommand 3 args }, Cmd.none ) + + _ -> + ( { model | content = model.content ++ wrongArgs CookiesCommand 2 args }, Cmd.none ) + + Just string -> + ( { model | content = model.content ++ wrongArgs CookiesCommand 1 args }, Cmd.none ) + + +runDebug : CommandRunner +runDebug model args = + ( model, getStorage "Theme" ) + + +runHello : CommandRunner +runHello model args = + case List.head args of + Nothing -> + ( { model | content = model.content ++ [ text "\nHello World!" ] }, Cmd.none ) + + _ -> + ( { model | content = model.content ++ wrongArgs HelloCommand 0 args }, Cmd.none ) + + +runFont : CommandRunner +runFont model args = + case List.head args of + Nothing -> + ( { model | content = model.content ++ wrongArgs FontCommand 1 args }, Cmd.none ) + + Just "size" -> + let + string = + case List.tail args of + Just tail -> + Maybe.withDefault "" (List.head tail) + + Nothing -> + "" + + fl = + String.toFloat string + in + case fl of + Just float -> + if float > 0 then + let + newModel = + { model + | content = + model.content + ++ [ text <| + "\nfontSize successfully set to " + ++ string + ++ "px" + ] + , font = { fontSize = float } + } + in + saveFont newModel + + else + ( { model + | content = + model.content + ++ [ text "\nPlease enter a valid fontSize, a Float greater than 0" ] + } + , Cmd.none + ) + + Nothing -> + case string of + "" -> + ( { model | content = model.content ++ [ text <| "\nfontSize is " ++ String.fromFloat model.font.fontSize ++ "px" ] } + , Cmd.none + ) + + "reset" -> + let + newModel = + { model + | content = + model.content + ++ [ text "\nfontSize reset to 20px" ] + , font = { fontSize = 20 } + } + in + saveFont newModel + + _ -> + ( { model + | content = + model.content + ++ [ text <| + "\nfontSize " + ++ string + ++ " not recognised; font size expected" + ] + } + , Cmd.none + ) + + Just "reset" -> + let + newModel = + { model + | content = model.content ++ [ text "\nfontSize reset to 20px" ] + , font = { fontSize = 20 } + } + in + saveFont newModel + + Just string -> + ( { model | content = model.content ++ wrongArgs FontCommand 1 args }, Cmd.none ) + + +runPrompt : CommandRunner +runPrompt model args = + case List.head args of + Nothing -> + ( { model | content = model.content ++ [ text <| "\ncurrent prompt is " ++ model.prompt.prompt ] }, Cmd.none ) + + Just string -> + let + oldPrompt = + model.prompt + in + savePrompt { model | prompt = { oldPrompt | prompt = string } } + + +runTheme : CommandRunner +runTheme model args = + case List.head args of + Nothing -> + ( { model + | content = + model.content + ++ [ text <| + "\nThe current theme is " + ++ (case model.theme of + Sun -> + "sun" + + Sky -> + "sky" + + Dim -> + "dim" + + Pit -> + "pit" + ) + ] + } + , Cmd.none + ) + + Just "sun" -> + setTheme model Sun + + Just "sky" -> + setTheme model Sky + + Just "dim" -> + setTheme model Dim + + Just "pit" -> + setTheme model Pit + + Just string -> + ( { model | content = model.content ++ wrongArgs ThemeCommand 1 args }, Cmd.none ) + + +runTodo : CommandRunner +runTodo model args = + ( case List.head args of + Nothing -> + { model + | content = + model.content + ++ [ text <| + "\nIn no particular order:" + ++ "\n- Implement colors throughout existing methods" + ++ "\n- Something like Neofetch" + ++ "\n- Collect and store feedback in a database" + ++ "\n- Create a style guide for programs involving console colors" + ++ "\n- Modularise the code (to have something more elegant than a single 2k line file)" + ++ "\n- Figure out a better way to parse commands" + ++ "\n- Add cache headers" + ] + } + + Just _ -> + { model | content = model.content ++ wrongArgs TodoCommand 0 args } + , Cmd.none + ) + + + +-- COMMAND ABSTRACTIONS + + +setTheme : Model -> Theme -> ( Model, Cmd Msg ) +setTheme model theme = + let + newModel = + { model | theme = theme } + in + saveTheme newModel + + +wrongArgs : Command -> Int -> List String -> List (Html Msg) +wrongArgs command expected args = + let + comstr = + case command of + HelpCommand -> + "help" + + ClearCommand -> + "clear" + + ColorsCommand -> + "colors" + + CookiesCommand -> + "cookies" + + DebugCommand -> + "debug" + + FontCommand -> + "font" + + HelloCommand -> + "hello" + + PromptCommand -> + "prompt" + + ThemeCommand -> + "theme" + + TodoCommand -> + "todo" + in + [ text + ((if expected > List.length args then + "\nToo few arguments for " ++ comstr + + else if expected < List.length args then + "\nToo many arguments for " ++ comstr + + else + "\nUnexpected arguments " ++ listToString args + ) + ++ ". Run `help " + ++ comstr + ++ "` for usage" + ) + ] + + +listToString : List String -> String +listToString list = + "[" ++ String.join "," list ++ "]" + + +boolToString : Bool -> String +boolToString bool = + case bool of + True -> + "True" + + False -> + "False" + + +cookiesKeptToString : CookiesKept -> String +cookiesKeptToString cookiesKept = + "{ keepFont = " + ++ boolToString cookiesKept.keepFont + ++ "\n, keepPrompt = " + ++ boolToString cookiesKept.keepPrompt + ++ "\n, keepTheme = " + ++ boolToString cookiesKept.keepTheme + ++ "\n}" + + + +-- PORTS +-- sets localStorage 'cookies' to E.Value + + +port setStorage : ( String, E.Value ) -> Cmd a + + +port getStorage : String -> Cmd a + + +port receiveStorageFromJS : (E.Value -> msg) -> Sub msg + + + +-- JSON + + +saveCookiesKept : Model -> ( Model, Cmd Msg ) +saveCookiesKept model = + ( model, setStorage ( "CookiesKept", encodeCookiesKept model.cookiesKept ) ) + + +saveFont : Model -> ( Model, Cmd Msg ) +saveFont model = + ( model, setStorage ( "Font", encodeFont model.font ) ) + + +savePrompt : Model -> ( Model, Cmd Msg ) +savePrompt model = + ( model, setStorage ( "Prompt", encodePrompt model.prompt ) ) + + +saveTheme : Model -> ( Model, Cmd Msg ) +saveTheme model = + ( model, setStorage ( "Theme", encodeTheme model.theme ) ) + + +loadStorage : Model -> String -> ( Model, Cmd Msg ) +loadStorage model key = + ( model, getStorage key ) + + + +-- SUBSCRIPTIONS + + +subscriptions : Model -> Sub Msg +subscriptions model = + receiveStorageFromJS ReceivedStorage + + + +-- VIEW + + +view : Model -> Browser.Document Msg +view model = + Browser.Document "elmskell" + [ toUnstyled <| viewBody model ] + + +viewBody : Model -> Html Msg +viewBody model = + styledBody model + [] + [ styledContent model [] model.content + , styledCL + model + [] + [ styledPrompt model [] [ coloredText (coreColor BrightMagenta) model.prompt.prompt ] + , styledCLI model [ onInput TakeInput, value model.cliContent, id "init-focus" ] [] + ] + ] + + + +-- STYLES + + +allColors : Model -> List Color +allColors model = + List.map + coreColor + [ Red + , Green + , Yellow + , Blue + , Magenta + , Cyan + , BrightRed + , BrightGreen + , BrightYellow + , BrightBlue + , BrightMagenta + , BrightCyan + ] + ++ List.map + (themeColor model) + [ Background + , Foreground + , Cursor + , Black + , White + , BrightBlack + , BrightWhite + ] + + + +-- Colors from Root Loops +-- flavor: intense +-- fruit: raspberry +-- milk: each option +-- sugar: 6 +-- colors: 9 +-- sogginess: 7 + + +coreColor : CoreColor -> Color +coreColor color = + case color of + Red -> + hex "e14433" + + Green -> + hex "#359b54" + + Yellow -> + hex "#a08016" + + Blue -> + hex "#5a77f2" + + Magenta -> + hex "#cf2ec8" + + Cyan -> + hex "1894a5" + + BrightRed -> + hex "#f36552" + + BrightGreen -> + hex "#3db361" + + BrightYellow -> + hex "#b9941a" + + BrightBlue -> + hex "#7491f8" + + BrightMagenta -> + hex "#e54ede" + + BrightCyan -> + hex "#1eabbf" + + +themeColor : Model -> ThemeColor -> Color +themeColor model color = + case model.theme of + Pit -> + case color of + Background -> + hex "#120211" + + Foreground -> + hex "#f3d9f0" + + Cursor -> + themeColor model White + + Black -> + hex "#380e36" + + White -> + hex "#e29edc" + + BrightBlack -> + hex "#7c2b77" + + BrightWhite -> + hex "#f9ecf7" + + Dim -> + case color of + Background -> + hex "#380e36" + + Foreground -> + hex "#f7e5f4" + + Cursor -> + themeColor model White + + Black -> + hex "#5e1c56" + + White -> + hex "#e8b2e2" + + BrightBlack -> + hex "#9d3c98" + + BrightWhite -> + hex "#fbf4fa" + + Sky -> + case color of + Background -> + hex "#f3d9f0" + + Foreground -> + hex "#380e36" + + Cursor -> + themeColor model White + + Black -> + hex "#eec6e9" + + White -> + hex "#7c2b77" + + BrightBlack -> + hex "#d575cd" + + BrightWhite -> + hex "#120211" + + Sun -> + case color of + Background -> + hex "#f9ecf7" + + Foreground -> + hex "#5a1c56" + + Cursor -> + themeColor model White + + Black -> + hex "#f3d9f0" + + White -> + hex "#9d3c98" + + BrightBlack -> + hex "#dc8ed5" + + BrightWhite -> + hex "#380e36" + + +styledBody : Model -> List (Attribute Msg) -> List (Html Msg) -> Html Msg +styledBody model = + styled Html.Styled.main_ + [ backgroundColor <| themeColor model Background + , color <| themeColor model Foreground + , minHeight (vh 100) + , width (vw 100) + , margin (px 0) + , padding (px 0) + ] + + +styledContent : Model -> List (Attribute Msg) -> List (Html Msg) -> Html Msg +styledContent model = + styled Html.Styled.span + [ color <| themeColor model Foreground + , fontSize (px model.font.fontSize) + , padding (px 0) + , margin (px 0) + , backgroundColor <| themeColor model Background + , borderWidth (px 0) + , width (vw 100) + , whiteSpace preWrap + , fontFamily monospace + ] + + +styledCL : Model -> List (Attribute Msg) -> List (Html Msg) -> Html Msg +styledCL model = + styled Html.Styled.span + [ backgroundColor <| themeColor model Background + , padding (px 0) + , margin (px 0) + , displayFlex + , flexDirection row + , flexWrap noWrap + , justifyContent flexStart + ] + + +styledCLI : Model -> List (Attribute Msg) -> List (Html Msg) -> Html Msg +styledCLI model = + styled Html.Styled.textarea + [ color <| themeColor model Foreground + , fontSize (px model.font.fontSize) + , padding (px 0) + , margin (px 0) + , backgroundColor <| themeColor model Background + , borderWidth (px 0) + , outlineWidth (px 0) + , height (px model.font.fontSize) + , resize none + , overflow hidden + , flexGrow (Css.int 100) + ] + + +styledPrompt : Model -> List (Attribute Msg) -> List (Html Msg) -> Html Msg +styledPrompt model = + styled Html.Styled.span + [ color <| themeColor model Foreground + , fontSize (px model.font.fontSize) + , padding (px 0) + , margin (px 0) + , backgroundColor <| themeColor model Background + , borderWidth (px 0) + , height (px model.font.fontSize) + , fontFamily monospace + ] + + +coloredText : Color -> String -> Html Msg +coloredText fgColor string = + coloredTextWBackground fgColor (rgba 0 0 0 0) string + + +coloredTextWBackground : Color -> Color -> String -> Html Msg +coloredTextWBackground fgColor bgColor string = + styled Html.Styled.span + [ color fgColor + , backgroundColor bgColor + , padding (px 0) + , margin (px 0) + , borderWidth (px 0) + ] + [] + [ text string ] diff --git a/justfile b/justfile new file mode 100755 index 0000000..123d885 --- /dev/null +++ b/justfile @@ -0,0 +1,32 @@ +produce: produce-elm haskell + echo "REMEMBER to RESTART elmskell.service TO UPDATE SITE IN PLACE" + echo "REMEMBER to RUN sudo iptables-apply -t 60 /etc/iptables/iptables.rules IF YOU HAVEN'T SINCE RESTART" + +types: haskell + rm -rf frontend/src/ElmskellTypes/Generated + stack exec ~/.local/bin/hs-server-exe + +compile: elm haskell + +run: produce exec + +exec: + stack exec ~/.local/bin/hs-server-exe + +haskell: + cd backend && stack install + +elm: + cd frontend && elm make src/Main.elm --output=../assets/js/main.js + rm -rf frontend/elm-stuff + +produce-elm: + cd frontend && elm make src/Main.elm --optimize --output=tmp.js + mv frontend/tmp.js assets/js/tmp.js + rm -rf frontend/elm-stuff + rm assets/js/main.js + esbuild assets/js/tmp.js --minify --target=es5 --outfile=assets/js/main.js + rm assets/js/tmp.js + +format-elm: + elm-format frontend/src/Main.elm --yes diff --git a/src/ElmskellTypes.hs b/src/ElmskellTypes.hs old mode 100644 new mode 100755 diff --git a/src/elm.json b/src/elm.json index 456d895..0a668c0 100644 --- a/src/elm.json +++ b/src/elm.json @@ -6,28 +6,15 @@ "elm-version": "0.19.1", "dependencies": { "direct": { - "NoRedInk/elm-json-decode-pipeline": "1.0.1", - "bartavelle/json-helpers": "2.0.2", "elm/browser": "1.0.2", "elm/core": "1.0.5", - "elm/html": "1.0.0", + "elm/html": "1.0.0" + }, + "indirect": { "elm/json": "1.1.3", "elm/time": "1.0.0", "elm/url": "1.0.0", - "lobanov/elm-localstorage": "1.0.1", - "rtfeldman/elm-css": "18.0.0", - "rtfeldman/elm-iso8601-date-strings": "1.1.4" - }, - "indirect": { - "elm/bytes": "1.0.8", - "elm/file": "1.0.5", - "elm/http": "2.0.0", - "elm/parser": "1.1.0", - "elm/random": "1.0.0", - "elm/virtual-dom": "1.0.3", - "lobanov/elm-taskport": "2.0.1", - "robinheghan/murmur3": "1.0.0", - "rtfeldman/elm-hex": "1.0.0" + "elm/virtual-dom": "1.0.3" } }, "test-dependencies": { diff --git a/src/init.js b/src/init.js old mode 100644 new mode 100755