var app,NekNek;NekNek=new function(){var B,A=this;A.UniqueP=function(C){var E,D;for(E=0;E<C.length;E++){for(D=E+1;D<C.length;D++){if(C[E]==C[D]){return false}}}return true};A.Constraint=function(D,E,C){if(!A.UniqueP(C)){throw new Error("Duplicate cells in constraint: "+E+"/"+C)}this.type=D;this.value=parseInt(E);this.cells=C.slice();this.cells.sort()};B=A.Constraint.prototype;B.print_lut={"+":"+","-":"-","*":"x","/":"\u00f7","!":"=","?":""};B.Copy=function(){return new A.Constraint(this.type,this.value,this.cells)};B.Print=function(D){var C=isNaN(this.value)?"???":this.value+this.print_lut[this.type];if(D){return C+" constraint for cell(s) ["+this.cells.join(",")+"]"}else{return C}};A.Puzzle=function(C){this.size=0;this.cages=[];if(C){this.Load(C)}};B=A.Puzzle.prototype;B.fmtError=new Error('Puzzle definitions must begin with a size ("#") line');B.Load=function(G){var F,D,E,C=G.split("\r\n");E=C[0].split(/\s/);if(E[0]!="#"){throw A.Puzzle.prototype.fmtError}this.size=parseInt(E[1]);for(F=1;F<C.length;F++){D=C[F].split(/\s/);this.cages.push(new A.Constraint(D[0],D[1],D.slice(2)))}};A.Board=function(C){if(C){this.Load(C)}};B=A.Board.prototype;B.MakeName=function(D,E){var C=this.codeLut[D];if(C){return C[E]}};B.MakeCode=function(C){return this.nameLut[C]};B.Load=function(H){this.size=H.size;this.rows="ABCDEFGHI".slice(0,H.size);this.cols="123456789".slice(0,H.size);this.codeLut=[];this.nameLut={};this.d_cells={};this.d_descs={};var G,F,D,E,C;for(G=0;G<H.cages.length;G++){D=H.cages[G].Copy();for(F=0;F<D.cells.length;F++){this.d_cells[D.cells[F]]=D}}for(G=0;G<this.rows.length;G++){this.codeLut.push(C=[]);for(F=0;F<this.cols.length;F++){E=this.rows.charAt(G)+this.cols.charAt(F);C.push(E);this.nameLut[E]=[G,F];if(!this.d_cells[E]){this.d_cells[E]=new A.Constraint("!",NaN,[E])}}}};B.Describe=function(G,K){var H,C,J,E,F,D,I,L=[];if(K==undefined){K=[];for(C=0;C<this.rows.length;C++){for(J=0;J<this.cols.length;J++){K.push(this.MakeName(C,J))}}}for(H=0;H<K.length;H++){E=K[H];F=this.MakeCode(E);C=F[0];J=F[1];D=this.d_cells[E];I=(E==D.cells[0])?32:0;if(this.d_cells[this.MakeName(C-1,J)]!=D){I+=16}if(this.d_cells[this.MakeName(C,J+1)]!=D){I+=8}if(this.d_cells[this.MakeName(C+1,J)]!=D){I+=4}if(this.d_cells[this.MakeName(C,J-1)]!=D){I+=2}if(G==D){I+=1}if(this.d_descs[E]!=I){this.d_descs[E]=I;L.push({r:C,c:J,name:E,cage:D,desc:I})}}return L};B.ParseSolution=function(F){var E,D,C=0,G={};for(E=0;E<this.rows.length;E++){for(D=0;D<this.cols.length;D++){G[this.MakeName(E,D)]=F[C++]}}return G}}();function App(C,A,B){this.label=undefined;this.board=new NekNek.Board();this.solution=undefined;this.n_hints=0;this.active=undefined;this.hintMode=false;connect("hint","onclick",this.MakeHintHook());connect("check","onclick",this.MakeCheckHook());connect("solve","onclick",this.MakeSolveHook());connect(document,"onkeydown",this,this.HandleKeyboard);this.Load(C,A,B)}App.prototype.MakeSolveHook=function(){var A=this;return function(){A.RenderSolution()}};App.prototype.MakeCheckHook=function(){var A=this;return function(){A.CheckSolution()}};App.prototype.MakeHintHook=function(){var A=this;return function(){alert("Please click a cell to reveal its value");A.hintMode=true}};App.prototype.MakeBoardHook=function(A){var B=this;return function(){if(B.hintMode){B.PostHint(A);B.hintMode=false}}};App.prototype.HandleKeyboard=function(E){var D,B,F=0,A=0,C=this.board.size;switch(E.key().string){case"KEY_ARROW_UP":F=-1;E.stop();break;case"KEY_ARROW_RIGHT":A=1;E.stop();break;case"KEY_ARROW_DOWN":F=1;E.stop();break;case"KEY_ARROW_LEFT":A=-1;E.stop();break;default:return ;break}if(this.active){D=this.board.MakeCode(this.active);B=this.board.MakeName((D[0]+C+F)%C,(D[1]+C+A)%C)}else{B="A1"}signal(document.getElementById("cell_"+B),"onclick",{})};App.prototype.HandleGuess=function(B){var A=B.key().string;if((A==" ")||((A>="0")&&(A<="9"))){this.value=""}};App.prototype.Load=function(C,B,A){this.label=A;this.board.Load(new NekNek.Puzzle(C));this.solution=this.board.ParseSolution(B);this.n_hints=0;this.active=undefined;this.hintMode=false;document.getElementById("title").innerHTML=A.spc?"Special":[A.gen,A.size,A.id].join("-");this.RenderBoard(this.board.Describe(undefined));signal(document.getElementById("cell_A1"),"onclick",{})};App.prototype.CheckSolution=function(){var A,F,K,D,G,B,H,I,J,E,C;K=this.solution;D=this.board.size;G=document.getElementById("test_div");B=G.firstChild.firstChild.childNodes;J=false;E=false;for(A=0;A<D;A++){H=B[A+1].childNodes;for(F=0;F<D;F++){I=H[F+1];if(I.childNodes[1].value.length==0){J=true}else{if(I.childNodes[1].value!=K[this.board.MakeName(A,F)]){E=true}}}}if(J){if(E){alert("This solution is incomplete; also, some of the entered values are incorrect.");return }else{alert("This solution is incomplete, but all of the values entered so far are correct.");return }}else{if(E){alert("This solution is incorrect.");return }}if(this.n_hints<0){C="This puzzle has been solved (but you peeked at the solution)."}else{if(this.n_hints>0){C="This puzzle has been solved (but you saw "+this.n_hints+" hints)."}else{C="Congratulations; you have solved this puzzle."}}if(confirm(C+"\nWould you like to try another?")){window.location.href=window.nxt}};App.prototype.PostHint=function(A){if(this.n_hints>=0){this.n_hints++}document.getElementById("cell_"+A).childNodes[1].value=this.solution[A]};App.prototype.RenderSolution=function(){var E,H,C,G,B,D,F,A;C=this.solution;G=this.board.size;B=document.getElementById("test_div");D=B.firstChild.firstChild.childNodes;this.n_hints=-1;for(E=0;E<G;E++){F=D[E+1].childNodes;for(H=0;H<G;H++){A=F[H+1];if(C){A.childNodes[1].value=C[this.board.MakeName(E,H)]}else{A.childNodes[1].value=""}}}};App.prototype.CellFocus=function(A){this.active=A;if(this.active){this.SwitchHighlight(this.active,1)}};App.prototype.CellBlur=function(A){if(this.active==A){this.active=undefined}if(A){this.SwitchHighlight(A,0)}};App.prototype.SwitchHighlight=function(C,B){var A=document.getElementById("cell_"+C);A.className=A.className.replace(" active","");if(B){A.className+=" active"}};App.prototype.MakeCell=function(D){var A,C,B;A=document.createElement("TD");A.id="cell_"+D.name;A.className="board_cell";connect(A,"onclick",this.MakeBoardHook(D.name));connect(A,"onclick",function(E){B.focus()});A.style.borderTopColor=D.desc&16?"black":"#ddd";A.style.borderTopStyle=D.desc&16?"solid":"dotted";A.style.borderRightColor=D.desc&8?"black":"#ddd";A.style.borderRightStyle=D.desc&8?"solid":"dotted";A.style.borderBottomColor=D.desc&4?"black":"#ddd";A.style.borderBottomStyle=D.desc&4?"solid":"dotted";A.style.borderLeftColor=D.desc&2?"black":"#ddd";A.style.borderLeftStyle=D.desc&2?"solid":"dotted";if(D.name==this.active){A.className+=" active"}C=A.appendChild(document.createElement("P"));B=(D.desc&32)?D.cage.Print():"\u00a0";C.appendChild(document.createElement("SPAN"));C.firstChild.appendChild(document.createTextNode(B));C.className="cage_header";B=A.appendChild(document.createElement("INPUT"));B.setAttribute("maxlength","1");B.className="cell_data";B.type="text";connect(B,"onblur",this,function(E){this.CellBlur(D.name)});connect(B,"onfocus",this,function(E){this.CellFocus(D.name)});connect(B,"onkeypress",this.HandleGuess);return A};App.prototype.RenderBoard=function(G){var C,J,F,I,H,A,E,D,B=0;C=document.createElement("TBODY");J=this.board.rows;F=this.board.cols;I=C.appendChild(document.createElement("TR"));I.appendChild(document.createElement("TD"));for(E=0;E<F.length;E++){H=I.appendChild(document.createElement("TD"));H.className="board_header";H.appendChild(document.createTextNode(F.charAt(E)))}for(A=0;A<J.length;A++){I=C.appendChild(document.createElement("TR"));H=I.appendChild(document.createElement("TD"));H.className="board_header";H.appendChild(document.createTextNode(J.charAt(A)));for(E=0;E<F.length;E++){I.appendChild(this.MakeCell(G[B++]))}}D=document.getElementById("test_div");while(D.firstChild){D.removeChild(D.firstChild)}D.appendChild(document.createElement("TABLE")).appendChild(C)};app=new App(window.mpp,window.sol,window.lbl);