if (!self.a11y) (function(d, n, r) {
  var ie, jscript, settings = {};
  function add(element, type, listener) { element.addEventListener(type, listener, false); };
  function remove(element, type, listener) { element.removeEventListener(type, listener, false); };

  /*@cc_on // msie hax
  function add(element, type, listener) { remove(element, type, listener); element.attachEvent("on"+ type, listener); };
  function remove(element, type, listener) { element.detachEvent("on"+ type, listener); };
  settings.jscript = jscript = @_jscript_version;
  settings.ie = ie = parseFloat(n.userAgent.split("MSIE ")[1]);
   if (d && d.execCommand) {
    try { d.execCommand("BackgroundImageCache",false, true); }
    catch (e) { }
  }
 @*/
 
  var l = {change:[], ready:[], load:[]};
  a11y = function(f) { a11y.change(f); };
  a11y.url = "a11y.jpg";
  a11y.tags = function(s, o) { return (o||d).getElementsByTagName(s); };
  a11y.id  = function(s, o) { return typeof s == "string" ? (o||d).getElementById(s) : s; };
  a11y.css = (self.getComputedStyle ?
    function(o, prop) { return getComputedStyle(o, "").getPropertyValue(prop); }:
    function(o, prop) {
      return o.currentStyle[
        prop.replace(/-(.)/g, function(c, s) { return s.toUpperCase() })
      ];
    }
  );
  a11y.change = function(f) { l.change.push(f); if (l.change.fired) dispatch("change"); };
  a11y.load   = function(f) {   l.load.push(f); if (  l.load.fired) dispatch("load");   };
  a11y.ready  = function(f) {  l.ready.push(f); if ( l.ready.fired) dispatch("ready");  };

  function dispatch(type) {
    for (var i = 0, n = l[type].length; i < n; i++) l[type][i](settings);
    if (type != "change") l[type].length = 0;
    l[type].fired = true;
  };

  if (ie) (function() {
    try { document.documentElement.doScroll("left");
      if (d.readyState != "complete") throw "wait"; dispatch("ready"); }
    catch (e) { setTimeout(arguments.callee); }})();
  else
    add(d, "DOMContentLoaded", function() { dispatch("ready"); });
  add(self, "load", function() { if (!l.ready.fired) dispatch("ready"); dispatch("load"); });

  // resize should dispatch change event
  function viewport(o) {
    var r = d.documentElement; if (!r||!r.clientWidth) r = d.body;
    o.innerWidth = r.clientWidth;
    o.innerHeight = r.clientHeight;
    try {d.recalc()} catch (helpCssExpressions) {}
  };

  var timer;
  add(ie ? self : d, "resize", function() {
    if (timer) clearTimeout(timer);
    timer = setTimeout(function() { dispatch("change") });
  });

  // wire up change detection code
  a11y.ready(function(o) {
    var b = d.getElementsByTagName("body")[0]; if (!b) return;
    var div = d.createElement("div"), id = div.id = "a11y-test-node";
    div.style.cssText = (
      'background-image: url("'+ a11y.url +'");' +
      'border-color: red green; color: rgb(1, 2, 3);' +
      'font: italic normal bold 69px a11y;' +
      'position: absolute; top: -999px;'
    );
    div.appendChild(d.createTextNode(" "));
    b.appendChild(div); b = div = null;
    var same = function(a, b) {
      for (var p in a) if (a[p] !== b[p]) return false; return true;
    };
    var check = function() {
      var div = d.getElementById(id), css = function(s) { return a11y.css(div, s) },
        bg = css("background-image"),
        bt = css("border-top-color"),
        br = css("border-right-color"),
        ff = css("font-family"),
        fs = css("font-size"),
        fS = css("font-style"),
        fw = css("font-weight"),
        oH = div.offsetHeight,
        needsA11y = (bt==br) || (bg!=null && (bg=="none"||bg=="url(invalid-url:)")),
        newSettings = {
          backgroundImages: !bg || !/none|invalid-url:/.test(bg),
          highContrastMode: (bt == br),
          ignoreColors: !/(rgb\(1, ?2, ?3\)|#010203)/i.test(a11y.css(div, "color")),
          ignoreFontSize: (oH < 69),
//        ignoreFontStyles: [ff,fs,fS,fw,oH],
          ie: ie,
          jscript: jscript
        };
      viewport(newSettings);
      if (!same(newSettings, settings)) setTimeout(function() { dispatch("change"); });
      settings = newSettings;
      if (!a11y.runOnce) setTimeout(check, 300);
    };
    check();
  });

})(self.document, self.navigator);
