Skip to content

Instantly share code, notes, and snippets.

@bananu7
Created January 21, 2014 00:57
Show Gist options
  • Select an option

  • Save bananu7/8532385 to your computer and use it in GitHub Desktop.

Select an option

Save bananu7/8532385 to your computer and use it in GitHub Desktop.
Sample Haste compiler output
/* Thunk
Creates a thunk representing the given closure.
Since we want automatic memoization of as many expressions as possible, we
use a JS object as a sort of tagged pointer, where the member x denotes the
object actually pointed to. If a "pointer" points to a thunk, it has a
member 't' which is set to true; if it points to a value, be it a function,
a value of an algebraic type of a primitive value, it has no member 't'.
*/
function T(f) {
this.f = new F(f);
}
function F(f) {
this.f = f;
}
/* Apply
Applies the function f to the arguments args. If the application is under-
saturated, a closure is returned, awaiting further arguments. If it is over-
saturated, the function is fully applied, and the result (assumed to be a
function) is then applied to the remaining arguments.
*/
function A(f, args) {
if(f instanceof T) {
f = E(f);
}
// Closure does some funny stuff with functions that occasionally
// results in non-functions getting applied, so we have to deal with
// it.
if(f.apply === undefined) {
return f;
}
if(f.arity === undefined) {
f.arity = f.length;
}
if(args.length === f.arity) {
return f.arity === 1 ? f(args[0]) : f.apply(null, args);
} else if(args.length > f.arity) {
return f.arity === 1 ? A(f(args.shift()), args)
: A(f.apply(null, args.splice(0, f.arity)), args);
} else {
var g = function() {
return A(f, args.concat(Array.prototype.slice.call(arguments)));
};
g.arity = f.arity - args.length;
return g;
}
}
/* Eval
Evaluate the given thunk t into head normal form.
If the "thunk" we get isn't actually a thunk, just return it.
*/
function E(t) {
if(t instanceof T) {
if(t.f instanceof F) {
return t.f = t.f.f();
} else {
return t.f;
}
} else {
return t;
}
}
/* Throw an error.
We need to be able to use throw as an exception so we wrap it in a function.
*/
function die(err) {
throw err;
}
function quot(a, b) {
return (a-a%b)/b;
}
function quotRemI(a, b) {
return [0, (a-a%b)/b, a%b];
}
// 32 bit integer multiplication, with correct overflow behavior
// note that |0 or >>>0 needs to be applied to the result, for int and word
// respectively.
function imul(a, b) {
// ignore high a * high a as the result will always be truncated
var lows = (a & 0xffff) * (b & 0xffff); // low a * low b
var aB = (a & 0xffff) * (b & 0xffff0000); // low a * high b
var bA = (a & 0xffff0000) * (b & 0xffff); // low b * high a
return lows + aB + bA; // sum will not exceed 52 bits, so it's safe
}
function addC(a, b) {
var x = a+b;
return [0, x & 0xffffffff, x > 0x7fffffff];
}
function subC(a, b) {
var x = a-b;
return [0, x & 0xffffffff, x < -2147483648];
}
function sinh (arg) {
return (Math.exp(arg) - Math.exp(-arg)) / 2;
}
function tanh (arg) {
return (Math.exp(arg) - Math.exp(-arg)) / (Math.exp(arg) + Math.exp(-arg));
}
function cosh (arg) {
return (Math.exp(arg) + Math.exp(-arg)) / 2;
}
// Scratch space for byte arrays.
var rts_scratchBuf = new ArrayBuffer(8);
var rts_scratchW32 = new Uint32Array(rts_scratchBuf);
var rts_scratchFloat = new Float32Array(rts_scratchBuf);
var rts_scratchDouble = new Float64Array(rts_scratchBuf);
function decodeFloat(x) {
rts_scratchFloat[0] = x;
var sign = x < 0 ? -1 : 1;
var exp = ((rts_scratchW32[0] >> 23) & 0xff) - 150;
var man = rts_scratchW32[0] & 0x7fffff;
if(exp === 0) {
++exp;
} else {
man |= (1 << 23);
}
return [0, sign*man, exp];
}
function decodeDouble(x) {
rts_scratchDouble[0] = x;
var sign = x < 0 ? -1 : 1;
var manHigh = rts_scratchW32[1] & 0xfffff;
var manLow = rts_scratchW32[0];
var exp = ((rts_scratchW32[1] >> 20) & 0x7ff) - 1075;
if(exp === 0) {
++exp;
} else {
manHigh |= (1 << 20);
}
return [0, sign, manHigh, manLow, exp];
}
function err(str) {
die(toJSStr(str)[1]);
}
/* unpackCString#
NOTE: update constructor tags if the code generator starts munging them.
*/
function unCStr(str) {return unAppCStr(str, [0]);}
function unFoldrCStr(str, f, z) {
var acc = z;
for(var i = str.length-1; i >= 0; --i) {
acc = A(f, [[0, str.charCodeAt(i)], acc]);
}
return acc;
}
function unAppCStr(str, chrs) {
var i = arguments[2] ? arguments[2] : 0;
if(i >= str.length) {
return E(chrs);
} else {
return [1,[0,str.charCodeAt(i)],new T(function() {
return unAppCStr(str,chrs,i+1);
})];
}
}
function charCodeAt(str, i) {return str.charCodeAt(i);}
function fromJSStr(str) {
return unCStr(E(str));
}
function toJSStr(hsstr) {
var s = '';
for(var str = E(hsstr); str[0] == 1; str = E(str[2])) {
s += String.fromCharCode(E(str[1])[1]);
}
return s;
}
// newMutVar
function nMV(val) {
return ({x: val});
}
// readMutVar
function rMV(mv) {
return mv.x;
}
// writeMutVar
function wMV(mv, val) {
mv.x = val;
}
// atomicModifyMutVar
function mMV(mv, f) {
var x = A(f, [mv.x]);
mv.x = x[1];
return x[2];
}
function localeEncoding() {
var le = newByteArr(5);
le['b']['i8'] = 'U'.charCodeAt(0);
le['b']['i8'] = 'T'.charCodeAt(0);
le['b']['i8'] = 'F'.charCodeAt(0);
le['b']['i8'] = '-'.charCodeAt(0);
le['b']['i8'] = '8'.charCodeAt(0);
return le;
}
var isFloatNaN = isDoubleNaN = isNaN;
function isDoubleInfinite(d) {
return (d === Infinity);
}
var isFloatInfinite = isDoubleInfinite;
function isDoubleNegativeZero(x) {
return (x===0 && (1/x)===-Infinity);
}
var isFloatNegativeZero = isDoubleNegativeZero;
function strEq(a, b) {
return a == b;
}
function strOrd(a, b) {
if(a < b) {
return [0];
} else if(a == b) {
return [1];
}
return [2];
}
function jsCatch(act, handler) {
try {
return A(act,[0]);
} catch(e) {
return A(handler,[e, 0]);
}
}
function hs_eqWord64(a, b) {
return (a[0] == b[0] && a[1] == b[1]);
}
// Word64# representation: (Word, Word)
function hs_wordToWord64(low) {
return [0, low];
}
function hs_mkWord64(high, low) {
return [high, low];
}
var coercionToken = undefined;
/* Haste represents constructors internally using 1 for the first constructor,
2 for the second, etc.
However, dataToTag should use 0, 1, 2, etc. Also, booleans might be unboxed.
*/
function dataToTag(x) {
if(x instanceof Array) {
return x[0];
} else {
return x;
}
}
function __word_encodeDouble(d, e) {
return d * Math.pow(2,e);
}
var __word_encodeFloat = __word_encodeDouble;
var jsRound = Math.round; // Stupid GHC doesn't like periods in FFI IDs...
if(typeof _ == 'undefined') {
var _ = undefined;
}
function jsAlert(val) {
if(typeof alert != 'undefined') {
alert(val);
} else {
print(val);
}
}
function jsLog(val) {
console.log(val);
}
function jsPrompt(str) {
var val;
if(typeof prompt != 'undefined') {
val = prompt(str);
} else {
print(str);
val = readline();
}
return val == undefined ? '' : val.toString();
}
function jsEval(str) {
var x = eval(str);
return x == undefined ? '' : x.toString();
}
function isNull(obj) {
return obj === null;
}
function jsRead(str) {
return Number(str);
}
function jsShowI(val) {return val.toString();}
function jsShow(val) {
var ret = val.toString();
return val == Math.round(val) ? ret + '.0' : ret;
}
function jsGetMouseCoords(e) {
var posx = 0;
var posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
return [posx - e.target.offsetLeft, posy - e.target.offsetTop];
}
function jsSetCB(elem, evt, cb) {
// Count return press in single line text box as a change event.
if(evt == 'change' && elem.type.toLowerCase() == 'text') {
setCB(elem, 'keyup', function(k) {
if(k == '\n'.charCodeAt(0)) {
A(cb,[[0,k.keyCode],0]);
}
});
}
var fun;
switch(evt) {
case 'click':
case 'dblclick':
case 'mouseup':
case 'mousedown':
fun = function(x) {
var mpos = jsGetMouseCoords(x);
var mx = [0,mpos[0]];
var my = [0,mpos[1]];
A(cb,[[0,x.button],[0,mx,my],0]);
};
break;
case 'mousemove':
case 'mouseover':
fun = function(x) {
var mpos = jsGetMouseCoords(x);
var mx = [0,mpos[0]];
var my = [0,mpos[1]];
A(cb,[[0,mx,my],0]);
};
break;
case 'keypress':
case 'keyup':
case 'keydown':
fun = function(x) {A(cb,[[0,x.keyCode],0]);};
break;
default:
fun = function() {A(cb,[0]);};
break;
}
return setCB(elem, evt, fun);
}
function setCB(elem, evt, cb) {
if(elem.addEventListener) {
elem.addEventListener(evt, cb, false);
return true;
} else if(elem.attachEvent) {
elem.attachEvent('on'+evt, cb);
return true;
}
return false;
}
function jsSetTimeout(msecs, cb) {
window.setTimeout(function() {A(cb,[0]);}, msecs);
}
function jsGet(elem, prop) {
return elem[prop].toString();
}
function jsSet(elem, prop, val) {
elem[prop] = val;
}
function jsGetStyle(elem, prop) {
return elem.style[prop].toString();
}
function jsSetStyle(elem, prop, val) {
elem.style[prop] = val;
}
function jsKillChild(child, parent) {
parent.removeChild(child);
}
function jsClearChildren(elem) {
while(elem.hasChildNodes()){
elem.removeChild(elem.lastChild);
}
}
function jsFind(elem) {
var e = document.getElementById(elem)
if(e) {
return [1,[0,e]];
}
return [0];
}
function jsCreateElem(tag) {
return document.createElement(tag);
}
function jsCreateTextNode(str) {
return document.createTextNode(str);
}
function jsGetChildBefore(elem) {
elem = elem.previousSibling;
while(elem) {
if(typeof elem.tagName != 'undefined') {
return [1,[0,elem]];
}
elem = elem.previousSibling;
}
return [0];
}
function jsGetLastChild(elem) {
var len = elem.childNodes.length;
for(var i = len-1; i >= 0; --i) {
if(typeof elem.childNodes[i].tagName != 'undefined') {
return [1,[0,elem.childNodes[i]]];
}
}
return [0];
}
function jsGetChildren(elem) {
var children = [0];
var len = elem.childNodes.length;
for(var i = len-1; i >= 0; --i) {
if(typeof elem.childNodes[i].tagName != 'undefined') {
children = [1, [0,elem.childNodes[i]], children];
}
}
return children;
}
function jsSetChildren(elem, children) {
children = E(children);
jsClearChildren(elem, 0);
while(children[0] === 1) {
elem.appendChild(E(E(children[1])[1]));
children = E(children[2]);
}
}
function jsAppendChild(child, container) {
container.appendChild(child);
}
function jsAddChildBefore(child, container, after) {
container.insertBefore(child, after);
}
var jsRand = Math.random;
// Concatenate a Haskell list of JS strings
function jsCat(strs, sep) {
var arr = [];
strs = E(strs);
while(strs[0]) {
strs = E(strs);
arr.push(E(strs[1])[1]);
strs = E(strs[2]);
}
return arr.join(sep);
}
// Escape all double quotes in a string
function jsUnquote(str) {
return str.replace(/"/, '\\"');
}
// Parse a JSON message into a Haste.JSON.JSON value.
// As this pokes around inside Haskell values, it'll need to be updated if:
// * Haste.JSON.JSON changes;
// * E() starts to choke on non-thunks;
// * data constructor code generation changes; or
// * Just and Nothing change tags.
function jsParseJSON(str) {
try {
var js = JSON.parse(str);
var hs = toHS(js);
} catch(_) {
return [0];
}
return [1,hs];
}
function toHS(obj) {
switch(typeof obj) {
case 'number':
return [0, [0, jsRead(obj)]];
case 'string':
return [1, [0, obj]];
break;
case 'boolean':
return [2, obj]; // Booleans are special wrt constructor tags!
break;
case 'object':
if(obj instanceof Array) {
return [3, arr2lst(obj, 0)];
} else {
// Object type but not array - it's a dictionary.
// The RFC doesn't say anything about the ordering of keys, but
// considering that lots of people rely on keys being "in order" as
// defined by "the same way someone put them in at the other end,"
// it's probably a good idea to put some cycles into meeting their
// misguided expectations.
var ks = [];
for(var k in obj) {
ks.unshift(k);
}
var xs = [0];
for(var i in ks) {
xs = [1, [0, [0,ks[i]], toHS(obj[ks[i]])], xs];
}
return [4, xs];
}
}
}
function arr2lst(arr, elem) {
if(elem >= arr.length) {
return [0];
}
return [1, toHS(arr[elem]), new T(function() {return arr2lst(arr,elem+1);})]
}
function ajaxReq(method, url, async, postdata, cb) {
var xhr = new XMLHttpRequest();
xhr.open(method, url, async);
xhr.setRequestHeader('Cache-control', 'no-cache');
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
A(cb,[[1,[0,xhr.responseText]],0]);
} else {
A(cb,[[0],0]); // Nothing
}
}
}
xhr.send(postdata);
}
// MVar implementation.
// Since Haste isn't concurrent, takeMVar and putMVar don't block on empty
// and full MVars respectively, but terminate the program since they would
// otherwise be blocking forever.
function newMVar() {
return ({empty: true});
}
function tryTakeMVar(mv) {
if(mv.empty) {
return [0, 0, undefined];
} else {
var val = mv.x;
mv.empty = true;
mv.x = null;
return [0, 1, val];
}
}
function takeMVar(mv) {
if(mv.empty) {
// TODO: real BlockedOnDeadMVar exception, perhaps?
err("Attempted to take empty MVar!");
}
var val = mv.x;
mv.empty = true;
mv.x = null;
return val;
}
function putMVar(mv, val) {
if(!mv.empty) {
// TODO: real BlockedOnDeadMVar exception, perhaps?
err("Attempted to put full MVar!");
}
mv.empty = false;
mv.x = val;
}
function tryPutMVar(mv, val) {
if(!mv.empty) {
return 0;
} else {
mv.empty = false;
mv.x = val;
return 1;
}
}
function sameMVar(a, b) {
return (a == b);
}
function isEmptyMVar(mv) {
return mv.empty ? 1 : 0;
}
// Implementation of stable names.
// Unlike native GHC, the garbage collector isn't going to move data around
// in a way that we can detect, so each object could serve as its own stable
// name if it weren't for the fact we can't turn a JS reference into an
// integer.
// So instead, each object has a unique integer attached to it, which serves
// as its stable name.
var __next_stable_name = 1;
function makeStableName(x) {
if(!x.stableName) {
x.stableName = __next_stable_name;
__next_stable_name += 1;
}
return x.stableName;
}
function eqStableName(x, y) {
return (x == y) ? 1 : 0;
}
var Integer = function(bits, sign) {
this.bits_ = [];
this.sign_ = sign;
var top = true;
for (var i = bits.length - 1; i >= 0; i--) {
var val = bits[i] | 0;
if (!top || val != sign) {
this.bits_[i] = val;
top = false;
}
}
};
Integer.IntCache_ = {};
var I_fromInt = function(value) {
if (-128 <= value && value < 128) {
var cachedObj = Integer.IntCache_[value];
if (cachedObj) {
return cachedObj;
}
}
var obj = new Integer([value | 0], value < 0 ? -1 : 0);
if (-128 <= value && value < 128) {
Integer.IntCache_[value] = obj;
}
return obj;
};
var I_fromNumber = function(value) {
if (isNaN(value) || !isFinite(value)) {
return Integer.ZERO;
} else if (value < 0) {
return I_negate(I_fromNumber(-value));
} else {
var bits = [];
var pow = 1;
for (var i = 0; value >= pow; i++) {
bits[i] = (value / pow) | 0;
pow *= Integer.TWO_PWR_32_DBL_;
}
return new Integer(bits, 0);
}
};
Integer.fromBits = function(bits) {
var high = bits[bits.length - 1];
return new Integer(bits, high & (1 << 31) ? -1 : 0);
};
I_fromString = function(str, opt_radix) {
if (str.length == 0) {
throw Error('number format error: empty string');
}
var radix = opt_radix || 10;
if (radix < 2 || 36 < radix) {
throw Error('radix out of range: ' + radix);
}
if (str.charAt(0) == '-') {
return I_negate(I_fromString(str.substring(1), radix));
} else if (str.indexOf('-') >= 0) {
throw Error('number format error: interior "-" character');
}
var radixToPower = I_fromNumber(Math.pow(radix, 8));
var result = Integer.ZERO;
for (var i = 0; i < str.length; i += 8) {
var size = Math.min(8, str.length - i);
var value = parseInt(str.substring(i, i + size), radix);
if (size < 8) {
var power = I_fromNumber(Math.pow(radix, size));
result = I_add(I_mul(result, power), I_fromNumber(value));
} else {
result = I_mul(result, radixToPower);
result = I_add(result, I_fromNumber(value));
}
}
return result;
};
Integer.TWO_PWR_32_DBL_ = (1 << 16) * (1 << 16);
Integer.ZERO = I_fromInt(0);
Integer.ONE = I_fromInt(1);
Integer.TWO_PWR_24_ = I_fromInt(1 << 24);
var I_toInt = function(self) {
return self.bits_.length > 0 ? self.bits_[0] : self.sign_;
};
var I_toWord = function(self) {
return I_toInt(self) >>> 0;
};
var I_toNumber = function(self) {
if (isNegative(self)) {
return -I_toNumber(I_negate(self));
} else {
var val = 0;
var pow = 1;
for (var i = 0; i < self.bits_.length; i++) {
val += getBitsUnsigned(self, i) * pow;
pow *= Integer.TWO_PWR_32_DBL_;
}
return val;
}
};
var getBits = function(self, index) {
if (index < 0) {
return 0;
} else if (index < self.bits_.length) {
return self.bits_[index];
} else {
return self.sign_;
}
};
var getBitsUnsigned = function(self, index) {
var val = getBits(self, index);
return val >= 0 ? val : Integer.TWO_PWR_32_DBL_ + val;
};
var getSign = function(self) {
return self.sign_;
};
var isZero = function(self) {
if (self.sign_ != 0) {
return false;
}
for (var i = 0; i < self.bits_.length; i++) {
if (self.bits_[i] != 0) {
return false;
}
}
return true;
};
var isNegative = function(self) {
return self.sign_ == -1;
};
var isOdd = function(self) {
return (self.bits_.length == 0) && (self.sign_ == -1) ||
(self.bits_.length > 0) && ((self.bits_[0] & 1) != 0);
};
var I_equals = function(self, other) {
if (self.sign_ != other.sign_) {
return false;
}
var len = Math.max(self.bits_.length, other.bits_.length);
for (var i = 0; i < len; i++) {
if (getBits(self, i) != getBits(other, i)) {
return false;
}
}
return true;
};
var I_notEquals = function(self, other) {
return !I_equals(self, other);
};
var greaterThan = function(self, other) {
return I_compare(self, other) > 0;
};
var greaterThanOrEqual = function(self, other) {
return I_compare(self, other) >= 0;
};
var lessThan = function(self, other) {
return I_compare(self, other) < 0;
};
var lessThanOrEqual = function(self, other) {
return I_compare(self, other) <= 0;
};
var I_compare = function(self, other) {
var diff = I_sub(self, other);
if (isNegative(diff)) {
return -1;
} else if (isZero(diff)) {
return 0;
} else {
return +1;
}
};
var I_compareInt = function(self, other) {
return I_compare(self, I_fromInt(other));
}
var shorten = function(self, numBits) {
var arr_index = (numBits - 1) >> 5;
var bit_index = (numBits - 1) % 32;
var bits = [];
for (var i = 0; i < arr_index; i++) {
bits[i] = getBits(self, i);
}
var sigBits = bit_index == 31 ? 0xFFFFFFFF : (1 << (bit_index + 1)) - 1;
var val = getBits(self, arr_index) & sigBits;
if (val & (1 << bit_index)) {
val |= 0xFFFFFFFF - sigBits;
bits[arr_index] = val;
return new Integer(bits, -1);
} else {
bits[arr_index] = val;
return new Integer(bits, 0);
}
};
var I_negate = function(self) {
return I_add(not(self), Integer.ONE);
};
var I_add = function(self, other) {
var len = Math.max(self.bits_.length, other.bits_.length);
var arr = [];
var carry = 0;
for (var i = 0; i <= len; i++) {
var a1 = getBits(self, i) >>> 16;
var a0 = getBits(self, i) & 0xFFFF;
var b1 = getBits(other, i) >>> 16;
var b0 = getBits(other, i) & 0xFFFF;
var c0 = carry + a0 + b0;
var c1 = (c0 >>> 16) + a1 + b1;
carry = c1 >>> 16;
c0 &= 0xFFFF;
c1 &= 0xFFFF;
arr[i] = (c1 << 16) | c0;
}
return Integer.fromBits(arr);
};
var I_sub = function(self, other) {
return I_add(self, I_negate(other));
};
var I_mul = function(self, other) {
if (isZero(self)) {
return Integer.ZERO;
} else if (isZero(other)) {
return Integer.ZERO;
}
if (isNegative(self)) {
if (isNegative(other)) {
return I_mul(I_negate(self), I_negate(other));
} else {
return I_negate(I_mul(I_negate(self), other));
}
} else if (isNegative(other)) {
return I_negate(I_mul(self, I_negate(other)));
}
if (lessThan(self, Integer.TWO_PWR_24_) &&
lessThan(other, Integer.TWO_PWR_24_)) {
return I_fromNumber(I_toNumber(self) * I_toNumber(other));
}
var len = self.bits_.length + other.bits_.length;
var arr = [];
for (var i = 0; i < 2 * len; i++) {
arr[i] = 0;
}
for (var i = 0; i < self.bits_.length; i++) {
for (var j = 0; j < other.bits_.length; j++) {
var a1 = getBits(self, i) >>> 16;
var a0 = getBits(self, i) & 0xFFFF;
var b1 = getBits(other, j) >>> 16;
var b0 = getBits(other, j) & 0xFFFF;
arr[2 * i + 2 * j] += a0 * b0;
Integer.carry16_(arr, 2 * i + 2 * j);
arr[2 * i + 2 * j + 1] += a1 * b0;
Integer.carry16_(arr, 2 * i + 2 * j + 1);
arr[2 * i + 2 * j + 1] += a0 * b1;
Integer.carry16_(arr, 2 * i + 2 * j + 1);
arr[2 * i + 2 * j + 2] += a1 * b1;
Integer.carry16_(arr, 2 * i + 2 * j + 2);
}
}
for (var i = 0; i < len; i++) {
arr[i] = (arr[2 * i + 1] << 16) | arr[2 * i];
}
for (var i = len; i < 2 * len; i++) {
arr[i] = 0;
}
return new Integer(arr, 0);
};
Integer.carry16_ = function(bits, index) {
while ((bits[index] & 0xFFFF) != bits[index]) {
bits[index + 1] += bits[index] >>> 16;
bits[index] &= 0xFFFF;
}
};
var I_mod = function(self, other) {
return I_rem(I_add(other, I_rem(self, other)), other);
}
var I_div = function(self, other) {
if(greaterThan(self, Integer.ZERO) != greaterThan(other, Integer.ZERO)) {
if(I_rem(self, other) != Integer.ZERO) {
return I_sub(I_quot(self, other), Integer.ONE);
}
}
return I_quot(self, other);
}
var I_quotRem = function(self, other) {
return [0, I_quot(self, other), I_rem(self, other)];
}
var I_divMod = function(self, other) {
return [0, I_div(self, other), I_mod(self, other)];
}
var I_quot = function(self, other) {
if (isZero(other)) {
throw Error('division by zero');
} else if (isZero(self)) {
return Integer.ZERO;
}
if (isNegative(self)) {
if (isNegative(other)) {
return I_quot(I_negate(self), I_negate(other));
} else {
return I_negate(I_quot(I_negate(self), other));
}
} else if (isNegative(other)) {
return I_negate(I_quot(self, I_negate(other)));
}
var res = Integer.ZERO;
var rem = self;
while (greaterThanOrEqual(rem, other)) {
var approx = Math.max(1, Math.floor(I_toNumber(rem) / I_toNumber(other)));
var log2 = Math.ceil(Math.log(approx) / Math.LN2);
var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
var approxRes = I_fromNumber(approx);
var approxRem = I_mul(approxRes, other);
while (isNegative(approxRem) || greaterThan(approxRem, rem)) {
approx -= delta;
approxRes = I_fromNumber(approx);
approxRem = I_mul(approxRes, other);
}
if (isZero(approxRes)) {
approxRes = Integer.ONE;
}
res = I_add(res, approxRes);
rem = I_sub(rem, approxRem);
}
return res;
};
var I_rem = function(self, other) {
return I_sub(self, I_mul(I_quot(self, other), other));
};
var not = function(self) {
var len = self.bits_.length;
var arr = [];
for (var i = 0; i < len; i++) {
arr[i] = ~self.bits_[i];
}
return new Integer(arr, ~self.sign_);
};
var I_and = function(self, other) {
var len = Math.max(self.bits_.length, other.bits_.length);
var arr = [];
for (var i = 0; i < len; i++) {
arr[i] = getBits(self, i) & getBits(other, i);
}
return new Integer(arr, self.sign_ & other.sign_);
};
var I_or = function(self, other) {
var len = Math.max(self.bits_.length, other.bits_.length);
var arr = [];
for (var i = 0; i < len; i++) {
arr[i] = getBits(self, i) | getBits(other, i);
}
return new Integer(arr, self.sign_ | other.sign_);
};
var I_xor = function(self, other) {
var len = Math.max(self.bits_.length, other.bits_.length);
var arr = [];
for (var i = 0; i < len; i++) {
arr[i] = getBits(self, i) ^ getBits(other, i);
}
return new Integer(arr, self.sign_ ^ other.sign_);
};
var I_shiftLeft = function(self, numBits) {
var arr_delta = numBits >> 5;
var bit_delta = numBits % 32;
var len = self.bits_.length + arr_delta + (bit_delta > 0 ? 1 : 0);
var arr = [];
for (var i = 0; i < len; i++) {
if (bit_delta > 0) {
arr[i] = (getBits(self, i - arr_delta) << bit_delta) |
(getBits(self, i - arr_delta - 1) >>> (32 - bit_delta));
} else {
arr[i] = getBits(self, i - arr_delta);
}
}
return new Integer(arr, self.sign_);
};
var I_shiftRight = function(self, numBits) {
var arr_delta = numBits >> 5;
var bit_delta = numBits % 32;
var len = self.bits_.length - arr_delta;
var arr = [];
for (var i = 0; i < len; i++) {
if (bit_delta > 0) {
arr[i] = (getBits(self, i + arr_delta) >>> bit_delta) |
(getBits(self, i + arr_delta + 1) << (32 - bit_delta));
} else {
arr[i] = getBits(self, i + arr_delta);
}
}
return new Integer(arr, self.sign_);
};
var I_signum = function(self) {
var cmp = I_compare(self, Integer.ZERO);
if(cmp > 0) {
return Integer.ONE
}
if(cmp < 0) {
return I_sub(Integer.ZERO, Integer.ONE);
}
return Integer.ZERO;
};
var I_abs = function(self) {
if(I_compare(self, Integer.ZERO) < 0) {
return I_sub(Integer.ZERO, self);
}
return self;
};
var I_decodeDouble = function(x) {
var dec = decodeDouble(x);
var mantissa = Integer.fromBits([dec[3], dec[2]]);
if(dec[1] < 0) {
mantissa = I_negate(mantissa);
}
return [0, dec[4], mantissa];
}
var I_toString = function(self) {
var radix = 10;
if (isZero(self)) {
return '0';
} else if (isNegative(self)) {
return '-' + I_toString(I_negate(self));
}
var radixToPower = I_fromNumber(Math.pow(radix, 6));
var rem = self;
var result = '';
while (true) {
var remDiv = I_div(rem, radixToPower);
var intval = I_toInt(I_sub(rem, I_mul(remDiv, radixToPower)));
var digits = intval.toString();
rem = remDiv;
if (isZero(rem)) {
return digits + result;
} else {
while (digits.length < 6) {
digits = '0' + digits;
}
result = '' + digits + result;
}
}
};
var I_fromRat = function(a, b) {
return I_toNumber(a) / I_toNumber(b);
}
// Joseph Myers' MD5 implementation; used under the BSD license.
function md5cycle(x, k) {
var a = x[0], b = x[1], c = x[2], d = x[3];
a = ff(a, b, c, d, k[0], 7, -680876936);
d = ff(d, a, b, c, k[1], 12, -389564586);
c = ff(c, d, a, b, k[2], 17, 606105819);
b = ff(b, c, d, a, k[3], 22, -1044525330);
a = ff(a, b, c, d, k[4], 7, -176418897);
d = ff(d, a, b, c, k[5], 12, 1200080426);
c = ff(c, d, a, b, k[6], 17, -1473231341);
b = ff(b, c, d, a, k[7], 22, -45705983);
a = ff(a, b, c, d, k[8], 7, 1770035416);
d = ff(d, a, b, c, k[9], 12, -1958414417);
c = ff(c, d, a, b, k[10], 17, -42063);
b = ff(b, c, d, a, k[11], 22, -1990404162);
a = ff(a, b, c, d, k[12], 7, 1804603682);
d = ff(d, a, b, c, k[13], 12, -40341101);
c = ff(c, d, a, b, k[14], 17, -1502002290);
b = ff(b, c, d, a, k[15], 22, 1236535329);
a = gg(a, b, c, d, k[1], 5, -165796510);
d = gg(d, a, b, c, k[6], 9, -1069501632);
c = gg(c, d, a, b, k[11], 14, 643717713);
b = gg(b, c, d, a, k[0], 20, -373897302);
a = gg(a, b, c, d, k[5], 5, -701558691);
d = gg(d, a, b, c, k[10], 9, 38016083);
c = gg(c, d, a, b, k[15], 14, -660478335);
b = gg(b, c, d, a, k[4], 20, -405537848);
a = gg(a, b, c, d, k[9], 5, 568446438);
d = gg(d, a, b, c, k[14], 9, -1019803690);
c = gg(c, d, a, b, k[3], 14, -187363961);
b = gg(b, c, d, a, k[8], 20, 1163531501);
a = gg(a, b, c, d, k[13], 5, -1444681467);
d = gg(d, a, b, c, k[2], 9, -51403784);
c = gg(c, d, a, b, k[7], 14, 1735328473);
b = gg(b, c, d, a, k[12], 20, -1926607734);
a = hh(a, b, c, d, k[5], 4, -378558);
d = hh(d, a, b, c, k[8], 11, -2022574463);
c = hh(c, d, a, b, k[11], 16, 1839030562);
b = hh(b, c, d, a, k[14], 23, -35309556);
a = hh(a, b, c, d, k[1], 4, -1530992060);
d = hh(d, a, b, c, k[4], 11, 1272893353);
c = hh(c, d, a, b, k[7], 16, -155497632);
b = hh(b, c, d, a, k[10], 23, -1094730640);
a = hh(a, b, c, d, k[13], 4, 681279174);
d = hh(d, a, b, c, k[0], 11, -358537222);
c = hh(c, d, a, b, k[3], 16, -722521979);
b = hh(b, c, d, a, k[6], 23, 76029189);
a = hh(a, b, c, d, k[9], 4, -640364487);
d = hh(d, a, b, c, k[12], 11, -421815835);
c = hh(c, d, a, b, k[15], 16, 530742520);
b = hh(b, c, d, a, k[2], 23, -995338651);
a = ii(a, b, c, d, k[0], 6, -198630844);
d = ii(d, a, b, c, k[7], 10, 1126891415);
c = ii(c, d, a, b, k[14], 15, -1416354905);
b = ii(b, c, d, a, k[5], 21, -57434055);
a = ii(a, b, c, d, k[12], 6, 1700485571);
d = ii(d, a, b, c, k[3], 10, -1894986606);
c = ii(c, d, a, b, k[10], 15, -1051523);
b = ii(b, c, d, a, k[1], 21, -2054922799);
a = ii(a, b, c, d, k[8], 6, 1873313359);
d = ii(d, a, b, c, k[15], 10, -30611744);
c = ii(c, d, a, b, k[6], 15, -1560198380);
b = ii(b, c, d, a, k[13], 21, 1309151649);
a = ii(a, b, c, d, k[4], 6, -145523070);
d = ii(d, a, b, c, k[11], 10, -1120210379);
c = ii(c, d, a, b, k[2], 15, 718787259);
b = ii(b, c, d, a, k[9], 21, -343485551);
x[0] = add32(a, x[0]);
x[1] = add32(b, x[1]);
x[2] = add32(c, x[2]);
x[3] = add32(d, x[3]);
}
function cmn(q, a, b, x, s, t) {
a = add32(add32(a, q), add32(x, t));
return add32((a << s) | (a >>> (32 - s)), b);
}
function ff(a, b, c, d, x, s, t) {
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function gg(a, b, c, d, x, s, t) {
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function hh(a, b, c, d, x, s, t) {
return cmn(b ^ c ^ d, a, b, x, s, t);
}
function ii(a, b, c, d, x, s, t) {
return cmn(c ^ (b | (~d)), a, b, x, s, t);
}
function md51(s) {
txt = '';
var n = s.length,
state = [1732584193, -271733879, -1732584194, 271733878], i;
for (i=64; i<=s.length; i+=64) {
md5cycle(state, md5blk(s.substring(i-64, i)));
}
s = s.substring(i-64);
var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
for (i=0; i<s.length; i++)
tail[i>>2] |= s.charCodeAt(i) << ((i%4) << 3);
tail[i>>2] |= 0x80 << ((i%4) << 3);
if (i > 55) {
md5cycle(state, tail);
for (i=0; i<16; i++) tail[i] = 0;
}
tail[14] = n*8;
md5cycle(state, tail);
return state;
}
function md5blk(s) {
var md5blks = [], i;
for (i=0; i<64; i+=4) {
md5blks[i>>2] = s.charCodeAt(i)
+ (s.charCodeAt(i+1) << 8)
+ (s.charCodeAt(i+2) << 16)
+ (s.charCodeAt(i+3) << 24);
}
return md5blks;
}
var hex_chr = '0123456789abcdef'.split('');
function rhex(n)
{
var s='', j=0;
for(; j<4; j++)
s += hex_chr[(n >> (j * 8 + 4)) & 0x0F]
+ hex_chr[(n >> (j * 8)) & 0x0F];
return s;
}
function hex(x) {
for (var i=0; i<x.length; i++)
x[i] = rhex(x[i]);
return x.join('');
}
function md5(s) {
return hex(md51(s));
}
function add32(a, b) {
return (a + b) & 0xFFFFFFFF;
}
// Functions for dealing with arrays.
function newArr(n, x) {
var arr = [];
for(; n >= 0; --n) {
arr.push(x);
}
return arr;
}
// Create all views at once; perhaps it's wasteful, but it's better than having
// to check for the right view at each read or write.
function newByteArr(n) {
// Pad the thing to multiples of 8.
var padding = 8 - n % 8;
if(padding < 8) {
n += padding;
}
var arr = {};
var buffer = new ArrayBuffer(n);
var views = {};
views['i8'] = new Int8Array(buffer);
views['i16'] = new Int16Array(buffer);
views['i32'] = new Int32Array(buffer);
views['w8'] = new Uint8Array(buffer);
views['w16'] = new Uint16Array(buffer);
views['w32'] = new Uint32Array(buffer);
views['f32'] = new Float32Array(buffer);
views['f64'] = new Float64Array(buffer);
arr['b'] = buffer;
arr['v'] = views;
// ByteArray and Addr are the same thing, so keep an offset if we get
// casted.
arr['off'] = 0;
return arr;
}
// An attempt at emulating pointers enough for ByteString and Text to be
// usable without patching the hell out of them.
// The general idea is that Addr# is a byte array with an associated offset.
function plusAddr(addr, off) {
var newaddr = {};
newaddr['off'] = addr['off'] + off;
newaddr['b'] = addr['b'];
newaddr['v'] = addr['v'];
return newaddr;
}
function writeOffAddr(type, elemsize, addr, off, x) {
addr['v'][type][addr.off/elemsize + off] = x;
}
function readOffAddr(type, elemsize, addr, off) {
return addr['v'][type][addr.off/elemsize + off];
}
// Two addresses are equal if they point to the same buffer and have the same
// offset. For other comparisons, just use the offsets - nobody in their right
// mind would check if one pointer is less than another, completely unrelated,
// pointer and then act on that information anyway.
function addrEq(a, b) {
if(a == b) {
return true;
}
return a && b && a['b'] == b['b'] && a['off'] == b['off'];
}
function addrLT(a, b) {
if(a) {
return b && a['off'] < b['off'];
} else {
return (b != 0);
}
}
function addrGT(a, b) {
if(b) {
return a && a['off'] > b['off'];
} else {
return (a != 0);
}
}
function withChar(f, charCode) {
return f(String.fromCharCode(charCode)).charCodeAt(0);
}
function u_towlower(charCode) {
return withChar(function(c) {return c.toLowerCase()}, charCode);
}
function u_towupper(charCode) {
return withChar(function(c) {return c.toUpperCase()}, charCode);
}
var u_towtitle = u_towupper;
function u_iswupper(charCode) {
var c = String.fromCharCode(charCode);
return c == c.toUpperCase() && c != c.toLowerCase();
}
function u_iswlower(charCode) {
var c = String.fromCharCode(charCode);
return c == c.toLowerCase() && c != c.toUpperCase();
}
function u_iswdigit(charCode) {
return charCode >= 48 && charCode <= 57;
}
function u_iswcntrl(charCode) {
return charCode <= 0x1f || charCode == 0x7f;
}
function u_iswspace(charCode) {
var c = String.fromCharCode(charCode);
return c.replace(/\s/g,'') != c;
}
function u_iswalpha(charCode) {
var c = String.fromCharCode(charCode);
return c.replace(__hs_alphare, '') != c;
}
function u_iswalnum(charCode) {
return u_iswdigit(charCode) || u_iswalpha(charCode);
}
function u_iswprint(charCode) {
return !u_iswcntrl(charCode);
}
function u_gencat(c) {
throw 'u_gencat is only supported with --full-unicode.';
}
// Regex that matches any alphabetic character in any language. Horrible thing.
var __hs_alphare = /[\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/g;
// 2D Canvas drawing primitives.
function jsHasCtx2D(elem) {return !!elem.getContext;}
function jsGetCtx2D(elem) {return elem.getContext('2d');}
function jsBeginPath(ctx) {ctx.beginPath();}
function jsMoveTo(ctx, x, y) {ctx.moveTo(x, y);}
function jsLineTo(ctx, x, y) {ctx.lineTo(x, y);}
function jsStroke(ctx) {ctx.stroke();}
function jsFill(ctx) {ctx.fill();}
function jsRotate(ctx, radians) {ctx.rotate(radians);}
function jsTranslate(ctx, x, y) {ctx.translate(x, y);}
function jsScale(ctx, x, y) {ctx.scale(x, y);}
function jsPushState(ctx) {ctx.save();}
function jsPopState(ctx) {ctx.restore();}
function jsResetCanvas(el) {el.width = el.width;}
function jsDrawImage(ctx, img, x, y) {ctx.drawImage(img, x, y);}
function jsDrawImageClipped(ctx, img, x, y, cx, cy, cw, ch) {
ctx.drawImage(img, cx, cy, cw, ch, x, y, cw, ch);
}
function jsDrawText(ctx, str, x, y) {ctx.fillText(str, x, y);}
function jsClip(ctx) {ctx.clip();}
function jsArc(ctx, x, y, radius, fromAngle, toAngle) {
ctx.arc(x, y, radius, fromAngle, toAngle);
}
function jsCanvasToDataURL(el) {return el.toDataURL('image/png');}
// Simulate handles.
// When implementing new handles, remember that passed strings may be thunks,
// and so need to be evaluated before use.
function jsNewHandle(init, read, write, flush, close, seek, tell) {
var h = {
read: read || function() {},
write: write || function() {},
seek: seek || function() {},
tell: tell || function() {},
close: close || function() {},
flush: flush || function() {}
};
init.call(h);
return h;
}
function jsReadHandle(h, len) {return h.read(len);}
function jsWriteHandle(h, str) {return h.write(str);}
function jsFlushHandle(h) {return h.flush();}
function jsCloseHandle(h) {return h.close();}
function jsMkConWriter(op) {
return function(str) {
str = E(str);
var lines = (this.buf + str).split('\n');
for(var i = 0; i < lines.length-1; ++i) {
op.call(console, lines[i]);
}
this.buf = lines[lines.length-1];
}
}
function jsMkStdout() {
return jsNewHandle(
function() {this.buf = '';},
function(_) {return '';},
jsMkConWriter(console.log),
function() {console.log(this.buf); this.buf = '';}
);
}
function jsMkStderr() {
return jsNewHandle(
function() {this.buf = '';},
function(_) {return '';},
jsMkConWriter(console.warn),
function() {console.warn(this.buf); this.buf = '';}
);
}
function jsMkStdin() {
return jsNewHandle(
function() {this.buf = '';},
function(len) {
while(this.buf.length < len) {
this.buf += prompt('[stdin]') + '\n';
}
var ret = this.buf.substr(0, len);
this.buf = this.buf.substr(len);
return ret;
}
);
}
var _0=unCStr("src"),_1=unCStr("img"),_2=0,_3=function(_4,_5,_6,_7){return A(_4,[new T(function(){return function(_){jsSet(E(_5)[1],toJSStr(E(_6)),toJSStr(E(_7)));return _2;};})]);},_8=function(_9){return E(_9);},_a=function(_b,_c){return A(_b,[function(_){var _d=jsCreateElem(toJSStr(E(_1))),_e=[0,_d];A(_3,[_8,_e,_0,_c,_]);return _e;}]);},_f=function(_g,_){return _2;},_h=function(_i,_j){if(_i<=_j){var _k=function(_l){return [1,[0,_l],new T(function(){return _l!=_j?_k(_l+1|0):[0];})];};return _k(_i);}else{return [0];}},_m=function(_n,_o){var _p=E(_n);return _p[0]==0?E(_o):[1,_p[1],new T(function(){return _m(_p[2],_o);})];},_q=function(_r,_s){var _t=jsShowI(_r);return _m(fromJSStr(_t),_s);},_u=[0,41],_v=[0,40],_w=function(_x,_y,_z){return _y>=0?_q(_y,_z):_x<=6?_q(_y,_z):[1,_v,new T(function(){var _A=jsShowI(_y);return _m(fromJSStr(_A),[1,_u,_z]);})];},_B=[0],_C=function(_D){return _w(0,E(_D)[1],_B);},_E=[0,44],_F=[0,93],_G=[0,91],_H=function(_I,_J,_K){var _L=E(_J);return _L[0]==0?unAppCStr("[]",_K):[1,_G,new T(function(){return A(_I,[_L[1],new T(function(){var _M=function(_N){var _O=E(_N);return _O[0]==0?E([1,_F,_K]):[1,_E,new T(function(){return A(_I,[_O[1],new T(function(){return _M(_O[2]);})]);})];};return _M(_L[2]);})]);})];},_P=function(_Q,_R){return _w(0,E(_Q)[1],_R);},_S=function(_T,_U){return _H(_P,_T,_U);},_V=function(_W,_X,_Y){return _w(E(_W)[1],E(_X)[1],_Y);},_Z=[0,_V,_C,_S],_10=[0,0],_11=function(_12,_13,_14){return A(_12,[[1,_E,new T(function(){return A(_13,[_14]);})]]);},_15=unCStr(": empty list"),_16=unCStr("Prelude."),_17=function(_18){return err(_m(_16,new T(function(){return _m(_18,_15);})));},_19=unCStr("foldr1"),_1a=new T(function(){return _17(_19);}),_1b=function(_1c,_1d){var _1e=E(_1d);if(!_1e[0]){return E(_1a);}else{var _1f=_1e[1],_1g=E(_1e[2]);return _1g[0]==0?E(_1f):A(_1c,[_1f,new T(function(){return _1b(_1c,_1g);})]);}},_1h=unCStr(" out of range "),_1i=unCStr("}.index: Index "),_1j=unCStr("Ix{"),_1k=[1,_u,_B],_1l=[1,_u,_1k],_1m=[0,0],_1n=function(_1o,_1p,_1q,_1r,_1s){return err(_m(_1j,new T(function(){return _m(_1o,new T(function(){return _m(_1i,[1,_v,new T(function(){return A(_1s,[_10,_1p,[1,_u,new T(function(){return _m(_1h,[1,_v,[1,_v,new T(function(){return A(_1b,[_11,[1,new T(function(){return A(_1s,[_1m,_1q]);}),[1,new T(function(){return A(_1s,[_1m,_1r]);}),_B]],_1l]);})]]);})]]);})]);}));})));},_1t=function(_1u,_1v,_1w,_1x){var _1y=E(_1w);return _1n(_1u,_1v,_1y[1],_1y[2],E(_1x)[1]);},_1z=function(_1A,_1B,_1C,_1D){return _1t(_1D,_1C,_1B,_1A);},_1E=unCStr("Int"),_1F=function(_1G,_1H,_1I){return _1z(_Z,[0,_1H,_1I],[0,_1G],_1E);},_1J=function(_1K,_1L,_1M){return _1F(_1K,_1L,_1M);},_1N=function(_1O,_1P,_1Q,_1R){var _1S=_1Q-1|0;if(0<=_1S){var _1T=function(_1U){var _1V=function(_1W){var _1X=E(_1W);if(!_1X[0]){return _1U!=_1S?_1T(_1U+1|0):E(_f);}else{var _1Y=_1X[1],_1Z=new T(function(){var _20=E(_1O),_21=E(_20[1]),_22=_21[1],_23=E(_20[2]),_24=(imul(E(_1Y)[1],_1Q)|0)+_1U|0;if(_22>_24){return _1J(_24,_21,_23);}else{if(_24>_23[1]){return _1J(_24,_21,_23);}else{var _25=quotRemI(E(_20[4][_24-_22|0])[1],11);return [0,[0,_25[1]],[0,_25[2]]];}}});return function(_26,_){var _27=E(_26);jsDrawImageClipped(_27[1],E(_1P)[1],_1U*16,E(_1Y)[1]*16,1+E(E(_1Z)[2])[1]*17,1+E(E(_1Z)[1])[1]*17,16,16);return A(_1V(_1X[2]),[_27,_]);};}};return _1V(new T(function(){return _h(0,E(_1R)[1]-1|0);}));};return _1T(0);}else{return E(_f);}},_28=unCStr("Pattern match failure in do expression at canvas.hs:125:3-14"),_29=new T(function(){return [0,"strokeStyle"];}),_2a=new T(function(){return [0,"fillStyle"];}),_2b=[0,44],_2c=[1,_2b,_B],_2d=new T(function(){return [0,toJSStr(_2c)];}),_2e=[1,_2b,_B],_2f=new T(function(){return [0,toJSStr(_2e)];}),_2g=new T(function(){return [0,"rgba("];}),_2h=new T(function(){return [0,toJSStr(_B)];}),_2i=[0,41],_2j=[1,_2i,_B],_2k=new T(function(){return [0,toJSStr(_2j)];}),_2l=[1,_2k,_B],_2m=[1,_2b,_B],_2n=new T(function(){return [0,toJSStr(_2m)];}),_2o=[1,_2b,_B],_2p=new T(function(){return [0,toJSStr(_2o)];}),_2q=new T(function(){return [0,"rgb("];}),_2r=[1,_2i,_B],_2s=new T(function(){return [0,toJSStr(_2r)];}),_2t=[1,_2s,_B],_2u=[1,_2b,_B],_2v=new T(function(){return [0,toJSStr(_2u)];}),_2w=function(_2x){var _2y=String(E(_2x)[1]);return [0,_2y];},_2z=function(_2A){var _2B=E(_2A);if(!_2B[0]){var _2C=jsCat([1,_2q,[1,new T(function(){return _2w(_2B[1]);}),[1,_2p,[1,new T(function(){return _2w(_2B[2]);}),[1,_2n,[1,new T(function(){return _2w(_2B[3]);}),_2l]]]]]],E(_2h)[1]);return [0,_2C];}else{var _2D=jsCat([1,_2g,[1,new T(function(){return _2w(_2B[1]);}),[1,_2f,[1,new T(function(){return _2w(_2B[2]);}),[1,_2d,[1,new T(function(){return _2w(_2B[3]);}),[1,_2v,[1,new T(function(){return _2w(_2B[4]);}),_2t]]]]]]]],E(_2h)[1]);return [0,_2D];}},_2E=function(_2F,_2G){return function(_2H,_){var _2I=E(_2H),_2J=_2I[1],_2K=E(_2a)[1],_2L=jsGet(_2J,_2K),_2M=E(_29)[1],_2N=jsGet(_2J,_2M),_2O=_2z(_2F)[1];jsSet(_2J,_2K,_2O);jsSet(_2J,_2M,_2O);A(_2G,[_2I,_]);jsSet(_2J,_2K,_2L);jsSet(_2J,_2M,_2N);return _2;};},_2P=unCStr("base"),_2Q=unCStr("GHC.IO.Exception"),_2R=unCStr("IOException"),_2S=[0,7.238999624334008e18,1.0769272474234763e19,_2P,_2Q,_2R],_2T=[0,7.238999624334008e18,1.0769272474234763e19,_2S,_B],_2U=function(_2V){return E(_2T);},_2W=function(_2X){return E(E(_2X)[1]);},_2Y=unCStr("Maybe.fromJust: Nothing"),_2Z=new T(function(){return err(_2Y);}),_30=function(_31,_32,_33){var _34=new T(function(){var _35=A(_31,[_33]),_36=A(_32,[new T(function(){var _37=E(_34);return _37[0]==0?E(_2Z):E(_37[1]);})]),_38=hs_eqWord64(_35[1],_36[1]);if(!E(_38)){return [0];}else{var _39=hs_eqWord64(_35[2],_36[2]);return E(_39)==0?[0]:[1,_33];}});return E(_34);},_3a=function(_3b){var _3c=E(_3b);return _30(_2W(_3c[1]),_2U,_3c[2]);},_3d=unCStr(": "),_3e=[0,41],_3f=unCStr(" ("),_3g=unCStr("already exists"),_3h=unCStr("does not exist"),_3i=unCStr("protocol error"),_3j=unCStr("failed"),_3k=unCStr("invalid argument"),_3l=unCStr("inappropriate type"),_3m=unCStr("hardware fault"),_3n=unCStr("unsupported operation"),_3o=unCStr("timeout"),_3p=unCStr("resource vanished"),_3q=unCStr("interrupted"),_3r=unCStr("resource busy"),_3s=unCStr("resource exhausted"),_3t=unCStr("end of file"),_3u=unCStr("illegal operation"),_3v=unCStr("permission denied"),_3w=unCStr("user error"),_3x=unCStr("unsatisified constraints"),_3y=unCStr("system error"),_3z=function(_3A,_3B){switch(E(_3A)){case 0:return _m(_3g,_3B);case 1:return _m(_3h,_3B);case 2:return _m(_3r,_3B);case 3:return _m(_3s,_3B);case 4:return _m(_3t,_3B);case 5:return _m(_3u,_3B);case 6:return _m(_3v,_3B);case 7:return _m(_3w,_3B);case 8:return _m(_3x,_3B);case 9:return _m(_3y,_3B);case 10:return _m(_3i,_3B);case 11:return _m(_3j,_3B);case 12:return _m(_3k,_3B);case 13:return _m(_3l,_3B);case 14:return _m(_3m,_3B);case 15:return _m(_3n,_3B);case 16:return _m(_3o,_3B);case 17:return _m(_3p,_3B);default:return _m(_3q,_3B);}},_3C=[0,125],_3D=unCStr("{handle: "),_3E=function(_3F,_3G,_3H,_3I,_3J,_3K){var _3L=new T(function(){var _3M=new T(function(){return _3z(_3G,new T(function(){var _3N=E(_3I);return _3N[0]==0?E(_3K):_m(_3f,new T(function(){return _m(_3N,[1,_3e,_3K]);}));}));}),_3O=E(_3H);return _3O[0]==0?E(_3M):_m(_3O,new T(function(){return _m(_3d,_3M);}));}),_3P=E(_3J);if(!_3P[0]){var _3Q=E(_3F);if(!_3Q[0]){return E(_3L);}else{var _3R=E(_3Q[1]);return _3R[0]==0?_m(_3D,new T(function(){return _m(_3R[1],[1,_3C,new T(function(){return _m(_3d,_3L);})]);})):_m(_3D,new T(function(){return _m(_3R[1],[1,_3C,new T(function(){return _m(_3d,_3L);})]);}));}}else{return _m(_3P[1],new T(function(){return _m(_3d,_3L);}));}},_3S=function(_3T){var _3U=E(_3T);return _3E(_3U[1],_3U[2],_3U[3],_3U[4],_3U[6],_B);},_3V=function(_3W,_3X){var _3Y=E(_3W);return _3E(_3Y[1],_3Y[2],_3Y[3],_3Y[4],_3Y[6],_3X);},_3Z=function(_40,_41){return _H(_3V,_40,_41);},_42=function(_43,_44,_45){var _46=E(_44);return _3E(_46[1],_46[2],_46[3],_46[4],_46[6],_45);},_47=[0,_42,_3S,_3Z],_48=[0,_2U,_47,_49,_3a],_49=function(_4a){return [0,_48,_4a];},_4b=[0],_4c=7,_4d=function(_4e){return [0,_4b,_4c,_B,_4e,_4b,_4b];},_4f=function(_4g,_){return die(new T(function(){return _49(new T(function(){return _4d(_4g);}));}));},_4h=function(_4i,_){return _4f(_4i,_);},_4j=function(_4k,_4l,_){var _4m=E(_4l),_4n=_4m[1];jsBeginPath(_4n);A(_4k,[_4m,_]);jsFill(_4n);return _2;},_4o=[0,255],_4p=[0,0.5],_4q=[1,_4o,_4o,_4o,_4p],_4r=unCStr("value"),_4s=unCStr("dataurl"),_4t=function(_4u,_){return _2;},_4v=function(_4w){var _4x=E(_4w);if(!_4x[0]){return E(_4t);}else{var _4y=E(_4x[1]);return function(_4z,_){var _4A=E(_4z)[1];jsMoveTo(_4A,E(_4y[1])[1],E(_4y[2])[1]);return (function(_4B,_){while(1){var _4C=E(_4B);if(!_4C[0]){return _2;}else{var _4D=E(_4C[1]);jsLineTo(_4A,E(_4D[1])[1],E(_4D[2])[1]);_4B=_4C[2];continue;}}})(_4x[2],_);};}},_4E=function(_4F,_4G,_4H,_4I,_4J,_4K,_4L,_4M,_4N,_){jsResetCanvas(_4K);var _4O=E(_4N),_4P=E(_4J),_4Q=_4P[1];jsPushState(_4Q);jsScale(_4Q,2,2);A(_1N,[_4F,_4G,_4H,_4I,_4P,_]);A(_2E,[_4q,function(_4R,_){return _4j(new T(function(){var _4S=new T(function(){return [0,imul(E(_4O[2])[1],16)|0];}),_4T=new T(function(){return [0,E(_4S)[1]+16];}),_4U=new T(function(){return [0,imul(E(_4O[1])[1],16)|0];}),_4V=new T(function(){return [0,E(_4U)[1]+16];});return _4v([1,[0,_4U,_4S],[1,[0,_4V,_4S],[1,[0,_4V,_4T],[1,[0,_4U,_4T],[1,[0,_4U,_4S],_B]]]]]);}),_4R,_);},_4P,_]);jsPopState(_4Q);var _4W=E(_4L),_4X=E(_4W[2])[1];jsResetCanvas(_4X);var _4Y=E(_4W[1]),_4Z=_4Y[1];jsPushState(_4Z);jsScale(_4Z,2,2);var _50=E(_4M),_51=E(_50[3]);A(_1N,[_50[1],_50[2],E(_51[1])[1],_51[2],_4Y,_]);jsPopState(_4Z);var _52=jsFind(toJSStr(E(_4s))),_53=E(_52);if(!_53[0]){return _4h(_28,_);}else{var _54=jsCanvasToDataURL(_4X);return A(_3,[_8,_53[1],_4r,new T(function(){return fromJSStr(_54);}),_]);}},_55=unCStr("(Array.!): undefined array element"),_56=new T(function(){return err(_55);}),_57=[0,0],_58=[0,120],_59=new T(function(){return _h(0,2147483647);}),_5a=function(_){var _5b=newArr(121,_56),_=(function(_5c,_5d,_){while(1){var _5e=E(_5c);if(_5e==121){return E(_);}else{var _5f=E(_5d);if(!_5f[0]){return E(_);}else{_5b[_5e]=_5f[1];_5c=_5e+1|0;_5d=_5f[2];continue;}}}})(0,_59,_),_5g=_5b;return [0,E(_57),E(_58),121,_5g];},_5h=function(_5i){var _5j=A(_5i,[_]);return E(_5j);},_5k=new T(function(){return _5h(_5a);}),_5l=[0,11],_5m=unCStr("Pattern match failure in do expression at canvas.hs:69:3-9"),_5n=unCStr("Pattern match failure in do expression at canvas.hs:70:3-8"),_5o=unCStr("Pattern match failure in do expression at canvas.hs:73:3-18"),_5p=unCStr("Pattern match failure in do expression at canvas.hs:74:3-12"),_5q=unCStr("Loading, please wait..."),_5r=[0,99],_5s=[0,12],_5t=[1,_5s,_B],_5u=function(_5v){return _5v>1?[1,_5s,new T(function(){return _5u(_5v-1|0);})]:E(_5t);},_5w=new T(function(){return _5u(100);}),_5x=function(_){var _5y=newArr(100,_56),_=(function(_5z,_5A,_){while(1){var _5B=E(_5z);if(_5B==100){return E(_);}else{var _5C=E(_5A);if(!_5C[0]){return E(_);}else{_5y[_5B]=_5C[1];_5z=_5B+1|0;_5A=_5C[2];continue;}}}})(0,_5w,_),_5D=_5y;return [0,E(_57),E(_5r),100,_5D];},_5E=new T(function(){return _5h(_5x);}),_5F=[0,10],_5G=[0,_5F,_5F],_5H=[0,_57,_57],_5I=unCStr("tileset.png"),_5J=unCStr("tiles"),_5K=unCStr("canvas"),_5L=function(_5M,_5N,_5O){return _1z(_Z,[0,_5N,_5O],[0,_5M],_1E);},_5P=[0,41],_5Q=[1,_5P,_B],_5R=function(_5S,_5T){return err(unAppCStr("Error in array index; ",new T(function(){return _m(_w(0,_5S,_B),new T(function(){return unAppCStr(" not in range [0..",new T(function(){return _m(_w(0,_5T,_B),_5Q);}));}));})));},_5U=new T(function(){return [0,"load"];}),_5V=new T(function(){return [0,"click"];}),_5W=function(_){var _5X=jsFind(toJSStr(E(_5K))),_5Y=E(_5X);if(!_5Y[0]){return _4h(_5m,_);}else{var _5Z=E(_5Y[1])[1],_60=jsHasCtx2D(_5Z);if(!E(_60)){return _4h(_5n,_);}else{var _61=jsGetCtx2D(_5Z),_62=jsFind(toJSStr(E(_5J))),_63=E(_62);if(!_63[0]){return _4h(_5o,_);}else{var _64=E(_63[1])[1],_65=jsHasCtx2D(_64),_66=function(_,_67){var _68=E(_67);if(!_68[0]){return _4h(_5p,_);}else{var _69=_68[1],_6a=A(_a,[_8,_5I,_]),_6b=nMV([0,[0,_5E,_6a,_5G],_5H]),_6c=E(_5V)[1];jsSetCB(_64,_6c,function(_6d,_6e,_){var _6f=E(_6e),_6g=rMV(_6b),_=wMV(_6b,new T(function(){return [0,E(_6g)[1],[0,new T(function(){return [0,quot(E(_6f[1])[1],32)];}),new T(function(){return [0,quot(E(_6f[2])[1],32)];})]];})),_6h=rMV(_6b),_6i=E(_69),_6j=E(_6h);return _4E(_5k,_6a,11,_5l,_6i[1],E(_6i[2])[1],[0,[0,_61],[0,_5Z]],_6j[1],_6j[2],_);});jsSetCB(_5Z,_6c,function(_6k,_6l,_){var _6m=E(_6l),_6n=rMV(_6b),_6o=E(_6n),_6p=_6o[2],_6q=E(_6o[1]),_6r=E(_6q[3]),_6s=E(_6q[1]),_6t=_6s[3],_6u=E(_6s[1]),_6v=_6u[1],_6w=E(_6s[2]),_6x=newArr(_6t,_56),_=(function(_6y,_){while(1){if(_6y!=_6t){_6x[_6y]=_6s[4][_6y];var _6z=_6y+1|0;_6y=_6z;continue;}else{return E(_);}}})(0,_),_6A=(imul(quot(E(_6m[2])[1],32),E(_6r[1])[1])|0)+quot(E(_6m[1])[1],32)|0;if(_6v>_6A){return _5L(_6A,_6u,_6w);}else{if(_6A>_6w[1]){return _5L(_6A,_6u,_6w);}else{var _6B=_6A-_6v|0;if(0>_6B){return _5R(_6B,_6t);}else{if(_6B>=_6t){return _5R(_6B,_6t);}else{var _=_6x[_6B]=new T(function(){var _6C=E(_6p);return [0,(imul(E(_6C[2])[1],11)|0)+E(_6C[1])[1]|0];}),_6D=newArr(_6t,_56),_=(function(_6E,_){while(1){if(_6E!=_6t){var _6F=_6x[_6E];_6D[_6E]=_6F;var _6G=_6E+1|0;_6E=_6G;continue;}else{return E(_);}}})(0,_),_6H=_6D,_6I=[0,[0,E(_6u),E(_6w),_6t,_6H],_6q[2],_6r],_=wMV(_6b,[0,_6I,_6p]),_6J=E(_69);return _4E(_5k,_6a,11,_5l,_6J[1],E(_6J[2])[1],[0,[0,_61],[0,_5Z]],_6I,_6p,_);}}}}});jsResetCanvas(_5Z);jsDrawText(_61,toJSStr(E(_5q)),110,120);jsSetCB(E(_6a)[1],E(_5U)[1],function(_){var _6K=rMV(_6b),_6L=E(_69),_6M=E(_6K);return _4E(_5k,_6a,11,_5l,_6L[1],E(_6L[2])[1],[0,[0,_61],[0,_5Z]],_6M[1],_6M[2],_);});return _2;}};if(!E(_65)){return _66(_,_4b);}else{var _6N=jsGetCtx2D(_64);return _66(_,[1,[0,[0,_6N],[0,_64]]]);}}}}},_6O=function(_){return _5W(_);};
var hasteMain = function() {A(_6O, [0]);};window.onload = hasteMain;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment