// 3    8      15            30   35   40        50        60                  80                  100
// -------------------------------------------------------------------------------------------------
// Project:  Wireless Data Lookup Chart
// Module:   Device
// -------------------------------------------------------------------------------------------------
// URL:      http://www.classaxe.com/wireless/data/set.js
// Filename: device.js                  Version:  1.0
// Date:     13/03/2001                 Author:   Martin Francis
// -------------------------------------------------------------------------------------------------
// **************************
// * Device Type definition *
// **************************
// Device["DeviceName"] = new DEVICE(code,[refs],[make],[type],base,diag,pins,pic,fv,fa,notes)
// Properties of DEVICE objects:
//   DEVICE.code       STRING   Code number of device
//   DEVICE.refs      [STRING]  References for device
//   DEVICE.make      [STRING]  Makers of device
//   DEVICE.type      [STRING]  Type of device (may be combination)
//           mr=Metal Rectifier, number of electrodes unknown
//          mr1=Metal Rectifier, single electrode
//          mr2=Metal Rectifier, two electrode
//          mr4=Metal Rectifier, four electrode (bridge)
//          npn=NPN transistor
//          pnp=PNP transistor
//           pn=Solid state diode
//            2=Diode   valve
//            3=Triode  valve
//            4=Tetrode valve
//            5=Pentode valve
//            6=Hexode  valve
//            7=Heptode valve
//            8=Octode  valve
//           ti=Tuning Indicator
//   DEVICE.base       STRING   "B7G","B8A","B8G","B9A","IO","MO" etc
//   DEVICE.diag       STRING   Variable name of circuit picture
//   DEVICE.pins       STRING   pins against diagram
//   DEVICE.pic        STRING   URL of photo
//   DEVICE.fv         NUMBER   Voltage of heater (or 0 if not known / not used)
//   DEVICE.fc         NUMBER   Current of heater (or 0 if not known / not used)
//   DEVICE.notes      STRING   Notes concerning the device
//   DEVICE.count      CALCULATE   count of devices
//   DEVICE.countSubs  CALCULATE   count of devices used as substitutes
//   DEVICE.history   [CALCULATE]  (Array of) years in which device was used
//   DEVICE.noDate     CALCULATE   Count of sets using device where date ia unknown
//   DEVICE.set       [CALCULATE]  Item numbers of all sets using device
//
// Functions of DEVICE objects:
//   DEVICE.popup()                alert with device details

base = new Array();
base["(unknown)"] = 1;
base["7 Pin"]	= 2;
base["10 Pin"]	= 3;
base["11 Pin"]	= 4;
base["Acorn A"]	= 5;
base["Acorn B"]	= 6;
base["Acorn C"]	= 7;
base["Acorn D"]	= 8;
base["B2A"]	= 9;
base["B2G"]	= 10;
base["B3G"]	= 11;
base["B4"]	= 12;
base["B4E"]	= 13;
base["B5"]	= 14;
base["B7"]	= 15;
base["B7B"]	= 16;
base["B7G"]	= 17;
base["B8A"]	= 18;
base["B8D"]	= 19;
base["B8G"]	= 20;
base["B8H"]	= 21;
base["B9"]	= 22;
base["B9A"]	= 23;
base["B9D"]	= 24;
base["B9G"]	= 25;
base["B11A"]	= 26;
base["B12A"]	= 27;
base["B14A"]	= 28;
base["B20A"]	= 29;
base["BC"]	= 30;
base["BC4"]	= 31;
base["BH8"]	= 32;
base["D5A"]	= 33;
base["Disc Seal"] = 34;
base["EMI"]	= 35;
base["EMI-BBC"]	= 36;
base["ES"]	= 37;
base["F8A"]	= 38;
base["G8A"]	= 39;
base["G8G"]	= 40;
base["G9"]	= 41;
base["G10A"]	= 42;
base["G10G"]	= 43;
base["IO"]	= 44;
base["M4"]	= 45;
base["M5"]	= 46;
base["M6"]	= 47;
base["MO"]	= 48;
base["Nuvistor"] = 49;
base["P"]	= 50;
base["P5"]	= 51;
base["Pencil"]	= 52;
base["Pins"]	= 53;
base["UX4"]	= 54;
base["UX5"]	= 55;
base["UX6"]	= 56;
base["UX7"]	= 57;
base["W3"]	= 58;
base["W4"]	= 59;
base["W6"]	= 60;
base["W7"]	= 61;
base["W8"]	= 62;
base["W10"]	= 63;
base["W13"]	= 64;
base["WA3"]	= 65;
base["WA5"]	= 66;
base["WA6"]	= 67;
base["WA7"]	= 68;
base["WA8"]	= 69;
base["WB5"]	= 70;
base["WB6"]	= 71;
base["WB7"]	= 72;
base["WB8"]	= 73;
base["WC5"]	= 74;
base["WC8"]	= 75;
base["WD6"]	= 76;
base["WD8"]	= 77;
base["WF8"]	= 78;



function DEVICE(code,refs,make,type,base,diag,pins,pic,fv,fc,notes)
// Device["DeviceName"]= new DEVICE(code,[refs],[make],[type],base,diag,pins,pic,fv,fa,notes)
{ this.code=code;               this.refs=refs;
  this.make=make;
  this.type=type;               this.base=base;
  this.diag=diag;               this.pins=pins;
  this.pic=pic;                 this.fv=fv;
  this.fc=fc;                   this.notes=notes;
  this.history=new Array();     this.noDate=0;
  this.count=0;                 this.countSubs=0; // Counters for device straight and substituted
  count.devicesUnique++;                          // Increment stats module unique device count
  this.set=[];                                    // Array for cross referencing sets
  this.ID = DeviceNames.length;
  DeviceNames[DeviceNames.length] = code;         // Index the newly created Device record
}


// ************************
// * Device History Graph *
// ************************
DEVICE.prototype.graph = function()
{ if (this.noDate==this.count+this.countSubs)
    return "<b>Sorry - not enough dates<br>known to produce a graph</b><br><br>";
  var out=new Array();
  var n=0;
  out[n++] = "<table class='grid' cellpadding='0' cellspacing='0' border='0'>\n";
  out[n++] = "  <tr>\n";
  out[n++] = "    <td class='grid'><img src='graph_top.gif' width='255' height='22'></td>\n";
  out[n++] = "  </tr>\n";
  out[n++] = "  <tr>\n";
  out[n++] = "    <td class='grid'><img src='vscale100.gif' width='32' height='199' alt='vertical scale 0-100'><img src='spacer.gif' width='43'>";
  for (var i=1915;i<1970;i++)
  { if (this.history[i])
      out[n++]="<img src='ff8080.gif' width='3' height='"+(2*this.history[i])+"' alt='"+i+": "+this.history[i]+"'\n>";
    else
      out[n++]="<img src='spacer.gif' width='3' height='1'\n>";
  }
  out[n++] = "<img src='graph_right.gif' width='15' height='199'></td>\n  </tr>\n  <tr>\n";
  out[n++] = "    <td class='grid'><img src='hscale1970.gif' width='255' height='22'></td>\n  </tr>\n"
  if (this.noDate!=0)
    out[n++] = "  <tr><td align='center'>(Plus "+this.noDate+" other sets, dates unknown)</td></tr>\n"
  out[n++] = "</table>\n";
  return out.join("");
}


// *************************
// * Device Popup Set List *
// *************************
DEVICE.prototype.setList = function()
{ var width=335 ; var height=400;
  DeviceSets=window.open('','DeviceSetList', 'width='+width+',height='+height+',resizable=1,menubar=0,location=0,scrollbars=1,toolbar=0');
  centerPopup(DeviceSets,width,height);
  var out=new Array() ; var n=0;
  this.set.sort(setsWithDevicesByDate)
  out[n++]="<html>\n<head>\n<title>All Sets with "+this.code+"</title>\n";
  out[n++]="<STYLE TYPE='text/css'>\n";
  out[n++]="  td.grid      { background: url('grid.gif'); }\n";
  out[n++]="  td           { font-family: Arial, sans-serif; font-size: 10pt; }\n";
  out[n++]="  table.graph  { background-color: rgb(196,251,206); padding: 3px; }\n";
  out[n++]="  table.dialog { background-color: rgb(255,255,183); }\n";
  out[n++]="</STYLE>\n</head>\n\n";
  out[n++]="<body BGCOLOR='#e0ffe0' background='wallpaper.gif' topmargin='5'>\n";
  out[n++]="<table border='3' cellspacing='0' cellpadding='5' ";
  out[n++]="class='dialog' bordercolor='#A8A800' bordercolorlight='#D0C991' bordercolordark='#BBBB00'>\n";
  out[n++]="<tr><td><h3 align='center'><u>All sets using "+this.code+"</u><br>(sorted by date)</h3>";
  out[n++]=this.graph()+"</td></tr>\n";
  out[n++]="<tr><td><ul>";
  for (var i=0;i<this.set.length;i++)
  { var sMake=Item[this.set[i]].make, sModel=Item[this.set[i]].model, sDate=Item[this.set[i]].date;
    var sDetails=sDate+": "+sMake+" - "+sModel;
    out[n++]="<li><a href='javascript:void window.opener.Item["+this.set[i]+"].popup()';>"
    if (isNaN(parseInt(Item[this.set[i]].date)))
      out[n++]="(<i>"+sDetails+"</i>)</a></li>\n";
    else
      out[n++]=sDetails+"</a></li>\n";
  }

  out[n++]="</ul></td>\n      </tr>\n";
  out[n++]="<tr>\n  <td align='center'><img src='spacer.gif' height='3'><br>\n";
  out[n++]="    <a href='javascript:window.close()'><img src='but_close.gif' width='40' height='21' border='0' alt='Close'></a>\n";
  out[n++]="  </td>\n";
  out[n++]="</tr>\n";

  out[n++]="</table>\n</body>\n</html>";
  DeviceSets.focus();
  DeviceSets.document.write(out.join(""));
  DeviceSets.document.close();
}


// ***********************
// * Device Popup window *
// ***********************
DEVICE.prototype.popup = function()
{ var width=780 ; var height=400;
  var oMake=this.make.join(", ").replace(/BRI/,"Brimar").
                             replace(/COS/,"Cossor").
                             replace(/EDI/,"Ediswan").
                             replace(/EUR/,"European").
                             replace(/MAR/,"Marconi").
                             replace(/MAZ/,"Mazda").
                             replace(/MOV/,"M.O.V. Valve Company").
                             replace(/MUL/,"Mullard").
                             replace(/OSR/,"Osram").
                             replace(/PHI/,"Philips").
                             replace(/SEI/,"Seimens").
                             replace(/SEN/,"SenTerCell").
                             replace(/TUN/,"Tungsram").
                             replace(/WES/,"Westinghouse");
  var oBase="&nbsp;";
  var oPic,oDiag;
  switch(this.base) {
    case "B2G" :oBase=IMG_B2G ;break;
    case "B3G" :oBase=IMG_B3G ;break;
    case "B7"  :oBase=IMG_B7  ;break;
    case "B7G" :oBase=IMG_B7G ;break;
    case "B8A" :oBase=IMG_B8A ;break;
    case "B8G" :oBase=IMG_B8G ;break;
    case "B9A" :oBase=IMG_B9A ;break;
    case "ES"  :oBase=IMG_ES  ;break;
    case "GT3" :oBase=IMG_GT3 ;break;
    case "MO"  :oBase=IMG_MO  ;break;
    case "IO"  :oBase=IMG_IO  ;break;
    case "TO1" :oBase=IMG_TO1 ;break; }
  if (this.pic!="")
  { oPic="<a href='javascript:window.opener.top.devicePhoto(\""+this.pic+"\")'><IMG border='1' SRC='..\/device_halfsize/"+
    this.pic+"' valign='middle' alt='"+this.code+
    " scanned at 1.75 pixels per mm. \nClick for view at 3.5 pixels per mm'></a>";
  } else oPic="<IMG border='1' src='..\/device_halfsize/noimage.gif' alt='No Image yet for this device'>";
  if (this.diag!="")
    oDiag=eval(this.diag) ; else oDiag="&nbsp;";
  if (this.tech=="V")   oTech="Valve" ; else oTech= "&nbsp;";

  DeviceDetails=window.open('','DeviceDetails', 'width='+width+',height='+height+',resizable=1,menubar=0,location=0,toolbar=0');
  centerPopup(DeviceDetails,width,height);
  var out=new Array() ; var n=0;
  out[n++]="<html>\n<head>\n<title>Device Details - "+this.code+"</title>\n";
  out[n++]="<STYLE TYPE='text/css'>\n";
  out[n++]="  td          { font-family: Arial, sans-serif; font-size: 10pt; }\n";
  out[n++]="  td.grid     { background: url('grid.gif'); }\n";
  out[n++]="  td.pic      { background-color: rgb(196,206,251); }\n";
  out[n++]="  table.pic   { background-color: rgb(196,206,251); \n";
  out[n++]="                padding: 3px;\n";
  out[n++]="                border-left: 2px outset rgb(145,145,255);\n";
  out[n++]="                border-top: 2px outset rgb(145,145,255);\n";
  out[n++]="                border-right: 2px outset rgb(0,0,255);\n";
  out[n++]="                border-bottom: 2px outset rgb(0,0,255); }\n";
  out[n++]="  table.graph  { background-color: rgb(196,251,206); padding: 3px; }\n";
  out[n++]="  table.dialog { background-color: rgb(255,255,183); }\n";
  out[n++]="</STYLE>\n</head>\n\n";

  out[n++]="<body BGCOLOR='#e0ffe0' background='wallpaper.gif' topmargin='5'>\n";
  out[n++]="<table border='3' cellspacing='0' cellpadding='5' ";
  out[n++]="class='dialog' bordercolor='#A8A800' bordercolorlight='#D0C991' bordercolordark='#BBBB00'>\n";
  out[n++]="  <tr>\n";
  out[n++]="    <td class='heading' colspan='3' align='center'><u><b>Device Details for "+this.code+"<b></u></td>\n";
  out[n++]="  </tr>\n";
  out[n++]="  <tr>\n";
  out[n++]="    <td  valign='top'>\n";
  out[n++]="      <table border='0' cellspacing='0' cellpadding='2'>\n";
  out[n++]="        <tr>\n";
  out[n++]="          <td width='70'><b>Code:</b></td>\n";
  out[n++]="            <td>"+this.code+"</td></tr>\n";
  out[n++]="        <tr><td><b>Count:</b></td>\n";
  out[n++]="            <td>"+(this.count+this.countSubs);
  if (this.countSubs!=0)
    out[n++]=" (inc "+this.countSubs+" as subs)";
  out[n++]="</td></tr>\n";
  if (this.type!="")
    out[n++]="      <tr><td><b>Type:<b></td>\n            <td>"+this.type+"</td></tr>\n";
  if (this.make!="")
    out[n++]="      <tr><td><b>Make:</b></td>\n            <td>"+oMake+"</td></tr>\n";
  if (this.refs!="")
    out[n++]="      <tr><td valign='top'><b>References:</b></td>\n            <td>"+this.refs+"</td></tr>\n";
  if (this.fv!=0)
    out[n++]="      <tr><td><b>Filament:</b></td><td>"+this.fv+"V / "+this.fc+"A</td></tr>\n";
  if (this.notes!="")
    out[n++]="      <tr><td valign='top'><b>Notes:</b></td>\n            <td>"+this.notes+"</td></tr>\n";
  out[n++]="    </table>\n";
  out[n++]="  </td>\n";
  out[n++]="  <td valign='top'>";
  out[n++]="<table border='0' class='pic' cellspacing='0' cellpadding='0'>\n";
  out[n++]="  <tr>\n";
  out[n++]="    <td width='100%'><table cellspacing='0' cellpadding='0' border='0' bgcolor='#AAAAFF'>\n";
  out[n++]="      <tr>\n";
  out[n++]="        <td valign='bottom' width='26'><img src='scale_17px_v.gif' width='26' height='260'></td>";
  out[n++]="        <td valign='bottom' align='left' width='108'>"+oPic+"</td>\n";
  out[n++]="        <td rowspan='2'><img src='spacer.gif' width='10'></td>";
  out[n++]="        <td rowspan='2' valign='top'>";
  out[n++]="          <img src='spacer.gif' height=10'><br>"+oBase+"<br><img src='spacer.gif' height=17'><br>\n";

// Start to show device diagram:
  out[n++]=           oDiag+"<br>";

  // Now line up numbers with pins and work out if there are any internal connections:
  var pinnames="123456789abcyz"  // a=11, b=12, c=13, y=Top Cap, z=Side Contact
  for (var i=0;i<pinnames.length;i++)                                     // Go through list of possible pins
  { if (this.pins.indexOf(pinnames.substr(i,1))!=-1)                      // Pin exists at least once
    { if (this.pins.match(new RegExp(pinnames.substr(i,1),"g")).length>1) // Pin appears more than once
      { var pin_joints_total=this.pins.match(new RegExp(pinnames.substr(i,1),"g")).length
        var pin_joints_left=pin_joints_total
        pin_join=false

        for (var j=0;j<this.pins.length;j++)                         // Go through the present row
        { if (this.pins.substr(j,1)==pinnames.substr(i,1))           // Is present pin joined?
          { if (pin_joints_left==pin_joints_total)                   // And is this first pin?
            { pin_joints_left--                                      // Subtract one from count
              pin_join=true                                          // Set flag
              out[n++]="<img src='diagrams/con_join_l.gif' width='12' height='8'>"  // Show left join
            }
            else if (pin_joints_left==1)                             // This is final pin
            { out[n++]="<img src='diagrams/con_join_r.gif' width='12' height='8'>"  // Show right join
              pin_join=false                                         // Clear flag
            }
            else
            { out[n++]="<img src='diagrams/con_join_m.gif' width='12' height='8'>"  // Show middle join
              pin_joints_left--
            }
          }
          else                                                       // Present pin is NOT joined
          { if (pin_join==true)                                      // Are we between joined pins?
              out[n++]="<img src='diagrams/con_cross.gif' width='12' height='8'>"   // Yes, show crossing
            else                                                                    // No,
              out[n++]="<img src='diagrams/con_through.gif' width='12' height='8'>" // show straight line
          }
        }
        out[n++]="<br>"                                              // end of this row
      }
    }
  }
  // Now extend leads to make easier reading
  for (var j=0;j<this.pins.length;j++)                         // Extend the leads
    out[n++]="<img src='diagrams/con_through.gif' width='12' height='4'>" // show straight line
  // Finally, assign correct numbers to pins
  out[n++]="<br><img src='spacer.gif' height='2' width='1'><br>";
  for (var i=0;i<this.pins.length;i++)
    out[n++]="<img src='diagrams/"+this.pins.substr(i,1)+".gif' width='12' height='8'>";
// End of device diagram


  out[n++]="</tr>\n";
  out[n++]="           <tr>\n";
  out[n++]="             <td valign='bottom' colspan='2' width='132'><img src='scale_17px_h.gif' width='132' height='17'></td>";
  out[n++]="           </tr>\n";
  out[n++]="         </table>\n";
  out[n++]="         </td>\n";
  out[n++]="       </tr>\n";
  out[n++]="     </table>\n";
  out[n++]="  </td>\n";
  out[n++]="  <td valign='top' align='center'><br>\n"+this.graph()+"<a ";
  out[n++]="href='javascript:void window.opener.Device[\""+this.code+"\"].setList()'>";
  out[n++]="  List sets with "+this.code+" in printable format</a></b>";
  out[n++]="</td>\n      </tr>\n";
  out[n++]="<tr>\n  <td align='center' colspan='3'><img src='spacer.gif' height='3'><br>\n";
  out[n++]="    <a href='javascript:window.close()'><img src='but_close.gif' width='40' height='21' border='0' alt='Close'></a>\n";
  out[n++]="  </td>\n";
  out[n++]="</tr>\n";

  out[n++]="</table>\n</body>\n</html>";
  DeviceDetails.focus();
  DeviceDetails.document.write(out.join(""));
  DeviceDetails.document.close();
}

function devicePhoto(what) {
  devicePhotoWin=window.open('','devicePhotoWin', 'width=300,height=400,scrollbars=1,resizable=1,menubar=0,location=0,toolbar=0');
  top.centerPopup(devicePhotoWin,300,500);
  var out= "<html>\n<head>\n<title>Photograph of "+what+" rendered at 34 pixels per cm<\/title>\n"+
           "<\/head>\n"+
           "<body background='wallpaper.gif' topmargin='4' leftmargin='4' leftmargin='4'>\n"+
           "<table bgcolor='#AAAAFF' border='1'><tr><td align='center'>"+
           "<font size='5'><b><u>"+what.split(".")[0]+"<\/u><\/b><\/font><\/td><\/tr>"+
           "<tr><td bgcolor='#ffffff'><img src='scale_34px_v.gif'>"+
           "<img src='..\/devices\/"+what+"'><br><img src='scale_34px_h.gif'><\/td><\/tr>"+
           "<tr><td align='center'><img src='spacer.gif' height='4'><br><a href='javascript:window.close()'>"+
           "<img src='but_close.gif' width='40' height='21' border='0' alt='Close'></a><\/td><\/tr><\/table>"+
           "\n";
           "<\/body>\n<\/html>"
   devicePhotoWin.focus();devicePhotoWin.document.write(out);devicePhotoWin.document.close();
   devicePhotoWin.scroll(300,500)
 }


// ***********************
// * Device Details List *
// ***********************
DEVICE.prototype.showDevice = function(deviceNumber)
{   var out  = new Array() ; var l=0
    var oRefs = this.refs !=""  ? this.refs.join("<br>") : "&nbsp;";
    var oMake = this.make !=""  ? this.make : "&nbsp;";
    var oType = this.type !=""  ? this.type : "&nbsp;";
    var oBase = this.base !=""  ? this.base : "&nbsp;";
    var oFv   = this.fv   !=0   ? this.fv   : "&nbsp;";
    var oFc   = this.fc   !=0   ? this.fc   : "&nbsp;";
    var oNote = this.notes!=""  ? this.notes: "&nbsp;";
    var oDiag = this.diag !=""  ? IMG_DIAG  : "&nbsp;";
    var oPic  = this.pic  !=""  ? IMG_PIC   : "&nbsp;";

  var oCount=(this.count+this.countSubs);
  out[l++] = "\n<TR>";
  out[l++] = "\n  <TD class='a'><a onmouseover='window.status=&quot;Click for info on this device&quot;;return true'";
  out[l++] = "onmouseout='window.status=&quot;&quot;;return true'";
  out[l++] = "href='javascript:top.Device[\""+this.code+"\"].popup()'>"+this.code+"</a></TD>";
  out[l++] = "\n  <TD class='b'>"+oRefs +"</TD>";
  out[l++] = "\n  <TD class='b'>"+oMake +"</TD>";
  out[l++] = "\n  <TD class='b'>"+oType +"</TD>";
  out[l++] = "\n  <TD class='b'>"+oBase +"</TD>";
  out[l++] = "\n  <TD class='b'>"+oFv +"</TD>";
  out[l++] = "\n  <TD class='b'>"+oFc +"</TD>";
  out[l++] = "\n  <TD class='b'>"+oNote +"</TD>";
  out[l++] = "\n  <TD class='c'>"+oDiag +"</TD>";
  out[l++] = "\n  <TD class='c'>"+oPic  +"</TD>";
  out[l++] = "\n  <TD class='d'>"+oCount+"</TD>";
  out[l++] = "</TD>\n</TR>";
  return out.join(""); } // 10 times faster than outputing each term directly


// ****************************
// * Device Definition Export *
// ****************************
DEVICE.prototype.exportDeviceHTML = function() // Generates array as used in set definitions
// Device["DeviceName"] = new DEVICE(code,[refs],[make],[type],base,diag,pins,pic,fv,fa,notes)

{ var out =  new Array(); var n=0; var id=1
  out[n++] = base[this.base] + "	";
  out[n++] = this.code + "	";
  out[n++] = this.pins + "	";
  out[n++] = this.diag + "	";
  out[n++] = this.fc + "	";
  out[n++] = this.fv + "	";
  out[n++] = id++ + "	";
  out[n++] = this.notes + "\n";
  return out.join("") } // 10 times faster than outputing each term directly


DEVICE.prototype.exportDeviceSQL = function()         // Export set as JavaScript Array
{ var out = new Array();                              // To hold output
  var n = 0;                                          // Output array counter
  out[n++] = (base[this.base])?("\"" + (base[this.base])+"\","):("\\N,");	// deviceCode
  out[n++] = (this.code)?("\"" + (this.code)+"\","):("\\N,");	// deviceCode
  out[n++] = (this.pins)?("\"" + (this.pins)+"\","):("\\N,");	// deviceConnections
  out[n++] = (this.diag)?("\"" + (this.diag)+"\","):("\\N,");	// deviceDiagram
  out[n++] = (this.fc)?("\"" + (this.fc)+"\","):("\\N,");	// deviceFc
  out[n++] = (this.fv)?("\"" + (this.fv)+"\","):("\\N,");	// deviceFv
  out[n++] = ("\"" + (this.ID+1)+"\",");			// deviceID
  out[n++] = (this.notes)?("\"" + this.notes + "\"\x0A"):("\\N\x0A");
  return out.join("");}                               // Return as a string



// ******************************
// * Devices List Header Output *
// ******************************
// Operation:
// 1) Create and write out[n] array containing search details as html
// 2) Write headings for table
// ----------------------------------------------------------------

function listDevicesTop()
{ var out=new Array();
  var l=0;
  var sortMsg= "onmouseover='window.status=\"Sort by this column\"; return true' onmouseout='window.status=\"\"; return true'";
  var sortCall='top.sortDevices()';
  out[l++]="<html>\n<head>\n  <title>Results for List Devices</title>\n\n";
  out[l++]="<STYLE TYPE='text/css'>\n";
  out[l++]="  BODY { font-family: Arial, sans-serif;font-size: 12pt}\n";
  out[l++]="  th.s { background-color: rgb(192,192,192);border-left: 1px solid rgb(255,255,255);\n";
  out[l++]="         border-right: 1px solid rgb(128,128,128);border-top: 1px solid rgb(255,255,255);\n";
  out[l++]="         border-bottom: 1px solid rgb(128,128,128); text-align: bottom; }\n";
  out[l++]="  th   { font-family: Arial;font-size: 10pt;padding-left: 1px;padding-right:1px;\n";
  out[l++]="         background-color: rgb(255,255,200);border-style: solid;border-bottom-width: 1px;\n";
  out[l++]="         border-top-width: 1;}\n";
  out[l++]="  td.a { text-align: left; font-weight: bold; border-left-width: 1px}\n";
  out[l++]="  td.b { text-align: left; font-size: 8pt; }\n";
  out[l++]="  td.c { text-align: center}\n";
  out[l++]="  td.d { text-align: right ;padding-right:4px;}\n";
  out[l++]="  td   { vertical-align: top;border-left-width: 0;border-right-width: 0;font-family: Arial;\n";
  out[l++]="         font-size: 8pt; padding-left: 1px;padding-right:1px;background-color: rgb(255,255,200);\n";
  out[l++]="         border-style: solid;border-bottom-width: 1px;border-top-width: 0;}\n";
  out[l++]="</STYLE>\n</head>\n\n";
  out[l++]="<body onload='top.window.status=&quot;Radio list complete.&quot;;return true'";
  out[l++]="background='wallpaper.gif'>\n";
  out[l++]="<p><font color='#797900'><big><b><u>British Wireless Database</u></b><br>";
  out[l++]="Results for List Devices:</big></font><p align='center'><TABLE border='1' cellpadding='0' cellspacing='0' >";
  out[l++]="\n  <TR>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Device Code\",top.devicesByCode);"+sortCall+"'>Device</a></TH>";
  out[l++]="\n    <TH class='s'>Refs</TH>";
  out[l++]="\n    <TH class='s'>Maker</TH>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Type\",top.devicesByType);"+sortCall+"'>Type</a></TH>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Base\",top.devicesByBase);"+sortCall+"'>Base</a></TH>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Filament Voltage\",top.devicesByFv);"+sortCall+"'>Fv</a></TH>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Filament Current\",top.devicesByFc);"+sortCall+"'>Fc</a></TH>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Notes\",top.devicesByNotes);"+sortCall+"'>Notes</a></TH>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Diagram\",top.devicesByDiag);"+sortCall+"'>"+IMG_DIAG+"</a></TH>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Picture\",top.devicesByPic);"+sortCall+"'>"+IMG_PIC+"</a></TH>";
  out[l++]="\n    <TH class='s'><a "+sortMsg+" href='javascript:void top.sortingDevices(\"Count\",top.devicesByCount);"+sortCall+"'>No.</a></TH>";
  out[l++]="\n  </TR>";
  return out.join(""); }


function listDevices(chosenDevice,chosenType,chosenBase)
{ var out=new Array();
  var l=0;
  var chosenDeviceMod   = buildRegExp(chosenDevice)
  RegExpDevice          = new RegExp(chosenDeviceMod,"i")
  DevicesMatched=new Array();
  var timeStart = new Date()          // For timing of search routine
  out[l++]=listDevicesTop();
  RegExp_chosenType=new RegExp(","+chosenType+",")
  var j=0
  for(var i=0;i<DeviceList.length;i++) {
//    if (DeviceList[i].pic!="")
    if (chosenDevice==""||RegExpDevice.test(DeviceList[i].code))
      if (chosenType=="(ALL)"||(","+DeviceList[i].type.join()+",").match(RegExp_chosenType))
        if (chosenBase=="(ALL)"||DeviceList[i].base==chosenBase)
        { out[l++]=DeviceList[i].showDevice(i);
          DevicesMatched[j++]=DeviceList[i];
        }
  }
  if (DevicesMatched.length==0) {
    out[l++]="<TR><TD class='z' colspan='11'>No records matched criteria given.</TD></TR>" }
  timeElapsed=Math.round((((new Date())-timeStart)/100)/10).toString()

  out[l++]="\n</TABLE><br>"
  out[l++]=barGraph(((Math.round((DevicesMatched.length*1000) / count.devicesUnique))/10),200,12)	// value in %, x width, y width
  out[l++]=" <font color='#0000ff'> (Matched " + DevicesMatched.length + " of " + count.devicesUnique + " devices in " + timeElapsed
  out[l++]=" seconds)";

  if (debugMode)
    out[l++]="<br><center><a href=\"javascript: void top.exportDevices()\">Export this List</a>";
  out[l++]="</center></body>\n</html>";

  frames.results.document.open();
  frames.results.document.write(out.join(""));
  frames.results.document.close(); }


function sortDevices()
{ var out=new Array();
  var l=0;
  out[l++]=listDevicesTop();

  for(var i=0;i<DevicesMatched.length;i++)
    out[l++]=DevicesMatched[i].showDevice(i);

  if (DevicesMatched.length==0) {
    out[l++]="<TR><TD class='z' colspan='11'>No records matched criteria given.</TD></TR>" }
  out[l++]="\n</TABLE><br>"
  out[l++]=barGraph(((Math.round((DevicesMatched.length*1000) / count.devicesUnique))/10),200,12)	// value in %, x width, y width
  out[l++]=" <font color='#0000ff'> (Matched " + DevicesMatched.length + " of " + count.devicesUnique + " devices)";
  if (debugMode)
    out[l++]="<br><center><a href=\"javascript: void top.exportDevices()\">Export this List</a>";
  out[l++]="</center></body>\n</html>";

  frames.results.document.open();
  frames.results.document.write(out.join(""));
  frames.results.document.close();
  Wait3.window.close(); }


// **************************
// * Devices Export Routine *
// **************************
function exportDevices(){
  var out = new Array() ; var l = 0 ;  // holds entire output string in chunks joined later
  for (var deviceNumber=0; deviceNumber < DevicesMatched.length; deviceNumber++)
    out[l++]=DevicesMatched[deviceNumber].exportDeviceSQL();
  if (DevicesMatched.length==0) {
    out[l++]="//No records matched criteria given.";}
  frames.results.document.open("text/plain");
  frames.results.document.write(out.join(""));
  frames.results.document.close();
}



// ****************************
// * Show all device diagrams *
// ****************************
function AllDiags()
{ var row=4;  // Number of diagrams to place on each row
  var Diags=new Array(
  "IMG_2A","IMG_2B","IMG_2_2A","IMG_2_2B","IMG_2_2C","IMG_2_2D",
  "IMG_2_2_3A","IMG_2_2_3B","IMG_2_2_3C","IMG_2_2_3D",
  "IMG_2_2_5A","IMG_2_2_5B","IMG_2_2_2_3A","IMG_2_2_2_3B",
  "IMG_2_2_2_3C","IMG_2_2_2_3D","IMG_2_2_2_3E",
  "IMG_2_3A","IMG_2_5A","IMG_2_5B","IMG_2_5C","IMG_2_5D",
  "IMG_3_3A","IMG_3_3B","IMG_3_3C","IMG_3_3D","IMG_3_3E",
  "IMG_3_5A","IMG_3_5B","IMG_3_5C","IMG_3_5D","IMG_3_5E",
  "IMG_3_6A","IMG_3_6B","IMG_3_6C",
  "IMG_3_7A","IMG_3_7B","IMG_4A","IMG_4B",
  "IMG_5A","IMG_5B","IMG_5C","IMG_5D","IMG_5E","IMG_5F",
  "IMG_7A","IMG_7B","IMG_7C",
  "IMG_TIA","IMG_TIB","IMG_PNP","IMG_PN","IMG_BAR");
  var out="<table border='1' cellspacing='0' cellpadding='0' bgcolor='#ffffdd'>";
  for (var i=0;i<Diags.length/row;i++)
  { out+="\n<tr>\n";
    for (var j=0;j<row;j++)
    { if(((i*row)+j)<Diags.length)
      { var filename=eval("top."+Diags[(i*row)+j]).match(/SRC=\'[^\']+/).join("").replace(/SRC=\'/,"");
        out+="  <td valign='top' align='center'><small>";
        out+=Diags[(i*row)+j]+"<br><a href=\""+filename+"\">"+filename.replace(/diagrams\//,"")+"</a><br>";
        out+=eval(Diags[(i*row)+j])+"</small></td>\n";
      } else { out+="<td>&nbsp;</td>"; }
    }
    out+="</tr>";
  }
  out+="</table>";
  frames.results.document.open();
  frames.results.document.write(out);
  frames.results.document.close();
}

Loading.document.write("#");

