function showdiv(w){    var d=(document[w] ? document[w]  : eval(w).style );	d.visibility='visible'}var  BASE=10,MAXINT=2*(Math.pow(2,30)-1)+1 , pstart="[",pend="]";var maxDIGlen=MAXINT.toString().length;var clearansTXT='In the box below, the recurring part of a decimal is shown between '+pstart+' and '+pend     +' brackets: eg\r3/44 = 0.06'+pstart+'81'+pend     +' means 3/44 = 0.06818181...\r';function IgnoreError(){self.onerror=ProcessErrors; return true};function ProcessErrors(){return false};function STOP(){  self.onerror=IgnoreError;  xxhaltxx() };function ERR(xx){ alert(xx);  STOP()};function ERRoverflow(m){ERR('Sorry, I cannot compute the answer because\r'  +'the calculations involve numbers that have become too large!')};function isOK(msg){   if(arguments.length>1)msg=arguments.join('');  if(!confirm(msg))STOP() };function maxdps(w){return getn("ndps",w)[0]};function setmaxdps(w){var fld=document["frac"+w].ndps;  var MAXNDP=getn("ndps",w)[0];  if(isNaN(MAXNDP) || MAXNDP<1)    {fld.value=10;     ERR("Your 'Number of dps' value is not a valid number so I've reset it to "+MAXNDP) }  else if(MAXNDP>1000)         if( ! confirm("Do you really want more than 1,000 decimal places computed?"))            fld.value=1000;};function put(w,X){  var s="";   for(var i=1;i<arguments.length;i++)  s=s+arguments[i];  s=s+"\r";    putmsg(s);};function mul(a,b){if(a==0)return 0  else if((a*b)/a!=b){ERRoverflow(a+" MUL "+b)}else{return a*b}};function add(a,b){if((a+b)-a!=b){ERRoverflow(a+" ADD "+b)}else{return a+b}};function isINT(N,nm){if(typeof N != "string")N=N.toString();  if(N.length>maxDIGlen )        ERR("Sorry - your "+nm+" number "+N+" is too large.\rIt must have no more than "+maxDIGlen+" digits.");  if(N>MAXINT)ERR("Sorry - your "+nm+" number "+N+" is too big.\rThe maximum number I can use is "+MAXINT+".");};function getn(fld,w){    var boxname=(fld=="numer"?"top (numerator)"              :fld=="denom"?"bottom (denominator)"              :fld=="ndps"?"number of decimal places"              :"");  var str=stripspace(eval("document.frac"+w+"."+fld+".value"));  if(str.match(/[^0-9,]/)!=null)    ERR("The "+boxname+" box must only contain digits:\n"+str);  var nbsRAW=str.replace(/\s|,/g,"").match(/\d+/g);   var nbs=nbsRAW;    if(!nbs || typeof nbs!="object" || nbs.length==0)ERR("I didn't find a number in the "+boxname+" input box.\n \nPlease enter a number and try again.");  isINT(nbs[0],boxname); if(nbs[1]){isINT(nbs[1],"")}else{nbs[1]=nbs[0]};  for(var i=0;i<nbs.length;i++)nbs[i]=parseInt(nbs[i],10);  if(nbs.length==2)      {if(nbs[1]<nbs[0])         ERR("The end of the range ("+nbs[1]+") is less that its start ("+nbs[0]+")")}  else if(nbs.length==1)nbs[1]=nbs[0]  else ERR('You have given me '+nbs.length+' numbers in the "+boxname+" box. Please give just 1.');  if(fld=="denom" && nbs[0]<2)ERR("The denominator must be 2 or more");    return nbs  };function getF(w){  return ratsimp(getn("numer",w)[0] ,getn("denom",w)[0] ) } ;function ratsimp(n,d){   if(typeof n=="string")n=parseInt(n,10);    if(typeof d=="string")d=parseInt(d,10);   var g=gcd(n,d);    if(g>1){var ans= {num:Math.round(n/g), den:Math.round(d/g)}}   else var ans= {num:n, den:d} ;   return ans};function top(){return getF().num};function bot(){return getF().den};function newPFs(w){  document["frac"+w].denomPFs.value=ordlistToZbag(primefactors(getF(w).den)); };function nonrecPer(w,N,D){   if(N/D>=1){ERR(N+"/"+D+" is not a proper fraction (it must be < 1)")}  else {var F=ratsimp(N,D);N=F.num;D=F.den;            var p2=0;  while(D%2==0){p2++;D=Math.round(D/2)};        var p5=0;  while(D%5==0){p5++;D=Math.round(D/5)};        var nonrecLen=Math.max(p2,p5);            return [nonrecLen,(D==1 ? 0 : order10(D)) ]       }};function firstdp(N,D){   var p1=Math.floor(10*N/D);  return [p1,10*N-p1*D]};function putdecs(w,N,D,maxnb){    if(arguments.length<4)maxnb=maxdps(w);  var np=nonrecPer(w,N,D);  var nonreclen=np[0], per=np[1],i=0;  if(np.length==0){putrawdecs(w,N,D,maxnb);return};  var dps="0.",R=N,dr;  for(var i=1;i<=Math.min(nonreclen,maxnb);i++)      {dr=firstdp(R,D); dps=dps+dr[0].toString(); R=dr[1] };  if(i>maxnb){dps=dps+"...";return dps};  if(per>0)dps=dps+pstart;  for(var i=nonreclen+1;i<=Math.min(nonreclen+per,maxnb);i++)      {dr=firstdp(R,D);dps=dps+dr[0].toString();R=dr[1] };  if(i<=nonreclen+per)dps=dps+"...";  if(per>0)dps=dps+pend;  return dps};function putrawdecs(w,N,D,maxnb){  if(arguments.length<4)maxnb=maxdps(w);  var dps="0.",R=N,dr;  for(var i=1;R>0 && i<=maxnb;i++)      {dr=firstdp(R,D); dps=dps+dr[0].toString(); R=dr[1] };  if(R>0)dps+="...";  return dps};function doPowMod(w){  var b=getn("numer")[0],pp=getn("denom");  for(p=pp[0];p<=pp[1];p++)put(w,b,"^",p," mod 10 = ",powmod(b,p,10))};function order10(N){   if(N==1)return 1;      var fs=factors(EulerPhi(N)),i=0;    while(powmod(10,fs[i],N)!=1)    {  i++;if(i>fs.length)ERR("ERROR found [overrun in order10].\rPlease email your input numbers to R.Knott@ronknott.com. Thank you.")};  return fs[i]};function doTerminates(w){  var ds=getn("denom",w); var nn=getn("numer",w)[0];    for(var d=ds[0];d<=ds[1];d++)    {var F=ratsimp(nn,d);           var np=nonrecPer(w,F.num,F.den);     put(w,nn,'/',d,(nn==F.num?"":"="+F.num+'/'+F.den),           (np[0]>0           ?(np[1]==0             ?" terminates after "+np[0]+" digit"+(np[0]>1?"s":"")              : " has "+np[0]+" initial digit" +(np[0]>1?"s":"")               +" followed by a period of "+np[1]+" digit"+(np[1]>1?"s":"")             )           :" is purely recurring with a period of "+np[1] +" digit"+(np[1]>1?"s":"")           ),".")     };};function doDecs(w,raw){  var ds=getn("denom",w),nn=getn("numer",w)[0];  for(var d=ds[0];d<=ds[1];d++)     {var F=ratsimp(nn,d);             put(w,F.num,'/',F.den," = ",(raw?putrawdecs:putdecs)(w,F.num,F.den)) }};function stripspace(s){   if(typeof s != "string")s=s.toString();  return s.replace(/\s/g,"")};function nbdigs(n){     if(typeof n!="string")ERR("nbdigs applied to non-string: "+n);    return (n+" ").indexOf(" ")};function decToFrac(w){    var fxd=document["frac"+w].decf.value,  rpt=document["frac"+w].decrpt.value,F;  fxd = stripspace(fxd);  rpt = stripspace(rpt);  if(fxd.match(/[^0-9]/)!=null)      {if(document["frac"+w].decf.value.indexOf(".")!=-1)          ERR("Only give the part of the number AFTER the decimal point (the fractional part).");        else ERR("The fixed part must be only digits")      };  if(rpt.match(/[^0-9]/)!=null)ERR("The repeating part must be only igits");  if(fxd=="" && rpt=="") ERR("To use this button, first type in a decimal number to be converted to a fraction .");  isINT(fxd,"FIXED"); isINT(rpt,"RECURRING");  if(rpt=="") {F=ratsimp(fxd,Math.pow(10, nbdigs(fxd)))}  else { var rexp=nbdigs(rpt),             fexp=nbdigs(fxd);           if(fxd=="")fxd='0';                  F=ratsimp(add(mul(fxd,(Math.pow(10,rexp)-1)),parseInt(rpt,10)),                   mul(Math.pow(10,fexp),(Math.pow(10,rexp)-1)))     };    document["frac"+w].Dnumer.value=F.num;  document["frac"+w].Ddenom.value=F.den;  put(w,"0."+document["frac"+w].decf.value+(document["frac"+w].decrpt.value==""?"":pstart+document["frac"+w].decrpt.value+pend)+"="      +F.num+"/"+F.den);};function clearDecToFrac(w,x){   document["frac"+w].Dnumer.value="";document["frac"+w].Ddenom.value="";  if(arguments.length>1){document["frac"+w].decf.value=""; document["frac"+w].decrpt.value=""}};function selectfrac(w){  if(document["frac"+w].egs.selectedIndex>0)    {var nd=document["frac"+w].egs[document["frac"+w].egs.selectedIndex].value;      var nd="document.frac"+w+".numer.value="+nd.replace(",",";document.frac"+w+".denom.value=");      eval(nd)    }};// -------------------------  Farey Fractions and Stern-Brocot Tree -----------function intdiv(a,b){  // floor(a/b)   return Math.round((a-a%b)/b)};function fnextRAT(r){halt('not implemented!')}var fseq=new Array();function fseqFAREY(maxd){var p; //GLOBAL fseq  fseq[1]=new RAT(1,maxd);  for(var i=2;fseq[i-1].top<fseq[i-1].bot;i++)  { p=intdiv( fseq[i-2].bot+maxd , fseq[i-1].bot );    fseq[i]=new RAT(p*fseq[i-1].top-fseq[i-2].top,                    p*fseq[i-1].bot-fseq[i-2].bot)   //alert(i+"="+fseq[i])}  };function fseqsbtfillin(f1,f2,rowlev,lev){  var f=new RAT(f1.top+f2.top,f1.bot+f2.bot);  if(rowlev==lev){fseq[fseq.length]=f;fseq[fseq.length]=f2;return};  fseqsbtfillin(f1,f,rowlev+1,lev);fseqsbtfillin(f,f2,rowlev+1,lev)};function fseqsbtree(level){  if(level==0){fseq[1]=new RAT(1,1);return};  fseqsbtfillin(new RAT(0,1),new RAT(1,0),1,level);}function ff(maxd,ct,which,disp){var p,q;  //alert("ff "+maxd+" "+which);  if(arguments.length<2)ct=false;  if(arguments.disp<4)disp="n/d";  if(maxd<1 || !isInt(maxd))   {if(which=="farey")         halt('The order (maximum denominator) must be at least 1')    else halt("The level must be a whole number")};  fseq[0]=new RAT(0,1);fseq.length=1;  switch(which){  case "farey":fseqFAREY(maxd);break;  case "sbt":  fseqsbtree(maxd);break;  };  var s=(disp=="top"?"Numerators of ":disp=="bot"?"Denominators of ":"")         +(which=="farey"?"Farey series of order "          :which=="sbt"?"Stern-Brocot tree at level ":"")+maxd+": ";  if(!ct)  { s=s+"<br>";    if(disp=="n/d")s=s+"0/1, "+fseq.slice(1).join(', ')    else {s=s+(disp=="top"?0:1)+", ";        for(var i=1;i<fseq.length-1;i++)s=s+fseq[i][disp]+", ";        s=s+"1"        };        s=s+"<br>"  };  s=s+fseq.length+" fractions";  putmsg(s);};   function LRpath(t,b){ // alert("LR path for "+Rat);  var path="",Lt=0,Lb=1,Mt=1,Mb=1,Rt=1,Rb=0,plen=0;  while(t!=Mt||b!=Mb)  { // if(t*Mb<b*Mt)      if(t/b<Mt/Mb)                  {Rt=Mt;Rb=Mb;path=path+"L"} //RATis(Rat,"<",Med)      else        {Lt=Mt;Lb=Mb;path=path+"R"};    plen++;    Mt=Lt+Rt;Mb=Lb+Rb;   // putmsg(path+": "+Mt+"/"+Mb);    if(! isInt(Mt) || !isInt(Mb) )       {putmsg("!! overflow !!");        halt("The numbers in the fractions have become too large for accurate computation")};    if(plen>500)halt("The path has become too long (>"+500+" in length)");  };  return path};function RATfrompath(LRstr){LRstr=LRstr.toUpperCase();  //alert("Fract for path "+LRstr);  var LRind=0,Lt=0,Lb=1,Mt=1,Mb=1,Rt=1,Rb=0;  while(LRind<LRstr.length)  { if(LRstr.charAt(LRind)=="L")         {Rt=Mt;Rb=Mb;;}    else {Lt=Mt;Lb=Mb};    LRind++;    if( !isInt(Lt+Rt) || !isInt(Lb+Rb) )       halt("The fractions has become too big for this Calculator");        Mt=Lt+Rt;Mb=Lb+Rb;  };  return [Mt,Mb]};
