function Checkpoint(gn,gp,pd){this.board_grid=gn;this.possible_grid=gp;this.solver_mode=pd;}
State=new function(){this.FULLSET=(1<<(DIM+1))-1;this.BOXES=[0,0,0,1,1,1,2,2,2];this.create_grid=function(){var g=new Array(DIM);for(var i=0;i<DIM;i++)g[i]=[0,0,0,0,0,0,0,0,0];return g;}
;this.grid_to_string=function(g,hp){var qn="";for(var i=0;i<DIM;i++)qn+=g[i].join("");if(hp)qn.replace("0"," ");return qn;}
this.init=function(ip,jd,hn){this.tag=hn;this.is_incorrect=false;this.coloring=0;this.emph_low=[];this.state_changed_callbacks=[];this.disable_state_changed_callbacks=false;this.emph_high=[];var jp=['solution_grid','constraints_grid','board_grid','constants_grid','user_colors_grid','correct_candidates'];for(var a in jp)this[jp[a]]=this.create_grid();this.possible_grid=new Array(DIM);for(var i=0;i<DIM;i++)this.possible_grid[i]=this.possible_grid_default();for(var j=0;j<ip.length;j++){var qf=Math.floor(j/DIM);this.board_grid[qf][j%DIM]=ip.charAt(j)*1;this.constants_grid[qf][j%DIM]=ip.charAt(j)*1;this.solution_grid[qf][j%DIM]=jd.charAt(j)*1;}
this.compute_constraints();this.correct_checkpoint=new Checkpoint(null,null,0);this.user_checkpoints=[];}
;this.get_tag=function(){return this.tag;}
this.possible_grid_default=function(){if(sd==SIMPLE)return[0,0,0,0,0,0,0,0,0];else{var a=this.FULLSET;return[a,a,a,a,a,a,a,a,a];}
}
;this.state_changed=function(x,y){if(this.disable_state_changed_callbacks)return;for(var i in this.state_changed_callbacks){this.state_changed_callbacks[i](x,y);}
}
;this.reset_possibles=function(){for(var i=0;i<DIM;i++){this.possible_grid[i]=this.possible_grid_default();}
}
;this.has_won=function(){for(var i=0;i<DIM;i++){for(var j=0;j<DIM;j++){if(this.board_grid[i][j]==0)return false;}
}
this.is_incorrect=false;return true;}
;this.is_number=function(r,c){return(this.board_grid[r][c]!=0);}
;this.is_constant=function(r,c){return(this.constants_grid[r][c]!=0);}
;this.get_number=function(r,c){return this.board_grid[r][c];}
;this.solution=function(r,c){return this.solution_grid[r][c];}
;this.grid_copy=function(kp){var qn=new Array(DIM);for(var i=0;i<DIM;i++)qn[i]=kp[i].concat();return qn;}
;this.tally_number_counts=function(){var zn=new Array(DIM+1);for(var k=0;k<DIM+1;k++)zn[k]=0;for(var i=0;i<DIM;i++){for(var j=0;j<DIM;j++){zn[this.board_grid[i][j]]++;}
}
return zn;}
;this.checkpoint=function(lp){var c=new Checkpoint(this.grid_copy(this.board_grid),this.grid_copy(this.possible_grid),sd);if(lp){this.correct_checkpoint=c;}
else{this.user_checkpoints.push(c);}
}
;this.explicit_checkpoint=function(gn,gp,pd){this.correct_checkpoint=new Checkpoint(gn,gp,pd);this.is_incorrect=true;}
;this.restore_checkpoint=function(c){if(sd!=c.solver_mode)an(c.solver_mode);this.board_grid=this.grid_copy(c.board_grid);this.possible_grid=this.grid_copy(c.possible_grid);this.compute_constraints();ud();this.state_changed(-1,-1);}
;this.undo_to_last_correct=function(){this.possibly_correct();if(!this.is_incorrect)return false;this.restore_checkpoint(this.correct_checkpoint);this.is_incorrect=false;this.correct_checkpoint=new Checkpoint(null,null,0);this.user_checkpoints=[];return true;}
;this.undo_last_user_move=function(){if(this.user_checkpoints.length==0)return false;this.restore_checkpoint(this.user_checkpoints.pop());if(this.is_incorrect){this.possibly_correct();if(!this.is_incorrect)this.correct_checkpoint=new Checkpoint(null,null,0);}
return true;}
this.clear_user_colors=function(){for(var i=0;i<DIM;i++){this.user_colors_grid[i]=[0,0,0,0,0,0,0,0,0];}
}
;this.set_user_color=function(r,c,pc){if(this.user_colors_grid[r][c]==pc)pc=0;this.user_colors_grid[r][c]=pc;}
;this.set_coloring=function(n){if(this.coloring==n)n=0;this.coloring=n;}
;this.get_coloring=function(n){return this.coloring;}
;this.background_color=function(r,c){var pc=C_background;if(this.coloring!=0&&!this.is_number(r,c)&&(this.constraints_allow(r,c,this.coloring))&&(!this.correct_candidates[r][c]||this.is_explicitly_possible(r,c,this.coloring)))pc=C_coloring;if(this.user_colors_grid[r][c])pc=COLORS[this.user_colors_grid[r][c]];var ye=1.0;if(this.emph_high.length>0||this.emph_low.length>0){for(var i=0;i<this.emph_low.length;i++){if(this.emph_low[i][0]==r&&this.emph_low[i][1]==c){ye=0.9;}
}
for(var i=0;i<this.emph_high.length;i++){if(this.emph_high[i][0]==r&&this.emph_high[i][1]==c){ye=0.9;}
}
pc=xe(pc,ye);}
return pc;}
;this.border_color=function(r,c){return this.background_color(r,c);}
this.set_emph=function(mp,np){this.emph_high=mp;this.emph_low=np;}
;this.has_emph=function(){return(this.emph_low.length>0||this.emph_high.length>0);}
;this.abort_incorrect_move=function(op,r,c){if(ug["no_incorrect"]){if(op){setTimeout(function(){if(State.get_number(r,c)!=State.solution(r,c))nd("Incorrect move!");}
,500);}
else{nd("Incorrect move!");}
return true;}
else{if(!this.is_incorrect){this.checkpoint(true);this.is_incorrect=true;}
return false;}
}
;this.possibly_correct=function(){if(this.is_incorrect==false)return;for(var i=0;i<DIM;i++){for(var j=0;j<DIM;j++){if(this.board_grid[i][j]!=0){if(this.board_grid[i][j]!=this.solution_grid[i][j])return;}
else{if(!this.constraints_allow(i,j,this.solution_grid[i][j]))return;}
}
}
this.is_incorrect=false;this.checkpoint(true);}
;this.set_number=function(r,c,n){var pp=this.board_grid[r][c];if(pp==n)return;var qp=this.is_incorrect;if(n!=0&&this.solution(r,c)!=n)if(this.abort_incorrect_move(false))return false;this.board_grid[r][c]=n;this.compute_constraints();if(qp&&(this.solution(r,c)==n||n==0))this.possibly_correct();this.state_changed(-1,-1);return true;}
;this.is_explicitly_possible=function(r,c,n){return((this.possible_grid[r][c]&(1<<(n-1)))!=0);}
;this.no_explicit_possibles=function(r,c){return(this.possible_grid[r][c]==0);}
;this.is_implicitly_possible=function(r,c,n){return((this.constraints_grid[r][c]&(1<<(n-1)))!=0);}
;this.is_visibly_possible=function(r,c,n){return((sd==SIMPLE||this.is_implicitly_possible(r,c,n))&&this.is_explicitly_possible(r,c,n));}
;this.constraints_allow=function(r,c,n){return((sd==SIMPLE||this.is_explicitly_possible(r,c,n))&&this.is_implicitly_possible(r,c,n));}
;this.hinting_possibles=function(r,c,n){if(sd==SIMPLE){if(this.correct_candidates[r][c]){return this.is_explicitly_possible(r,c,n);}
else{return this.constraints_allow(r,c,n);}
}
else{return this.constraints_allow(r,c,n);}
}
this.has_correct_candidates=function(r,c){return(sd==ADVANCED||this.correct_candidates[r][c]);}
this.constraint_conflict=function(r,c,n){for(var i=0;i<DIM;i++){if(this.get_number(r,i)==n)return"row";else if(this.get_number(i,c)==n)return"column";}
return"box";}
this.set_explicitly_possible=function(r,c,n){var qp=this.is_incorrect;if(!this.is_implicitly_possible(r,c,n)){this.abort_incorrect_move(false);return false;}
this.possible_grid[r][c]|=1<<(n-1);if(qp&&this.solution(r,c)==n)this.possibly_correct();this.state_changed(-1,-1);return true;}
;this.set_explicitly_impossible=function(r,c,n){if(this.solution(r,c)==n){if(this.abort_incorrect_move(true,r,c))return false;}
this.possible_grid[r][c]&=~(1<<(n-1));this.state_changed(-1,-1);return true;}
;this.set_possibles_directly=function(r,c,n){this.possible_grid[r][c]=n;}
;this.get_singleton_possibility=function(r,c){var rp=0;for(var i=1;i<=DIM;i++){if(this.constraints_allow(r,c,i)){if(rp!=0)return 0;rp=i;}
}
return rp;}
;this.is_only_empty_square_in_some_dimension=function(r,c){var qf=true,il=true,jg=true;for(var i=0;i<DIM;i++){if(this.board_grid[r][i]==0&&i!=c)qf=false;if(this.board_grid[i][c]==0&&i!=r)il=false;}
var sp=this.box_coordinates(r,c);for(var tp in sp){var j=sp[tp][0];var k=sp[tp][1];if(this.board_grid[j][k]==0&&(j!=r||k!=c))jg=false;}
return qf||il||jg;}
;this.box_coordinates=function(r,c){var zo=[];var up=this.BOXES[r]*BOX;var vp=this.BOXES[c]*BOX;for(var j=up;j<up+BOX;j++){for(var k=vp;k<vp+BOX;k++){zo.push([j,k]);}
}
return zo;}
;this.get_st00pid_hint=function(){for(var r=0;r<DIM;r++){for(var c=0;c<DIM;c++){if(!this.is_number(r,c)&&this.get_singleton_possibility(r,c)){return[r,c,this.get_singleton_possibility(r,c)];}
}
}
return null;}
;this.get_hinting_possibles_hint=function(){for(var r=0;r<DIM;r++){for(var c=0;c<DIM;c++){if(this.board_grid[r][c]==0&&this.has_correct_candidates(r,c)){if(!this.is_explicitly_possible(r,c,this.solution_grid[r][c]))return[r,c,this.solution_grid[r][c],false];for(var i=0;i<DIM;i++){if(this.possible_grid[r][c]==1<<i){return[r,c,i+1,true];}
}
}
}
}
return null;}
this.compute_constraints=function(){var gb=[0,0,0,0,0,0,0,0,0];var hb=[0,0,0,0,0,0,0,0,0];var i,j;var wp=[[0,0,0],[0,0,0],[0,0,0]];for(i=0;i<DIM;i++){for(j=0;j<DIM;j++){var tg=this.board_grid[i][j];if(tg==0)continue;var cc=1<<(tg-1);gb[i]|=cc;hb[j]|=cc;wp[this.BOXES[i]][this.BOXES[j]]|=cc;}
}
for(i=0;i<DIM;i++){for(j=0;j<DIM;j++){this.constraints_grid[i][j]=~(gb[i]|hb[j]|wp[this.BOXES[i]][this.BOXES[j]]);}
}
}
;}
;