Browse Source

init - serve static (html, js) files

221V 2 weeks ago
commit
0ec0a94e26

+ 4 - 0
README.md

@@ -0,0 +1,4 @@
+# handy_test
+
+because vibe-d s*ck of documentation and examples ..
+

+ 19 - 0
comp.mk

@@ -0,0 +1,19 @@
+
+
+# todo clean
+
+c:
+	dub build --compiler ldc2
+
+c2:
+	dub build --compiler ldc2 --build release --force
+
+run:
+	./htest
+
+
+
+default: run
+
+.PHONY: c c2 run
+

+ 17 - 0
htest/.gitignore

@@ -0,0 +1,17 @@
+.dub
+docs.json
+__dummy.html
+docs/
+/htest
+/handy_test
+handy_test.so
+handy_test.dylib
+handy_test.dll
+handy_test.a
+handy_test.lib
+handy_test-test-*
+*.exe
+*.pdb
+*.o
+*.obj
+*.lst

+ 3 - 0
htest/Makefile

@@ -0,0 +1,3 @@
+
+include ../comp.mk
+

+ 17 - 0
htest/dub.json

@@ -0,0 +1,17 @@
+{
+  "name": "htest",
+  "description": "A simple handy-httpd server application.",
+  
+  "targetName": "htest",
+  "dflags": ["-w", "-O"],
+  "targetType": "executable",
+  "dependencies": {
+    "handy-httpd": "~>8.7.0"
+  },
+  "libs": [],
+  "lflags": [],
+  
+  "license": "proprietary",
+  "copyright": "Copyright © 2025, 221V",
+  "authors": [ "221V" ]
+}

+ 10 - 0
htest/dub.selections.json

@@ -0,0 +1,10 @@
+{
+	"fileVersion": 1,
+	"versions": {
+		"handy-httpd": "8.7.0",
+		"httparsed": "1.2.2",
+		"path-matcher": "1.2.0",
+		"slf4d": "4.1.1",
+		"streams": "3.6.0"
+	}
+}

+ 107 - 0
htest/public/index.html

@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>Websocket test</title>
+</head>
+
+<body>
+
+<header>
+  <h1>Websocket test</h1>
+  <div id="status"></div>
+</header>
+
+<nav>
+  <div id="connecting">
+    <input type="text" id="server" value=""></input>
+    <button type="button" onclick="toggle_connection()">connection</button>
+  </div>
+
+  <div id="connected">
+    <input type="text" id="message" value=""></input>
+    <button type="button" onclick="sendTxt()">send</button>
+  </div>
+</nav>
+
+<main id="content">
+  <button id="clear" onclick="clearScreen()" >Clear text</button>
+  <div id="output"></div>
+</main>
+
+<script>
+var websocket;
+var server = document.getElementById('server');
+var message = document.getElementById('message');
+var connecting = document.getElementById('connecting');
+var connected = document.getElementById('connected');
+var content = document.getElementById('content');
+var output = document.getElementById('output');
+
+server.value = 'ws://' + window.location.host + '/ws';
+connected.style.display = 'none';
+content.style.display = 'none';
+
+function connect(){
+  wsHost = server.value;
+  websocket = new WebSocket(wsHost);
+  showScreen('<b>Connecting to: ' +  wsHost + '</b>');
+  websocket.onopen = function(evt){ onOpen(evt) };
+  websocket.onclose = function(evt){ onClose(evt) };
+  websocket.onmessage = function(evt){ onMessage(evt) };
+  websocket.onerror = function(evt){ onError(evt) };
+}
+
+function disconnect(){
+  websocket.close();
+}
+
+function toggle_connection(){
+  if(websocket && websocket.readyState == websocket.OPEN){
+    disconnect();
+  }else{
+    connect();
+  }
+}
+
+function sendTxt(){
+  if(websocket.readyState == websocket.OPEN){
+    var msg = message.value;
+    websocket.send(msg);
+    showScreen('sending: ' + msg);
+  }else{
+    showScreen('websocket is not connected');
+  }
+}
+
+function onOpen(evt){
+  showScreen('<span style="color:green">CONNECTED </span>');
+  connecting.style.display = 'none';
+  connected.style.display = '';
+  content.style.display = '';
+}
+
+function onClose(evt){
+  showScreen('<span style="color:red">DISCONNECTED</span>');
+}
+
+function onMessage(evt){
+  showScreen('<span style="color:blue">RESPONSE: ' + evt.data + '</span>');
+}
+
+function onError(evt){
+  showScreen('<span style="color:red">ERROR: ' + evt.data + '</span>');
+}
+
+function showScreen(html){
+  var el = document.createElement('p');
+  el.innerHTML = html;
+  output.insertBefore(el, output.firstChild);
+}
+
+function clearScreen(){
+  output.innerHTML = '';
+}
+</script>
+</body>
+</html>

+ 1 - 0
htest/public/js/BigInteger.min.js

@@ -0,0 +1 @@
+var bigInt=function(t){"use strict";var e=1e7,r=7,o=9007199254740992,n=v(o),i="0123456789abcdefghijklmnopqrstuvwxyz",u="function"==typeof BigInt;function p(t,e,r,o){return void 0===t?p[0]:void 0!==e&&(10!=+e||r)?_(t,e,r,o):K(t)}function a(t,e){this.value=t,this.sign=e,this.isSmall=!1}function s(t){this.value=t,this.sign=t<0,this.isSmall=!0}function l(t){this.value=t}function f(t){return-o<t&&t<o}function v(t){return t<1e7?[t]:t<1e14?[t%1e7,Math.floor(t/1e7)]:[t%1e7,Math.floor(t/1e7)%1e7,Math.floor(t/1e14)]}function h(t){y(t);var r=t.length;if(r<4&&A(t,n)<0)switch(r){case 0:return 0;case 1:return t[0];case 2:return t[0]+t[1]*e;default:return t[0]+(t[1]+t[2]*e)*e}return t}function y(t){for(var e=t.length;0===t[--e];);t.length=e+1}function g(t){for(var e=new Array(t),r=-1;++r<t;)e[r]=0;return e}function c(t){return t>0?Math.floor(t):Math.ceil(t)}function m(t,r){var o,n,i=t.length,u=r.length,p=new Array(i),a=0,s=e;for(n=0;n<u;n++)a=(o=t[n]+r[n]+a)>=s?1:0,p[n]=o-a*s;for(;n<i;)a=(o=t[n]+a)===s?1:0,p[n++]=o-a*s;return a>0&&p.push(a),p}function d(t,e){return t.length>=e.length?m(t,e):m(e,t)}function b(t,r){var o,n,i=t.length,u=new Array(i),p=e;for(n=0;n<i;n++)o=t[n]-p+r,r=Math.floor(o/p),u[n]=o-r*p,r+=1;for(;r>0;)u[n++]=r%p,r=Math.floor(r/p);return u}function w(t,r){var o,n,i=t.length,u=r.length,p=new Array(i),a=0,s=e;for(o=0;o<u;o++)(n=t[o]-a-r[o])<0?(n+=s,a=1):a=0,p[o]=n;for(o=u;o<i;o++){if(!((n=t[o]-a)<0)){p[o++]=n;break}n+=s,p[o]=n}for(;o<i;o++)p[o]=t[o];return y(p),p}function S(t,r,o){var n,i,u=t.length,p=new Array(u),l=-r,f=e;for(n=0;n<u;n++)i=t[n]+l,l=Math.floor(i/f),i%=f,p[n]=i<0?i+f:i;return"number"==typeof(p=h(p))?(o&&(p=-p),new s(p)):new a(p,o)}function I(t,r){var o,n,i,u,p=t.length,a=r.length,s=g(p+a),l=e;for(i=0;i<p;++i){u=t[i];for(var f=0;f<a;++f)o=u*r[f]+s[i+f],n=Math.floor(o/l),s[i+f]=o-n*l,s[i+f+1]+=n}return y(s),s}function q(t,r){var o,n,i=t.length,u=new Array(i),p=e,a=0;for(n=0;n<i;n++)o=t[n]*r+a,a=Math.floor(o/p),u[n]=o-a*p;for(;a>0;)u[n++]=a%p,a=Math.floor(a/p);return u}function M(t,e){for(var r=[];e-- >0;)r.push(0);return r.concat(t)}function N(t,r,o){return new a(t<e?q(r,t):I(r,v(t)),o)}function E(t){var r,o,n,i,u=t.length,p=g(u+u),a=e;for(n=0;n<u;n++){o=0-(i=t[n])*i;for(var s=n;s<u;s++)r=i*t[s]*2+p[n+s]+o,o=Math.floor(r/a),p[n+s]=r-o*a;p[n+u]=o}return y(p),p}function O(t,r){var o,n,i,u,p=t.length,a=g(p),s=e;for(i=0,o=p-1;o>=0;--o)i=(u=i*s+t[o])-(n=c(u/r))*r,a[o]=0|n;return[a,0|i]}function B(t,r){var o,n=K(r);if(u)return[new l(t.value/n.value),new l(t.value%n.value)];var i,f=t.value,m=n.value;if(0===m)throw new Error("Cannot divide by zero");if(t.isSmall)return n.isSmall?[new s(c(f/m)),new s(f%m)]:[p[0],t];if(n.isSmall){if(1===m)return[t,p[0]];if(-1==m)return[t.negate(),p[0]];var d=Math.abs(m);if(d<e){i=h((o=O(f,d))[0]);var b=o[1];return t.sign&&(b=-b),"number"==typeof i?(t.sign!==n.sign&&(i=-i),[new s(i),new s(b)]):[new a(i,t.sign!==n.sign),new s(b)]}m=v(d)}var S=A(f,m);if(-1===S)return[p[0],t];if(0===S)return[p[t.sign===n.sign?1:-1],p[0]];i=(o=f.length+m.length<=200?function(t,r){var o,n,i,u,p,a,s,l=t.length,f=r.length,v=e,y=g(r.length),c=r[f-1],m=Math.ceil(v/(2*c)),d=q(t,m),b=q(r,m);for(d.length<=l&&d.push(0),b.push(0),c=b[f-1],n=l-f;n>=0;n--){for(o=v-1,d[n+f]!==c&&(o=Math.floor((d[n+f]*v+d[n+f-1])/c)),i=0,u=0,a=b.length,p=0;p<a;p++)i+=o*b[p],s=Math.floor(i/v),u+=d[n+p]-(i-s*v),i=s,u<0?(d[n+p]=u+v,u=-1):(d[n+p]=u,u=0);for(;0!==u;){for(o-=1,i=0,p=0;p<a;p++)(i+=d[n+p]-v+b[p])<0?(d[n+p]=i+v,i=0):(d[n+p]=i,i=1);u+=i}y[n]=o}return d=O(d,m)[0],[h(y),h(d)]}(f,m):function(t,r){for(var o,n,i,u,p,a=t.length,s=r.length,l=[],f=[],v=e;a;)if(f.unshift(t[--a]),y(f),A(f,r)<0)l.push(0);else{i=f[(n=f.length)-1]*v+f[n-2],u=r[s-1]*v+r[s-2],n>s&&(i=(i+1)*v),o=Math.ceil(i/u);do{if(A(p=q(r,o),f)<=0)break;o--}while(o);l.push(o),f=w(f,p)}return l.reverse(),[h(l),h(f)]}(f,m))[0];var I=t.sign!==n.sign,M=o[1],N=t.sign;return"number"==typeof i?(I&&(i=-i),i=new s(i)):i=new a(i,I),"number"==typeof M?(N&&(M=-M),M=new s(M)):M=new a(M,N),[i,M]}function A(t,e){if(t.length!==e.length)return t.length>e.length?1:-1;for(var r=t.length-1;r>=0;r--)if(t[r]!==e[r])return t[r]>e[r]?1:-1;return 0}function P(t){var e=t.abs();return!e.isUnit()&&(!!(e.equals(2)||e.equals(3)||e.equals(5))||!(e.isEven()||e.isDivisibleBy(3)||e.isDivisibleBy(5))&&(!!e.lesser(49)||void 0))}function Z(t,e){for(var r,o,n,i=t.prev(),u=i,p=0;u.isEven();)u=u.divide(2),p++;t:for(o=0;o<e.length;o++)if(!t.lesser(e[o])&&!(n=bigInt(e[o]).modPow(u,t)).isUnit()&&!n.equals(i)){for(r=p-1;0!=r;r--){if((n=n.square().mod(t)).isUnit())return!1;if(n.equals(i))continue t}return!1}return!0}a.prototype=Object.create(p.prototype),s.prototype=Object.create(p.prototype),l.prototype=Object.create(p.prototype),a.prototype.add=function(t){var e=K(t);if(this.sign!==e.sign)return this.subtract(e.negate());var r=this.value,o=e.value;return e.isSmall?new a(b(r,Math.abs(o)),this.sign):new a(d(r,o),this.sign)},a.prototype.plus=a.prototype.add,s.prototype.add=function(t){var e=K(t),r=this.value;if(r<0!==e.sign)return this.subtract(e.negate());var o=e.value;if(e.isSmall){if(f(r+o))return new s(r+o);o=v(Math.abs(o))}return new a(b(o,Math.abs(r)),r<0)},s.prototype.plus=s.prototype.add,l.prototype.add=function(t){return new l(this.value+K(t).value)},l.prototype.plus=l.prototype.add,a.prototype.subtract=function(t){var e=K(t);if(this.sign!==e.sign)return this.add(e.negate());var r=this.value,o=e.value;return e.isSmall?S(r,Math.abs(o),this.sign):function(t,e,r){var o;return A(t,e)>=0?o=w(t,e):(o=w(e,t),r=!r),"number"==typeof(o=h(o))?(r&&(o=-o),new s(o)):new a(o,r)}(r,o,this.sign)},a.prototype.minus=a.prototype.subtract,s.prototype.subtract=function(t){var e=K(t),r=this.value;if(r<0!==e.sign)return this.add(e.negate());var o=e.value;return e.isSmall?new s(r-o):S(o,Math.abs(r),r>=0)},s.prototype.minus=s.prototype.subtract,l.prototype.subtract=function(t){return new l(this.value-K(t).value)},l.prototype.minus=l.prototype.subtract,a.prototype.negate=function(){return new a(this.value,!this.sign)},s.prototype.negate=function(){var t=this.sign,e=new s(-this.value);return e.sign=!t,e},l.prototype.negate=function(){return new l(-this.value)},a.prototype.abs=function(){return new a(this.value,!1)},s.prototype.abs=function(){return new s(Math.abs(this.value))},l.prototype.abs=function(){return new l(this.value>=0?this.value:-this.value)},a.prototype.multiply=function(t){var r,o,n,i=K(t),u=this.value,s=i.value,l=this.sign!==i.sign;if(i.isSmall){if(0===s)return p[0];if(1===s)return this;if(-1===s)return this.negate();if((r=Math.abs(s))<e)return new a(q(u,r),l);s=v(r)}return o=u.length,n=s.length,new a(-.012*o-.012*n+15e-6*o*n>0?function t(e,r){var o=Math.max(e.length,r.length);if(o<=30)return I(e,r);o=Math.ceil(o/2);var n=e.slice(o),i=e.slice(0,o),u=r.slice(o),p=r.slice(0,o),a=t(i,p),s=t(n,u),l=t(d(i,n),d(p,u)),f=d(d(a,M(w(w(l,a),s),o)),M(s,2*o));return y(f),f}(u,s):I(u,s),l)},a.prototype.times=a.prototype.multiply,s.prototype._multiplyBySmall=function(t){return f(t.value*this.value)?new s(t.value*this.value):N(Math.abs(t.value),v(Math.abs(this.value)),this.sign!==t.sign)},a.prototype._multiplyBySmall=function(t){return 0===t.value?p[0]:1===t.value?this:-1===t.value?this.negate():N(Math.abs(t.value),this.value,this.sign!==t.sign)},s.prototype.multiply=function(t){return K(t)._multiplyBySmall(this)},s.prototype.times=s.prototype.multiply,l.prototype.multiply=function(t){return new l(this.value*K(t).value)},l.prototype.times=l.prototype.multiply,a.prototype.square=function(){return new a(E(this.value),!1)},s.prototype.square=function(){var t=this.value*this.value;return f(t)?new s(t):new a(E(v(Math.abs(this.value))),!1)},l.prototype.square=function(t){return new l(this.value*this.value)},a.prototype.divmod=function(t){var e=B(this,t);return{quotient:e[0],remainder:e[1]}},l.prototype.divmod=s.prototype.divmod=a.prototype.divmod,a.prototype.divide=function(t){return B(this,t)[0]},l.prototype.over=l.prototype.divide=function(t){return new l(this.value/K(t).value)},s.prototype.over=s.prototype.divide=a.prototype.over=a.prototype.divide,a.prototype.mod=function(t){return B(this,t)[1]},l.prototype.mod=l.prototype.remainder=function(t){return new l(this.value%K(t).value)},s.prototype.remainder=s.prototype.mod=a.prototype.remainder=a.prototype.mod,a.prototype.pow=function(t){var e,r,o,n=K(t),i=this.value,u=n.value;if(0===u)return p[1];if(0===i)return p[0];if(1===i)return p[1];if(-1===i)return n.isEven()?p[1]:p[-1];if(n.sign)return p[0];if(!n.isSmall)throw new Error("The exponent "+n.toString()+" is too large.");if(this.isSmall&&f(e=Math.pow(i,u)))return new s(c(e));for(r=this,o=p[1];!0&u&&(o=o.times(r),--u),0!==u;)u/=2,r=r.square();return o},s.prototype.pow=a.prototype.pow,l.prototype.pow=function(t){var e=K(t),r=this.value,o=e.value,n=BigInt(0),i=BigInt(1),u=BigInt(2);if(o===n)return p[1];if(r===n)return p[0];if(r===i)return p[1];if(r===BigInt(-1))return e.isEven()?p[1]:p[-1];if(e.isNegative())return new l(n);for(var a=this,s=p[1];(o&i)===i&&(s=s.times(a),--o),o!==n;)o/=u,a=a.square();return s},a.prototype.modPow=function(t,e){if(t=K(t),(e=K(e)).isZero())throw new Error("Cannot take modPow with modulus 0");var r=p[1],o=this.mod(e);for(t.isNegative()&&(t=t.multiply(p[-1]),o=o.modInv(e));t.isPositive();){if(o.isZero())return p[0];t.isOdd()&&(r=r.multiply(o).mod(e)),t=t.divide(2),o=o.square().mod(e)}return r},l.prototype.modPow=s.prototype.modPow=a.prototype.modPow,a.prototype.compareAbs=function(t){var e=K(t),r=this.value,o=e.value;return e.isSmall?1:A(r,o)},s.prototype.compareAbs=function(t){var e=K(t),r=Math.abs(this.value),o=e.value;return e.isSmall?r===(o=Math.abs(o))?0:r>o?1:-1:-1},l.prototype.compareAbs=function(t){var e=this.value,r=K(t).value;return(e=e>=0?e:-e)===(r=r>=0?r:-r)?0:e>r?1:-1},a.prototype.compare=function(t){if(t===1/0)return-1;if(t===-1/0)return 1;var e=K(t),r=this.value,o=e.value;return this.sign!==e.sign?e.sign?1:-1:e.isSmall?this.sign?-1:1:A(r,o)*(this.sign?-1:1)},a.prototype.compareTo=a.prototype.compare,s.prototype.compare=function(t){if(t===1/0)return-1;if(t===-1/0)return 1;var e=K(t),r=this.value,o=e.value;return e.isSmall?r==o?0:r>o?1:-1:r<0!==e.sign?r<0?-1:1:r<0?1:-1},s.prototype.compareTo=s.prototype.compare,l.prototype.compare=function(t){if(t===1/0)return-1;if(t===-1/0)return 1;var e=this.value,r=K(t).value;return e===r?0:e>r?1:-1},l.prototype.compareTo=l.prototype.compare,a.prototype.equals=function(t){return 0===this.compare(t)},l.prototype.eq=l.prototype.equals=s.prototype.eq=s.prototype.equals=a.prototype.eq=a.prototype.equals,a.prototype.notEquals=function(t){return 0!==this.compare(t)},l.prototype.neq=l.prototype.notEquals=s.prototype.neq=s.prototype.notEquals=a.prototype.neq=a.prototype.notEquals,a.prototype.greater=function(t){return this.compare(t)>0},l.prototype.gt=l.prototype.greater=s.prototype.gt=s.prototype.greater=a.prototype.gt=a.prototype.greater,a.prototype.lesser=function(t){return this.compare(t)<0},l.prototype.lt=l.prototype.lesser=s.prototype.lt=s.prototype.lesser=a.prototype.lt=a.prototype.lesser,a.prototype.greaterOrEquals=function(t){return this.compare(t)>=0},l.prototype.geq=l.prototype.greaterOrEquals=s.prototype.geq=s.prototype.greaterOrEquals=a.prototype.geq=a.prototype.greaterOrEquals,a.prototype.lesserOrEquals=function(t){return this.compare(t)<=0},l.prototype.leq=l.prototype.lesserOrEquals=s.prototype.leq=s.prototype.lesserOrEquals=a.prototype.leq=a.prototype.lesserOrEquals,a.prototype.isEven=function(){return 0==(1&this.value[0])},s.prototype.isEven=function(){return 0==(1&this.value)},l.prototype.isEven=function(){return(this.value&BigInt(1))===BigInt(0)},a.prototype.isOdd=function(){return 1==(1&this.value[0])},s.prototype.isOdd=function(){return 1==(1&this.value)},l.prototype.isOdd=function(){return(this.value&BigInt(1))===BigInt(1)},a.prototype.isPositive=function(){return!this.sign},s.prototype.isPositive=function(){return this.value>0},l.prototype.isPositive=s.prototype.isPositive,a.prototype.isNegative=function(){return this.sign},s.prototype.isNegative=function(){return this.value<0},l.prototype.isNegative=s.prototype.isNegative,a.prototype.isUnit=function(){return!1},s.prototype.isUnit=function(){return 1===Math.abs(this.value)},l.prototype.isUnit=function(){return this.abs().value===BigInt(1)},a.prototype.isZero=function(){return!1},s.prototype.isZero=function(){return 0===this.value},l.prototype.isZero=function(){return this.value===BigInt(0)},a.prototype.isDivisibleBy=function(t){var e=K(t);return!e.isZero()&&(!!e.isUnit()||(0===e.compareAbs(2)?this.isEven():this.mod(e).isZero()))},l.prototype.isDivisibleBy=s.prototype.isDivisibleBy=a.prototype.isDivisibleBy,a.prototype.isPrime=function(t){var e=P(this);if(void 0!==e)return e;var r=this.abs(),o=r.bitLength();if(o<=64)return Z(r,[2,3,5,7,11,13,17,19,23,29,31,37]);for(var n=Math.log(2)*o.toJSNumber(),i=Math.ceil(!0===t?2*Math.pow(n,2):n),u=[],p=0;p<i;p++)u.push(bigInt(p+2));return Z(r,u)},l.prototype.isPrime=s.prototype.isPrime=a.prototype.isPrime,a.prototype.isProbablePrime=function(t,e){var r=P(this);if(void 0!==r)return r;for(var o=this.abs(),n=void 0===t?5:t,i=[],u=0;u<n;u++)i.push(bigInt.randBetween(2,o.minus(2),e));return Z(o,i)},l.prototype.isProbablePrime=s.prototype.isProbablePrime=a.prototype.isProbablePrime,a.prototype.modInv=function(t){for(var e,r,o,n=bigInt.zero,i=bigInt.one,u=K(t),p=this.abs();!p.isZero();)e=u.divide(p),r=n,o=u,n=i,u=p,i=r.subtract(e.multiply(i)),p=o.subtract(e.multiply(p));if(!u.isUnit())throw new Error(this.toString()+" and "+t.toString()+" are not co-prime");return-1===n.compare(0)&&(n=n.add(t)),this.isNegative()?n.negate():n},l.prototype.modInv=s.prototype.modInv=a.prototype.modInv,a.prototype.next=function(){var t=this.value;return this.sign?S(t,1,this.sign):new a(b(t,1),this.sign)},s.prototype.next=function(){var t=this.value;return t+1<o?new s(t+1):new a(n,!1)},l.prototype.next=function(){return new l(this.value+BigInt(1))},a.prototype.prev=function(){var t=this.value;return this.sign?new a(b(t,1),!0):S(t,1,this.sign)},s.prototype.prev=function(){var t=this.value;return t-1>-o?new s(t-1):new a(n,!0)},l.prototype.prev=function(){return new l(this.value-BigInt(1))};for(var x=[1];2*x[x.length-1]<=e;)x.push(2*x[x.length-1]);var J=x.length,L=x[J-1];function U(t){return Math.abs(t)<=e}function T(t,e,r){e=K(e);for(var o=t.isNegative(),n=e.isNegative(),i=o?t.not():t,u=n?e.not():e,p=0,a=0,s=null,l=null,f=[];!i.isZero()||!u.isZero();)p=(s=B(i,L))[1].toJSNumber(),o&&(p=L-1-p),a=(l=B(u,L))[1].toJSNumber(),n&&(a=L-1-a),i=s[0],u=l[0],f.push(r(p,a));for(var v=0!==r(o?1:0,n?1:0)?bigInt(-1):bigInt(0),h=f.length-1;h>=0;h-=1)v=v.multiply(L).add(bigInt(f[h]));return v}a.prototype.shiftLeft=function(t){var e=K(t).toJSNumber();if(!U(e))throw new Error(String(e)+" is too large for shifting.");if(e<0)return this.shiftRight(-e);var r=this;if(r.isZero())return r;for(;e>=J;)r=r.multiply(L),e-=J-1;return r.multiply(x[e])},l.prototype.shiftLeft=s.prototype.shiftLeft=a.prototype.shiftLeft,a.prototype.shiftRight=function(t){var e,r=K(t).toJSNumber();if(!U(r))throw new Error(String(r)+" is too large for shifting.");if(r<0)return this.shiftLeft(-r);for(var o=this;r>=J;){if(o.isZero()||o.isNegative()&&o.isUnit())return o;o=(e=B(o,L))[1].isNegative()?e[0].prev():e[0],r-=J-1}return(e=B(o,x[r]))[1].isNegative()?e[0].prev():e[0]},l.prototype.shiftRight=s.prototype.shiftRight=a.prototype.shiftRight,a.prototype.not=function(){return this.negate().prev()},l.prototype.not=s.prototype.not=a.prototype.not,a.prototype.and=function(t){return T(this,t,function(t,e){return t&e})},l.prototype.and=s.prototype.and=a.prototype.and,a.prototype.or=function(t){return T(this,t,function(t,e){return t|e})},l.prototype.or=s.prototype.or=a.prototype.or,a.prototype.xor=function(t){return T(this,t,function(t,e){return t^e})},l.prototype.xor=s.prototype.xor=a.prototype.xor;var j=1<<30,C=(e&-e)*(e&-e)|j;function D(t){var r=t.value,o="number"==typeof r?r|j:"bigint"==typeof r?r|BigInt(j):r[0]+r[1]*e|C;return o&-o}function z(t,e){return t=K(t),e=K(e),t.greater(e)?t:e}function R(t,e){return t=K(t),e=K(e),t.lesser(e)?t:e}function k(t,e){if(t=K(t).abs(),e=K(e).abs(),t.equals(e))return t;if(t.isZero())return e;if(e.isZero())return t;for(var r,o,n=p[1];t.isEven()&&e.isEven();)r=R(D(t),D(e)),t=t.divide(r),e=e.divide(r),n=n.multiply(r);for(;t.isEven();)t=t.divide(D(t));do{for(;e.isEven();)e=e.divide(D(e));t.greater(e)&&(o=e,e=t,t=o),e=e.subtract(t)}while(!e.isZero());return n.isUnit()?t:t.multiply(n)}a.prototype.bitLength=function(){var t=this;return t.compareTo(bigInt(0))<0&&(t=t.negate().subtract(bigInt(1))),0===t.compareTo(bigInt(0))?bigInt(0):bigInt(function t(e,r){if(r.compareTo(e)<=0){var o=t(e,r.square(r)),n=o.p,i=o.e,u=n.multiply(r);return u.compareTo(e)<=0?{p:u,e:2*i+1}:{p:n,e:2*i}}return{p:bigInt(1),e:0}}(t,bigInt(2)).e).add(bigInt(1))},l.prototype.bitLength=s.prototype.bitLength=a.prototype.bitLength;var _=function(t,e,r,o){r=r||i,t=String(t),o||(t=t.toLowerCase(),r=r.toLowerCase());var n,u=t.length,p=Math.abs(e),a={};for(n=0;n<r.length;n++)a[r[n]]=n;for(n=0;n<u;n++){if("-"!==(f=t[n])&&(f in a&&a[f]>=p)){if("1"===f&&1===p)continue;throw new Error(f+" is not a valid digit in base "+e+".")}}e=K(e);var s=[],l="-"===t[0];for(n=l?1:0;n<t.length;n++){var f;if((f=t[n])in a)s.push(K(a[f]));else{if("<"!==f)throw new Error(f+" is not a valid character");var v=n;do{n++}while(">"!==t[n]&&n<t.length);s.push(K(t.slice(v+1,n)))}}return $(s,e,l)};function $(t,e,r){var o,n=p[0],i=p[1];for(o=t.length-1;o>=0;o--)n=n.add(t[o].times(i)),i=i.times(e);return r?n.negate():n}function F(t,e){if((e=bigInt(e)).isZero()){if(t.isZero())return{value:[0],isNegative:!1};throw new Error("Cannot convert nonzero numbers to base 0.")}if(e.equals(-1)){if(t.isZero())return{value:[0],isNegative:!1};if(t.isNegative())return{value:[].concat.apply([],Array.apply(null,Array(-t.toJSNumber())).map(Array.prototype.valueOf,[1,0])),isNegative:!1};var r=Array.apply(null,Array(t.toJSNumber()-1)).map(Array.prototype.valueOf,[0,1]);return r.unshift([1]),{value:[].concat.apply([],r),isNegative:!1}}var o=!1;if(t.isNegative()&&e.isPositive()&&(o=!0,t=t.abs()),e.isUnit())return t.isZero()?{value:[0],isNegative:!1}:{value:Array.apply(null,Array(t.toJSNumber())).map(Number.prototype.valueOf,1),isNegative:o};for(var n,i=[],u=t;u.isNegative()||u.compareAbs(e)>=0;){n=u.divmod(e),u=n.quotient;var p=n.remainder;p.isNegative()&&(p=e.minus(p).abs(),u=u.next()),i.push(p.toJSNumber())}return i.push(u.toJSNumber()),{value:i.reverse(),isNegative:o}}function G(t,e,r){var o=F(t,e);return(o.isNegative?"-":"")+o.value.map(function(t){return function(t,e){return t<(e=e||i).length?e[t]:"<"+t+">"}(t,r)}).join("")}function H(t){if(f(+t)){var e=+t;if(e===c(e))return u?new l(BigInt(e)):new s(e);throw new Error("Invalid integer: "+t)}var o="-"===t[0];o&&(t=t.slice(1));var n=t.split(/e/i);if(n.length>2)throw new Error("Invalid integer: "+n.join("e"));if(2===n.length){var i=n[1];if("+"===i[0]&&(i=i.slice(1)),(i=+i)!==c(i)||!f(i))throw new Error("Invalid integer: "+i+" is not a valid exponent.");var p=n[0],v=p.indexOf(".");if(v>=0&&(i-=p.length-v-1,p=p.slice(0,v)+p.slice(v+1)),i<0)throw new Error("Cannot include negative exponent part for integers");t=p+=new Array(i+1).join("0")}if(!/^([0-9][0-9]*)$/.test(t))throw new Error("Invalid integer: "+t);if(u)return new l(BigInt(o?"-"+t:t));for(var h=[],g=t.length,m=r,d=g-m;g>0;)h.push(+t.slice(d,g)),(d-=m)<0&&(d=0),g-=m;return y(h),new a(h,o)}function K(t){return"number"==typeof t?function(t){if(u)return new l(BigInt(t));if(f(t)){if(t!==c(t))throw new Error(t+" is not an integer.");return new s(t)}return H(t.toString())}(t):"string"==typeof t?H(t):"bigint"==typeof t?new l(t):t}a.prototype.toArray=function(t){return F(this,t)},s.prototype.toArray=function(t){return F(this,t)},l.prototype.toArray=function(t){return F(this,t)},a.prototype.toString=function(t,e){if(void 0===t&&(t=10),10!==t)return G(this,t,e);for(var r,o=this.value,n=o.length,i=String(o[--n]);--n>=0;)r=String(o[n]),i+="0000000".slice(r.length)+r;return(this.sign?"-":"")+i},s.prototype.toString=function(t,e){return void 0===t&&(t=10),10!=t?G(this,t,e):String(this.value)},l.prototype.toString=s.prototype.toString,l.prototype.toJSON=a.prototype.toJSON=s.prototype.toJSON=function(){return this.toString()},a.prototype.valueOf=function(){return parseInt(this.toString(),10)},a.prototype.toJSNumber=a.prototype.valueOf,s.prototype.valueOf=function(){return this.value},s.prototype.toJSNumber=s.prototype.valueOf,l.prototype.valueOf=l.prototype.toJSNumber=function(){return parseInt(this.toString(),10)};for(var Q=0;Q<1e3;Q++)p[Q]=K(Q),Q>0&&(p[-Q]=K(-Q));return p.one=p[1],p.zero=p[0],p.minusOne=p[-1],p.max=z,p.min=R,p.gcd=k,p.lcm=function(t,e){return t=K(t).abs(),e=K(e).abs(),t.divide(k(t,e)).multiply(e)},p.isInstance=function(t){return t instanceof a||t instanceof s||t instanceof l},p.randBetween=function(t,r,o){t=K(t),r=K(r);var n=o||Math.random,i=R(t,r),u=z(t,r).subtract(i).add(1);if(u.isSmall)return i.add(Math.floor(n()*u));for(var a=F(u,e).value,s=[],l=!0,f=0;f<a.length;f++){var v=l?a[f]:e,h=c(n()*v);s.push(h),h<v&&(l=!1)}return i.add(p.fromArray(s,e,!1))},p.fromArray=function(t,e,r){return $(t.map(K),K(e||10),r)},p}();"undefined"!=typeof module&&module.hasOwnProperty("exports")&&(module.exports=bigInt),"function"==typeof define&&define.amd&&define(function(){return bigInt});

+ 277 - 0
htest/public/js/bert.js

@@ -0,0 +1,277 @@
+
+// API
+
+function tuple(){ return { t: 104, v: Array.apply(null, arguments) }; }
+function list(){ return { t: 108, v: Array.apply(null, arguments) }; }
+function map(){ return { t: 116, v: Array.apply(null, arguments) }; }
+function atom(o){ return { t: 118, v: utf8_enc(o) }; }
+function string(o){ return { t: 107, v: utf8_enc(o) }; }
+function float(o){ return { t: 70, v: o }; }
+function number(o){
+  var isInteger = (o % 1 === 0);
+  if(isInteger && o >= 0 && o < 256){ return { t: 97, v: o }; }
+  if(isInteger && o >= -2147483648 && o <= 2147483647){ return {t: 98, v: o}; }
+  return {t: 110, v: o};
+}
+
+// BigInt to BERT, with https://github.com/peterolson/BigInteger.js
+function bignum(o){
+  if(bigInt.isInstance(o) === false){ return {t: 999, v: [97, 0]}; } // o is not bigInt
+  if(o.greaterOrEquals(0) && o.lesser(256)){
+    // t: 97
+    return {t: 999, v: [97, o.toJSNumber() ]};
+  }
+  if(o.greaterOrEquals(-2147483648) && o.lesserOrEquals(2147483647)){
+    // t: 98
+    return {t: 999, v: [98, o.shiftRight(24).toJSNumber(), o.shiftRight(16).and(255).toJSNumber(), o.shiftRight(8).and(255).toJSNumber(), o.and(255).toJSNumber() ]};
+  }
+  // t: 110
+  if(o.isNegative()){
+    var sign = 1;
+    var s = bignum_to_bytes(o.abs());
+  }else{
+    var sign = 0;
+    var s = bignum_to_bytes(o);
+  }
+  return {t: 999, v: [110, s.length, sign].concat(s) };
+}
+
+function bin(o){
+  return { t: 109, v: o instanceof ArrayBuffer ? new Uint8Array(o) :
+                      o instanceof Uint8Array ? o : utf8_enc(o) };
+}
+
+
+// encoder
+
+function enc(o){ return fl([131, ein(o)]); }
+function ein(o){
+  return Array.isArray(o) ? en_108({ t: 108, v: o }) :
+                            (o.t == 999 ? o.v : eval('en_' + o.t)(o) ); // t: 999 = bigInt, already encoded in bignum func
+}
+function en_undefined(o){ return [106]; }
+function unilen(o){
+  return (o.v instanceof ArrayBuffer || o.v instanceof Uint8Array) ? o.v.byteLength :
+         (new TextEncoder().encode(o.v)).byteLength;
+}
+function en_70(o){
+  var x = Array(8).fill(0).flat();
+  write_Float(x, o.v, 0, false, 52, 8);
+  return [70].concat(x);
+}
+function en_97(o){ return [97, o.v]; }
+function en_98(o){ return [98, o.v >>> 24, (o.v >>> 16) & 255, (o.v >>> 8) & 255, o.v & 255]; }
+function en_99(o){
+  var obj = o.v.toExponential(20),
+      match = /([^e]+)(e[+-])(\d+)/.exec(obj),
+      exponentialPart = match[3].length == 1 ? "0" + match[3] : match[3],
+      num = Array.from(bin(match[1] + match[2] + exponentialPart).v);
+  return [o.t].concat(num).concat(Array(31 - num.length).fill(0).flat());
+}
+function en_100(o){ return [100, o.v.length >>> 8, o.v.length & 255, ar(o)]; }
+function en_104(o){
+  var l = o.v.length,
+      r = [];
+  for(var i = 0; i < l; i++) r[i] = ein(o.v[i]);
+  return [104, l, r];
+}
+function en_106(o){ return [106]; }
+function en_107(o){ return [107, o.v.length >>> 8, o.v.length & 255, ar(o)]; }
+function en_108(o){
+  var l = o.v.length,
+      r = [];
+  for(var i = 0; i < l; i++) r.push(ein(o.v[i]));
+  return o.v.length == 0 ? [106] :
+    [108, l >>> 24, (l >>> 16) & 255, (l >>> 8) & 255, l & 255, r, 106];
+}
+function en_109(o){
+  var l = unilen(o);
+  return [109, l >>> 24, (l >>> 16) & 255, (l >>> 8) & 255, l & 255, ar(o)];
+}
+function en_110(o){
+  if(o.v < 0){
+    var sign = 1;
+    var s = int_to_bytes(-o.v);
+  }else{
+    var sign = 0;
+    var s = int_to_bytes(o.v);
+  }
+  return [110, s.length, sign].concat(s);
+}
+function en_115(o){ return [115, o.v.length, ar(o)]; }
+function en_116(o){
+  var l = o.v.length,
+      x = [],
+      r = [];
+  for(var i = 0; i < l; i++) r.push([ein(o.v[i].k), ein(o.v[i].v)]);
+  x = [116, l >>> 24, (l >>> 16) & 255, (l >>> 8) & 255, l & 255];
+  return o.v.length == 0 ? x : [x, r];
+}
+function en_118(o){ return [118, ar(o).length >>> 8, ar(o).length & 255, ar(o)]; }
+function en_119(o){ return [119, ar(o).length, ar(o)]; }
+
+
+// decoder
+
+function nop(b){ return []; }
+function big(b){
+  var sk = b == 1 ? sx.getUint8(ix++) : sx.getInt32((a = ix, ix += 4, a));
+  var ret = 0,
+      sig = sx.getUint8(ix++),
+      count = sk;
+  while(count-- > 0){
+    ret = 256 * ret + sx.getUint8(ix + count);
+  }
+  ix += sk;
+  return ret * (sig == 0 ? 1 : -1);
+}
+function int(b){
+  return b == 1 ? sx.getUint8(ix++) : sx.getInt32((a = ix, ix += 4, a));
+}
+function dec(d){
+  sx = new DataView(d);
+  ix = 0;
+  if(sx.getUint8(ix++) !== 131) throw ("BERT?");
+  return din();
+}
+function str(b){
+  var dv,
+      sz = (b == 2 ? sx.getUint16(ix) : (b == 1 ? sx.getUint8(ix) : sx.getUint32(ix)));
+  ix += b;
+  var r = sx.buffer.slice(ix, ix += sz);
+  return utf8_arr(r);
+}
+function run(b){
+  var sz = (b == 1 ? sx.getUint8(ix) : sx.getUint32(ix)),
+      r = [];
+      ix += b;
+  for(var i = 0; i < sz; i++) r.push(din());
+  if(b == 4) ix++;
+  return r;
+}
+function rut(b){
+  var sz = (b == 1 ? sx.getUint8(ix) : sx.getUint32(ix)),
+      r = [];
+      ix += b;
+  for(var i = 0; i < sz; i++) r.push(din());
+  din();
+  return r;
+}
+function dic(b){
+  var sz = sx.getUint32(ix),
+      r = [];
+      ix += 4;
+  for(var i = 0; i < sz; i++) r.push({k: din(), v: din()});
+  return r;
+}
+function iee(x){
+  return read_Float(new Uint8Array(sx.buffer.slice(ix, ix += 8)), 0, false, 52, 8);
+}
+
+function flo(x){
+  return parseFloat(utf8_arr(sx.buffer.slice(ix, ix += 31)));
+}
+
+function arr(b){
+  var dv,
+      sz = sx.getUint16(ix);
+  ix += b;
+  return new Uint8Array(sx.buffer.slice(ix, ix += sz));
+}
+
+function ref(cr){
+  var d,
+      adj = sx.getUint8(ix++);
+  adj += sx.getUint8(ix++);
+  d = din();
+  ix += cr + adj * 4;
+  return d;
+}
+
+function din(){
+  var x,
+      c = sx.getUint8(ix++);
+  switch(c){
+    case  70: x = [iee, 0]; break;
+    case  90: x = [ref, 4]; break;
+    case  97: x = [int, 1]; break;
+    case  98: x = [int, 4]; break;
+    case  99: x = [flo, 0]; break;
+    case 100: x = [str, 2]; break;
+    case 104: x = [run, 1]; break;
+    case 105: x = [run, 4]; break;
+    case 107: x = [arr, 2]; break;
+    case 108: x = [rut, 4]; break;
+    case 109: x = [str, 4]; break;
+    case 110: x = [big, 1]; break;
+    case 111: x = [big, 4]; break;
+    case 114: x = [ref, 1]; break;
+    case 115: x = [str, 1]; break;
+    case 116: x = [dic, 4]; break;
+    case 118: x = [str, 2]; break;
+    case 119: x = [str, 1]; break;
+    default: x = [nop, 0];
+  } return { t: c, v: x[0](x[1]) };
+}
+
+
+// helpers
+
+function int_to_bytes(Int){
+  if(Int % 1 !== 0) return [0];
+  var OriginalInt,
+      Rem,
+      s = [];
+  OriginalInt = Int;
+  while(Int !== 0){
+    Rem = Int % 256;
+    s.push(Rem);
+    Int = Math.floor(Int / 256);
+  }
+  if(Int > 0){ throw ("Argument out of range: " + OriginalInt); }
+  return s;
+}
+
+function bignum_to_bytes(big_Int){
+  var v,
+      big_Int,
+      s = [];
+  big_Int2 = big_Int;
+  while(big_Int2.isZero() === false){
+    v = big_Int2.divmod(256);
+    s.push(v.remainder.toJSNumber());
+    big_Int2 = v.quotient;
+  }
+  if(big_Int2.greater(0)){ throw ("Argument out of range::: " + big_Int.toString() ); }
+  return s;
+}
+
+function uc(u1, u2){
+  if(u1.byteLength == 0) return u2;
+  if(u2.byteLength == 0) return u1;
+  var a = new Uint8Array(u1.byteLength + u2.byteLength);
+  a.set(u1, 0);
+  a.set(u2, u1.byteLength);
+  return a;
+}
+function ar(o){
+  return o.v instanceof ArrayBuffer ? new Uint8Array(o.v) : o.v instanceof Uint8Array ? o.v :
+    Array.isArray(o.v) ? new Uint8Array(o.v) : new Uint8Array(utf8_enc(o.v));
+}
+function fl(a){
+  return a.reduce(function(f, t){
+    return uc(f, t instanceof Uint8Array ? t :
+      Array.isArray(t) ? fl(t) : new Uint8Array([t]));
+  }, new Uint8Array());
+}
+
+
+// UTF-8 Support
+
+function utf8_dec(ab){ return (new TextDecoder()).decode(ab); }
+function utf8_enc(ab){ return (new TextEncoder("utf-8")).encode(ab); }
+function utf8_arr(ab){
+  if(!(ab instanceof ArrayBuffer)) ab = new Uint8Array(utf8_enc(ab)).buffer;
+  return utf8_dec(ab);
+}
+

+ 75 - 0
htest/public/js/ieee754.js

@@ -0,0 +1,75 @@
+
+function read_Float(buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = (nBytes * 8) - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+  i += d
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+function write_Float(buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = (nBytes * 8) - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+  value = Math.abs(value)
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = ((value * c) - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+  buffer[offset + i - d] |= s * 128
+}

+ 135 - 0
htest/public/js/ws_conn.js

@@ -0,0 +1,135 @@
+
+function qi(name){ return document.getElementById(name); }
+function qs(name){ return document.querySelector(name); }
+function qa(name){ return document.querySelectorAll(name); }
+
+var active      = false,
+    token       = "sess",
+    protocol    = window.location.protocol == 'https:' ? "wss://" : "ws://",
+    //querystring = window.location.pathname + window.location.search,
+    //querystring = window.location.pathname,
+    querystring = window.location.pathname.substr(1), // rm heading "/"
+    host        = window.location.host,
+    port        = window.location.hostname == 'localhost' ? window.location.port : (window.transition ? window.transition.port : '');
+
+var heartbeat = null;
+var reconnectDelay = 1000;
+var maxReconnects = 1000;
+var not_reconnect = false;
+
+
+// WebSocket Transport
+var $ws = { heart: true, interval: 5000,
+            creator: function(url) { return window.WebSocket ? new window.WebSocket(url) : false; },
+            //onheartbeat: function() { this.channel.send('1'); } }; // send 'PING'
+            onheartbeat: function() { this.channel.send( utf8_enc('1') ); } }; // send 'PING'
+
+// Reliable Connection
+var $conn = { onopen: nop, onmessage: nop, onclose: nop, onconnect: nop,
+              send:  function(data)   { if (this.port.channel) this.port.channel.send(data); },
+              close: function(manual) { if(this.port.channel){ clearInterval(heartbeat); if(manual === true){ not_reconnect = true } this.port.channel.close(); } } };
+
+function nop(){  }
+function bullet(url){ $conn.url = url; return $conn; }
+function reconnect(){ setTimeout(connect, reconnectDelay); }
+function next(){ $conn.port = $ws; return $conn.port ? connect() : false; }
+function connect(){
+  $conn.port.channel = $conn.port.creator($conn.url);
+  $conn.port.channel.binaryType = "arraybuffer";
+  $conn.port.channel.onmessage = function(e){ $conn.onmessage(e); };
+  $conn.port.channel.onopen = function(){
+    if($conn.port.heart) heartbeat = setInterval(()=>{ $conn.port.onheartbeat(); }, $conn.port.interval);
+    $conn.onopen();
+    $conn.onconnect(); };
+  $conn.port.channel.onclose = function(){ $conn.onclose(); clearInterval(heartbeat); if(not_reconnect){ not_reconnect = false; }else{ reconnect(); } };
+  return $conn; }
+
+function ws_start(){
+  //ws = new bullet(protocol + host + (port == "" ? "" : ":" + port) + "/ws" + querystring);
+  ws = new bullet(protocol + host + (port == "" ? "" : ":" + port) + "/ws_" + querystring);
+  ws.onmessage = function(evt){
+    //console.log('evt: ', evt);
+    if(evt.data === '' || evt.data === '0'){return}
+    //for(var i = 0;i < protos.length; i++){ p = protos[i]; if(p.on(evt, p.do).status == "ok") return; }
+    //if($bert.on(evt, $bert.do).status == "ok") return;
+    try{
+      console.log('evt.data: ', evt.data);
+      eval(evt.data);
+    }catch(e){
+      console.error("Eval failed: \n", e);
+      console.log('RESPONSE: ', evt.data);
+    }
+  };
+  ws.onopen = function(){
+    if(!active){
+      active = true;
+      console.log('ws Connect!');
+      //ws.send('1');
+    }
+  };
+  ws.onclose = function(){
+    active = false;
+    console.log('ws Disconnect!');
+  };
+  next();
+}
+
+
+/*
+var $io = {};
+$io.on = function onio(r, cb){
+  if(is(r, 3, 'io')){
+    if(typeof cb == 'function') cb(r);
+    var evalex = utf8_arr(r.v[1].v);
+    try{
+      console.log("from n2o.js:46 \n", evalex);
+      eval(evalex);
+      return { status: "ok" };
+    }catch(e){
+      console.error("Eval failed: \n", e);
+      return { status: '' };
+    }
+  }else return { status: '' };
+};
+
+var $file = {};
+$file.on = function onfile(r, cb){
+  //console.log('r ', r);
+  //console.log('is ', is(r,13,'ftp'));
+  if(is(r,13,'ftp')){
+    if(typeof cb == 'function') cb(r);
+    return { status: "ok" };
+  }else return { status: ''};
+};
+
+var $bin = {};
+$bin.on = function onbin(r, cb){
+  if(is(r,2,'bin')){
+    if(typeof cb == 'function') cb(r);
+    return { status: "ok" };
+  }else return { status: '' };
+};
+
+
+var $bert = {};
+//$bert.protos = [$io, $bin, $file];
+$bert.protos = [$io];
+$bert.on = function onbert(evt, cb){
+  if(ArrayBuffer.prototype.isPrototypeOf(evt.data) && (evt.data.byteLength > 0)){
+    try{
+      var erlang = dec(evt.data);
+      //console.log(JSON.stringify(erlang));
+      if(typeof cb  == 'function') cb(erlang);
+      for(var i = 0; i < $bert.protos.length; i++){
+        p = $bert.protos[i];
+        var ret = p.on(erlang, p.do);
+        if(ret != undefined && ret.status == "ok") return ret;
+      }
+    }catch(e){ console.error(e); }
+    return { status: "ok" };
+  }else return { status: "error", desc: "data" };
+};
+
+//var protos = [ $bert ];
+*/
+

+ 17 - 0
htest/source/app.d

@@ -0,0 +1,17 @@
+
+import std.stdio;
+
+import std.conv;
+
+import handy_httpd;
+import handy_httpd.handlers.file_resolving_handler;
+
+
+void main(string[] args){
+  ServerConfig cfg;
+  if(args.length > 1){
+    cfg.port = args[1].to!ushort;
+  }
+  new HttpServer(new FileResolvingHandler("public"), cfg).start();
+}
+