
function Caption1() {
  //     JAVASCRIPT INCLUDE FILE - (c) J R Stockton  >= 2009-11-11
  //             http://www.merlyn.demon.co.uk/include1.js
  //       Routines may be copied, but URL must not be linked to.
  }

var Inc1T=0

var Site = "Merlyn", Owner = "J R Stockton"

// In lieu of DynWrite :

function Wryt(ID, S) { document.getElementById(ID).innerHTML = S }
// document.getElementById("Divn").firstChild.data = S 


// General Utilities :

function BR() { document.writeln("<br>") }

function HR() { document.writeln("<hr>") }

function LS(n) { return String(n).replace(/\b(\d)\b/g, '0$1') }

function LZ(n) { return (n!=null&&n<10&&n>=0?"0":"") + n }

function LZZ(n) { return (n!=null&&n<100&&n>=0?"0"+LZ(n):""+n) }

function lz(n) { var t = n+"" ; return t.length==1 ? "0"+t : t } // slower?


function TrimS() { // used for String.prototype.trim  \u00A0?
  return (this.toString() ?
    this.toString().replace(/\s+$|^\s+/g, "") : "") }
String.prototype.trim = TrimS

function Space(N) { var S = "" ; while (N-->0) S += " " ; return S }

function T8(Str) { // Expands Tab to spaces up to Column 8N (EjH)
  var Lines = Str.split("\n"), L, Parts, Row, P, S8 = "        "
  for (L=0 ; L < Lines.length ; L++) { Parts = Lines[L].split("\t")
    Row = "" ; P = 0 ; while (1) { Row += Parts[P]
      if (++P==Parts.length) break
      Row += S8.substring(Row.length%8) /* 1..8 spaces */ }
    Lines[L] = Row }
  return Lines.join("\n") }


function NameFunc(Fn) { // Fn is a function; return its name
  var A = Fn.toString().match(/function\s+(\w+)\(/)
  return A ? A[1] : "anon" }



function DummyF(X) { return X /* Dummy */ }


function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }

function Sygn(X) { return (X+1/X)<0 ? "-" : "+" /* signed zero */ }

function Sgnd(X) { return Sign(X) + Math.abs(X) }

function SpcsTo(S, L) { S += ""
  while (S.length<L) S = " " + S ; return S }

function ZeroTo(S, L) { S += ""
  while (S.length<L) S = "0" + S ; return S }

function ToNd(X, N) { // developed from ZeroTo
  if (X<0) return "-" + ToNd(-X, N)
  X += "" ; while (X.length<N) X = "0" + X ; return X }

function ChrsTo(S, L, C) { // ChrsTo is a new PrfxTo
  for (var i = String(S).length ; i < L ; i++) S = C + S
  return S }



// New 20090112+
function StrC(X, M, N, B) { var St, J // to M digits point N digits
  St = String(Math.round((B ? Math.abs(X) : X)*Math.pow(10, N)))
  if (X===null || /\D/.test(St)) return ChrsTo(X, M+N+1+B, " ")
  St = ChrsTo(St, M+N, "0") ; J = St.length - N // 20090113
  return (B ? Sign(X) : "" ) + 
    St.substring(0, J) + "." + St.substring(J) }

function StrU(X, M, N) { return StrC(X, M, N, 0) /* X>-0.5e-N */ }
 
function StrS(X, M, N) { return StrC(X, M, N, 1) /* uses Sign */ }

function StrT(X, M, N) { return ChrsTo(StrU(X, 1, N), M+N+1, " ") }

function StrW(X, M, N) { return ChrsTo(StrS(X, 1, N), M+N+2, " ") }


if (!Number.prototype.toFixed) { // || !+0.9.toFixed(0) maybe
  Number.prototype.toFixed = // JL.  For exact match, change Sign
    new Function("X",
      "  /* toFixed */ if (!X) X=0\n  return StrS(this, 1, X)") }


function Expo(E) { return "e" + (E<0?'-':'+') + LZ(Math.abs(E)) }

function GetSEM(X) { // returns Sign Mantissa Exponent (base 10)
  var U, Obj = { S : Sign(X), E : 0, M : X==U?U:Math.abs(X) }
  with (Obj) { if (M==0 || !isFinite(M)) return Obj
    while (M >= 10) { E++ ; M /= 10 }
    while (M < 1.0) { E-- ; M *= 10 } }
  return Obj }

function NumDecSigFig(X, N) { var U // returns a Number
  if (X==0||X==U) return X
  with (GetSEM(X)) var P = Math.pow(10, N-E-1)
  return Math.round(X*P)/P }

function StrSigFigFxd(X, N) { var U // ?? for 2 <= N <= 16 ??
  if (X==U) return " " + U
  with (GetSEM(X)) { var P, Q
    P = Math.pow(10, N-E-1) ; Q = Math.round(Math.abs(X)*P)/P
    return S + StrU(Q, 1, Math.max(1, N-E-1)) } }

function StrSigFigExp(X, N) { // ?? for 2 <= N <= 16 ??
  with (GetSEM(X))
    return S + StrU(M, 1, N-1) + (isFinite(M) ? Expo(E) : " ") }


function SigFigSet() { // sets globals
  SigFigNum = NumDecSigFig
  SigFigFxd = StrSigFigFxd
  SigFigExp = StrSigFigExp }

SigFigSet()


function SigFigAre() { var IzN = "\t"
  document.write( "Across this site,\n",
    "Name Used\tThe Function\tReturn".italics(),
    "\nSigFigNum", IzN, NameFunc(SigFigNum), "\tNumber",
    "\nSigFigFxd", IzN, NameFunc(SigFigFxd), "\tString '#.#'",
    "\nSigFigExp", IzN, NameFunc(SigFigExp), "\tString '#.#e#'") }



function Div(X, Y) { return Math.floor(X/Y) /* full range */ }

function Mod(X, Y) { return X - Math.floor(X/Y)*Y }


function userIn(Ctrl) { // input for numbers and expressions
  return +eval(Ctrl.value) }

function GetNum(Ctrl) { // input for expressions, allows spaces
  return +eval(Ctrl.value.replace(/[ ]/g, '')) }

function RadBtns(Rbtn, Arr) { var Q, J=0 // Read RadioButtons
  while (Q=Rbtn[J]) { if (Q.checked) return Arr[J] ; J++ } }



// After LRN :

var BoxW = 69

function SafeHTML(S) {
  return S.split("&").join("&amp;").split("<").join("&lt;").
    split(">").join("&gt;") } // IAS

function Depikt(X, Y, S, Hue) { // String S is shown in a box
  document.writeln(
    "<p class=DEPIKT align=center>\n<textarea readonly wrap=virtual",
    " style=\"border: double thick ", Hue || "black", " ;\"",
    " cols=", X, " rows=", Y, ">\n", SafeHTML(S),
    "<\/textarea><\/p>") }

function ShoTrim(St) {
  var match = /\S([\s\S]*\S)*/.exec(St)
  return match ? match[0] : " eh? " }

function ShoLinCnt(St, Mx) { // counts lines when wrapped at     lineLength Mx
  var Ch, j = xj = CR = NL = 0, Len = St.length, X = 1
  while (j<Len) { Ch = St.charCodeAt(j++)
    if (Ch!=10 && Ch!=13) continue
    if (Ch==10) NL++
    if (Ch==13) CR++
    X += Math.max(Math.floor((j-xj-2)/Mx), 0) ; xj = j }
  // In principle, not quite right, as MSIE wraps at whitespace
  return X + Math.max(NL, CR) }

function ShoGen(A) { // see ShoFFF
  var St = "", Len = A.length, j = 0, Vis = 1, Arg, LC = 0
  while (Len>0) {
    Arg = A[j++]
    if (!Arg) { Vis = 0 ; continue }
    if (Arg.join) Arg =
      "[\n" + Arg.join("\n,\n") + "\n]" // ?? 2006-10-29 ??
    Arg = ShoTrim(Arg.toString())
    St += Arg ; if (Vis) LC += ShoLinCnt(Arg, BoxW)
    if (j==Len) break
    St += "\n\n" ; LC += Vis }
  return {Str:St, Cnt:LC} }

function ShoFFF() {
  // Show code of ArgListed functions, strings; 0 ends visibles
  with (ShoGen(arguments)) Depikt(BoxW, Cnt, Str, "lightgreen") }

function ShoCod(Fn) { // N.B. Fn() should be called externally
  var St = ShoTrim(Fn.toString())
  Depikt(BoxW, ShoLinCnt(St, BoxW), St, "red") }

function ShoOut(Fn) { // N.B. this calls Fn(), shows output in PRE
  document.writeln("<pre class=OUT>")
  Fn()
  document.writeln("<\/pre>") }

function ShoDoo(Fn) { // N.B. this calls  Fn() - ADD show others ?
  ShoCod(Fn) ; Fn() /* no visible output expected */ }

function ShoDuu(Fn) { // N.B. this calls  Fn() - ADD show others ?
  ShoCod(Fn) ; ShoOut(Fn) /* visible output expected */ }

function ShoBad() {
  document.body.lastChild.style.backgroundColor = "#ffc0c0" }

// .


function eIVSF() {
  Depikt(47, 2, "  For the code, view the source of this page,\n" +
                "     and any include files which it calls.") }


var BoxX = 70


function PopThis(btn) { // Executed by PopBtn buttons
  var Obj = ShoGen(btn.btnargs)
  // Height and Width values need improving
  var Wndw = window.open("", "X"+ +new Date(),
    "height=" + (16*Obj.Cnt+30) + ",width=" + (8*BoxX+20) +
    ",resizable,scrollbars")
  Wndw.document.write( // leading spaces for Opera
    "        <pre>\n", SafeHTML(Obj.Str), "\n<\/pre>")
  Wndw.document.close() /* DU */ }

function PopBtn() { // Call with ArgList to generate button
  document.write("<input type=button value='Pop Code'",
    " onClick='PopThis(this)'> ")
  var inputs = document.getElementsByTagName('input')	// MH
  var Btn = inputs[inputs.length - 1]
  Btn.btnargs = arguments
  return Btn }

function PopAll() { var Arry, ArrL, ArrJ, Text
  // scan loaded source for normal functions and make their PopBtns
  document.writeln(
    "<fieldset><legend>Automatic function source view<\/legend>")
  Text = document.body ; Text = Text.textContent || Text.innerHTML
  Arry = Text.match(/^function\s+\w+/gm) // alert(Arry.join("\n"))
  if (Arry) { ArrL = Arry.length
    for (ArrJ = 0 ; ArrJ < ArrL ; ArrJ++) {
      Text = Arry[ArrJ].split(" ")[1]
      PopBtn(window[Text]).value = Text } }
  document.writeln("<\/fieldset>") }


function PageString(Site, Title, Owner, Body) { // OK by TIDY
  return '<!DOCTYPE HTML PUBLIC' +
    ' "-//W3C//DTD HTML 4.01 Transitional//EN"\n' +
    ' "http://www.w3.org/TR/html4/strict.dtd">\n' +
    '<HTML lang="en">\n<HEAD>\n' +
    '<META HTTP-EQUIV="Content-Type"' +
    ' CONTENT="text/html; charset=ISO-8859-1">\n' +
    '<TITLE>' + Site + ' -\n ' +
    Title + '\n  - ' + Owner + '<\/TITLE>\n<\/HEAD>\n<BODY>\n' +
    '&copy; J R Stockton, www.merlyn.demon.co.uk, generated ' +
    new Date().toUTCString() + '\n<hr>\n' +
    Body + "\n\n<hr>\n<\/BODY>\n</\HTML>\n"}

function NewPage(Title, Body) { // Same window, new content
  document.writeln(PageString(Site, Title, Owner, Body))
  document.close() } // 20070212 for RobG       *********

function FreshPage(Title, Body) { // New window and content
  var Wndw = window.open("", "X"+new Date().getTime())
  var Site = "Merlyn", Owner = "J R Stockton" // not inherited
  Wndw.document.writeln(PageString(Site, Title, Owner, Body))
  Wndw.document.close() }




function Cuffs() { var ThisPage, ThisSite, J, DLJ, HREF
  ThisPage = location.href.replace(/#.*/, "")
  ThisSite = location.protocol + "//" + location.hostname + "/"
  J = document.links.length ; while (J--) {
    DLJ = document.links[J] ;
    if (typeof DLJ.href != "string") continue // RikW c.l.j 20070719
    HREF = DLJ.href // HREF = String(HREF)
    if (HREF.indexOf(ThisPage) == 0) DLJ.title = "." ;
      else if (HREF.indexOf(ThisSite) == 0) DLJ.title = "+" ;
      else if (HREF.indexOf("http://") == 0) DLJ.title = "#" ;
      else DLJ.title = "*" } }



function getXMLHTTPobj() {
  // adapted from http://jibbering.com/2002/4/httprequest.html
  var XMLhttp = false
  /*@cc_on @*/
  /*@if (@_jscript_version >= 5)
  // JScript gives us Conditional compilation, we can cope with old
  // IE versions and security blocked creation of the objects.
    try { XMLhttp = new ActiveXObject("Msxml2.XMLHTTP") }
    catch (e) {
      try { XMLhttp = new ActiveXObject("Microsoft.XMLHTTP") }
      catch (E) { XMLhttp = false }
      }
  @end @*/
  if (!XMLhttp && typeof XMLHttpRequest!='undefined') {
    try { XMLhttp = new XMLHttpRequest() }
    catch (e) { XMLhttp = false }
    }
  if (!XMLhttp && window.createRequest) {
    try { XMLhttp = window.createRequest() }
    catch (e) { XMLhttp = false }
    }
  return XMLhttp }


function ToglDepikt() { var K=0, Elems, Elem, ElSty
  Elems = document.getElementsByTagName("p")
  while (Elem=Elems[K++]) if (Elem.className=="DEPIKT") {
    ElSty = Elem.style
    ElSty.display = ElSty.display=="none" ? "block" : "none" } }

function TPCV() { document.writeln("<div class=CEN>", 
  "<input type=button value = 'Toggle Page Code View'" +
  " onClick='ToglDepikt()'><\/div>") }

function ReFormatsCode() { var Bad // Warns where needed
  if (Bad = !/\*/.test(function(){/**/}))
    document.writeln("<div class=CAN>This browser reformats ",
      "displayed script functions, omitting comment.<\/div>")
  TPCV() ; return Bad }


var Inc1B=0 // end.



