Created
January 21, 2014 00:57
-
-
Save bananu7/8532385 to your computer and use it in GitHub Desktop.
Sample Haste compiler output
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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