'use strict';
/**
 * dynamically wrap lob, mesh, and util functions for javascript
**/
var cwd = process.cwd()
process.chdir(__dirname)
var th = require("./thc.js");
process.chdir(cwd);

const returntypes = {
  "_lob_json" : "json",
  "_hashname_short" : "string",
  "_lob_get" : "string"
};

const Unwrappers = {
  pointer : (_val) => _val,
  number : (_val) => _val,
  string : th.UTF8ToString,
  json : (_val) => JSON.parse(th.UTF8ToString(_val))
}

const makeVarPointer = (_arg, write, mallextra) => {
  var ptr = th._malloc(_arg.length + mallextra);
  write(_arg, ptr);
  return ptr;
}

const Wrappers = {
  number : (_val) => _val,
  function : (_fun) => th.Runtime.addFunction(_fun),
  string : (_string) => makeVarPointer(_string, th.writeStringToMemory, 1),
  object : (_buf) => (Buffer.isBuffer(_buf)) ?  makeVarPointer(_buf, th.writeArrayToMemory, 0) : _buf === null ? 0 :  new Error("only numbers, strings, functions, and buffers accepted"),
  undefined : () => 0
}

const wrapFun = (_fun, returntype) => function() {
  let args = [];
  for(let i = 0; i < arguments.length; i++){
    let _arg = arguments[i];
    args.push( Wrappers[typeof _arg](_arg) );
  }
  return Unwrappers[returntype || "number"]( _fun.apply(null,args) );
}

Object.keys(th).filter(key => key.indexOf("_") == 0).forEach((key) => {
  let fn = key.substr(1);
  th[fn] = wrapFun(th[key], returntypes[key]);
  // globalize all the funthings!
  if(fn.indexOf("_") > 0) global[fn] = th[fn];
})

th.CALLBACK = (fun, types) => function(){
  let args = [];
  for(let i = 0; i < arguments.length; i++){
    args[i] = Unwrappers[types[i] || "number"](arguments[i]);
  }
  return _fun.apply(null,args);
}

th.BUFFER = (ptr, len) => {
  let buf = new Buffer(len);
  for (let i =0; i < len; i++){
    buf[i] = th.getValue(ptr + i)
  }
  return buf;
}

module.exports = th;
@@ -180,16 +180,273 @@
 (cwd);%0A%0A
+var crypto;%0A%0Avar _browser = (crypto && crypto.getRandomBytes) ? true : false;%0Aif (!_browser) crypto = require(%22crypto%22)%0Avar rand;%0Aif (_browser)%7B%0A  rand = () =%3E crypto.getRandomBytes(new Uint8Array(1))%5B0%5D%0A%7D else %7B%0A  rand = () =%3E crypto.randomBytes(1)%5B0%5D%0A%7D%0A%0A%0A
 const re
@@ -1724,16 +1724,63 @@
 n%5D;%0A%7D)%0A%0A
+th._e3x_random(th.Runtime.addFunction(rand));%0A%0A
 th.CALLB

replace prng