


function load_json(t) {
  

  
  if(window.JSON && JSON.parse) {
    return JSON.parse(t);
  } else {
    return eval("(" + t + ")");
  }
}














function abbreviate_middle(l, s) {
  if(s.length <= l) return s;
  var length_left = parseInt( (l-3) / 2, 10);
  return s.substr(0, length_left) + "..." + s.substr( - (l-3-length_left), l-3-length_left);
}





Number.prototype.padTo=function(n) {
  if(this.length > n) return this;
  var r = "" + this;
  while(r.length < n) r = "0" + r;
  return r;
};




function pad_2(num_string) {
  num_string = "" + num_string;
  if(num_string.length >= 2) {
    return num_string;
  } else {
    return "0"+num_string;
  }
}




function days_in_month(year, month) {
  month--; // To get 0-11 months
  month++; // Because we want to look at the next month!
  
  if(month>11) {
    month=0;
    year++;
  }
  var start_of_next_month = new Date(year, month);
  var end_of_this_month = new Date(start_of_next_month.getTime() - (1000*60*60*12));
  return end_of_this_month.getDate();
}





function set_max_day_from_value(name) {
  var i;
  var max_day=days_in_month(
    document.getElementById(name+".y").value, 
    document.getElementById(name+".m").value
  );
  for(i = 28; i<max_day+1; i++) {
    document.getElementById(name+".d."+i).disabled=false;
  }
  for(i = max_day+1; i<32; i++) {
    document.getElementById(name+".d."+i).disabled=true;
  }
  if(document.getElementById(name+".d").value > max_day)
    document.getElementById(name+".d").value = max_day;
}





function update_hidden_date(name) {
  document.getElementById(name+".h").value =
    document.getElementById(name+".y").value + "-" +
    pad_2(document.getElementById(name+".m").value) + "-" + 
    pad_2(document.getElementById(name+".d").value) +
    document.getElementById(name+".t").value;
}




function update_hidden_date_ym(name) {
  document.getElementById(name+".h").value =
    document.getElementById(name+".y").value + "-" +
    pad_2(document.getElementById(name+".m").value);
}






function find_element_root_offset(element) {
  var x=0, y=0;
  var e, i;
  while(element && element.offsetLeft!==undefined) {
    x+=element.offsetLeft;
    y+=element.offsetTop;
    for(e=element; e!==element.offsetParent; e=e.parentNode) {
      

      if(
        e.offsetLeft == 0 &&
        e.tagName=="TD" &&
        e!==e.parentNode.getElementsByTagName("TD").item(0)
      ) {
        var cn = e.parentNode.childNodes;
        for(i=0; i<cn.length && e!==cn.item(i); i++)
          if(cn.item(i).tagName && cn.item(i).tagName=="TD")
            x+=cn.item(i).offsetWidth;
      }
    }
    element=element.offsetParent;
  }
  return [x,y];
}













function overlay_near_element(target_element, move_element_id, approx_width, approx_height, move_element) {
  var target_position = find_element_root_offset(target_element);
  var x = target_position[0];
  var y = target_position[1];
  move_element = move_element || document.getElementById(move_element_id);
  var divstyle=move_element.style;
  if(x>approx_width/2) x-=approx_width/2; else x=0;
  if(y>approx_height/2) y-=approx_height/2; else y=0;
  divstyle.left=x+"px";
  divstyle.top=y+"px";
  divstyle.visibility='visible';
}





function try_refresh(time, url) {
  location.href=url;
  setTimeout("try_refresh(" + time + ", '" + url + "')",time*1000);
}




function set_action(this_form, new_action) {
  var i;
  var elements = this_form.elements;
  for(i = 0 ; i < elements.length ; ++i) {
    if(elements[i].name == "action")
      elements[i].value = new_action;
  }
  return true;
}
var page_title;






function override_page_title(t) {
  page_title = t;
}

var other_title_callbacks = [];








function set_title() {
  var i;
  var title_text_node;
  if(!page_title) {
    var heads = document.getElementsByTagName("h1");
    if(heads.length > 0) {
      for(i=0; i<heads.item(0).childNodes.length; i++) {
        if(heads.item(0).childNodes.item(i).data) {
          title_text_node = heads.item(0).childNodes.item(i);
          break;
        }
      }
    } else if(document.getElementById("effective-title")) {
      title_text_node=document.getElementById("effective-title").firstChild;
    } else {
      return false;
    }
    if(!title_text_node) return false;
    page_title = title_text_node.data;
  }
  var new_title = "Heart: ";
  // The first head should be the one we want
  new_title = new_title + page_title;
  for(i=0; i<other_title_callbacks.length; i++)
    other_title_callbacks[i](page_title);
  document.title = new_title;
  return true; 
}





function toggle_div(id) {
  var div=document.getElementById(id);
  if (div.style.display == 'none') {
    div.style.display = 'block';
  } else {
    div.style.display = 'none';
  }
}





function go_back_ish() {
  if(document.referrer && document.referrer != location.href) {
               history.go(-1); // We just go straight back.
  } else if(document.getElementById(':1.container')) {
    history.go(-2); // Go back twice if translator is loaded.
  } else {
    location.href = "/";
  }
  return false;
}





var broken_windows_browser=0;
if(navigator.userAgent.toLowerCase().indexOf("msie")>=0) broken_windows_browser=1;




var broken_windows_browser_le_8 = false;
var md = navigator.userAgent.match(/MSIE ([0-9]+)/);
if(md && parseInt(md[0]) < 9) broken_windows_browser_le_8 = true;

var xmlhttp_by_name = {};









function object_to_arg_string(args) {
  var post_content = "";
  var i, j;
  for(i in args) {
    if(args[i] === undefined) continue;
    if(args[i] instanceof Array) {
      for(j=0; j<args[i].length; j++)
        post_content += i + "=" + encodeURIComponent(args[i][j]) + ";";
    } else {
      post_content += i + "=" + encodeURIComponent(args[i]) + ";";
    }
  }
  return post_content;
}







function xmlhttp_call_with_args(name, orst, url, args, sync) {
  var post_content = object_to_arg_string(args);

  var xmlhttp_o;
  if(broken_windows_browser) {
    xmlhttp_o = new ActiveXObject("MsXml2.XmlHttp");
  } else {
    xmlhttp_o = new XMLHttpRequest();
  }
  xmlhttp_by_name[name] = xmlhttp_o;
  xmlhttp_o.onreadystatechange=orst;
  xmlhttp_o.open("POST", url, !sync);
  xmlhttp_o.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  if(!navigator.userAgent.match(/AppleWebKit/)) {
    // WebKit hates this, but some other browsers may need it.
    xmlhttp_o.setRequestHeader("Content-length", post_content.length);
    xmlhttp_o.setRequestHeader("Connection", "close");
  }
  xmlhttp_o.send(post_content);
  if(sync) {
    // onreadystatechange won't have fired.
    orst();
  }
  return xmlhttp_o;
}







var alert_count = 0;
var alert_limit = 20;
function alert_l(str, chosen_limit) {
  alert_count++;
  if(!chosen_limit) chosen_limit=alert_limit;
  if(alert_count>= chosen_limit) return false;
  return window.alert(str);
}








function build_simple_xmlr_statechange(n, on_success, on_failure, check_for_success, options) {
  options = options||{};

  var orst_fired = false;
  return function() {
    if(orst_fired) return;
    
    // if LOADED
    var my_xmlhttp = xmlhttp_by_name[n];
    if(my_xmlhttp.readyState == 4 && my_xmlhttp.status == 200) {
      orst_fired = true;
      var xmldoc=my_xmlhttp.responseXML;
      if(!xmldoc) {
        if(on_failure) on_failure();
      } else if(!xmldoc.lastChild) {
        if(on_failure) on_failure(xmldoc.lastChild);
      } else if(check_for_success && !check_for_success(xmldoc.lastChild)) {
        if(on_failure) on_failure(xmldoc.lastChild);
      } else {
        if(on_success) on_success(xmldoc.lastChild);
      }
    } else if(my_xmlhttp.readyState == 4) {
      orst_fired = true;
      if(my_xmlhttp.status && !options.skipError) {
        if(!options.silentError) alert_l("HTTP error: "+my_xmlhttp.status);
        if(on_failure) on_failure();
      }
    }
  };
}
























function xmlhttp_simple_full(url, args, check_for_success, on_success, on_failure, options) {
  var i, j;
  options = options||{};

  // Convert the args to a POST string
  var post_content = "";
  for(i in args) {
    if(args[i] === undefined) continue;
    if(args[i] instanceof Array) {
      for(j=0; j<args[i].length; j++)
        post_content += i + "=" + encodeURIComponent(args[i][j]) + ";";
    } else {
      post_content += i + "=" + encodeURIComponent(args[i]) + ";";
    }
  }

  // Allocate the object
  var xmlhttp_o;
  if(broken_windows_browser) {
    xmlhttp_o = new ActiveXObject("MsXml2.XmlHttp");
  } else {
    xmlhttp_o = new XMLHttpRequest();
  }
  var on_load_fired = false;
  function on_load() {
    on_load_fired = true;
    if(xmlhttp_o.status == 200) {
      if(options.returnText) {
        if(on_success) on_success(xmlhttp_o.responseText);
      } else {
        var xmldoc=xmlhttp_o.responseXML;
        if(!xmldoc) {
          if(on_failure) on_failure();
        } else if(!xmldoc.lastChild) {
          if(on_failure) on_failure(xmldoc.lastChild);
        } else if(check_for_success && !check_for_success(xmldoc.lastChild)) {
          if(on_failure) on_failure(xmldoc.lastChild);
        } else {
          if(on_success) on_success(xmldoc.lastChild);
        }
      }
    } else {
      if(xmlhttp_o.status && !options.skipError) {
        if(!options.silentError) alert_l("HTTP error: "+xmlhttp_o.status);
        if(on_failure) on_failure();
      }
    }
  }
  var partial_load_failed = false;
  xmlhttp_o.onreadystatechange = function() {
    // if LOADED
    if(xmlhttp_o.readyState == 4) {
      // MSIE has to catch up here.
      if(partial_load_failed) options.onPartialLoad(xmlhttp_o.responseText);
      on_load();
    }
    // if partly loaded
    if(options.onPartialLoad && xmlhttp_o.readyState == 3) {
      try {
        options.onPartialLoad(xmlhttp_o.responseText);
      } catch(e) {
        // Do nothing - MSIE will just have to wait.
        partial_load_failed = true;
      }
    }
  };
  if(options.get) {
    var full_url = post_content.length ? url+"?"+post_content : url;
    xmlhttp_o.open("GET", full_url, options.sync ? false : true);
    xmlhttp_o.send();
  } else {
    xmlhttp_o.open("POST", url, options.sync ? false : true);
    xmlhttp_o.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    if(!navigator.userAgent.match(/AppleWebKit/)) {
      // WebKit hates this, but some other browsers may need it.
      xmlhttp_o.setRequestHeader("Content-length", post_content.length);
      xmlhttp_o.setRequestHeader("Connection", "close");
    }
    xmlhttp_o.send(post_content);
  }
  if(options.sync && ! on_load_fired) on_load();
  return xmlhttp_o;
}

















function form_to_http_request(f, on_success, on_failure, check_for_success, override_action, include_last_submit, options) {
  var form_contents = {};

  function add_contents(e, default_name) {
    var name = e.name || default_name;
               if(!name) return false; // Should never happen, but does.
               form_contents[name]=form_contents[name] || [];
               form_contents[name].push(e.value);
    return true;
  }

  var last_submit;
  var i;

  for(i=0; i<f.elements.length; i++) {
    var e = f.elements.item(i);
    if(e.disabled) continue;
    if(e.type == "radio" || e.type == "checkbox") {
      if(!e.checked) continue;
    } else if(e.type == "submit") {
      last_submit=e;
      continue;
    } else if(e.type == "submit" || e.type == "image") {
      // Broken for now.
      continue;
    }
    add_contents(e);
  }
  if(include_last_submit && last_submit) add_contents(last_submit, "submit");
  form_contents['using-ajax-really']=["1"];
  var action_to_use = override_action || f.action;
  if(!action_to_use) return true; // Cannot work
  xmlhttp_simple_full(action_to_use, form_contents, check_for_success, on_success, on_failure, options);
  return false;
}





function replace_el_with_id(id, w) {
  var s = document.getElementById(id);
  s.parentNode.replaceChild(w, s);
  if(!w.id) w.id=id;
}







function _add_nodes(e, contents) {
  var i;
  if(!contents) return false;
  if(contents.constructor!=Array) contents=[contents];
  for(i=0; i<contents.length; i++) {
    var item = contents[i];
    if(item === undefined) continue; // Should never happen, but... you know the drill.
    if(item === null) continue;
    if(item.nodeType) {
      e.appendChild(item);
    } else {
      if(name=="input") {
        alert("Can't add node to element of type '" + name + "'");
      } else {
        e.appendChild(document.createTextNode(item));
      }
    }
  }
  return true;
}






















function _mkel(name, attributes, contents, tail_tweaks) {
  var n, s;
  var e = document.createElement(name);
  if(attributes && attributes.constructor != Object) {
    tail_tweaks = contents;
    contents = attributes;
    attributes = {};
  }
  if(attributes) {
    for(n in attributes) {
      if(!n) continue;
      if(broken_windows_browser && n == "type" && name == "button") continue; // Skip it, cross fingers.
      if(
        attributes[n] === null ||
        attributes[n] === undefined ||
        (
          attributes[n].constructor != String &&
          attributes[n].constructor != Boolean
        )
      ) {
        






        if(!attributes[n]) continue;
      }
      if(attributes[n] && attributes[n].constructor == Object) {
        for(s in attributes[n]) e[n][s] = attributes[n][s];
      } else {
        e[n]=attributes[n];
      }
    }
  }
  if(contents && contents.constructor==Function) {
    tail_tweaks = contents;
    contents = undefined;
  }
  _add_nodes(e, contents);
  if(tail_tweaks)
    tail_tweaks.call(e, e);
  return e;
}





var popup__detail_container;
function prepare_detail_container() {
  window.onscroll=function() {
    if(popup__detail_container)
      document.body.removeChild(popup__detail_container);
    popup__detail_container = undefined;
  };
}
























function show_popup_detail(ndc, desired_width, options) {
  var i;
  options=options||{};
  var duration=0.5;
  if(undefined != options.popup_duration)
    duration = options.popup_duration;
  var detail_container = popup__detail_container;
  if(detail_container) try {
    document.body.removeChild(detail_container);
    document.body.removeChild(document.getElementById("clickable-underlay"));
  } catch(e) {}

  popup__detail_container = detail_container = ndc;
  var underlay;
  var onclick_closes = function() {
    if(underlay) document.body.removeChild(underlay);
    new Effect.Shrink(detail_container.id, {duration: duration, direction: "center"});
    if(options.onclose) options.onclose();
  };
  function fix_close_widget(w) {
    var original_onclick = w.onclick;
    w.onclick = function() {
      onclick_closes.call(this);
      if(original_onclick) original_onclick.call(this);
    };
  }
  if(options.closeWidget) {
    var close_widgets = (options.closeWidget.constructor == Array) ?
      options.closeWidget :
      [ options.closeWidget ];
    for(i=0; i<close_widgets.length; i++)
      fix_close_widget( close_widgets[i] );
  }

  var anchor_p = document.createElement("p");
  anchor_p.style.textAlign="center";
  if(options.footer_extra) {
    for(i=0; i<options.footer_extra.length; i++)
      anchor_p.appendChild(options.footer_extra[i]);
  }
  if(!options.closeWidget) {
    var close_el = document.createElement("button");
    //close_el.type="button";
    close_el.onclick = onclick_closes;
    close_el.appendChild(document.createTextNode("Close"));
    anchor_p.appendChild(close_el);
  }
  detail_container.appendChild(anchor_p);
  var de = document.documentElement;
  var w = window.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
  var h = window.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;

  detail_container.style.position= options.absolutePosition ? 'absolute' : 'fixed';
  detail_container.style.display="none";
  detail_container.style.zIndex=100;
  if(desired_width)
    detail_container.style.width = desired_width;
  if(options.be_square)
    detail_container.style.height = detail_container.style.width;
  detail_container.id="pseudo-popup";

  if(options.clickableUnderlay) {
    underlay = _mkel("div", {
      id: "clickable-underlay",
      style: {
        position: "fixed",
        top: "0px",
        left: "0px",
        width: w + "px",
        height: h + "px",
        zIndex: 99 
      },
      onclick: onclick_closes
    });
    if(options.shadowUnderlay) {
      underlay.style.background = "#888"; 
      if(broken_windows_browser) {
        underlay.style.background = "black";
        underlay.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=50)";
      } else {
        underlay.style.background = "rgba(0, 0, 0, 0.5)";
      }
    }
    document.body.appendChild(underlay);
  }

  document.body.appendChild(detail_container);

  var translate_x = 0;
  var translate_y = 0;
  if(options.adjustToScrollPos) {
    translate_x = window.scrollX || document.body.scrollLeft || document.documentElement.scrollLeft;
    translate_y = window.scrollY || document.body.scrollTop || document.documentElement.scrollTop;
  }

  detail_container.style.left = translate_x + Math.round((w - Element.getWidth(detail_container)) / 2 ) + "px";
  detail_container.style.top = translate_y + Math.round((h - Element.getHeight(detail_container)) / 2 ) + "px";

  if(detail_container.style.top.match(/^-/)) {
    detail_container.style.top = "20px";
  }
  new Effect.Grow(detail_container.id, {duration: duration, direction: "center"});
}






















function unhtml(content_to_decode, preserve_tags) {

  if(preserve_tags)
    content_to_decode =
      content_to_decode.replace(/</g, "&lt;").replace(/>/g, "&gt;");

  var span = document.createElement("span");
  span.innerHTML=content_to_decode;
  return(span.innerText || span.textContent);
}







function convert_html_entities(content_to_decode) {
  content_to_decode = content_to_decode.replace(/\n/g, '[BACKSLASH]n');
  var span = document.createElement("span");
  span.innerHTML=content_to_decode;
  return span.innerHTML.replace(/\[BACKSLASH\]n/g, '\n');
}







var rlbns__timeouts={};
function run_late_but_not_simultaneously(c, time) {
  var timeout = rlbns__timeouts[c];
  if(timeout) clearTimeout(timeout);
  rlbns__timeouts[c] = setTimeout(c, time);
  return rlbns__timeouts[c];
}




function _bind_to_any(t, f) { // Utility.
  return function() {return f.apply(t, arguments);};
}






var _utils_prototypes = {
  getElementsByClassName: function(strClassName){
    var i;
    if(!strClassName) return [];
    var arrElements = this.all;
    var arrReturnElements = [];
    strClassName = strClassName.replace(/-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(i=0; i<arrElements.length; i++){
      oElement = arrElements[i];
      if(oRegExp.test(oElement.className)){
        arrReturnElements.push(oElement);
      }
    }
    return (arrReturnElements);
  },
  stripSuffix: function(s) {
     if(this.indexOf(s)==0) return this.substring(s.length);
     return this;
   }
};

  if(!broken_windows_browser) {
    if(!String.prototype.stripSuffix) 
      String.prototype.stripSuffix = _utils_prototypes.stripSuffix;
  }








function _u_prototype() {
  var name = arguments[0];
  var a = [];
  var i;
  for(i=1; i<arguments.length; i++)
    a[i-1]=arguments[i];
  if(!this[name])
    this[name] = _utils_prototypes[name];
  return this[name].apply(this, a);
}





function ordinal(n) {
  var end = 'th';
  if(n % 100 < 10 || n % 100 > 20) {
    switch(n % 10) {
      case 1: end = 'st'; break;
      case 2: end = 'nd'; break;
      case 3: end = 'rd'; break;
    }
  }

  return end;
}





var month_names = ['January', 'February', 'March',
                   'April', 'May', 'June',
                   'July', 'August', 'September',
                   'October', 'November', 'December'];




var month_numbers = ['01', '02', '03',
                     '04', '05', '06',
                     '07', '08', '09',
                     '10', '11', '12'];






function ISO8601_to_GB(dt) {
  var d_t = dt.split(/[T ]/);
  d_t[0] = d_t[0].split(/-/).reverse().join("/");
  return d_t.reverse().join(" ");
}







function binary_insert(top_element, sort_function, o, build_nodes, on_add) {
  var cn = top_element.childNodes;
  var insertion_point = binary_search(top_element, sort_function, o);
  var a = build_nodes(o);
  var i;
  if(insertion_point >= cn.length) {
    for(i=0; i<a.length; i++) {
      top_element.appendChild(a[i]);
      if(on_add) on_add.call(a[i]);
    }
  } else {
    var add_before = cn.item(insertion_point);
    for(i=0; i<a.length; i++) {
      top_element.insertBefore(a[i], add_before);
      if(on_add) on_add.call(a[i]);
    }
  }
}
























function merge_node_list(top_element, build_nodes, node_to_uid, detect_change, objects_by_uid, sort_function, on_delete, on_add, on_no_change) {
  var cn = top_element.childNodes;
  // Pass 1: remove dirty nodes
  var skip_uids = {};
  var i, uid;
  for(i=cn.length-1; i>=0; i--) {
    var element_to_consider = cn.item(i);
    uid = node_to_uid(element_to_consider);
    if(!uid) continue;
    var o = objects_by_uid[uid];
    if(o && !detect_change(element_to_consider, o)) {
      skip_uids[uid] = 1;
      if(on_no_change)
        on_no_change.call(element_to_consider);
    } else {
      if(on_delete) {
        if(on_delete.call(element_to_consider))
          top_element.removeChild(element_to_consider);
      } else {
        top_element.removeChild(element_to_consider);
      }
    }
  }

  // Pass 2: add fresh nodes
  for(uid in objects_by_uid)
    if(!skip_uids[uid])
      binary_insert(top_element, sort_function, objects_by_uid[uid], build_nodes, on_add);
}









function binary_search(top_element, sort_function, o) {
  var cn = top_element.childNodes;
  var top = cn.length; // Note that this is just past the end.
  var bottom = 0;
  if(bottom == top) return 0; // This covers the zero-content scenario.

  var last_position = -1;
  var test_position = Math.round((top+bottom) / 2);
  if(test_position == top) {
    


    test_position--;
  }
  var i=0;
  do {
    var e = cn.item(test_position);
    var result = sort_function(e, o);
    if(result>0) {
      // In correct order, ie we're at or past the bottom.
      bottom = test_position + 1;
    } else if(result<0) {
      // Out of order
      top = test_position - 1;
    } else {
      // If == 0, might as well abort.
      break;
    }

    last_position = test_position;
    test_position = Math.round((top+bottom) / 2);
    i++;
  } while(test_position != last_position && test_position < cn.length && i<32);

  return test_position;
}













function build_chain(values, f, tf, sleep_ms) {
  var i;
  tf = tf || function() {};
  function _build_tf(v, otf) {
    function to_call() {
      f(v, otf);
    }
    if(sleep_ms) {
      return function() {
        setTimeout(to_call, sleep_ms); 
      };
    } else {
      return function() {
        f(v, otf);
      };
    }
  }
  for(i=values.length - 1; i>=0; i--)
    tf = _build_tf(values[i], tf);
  return tf;
}











function chain(values, f, tf, sleep_ms) {
  return build_chain(values, f, tf, sleep_ms)();
}
















function build_function_chain(functions, tf) {
  var i;
  tf = tf || function() {};
  function _build_tf(f, otf) {
    return function() {
      f(otf);
    };
  }
  for(i=functions.length - 1; i>=0; i--)
    tf = _build_tf(functions.item(i), tf);
  return tf;
}




function emulate_html5_input_placeholder() {
  function add_placeholder_emulation(input) {
    

    if(input.value == input.getAttribute("placeholder"))
      input.value = "";
    var old_onfocus = input.onfocus;
    var old_colour = input.style.color;
    var placeholder_onfocus = function() {
      this.onfocus = old_onfocus;
      this.value = "";
      this.style.color = old_colour;
      if(this.onfocus) this.onfocus();
    };
    var old_onblur = input.onblur;
    input.onblur = function() {
      if(this.value == "") {
        this.onfocus = placeholder_onfocus;
        this.value = this.getAttribute("placeholder");
        this.style.color = "#888";
      }
      if(old_onblur) old_onblur.call(this);
    };
    input.onblur();
  }

  var inputs = document.getElementsByTagName("input");
  var i;
  for(i=0; i<inputs.length; i++) {
    var input = inputs.item(i);
    if(input.type=="text" && input.getAttribute("placeholder") && (broken_windows_browser || !input.placeholder) )
      add_placeholder_emulation(input);
  }
}





var override_css_animation = false;





var manual_animate_interval_o;






var manual_animate_callbacks = [];







function animate_height(node, from, to, animate_length, replacement) {
  function clean_up() {
    if(!node.parentNode) return;
    if(replacement) {
      node.parentNode.replaceChild(replacement, node);
    } else {
      node.parentNode.removeChild(node);
    }
  }
  setTimeout(clean_up, animate_length);  

  





  function animation_thread() {
    var i;
    if(manual_animate_callbacks.length == 0) {
      clearInterval(manual_animate_interval_o);
      manual_animate_interval_o = undefined;
    } else {
      var mac_out = [];
      for(i=0; i<manual_animate_callbacks.length; i++) {
        var cb = manual_animate_callbacks[i];
        if(cb()) mac_out.push(cb);
      }
      manual_animate_callbacks = mac_out;
    }  
  }
  var start_point;
  function ah_inner() {
    if(!node.parentNode) return false;
    
    var offset = new Date() - start_point;
    if(offset > animate_length) offset=animate_length;
    if(offset < 0) offset=10;
    var completeness = offset / animate_length;

    var ch_from = from * ( 1 - completeness );
    var ch_to = to * completeness;
    
    node.firstChild.style.height = Math.floor(ch_from + ch_to) + "px";
    if(offset < animate_length) {
      return true;
    } else {
      return false;
    }
  }

  if(navigator.userAgent.match(/webkit/i) && !override_css_animation) {
    node.style.height = from + "px";
    node.style.WebkitTransitionProperty = "height";
    node.style.WebkitTransitionDuration = (animate_length/1000) + "s";
    setTimeout(function() {
      node.style.height = to + "px";
    }, 0);
  } else if(navigator.userAgent.match(/gecko/i) && !override_css_animation) {
    node.style.height = from + "px";
    node.style.MozTransitionProperty = "height";
    node.style.MozTransitionDuration = (animate_length/1000) + "s";
    setTimeout(function() {
      node.style.height = to + "px";
    }, 0);
  } else {
    
    var animate_preferred_interval = 100;

    start_point = new Date();
    manual_animate_callbacks.push(ah_inner);

    if(!manual_animate_interval_o) {
      manual_animate_interval_o =
        setInterval(animation_thread, animate_preferred_interval);
    }
  }
}




var small_screen = (screen.availWidth <= 480);





if(location.href.match(/simulate-iphone-screen/) || document.cookie.match(/simulate-iphone-screen/) ) {
  small_screen = true;

  
  var needed_stylesheets = [];
  var ls = document.head.getElementsByTagName("link");
  for(var i=0; i<ls.length; i++)
    if(ls.item(i).rel == "stylesheet" && ls.item(i).href.match(/-iphone.css/))
      needed_stylesheets.push(ls.item(i).href);

  
  for(var i=ls.length - 1; i>=0; i--)
    if(ls.item(i).className && ls.item(i).className.match(/html-head-css-large/))
      document.head.removeChild(ls.item(i));

  
  ls = document.head.getElementsByTagName("style");
  for(var i=ls.length - 1; i>=0; i--)
    if(ls.item(i).className && ls.item(i).className.match(/html-head-css-large/))
      document.head.removeChild(ls.item(i));

  
  for(var i=0; i<needed_stylesheets.length; i++)
    document.head.appendChild(
      _mkel("link", {
        rel: "stylesheet", 
        type: "text/css", 
        href: needed_stylesheets[i].replace(/-iphone.css/, "-iphone-inner.css")
      })
    );

  
  document.head.appendChild(
    _mkel("link", {
      rel: "stylesheet", 
      type: "text/css", 
      href: "/iphone-width-force.css"
    })
  );
  
}
var tpn;









function prune_other_nodes() {
	if(!small_screen) return;
	var bcn = document.body.childNodes;
	for(var i=bcn.length - 1; i>=0; i--) 
		if(!(bcn.item(i).className||"").match(/root-header/)) 
			document.body.removeChild(bcn.item(i));
	var tpncn = tpn.childNodes;
	for(var i=tpncn.length - 1; i>=0; i--) 
		if(!(tpncn.item(i).className||"").match(/root-header/)) 
			tpn.removeChild(tpncn.item(i));
}






function rewrite_head() {
	if(!small_screen) return;
	tpn = document.getElementById('js-adjust-self').parentNode;
	prune_other_nodes();
	function _t(s) {
		return document.createTextNode(s);
	}
	function _d(i, c) {
		var d = document.createElement("div");
		if(i) d.id = i;
		c = c || [];
		for(var i=0; i<c.length; i++) d.appendChild(c[i]);
		return d;
	}
	function _s(i, c, cl) {
		var s = document.createElement("span");
		if(i) s.id = i;
		if(cl) s.className = cl;
		c = c || [];
		for(var i=0; i<c.length; i++) s.appendChild(c[i]);
		return s;
	}
	function _a(i, u, n, nw) {
		var a = document.createElement("a");
		if(i) a.id = i;
		if(u) a.href = u;
		a.innerHTML = n||"";
		if(nw) a.target="_blank";
		return a;
	}
	function _i(i) {
		var img = document.createElement("img");
		if(i) img.id = i;
		return img;
	}
	var top = _d("header-block", [
		_d("top-text-block", [
			_d("top-link-block", [
				_a('home-link', '/', 'Home'),
				_a('logout-link', '/expired.cgi?logout=1', 'Log Out'),
				_s('help-block', [
					_a('help-link', '/support.cgi', "Help")
				]),
				_a('managing-domain-name', undefined, "", 1)
			]),
			_s('cp-name-block', undefined, 'cp-name-here')
		])
	]);
	tpn.id = 'body-block';
	top.appendChild(tpn);
	top.className = 'root-header';
	document.body.appendChild(top);
}
























































function http_simple(url, options) {
	options = options||{};
  options.args = options.args || {};

	// Convert the args to a POST string
	var post_content = "";
	for(var i in options.args) {
		if(options.args[i] === undefined) continue;
		if(options.args[i] instanceof Array) {
			for(var j=0; j<options.args[i].length; j++)
        
				post_content += i + "=" + encodeURIComponent(options.args[i][j]) + ";";
		} else {
			post_content += i + "=" + encodeURIComponent(options.args[i]) + ";";
		}
	}

	// Allocate the object
	var xmlhttp_o;
	if(broken_windows_browser) {
		xmlhttp_o = new ActiveXObject("MsXml2.XmlHttp");
	} else {
		xmlhttp_o = new XMLHttpRequest();
	}
  var detect_success = options.detectSuccess || function() {return true};
  var on_success = options.onSuccess || function() {return true};
  var on_failure = options.onFailure || function() {return false};
  var http_error_handling = options.httpErrorHandling || "both";
  var return_type = options.returnType || "xml";
  var method = post_content ? "post" : "get";

	var on_load_fired = false;
	function on_load() {
		on_load_fired = true;
		if(xmlhttp_o.status == 200) { 
      if(return_type == "text") {

        if(detect_success(xmlhttp_o.responseText))
          on_success(xmlhttp_o.responseText);
        else
          on_failure(xmlhttp_o.responseText);

      } else {

        var xmldoc=xmlhttp_o.responseXML;
        if(!xmldoc)
          on_failure();
        else if(!xmldoc.lastChild)
          on_failure(xmldoc.lastChild);
        else if(detect_success(xmldoc.lastChild))
          on_success(xmldoc.lastChild);
        else
          on_failure(xmldoc.lastChild);

      }
		} else if(xmlhttp_o.status && http_error_handling != "none") {
      if(! ( http_error_handling == "fail" && options.onFailure ) ) {
        alert_l("HTTP error: " + xmlhttp_o.status);
      }
      on_failure();
		}
	}
  var partial_load_failed = false;
	xmlhttp_o.onreadystatechange = function() {
		// if LOADED
		if(xmlhttp_o.readyState == 4) {
      // MSIE has to catch up here.
      if(partial_load_failed && options.onPartialLoad) options.onPartialLoad(xmlhttp_o.responseText);
      on_load();
    }
    // if partly loaded
		if(options.onPartialLoad && xmlhttp_o.readyState == 3 && ! partial_load_failed) {
      try {
        options.onPartialLoad(xmlhttp_o.responseText);
      } catch(e) {
        // Do nothing - MSIE will just have to wait.
        partial_load_failed = true;
      }
    }
	};
  if(method == "get") {
    xmlhttp_o.open("GET", url+"?"+post_content, options.sync ? false : true);
    xmlhttp_o.send();
  } else {
    xmlhttp_o.open("POST", url, options.sync ? false : true);
    xmlhttp_o.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    if(!navigator.userAgent.match(/AppleWebKit/)) {
      // WebKit hates this, but some other browsers may need it.
      xmlhttp_o.setRequestHeader("Content-length", post_content.length);
      xmlhttp_o.setRequestHeader("Connection", "close");
    }
    xmlhttp_o.send(post_content);
  }
	if(options.sync && ! on_load_fired) on_load();
	return xmlhttp_o;
}




function proper_split_msie(s, re) {
  var results = [];
  while(s.match(re)) {
    results.push(RegExp.leftContext);
    results.push(RegExp.$1);
    s = s.substr(RegExp.leftContext.length + RegExp.$1.length);
  }
  results.push(s);
  return results;
}

