//
// ******************************************************************************************************
// *                                                                                                    *
// *                                  Javascript Classes and Functions                                  *
// *                                                                                                    *
// *  Class                                           Base Class                                        *
// *                                                                                                    *
// *    VCSH_CCData                                     (n/a)                                           *
// *    VCSH_Data                                       (n/a)                                           *
// *    VCSH_User                                       VCSH_Data                                       *
// *    VCSH_ExchangeUser                               VCSH_User                                       *
// *    VCSH_Flow                                       VCSH_Data                                       *
// *    VCSH_LETSplayFlow                               VCSH_Flow                                       *
// *    VCSH_MutualCreditFlow                           VCSH_Flow                                       *
// *    VCSH_Text                                       VCSH_Data                                       *
// *    VCSH_ExchangeText                               VCSH_Data                                       *
// *    VCSH_ValueItem                                  VCSH_Text                                       *
// *    VCSH_LETSplayItem                               VCSH_ValueItem                                  *
// *                                                                                                    *
// ******************************************************************************************************
//

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_CCData                                                                                  *
// *                                                                                                    *
// ******************************************************************************************************
//
// constructor
//
function VCSH_CCData(id, timestamp, signature, data, user, flow, text) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_CCData) {
    this.init(id.id, id.timestamp, id.signature, id.data, id.user, id.flow, id.text);
  } else if (id.nodeType === 9 || id.nodeType === 11) { // DOM Document or DocumentFragment
    this.init("", {}, {}, {}, {}, {}, {});
    this.fromXML(id);
  } else {
    this.init(id["id"], id["timestamp"], id["signature"], id["data"], id["user"], id["flow"], id["text"]);
  }
};
//
// protected (initializer)
//
VCSH_CCData.prototype.init = function(id, timestamp, signature, data, user, flow, text) {
  this.id        = id        !== undefined ? id        : "";
  this.timestamp = timestamp !== undefined ? timestamp : {};
  this.signature = signature !== undefined ? signature : {};
  this.data      = data      !== undefined ? data      : {};
  this.user      = user      !== undefined ? user      : {};
  this.flow      = flow      !== undefined ? flow      : {};
  this.text      = text      !== undefined ? text      : {};
};
//
// public
//
VCSH_CCData.prototype.sprint   = function() { return "VCSH_CCData {" + this.toString() + "\n}"; };
VCSH_CCData.prototype.toString = function() {
  var s = "";
  if (this.id !== undefined) s += "\n  [id]        => " + this.id;
  if (this.timestamp !== undefined) {
    s += "\n  [timestamp] => {";
    var and = " ";
    for (var i in this.timestamp) { s += and + i + " => '" + this.timestamp[i] + "'"; and = ", "; }
    s += " }";
  }
  if (this.signature !== undefined) {
    s += "\n  [signature] => {";
    var and = " ";
    for (var i in this.signature) { s += and + i; and = ", "; }
    s += " }";
  }
  if (this.data !== undefined) {
    s += "\n  [data]      => {";
    var and = " ";
    for (var i in this.data) { s += and + i; and = ", "; }
    s += " }";
  }
  if (this.user !== undefined) {
    s += "\n  [user]      => {";
    var and = " ";
    for (var i in this.user) { s += and + i; and = ", "; }
    s += " }";
  }
  if (this.flow !== undefined) {
    s += "\n  [flow]      => {";
    var and = " ";
    for (var i in this.flow) { s += and + i; and = ", "; }
    s += " }";
  }
  if (this.text !== undefined) {
    s += "\n  [text]      => {";
    var and = " ";
    for (var i in this.text) { s += and + i; and = ", "; }
    s += " }";
  }
  return s;
};
VCSH_CCData.prototype.merge = function(x) {
  //
  // Merge the object(s) x into this VCSH_CCData.
  // x may be a VCSH_Data, a VCSH_User, a VCSH_Flow, a VCSH_Text, or an array of any combination of these.
  // The id property of object(s) in x are set and used as keys, as they are merged into this.
  //
  var k = {}; // the keys of this[*];
  k.data = []; for (var j in this.data) k.data.push(j);
  k.user = []; for (var j in this.user) k.user.push(j);
  k.flow = []; for (var j in this.flow) k.flow.push(j);
  k.text = []; for (var j in this.text) k.text.push(j);
  if (x === null);
  else if (x instanceof VCSH_Text) this.text["t" + (x.id = k.text.length)] = x;
  else if (x instanceof VCSH_Flow) this.flow["f" + (x.id = k.flow.length)] = x;
  else if (x instanceof VCSH_User) this.user["u" + (x.id = k.user.length)] = x;
  else if (x instanceof VCSH_Data) this.data["c" + (x.id = k.data.length)] = x;
  else if (typeof x == "object") for (var i in x) {
    if      (x[i] instanceof VCSH_Text)
      { k.text.push("t" + (x[i].id = k.text.length)); this.text["t" + x[i].id] = x[i]; }
    else if (x[i] instanceof VCSH_Flow)
      { k.flow.push("f" + (x[i].id = k.flow.length)); this.flow["f" + x[i].id] = x[i]; }
    else if (x[i] instanceof VCSH_User)
      { k.user.push("u" + (x[i].id = k.user.length)); this.user["u" + x[i].id] = x[i]; }
    else if (x[i] instanceof VCSH_Data)
      { k.data.push("c" + (x[i].id = k.data.length)); this.data["c" + x[i].id] = x[i]; }
  }
  return this;
};
VCSH_CCData.prototype.toXML = function(what) {
  //
  // Generate a CCData XML Stream (DOM Document or XML text) from  timestamps, signatures, users, flows and texts.
  // what = "dom" or "xml" (case insensitive), the type of result desired.  The default is "dom".
  //
  // Note:  Signatures are attached to users, flows and texts, but only if their names match.
  // *****  For example, x.signature.u1s matches x.users.u1, x.signature.f2s matches x.flow.f2 and so on.
  // *****  These signatures will match the attached user, flow or text only if the latter is intact.
  //
  if (what === undefined) what = "DOM"; else if (typeof what != "string") return null;
  //
  // Generate boiler-plate XML header and footer.
  //
  var xml = [
    '<?xml version="1.0" encoding="utf-8"?>\n' +
    '<?xml-stylesheet href="'+TRANSPORT+HOST+'/index.php?s=XSL&amp;t=ccd" type="text/xsl"?>\n' +
    '<rdf:RDF\n'                                                  +
    '  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\n' +
    '  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"\n'      +
    '  xmlns:c="'+TRANSPORT+HOST+'/index.php?s=RDF#"\n'              +
    '  xmlns:u="'+TRANSPORT+HOST+'/index.php?s=RDF&amp;t=user#"\n'   +
    '  xmlns:f="'+TRANSPORT+HOST+'/index.php?s=RDF&amp;t=flow#"\n'   +
    '  xmlns:t="'+TRANSPORT+HOST+'/index.php?s=RDF&amp;t=text#">\n'  +
    '  <rdf:Description rdf:about="">\n'], tail =
    '  </rdf:Description>\n' +
    '</rdf:RDF>';
  //
  // Generate XML for timestamps.  Normally, there would be only one timestamp.
  //
  for (var i in this.timestamp) xml.push('    <c:Timestamp rdf:ID="',  i,  '">',  this.timestamp[i],  '</c:Timestamp>\n');
  //
  // Generate XML for data.
  //
  for (var i in this.data) {
//  if (this.signature[i+"s"] !== undefined) xml.push('    <c:Signature rdf:ID="',i,'s">', this.signature[i+"s"], '</c:Signature>\n');
                                             xml.push('    <u:', this.data[i].class_name, ' rdf:ID="',i,'">\n',
                                                      '      <rdf:Description rdf:about="#',i,'">\n');
//                                           xml.push('        <rdfs:label>', this.data[i].uri,                                    '</rdfs:label>\n');
    if (this.data[i].uri             !== "") xml.push('        <c:uri>',      this.data[i].uri,                                    '</c:uri>\n');
    if (this.data[i].created         !== "") xml.push('        <c:created>',  VCSH_Data.date("Y-m-d H:i:s", this.data[i].created), '</c:created>\n');
    if (this.data[i].updated         !== "") xml.push('        <c:updated>',  VCSH_Data.date("Y-m-d H:i:s", this.data[i].updated), '</c:updated>\n');
    if (this.data[i].language        !== "") xml.push('        <c:language>', this.data[i].language,                               '</c:language>\n');
    if (this.data[i].type            !== "") xml.push('        <c:type>',     this.data[i].type,                                   '</c:type>\n');
    if (this.data[i].status          !== "") xml.push('        <c:status>',   this.data[i].status,                                 '</c:status>\n');
                                             xml.push('      </rdf:Description>\n',
                                                      '    </u:', this.data[i].class_name, '>\n');
  }
  //
  // Generate XML for users.
  //
  for (var i in this.user) {
//  if (this.signature[i+"s"]     !== undefined)
//                                        xml.push('    <c:Signature rdf:ID="',i,'s">', this.signature[i+"s"], '</c:Signature>\n');
    switch (this.user[i].class_name) {
    case "CCUser" :
                                          xml.push('    <u:', this.user[i].class_name, ' rdf:ID="',i,'">\n',
                                                   '      <rdf:Description rdf:about="#',i,'">\n');
//                                        xml.push('        <rdfs:label>',   this.user[i].user_id,                                        '</rdfs:label>\n');
      if (this.user[i].uri        !== "") xml.push('        <c:uri>',        this.user[i].uri,                                            '</c:uri>\n');
      if (this.user[i].created    !== "") xml.push('        <c:created>',    VCSH_Data.date("Y-m-d H:i:s", this.user[i].created),         '</c:created>\n');
      if (this.user[i].updated    !== "") xml.push('        <c:updated>',    VCSH_Data.date("Y-m-d H:i:s", this.user[i].updated),         '</c:updated>\n');
      if (this.user[i].language   !== "") xml.push('        <c:language>',   this.user[i].language,                                       '</c:language>\n');
      if (this.user[i].type       !== "") xml.push('        <c:type>',       this.user[i].type,                                           '</c:type>\n');
      if (this.user[i].status     !== "") xml.push('        <c:status>',     this.user[i].status,                                         '</c:status>\n');
      if (this.user[i].user_id    !== "") xml.push('        <u:user_id>',    this.user[i].user_id,                                        '</u:user_id>\n');
      if (this.user[i].short_name !== "") xml.push('        <u:short_name>', ShowPage.htmlentities(Utf8.decode(this.user[i].short_name)), '</u:short_name>\n');
      if (this.user[i].full_name  !== "") xml.push('        <u:full_name>',  ShowPage.htmlentities(Utf8.decode(this.user[i].full_name)),  '</u:full_name>\n');
                                          xml.push( '      </rdf:Description>\n',
                                                    '    </u:', this.user[i].class_name, '>\n');
      break;
    case "VCSHUser" :
                                             xml.push('    <u:', this.user[i].class_name, ' rdf:ID="',i,'">\n',
                                                      '      <rdf:Description rdf:about="#',i,'">\n');
//                                           xml.push('        <rdfs:label>',      this.user[i].user_id,                                        '</rdfs:label>\n');
      if (this.user[i].uri           !== "") xml.push('        <c:uri>',           this.user[i].uri,                                            '</c:uri>\n');
      if (this.user[i].created       !== "") xml.push('        <c:created>',       VCSH_Data.date("Y-m-d H:i:s", this.user[i].created),         '</c:created>\n');
      if (this.user[i].updated       !== "") xml.push('        <c:updated>',       VCSH_Data.date("Y-m-d H:i:s", this.user[i].updated),         '</c:updated>\n');
      if (this.user[i].language      !== "") xml.push('        <c:language>',      this.user[i].language,                                       '</c:language>\n');
      if (this.user[i].type          !== "") xml.push('        <c:type>',          this.user[i].type,                                           '</c:type>\n');
      if (this.user[i].status        !== "") xml.push('        <c:status>',        this.user[i].status,                                         '</c:status>\n');
      if (this.user[i].user_id       !== "") xml.push('        <u:user_id>',       this.user[i].user_id,                                        '</u:user_id>\n');
      if (this.user[i].short_name    !== "") xml.push('        <u:short_name>',    ShowPage.htmlentities(Utf8.decode(this.user[i].short_name)), '</u:short_name>\n');
      if (this.user[i].full_name     !== "") xml.push('        <u:full_name>',     ShowPage.htmlentities(Utf8.decode(this.user[i].full_name)),  '</u:full_name>\n');
      if (this.user[i].last_login    !== "") xml.push('        <u:last_login>',    VCSH_Data.date("Y-m-d H:i:s", this.user[i].last_login),      '</u:last_login>\n');
      if (this.user[i].password_salt !== "") xml.push('        <u:password_salt>', this.user[i].password_salt,                                  '</u:password_salt>\n');
      if (this.user[i].password      !== "") xml.push('        <u:password>',      this.user[i].password,                                       '</u:password>\n');
      var access = ['access_from','access_to'];
      for (var j=0; j<access.length; j++) {
        var ac_j = this.user[i].serialize_access(this.user[i][access[j]]).split(" "), regs;
        for (var k=0; k<ac_j.length; k++) if (regs = ac_j[k].match(/^<([a-z][a-z0-9]*)&(.*)>$/))
                                             xml.push('        <u:',access[j],' rdf:parseType="Resource">', '<c:c>',regs[1],'</c:c><c:n>',regs[2],'</c:n></u:',access[j],'>\n');
      }
                                             xml.push('      </rdf:Description>\n',
                                                      '    </u:', this.user[i].class_name, '>\n');
      break;
    case "SocialUser" :
                                              xml.push('    <u:', this.user[i].class_name, ' rdf:ID="',i,'">\n',
                                                       '      <rdf:Description rdf:about="#',i,'">\n');
//                                            xml.push('        <rdfs:label>',       this.user[i].user_id,                                        '</rdfs:label>\n');
      if (this.user[i].uri            !== "") xml.push('        <c:uri>',            this.user[i].uri,                                            '</c:uri>\n');
      if (this.user[i].created        !== "") xml.push('        <c:created>',        VCSH_Data.date("Y-m-d H:i:s", this.user[i].created),         '</c:created>\n');
      if (this.user[i].updated        !== "") xml.push('        <c:updated>',        VCSH_Data.date("Y-m-d H:i:s", this.user[i].updated),         '</c:updated>\n');
      if (this.user[i].language       !== "") xml.push('        <c:language>',       this.user[i].language,                                       '</c:language>\n');
      if (this.user[i].type           !== "") xml.push('        <c:type>',           this.user[i].type,                                           '</c:type>\n');
      if (this.user[i].status         !== "") xml.push('        <c:status>',         this.user[i].status,                                         '</c:status>\n');
      if (this.user[i].user_id        !== "") xml.push('        <u:user_id>',        this.user[i].user_id,                                        '</u:user_id>\n');
      if (this.user[i].short_name     !== "") xml.push('        <u:short_name>',     ShowPage.htmlentities(Utf8.decode(this.user[i].short_name)), '</u:short_name>\n');
      if (this.user[i].full_name      !== "") xml.push('        <u:full_name>',      ShowPage.htmlentities(Utf8.decode(this.user[i].full_name)),  '</u:full_name>\n');
      if (this.user[i].last_login     !== "") xml.push('        <u:last_login>',     VCSH_Data.date("Y-m-d H:i:s", this.user[i].last_login),      '</u:last_login>\n');
      if (this.user[i].password_salt  !== "") xml.push('        <u:password_salt>',  this.user[i].password_salt,                                  '</u:password_salt>\n');
      if (this.user[i].password       !== "") xml.push('        <u:password>',       this.user[i].password,                                       '</u:password>\n');
      var access = ['access_from','access_to'];
      for (var j=0; j<access.length; j++) {
        var ac_j = this.user[i].serialize_access(this.user[i][access[j]]).split(" "), regs;
        for (var k=0; k<ac_j.length; k++) if (regs = ac_j[k].match(/^<([a-z][a-z0-9]*)&(.*)>$/))
                                             xml.push('        <u:',access[j],' rdf:parseType="Resource">', '<c:c>',regs[1],'</c:c><c:n>',regs[2],'</c:n></u:',access[j],'>\n');
      }
      if (this.user[i].regy_id        !== "") xml.push('        <u:regy_id>',        this.user[i].regy_id,                                        '</u:regy_id>\n');
      if (this.user[i].comm_id        !== "") xml.push('        <u:comm_id>',        this.user[i].comm_id,                                        '</u:comm_id>\n');
      if (this.user[i].time_value     !== "") xml.push('        <u:time_value>',     this.user[i].time_value,                                     '</u:time_value>\n');
      if (this.user[i].deprec_time    !== "") xml.push('        <u:deprec_time>',    this.user[i].deprec_time,                                    '</u:deprec_time>\n');
      if (this.user[i].user_interface !== "") xml.push('        <u:user_interface>', this.user[i].user_interface,                                 '</u:user_interface>\n');
      if (this.user[i].letter_format  !== "") xml.push('        <u:letter_format>',  this.user[i].letter_format,                                  '</u:letter_format>\n');
      if (this.user[i].image_type     !== "") xml.push('        <u:image_type>',     this.user[i].image_type,                                     '</u:image_type>\n');
      if (this.user[i].image_data     !== "") xml.push('        <u:image_data>',     base64_encode(this.user[i].image_data),                      '</u:image_data>\n');
                                              xml.push('      </rdf:Description>\n',
                                                       '    </u:', this.user[i].class_name, '>\n');
      break;
    }
  }
  //
  // Generate XML for flows.
  //
  for (var i in this.flow) {
//  if (this.signature[i+"s"] !== undefined) xml.push('    <c:Signature rdf:ID="',i,'s">',  this.signature[i+"s"],  '</c:Signature>\n');
    switch (this.flow[i].class_name) {
    case "CCFlow" :
                                           xml.push('    <f:', this.flow[i].class_name, ' rdf:ID="',i,'">\n',
                                                    '      <rdf:Description rdf:about="#',i,'">\n');
//                                         xml.push('        <rdfs:label>',    this.flow[i].date, ' : ', this.flow[i].user_id1, ' : ', this.flow[i].user_id2, '</rdfs:label>\n');
      if (this.flow[i].uri         !== "") xml.push('        <c:uri>',         this.flow[i].uri,                                             '</c:uri>\n');
      if (this.flow[i].created     !== "") xml.push('        <c:created>',     VCSH_Data.date("Y-m-d H:i:s", this.flow[i].created),          '</c:created>\n');
      if (this.flow[i].updated     !== "") xml.push('        <c:updated>',     VCSH_Data.date("Y-m-d H:i:s", this.flow[i].updated),          '</c:updated>\n');
      if (this.flow[i].language    !== "") xml.push('        <c:language>',    this.flow[i].language,                                        '</c:language>\n');
      if (this.flow[i].type        !== "") xml.push('        <c:type>',        this.flow[i].type,                                            '</c:type>\n');
      if (this.flow[i].status      !== "") xml.push('        <c:status>',      this.flow[i].status,                                          '</c:status>\n');
      if (this.flow[i].date        !== "") xml.push('        <f:date>',        VCSH_Data.date("Y-m-d", this.flow[i].date),                   '</f:date>\n');
      if (this.flow[i].user_id1    !== "") xml.push('        <f:user_id1>',    this.flow[i].user_id1,                                        '</f:user_id1>\n');
      if (this.flow[i].user_id2    !== "") xml.push('        <f:user_id2>',    this.flow[i].user_id2,                                        '</f:user_id2>\n');
      if (this.flow[i].description !== "") xml.push('        <f:description>', ShowPage.htmlentities(Utf8.decode(this.flow[i].description)), '</f:description>\n');
                                           xml.push('      </rdf:Description>\n',
                                                    '    </f:',  this.flow[i].class_name,  '>\n');
      break;
    case "VCSHFlow" :
                                           xml.push('    <f:', this.flow[i].class_name, ' rdf:ID="',i,'">\n',
                                                    '      <rdf:Description rdf:about="#',i,'">\n');
//                                         xml.push('        <rdfs:label>',    this.flow[i].date, ' : ', this.flow[i].user_id1, ' : ', this.flow[i].user_id2, '</rdfs:label>\n');
      if (this.flow[i].uri         !== "") xml.push('        <c:uri>',         this.flow[i].uri,                                             '</c:uri>\n');
      if (this.flow[i].created     !== "") xml.push('        <c:created>',     VCSH_Data.date("Y-m-d H:i:s", this.flow[i].created),          '</c:created>\n');
      if (this.flow[i].updated     !== "") xml.push('        <c:updated>',     VCSH_Data.date("Y-m-d H:i:s", this.flow[i].updated),          '</c:updated>\n');
      if (this.flow[i].language    !== "") xml.push('        <c:language>',    this.flow[i].language,                                        '</c:language>\n');
      if (this.flow[i].type        !== "") xml.push('        <c:type>',        this.flow[i].type,                                            '</c:type>\n');
      if (this.flow[i].status      !== "") xml.push('        <c:status>',      this.flow[i].status,                                          '</c:status>\n');
      if (this.flow[i].date        !== "") xml.push('        <f:date>',        VCSH_Data.date("Y-m-d", this.flow[i].date),                   '</f:date>\n');
      if (this.flow[i].user_id1    !== "") xml.push('        <f:user_id1>',    this.flow[i].user_id1,                                        '</f:user_id1>\n');
      if (this.flow[i].user_id2    !== "") xml.push('        <f:user_id2>',    this.flow[i].user_id2,                                        '</f:user_id2>\n');
      if (this.flow[i].description !== "") xml.push('        <f:description>', ShowPage.htmlentities(Utf8.decode(this.flow[i].description)), '</f:description>\n');
      if (this.flow[i].give        !== "") xml.push('        <f:give>',        this.flow[i].give,                                            '</f:give>\n');
      if (this.flow[i].type1       !== "") xml.push('        <f:type1>',       this.flow[i].type1,                                           '</f:type1>\n');
      if (this.flow[i].type2       !== "") xml.push('        <f:type2>',       this.flow[i].type2,                                           '</f:type2>\n');
                                           xml.push('      </rdf:Description>\n',
                                                    '    </f:', this.flow[i].class_name, '>\n');
      break;
    case "AccessFlow" :
                                           xml.push('    <f:', this.flow[i].class_name, ' rdf:ID="',i,'">\n',
                                                    '      <rdf:Description rdf:about="#',i,'">\n');
//                                         xml.push('        <rdfs:label>', this.flow[i].date, ' : ', this.flow[i].user_id1, ' : ', this.flow[i].user_id2, '</rdfs:label>\n');
      if (this.flow[i].uri         !== "") xml.push('        <c:uri>',             this.flow[i].uri,                                    '</c:uri>\n');
      if (this.flow[i].created     !== "") xml.push('        <c:created>',         VCSH_Data.date("Y-m-d H:i:s", this.flow[i].created), '</c:created>\n');
      if (this.flow[i].updated     !== "") xml.push('        <c:updated>',         VCSH_Data.date("Y-m-d H:i:s", this.flow[i].updated), '</c:updated>\n');
      if (this.flow[i].language    !== "") xml.push('        <c:language>',        this.flow[i].language,                               '</c:language>\n');
      if (this.flow[i].type        !== "") xml.push('        <c:type>',            this.flow[i].type,                                   '</c:type>\n');
      if (this.flow[i].status      !== "") xml.push('        <c:status>',          this.flow[i].status,                                 '</c:status>\n');
      if (this.flow[i].date        !== "") xml.push('        <f:date>',            VCSH_Data.date("Y-m-d", this.flow[i].date),          '</f:date>\n');
      if (this.flow[i].user_id1    !== "") xml.push('        <f:user_id1>',        this.flow[i].user_id1,                               '</f:user_id1>\n');
      if (this.flow[i].user_id2    !== "") xml.push('        <f:user_id2>',        this.flow[i].user_id2,                               '</f:user_id2>\n');
      if (this.flow[i].description !== "") xml.push('        <f:description>',     ShowPage.htmlentities(Utf8.decode(this.flow[i].description)), '</f:description>\n');
      if (this.flow[i].give        !== "") xml.push('        <f:give>',            this.flow[i].give,                                   '</f:give>\n');
      if (this.flow[i].type1       !== "") xml.push('        <f:type1>',           this.flow[i].type1,                                  '</f:type1>\n');
      if (this.flow[i].type2       !== "") xml.push('        <f:type2>',           this.flow[i].type2,                                  '</f:type2>\n');
      if (this.flow[i].ac_code     !== "") xml.push('        <f:ac_code>',         this.flow[i].comm_id,                                '</f:ac_code>\n');
                                           xml.push('      </rdf:Description>\n',
                                                    '    </f:', this.flow[i].class_name, '>\n');
      break;
    case "SocialFlow" :
                                           xml.push('    <f:', this.flow[i].class_name, ' rdf:ID="',i,'">\n',
                                                    '      <rdf:Description rdf:about="#',i,'">\n');
//                                         xml.push('        <rdfs:label>',        this.flow[i].date, ' : ', this.flow[i].user_id1, ' : ', this.flow[i].user_id2, '</rdfs:label>\n');
      if (this.flow[i].uri         !== "") xml.push('        <c:uri>',             this.flow[i].uri,                                             '</c:uri>\n');
      if (this.flow[i].created     !== "") xml.push('        <c:created>',         VCSH_Data.date("Y-m-d H:i:s", this.flow[i].created),          '</c:created>\n');
      if (this.flow[i].updated     !== "") xml.push('        <c:updated>',         VCSH_Data.date("Y-m-d H:i:s", this.flow[i].updated),          '</c:updated>\n');
      if (this.flow[i].language    !== "") xml.push('        <c:language>',        this.flow[i].language,                                        '</c:language>\n');
      if (this.flow[i].type        !== "") xml.push('        <c:type>',            this.flow[i].type,                                            '</c:type>\n');
      if (this.flow[i].status      !== "") xml.push('        <c:status>',          this.flow[i].status,                                          '</c:status>\n');
      if (this.flow[i].date        !== "") xml.push('        <f:date>',            VCSH_Data.date("Y-m-d", this.flow[i].date),                   '</f:date>\n');
      if (this.flow[i].user_id1    !== "") xml.push('        <f:user_id1>',        this.flow[i].user_id1,                                        '</f:user_id1>\n');
      if (this.flow[i].user_id2    !== "") xml.push('        <f:user_id2>',        this.flow[i].user_id2,                                        '</f:user_id2>\n');
      if (this.flow[i].description !== "") xml.push('        <f:description>',     ShowPage.htmlentities(Utf8.decode(this.flow[i].description)), '</f:description>\n');
      if (this.flow[i].give        !== "") xml.push('        <f:give>',            this.flow[i].give,                                            '</f:give>\n');
      if (this.flow[i].type1       !== "") xml.push('        <f:type1>',           this.flow[i].type1,                                           '</f:type1>\n');
      if (this.flow[i].type2       !== "") xml.push('        <f:type2>',           this.flow[i].type2,                                           '</f:type2>\n');
      if (this.flow[i].comm_id     !== "") xml.push('        <f:comm_id>',         this.flow[i].comm_id,                                         '</f:comm_id>\n');
      if (this.flow[i].details     !== "") xml.push('        <f:details>',         ShowPage.htmlentities(Utf8.decode(this.flow[i].details)),     '</f:details>\n');
      if (this.flow[i].note1       !== "") xml.push('        <f:note1>',           ShowPage.htmlentities(Utf8.decode(this.flow[i].note1)),       '</f:note1>\n');
      if (this.flow[i].note2       !== "") xml.push('        <f:note2>',           ShowPage.htmlentities(Utf8.decode(this.flow[i].note2)),       '</f:note2>\n');
      var value = this.flow[i].serialize_value(this.flow[i].value).split(" "), regs;
      for (var j=0; j<value.length; j++)
        if (regs = value[j].match(/^<([a-z][a-z0-9]*)&(.*)&(\-?\d*\.?\d*)>$/))
                                           xml.push('        <f:value rdf:parseType="Resource">', '<c:c>',regs[1],'</c:c><c:n>',regs[2],'</c:n><c:v>',regs[3],'</c:v></f:value>\n');
        else if (regs = value[j].match(/^<([a-z][a-z0-9]*)&(.*)>$/))
                                           xml.push('        <f:value rdf:parseType="Resource">', '<c:c>',regs[1],'</c:c><c:v>',regs[2],'</c:v></f:value>\n');
                                           xml.push('      </rdf:Description>\n',
                                                    '    </f:', this.flow[i].class_name, '>\n');
      break;
    }
  }
  //
  // Generate XML for texts.
  //
  for (var i in this.text) {
//  if (this.signature[i+"s"] !== undefined) xml.push('    <c:Signature rdf:ID="',i,'s">',   this.signature[i+"s"],  '</c:Signature>\n');
    switch (this.text[i].class_name) {
    case "CCText" :
                                        xml.push('    <t:', this.text[i].class_name, ' rdf:ID="',i,'">\n',
                                                 '      <rdf:Description rdf:about="#',i,'">\n');
//                                      xml.push('        <rdfs:label>',        this.text[i].section, ' : ', this.text[i].block, (this.text[i].user_id1 == '' ? '' : ' : ', this.text[i].user_id1),
//                                                                              (this.text[i].user_id2 == '' ? '' : ' : ',  this.text[i].user_id2), '</rdfs:label>\n');
      if (this.text[i].uri      !== "") xml.push('        <c:uri>',             this.text[i].uri,                                         '</c:uri>\n');
      if (this.text[i].created  !== "") xml.push('        <c:created>',         VCSH_Data.date("Y-m-d H:i:s", this.text[i].created),      '</c:created>\n');
      if (this.text[i].updated  !== "") xml.push('        <c:updated>',         VCSH_Data.date("Y-m-d H:i:s", this.text[i].updated),      '</c:updated>\n');
      if (this.text[i].language !== "") xml.push('        <c:language>',        this.text[i].language,                                    '</c:language>\n');
      if (this.text[i].type     !== "") xml.push('        <c:type>',            this.text[i].type,                                        '</c:type>\n');
      if (this.text[i].status   !== "") xml.push('        <c:status>',          this.text[i].status,                                      '</c:status>\n');
      if (this.text[i].title    !== "") xml.push('        <t:title>',           ShowPage.htmlentities(Utf8.decode(this.text[i].title)),   '</t:title>\n');
      if (this.text[i].content  !== "") xml.push('        <t:content>',         ShowPage.htmlentities(Utf8.decode(this.text[i].content)), '</t:content>\n');
                                        xml.push('      </rdf:Description>\n',
                                                 '    </t:', this.text[i].class_name, '>\n');
      break;
    case "VCSHText" :
    case "SocialText" :
                                        xml.push('    <t:', this.text[i].class_name, ' rdf:ID="',i,'">\n',
                                                 '      <rdf:Description rdf:about="#',i,'">\n');
//                                      xml.push('        <rdfs:label>',        this.text[i].section, ' : ',  this.text[i].block, (this.text[i].user_id1 == '' ? '' : ' : ', this.text[i].user_id1),
//                                                                              (this.text[i].user_id2 == '' ? '' : ' : ', this.text[i].user_id2), '</rdfs:label>\n');
      if (this.text[i].uri      !== "") xml.push('        <c:uri>',             this.text[i].uri,                                         '</c:uri>\n');
      if (this.text[i].created  !== "") xml.push('        <c:created>',         VCSH_Data.date("Y-m-d H:i:s", this.text[i].created),      '</c:created>\n');
      if (this.text[i].updated  !== "") xml.push('        <c:updated>',         VCSH_Data.date("Y-m-d H:i:s", this.text[i].updated),      '</c:updated>\n');
      if (this.text[i].language !== "") xml.push('        <c:language>',        this.text[i].language,                                    '</c:language>\n');
      if (this.text[i].type     !== "") xml.push('        <c:type>',            this.text[i].type,                                        '</c:type>\n');
      if (this.text[i].status   !== "") xml.push('        <c:status>',          this.text[i].status,                                      '</c:status>\n');
      if (this.text[i].title    !== "") xml.push('        <t:title>',           ShowPage.htmlentities(Utf8.decode(this.text[i].title)),   '</t:title>\n');
      if (this.text[i].content  !== "") xml.push('        <t:content>',         ShowPage.htmlentities(Utf8.decode(this.text[i].content)), '</t:content>\n');
      if (this.text[i].section  !== "") xml.push('        <t:section>',         this.text[i].section,                                     '</t:section>\n');
      if (this.text[i].block    !== "") xml.push('        <t:block>',           this.text[i].block,                                       '</t:block>\n');
      if (this.text[i].user_id1 !== "") xml.push('        <t:user_id1>',        this.text[i].user_id1,                                    '</t:user_id1>\n');
      if (this.text[i].user_id2 !== "") xml.push('        <t:user_id2>',        this.text[i].user_id2,                                    '</t:user_id2>\n');
                                        xml.push('      </rdf:Description>\n',
                                                 '    </t:', this.text[i].class_name, '>\n');
      break;
    }
  }
  xml.push(tail);

  if (what.match(/^xml$/i)) {
    //
    // Return XML text.
    //
    return xml.join("");
  } else {
    //
    // Use XML-RPC to parse the XML into an XML DOM Document.  Tricky, no?
    //
    var result = (new xmlrpcmsg("",[])).parseResponse(xml.join(""));
    if (typeof result == "string") {
      VCSH_Global.errorMessage += "VCSH_CCData.toXML() Error: parseResponse() returned a string\n";
      return null;
    } else if (typeof result.value() == "object") {
      return result.value();
    } else {
      return null;
    }
  }
};
VCSH_CCData.prototype.fromXML = function(x) {
  //
  // Extract timestamps, signatures, users, flows and texts from a CCData XML stream (XML DOM Document).
  // Insert them into this VCSH_CCData.  This may result in some of the objects in this being replaced.
  // Note:  There is also a static member function that inserts into a new VCSH_CCData and returns it.
  //
  // Make sure that x is a DOM Document or DocumentFragment
  if (x === null || typeof x != "object" || !(x.nodeType === 9 || x.nodeType === 11)) return this;
  var fields = {
    "c:id"           : "id",           "c:uri"            : "uri",            "c:id"            : "id",
    "c:uri"          : "uri",          "c:class_name"     : "class_name",     "c:xml"           : "xml",
    "c:updated"      : "updated",      "c:created"        : "created",        "c:cached"        : "cached",
    "c:language"     : "language",     "c:type"           : "type",           "c:status"        : "status",
    "c:CCData"       : "CCData",       "c:c"              : "c",              "c:n"             : "n",
    "c:v"            : "v",            "u:CCUser"         : "CCUser",         "u:VCSHUser"      : "VCSHUser",
    "u:SocialUser"   : "SocialUser",   "u:last_login"     : "last_login",     "u:user_id"       : "user_id",
    "u:regy_id"      : "regy_id",      "u:comm_id"        : "comm_id",        "u:short_name"    : "short_name",
    "u:full_name"    : "full_name",    "u:password_salt"  : "password_salt",  "u:password"      : "password",
    "u:access_from"  : "access_from",  "u:access_to"      : "access_to",      "u:time_value"    : "time_value",
    "u:deprec_time"  : "deprec_time",  "u:user_interface" : "user_interface", "u:letter_format" : "letter_format",
    "u:image_type"   : "image_type",   "u:image_data"     : "image_data",     "f:CCFlow"        : "CCFlow",
    "f:VCSHFlow"     : "VCSHFlow",     "f:AccessFlow"     : "AccessFlow",     "f:SocialFlow"    : "SocialFlow",
    "f:date"         : "date",         "f:give"           : "give",           "f:type1"         : "type1",
    "f:type2"        : "type2",        "f:user_id1"       : "user_id1",       "f:user_id2"      : "user_id2",
    "f:comm_id"      : "comm_id",      "f:ac_code"        : "comm_id",        "f:description"   : "description",
    "f:details"      : "details",      "f:note1"          : "note1",          "f:note2"         : "note2",
    "f:value"        : "value",        "f:socap"          : "socap",          "f:tcash"         : "tcash",
    "f:ccash"        : "ccash",        "f:fcash"          : "fcash",          "t:CCText"        : "CCText",
    "t:VCSHText"     : "VCSHText",     "t:SocialText"     : "SocialText",     "t:ValueItem"     : "ValueItem",
    "t:LETSplayItem" : "LETSplayItem", "t:section"        : "section",        "t:block"         : "block",
    "t:user_id1"     : "user_id1",     "t:user_id2"       : "user_id2",       "t:title"         : "title",
    "t:content"      : "content",      "t:value"          : "value",          "t:tcash"         : "tcash",
    "t:ccash"        : "ccash",        "t:fcash"          : "fcash",          "t:local"         : "local",
    "t:stars"        : "stars"
  };
  for (var a=x.firstChild; a; a=a.nextSibling)
  if (a.nodeType == 1) {
    switch (a.tagName) {
    case "rdf:RDF" :
    default        :
      for (var b=a.firstChild; b; b=b.nextSibling)
      if (b.nodeType == 1) {
        switch (b.tagName) {
        case "rdf:Description" :
        default                :
          for (var c=b.firstChild; c; c=c.nextSibling)
          if (c.nodeType == 1) {
            switch (c.tagName) {
            case "c:Timestamp"  :
            case "c:Signature"  :
              var c_value = "";
              for (var d=c.firstChild; d; d=d.nextSibling) if (d.nodeType == 3) c_value += d.data;
              break;
            case "u:SocialUser" :
            case "f:AccessFlow" :
            case "f:SocialFlow" :
            case "t:SocialText" :
            default             :
              var c_value = {};
              if (c.attributes) for (var d=0; d<c.attributes.length; d++)
                if (c.attributes.item(d).name == "rdf:ID") {
                  c_value[fields["c:id"]]     = c.attributes.item(d).value.substr(1);
                  break;
              }
              c_value[fields["c:class_name"]] = fields[c.tagName];
              c_value[fields["c:xml"]]        = "";
              c_value[fields["c:cached"]]     = "2000-01-01 00:00:00";
              for (var d=c.firstChild; d; d=d.nextSibling)
              if (d.nodeType == 1) {
                switch (d.tagName) {
                case "rdf:Description" :
                default                :
                  for (var e=d.firstChild; e; e=e.nextSibling)
                  if (e.nodeType == 1) {
                    switch (e.tagName) {
                    case "rdfs:label"    :
                      break;
                    case "u:access_from" :
                    case "u:access_to"   :
                    case "f:value"       :
                      var e_value = {};
                      for (var f=e.firstChild; f; f=f.nextSibling)
                      if (f.nodeType == 1) {
                        switch (f.tagName) {
                        case "c:c" :
                        case "c:n" :
                        case "c:v" :
                        default    :
                          var f_value = "";
                          for (var g=f.firstChild; g; g=g.nextSibling) if (g.nodeType == 3) f_value += g.data;
                          e_value[fields[f.tagName]] = f_value;
                          break;
                        } // switch (f)
                      } // for (f) if (f)
                      //
                      // Convert e_value from the form
                      //   {a : b, c : d, ..., y : z}
                      // to the form
                      //   "<b&d&...&z>"
                      //
                      var e_copy = [];
                      for (var f in e_value) e_copy.push(e_value[f]);
                      e_value = "<" + e_copy.join("&") + ">";
                      //
                      // Copy or append e_value to c_value[fields[e.tagName]]
                      //
                      var e_copy = true;
                      if (e.attributes) for (var f=0; f<e.attributes.length; f++)
                        if (e.attributes.item(f).name == "rdf:parseType") {
                          if (e.attributes.item(f).value == "Resource")
                            e_copy = c_value[fields[e.tagName]] === undefined;
                          break;
                      }
                      if (e_copy) c_value[fields[e.tagName]] = e_value;
                      else        c_value[fields[e.tagName]] += " " + e_value;
                      break;
                    default :
                      var e_value = "";
                      for (var f=e.firstChild; f; f=f.nextSibling) if (f.nodeType == 3) e_value += f.data;
                      c_value[fields[e.tagName]] = e_value;
                      break;
                    } // switch (e)
                    switch (e.tagName) {
                    case "u:short_name"  :
                    case "u:full_name"   :
                    case "f:description" :
                    case "f:details"     :
                    case "f:note1"       :
                    case "f:note2"       :
                    case "t:title"       :
                    case "t:content"     :
//                    c_value[fields[e.tagName]] = Utf8.encode(c_value[fields[e.tagName]]);
                      c_value[fields[e.tagName]] =
                        Utf8.encode(ShowPage.numeric_html_entity_decode(c_value[fields[e.tagName]],'control'));
                      break
                    case "u:image_data"  :
                      c_value[fields[e.tagName]] = base64_decode(c_value[fields[e.tagName]]);
                      break;
                    } // switch (e)
                  } // for (e) if (e)
                  break;
                } // switch (d)
              } else if (d.nodeType == 3 && d.data == "XML parsing error") {
                //
                // Konqueror's XML parser choked.
                //
                VCSH_Global.errorMessage += d.data + "\n";
                return this;
              } // for (d) if (d)
              break;
            } // switch (c)
            var c_id = "_";
            if (c.attributes) for (var i=0; i<c.attributes.length; i++) if (c.attributes.item(i).name == "rdf:ID") {
              c_id = c.attributes.item(i).value;
              break;
            }
            switch (c.tagName) {
            case "c:Timestamp"  :
              this.timestamp[c_id] = c_value;
              break;
            case "c:Signature"  :
              this.signature[c_id] = c_value;
              break;
            case "c:CCData"       :
            case "c:VCSHData"     :
              this.data[c_id] = new VCSH_Data(c_value);
              this.data[c_id].xml = this.data[c_id].toXML("xml"); // DOM may have circular references
              this.data[c_id].unserialize();                      // Optional; should we do this?
//            this.data[c_id].serialize();                        // For testing purposes only
              break;
            case "u:CCUser"       :
            case "u:VCSHUser"     :
            case "u:SocialUser"   :
              c_value.bits      = "00000000000000000000000000000000";
              this.user[c_id] = new VCSH_User(c_value);
              this.user[c_id].xml = this.user[c_id].toXML("xml"); // DOM may have circular references
              this.user[c_id].unserialize();                      // Optional; should we do this?
//            this.user[c_id].serialize();                        // For testing purposes only
              break;
            case "f:CCFlow"       :
            case "f:VCSHFlow"     :
            case "f:AccessFlow"   :
            case "f:SocialFlow"   :
              c_value.and_bits = c_value.or_bits  = "00000000000000000000000000000000";
              this.flow[c_id] = new VCSH_Flow(c_value);
              this.flow[c_id].xml = this.flow[c_id].toXML("xml"); // DOM may have circular references
              this.flow[c_id].unserialize();                      // Optional; should we do this?
//            this.flow[c_id].serialize();                        // For testing purposes only
              break;
            case "t:CCText"       :
            case "t:VCSHText"     :
            case "t:SocialText"   :
            case "t:ValueItem"    :
            case "t:LETSplayItem" :
              switch (c.tagName) {
                case "t:LETSplayItem" : this.text[c_id] = new VCSH_LETSplayItem(c_value); break;
                case "t:ValueItem"    : this.text[c_id] = new VCSH_ValueItem(c_value);    break;
                default               : this.text[c_id] = new VCSH_Text(c_value);         break;
              }
              this.text[c_id].xml = this.text[c_id].toXML("xml"); // DOM may have circular references
              this.text[c_id].unserialize();                      // Optional; should we do this?
//            this.text[c_id].serialize();                        // For testing purposes only
              break;
            } // switch (c)
          } // for (c) if (c)
          break;
        } // switch (b)
      } // for (b) if (b)
      break;
    } // switch (a)
  } // for (a) if (a)
  return this;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_Data                                                                                    *
// *                                                                                                    *
// ******************************************************************************************************
//
// constructor
//
function VCSH_Data(id, uri, class_name, xml, created, updated, cached, language, type, status) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_Data) {
    this.init(id.id, id.uri, id.class_name, id.xml, id.created, id.updated, id.cached, id.language,
      id.type, id.status);
  } else if (id.nodeType === 9 || id.nodeType === 11) { // DOM Document or DocumentFragment
    var c = new VCSH_CCData(id), x = null;
    for (var i in c.data) { x = c.data[i]; break; }
    if (x === null) this.init();
    else this.init(x.id, x.uri, x.class_name, x.xml, x.created, x.updated, x.cached, x.language,
      x.type, x.status);
  } else {
    this.init(id['id'], id['uri'], id['class_name'], id['xml'], id['created'], id['updated'], id['cached'],
      id['language'], id['type'], id['status']);
  }
};
//
// protected (initializer)
//
VCSH_Data.prototype.init = function(id, uri, class_name, xml, created, updated, cached, language,
  type, status) {
  this.id         = id         !== undefined ? id         : "";
  this.uri        = uri        !== undefined ? uri        : "";
  this.class_name = class_name !== undefined ? class_name : "VCSHData";
  this.xml        = xml        !== undefined ? xml        : "";
  this.created    = created    !== undefined ? created    : "";
  this.updated    = updated    !== undefined ? updated    : "";
  this.cached     = cached     !== undefined ? cached     : "";
  this.language   = language   !== undefined ? language   : "";
  this.type       = type       !== undefined ? type       : "";
  this.status     = status     !== undefined ? status     : "";
};
//
// public
//
VCSH_Data.prototype.sprint   = function() { return "VCSH_Data {" + this.toString() + "\n}"; };
VCSH_Data.prototype.toString = function() {
  var s = "";
  if (this.id         !== undefined) s += "\n  [id]             => " + this.id;
  if (this.uri        !== undefined) s += "\n  [uri]            => " + this.uri;
  if (this.class_name !== undefined) s += "\n  [class_name]     => " + this.class_name;
  if (this.xml        !== undefined) s += "\n  [xml]            => (" + typeof this.xml + ")";
  if (this.created    !== undefined) s += "\n  [created]        => " + this.created;
  if (this.updated    !== undefined) s += "\n  [updated]        => " + this.updated;
  if (this.cached     !== undefined) s += "\n  [cached]         => " + this.cached;
  if (this.language   !== undefined) s += "\n  [language]       => " + this.language;
  if (this.type       !== undefined) s += "\n  [type]           => " + this.type;
  if (this.status     !== undefined) s += "\n  [status]         => " + this.status;
  return s
};
VCSH_Data.prototype.serialize_bits = function serialize_bits(bits) {
  //
  // bits comes in the form:
  //   array(b0, b1, b2, b3, b4, b5, b6, b7)
  //   where b0 ... b7 are 16-bit unsigned integers.
  //
  if (!(bits !== null && typeof bits == "object" && bits instanceof Array)) return bits;
  var b = VCSH_Global.hex_128(bits);
  return b._01 + b._00;
};
VCSH_Data.prototype.unserialize_bits = function(bits) {
  //
  // bits comes in the form:
  //   'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  //   32 hex digits, including leading zeros.
  //
  if (typeof bits != "string") return bits;
  return VCSH_Global.makebits_128(
    parseInt(bits.substr(28,4),16), parseInt(bits.substr(24,4),16),
    parseInt(bits.substr(20,4),16), parseInt(bits.substr(16,4),16),
    parseInt(bits.substr(12,4),16), parseInt(bits.substr( 8,4),16),
    parseInt(bits.substr( 4,4),16), parseInt(bits.substr( 0,4),16));
};
VCSH_Data.prototype.serialize_access = function(access) {
  //
  // access comes in the form:
  //   {a : [b, ...], c : [d, ...], ..., y : [z, ...]}
  //   where a,c,...,y are strings of lower-case letters, and b,d,...,z are
  //   valid user_ids and/or quoted lower-case words (e.g., "joe" or "'access'").
  //
  // This is serialized as:
  //   '<a&c> <d&f> ... <x&z>'
  //
  // access may also contain scalar elements:
  //   {a : b, c : d, ..., y : z}
  //
  // This is serialized as:
  //   '<a&b> <c&d> ... <y&z>'
  //
  if (typeof access != "object") return access;
  var a = [];
  for (var i in access)
    if (typeof access[i] == "object") for (var j=0; j<access[i].length; j++) a.push("<"+i+"&"+access[i][j]+">");
    else                                                                     a.push("<"+i+"&"+access[i]+">");
  return a.join(" ");
};
VCSH_Data.prototype.unserialize_access = function(access) {
  //
  // access comes serialized in the form:
  //   '<a&b> <c&d> ... <y&z>'
  //   where a,c,...,y are strings of lower-case letters, and b,d,...,z are
  //   valid user_ids and/or quoted lower-case words (e.g., "joe" or "'access'")
  //
  // This is unserialized as:
  //   {a : [b, ...], c : [d, ...], ..., y : [z, ...]}
  //
  if (typeof access != "string") return access;
  var a1 = access.split(" "), a2 = {}, regs;
  for (var a=0; a<a1.length; a++) if (regs = a1[a].match(/^<([a-z][a-z0-9]*)&([^&>]*)>$/)) {
    if (a2[regs[1]] !== undefined) a2[regs[1]].push(regs[2]);
    else                           a2[regs[1]] = [regs[2]];
  }
  return a2;
};
VCSH_Data.prototype.serialize_value = function(value) {
  //
  // value comes in the form:
  //   {a : {b : c}, d : {e : f}, ..., x : {y => z}}
  //   where a,d,...,x are strings of lower-case letters, and f,i,...,z are numbers
  //
  // This is serialized as:
  //   '<a&b&c> <d&e&f> ... <x&y&z>'
  //
  // value may also contain scalar elements:
  //   {a : c, d : f, ..., x : z}
  //
  // This is serialized as:
  //   '<a&c> <d&f> ... <x&z>'
  //
  if (typeof value != "object") return value;
  var v1 = {};
  for (i in value) if (typeof value[i] == "object") {
    var v_i = [];
    for (var j in value[i]) if (value[i][j] != 0.) v_i.push("<"+i+"&"+j+"&"+value[i][j]+">");
    v1[i] = v_i.join(' ');
  } else {
    v1[i] = "<"+i+"&"+value[i]+">";
  }
  var v2 = [];
  for (var i in v1) v2.push(v1[i]);
  return v2.join(" ");
};
VCSH_Data.prototype.unserialize_value = function(value) {
  //
  // value comes serialized in the form:
  //   '<a&b&c> <d&e&f> <g&h&i> ... <x&y&z>'
  //   where a,d,...,x are strings of lower-case letters, and f,i,...,z are numbers
  //
  // This is unserialized as:
  //   {a : {b : c}, d : {e : f}, ..., x : {y : z}}.
  //
  // The first two indices, taken together, should be unique, so for example if a=d, this is unserialized as:
  //   {a : {b : c, e : f}, ..., x : {y : z}}
  //
  // value may also contain terms of the form:
  //   '<a&c> <d&f> ... <x&z>'
  //
  // This is unserialized as
  //   {a : c, d : f, ..., x : z}
  //
  if (typeof value != "string") return value;
  var v1 = value.split(" "), v2 = {}, regs;
  for (var v=0; v<v1.length; v++)
    if (regs = v1[v].match(/^<([a-z][a-z0-9]*)&([^&]*)&(\-?\d*\.?\d*)\>/)) {
    if (regs[3] == 0. && ! regs[2].match(/^'[a-z][a-z0-9]'$/)) {
      //
      // Filter out zero values, unless regs[2] is a quoted keyword.
      //
      if (v2[regs[1]] !== undefined) {
        if (v2[regs[1]][regs[2]] !== undefined) v2[regs[1]][regs[2]] = undefined;
        if (v2[regs[1]].length == 0) v2[regs[1]] = undefined;
      }
    } else {
      if (v2[regs[1]] === undefined) v2[regs[1]] = {};
      v2[regs[1]][regs[2]] = Number(regs[3]);
    }
  } else if (regs = v1[v].match(/^<([a-z][a-z0-9]*)&(\-?\d*\.?\d*)>$/)) {
    v2[regs[1]] = Number(regs[2]);
  }
  return v2;
};
VCSH_Data.prototype.serialize = function() { };
VCSH_Data.prototype.unserialize = function() { };
VCSH_Data.prototype.toXML = function(what) {
  //
  // Generate a CCData XML Stream (XML DOM Document) from a VCSH_Data.
  //
  var x = new VCSH_CCData("");
  x.data[this.id] = this;
  return x.toXML(what);
};
VCSH_Data.prototype.merge = function(x) {
  //
  // Merge this and x (another VCSH_Data) into a VCSH_CCData.
  //
  this.id = "0";
  return x instanceof VCSH_Data ?
    (new VCSH_CCData("", {}, {}, { c0 : this }, {}, {}, {})).merge(x) : this;
};
//
// static
//
VCSH_Data.Date = function(d) {
  //
  // Convert d into a Date object.
  //
  if (d instanceof Date) return d;
  var t = String(d);
  if (t.search(/[^0-9]/) == -1) {
    //
    // String contains only digits.
    // It should be a 6, 8, 12 or 14-digit MySQL timestamp.
    //
    switch (t.length) {
    case 6:
      t = t.replace(/(..)(..)(..)/, "$1-$2-$3");
      break;
    case 8:
      t = t.replace(/(....)(..)(..)/, "$1-$2-$3");
      break;
    case 12:
      t = t.replace(/(..)(..)(..)(..)(..)(..)/, "$1-$2-$3 $4:$5:$6");
      break;
    case 14:
      t = t.replace(/(....)(..)(..)(..)(..)(..)/, "$1-$2-$3 $4:$5:$6");
      break;
    default:
      t = "2000-01-01 00:00:00";
    }
  }
  //
  // Format: mm/dd/yy
  // If yy < 70 then 2000 + yy; otherwise 1900 + yy.
  //
  if (t.length == 8)
    return new Date(
      (yy = parseInt(t.substr(6,2),10)) + (yy < 70 ? 2000 : 1900),
      parseInt(t.substr(0,2),10) - 1,
      parseInt(t.substr(3,2),10));
  //
  // Format: mm/dd/yyyy
  //
  else if (t.length == 10 && t.indexOf('/') == 2)
    return new Date(
      parseInt(t.substr(6,4),10),
      parseInt(t.substr(0,2),10) - 1,
      parseInt(t.substr(3,2),10));
  //
  // Format: yyyy-mm-dd 00:00:00
  //
  else if (t.length == 19)
    return new Date(
      parseInt(t.substr(0,4),10),
      parseInt(t.substr(5,2),10) - 1,
      parseInt(t.substr(8,2),10),
      parseInt(t.substr(11,2),10),
      parseInt(t.substr(14,2),10),
      parseInt(t.substr(17,2),10));
  //
  // Format: yyyy-mm-dd
  //
  else return new Date(
    parseInt(t.substr(0,4),10),
    parseInt(t.substr(5,2),10) - 1,
    parseInt(t.substr(8,2),10));
};

VCSH_Data.date = function(f, t) {
  //
  // Format a Date object as in the PHP date() function.
  //
  var d = VCSH_Data.Date(t);
  switch (f) {
  case "Y-m-d" :
    return sprintf("%04d-%02d-%02d",
      d.getFullYear(), d.getMonth()+1, d.getDate());
  case "Y-m-d H:i:s" :
  default :
    return sprintf("%04d-%02d-%02d %02d:%02d:%02d",
      d.getFullYear(), d.getMonth()+1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
  }
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_User (extends class VCSH_Data)                                                          *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_User.prototype = new VCSH_Data();
VCSH_User.prototype.constructor = VCSH_User;
VCSH_User.superclass = VCSH_Data.prototype;
//
// constructor
//
function VCSH_User(id, uri, class_name, xml, created, updated, cached, language, type, status,
  last_login, user_id, regy_id, comm_id, short_name, full_name, password_salt, password, bits,
  access_from, access_to, time_value, deprec_time, user_interface, letter_format, image_type,
  image_data) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_User) {
    this.init(id.id, id.uri, id.class_name, id.xml, id.created, id.updated, id.cached, id.language,
      id.type, id.status, id.last_login, id.user_id, id.regy_id, id.comm_id, id.short_name, id.full_name,
      id.password_salt, id.password, id.bits, id.access_from, id.access_to, id.time_value, id.deprec_time,
      id.user_interface, id.letter_format, id.image_type, id.image_data);
  } else if (id.nodeType === 9 || id.nodeType === 11) { // DOM Document or DocumentFragment
    var c = new VCSH_CCData(id), x = null;
    for (var i in c.user) { x = c.user[i]; break; }
    if (x === null) this.init();
    else this.init(x.id, x.uri, x.class_name, x.xml, x.created, x.updated, x.cached, x.language, x.type,
      x.status, x.last_login, x.user_id, x.regy_id, x.comm_id, x.short_name, x.full_name, x.password_salt,
      x.password, x.bits, x.access_from, x.access_to, x.time_value, x.deprec_time, x.user_interface,
      x.letter_format, x.image_type, x.image_data);
  } else {
    this.init(id['id'], id['uri'], id['class_name'], id['xml'], id['created'], id['updated'], id['cached'],
      id['language'], id['type'], id['status'], id['last_login'], id['user_id'], id['regy_id'],
      id['comm_id'], id['short_name'], id['full_name'], id['password_salt'], id['password'], id['bits'],
      id['access_from'], id['access_to'], id['time_value'], id['deprec_time'], id['user_interface'],
      id['letter_format'], id['image_type'], id['image_data']);
  }
}
//
// protected (initializer)
//
VCSH_User.prototype.init = function(id, uri, class_name, xml, created, updated, cached, language, type,
  status, last_login, user_id, regy_id, comm_id, short_name, full_name, password_salt, password, bits,
  access_from, access_to, time_value, deprec_time, user_interface, letter_format, image_type, image_data) {
  VCSH_User.superclass.init.apply(this, arguments);
  this.class_name     = class_name     !== undefined ? class_name     : "VCSHUser";
  this.last_login     = last_login     !== undefined ? last_login     : "";
  this.user_id        = user_id        !== undefined ? user_id        : "";
  this.regy_id        = regy_id        !== undefined ? regy_id        : "";
  this.comm_id        = comm_id        !== undefined ? comm_id        : "";
  this.short_name     = short_name     !== undefined ? short_name     : "";
  this.full_name      = full_name      !== undefined ? full_name      : "";
  this.password_salt  = password_salt  !== undefined ? password_salt  : "";
  this.password       = password       !== undefined ? password       : "";
  this.bits           = bits           !== undefined ? bits           : "";
  this.access_from    = access_from    !== undefined ? access_from    : "";
  this.access_to      = access_to      !== undefined ? access_to      : "";
  this.time_value     = time_value     !== undefined ? time_value     : 20.;
  this.deprec_time    = deprec_time    !== undefined ? deprec_time    : 12.;
  this.user_interface = user_interface !== undefined ? user_interface : "";
  this.letter_format  = letter_format  !== undefined ? letter_format  : "";
  this.image_type     = image_type     !== undefined ? image_type     : "";
  this.image_data     = image_data     !== undefined ? image_data     : "";
};
//
// public
//
VCSH_User.prototype.sprint   = function() { return "VCSH_User {" + this.toString() + "\n}"; };
VCSH_User.prototype.toString = function() {
  var s = VCSH_User.superclass.toString.call(this);
  if (this.last_login     !== undefined) s += "\n  [last_login]     => " + this.last_login;
  if (this.user_id        !== undefined) s += "\n  [user_id]        => " + this.user_id;
  if (this.regy_id        !== undefined) s += "\n  [regy_id]        => " + this.regy_id;
  if (this.comm_id        !== undefined) s += "\n  [comm_id]        => " + this.comm_id;
  if (this.short_name     !== undefined) s += "\n  [short_name]     => " +
                                         ShowPage.htmlentities(Utf8.decode(this.short_name));
  if (this.full_name      !== undefined) s += "\n  [full_name]      => " +
                                         ShowPage.htmlentities(Utf8.decode(this.full_name));
  if (this.password_salt  !== undefined) s += "\n  [password_salt]  => " + this.password_salt;
  if (this.password       !== undefined) s += "\n  [password]       => " + this.password;
  if (this.bits           !== undefined) s += "\n  [bits]           => " +
                                 ShowPage.htmlentities(this.serialize_bits(this.bits));
  if (this.access_from    !== undefined) s += "\n  [access_from]    => " +
                               ShowPage.htmlentities(this.serialize_access(this.access_from));
  if (this.access_to      !== undefined) s += "\n  [access_to]      => " +
                               ShowPage.htmlentities(this.serialize_access(this.access_to));
  if (this.time_value     !== undefined) s += "\n  [time_value]     => " + this.time_value;
  if (this.deprec_time    !== undefined) s += "\n  [deprec_time]    => " + this.deprec_time;
  if (this.user_interface !== undefined) s += "\n  [user_interface] => " + this.user_interface;
  if (this.letter_format  !== undefined) s += "\n  [letter_format]  => " + this.letter_format;
  if (this.image_type     !== undefined) s += "\n  [image_type]     => " + this.image_type;
  if (this.image_data     !== undefined) s += "\n  [image_data]     => (" + typeof this.image_data + ")";
  return s;
};
VCSH_User.prototype.serialize = function() {
  VCSH_User.superclass.serialize.call(this);
  this.bits        = this.serialize_bits(this.bits);
  this.access_from = this.serialize_access(this.access_from);
  this.access_to   = this.serialize_access(this.access_to);
};
VCSH_User.prototype.unserialize = function() {
  VCSH_User.superclass.unserialize.call(this);
  this.bits        = this.unserialize_bits(this.bits);
  this.access_from = this.unserialize_access(this.access_from);
  this.access_to   = this.unserialize_access(this.access_to);
};
VCSH_User.prototype.toXML = function(what) {
  //
  // Generate a CCData XML Stream (XML DOM Document) from a VCSH_User.
  //
  var x = new VCSH_CCData("");
  x.user[this.id] = this;
  return x.toXML(what);
};
VCSH_User.prototype.merge = function(x) {
  //
  // Merge this and x (another VCSH_User) into a VCSH_CCData.
  //
  this.id = "0";
  return x instanceof VCSH_User ?
    (new VCSH_CCData("", {}, {}, {}, { u0 : this }, {}, {})).merge(x) : this;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_ExchangeUser (extends class VCSH_User)                                                  *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_ExchangeUser.prototype = new VCSH_User();
VCSH_ExchangeUser.prototype.constructor = VCSH_ExchangeUser;
VCSH_ExchangeUser.superclass = VCSH_User.prototype;
//
// constructor
//
function VCSH_ExchangeUser(id, uri, type, status,
  last_login, user_id, short_name, full_name, access_from, access_to) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_ExchangeUser) {
    this.init(id.id, id.uri, id.type, id.status,
      id.last_login, id.user_id, id.short_name, id.full_name, id.access_from, id.access_to);
  } else {
    this.init(id['id'], id['uri'], id['type'], id['status'],
      id['last_login'], id['user_id'], id['short_name'], id['full_name'], id['access_from'], id['access_to']);
  }
}
//
// protected (initializer)
//
VCSH_ExchangeUser.prototype.init = function(id, uri, type, status,
  last_login, user_id, short_name, full_name, access_from, access_to) {
  var t = "2000-01-01 00:00:00";
  VCSH_ExchangeUser.superclass.init.call(this, id, uri, "SocialUser", "", t, t, t, "", type, status,
    last_login, user_id, user_id.replace(/^[^\.]*\./,""), "", short_name, full_name,
    "", "", "", access_from, access_to, 20., 12., "full-featured", "plain", "", "");
};
//
// public
//
VCSH_ExchangeUser.prototype.sprint = function() { return "VCSH_ExchangeUser {" + this.toString() + "\n}"; };

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_Flow (extends class VCSH_Data)                                                          *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_Flow.prototype = new VCSH_Data();
VCSH_Flow.prototype.constructor = VCSH_Flow;
VCSH_Flow.superclass = VCSH_Data.prototype;
//
// constructor
//
function VCSH_Flow(id, uri, class_name, xml, created, updated, cached, language, type, status,
  date, give, type1, type2, user_id1, user_id2, comm_id, and_bits, or_bits,
  description, details, note1, note2, value) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_Flow) {
    this.init(id.id, id.uri, id.class_name, id.xml, id.created, id.updated, id.cached, id.language,
      id.type, id.status, id.date, id.give, id.type1, id.type2, id.user_id1, id.user_id2, id.comm_id,
      id.and_bits, id.or_bits, id.description, id.details, id.note1, id.note2, id.value);
  } else if (id.nodeType === 9 || id.nodeType === 11) { // DOM Document or DocumentFragment
    var c = new VCSH_CCData(id), x = null;
    for (var i in c.flow) { x = c.flow[i]; break; }
    if (x === null) this.init();
    else this.init(x.id, x.uri, x.class_name, x.xml, x.created, x.updated, x.cached, x.language,
      x.type, x.status, x.date, x.give, x.type1, x.type2, x.user_id1, x.user_id2, x.comm_id,
      x.and_bits, x.or_bits, x.description, x.details, x.note1, x.note2, x.value);
  } else {
    this.init(id['id'], id['uri'], id['class_name'], id['xml'], id['created'], id['updated'],
      id['cached'], id['language'], id['type'], id['status'], id['date'], id['give'], id['type1'],
      id['type2'], id['user_id1'], id['user_id2'], id['comm_id'], id['and_bits'], id['or_bits'],
      id['description'], id['details'], id['note1'], id['note2'], id['value']);
  }
}
//
// protected (initializer)
//
VCSH_Flow.prototype.init = function(id, uri, class_name, xml, created, updated, cached, language,
  type, status, date, give, type1, type2, user_id1, user_id2, comm_id, and_bits, or_bits,
  description, details, note1, note2, value) {
  VCSH_Flow.superclass.init.apply(this, arguments);
  this.class_name  = class_name  !== undefined ? class_name  : "VCSHFlow";
  this.date        = date        !== undefined ? date        : "";
  this.give        = give        !== undefined ? give        : "";
  this.type1       = type1       !== undefined ? type1       : "";
  this.type2       = type2       !== undefined ? type2       : "";
  this.user_id1    = user_id1    !== undefined ? user_id1    : "";
  this.user_id2    = user_id2    !== undefined ? user_id2    : "";
  this.comm_id     = comm_id     !== undefined ? comm_id     : "";
  this.and_bits    = and_bits    !== undefined ? and_bits    : "";
  this.or_bits     = or_bits     !== undefined ? or_bits     : "";
  this.description = description !== undefined ? description : "";
  this.details     = details     !== undefined ? details     : "";
  this.note1       = note1       !== undefined ? note1       : "";
  this.note2       = note2       !== undefined ? note2       : "";
  this.value       = value       !== undefined ? value       : "";
  var v = this.unserialize_value(this.value),
    c = { 'gain' : ['socap'], 'flow' : ['tcash','ccash','fcash'] };
  for (var j in c) for (var i=0; i<c[j].length; i++) this[c[j][i]] = v[j] !== undefined &&
    v[j] !== null && typeof v[j] == "object" && v[j]["'"+c[j][i]+"'"] !== undefined ?
    v[j]["'"+c[j][i]+"'"] : 0.;
};
//
// public
//
VCSH_Flow.prototype.sprint   = function() { return "VCSH_Flow {" + this.toString() + "\n}"; };
VCSH_Flow.prototype.toString = function() {
  var s = VCSH_Flow.superclass.toString.call(this);
  if (this.date        !== undefined) s += "\n  [date]           => " + this.date;
  if (this.give        !== undefined) s += "\n  [give]           => " + this.give;
  if (this.type1       !== undefined) s += "\n  [type1]          => " + this.type1;
  if (this.type2       !== undefined) s += "\n  [type2]          => " + this.type2;
  if (this.user_id1    !== undefined) s += "\n  [user_id1]       => " + this.user_id1;
  if (this.user_id2    !== undefined) s += "\n  [user_id2]       => " + this.user_id2;
  if (this.comm_id     !== undefined) s += "\n  [comm_id]        => " + this.comm_id;
  if (this.and_bits    !== undefined) s += "\n  [and_bits]       => " +
                              ShowPage.htmlentities(this.serialize_bits(this.and_bits));
  if (this.or_bits     !== undefined) s += "\n  [or_bits]        => " +
                              ShowPage.htmlentities(this.serialize_bits(this.or_bits));
  if (this.description !== undefined) s += "\n  [description]    => " +
                                      ShowPage.htmlentities(Utf8.decode(this.description));
  if (this.details     !== undefined) s += "\n  [details]        => " +
                                      ShowPage.htmlentities(Utf8.decode(this.details));
  if (this.note1       !== undefined) s += "\n  [note1]          => " +
                                      ShowPage.htmlentities(Utf8.decode(this.note1));
  if (this.note2       !== undefined) s += "\n  [note2]          => " +
                                      ShowPage.htmlentities(Utf8.decode(this.note2));
  if (this.value       !== undefined) s += "\n  [value]          => " +
                             ShowPage.htmlentities(this.serialize_value(this.value));
  if (this.socap       !== undefined) s += "\n  [socap]          => " + this.socap;
  if (this.tcash       !== undefined) s += "\n  [tcash]          => " + this.tcash;
  if (this.ccash       !== undefined) s += "\n  [ccash]          => " + this.ccash;
  if (this.fcash       !== undefined) s += "\n  [fcash]          => " + this.fcash;
  return s;
};
VCSH_Flow.prototype.serialize = function() {
  VCSH_Flow.superclass.serialize.call(this);
  this.and_bits = this.serialize_bits(this.and_bits);
  this.or_bits  = this.serialize_bits(this.or_bits);
  this.value    = this.serialize_value(this.value);
};
VCSH_Flow.prototype.unserialize = function() {
  VCSH_Flow.superclass.unserialize.call(this);
  this.and_bits = this.unserialize_bits(this.and_bits);
  this.or_bits  = this.unserialize_bits(this.or_bits);
  this.value    = this.unserialize_value(this.value);
};
VCSH_Flow.prototype.toXML = function(what) {
  //
  // Generate a CCData XML Stream (XML DOM Document) from a VCSH_Flow.
  //
  var x = new VCSH_CCData("");
  x.flow[this.id] = this;
  return x.toXML(what);
};
VCSH_Flow.prototype.merge = function(x) {
  //
  // Merge this and x (another VCSH_Flow) into a VCSH_CCData.
  //
  this.id = "0";
  return x instanceof VCSH_Flow ?
    (new VCSH_CCData("", {}, {}, {}, {}, { f0 : this }, {})).merge(x) : this;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_LETSplayFlow (extends class VCSH_Flow)                                                  *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_LETSplayFlow.prototype = new VCSH_Flow();
VCSH_LETSplayFlow.prototype.constructor = VCSH_LETSplayFlow;
VCSH_LETSplayFlow.superclass = VCSH_Flow.prototype;
//
// constructor
//
function VCSH_LETSplayFlow(id, created, user_id1, user_id2, description, tcash, ccash, fcash) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_LETSplayFlow) {
    this.init(id.id, id.created, id.user_id1, id.user_id2, id.description, id.tcash, id.ccash, id.fcash);
  } else {
    this.init(id['id'], id['created'], id['user_id1'], id['user_id2'], id['description'], id['tcash'],
      id['ccash'], id['fcash']);
  }
}
//
// protected (initializer)
//
VCSH_LETSplayFlow.prototype.init = function(id, created, user_id1, user_id2, description, tcash, ccash,
  fcash) {
  var t = "2000-01-01 00:00:00", d = "2000-01-01";
  VCSH_LETSplayFlow.superclass.init.call(this, id, "", "SocialFlow", "", created, t, t, "en", "trade",
    "accepted", d, false, "individual", "individual", user_id1, user_id2, "", "", "", description, "",
    "", "", { tcash : tcash, ccash : ccash, fcash : fcash });
};

//
// class VCSH_MutualCreditFlow extends VCSH_Flow
//
VCSH_MutualCreditFlow.prototype = new VCSH_Flow();
VCSH_MutualCreditFlow.prototype.constructor = VCSH_MutualCreditFlow;
VCSH_MutualCreditFlow.superclass = VCSH_Flow.prototype;
//
// constructor
//
function VCSH_MutualCreditFlow(id, uri, class_name, xml, created, updated, cached, language, type, status,
 date, give, user_id1, user_id2, description, ccash) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_MutualCreditFlow) {
    this.init(id.id, id.uri, id.class_name, id.xml, id.created, id.updated, id.cached, id.language,
      id.type, id.status, id.date, id.give, id.user_id1, id.user_id2, id.description, id.ccash);
  } else {
    this.init(id['id'], id['uri'], id['class_name'], id['xml'], id['created'], id['updated'], id['cached'],
      id['language'], id['type'], id['status'], id['date'], id['give'], id['user_id1'], id['user_id2'],
      id['description'], id['ccash']);
  }
}
//
// protected (initializer)
//
VCSH_MutualCreditFlow.prototype.init = function(id, uri, class_name, xml, created, updated, cached,
  language, type, status, date, give, user_id1, user_id2, description, ccash) {
  VCSH_MutualCreditFlow.superclass.init.call(this, id, uri, class_name, xml, created, updated, cached,
    language, type, status, date, give, "individual", "individual", user_id1, user_id2, "", "", "",
    description, "", "", "", { ccash : ccash });
};
//
// public
//
VCSH_MutualCreditFlow.prototype.sprint = function() { return "VCSH_MutualCreditFlow {" + this.toString() + "\n}"; };

//
// class VCSH_ExchangeFlow extends VCSH_Flow
//
VCSH_ExchangeFlow.prototype = new VCSH_Flow();
VCSH_ExchangeFlow.prototype.constructor = VCSH_ExchangeFlow;
VCSH_ExchangeFlow.superclass = VCSH_Flow.prototype;
//
// constructor
//
function VCSH_ExchangeFlow(id, uri, type, status, date, user_id1, user_id2, comm_id, description, ccash) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_ExchangeFlow) {
    this.init(id.id, id.uri, id.type, id.status, id.date, id.user_id1, id.user_id2,
      id.comm_id, id.description, id.ccash);
  } else {
    this.init(id['id'], id['uri'], id['type'], id['status'], id['date,'], id['user_id1'], id['user_id2'],
      id['comm_id'], id['description'], id['ccash']);
  }
}
//
// protected (initializer)
//
VCSH_ExchangeFlow.prototype.init = function(id, uri, type, status, date, user_id1, user_id2, comm_id,
  description, ccash) {
  var t = "2000-01-01 00:00:00";
  VCSH_ExchangeFlow.superclass.init.call(this, id, uri, "SocialFlow", "", t, t, t, "en", type, status,
    date, false, "individual", "individual", user_id1, user_id2, comm_id, "", "", description, "",
    "", "", { ccash : ccash });
};
//
// public
//
VCSH_ExchangeFlow.prototype.sprint = function() { return "VCSH_ExchangeFlow {" + this.toString() + "\n}"; };

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_Text (extends class VCSH_Data)                                                          *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_Text.prototype = new VCSH_Data();
VCSH_Text.prototype.constructor = VCSH_Text;
VCSH_Text.superclass = VCSH_Data.prototype;
//
// constructor
//
function VCSH_Text(id, uri, class_name, xml, created, updated, cached, language, type, status,
  section, block, user_id1, user_id2, title, content) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_Text) {
    this.init(id.id, id.uri, id.class_name, id.xml, id.created, id.updated, id.cached, id.language,
      id.type, id.status, id.section, id.block, id.user_id1, id.user_id2, id.title, id.content);
  } else if (id.nodeType === 9 || id.nodeType === 11) { // DOM Document or DocumentFragment
    var c = new VCSH_CCData(id), x = null;
    for (var i in c.text) { x = c.text[i]; break; }
    if (x === null) this.init();
    else this.init(x.id, x.uri, x.class_name, x.xml, x.created, x.updated, x.cached, x.language,
      x.type, x.status, x.section, x.block, x.user_id1, x.user_id2, x.title, x.content);
  } else {
    this.init(id['id'], id['uri'], id['class_name'], id['xml'], id['created'], id['updated'], id['cached'],
      id['language'], id['type'], id['status'], id['section'], id['block'], id['user_id1'], id['user_id2'],
      id['title'], id['content']);
  }
}
//
// protected (initializer)
//
VCSH_Text.prototype.init = function(id, uri, class_name, xml, created, updated, cached, language,
  type, status, section, block, user_id1, user_id2, title, content) {
  VCSH_Text.superclass.init.apply(this, arguments);
  this.class_name = class_name !== undefined ? class_name : "VCSHText";
  this.section    = section    !== undefined ? section    : "";
  this.block      = block      !== undefined ? block      : "";
  this.user_id1   = user_id1   !== undefined ? user_id1   : "";
  this.user_id2   = user_id2   !== undefined ? user_id2   : "";
  this.title      = title      !== undefined ? title      : "";
  this.content    = content    !== undefined ? content    : "";
};
//
// public
//
VCSH_Text.prototype.sprint   = function() { return "VCSH_Text {" + this.toString() + "\n}"; };
VCSH_Text.prototype.toString = function() {
  var s = VCSH_Text.superclass.toString.call(this);
  if (this.section  !== undefined) s += "\n  [section]        => " + this.section;
  if (this.block    !== undefined) s += "\n  [block]          => " + this.block;
  if (this.user_id1 !== undefined) s += "\n  [user_id1]       => " + this.user_id1;
  if (this.user_id2 !== undefined) s += "\n  [user_id2]       => " + this.user_id2;
  if (this.title    !== undefined) s += "\n  [title]          => " +
                                   ShowPage.htmlentities(Utf8.decode(this.title));
  if (this.content  !== undefined) s += "\n  [content]        => " +
                                   ShowPage.htmlentities(Utf8.decode(this.content));
  return s;
};
VCSH_Text.prototype.toXML = function(what) {
  //
  // Generate a CCData XML Stream (XML DOM Document) from a VCSH_Text.
  //
  var x = new VCSH_CCData("");
  x.text[this.id] = this;
  return x.toXML(what);
};
VCSH_Text.prototype.merge = function(x) {
  //
  // Merge this and x (another VCSH_Text) into a VCSH_CCData.
  //
  this.id = "0";
  return x instanceof VCSH_Text ?
    (new VCSH_CCData("", {}, {}, {}, {}, {}, { t0 : this })).merge(x) : this;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_ExchangeText (extends class VCSH_Text)                                                  *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_ExchangeText.prototype = new VCSH_Text();
VCSH_ExchangeText.prototype.constructor = VCSH_ExchangeText;
VCSH_ExchangeText.superclass = VCSH_Text.prototype;
//
// constructor
//
function VCSH_ExchangeText(id, uri, updated, status, section, block, user_id1, user_id2, title) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_ExchangeText) {
    this.init(id.id, id.uri, id.updated, id.status, id.section, id.block,
    id.user_id1, id.user_id2, id.title);
  } else {
    this.init(id['id'], id['uri'], id['updated'], id['status'], id['section'], id['block'],
      id['user_id1'], id['user_id2'], id['title']);
  }
}
//
// protected (initializer)
//
VCSH_ExchangeText.prototype.init = function(id, uri, updated, status, section, block, user_id1, user_id2,
  title) {
  var t = "2000-01-01 00:00:00";
  VCSH_ExchangeText.superclass.init.call(this, id, uri, "SocialText", "", t, updated, t, "",
    "html", status, section, block, user_id1, user_id2, title, "");
};
//
// public
//
VCSH_ExchangeText.prototype.sprint = function() { return "VCSH_ExchangeText {" + this.toString() + "\n}"; };

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_ValueItem (extends class VCSH_Text)                                                     *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_ValueItem.prototype = new VCSH_Text();
VCSH_ValueItem.prototype.constructor = VCSH_ValueItem;
VCSH_ValueItem.superclass = VCSH_Text.prototype;
//
// constructor
//
function VCSH_ValueItem(id, uri, class_name, xml, created, updated, cached, language, type, status,
  section, block, user_id1, user_id2, title, content, value) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_ValueItem) {
    this.init(id.id, id.uri, id.class_name, id.xml, id.created, id.updated, id.cached, id.language,
      id.type, id.status, id.section, id.block, id.user_id1, id.user_id2, id.title, id.content, id.value);
  } else {
    this.init(id['id'], id['uri'], id['class_name'], id['xml'], id['created'], id['updated'], id['cached'],
      id['language'], id['type'], id['status'], id['section'], id['block'], id['user_id1'], id['user_id2'],
      id['title'], id['content'], id['value']);
  }
}
//
// protected (initializer)
//
VCSH_ValueItem.prototype.init = function(id, uri, class_name, xml, created, updated, cached, language,
  type, status, section, block, user_id1, user_id2, title, content, value) {
  VCSH_ValueItem.superclass.init.apply(this, arguments);
  this.value = value !== undefined ? value  : "";
  var v = this.unserialize_value(this.value), c = { 'flow' : ['tcash','ccash','fcash'] };
  for (var j in c) for (var i=0; i<c[j].length; i++) this[c[j][i]] = v[j] !== undefined &&
    v[j] !== null && typeof v[j] == "object" && v[j]["'"+c[j][i]+"'"] !== undefined ?
    v[j]["'"+c[j][i]+"'"] : 0.;
};
//
// public
//
VCSH_ValueItem.prototype.sprint   = function() { return "VCSH_ValueItem {" + this.toString() + "\n}"; };
VCSH_ValueItem.prototype.toString = function() {
  var s = VCSH_ValueItem.superclass.toString.call(this);
  if (this.value !== undefined) s += "\n  [value]          => " +
                       ShowPage.htmlentities(this.serialize_value(this.value));
  if (this.tcash !== undefined) s += "\n  [tcash]          => " + this.tcash;
  if (this.ccash !== undefined) s += "\n  [ccash]          => " + this.ccash;
  if (this.fcash !== undefined) s += "\n  [fcash]          => " + this.fcash;
  return s;
};
VCSH_ValueItem.prototype.serialize = function() {
  VCSH_ValueItem.superclass.serialize.call(this);
  this.value = this.serialize_value(this.value);
};
VCSH_ValueItem.prototype.unserialize = function() {
  VCSH_ValueItem.superclass.unserialize.call(this);
  this.value = this.unserialize_value(this.value);
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Class VCSH_LETSplayItem (extends class VCSH_ValueItem)                                             *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_LETSplayItem.prototype = new VCSH_ValueItem();
VCSH_LETSplayItem.prototype.constructor = VCSH_LETSplayItem;
VCSH_LETSplayItem.superclass = VCSH_ValueItem.prototype;
//
// constructor
//
function VCSH_LETSplayItem(id, uri, class_name, xml, created, updated, cached, language, type, status,
  section, block, user_id1, user_id2, title, content, value, local, stars) {
  if (arguments.length == 0 || id === null) {
  } else if (typeof id != "object") {
    this.init.apply(this, arguments);
  } else if (id instanceof VCSH_LETSplayItem) {
    this.init(id.id, id.uri, id.class_name, id.xml, id.created, id.updated, id.cached, id.language,
      id.type, id.status, id.section, id.block, id.user_id1, id.user_id2, id.title, id.content, id.value,
      id.local, id.stars);
  } else {
    this.init(id['id'], id['uri'], id['class_name'], id['xml'], id['created'], id['updated'], id['cached'],
      id['language'], id['type'], id['status'], id['section'], id['block'], id['user_id1'], id['user_id2'],
      id['title'], id['content'], id['value'], id['local'], id['stars']);
  }
}
//
// protected (initializer)
//
VCSH_LETSplayItem.prototype.init = function(id, uri, class_name, xml, created, updated, cached, language,
  type, status, section, block, user_id1, user_id2, title, content, value, local, stars) {
  VCSH_LETSplayItem.superclass.init.apply(this, arguments);
  this.local = local !== undefined ? local : "";
  this.stars = stars !== undefined ? stars : "";
};
//
// public
//
VCSH_LETSplayItem.prototype.sprint   = function() { return "VCSH_LETSplayItem {" + this.toString() + "\n}"; };
VCSH_LETSplayItem.prototype.toString = function() {
  var s = VCSH_LETSplayItem.superclass.toString.call(this);
  if (this.local !== undefined) s += "\n  [local]          => " + this.local;
  if (this.stars !== undefined) s += "\n  [stars]          => " + this.stars;
  return s;
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Comparison functions (static members of various classes)                                           *
// *                                                                                                    *
// ******************************************************************************************************
//
// *.compare_id(a, b)
//
VCSH_Data.compare_id         =
VCSH_User.compare_id         =
VCSH_ExchangeUser.compare_id =
VCSH_Flow.compare_id         =
VCSH_LETSplayFlow.compare_id =
VCSH_ExchangeFlow.compare_id =
VCSH_Text.compare_id         =
VCSH_ValueItem.compare_id    =
VCSH_LETSplayItem.compare_id =
function(a, b) {
  return a.id - b.id;
};
//
// *.compare_uri(a, b)
//
VCSH_Data.compare_uri         =
VCSH_User.compare_uri         =
VCSH_ExchangeUser.compare_uri =
VCSH_Flow.compare_uri         =
VCSH_LETSplayFlow.compare_uri =
VCSH_ExchangeFlow.compare_uri =
VCSH_Text.compare_uri         =
VCSH_ValueItem.compare_uri    =
VCSH_LETSplayItem.compare_uri =
function(a, b) {
  var a_c = a.uri.lastIndexOf('/');
  if (a_c >= 0) {
    var a_1 = a.uri.substring(0, a_c).toLowerCase(); a_2 = a.uri.substring(a_c + 1).toLowerCase();
  } else {
    var a_1 = a.uri.toLowerCase(); a_2 = '0';
  }
  var b_c = b.uri.lastIndexOf('/');
  if (b_c >= 0) {
    var b_1 = b.uri.substring(0, b_c).toLowerCase(); b_2 = b.uri.substring(b_c + 1).toLowerCase();
  } else {
    var b_1 = b.uri.toLowerCase(); b_2 = '0';
  }
  while (a_2.length < b_2.length) a_2 = '0' + a_2;
  while (b_2.length < a_2.length) b_2 = '0' + b_2;
  var c_1 = a_1 < b_1 ? -1 : a_1 > b_1 ? 1 : 0;
  var c_2 = a_2 < b_2 ? -1 : a_2 > b_2 ? 1 : 0;
  return c_1 ? c_1 : c_2 ? c_2 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_class_name(a, b)
//
VCSH_Data.compare_class_name         =
VCSH_User.compare_class_name         =
VCSH_ExchangeUser.compare_class_name =
VCSH_Flow.compare_class_name         =
VCSH_LETSplayFlow.compare_class_name =
VCSH_ExchangeFlow.compare_class_name =
VCSH_Text.compare_class_name         =
VCSH_ValueItem.compare_class_name    =
VCSH_LETSplayItem.compare_class_name =
function(a, b) {
  var a_class_name = a.class_name.toLowerCase();
  var b_class_name = b.class_name.toLowerCase();
  return a_class_name < b_class_name ? -1 :
         a_class_name > b_class_name ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_xml(a, b)
//
VCSH_Data.compare_xml         =
VCSH_User.compare_xml         =
VCSH_ExchangeUser.compare_xml =
VCSH_Flow.compare_xml         =
VCSH_LETSplayFlow.compare_xml =
VCSH_ExchangeFlow.compare_xml =
VCSH_Text.compare_xml         =
VCSH_ValueItem.compare_xml    =
VCSH_LETSplayItem.compare_xml =
function(a, b) {
  var a_xml = a.xml.toLowerCase();
  var b_xml = b.xml.toLowerCase();
  return a_xml < b_xml ? -1 :
         a_xml > b_xml ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_created(a, b)
//
VCSH_Data.compare_created         =
VCSH_User.compare_created         =
VCSH_ExchangeUser.compare_created =
VCSH_Flow.compare_created         =
VCSH_LETSplayFlow.compare_created =
VCSH_ExchangeFlow.compare_created =
VCSH_Text.compare_created         =
VCSH_ValueItem.compare_created    =
VCSH_LETSplayItem.compare_created =
function(a, b) {
  var a_date = VCSH_Data.Date(a.created);
  var b_date = VCSH_Data.Date(b.created);
  return a_date < b_date ? -1 :
         a_date > b_date ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_updated(a, b)
//
VCSH_Data.compare_updated         =
VCSH_User.compare_updated         =
VCSH_ExchangeUser.compare_updated =
VCSH_Flow.compare_updated         =
VCSH_LETSplayFlow.compare_updated =
VCSH_ExchangeFlow.compare_updated =
VCSH_Text.compare_updated         =
VCSH_ExchangeText.compare_updated =
VCSH_ValueItem.compare_updated    =
VCSH_LETSplayItem.compare_updated =
function(a, b) {
  var a_date = VCSH_Data.Date(a.updated);
  var b_date = VCSH_Data.Date(b.updated);
  return a_date < b_date ? -1 :
         a_date > b_date ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_cached(a, b)
//
VCSH_Data.compare_cached         =
VCSH_User.compare_cached         =
VCSH_ExchangeUser.compare_cached =
VCSH_Flow.compare_cached         =
VCSH_LETSplayFlow.compare_cached =
VCSH_ExchangeFlow.compare_cached =
VCSH_Text.compare_cached         =
VCSH_ValueItem.compare_cached    =
VCSH_LETSplayItem.compare_cached =
function(a, b) {
  var a_date = VCSH_Data.Date(a.cached);
  var b_date = VCSH_Data.Date(b.cached);
  return a_date < b_date ? -1 :
         a_date > b_date ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_language(a, b)
//
VCSH_Data.compare_language         =
VCSH_User.compare_language         =
VCSH_ExchangeUser.compare_language =
VCSH_Flow.compare_language         =
VCSH_LETSplayFlow.compare_language =
VCSH_ExchangeFlow.compare_language =
VCSH_Text.compare_language         =
VCSH_ValueItem.compare_language    =
VCSH_LETSplayItem.compare_language =
function(a, b) {
  var a_language = a.language.toLowerCase();
  var b_language = b.language.toLowerCase();
  return a_language < b_language ? -1 :
         a_language > b_language ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_type(a, b)
//
VCSH_Data.compare_type         =
VCSH_User.compare_type         =
VCSH_ExchangeUser.compare_type =
VCSH_Flow.compare_type         =
VCSH_LETSplayFlow.compare_type =
VCSH_ExchangeFlow.compare_type =
VCSH_Text.compare_type         =
VCSH_ValueItem.compare_type    =
VCSH_LETSplayItem.compare_type =
function(a, b) {
  var a_type = a.type.toLowerCase();
  var b_type = b.type.toLowerCase();
  return a_type < b_type ? -1 :
         a_type > b_type ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_status(a, b)
//
VCSH_Data.compare_status             =
VCSH_User.compare_status             =
VCSH_ExchangeUser.compare_status     =
VCSH_Flow.compare_status             =
VCSH_LETSplayFlow.compare_status     =
VCSH_MutualCreditFlow.compare_status =
VCSH_ExchangeFlow.compare_status     =
VCSH_Text.compare_status             =
VCSH_ExchangeText.compare_status     =
VCSH_ValueItem.compare_status        =
VCSH_LETSplayItem.compare_status     =
function(a, b) {
  var a_status = a.status.toLowerCase();
  var b_status = b.status.toLowerCase();
  return a_status < b_status ? -1 :
         a_status > b_status ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_last_login(a, b)
//
VCSH_User.compare_last_login         =
VCSH_ExchangeUser.compare_last_login =
function(a, b) {
  var a_date = VCSH_Data.Date(a.last_login);
  var b_date = VCSH_Data.Date(b.last_login);
  return a_date < b_date ? -1 :
         a_date > b_date ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_user_id(a, b)
//
VCSH_User.compare_user_id         =
VCSH_ExchangeUser.compare_user_id =
function(a, b) {
  var a_user_id = a.user_id.toLowerCase();
  var b_user_id = b.user_id.toLowerCase();
  return a_user_id < b_user_id ? -1 :
         a_user_id > b_user_id ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_regy_id(a, b)
//
VCSH_User.compare_regy_id         =
VCSH_Flow.compare_regy_id         =
VCSH_ExchangeFlow.compare_regy_id =
function(a, b) {
  var a_regy_id = a.regy_id.toLowerCase();
  var b_regy_id = b.regy_id.toLowerCase();
  return a_regy_id < b_regy_id ? -1 :
         a_regy_id > b_regy_id ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_comm_id(a, b)
//
VCSH_User.compare_comm_id         =
VCSH_Flow.compare_comm_id         =
VCSH_ExchangeFlow.compare_comm_id =
function(a, b) {
  var a_comm_id = a.comm_id.toLowerCase();
  var b_comm_id = b.comm_id.toLowerCase();
  return a_comm_id < b_comm_id ? -1 :
         a_comm_id > b_comm_id ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_short_name(a, b)
//
VCSH_User.compare_short_name         =
VCSH_ExchangeUser.compare_short_name =
function(a, b) {
  var a_short_name = a.short_name.toLowerCase();
  var b_short_name = b.short_name.toLowerCase();
  return a_short_name < b_short_name ? -1 :
         a_short_name > b_short_name ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_full_name(a, b)
//
VCSH_User.compare_full_name         =
VCSH_ExchangeUser.compare_full_name =
function(a, b) {
  var a_full_name = a.full_name.toLowerCase();
  var b_full_name = b.full_name.toLowerCase();
  return a_full_name < b_full_name ? -1 :
         a_full_name > b_full_name ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_password_salt(a, b)
//
VCSH_User.compare_password_salt =
function(a, b) {
  var a_password_salt = a.password_salt.toLowerCase();
  var b_password_salt = b.password_salt.toLowerCase();
  return a_password_salt < b_password_salt ? -1 :
         a_password_salt > b_password_salt ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_password(a, b)
//
VCSH_User.compare_password =
function(a, b) {
  var a_password = a.password.toLowerCase();
  var b_password = b.password.toLowerCase();
  return a_password < b_password ? -1 :
         a_password > b_password ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_bits(a, b)
//
VCSH_User.compare_bits =
function(a, b) {
  return a.bits < b.bits ? -1 :
         a.bits > b.bits ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_access_from(a, b)
//
VCSH_User.compare_access_from         =
VCSH_ExchangeUser.compare_access_from =
function(a, b) {
  var a_access_from = a.access_from.toLowerCase();
  var b_access_from = b.access_from.toLowerCase();
  return a_access_from < b_access_from ? -1 :
         a_access_from > b_access_from ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_access_to(a, b)
//
VCSH_User.compare_access_to         =
VCSH_ExchangeUser.compare_access_to =
function(a, b) {
  var a_access_to = a.access_to.toLowerCase();
  var b_access_to = b.access_to.toLowerCase();
  return a_access_to < b_access_to ? -1 :
         a_access_to > b_access_to ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_time_value(a, b)
//
VCSH_User.compare_time_value =
function(a, b) {
  var time_value = a.time_value - b.time_value;
  return time_value ? time_value : VCSH_Data.compare_id(a, b);
};
//
// *.compare_deprec_time(a, b)
//
VCSH_User.compare_deprec_time =
function(a, b) {
  var deprec_time = a.deprec_time - b.deprec_time;
  return deprec_time ? deprec_time : VCSH_Data.compare_id(a, b);
};
//
// *.compare_user_interface(a, b)
//
VCSH_User.compare_user_interface =
function(a, b) {
  var a_user_interface = a.user_interface.toLowerCase();
  var b_user_interface = b.user_interface.toLowerCase();
  return a_user_interface < b_user_interface ? -1 :
         a_user_interface > b_user_interface ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_letter_format(a, b)
//
VCSH_User.compare_letter_format =
function(a, b) {
  var a_letter_format = a.letter_format.toLowerCase();
  var b_letter_format = b.letter_format.toLowerCase();
  return a_letter_format < b_letter_format ? -1 :
         a_letter_format > b_letter_format ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_image_type(a, b)
//
VCSH_User.compare_image_type =
function(a, b) {
  var a_image_type = a.image_type.toLowerCase();
  var b_image_type = b.image_type.toLowerCase();
  return a_image_type < b_image_type ? -1 :
         a_image_type > b_image_type ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_date(a, b)
//
VCSH_Flow.compare_date             =
VCSH_MutualCreditFlow.compare_date =
VCSH_ExchangeFlow.compare_date     =
function(a, b) {
  var a_date = VCSH_Data.Date(a.date);
  var b_date = VCSH_Data.Date(b.date);
  return a_date < b_date ? -1 :
         a_date > b_date ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_give(a, b)
//
VCSH_Flow.compare_give =
function(a, b) {
  var give = b.give - a.give;
  return give ? give : VCSH_Data.compare_id(a, b);
};
//
// *.compare_type1(a, b)
//
VCSH_Flow.compare_type1 =
function(a, b) {
  var a_type = a.type1.toLowerCase();
  var b_type = b.type1.toLowerCase();
  return a_type < b_type ? -1 :
         a_type > b_type ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_type2(a, b)
//
VCSH_Flow.compare_type2 =
function(a, b) {
  var a_type = a.type2.toLowerCase();
  var b_type = b.type2.toLowerCase();
  return a_type < b_type ? -1 :
         a_type > b_type ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_type11(a, b)
//
VCSH_Flow.compare_type11 =
function(a, b) {
  var a_type = a.type1.toLowerCase();
  var b_type = b.type1.toLowerCase();
  return a_type < b_type ? -1 :
         a_type > b_type ?  1 : 0;
};
//
// *.compare_type12(a, b)
//
VCSH_Flow.compare_type12 =
function(a, b) {
  var a_type = a.type1.toLowerCase();
  var b_type = b.type2.toLowerCase();
  return a_type < b_type ? -1 :
         a_type > b_type ?  1 : 0;
};
//
// *.compare_type21(a, b)
//
VCSH_Flow.compare_type21 =
function(a, b) {
  var a_type = a.type2.toLowerCase();
  var b_type = b.type1.toLowerCase();
  return a_type < b_type ? -1 :
         a_type > b_type ?  1 : 0;
};
//
// *.compare_type22(a, b)
//
VCSH_Flow.compare_type22 =
function(a, b) {
  var a_type = a.type2.toLowerCase();
  var b_type = b.type2.toLowerCase();
  return a_type < b_type ? -1 :
         a_type > b_type ?  1 : 0;
};
//
// *.compare_ac_types(a, b)
//
VCSH_Flow.compare_ac_types =
function(a, b) {
  var type11 = VCSH_Flow.compare_type11(a, b);
  var type12 = VCSH_Flow.compare_type12(a, b);
  var type21 = VCSH_Flow.compare_type21(a, b);
  var type22 = VCSH_Flow.compare_type22(a, b);
  return (type11 == 0 && type22 != 0) ? type22 :
         (type12 == 0 && type21 != 0) ? type21 :
         (type21 == 0 && type12 != 0) ? type12 :
         (type22 == 0 && type11 != 0) ? type11 :
         (type11 <  0 && type12 <  0) ? -1 :
         (type21 <  0 && type22 <  0) ? -1 :
         (type11 >  0 && type21 >  0) ?  1 :
         (type12 >  0 && type22 >  0) ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_user_id1(a, b)
//
VCSH_Flow.compare_user_id1             =
VCSH_LETSplayFlow.compare_user_id1     =
VCSH_MutualCreditFlow.compare_user_id1 =
VCSH_ExchangeFlow.compare_user_id1     =
VCSH_Text.compare_user_id1             =
VCSH_ExchangeText.compare_user_id1     =
VCSH_ValueItem.compare_user_id1        =
VCSH_LETSplayItem.compare_user_id1     =
function(a, b) {
  var a_user_id = a.user_id1.toLowerCase();
  var b_user_id = b.user_id1.toLowerCase();
  return a_user_id < b_user_id ? -1 :
         a_user_id > b_user_id ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_user_id2(a, b)
//
VCSH_Flow.compare_user_id2             =
VCSH_LETSplayFlow.compare_user_id2     =
VCSH_MutualCreditFlow.compare_user_id2 =
VCSH_ExchangeFlow.compare_user_id2     =
VCSH_Text.compare_user_id2             =
VCSH_ExchangeText.compare_user_id2     =
VCSH_ValueItem.compare_user_id2        =
VCSH_LETSplayItem.compare_user_id2     =
function(a, b) {
  var a_user_id = a.user_id2.toLowerCase();
  var b_user_id = b.user_id2.toLowerCase();
  return a_user_id < b_user_id ? -1 :
         a_user_id > b_user_id ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_user_id11(a, b)
//
VCSH_Data.compare_user_id11 =
function(a, b) {
  var a_user_id = a.user_id1.toLowerCase();
  var b_user_id = b.user_id1.toLowerCase();
  return a_user_id < b_user_id ? -1 :
         a_user_id > b_user_id ?  1 : 0;
};
//
// *.compare_user_id12(a, b)
//
VCSH_Data.compare_user_id12 =
function(a, b) {
  var a_user_id = a.user_id1.toLowerCase();
  var b_user_id = b.user_id2.toLowerCase();
  return a_user_id < b_user_id ? -1 :
         a_user_id > b_user_id ?  1 : 0;
};
//
// *.compare_user_id21(a, b)
//
VCSH_Data.compare_user_id21 =
function(a, b) {
  var a_user_id = a.user_id2.toLowerCase();
  var b_user_id = b.user_id1.toLowerCase();
  return a_user_id < b_user_id ? -1 :
         a_user_id > b_user_id ?  1 : 0;
};
//
// *.compare_user_id_22(a, b)
//
VCSH_Data.compare_user_id22 =
function(a, b) {
  var a_user_id = a.user_id2.toLowerCase();
  var b_user_id = b.user_id2.toLowerCase();
  return a_user_id < b_user_id ? -1 :
         a_user_id > b_user_id ?  1 : 0;
};
//
// *.compare_user_ids(a, b)
//
VCSH_Flow.compare_user_ids         =
VCSH_LETSplayFlow.compare_user_ids =
VCSH_ExchangeFlow.compare_user_ids =
VCSH_Text.compare_user_ids         =
VCSH_ExchangeText.compare_user_ids =
VCSH_ValueItem.compare_user_ids    =
VCSH_LETSplayItem.compare_user_ids =
function(a, b) {
  var user_id11 = VCSH_Data.compare_user_id11(a, b);
  var user_id12 = VCSH_Data.compare_user_id12(a, b);
  var user_id21 = VCSH_Data.compare_user_id21(a, b);
  var user_id22 = VCSH_Data.compare_user_id22(a, b);
  return (user_id11 == 0 && user_id22 != 0) ? user_id22 :
         (user_id12 == 0 && user_id21 != 0) ? user_id21 :
         (user_id21 == 0 && user_id12 != 0) ? user_id12 :
         (user_id22 == 0 && user_id11 != 0) ? user_id11 :
         (user_id11 <  0 && user_id12 <  0) ? -1 :
         (user_id21 <  0 && user_id22 <  0) ? -1 :
         (user_id11 >  0 && user_id21 >  0) ?  1 :
         (user_id12 >  0 && user_id22 >  0) ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_and_bits(a, b)
//
VCSH_Flow.compare_and_bits =
function(a, b) {
  return a.and_bits < b.and_bits ? -1 :
         a.and_bits > b.and_bits ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_or_bits(a, b)
//
VCSH_Flow.compare_or_bits =
function(a, b) {
  return a.or_bits < b.or_bits ? -1 :
         a.or_bits > b.or_bits ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_description(a, b)
//
VCSH_Flow.compare_description             =
VCSH_LETSplayFlow.compare_description     =
VCSH_MutualCreditFlow.compare_description =
VCSH_ExchangeFlow.compare_description     =
function(a, b) {
  var a_description = a.description.toLowerCase();
  var b_description = b.description.toLowerCase();
  return a_description < b_description ? -1 :
         a_description > b_description ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_details(a, b)
//
VCSH_Flow.compare_details =
function(a, b) {
  var a_details = a.details.toLowerCase();
  var b_details = b.details.toLowerCase();
  return a_details < b_details ? -1 :
         a_details > b_details ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_note1(a, b)
//
VCSH_Flow.compare_note1 =
function(a, b) {
  var a_note1 = a.note1.toLowerCase();
  var b_note1 = b.note1.toLowerCase();
  return a_note1 < b_note1 ? -1 :
         a_note1 > b_note1 ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_note2(a, b)
//
VCSH_Flow.compare_note2 =
function(a, b) {
  var a_note2 = a.note2.toLowerCase();
  var b_note2 = b.note2.toLowerCase();
  return a_note2 < b_note2 ? -1 :
         a_note2 > b_note2 ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_value(a, b)
//
VCSH_Flow.compare_value =
function(a, b) {
  var a_value = a.value.toLowerCase();
  var b_value = b.value.toLowerCase();
  return a_value < b_value ? -1 :
         a_value > b_value ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_socap(a, b)
//
VCSH_Flow.compare_socap =
function(a, b) {
  var socap = a.socap - b.socap;
  return socap ? socap : VCSH_Data.compare_id(a, b);
};
//
// *.compare_tcash(a, b)
//
VCSH_Flow.compare_tcash         =
VCSH_LETSplayFlow.compare_tcash =
VCSH_ValueItem.compare_tcash    =
VCSH_LETSplayItem.compare_tcash =
function(a, b) {
  var tcash = a.tcash - b.tcash;
  return tcash ? tcash : VCSH_Data.compare_id(a, b);
};
//
// *.compare_ccash(a, b)
//
VCSH_Flow.compare_ccash             =
VCSH_LETSplayFlow.compare_ccash     =
VCSH_MutualCreditFlow.compare_ccash =
VCSH_ExchangeFlow.compare_ccash     =
VCSH_ValueItem.compare_ccash        =
VCSH_LETSplayItem.compare_ccash     =
function(a, b) {
  var ccash = a.ccash - b.ccash;
  return ccash ? ccash : VCSH_Data.compare_id(a, b);
};
//
// *.compare_fcash(a, b)
//
VCSH_Flow.compare_fcash         =
VCSH_LETSplayFlow.compare_fcash =
VCSH_ValueItem.compare_fcash    =
VCSH_LETSplayItem.compare_fcash =
function(a, b) {
  var fcash = a.fcash - b.fcash;
  return fcash ? fcash : VCSH_Data.compare_id(a, b);
};
//
// *.compare_section(a, b)
//
VCSH_Text.compare_section         =
VCSH_ExchangeText.compare_section =
VCSH_ValueItem.compare_section    =
VCSH_LETSplayItem.compare_section =
function(a, b) {
  var a_section = a.section.toLowerCase();
  var b_section = b.section.toLowerCase();
  return a_section < b_section ? -1 :
         a_section > b_section ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_block(a, b)
//
VCSH_Text.compare_block         =
VCSH_ExchangeText.compare_block =
VCSH_ValueItem.compare_block    =
VCSH_LETSplayItem.compare_block =
function(a, b) {
  var a_block = a.block.toLowerCase();
  var b_block = b.block.toLowerCase();
  return a_block < b_block ? -1 :
         a_block > b_block ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_title(a, b)
//
VCSH_Text.compare_title         =
VCSH_ExchangeText.compare_title =
VCSH_ValueItem.compare_title    =
VCSH_LETSplayItem.compare_title =
function(a, b) {
  var a_title = a.title.toLowerCase();
  var b_title = b.title.toLowerCase();
  return a_title < b_title ? -1 :
         a_title > b_title ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_content(a, b)
//
VCSH_Text.compare_content         =
VCSH_ExchangeText.compare_content =
VCSH_ValueItem.compare_content    =
VCSH_LETSplayItem.compare_content =
function(a, b) {
  var a_content = a.content.toLowerCase();
  var b_content = b.content.toLowerCase();
  return a_content < b_content ? -1 :
         a_content > b_content ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_value(a, b)
//
VCSH_ValueItem.compare_value    =
VCSH_LETSplayItem.compare_value =
function(a, b) {
  var a_value = a.value.toLowerCase();
  var b_value = b.value.toLowerCase();
  return a_value < b_value ? -1 :
         a_value > b_value ?  1 :
         VCSH_Data.compare_id(a, b);
};
//
// *.compare_local(a, b)
//
VCSH_LETSplayItem.compare_local =
function(a, b) {
  var local = a.local - b.local;
  return local ? local : VCSH_Data.compare_id(a, b);
};
//
// *.compare_stars(a, b)
//
VCSH_LETSplayItem.compare_stars =
function(a, b) {
  var stars = a.stars - b.stars;
  return stars ? stars : VCSH_Data.compare_id(a, b);
};

//
// ******************************************************************************************************
// *                                                                                                    *
// * Table-Sort functions (static members of various classes)                                           *
// *                                                                                                    *
// ******************************************************************************************************
//
VCSH_User.myselfTableSort = function(compare, direction) {
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('myselfTable').rows, myself_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell        = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 1;
    var uri         = "/" + i;
    if (cell[0].firstChild && cell[0].firstChild.nodeType == 1) {
      if (cell[0].firstChild.tagName.search(/^a$/i) != -1)
        uri         = cell[0].firstChild.getAttribute("href").replace(/^index\.php\?s\=EditFlow&n\=/, "");
      else if (cell[0].firstChild.tagName.search(/^input$/i) != -1)
        uri         = cell[0].firstChild.getAttribute("value");
    }
    var date        = ShowPage.stripTags(cell[k++].innerHTML);
    var type        = ShowPage.stripTags(cell[k++].innerHTML);
    var status      = ShowPage.stripTags(cell[k++].innerHTML);
    var give        = ShowPage.stripTags(cell[k++].innerHTML) == "given to";
    var user_id2    = ShowPage.stripTags(cell[k++].innerHTML);
    var description = ShowPage.stripTags(cell[k++].innerHTML); if (description == nbsp) description = "";
    var comm_id     = ShowPage.stripTags(cell[k++].innerHTML); if (comm_id     == nbsp) comm_id     = "";
    var tcash       = ShowPage.stripTags(cell[k++].innerHTML);
    var ccash       = ShowPage.stripTags(cell[k++].innerHTML);
    var fcash       = ShowPage.stripTags(cell[k++].innerHTML);
    myself_table.push(new VCSH_Flow(j, uri, "", "", "", "", "", "", type, status,
      date, give, "", "", "", user_id2, comm_id, "", "", description, "", "", "",
      { tcash : tcash, ccash : ccash, fcash : fcash }));
  }
  myself_table.sort(compare);
  var whitespace = '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">';
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = '', table_j = myself_table[j];
    if (table_j.status != 'rejected' && table_j.type != 'add' && table_j.type != 'drop') c +=
      '<a href="'+TRANSPORT+HOST+'/index.php?s=EditFlow&n=' + table_j.uri + '" title="Adjust"><img src="' + HOME + 'images/edit1.gif" alt="Adjust" align="absmiddle" border="0"></a>' + whitespace;
    c += table_j.status == 'offered' || table_j.status == 'rejected' ?
      '<input name="WithdrawFlow" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'myselfSubmit\',event)" onmouseover="ShowPage.setValue(\'myselfURI\',\'' + table_j.uri + '\',event)" title="Withdraw" src="' + HOME + 'images/withdraw1.gif" alt="Withdraw" align="absmiddle" border="0">' :
      '<input name="RejectFlow" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'myselfSubmit\',event)" onmouseover="ShowPage.setValue(\'myselfURI\',\'' + table_j.uri + '\',event)" title="Reject" src="' + HOME + 'images/withdraw1.gif" alt="Reject" align="absmiddle" border="0">';
    if (table_j.status == 'countered-2') c += whitespace + (table_j.type == 'add' ?
      '<input name="AcceptFlow" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'myselfSubmit\',event)" onmouseover="ShowPage.setValue(\'myselfURI\',\'' + table_j.uri + '\',event)" title="Accept" src="' + HOME + 'images/accept1.gif" alt="Accept" align="absmiddle" border="0">' :
      '<input name="AcceptFlow" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'myselfSubmit\',event)" onmouseover="ShowPage.setValue(\'myselfURI\',\'' + table_j.uri + '\',event)" title="Confirm" src="' + HOME + 'images/accept1.gif" alt="Confirm" align="absmiddle" border="0">');
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.date;
    cell[k++].innerHTML = table_j.type;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = table_j.type == 'add' || table_j.type == 'drop' ? '<span class="yes">(access)</span>' : (table_j.give ? '<span class="yes">given to</span>' : '<span class="no">rec. from</span>');
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=Personal&n=' + table_j.user_id2 + '" title="View Personal Page for ' + table_j.user_id2 + '">' + table_j.user_id2 + '</a>';
    cell[k++].innerHTML = table_j.description == '' ? nbsp : table_j.description;
    cell[k++].innerHTML = table_j.type == 'add' || table_j.type == 'drop' ? ('<span class="yes">' + table_j.comm_id + '</span>') : (table_j.comm_id == '' ? nbsp : table_j.comm_id);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.tcash);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.ccash);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.fcash);
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_User.otherTable = [];
VCSH_User.otherTableSort = function(compare, direction) {
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('otherTable').rows, other_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell        = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 1;
    var uri         = "/" + i;
    if (cell[0].firstChild && cell[0].firstChild.nodeType == 1) {
      if (cell[0].firstChild.tagName.search(/^a$/i) != -1)
        uri         = cell[0].firstChild.getAttribute("href").replace(/^index\.php\?s\=EditFlow&n\=/, "");
      else if (cell[0].firstChild.tagName.search(/^input$/i) != -1)
        uri         = cell[0].firstChild.getAttribute("value");
    }
    var date        = ShowPage.stripTags(cell[k++].innerHTML);
    var type        = ShowPage.stripTags(cell[k++].innerHTML);
    var status      = ShowPage.stripTags(cell[k++].innerHTML);
    var give        = ShowPage.stripTags(cell[k++].innerHTML) == "given by";
    var user_id1    = ShowPage.stripTags(cell[k++].innerHTML);
    var description = ShowPage.stripTags(cell[k++].innerHTML); if (description == nbsp) description = "";
    var comm_id     = ShowPage.stripTags(cell[k++].innerHTML); if (comm_id     == nbsp) comm_id     = "";
    var tcash       = ShowPage.stripTags(cell[k++].innerHTML);
    var ccash       = ShowPage.stripTags(cell[k++].innerHTML);
    var fcash       = ShowPage.stripTags(cell[k++].innerHTML);
    other_table.push(new VCSH_Flow(j, uri, "", "", "", "", "", "", type, status,
      date, give, "", "", user_id1, "", comm_id, "", "", description, "", "", "",
      { tcash : tcash, ccash : ccash, fcash : fcash }));
  }
  other_table.sort(compare);
  var whitespace = '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">';
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = '', table_j = other_table[j];
    if (table_j.status != 'rejected' && table_j.type != 'add' && table_j.type != 'drop') c +=
      '<a href="'+TRANSPORT+HOST+'/index.php?s=EditFlow&n=' + table_j.uri + '" title="Adjust"><img src="' + HOME + 'images/edit1.gif" alt="Adjust" align="absmiddle" border="0"></a>' + whitespace;
    c += table_j.status == 'rejected' ?
      '<input name="WithdrawFlow" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'otherSubmit\',event)" onmouseover="ShowPage.setValue(\'otherURI\',\'' + table_j.uri + '\',event)" title="Withdraw" src="' + HOME + 'images/withdraw1.gif" alt="Withdraw" align="absmiddle" border="0">' :
      '<input name="RejectFlow" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'otherSubmit\',event)" onmouseover="ShowPage.setValue(\'otherURI\',\'' + table_j.uri + '\',event)" title="Reject" src="' + HOME + 'images/withdraw1.gif" alt="Reject" align="absmiddle" border="0">';
    if (table_j.status == 'posted' || table_j.status == 'adjusted') c += whitespace + (table_j.type == 'add' ?
      '<input name="AcceptFlow" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'otherSubmit\',event)" onmouseover="ShowPage.setValue(\'otherURI\',\'' + table_j.uri + '\',event)" title="Accept" src="' + HOME + 'images/accept1.gif" alt="Accept" align="absmiddle" border="0">' :
      '<input name="AcceptFlow" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'otherSubmit\',event)" onmouseover="ShowPage.setValue(\'otherURI\',\'' + table_j.uri + '\',event)" title="Confirm" src="' + HOME + 'images/accept1.gif" alt="Confirm" align="absmiddle" border="0">');
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.date;
    cell[k++].innerHTML = table_j.type;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = table_j.type == 'add' || table_j.type == 'drop' ? '<span class="yes">(access)</span>' : (table_j.give ? '<span class="yes">given by</span>' : '<span class="no">rec. by</span>');
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=Personal&n=' + table_j.user_id1 + '" title="View Personal Page for ' + table_j.user_id1 + '">' + table_j.user_id1 + '</a>';
    cell[k++].innerHTML = table_j.description == '' ? nbsp : table_j.description;
    cell[k++].innerHTML = table_j.type == 'add' || table_j.type == 'drop' ? ('<span class="yes">' + table_j.comm_id + '</span>') : (table_j.comm_id == '' ? nbsp : table_j.comm_id);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.tcash);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.ccash);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.fcash);
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_User.user_type = "";
VCSH_User.tableSort = function(compare, direction, eventObj) {
  if (eventObj !== undefined) {
    if (!eventObj) eventObj = window.event;
    if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  }
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('userTable').rows, user_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell           = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 1;
    var uri            = ShowPage.stripTags(cell[k++].innerHTML);
    var class_name     = ShowPage.stripTags(cell[k++].innerHTML);
    var created        = ShowPage.stripTags(cell[k++].innerHTML);
    var updated        = ShowPage.stripTags(cell[k++].innerHTML);
    var last_login     = ShowPage.stripTags(cell[k++].innerHTML);
    var language       = ShowPage.stripTags(cell[k++].innerHTML);
    var type           = ShowPage.stripTags(cell[k++].innerHTML);
    var status         = ShowPage.stripTags(cell[k++].innerHTML);
    var user_id        = ShowPage.stripTags(cell[k++].innerHTML);
    var regy_id        = ShowPage.stripTags(cell[k++].innerHTML);
    var comm_id        = ShowPage.stripTags(cell[k++].innerHTML);
    var full_name      = ShowPage.stripTags(cell[k++].innerHTML); if (full_name   == nbsp) full_name   = "";
    var access_from    = ShowPage.stripTags(cell[k++].innerHTML); if (access_from == nbsp) access_from = "";
    var access_to      = ShowPage.stripTags(cell[k++].innerHTML); if (access_to   == nbsp) access_to   = "";
    var time_value     = ShowPage.stripTags(cell[k++].innerHTML);
    var deprec_time    = ShowPage.stripTags(cell[k++].innerHTML);
    var user_interface = ShowPage.stripTags(cell[k++].innerHTML);
    var letter_format  = ShowPage.stripTags(cell[k++].innerHTML);
    var image_type     = ShowPage.stripTags(cell[k++].innerHTML);
    user_table.push(new VCSH_User(j, uri, class_name, "", created, updated, "", language, type, status,
      last_login, user_id, regy_id, comm_id, "", full_name, "", "", "",
      access_from, access_to, time_value, deprec_time, user_interface, letter_format, image_type, ""));
  }
  user_table.sort(compare);
  var whitespace = '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">', user_del = VCSH_User.user_type.match(/^(sysadmin|server)$/);
  var row = window.document.getElementById('userTable').rows;
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = nbsp, table_j = user_table[j];
    if (table_j.type != 'sysadmin') {
      switch (table_j.status) {
      case "active" :
        c = '<input name="SuspendAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Suspend Account" src="' + HOME + 'images/withdraw1.gif" alt="Suspend Account" align="absmiddle" border="0">';
        break;
      case "suspended" :
        c = '<input name="ReactivateAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Reactivate Account" src="' + HOME + 'images/accept1.gif" alt="Reactivate Account" align="absmiddle" border="0">' + whitespace + '<input name="CloseAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Close Account" src="' + HOME + 'images/withdraw1.gif" alt="Close Account" align="absmiddle" border="0">';
        break;
      case "closed" :
        c = '<input name="ReopenAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Reopen Account" src="' + HOME + 'images/accept1.gif" alt="Reopen Account" align="absmiddle" border="0">';
        if (user_del) c += whitespace + '<input name="DeleteAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Delete Account" src="' + HOME + 'images/withdraw1.gif" alt="Delete Account" align="absmiddle" border="0">';
        break;
      }
    }
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.uri;
    cell[k++].innerHTML = table_j.class_name;
    cell[k++].innerHTML = table_j.created;
    cell[k++].innerHTML = table_j.updated;
    cell[k++].innerHTML = table_j.last_login;
    cell[k++].innerHTML = table_j.language;
    cell[k++].innerHTML = table_j.type;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id + '" title="Login as ' + table_j.user_id + '">' + table_j.user_id + '</a>';
    cell[k++].innerHTML = table_j.regy_id == '' ? nbsp : table_j.regy_id;
    cell[k++].innerHTML = table_j.comm_id == '' ? nbsp : table_j.comm_id;
    cell[k++].innerHTML = table_j.full_name == '' ? nbsp : table_j.full_name;
    cell[k++].innerHTML = table_j.access_from == '' ? nbsp : table_j.access_from;
    cell[k++].innerHTML = table_j.access_to == '' ? nbsp : table_j.access_to;
    cell[k++].innerHTML = sprintf('%1.2f', table_j.time_value);
    cell[k++].innerHTML = sprintf('%1.2f', table_j.deprec_time);
    cell[k++].innerHTML = table_j.user_interface;
    cell[k++].innerHTML = table_j.letter_format;
    cell[k++].innerHTML = table_j.image_type == '' ? nbsp : '<a href="'+TRANSPORT+HOST+'/index.php?s=Image&n=' + table_j.user_id + '" title="Show Image">' + table_j.image_type + '</a>';
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_ExchangeUser.user_type = "";
VCSH_ExchangeUser.tableSort = function(compare, direction, eventObj) {
  if (eventObj !== undefined) {
    if (!eventObj) eventObj = window.event;
    if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  }
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('userTable').rows, user_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell        = row[i+1].cells, j = direction ? i : row.length - i - 2;
    var uri         = cell[0].firstChild && cell[0].firstChild.nodeType == 1 ? cell[0].firstChild.getAttribute("value") : "/" + i;
    var type        = ShowPage.stripTags(cell[2].innerHTML);
    var last_login  = ShowPage.stripTags(cell[1].innerHTML);
    var status      = ShowPage.stripTags(cell[3].innerHTML);
    var user_id     = ShowPage.stripTags(cell[4].innerHTML);
    var name        = ShowPage.stripTags(cell[5].innerHTML);
    var access_from = ShowPage.stripTags(cell[6].innerHTML); if (access_from == nbsp) access_from = "";
    var access_to   = ShowPage.stripTags(cell[7].innerHTML); if (access_to   == nbsp) access_to   = "";
    user_table.push(new VCSH_ExchangeUser(j, uri, type, status, last_login, user_id, name, '', access_from, access_to));
  }
  user_table.sort(compare);
  var whitespace = '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">', user_del = VCSH_ExchangeUser.user_type.match(/^(sysadmin|server)$/);
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = nbsp, table_j = user_table[j];
    if (table_j.type != 'sysadmin') {
      switch (table_j.status) {
      case "active" :
        c = '<input name="SuspendAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Suspend Account" src="' + HOME + 'images/withdraw1.gif" alt="Suspend Account" align="absmiddle" border="0">';
        break;
      case "suspended" :
        c = '<input name="ReactivateAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Reactivate Account" src="' + HOME + 'images/accept1.gif" alt="Reactivate Account" align="absmiddle" border="0">' + whitespace + '<input name="CloseAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Close Account" src="' + HOME + 'images/withdraw1.gif" alt="Close Account" align="absmiddle" border="0">';
        break;
      case "closed" :
        c = '<input name="ReopenAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Reopen Account" src="' + HOME + 'images/accept1.gif" alt="Reopen Account" align="absmiddle" border="0">';
        if (user_del) c += whitespace + '<input name="DeleteAccount" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'UserSubmit\',event)" onmouseover="ShowPage.setValue(\'UserURI\',\'' + table_j.uri + '\',event)" title="Delete Account" src="' + HOME + 'images/withdraw1.gif" alt="Delete Account" align="absmiddle" border="0">';
        break;
      }
    }
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.last_login;
    cell[k++].innerHTML = table_j.type;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id + '" title="Login as ' + table_j.user_id + '">' + table_j.user_id + '</a>';
    cell[k++].innerHTML = table_j.full_name   == '' ? nbsp : table_j.full_name;
    cell[k++].innerHTML = table_j.access_from == '' ? nbsp : table_j.access_from;
    cell[k++].innerHTML = table_j.access_to   == '' ? nbsp : table_j.access_to;
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_Flow.user_type = "";
VCSH_Flow.tableSort = function(compare, direction, eventObj) {
  if (eventObj !== undefined) {
    if (!eventObj) eventObj = window.event;
    if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  }
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('flowTable').rows, flow_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell        = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 1;
    var uri         = ShowPage.stripTags(cell[k++].innerHTML);
    var class_name  = ShowPage.stripTags(cell[k++].innerHTML);
    var created     = ShowPage.stripTags(cell[k++].innerHTML);
    var updated     = ShowPage.stripTags(cell[k++].innerHTML);
    var date        = ShowPage.stripTags(cell[k++].innerHTML);
    var language    = ShowPage.stripTags(cell[k++].innerHTML);
    var type        = ShowPage.stripTags(cell[k++].innerHTML);
    var status      = ShowPage.stripTags(cell[k++].innerHTML);
    var give        = ShowPage.stripTags(cell[k++].innerHTML) == "give";
    var type1       = ShowPage.stripTags(cell[k++].innerHTML);
    var type2       = ShowPage.stripTags(cell[k++].innerHTML);
    var user_id1    = ShowPage.stripTags(cell[k++].innerHTML);
    var user_id2    = ShowPage.stripTags(cell[k++].innerHTML);
    var comm_id     = ShowPage.stripTags(cell[k++].innerHTML); if (comm_id     == nbsp) comm_id     = "";
    var description = ShowPage.stripTags(cell[k++].innerHTML); if (description == nbsp) description = "";
    var socap       = ShowPage.stripTags(cell[k++].innerHTML); if (socap       == nbsp) socap       = 0;
    var tcash       = ShowPage.stripTags(cell[k++].innerHTML); if (tcash       == nbsp) tcash       = 0;
    var ccash       = ShowPage.stripTags(cell[k++].innerHTML); if (ccash       == nbsp) ccash       = 0;
    var fcash       = ShowPage.stripTags(cell[k++].innerHTML); if (fcash       == nbsp) fcash       = 0;
    flow_table.push(new VCSH_Flow(j, uri, class_name, "", created, updated, "", language, type, status,
      date, give, type1, type2, user_id1, user_id2, comm_id, "", "", description, "", "", "",
      { socap : socap, tcash : tcash, ccash : ccash, fcash : fcash }));
  }
  flow_table.sort(compare);
  switch (VCSH_Flow.user_type) {
  case 'sysadmin'  :
  case 'server'    :
    var flow_image2  = HOME + "images/withdraw1.gif",
      flow_process1a = "DeleteFlow",
      flow_process2a = "Delete Participation",
      flow_process1b = "CancelFlow",
      flow_process2b = "Cancel Participation";
    break;
  case 'registry'  :
    var flow_image2  = HOME + "images/withdraw1.gif",
      flow_process1a = "",
      flow_process2a = "",
      flow_process1b = 'CancelFlow',
      flow_process2b = "Cancel Participation";
    break;
  case 'community' :
    var flow_image2  = HOME + "images/reverse1.gif",
      flow_process1a = "",
      flow_process2a = "",
      flow_process1b = "ReverseFlow",
      flow_process2b = "Reverse Participation";
    break;
  default          :
    var flow_image2  = HOME + "images/white.gif",
      flow_process1a = "",
      flow_process2a = "",
      flow_process1b = "",
      flow_process2b = "";
    break;
  }
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = nbsp, table_j = flow_table[j];
    if (flow_process1b != "")
      switch (table_j.status) {
      case "canceled" :
        if (flow_process1a != "") c = '<input name="' + flow_process1a + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2a + '" src="' + flow_image2 + '" alt="' + flow_process2a + '" border="0">';
        break;
      case "accepted" :
        if (flow_process1b != "") c = '<input name="' + flow_process1b + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2b + '" src="' + flow_image2 + '" alt="' + flow_process2b + '" border="0">';
        break;
      default :
        if (flow_process1b != "" && flow_process1b != "ReverseFlow") c = '<input name="' + flow_process1b + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2b + '" src="' + flow_image2 + '" alt="' + flow_process2b + '" border="0">';
        break;
    }
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.uri;
    cell[k++].innerHTML = table_j.class_name;
    cell[k++].innerHTML = table_j.created;
    cell[k++].innerHTML = table_j.updated;
    cell[k++].innerHTML = table_j.date;
    cell[k++].innerHTML = table_j.language;
    cell[k++].innerHTML = table_j.type;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = table_j.give ? '<span class="yes">give</span>' : '<span class="no">rec.</span>';
    cell[k++].innerHTML = table_j.type1;
    cell[k++].innerHTML = table_j.type2;
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id1 + '" title="Login as ' + table_j.user_id1 + '">' + table_j.user_id1 + '</a>';
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id2 + '" title="Login as ' + table_j.user_id2 + '">' + table_j.user_id2 + '</a>';
    if (table_j.type == 'add' || table_j.type == 'drop') cell[k++].innerHTML = '<span class="yes">' + table_j.comm_id + '</span>';
    else if (table_j.comm_id == '') cell[k++].innerHTML = nbsp;
    else cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.comm_id + '" title="Login as ' + table_j.comm_id + '">' + table_j.comm_id + '</a>';
    cell[k++].innerHTML = table_j.description == '' ? nbsp : table_j.description;
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.socap);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.tcash);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.ccash);
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.fcash);
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_LETSplayFlow.user_interface = 'lets-play2';
VCSH_LETSplayFlow.tableSort = function(compare, direction, eventObj) {
  if (eventObj !== undefined) {
    if (!eventObj) eventObj = window.event;
    if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  }
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('flowTable').rows, flow_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell        = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0;
    var created     = ShowPage.stripTags(cell[k++].innerHTML);
    var description = ShowPage.stripTags(cell[k++].innerHTML); if (description == nbsp) description = "";
    var user_id1    = ShowPage.stripTags(cell[k++].innerHTML);
    var user_id2    = ShowPage.stripTags(cell[k++].innerHTML);
    if (VCSH_LETSplayFlow.user_interface == 'lets-play3') {
      var tcash     = ShowPage.stripTags(cell[k++].innerHTML); if (tcash       == nbsp) tcash       = 0;
    } else {
      var tcash     = 0;
    }
    var ccash       = ShowPage.stripTags(cell[k++].innerHTML); if (ccash       == nbsp) ccash       = 0;
    var fcash       = ShowPage.stripTags(cell[k++].innerHTML); if (fcash       == nbsp) fcash       = 0;
    flow_table.push(new VCSH_LETSplayFlow(j, created, user_id1, user_id2, description, tcash, ccash, fcash));
  }
  flow_table.sort(compare);
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, table_j = flow_table[j];
    cell[k++].innerHTML   = table_j.created;
    cell[k++].innerHTML   = table_j.description == '' ? nbsp : table_j.description;
    cell[k++].innerHTML   = '<a href="'+TRANSPORT+HOST+'/index.php?n=' + table_j.user_id1 + '" title="View participation charts for ' + table_j.user_id1 + '">' + table_j.user_id1 + '</a>';
    cell[k++].innerHTML   = '<a href="'+TRANSPORT+HOST+'/index.php?n=' + table_j.user_id2 + '" title="View participation charts for ' + table_j.user_id2 + '">' + table_j.user_id2 + '</a>';
    if (VCSH_LETSplayFlow.user_interface == 'lets-play3')
      cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.tcash);
    cell[k++].innerHTML   = ShowPage.redOrGreen('%1.2f', table_j.ccash);
    cell[k++].innerHTML   = ShowPage.redOrGreen('%1.2f', table_j.fcash);
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_MutualCreditFlow.tableSort = function(compare, direction, eventObj) {
  if (eventObj !== undefined) {
    if (!eventObj) eventObj = window.event;
    if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  }
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('flowTable').rows, flow_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell        = row[i+1].cells, j = direction ? i : row.length - i - 2;
    var uri         = cell[0].firstChild && cell[0].firstChild.nodeType == 1 ? cell[0].firstChild.getAttribute("value") : "/" + i;
    var status      = ShowPage.stripTags(cell[2].innerHTML);
    var date        = ShowPage.stripTags(cell[1].innerHTML);
    var user_id1    = ShowPage.stripTags(cell[3].innerHTML);
    var user_id2    = ShowPage.stripTags(cell[4].innerHTML);
    var description = ShowPage.stripTags(cell[5].innerHTML); if (description == nbsp) description = "";
    var ccash       = ShowPage.stripTags(cell[6].innerHTML);
    var t           = "2000-01-01 00:00:00";
    flow_table.push(new VCSH_MutualCreditFlow(j, uri, "SocialFlow", "", t, t, t, "", "trade", status, date, false, user_id1, user_id2, description, ccash));
  }
  flow_table.sort(compare);
  var flow_image2  = HOME + "images/reverse1.gif",
    flow_process1a = "",
    flow_process2a = "",
    flow_process1b = "ReverseFlow",
    flow_process2b = "Reverse Transaction";
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = nbsp, table_j = flow_table[j];
    if (flow_process1b != "")
      switch (table_j.status) {
      case "canceled" :
        if (flow_process1a != "") c = '<input name="' + flow_process1a + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2a + '" src="' + flow_image2 + '" alt="' + flow_process2a + '" border="0">';
        break;
      case "accepted" :
        if (flow_process1b != "") c = '<input name="' + flow_process1b + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2b + '" src="' + flow_image2 + '" alt="' + flow_process2b + '" border="0">';
        break;
      default :
        if (flow_process1b != "" && flow_process1b != "ReverseFlow") c = '<input name="' + flow_process1b + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2b + '" src="' + flow_image2 + '" alt="' + flow_process2b + '" border="0">';
        break;
    }
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.date;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id1 + '" title="Login as ' + table_j.user_id1 + '">' + table_j.user_id1 + '</a>';
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id2 + '" title="Login as ' + table_j.user_id2 + '">' + table_j.user_id2 + '</a>';
    cell[k++].innerHTML = table_j.description == '' ? nbsp : table_j.description;
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.ccash);
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_ExchangeFlow.user_type = "";
VCSH_ExchangeFlow.tableSort = function(compare, direction, eventObj) {
  if (eventObj !== undefined) {
    if (!eventObj) eventObj = window.event;
    if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  }
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('flowTable').rows, flow_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell        = row[i+1].cells, j = direction ? i : row.length - i - 2;
    var uri         = cell[0].firstChild && cell[0].firstChild.nodeType == 1 ? cell[0].firstChild.getAttribute("value") : "/" + i;
    var type        = cell[5].firstChild && cell[5].firstChild.nodeType == 1 && cell[5].firstChild.getAttribute("class") == "yes" ? "access" : "trade";
    var status      = ShowPage.stripTags(cell[2].innerHTML);
    var date        = ShowPage.stripTags(cell[1].innerHTML);
    var user_id1    = ShowPage.stripTags(cell[3].innerHTML);
    var user_id2    = ShowPage.stripTags(cell[4].innerHTML);
    var comm_id     = ShowPage.stripTags(cell[5].innerHTML); if (comm_id     == nbsp) comm_id     = "";
    var description = ShowPage.stripTags(cell[6].innerHTML); if (description == nbsp) description = "";
    var ccash       = ShowPage.stripTags(cell[7].innerHTML);
    flow_table.push(new VCSH_ExchangeFlow(j, uri, type, status, date, user_id1, user_id2, comm_id, description, ccash));
  }
  flow_table.sort(compare);
  switch (VCSH_ExchangeFlow.user_type) {
  case "sysadmin"  :
  case "server"    :
    var flow_image2  = HOME + "images/withdraw1.gif",
      flow_process1a = "DeleteFlow",
      flow_process2a = "Delete Transaction",
      flow_process1b = "CancelFlow",
      flow_process2b = "Cancel Transaction";
    break;
  case "registry"  :
    var flow_image2  = HOME + "images/withdraw1.gif",
      flow_process1a = "",
      flow_process2a = "",
      flow_process1b = "CancelFlow",
      flow_process2b = "Cancel Transaction";
    break;
  case "community" :
    var flow_image2  = HOME + "images/reverse1.gif",
      flow_process1a = "",
      flow_process2a = "",
      flow_process1b = "ReverseFlow",
      flow_process2b = "Reverse Transaction";
    break;
  default          :
    var flow_image2  = HOME + "images/white.gif",
      flow_process1a = "",
      flow_process2a = "",
      flow_process1b = "",
      flow_process2b = "";
    break;
  }
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = nbsp, table_j = flow_table[j];
    if (flow_process1b != "")
      switch (table_j.status) {
      case "canceled" :
        if (flow_process1a != "") c = '<input name="' + flow_process1a + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2a + '" src="' + flow_image2 + '" alt="' + flow_process2a + '" border="0">';
        break;
      case "accepted" :
        if (flow_process1b != "") c = '<input name="' + flow_process1b + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2b + '" src="' + flow_image2 + '" alt="' + flow_process2b + '" border="0">';
        break;
      default :
        if (flow_process1b != "" && flow_process1b != "ReverseFlow") c = '<input name="' + flow_process1b + '" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'FlowSubmit\',event)" onmouseover="ShowPage.setValue(\'FlowURI\',\'' + table_j.uri + '\',event)" title="' + flow_process2b + '" src="' + flow_image2 + '" alt="' + flow_process2b + '" border="0">';
        break;
    }
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.date;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id1 + '" title="Login as ' + table_j.user_id1 + '">' + table_j.user_id1 + '</a>';
    cell[k++].innerHTML = '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id2 + '" title="Login as ' + table_j.user_id2 + '">' + table_j.user_id2 + '</a>';
    cell[k++].innerHTML = table_j.type == 'access' ? '<span class="yes">' + table_j.comm_id + '</span>' : (table_j.comm_id == '' ? nbsp : '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.comm_id + '" title="Login as ' + table_j.comm_id + '">' + table_j.comm_id + '</a>');
    cell[k++].innerHTML = table_j.description == '' ? nbsp : table_j.description;
    cell[k++].innerHTML = ShowPage.redOrGreen('%1.2f', table_j.ccash);
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_Text.user_type = "";
VCSH_Text.tableSort = function(compare, direction, eventObj) {
  if (eventObj !== undefined) {
    if (!eventObj) eventObj = window.event;
    if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  }
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('textTable').rows, text_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell       = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 1;
    var uri        = ShowPage.stripTags(cell[k++].innerHTML);
    var class_name = ShowPage.stripTags(cell[k++].innerHTML);
    var created    = ShowPage.stripTags(cell[k++].innerHTML);
    var updated    = ShowPage.stripTags(cell[k++].innerHTML);
    var language   = ShowPage.stripTags(cell[k++].innerHTML);
    var type       = ShowPage.stripTags(cell[k++].innerHTML);
    var status     = ShowPage.stripTags(cell[k++].innerHTML);
    var section    = ShowPage.stripTags(cell[k++].innerHTML);
    var block      = ShowPage.stripTags(cell[k++].innerHTML);
    var user_id1   = ShowPage.stripTags(cell[k++].innerHTML); if (user_id1 == nbsp) user_id1 = "";
    var user_id2   = ShowPage.stripTags(cell[k++].innerHTML); if (user_id2 == nbsp) user_id2 = "";
    text_table.push(new VCSH_Text(j, uri, class_name, "", created, updated, "", language, type, status, section, block, user_id1, user_id2));
  }
  text_table.sort(compare);
  var text_del   = VCSH_Text.user_type.match(/^(sysadmin|server)$/),
    text_process = VCSH_Text.user_type.match(/^(sysadmin|server|registry)$/);
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = nbsp, table_j = text_table[j];
    if (text_process)
      switch (table_j.status) {
      case "valid" :
        c = '<input name="InvalidateText" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'TextSubmit\',event)" onmouseover="ShowPage.setValue(\'TextURI\',\'' + table_j.uri + '\',event)" title="Invalidate Text" src="' + HOME + 'images/withdraw1.gif" alt="Invalidate Text" align="absmiddle" border="0">';
        break;
      case "invalid" :
        c = '<input name="RestoreText" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'TextSubmit\',event)" onmouseover="ShowPage.setValue(\'TextURI\',\'' + table_j.uri + '\',event)" title="Restore Text" src="' + HOME + 'images/accept1.gif" alt="Restore Text" align="absmiddle" border="0">';
        if (text_del) c +=
          '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">' +
          '<input name="DeleteText" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'TextSubmit\',event)" onmouseover="ShowPage.setValue(\'TextURI\',\'' + table_j.uri + '\',event)" title="Delete Text" src="' + HOME + 'images/withdraw1.gif" alt="Delete Text" align="absmiddle" border="0">';
        break;
    }
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.uri;
    cell[k++].innerHTML = table_j.class_name;
    cell[k++].innerHTML = table_j.created;
    cell[k++].innerHTML = table_j.updated;
    cell[k++].innerHTML = table_j.language;
    cell[k++].innerHTML = table_j.type;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = table_j.section;
    cell[k++].innerHTML = table_j.block;
    cell[k++].innerHTML = table_j.user_id1 == '' ? nbsp : '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id1 + '" title="Login as ' + table_j.user_id1 + '">' + table_j.user_id1 + '</a>';
    cell[k++].innerHTML = table_j.user_id2 == '' ? nbsp : '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id2 + '" title="Login as ' + table_j.user_id2 + '">' + table_j.user_id2 + '</a>';
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};

VCSH_ExchangeText.user_type = "";
VCSH_ExchangeText.tableSort = function(compare, direction, eventObj) {
  if (eventObj !== undefined) {
    if (!eventObj) eventObj = window.event;
    if (eventObj.stopPropagation) eventObj.stopPropagation(); else eventObj.cancelBubble = true;
  }
  if (direction) {
    if (ShowPage.mayIgnoreSingleClick()) return true; // Ignore this single click, which came too soon after a double click.
  } else {
    ShowPage.doIgnoreSingleClick(); // Ignore a subsequent single click.
  }
  var row = window.document.getElementById('textTable').rows, text_table = [], nbsp = String.fromCharCode(160);
  for (var i=0; i<row.length-1; i++) {
    var cell     = row[i+1].cells, j = direction ? i : row.length - i - 2;
    var uri      = cell[0].firstChild && cell[0].firstChild.nodeType == 1 ? cell[0].firstChild.getAttribute("value") : "/" + i;
    var updated  = ShowPage.stripTags(cell[1].innerHTML);
    var status   = ShowPage.stripTags(cell[2].innerHTML);
    var section  = ShowPage.stripTags(cell[3].innerHTML);
    var block    = ShowPage.stripTags(cell[4].innerHTML);
    var user_id1 = ShowPage.stripTags(cell[5].innerHTML); if (user_id1 == nbsp) user_id1 = "";
    var user_id2 = ShowPage.stripTags(cell[6].innerHTML); if (user_id2 == nbsp) user_id2 = "";
    text_table.push(new VCSH_ExchangeText(j, uri, updated, status, section, block, user_id1, user_id2));
  }
  text_table.sort(compare);
  var text_del   = VCSH_ExchangeText.user_type.match(/^(sysadmin|server)$/),
    text_process = VCSH_ExchangeText.user_type.match(/^(sysadmin|server|registry)$/);
  for (var i=0; i<row.length-1; i++) {
    var cell = row[i+1].cells, j = direction ? i : row.length - i - 2, k = 0, c = nbsp, table_j = text_table[j];
    if (text_process)
      switch (table_j.status) {
      case "valid" :
        c = '<input name="InvalidateText" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'TextSubmit\',event)" onmouseover="ShowPage.setValue(\'TextURI\',\'' + table_j.uri + '\',event)" title="Invalidate Text" src="' + HOME + 'images/withdraw1.gif" alt="Invalidate Text" align="absmiddle" border="0">';
        break;
      case "invalid" :
        c = '<input name="RestoreText" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'TextSubmit\',event)" onmouseover="ShowPage.setValue(\'TextURI\',\'' + table_j.uri + '\',event)" title="Restore Text" src="' + HOME + 'images/accept1.gif" alt="Restore Text" align="absmiddle" border="0">';
        if (text_del) c +=
          '<img src="' + HOME + 'images/white.gif" alt="" width="4" height="1" border="0">' +
          '<input name="DeleteText" type="image" value="' + table_j.uri + '" onclick="ShowPage.submitOnce(this,\'TextSubmit\',event)" onmouseover="ShowPage.setValue(\'TextURI\',\'' + table_j.uri + '\',event)" title="Delete Text" src="' + HOME + 'images/withdraw1.gif" alt="Delete Text" align="absmiddle" border="0">';
        break;
    }
    cell[k++].innerHTML = c;
    cell[k++].innerHTML = table_j.updated;
    cell[k++].innerHTML = table_j.status;
    cell[k++].innerHTML = table_j.section;
    cell[k++].innerHTML = table_j.block;
    cell[k++].innerHTML = table_j.user_id1 == '' ? nbsp : '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id1 + '" title="Login as ' + table_j.user_id1 + '">' + table_j.user_id1 + '</a>';
    cell[k++].innerHTML = table_j.user_id2 == '' ? nbsp : '<a href="'+TRANSPORT+HOST+'/index.php?s=LoginAs&n=' + table_j.user_id2 + '" title="Login as ' + table_j.user_id2 + '">' + table_j.user_id2 + '</a>';
  }
  if (!direction) setTimeout('ShowPage.doAllowSingleClick()', 1000);
  return true;
};
