
//== PARMS & GLOBAL =============================================================
var ie=false;  if(top.navigator.userAgent.toLowerCase().indexOf("msie")>-1)ie=true;
var gKeys=["pinground","tnsna","tnnetwork","tnresponse","httphandshake","httpserver","httpnetwork","http1byte","httprate"];

var speed=160;    if(ie)speed=160;
var stride=40;    if(ie)stride=40;
var padG=0;       if(ie)padG=6;
var gDS=0;        if(ie)gDS=-1;
var gCnt=1;       var timeFudge=1;
var hiSpeed=160;  var dfltSpeed=speed;
var arrowWG=9;    var arrowHG=9;
var bennyWG=11;   var bennyWGsmall=8;
//benny.gif, get*.gif, point*.gif = 8x16;
//run*.gif,  wave*gif, jump*.gif  = 11x16

var lineWG, fieldG, floorG, rowG, ghost, timer, time0, time99, ticker, tickTimer;
var funList=new Array(); var colorsG=new Array();
var showMeList=new Array(); var showMeList2=new Array();

if((ie)&&(window.name!="benny"))top.window.resizeBy(-9,-9);

//== LOAD & INIT =============================================================
timer=window.setInterval("loader()",200);
//--------------------------------------------------------------------------
function loader(){
   if(!document)return;if(!document.body)return;
   if(!document.getElementById("timeFudge1"))return;
   window.clearInterval(timer); timer=false;
   fieldG=document.getElementById("fieldG");
   floorG=document.getElementById("floorG");
   ghost=document.getElementById("ghost");
   document.getElementById("timeFudge1").firstChild.data=timeFudge;
   document.getElementById("timeFudge2").firstChild.data=timeFudge;
   for(c=0;c<gKeys.length;c++){colorsG[gKeys[c]]=readCss("#"+gKeys[c],"color");}
   setWidths();
   fieldG.style.display="block";
   if(window==top)document.getElementById("bnycntrl").style.display="block";
   window.focus();
   setListener(window,"resize",afterResize,true);
   reshow();
}//loader
//--------------------------------------------------------------------------
//at setRow and endRow, IE needs to re-draw
function doResize(mult){
   if(gDS==0)return;
   if(!mult)mult=1;
   var dog=gDS*mult;
   top.resizeBy(dog,dog);
   gDS=0-gDS;
}//doResize
//--------------------------------------------------------------------------
function afterResize(){
   if(rowG)return;
   if(ie){setWidths();return;}
   if(!showMeList)return;
   if(showMeList.length==0)return;
   location.search=showMeList.join(";");
}//afterResize
//--------------------------------------------------------------------------
function reshow(){
   var dog=getSearch(); if(!dog)return;
   dog=dog.split(";");
   showMeList2=new Array();
   var cat, ok;
   while(dog.length>0){
      cat=dog.pop();
      ok=false;
      for(i=0;i<gKeys.length;i++){if(cat==gKeys[i])ok=true;}
      if(ok)showMeList2.push(cat);
      }//while
   dog=showMeList2.pop();
   if(dog)showById(dog);
}//reshow
//----------------------------------------------------
function getSearch(){
   fish=location.search;
   if(!fish)fish=location.hash;
   if(!fish)return null;
   var dog=fish.indexOf("?");
       if(dog>-1)fish=fish.slice(dog+1);
   dog=fish.indexOf("#");
      if(dog>-1)fish=fish.slice(0,dog);
   if(fish=="")return null;
   return fish;
}//getSearch
//--------------------------------------------------------------------------
function setWidths(){
   if(!ghost){loader();return;}
   var dog, fish, imgs, img, cells, cell, blank, line, benny, arrow, wdth;
   blanks=new Array(); lines=new Array(); bennys=new Array();
   lineWG=Math.round((document.body.clientWidth*.94*.24));
   imgs=ghost.getElementsByTagName("img");
       for(i=0;i<imgs.length;i++){imgs[i].style.width=lineWG+"px";}
   imgs=document.getElementById("titleblnk").getElementsByTagName("img");
       for(i=0;i<imgs.length;i++){imgs[i].style.width=lineWG+"px";}
   cells=fieldG.getElementsByTagName("td");
   for(i=0;i<cells.length;i++){
      cell=cells[i];
      imgs=cell.getElementsByTagName("img");
      blank=null; line=null; benny=null; arrow=null;
      for(j=0;j<imgs.length;j++){
         if(imgs[j].style.display!="none"){
            if(imgs[j].className=="blank")blank=imgs[j];
            if(imgs[j].className=="line")  line=imgs[j];
            if(imgs[j].className=="benny")benny=imgs[j];
            if(imgs[j].className=="arrow")arrow=imgs[j];
         }//if displayed
      }//for j
      wdth=null;
         if(benny){if(benny.style){if(benny.style.width)wdth=parseInt(benny.style.width);}}
         if(arrow){if(arrow.style){if(arrow.style.width)wdth=parseInt(arrow.style.width);}}
         if((!wdth)&&(benny))wdth=bennyWG;
         if((!wdth)&&(arrow))wdth=arrowWG;
         if((wdth)&&(benny))wdth=(lineWG-wdth-padG-padG)+"px";
         if((wdth)&&(arrow))wdth=(lineWG-wdth-padG)+"px";
         if(!wdth)wdth="90%";
      if(blank)blank.style.width=lineWG+"px";
      if((!rowG)&&(line))line.style.width=wdth;
   }//for i, @ cell
}//setWidths
//== UTILITIES =============================================================
function show(nd){showById(nd.getAttribute("id"));}
//--------------------------------------------------
function showById(id){
   if(!id)id=""; if(id=="")return true;
   if(rowG)return false;
   var dog=document.getElementById(id);
   if(!dog)return false;
   if(!dog.firstChild)return false;
   if(!dog.firstChild.data)return false;

   reSetTicker();
   showMeList.push(id);
   var clr=readCss("#"+id,"color");
   var title=document.getElementById(id).firstChild.data;
   document.getElementById("title").firstChild.data=title;
   document.getElementById("tickcell").style.visibility="visible";
   document.getElementById("clear").style.visibility="visible";
   //document.getElementById("timenote").style.visibility="visible";
   defaultStatus="speed = "+speed+" msec's/step; stride = "+stride+" pix";
   eval(id+"('"+clr+"');");
}//show
//--------------------------------------------------
function startTicker(){
   ticker=new Date().getTime();
   tickTimer=window.setInterval("setTicker()",500);
   document.getElementById("clock").src="img/clock.gif";
}//startTicker
//--------------------------------------------------
function setTicker(){
   var delta=Math.floor( (new Date().getTime()-ticker)/timeFudge );
   document.getElementById("ticker").firstChild.data=delta;
}//setTicker
//--------------------------------------------------
function reSetTicker(){
   document.getElementById("ticker").firstChild.data=0;
   document.getElementById("clock").src="img/clock0.gif";
}//setTicker
//--------------------------------------------------
function stopTicker(){
   setTicker();
   window.clearInterval(tickTimer);
   document.getElementById("clock").src="img/clock0.gif";
}//stopTicker
//--------------------------------------------------
function bennyClear(){
   if(rowG)return;
   document.getElementById("ticker").firstChild.data="0";
   while(fieldG.firstChild.nextSibling){
      fieldG.removeChild(fieldG.firstChild.nextSibling);
   }//while
   funList=new Array();
   showMeList=new Array();
   location.search=null;
}//clear
//--------------------------------------------------
function readCss(clsid,parm){
   var sheets, rules, rule, selector, val, fish, dog;
   val=null;
   fish=clsid.slice(0,1);
       if((fish!="#")&&(fish!="."))clsid="."+clsid;
   var sheets=document.styleSheets;

   for(i=0;i<sheets.length;i++){
      if(ie) rules=sheets[i].rules;
         if(!ie)rules=sheets[i].cssRules;

      for(j=0;j<rules.length;j++){
         if(!ie)rule=rules[j].cssText;
            if(ie) rule=rules[j].selectorText+"{"+rules[j].style.cssText+"}";
         rule=swap(rule," ","");
         //rule: .field.c3{border-width:0px;width:1px;

         if(rule.indexOf(clsid+"{")>-1){
            rule=rule.slice(rule.indexOf("{")+1);
            rule=rule.slice(0,rule.indexOf("}"));
            rule=";"+rule+";"; rule=swap(rule,";;",";");
            dog=rule.toLowerCase().indexOf(";"+parm.toLowerCase());
            if(dog>-1){
               val=rule.slice(dog+parm.length+2);
               val=val.slice(0,val.indexOf(";"));
               break;
   }}}}//if if for for
   if(val){if(val.indexOf("rgb(")==0)val=rgbToHex(val);}
   return val;
}//readCss
//--------------------------------------------------
function rgbToHex(rgb){
   var dog=rgb.lastIndexOf("rgb");
      if(dog<0)return rgb;
      rgb=rgb.slice(dog+4,-1);
   rgb=rgb.split(",");
   var r=decToHex(rgb[0]);
   var g=decToHex(rgb[1]);
   var b=decToHex(rgb[2]);
   return "#"+r+g+b;
}//rgbToHex
//--------------------------------------------------
function decToHex(nnn){
   var a=Math.floor(nnn/16); a=tenVsA(a);
   var b=nnn%16; b=tenVsA(b);
   return a.toString()+b.toString();
}//dec3Hex(nnn)
//--------------------------------------------------
function tenVsA(n){
   var abc=["a","b","c","d","e","f"];
   var ten=[10,11,12,13,14,15];
   for(i=0;i<6;i++){if(n==ten[i])return abc[i];}
   return n;
}//tenVsA
//--------------------------------------------------
function swap(fish,olds,news){
    var dog=fish.indexOf(olds);
    while(dog>-1){
      fish=fish.slice(0,dog)+news+fish.slice(dog+olds.length);
      dog=fish.indexOf(olds);
      }//while
    return fish;
}//swap
//--------------------------------------
function setListener(elm,act,fun,cap){
   if(document.addEventListener){if(elm.addEventListener){
      elm.addEventListener(act,fun,cap); return;}}
   if (document.attachEvent){if(elm.attachEvent){
      elm.attachEvent("on"+act,fun);return;}}
   eval("elm.on"+act+"="+fun);
}//setListener
//----------------------------------------------------
function getTarget(e){
   var dog;
   if(!e)e=window.event;
   if(e.srcElement)dog=e.srcElement;
   if(e.target)dog=e.target;
   return dog;
}//getTarget

/*===============================================================
colorG = ["pinground","tnsna","tnnetwork","tnresponse","httphandshake","httpserver","http1byte","httprate"];

ping   pinground
tn3270 tnsna         + tnnetwork  = tnresponse
http   httphandshake   httpserver   http1byte  httprate

       tnround         tntrans         tnconnect
       httpround       httptrans       httpconnect
       httpserver    + httpnetwork   = httpresponse
*/

//== ROW OBJECT =============================================================
function Row(lnclr,txtclr){
   var col=3;             var cB4=4;           var cAft=2;
   var sender="client";   var dir="right";     var notdir="left";
   var clr="#999999"; var clrB4="#000000";
       if(lnclr)clr=lnclr; if(txtclr)clrB4=txtclr; clrAft=clrB4;
   var msgB4=null;        var msgAft=null;     var imgAft="arrow";
   var arwClr="#ffffff";  var arwSrc="img/arrowffffffright.gif";
   var time=null; var border=false;
   var id="row"+gCnt; gCnt++;
   var row=ghost.cloneNode(true);
       row.setAttribute("id",id);
   var cell=row.getElementsByTagName("td")[2];
   var line=document.createElement("img");
       line.className="line";
       line.src="img/blank.gif";
       line.style.width="1px";
       line.setAttribute("id",id+"line");
   var benny=document.createElement("img");
       benny.className="benny";
       benny.setAttribute("id",id+"benny");

   this.col=col;       this.cB4=cB4;       this.cAft=cAft;
   this.sender=sender; this.dir=dir;       this.notdir=notdir;
   this.clr=clr;       this.clrB4=clrB4;   this.clrAft=clrAft;
   this.msgB4=msgB4;   this.msgAft=msgAft; this.imgAft=imgAft;
   this.arwClr=arwClr; this.arwSrc=arwSrc; this.time=time;
   this.border=border; this.id=id;
   this.row=row;       this.cell=cell;
   this.line=line;     this.benny=benny;
   this.setRow=setRow; this.endRow=endRow;
   return this;
}//Row

//-------------------------------------------------------
function setRow(){
   if(this.dir=="right"){this.cB4=this.col+1; this.cAft=this.col-1;}
      if(this.dir=="left") {this.cB4=this.col-1; this.cAft=this.col+1;}
   if(this.dir=="left")this.notdir="right";
   this.cell=this.row.getElementsByTagName("td")[this.col-1];
      this.cell.style.textAlign=this.dir;
      this.cell.firstChild.data="";
      this.cell.className="c"+this.col;
   this.arwClr=readCss(".field."+this.cell.className,"background-color");
      this.arwSrc="img/arrow"+this.arwClr.slice(1)+this.dir+".gif";
   if((this.cB4<1)||(this.cB4>4))this.cB4=null;
      if(this.cB4)this.cB4=this.row.getElementsByTagName("td")[this.cB4-1];
   if((this.cAft<1)||(this.cAft>4))this.cAft=null;
      if(this.cAft)this.cAft=this.row.getElementsByTagName("td")[this.cAft-1];
   if((this.msgB4)&&(this.cB4)){
      this.cB4.style.color=this.clrB4;
      this.cB4.style.textAlign=this.notdir;
      this.cB4.firstChild.data=this.msgB4;
      }//if
   this.line.setAttribute("align",this.dir);
      this.line.style.borderColor=this.clr;
      this.line.style.backgroundColor=this.arwClr;
      this.line=this.cell.appendChild(this.line);
   if(this.benny){
      this.benny.src="img/run"+this.dir+"1.gif";
      this.benny=this.cell.appendChild(this.benny);
      }//if
   if(this.border){
      dog=this.row.getElementsByTagName("td");
      for(i=0;i<dog.length;i++)dog[i].style.borderBottomWidth="1px";
      }//if first row in process
   this.row=fieldG.insertBefore(this.row,fieldG.getElementsByTagName("table")[0].nextSibling);
      this.line=document.getElementById(this.id+"line");
     this.benny=document.getElementById(this.id+"benny");
   this.row.style.display="block"
   doResize();
}//setRow
//-------------------------------------------------------
function runRow(tf){
   if(!rowG)return;
   var lineW =parseInt(rowG.line.style.width)+stride;
   var bennyW=padG;
       if(rowG.benny)bennyW=bennyW+parseInt(readCss(".benny","width"));
   if(lineW>=lineWG-bennyW)lineW=lineWG-bennyW;
   rowG.line.style.width=lineW+"px";
   if(rowG.benny){
      var num=rowG.benny.src.slice(-5);
      var src=rowG.benny.src.slice(0,-5);
      if(num=="1.gif")src=src+"2.gif"; else{src=src+"1.gif";}
      rowG.benny.src=src;
      }//if benny
   if((!rowG.benny)||(lineW==lineWG-bennyW)){
      rowG.endRow();
      if(funList.length>0){eval(funList.pop());return;}
      stopTicker();
      doResize();
      if(showMeList2.length>0)showById(showMeList2.pop());
      }//if
   if(rowG)window.setTimeout("runRow()",speed);
}//runRow
//--------------------------------------------------
function endRow(col,txt,dir,clr){
   var dog;
   if(!this.imgAft){
      if(this.benny)this.benny.style.visibility="hidden";
      if(this.line)this.line.style.visibility="hidden";
      }//if no imgAft
   if(this.imgAft=="arrow"){
      this.benny.src=this.arwSrc;
      this.benny.className="arrow";
      this.benny.style.backgroundColor=this.clr;
      dog=1; if(this.dir=="left")dog=-1;
      this.benny.style.left=(padG*dog)+"px";
      this.line.style.width=(lineWG-arrowWG-padG)+"px";
      }//if arrow
   if((this.imgAft=="point")||(this.imgAft=="pointer")){
      this.benny.src="img/point"+rowG.dir+".gif";
      this.benny.style.width=bennyWGsmall+"px";
      this.line.style.width=(lineWG-bennyWGsmall-padG)+"px";
      }//if point
   dog=Math.floor( ( (new Date().getTime()) - time0 ) / timeFudge );
      if(!this.time)this.time=dog;
   if((this.msgAft)&&(this.cAft)){
      this.msgAft=swap(this.msgAft,"%time%",this.time);
         if(!time99)time99=0;
         time99=(parseInt(time99)+parseInt(this.time));
      this.cAft.style.color=this.clrAft;
      this.cAft.style.textAlign=this.dir;
      this.cAft.firstChild.data=this.msgAft;
      }//if cAft msgAft
   if(funList.length==0)time99=0;
   rowG=null;
   doResize();
   doResize();
}//endRow

//== PING, TN3270======================================================
function pinground(clr){ // stack sends ping
   funList.push("pinground2('"+clr+"');"); // ping bounces back to stack
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="left";
   rowG.msgB4="Stack sends a ping";
   rowG.border=true;
   rowG.setRow();
   time0=new Date().getTime();
   startTicker();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//pinground
//--------------------------------------------------
function pinground2(clr){ // ping bounces back to stack
   rowG=new Row(clr);
   rowG.msgB4="Ping bounces back";
   rowG.imgAft="point";
   rowG.msgAft="Round trip: %time% ms.";
   rowG.clrAft=clr;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//pinground2
//--------------------------------------------------
//--------------------------------------------------
function tnsna(clr){ // client sends tn3270 request
   funList.push("tnsna3('"+clr+"');"); // SNA reply arrives at stack = SNA time
   funList.push("tnsna2('"+clr+"');"); // stack passes tn3270 request to SNA
   rowG=new Row("#000000");
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client sends request";
   rowG.border=true;
   rowG.setRow();
   time0=new Date().getTime();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//tnsna
//--------------------------------------------------
function tnsna2(clr){ // stack passes tn3270 request to SNA
   rowG=new Row(clr);
   rowG.sender="stack";
   rowG.dir="right";
   rowG.col=1;
   rowG.msgB4="Stack passes request to SNA";
   rowG.setRow();
   time0=new Date().getTime();
   startTicker();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//tnsna2
//--------------------------------------------------
function tnsna3(clr){ // SNA reply arrives at stack = SNA time
   rowG=new Row(clr);
   rowG.sender="stack";
   rowG.dir="left";
   rowG.col=1;
   rowG.imgAft="point";
   rowG.msgAft="SNA time: %time% ms.";
   rowG.clrAft=clr;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//tnsna3
//--------------------------------------------------
//--------------------------------------------------
function tnnetwork(clr){ // client sends tn3270 request
   funList.push("tnnet3('"+clr+"');"); // client send tn3270 response/ack, stack reports IP network time
   funList.push("tnnet2('"+clr+"');"); // stack sends tn3270 reply
   funList.push("tnsna3('#000000');"); // SNA reply arrives at stack = SNA time
   funList.push("tnsna2('#000000');"); // stack passes tn3270 request to SNA
   rowG=new Row("#000000");
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client sends request";
   rowG.border=true;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//tnnetwork
//--------------------------------------------------
function tnnet2(clr){ // stack sends tn3270 reply
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="left";
   rowG.msgB4="Stack sends reply";
   rowG.setRow();
   time0=new Date().getTime();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//tnnet2
//--------------------------------------------------
function tnnet3(clr){ // client send tn3270 response/ack, stack reports IP network time
   rowG=new Row(clr);
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client sends response / acknowledgement";
   rowG.msgAft="IP network time: %time% ms.";
   rowG.clrAft=clr;
   rowG.imgAft="point";
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//tnnet3
//--------------------------------------------------
//--------------------------------------------------
function tnresponse(clr){ // client sends tn3270 request
   funList.push("tnresponse2('"+clr+"');"); // stack reports response time
   funList.push("tnnet3('"+clr+"');"); // client sends tn3270 response/ack, stack reports IP network time
   funList.push("tnnet2('"+clr+"');"); // stack sends tn3270 reply
   funList.push("tnsna3('"+clr+"');"); // SNA reply arrives at stack = SNA time
   funList.push("tnsna2('"+clr+"');"); // stack passes tn3270 request to SNA
   rowG=new Row("#000000");
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client sends request";
   rowG.border=true;
   rowG.setRow();
   time99=0;
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//tnresponse
//--------------------------------------------------
function tnresponse2(clr){ // stack reports response time
   stopTicker();
   rowG=new Row(clr);
   rowG.time=time99;
   rowG.sender="client"; rowG.dir="right";
   rowG.msgAft="Response time: %time% ms.";
   rowG.clrAft=clr;
   rowG.imgAft=null;
   rowG.benny=null;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//tnresponse2

//== HTTP ======================================================
//--------------------------------------------------
function httphandshake(clr){ // client sends connection request
   funList.push("httphandshake3('"+clr+"');"); //
   funList.push("httphandshake2('"+clr+"');"); //
   rowG=new Row(clr);
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client sends connection request (syn)"; rowG.msgAft=null;
   rowG.border=true;
   rowG.setRow();
   time0=new Date().getTime();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httphandshake
//--------------------------------------------------
function httphandshake2(clr){ // stack acknowledges, sends connect request
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="left";
   rowG.msgB4="Stack acknowledges; sends connection request (ack, syn)";
   rowG.setRow();
   startTicker();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httphandshake2
//--------------------------------------------------
function httphandshake3(clr){ // client acknowledges, stack reports handshake time
   rowG=new Row(clr);
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client acknowledges (ack)";
   rowG.msgAft="Handshake time: %time% ms.";
   rowG.imgAft="point"; rowG.clrAft=clr;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httphandshake3
//--------------------------------------------------
//--------------------------------------------------
function httpserver(clr){ //
   funList.push("httpserver4('"+clr+"');"); //
   funList.push("httpserver3('"+clr+"');"); //
   funList.push("httpserver2('#000000');"); //
   httphandshake("#000000");
}//httpserver
//--------------------------------------------------
function httpserver2(clr){ // client sends request
   rowG=new Row(clr);
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client sends request";
   rowG.setRow();
   time99=0;
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httpserver2
//--------------------------------------------------
function httpserver3(clr){ // stack passes request to server
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="right"; rowG.col=1;
   rowG.msgB4="Stack passes request to server";
   rowG.setRow();
   time0=new Date().getTime();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httpserver3
//--------------------------------------------------
function httpserver4(clr){ // server replies to stack, stack reports server time
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="left"; rowG.col=1;
   rowG.msgAft="Server time: %time% ms.";
   rowG.imgAft="point"; rowG.clrAft=clr;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httpserver4
//--------------------------------------------------
//--------------------------------------------------
function httpnetwork(clr){ // repeat server time
   funList.push("httpnetwork3('"+clr+"');"); //
   funList.push("httpnetwork2('"+clr+"');"); //
   httpserver("#000000");
}//httpnetwork
//--------------------------------------------------
function httpnetwork2(clr){ // stack replies 1st packet
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="left";
   rowG.msgB4="Stack sends 1st packet of reply";
   rowG.setRow();
   time0=new Date().getTime();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httpnetwork2
//--------------------------------------------------
function httpnetwork3(clr){ // client acknowledges 1st packet, stack reports network time
   rowG=new Row(clr);
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client acknowledges 1st packet of reply";
   rowG.msgAft="IP network time: %time% ms.";
   rowG.imgAft="point"; rowG.clrAft=clr;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httpnetwork3
//--------------------------------------------------
//--------------------------------------------------
function http1byte(clr){ // repeat network time
   funList.push("http1byte2('"+clr+"');"); //
   funList.push("httpnetwork3('"+colorsG["httpnetwork"]+"');"); //
   funList.push("httpnetwork2('"+colorsG["httpnetwork"]+"');"); //
   funList.push("httpserver4('"+colorsG["httpserver"]+"');"); //
   funList.push("httpserver3('"+colorsG["httpserver"]+"');"); //
   funList.push("httpserver2('#000000');"); //
   httphandshake("#000000");
}//http1byte
//--------------------------------------------------
function http1byte2(clr){ // stack reports 1st-byte response time
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="right";
   rowG.msgAft="1st-byte response time: %time% ms.";
   rowG.imgAft=null; rowG.clrAft=clr;
   rowG.benny=null;
   rowG.time=time99;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//http1byte2
//--------------------------------------------------
//--------------------------------------------------
function httprate(clr){ // repeat http1byte
   funList.push("httprate4('"+clr+"');"); //
   funList.push("httprate3('"+clr+"');"); //
   funList.push("httprate2('"+clr+"');"); //
   funList.push("http1byte2('#000000');"); //
   funList.push("httpnetwork3('#000000');"); //
   funList.push("httpnetwork2('"+clr+"');"); //
   httpserver("#000000");
}//httprate
//--------------------------------------------------
function httprate2(clr){ // stack replies 2d packet
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="left"; rowG.col=3;
   rowG.msgB4="Stack sends 2nd packet of reply";
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httprate2
//--------------------------------------------------
function httprate3(clr){ // stack replies 3rd packet
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="left"; rowG.col=3;
   rowG.msgB4="Stack sends 3rd packet of reply";
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httprate3
//--------------------------------------------------
function httprate4(clr){ // client acknowledges 3d packet, stack calculates data-transfer rate
   rowG=new Row("#000000");
   rowG.sender="client"; rowG.dir="right";
   rowG.msgB4="Client acknowledges 2nd & 3rd packets";
   rowG.msgAft="Data transfer rate = bytes in 3 packets / %time% ms.";
   rowG.imgAft="point"; rowG.clrAft=clr;
   rowG.setRow();
   window.setTimeout("runRow()",speed);
   //timer=window.setInterval("runRow()",speed);
}//httprate4

/*===============================================================
function fun(clr){ //
   colorsG = ["pinground","tnsna","tnnetwork","tnresponse",
              "httphandshake","httpserver","http1byte","httprate"];
   funList.push("fun3('"+clr+"');"); //
   funList.push("fun2('"+clr+"');"); //
   rowG=new Row(clr);
   rowG.sender="stack"; rowG.dir="left"; rowG.col=3;
   rowG.msgB4=""; rowG.msgAft="";
   rowG.clr=""; rowG.clrB4=""; rowG.clrAft="";
   rowG.imgAft="arrow|point";
   rowG.time=time99;
   rowG.setRow();
   time0=new Date().getTime(); time99=0;
   //timer=window.setInterval("runRow()",speed);
}//fun
--------------------------------------------------
row needs:
   col, dir, clr, clrB4, clrAft, msgB4, msgAft, imgAft
action needs:
   time0, time99,
row dflts:
   col=3, cB4=4, cAft=2;
   sender=client, dir=right, notdir=left
   clr=gray, clrB4=black, clrAft=black
   msgB4, msgAft, imgAft=arrow | point
   arwClr=ffffff, arwSrc=arrowffffffright.gif
   id=rowN, time, row, cell, line, benny
   setRow(), endRow()
colorsG = ["pinground","tnsna","tnnetwork","tnresponse",
          "httphandshake","httpserver","http1byte","httprate"];
ping   pinground
tn3270 tnsna         + tnnetwork  = tnresponse
http   httphandshake   httpserver   http1byte  httprate
== 30 =============================================================*/

//== DEBUG =============================================================
var debug, zerobug, timebug, deltabug, cntbug;
debug=0;
var arabug=new Array();
function fourDigits(n){
   if(n<10)n="0"+n;
   if(n<100)n="0"+n;
   if(n<1000)n="0"+n;
   return n;
}//fourDigits


//== 30 =============================================================
