/*

ZVM - the ifvms.js implementation of the Z-Machine
==================================================

Built: 2013-03-31

Copyright (c) 2012 The ifvms.js team
BSD licenced
http://github.com/curiousdannii/ifvms.js

*/
(function(C,l){if(![].indexOf){Array.prototype.indexOf=function(P,O){for(var N=O||0,M=this.length;N<M;N++){if(this[N]==P){return N}}return -1}}var k=function(M,O){for(var N in O){M[N]=O[N]}return M},s=C.console||{log:function(){},info:function(){},warn:function(){}},I=function(M){return M<<16>>16},f=function(M){return M&65535},t=function(P){var O=0,N=P.length,M=[];while(O<N){M[O/2]=P[O++]<<8|P[O++]}return M},c=function(M){return M.replace(/(e\.)?U2S\(([^(]+?)\)/g,"(($2)<<16>>16)").replace(/(e\.)?S2U\(([^(]+?)\)/g,"(($2)&65535)").replace(/([\w.]+)\.getUint8\(([^(]+?)\)/g,"$1[$2]").replace(/([\w.]+)\.getUint16\(([^(]+?)\)/g,"($1[$2]<<8|$1[$2+1])")},d=function(Q,P){var M,O,N=[];for(M in Q){if(P.indexOf(M)>=0){O=/function\s*\(([^(]*)\)\s*\{([\s\S]+)\}/.exec(""+Q[M]);N.push(M+":function("+O[1]+"){"+c(O[2])+"}")}}k(Q,C["eval"]("({"+N.join()+"})"))};var b=0,G=b?function(N){var M=new ArrayBuffer(N),N=new DataView(M);N.buffer=M;return N}:function(M){M=M.slice();return k(M,{data:M,getUint8:function(N){return M[N]},getUint16:function(N){return M[N]<<8|M[N+1]},getBuffer:function(O,N){return M.slice(O,O+N)},getBuffer16:function(O,N){return t(M.slice(O,O+N*2))},setUint8:function(N,O){return M[N]=O&255},setUint16:function(N,O){M[N]=(O>>8)&255;M[N+1]=O&255;return O&65535},setBuffer:function(P,O){var Q=0,N=O.length;while(Q<N){M[Q+P]=O[Q++]}}})};var K=Object.subClass({init:function(M,N){this.e=M;this.v=N},toString:function(){return this.v},U2S:function(){return I(this.v)}}),i=K.subClass({toString:function(){var M=this.v;if(this.indirect){return"e.indirect("+M+")"}if(M==0){return"s.pop()"}if(--M<15){return"l["+M+"]"}return"m.getUint16("+(this.e.globals+(M-15)*2)+")"},store:function(N){var M=this.v;if(this.indirect){return"e.indirect("+M+","+N+")"}if(this.returnval){return"e.variable("+M+","+N+")"}if(M==0){return"s.push("+N+")"}if(--M<15){return"l["+M+"]="+N}return"m.setUint16("+(this.e.globals+(M-15)*2)+","+N+")"},U2S:function(){return"e.U2S("+this+")"}}),h=Object.subClass({init:function(Q,O,R,N,P,M){this.e=Q;this.context=O;this.code=R;this.pc=N;this.labels=[this.pc+"/"+this.code];this.next=P;this.operands=M;if(this.post){this.post()}},toString:function(){return this.label()+(this.func?this.func.apply(this,this.operands):"")},args:function(M){return this.operands.join(M)},label:function(){return"/* "+this.labels.join()+" */ "}}),u=h.subClass({stopper:1}),n=u.subClass({storer:1,post:function(){this.storer=this.operands.pop();this.origfunc=this.func;this.func=this.newfunc},newfunc:function(){return"e.pc="+this.next+";"+this.origfunc.apply(this,arguments)}}),E=Object.subClass({init:function(M,N){this.ops=M||[];this.code=N||"||"},toString:function(){var M=0,N=[],O;while(M<this.ops.length){O=this.ops[M++];N.push(O.func?(O.iftrue?"":"!(")+O.func.apply(O,O.operands)+(O.iftrue?"":")"):O)}return(this.invert?"(!(":"(")+N.join(this.code)+(this.invert?"))":")")}}),F=h.subClass({brancher:1,keyword:"if",post:function(){var M,O,N=this.operands.pop(),P=N[1];this.iftrue=N[0];if(P==0||P==1){M="e.ret("+P+")"}else{P+=this.next-2;this.context.targets.push(P);M="e.pc="+P}this.result=M+"; return";this.offset=P;this.cond=new E([this]);if(this.context.ops.length){O=this.context.ops.pop();if(O.offset==P){this.cond.ops.unshift(O.cond);this.labels=O.labels;this.labels.push(this.pc+"/"+this.code)}else{this.context.ops.push(O)}}},toString:function(){var N=0,M=this.result;if(M instanceof H){M=M+(M.stopper?"; return":"");if(this.result.ops.length>1){M="\n"+M+"\n"}}return this.label()+this.keyword+this.cond+" {"+M+"}"}}),A=F.subClass({storer:1,post:function(){this._super();this.storer=this.operands.pop();this.storer.returnval=1;this.origfunc=this.func;this.func=this.newfunc},newfunc:function(){return this.storer.store(this.origfunc.apply(this,arguments))}}),o=h.subClass({storer:1,post:function(){this.storer=this.operands.pop()},toString:function(){var M=this._super();return this.storer?this.storer.store(M):M}}),z=u.subClass({result:{v:-1},toString:function(){return this.label()+"e.call("+this.operands.shift()+","+this.result.v+","+this.next+",["+this.args()+"])"}}),p=z.subClass({storer:1,post:function(){this.result=this.operands.pop()}}),H=Object.subClass({init:function(N,M){this.e=N;this.pc=M;this.pre=[];this.ops=[];this.post=[];this.targets=[]},toString:function(){return this.pre.join("")+this.ops.join(";")+this.post.join("")}}),B=H.subClass({toString:function(){this.pre.unshift("var l=e.l,m=e.m,s=e.s;\n");return this._super()}}),L=function(N,O,M){var M=M||{};if(O){M.func=O}return N.subClass(M)};var y=IFF.subClass({init:function(N){this._super(N);if(N){if(this.type!="IFZS"){throw new Error("Not a Quetzal savefile")}for(var O=0,M=this.chunks.length;O<M;O++){var P=this.chunks[O].type,Q=this.chunks[O].data;if(P=="CMem"||P=="UMem"){this.memory=Q;this.compressed=(P=="CMem")}else{if(P=="Stks"){this.stacks=Q}else{if(P=="IFhd"){this.release=Q.slice(0,2);this.serial=Q.slice(2,8);this.checksum=Q.slice(8,10);this.pc=Q[10]<<16|Q[11]<<8|Q[12]}}}}}},write:function(){this.type="IFZS";var N=this.pc,M=this.release.concat(this.serial,this.checksum,(N>>16)&255,(N>>8)&255,N&255);this.chunks=[{type:"IFhd",data:M},{type:(this.compressed?"CMem":"UMem"),data:this.memory},{type:"Stks",data:this.stacks}];return this._super()}});var J=(function(){var N={8:8,13:13,27:27,37:131,38:129,39:132,40:130},M=96;while(M<106){N[M]=49+M++}M=112;while(M<124){N[M]=21+M++}return N})(),q=Object.subClass({init:function(R){var S=R.m,P=S.getUint16(52),N=R.extension_table(3),Q=N&&S.getUint8(N++),O=0,M=96;this.e=R;this.maxaddr=S.getUint16(26)*R.addr_multipler;this.make_alphabet(P?S.getBuffer(P,78):this.text_to_zscii("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ \r0123456789.,!?_#'\"/\\-:()",1));this.make_unicode(N?S.getBuffer16(N,Q):this.text_to_zscii(unescape("%E4%F6%FC%C4%D6%DC%DF%BB%AB%EB%EF%FF%CB%CF%E1%E9%ED%F3%FA%FD%C1%C9%CD%D3%DA%DD%E0%E8%EC%F2%F9%C0%C8%CC%D2%D9%E2%EA%EE%F4%FB%C2%CA%CE%D4%DB%E5%C5%F8%D8%E3%F1%F5%C3%D1%D5%E6%C6%E7%C7%FE%F0%DE%D0%A3%u0153%u0152%A1%BF"),1));this.abbreviations=S.getUint16(24);if(this.abbreviations){while(O<M){this.decode(S.getUint16(this.abbreviations+2*O++)*2)}}this.dictionaries={};this.dict=S.getUint16(8);this.parse_dict(this.dict)},make_alphabet:function(N){var O=[[],[],[]],M=0;while(M<78){O[parseInt(M/26)][M%26]=N[M++]}O[2][1]=13;this.alphabets=O},make_unicode:function(P){var O={13:"\n"},M={10:13},N=0;while(N<P.length){O[155+N]=String.fromCharCode(P[N]);M[P[N]]=155+N++}N=32;while(N<127){O[N]=String.fromCharCode(N);M[N]=N++}this.unicode_table=O;this.reverse_unicode_table=M},decode:function(V,N,W){var R=this.e.m,aa=V,M,Q=[],S=0,T,O=0,ab=[],Z=[],P,Y,X,U=0;if(this.e.jit[V]){return this.e.jit[V]}N=N?N+V:this.maxaddr;while(V<N){M=R.getUint16(V);V+=2;Q.push(M>>10&31,M>>5&31,M&31);if(M&32768){break}}while(S<Q.length){T=Q[S++];if(T==0){ab.push(32)}else{if(T<4){ab.push(-1);Z.push(this.decode(R.getUint16(this.abbreviations+2*(32*(T-1)+Q[S++]))*2));P=1}else{if(T<6){O=T}else{if(O==2&&T==6){if(S+1<Q.length){Y=Q[S++]<<5|Q[S++];if(Y<768){ab.push(Y)}else{Y-=767;U+=Y;X=S;S=(S%3)+3;while(Y--){ab.push(-1);Z.push(String.fromCharCode(Q[S]<<10|Q[S+1]<<5|Q[S+2]));Q[S++]=Q[S++]=Q[S++]=32}S=X}}}else{if(T<32){ab.push(this.alphabets[O][T-6])}}}}}O=O<4?0:O-3;if((S%3)==0){S+=U;U=0}}ab=new String(this.zscii_to_text(ab,Z));ab.pc=V;if(!P&&aa>=this.e.staticmem){this.e.jit[aa]=ab}return ab},encode:function(R){var S=this.alphabets,Q=[],P=0,O,N,M=[];while(Q.length<9){O=R[P++];if(O==32){Q.push(0)}else{if((N=S[0].indexOf(O))>=0){Q.push(N+6)}else{if((N=S[1].indexOf(O))>=0){Q.push(4,N+6)}else{if((N=S[2].indexOf(O))>=0){Q.push(5,N+6)}else{if(N=this.reverse_unicode_table[O]){Q.push(5,6,N>>5,N&31)}else{if(O==l){Q.push(5)}}}}}}}Q.length=9;P=0;while(P<9){M.push(Q[P++]<<2|Q[P]>>3,(Q[P++]&7)<<5|Q[P++])}M[4]|=128;return M},zscii_to_text:function(S,R){var P=0,N=S.length,Q,O=0,M="";while(P<N){Q=S[P++];if(Q==-1){M+=R[O++]}if(Q=this.unicode_table[Q]){M+=Q}}return M},text_to_zscii:function(Q,P){var R=[],N=0,M=Q.length,O;while(N<M){O=Q.charCodeAt(N++);if(!P){O=this.reverse_unicode_table[O]||63}R.push(O)}return R},parse_dict:function(T){var S=this.e.m,M=T,R={},Q,P,O,N,Q=S.getUint8(T++);R.separators=S.getBuffer(T,Q);T+=Q;P=S.getUint8(T++);O=T+2+P*S.getUint16(T);T+=2;while(T<O){R[""+S.getBuffer(T,6)]=T;T+=P}this.dictionaries[M]=R;return R},tokenise:function(Z,Q,Y,W){Y=Y||this.dict;Y=this.dictionaries[Y]||this.parse_dict(Y);var R=this.e.m,S=2,U=S+R.getUint8(Z+1),O,P=Y.separators,M=[],X=[],N=S,T,V=0;while(S<U){O=R.getUint8(Z+S++);if(O==32||P.indexOf(O)>=0){if(M.length){X.push([M,N]);N+=M.length;M=[]}if(O!=32){X.push([[O],N])}N++}else{M.push(O)}}if(M.length){X.push([M,N])}T=Math.min(X.length,R.getUint8(Q));while(V<T){M=Y[""+this.encode(X[V][0])];if(!W||M){R.setUint16(Q+2+V*4,M||0);R.setUint8(Q+4+V*4,X[V][0].length);R.setUint8(Q+5+V*4,X[V][1])}V++}R.setUint8(Q+1,V)},keyinput:function(N){var M=N.charCode,O=N.keyCode;if(J[O]){return J[O]}return this.reverse_unicode_table[M]||63}});var j=(function(O){var P=function(Q,S){for(var R in S){if(S[R]!=O){Q[R]=S[R]}}return Q},N=[65534,65535,0,29,832,957,22944,31775,30624,32767,23254,17969,11627],M=function(Q){var R=Math.round((Q&31)*8.226)<<16|Math.round(((Q&992)>>5)*8.226)<<8|Math.round(((Q&31744)>>10)*8.226);R=R.toString(16);while(R.length<6){R="0"+R}return"#"+R};return Object.subClass({colours:N,init:function(Q,R){this.e=Q;this.buffer="";this.styles={};this.env={fgcolour:Q.env.fgcolour||"#000",bgcolour:Q.env.bgcolour||"#fff"};this.mono=R;this.currentwin=0;this.status=[];Q.orders.push({code:"stream",name:"status"},{code:"stream",name:"main"},{code:"find",name:"main"})},clear_window:function(){this.e.orders.push({code:"clear",name:"main",css:P({},this.styles)})},convert_RGB:function(S){var R=Math.round,T=/(\d+),\s*(\d+),\s*(\d+)|#(\w{1,2})(\w{1,2})(\w{1,2})/.exec(S),Q;if(T[1]){Q=[T[1],T[2],T[3]]}else{Q=[parseInt(T[4],16),parseInt(T[5],16),parseInt(T[6],16)];if(S.length==4){Q=[Q[0]<<4|Q[0],Q[1]<<4|Q[1],Q[2]<<4|Q[2]]}}return R(Q[2]/8.226)<<10|R(Q[1]/8.226)<<5|R(Q[0]/8.226)},erase_line:function(Q){if(Q==1){this.flush();this.status.push({code:"eraseline"})}},erase_window:function(Q){this.flush();if(Q<1){this.clear_window()}if(Q==-1){this.split_window(0)}if(Q==-2||Q==1){this.status.push({code:"clear"})}},flush:function(){var Q;if(this.buffer!=""){Q={code:"stream",css:P({},this.styles),text:this.buffer};if(this.mono){Q.node="tt"}(this.currentwin?this.status:this.e.orders).push(Q);this.buffer=""}},get_cursor:function(Q){this.status.push({code:"get_cursor",addr:Q});this.e.act()},set_colour:function(R,Q){this.set_true_colour(N[R],N[Q])},set_cursor:function(R,Q){this.flush();this.status.push({code:"cursor",to:[R-1,Q-1]})},set_font:function(Q){if(Q!=1&&Q!=4){return 0}var R=this.mono&4?4:1;if(Q!=R){this.flush();this.mono^=4}return R},set_style:function(S){var T=this.styles;var R;var Q;this.flush();if(S==0){R=this.reverse;this.reverse=T["font-weight"]=T["font-style"]=O;this.mono&=254}if(S&1){R=!this.reverse;this.reverse=1}if(S&2){T["font-weight"]="bold"}if(S&4){T["font-style"]="italic"}if(S&8){this.mono|=1}if(R){Q=T.color||this.env.fgcolour;T.color=T["background-color"]||this.env.bgcolour;T["background-color"]=Q}},set_true_colour:function(U,S){var T=this.styles,V=T.color,R=T["background-color"];var Q;this.flush();if(this.reverse){Q=U;U=S;S=Q}if(U==65535){V=O}else{if(U<32768){V=M(U)}}if(S==65535){R=O}else{if(S<32768){R=M(S)}}if(this.reverse){V=V||this.env.bgcolour;R=R||this.env.fgcolour}T.color=V;T["background-color"]=R},set_window:function(Q){this.flush();this.currentwin=Q;this.e.orders.push({code:"find",name:Q?"status":"main"});if(Q){this.status.push({code:"cursor",to:[0,0]})}},split_window:function(Q){this.flush();this.status.push({code:"height",lines:Q})}})})();var a=function(M){return""+M},m=L(F,function(){return 1}),r=o.subClass({storer:0,post:function(){var M=this.operands,O=M[0],N=O instanceof i;M[0]=new i(this.e,N?O:O.v);if(N||O.v==0){M[0].indirect=1}this.storer=this.code==142?M.pop():M.shift();if(M.length==0){M.push(new i(this.e,0))}},func:a}),x=h.subClass({func:function(N){var O=N.v-1,M=this.code%2?1:-1;if(N instanceof i||O>14){return"e.incdec("+N+","+M+")"}return(O<0?"e.s[e.s.length-1]=e.S2U(e.s[e.s.length-1]+":("e.l["+O+"]=e.S2U(e.l["+O+"]+"))+M+")"}}),D={1:L(F,function(){return arguments.length==2?this.args("=="):"e.jeq("+this.args()+")"}),2:L(F,function(N,M){return N.U2S()+"<"+M.U2S()}),3:L(F,function(N,M){return N.U2S()+">"+M.U2S()}),4:L(F,function(M,N){return"e.U2S(e.incdec("+M+",-1))<"+N.U2S()}),5:L(F,function(M,N){return"e.U2S(e.incdec("+M+",1))>"+N.U2S()}),6:L(F,function(){return"e.jin("+this.args()+")"}),7:L(F,function(){return"e.test("+this.args()+")"}),8:L(o,function(){return this.args("|")}),9:L(o,function(){return this.args("&")}),10:L(F,function(){return"e.test_attr("+this.args()+")"}),11:L(h,function(){return"e.set_attr("+this.args()+")"}),12:L(h,function(){return"e.clear_attr("+this.args()+")"}),13:r,14:L(h,function(){return"e.insert_obj("+this.args()+")"}),15:L(o,function(N,M){return"m.getUint16(e.S2U("+N+"+2*"+M.U2S()+"))"}),16:L(o,function(N,M){return"m.getUint8(e.S2U("+N+"+"+M.U2S()+"))"}),17:L(o,function(){return"e.get_prop("+this.args()+")"}),18:L(o,function(){return"e.find_prop("+this.args()+")"}),19:L(o,function(){return"e.find_prop("+this.args(",0,")+")"}),20:L(o,function(){return"e.S2U("+this.args("+")+")"}),21:L(o,function(){return"e.S2U("+this.args("-")+")"}),22:L(o,function(){return"e.S2U("+this.args("*")+")"}),23:L(o,function(N,M){return"e.S2U(parseInt("+N.U2S()+"/"+M.U2S()+"))"}),24:L(o,function(N,M){return"e.S2U("+N.U2S()+"%"+M.U2S()+")"}),25:p,26:z,27:L(h,function(){return"e.ui.set_colour("+this.args()+")"}),28:L(u,function(N,M){return"while(e.call_stack.length>"+M+"){e.call_stack.shift()}e.ret("+N+")"}),128:L(F,function(M){return M+"==0"}),129:L(A,function(M){return"e.get_sibling("+M+")"}),130:L(A,function(M){return"e.get_child("+M+")"}),131:L(o,function(M){return"e.get_parent("+M+")"}),132:L(o,function(M){return"e.get_prop_len("+M+")"}),133:x,134:x,135:L(h,function(M){return"e.print_addr("+M+")"}),136:p,137:L(h,function(M){return"e.remove_obj("+M+")"}),138:L(h,function(M){return"e.print_obj("+M+")"}),139:L(u,function(M){return"e.ret("+M+")"}),140:L(u,function(M){return"e.pc="+M.U2S()+"+"+(this.next-2)}),141:L(h,function(M){return"e.print_addr("+M+"*"+this.e.addr_multipler+")"}),142:r.subClass({storer:1}),143:z,176:L(u,function(){return"e.ret(1)"}),177:L(u,function(){return"e.ret(0)"}),178:L(h,function(M){return"e.print_addr("+M+")"},{printer:1}),179:L(u,function(M){return"e.print_addr("+M+");e.ret(1)"},{printer:1}),180:h,183:L(u,function(){return'e.act("restart")'}),184:L(u,function(M){return"e.ret("+M+")"},{post:function(){this.operands.push(new i(this.e,0))}}),185:L(o,function(){return"e.call_stack.length"}),186:L(u,function(){return'e.act("quit")'}),187:L(h,function(){return'e.print("\\n")'}),189:m,191:m,224:p,225:L(h,function(O,M,N){return"m.setUint16(e.S2U("+O+"+2*"+M.U2S()+"),"+N+")"}),226:L(h,function(O,M,N){return"m.setUint8(e.S2U("+O+"+"+M.U2S()+"),"+N+")"}),227:L(h,function(){return"e.put_prop("+this.args()+")"}),228:L(n,function(){return"e.read("+this.args()+","+this.storer.v+")"}),229:L(h,function(M){return"e.print(e.text.zscii_to_text(["+M+"]))"}),230:L(h,function(M){return"e.print("+M.U2S()+")"}),231:L(o,function(M){return"e.random("+M.U2S()+")"}),232:L(o,a,{post:function(){this.storer=new i(this.e,0)},storer:0}),233:r,234:L(h,function(M){return"e.ui.split_window("+M+")"}),235:L(h,function(M){return"e.ui.set_window("+M+")"}),236:p,237:L(h,function(M){return"e.ui.erase_window("+M.U2S()+")"}),238:L(h,function(M){return"e.ui.erase_line("+M+")"}),239:L(h,function(){return"e.ui.set_cursor("+this.args()+")"}),240:L(n,function(M){return"e.ui.get_cursor("+M+")"}),241:L(h,function(M){return"e.ui.set_style("+M+")"}),242:h,243:L(h,function(){return"e.output_stream("+this.args()+")"}),244:h,245:h,246:L(n,function(){return"e.read_char("+(this.args()||"1")+","+this.storer.v+")"}),247:L(A,function(){return"e.scan_table("+this.args()+")"}),248:L(o,function(M){return"e.S2U(~"+M+")"}),249:z,250:z,251:L(h,function(){return"e.text.tokenise("+this.args()+")"}),252:L(h,function(){return"e.encode_text("+this.args()+")"}),253:L(h,function(){return"e.copy_table("+this.args()+")"}),254:L(h,function(){return"e.print_table("+this.args()+")"}),255:L(F,function(M){return M+"<=e.call_stack[0][4]"}),1000:L(n,function(){return"e.save("+(this.next-1)+","+this.storer.v+")"}),1001:L(n,function(){return'e.act("restore",{storer:'+this.storer.v+"})"}),1002:L(o,function(N,M){return"e.S2U(e.log_shift("+N+","+M.U2S()+"))"}),1003:L(o,function(N,M){return"e.S2U(e.art_shift("+N.U2S()+","+M.U2S()+"))"}),1004:L(o,function(M){return"e.ui.set_font("+M+")"}),1009:L(o,function(){return"e.save_undo("+this.next+","+this.storer.v+")"}),1010:L(h,function(){return"if(e.restore_undo())return"},{storer:1}),1011:L(h,function(M){return"e.print(String.fromCharCode("+M+"))"}),1012:L(o,function(){return 3}),1013:L(h,function(){return"e.ui.set_true_colour("+this.args()+")"}),1014:h.subClass({brancher:1}),1030:L(o,function(){return"e.gestalt("+this.args()+")"})};var v=function(Q,O){var P=0,M,T,N,S,R;while(P<Q.ops.length-1){if(Q.ops[P].offset==O){if(Q.ops.length-P==2&&Q.ops[P+1].offset){S=Q.ops.pop();R=Q.ops.pop();R.cond.invert=!R.cond.invert;S.cond=new E([R.cond,S.cond],"&&");S.labels=R.labels.concat(S.labels);Q.ops.push(S);return 1}M=new H(Q.e,Q.ops[P+1].pc);M.ops=Q.ops.slice(P+1);T=M.ops.length-1;Q.ops.length=P+1;N=Q.ops[P];N.result=M;N.cond.invert=!N.cond.invert;S=M.ops[T];if(S.code==140&&(I(S.operands[0].v)+S.next-2)==N.pc){N.keyword="while";M.ops.pop()}else{M.stopper=S.stopper}return 1}P++}},w=function(M){};var e=function(R){var S,O,P=R.m,U,N,T,V,Q,M=new B(R,R.pc);while(1){O=S=R.pc;N=P.getUint8(S++);if(N==190){V=-1;N=P.getUint8(S++)+1000}else{if(N&128){if(N&64){V=-1;if(!(N&32)){N&=31}}else{V=[(N&48)>>4];if(V[0]<3){N&=207}}}else{V=[N&64?2:1,N&32?2:1];N&=31}}if(!D[N]){R.stop=1;throw new Error("Unknown opcode #"+N+" at pc="+O)}T=D[N].prototype;if(V==-1){V=[];g(P.getUint8(S++),V);if(N==236||N==250){g(P.getUint8(S++),V)}}Q=[];U=0;while(U<V.length){if(V[U]==0){Q.push(new K(R,P.getUint16(S)));S+=2}if(V[U]==1){Q.push(new K(R,P.getUint8(S++)))}if(V[U++]==2){Q.push(new i(R,P.getUint8(S++)))}}if(T.storer){Q.push(new i(R,P.getUint8(S++)))}if(T.brancher){U=P.getUint8(S++);Q.push([U&128,U&64?U&63:(U<<8|P.getUint8(S++))<<18>>18])}if(T.printer){U=R.text.decode(S);Q.push(S);S=U.pc}R.pc=S;M.ops.push(new D[N](R,M,N,O,S,Q));U=0;if(M.targets.indexOf(S)>=0){U=v(M,S)}if(T.stopper&&!U){break}}return M},g=function(N,O){for(var M=0;M<4;M++){O.push((N&192)>>6);N<<=2}};C.ZVM=Object.subClass({art_shift:function(N,M){return M>0?N<<M:N>>-M},call:function(T,M,Q,O){var P,N,S=this.l.length,R=O.length;this.pc=T*this.addr_multipler;N=this.m.getUint8(this.pc++);O=O.slice(0,N);for(P=O.length;P<N;P++){O.push(0)}this.l=O.concat(this.l);this.call_stack.unshift([Q,M,N,this.s.length,R,S])},clear_attr:function(M,N){var O=this.objects+14*M+parseInt(N/8);this.m.setUint8(O,this.m.getUint8(O)&~(128>>N%8))},copy_table:function(P,M,O){O=I(O);var R=this.m,N=0,Q=O<0;O=Math.abs(O);if(M==0){while(N<O){R.setUint8(P+N++,0)}return}if(Q){while(N<O){R.setUint8(M+N,R.getUint8(P+N++))}}else{R.setBuffer(M,R.getBuffer(P,O))}},encode_text:function(N,M,P,O){this.m.setBuffer(O,this.text.encode(this.m.getBuffer(N+P,M)))},extension_table:function(N,M){var O=this.extension;if(!O||N>this.extension_count){return 0}O+=2*N;if(M==l){return this.m.getUint16(O)}this.e.setUint16(O,M)},find_prop:function(M,Q,P){var T=this.m,S,R,O=0,N=T.getUint16(this.objects+14*M+12);N+=T.getUint8(N)*2+1;while(1){S=T.getUint8(N);R=S&63;if(O==P){return R}if(R==Q){return N+(S&128?2:1)}if(R<Q){return 0}O=R;if(S&128){R=T.getUint8(N+1)&63;N+=R?R+2:66}else{N+=S&64?3:2}}},gestalt:function(N,M){switch(N){case 1:return 258;case 8192:return 1;case 8193:case 8194:return 2}return 0},get_child:function(M){return this.m.getUint16(this.objects+14*M+10)},get_sibling:function(M){return this.m.getUint16(this.objects+14*M+8)},get_parent:function(M){return this.m.getUint16(this.objects+14*M+6)},get_prop:function(M,N){var P=this.m,O=this.find_prop(M,N);if(O){return(P.getUint8(O-1)&64?P.getUint16:P.getUint8)(O)}return P.getUint16(this.properties+2*(N-1))},get_prop_len:function(N){if(N==0){return 0}var M=this.m.getUint8(N-1);if(M&128){M&=63;return M==0?64:M}return M&64?2:1},incdec:function(N,P){var M,O;if(N==0){M=f(this.s.pop()+P);this.s.push(M);return M}if(N<16){return this.l[N-1]=f(this.l[N-1]+P)}else{O=this.globals+(N-16)*2;return this.m.setUint16(O,this.m.getUint16(O)+P)}},indirect:function(M,N){if(M==0){if(arguments.length>1){return this.s[this.s.length-1]=N}else{return this.s[this.s.length-1]}}return this.variable(M,N)},insert_obj:function(N,M){this.remove_obj(N);this.set_family(N,M,M,N,N,this.get_child(M))},jeq:function(){var M=1,N;while(M<arguments.length){if(arguments[M++]==arguments[0]){N=1}}return N},jin:function(N,M){return this.get_parent(N)==M},log_shift:function(N,M){return M>0?N<<M:N>>>-M},output_stream:function(O,P){O=I(O);if(O==1){this.streams[0]=1}if(O==-1){this.streams[0]=0}if(O==3){this.streams[2].unshift([P,""])}if(O==-3){var M=this.streams[2].shift(),N=this.text.text_to_zscii(M[1]);this.m.setUint16(M[0],N.length);this.m.setBuffer(M[0]+2,N)}},print:function(N){if(this.streams[2].length){this.streams[2][0][1]+=N}else{if(this.streams[0]){var M=this.m.getUint8(17)&2;if(M!=(this.ui.mono&2)){if(!(this.ui.mono&253)){this.ui.flush()}this.ui.mono^=2}this.ui.buffer+=N}}},print_addr:function(M){this.print(this.jit[M]||this.text.decode(M))},print_obj:function(N){var M=this.m.getUint16(this.objects+14*N+12);this.print(this.text.decode(M+1,this.m.getUint8(M)*2))},print_table:function(Q,O,M,P){M=M||1;P=P||0;var N=0;while(N<M){this.print("\n"+this.text.zscii_to_text(this.m.getBuffer(Q,O)));Q+=O+P;N++}},put_prop:function(M,O,N){var Q=this.m,P=this.find_prop(M,O);(Q.getUint8(P-1)&64?Q.setUint16:Q.setUint8)(P,N)},random:function(M){var N;if(M<1){this.random_state=Math.abs(M);this.random_seq=0;return 0}if(this.random_state==0){return parseInt(Math.random()*M)+1}else{this.random_seq++;if(this.random_seq>this.random_state){this.random_seq=1}return this.random_seq%M}},read:function(Q,P,O,M,N){if(arguments.length==3){N=O;O=M=0}this.act("read",{buffer:Q,parse:P,len:this.m.getUint8(Q),initiallen:this.m.getUint8(Q+1),time:O,routine:M,storer:N})},read_char:function(O,P,M,N){if(arguments.length==2){N=P;P=M=0}this.act("char",{time:P,routine:M,storer:N})},remove_obj:function(Q){var P=this.get_parent(Q),N,O,M;if(P==0){return}N=this.get_child(P);O=this.get_sibling(Q);if(N==Q){this.set_family(Q,0,P,O)}else{while(1){M=this.get_sibling(N);if(M==Q){break}N=M}this.set_family(Q,0,0,0,N,O)}},restore:function(R){var O=new y(R),P=O.memory,T=O.stacks,V=O.pc,W=this.m.getUint8(17),X,S=0,Q=0,U=[],N=[],M;this.m.setBuffer(0,this.data.slice(0,this.staticmem));if(O.compressed){while(S<P.length){X=P[S++];if(X==0){Q+=1+P[S++]}else{this.m.setUint8(Q,X^this.data[Q++])}}}else{this.m.setBuffer(0,P)}this.m.setUint8(17,W);S=6;X=T[S++]<<8|T[S++];M=t(T.slice(S,X));while(S<T.length){U.unshift([T[S++]<<16|T[S++]<<8|T[S++],0,0,M.length,0,N.length]);U[0][1]=T[S]&16?-1:T[S+1];U[0][2]=T[S]&15;S+=2;X=T[S++];while(X){U[0][4]++;X>>=1}X=T[S++]<<8|T[S++];N=t(T.slice(S,S+U[0][2])).concat(N);S+=U[0][2]*2;M=M.concat(t(T.slice(S,X)))}this.call_stack=U;this.l=N;this.s=M;this.update_header();this.variable(this.m.getUint8(V++),2);this.pc=V},restore_undo:function(){if(this.undo.length==0){return 0}var M=this.undo.pop();this.pc=M[0];M[2][17]=this.m.getUint8(17);this.m.setBuffer(0,M[2]);this.l=M[3];this.s=M[4];this.call_stack=M[5];this.variable(M[1],2);return 1},ret:function(M){var O=this.call_stack.shift(),N=O[1];this.pc=O[0];this.l=this.l.slice(this.l.length-O[5]);this.s.length=O[3];if(N>=0){this.variable(N,M)}},save:function(X,aa){var T=this.m,Y=this.s,O=this.l,Q=new y(),S=[],U,R,V,Z=0,W=this.call_stack.reverse(),N,P,M=[0,0,0,0,0,0];Q.release=T.getBuffer(2,2);Q.serial=T.getBuffer(18,6);Q.checksum=T.getBuffer(28,2);Q.pc=X;Q.compressed=1;for(U=0;U<this.staticmem;U++){V=T.getUint8(U)^this.data[U];if(V==0){if(++Z==256){S.push(0,255);Z=0}}else{if(Z){S.push(0,Z-1);Z=0}S.push(V)}}Q.memory=S;M.push(W[0][3]>>8,W[0][3]&255);for(R=0;R<W[0][3];R++){M.push(Y[R]>>8,Y[R]&255)}for(U=0;U<W.length;U++){N=W[U];P=(W[U+1]?W[U+1][3]:Y.length)-N[3];M.push(N[0]>>16,N[0]>>8&255,N[0]&255,N[2]|(N[1]<0?16:0),N[1]<0?0:N[1],(1<<N[4])-1,P>>8,P&255);for(R=O.length-N[5]-N[2];R<O.length-N[5];R++){M.push(O[R]>>8,O[R]&255)}for(R=N[3];R<N[3]+P;R++){M.push(Y[R]>>8,Y[R]&255)}}W.reverse();Q.stacks=M;this.act("save",{data:Q.write(),storer:aa})},save_undo:function(N,M){this.undo.push([N,M,this.m.getBuffer(0,this.staticmem),this.l.slice(),this.s.slice(),this.call_stack.slice()]);return 1},scan_table:function(M,Q,O,N){N=N||130;var P=N&128?this.m.getUint16:this.m.getUint8;N&=127;O=Q+O*N;while(Q<O){if(P(Q)==M){return Q}Q+=N}return 0},set_attr:function(M,N){var O=this.objects+14*M+parseInt(N/8);this.m.setUint8(O,this.m.getUint8(O)|128>>N%8)},set_family:function(O,P,N,R,M,Q){this.m.setUint16(this.objects+14*O+6,P);if(N){this.m.setUint16(this.objects+14*N+10,R)}if(M){this.m.setUint16(this.objects+14*M+8,Q)}},test:function(N,M){return N&M==M},test_attr:function(M,N){return(this.m.getUint8(this.objects+14*M+parseInt(N/8))<<N%8)&128},variable:function(N,O){var M=O!==l;if(N==0){if(M){this.s.push(O)}else{return this.s.pop()}}else{if(N<16){if(M){this.l[N-1]=O}else{return this.l[N-1]}}else{if(M){this.m.setUint16(this.globals+(N-16)*2,O)}else{this.m.getUint16(this.globals+(N-16)*2)}}}return O},U2S:I,S2U:f,init:function(){this.jit={};this.env={width:80};d(this,["find_prop"])},inputEvent:function(O){var P=this.m,N=O.code,M;if(O.env){k(this.env,O.env);if(!N){return}}this.orders=[];if(N=="load"){this.data=O.data;return}if(N=="restart"){this.restart()}if(N=="save"){this.variable(O.storer,O.result||1)}if(N=="restore"){if(!this.m){this.restart()}if(O.data){this.restore(O.data)}else{this.variable(O.storer,0)}}if(N=="read"){this.variable(O.storer,O.terminator);M=O.response;this.print(M+"\n");M=this.text.text_to_zscii(M.toLowerCase());if(M.length>O.len){M=M.slice(0,O.len)}P.setUint8(O.buffer+1,M.length);P.setBuffer(O.buffer+2,M);if(O.parse){this.text.tokenise(O.buffer,O.parse)}}if(N=="char"){this.variable(O.storer,this.text.keyinput(O.response))}if(N=="get_cursor"){P.setUint16(O.addr,O.pos[0]+1);P.setUint16(O.addr+2,O.pos[1]+1)}this.run()},restart:function(){var P=G(this.data),M=P.getUint8(0),N=P.getUint16(10),O=P.getUint16(54);if(M!=5&&M!=8){throw new Error("Unsupported Z-Machine version: "+M)}if(this.m){P.setUint8(17,this.m.getUint8(17))}k(this,{m:P,s:[],l:[],call_stack:[],undo:[],orders:[],streams:[1,0,[],0],version:M,pc:P.getUint16(6),properties:N,objects:N+112,globals:P.getUint16(12),staticmem:P.getUint16(14),extension:O,extension_count:O?P.getUint16(O):0,addr_multipler:M==5?4:8});k(this,{ui:new j(this,P.getUint8(17)&2),text:new q(this)});this.update_header()},update_header:function(){var O=this.m,M=this.env.fgcolour?this.ui.convert_RGB(this.env.fgcolour):65535,N=this.env.bgcolour?this.ui.convert_RGB(this.env.bgcolour):65535;this.random_state=0;O.setUint8(1,29|(this.env.timed?128:0));O.setUint8(17,O.getUint8(17)&87);O.setUint8(32,255);O.setUint8(33,this.env.width);O.setUint16(34,this.env.width);O.setUint16(36,255);O.setUint16(38,257);O.setUint8(44,Math.abs(this.ui.colours.indexOf(N)));O.setUint8(45,Math.abs(this.ui.colours.indexOf(M)));O.setUint16(50,258);this.extension_table(4,0);this.extension_table(5,M);this.extension_table(6,N)},run:function(){var N=new Date,M,O=0;this.stop=0;while(!this.stop){M=this.pc;if(!this.jit[M]){this.compile()}this.jit[M](this);if(++O%50000==0&&((new Date)-N)>5000){this.act("tick");return}}},compile:function(){var M=e(this);this.jit[M.pc]=new Function("e",c(""+M));if(M.pc<this.staticmem){s.warn("Caching a JIT function in dynamic memory: "+M.pc)}},act:function(N,M){var M=M||{};this.ui.flush();if(this.ui.status.length){this.orders.push({code:"stream",to:"status",data:this.ui.status});this.ui.status=[]}M.code=N;this.orders.push(M);this.stop=1;this.outputEvent(this.orders)}})})(this);