/*  Prototype JavaScript framework, version 1.6.0.3
 *  (c) 2005-2008 Sam Stephenson
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://www.prototypejs.org/
 *
 *--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.6.0.3',

  Browser: {
    IE:     !!(window.attachEvent &&
      navigator.userAgent.indexOf('Opera') === -1),
    Opera:  navigator.userAgent.indexOf('Opera') > -1,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 &&
      navigator.userAgent.indexOf('KHTML') === -1,
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    SelectorsAPI: !!document.querySelector,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      document.createElement('div')['__proto__'] &&
      document.createElement('div')['__proto__'] !==
        document.createElement('form')['__proto__']
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
};

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;


/* Based on Alex Arnell's inheritance implementation. */
var Class = {
  create: function() {
    var parent = null, properties = $A(arguments);
    if (Object.isFunction(properties[0]))
      parent = properties.shift();

    function klass() {
      this.initialize.apply(this, arguments);
    }

    Object.extend(klass, Class.Methods);
    klass.superclass = parent;
    klass.subclasses = [];

    if (parent) {
      var subclass = function() { };
      subclass.prototype = parent.prototype;
      klass.prototype = new subclass;
      parent.subclasses.push(klass);
    }

    for (var i = 0; i < properties.length; i++)
      klass.addMethods(properties[i]);

    if (!klass.prototype.initialize)
      klass.prototype.initialize = Prototype.emptyFunction;

    klass.prototype.constructor = klass;

    return klass;
  }
};

Class.Methods = {
  addMethods: function(source) {
    var ancestor   = this.superclass && this.superclass.prototype;
    var properties = Object.keys(source);

    if (!Object.keys({ toString: true }).length)
      properties.push("toString", "valueOf");

    for (var i = 0, length = properties.length; i < length; i++) {
      var property = properties[i], value = source[property];
      if (ancestor && Object.isFunction(value) &&
          value.argumentNames().first() == "$super") {
        var method = value;
        value = (function(m) {
          return function() { return ancestor[m].apply(this, arguments) };
        })(property).wrap(method);

        value.valueOf = method.valueOf.bind(method);
        value.toString = method.toString.bind(method);
      }
      this.prototype[property] = value;
    }

    return this;
  }
};

var Abstract = { };

Object.extend = function(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
};

Object.extend(Object, {
  inspect: function(object) {
    try {
      if (Object.isUndefined(object)) return 'undefined';
      if (object === null) return 'null';
      return object.inspect ? object.inspect() : String(object);
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
  },

  toJSON: function(object) {
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (Object.isElement(object)) return;

    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (!Object.isUndefined(value))
        results.push(property.toJSON() + ': ' + value);
    }

    return '{' + results.join(', ') + '}';
  },

  toQueryString: function(object) {
    return $H(object).toQueryString();
  },

  toHTML: function(object) {
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
  },

  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },

  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },

  clone: function(object) {
    return Object.extend({ }, object);
  },

  isElement: function(object) {
    return !!(object && object.nodeType == 1);
  },

  isArray: function(object) {
    return object != null && typeof object == "object" &&
      'splice' in object && 'join' in object;
  },

  isHash: function(object) {
    return object instanceof Hash;
  },

  isFunction: function(object) {
    return typeof object == "function";
  },

  isString: function(object) {
    return typeof object == "string";
  },

  isNumber: function(object) {
    return typeof object == "number";
  },

  isUndefined: function(object) {
    return typeof object == "undefined";
  }
});

Object.extend(Function.prototype, {
  argumentNames: function() {
    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
      .replace(/\s+/g, '').split(',');
    return names.length == 1 && !names[0] ? [] : names;
  },

  bind: function() {
    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
    var __method = this, args = $A(arguments), object = args.shift();
    return function() {
      return __method.apply(object, args.concat($A(arguments)));
    }
  },

  bindAsEventListener: function() {
    var __method = this, args = $A(arguments), object = args.shift();
    return function(event) {
      return __method.apply(object, [event || window.event].concat(args));
    }
  },

  curry: function() {
    if (!arguments.length) return this;
    var __method = this, args = $A(arguments);
    return function() {
      return __method.apply(this, args.concat($A(arguments)));
    }
  },

  delay: function() {
    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
    return window.setTimeout(function() {
      return __method.apply(__method, args);
    }, timeout);
  },

  defer: function() {
    var args = [0.01].concat($A(arguments));
    return this.delay.apply(this, args);
  },

  wrap: function(wrapper) {
    var __method = this;
    return function() {
      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
    }
  },

  methodize: function() {
    if (this._methodized) return this._methodized;
    var __method = this;
    return this._methodized = function() {
      return __method.apply(null, [this].concat($A(arguments)));
    };
  }
});

Date.prototype.toJSON = function() {
  return '"' + this.getUTCFullYear() + '-' +
    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
    this.getUTCDate().toPaddedString(2) + 'T' +
    this.getUTCHours().toPaddedString(2) + ':' +
    this.getUTCMinutes().toPaddedString(2) + ':' +
    this.getUTCSeconds().toPaddedString(2) + 'Z"';
};

var Try = {
  these: function() {
    var returnValue;

    for (var i = 0, length = arguments.length; i < length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) { }
    }

    return returnValue;
  }
};

RegExp.prototype.match = RegExp.prototype.test;

RegExp.escape = function(str) {
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create({
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;

    this.registerCallback();
  },

  registerCallback: function() {
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  execute: function() {
    this.callback(this);
  },

  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.execute();
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
});
Object.extend(String, {
  interpret: function(value) {
    return value == null ? '' : String(value);
  },
  specialChar: {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '\\': '\\\\'
  }
});

Object.extend(String.prototype, {
  gsub: function(pattern, replacement) {
    var result = '', source = this, match;
    replacement = arguments.callee.prepareReplacement(replacement);

    while (source.length > 0) {
      if (match = source.match(pattern)) {
        result += source.slice(0, match.index);
        result += String.interpret(replacement(match));
        source  = source.slice(match.index + match[0].length);
      } else {
        result += source, source = '';
      }
    }
    return result;
  },

  sub: function(pattern, replacement, count) {
    replacement = this.gsub.prepareReplacement(replacement);
    count = Object.isUndefined(count) ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  },

  scan: function(pattern, iterator) {
    this.gsub(pattern, iterator);
    return String(this);
  },

  truncate: function(length, truncation) {
    length = length || 30;
    truncation = Object.isUndefined(truncation) ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : String(this);
  },

  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  },

  stripTags: function() {
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  stripScripts: function() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  },

  extractScripts: function() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  },

  escapeHTML: function() {
    var self = arguments.callee;
    self.text.data = this;
    return self.div.innerHTML;
  },

  unescapeHTML: function() {
    var div = new Element('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
      div.childNodes[0].nodeValue) : '';
  },

  toQueryParams: function(separator) {
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    if (!match) return { };

    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
      if ((pair = pair.split('='))[0]) {
        var key = decodeURIComponent(pair.shift());
        var value = pair.length > 1 ? pair.join('=') : pair[0];
        if (value != undefined) value = decodeURIComponent(value);

        if (key in hash) {
          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
          hash[key].push(value);
        }
        else hash[key] = value;
      }
      return hash;
    });
  },

  toArray: function() {
    return this.split('');
  },

  succ: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  times: function(count) {
    return count < 1 ? '' : new Array(count + 1).join(this);
  },

  camelize: function() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  },

  capitalize: function() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
  },

  dasherize: function() {
    return this.gsub(/_/,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
      var character = String.specialChar[match[0]];
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  },

  toJSON: function() {
    return this.inspect(true);
  },

  unfilterJSON: function(filter) {
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
  },

  isJSON: function() {
    var str = this;
    if (str.blank()) return false;
    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
  },

  evalJSON: function(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  },

  include: function(pattern) {
    return this.indexOf(pattern) > -1;
  },

  startsWith: function(pattern) {
    return this.indexOf(pattern) === 0;
  },

  endsWith: function(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  },

  empty: function() {
    return this == '';
  },

  blank: function() {
    return /^\s*$/.test(this);
  },

  interpolate: function(object, pattern) {
    return new Template(this, pattern).evaluate(object);
  }
});

if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
  escapeHTML: function() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  },
  unescapeHTML: function() {
    return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (Object.isFunction(replacement)) return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
};

String.prototype.parseQuery = String.prototype.toQueryParams;

Object.extend(String.prototype.escapeHTML, {
  div:  document.createElement('div'),
  text: document.createTextNode('')
});

String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);

var Template = Class.create({
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern = pattern || Template.Pattern;
  },

  evaluate: function(object) {
    if (Object.isFunction(object.toTemplateReplacements))
      object = object.toTemplateReplacements();

    return this.template.gsub(this.pattern, function(match) {
      if (object == null) return '';

      var before = match[1] || '';
      if (before == '\\') return match[2];

      var ctx = object, expr = match[3];
      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
      match = pattern.exec(expr);
      if (match == null) return before;

      while (match != null) {
        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
        ctx = ctx[comp];
        if (null == ctx || '' == match[3]) break;
        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
        match = pattern.exec(expr);
      }

      return before + String.interpret(ctx);
    });
  }
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;

var $break = { };

var Enumerable = {
  each: function(iterator, context) {
    var index = 0;
    try {
      this._each(function(value) {
        iterator.call(context, value, index++);
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  },

  eachSlice: function(number, iterator, context) {
    var index = -number, slices = [], array = this.toArray();
    if (number < 1) return array;
    while ((index += number) < array.length)
      slices.push(array.slice(index, index+number));
    return slices.collect(iterator, context);
  },

  all: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var result = true;
    this.each(function(value, index) {
      result = result && !!iterator.call(context, value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var result = false;
    this.each(function(value, index) {
      if (result = !!iterator.call(context, value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var results = [];
    this.each(function(value, index) {
      results.push(iterator.call(context, value, index));
    });
    return results;
  },

  detect: function(iterator, context) {
    var result;
    this.each(function(value, index) {
      if (iterator.call(context, value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator, context) {
    var results = [];
    this.each(function(value, index) {
      if (iterator.call(context, value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(filter, iterator, context) {
    iterator = iterator || Prototype.K;
    var results = [];

    if (Object.isString(filter))
      filter = new RegExp(filter);

    this.each(function(value, index) {
      if (filter.match(value))
        results.push(iterator.call(context, value, index));
    });
    return results;
  },

  include: function(object) {
    if (Object.isFunction(this.indexOf))
      if (this.indexOf(object) != -1) return true;

    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  },

  inGroupsOf: function(number, fillWith) {
    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
    return this.eachSlice(number, function(slice) {
      while(slice.length < number) slice.push(fillWith);
      return slice;
    });
  },

  inject: function(memo, iterator, context) {
    this.each(function(value, index) {
      memo = iterator.call(context, memo, value, index);
    });
    return memo;
  },

  invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.map(function(value) {
      return value[method].apply(value, args);
    });
  },

  max: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator.call(context, value, index);
      if (result == null || value >= result)
        result = value;
    });
    return result;
  },

  min: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator.call(context, value, index);
      if (result == null || value < result)
        result = value;
    });
    return result;
  },

  partition: function(iterator, context) {
    iterator = iterator || Prototype.K;
    var trues = [], falses = [];
    this.each(function(value, index) {
      (iterator.call(context, value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator, context) {
    var results = [];
    this.each(function(value, index) {
      if (!iterator.call(context, value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator, context) {
    return this.map(function(value, index) {
      return {
        value: value,
        criteria: iterator.call(context, value, index)
      };
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  },

  toArray: function() {
    return this.map();
  },

  zip: function() {
    var iterator = Prototype.K, args = $A(arguments);
    if (Object.isFunction(args.last()))
      iterator = args.pop();

    var collections = [this].concat(args).map($A);
    return this.map(function(value, index) {
      return iterator(collections.pluck(index));
    });
  },

  size: function() {
    return this.toArray().length;
  },

  inspect: function() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }
};

Object.extend(Enumerable, {
  map:     Enumerable.collect,
  find:    Enumerable.detect,
  select:  Enumerable.findAll,
  filter:  Enumerable.findAll,
  member:  Enumerable.include,
  entries: Enumerable.toArray,
  every:   Enumerable.all,
  some:    Enumerable.any
});
function $A(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) return iterable.toArray();
  var length = iterable.length || 0, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

if (Prototype.Browser.WebKit) {
  $A = function(iterable) {
    if (!iterable) return [];
    // In Safari, only use the `toArray` method if it's not a NodeList.
    // A NodeList is a function, has an function `item` property, and a numeric
    // `length` property. Adapted from Google Doctype.
    if (!(typeof iterable === 'function' && typeof iterable.length ===
        'number' && typeof iterable.item === 'function') && iterable.toArray)
      return iterable.toArray();
    var length = iterable.length || 0, results = new Array(length);
    while (length--) results[length] = iterable[length];
    return results;
  };
}

Array.from = $A;

Object.extend(Array.prototype, Enumerable);

if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(Object.isArray(value) ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  },

  intersect: function(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  },

  toJSON: function() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
});

// use native browser JS 1.6 implementation if available
if (Object.isFunction(Array.prototype.forEach))
  Array.prototype._each = Array.prototype.forEach;

if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
};

if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
  var n = this.slice(0, i).reverse().indexOf(item);
  return (n < 0) ? n : i - n - 1;
};

Array.prototype.toArray = Array.prototype.clone;

function $w(string) {
  if (!Object.isString(string)) return [];
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if (Prototype.Browser.Opera){
  Array.prototype.concat = function() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (Object.isArray(arguments[i])) {
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  };
}
Object.extend(Number.prototype, {
  toColorPart: function() {
    return this.toPaddedString(2, 16);
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator, context) {
    $R(0, this, true).each(iterator, context);
    return this;
  },

  toPaddedString: function(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  },

  toJSON: function() {
    return isFinite(this) ? this.toString() : 'null';
  }
});

$w('abs round ceil floor').each(function(method){
  Number.prototype[method] = Math[method].methodize();
});
function $H(object) {
  return new Hash(object);
};

var Hash = Class.create(Enumerable, (function() {

  function toQueryPair(key, value) {
    if (Object.isUndefined(value)) return key;
    return key + '=' + encodeURIComponent(String.interpret(value));
  }

  return {
    initialize: function(object) {
      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
    },

    _each: function(iterator) {
      for (var key in this._object) {
        var value = this._object[key], pair = [key, value];
        pair.key = key;
        pair.value = value;
        iterator(pair);
      }
    },

    set: function(key, value) {
      return this._object[key] = value;
    },

    get: function(key) {
      // simulating poorly supported hasOwnProperty
      if (this._object[key] !== Object.prototype[key])
        return this._object[key];
    },

    unset: function(key) {
      var value = this._object[key];
      delete this._object[key];
      return value;
    },

    toObject: function() {
      return Object.clone(this._object);
    },

    keys: function() {
      return this.pluck('key');
    },

    values: function() {
      return this.pluck('value');
    },

    index: function(value) {
      var match = this.detect(function(pair) {
        return pair.value === value;
      });
      return match && match.key;
    },

    merge: function(object) {
      return this.clone().update(object);
    },

    update: function(object) {
      return new Hash(object).inject(this, function(result, pair) {
        result.set(pair.key, pair.value);
        return result;
      });
    },

    toQueryString: function() {
      return this.inject([], function(results, pair) {
        var key = encodeURIComponent(pair.key), values = pair.value;

        if (values && typeof values == 'object') {
          if (Object.isArray(values))
            return results.concat(values.map(toQueryPair.curry(key)));
        } else results.push(toQueryPair(key, values));
        return results;
      }).join('&');
    },

    inspect: function() {
      return '#<Hash:{' + this.map(function(pair) {
        return pair.map(Object.inspect).join(': ');
      }).join(', ') + '}>';
    },

    toJSON: function() {
      return Object.toJSON(this.toObject());
    },

    clone: function() {
      return new Hash(this);
    }
  }
})());

Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
Hash.from = $H;
var ObjectRange = Class.create(Enumerable, {
  initialize: function(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  },

  _each: function(iterator) {
    var value = this.start;
    while (this.include(value)) {
      iterator(value);
      value = value.succ();
    }
  },

  include: function(value) {
    if (value < this.start)
      return false;
    if (this.exclusive)
      return value < this.end;
    return value <= this.end;
  }
});

var $R = function(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
};

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },

  activeRequestCount: 0
};

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responder) {
    if (!this.include(responder))
      this.responders.push(responder);
  },

  unregister: function(responder) {
    this.responders = this.responders.without(responder);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (Object.isFunction(responder[callback])) {
        try {
          responder[callback].apply(responder, [request, transport, json]);
        } catch (e) { }
      }
    });
  }
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
  onCreate:   function() { Ajax.activeRequestCount++ },
  onComplete: function() { Ajax.activeRequestCount-- }
});

Ajax.Base = Class.create({
  initialize: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      contentType:  'application/x-www-form-urlencoded',
      encoding:     'UTF-8',
      parameters:   '',
      evalJSON:     true,
      evalJS:       true
    };
    Object.extend(this.options, options || { });

    this.options.method = this.options.method.toLowerCase();

    if (Object.isString(this.options.parameters))
      this.options.parameters = this.options.parameters.toQueryParams();
    else if (Object.isHash(this.options.parameters))
      this.options.parameters = this.options.parameters.toObject();
  }
});

Ajax.Request = Class.create(Ajax.Base, {
  _complete: false,

  initialize: function($super, url, options) {
    $super(options);
    this.transport = Ajax.getTransport();
    this.request(url);
  },

  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = Object.clone(this.options.parameters);

    if (!['get', 'post'].include(this.method)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }

    this.parameters = params;

    if (params = Object.toQueryString(params)) {
      // when GET, append parameters to URL
      if (this.method == 'get')
        this.url += (this.url.include('?') ? '&' : '?') + params;
      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        params += '&_=';
    }

    try {
      var response = new Ajax.Response(this);
      if (this.options.onCreate) this.options.onCreate(response);
      Ajax.Responders.dispatch('onCreate', this, response);

      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);

      this.transport.onreadystatechange = this.onStateChange.bind(this);
      this.setRequestHeaders();

      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
      this.transport.send(this.body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers['Connection'] = 'close';
    }

    // user-defined headers
    if (typeof this.options.requestHeaders == 'object') {
      var extras = this.options.requestHeaders;

      if (Object.isFunction(extras.push))
        for (var i = 0, length = extras.length; i < length; i += 2)
          headers[extras[i]] = extras[i+1];
      else
        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
    }

    for (var name in headers)
      this.transport.setRequestHeader(name, headers[name]);
  },

  success: function() {
    var status = this.getStatus();
    return !status || (status >= 200 && status < 300);
  },

  getStatus: function() {
    try {
      return this.transport.status || 0;
    } catch (e) { return 0 }
  },

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + response.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(response, response.headerJSON);
      } catch (e) {
        this.dispatchException(e);
      }

      var contentType = response.getHeader('Content-type');
      if (this.options.evalJS == 'force'
          || (this.options.evalJS && this.isSameOrigin() && contentType
          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
        this.evalResponse();
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
    } catch (e) {
      this.dispatchException(e);
    }

    if (state == 'Complete') {
      // avoid memory leak in MSIE: clean up
      this.transport.onreadystatechange = Prototype.emptyFunction;
    }
  },

  isSameOrigin: function() {
    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
      protocol: location.protocol,
      domain: document.domain,
      port: location.port ? ':' + location.port : ''
    }));
  },

  getHeader: function(name) {
    try {
      return this.transport.getResponseHeader(name) || null;
    } catch (e) { return null }
  },

  evalResponse: function() {
    try {
      return eval((this.transport.responseText || '').unfilterJSON());
    } catch (e) {
      this.dispatchException(e);
    }
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Response = Class.create({
  initialize: function(request){
    this.request = request;
    var transport  = this.transport  = request.transport,
        readyState = this.readyState = transport.readyState;

    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
      this.status       = this.getStatus();
      this.statusText   = this.getStatusText();
      this.responseText = String.interpret(transport.responseText);
      this.headerJSON   = this._getHeaderJSON();
    }

    if(readyState == 4) {
      var xml = transport.responseXML;
      this.responseXML  = Object.isUndefined(xml) ? null : xml;
      this.responseJSON = this._getResponseJSON();
    }
  },

  status:      0,
  statusText: '',

  getStatus: Ajax.Request.prototype.getStatus,

  getStatusText: function() {
    try {
      return this.transport.statusText || '';
    } catch (e) { return '' }
  },

  getHeader: Ajax.Request.prototype.getHeader,

  getAllHeaders: function() {
    try {
      return this.getAllResponseHeaders();
    } catch (e) { return null }
  },

  getResponseHeader: function(name) {
    return this.transport.getResponseHeader(name);
  },

  getAllResponseHeaders: function() {
    return this.transport.getAllResponseHeaders();
  },

  _getHeaderJSON: function() {
    var json = this.getHeader('X-JSON');
    if (!json) return null;
    json = decodeURIComponent(escape(json));
    try {
      return json.evalJSON(this.request.options.sanitizeJSON ||
        !this.request.isSameOrigin());
    } catch (e) {
      this.request.dispatchException(e);
    }
  },

  _getResponseJSON: function() {
    var options = this.request.options;
    if (!options.evalJSON || (options.evalJSON != 'force' &&
      !(this.getHeader('Content-type') || '').include('application/json')) ||
        this.responseText.blank())
          return null;
    try {
      return this.responseText.evalJSON(options.sanitizeJSON ||
        !this.request.isSameOrigin());
    } catch (e) {
      this.request.dispatchException(e);
    }
  }
});

Ajax.Updater = Class.create(Ajax.Request, {
  initialize: function($super, container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    };

    options = Object.clone(options);
    var onComplete = options.onComplete;
    options.onComplete = (function(response, json) {
      this.updateContent(response.responseText);
      if (Object.isFunction(onComplete)) onComplete(response, json);
    }).bind(this);

    $super(url, options);
  },

  updateContent: function(responseText) {
    var receiver = this.container[this.success() ? 'success' : 'failure'],
        options = this.options;

    if (!options.evalScripts) responseText = responseText.stripScripts();

    if (receiver = $(receiver)) {
      if (options.insertion) {
        if (Object.isString(options.insertion)) {
          var insertion = { }; insertion[options.insertion] = responseText;
          receiver.insert(insertion);
        }
        else options.insertion(receiver, responseText);
      }
      else receiver.update(responseText);
    }
  }
});

Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
  initialize: function($super, container, url, options) {
    $super(options);
    this.onComplete = this.options.onComplete;

    this.frequency = (this.options.frequency || 2);
    this.decay = (this.options.decay || 1);

    this.updater = { };
    this.container = container;
    this.url = url;

    this.start();
  },

  start: function() {
    this.options.onComplete = this.updateComplete.bind(this);
    this.onTimerEvent();
  },

  stop: function() {
    this.updater.options.onComplete = undefined;
    clearTimeout(this.timer);
    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  },

  updateComplete: function(response) {
    if (this.options.decay) {
      this.decay = (response.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = response.responseText;
    }
    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
  },

  onTimerEvent: function() {
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
  }
});
function $(element) {
  if (arguments.length > 1) {
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
      elements.push($(arguments[i]));
    return elements;
  }
  if (Object.isString(element))
    element = document.getElementById(element);
  return Element.extend(element);
}

if (Prototype.BrowserFeatures.XPath) {
  document._getElementsByXPath = function(expression, parentElement) {
    var results = [];
    var query = document.evaluate(expression, $(parentElement) || document,
      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, length = query.snapshotLength; i < length; i++)
      results.push(Element.extend(query.snapshotItem(i)));
    return results;
  };
}

/*--------------------------------------------------------------------------*/

if (!window.Node) var Node = { };

if (!Node.ELEMENT_NODE) {
  // DOM level 2 ECMAScript Language Binding
  Object.extend(Node, {
    ELEMENT_NODE: 1,
    ATTRIBUTE_NODE: 2,
    TEXT_NODE: 3,
    CDATA_SECTION_NODE: 4,
    ENTITY_REFERENCE_NODE: 5,
    ENTITY_NODE: 6,
    PROCESSING_INSTRUCTION_NODE: 7,
    COMMENT_NODE: 8,
    DOCUMENT_NODE: 9,
    DOCUMENT_TYPE_NODE: 10,
    DOCUMENT_FRAGMENT_NODE: 11,
    NOTATION_NODE: 12
  });
}

(function() {
  var element = this.Element;
  this.Element = function(tagName, attributes) {
    attributes = attributes || { };
    tagName = tagName.toLowerCase();
    var cache = Element.cache;
    if (Prototype.Browser.IE && attributes.name) {
      tagName = '<' + tagName + ' name="' + attributes.name + '">';
      delete attributes.name;
      return Element.writeAttribute(document.createElement(tagName), attributes);
    }
    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
  };
  Object.extend(this.Element, element || { });
  if (element) this.Element.prototype = element.prototype;
}).call(window);

Element.cache = { };

Element.Methods = {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function(element) {
    element = $(element);
    Element[Element.visible(element) ? 'hide' : 'show'](element);
    return element;
  },

  hide: function(element) {
    element = $(element);
    element.style.display = 'none';
    return element;
  },

  show: function(element) {
    element = $(element);
    element.style.display = '';
    return element;
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);
    content = Object.toHTML(content);
    element.innerHTML = content.stripScripts();
    content.evalScripts.bind(content).defer();
    return element;
  },

  replace: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    else if (!Object.isElement(content)) {
      content = Object.toHTML(content);
      var range = element.ownerDocument.createRange();
      range.selectNode(element);
      content.evalScripts.bind(content).defer();
      content = range.createContextualFragment(content.stripScripts());
    }
    element.parentNode.replaceChild(content, element);
    return element;
  },

  insert: function(element, insertions) {
    element = $(element);

    if (Object.isString(insertions) || Object.isNumber(insertions) ||
        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
          insertions = {bottom:insertions};

    var content, insert, tagName, childNodes;

    for (var position in insertions) {
      content  = insertions[position];
      position = position.toLowerCase();
      insert = Element._insertionTranslations[position];

      if (content && content.toElement) content = content.toElement();
      if (Object.isElement(content)) {
        insert(element, content);
        continue;
      }

      content = Object.toHTML(content);

      tagName = ((position == 'before' || position == 'after')
        ? element.parentNode : element).tagName.toUpperCase();

      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());

      if (position == 'top' || position == 'after') childNodes.reverse();
      childNodes.each(insert.curry(element));

      content.evalScripts.bind(content).defer();
    }

    return element;
  },

  wrap: function(element, wrapper, attributes) {
    element = $(element);
    if (Object.isElement(wrapper))
      $(wrapper).writeAttribute(attributes || { });
    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
    else wrapper = new Element('div', wrapper);
    if (element.parentNode)
      element.parentNode.replaceChild(wrapper, element);
    wrapper.appendChild(element);
    return wrapper;
  },

  inspect: function(element) {
    element = $(element);
    var result = '<' + element.tagName.toLowerCase();
    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
      var property = pair.first(), attribute = pair.last();
      var value = (element[property] || '').toString();
      if (value) result += ' ' + attribute + '=' + value.inspect(true);
    });
    return result + '>';
  },

  recursivelyCollect: function(element, property) {
    element = $(element);
    var elements = [];
    while (element = element[property])
      if (element.nodeType == 1)
        elements.push(Element.extend(element));
    return elements;
  },

  ancestors: function(element) {
    return $(element).recursivelyCollect('parentNode');
  },

  descendants: function(element) {
    return $(element).select("*");
  },

  firstDescendant: function(element) {
    element = $(element).firstChild;
    while (element && element.nodeType != 1) element = element.nextSibling;
    return $(element);
  },

  immediateDescendants: function(element) {
    if (!(element = $(element).firstChild)) return [];
    while (element && element.nodeType != 1) element = element.nextSibling;
    if (element) return [element].concat($(element).nextSiblings());
    return [];
  },

  previousSiblings: function(element) {
    return $(element).recursivelyCollect('previousSibling');
  },

  nextSiblings: function(element) {
    return $(element).recursivelyCollect('nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return element.previousSiblings().reverse().concat(element.nextSiblings());
  },

  match: function(element, selector) {
    if (Object.isString(selector))
      selector = new Selector(selector);
    return selector.match($(element));
  },

  up: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(element.parentNode);
    var ancestors = element.ancestors();
    return Object.isNumber(expression) ? ancestors[expression] :
      Selector.findElement(ancestors, expression, index);
  },

  down: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return element.firstDescendant();
    return Object.isNumber(expression) ? element.descendants()[expression] :
      Element.select(element, expression)[index || 0];
  },

  previous: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
    var previousSiblings = element.previousSiblings();
    return Object.isNumber(expression) ? previousSiblings[expression] :
      Selector.findElement(previousSiblings, expression, index);
  },

  next: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
    var nextSiblings = element.nextSiblings();
    return Object.isNumber(expression) ? nextSiblings[expression] :
      Selector.findElement(nextSiblings, expression, index);
  },

  select: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element, args);
  },

  adjacent: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element.parentNode, args).without(element);
  },

  identify: function(element) {
    element = $(element);
    var id = element.readAttribute('id'), self = arguments.callee;
    if (id) return id;
    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
    element.writeAttribute('id', id);
    return id;
  },

  readAttribute: function(element, name) {
    element = $(element);
    if (Prototype.Browser.IE) {
      var t = Element._attributeTranslations.read;
      if (t.values[name]) return t.values[name](element, name);
      if (t.names[name]) name = t.names[name];
      if (name.include(':')) {
        return (!element.attributes || !element.attributes[name]) ? null :
         element.attributes[name].value;
      }
    }
    return element.getAttribute(name);
  },

  writeAttribute: function(element, name, value) {
    element = $(element);
    var attributes = { }, t = Element._attributeTranslations.write;

    if (typeof name == 'object') attributes = name;
    else attributes[name] = Object.isUndefined(value) ? true : value;

    for (var attr in attributes) {
      name = t.names[attr] || attr;
      value = attributes[attr];
      if (t.values[attr]) name = t.values[attr](element, value);
      if (value === false || value === null)
        element.removeAttribute(name);
      else if (value === true)
        element.setAttribute(name, name);
      else element.setAttribute(name, value);
    }
    return element;
  },

  getHeight: function(element) {
    return $(element).getDimensions().height;
  },

  getWidth: function(element) {
    return $(element).getDimensions().width;
  },

  classNames: function(element) {
    return new Element.ClassNames(element);
  },

  hasClassName: function(element, className) {
    if (!(element = $(element))) return;
    var elementClassName = element.className;
    return (elementClassName.length > 0 && (elementClassName == className ||
      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    if (!element.hasClassName(className))
      element.className += (element.className ? ' ' : '') + className;
    return element;
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    element.className = element.className.replace(
      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
    return element;
  },

  toggleClassName: function(element, className) {
    if (!(element = $(element))) return;
    return element[element.hasClassName(className) ?
      'removeClassName' : 'addClassName'](className);
  },

  // removes whitespace-only text node children
  cleanWhitespace: function(element) {
    element = $(element);
    var node = element.firstChild;
    while (node) {
      var nextNode = node.nextSibling;
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        element.removeChild(node);
      node = nextNode;
    }
    return element;
  },

  empty: function(element) {
    return $(element).innerHTML.blank();
  },

  descendantOf: function(element, ancestor) {
    element = $(element), ancestor = $(ancestor);

    if (element.compareDocumentPosition)
      return (element.compareDocumentPosition(ancestor) & 8) === 8;

    if (ancestor.contains)
      return ancestor.contains(element) && ancestor !== element;

    while (element = element.parentNode)
      if (element == ancestor) return true;

    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = element.cumulativeOffset();
    window.scrollTo(pos[0], pos[1]);
    return element;
  },

  getStyle: function(element, style) {
    element = $(element);
    style = style == 'float' ? 'cssFloat' : style.camelize();
    var value = element.style[style];
    if (!value || value == 'auto') {
      var css = document.defaultView.getComputedStyle(element, null);
      value = css ? css[style] : null;
    }
    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
    return value == 'auto' ? null : value;
  },

  getOpacity: function(element) {
    return $(element).getStyle('opacity');
  },

  setStyle: function(element, styles) {
    element = $(element);
    var elementStyle = element.style, match;
    if (Object.isString(styles)) {
      element.style.cssText += ';' + styles;
      return styles.include('opacity') ?
        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
    }
    for (var property in styles)
      if (property == 'opacity') element.setOpacity(styles[property]);
      else
        elementStyle[(property == 'float' || property == 'cssFloat') ?
          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
            property] = styles[property];

    return element;
  },

  setOpacity: function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
    return element;
  },

  getDimensions: function(element) {
    element = $(element);
    var display = element.getStyle('display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (Prototype.Browser.Opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
    return element;
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
    return element;
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return element;
    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
    if (element._overflow !== 'hidden')
      element.style.overflow = 'hidden';
    return element;
  },

  undoClipping: function(element) {
    element = $(element);
    if (!element._overflow) return element;
    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
    element._overflow = null;
    return element;
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  positionedOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
      if (element) {
        if (element.tagName.toUpperCase() == 'BODY') break;
        var p = Element.getStyle(element, 'position');
        if (p !== 'static') break;
      }
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  absolutize: function(element) {
    element = $(element);
    if (element.getStyle('position') == 'absolute') return element;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    var offsets = element.positionedOffset();
    var top     = offsets[1];
    var left    = offsets[0];
    var width   = element.clientWidth;
    var height  = element.clientHeight;

    element._originalLeft   = left - parseFloat(element.style.left  || 0);
    element._originalTop    = top  - parseFloat(element.style.top || 0);
    element._originalWidth  = element.style.width;
    element._originalHeight = element.style.height;

    element.style.position = 'absolute';
    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.width  = width + 'px';
    element.style.height = height + 'px';
    return element;
  },

  relativize: function(element) {
    element = $(element);
    if (element.getStyle('position') == 'relative') return element;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    element.style.position = 'relative';
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.height = element._originalHeight;
    element.style.width  = element._originalWidth;
    return element;
  },

  cumulativeScrollOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  getOffsetParent: function(element) {
    if (element.offsetParent) return $(element.offsetParent);
    if (element == document.body) return $(element);

    while ((element = element.parentNode) && element != document.body)
      if (Element.getStyle(element, 'position') != 'static')
        return $(element);

    return $(document.body);
  },

  viewportOffset: function(forElement) {
    var valueT = 0, valueL = 0;

    var element = forElement;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;

      // Safari fix
      if (element.offsetParent == document.body &&
        Element.getStyle(element, 'position') == 'absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
        valueT -= element.scrollTop  || 0;
        valueL -= element.scrollLeft || 0;
      }
    } while (element = element.parentNode);

    return Element._returnOffset(valueL, valueT);
  },

  clonePosition: function(element, source) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,
      offsetTop:  0,
      offsetLeft: 0
    }, arguments[2] || { });

    // find page position of source
    source = $(source);
    var p = source.viewportOffset();

    // find coordinate system to use
    element = $(element);
    var delta = [0, 0];
    var parent = null;
    // delta [0,0] will do fine with position: fixed elements,
    // position:absolute needs offsetParent deltas
    if (Element.getStyle(element, 'position') == 'absolute') {
      parent = element.getOffsetParent();
      delta = parent.viewportOffset();
    }

    // correct by body offsets (fixes Safari)
    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    // set position
    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
    return element;
  }
};

Element.Methods.identify.counter = 1;

Object.extend(Element.Methods, {
  getElementsBySelector: Element.Methods.select,
  childElements: Element.Methods.immediateDescendants
});

Element._attributeTranslations = {
  write: {
    names: {
      className: 'class',
      htmlFor:   'for'
    },
    values: { }
  }
};

if (Prototype.Browser.Opera) {
  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
    function(proceed, element, style) {
      switch (style) {
        case 'left': case 'top': case 'right': case 'bottom':
          if (proceed(element, 'position') === 'static') return null;
        case 'height': case 'width':
          // returns '0px' for hidden elements; we want it to return null
          if (!Element.visible(element)) return null;

          // returns the border-box dimensions rather than the content-box
          // dimensions, so we subtract padding and borders from the value
          var dim = parseInt(proceed(element, style), 10);

          if (dim !== element['offset' + style.capitalize()])
            return dim + 'px';

          var properties;
          if (style === 'height') {
            properties = ['border-top-width', 'padding-top',
             'padding-bottom', 'border-bottom-width'];
          }
          else {
            properties = ['border-left-width', 'padding-left',
             'padding-right', 'border-right-width'];
          }
          return properties.inject(dim, function(memo, property) {
            var val = proceed(element, property);
            return val === null ? memo : memo - parseInt(val, 10);
          }) + 'px';
        default: return proceed(element, style);
      }
    }
  );

  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
    function(proceed, element, attribute) {
      if (attribute === 'title') return element.title;
      return proceed(element, attribute);
    }
  );
}

else if (Prototype.Browser.IE) {
  // IE doesn't report offsets correctly for static elements, so we change them
  // to "relative" to get the values, then change them back.
  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
    function(proceed, element) {
      element = $(element);
      // IE throws an error if element is not in document
      try { element.offsetParent }
      catch(e) { return $(document.body) }
      var position = element.getStyle('position');
      if (position !== 'static') return proceed(element);
      element.setStyle({ position: 'relative' });
      var value = proceed(element);
      element.setStyle({ position: position });
      return value;
    }
  );

  $w('positionedOffset viewportOffset').each(function(method) {
    Element.Methods[method] = Element.Methods[method].wrap(
      function(proceed, element) {
        element = $(element);
        try { element.offsetParent }
        catch(e) { return Element._returnOffset(0,0) }
        var position = element.getStyle('position');
        if (position !== 'static') return proceed(element);
        // Trigger hasLayout on the offset parent so that IE6 reports
        // accurate offsetTop and offsetLeft values for position: fixed.
        var offsetParent = element.getOffsetParent();
        if (offsetParent && offsetParent.getStyle('position') === 'fixed')
          offsetParent.setStyle({ zoom: 1 });
        element.setStyle({ position: 'relative' });
        var value = proceed(element);
        element.setStyle({ position: position });
        return value;
      }
    );
  });

  Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
    function(proceed, element) {
      try { element.offsetParent }
      catch(e) { return Element._returnOffset(0,0) }
      return proceed(element);
    }
  );

  Element.Methods.getStyle = function(element, style) {
    element = $(element);
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
    var value = element.style[style];
    if (!value && element.currentStyle) value = element.currentStyle[style];

    if (style == 'opacity') {
      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }

    if (value == 'auto') {
      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        return element['offset' + style.capitalize()] + 'px';
      return null;
    }
    return value;
  };

  Element.Methods.setOpacity = function(element, value) {
    function stripAlpha(filter){
      return filter.replace(/alpha\([^\)]*\)/gi,'');
    }
    element = $(element);
    var currentStyle = element.currentStyle;
    if ((currentStyle && !currentStyle.hasLayout) ||
      (!currentStyle && element.style.zoom == 'normal'))
        element.style.zoom = 1;

    var filter = element.getStyle('filter'), style = element.style;
    if (value == 1 || value === '') {
      (filter = stripAlpha(filter)) ?
        style.filter = filter : style.removeAttribute('filter');
      return element;
    } else if (value < 0.00001) value = 0;
    style.filter = stripAlpha(filter) +
      'alpha(opacity=' + (value * 100) + ')';
    return element;
  };

  Element._attributeTranslations = {
    read: {
      names: {
        'class': 'className',
        'for':   'htmlFor'
      },
      values: {
        _getAttr: function(element, attribute) {
          return element.getAttribute(attribute, 2);
        },
        _getAttrNode: function(element, attribute) {
          var node = element.getAttributeNode(attribute);
          return node ? node.value : "";
        },
        _getEv: function(element, attribute) {
          attribute = element.getAttribute(attribute);
          return attribute ? attribute.toString().slice(23, -2) : null;
        },
        _flag: function(element, attribute) {
          return $(element).hasAttribute(attribute) ? attribute : null;
        },
        style: function(element) {
          return element.style.cssText.toLowerCase();
        },
        title: function(element) {
          return element.title;
        }
      }
    }
  };

  Element._attributeTranslations.write = {
    names: Object.extend({
      cellpadding: 'cellPadding',
      cellspacing: 'cellSpacing'
    }, Element._attributeTranslations.read.names),
    values: {
      checked: function(element, value) {
        element.checked = !!value;
      },

      style: function(element, value) {
        element.style.cssText = value ? value : '';
      }
    }
  };

  Element._attributeTranslations.has = {};

  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
  });

  (function(v) {
    Object.extend(v, {
      href:        v._getAttr,
      src:         v._getAttr,
      type:        v._getAttr,
      action:      v._getAttrNode,
      disabled:    v._flag,
      checked:     v._flag,
      readonly:    v._flag,
      multiple:    v._flag,
      onload:      v._getEv,
      onunload:    v._getEv,
      onclick:     v._getEv,
      ondblclick:  v._getEv,
      onmousedown: v._getEv,
      onmouseup:   v._getEv,
      onmouseover: v._getEv,
      onmousemove: v._getEv,
      onmouseout:  v._getEv,
      onfocus:     v._getEv,
      onblur:      v._getEv,
      onkeypress:  v._getEv,
      onkeydown:   v._getEv,
      onkeyup:     v._getEv,
      onsubmit:    v._getEv,
      onreset:     v._getEv,
      onselect:    v._getEv,
      onchange:    v._getEv
    });
  })(Element._attributeTranslations.read.values);
}

else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
      (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
  };
}

else if (Prototype.Browser.WebKit) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;

    if (value == 1)
      if(element.tagName.toUpperCase() == 'IMG' && element.width) {
        element.width++; element.width--;
      } else try {
        var n = document.createTextNode(' ');
        element.appendChild(n);
        element.removeChild(n);
      } catch (e) { }

    return element;
  };

  // Safari returns margins on body which is incorrect if the child is absolutely
  // positioned.  For performance reasons, redefine Element#cumulativeOffset for
  // KHTML/WebKit only.
  Element.Methods.cumulativeOffset = function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      if (element.offsetParent == document.body)
        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;
    } while (element);

    return Element._returnOffset(valueL, valueT);
  };
}

if (Prototype.Browser.IE || Prototype.Browser.Opera) {
  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
  Element.Methods.update = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);

    content = Object.toHTML(content);
    var tagName = element.tagName.toUpperCase();

    if (tagName in Element._insertionTranslations.tags) {
      $A(element.childNodes).each(function(node) { element.removeChild(node) });
      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
        .each(function(node) { element.appendChild(node) });
    }
    else element.innerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

if ('outerHTML' in document.createElement('div')) {
  Element.Methods.replace = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) {
      element.parentNode.replaceChild(content, element);
      return element;
    }

    content = Object.toHTML(content);
    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();

    if (Element._insertionTranslations.tags[tagName]) {
      var nextSibling = element.next();
      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
      parent.removeChild(element);
      if (nextSibling)
        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
      else
        fragments.each(function(node) { parent.appendChild(node) });
    }
    else element.outerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

Element._returnOffset = function(l, t) {
  var result = [l, t];
  result.left = l;
  result.top = t;
  return result;
};

Element._getContentFromAnonymousElement = function(tagName, html) {
  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
  if (t) {
    div.innerHTML = t[0] + html + t[1];
    t[2].times(function() { div = div.firstChild });
  } else div.innerHTML = html;
  return $A(div.childNodes);
};

Element._insertionTranslations = {
  before: function(element, node) {
    element.parentNode.insertBefore(node, element);
  },
  top: function(element, node) {
    element.insertBefore(node, element.firstChild);
  },
  bottom: function(element, node) {
    element.appendChild(node);
  },
  after: function(element, node) {
    element.parentNode.insertBefore(node, element.nextSibling);
  },
  tags: {
    TABLE:  ['<table>',                '</table>',                   1],
    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
    SELECT: ['<select>',               '</select>',                  1]
  }
};

(function() {
  Object.extend(this.tags, {
    THEAD: this.tags.TBODY,
    TFOOT: this.tags.TBODY,
    TH:    this.tags.TD
  });
}).call(Element._insertionTranslations);

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    attribute = Element._attributeTranslations.has[attribute] || attribute;
    var node = $(element).getAttributeNode(attribute);
    return !!(node && node.specified);
  }
};

Element.Methods.ByTag = { };

Object.extend(Element, Element.Methods);

if (!Prototype.BrowserFeatures.ElementExtensions &&
    document.createElement('div')['__proto__']) {
  window.HTMLElement = { };
  window.HTMLElement.prototype = document.createElement('div')['__proto__'];
  Prototype.BrowserFeatures.ElementExtensions = true;
}

Element.extend = (function() {
  if (Prototype.BrowserFeatures.SpecificElementExtensions)
    return Prototype.K;

  var Methods = { }, ByTag = Element.Methods.ByTag;

  var extend = Object.extend(function(element) {
    if (!element || element._extendedByPrototype ||
        element.nodeType != 1 || element == window) return element;

    var methods = Object.clone(Methods),
      tagName = element.tagName.toUpperCase(), property, value;

    // extend methods for specific tags
    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);

    for (property in methods) {
      value = methods[property];
      if (Object.isFunction(value) && !(property in element))
        element[property] = value.methodize();
    }

    element._extendedByPrototype = Prototype.emptyFunction;
    return element;

  }, {
    refresh: function() {
      // extend methods for all tags (Safari doesn't need this)
      if (!Prototype.BrowserFeatures.ElementExtensions) {
        Object.extend(Methods, Element.Methods);
        Object.extend(Methods, Element.Methods.Simulated);
      }
    }
  });

  extend.refresh();
  return extend;
})();

Element.hasAttribute = function(element, attribute) {
  if (element.hasAttribute) return element.hasAttribute(attribute);
  return Element.Methods.Simulated.hasAttribute(element, attribute);
};

Element.addMethods = function(methods) {
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

  if (!methods) {
    Object.extend(Form, Form.Methods);
    Object.extend(Form.Element, Form.Element.Methods);
    Object.extend(Element.Methods.ByTag, {
      "FORM":     Object.clone(Form.Methods),
      "INPUT":    Object.clone(Form.Element.Methods),
      "SELECT":   Object.clone(Form.Element.Methods),
      "TEXTAREA": Object.clone(Form.Element.Methods)
    });
  }

  if (arguments.length == 2) {
    var tagName = methods;
    methods = arguments[1];
  }

  if (!tagName) Object.extend(Element.Methods, methods || { });
  else {
    if (Object.isArray(tagName)) tagName.each(extend);
    else extend(tagName);
  }

  function extend(tagName) {
    tagName = tagName.toUpperCase();
    if (!Element.Methods.ByTag[tagName])
      Element.Methods.ByTag[tagName] = { };
    Object.extend(Element.Methods.ByTag[tagName], methods);
  }

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    for (var property in methods) {
      var value = methods[property];
      if (!Object.isFunction(value)) continue;
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = value.methodize();
    }
  }

  function findDOMClass(tagName) {
    var klass;
    var trans = {
      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
      "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    window[klass] = { };
    window[klass].prototype = document.createElement(tagName)['__proto__'];
    return window[klass];
  }

  if (F.ElementExtensions) {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
  }

  if (F.SpecificElementExtensions) {
    for (var tag in Element.Methods.ByTag) {
      var klass = findDOMClass(tag);
      if (Object.isUndefined(klass)) continue;
      copy(T[tag], klass.prototype);
    }
  }

  Object.extend(Element, Element.Methods);
  delete Element.ByTag;

  if (Element.extend.refresh) Element.extend.refresh();
  Element.cache = { };
};

document.viewport = {
  getDimensions: function() {
    var dimensions = { }, B = Prototype.Browser;
    $w('width height').each(function(d) {
      var D = d.capitalize();
      if (B.WebKit && !document.evaluate) {
        // Safari <3.0 needs self.innerWidth/Height
        dimensions[d] = self['inner' + D];
      } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
        // Opera <9.5 needs document.body.clientWidth/Height
        dimensions[d] = document.body['client' + D]
      } else {
        dimensions[d] = document.documentElement['client' + D];
      }
    });
    return dimensions;
  },

  getWidth: function() {
    return this.getDimensions().width;
  },

  getHeight: function() {
    return this.getDimensions().height;
  },

  getScrollOffsets: function() {
    return Element._returnOffset(
      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
  }
};
/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
 * license.  Please see http://www.yui-ext.com/ for more information. */

var Selector = Class.create({
  initialize: function(expression) {
    this.expression = expression.strip();

    if (this.shouldUseSelectorsAPI()) {
      this.mode = 'selectorsAPI';
    } else if (this.shouldUseXPath()) {
      this.mode = 'xpath';
      this.compileXPathMatcher();
    } else {
      this.mode = "normal";
      this.compileMatcher();
    }

  },

  shouldUseXPath: function() {
    if (!Prototype.BrowserFeatures.XPath) return false;

    var e = this.expression;

    // Safari 3 chokes on :*-of-type and :empty
    if (Prototype.Browser.WebKit &&
     (e.include("-of-type") || e.include(":empty")))
      return false;

    // XPath can't do namespaced attributes, nor can it read
    // the "checked" property from DOM nodes
    if ((/(\[[\w-]*?:|:checked)/).test(e))
      return false;

    return true;
  },

  shouldUseSelectorsAPI: function() {
    if (!Prototype.BrowserFeatures.SelectorsAPI) return false;

    if (!Selector._div) Selector._div = new Element('div');

    // Make sure the browser treats the selector as valid. Test on an
    // isolated element to minimize cost of this check.
    try {
      Selector._div.querySelector(this.expression);
    } catch(e) {
      return false;
    }

    return true;
  },

  compileMatcher: function() {
    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        c = Selector.criteria, le, p, m;

    if (Selector._cache[e]) {
      this.matcher = Selector._cache[e];
      return;
    }

    this.matcher = ["this.matcher = function(root) {",
                    "var r = root, h = Selector.handlers, c = false, n;"];

    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
            new Template(c[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.matcher.push("return h.unique(n);\n}");
    eval(this.matcher.join('\n'));
    Selector._cache[this.expression] = this.matcher;
  },

  compileXPathMatcher: function() {
    var e = this.expression, ps = Selector.patterns,
        x = Selector.xpath, le, m;

    if (Selector._cache[e]) {
      this.xpath = Selector._cache[e]; return;
    }

    this.matcher = ['.//*'];
    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        if (m = e.match(ps[i])) {
          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
            new Template(x[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.xpath = this.matcher.join('');
    Selector._cache[this.expression] = this.xpath;
  },

  findElements: function(root) {
    root = root || document;
    var e = this.expression, results;

    switch (this.mode) {
      case 'selectorsAPI':
        // querySelectorAll queries document-wide, then filters to descendants
        // of the context element. That's not what we want.
        // Add an explicit context to the selector if necessary.
        if (root !== document) {
          var oldId = root.id, id = $(root).identify();
          e = "#" + id + " " + e;
        }

        results = $A(root.querySelectorAll(e)).map(Element.extend);
        root.id = oldId;

        return results;
      case 'xpath':
        return document._getElementsByXPath(this.xpath, root);
      default:
       return this.matcher(root);
    }
  },

  match: function(element) {
    this.tokens = [];

    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
    var le, p, m;

    while (e && le !== e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          // use the Selector.assertions methods unless the selector
          // is too complex.
          if (as[i]) {
            this.tokens.push([i, Object.clone(m)]);
            e = e.replace(m[0], '');
          } else {
            // reluctantly do a document-wide search
            // and look for a match in the array
            return this.findElements(document).include(element);
          }
        }
      }
    }

    var match = true, name, matches;
    for (var i = 0, token; token = this.tokens[i]; i++) {
      name = token[0], matches = token[1];
      if (!Selector.assertions[name](element, matches)) {
        match = false; break;
      }
    }

    return match;
  },

  toString: function() {
    return this.expression;
  },

  inspect: function() {
    return "#<Selector:" + this.expression.inspect() + ">";
  }
});

Object.extend(Selector, {
  _cache: { },

  xpath: {
    descendant:   "//*",
    child:        "/*",
    adjacent:     "/following-sibling::*[1]",
    laterSibling: '/following-sibling::*',
    tagName:      function(m) {
      if (m[1] == '*') return '';
      return "[local-name()='" + m[1].toLowerCase() +
             "' or local-name()='" + m[1].toUpperCase() + "']";
    },
    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
    id:           "[@id='#{1}']",
    attrPresence: function(m) {
      m[1] = m[1].toLowerCase();
      return new Template("[@#{1}]").evaluate(m);
    },
    attr: function(m) {
      m[1] = m[1].toLowerCase();
      m[3] = m[5] || m[6];
      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
    },
    pseudo: function(m) {
      var h = Selector.xpath.pseudos[m[1]];
      if (!h) return '';
      if (Object.isFunction(h)) return h(m);
      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
    },
    operators: {
      '=':  "[@#{1}='#{3}']",
      '!=': "[@#{1}!='#{3}']",
      '^=': "[starts-with(@#{1}, '#{3}')]",
      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
      '*=': "[contains(@#{1}, '#{3}')]",
      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
    },
    pseudos: {
      'first-child': '[not(preceding-sibling::*)]',
      'last-child':  '[not(following-sibling::*)]',
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
      'empty':       "[count(*) = 0 and (count(text()) = 0)]",
      'checked':     "[@checked]",
      'disabled':    "[(@disabled) and (@type!='hidden')]",
      'enabled':     "[not(@disabled) and (@type!='hidden')]",
      'not': function(m) {
        var e = m[6], p = Selector.patterns,
            x = Selector.xpath, le, v;

        var exclusion = [];
        while (e && le != e && (/\S/).test(e)) {
          le = e;
          for (var i in p) {
            if (m = e.match(p[i])) {
              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
              e = e.replace(m[0], '');
              break;
            }
          }
        }
        return "[not(" + exclusion.join(" and ") + ")]";
      },
      'nth-child':      function(m) {
        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
      },
      'nth-last-child': function(m) {
        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
      },
      'nth-of-type':    function(m) {
        return Selector.xpath.pseudos.nth("position() ", m);
      },
      'nth-last-of-type': function(m) {
        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
      },
      'first-of-type':  function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
      },
      'last-of-type':   function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
      },
      'only-of-type':   function(m) {
        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
      },
      nth: function(fragment, m) {
        var mm, formula = m[6], predicate;
        if (formula == 'even') formula = '2n+0';
        if (formula == 'odd')  formula = '2n+1';
        if (mm = formula.match(/^(\d+)$/)) // digit only
          return '[' + fragment + "= " + mm[1] + ']';
        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
          if (mm[1] == "-") mm[1] = -1;
          var a = mm[1] ? Number(mm[1]) : 1;
          var b = mm[2] ? Number(mm[2]) : 0;
          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
          "((#{fragment} - #{b}) div #{a} >= 0)]";
          return new Template(predicate).evaluate({
            fragment: fragment, a: a, b: b });
        }
      }
    }
  },

  criteria: {
    tagName:      'n = h.tagName(n, r, "#{1}", c);      c = false;',
    className:    'n = h.className(n, r, "#{1}", c);    c = false;',
    id:           'n = h.id(n, r, "#{1}", c);           c = false;',
    attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
    attr: function(m) {
      m[3] = (m[5] || m[6]);
      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
    },
    pseudo: function(m) {
      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
    },
    descendant:   'c = "descendant";',
    child:        'c = "child";',
    adjacent:     'c = "adjacent";',
    laterSibling: 'c = "laterSibling";'
  },

  patterns: {
    // combinators must be listed first
    // (and descendant needs to be last combinator)
    laterSibling: /^\s*~\s*/,
    child:        /^\s*>\s*/,
    adjacent:     /^\s*\+\s*/,
    descendant:   /^\s/,

    // selectors follow
    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
    id:           /^#([\w\-\*]+)(\b|$)/,
    className:    /^\.([\w\-\*]+)(\b|$)/,
    pseudo:
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
    attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
  },

  // for Selector.match and Element#match
  assertions: {
    tagName: function(element, matches) {
      return matches[1].toUpperCase() == element.tagName.toUpperCase();
    },

    className: function(element, matches) {
      return Element.hasClassName(element, matches[1]);
    },

    id: function(element, matches) {
      return element.id === matches[1];
    },

    attrPresence: function(element, matches) {
      return Element.hasAttribute(element, matches[1]);
    },

    attr: function(element, matches) {
      var nodeValue = Element.readAttribute(element, matches[1]);
      return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
    }
  },

  handlers: {
    // UTILITY FUNCTIONS
    // joins two collections
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        a.push(node);
      return a;
    },

    // marks an array of nodes for counting
    mark: function(nodes) {
      var _true = Prototype.emptyFunction;
      for (var i = 0, node; node = nodes[i]; i++)
        node._countedByPrototype = _true;
      return nodes;
    },

    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._countedByPrototype = undefined;
      return nodes;
    },

    // mark each child node with its position (for nth calls)
    // "ofType" flag indicates whether we're indexing for nth-of-type
    // rather than nth-child
    index: function(parentNode, reverse, ofType) {
      parentNode._countedByPrototype = Prototype.emptyFunction;
      if (reverse) {
        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
          var node = nodes[i];
          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
        }
      } else {
        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
      }
    },

    // filters out duplicates and extends all nodes
    unique: function(nodes) {
      if (nodes.length == 0) return nodes;
      var results = [], n;
      for (var i = 0, l = nodes.length; i < l; i++)
        if (!(n = nodes[i])._countedByPrototype) {
          n._countedByPrototype = Prototype.emptyFunction;
          results.push(Element.extend(n));
        }
      return Selector.handlers.unmark(results);
    },

    // COMBINATOR FUNCTIONS
    descendant: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, node.getElementsByTagName('*'));
      return results;
    },

    child: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        for (var j = 0, child; child = node.childNodes[j]; j++)
          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
      }
      return results;
    },

    adjacent: function(nodes) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        var next = this.nextElementSibling(node);
        if (next) results.push(next);
      }
      return results;
    },

    laterSibling: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, Element.nextSiblings(node));
      return results;
    },

    nextElementSibling: function(node) {
      while (node = node.nextSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    previousElementSibling: function(node) {
      while (node = node.previousSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    // TOKEN FUNCTIONS
    tagName: function(nodes, root, tagName, combinator) {
      var uTagName = tagName.toUpperCase();
      var results = [], h = Selector.handlers;
      if (nodes) {
        if (combinator) {
          // fastlane for ordinary descendant combinators
          if (combinator == "descendant") {
            for (var i = 0, node; node = nodes[i]; i++)
              h.concat(results, node.getElementsByTagName(tagName));
            return results;
          } else nodes = this[combinator](nodes);
          if (tagName == "*") return nodes;
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName.toUpperCase() === uTagName) results.push(node);
        return results;
      } else return root.getElementsByTagName(tagName);
    },

    id: function(nodes, root, id, combinator) {
      var targetNode = $(id), h = Selector.handlers;
      if (!targetNode) return [];
      if (!nodes && root == document) return [targetNode];
      if (nodes) {
        if (combinator) {
          if (combinator == 'child') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (targetNode.parentNode == node) return [targetNode];
          } else if (combinator == 'descendant') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Element.descendantOf(targetNode, node)) return [targetNode];
          } else if (combinator == 'adjacent') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Selector.handlers.previousElementSibling(targetNode) == node)
                return [targetNode];
          } else nodes = h[combinator](nodes);
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node == targetNode) return [targetNode];
        return [];
      }
      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
    },

    className: function(nodes, root, className, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      return Selector.handlers.byClassName(nodes, root, className);
    },

    byClassName: function(nodes, root, className) {
      if (!nodes) nodes = Selector.handlers.descendant([root]);
      var needle = ' ' + className + ' ';
      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
        nodeClassName = node.className;
        if (nodeClassName.length == 0) continue;
        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
          results.push(node);
      }
      return results;
    },

    attrPresence: function(nodes, root, attr, combinator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      if (nodes && combinator) nodes = this[combinator](nodes);
      var results = [];
      for (var i = 0, node; node = nodes[i]; i++)
        if (Element.hasAttribute(node, attr)) results.push(node);
      return results;
    },

    attr: function(nodes, root, attr, value, operator, combinator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      if (nodes && combinator) nodes = this[combinator](nodes);
      var handler = Selector.operators[operator], results = [];
      for (var i = 0, node; node = nodes[i]; i++) {
        var nodeValue = Element.readAttribute(node, attr);
        if (nodeValue === null) continue;
        if (handler(nodeValue, value)) results.push(node);
      }
      return results;
    },

    pseudo: function(nodes, name, value, root, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      if (!nodes) nodes = root.getElementsByTagName("*");
      return Selector.pseudos[name](nodes, value, root);
    }
  },

  pseudos: {
    'first-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.previousElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'last-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.nextElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'only-child': function(nodes, value, root) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
          results.push(node);
      return results;
    },
    'nth-child':        function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root);
    },
    'nth-last-child':   function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true);
    },
    'nth-of-type':      function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, false, true);
    },
    'nth-last-of-type': function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true, true);
    },
    'first-of-type':    function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, false, true);
    },
    'last-of-type':     function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, true, true);
    },
    'only-of-type':     function(nodes, formula, root) {
      var p = Selector.pseudos;
      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
    },

    // handles the an+b logic
    getIndices: function(a, b, total) {
      if (a == 0) return b > 0 ? [b] : [];
      return $R(1, total).inject([], function(memo, i) {
        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
        return memo;
      });
    },

    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
    nth: function(nodes, formula, root, reverse, ofType) {
      if (nodes.length == 0) return [];
      if (formula == 'even') formula = '2n+0';
      if (formula == 'odd')  formula = '2n+1';
      var h = Selector.handlers, results = [], indexed = [], m;
      h.mark(nodes);
      for (var i = 0, node; node = nodes[i]; i++) {
        if (!node.parentNode._countedByPrototype) {
          h.index(node.parentNode, reverse, ofType);
          indexed.push(node.parentNode);
        }
      }
      if (formula.match(/^\d+$/)) { // just a number
        formula = Number(formula);
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.nodeIndex == formula) results.push(node);
      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        if (m[1] == "-") m[1] = -1;
        var a = m[1] ? Number(m[1]) : 1;
        var b = m[2] ? Number(m[2]) : 0;
        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
          for (var j = 0; j < l; j++)
            if (node.nodeIndex == indices[j]) results.push(node);
        }
      }
      h.unmark(nodes);
      h.unmark(indexed);
      return results;
    },

    'empty': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        // IE treats comments as element nodes
        if (node.tagName == '!' || node.firstChild) continue;
        results.push(node);
      }
      return results;
    },

    'not': function(nodes, selector, root) {
      var h = Selector.handlers, selectorType, m;
      var exclusions = new Selector(selector).findElements(root);
      h.mark(exclusions);
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node._countedByPrototype) results.push(node);
      h.unmark(exclusions);
      return results;
    },

    'enabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node.disabled && (!node.type || node.type !== 'hidden'))
          results.push(node);
      return results;
    },

    'disabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.disabled) results.push(node);
      return results;
    },

    'checked': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.checked) results.push(node);
      return results;
    }
  },

  operators: {
    '=':  function(nv, v) { return nv == v; },
    '!=': function(nv, v) { return nv != v; },
    '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
    '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
    '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
    '$=': function(nv, v) { return nv.endsWith(v); },
    '*=': function(nv, v) { return nv.include(v); },
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
    '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
     '-').include('-' + (v || "").toUpperCase() + '-'); }
  },

  split: function(expression) {
    var expressions = [];
    expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
      expressions.push(m[1].strip());
    });
    return expressions;
  },

  matchElements: function(elements, expression) {
    var matches = $$(expression), h = Selector.handlers;
    h.mark(matches);
    for (var i = 0, results = [], element; element = elements[i]; i++)
      if (element._countedByPrototype) results.push(element);
    h.unmark(matches);
    return results;
  },

  findElement: function(elements, expression, index) {
    if (Object.isNumber(expression)) {
      index = expression; expression = false;
    }
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    expressions = Selector.split(expressions.join(','));
    var results = [], h = Selector.handlers;
    for (var i = 0, l = expressions.length, selector; i < l; i++) {
      selector = new Selector(expressions[i].strip());
      h.concat(results, selector.findElements(element));
    }
    return (l > 1) ? h.unique(results) : results;
  }
});

if (Prototype.Browser.IE) {
  Object.extend(Selector.handlers, {
    // IE returns comment nodes on getElementsByTagName("*").
    // Filter them out.
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        if (node.tagName !== "!") a.push(node);
      return a;
    },

    // IE improperly serializes _countedByPrototype in (inner|outer)HTML.
    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node.removeAttribute('_countedByPrototype');
      return nodes;
    }
  });
}

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}
var Form = {
  reset: function(form) {
    $(form).reset();
    return form;
  },

  serializeElements: function(elements, options) {
    if (typeof options != 'object') options = { hash: !!options };
    else if (Object.isUndefined(options.hash)) options.hash = true;
    var key, value, submitted = false, submit = options.submit;

    var data = elements.inject({ }, function(result, element) {
      if (!element.disabled && element.name) {
        key = element.name; value = $(element).getValue();
        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
            submit !== false && (!submit || key == submit) && (submitted = true)))) {
          if (key in result) {
            // a key is already present; construct an array of values
            if (!Object.isArray(result[key])) result[key] = [result[key]];
            result[key].push(value);
          }
          else result[key] = value;
        }
      }
      return result;
    });

    return options.hash ? data : Object.toQueryString(data);
  }
};

Form.Methods = {
  serialize: function(form, options) {
    return Form.serializeElements(Form.getElements(form), options);
  },

  getElements: function(form) {
    return $A($(form).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
          elements.push(Element.extend(child));
        return elements;
      }
    );
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name) return $A(inputs).map(Element.extend);

    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) || (name && input.name != name))
        continue;
      matchingInputs.push(Element.extend(input));
    }

    return matchingInputs;
  },

  disable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('disable');
    return form;
  },

  enable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('enable');
    return form;
  },

  findFirstElement: function(form) {
    var elements = $(form).getElements().findAll(function(element) {
      return 'hidden' != element.type && !element.disabled;
    });
    var firstByIndex = elements.findAll(function(element) {
      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
    }).sortBy(function(element) { return element.tabIndex }).first();

    return firstByIndex ? firstByIndex : elements.find(function(element) {
      return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  },

  request: function(form, options) {
    form = $(form), options = Object.clone(options || { });

    var params = options.parameters, action = form.readAttribute('action') || '';
    if (action.blank()) action = window.location.href;
    options.parameters = form.serialize(true);

    if (params) {
      if (Object.isString(params)) params = params.toQueryParams();
      Object.extend(options.parameters, params);
    }

    if (form.hasAttribute('method') && !options.method)
      options.method = form.method;

    return new Ajax.Request(action, options);
  }
};

/*--------------------------------------------------------------------------*/

Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
};

Form.Element.Methods = {
  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();
      if (value != undefined) {
        var pair = { };
        pair[element.name] = value;
        return Object.toQueryString(pair);
      }
    }
    return '';
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    return Form.Element.Serializers[method](element);
  },

  setValue: function(element, value) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    Form.Element.Serializers[method](element, value);
    return element;
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
          !['button', 'reset', 'submit'].include(element.type)))
        element.select();
    } catch (e) { }
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.disabled = false;
    return element;
  }
};

/*--------------------------------------------------------------------------*/

var Field = Form.Element;
var $F = Form.Element.Methods.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element, value) {
    switch (element.type.toLowerCase()) {
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element, value);
      default:
        return Form.Element.Serializers.textarea(element, value);
    }
  },

  inputSelector: function(element, value) {
    if (Object.isUndefined(value)) return element.checked ? element.value : null;
    else element.checked = !!value;
  },

  textarea: function(element, value) {
    if (Object.isUndefined(value)) return element.value;
    else element.value = value;
  },

  select: function(element, value) {
    if (Object.isUndefined(value))
      return this[element.type == 'select-one' ?
        'selectOne' : 'selectMany'](element);
    else {
      var opt, currentValue, single = !Object.isArray(value);
      for (var i = 0, length = element.length; i < length; i++) {
        opt = element.options[i];
        currentValue = this.optionValue(opt);
        if (single) {
          if (currentValue == value) {
            opt.selected = true;
            return;
          }
        }
        else opt.selected = value.include(currentValue);
      }
    }
  },

  selectOne: function(element) {
    var index = element.selectedIndex;
    return index >= 0 ? this.optionValue(element.options[index]) : null;
  },

  selectMany: function(element) {
    var values, length = element.length;
    if (!length) return null;

    for (var i = 0, values = []; i < length; i++) {
      var opt = element.options[i];
      if (opt.selected) values.push(this.optionValue(opt));
    }
    return values;
  },

  optionValue: function(opt) {
    // extend element because hasAttribute may not be native
    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
  }
};

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
  initialize: function($super, element, frequency, callback) {
    $super(callback, frequency);
    this.element   = $(element);
    this.lastValue = this.getValue();
  },

  execute: function() {
    var value = this.getValue();
    if (Object.isString(this.lastValue) && Object.isString(value) ?
        this.lastValue != value : String(this.lastValue) != String(value)) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
});

Form.Element.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = Class.create({
  initialize: function(element, callback) {
    this.element  = $(element);
    this.callback = callback;

    this.lastValue = this.getValue();
    if (this.element.tagName.toLowerCase() == 'form')
      this.registerFormCallbacks();
    else
      this.registerCallback(this.element);
  },

  onElementEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  },

  registerFormCallbacks: function() {
    Form.getElements(this.element).each(this.registerCallback, this);
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        default:
          Event.observe(element, 'change', this.onElementEvent.bind(this));
          break;
      }
    }
  }
});

Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
if (!window.Event) var Event = { };

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,
  KEY_HOME:     36,
  KEY_END:      35,
  KEY_PAGEUP:   33,
  KEY_PAGEDOWN: 34,
  KEY_INSERT:   45,

  cache: { },

  relatedTarget: function(event) {
    var element;
    switch(event.type) {
      case 'mouseover': element = event.fromElement; break;
      case 'mouseout':  element = event.toElement;   break;
      default: return null;
    }
    return Element.extend(element);
  }
});

Event.Methods = (function() {
  var isButton;

  if (Prototype.Browser.IE) {
    var buttonMap = { 0: 1, 1: 4, 2: 2 };
    isButton = function(event, code) {
      return event.button == buttonMap[code];
    };

  } else if (Prototype.Browser.WebKit) {
    isButton = function(event, code) {
      switch (code) {
        case 0: return event.which == 1 && !event.metaKey;
        case 1: return event.which == 1 && event.metaKey;
        default: return false;
      }
    };

  } else {
    isButton = function(event, code) {
      return event.which ? (event.which === code + 1) : (event.button === code);
    };
  }

  return {
    isLeftClick:   function(event) { return isButton(event, 0) },
    isMiddleClick: function(event) { return isButton(event, 1) },
    isRightClick:  function(event) { return isButton(event, 2) },

    element: function(event) {
      event = Event.extend(event);

      var node          = event.target,
          type          = event.type,
          currentTarget = event.currentTarget;

      if (currentTarget && currentTarget.tagName) {
        // Firefox screws up the "click" event when moving between radio buttons
        // via arrow keys. It also screws up the "load" and "error" events on images,
        // reporting the document as the target instead of the original image.
        if (type === 'load' || type === 'error' ||
          (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
            && currentTarget.type === 'radio'))
              node = currentTarget;
      }
      if (node.nodeType == Node.TEXT_NODE) node = node.parentNode;
      return Element.extend(node);
    },

    findElement: function(event, expression) {
      var element = Event.element(event);
      if (!expression) return element;
      try {
        var elements = [element].concat(element.ancestors());
      } catch(e) {
        var elements = [element];
      }
      return Selector.findElement(elements, expression, 0);
    },

    pointer: function(event) {
      var docElement = document.documentElement,
      body = document.body || { scrollLeft: 0, scrollTop: 0 };
      return {
        x: event.pageX || (event.clientX +
          (docElement.scrollLeft || body.scrollLeft) -
          (docElement.clientLeft || 0)),
        y: event.pageY || (event.clientY +
          (docElement.scrollTop || body.scrollTop) -
          (docElement.clientTop || 0))
      };
    },

    pointerX: function(event) { return Event.pointer(event).x },
    pointerY: function(event) { return Event.pointer(event).y },

    stop: function(event) {
      Event.extend(event);
      event.preventDefault();
      event.stopPropagation();
      event.stopped = true;
    }
  };
})();

Event.extend = (function() {
  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
    m[name] = Event.Methods[name].methodize();
    return m;
  });

  if (Prototype.Browser.IE) {
    Object.extend(methods, {
      stopPropagation: function() { this.cancelBubble = true },
      preventDefault:  function() { this.returnValue = false },
      inspect: function() { return "[object Event]" }
    });

    return function(event) {
      if (!event) return false;
      if (event._extendedByPrototype) return event;

      event._extendedByPrototype = Prototype.emptyFunction;
      var pointer = Event.pointer(event);
      Object.extend(event, {
        target: event.srcElement,
        relatedTarget: Event.relatedTarget(event),
        pageX:  pointer.x,
        pageY:  pointer.y
      });
      return Object.extend(event, methods);
    };

  } else {
    Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
    Object.extend(Event.prototype, methods);
    return Prototype.K;
  }
})();

Object.extend(Event, (function() {
  var cache = Event.cache;

  function getEventID(element) {
    if (element._prototypeEventID) return element._prototypeEventID[0];
    arguments.callee.id = arguments.callee.id || 1;
    return element._prototypeEventID = [++arguments.callee.id];
  }

  function getDOMEventName(eventName) {
    if (eventName && eventName.include(':')) return "dataavailable";
    return eventName;
  }

  function getCacheForID(id) {
    return cache[id] = cache[id] || { };
  }

  function getWrappersForEventName(id, eventName) {
    var c = getCacheForID(id);
    return c[eventName] = c[eventName] || [];
  }

  function createWrapper(element, eventName, handler) {
    var id = getEventID(element);
    var c = getWrappersForEventName(id, eventName);
    if (c.pluck("handler").include(handler)) return false;

    var wrapper = function(event) {
      if (!Event || !Event.extend ||
        (event.eventName && event.eventName != eventName))
          return false;

      Event.extend(event);
      handler.call(element, event);
    };

    wrapper.handler = handler;
    c.push(wrapper);
    return wrapper;
  }

  function findWrapper(id, eventName, handler) {
    var c = getWrappersForEventName(id, eventName);
    return c.find(function(wrapper) { return wrapper.handler == handler });
  }

  function destroyWrapper(id, eventName, handler) {
    var c = getCacheForID(id);
    if (!c[eventName]) return false;
    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
  }

  function destroyCache() {
    for (var id in cache)
      for (var eventName in cache[id])
        cache[id][eventName] = null;
  }


  // Internet Explorer needs to remove event handlers on page unload
  // in order to avoid memory leaks.
  if (window.attachEvent) {
    window.attachEvent("onunload", destroyCache);
  }

  // Safari has a dummy event handler on page unload so that it won't
  // use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
  // object when page is returned to via the back button using its bfcache.
  if (Prototype.Browser.WebKit) {
    window.addEventListener('unload', Prototype.emptyFunction, false);
  }

  return {
    observe: function(element, eventName, handler) {
      element = $(element);
      var name = getDOMEventName(eventName);

      var wrapper = createWrapper(element, eventName, handler);
      if (!wrapper) return element;

      if (element.addEventListener) {
        element.addEventListener(name, wrapper, false);
      } else {
        element.attachEvent("on" + name, wrapper);
      }

      return element;
    },

    stopObserving: function(element, eventName, handler) {
      element = $(element);
      var id = getEventID(element), name = getDOMEventName(eventName);

      if (!handler && eventName) {
        getWrappersForEventName(id, eventName).each(function(wrapper) {
          element.stopObserving(eventName, wrapper.handler);
        });
        return element;

      } else if (!eventName) {
        Object.keys(getCacheForID(id)).each(function(eventName) {
          element.stopObserving(eventName);
        });
        return element;
      }

      var wrapper = findWrapper(id, eventName, handler);
      if (!wrapper) return element;

      if (element.removeEventListener) {
        element.removeEventListener(name, wrapper, false);
      } else {
        element.detachEvent("on" + name, wrapper);
      }

      destroyWrapper(id, eventName, handler);

      return element;
    },

    fire: function(element, eventName, memo) {
      element = $(element);
      if (element == document && document.createEvent && !element.dispatchEvent)
        element = document.documentElement;

      var event;
      if (document.createEvent) {
        event = document.createEvent("HTMLEvents");
        event.initEvent("dataavailable", true, true);
      } else {
        event = document.createEventObject();
        event.eventType = "ondataavailable";
      }

      event.eventName = eventName;
      event.memo = memo || { };

      if (document.createEvent) {
        element.dispatchEvent(event);
      } else {
        element.fireEvent(event.eventType, event);
      }

      return Event.extend(event);
    }
  };
})());

Object.extend(Event, Event.Methods);

Element.addMethods({
  fire:          Event.fire,
  observe:       Event.observe,
  stopObserving: Event.stopObserving
});

Object.extend(document, {
  fire:          Element.Methods.fire.methodize(),
  observe:       Element.Methods.observe.methodize(),
  stopObserving: Element.Methods.stopObserving.methodize(),
  loaded:        false
});

(function() {
  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
     Matthias Miller, Dean Edwards and John Resig. */

  var timer;

  function fireContentLoadedEvent() {
    if (document.loaded) return;
    if (timer) window.clearInterval(timer);
    document.fire("dom:loaded");
    document.loaded = true;
  }

  if (document.addEventListener) {
    if (Prototype.Browser.WebKit) {
      timer = window.setInterval(function() {
        if (/loaded|complete/.test(document.readyState))
          fireContentLoadedEvent();
      }, 0);

      Event.observe(window, "load", fireContentLoadedEvent);

    } else {
      document.addEventListener("DOMContentLoaded",
        fireContentLoadedEvent, false);
    }

  } else {
    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
    $("__onDOMContentLoaded").onreadystatechange = function() {
      if (this.readyState == "complete") {
        this.onreadystatechange = null;
        fireContentLoadedEvent();
      }
    };
  }
})();
/*------------------------------- DEPRECATED -------------------------------*/

Hash.toQueryString = Object.toQueryString;

var Toggle = { display: Element.toggle };

Element.Methods.childOf = Element.Methods.descendantOf;

var Insertion = {
  Before: function(element, content) {
    return Element.insert(element, {before:content});
  },

  Top: function(element, content) {
    return Element.insert(element, {top:content});
  },

  Bottom: function(element, content) {
    return Element.insert(element, {bottom:content});
  },

  After: function(element, content) {
    return Element.insert(element, {after:content});
  }
};

var $continue = new Error('"throw $continue" is deprecated, use "return" instead');

// This should be moved to script.aculo.us; notice the deprecated methods
// further below, that map to the newer Element methods.
var Position = {
  // set to true if needed, warning: firefox performance problems
  // NOT neeeded for page scrolling, only if draggable contained in
  // scrollable elements
  includeScrollOffsets: false,

  // must be called before calling withinIncludingScrolloffset, every time the
  // page is scrolled
  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  // caches x/y coordinate pair to use with overlap
  within: function(element, x, y) {
    if (this.includeScrollOffsets)
      return this.withinIncludingScrolloffsets(element, x, y);
    this.xcomp = x;
    this.ycomp = y;
    this.offset = Element.cumulativeOffset(element);

    return (y >= this.offset[1] &&
            y <  this.offset[1] + element.offsetHeight &&
            x >= this.offset[0] &&
            x <  this.offset[0] + element.offsetWidth);
  },

  withinIncludingScrolloffsets: function(element, x, y) {
    var offsetcache = Element.cumulativeScrollOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = Element.cumulativeOffset(element);

    return (this.ycomp >= this.offset[1] &&
            this.ycomp <  this.offset[1] + element.offsetHeight &&
            this.xcomp >= this.offset[0] &&
            this.xcomp <  this.offset[0] + element.offsetWidth);
  },

  // within must be called directly before
  overlap: function(mode, element) {
    if (!mode) return 0;
    if (mode == 'vertical')
      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        element.offsetHeight;
    if (mode == 'horizontal')
      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        element.offsetWidth;
  },

  // Deprecation layer -- use newer Element methods now (1.5.2).

  cumulativeOffset: Element.Methods.cumulativeOffset,

  positionedOffset: Element.Methods.positionedOffset,

  absolutize: function(element) {
    Position.prepare();
    return Element.absolutize(element);
  },

  relativize: function(element) {
    Position.prepare();
    return Element.relativize(element);
  },

  realOffset: Element.Methods.cumulativeScrollOffset,

  offsetParent: Element.Methods.getOffsetParent,

  page: Element.Methods.viewportOffset,

  clone: function(source, target, options) {
    options = options || { };
    return Element.clonePosition(target, source, options);
  }
};

/*--------------------------------------------------------------------------*/

if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
  function iter(name) {
    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
  }

  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
  function(element, className) {
    className = className.toString().strip();
    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
  } : function(element, className) {
    className = className.toString().strip();
    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
    if (!classNames && !className) return elements;

    var nodes = $(element).getElementsByTagName('*');
    className = ' ' + className + ' ';

    for (var i = 0, child, cn; child = nodes[i]; i++) {
      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
          (classNames && classNames.all(function(name) {
            return !name.toString().blank() && cn.include(' ' + name + ' ');
          }))))
        elements.push(Element.extend(child));
    }
    return elements;
  };

  return function(className, parentElement) {
    return $(parentElement || document.body).getElementsByClassName(className);
  };
}(Element.Methods);

/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;
    this.set($A(this).concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set($A(this).without(classNameToRemove).join(' '));
  },

  toString: function() {
    return $A(this).join(' ');
  }
};

Object.extend(Element.ClassNames.prototype, Enumerable);

/*--------------------------------------------------------------------------*/

Element.addMethods();

// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
//  Justin Palmer (http://encytemedia.com/)
//  Mark Pilgrim (http://diveintomark.org/)
//  Martin Bialasinki
//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/

// converts rgb() and #xxx to #xxxxxx format,
// returns self (or first argument) if not convertable
String.prototype.parseColor = function() {
  var color = '#';
  if (this.slice(0,4) == 'rgb(') {
    var cols = this.slice(4,this.length-1).split(',');
    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
  } else {
    if (this.slice(0,1) == '#') {
      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
      if (this.length==7) color = this.toLowerCase();
    }
  }
  return (color.length==7 ? color : (arguments[0] || this));
};

/*--------------------------------------------------------------------------*/

Element.collectTextNodes = function(element) {
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue :
      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
  }).flatten().join('');
};

Element.collectTextNodesIgnoreClass = function(element, className) {
  return $A($(element).childNodes).collect( function(node) {
    return (node.nodeType==3 ? node.nodeValue :
      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
        Element.collectTextNodesIgnoreClass(node, className) : ''));
  }).flatten().join('');
};

Element.setContentZoom = function(element, percent) {
  element = $(element);
  element.setStyle({fontSize: (percent/100) + 'em'});
  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
  return element;
};

Element.getInlineOpacity = function(element){
  return $(element).style.opacity || '';
};

Element.forceRerendering = function(element) {
  try {
    element = $(element);
    var n = document.createTextNode(' ');
    element.appendChild(n);
    element.removeChild(n);
  } catch(e) { }
};

/*--------------------------------------------------------------------------*/

var Effect = {
  _elementDoesNotExistError: {
    name: 'ElementDoesNotExistError',
    message: 'The specified DOM element does not exist, but is required for this effect to operate'
  },
  Transitions: {
    linear: Prototype.K,
    sinoidal: function(pos) {
      return (-Math.cos(pos*Math.PI)/2) + .5;
    },
    reverse: function(pos) {
      return 1-pos;
    },
    flicker: function(pos) {
      var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
      return pos > 1 ? 1 : pos;
    },
    wobble: function(pos) {
      return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
    },
    pulse: function(pos, pulses) {
      return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
    },
    spring: function(pos) {
      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
    },
    none: function(pos) {
      return 0;
    },
    full: function(pos) {
      return 1;
    }
  },
  DefaultOptions: {
    duration:   1.0,   // seconds
    fps:        100,   // 100= assume 66fps max.
    sync:       false, // true for combining
    from:       0.0,
    to:         1.0,
    delay:      0.0,
    queue:      'parallel'
  },
  tagifyText: function(element) {
    var tagifyStyle = 'position:relative';
    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';

    element = $(element);
    $A(element.childNodes).each( function(child) {
      if (child.nodeType==3) {
        child.nodeValue.toArray().each( function(character) {
          element.insertBefore(
            new Element('span', {style: tagifyStyle}).update(
              character == ' ' ? String.fromCharCode(160) : character),
              child);
        });
        Element.remove(child);
      }
    });
  },
  multiple: function(element, effect) {
    var elements;
    if (((typeof element == 'object') ||
        Object.isFunction(element)) &&
       (element.length))
      elements = element;
    else
      elements = $(element).childNodes;

    var options = Object.extend({
      speed: 0.1,
      delay: 0.0
    }, arguments[2] || { });
    var masterDelay = options.delay;

    $A(elements).each( function(element, index) {
      new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
    });
  },
  PAIRS: {
    'slide':  ['SlideDown','SlideUp'],
    'blind':  ['BlindDown','BlindUp'],
    'appear': ['Appear','Fade']
  },
  toggle: function(element, effect) {
    element = $(element);
    effect = (effect || 'appear').toLowerCase();
    var options = Object.extend({
      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
    }, arguments[2] || { });
    Effect[element.visible() ?
      Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
  }
};

Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;

/* ------------- core effects ------------- */

Effect.ScopedQueue = Class.create(Enumerable, {
  initialize: function() {
    this.effects  = [];
    this.interval = null;
  },
  _each: function(iterator) {
    this.effects._each(iterator);
  },
  add: function(effect) {
    var timestamp = new Date().getTime();

    var position = Object.isString(effect.options.queue) ?
      effect.options.queue : effect.options.queue.position;

    switch(position) {
      case 'front':
        // move unstarted effects after this effect
        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
            e.startOn  += effect.finishOn;
            e.finishOn += effect.finishOn;
          });
        break;
      case 'with-last':
        timestamp = this.effects.pluck('startOn').max() || timestamp;
        break;
      case 'end':
        // start effect after last queued effect has finished
        timestamp = this.effects.pluck('finishOn').max() || timestamp;
        break;
    }

    effect.startOn  += timestamp;
    effect.finishOn += timestamp;

    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
      this.effects.push(effect);

    if (!this.interval)
      this.interval = setInterval(this.loop.bind(this), 15);
  },
  remove: function(effect) {
    this.effects = this.effects.reject(function(e) { return e==effect });
    if (this.effects.length == 0) {
      clearInterval(this.interval);
      this.interval = null;
    }
  },
  loop: function() {
    var timePos = new Date().getTime();
    for(var i=0, len=this.effects.length;i<len;i++)
      this.effects[i] && this.effects[i].loop(timePos);
  }
});

Effect.Queues = {
  instances: $H(),
  get: function(queueName) {
    if (!Object.isString(queueName)) return queueName;

    return this.instances.get(queueName) ||
      this.instances.set(queueName, new Effect.ScopedQueue());
  }
};
Effect.Queue = Effect.Queues.get('global');

Effect.Base = Class.create({
  position: null,
  start: function(options) {
    function codeForEvent(options,eventName){
      return (
        (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
        (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
      );
    }
    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
    this.currentFrame = 0;
    this.state        = 'idle';
    this.startOn      = this.options.delay*1000;
    this.finishOn     = this.startOn+(this.options.duration*1000);
    this.fromToDelta  = this.options.to-this.options.from;
    this.totalTime    = this.finishOn-this.startOn;
    this.totalFrames  = this.options.fps*this.options.duration;

    this.render = (function() {
      function dispatch(effect, eventName) {
        if (effect.options[eventName + 'Internal'])
          effect.options[eventName + 'Internal'](effect);
        if (effect.options[eventName])
          effect.options[eventName](effect);
      }

      return function(pos) {
        if (this.state === "idle") {
          this.state = "running";
          dispatch(this, 'beforeSetup');
          if (this.setup) this.setup();
          dispatch(this, 'afterSetup');
        }
        if (this.state === "running") {
          pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
          this.position = pos;
          dispatch(this, 'beforeUpdate');
          if (this.update) this.update(pos);
          dispatch(this, 'afterUpdate');
        }
      };
    })();

    this.event('beforeStart');
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ?
        'global' : this.options.queue.scope).add(this);
  },
  loop: function(timePos) {
    if (timePos >= this.startOn) {
      if (timePos >= this.finishOn) {
        this.render(1.0);
        this.cancel();
        this.event('beforeFinish');
        if (this.finish) this.finish();
        this.event('afterFinish');
        return;
      }
      var pos   = (timePos - this.startOn) / this.totalTime,
          frame = (pos * this.totalFrames).round();
      if (frame > this.currentFrame) {
        this.render(pos);
        this.currentFrame = frame;
      }
    }
  },
  cancel: function() {
    if (!this.options.sync)
      Effect.Queues.get(Object.isString(this.options.queue) ?
        'global' : this.options.queue.scope).remove(this);
    this.state = 'finished';
  },
  event: function(eventName) {
    if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
    if (this.options[eventName]) this.options[eventName](this);
  },
  inspect: function() {
    var data = $H();
    for(property in this)
      if (!Object.isFunction(this[property])) data.set(property, this[property]);
    return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
  }
});

Effect.Parallel = Class.create(Effect.Base, {
  initialize: function(effects) {
    this.effects = effects || [];
    this.start(arguments[1]);
  },
  update: function(position) {
    this.effects.invoke('render', position);
  },
  finish: function(position) {
    this.effects.each( function(effect) {
      effect.render(1.0);
      effect.cancel();
      effect.event('beforeFinish');
      if (effect.finish) effect.finish(position);
      effect.event('afterFinish');
    });
  }
});

Effect.Tween = Class.create(Effect.Base, {
  initialize: function(object, from, to) {
    object = Object.isString(object) ? $(object) : object;
    var args = $A(arguments), method = args.last(),
      options = args.length == 5 ? args[3] : null;
    this.method = Object.isFunction(method) ? method.bind(object) :
      Object.isFunction(object[method]) ? object[method].bind(object) :
      function(value) { object[method] = value };
    this.start(Object.extend({ from: from, to: to }, options || { }));
  },
  update: function(position) {
    this.method(position);
  }
});

Effect.Event = Class.create(Effect.Base, {
  initialize: function() {
    this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
  },
  update: Prototype.emptyFunction
});

Effect.Opacity = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    // make this work on IE on elements without 'layout'
    if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
      this.element.setStyle({zoom: 1});
    var options = Object.extend({
      from: this.element.getOpacity() || 0.0,
      to:   1.0
    }, arguments[1] || { });
    this.start(options);
  },
  update: function(position) {
    this.element.setOpacity(position);
  }
});

Effect.Move = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      x:    0,
      y:    0,
      mode: 'relative'
    }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    this.element.makePositioned();
    this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
    this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
    if (this.options.mode == 'absolute') {
      this.options.x = this.options.x - this.originalLeft;
      this.options.y = this.options.y - this.originalTop;
    }
  },
  update: function(position) {
    this.element.setStyle({
      left: (this.options.x  * position + this.originalLeft).round() + 'px',
      top:  (this.options.y  * position + this.originalTop).round()  + 'px'
    });
  }
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
  return new Effect.Move(element,
    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};

Effect.Scale = Class.create(Effect.Base, {
  initialize: function(element, percent) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      scaleX: true,
      scaleY: true,
      scaleContent: true,
      scaleFromCenter: false,
      scaleMode: 'box',        // 'box' or 'contents' or { } with provided values
      scaleFrom: 100.0,
      scaleTo:   percent
    }, arguments[2] || { });
    this.start(options);
  },
  setup: function() {
    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
    this.elementPositioning = this.element.getStyle('position');

    this.originalStyle = { };
    ['top','left','width','height','fontSize'].each( function(k) {
      this.originalStyle[k] = this.element.style[k];
    }.bind(this));

    this.originalTop  = this.element.offsetTop;
    this.originalLeft = this.element.offsetLeft;

    var fontSize = this.element.getStyle('font-size') || '100%';
    ['em','px','%','pt'].each( function(fontSizeType) {
      if (fontSize.indexOf(fontSizeType)>0) {
        this.fontSize     = parseFloat(fontSize);
        this.fontSizeType = fontSizeType;
      }
    }.bind(this));

    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;

    this.dims = null;
    if (this.options.scaleMode=='box')
      this.dims = [this.element.offsetHeight, this.element.offsetWidth];
    if (/^content/.test(this.options.scaleMode))
      this.dims = [this.element.scrollHeight, this.element.scrollWidth];
    if (!this.dims)
      this.dims = [this.options.scaleMode.originalHeight,
                   this.options.scaleMode.originalWidth];
  },
  update: function(position) {
    var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
    if (this.options.scaleContent && this.fontSize)
      this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
    this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
  },
  finish: function(position) {
    if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
  },
  setDimensions: function(height, width) {
    var d = { };
    if (this.options.scaleX) d.width = width.round() + 'px';
    if (this.options.scaleY) d.height = height.round() + 'px';
    if (this.options.scaleFromCenter) {
      var topd  = (height - this.dims[0])/2;
      var leftd = (width  - this.dims[1])/2;
      if (this.elementPositioning == 'absolute') {
        if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
        if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
      } else {
        if (this.options.scaleY) d.top = -topd + 'px';
        if (this.options.scaleX) d.left = -leftd + 'px';
      }
    }
    this.element.setStyle(d);
  }
});

Effect.Highlight = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
    this.start(options);
  },
  setup: function() {
    // Prevent executing on elements not in the layout flow
    if (this.element.getStyle('display')=='none') { this.cancel(); return; }
    // Disable background image during the effect
    this.oldStyle = { };
    if (!this.options.keepBackgroundImage) {
      this.oldStyle.backgroundImage = this.element.getStyle('background-image');
      this.element.setStyle({backgroundImage: 'none'});
    }
    if (!this.options.endcolor)
      this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
    if (!this.options.restorecolor)
      this.options.restorecolor = this.element.getStyle('background-color');
    // init color calculations
    this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
    this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
  },
  update: function(position) {
    this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
      return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
  },
  finish: function() {
    this.element.setStyle(Object.extend(this.oldStyle, {
      backgroundColor: this.options.restorecolor
    }));
  }
});

Effect.ScrollTo = function(element) {
  var options = arguments[1] || { },
  scrollOffsets = document.viewport.getScrollOffsets(),
  elementOffsets = $(element).cumulativeOffset();

  if (options.offset) elementOffsets[1] += options.offset;

  return new Effect.Tween(null,
    scrollOffsets.top,
    elementOffsets[1],
    options,
    function(p){ scrollTo(scrollOffsets.left, p.round()); }
  );
};

/* ------------- combination effects ------------- */

Effect.Fade = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  var options = Object.extend({
    from: element.getOpacity() || 1.0,
    to:   0.0,
    afterFinishInternal: function(effect) {
      if (effect.options.to!=0) return;
      effect.element.hide().setStyle({opacity: oldOpacity});
    }
  }, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Appear = function(element) {
  element = $(element);
  var options = Object.extend({
  from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
  to:   1.0,
  // force Safari to render floated elements properly
  afterFinishInternal: function(effect) {
    effect.element.forceRerendering();
  },
  beforeSetup: function(effect) {
    effect.element.setOpacity(effect.options.from).show();
  }}, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Puff = function(element) {
  element = $(element);
  var oldStyle = {
    opacity: element.getInlineOpacity(),
    position: element.getStyle('position'),
    top:  element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height
  };
  return new Effect.Parallel(
   [ new Effect.Scale(element, 200,
      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
     Object.extend({ duration: 1.0,
      beforeSetupInternal: function(effect) {
        Position.absolutize(effect.effects[0].element);
      },
      afterFinishInternal: function(effect) {
         effect.effects[0].element.hide().setStyle(oldStyle); }
     }, arguments[1] || { })
   );
};

Effect.BlindUp = function(element) {
  element = $(element);
  element.makeClipping();
  return new Effect.Scale(element, 0,
    Object.extend({ scaleContent: false,
      scaleX: false,
      restoreAfterFinish: true,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping();
      }
    }, arguments[1] || { })
  );
};

Effect.BlindDown = function(element) {
  element = $(element);
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({
    scaleContent: false,
    scaleX: false,
    scaleFrom: 0,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makeClipping().setStyle({height: '0px'}).show();
    },
    afterFinishInternal: function(effect) {
      effect.element.undoClipping();
    }
  }, arguments[1] || { }));
};

Effect.SwitchOff = function(element) {
  element = $(element);
  var oldOpacity = element.getInlineOpacity();
  return new Effect.Appear(element, Object.extend({
    duration: 0.4,
    from: 0,
    transition: Effect.Transitions.flicker,
    afterFinishInternal: function(effect) {
      new Effect.Scale(effect.element, 1, {
        duration: 0.3, scaleFromCenter: true,
        scaleX: false, scaleContent: false, restoreAfterFinish: true,
        beforeSetup: function(effect) {
          effect.element.makePositioned().makeClipping();
        },
        afterFinishInternal: function(effect) {
          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
        }
      });
    }
  }, arguments[1] || { }));
};

Effect.DropOut = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left'),
    opacity: element.getInlineOpacity() };
  return new Effect.Parallel(
    [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
    Object.extend(
      { duration: 0.5,
        beforeSetup: function(effect) {
          effect.effects[0].element.makePositioned();
        },
        afterFinishInternal: function(effect) {
          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
        }
      }, arguments[1] || { }));
};

Effect.Shake = function(element) {
  element = $(element);
  var options = Object.extend({
    distance: 20,
    duration: 0.5
  }, arguments[1] || {});
  var distance = parseFloat(options.distance);
  var split = parseFloat(options.duration) / 10.0;
  var oldStyle = {
    top: element.getStyle('top'),
    left: element.getStyle('left') };
    return new Effect.Move(element,
      { x:  distance, y: 0, duration: split, afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x:  distance*2, y: 0, duration: split*2,  afterFinishInternal: function(effect) {
    new Effect.Move(effect.element,
      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
        effect.element.undoPositioned().setStyle(oldStyle);
  }}); }}); }}); }}); }}); }});
};

Effect.SlideDown = function(element) {
  element = $(element).cleanWhitespace();
  // SlideDown need to have the content of the element wrapped in a container element with fixed height!
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, 100, Object.extend({
    scaleContent: false,
    scaleX: false,
    scaleFrom: window.opera ? 0 : 1,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().setStyle({height: '0px'}).show();
    },
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' });
    },
    afterFinishInternal: function(effect) {
      effect.element.undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
    }, arguments[1] || { })
  );
};

Effect.SlideUp = function(element) {
  element = $(element).cleanWhitespace();
  var oldInnerBottom = element.down().getStyle('bottom');
  var elementDimensions = element.getDimensions();
  return new Effect.Scale(element, window.opera ? 0 : 1,
   Object.extend({ scaleContent: false,
    scaleX: false,
    scaleMode: 'box',
    scaleFrom: 100,
    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
    restoreAfterFinish: true,
    afterSetup: function(effect) {
      effect.element.makePositioned();
      effect.element.down().makePositioned();
      if (window.opera) effect.element.setStyle({top: ''});
      effect.element.makeClipping().show();
    },
    afterUpdateInternal: function(effect) {
      effect.element.down().setStyle({bottom:
        (effect.dims[0] - effect.element.clientHeight) + 'px' });
    },
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping().undoPositioned();
      effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
    }
   }, arguments[1] || { })
  );
};

// Bug in opera makes the TD containing this element expand for a instance after finish
Effect.Squish = function(element) {
  return new Effect.Scale(element, window.opera ? 1 : 0, {
    restoreAfterFinish: true,
    beforeSetup: function(effect) {
      effect.element.makeClipping();
    },
    afterFinishInternal: function(effect) {
      effect.element.hide().undoClipping();
    }
  });
};

Effect.Grow = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.full
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var initialMoveX, initialMoveY;
  var moveX, moveY;

  switch (options.direction) {
    case 'top-left':
      initialMoveX = initialMoveY = moveX = moveY = 0;
      break;
    case 'top-right':
      initialMoveX = dims.width;
      initialMoveY = moveY = 0;
      moveX = -dims.width;
      break;
    case 'bottom-left':
      initialMoveX = moveX = 0;
      initialMoveY = dims.height;
      moveY = -dims.height;
      break;
    case 'bottom-right':
      initialMoveX = dims.width;
      initialMoveY = dims.height;
      moveX = -dims.width;
      moveY = -dims.height;
      break;
    case 'center':
      initialMoveX = dims.width / 2;
      initialMoveY = dims.height / 2;
      moveX = -dims.width / 2;
      moveY = -dims.height / 2;
      break;
  }

  return new Effect.Move(element, {
    x: initialMoveX,
    y: initialMoveY,
    duration: 0.01,
    beforeSetup: function(effect) {
      effect.element.hide().makeClipping().makePositioned();
    },
    afterFinishInternal: function(effect) {
      new Effect.Parallel(
        [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
          new Effect.Scale(effect.element, 100, {
            scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
        ], Object.extend({
             beforeSetup: function(effect) {
               effect.effects[0].element.setStyle({height: '0px'}).show();
             },
             afterFinishInternal: function(effect) {
               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
             }
           }, options)
      );
    }
  });
};

Effect.Shrink = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.none
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var moveX, moveY;

  switch (options.direction) {
    case 'top-left':
      moveX = moveY = 0;
      break;
    case 'top-right':
      moveX = dims.width;
      moveY = 0;
      break;
    case 'bottom-left':
      moveX = 0;
      moveY = dims.height;
      break;
    case 'bottom-right':
      moveX = dims.width;
      moveY = dims.height;
      break;
    case 'center':
      moveX = dims.width / 2;
      moveY = dims.height / 2;
      break;
  }

  return new Effect.Parallel(
    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
    ], Object.extend({
         beforeStartInternal: function(effect) {
           effect.effects[0].element.makePositioned().makeClipping();
         },
         afterFinishInternal: function(effect) {
           effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
       }, options)
  );
};

Effect.Pulsate = function(element) {
  element = $(element);
  var options    = arguments[1] || { },
    oldOpacity = element.getInlineOpacity(),
    transition = options.transition || Effect.Transitions.linear,
    reverser   = function(pos){
      return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
    };

  return new Effect.Opacity(element,
    Object.extend(Object.extend({  duration: 2.0, from: 0,
      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
    }, options), {transition: reverser}));
};

Effect.Fold = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height };
  element.makeClipping();
  return new Effect.Scale(element, 5, Object.extend({
    scaleContent: false,
    scaleX: false,
    afterFinishInternal: function(effect) {
    new Effect.Scale(element, 1, {
      scaleContent: false,
      scaleY: false,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping().setStyle(oldStyle);
      } });
  }}, arguments[1] || { }));
};

Effect.Morph = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      style: { }
    }, arguments[1] || { });

    if (!Object.isString(options.style)) this.style = $H(options.style);
    else {
      if (options.style.include(':'))
        this.style = options.style.parseStyle();
      else {
        this.element.addClassName(options.style);
        this.style = $H(this.element.getStyles());
        this.element.removeClassName(options.style);
        var css = this.element.getStyles();
        this.style = this.style.reject(function(style) {
          return style.value == css[style.key];
        });
        options.afterFinishInternal = function(effect) {
          effect.element.addClassName(effect.options.style);
          effect.transforms.each(function(transform) {
            effect.element.style[transform.style] = '';
          });
        };
      }
    }
    this.start(options);
  },

  setup: function(){
    function parseColor(color){
      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
      color = color.parseColor();
      return $R(0,2).map(function(i){
        return parseInt( color.slice(i*2+1,i*2+3), 16 );
      });
    }
    this.transforms = this.style.map(function(pair){
      var property = pair[0], value = pair[1], unit = null;

      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
        value = value.parseColor();
        unit  = 'color';
      } else if (property == 'opacity') {
        value = parseFloat(value);
        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
          this.element.setStyle({zoom: 1});
      } else if (Element.CSS_LENGTH.test(value)) {
          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
          value = parseFloat(components[1]);
          unit = (components.length == 3) ? components[2] : null;
      }

      var originalValue = this.element.getStyle(property);
      return {
        style: property.camelize(),
        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
        targetValue: unit=='color' ? parseColor(value) : value,
        unit: unit
      };
    }.bind(this)).reject(function(transform){
      return (
        (transform.originalValue == transform.targetValue) ||
        (
          transform.unit != 'color' &&
          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
        )
      );
    });
  },
  update: function(position) {
    var style = { }, transform, i = this.transforms.length;
    while(i--)
      style[(transform = this.transforms[i]).style] =
        transform.unit=='color' ? '#'+
          (Math.round(transform.originalValue[0]+
            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
          (Math.round(transform.originalValue[1]+
            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
          (Math.round(transform.originalValue[2]+
            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
        (transform.originalValue +
          (transform.targetValue - transform.originalValue) * position).toFixed(3) +
            (transform.unit === null ? '' : transform.unit);
    this.element.setStyle(style, true);
  }
});

Effect.Transform = Class.create({
  initialize: function(tracks){
    this.tracks  = [];
    this.options = arguments[1] || { };
    this.addTracks(tracks);
  },
  addTracks: function(tracks){
    tracks.each(function(track){
      track = $H(track);
      var data = track.values().first();
      this.tracks.push($H({
        ids:     track.keys().first(),
        effect:  Effect.Morph,
        options: { style: data }
      }));
    }.bind(this));
    return this;
  },
  play: function(){
    return new Effect.Parallel(
      this.tracks.map(function(track){
        var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
        var elements = [$(ids) || $$(ids)].flatten();
        return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
      }).flatten(),
      this.options
    );
  }
});

Element.CSS_PROPERTIES = $w(
  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
  'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
  'fontSize fontWeight height left letterSpacing lineHeight ' +
  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
  'right textIndent top width wordSpacing zIndex');

Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;

String.__parseStyleElement = document.createElement('div');
String.prototype.parseStyle = function(){
  var style, styleRules = $H();
  if (Prototype.Browser.WebKit)
    style = new Element('div',{style:this}).style;
  else {
    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
    style = String.__parseStyleElement.childNodes[0].style;
  }

  Element.CSS_PROPERTIES.each(function(property){
    if (style[property]) styleRules.set(property, style[property]);
  });

  if (Prototype.Browser.IE && this.include('opacity'))
    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);

  return styleRules;
};

if (document.defaultView && document.defaultView.getComputedStyle) {
  Element.getStyles = function(element) {
    var css = document.defaultView.getComputedStyle($(element), null);
    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
      styles[property] = css[property];
      return styles;
    });
  };
} else {
  Element.getStyles = function(element) {
    element = $(element);
    var css = element.currentStyle, styles;
    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
      results[property] = css[property];
      return results;
    });
    if (!styles.opacity) styles.opacity = element.getOpacity();
    return styles;
  };
}

Effect.Methods = {
  morph: function(element, style) {
    element = $(element);
    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
    return element;
  },
  visualEffect: function(element, effect, options) {
    element = $(element);
    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
    new Effect[klass](element, options);
    return element;
  },
  highlight: function(element, options) {
    element = $(element);
    new Effect.Highlight(element, options);
    return element;
  }
};

$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
  'pulsate shake puff squish switchOff dropOut').each(
  function(effect) {
    Effect.Methods[effect] = function(element, options){
      element = $(element);
      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
      return element;
    };
  }
);

$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
  function(f) { Effect.Methods[f] = Element[f]; }
);

Element.addMethods(Effect.Methods);

// script.aculo.us scriptaculous.js v1.8.2, Tue Nov 18 18:30:58 +0100 2008

// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// For details, see the script.aculo.us web site: http://script.aculo.us/

var Scriptaculous = {
  Version: '1.8.2',
  require: function(libraryName) {
    // inserting via DOM fails in Safari 2.0, so brute force approach
    document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
  },
  REQUIRED_PROTOTYPE: '1.6.0.3',
  load: function() {
    function convertVersionString(versionString) {
      var v = versionString.replace(/_.*|\./g, '');
      v = parseInt(v + '0'.times(4-v.length));
      return versionString.indexOf('_') > -1 ? v-1 : v;
    }

    if((typeof Prototype=='undefined') ||
       (typeof Element == 'undefined') ||
       (typeof Element.Methods=='undefined') ||
       (convertVersionString(Prototype.Version) <
        convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
       throw("script.aculo.us requires the Prototype JavaScript framework >= " +
        Scriptaculous.REQUIRED_PROTOTYPE);

    var js = /scriptaculous\.js(\?.*)?$/;
    $$('head script[src]').findAll(function(s) {
      return s.src.match(js);
    }).each(function(s) {
      var path = s.src.replace(js, ''),
      includes = s.src.match(/\?.*load=([a-z,]*)/);
      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
       function(include) { Scriptaculous.require(path+include+'.js') });
    });
  }
};

Scriptaculous.load();

/*
 * Raphael 1.3.0 - JavaScript Vector Library
 *
 * Copyright (c) 2008 - 2009 Dmitry Baranovskiy (http://raphaeljs.com)
 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
 */
window.Raphael=(function(){var a=/[, ]+/,aO=/^(circle|rect|path|ellipse|text|image)$/,L=document,au=window,l={was:"Raphael" in au,is:au.Raphael},an=function(){if(an.is(arguments[0],"array")){var d=arguments[0],e=w[aW](an,d.splice(0,3+an.is(d[0],al))),S=e.set();for(var R=0,a0=d[m];R<a0;R++){var E=d[R]||{};aO.test(E.type)&&S[f](e[E.type]().attr(E));}return S;}return w[aW](an,arguments);},aT=function(){},aL="appendChild",aW="apply",aS="concat",at="",am=" ",z="split",F="click dblclick mousedown mousemove mouseout mouseover mouseup"[z](am),Q="hasOwnProperty",az="join",m="length",aY="prototype",aZ=String[aY].toLowerCase,ab=Math,g=ab.max,aI=ab.min,al="number",aA="toString",aw=Object[aY][aA],aQ={},aM=ab.pow,f="push",aU=/^(?=[\da-f]$)/,c=/^url\(['"]?([^\)]+)['"]?\)$/i,x=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgb\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|rgb\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\)|hs[bl]\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hs[bl]\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i,O=ab.round,v="setAttribute",W=parseFloat,G=parseInt,aN=String[aY].toUpperCase,j={"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},Z={along:"along","clip-rect":"csv",cx:al,cy:al,fill:"colour","fill-opacity":al,"font-size":al,height:al,opacity:al,path:"path",r:al,rotation:"csv",rx:al,ry:al,scale:"csv",stroke:"colour","stroke-opacity":al,"stroke-width":al,translation:"csv",width:al,x:al,y:al},aP="replace";an.version="1.3.0";an.type=(au.SVGAngle||L.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML");if(an.type=="VML"){var ag=document.createElement("div");ag.innerHTML="<!--[if vml]><br><br><![endif]-->";if(ag.childNodes[m]!=2){return null;}}an.svg=!(an.vml=an.type=="VML");aT[aY]=an[aY];an._id=0;an._oid=0;an.fn={};an.is=function(e,d){d=aZ.call(d);return((d=="object"||d=="undefined")&&typeof e==d)||(e==null&&d=="null")||aZ.call(aw.call(e).slice(8,-1))==d;};an.setWindow=function(d){au=d;L=au.document;};var aD=function(e){if(an.vml){var d=/^\s+|\s+$/g;aD=aj(function(R){var S;R=(R+at)[aP](d,at);try{var a0=new ActiveXObject("htmlfile");a0.write("<body>");a0.close();S=a0.body;}catch(a2){S=createPopup().document.body;}var i=S.createTextRange();try{S.style.color=R;var a1=i.queryCommandValue("ForeColor");a1=((a1&255)<<16)|(a1&65280)|((a1&16711680)>>>16);return"#"+("000000"+a1[aA](16)).slice(-6);}catch(a2){return"none";}});}else{var E=L.createElement("i");E.title="Rapha\xebl Colour Picker";E.style.display="none";L.body[aL](E);aD=aj(function(i){E.style.color=i;return L.defaultView.getComputedStyle(E,at).getPropertyValue("color");});}return aD(e);};an.hsb2rgb=aj(function(a3,a1,a7){if(an.is(a3,"object")&&"h" in a3&&"s" in a3&&"b" in a3){a7=a3.b;a1=a3.s;a3=a3.h;}var R,S,a8;if(a7==0){return{r:0,g:0,b:0,hex:"#000"};}if(a3>1||a1>1||a7>1){a3/=255;a1/=255;a7/=255;}var a0=~~(a3*6),a4=(a3*6)-a0,E=a7*(1-a1),e=a7*(1-(a1*a4)),a9=a7*(1-(a1*(1-a4)));R=[a7,e,E,E,a9,a7,a7][a0];S=[a9,a7,a7,e,E,E,a9][a0];a8=[E,E,a9,a7,a7,e,E][a0];R*=255;S*=255;a8*=255;var a5={r:R,g:S,b:a8},d=(~~R)[aA](16),a2=(~~S)[aA](16),a6=(~~a8)[aA](16);d=d[aP](aU,"0");a2=a2[aP](aU,"0");a6=a6[aP](aU,"0");a5.hex="#"+d+a2+a6;return a5;},an);an.rgb2hsb=aj(function(d,e,a1){if(an.is(d,"object")&&"r" in d&&"g" in d&&"b" in d){a1=d.b;e=d.g;d=d.r;}if(an.is(d,"string")){var a3=an.getRGB(d);d=a3.r;e=a3.g;a1=a3.b;}if(d>1||e>1||a1>1){d/=255;e/=255;a1/=255;}var a0=g(d,e,a1),i=aI(d,e,a1),R,E,S=a0;if(i==a0){return{h:0,s:0,b:a0};}else{var a2=(a0-i);E=a2/a0;if(d==a0){R=(e-a1)/a2;}else{if(e==a0){R=2+((a1-d)/a2);}else{R=4+((d-e)/a2);}}R/=6;R<0&&R++;R>1&&R--;}return{h:R,s:E,b:S};},an);var aE=/,?([achlmqrstvxz]),?/gi;an._path2string=function(){return this.join(",")[aP](aE,"$1");};function aj(E,e,d){function i(){var R=Array[aY].slice.call(arguments,0),a0=R[az]("\u25ba"),S=i.cache=i.cache||{},a1=i.count=i.count||[];if(S[Q](a0)){return d?d(S[a0]):S[a0];}a1[m]>=1000&&delete S[a1.shift()];a1[f](a0);S[a0]=E[aW](e,R);return d?d(S[a0]):S[a0];}return i;}an.getRGB=aj(function(d){if(!d||!!((d=d+at).indexOf("-")+1)){return{r:-1,g:-1,b:-1,hex:"none",error:1};}if(d=="none"){return{r:-1,g:-1,b:-1,hex:"none"};}!(({hs:1,rg:1})[Q](d.substring(0,2))||d.charAt()=="#")&&(d=aD(d));var S,i,E,a2,a3,a0=d.match(x);if(a0){if(a0[2]){a2=G(a0[2].substring(5),16);E=G(a0[2].substring(3,5),16);i=G(a0[2].substring(1,3),16);}if(a0[3]){a2=G((a3=a0[3].charAt(3))+a3,16);E=G((a3=a0[3].charAt(2))+a3,16);i=G((a3=a0[3].charAt(1))+a3,16);}if(a0[4]){a0=a0[4][z](/\s*,\s*/);i=W(a0[0]);E=W(a0[1]);a2=W(a0[2]);}if(a0[5]){a0=a0[5][z](/\s*,\s*/);i=W(a0[0])*2.55;E=W(a0[1])*2.55;a2=W(a0[2])*2.55;}if(a0[6]){a0=a0[6][z](/\s*,\s*/);i=W(a0[0]);E=W(a0[1]);a2=W(a0[2]);return an.hsb2rgb(i,E,a2);}if(a0[7]){a0=a0[7][z](/\s*,\s*/);i=W(a0[0])*2.55;E=W(a0[1])*2.55;a2=W(a0[2])*2.55;return an.hsb2rgb(i,E,a2);}a0={r:i,g:E,b:a2};var e=(~~i)[aA](16),R=(~~E)[aA](16),a1=(~~a2)[aA](16);e=e[aP](aU,"0");R=R[aP](aU,"0");a1=a1[aP](aU,"0");a0.hex="#"+e+R+a1;return a0;}return{r:-1,g:-1,b:-1,hex:"none",error:1};},an);an.getColor=function(e){var i=this.getColor.start=this.getColor.start||{h:0,s:1,b:e||0.75},d=this.hsb2rgb(i.h,i.s,i.b);i.h+=0.075;if(i.h>1){i.h=0;i.s-=0.2;i.s<=0&&(this.getColor.start={h:0,s:1,b:i.b});}return d.hex;};an.getColor.reset=function(){delete this.start;};an.parsePathString=aj(function(d){if(!d){return null;}var i={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},e=[];if(an.is(d,"array")&&an.is(d[0],"array")){e=av(d);}if(!e[m]){(d+at)[aP](/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,function(R,E,a1){var a0=[],S=aZ.call(E);a1[aP](/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,function(a3,a2){a2&&a0[f](+a2);});while(a0[m]>=i[S]){e[f]([E][aS](a0.splice(0,i[S])));if(!i[S]){break;}}});}e[aA]=an._path2string;return e;});an.findDotsAtSegment=function(e,d,be,bc,a0,R,a2,a1,a8){var a6=1-a8,a5=aM(a6,3)*e+aM(a6,2)*3*a8*be+a6*3*a8*a8*a0+aM(a8,3)*a2,a3=aM(a6,3)*d+aM(a6,2)*3*a8*bc+a6*3*a8*a8*R+aM(a8,3)*a1,ba=e+2*a8*(be-e)+a8*a8*(a0-2*be+e),a9=d+2*a8*(bc-d)+a8*a8*(R-2*bc+d),bd=be+2*a8*(a0-be)+a8*a8*(a2-2*a0+be),bb=bc+2*a8*(R-bc)+a8*a8*(a1-2*R+bc),a7=(1-a8)*e+a8*be,a4=(1-a8)*d+a8*bc,E=(1-a8)*a0+a8*a2,i=(1-a8)*R+a8*a1,S=(90-ab.atan((ba-bd)/(a9-bb))*180/ab.PI);(ba>bd||a9<bb)&&(S+=180);return{x:a5,y:a3,m:{x:ba,y:a9},n:{x:bd,y:bb},start:{x:a7,y:a4},end:{x:E,y:i},alpha:S};};var U=aj(function(a5){if(!a5){return{x:0,y:0,width:0,height:0};}a5=H(a5);var a2=0,a1=0,R=[],e=[],E;for(var S=0,a4=a5[m];S<a4;S++){E=a5[S];if(E[0]=="M"){a2=E[1];a1=E[2];R[f](a2);e[f](a1);}else{var a0=aC(a2,a1,E[1],E[2],E[3],E[4],E[5],E[6]);R=R[aS](a0.min.x,a0.max.x);e=e[aS](a0.min.y,a0.max.y);a2=E[5];a1=E[6];}}var d=aI[aW](0,R),a3=aI[aW](0,e);return{x:d,y:a3,width:g[aW](0,R)-d,height:g[aW](0,e)-a3};}),av=function(a0){var E=[];if(!an.is(a0,"array")||!an.is(a0&&a0[0],"array")){a0=an.parsePathString(a0);}for(var e=0,R=a0[m];e<R;e++){E[e]=[];for(var d=0,S=a0[e][m];d<S;d++){E[e][d]=a0[e][d];}}E[aA]=an._path2string;return E;},ad=aj(function(R){if(!an.is(R,"array")||!an.is(R&&R[0],"array")){R=an.parsePathString(R);}var a4=[],a6=0,a5=0,a9=0,a8=0,E=0;if(R[0][0]=="M"){a6=R[0][1];a5=R[0][2];a9=a6;a8=a5;E++;a4[f](["M",a6,a5]);}for(var a1=E,ba=R[m];a1<ba;a1++){var d=a4[a1]=[],a7=R[a1];if(a7[0]!=aZ.call(a7[0])){d[0]=aZ.call(a7[0]);switch(d[0]){case"a":d[1]=a7[1];d[2]=a7[2];d[3]=a7[3];d[4]=a7[4];d[5]=a7[5];d[6]=+(a7[6]-a6).toFixed(3);d[7]=+(a7[7]-a5).toFixed(3);break;case"v":d[1]=+(a7[1]-a5).toFixed(3);break;case"m":a9=a7[1];a8=a7[2];default:for(var a0=1,a2=a7[m];a0<a2;a0++){d[a0]=+(a7[a0]-((a0%2)?a6:a5)).toFixed(3);}}}else{d=a4[a1]=[];if(a7[0]=="m"){a9=a7[1]+a6;a8=a7[2]+a5;}for(var S=0,e=a7[m];S<e;S++){a4[a1][S]=a7[S];}}var a3=a4[a1][m];switch(a4[a1][0]){case"z":a6=a9;a5=a8;break;case"h":a6+=+a4[a1][a3-1];break;case"v":a5+=+a4[a1][a3-1];break;default:a6+=+a4[a1][a3-2];a5+=+a4[a1][a3-1];}}a4[aA]=an._path2string;return a4;},0,av),r=aj(function(R){if(!an.is(R,"array")||!an.is(R&&R[0],"array")){R=an.parsePathString(R);}var a3=[],a5=0,a4=0,a8=0,a7=0,E=0;if(R[0][0]=="M"){a5=+R[0][1];a4=+R[0][2];a8=a5;a7=a4;E++;a3[0]=["M",a5,a4];}for(var a1=E,a9=R[m];a1<a9;a1++){var d=a3[a1]=[],a6=R[a1];if(a6[0]!=aN.call(a6[0])){d[0]=aN.call(a6[0]);switch(d[0]){case"A":d[1]=a6[1];d[2]=a6[2];d[3]=a6[3];d[4]=a6[4];d[5]=a6[5];d[6]=+(a6[6]+a5);d[7]=+(a6[7]+a4);break;case"V":d[1]=+a6[1]+a4;break;case"H":d[1]=+a6[1]+a5;break;case"M":a8=+a6[1]+a5;a7=+a6[2]+a4;default:for(var a0=1,a2=a6[m];a0<a2;a0++){d[a0]=+a6[a0]+((a0%2)?a5:a4);}}}else{for(var S=0,e=a6[m];S<e;S++){a3[a1][S]=a6[S];}}switch(d[0]){case"Z":a5=a8;a4=a7;break;case"H":a5=d[1];break;case"V":a4=d[1];break;default:a5=a3[a1][a3[a1][m]-2];a4=a3[a1][a3[a1][m]-1];}}a3[aA]=an._path2string;return a3;},null,av),aX=function(e,E,d,i){return[e,E,d,i,d,i];},aK=function(e,E,a0,R,d,i){var S=1/3,a1=2/3;return[S*e+a1*a0,S*E+a1*R,S*d+a1*a0,S*i+a1*R,d,i];},K=function(a9,bD,bi,bg,ba,a4,S,a8,bC,bb){var R=ab.PI,bf=R*120/180,d=R/180*(+ba||0),bm=[],bj,bz=aj(function(bE,bH,i){var bG=bE*ab.cos(i)-bH*ab.sin(i),bF=bE*ab.sin(i)+bH*ab.cos(i);return{x:bG,y:bF};});if(!bb){bj=bz(a9,bD,-d);a9=bj.x;bD=bj.y;bj=bz(a8,bC,-d);a8=bj.x;bC=bj.y;var e=ab.cos(R/180*ba),a6=ab.sin(R/180*ba),bo=(a9-a8)/2,bn=(bD-bC)/2;bi=g(bi,ab.abs(bo));bg=g(bg,ab.abs(bn));var E=bi*bi,br=bg*bg,bt=(a4==S?-1:1)*ab.sqrt(ab.abs((E*br-E*bn*bn-br*bo*bo)/(E*bn*bn+br*bo*bo))),bd=bt*bi*bn/bg+(a9+a8)/2,bc=bt*-bg*bo/bi+(bD+bC)/2,a3=ab.asin(((bD-bc)/bg).toFixed(7)),a2=ab.asin(((bC-bc)/bg).toFixed(7));a3=a9<bd?R-a3:a3;a2=a8<bd?R-a2:a2;a3<0&&(a3=R*2+a3);a2<0&&(a2=R*2+a2);if(S&&a3>a2){a3=a3-R*2;}if(!S&&a2>a3){a2=a2-R*2;}}else{a3=bb[0];a2=bb[1];bd=bb[2];bc=bb[3];}var a7=a2-a3;if(ab.abs(a7)>bf){var be=a2,bh=a8,a5=bC;a2=a3+bf*(S&&a2>a3?1:-1);a8=bd+bi*ab.cos(a2);bC=bc+bg*ab.sin(a2);bm=K(a8,bC,bi,bg,ba,0,S,bh,a5,[a2,be,bd,bc]);}a7=a2-a3;var a1=ab.cos(a3),bB=ab.sin(a3),a0=ab.cos(a2),bA=ab.sin(a2),bp=ab.tan(a7/4),bs=4/3*bi*bp,bq=4/3*bg*bp,by=[a9,bD],bx=[a9+bs*bB,bD-bq*a1],bw=[a8+bs*bA,bC-bq*a0],bu=[a8,bC];bx[0]=2*by[0]-bx[0];bx[1]=2*by[1]-bx[1];if(bb){return[bx,bw,bu][aS](bm);}else{bm=[bx,bw,bu][aS](bm)[az]()[z](",");var bk=[];for(var bv=0,bl=bm[m];bv<bl;bv++){bk[bv]=bv%2?bz(bm[bv-1],bm[bv],d).y:bz(bm[bv],bm[bv+1],d).x;}return bk;}},M=function(e,d,E,i,a2,a1,a0,S,a3){var R=1-a3;return{x:aM(R,3)*e+aM(R,2)*3*a3*E+R*3*a3*a3*a2+aM(a3,3)*a0,y:aM(R,3)*d+aM(R,2)*3*a3*i+R*3*a3*a3*a1+aM(a3,3)*S};},aC=aj(function(i,d,R,E,a9,a8,a5,a2){var a7=(a9-2*R+i)-(a5-2*a9+R),a4=2*(R-i)-2*(a9-R),a1=i-R,a0=(-a4+ab.sqrt(a4*a4-4*a7*a1))/2/a7,S=(-a4-ab.sqrt(a4*a4-4*a7*a1))/2/a7,a3=[d,a2],a6=[i,a5],e;ab.abs(a0)>1000000000000&&(a0=0.5);ab.abs(S)>1000000000000&&(S=0.5);if(a0>0&&a0<1){e=M(i,d,R,E,a9,a8,a5,a2,a0);a6[f](e.x);a3[f](e.y);}if(S>0&&S<1){e=M(i,d,R,E,a9,a8,a5,a2,S);a6[f](e.x);a3[f](e.y);}a7=(a8-2*E+d)-(a2-2*a8+E);a4=2*(E-d)-2*(a8-E);a1=d-E;a0=(-a4+ab.sqrt(a4*a4-4*a7*a1))/2/a7;S=(-a4-ab.sqrt(a4*a4-4*a7*a1))/2/a7;ab.abs(a0)>1000000000000&&(a0=0.5);ab.abs(S)>1000000000000&&(S=0.5);if(a0>0&&a0<1){e=M(i,d,R,E,a9,a8,a5,a2,a0);a6[f](e.x);a3[f](e.y);}if(S>0&&S<1){e=M(i,d,R,E,a9,a8,a5,a2,S);a6[f](e.x);a3[f](e.y);}return{min:{x:aI[aW](0,a6),y:aI[aW](0,a3)},max:{x:g[aW](0,a6),y:g[aW](0,a3)}};}),H=aj(function(a9,a4){var R=r(a9),a5=a4&&r(a4),a6={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},d={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},a0=function(ba,bb){var i,bc;if(!ba){return["C",bb.x,bb.y,bb.x,bb.y,bb.x,bb.y];}!(ba[0] in {T:1,Q:1})&&(bb.qx=bb.qy=null);switch(ba[0]){case"M":bb.X=ba[1];bb.Y=ba[2];break;case"A":ba=["C"][aS](K[aW](0,[bb.x,bb.y][aS](ba.slice(1))));break;case"S":i=bb.x+(bb.x-(bb.bx||bb.x));bc=bb.y+(bb.y-(bb.by||bb.y));ba=["C",i,bc][aS](ba.slice(1));break;case"T":bb.qx=bb.x+(bb.x-(bb.qx||bb.x));bb.qy=bb.y+(bb.y-(bb.qy||bb.y));ba=["C"][aS](aK(bb.x,bb.y,bb.qx,bb.qy,ba[1],ba[2]));break;case"Q":bb.qx=ba[1];bb.qy=ba[2];ba=["C"][aS](aK(bb.x,bb.y,ba[1],ba[2],ba[3],ba[4]));break;case"L":ba=["C"][aS](aX(bb.x,bb.y,ba[1],ba[2]));break;case"H":ba=["C"][aS](aX(bb.x,bb.y,ba[1],bb.y));break;case"V":ba=["C"][aS](aX(bb.x,bb.y,bb.x,ba[1]));break;case"Z":ba=["C"][aS](aX(bb.x,bb.y,bb.X,bb.Y));break;}return ba;},e=function(ba,bb){if(ba[bb][m]>7){ba[bb].shift();var bc=ba[bb];while(bc[m]){ba.splice(bb++,0,["C"][aS](bc.splice(0,6)));}ba.splice(bb,1);a7=g(R[m],a5&&a5[m]||0);}},E=function(be,bd,bb,ba,bc){if(be&&bd&&be[bc][0]=="M"&&bd[bc][0]!="M"){bd.splice(bc,0,["M",ba.x,ba.y]);bb.bx=0;bb.by=0;bb.x=be[bc][1];bb.y=be[bc][2];a7=g(R[m],a5&&a5[m]||0);}};for(var a2=0,a7=g(R[m],a5&&a5[m]||0);a2<a7;a2++){R[a2]=a0(R[a2],a6);e(R,a2);a5&&(a5[a2]=a0(a5[a2],d));a5&&e(a5,a2);E(R,a5,a6,d,a2);E(a5,R,d,a6,a2);var a1=R[a2],a8=a5&&a5[a2],S=a1[m],a3=a5&&a8[m];a6.x=a1[S-2];a6.y=a1[S-1];a6.bx=W(a1[S-4])||a6.x;a6.by=W(a1[S-3])||a6.y;d.bx=a5&&(W(a8[a3-4])||d.x);d.by=a5&&(W(a8[a3-3])||d.y);d.x=a5&&a8[a3-2];d.y=a5&&a8[a3-1];}return a5?[R,a5]:R;},null,av),p=aj(function(a4){var a3=[];for(var a0=0,a5=a4[m];a0<a5;a0++){var e={},a2=a4[a0].match(/^([^:]*):?([\d\.]*)/);e.color=an.getRGB(a2[1]);if(e.color.error){return null;}e.color=e.color.hex;a2[2]&&(e.offset=a2[2]+"%");a3[f](e);}for(var a0=1,a5=a3[m]-1;a0<a5;a0++){if(!a3[a0].offset){var E=W(a3[a0-1].offset||0),R=0;for(var S=a0+1;S<a5;S++){if(a3[S].offset){R=a3[S].offset;break;}}if(!R){R=100;S=a5;}R=W(R);var a1=(R-E)/(S-a0+1);for(;a0<S;a0++){E+=a1;a3[a0].offset=E+"%";}}}return a3;}),ao=function(){var i,e,R,E,d;if(an.is(arguments[0],"string")||an.is(arguments[0],"object")){if(an.is(arguments[0],"string")){i=L.getElementById(arguments[0]);}else{i=arguments[0];}if(i.tagName){if(arguments[1]==null){return{container:i,width:i.style.pixelWidth||i.offsetWidth,height:i.style.pixelHeight||i.offsetHeight};}else{return{container:i,width:arguments[1],height:arguments[2]};}}}else{if(an.is(arguments[0],al)&&arguments[m]>3){return{container:1,x:arguments[0],y:arguments[1],width:arguments[2],height:arguments[3]};}}},aG=function(d,i){var e=this;for(var E in i){if(i[Q](E)&&!(E in d)){switch(typeof i[E]){case"function":(function(R){d[E]=d===e?R:function(){return R[aW](e,arguments);};})(i[E]);break;case"object":d[E]=d[E]||{};aG.call(this,d[E],i[E]);break;default:d[E]=i[E];break;}}}},ak=function(d,e){d==e.top&&(e.top=d.prev);d==e.bottom&&(e.bottom=d.next);d.next&&(d.next.prev=d.prev);d.prev&&(d.prev.next=d.next);},Y=function(d,e){if(e.top===d){return;}ak(d,e);d.next=null;d.prev=e.top;e.top.next=d;e.top=d;},k=function(d,e){if(e.bottom===d){return;}ak(d,e);d.next=e.bottom;d.prev=null;e.bottom.prev=d;e.bottom=d;},A=function(e,d,i){ak(e,i);d==i.top&&(i.top=e);d.next&&(d.next.prev=e);e.next=d.next;e.prev=d;d.next=e;},aq=function(e,d,i){ak(e,i);d==i.bottom&&(i.bottom=e);d.prev&&(d.prev.next=e);e.prev=d.prev;d.prev=e;e.next=d;},s=function(d){return function(){throw new Error("Rapha\xebl: you are calling to method \u201c"+d+"\u201d of removed object");};},ar=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/;if(an.svg){aT[aY].svgns="http://www.w3.org/2000/svg";aT[aY].xlink="http://www.w3.org/1999/xlink";var O=function(d){return +d+(~~d===d)*0.5;},V=function(S){for(var e=0,E=S[m];e<E;e++){if(aZ.call(S[e][0])!="a"){for(var d=1,R=S[e][m];d<R;d++){S[e][d]=O(S[e][d]);}}else{S[e][6]=O(S[e][6]);S[e][7]=O(S[e][7]);}}return S;},aJ=function(i,d){if(d){for(var e in d){if(d[Q](e)){i[v](e,d[e]);}}}else{return L.createElementNS(aT[aY].svgns,i);}};an[aA]=function(){return"Your browser supports SVG.\nYou are running Rapha\xebl "+this.version;};var q=function(d,E){var e=aJ("path");E.canvas&&E.canvas[aL](e);var i=new ax(e,E);i.type="path";aa(i,{fill:"none",stroke:"#000",path:d});return i;};var b=function(E,a7,d){var a4="linear",a1=0.5,S=0.5,a9=E.style;a7=(a7+at)[aP](ar,function(bb,i,bc){a4="radial";if(i&&bc){a1=W(i);S=W(bc);var ba=((S>0.5)*2-1);aM(a1-0.5,2)+aM(S-0.5,2)>0.25&&(S=ab.sqrt(0.25-aM(a1-0.5,2))*ba+0.5)&&S!=0.5&&(S=S.toFixed(5)-0.00001*ba);}return at;});a7=a7[z](/\s*\-\s*/);if(a4=="linear"){var a0=a7.shift();a0=-W(a0);if(isNaN(a0)){return null;}var R=[0,0,ab.cos(a0*ab.PI/180),ab.sin(a0*ab.PI/180)],a6=1/(g(ab.abs(R[2]),ab.abs(R[3]))||1);R[2]*=a6;R[3]*=a6;if(R[2]<0){R[0]=-R[2];R[2]=0;}if(R[3]<0){R[1]=-R[3];R[3]=0;}}var a3=p(a7);if(!a3){return null;}var e=aJ(a4+"Gradient");e.id="r"+(an._id++)[aA](36);aJ(e,a4=="radial"?{fx:a1,fy:S}:{x1:R[0],y1:R[1],x2:R[2],y2:R[3]});d.defs[aL](e);for(var a2=0,a8=a3[m];a2<a8;a2++){var a5=aJ("stop");aJ(a5,{offset:a3[a2].offset?a3[a2].offset:!a2?"0%":"100%","stop-color":a3[a2].color||"#fff"});e[aL](a5);}aJ(E,{fill:"url(#"+e.id+")",opacity:1,"fill-opacity":1});a9.fill=at;a9.opacity=1;a9.fillOpacity=1;return 1;};var N=function(e){var d=e.getBBox();aJ(e.pattern,{patternTransform:an.format("translate({0},{1})",d.x,d.y)});};var aa=function(a6,bf){var a9={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},bb=a6.node,a7=a6.attrs,a3=a6.rotate(),S=function(bm,bl){bl=a9[aZ.call(bl)];if(bl){var bj=bm.attrs["stroke-width"]||"1",bh={round:bj,square:bj,butt:0}[bm.attrs["stroke-linecap"]||bf["stroke-linecap"]]||0,bk=[];var bi=bl[m];while(bi--){bk[bi]=bl[bi]*bj+((bi%2)?1:-1)*bh;}aJ(bb,{"stroke-dasharray":bk[az](",")});}};bf[Q]("rotation")&&(a3=bf.rotation);var a2=(a3+at)[z](a);if(!(a2.length-1)){a2=null;}else{a2[1]=+a2[1];a2[2]=+a2[2];}W(a3)&&a6.rotate(0,true);for(var ba in bf){if(bf[Q](ba)){if(!j[Q](ba)){continue;}var a8=bf[ba];a7[ba]=a8;switch(ba){case"rotation":a6.rotate(a8,true);break;case"href":case"title":case"target":var bd=bb.parentNode;if(aZ.call(bd.tagName)!="a"){var E=aJ("a");bd.insertBefore(E,bb);E[aL](bb);bd=E;}bd.setAttributeNS(a6.Paper[aY].xlink,ba,a8);break;case"cursor":bb.style.cursor=a8;break;case"clip-rect":var e=(a8+at)[z](a);if(e[m]==4){a6.clip&&a6.clip.parentNode.parentNode.removeChild(a6.clip.parentNode);var i=aJ("clipPath"),bc=aJ("rect");i.id="r"+(an._id++)[aA](36);aJ(bc,{x:e[0],y:e[1],width:e[2],height:e[3]});i[aL](bc);a6.paper.defs[aL](i);aJ(bb,{"clip-path":"url(#"+i.id+")"});a6.clip=bc;}if(!a8){var be=L.getElementById(bb.getAttribute("clip-path")[aP](/(^url\(#|\)$)/g,at));be&&be.parentNode.removeChild(be);aJ(bb,{"clip-path":at});delete a6.clip;}break;case"path":if(a8&&a6.type=="path"){a7.path=V(r(a8));aJ(bb,{d:a7.path});}break;case"width":bb[v](ba,a8);if(a7.fx){ba="x";a8=a7.x;}else{break;}case"x":if(a7.fx){a8=-a7.x-(a7.width||0);}case"rx":if(ba=="rx"&&a6.type=="rect"){break;}case"cx":a2&&(ba=="x"||ba=="cx")&&(a2[1]+=a8-a7[ba]);bb[v](ba,O(a8));a6.pattern&&N(a6);break;case"height":bb[v](ba,a8);if(a7.fy){ba="y";a8=a7.y;}else{break;}case"y":if(a7.fy){a8=-a7.y-(a7.height||0);}case"ry":if(ba=="ry"&&a6.type=="rect"){break;}case"cy":a2&&(ba=="y"||ba=="cy")&&(a2[2]+=a8-a7[ba]);bb[v](ba,O(a8));a6.pattern&&N(a6);break;case"r":if(a6.type=="rect"){aJ(bb,{rx:a8,ry:a8});}else{bb[v](ba,a8);}break;case"src":if(a6.type=="image"){bb.setAttributeNS(a6.paper.xlink,"href",a8);}break;case"stroke-width":bb.style.strokeWidth=a8;bb[v](ba,a8);if(a7["stroke-dasharray"]){S(a6,a7["stroke-dasharray"]);}break;case"stroke-dasharray":S(a6,a8);break;case"translation":var a0=(a8+at)[z](a);a0[0]=+a0[0]||0;a0[1]=+a0[1]||0;if(a2){a2[1]+=a0[0];a2[2]+=a0[1];}t.call(a6,a0[0],a0[1]);break;case"scale":var a0=(a8+at)[z](a);a6.scale(+a0[0]||1,+a0[1]||+a0[0]||1,+a0[2]||null,+a0[3]||null);break;case"fill":var R=(a8+at).match(c);if(R){var i=aJ("pattern"),a5=aJ("image");i.id="r"+(an._id++)[aA](36);aJ(i,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});aJ(a5,{x:0,y:0});a5.setAttributeNS(a6.paper.xlink,"href",R[1]);i[aL](a5);var bg=L.createElement("img");bg.style.cssText="position:absolute;left:-9999em;top-9999em";bg.onload=function(){aJ(i,{width:this.offsetWidth,height:this.offsetHeight});aJ(a5,{width:this.offsetWidth,height:this.offsetHeight});L.body.removeChild(this);a6.paper.safari();};L.body[aL](bg);bg.src=R[1];a6.paper.defs[aL](i);bb.style.fill="url(#"+i.id+")";aJ(bb,{fill:"url(#"+i.id+")"});a6.pattern=i;a6.pattern&&N(a6);break;}if(!an.getRGB(a8).error){delete bf.gradient;delete a7.gradient;!an.is(a7.opacity,"undefined")&&an.is(bf.opacity,"undefined")&&aJ(bb,{opacity:a7.opacity});!an.is(a7["fill-opacity"],"undefined")&&an.is(bf["fill-opacity"],"undefined")&&aJ(bb,{"fill-opacity":a7["fill-opacity"]});}else{if((({circle:1,ellipse:1})[Q](a6.type)||(a8+at).charAt()!="r")&&b(bb,a8,a6.paper)){a7.gradient=a8;a7.fill="none";break;}}case"stroke":bb[v](ba,an.getRGB(a8).hex);break;case"gradient":(({circle:1,ellipse:1})[Q](a6.type)||(a8+at).charAt()!="r")&&b(bb,a8,a6.paper);break;case"opacity":case"fill-opacity":if(a7.gradient){var d=L.getElementById(bb.getAttribute("fill")[aP](/^url\(#|\)$/g,at));if(d){var a1=d.getElementsByTagName("stop");a1[a1[m]-1][v]("stop-opacity",a8);}break;}default:ba=="font-size"&&(a8=G(a8,10)+"px");var a4=ba[aP](/(\-.)/g,function(bh){return aN.call(bh.substring(1));});bb.style[a4]=a8;bb[v](ba,a8);break;}}}D(a6,bf);if(a2){a6.rotate(a2.join(am));}else{W(a3)&&a6.rotate(a3,true);}};var h=1.2;var D=function(d,R){if(d.type!="text"||!(R[Q]("text")||R[Q]("font")||R[Q]("font-size")||R[Q]("x")||R[Q]("y"))){return;}var a3=d.attrs,e=d.node,a5=e.firstChild?G(L.defaultView.getComputedStyle(e.firstChild,at).getPropertyValue("font-size"),10):10;if(R[Q]("text")){a3.text=R.text;while(e.firstChild){e.removeChild(e.firstChild);}var E=(R.text+at)[z]("\n");for(var S=0,a4=E[m];S<a4;S++){if(E[S]){var a1=aJ("tspan");S&&aJ(a1,{dy:a5*h,x:a3.x});a1[aL](L.createTextNode(E[S]));e[aL](a1);}}}else{var E=e.getElementsByTagName("tspan");for(var S=0,a4=E[m];S<a4;S++){S&&aJ(E[S],{dy:a5*h,x:a3.x});}}aJ(e,{y:a3.y});var a0=d.getBBox(),a2=a3.y-(a0.y+a0.height/2);a2&&isFinite(a2)&&aJ(e,{y:a3.y+a2});};var ax=function(e,d){var E=0,i=0;this[0]=e;this.id=an._oid++;this.node=e;e.raphael=this;this.paper=d;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null;};ax[aY].rotate=function(e,d,E){if(this.removed){return this;}if(e==null){if(this._.rt.cx){return[this._.rt.deg,this._.rt.cx,this._.rt.cy][az](am);}return this._.rt.deg;}var i=this.getBBox();e=(e+at)[z](a);if(e[m]-1){d=W(e[1]);E=W(e[2]);}e=W(e[0]);if(d!=null){this._.rt.deg=e;}else{this._.rt.deg+=e;}(E==null)&&(d=null);this._.rt.cx=d;this._.rt.cy=E;d=d==null?i.x+i.width/2:d;E=E==null?i.y+i.height/2:E;if(this._.rt.deg){this.transformations[0]=an.format("rotate({0} {1} {2})",this._.rt.deg,d,E);this.clip&&aJ(this.clip,{transform:an.format("rotate({0} {1} {2})",-this._.rt.deg,d,E)});}else{this.transformations[0]=at;this.clip&&aJ(this.clip,{transform:at});}aJ(this.node,{transform:this.transformations[az](am)});return this;};ax[aY].hide=function(){!this.removed&&(this.node.style.display="none");return this;};ax[aY].show=function(){!this.removed&&(this.node.style.display="");return this;};ax[aY].remove=function(){if(this.removed){return;}ak(this,this.paper);this.node.parentNode.removeChild(this.node);for(var d in this){delete this[d];}this.removed=true;};ax[aY].getBBox=function(){if(this.removed){return this;}if(this.type=="path"){return U(this.attrs.path);}if(this.node.style.display=="none"){this.show();var E=true;}var a1={};try{a1=this.node.getBBox();}catch(S){}finally{a1=a1||{};}if(this.type=="text"){a1={x:a1.x,y:Infinity,width:0,height:0};for(var d=0,R=this.node.getNumberOfChars();d<R;d++){var a0=this.node.getExtentOfChar(d);(a0.y<a1.y)&&(a1.y=a0.y);(a0.y+a0.height-a1.y>a1.height)&&(a1.height=a0.y+a0.height-a1.y);(a0.x+a0.width-a1.x>a1.width)&&(a1.width=a0.x+a0.width-a1.x);}}E&&this.hide();return a1;};ax[aY].attr=function(){if(this.removed){return this;}if(arguments[m]==0){var R={};for(var E in this.attrs){if(this.attrs[Q](E)){R[E]=this.attrs[E];}}this._.rt.deg&&(R.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(R.scale=this.scale());R.gradient&&R.fill=="none"&&(R.fill=R.gradient)&&delete R.gradient;return R;}if(arguments[m]==1&&an.is(arguments[0],"string")){if(arguments[0]=="translation"){return t.call(this);}if(arguments[0]=="rotation"){return this.rotate();}if(arguments[0]=="scale"){return this.scale();}if(arguments[0]=="fill"&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient;}return this.attrs[arguments[0]];}if(arguments[m]==1&&an.is(arguments[0],"array")){var d={};for(var e in arguments[0]){if(arguments[0][Q](e)){d[arguments[0][e]]=this.attrs[arguments[0][e]];}}return d;}if(arguments[m]==2){var S={};S[arguments[0]]=arguments[1];aa(this,S);}else{if(arguments[m]==1&&an.is(arguments[0],"object")){aa(this,arguments[0]);}}return this;};ax[aY].toFront=function(){if(this.removed){return this;}this.node.parentNode[aL](this.node);var d=this.paper;d.top!=this&&Y(this,d);return this;};ax[aY].toBack=function(){if(this.removed){return this;}if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);k(this,this.paper);var d=this.paper;}return this;};ax[aY].insertAfter=function(d){if(this.removed){return this;}var e=d.node;if(e.nextSibling){e.parentNode.insertBefore(this.node,e.nextSibling);}else{e.parentNode[aL](this.node);}A(this,d,this.paper);return this;};ax[aY].insertBefore=function(d){if(this.removed){return this;}var e=d.node;e.parentNode.insertBefore(this.node,e);aq(this,d,this.paper);return this;};var P=function(e,d,S,R){d=O(d);S=O(S);var E=aJ("circle");e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={cx:d,cy:S,r:R,fill:"none",stroke:"#000"};i.type="circle";aJ(E,i.attrs);return i;};var aF=function(i,d,a1,e,S,a0){d=O(d);a1=O(a1);var R=aJ("rect");i.canvas&&i.canvas[aL](R);var E=new ax(R,i);E.attrs={x:d,y:a1,width:e,height:S,r:a0||0,rx:a0||0,ry:a0||0,fill:"none",stroke:"#000"};E.type="rect";aJ(R,E.attrs);return E;};var ai=function(e,d,a0,S,R){d=O(d);a0=O(a0);var E=aJ("ellipse");e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={cx:d,cy:a0,rx:S,ry:R,fill:"none",stroke:"#000"};i.type="ellipse";aJ(E,i.attrs);return i;};var o=function(i,a0,d,a1,e,S){var R=aJ("image");aJ(R,{x:d,y:a1,width:e,height:S,preserveAspectRatio:"none"});R.setAttributeNS(i.xlink,"href",a0);i.canvas&&i.canvas[aL](R);var E=new ax(R,i);E.attrs={x:d,y:a1,width:e,height:S,src:a0};E.type="image";return E;};var X=function(e,d,S,R){var E=aJ("text");aJ(E,{x:d,y:S,"text-anchor":"middle"});e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={x:d,y:S,"text-anchor":"middle",text:R,font:j.font,stroke:"none",fill:"#000"};i.type="text";aa(i,i.attrs);return i;};var aV=function(e,d){this.width=e||this.width;this.height=d||this.height;this.canvas[v]("width",this.width);this.canvas[v]("height",this.height);return this;};var w=function(){var E=ao[aW](null,arguments),i=E&&E.container,e=E.x,a0=E.y,R=E.width,d=E.height;if(!i){throw new Error("SVG container not found.");}var S=aJ("svg");R=R||512;d=d||342;aJ(S,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:R,height:d});if(i==1){S.style.cssText="position:absolute;left:"+e+"px;top:"+a0+"px";L.body[aL](S);}else{if(i.firstChild){i.insertBefore(S,i.firstChild);}else{i[aL](S);}}i=new aT;i.width=R;i.height=d;i.canvas=S;aG.call(i,i,an.fn);i.clear();return i;};aT[aY].clear=function(){var d=this.canvas;while(d.firstChild){d.removeChild(d.firstChild);}this.bottom=this.top=null;(this.desc=aJ("desc"))[aL](L.createTextNode("Created with Rapha\xebl"));d[aL](this.desc);d[aL](this.defs=aJ("defs"));};aT[aY].remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var d in this){this[d]=s(d);}};}if(an.vml){var aH=function(a8){var a5=/[ahqstv]/ig,a0=r;(a8+at).match(a5)&&(a0=H);a5=/[clmz]/g;if(a0==r&&!(a8+at).match(a5)){var e={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},R=/([clmz]),?([^clmz]*)/gi,S=/-?[^,\s-]+/g;var a4=(a8+at)[aP](R,function(a9,bb,i){var ba=[];i[aP](S,function(bc){ba[f](O(bc));});return e[bb]+ba;});return a4;}var a6=a0(a8),E,a4=[],d;for(var a2=0,a7=a6[m];a2<a7;a2++){E=a6[a2];d=aZ.call(a6[a2][0]);d=="z"&&(d="x");for(var a1=1,a3=E[m];a1<a3;a1++){d+=O(E[a1])+(a1!=a3-1?",":at);}a4[f](d);}return a4[az](am);};an[aA]=function(){return"Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl "+this.version;};var q=function(d,S){var E=ah("group");E.style.cssText="position:absolute;left:0;top:0;width:"+S.width+"px;height:"+S.height+"px";E.coordsize=S.coordsize;E.coordorigin=S.coordorigin;var i=ah("shape"),e=i.style;e.width=S.width+"px";e.height=S.height+"px";i.coordsize=this.coordsize;i.coordorigin=this.coordorigin;E[aL](i);var R=new ax(i,E,S);R.isAbsolute=true;R.type="path";R.path=[];R.Path=at;d&&aa(R,{fill:"none",stroke:"#000",path:d});S.canvas[aL](E);return R;};var aa=function(a3,a8){a3.attrs=a3.attrs||{};var a6=a3.node,a9=a3.attrs,a0=a6.style,E,bd=a3;for(var a1 in a8){if(a8[Q](a1)){a9[a1]=a8[a1];}}a8.href&&(a6.href=a8.href);a8.title&&(a6.title=a8.title);a8.target&&(a6.target=a8.target);a8.cursor&&(a0.cursor=a8.cursor);if(a8.path&&a3.type=="path"){a9.path=a8.path;a6.path=aH(a9.path);}if(a8.rotation!=null){a3.rotate(a8.rotation,true);}if(a8.translation){E=(a8.translation+at)[z](a);t.call(a3,E[0],E[1]);if(a3._.rt.cx!=null){a3._.rt.cx+=+E[0];a3._.rt.cy+=+E[1];a3.setBox(a3.attrs,E[0],E[1]);}}if(a8.scale){E=(a8.scale+at)[z](a);a3.scale(+E[0]||1,+E[1]||+E[0]||1,+E[2]||null,+E[3]||null);}if("clip-rect" in a8){var d=(a8["clip-rect"]+at)[z](a);if(d[m]==4){d[2]=+d[2]+(+d[0]);d[3]=+d[3]+(+d[1]);var a2=a6.clipRect||L.createElement("div"),bc=a2.style,S=a6.parentNode;bc.clip=an.format("rect({1}px {2}px {3}px {0}px)",d);if(!a6.clipRect){bc.position="absolute";bc.top=0;bc.left=0;bc.width=a3.paper.width+"px";bc.height=a3.paper.height+"px";S.parentNode.insertBefore(a2,S);a2[aL](S);a6.clipRect=a2;}}if(!a8["clip-rect"]){a6.clipRect&&(a6.clipRect.style.clip=at);}}if(a3.type=="image"&&a8.src){a6.src=a8.src;}if(a3.type=="image"&&a8.opacity){a6.filterOpacity=" progid:DXImageTransform.Microsoft.Alpha(opacity="+(a8.opacity*100)+")";a0.filter=(a6.filterMatrix||at)+(a6.filterOpacity||at);}a8.font&&(a0.font=a8.font);a8["font-family"]&&(a0.fontFamily='"'+a8["font-family"][z](",")[0][aP](/^['"]+|['"]+$/g,at)+'"');a8["font-size"]&&(a0.fontSize=a8["font-size"]);a8["font-weight"]&&(a0.fontWeight=a8["font-weight"]);a8["font-style"]&&(a0.fontStyle=a8["font-style"]);if(a8.opacity!=null||a8["stroke-width"]!=null||a8.fill!=null||a8.stroke!=null||a8["stroke-width"]!=null||a8["stroke-opacity"]!=null||a8["fill-opacity"]!=null||a8["stroke-dasharray"]!=null||a8["stroke-miterlimit"]!=null||a8["stroke-linejoin"]!=null||a8["stroke-linecap"]!=null){a6=a3.shape||a6;var a7=(a6.getElementsByTagName("fill")&&a6.getElementsByTagName("fill")[0]),ba=false;!a7&&(ba=a7=ah("fill"));if("fill-opacity" in a8||"opacity" in a8){var e=((+a9["fill-opacity"]+1||2)-1)*((+a9.opacity+1||2)-1);e<0&&(e=0);e>1&&(e=1);a7.opacity=e;}a8.fill&&(a7.on=true);if(a7.on==null||a8.fill=="none"){a7.on=false;}if(a7.on&&a8.fill){var i=a8.fill.match(c);if(i){a7.src=i[1];a7.type="tile";}else{a7.color=an.getRGB(a8.fill).hex;a7.src=at;a7.type="solid";if(an.getRGB(a8.fill).error&&(bd.type in {circle:1,ellipse:1}||(a8.fill+at).charAt()!="r")&&b(bd,a8.fill)){a9.fill="none";a9.gradient=a8.fill;}}}ba&&a6[aL](a7);var R=(a6.getElementsByTagName("stroke")&&a6.getElementsByTagName("stroke")[0]),bb=false;!R&&(bb=R=ah("stroke"));if((a8.stroke&&a8.stroke!="none")||a8["stroke-width"]||a8["stroke-opacity"]!=null||a8["stroke-dasharray"]||a8["stroke-miterlimit"]||a8["stroke-linejoin"]||a8["stroke-linecap"]){R.on=true;}(a8.stroke=="none"||R.on==null||a8.stroke==0||a8["stroke-width"]==0)&&(R.on=false);R.on&&a8.stroke&&(R.color=an.getRGB(a8.stroke).hex);var e=((+a9["stroke-opacity"]+1||2)-1)*((+a9.opacity+1||2)-1),a4=(W(a8["stroke-width"])||1)*0.75;e<0&&(e=0);e>1&&(e=1);a8["stroke-width"]==null&&(a4=a9["stroke-width"]);a8["stroke-width"]&&(R.weight=a4);a4&&a4<1&&(e*=a4)&&(R.weight=1);R.opacity=e;a8["stroke-linejoin"]&&(R.joinstyle=a8["stroke-linejoin"]||"miter");R.miterlimit=a8["stroke-miterlimit"]||8;a8["stroke-linecap"]&&(R.endcap=a8["stroke-linecap"]=="butt"?"flat":a8["stroke-linecap"]=="square"?"square":"round");if(a8["stroke-dasharray"]){var a5={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};R.dashstyle=a5[Q](a8["stroke-dasharray"])?a5[a8["stroke-dasharray"]]:at;}bb&&a6[aL](R);}if(bd.type=="text"){var a0=bd.paper.span.style;a9.font&&(a0.font=a9.font);a9["font-family"]&&(a0.fontFamily=a9["font-family"]);a9["font-size"]&&(a0.fontSize=a9["font-size"]);a9["font-weight"]&&(a0.fontWeight=a9["font-weight"]);a9["font-style"]&&(a0.fontStyle=a9["font-style"]);bd.node.string&&(bd.paper.span.innerHTML=(bd.node.string+at)[aP](/</g,"&#60;")[aP](/&/g,"&#38;")[aP](/\n/g,"<br>"));bd.W=a9.w=bd.paper.span.offsetWidth;bd.H=a9.h=bd.paper.span.offsetHeight;bd.X=a9.x;bd.Y=a9.y+O(bd.H/2);switch(a9["text-anchor"]){case"start":bd.node.style["v-text-align"]="left";bd.bbx=O(bd.W/2);break;case"end":bd.node.style["v-text-align"]="right";bd.bbx=-O(bd.W/2);break;default:bd.node.style["v-text-align"]="center";break;}}};var b=function(d,a1){d.attrs=d.attrs||{};var a2=d.attrs,a4=d.node.getElementsByTagName("fill"),S="linear",a0=".5 .5";d.attrs.gradient=a1;a1=(a1+at)[aP](ar,function(a6,a7,i){S="radial";if(a7&&i){a7=W(a7);i=W(i);aM(a7-0.5,2)+aM(i-0.5,2)>0.25&&(i=ab.sqrt(0.25-aM(a7-0.5,2))*((i>0.5)*2-1)+0.5);a0=a7+am+i;}return at;});a1=a1[z](/\s*\-\s*/);if(S=="linear"){var e=a1.shift();e=-W(e);if(isNaN(e)){return null;}}var R=p(a1);if(!R){return null;}d=d.shape||d.node;a4=a4[0]||ah("fill");if(R[m]){a4.on=true;a4.method="none";a4.type=(S=="radial")?"gradientradial":"gradient";a4.color=R[0].color;a4.color2=R[R[m]-1].color;var a5=[];for(var E=0,a3=R[m];E<a3;E++){R[E].offset&&a5[f](R[E].offset+am+R[E].color);}a4.colors&&(a4.colors.value=a5[m]?a5[az](","):"0% "+a4.color);if(S=="radial"){a4.focus="100%";a4.focussize=a0;a4.focusposition=a0;}else{a4.angle=(270-e)%360;}}return 1;};var ax=function(R,a0,d){var S=0,i=0,e=0,E=1;this[0]=R;this.id=an._oid++;this.node=R;R.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=a0;this.paper=d;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null;};ax[aY].rotate=function(e,d,i){if(this.removed){return this;}if(e==null){if(this._.rt.cx){return[this._.rt.deg,this._.rt.cx,this._.rt.cy][az](am);}return this._.rt.deg;}e=(e+at)[z](a);if(e[m]-1){d=W(e[1]);i=W(e[2]);}e=W(e[0]);if(d!=null){this._.rt.deg=e;}else{this._.rt.deg+=e;}i==null&&(d=null);this._.rt.cx=d;this._.rt.cy=i;this.setBox(this.attrs,d,i);this.Group.style.rotation=this._.rt.deg;return this;};ax[aY].setBox=function(bb,e,d){if(this.removed){return this;}var a5=this.Group.style,R=(this.shape&&this.shape.style)||this.node.style;bb=bb||{};for(var a9 in bb){if(bb[Q](a9)){this.attrs[a9]=bb[a9];}}e=e||this._.rt.cx;d=d||this._.rt.cy;var a7=this.attrs,a1,a0,a2,ba;switch(this.type){case"circle":a1=a7.cx-a7.r;a0=a7.cy-a7.r;a2=ba=a7.r*2;break;case"ellipse":a1=a7.cx-a7.rx;a0=a7.cy-a7.ry;a2=a7.rx*2;ba=a7.ry*2;break;case"rect":case"image":a1=+a7.x;a0=+a7.y;a2=a7.width||0;ba=a7.height||0;break;case"text":this.textpath.v=["m",O(a7.x),", ",O(a7.y-2),"l",O(a7.x)+1,", ",O(a7.y-2)][az](at);a1=a7.x-O(this.W/2);a0=a7.y-this.H/2;a2=this.W;ba=this.H;break;case"path":if(!this.attrs.path){a1=0;a0=0;a2=this.paper.width;ba=this.paper.height;}else{var a8=U(this.attrs.path);a1=a8.x;a0=a8.y;a2=a8.width;ba=a8.height;}break;default:a1=0;a0=0;a2=this.paper.width;ba=this.paper.height;break;}e=(e==null)?a1+a2/2:e;d=(d==null)?a0+ba/2:d;var E=e-this.paper.width/2,a4=d-this.paper.height/2;if(this.type=="path"||this.type=="text"){(a5.left!=E+"px")&&(a5.left=E+"px");(a5.top!=a4+"px")&&(a5.top=a4+"px");this.X=this.type=="text"?a1:-E;this.Y=this.type=="text"?a0:-a4;this.W=a2;this.H=ba;(R.left!=-E+"px")&&(R.left=-E+"px");(R.top!=-a4+"px")&&(R.top=-a4+"px");}else{(a5.left!=E+"px")&&(a5.left=E+"px");(a5.top!=a4+"px")&&(a5.top=a4+"px");this.X=a1;this.Y=a0;this.W=a2;this.H=ba;(a5.width!=this.paper.width+"px")&&(a5.width=this.paper.width+"px");(a5.height!=this.paper.height+"px")&&(a5.height=this.paper.height+"px");(R.left!=a1-E+"px")&&(R.left=a1-E+"px");(R.top!=a0-a4+"px")&&(R.top=a0-a4+"px");(R.width!=a2+"px")&&(R.width=a2+"px");(R.height!=ba+"px")&&(R.height=ba+"px");var S=(+bb.r||0)/aI(a2,ba);if(this.type=="rect"&&this.arcsize.toFixed(4)!=S.toFixed(4)&&(S||this.arcsize)){var a6=ah("roundrect"),bc={},a9=0,a3=this.events&&this.events[m];a6.arcsize=S;a6.raphael=this;this.Group[aL](a6);this.Group.removeChild(this.node);this[0]=this.node=a6;this.arcsize=S;for(var a9 in a7){bc[a9]=a7[a9];}delete bc.scale;this.attr(bc);if(this.events){for(;a9<a3;a9++){this.events[a9].unbind=ae(this.node,this.events[a9].name,this.events[a9].f,this);}}}}};ax[aY].hide=function(){!this.removed&&(this.Group.style.display="none");return this;};ax[aY].show=function(){!this.removed&&(this.Group.style.display="block");return this;};ax[aY].getBBox=function(){if(this.removed){return this;}if(this.type=="path"){return U(this.attrs.path);}return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H};};ax[aY].remove=function(){if(this.removed){return;}ak(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var d in this){delete this[d];}this.removed=true;};ax[aY].attr=function(){if(this.removed){return this;}if(arguments[m]==0){var E={};for(var e in this.attrs){if(this.attrs[Q](e)){E[e]=this.attrs[e];}}this._.rt.deg&&(E.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(E.scale=this.scale());E.gradient&&E.fill=="none"&&(E.fill=E.gradient)&&delete E.gradient;return E;}if(arguments[m]==1&&an.is(arguments[0],"string")){if(arguments[0]=="translation"){return t.call(this);}if(arguments[0]=="rotation"){return this.rotate();}if(arguments[0]=="scale"){return this.scale();}if(arguments[0]=="fill"&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient;}return this.attrs[arguments[0]];}if(this.attrs&&arguments[m]==1&&an.is(arguments[0],"array")){var d={};for(var e=0,R=arguments[0][m];e<R;e++){d[arguments[0][e]]=this.attrs[arguments[0][e]];}return d;}var S;if(arguments[m]==2){S={};S[arguments[0]]=arguments[1];}arguments[m]==1&&an.is(arguments[0],"object")&&(S=arguments[0]);if(S){if(S.text&&this.type=="text"){this.node.string=S.text;}aa(this,S);if(S.gradient&&(({circle:1,ellipse:1})[Q](this.type)||(S.gradient+at).charAt()!="r")){b(this,S.gradient);}(this.type!="path"||this._.rt.deg)&&this.setBox(this.attrs);}return this;};ax[aY].toFront=function(){!this.removed&&this.Group.parentNode[aL](this.Group);this.paper.top!=this&&Y(this,this.paper);return this;};ax[aY].toBack=function(){if(this.removed){return this;}if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);k(this,this.paper);}return this;};ax[aY].insertAfter=function(d){if(this.removed){return this;}if(d.Group.nextSibling){d.Group.parentNode.insertBefore(this.Group,d.Group.nextSibling);}else{d.Group.parentNode[aL](this.Group);}A(this,d,this.paper);return this;};ax[aY].insertBefore=function(d){if(this.removed){return this;}d.Group.parentNode.insertBefore(this.Group,d.Group);aq(this,d,this.paper);return this;};var P=function(e,d,a1,S){var R=ah("group"),a0=ah("oval"),i=a0.style;R.style.cssText="position:absolute;left:0;top:0;width:"+e.width+"px;height:"+e.height+"px";R.coordsize=e.coordsize;R.coordorigin=e.coordorigin;R[aL](a0);var E=new ax(a0,R,e);E.type="circle";aa(E,{stroke:"#000",fill:"none"});E.attrs.cx=d;E.attrs.cy=a1;E.attrs.r=S;E.setBox({x:d-S,y:a1-S,width:S*2,height:S*2});e.canvas[aL](R);return E;},aF=function(e,a1,a0,a2,E,d){var R=ah("group"),i=ah("roundrect"),a3=(+d||0)/(aI(a2,E));R.style.cssText="position:absolute;left:0;top:0;width:"+e.width+"px;height:"+e.height+"px";R.coordsize=e.coordsize;R.coordorigin=e.coordorigin;R[aL](i);i.arcsize=a3;var S=new ax(i,R,e);S.type="rect";aa(S,{stroke:"#000"});S.arcsize=a3;S.setBox({x:a1,y:a0,width:a2,height:E,r:d});e.canvas[aL](R);return S;},ai=function(d,a2,a1,i,e){var R=ah("group"),E=ah("oval"),a0=E.style;R.style.cssText="position:absolute;left:0;top:0;width:"+d.width+"px;height:"+d.height+"px";R.coordsize=d.coordsize;R.coordorigin=d.coordorigin;R[aL](E);var S=new ax(E,R,d);S.type="ellipse";aa(S,{stroke:"#000"});S.attrs.cx=a2;S.attrs.cy=a1;S.attrs.rx=i;S.attrs.ry=e;S.setBox({x:a2-i,y:a1-e,width:i*2,height:e*2});d.canvas[aL](R);return S;},o=function(e,d,a2,a1,a3,E){var R=ah("group"),i=ah("image"),a0=i.style;R.style.cssText="position:absolute;left:0;top:0;width:"+e.width+"px;height:"+e.height+"px";R.coordsize=e.coordsize;R.coordorigin=e.coordorigin;i.src=d;R[aL](i);var S=new ax(i,R,e);S.type="image";S.attrs.src=d;S.attrs.x=a2;S.attrs.y=a1;S.attrs.w=a3;S.attrs.h=E;S.setBox({x:a2,y:a1,width:a3,height:E});e.canvas[aL](R);return S;},X=function(e,a2,a1,a3){var R=ah("group"),E=ah("shape"),a0=E.style,a4=ah("path"),d=a4.style,i=ah("textpath");R.style.cssText="position:absolute;left:0;top:0;width:"+e.width+"px;height:"+e.height+"px";R.coordsize=e.coordsize;R.coordorigin=e.coordorigin;a4.v=an.format("m{0},{1}l{2},{1}",O(a2),O(a1),O(a2)+1);a4.textpathok=true;a0.width=e.width;a0.height=e.height;i.string=a3+at;i.on=true;E[aL](i);E[aL](a4);R[aL](E);var S=new ax(i,R,e);S.shape=E;S.textpath=a4;S.type="text";S.attrs.text=a3;S.attrs.x=a2;S.attrs.y=a1;S.attrs.w=1;S.attrs.h=1;aa(S,{font:j.font,stroke:"none",fill:"#000"});S.setBox();e.canvas[aL](R);return S;},aV=function(i,d){var e=this.canvas.style;i==+i&&(i+="px");d==+d&&(d+="px");e.width=i;e.height=d;e.clip="rect(0 "+i+" "+d+" 0)";return this;},ah;L.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!L.namespaces.rvml&&L.namespaces.add("rvml","urn:schemas-microsoft-com:vml");ah=function(d){return L.createElement("<rvml:"+d+' class="rvml">');};}catch(af){ah=function(d){return L.createElement("<"+d+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');};}var w=function(){var i=ao[aW](null,arguments),d=i.container,a2=i.height,a3,e=i.width,a1=i.x,a0=i.y;if(!d){throw new Error("VML container not found.");}var R=new aT,S=R.canvas=L.createElement("div"),E=S.style;e=e||512;a2=a2||342;e==+e&&(e+="px");a2==+a2&&(a2+="px");R.width=1000;R.height=1000;R.coordsize="1000 1000";R.coordorigin="0 0";R.span=L.createElement("span");R.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";S[aL](R.span);E.cssText=an.format("width:{0};height:{1};position:absolute;clip:rect(0 {0} {1} 0);overflow:hidden",e,a2);if(d==1){L.body[aL](S);E.left=a1+"px";E.top=a0+"px";}else{d.style.width=e;d.style.height=a2;if(d.firstChild){d.insertBefore(S,d.firstChild);}else{d[aL](S);}}aG.call(R,R,an.fn);return R;};aT[aY].clear=function(){this.canvas.innerHTML=at;this.span=L.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[aL](this.span);this.bottom=this.top=null;};aT[aY].remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var d in this){this[d]=s(d);}};}if((/^Apple|^Google/).test(navigator.vendor)&&!(navigator.userAgent.indexOf("Version/4.0")+1)){aT[aY].safari=function(){var d=this.rect(-99,-99,this.width+99,this.height+99);setTimeout(function(){d.remove();});};}else{aT[aY].safari=function(){};}var ae=(function(){if(L.addEventListener){return function(R,i,e,d){var E=function(S){return e.call(d,S);};R.addEventListener(i,E,false);return function(){R.removeEventListener(i,E,false);return true;};};}else{if(L.attachEvent){return function(S,E,i,e){var R=function(a0){return i.call(e,a0||au.event);};S.attachEvent("on"+E,R);var d=function(){S.detachEvent("on"+E,R);return true;};return d;};}}})();for(var ac=F[m];ac--;){(function(d){ax[aY][d]=function(e){if(an.is(e,"function")){this.events=this.events||[];this.events.push({name:d,f:e,unbind:ae(this.shape||this.node,d,e,this)});}return this;};ax[aY]["un"+d]=function(E){var i=this.events,e=i[m];while(e--){if(i[e].name==d&&i[e].f==E){i[e].unbind();i.splice(e,1);!i.length&&delete this.events;return this;}}return this;};})(F[ac]);}ax[aY].hover=function(e,d){return this.mouseover(e).mouseout(d);};ax[aY].unhover=function(e,d){return this.unmouseover(e).unmouseout(d);};aT[aY].circle=function(d,i,e){return P(this,d||0,i||0,e||0);};aT[aY].rect=function(d,R,e,i,E){return aF(this,d||0,R||0,e||0,i||0,E||0);};aT[aY].ellipse=function(d,E,i,e){return ai(this,d||0,E||0,i||0,e||0);};aT[aY].path=function(d){d&&!an.is(d,"string")&&!an.is(d[0],"array")&&(d+=at);return q(an.format[aW](an,arguments),this);};aT[aY].image=function(E,d,R,e,i){return o(this,E||"about:blank",d||0,R||0,e||0,i||0);};aT[aY].text=function(d,i,e){return X(this,d||0,i||0,e||at);};aT[aY].set=function(d){arguments[m]>1&&(d=Array[aY].splice.call(arguments,0,arguments[m]));return new T(d);};aT[aY].setSize=aV;aT[aY].top=aT[aY].bottom=null;aT[aY].raphael=an;function u(){return this.x+am+this.y;}ax[aY].scale=function(a6,a5,E,e){if(a6==null&&a5==null){return{x:this._.sx,y:this._.sy,toString:u};}a5=a5||a6;!+a5&&(a5=a6);var ba,a8,a9,a7,bm=this.attrs;if(a6!=0){var a4=this.getBBox(),a1=a4.x+a4.width/2,R=a4.y+a4.height/2,bl=a6/this._.sx,bk=a5/this._.sy;E=(+E||E==0)?E:a1;e=(+e||e==0)?e:R;var a3=~~(a6/ab.abs(a6)),a0=~~(a5/ab.abs(a5)),be=this.node.style,bo=E+(a1-E)*bl,bn=e+(R-e)*bk;switch(this.type){case"rect":case"image":var a2=bm.width*a3*bl,bd=bm.height*a0*bk;this.attr({height:bd,r:bm.r*aI(a3*bl,a0*bk),width:a2,x:bo-a2/2,y:bn-bd/2});break;case"circle":case"ellipse":this.attr({rx:bm.rx*a3*bl,ry:bm.ry*a0*bk,r:bm.r*aI(a3*bl,a0*bk),cx:bo,cy:bn});break;case"path":var bg=ad(bm.path),bh=true;for(var bj=0,bc=bg[m];bj<bc;bj++){var bf=bg[bj],bi,S=aN.call(bf[0]);if(S=="M"&&bh){continue;}else{bh=false;}if(S=="A"){bf[bg[bj][m]-2]*=bl;bf[bg[bj][m]-1]*=bk;bf[1]*=a3*bl;bf[2]*=a0*bk;bf[5]=+(a3+a0?!!+bf[5]:!+bf[5]);}else{if(S=="H"){for(bi=1,jj=bf[m];bi<jj;bi++){bf[bi]*=bl;}}else{if(S=="V"){for(bi=1,jj=bf[m];bi<jj;bi++){bf[bi]*=bk;}}else{for(bi=1,jj=bf[m];bi<jj;bi++){bf[bi]*=(bi%2)?bl:bk;}}}}}var d=U(bg),ba=bo-d.x-d.width/2,a8=bn-d.y-d.height/2;bg[0][1]+=ba;bg[0][2]+=a8;this.attr({path:bg});break;}if(this.type in {text:1,image:1}&&(a3!=1||a0!=1)){if(this.transformations){this.transformations[2]="scale("[aS](a3,",",a0,")");this.node[v]("transform",this.transformations[az](am));ba=(a3==-1)?-bm.x-(a2||0):bm.x;a8=(a0==-1)?-bm.y-(bd||0):bm.y;this.attr({x:ba,y:a8});bm.fx=a3-1;bm.fy=a0-1;}else{this.node.filterMatrix=" progid:DXImageTransform.Microsoft.Matrix(M11="[aS](a3,", M12=0, M21=0, M22=",a0,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");be.filter=(this.node.filterMatrix||at)+(this.node.filterOpacity||at);}}else{if(this.transformations){this.transformations[2]=at;this.node[v]("transform",this.transformations[az](am));bm.fx=0;bm.fy=0;}else{this.node.filterMatrix=at;be.filter=(this.node.filterMatrix||at)+(this.node.filterOpacity||at);}}bm.scale=[a6,a5,E,e][az](am);this._.sx=a6;this._.sy=a5;}return this;};ax[aY].clone=function(){var d=this.attr();delete d.scale;delete d.translation;return this.paper[this.type]().attr(d);};var aB=function(d,e){return function(a9,S,a0){a9=H(a9);var a5,a4,E,a1,R="",a8={},a6,a3=0;for(var a2=0,a7=a9.length;a2<a7;a2++){E=a9[a2];if(E[0]=="M"){a5=+E[1];a4=+E[2];}else{a1=n(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6]);if(a3+a1>S){if(e&&!a8.start){a6=an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],(S-a3)/a1);R+=["C",a6.start.x,a6.start.y,a6.m.x,a6.m.y,a6.x,a6.y];if(a0){return R;}a8.start=R;R=["M",a6.x,a6.y,"C",a6.n.x,a6.n.y,a6.end.x,a6.end.y,E[5],E[6]][az]();a3+=a1;a5=+E[5];a4=+E[6];continue;}if(!d&&!e){a6=an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],(S-a3)/a1);return{x:a6.x,y:a6.y,alpha:a6.alpha};}}a3+=a1;a5=+E[5];a4=+E[6];}R+=E;}a8.end=R;a6=d?a3:e?a8:an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],1);a6.alpha&&(a6={x:a6.x,y:a6.y,alpha:a6.alpha});return a6;};},n=aj(function(E,d,a0,S,a6,a5,a4,a3){var R={x:0,y:0},a2=0;for(var a1=0;a1<1.01;a1+=0.01){var e=M(E,d,a0,S,a6,a5,a4,a3,a1);a1&&(a2+=ab.sqrt(aM(R.x-e.x,2)+aM(R.y-e.y,2)));R=e;}return a2;});var ap=aB(1),C=aB(),J=aB(0,1);ax[aY].getTotalLength=function(){if(this.type!="path"){return;}return ap(this.attrs.path);};ax[aY].getPointAtLength=function(d){if(this.type!="path"){return;}return C(this.attrs.path,d);};ax[aY].getSubpath=function(i,e){if(this.type!="path"){return;}var d=J(this.attrs.path,e,1);return i?J(d,i).end:d;};an.easing_formulas={linear:function(d){return d;},"<":function(d){return aM(d,3);},">":function(d){return aM(d-1,3)+1;},"<>":function(d){d=d*2;if(d<1){return aM(d,3)/2;}d-=2;return(aM(d,3)+2)/2;},backIn:function(e){var d=1.70158;return e*e*((d+1)*e-d);},backOut:function(e){e=e-1;var d=1.70158;return e*e*((d+1)*e+d)+1;},elastic:function(i){if(i==0||i==1){return i;}var e=0.3,d=e/4;return aM(2,-10*i)*ab.sin((i-d)*(2*ab.PI)/e)+1;},bounce:function(E){var e=7.5625,i=2.75,d;if(E<(1/i)){d=e*E*E;}else{if(E<(2/i)){E-=(1.5/i);d=e*E*E+0.75;}else{if(E<(2.5/i)){E-=(2.25/i);d=e*E*E+0.9375;}else{E-=(2.625/i);d=e*E*E+0.984375;}}}return d;}};var I={length:0},aR=function(){var a2=+new Date;for(var be in I){if(be!="length"&&I[Q](be)){var bj=I[be];if(bj.stop){delete I[be];I[m]--;continue;}var a0=a2-bj.start,bb=bj.ms,ba=bj.easing,bf=bj.from,a7=bj.diff,E=bj.to,a6=bj.t,a9=bj.prev||0,a1=bj.el,R=bj.callback,a8={},d;if(a0<bb){var S=an.easing_formulas[ba]?an.easing_formulas[ba](a0/bb):a0/bb;for(var bc in bf){if(bf[Q](bc)){switch(Z[bc]){case"along":d=S*bb*a7[bc];E.back&&(d=E.len-d);var bd=C(E[bc],d);a1.translate(a7.sx-a7.x||0,a7.sy-a7.y||0);a7.x=bd.x;a7.y=bd.y;a1.translate(bd.x-a7.sx,bd.y-a7.sy);E.rot&&a1.rotate(a7.r+bd.alpha,bd.x,bd.y);break;case"number":d=+bf[bc]+S*bb*a7[bc];break;case"colour":d="rgb("+[B(O(bf[bc].r+S*bb*a7[bc].r)),B(O(bf[bc].g+S*bb*a7[bc].g)),B(O(bf[bc].b+S*bb*a7[bc].b))][az](",")+")";break;case"path":d=[];for(var bh=0,a5=bf[bc][m];bh<a5;bh++){d[bh]=[bf[bc][bh][0]];for(var bg=1,bi=bf[bc][bh][m];bg<bi;bg++){d[bh][bg]=+bf[bc][bh][bg]+S*bb*a7[bc][bh][bg];}d[bh]=d[bh][az](am);}d=d[az](am);break;case"csv":switch(bc){case"translation":var a4=a7[bc][0]*(a0-a9),a3=a7[bc][1]*(a0-a9);a6.x+=a4;a6.y+=a3;d=a4+am+a3;break;case"rotation":d=+bf[bc][0]+S*bb*a7[bc][0];bf[bc][1]&&(d+=","+bf[bc][1]+","+bf[bc][2]);break;case"scale":d=[+bf[bc][0]+S*bb*a7[bc][0],+bf[bc][1]+S*bb*a7[bc][1],(2 in E[bc]?E[bc][2]:at),(3 in E[bc]?E[bc][3]:at)][az](am);break;case"clip-rect":d=[];var bh=4;while(bh--){d[bh]=+bf[bc][bh]+S*bb*a7[bc][bh];}break;}break;}a8[bc]=d;}}a1.attr(a8);a1._run&&a1._run.call(a1);}else{if(E.along){var bd=C(E.along,E.len*!E.back);a1.translate(a7.sx-(a7.x||0)+bd.x-a7.sx,a7.sy-(a7.y||0)+bd.y-a7.sy);E.rot&&a1.rotate(a7.r+bd.alpha,bd.x,bd.y);}(a6.x||a6.y)&&a1.translate(-a6.x,-a6.y);E.scale&&(E.scale=E.scale+at);a1.attr(E);delete I[be];I[m]--;a1.in_animation=null;an.is(R,"function")&&R.call(a1);}bj.prev=a0;}}an.svg&&a1&&a1.paper.safari();I[m]&&setTimeout(aR);},B=function(d){return d>255?255:(d<0?0:d);},t=function(d,i){if(d==null){return{x:this._.tx,y:this._.ty,toString:u};}this._.tx+=+d;this._.ty+=+i;switch(this.type){case"circle":case"ellipse":this.attr({cx:+d+this.attrs.cx,cy:+i+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+d+this.attrs.x,y:+i+this.attrs.y});break;case"path":var e=ad(this.attrs.path);e[0][1]+=+d;e[0][2]+=+i;this.attr({path:e});break;}return this;};ax[aY].animateWith=function(e,i,d,R,E){I[e.id]&&(i.start=I[e.id].start);return this.animate(i,d,R,E);};ax[aY].animateAlong=ay();ax[aY].animateAlongBack=ay(1);function ay(d){return function(E,i,e,S){var R={back:d};an.is(e,"function")?(S=e):(R.rot=e);E&&E.constructor==ax&&(E=E.attrs.path);E&&(R.along=E);return this.animate(R,i,S);};}ax[aY].onAnimation=function(d){this._run=d||0;return this;};ax[aY].animate=function(be,a5,a4,E){if(an.is(a4,"function")||!a4){E=a4||null;}var a9={},e={},a2={};for(var a6 in be){if(be[Q](a6)){if(Z[Q](a6)){a9[a6]=this.attr(a6);(a9[a6]==null)&&(a9[a6]=j[a6]);e[a6]=be[a6];switch(Z[a6]){case"along":var bc=ap(be[a6]),a7=C(be[a6],bc*!!be.back),R=this.getBBox();a2[a6]=bc/a5;a2.tx=R.x;a2.ty=R.y;a2.sx=a7.x;a2.sy=a7.y;e.rot=be.rot;e.back=be.back;e.len=bc;be.rot&&(a2.r=W(this.rotate())||0);break;case"number":a2[a6]=(e[a6]-a9[a6])/a5;break;case"colour":a9[a6]=an.getRGB(a9[a6]);var a8=an.getRGB(e[a6]);a2[a6]={r:(a8.r-a9[a6].r)/a5,g:(a8.g-a9[a6].g)/a5,b:(a8.b-a9[a6].b)/a5};break;case"path":var S=H(a9[a6],e[a6]);a9[a6]=S[0];var a3=S[1];a2[a6]=[];for(var bb=0,a1=a9[a6][m];bb<a1;bb++){a2[a6][bb]=[0];for(var ba=1,bd=a9[a6][bb][m];ba<bd;ba++){a2[a6][bb][ba]=(a3[bb][ba]-a9[a6][bb][ba])/a5;}}break;case"csv":var d=(be[a6]+at)[z](a),a0=(a9[a6]+at)[z](a);switch(a6){case"translation":a9[a6]=[0,0];a2[a6]=[d[0]/a5,d[1]/a5];break;case"rotation":a9[a6]=(a0[1]==d[1]&&a0[2]==d[2])?a0:[0,d[1],d[2]];a2[a6]=[(d[0]-a9[a6][0])/a5,0,0];break;case"scale":be[a6]=d;a9[a6]=(a9[a6]+at)[z](a);a2[a6]=[(d[0]-a9[a6][0])/a5,(d[1]-a9[a6][1])/a5,0,0];break;case"clip-rect":a9[a6]=(a9[a6]+at)[z](a);a2[a6]=[];var bb=4;while(bb--){a2[a6][bb]=(d[bb]-a9[a6][bb])/a5;}break;}e[a6]=d;}}}}this.stop();this.in_animation=1;I[this.id]={start:be.start||+new Date,ms:a5,easing:a4,from:a9,diff:a2,to:e,el:this,callback:E,t:{x:0,y:0}};++I[m]==1&&aR();return this;};ax[aY].stop=function(){I[this.id]&&I[m]--;delete I[this.id];return this;};ax[aY].translate=function(d,e){return this.attr({translation:d+" "+e});};ax[aY][aA]=function(){return"Rapha\xebl\u2019s object";};an.ae=I;var T=function(d){this.items=[];this[m]=0;if(d){for(var e=0,E=d[m];e<E;e++){if(d[e]&&(d[e].constructor==ax||d[e].constructor==T)){this[this.items[m]]=this.items[this.items[m]]=d[e];this[m]++;}}}};T[aY][f]=function(){var R,d;for(var e=0,E=arguments[m];e<E;e++){R=arguments[e];if(R&&(R.constructor==ax||R.constructor==T)){d=this.items[m];this[d]=this.items[d]=R;this[m]++;}}return this;};T[aY].pop=function(){delete this[this[m]--];return this.items.pop();};for(var y in ax[aY]){if(ax[aY][Q](y)){T[aY][y]=(function(d){return function(){for(var e=0,E=this.items[m];e<E;e++){this.items[e][d][aW](this.items[e],arguments);}return this;};})(y);}}T[aY].attr=function(e,a0){if(e&&an.is(e,"array")&&an.is(e[0],"object")){for(var d=0,S=e[m];d<S;d++){this.items[d].attr(e[d]);}}else{for(var E=0,R=this.items[m];E<R;E++){this.items[E].attr[aW](this.items[E],arguments);}}return this;};T[aY].animate=function(S,e,a2,a1){(an.is(a2,"function")||!a2)&&(a1=a2||null);var d=this.items[m],E=d,a0=this,R;a1&&(R=function(){!--d&&a1.call(a0);});this.items[--E].animate(S,e,a2||R,R);while(E--){this.items[E].animateWith(this.items[d-1],S,e,a2||R,R);}return this;};T[aY].insertAfter=function(e){var d=this.items[m];while(d--){this.items[d].insertAfter(e);}return this;};T[aY].getBBox=function(){var d=[],a0=[],e=[],R=[];for(var E=this.items[m];E--;){var S=this.items[E].getBBox();d[f](S.x);a0[f](S.y);e[f](S.x+S.width);R[f](S.y+S.height);}d=aI[aW](0,d);a0=aI[aW](0,a0);return{x:d,y:a0,width:g[aW](0,e)-d,height:g[aW](0,R)-a0};};an.registerFont=function(e){if(!e.face){return e;}this.fonts=this.fonts||{};var E={w:e.w,face:{},glyphs:{}},i=e.face["font-family"];for(var a0 in e.face){if(e.face[Q](a0)){E.face[a0]=e.face[a0];}}if(this.fonts[i]){this.fonts[i][f](E);}else{this.fonts[i]=[E];}if(!e.svg){E.face["units-per-em"]=G(e.face["units-per-em"],10);for(var R in e.glyphs){if(e.glyphs[Q](R)){var S=e.glyphs[R];E.glyphs[R]={w:S.w,k:{},d:S.d&&"M"+S.d[aP](/[mlcxtrv]/g,function(a1){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a1]||"M";})+"z"};if(S.k){for(var d in S.k){if(S[Q](d)){E.glyphs[R].k[d]=S.k[d];}}}}}}return e;};aT[aY].getFont=function(a2,a3,e,R){R=R||"normal";e=e||"normal";a3=+a3||{normal:400,bold:700,lighter:300,bolder:800}[a3]||400;var S=an.fonts[a2];if(!S){var E=new RegExp("(^|\\s)"+a2[aP](/[^\w\d\s+!~.:_-]/g,at)+"(\\s|$)","i");for(var d in an.fonts){if(an.fonts[Q](d)){if(E.test(d)){S=an.fonts[d];break;}}}}var a0;if(S){for(var a1=0,a4=S[m];a1<a4;a1++){a0=S[a1];if(a0.face["font-weight"]==a3&&(a0.face["font-style"]==e||!a0.face["font-style"])&&a0.face["font-stretch"]==R){break;}}}return a0;};aT[aY].print=function(R,E,d,a1,a2,bb){bb=bb||"middle";var a7=this.set(),ba=(d+at)[z](at),a8=0,a4=at,bc;an.is(a1,"string")&&(a1=this.getFont(a1));if(a1){bc=(a2||16)/a1.face["units-per-em"];var e=a1.face.bbox.split(a),a0=+e[0],a3=+e[1]+(bb=="baseline"?e[3]-e[1]+(+a1.face.descent):(e[3]-e[1])/2);for(var a6=0,S=ba[m];a6<S;a6++){var a5=a6&&a1.glyphs[ba[a6-1]]||{},a9=a1.glyphs[ba[a6]];a8+=a6?(a5.w||a1.w)+(a5.k&&a5.k[ba[a6]]||0):0;a9&&a9.d&&a7[f](this.path(a9.d).attr({fill:"#000",stroke:"none",translation:[a8,0]}));}a7.scale(bc,bc,a0,a3).translate(R-a0,E-a3);}return a7;};an.format=function(i){var e=an.is(arguments[1],"array")?[0][aS](arguments[1]):arguments,d=/\{(\d+)\}/g;i&&an.is(i,"string")&&e[m]-1&&(i=i[aP](d,function(R,E){return e[++E]==null?at:e[E];}));return i||at;};an.ninja=function(){var i=au.Raphael,d;if(l.was){au.Raphael=l.is;}else{try{delete au.Raphael;}catch(E){au.Raphael=d;}}return i;};an.el=ax[aY];return an;})();

// script.aculo.us slider.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009

// Copyright (c) 2005-2009 Marty Haught, Thomas Fuchs
//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/

if (!Control) var Control = { };

// options:
//  axis: 'vertical', or 'horizontal' (default)
//
// callbacks:
//  onChange(value)
//  onSlide(value)
Control.Slider = Class.create({
  initialize: function(handle, track, options) {
    var slider = this;

    if (Object.isArray(handle)) {
      this.handles = handle.collect( function(e) { return $(e) });
    } else {
      this.handles = [$(handle)];
    }

    this.track   = $(track);
    this.options = options || { };

    this.axis      = this.options.axis || 'horizontal';
    this.increment = this.options.increment || 1;
    this.step      = parseInt(this.options.step || '1');
    this.range     = this.options.range || $R(0,1);

    this.value     = 0; // assure backwards compat
    this.values    = this.handles.map( function() { return 0 });
    this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
    this.options.startSpan = $(this.options.startSpan || null);
    this.options.endSpan   = $(this.options.endSpan || null);

    this.restricted = this.options.restricted || false;

    this.maximum   = this.options.maximum || this.range.end;
    this.minimum   = this.options.minimum || this.range.start;

    // Will be used to align the handle onto the track, if necessary
    this.alignX = parseInt(this.options.alignX || '0');
    this.alignY = parseInt(this.options.alignY || '0');

    this.trackLength = this.maximumOffset() - this.minimumOffset();

    this.handleLength = this.isVertical() ?
      (this.handles[0].offsetHeight != 0 ?
        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
        this.handles[0].style.width.replace(/px$/,""));

    this.active   = false;
    this.dragging = false;
    this.disabled = false;

    if (this.options.disabled) this.setDisabled();

    // Allowed values array
    this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
    if (this.allowedValues) {
      this.minimum = this.allowedValues.min();
      this.maximum = this.allowedValues.max();
    }

    this.eventMouseDown = this.startDrag.bindAsEventListener(this);
    this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
    this.eventMouseMove = this.update.bindAsEventListener(this);

    // Initialize handles in reverse (make sure first handle is active)
    this.handles.each( function(h,i) {
      i = slider.handles.length-1-i;
      slider.setValue(parseFloat(
        (Object.isArray(slider.options.sliderValue) ?
          slider.options.sliderValue[i] : slider.options.sliderValue) ||
         slider.range.start), i);
      h.makePositioned().observe("mousedown", slider.eventMouseDown);
    });

    this.track.observe("mousedown", this.eventMouseDown);
    document.observe("mouseup", this.eventMouseUp);
    document.observe("mousemove", this.eventMouseMove);

    this.initialized = true;
  },
  dispose: function() {
    var slider = this;
    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
    Event.stopObserving(document, "mouseup", this.eventMouseUp);
    Event.stopObserving(document, "mousemove", this.eventMouseMove);
    this.handles.each( function(h) {
      Event.stopObserving(h, "mousedown", slider.eventMouseDown);
    });
  },
  setDisabled: function(){
    this.disabled = true;
  },
  setEnabled: function(){
    this.disabled = false;
  },
  getNearestValue: function(value){
    if (this.allowedValues){
      if (value >= this.allowedValues.max()) return(this.allowedValues.max());
      if (value <= this.allowedValues.min()) return(this.allowedValues.min());

      var offset = Math.abs(this.allowedValues[0] - value);
      var newValue = this.allowedValues[0];
      this.allowedValues.each( function(v) {
        var currentOffset = Math.abs(v - value);
        if (currentOffset <= offset){
          newValue = v;
          offset = currentOffset;
        }
      });
      return newValue;
    }
    if (value > this.range.end) return this.range.end;
    if (value < this.range.start) return this.range.start;
    return value;
  },
  setValue: function(sliderValue, handleIdx){
    if (!this.active) {
      this.activeHandleIdx = handleIdx || 0;
      this.activeHandle    = this.handles[this.activeHandleIdx];
      this.updateStyles();
    }
    handleIdx = handleIdx || this.activeHandleIdx || 0;
    if (this.initialized && this.restricted) {
      if ((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
        sliderValue = this.values[handleIdx-1];
      if ((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
        sliderValue = this.values[handleIdx+1];
    }
    sliderValue = this.getNearestValue(sliderValue);
    this.values[handleIdx] = sliderValue;
    this.value = this.values[0]; // assure backwards compat

    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
      this.translateToPx(sliderValue);

    this.drawSpans();
    if (!this.dragging || !this.event) this.updateFinished();
  },
  setValueBy: function(delta, handleIdx) {
    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
      handleIdx || this.activeHandleIdx || 0);
  },
  translateToPx: function(value) {
    return Math.round(
      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
      (value - this.range.start)) + "px";
  },
  translateToValue: function(offset) {
    return ((offset/(this.trackLength-this.handleLength) *
      (this.range.end-this.range.start)) + this.range.start);
  },
  getRange: function(range) {
    var v = this.values.sortBy(Prototype.K);
    range = range || 0;
    return $R(v[range],v[range+1]);
  },
  minimumOffset: function(){
    return(this.isVertical() ? this.alignY : this.alignX);
  },
  maximumOffset: function(){
    return(this.isVertical() ?
      (this.track.offsetHeight != 0 ? this.track.offsetHeight :
        this.track.style.height.replace(/px$/,"")) - this.alignY :
      (this.track.offsetWidth != 0 ? this.track.offsetWidth :
        this.track.style.width.replace(/px$/,"")) - this.alignX);
  },
  isVertical:  function(){
    return (this.axis == 'vertical');
  },
  drawSpans: function() {
    var slider = this;
    if (this.spans)
      $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
    if (this.options.startSpan)
      this.setSpan(this.options.startSpan,
        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
    if (this.options.endSpan)
      this.setSpan(this.options.endSpan,
        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
  },
  setSpan: function(span, range) {
    if (this.isVertical()) {
      span.style.top = this.translateToPx(range.start);
      span.style.height = this.translateToPx(range.end - range.start + this.range.start);
    } else {
      span.style.left = this.translateToPx(range.start);
      span.style.width = this.translateToPx(range.end - range.start + this.range.start);
    }
  },
  updateStyles: function() {
    this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
    Element.addClassName(this.activeHandle, 'selected');
  },
  startDrag: function(event) {
    if (Event.isLeftClick(event)) {
      if (!this.disabled){
        this.active = true;

        var handle = Event.element(event);
        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
        var track = handle;
        if (track==this.track) {
          var offsets  = this.track.cumulativeOffset();
          this.event = event;
          this.setValue(this.translateToValue(
           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
          ));
          var offsets  = this.activeHandle.cumulativeOffset();
          this.offsetX = (pointer[0] - offsets[0]);
          this.offsetY = (pointer[1] - offsets[1]);
        } else {
          // find the handle (prevents issues with Safari)
          while((this.handles.indexOf(handle) == -1) && handle.parentNode)
            handle = handle.parentNode;

          if (this.handles.indexOf(handle)!=-1) {
            this.activeHandle    = handle;
            this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
            this.updateStyles();

            var offsets  = this.activeHandle.cumulativeOffset();
            this.offsetX = (pointer[0] - offsets[0]);
            this.offsetY = (pointer[1] - offsets[1]);
          }
        }
      }
      Event.stop(event);
    }
  },
  update: function(event) {
   if (this.active) {
      if (!this.dragging) this.dragging = true;
      this.draw(event);
      if (Prototype.Browser.WebKit) window.scrollBy(0,0);
      Event.stop(event);
   }
  },
  draw: function(event) {
    var pointer = [Event.pointerX(event), Event.pointerY(event)];
    var offsets = this.track.cumulativeOffset();
    pointer[0] -= this.offsetX + offsets[0];
    pointer[1] -= this.offsetY + offsets[1];
    this.event = event;
    this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
    if (this.initialized && this.options.onSlide)
      this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
  },
  endDrag: function(event) {
    if (this.active && this.dragging) {
      this.finishDrag(event, true);
      Event.stop(event);
    }
    this.active = false;
    this.dragging = false;
  },
  finishDrag: function(event, success) {
    this.active = false;
    this.dragging = false;
    this.updateFinished();
  },
  updateFinished: function() {
    if (this.initialized && this.options.onChange)
      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
    this.event = null;
  }
});

// Copyright (c) 2005-2008 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//           (c) 2005-2008 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
//
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/

if(Object.isUndefined(Effect))
  throw("dragdrop.js requires including script.aculo.us' effects.js library");

var Droppables = {
  drops: [],

  remove: function(element) {
    this.drops = this.drops.reject(function(d) { return d.element==$(element) });
  },

  add: function(element) {
    element = $(element);
    var options = Object.extend({
      greedy:     true,
      hoverclass: null,
      tree:       false
    }, arguments[1] || { });

    // cache containers
    if(options.containment) {
      options._containers = [];
      var containment = options.containment;
      if(Object.isArray(containment)) {
        containment.each( function(c) { options._containers.push($(c)) });
      } else {
        options._containers.push($(containment));
      }
    }

    if(options.accept) options.accept = [options.accept].flatten();

    Element.makePositioned(element); // fix IE
    options.element = element;

    this.drops.push(options);
  },

  findDeepestChild: function(drops) {
    deepest = drops[0];

    for (i = 1; i < drops.length; ++i)
      if (Element.isParent(drops[i].element, deepest.element))
        deepest = drops[i];

    return deepest;
  },

  isContained: function(element, drop) {
    var containmentNode;
    if(drop.tree) {
      containmentNode = element.treeNode;
    } else {
      containmentNode = element.parentNode;
    }
    return drop._containers.detect(function(c) { return containmentNode == c });
  },

  isAffected: function(point, element, drop) {
    return (
      (drop.element!=element) &&
      ((!drop._containers) ||
        this.isContained(element, drop)) &&
      ((!drop.accept) ||
        (Element.classNames(element).detect(
          function(v) { return drop.accept.include(v) } ) )) &&
      Position.within(drop.element, point[0], point[1]) );
  },

  deactivate: function(drop) {
    if(drop.hoverclass)
      Element.removeClassName(drop.element, drop.hoverclass);
    this.last_active = null;
  },

  activate: function(drop) {
    if(drop.hoverclass)
      Element.addClassName(drop.element, drop.hoverclass);
    this.last_active = drop;
  },

  show: function(point, element) {
    if(!this.drops.length) return;
    var drop, affected = [];

    this.drops.each( function(drop) {
      if(Droppables.isAffected(point, element, drop))
        affected.push(drop);
    });

    if(affected.length>0)
      drop = Droppables.findDeepestChild(affected);

    if(this.last_active && this.last_active != drop) this.deactivate(this.last_active);
    if (drop) {
      Position.within(drop.element, point[0], point[1]);
      if(drop.onHover)
        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));

      if (drop != this.last_active) Droppables.activate(drop);
    }
  },

  fire: function(event, element) {
    if(!this.last_active) return;
    Position.prepare();

    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
      if (this.last_active.onDrop) {
        this.last_active.onDrop(element, this.last_active.element, event);
        return true;
      }
  },

  reset: function() {
    if(this.last_active)
      this.deactivate(this.last_active);
  }
};

var Draggables = {
  drags: [],
  observers: [],

  register: function(draggable) {
    if(this.drags.length == 0) {
      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
      this.eventKeypress  = this.keyPress.bindAsEventListener(this);

      Event.observe(document, "mouseup", this.eventMouseUp);
      Event.observe(document, "mousemove", this.eventMouseMove);
      Event.observe(document, "keypress", this.eventKeypress);
    }
    this.drags.push(draggable);
  },

  unregister: function(draggable) {
    this.drags = this.drags.reject(function(d) { return d==draggable });
    if(this.drags.length == 0) {
      Event.stopObserving(document, "mouseup", this.eventMouseUp);
      Event.stopObserving(document, "mousemove", this.eventMouseMove);
      Event.stopObserving(document, "keypress", this.eventKeypress);
    }
  },

  activate: function(draggable) {
    if(draggable.options.delay) {
      this._timeout = setTimeout(function() {
        Draggables._timeout = null;
        window.focus();
        Draggables.activeDraggable = draggable;
      }.bind(this), draggable.options.delay);
    } else {
      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
      this.activeDraggable = draggable;
    }
  },

  deactivate: function() {
    this.activeDraggable = null;
  },

  updateDrag: function(event) {
    if(!this.activeDraggable) return;
    var pointer = [Event.pointerX(event), Event.pointerY(event)];
    // Mozilla-based browsers fire successive mousemove events with
    // the same coordinates, prevent needless redrawing (moz bug?)
    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
    this._lastPointer = pointer;

    this.activeDraggable.updateDrag(event, pointer);
  },

  endDrag: function(event) {
    if(this._timeout) {
      clearTimeout(this._timeout);
      this._timeout = null;
    }
    if(!this.activeDraggable) return;
    this._lastPointer = null;
    this.activeDraggable.endDrag(event);
    this.activeDraggable = null;
  },

  keyPress: function(event) {
    if(this.activeDraggable)
      this.activeDraggable.keyPress(event);
  },

  addObserver: function(observer) {
    this.observers.push(observer);
    this._cacheObserverCallbacks();
  },

  removeObserver: function(element) {  // element instead of observer fixes mem leaks
    this.observers = this.observers.reject( function(o) { return o.element==element });
    this._cacheObserverCallbacks();
  },

  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
    if(this[eventName+'Count'] > 0)
      this.observers.each( function(o) {
        if(o[eventName]) o[eventName](eventName, draggable, event);
      });
    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
  },

  _cacheObserverCallbacks: function() {
    ['onStart','onEnd','onDrag'].each( function(eventName) {
      Draggables[eventName+'Count'] = Draggables.observers.select(
        function(o) { return o[eventName]; }
      ).length;
    });
  }
};

/*--------------------------------------------------------------------------*/

var Draggable = Class.create({
  initialize: function(element) {
    var defaults = {
      handle: false,
      reverteffect: function(element, top_offset, left_offset) {
        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
        new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
          queue: {scope:'_draggable', position:'end'}
        });
      },
      endeffect: function(element) {
        var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
          queue: {scope:'_draggable', position:'end'},
          afterFinish: function(){
            Draggable._dragging[element] = false
          }
        });
      },
      zindex: 1000,
      revert: false,
      quiet: false,
      scroll: false,
      scrollSensitivity: 20,
      scrollSpeed: 15,
      snap: false,  // false, or xy or [x,y] or function(x,y){ return [x,y] }
      delay: 0
    };

    if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
      Object.extend(defaults, {
        starteffect: function(element) {
          element._opacity = Element.getOpacity(element);
          Draggable._dragging[element] = true;
          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
        }
      });

    var options = Object.extend(defaults, arguments[1] || { });

    this.element = $(element);

    if(options.handle && Object.isString(options.handle))
      this.handle = this.element.down('.'+options.handle, 0);

    if(!this.handle) this.handle = $(options.handle);
    if(!this.handle) this.handle = this.element;

    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
      options.scroll = $(options.scroll);
      this._isScrollChild = Element.childOf(this.element, options.scroll);
    }

    Element.makePositioned(this.element); // fix IE

    this.options  = options;
    this.dragging = false;

    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
    Event.observe(this.handle, "mousedown", this.eventMouseDown);

    Draggables.register(this);
  },

  destroy: function() {
    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
    Draggables.unregister(this);
  },

  currentDelta: function() {
    return([
      parseInt(Element.getStyle(this.element,'left') || '0'),
      parseInt(Element.getStyle(this.element,'top') || '0')]);
  },

  initDrag: function(event) {
    if(!Object.isUndefined(Draggable._dragging[this.element]) &&
      Draggable._dragging[this.element]) return;
    if(Event.isLeftClick(event)) {
      // abort on form elements, fixes a Firefox issue
      var src = Event.element(event);
      if((tag_name = src.tagName.toUpperCase()) && (
        tag_name=='INPUT' ||
        tag_name=='SELECT' ||
        tag_name=='OPTION' ||
        tag_name=='BUTTON' ||
        tag_name=='TEXTAREA')) return;

      var pointer = [Event.pointerX(event), Event.pointerY(event)];
      var pos     = Position.cumulativeOffset(this.element);
      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });

      Draggables.activate(this);
      Event.stop(event);
    }
  },

  startDrag: function(event) {
    this.dragging = true;
    if(!this.delta)
      this.delta = this.currentDelta();

    if(this.options.zindex) {
      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
      this.element.style.zIndex = this.options.zindex;
    }

    if(this.options.ghosting) {
      this._clone = this.element.cloneNode(true);
      this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
      if (!this._originallyAbsolute)
        Position.absolutize(this.element);
      this.element.parentNode.insertBefore(this._clone, this.element);
    }

    if(this.options.scroll) {
      if (this.options.scroll == window) {
        var where = this._getWindowScroll(this.options.scroll);
        this.originalScrollLeft = where.left;
        this.originalScrollTop = where.top;
      } else {
        this.originalScrollLeft = this.options.scroll.scrollLeft;
        this.originalScrollTop = this.options.scroll.scrollTop;
      }
    }

    Draggables.notify('onStart', this, event);

    if(this.options.starteffect) this.options.starteffect(this.element);
  },

  updateDrag: function(event, pointer) {
    if(!this.dragging) this.startDrag(event);

    if(!this.options.quiet){
      Position.prepare();
      Droppables.show(pointer, this.element);
    }

    Draggables.notify('onDrag', this, event);

    this.draw(pointer);
    if(this.options.change) this.options.change(this);

    if(this.options.scroll) {
      this.stopScrolling();

      var p;
      if (this.options.scroll == window) {
        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
      } else {
        p = Position.page(this.options.scroll);
        p[0] += this.options.scroll.scrollLeft + Position.deltaX;
        p[1] += this.options.scroll.scrollTop + Position.deltaY;
        p.push(p[0]+this.options.scroll.offsetWidth);
        p.push(p[1]+this.options.scroll.offsetHeight);
      }
      var speed = [0,0];
      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
      this.startScrolling(speed);
    }

    // fix AppleWebKit rendering
    if(Prototype.Browser.WebKit) window.scrollBy(0,0);

    Event.stop(event);
  },

  finishDrag: function(event, success) {
    this.dragging = false;

    if(this.options.quiet){
      Position.prepare();
      var pointer = [Event.pointerX(event), Event.pointerY(event)];
      Droppables.show(pointer, this.element);
    }

    if(this.options.ghosting) {
      if (!this._originallyAbsolute)
        Position.relativize(this.element);
      delete this._originallyAbsolute;
      Element.remove(this._clone);
      this._clone = null;
    }

    var dropped = false;
    if(success) {
      dropped = Droppables.fire(event, this.element);
      if (!dropped) dropped = false;
    }
    if(dropped && this.options.onDropped) this.options.onDropped(this.element);
    Draggables.notify('onEnd', this, event);

    var revert = this.options.revert;
    if(revert && Object.isFunction(revert)) revert = revert(this.element);

    var d = this.currentDelta();
    if(revert && this.options.reverteffect) {
      if (dropped == 0 || revert != 'failure')
        this.options.reverteffect(this.element,
          d[1]-this.delta[1], d[0]-this.delta[0]);
    } else {
      this.delta = d;
    }

    if(this.options.zindex)
      this.element.style.zIndex = this.originalZ;

    if(this.options.endeffect)
      this.options.endeffect(this.element);

    Draggables.deactivate(this);
    Droppables.reset();
  },

  keyPress: function(event) {
    if(event.keyCode!=Event.KEY_ESC) return;
    this.finishDrag(event, false);
    Event.stop(event);
  },

  endDrag: function(event) {
    if(!this.dragging) return;
    this.stopScrolling();
    this.finishDrag(event, true);
    Event.stop(event);
  },

  draw: function(point) {
    var pos = Position.cumulativeOffset(this.element);
    if(this.options.ghosting) {
      var r   = Position.realOffset(this.element);
      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
    }

    var d = this.currentDelta();
    pos[0] -= d[0]; pos[1] -= d[1];

    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
    }

    var p = [0,1].map(function(i){
      return (point[i]-pos[i]-this.offset[i])
    }.bind(this));

    if(this.options.snap) {
      if(Object.isFunction(this.options.snap)) {
        p = this.options.snap(p[0],p[1],this);
      } else {
      if(Object.isArray(this.options.snap)) {
        p = p.map( function(v, i) {
          return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
      } else {
        p = p.map( function(v) {
          return (v/this.options.snap).round()*this.options.snap }.bind(this));
      }
    }}

    var style = this.element.style;
    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
      style.left = p[0] + "px";
    if((!this.options.constraint) || (this.options.constraint=='vertical'))
      style.top  = p[1] + "px";

    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
  },

  stopScrolling: function() {
    if(this.scrollInterval) {
      clearInterval(this.scrollInterval);
      this.scrollInterval = null;
      Draggables._lastScrollPointer = null;
    }
  },

  startScrolling: function(speed) {
    if(!(speed[0] || speed[1])) return;
    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
    this.lastScrolled = new Date();
    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
  },

  scroll: function() {
    var current = new Date();
    var delta = current - this.lastScrolled;
    this.lastScrolled = current;
    if(this.options.scroll == window) {
      with (this._getWindowScroll(this.options.scroll)) {
        if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
          var d = delta / 1000;
          this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
        }
      }
    } else {
      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
    }

    Position.prepare();
    Droppables.show(Draggables._lastPointer, this.element);
    Draggables.notify('onDrag', this);
    if (this._isScrollChild) {
      Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
      Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
      Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
      if (Draggables._lastScrollPointer[0] < 0)
        Draggables._lastScrollPointer[0] = 0;
      if (Draggables._lastScrollPointer[1] < 0)
        Draggables._lastScrollPointer[1] = 0;
      this.draw(Draggables._lastScrollPointer);
    }

    if(this.options.change) this.options.change(this);
  },

  _getWindowScroll: function(w) {
    var T, L, W, H;
    with (w.document) {
      if (w.document.documentElement && documentElement.scrollTop) {
        T = documentElement.scrollTop;
        L = documentElement.scrollLeft;
      } else if (w.document.body) {
        T = body.scrollTop;
        L = body.scrollLeft;
      }
      if (w.innerWidth) {
        W = w.innerWidth;
        H = w.innerHeight;
      } else if (w.document.documentElement && documentElement.clientWidth) {
        W = documentElement.clientWidth;
        H = documentElement.clientHeight;
      } else {
        W = body.offsetWidth;
        H = body.offsetHeight;
      }
    }
    return { top: T, left: L, width: W, height: H };
  }
});

Draggable._dragging = { };

/*--------------------------------------------------------------------------*/

var SortableObserver = Class.create({
  initialize: function(element, observer) {
    this.element   = $(element);
    this.observer  = observer;
    this.lastValue = Sortable.serialize(this.element);
  },

  onStart: function() {
    this.lastValue = Sortable.serialize(this.element);
  },

  onEnd: function() {
    Sortable.unmark();
    if(this.lastValue != Sortable.serialize(this.element))
      this.observer(this.element)
  }
});

var Sortable = {
  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,

  sortables: { },

  _findRootElement: function(element) {
    while (element.tagName.toUpperCase() != "BODY") {
      if(element.id && Sortable.sortables[element.id]) return element;
      element = element.parentNode;
    }
  },

  options: function(element) {
    element = Sortable._findRootElement($(element));
    if(!element) return;
    return Sortable.sortables[element.id];
  },

  destroy: function(element){
    element = $(element);
    var s = Sortable.sortables[element.id];

    if(s) {
      Draggables.removeObserver(s.element);
      s.droppables.each(function(d){ Droppables.remove(d) });
      s.draggables.invoke('destroy');

      delete Sortable.sortables[s.element.id];
    }
  },

  create: function(element) {
    element = $(element);
    var options = Object.extend({
      element:     element,
      tag:         'li',       // assumes li children, override with tag: 'tagname'
      dropOnEmpty: false,
      tree:        false,
      treeTag:     'ul',
      overlap:     'vertical', // one of 'vertical', 'horizontal'
      constraint:  'vertical', // one of 'vertical', 'horizontal', false
      containment: element,    // also takes array of elements (or id's); or false
      handle:      false,      // or a CSS class
      only:        false,
      delay:       0,
      hoverclass:  null,
      ghosting:    false,
      quiet:       false,
      scroll:      false,
      scrollSensitivity: 20,
      scrollSpeed: 15,
      format:      this.SERIALIZE_RULE,

      // these take arrays of elements or ids and can be
      // used for better initialization performance
      elements:    false,
      handles:     false,

      onChange:    Prototype.emptyFunction,
      onUpdate:    Prototype.emptyFunction
    }, arguments[1] || { });

    // clear any old sortable with same element
    this.destroy(element);

    // build options for the draggables
    var options_for_draggable = {
      revert:      true,
      quiet:       options.quiet,
      scroll:      options.scroll,
      scrollSpeed: options.scrollSpeed,
      scrollSensitivity: options.scrollSensitivity,
      delay:       options.delay,
      ghosting:    options.ghosting,
      constraint:  options.constraint,
      handle:      options.handle };

    if(options.starteffect)
      options_for_draggable.starteffect = options.starteffect;

    if(options.reverteffect)
      options_for_draggable.reverteffect = options.reverteffect;
    else
      if(options.ghosting) options_for_draggable.reverteffect = function(element) {
        element.style.top  = 0;
        element.style.left = 0;
      };

    if(options.endeffect)
      options_for_draggable.endeffect = options.endeffect;

    if(options.zindex)
      options_for_draggable.zindex = options.zindex;

    // build options for the droppables
    var options_for_droppable = {
      overlap:     options.overlap,
      containment: options.containment,
      tree:        options.tree,
      hoverclass:  options.hoverclass,
      onHover:     Sortable.onHover
    };

    var options_for_tree = {
      onHover:      Sortable.onEmptyHover,
      overlap:      options.overlap,
      containment:  options.containment,
      hoverclass:   options.hoverclass
    };

    // fix for gecko engine
    Element.cleanWhitespace(element);

    options.draggables = [];
    options.droppables = [];

    // drop on empty handling
    if(options.dropOnEmpty || options.tree) {
      Droppables.add(element, options_for_tree);
      options.droppables.push(element);
    }

    (options.elements || this.findElements(element, options) || []).each( function(e,i) {
      var handle = options.handles ? $(options.handles[i]) :
        (options.handle ? $(e).select('.' + options.handle)[0] : e);
      options.draggables.push(
        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
      Droppables.add(e, options_for_droppable);
      if(options.tree) e.treeNode = element;
      options.droppables.push(e);
    });

    if(options.tree) {
      (Sortable.findTreeElements(element, options) || []).each( function(e) {
        Droppables.add(e, options_for_tree);
        e.treeNode = element;
        options.droppables.push(e);
      });
    }

    // keep reference
    this.sortables[element.id] = options;

    // for onupdate
    Draggables.addObserver(new SortableObserver(element, options.onUpdate));

  },

  // return all suitable-for-sortable elements in a guaranteed order
  findElements: function(element, options) {
    return Element.findChildren(
      element, options.only, options.tree ? true : false, options.tag);
  },

  findTreeElements: function(element, options) {
    return Element.findChildren(
      element, options.only, options.tree ? true : false, options.treeTag);
  },

  onHover: function(element, dropon, overlap) {
    if(Element.isParent(dropon, element)) return;

    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
      return;
    } else if(overlap>0.5) {
      Sortable.mark(dropon, 'before');
      if(dropon.previousSibling != element) {
        var oldParentNode = element.parentNode;
        element.style.visibility = "hidden"; // fix gecko rendering
        dropon.parentNode.insertBefore(element, dropon);
        if(dropon.parentNode!=oldParentNode)
          Sortable.options(oldParentNode).onChange(element);
        Sortable.options(dropon.parentNode).onChange(element);
      }
    } else {
      Sortable.mark(dropon, 'after');
      var nextElement = dropon.nextSibling || null;
      if(nextElement != element) {
        var oldParentNode = element.parentNode;
        element.style.visibility = "hidden"; // fix gecko rendering
        dropon.parentNode.insertBefore(element, nextElement);
        if(dropon.parentNode!=oldParentNode)
          Sortable.options(oldParentNode).onChange(element);
        Sortable.options(dropon.parentNode).onChange(element);
      }
    }
  },

  onEmptyHover: function(element, dropon, overlap) {
    var oldParentNode = element.parentNode;
    var droponOptions = Sortable.options(dropon);

    if(!Element.isParent(dropon, element)) {
      var index;

      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
      var child = null;

      if(children) {
        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);

        for (index = 0; index < children.length; index += 1) {
          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
            offset -= Element.offsetSize (children[index], droponOptions.overlap);
          } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
            child = index + 1 < children.length ? children[index + 1] : null;
            break;
          } else {
            child = children[index];
            break;
          }
        }
      }

      dropon.insertBefore(element, child);

      Sortable.options(oldParentNode).onChange(element);
      droponOptions.onChange(element);
    }
  },

  unmark: function() {
    if(Sortable._marker) Sortable._marker.hide();
  },

  mark: function(dropon, position) {
    // mark on ghosting only
    var sortable = Sortable.options(dropon.parentNode);
    if(sortable && !sortable.ghosting) return;

    if(!Sortable._marker) {
      Sortable._marker =
        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
          hide().addClassName('dropmarker').setStyle({position:'absolute'});
      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
    }
    var offsets = Position.cumulativeOffset(dropon);
    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});

    if(position=='after')
      if(sortable.overlap == 'horizontal')
        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
      else
        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});

    Sortable._marker.show();
  },

  _tree: function(element, options, parent) {
    var children = Sortable.findElements(element, options) || [];

    for (var i = 0; i < children.length; ++i) {
      var match = children[i].id.match(options.format);

      if (!match) continue;

      var child = {
        id: encodeURIComponent(match ? match[1] : null),
        element: element,
        parent: parent,
        children: [],
        position: parent.children.length,
        container: $(children[i]).down(options.treeTag)
      };

      /* Get the element containing the children and recurse over it */
      if (child.container)
        this._tree(child.container, options, child);

      parent.children.push (child);
    }

    return parent;
  },

  tree: function(element) {
    element = $(element);
    var sortableOptions = this.options(element);
    var options = Object.extend({
      tag: sortableOptions.tag,
      treeTag: sortableOptions.treeTag,
      only: sortableOptions.only,
      name: element.id,
      format: sortableOptions.format
    }, arguments[1] || { });

    var root = {
      id: null,
      parent: null,
      children: [],
      container: element,
      position: 0
    };

    return Sortable._tree(element, options, root);
  },

  /* Construct a [i] index for a particular node */
  _constructIndex: function(node) {
    var index = '';
    do {
      if (node.id) index = '[' + node.position + ']' + index;
    } while ((node = node.parent) != null);
    return index;
  },

  sequence: function(element) {
    element = $(element);
    var options = Object.extend(this.options(element), arguments[1] || { });

    return $(this.findElements(element, options) || []).map( function(item) {
      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
    });
  },

  setSequence: function(element, new_sequence) {
    element = $(element);
    var options = Object.extend(this.options(element), arguments[2] || { });

    var nodeMap = { };
    this.findElements(element, options).each( function(n) {
        if (n.id.match(options.format))
            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
        n.parentNode.removeChild(n);
    });

    new_sequence.each(function(ident) {
      var n = nodeMap[ident];
      if (n) {
        n[1].appendChild(n[0]);
        delete nodeMap[ident];
      }
    });
  },

  serialize: function(element) {
    element = $(element);
    var options = Object.extend(Sortable.options(element), arguments[1] || { });
    var name = encodeURIComponent(
      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);

    if (options.tree) {
      return Sortable.tree(element, arguments[1]).children.map( function (item) {
        return [name + Sortable._constructIndex(item) + "[id]=" +
                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
      }).flatten().join('&');
    } else {
      return Sortable.sequence(element, arguments[1]).map( function(item) {
        return name + "[]=" + encodeURIComponent(item);
      }).join('&');
    }
  }
};

// Returns true if child is contained within element
Element.isParent = function(child, element) {
  if (!child.parentNode || child == element) return false;
  if (child.parentNode == element) return true;
  return Element.isParent(child.parentNode, element);
};

Element.findChildren = function(element, only, recursive, tagName) {
  if(!element.hasChildNodes()) return null;
  tagName = tagName.toUpperCase();
  if(only) only = [only].flatten();
  var elements = [];
  $A(element.childNodes).each( function(e) {
    if(e.tagName && e.tagName.toUpperCase()==tagName &&
      (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
        elements.push(e);
    if(recursive) {
      var grandchildren = Element.findChildren(e, only, recursive, tagName);
      if(grandchildren) elements.push(grandchildren);
    }
  });

  return (elements.length>0 ? elements.flatten() : []);
};

Element.offsetSize = function (element, type) {
  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
};

/*
 * Q.js 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Prototype=='undefined')
alert("Q Error:  Prototype is not loaded. Please make sure that your page includes prototype.js before it includes q.js");if(Prototype.Version<"1.6")
alert("Q Error:  Minimum Prototype 1.6.0 is required; you are using "+Prototype.Version);if(Prototype.Browser.IE)
if(/MSIE (\d+\.\d+);/.test(navigator.userAgent))
Prototype.BrowserFeatures.version=new Number(RegExp.$1);if(Prototype.Browser.IE&&Prototype.BrowserFeatures.version<7)
alert("Your webbrowser, Internet Explorer "+Prototype.BrowserFeatures.version+", is more than 8 years old and doesn't support many of the features necessary for using this page.")
var Q={imagePath:"images/q",style:"default",types:$w("plain info notice warning error dark"),fontFamily:"Lucida Sans Unicode, Lucida Grande, sans-serif;",fontSize:"12px",imageTypes:{plain:0,info:1,notice:2,warning:3,error:4,dark:5},IE:Prototype.Browser.IE,Opera:Prototype.Browser.Opera,WebKit:Prototype.Browser.WebKit,Gecko:Prototype.Browser.Gecko,MobileSafari:Prototype.Browser.MobileSafari,instances:[],counts:{},active:false,cssDeclarations:[],setup:function(){Q.addDynamicStylesheetMethodsTo(document);this.css=document.createStyleSheet();this.setSkin();this.addCssFor('base');document.fire('q:loaded');},set:function(options){if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();if(options.image_path)
options.imagePath=options.image_path;$H(options).each((function(pair){this[pair.key]=pair.value;}).bind(this));this.setSkin(this.style,true);},setSkin:function(style,load){var preload=load?new Image(25,25):{};if(style)
this.style=style;$w("h v").each((function(part){preload.src=this["imagePath_"+part]=this.imagePath+"/"+this.style+"-"+part+".png";}).bind(this));this.types.each((function(type){preload.src=this["filler_path_"+type]=this.imagePath+"/"+this.style+"-"+type+".png";}).bind(this));["#q_wrapper","#q_wrapper input","#q_wrapper textarea"].each((function(klass){this.addCss(klass,"font-family:"+this.fontFamily+";font-size:"+this.fontSize+";");}).bind(this));},create:function(subclass,options){var klass=options.klass||'q-'+subclass.toLowerCase(),inputType='input';if(subclass=='Textarea')
inputType='textarea'
$$(inputType+'.'+klass).each(function(input){new Q[subclass](input,options);});},register:function(subclass){if(this.counts[subclass])
this.counts[subclass]+=1;else
this.counts[subclass]=1;},hide:function(force){if(force||(this.active&&!this.active.persistent))
this.active.hide();},hideAll:function(force){this.instances.each((function(instance){if(instance!=this&&(force||!instance.persistent))
instance.hide(force);}).bind(this));},reposition:function(){this.instances.invoke("positionHolder");},addCss:function(targets,cssText){if(typeof targets=='string'){targets.split(',').collect(function(part){return part.strip();}).each((function(selector){this.css.addRule(selector,cssText);}).bind(this));}else if(typeof targets=='object'){$H(targets).each((function(pair){if(typeof pair.value=='object'){cssText='';$H(pair.value).each(function(p){cssText+=p.key.underscore().dasherize()+':'+p.value+';';});}else{cssText=pair.value;}
this.css.addRule(pair.key,cssText);}).bind(this));}},addCssFor:function(plugin){if(this.cssDeclarations.indexOf(plugin)>-1)return;switch(plugin){case"base":this.addCss("div.q-protective-layer","position:fixed;left:0;top:0;width:100%;height:100%;z-index:99997;background-color:#fff;");this.addCss("div.q-wrapper","position:absolute;left:0;top:0;z-index:99999999;width:100%;height:1px;");this.addCss(".q-clearer","content:'.';display:block;clear:both;visibility:hidden;line-height:0;height:0;zoom:1;list-style-type:none;margin:0;padding:0;");this.addCss("div.q-background","width:100%;height:100%;padding:0;margin:0;border-spacing:0;position:relative;");this.addCss("div.q-background div.q-center","margin:0 12px;position:relative;");this.addCss("div.q-background div.q-center div.q-top-spacer","height:1px;");this.addCss("div.q-background div.q-corner","width:12px;height:12px;position:absolute;margin:0;padding:0;");this.addCss("div.q-background div.q-edge","width:100%;height:12px;position:absolute;left:0;");this.addCss("div.q-background div.q-edge-spacer","height:12px;position:relative;");this.addCss("div.q-background div.q-border","width:12px;height:100%;position:absolute;margin:0;padding:0;");this.addCss(".q-plain","color:#333;");this.addCss(".q-info","color:rgb(44, 50, 51);");this.addCss(".q-notice","color:rgb(40, 51, 0);");this.addCss(".q-warning","color:rgb(51, 31, 2);");this.addCss(".q-error","color:#fff;");this.addCss(".q-dark","color:#fff;");break;case"informer":this.addCss(".q-message","position:relative;margin:0 0 5px 0;overflow:hidden;cursor:pointer;");this.addCss("div.q-message div.q-message-close","position:absolute;width:24px;height:24px;right:0px;top:0px;z-index:100;cursor:pointer;background-position:-24px -168px;background-image:url("+Q.imagePath_h+");visibility:hidden;");this.addCss("div.q-message:hover div.q-message-close","visibility:visible;");this.addCss("div.q-message div.q-message-close.q-left","left:0px;right:auto;");this.addCss(".q-text","font-size:12px;");this.addCss(".q-pending-bar","width:auto;height:16px;border:1px solid #999;-moz-border-radius:2px;-webkit-border-radius:2px;background-image:url("+Q.imagePath+"/pending.gif"+");");this.addCss(".q-progress-bar","width:auto;height:16px;border:1px solid #999;-moz-border-radius:2px;-webkit-border-radius:2px;");this.addCss(".q-progress-bar .q-indicator","width:0;height:100%;background-color:#ccc;");break;case"palette":this.addCss("#q_wrapper ul.q-palette","margin:0; padding:0; max-width:342px");this.addCss("#q_wrapper ul.q-palette li.q-color","padding:0; list-style-type:none; margin:2px; float:left; width:15px; height:15px; cursor:pointer;");this.addCss("#q_wrapper ul.q-palette li.q-color:hover","margin:0px; width:19px; height:19px;");this.addCss("#q_wrapper ul.q-palette li.q-color.active","margin:0px; width:19px; height:19px;");this.addCss("#q_wrapper ul.q-palette li.q-color.round","-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;");break;case"tagger":this.addCss("#q_wrapper ul.q-taglist","margin:0;padding:0;");this.addCss("#q_wrapper ul.q-taglist li.q-tag","margin:3px;padding:0px 8px;list-style-type:none;float:left;background-color:#666;color:#fff;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;cursor:pointer;");this.addCss("#q_wrapper ul.q-taglist li.q-tag:hover","background-color:#ccc;color:#666;text-decoration:line-through;");this.addCss("#q_wrapper ul.q-taglist li.q-tag.q-used","background-color:#ccc;color:#666;text-decoration:line-through;");this.addCss("#q_wrapper ul.q-taglist li.q-tag.q-used:hover","background-color:#666;color:#fff;text-decoration:none;");break;case"tooltip":this.addCss("#q_wrapper div.q-tooltip","position:absolute;");this.addCss("#q_wrapper div.q-tooltip div.q-content","overflow:hidden;");break;case"textarea":var cssClass;border:'1px solid #ccc'
this.addCss('div.q-textarea-wrapper iframe','border: 1px solid #ccc');this.addCss("ul.q-textarea-toolbar","margin:0; padding: 0; background-color:#f2f2f2; position:relative;");this.addCss("ul.q-textarea-toolbar li.button","margin:0; padding:0; list-style-type:none; cursor:pointer; float:left; position:relative; width:30px; height:30px; background-image: url("+Q.imagePath+"/textarea.png);");this.addCss("ul.q-textarea-toolbar li.q-heading-select","position:absolute; margin:0; padding:0; list-style-type:none; top:0px; left:0; z-index:10;");this.addCss("ul.q-textarea-toolbar li.q-heading-select ul","margin:0; padding:0; top:0px; width:210px; height:30px; background-color:#fff; -webkit-box-shadow: rgba(0, 0, 0, 0.5) 0px 2px 7px; box-shadow: rgba(0, 0, 0, 0.5) 0px 2px 7px; -moz-box-shadow: rgba(0, 0, 0, 0.5) 0px 2px 7px;");this.addCss("ul.q-textarea-toolbar li.q-heading-select ul li","margin:0; padding:0; list-style-type:none; float:left; cursor:pointer;");this.addCss("ul.q-textarea-toolbar li.button input.q-editor-color-field","width:28px; height:28px; margin:0; padding:0; opacity:0; -moz-opacity:0; cursor:pointer;");if(Q.IE){this.addCss("ul.q-textarea-toolbar li.button input.q-editor-color-field","filter:alpha(opacity=0);");this.addCss("ul.q-textarea-toolbar li.q-heading-select ul","border: 2px solid #666;");}
this.addCss("ul.q-textarea-toolbar.small li.q-heading-select ul","width:140px; height:20px;");this.addCss("ul.q-textarea-toolbar.small li.button","width:20px; height:20px; background-image: url("+Q.imagePath+"/textarea-small.png);");this.addCss("ul.q-textarea-toolbar.small li.button select.q-editor-select","top: 2px; width:20px; height:20px;");this.addCss("ul.q-textarea-toolbar.small li.button input.q-editor-color-field","width:18px; height:18px;");$w('Heading Bold Italic Underline StrikeThrough CreateLink InsertImage JustifyLeft JustifyCenter JustifyRight JustifyFull Indent Outdent ForeColor BackColor InsertUnorderedList InsertOrderedList RemoveFormat EditCode').each((function(button,i){cssClass=button.underscore().dasherize();this.addCss("ul.q-textarea-toolbar li."+cssClass,"background-position: -"+i*30+"px 0;");this.addCss("ul.q-textarea-toolbar li."+cssClass+":hover"+", ul.q-textarea-toolbar li."+cssClass+".active","background-position: -"+i*30+"px -30px;");this.addCss("ul.q-textarea-toolbar li."+cssClass+".inactive","background-position: -"+i*30+"px -60px !important; cursor:default !important;");this.addCss("ul.q-textarea-toolbar.small li."+cssClass,"background-position: -"+i*20+"px 0;");this.addCss("ul.q-textarea-toolbar.small li."+cssClass+":hover"+", ul.q-textarea-toolbar.small li."+cssClass+".active","background-position: -"+i*20+"px -20px;");this.addCss("ul.q-textarea-toolbar.small li."+cssClass+".inactive","background-position: -"+i*20+"px -40px !important; cursor:default !important;");}).bind(this));this.addCss("ul.q-textarea-toolbar li.option.div","background-position: 0px 0px;");this.addCss("ul.q-textarea-toolbar li.option.div:hover","background-position: 0px -30px;");this.addCss("ul.q-textarea-toolbar.small li.option.div","background-position: 0px 0px;");this.addCss("ul.q-textarea-toolbar.small li.option.div:hover","background-position: 0px -20px;");$R(1,6).each((function(i){this.addCss("ul.q-textarea-toolbar li.option.h"+i,"background-position: -"+(540+i*30)+"px 0px;");this.addCss("ul.q-textarea-toolbar li.heading.h"+i+", ul.q-textarea-toolbar li.option.h"+i+":hover","background-position: -"+(540+i*30)+"px -30px;");this.addCss("ul.q-textarea-toolbar li.heading.h"+i+".inactive","background-position: -"+(540+i*30)+"px -60px;");this.addCss("ul.q-textarea-toolbar.small li.option.h"+i,"background-position: -"+(360+i*20)+"px 0px;");this.addCss("ul.q-textarea-toolbar.small li.heading.h"+i+", ul.q-textarea-toolbar.small li.option.h"+i+":hover","background-position: -"+(360+i*20)+"px -20px;");this.addCss("ul.q-textarea-toolbar.small li.heading.h"+i+".inactive","background-position: -"+(360+i*20)+"px -40px;");}).bind(this));break;case"window":this.addCss("div.q-window","z-index:99996;font-size:12px;");this.addCss("div.q-window div.q-content","overflow:hidden;");this.addCss("div.q-window div.q-window-close","position:absolute;width:24px;height:24px;right:0px;top:0px;z-index:100;cursor:pointer;background-position:-24px -168px;background-image:url("+Q.imagePath_h+");");this.addCss("div.q-window div.q-window-close.q-left","left:0px;right:auto;");this.addCss("div.q-window div.q-window-resize","position:absolute;width:24px;height:24px;right:6px;bottom:5px;z-index:101;cursor:move;background-position:-72px -168px;background-image:url("+Q.imagePath_h+");");this.addCss("div.q-plain div.q-window-resize","background-position:-96px -168px;");this.addCss("div.q-window div.q-window-title","position:absolute;width:100%;height:24px;left:0px;top:6px;");this.addCss("div.q-window div.q-window-title p.q-window-label","height:100%;margin:0 25px;font-weight:bold;text-align:center;");this.addCss("div.q-window div.q-buttons-wrapper","position:relative;height:25px;")
this.addCss("div.q-window div.q-buttons-wrapper input.q-button","width:100px;height:22px;cursor:pointer;-moz-border-radius:3px;-webkit-border-radius:3px;border:1px solid #fff;font-size:12px;font-weight:bold;background-color:#ccc;background-image:url("+Q.imagePath_h+");background-position:0 -200px;");this.addCss("div.q-window input.q-button:hover","background-color:#999;");this.addCss("div.q-window div.q-buttons-wrapper input.q-next-button","background-color:#8CC63F;text-shadow:#BFFF5C 0px 1px 0px;color:#111;float:right;margin-right:10px;");this.addCss("div.q-window input.q-next-button:hover","background-color:#67991D;");this.addCss("div.q-window div.q-buttons-wrapper input.q-cancel-button","text-shadow:#fff 0px 1px 0px;color:#333;float:left;margin-left:10px;display:block;");this.addCss("div.q-window textarea.q-textarea","width:94%;height:150px;resize:vertical;margin:0 3% 20px 3%;");break;}
this.cssDeclarations.push(plugin);},callback:function(method,self,value,state){switch(typeof self.options[method]){case'function':if(typeof state!='undefined')
self.options[method](value,state,self);else if(typeof value!='undefined')
self.options[method](value,self);else
self.options[method](self);break;case'string':(function(){eval(self.options[method]);}).bind(self)();break;}}};Q.Base=Class.create({initialize:function(input){this.options={};this.createWrapper();this.is_over=false;Q.instances.push(this);if(input)
this.input=$(input);},createWrapper:function(){if($("q_wrapper")){this.div=$("q_wrapper");}else{this.div=new Element("div",{id:"q_wrapper","class":"q-wrapper"});$(document.body).insert({bottom:this.div});}},createHolder:function(type){var holder=this.holder=new Element("div");if(this.options.div)
this.div=$(this.options.div);if(!type)
this.options.style||"plain";holder.addClassName("q-holder").setStyle(this.options.holderStyle).hide();holder.background=this.buildBackground(type);holder.insert(holder.background);this.div.insert(holder);if(!this.options.div)
this.positionHolder();this.holder.observe("mouseover",(function(){this.is_over=true;}).bind(this));this.holder.observe("mouseout",(function(){if(this.is_over)
this.input.focus();this.is_over=false;}).bind(this));this.input.observe("focus",(function(){this.show();}).bind(this));this.input.observe("blur",(function(){if(!this.is_over)this.hide();}).bind(this));return holder;},buildBackground:function(type){var table=new Element("table",{"class":"q-background"}),c=Q.imageTypes[type||"plain"],s=24,div,center;div=new Element("div").addClassName("q-background q-"+type);div.insert(new Element("div").addClassName("q-corner").setStyle({left:0,top:0,backgroundImage:"url("+Q.imagePath_h+")",backgroundPosition:-(c*s)+"px -144px"}));div.insert(new Element("div").addClassName("q-edge-spacer"));div.insert(new Element("div").addClassName("q-corner").setStyle({right:0,top:0,backgroundImage:"url("+Q.imagePath_h+")",backgroundPosition:-(c*s+12)+"px -144px"}));div.center=new Element("div").addClassName("q-content");div.insert(center=new Element("div").addClassName("q-center").setStyle({backgroundImage:"url("+Q["filler_path_"+type]+")"}).insert(new Element("div").addClassName("q-border").setStyle({left:"-12px",top:"0px",backgroundImage:"url("+Q.imagePath_v+")",backgroundPosition:-(c*s)+"px 0"})).insert(new Element("div").addClassName("q-border").setStyle({right:"-12px",top:"0px",backgroundImage:"url("+Q.imagePath_v+")",backgroundPosition:-(c*s+12)+"px 0"})).insert(new Element("div").addClassName("q-edge").setStyle({top:"-12px",backgroundImage:"url("+Q.imagePath_h+")",backgroundPosition:"0 "+-(c*s)+"px"})).insert(new Element("div").addClassName("q-edge").setStyle({bottom:"-12px",backgroundImage:"url("+Q.imagePath_h+")",backgroundPosition:"0 "+-(c*s+11)+"px"})).insert(new Element("div").addClassName("q-top-spacer")));if(Prototype.Browser.IE)
center.insert(new Element("div").addClassName("q-top-spacer"))
center.insert(div.center)
div.insert(new Element("div").addClassName("q-corner").setStyle({left:0,bottom:0,backgroundImage:"url("+Q.imagePath_h+")",backgroundPosition:-(c*s)+"px -155px"}));div.insert(new Element("div").addClassName("q-edge-spacer"));div.insert(new Element("div").addClassName("q-corner").setStyle({right:0,bottom:0,backgroundImage:"url("+Q.imagePath_h+")",backgroundPosition:-(c*s+12)+"px -155px"}));div.insert=function(content,options){this.center.insert(content,options);return this;}
div.update=function(content){this.center.update(content);return this;}
return div;},positionHolder:function(){if(this.holder&&typeof this.input!="undefined"){var pos=this.input.cumulativeOffset(),dim=this.input.getDimensions(),doc=document.viewport.getDimensions(),left=pos[0],top=pos[1]+dim.height,x=this.options.left,y=this.options.top;if(this.options.axis=="vertical"){left=pos[0]+dim.width;top=pos[1];}
if(x==0||parseInt(x))
left+=parseInt(x);if(left+this.holder.getWidth()>doc.width)
left=doc.width-this.holder.getWidth()-5;if(y==0||parseInt(y))
top+=parseInt(y);this.holder.setStyle({left:left+"px",top:top+"px"});}},show:function(force){if(Q.active!=this||force){this.positionHolder();if(typeof this.setValue=="function"&&this.input)
this.setValue(this.input.value);Q.callback('onShow',this);Q.active=this;this.holder.appear({duration:0.1});}},hide:function(force){if(Q.active||force){Q.active=false;if(force){this.is_over=false;this.holder.hide();}else{this.holder.fade({duration:0.05});}
if(this.input)
this.input.blur();Q.callback('onHide',this);}},close:function(){this.hide(true);Q.callback('onClose',this);}});Q.Cookies=Class.create({initialize:function(options){this.options={expires:3600,path:'',domain:'',secure:false,prefix:'Q_'};$H(this.options).merge(options||{}).toObject();if(this.options.expires!=''){var date=new Date();date=new Date(date.getTime()+(this.options.expires*1000));this.options.expires='; expires='+date.toGMTString();}
if(this.options.path!='')
this.options.path='; path='+escape(this.options.path);if(this.options.domain!='')
this.options.domain='; domain='+escape(this.options.domain);if(this.options.secure==true)
this.options.secure='; secure';else
this.options.secure='';},create:function(name,value){var cookie_string,cookie=this.options;name=this.options.prefix+name;switch(typeof value){case'undefined':case'function':case'unknown':return false;case'boolean':case'string':case'number':value=String(value.toString());}
cookie_string=name+"="+escape(Object.toJSON(value));try{document.cookie=cookie_string+cookie.expires+cookie.path+cookie.domain+cookie.secure;}catch(e){return false;}
return true;},remove:function(name){var cookie=this.options,date,expires;name=this.options.prefix+name;try{date=new Date();date.setTime(date.getTime()-(3600*1000));expires='; expires='+date.toGMTString();document.cookie=name+"="+expires+cookie.path+cookie.domain+cookie.secure;}catch(e){return false;}
return true;},get:function(name){name=this.options.prefix+name;var cookies=document.cookie.match(name+'=(.*?)(;|$)');if(cookies){return(unescape(cookies[1])).evalJSON();}else{return null;}},clear:function(){this.names().each((function(key){this.remove(key);}).bind(this));},all:function(){var cookies={};this.names().each((function(key,i){cookies[key]=this.get(key);}).bind(this));return cookies;},names:function(){var keys=[],key_format=/[^=; ]+(?=\=)/g,raw_string=document.cookie,reg_exp=new RegExp("^"+this.options.prefix);while((match=key_format.exec(raw_string))!=undefined){if(reg_exp.test(match[0].strip()))
keys.push(match[0].strip().gsub("^"+this.options.prefix,""));}
return keys;}});Q.I18n={locale:"en",locales:{},add:function(locales){if(typeof locales=="string"&&locales.isJSON())
locales=locales.evalJSON();this.locales=$H(this.locales).merge(locales).toObject();},t:function(key,interpolations){var loc=this.locales,list;key.split(".").each((function(k){if(loc[k])
loc=loc[k];}).bind(this));if(typeof loc=='object'){if(interpolations&&interpolations.fallback){return interpolations.fallback;}else{list=key.split(".");list.unshift(this.locale);return"translation missing: "+list.join(", ");}}else if(typeof loc=="string"&&typeof interpolations=="object"){$H(interpolations).each(function(pair){loc=loc.gsub(new RegExp("\{\{([ ]+)?"+pair.key+"([ ]+)?\}\}"),pair.value)});return loc;}else{return loc;}}}
Object.extend(window,{observe:Element.Methods.observe.methodize(),stopObserving:Element.Methods.stopObserving.methodize()});(document.onresize?document:window).observe("resize",function(){if(!document.viewport.is_resized){document.viewport.is_resized=true;document.fire("resize:start");var resizeEnd=(function(){document.viewport.is_resized=false;document.fire("resize:end");Event.stopObserving(document,"mousemove",resizeEnd);}).bind(this);document.observe("mousemove",resizeEnd);}});Object.extend(String.prototype,{toMD5:function(){var string=this;function RotateLeft(lValue,iShiftBits){return(lValue<<iShiftBits)|(lValue>>>(32-iShiftBits));}
function AddUnsigned(lX,lY){var lX4,lY4,lX8,lY8,lResult;lX8=(lX&0x80000000);lY8=(lY&0x80000000);lX4=(lX&0x40000000);lY4=(lY&0x40000000);lResult=(lX&0x3FFFFFFF)+(lY&0x3FFFFFFF);if(lX4&lY4){return(lResult^0x80000000^lX8^lY8);}
if(lX4|lY4){if(lResult&0x40000000){return(lResult^0xC0000000^lX8^lY8);}else{return(lResult^0x40000000^lX8^lY8);}}else{return(lResult^lX8^lY8);}}
function F(x,y,z){return(x&y)|((~x)&z);}
function G(x,y,z){return(x&z)|(y&(~z));}
function H(x,y,z){return(x^y^z);}
function I(x,y,z){return(y^(x|(~z)));}
function FF(a,b,c,d,x,s,ac){a=AddUnsigned(a,AddUnsigned(AddUnsigned(F(b,c,d),x),ac));return AddUnsigned(RotateLeft(a,s),b);};function GG(a,b,c,d,x,s,ac){a=AddUnsigned(a,AddUnsigned(AddUnsigned(G(b,c,d),x),ac));return AddUnsigned(RotateLeft(a,s),b);};function HH(a,b,c,d,x,s,ac){a=AddUnsigned(a,AddUnsigned(AddUnsigned(H(b,c,d),x),ac));return AddUnsigned(RotateLeft(a,s),b);};function II(a,b,c,d,x,s,ac){a=AddUnsigned(a,AddUnsigned(AddUnsigned(I(b,c,d),x),ac));return AddUnsigned(RotateLeft(a,s),b);};function ConvertToWordArray(string){var lWordCount;var lMessageLength=string.length;var lNumberOfWords_temp1=lMessageLength+8;var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1%64))/64;var lNumberOfWords=(lNumberOfWords_temp2+1)*16;var lWordArray=Array(lNumberOfWords-1);var lBytePosition=0;var lByteCount=0;while(lByteCount<lMessageLength){lWordCount=(lByteCount-(lByteCount%4))/4;lBytePosition=(lByteCount%4)*8;lWordArray[lWordCount]=(lWordArray[lWordCount]|(string.charCodeAt(lByteCount)<<lBytePosition));lByteCount++;}
lWordCount=(lByteCount-(lByteCount%4))/4;lBytePosition=(lByteCount%4)*8;lWordArray[lWordCount]=lWordArray[lWordCount]|(0x80<<lBytePosition);lWordArray[lNumberOfWords-2]=lMessageLength<<3;lWordArray[lNumberOfWords-1]=lMessageLength>>>29;return lWordArray;};function WordToHex(lValue){var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;for(lCount=0;lCount<=3;lCount++){lByte=(lValue>>>(lCount*8))&255;WordToHexValue_temp="0"+lByte.toString(16);WordToHexValue=WordToHexValue+WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);}
return WordToHexValue;};function Utf8Encode(string){string=string.replace(/\r\n/g,"\n");var utftext="";for(var n=0;n<string.length;n++){var c=string.charCodeAt(n);if(c<128){utftext+=String.fromCharCode(c);}
else if((c>127)&&(c<2048)){utftext+=String.fromCharCode((c>>6)|192);utftext+=String.fromCharCode((c&63)|128);}
else{utftext+=String.fromCharCode((c>>12)|224);utftext+=String.fromCharCode(((c>>6)&63)|128);utftext+=String.fromCharCode((c&63)|128);}}
return utftext;};var x=Array();var k,AA,BB,CC,DD,a,b,c,d;var S11=7,S12=12,S13=17,S14=22;var S21=5,S22=9,S23=14,S24=20;var S31=4,S32=11,S33=16,S34=23;var S41=6,S42=10,S43=15,S44=21;string=Utf8Encode(string);x=ConvertToWordArray(string);a=0x67452301;b=0xEFCDAB89;c=0x98BADCFE;d=0x10325476;for(k=0;k<x.length;k+=16){AA=a;BB=b;CC=c;DD=d;a=FF(a,b,c,d,x[k+0],S11,0xD76AA478);d=FF(d,a,b,c,x[k+1],S12,0xE8C7B756);c=FF(c,d,a,b,x[k+2],S13,0x242070DB);b=FF(b,c,d,a,x[k+3],S14,0xC1BDCEEE);a=FF(a,b,c,d,x[k+4],S11,0xF57C0FAF);d=FF(d,a,b,c,x[k+5],S12,0x4787C62A);c=FF(c,d,a,b,x[k+6],S13,0xA8304613);b=FF(b,c,d,a,x[k+7],S14,0xFD469501);a=FF(a,b,c,d,x[k+8],S11,0x698098D8);d=FF(d,a,b,c,x[k+9],S12,0x8B44F7AF);c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);a=FF(a,b,c,d,x[k+12],S11,0x6B901122);d=FF(d,a,b,c,x[k+13],S12,0xFD987193);c=FF(c,d,a,b,x[k+14],S13,0xA679438E);b=FF(b,c,d,a,x[k+15],S14,0x49B40821);a=GG(a,b,c,d,x[k+1],S21,0xF61E2562);d=GG(d,a,b,c,x[k+6],S22,0xC040B340);c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);b=GG(b,c,d,a,x[k+0],S24,0xE9B6C7AA);a=GG(a,b,c,d,x[k+5],S21,0xD62F105D);d=GG(d,a,b,c,x[k+10],S22,0x2441453);c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);b=GG(b,c,d,a,x[k+4],S24,0xE7D3FBC8);a=GG(a,b,c,d,x[k+9],S21,0x21E1CDE6);d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);c=GG(c,d,a,b,x[k+3],S23,0xF4D50D87);b=GG(b,c,d,a,x[k+8],S24,0x455A14ED);a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);d=GG(d,a,b,c,x[k+2],S22,0xFCEFA3F8);c=GG(c,d,a,b,x[k+7],S23,0x676F02D9);b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);a=HH(a,b,c,d,x[k+5],S31,0xFFFA3942);d=HH(d,a,b,c,x[k+8],S32,0x8771F681);c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);a=HH(a,b,c,d,x[k+1],S31,0xA4BEEA44);d=HH(d,a,b,c,x[k+4],S32,0x4BDECFA9);c=HH(c,d,a,b,x[k+7],S33,0xF6BB4B60);b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);d=HH(d,a,b,c,x[k+0],S32,0xEAA127FA);c=HH(c,d,a,b,x[k+3],S33,0xD4EF3085);b=HH(b,c,d,a,x[k+6],S34,0x4881D05);a=HH(a,b,c,d,x[k+9],S31,0xD9D4D039);d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);b=HH(b,c,d,a,x[k+2],S34,0xC4AC5665);a=II(a,b,c,d,x[k+0],S41,0xF4292244);d=II(d,a,b,c,x[k+7],S42,0x432AFF97);c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);b=II(b,c,d,a,x[k+5],S44,0xFC93A039);a=II(a,b,c,d,x[k+12],S41,0x655B59C3);d=II(d,a,b,c,x[k+3],S42,0x8F0CCC92);c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);b=II(b,c,d,a,x[k+1],S44,0x85845DD1);a=II(a,b,c,d,x[k+8],S41,0x6FA87E4F);d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);c=II(c,d,a,b,x[k+6],S43,0xA3014314);b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);a=II(a,b,c,d,x[k+4],S41,0xF7537E82);d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);c=II(c,d,a,b,x[k+2],S43,0x2AD7D2BB);b=II(b,c,d,a,x[k+9],S44,0xEB86D391);a=AddUnsigned(a,AA);b=AddUnsigned(b,BB);c=AddUnsigned(c,CC);d=AddUnsigned(d,DD);}
var temp=WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);return temp.toLowerCase();},HTMLencode:function(){var str=this.replace(/&/g,"&amp;");str=str.replace(/>/g,"&gt;");str=str.replace(/</g,"&lt;");str=str.replace(/"/g,"&quot;");str=str.replace(/'/g,"&#039;");return str;},HTMLdecode:function(){var str=this.replace(/&amp;/g,"&");str=str.replace(/&gt;/g,">");str=str.replace(/&lt;/g,"<");str=str.replace(/&quot;/g,"\"");str=str.replace(/&#039;/g,"'");return str;},humanize:function(){return this.underscore().capitalize().gsub(/(_id)|\-|\.|_/,' ');}});Object.extend(Number.prototype,{toMD5:function(){return this.toString().toMD5();},withFormat:function(options){var prefix=options.prefix||'',delimiter=options.delimiter||'',separator=options.separator||'',suffix=options.suffix||'',precision=options.precision,parts,number=this;if(typeof precision=='number')
number=number.toFixed(precision);parts=number.toString().split('.');parts[0]=parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1"+delimiter);return prefix+parts.join(separator)+suffix;}});Q.addDynamicStylesheetMethodsTo=function(doc){if(typeof doc.createStyleSheet=='undefined'){doc.createStyleSheet=(function(){function createStyleSheet(href){if(typeof href!=='undefined'){var element=doc.createElement('link');element.type='text/css';element.rel='stylesheet';element.href=href;}
else{var element=doc.createElement('style');element.type='text/css';}
doc.getElementsByTagName('head')[0].appendChild(element);var sheet=doc.styleSheets[doc.styleSheets.length-1];if(typeof sheet.addRule==='undefined')
sheet.addRule=addRule;if(typeof sheet.removeRule==='undefined')
sheet.removeRule=sheet.deleteRule;return sheet;}
function addRule(selectorText,cssText,index){if(typeof index==='undefined')
index=this.cssRules.length;this.insertRule(selectorText+' {'+cssText+'}',index);}
return createStyleSheet;})();}}
document.observe("dom:loaded",function(){document.observe("resize:start",function(){Q.hide();});document.observe("resize:end",function(){Q.reposition();});Q.setup();});

/*
 * Q.Informer 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Q=='undefined')
alert("Q is not loaded. Please make sure that your page includes q.js before it includes q.informer.js");Q.Informer=Class.create(Q.Base,{initialize:function($super,options){$super();if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();Q.addCssFor('informer');Q.register('informer');this.options=$H(this.options).merge({closeButton:'right',life:{plain:10,info:10,notice:7,warning:12,error:"immortal",dark:10},holderStyle:{position:"fixed",right:"10px",top:"10px",width:"250px",zIndex:100001}}).merge(options).toObject();if(!this.div.down("div.q-holder.messages")){var holder,width;if(width=parseInt(this.options.width))
this.options.holderStyle.width=width+'px';holder=this.holder=new Element("div").addClassName("q-holder messages").setStyle(this.options.holderStyle);this.div.insert(holder);if(Prototype.Browser.MobileSafari){var holder_width=parseInt(this.options.holderStyle.width)||250,holder_top=parseInt(this.options.holderStyle.top)||10,holder_right=parseInt(this.options.holderStyle.right),holder_left=parseInt(this.options.holderStyle.left),screen_width=document.viewport.getWidth(),off=document.viewport.getScrollOffsets(),left;holder.setStyle({position:'absolute',right:'auto'});_QInformerRepositionEvent=function(){off=document.viewport.getScrollOffsets();screen_width=document.viewport.getWidth();if(holder_right==0||holder_right)
left=(screen_width-holder_width-holder_right-off.left)+'px';else if(holder_left==0||holder_left)
left=holder_left+'px';else
left='10px';holder.morph('left:'+left+';top:'+(off.top+10)+'px;',{duration:0.3});}
window.observe('scroll',_QInformerRepositionEvent);}}else{this.holder=this.div.down("div.q-holder.messages");}
$w("plain info notice warning error dark").each((function(type){this[type]=(function(message,life){this.message(type,message,life);}).bind(this);$$("p.q-"+type).each((function(message){var m,life;if(m=message.className.match(/q-life-([\d\.]+)/))
life=parseFloat(m[1]);else if(message.hasClassName("q-immortal"))
life="immortal";this.message(type,message.innerHTML,life);message.remove();}).bind(this));}).bind(this));},messages:function(type,list,life){if(!list)return;if(typeof list=="string"&&list.isJSON())
list=list.evalJSON();list.each((function(message){this.message(type,message,life)}).bind(this));return this;},message:function(type,text,life){var id=type+"_"+text.toMD5(),message,disappear,remove,close;if(!life)
life=this.options.life[type];if($(id)&&$(id).visible()){$(id).pulsate({pulses:3,duration:1});}else{message=new Element("div",{id:id}).addClassName("q-message q-"+type).setStyle({width:"100%",left:"0"}).hide();message.insert(this.buildBackground(type));message.down(".q-center").insert(text);if(this.options.closeButton){close=new Element("div").addClassName("q-message-close");if(this.options.closeButton=='left')
close.addClassName("q-left");message.insert(close);}
message.observe("click",(function(){this.disappear(message);}).bind(this));this.holder.insert(message);if(life!="immortal")
(this.disappear).bind(this).delay(life,message);this.appear(message);}
return message;},pending:function(message,id){var pending,bar,text;if(!id)
id="pending_"+Math.random().toMD5();if($(id)){pending=$(id);if(!$(id).visible())
this.holder.insert(pending.remove());}else{pending=new Element("div",{id:id}).addClassName("q-message q-plain q-pending").setStyle({width:"100%",left:"0"}).hide();bar=new Element("div").addClassName("q-pending-bar");pending.insert(this.buildBackground("plain"));if(message&&!message.blank()){text=new Element("div").update(message).addClassName("q-text");pending.down(".q-center").insert(text);}
pending.down(".q-center").insert(bar);Event.observe(pending,"click",(function(){this.disappear(pending);}).bind(this));pending.ready=(function(){this.disappear(pending);}).bind(this);}
this.holder.insert(pending);this.appear(pending);return pending;},progress:function(message,id){var progress,bar,indicator,text;if(!id)
id="progress_"+Math.random().toMD5();if($(id)){progress=$(id);if(!$(id).visible())
this.holder.insert(progress.remove());}else{progress=new Element("div",{id:id}).addClassName("q-message q-plain q-progress").setStyle({width:"100%",left:"0"}).hide();indicator=new Element("div").addClassName("q-indicator");bar=new Element("div").addClassName("q-progress-bar").insert(indicator);progress.insert(this.buildBackground("plain"));if(message&&!message.blank()){text=new Element("div").addClassName("q-text");progress.down(".q-center").insert(text);}
progress.down(".q-center").insert(bar);this.holder.insert(progress);Event.observe(progress,"click",(function(){this.disappear(progress);}).bind(this));progress.update=(function(percent,new_message){if(new_message)
message=new_message;if(percent==0||(percent=parseInt(percent))){if(percent>=100){progress.down(".q-indicator").setStyle({width:"0%"});this.disappear(progress);progress.status=0;}else{text.update(message.gsub(/%n/,percent));progress.down(".q-indicator").morph("width: "+percent+"%",{duration:0.1});progress.status=percent;}}}).bind(this);progress.ready=(function(){this.disappear(progress);}).bind(this);progress.update(0);}
this.appear(progress);return progress;},appear:function(message){if(message.visible())
message.pulsate({pulses:3,duration:0.8});else{message.appear({duration:0.2});if(Prototype.Browser.MobileSafari)
_QInformerRepositionEvent();}},disappear:function(message){message=$(message);if(message.visible()){message.slideUp({duration:0.2});message.morph("margin:0;padding:0;width:0;left:100%;",{duration:0.2});var resetStyle=(function(){message.setStyle({width:"100%",left:"0"});}).bind(this);resetStyle.delay(0.25);}},shutUp:function(){this.holder.select(".q-message").each((function(message){this.disappear(message);}).bind(this));return this;},purgeHidden:function(id){this.holder.select(".q-message").each((function(message){if(!message.visible())
message.remove();}).bind(this));}});var _QInformerRepositionEvent;

/*
 * Q.Picker 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Q=='undefined')
alert("Q is not loaded. Please make sure that your page includes q.js before it includes q.picker.js");Q.Picker=Class.create(Q.Base,{initialize:function($super,input,options){$super(input);if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();this.options=$H(this.options).merge({holderStyle:{position:"absolute"},offset:{left:0,top:0}}).merge(options).toObject();this.picking=false;Q.register('picker');if(!this.input)
alert("Q.Picker Error: No input was defined to attach the Picker to!");else
this.build();},build:function(){var paper=new Element("div"),color=this.options.value||this.input.value,holder;this.size=this.options.size||200;if(this.size<75)
this.size=75;else if(this.size>500)
this.size=500;if(!(holder=$(this.options.div))){holder=this.createHolder("plain").down("div.q-background").center;}
holder.insert(paper.setStyle({width:this.size+"px",height:this.size+"px"}));this.zoom=this.size/200;this.paper=Raphael(paper,this.size,this.size);this.mode=null;this.sb_box={x:35*this.zoom,y:25*this.zoom,width:130*this.zoom,height:112*this.zoom};this.buildColorwheel();this.buildTriangle();switch(this.identify(color)){case"hex":this.setHex(color);break;case"rgb":this.setRgb(color);break;case"hsb":this.setHsb(color);break;default:this.setHsb({h:0,s:100,b:100});break;}
holder.observe("mousedown",(function(event){event.preventDefault?event.preventDefault():event.returnValue=false;this.picking=true;this.onMouseDown(Event.pointerX(event)-this.offset(holder).x,Event.pointerY(event)-this.offset(holder).y,event.target);}).bind(this));document.observe("mousemove",(function(event){if(this.picking){event.preventDefault?event.preventDefault():event.returnValue=false;this.onMouseMove(Event.pointerX(event)-this.offset(holder).x,Event.pointerY(event)-this.offset(holder).y,event.target);}}).bind(this));document.observe("mouseup",(function(event){if(this.picking){event.preventDefault?event.preventDefault():event.returnValue=false;this.picking=false;this.onMouseUp(Event.pointerX(event)-this.offset(holder).x,Event.pointerY(event)-this.offset(holder).y,event.target);}}).bind(this));$w("Open Pick Change Close").each((function(e){this["on"+e]=function(){var hex=this.getHex(this.hsb);Q.callback("on"+e,this,hex);this.input.setValue(hex);}}).bind(this));this.input.observe("focus",(function(){this.onOpen(this.hsb,this);}).bind(this));this.input.observe("blur",(function(){this.onClose(this.hsb,this);}).bind(this));this.input.observe("change",(function(){this.setHex(this.input.value);}).bind(this));},setMode:function(mode){this.mode=mode||null;},buildColorwheel:function(){var wheel;wheel=this.paper.image(Q.imagePath+"/colorwheel.png",0,0,this.size,this.size);wheel.id="wheel";Event.observe(wheel.node,"mousedown",(function(){this.setMode("hue");}).bind(this));this.hue_picker=this.buildPicker(14,"hue");this.hue_picker.translate(this.size/2,8.5*this.zoom);},buildTriangle:function(){var points=[],r=75*this.zoom,part=120,tri,gradient,box,hit;(3).times(function(i){var a=i*part-90,x=r*Math.cos(a*Math.PI/180),y=r*Math.sin(a*Math.PI/180);points.push((i==0?"M":"L")+x+","+y);});points.push("Z");this.triangle=this.paper.set();tri=this.paper.path(points.join(" ")).translate(this.size/2,this.size/2+0.45*this.zoom).scale(0.985,0.985,this.size/2,this.size/2).attr({fill:"#f00","stroke-width":0}).toBack();this.triangle.push(tri);$w("#f00 #000 #fff").each((function(color,i){var c=this.paper.circle(this.size/2,25*this.zoom,7*this.zoom).attr({fill:color,"stroke-width":0}).rotate(120*i,this.size/2,this.size/2).toFront();if(i==0)
this.triangle.push(c);}).bind(this));hit=this.paper.circle(this.size/2,this.size/2,80*this.zoom).attr({fill:"#f00","stroke-width":0,opacity:0});Event.observe(hit.node,"mousedown",(function(){this.setMode("sb");}).bind(this));this.sb_picker=this.buildPicker(12,"sb");this.sb_picker.translate(this.size/2,25*this.zoom)},buildPicker:function(size,mode){var light=this.paper.circle(0,0,size/2*this.zoom).attr({"stroke-width":3*this.zoom,stroke:"#fff","stroke-opacity":0.8}),dark=this.paper.circle(0,0,size/3*this.zoom).attr({"stroke-width":1*this.zoom,stroke:"#333","stroke-opacity":0.8}),set=this.paper.set();Event.observe(light.node,"mousedown",(function(){this.setMode(mode);}).bind(this));Event.observe(dark.node,"mousedown",(function(){this.setMode(mode);}).bind(this));set.push(light,dark);return set;},onMouseDown:function(x,y,target){switch(this.mode){case"hue":this.changeHue(x,y);break;case"sb":this.changeSB(x,y);break;}},onMouseMove:function(x,y,target){switch(this.mode){case"hue":this.changeHue(x,y);break;case"sb":this.changeSB(x,y);break;}},onMouseUp:function(x,y,target){if(this.mode)
this.onChange();this.setMode();},changeHue:function(x,y){x-=this.size/2;y-=this.size/2;var hyp=Math.sqrt(Math.pow(x,2)+Math.pow(y,2)),cos=x/hyp,rad=Math.acos(cos),deg=Math.floor(180/(Math.PI/rad));if(y<0)
deg=-deg;else if((Math.floor(y)==0)&&(x<0))
deg=180;deg+=90;this.setHue(deg);this.applyValue({h:deg,s:this.hsb.s,b:this.hsb.b});this.onPick();},setHue:function(hue){this.hue_picker.rotate(hue,this.size/2,this.size/2);this.triangle.attr({fill:this.hsbToHex({h:hue,s:100,b:100})});},changeSB:function(x,y){var box,pct,sat,bgt,half,left,right;box=this.sb_box;if(x<box.x)x=box.x;if(x>box.x+box.width)x=box.x+box.width;if(y<box.y)y=box.y;if(y>box.y+box.height)y=box.y+box.height;pct=(y-box.y)/box.height;half=box.width/2;left=box.x+half-(half*pct);right=box.x+half+half*pct;if(x<left)x=left;if(x>right)x=right;this.sb_picker.attr({cx:x,cy:y});sat=Math.abs(-100+pct*100);brt=Math.abs(-100+(((x-box.x)+pct*half)-half)/box.width*100);this.applyValue({h:this.hsb.h,s:sat,b:brt});this.onPick();},setSB:function(sat,brt){var n_sat=Math.abs(-100+sat),n_brt=Math.abs(-100+brt),half=this.sb_box.width/2,width=this.sb_box.width/100*n_sat,x_off=this.sb_box.x+half/100*sat,point=(brt-sat)/(100-sat)*width,x=x_off+width-(point||0),y=this.sb_box.y+n_sat/100*this.sb_box.height;this.sb_picker.attr({cx:x,cy:y});},applyValue:function(hsb){this.hsb=hsb;var hex=this.getHex();this.input.setValue(hex).setStyle({backgroundColor:hex,color:this.getTextColor(hsb)});},setValue:function(hsb){if(typeof hsb!="string"){this.setHue(hsb.h);this.setSB(hsb.s,hsb.b);this.applyValue(hsb);}},setHex:function(hex){this.setValue(this.hexToHsb(hex));},setRgb:function(rgb){this.setValue(this.rgbToHsb(rgb));},setHsb:function(hsb){this.setValue(hsb);},getHex:function(){return this.rgbToHex(this.hsbToRgb(this.hsb));},getRgb:function(){return this.hsbToRgb(this.hsb);},getHsb:function(){return this.hsb;},getTextColor:function(hsb){var rgb=this.hsbToRgb(hsb),brt=(rgb.r/255*0.30)+(rgb.g/255*0.59)+(rgb.b/255*0.11);if(brt<0.5){var m=Math.floor(brt*20)+3;var im=255*(m-1);}else{var m=Math.floor((1.0-brt)*20)+3;var im=0;}
return this.rgbToHex({r:Math.floor((rgb.r+im)/m),g:Math.floor((rgb.g+im)/m),b:Math.floor((rgb.b+im)/m)});},offset:function(element){var pos=$(this.options.div||element).cumulativeOffset(),off={x:pos.left,y:pos.top},scroll;if(Prototype.Browser.IE&&typeof this.options.div=="undefined"&&Prototype.BrowserFeatures.version<8){off.x-=12;off.y-=12;}
if(this.options.position=='fixed'){scroll=document.viewport.getScrollOffsets();off.x+=scroll.left;off.y+=scroll.top;}
return off;},hsbToRgb:function(hsb){var v=this.toNumber(hsb.b);if(v<0)v=0;if(v>100)v=100;v=v*255/100;var s=this.toNumber(hsb.s);if(s>100)s=100;var h=this.toNumber(hsb.h);h=h%360;if(h<0)h+=360;var vs=v*s/100;var vsf=(vs*((h*256/60)%256))/256;var r,g,b;switch(Math.floor(h/60)){case 0:r=v;g=v-vs+vsf;b=v-vs;break;case 1:r=v-vsf;g=v;b=v-vs;break;case 2:r=v-vs;g=v;b=v-vs+vsf;break;case 3:r=v-vs;g=v-vsf;b=v;break;case 4:r=v-vs+vsf;g=v-vs;b=v;break;case 5:r=v;g=v-vs;b=v-vsf;break;}
r=Math.floor(r+0.5);g=Math.floor(g+0.5);b=Math.floor(b+0.5);return this.normalize({r:r,g:g,b:b});},hsbToHex:function(hsb){return this.rgbToHex(this.hsbToRgb(hsb));},rgbToHsb:function(rgb){var r=Math.floor(this.toNumber(rgb.r)+0.5);var g=Math.floor(this.toNumber(rgb.g)+0.5);var b=Math.floor(this.toNumber(rgb.b)+0.5);if(r<0)r=0;if(r>255)r=255;if(g<0)g=0;if(g>255)g=255;if(b<0)b=0;if(b>255)b=255;var max,delta,diff,offset;var h=r,s=g,v=b;if(r>g){if(r>b)v=max=r,offset=0,diff=g-b;else v=max=b,offset=240,diff=r-g;delta=max-((g<b)?g:b);}
else{if(g>b)v=max=g,offset=120,diff=b-r;else v=max=b,offset=240,diff=r-g;delta=max-((r<b)?r:b);}
if(max!=0)s=Math.floor((delta*100)/max+0.5);else s=0;if(s!=0){h=(offset+Math.floor(diff*120/(delta*2)+0.5))%360;if(h<0)h+=360;}
else h=0;v=Math.floor(v*100/255+0.5);return this.normalize({h:h,s:s,b:v});},rgbToHex:function(rgb){rgb=this.normalize(rgb);return"#"+rgb.r.toColorPart()+rgb.g.toColorPart()+rgb.b.toColorPart();},hexToRgb:function(hex){var m;if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{0,2})(?:[^0-9A-Fa-f]|$)/.exec(hex))
return{r:parseInt(m[1],16),g:parseInt(m[2],16),b:parseInt(m[3],16)};if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f])(?:[^0-9A-Fa-f]|$)/.exec(hex)){var b=parseInt(m[3],16);return{r:parseInt(m[1],16),g:parseInt(m[2],16),b:b*16+b};}
if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})(?:[^0-9A-Fa-f]|$)/.exec(hex)){var g=parseInt(m[2],16);return{r:parseInt(m[1],16),g:g,b:g};}
if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f]{0,2})(?:[^0-9A-Fa-f]|$)/.exec(hex)){var r=parseInt(m[1],16);var g=parseInt(m[2],16);var b=parseInt(m[3],16);return{r:r*16+r,g:g*16+g,b:b*16+b};}
if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f]{2})(?:[^0-9A-Fa-f]|$)/.exec(hex)){var g=parseInt(m[1],16);return{r:g,g:g,b:g};}
if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f])(?:[^0-9A-Fa-f]|$)/.exec(hex)){var g=parseInt(m[1],16);g=g*16+g;return{r:g,g:g,b:g};}
return false;},hexToHsb:function(hex){return this.rgbToHsb(this.hexToRgb(hex));},toNumber:function(data){switch(typeof data){case"number":return data;break;case"string":if(m=/^[^0-9.+-]*([+-]?(?:[0-9]*\.[0-9]+|[0-9]+(?:\.[0-9]*)?))(?:[^0-9]|$)/.exec(data))
return Number(m[1]);else return 0;break;case"boolean":return data?1:0;break;case"object":return data?1:0;break;case"function":return 1;break;default:case"undefined":return 0;break;}},normalize:function(color){switch(this.identify(color)){case"rgb":var rgb=color;rgb.r=this.toNumber(rgb.r);rgb.g=this.toNumber(rgb.g);rgb.b=this.toNumber(rgb.b);if(rgb.r<0)rgb.r=0;if(rgb.r>255)rgb.r=255;if(rgb.g<0)rgb.g=0;if(rgb.g>255)rgb.g=255;if(rgb.b<0)rgb.b=0;if(rgb.b>255)rgb.b=255;return rgb;break;case"hsb":var hsb=color;hsb.h=this.toNumber(hsb.h);hsb.s=this.toNumber(hsb.s);hsb.b=this.toNumber(hsb.b);if(hsb.h<0)hsb.h+=360;if(hsb.h>360)hsb.h-=360;if(hsb.s<0)hsb.s=0;if(hsb.s>100)hsb.s=100;if(hsb.b<0)hsb.b=0;if(hsb.b>100)hsb.b=100;return hsb;break;default:return color;break;}},identify:function(data){switch(typeof data){case"string":if(m=data.match(/^#([A-Fa-f0-9]{2,8})$/))
return"hex";break;case"object":if((data.r===0||data.r)&&(data.g===0||data.g)&&(data.b===0||data.b))
return"rgb";if((data.h===0||data.h)&&(data.s===0||data.s)&&(data.b===0||data.b))
return"hsb";break;}}});

/*
 * Q.Palette 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Q=='undefined')
alert("Q is not loaded. Please make sure that your page includes q.js before it includes q.palette.js");Q.Palette=Class.create(Q.Base,{initialize:function($super,input,options){$super(input);if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();this.options=$H(this.options).merge({round:true,maxRowSize:18,maxWidth:342,colorizeInput:true,swatchSize:19,swatchSpace:2,holderStyle:{position:'absolute'}}).merge(options).toObject();Q.addCssFor('palette');Q.register('palette');if(!this.input)
alert('Q.Palette Error: No input was defined to attach the Palette to!');else
this.build();},build:function(){var holder=this.createHolder('plain'),ulClass='q-palette-'+Q.counts.palette,shrunken=this.options.swatchSize-(this.options.swatchSpace*2),round=Math.ceil(this.options.swatchSize/2),maxWidth=this.options.maxRowSize?this.options.maxRowSize*this.options.swatchSize:this.options.maxWidth,value=this.value=this.input.value,valid=this.hexToRgb(value),ul;Q.addCss('#q_wrapper ul.q-palette.'+ulClass,'max-width:'+maxWidth+'px;');Q.addCss('#q_wrapper ul.q-palette.'+ulClass+' li.q-color','margin:'+this.options.swatchSpace+'px; width:'+shrunken+'px; height:'+shrunken+'px;');Q.addCss('#q_wrapper ul.q-palette.'+ulClass+' li.q-color:hover','margin:0px; width:'+this.options.swatchSize+'px; height:'+this.options.swatchSize+'px;');Q.addCss('#q_wrapper ul.q-palette.'+ulClass+' li.q-color.active','margin:0px; width:'+this.options.swatchSize+'px; height:'+this.options.swatchSize+'px;');Q.addCss('#q_wrapper ul.q-palette.'+ulClass+' li.q-color.round','-moz-border-radius:'+round+'px;-webkit-border-radius:'+round+'px;border-radius:'+round+'px;');ul=new Element('ul').addClassName('q-palette').addClassName(ulClass);this.colorList().each((function(color){var li=new Element('li').addClassName('q-color').setStyle({backgroundColor:color}).update('&nbsp;');if(this.options.round)
li.addClassName('round');if(value==color)
li.addClassName('active');li.onmouseover=(function(){Q.callback('onPick',this,color);}).bind(this);li.onclick=(function(){if(color!=this.value){Q.callback('onChange',this,color);li.up('ul.q-palette').select('li.active').invoke('removeClassName','active');li.addClassName('active');this.input.value=this.value=color;this.colorizeInput(color);}}).bind(this);ul.insert(li);}).bind(this));ul.insert(new Element('li').addClassName('q-clearer').update('&nbsp;'));if(valid)
this.colorizeInput(this.rgbToHex(valid));holder.down("div.q-center").insert(ul);},colorList:function(){if(this.options.colors){return this.options.colors;}else{var colors=[];$w('00 33 66 99 cc ff').each(function(part_1){$w('00 33 66 99 cc ff').each(function(part_2){$w('00 33 66 99 cc ff').each(function(part_3){colors.push('#'+part_1+part_2+part_3);});});});return colors;}},colorizeInput:function(color){if(this.options.colorizeInput)
this.input.setStyle({backgroundColor:color,color:this.getTextColor(color)});return this;},getTextColor:function(hex){var rgb=this.hexToRgb(hex),brt=(rgb.r/255*0.30)+(rgb.g/255*0.59)+(rgb.b/255*0.11);if(brt<0.5){var m=Math.floor(brt*20)+3;var im=255*(m-1);}else{var m=Math.floor((1.0-brt)*20)+3;var im=0;}
return this.rgbToHex({r:Math.floor((rgb.r+im)/m),g:Math.floor((rgb.g+im)/m),b:Math.floor((rgb.b+im)/m)});},hexToRgb:function(hex){var m;if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{0,2})(?:[^0-9A-Fa-f]|$)/.exec(hex))
return{r:parseInt(m[1],16),g:parseInt(m[2],16),b:parseInt(m[3],16)};if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f])(?:[^0-9A-Fa-f]|$)/.exec(hex)){var b=parseInt(m[3],16);return{r:parseInt(m[1],16),g:parseInt(m[2],16),b:b*16+b};}
if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})(?:[^0-9A-Fa-f]|$)/.exec(hex)){var g=parseInt(m[2],16);return{r:parseInt(m[1],16),g:g,b:g};}
if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f]{0,2})(?:[^0-9A-Fa-f]|$)/.exec(hex)){var r=parseInt(m[1],16);var g=parseInt(m[2],16);var b=parseInt(m[3],16);return{r:r*16+r,g:g*16+g,b:b*16+b};}
if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f]{2})(?:[^0-9A-Fa-f]|$)/.exec(hex)){var g=parseInt(m[1],16);return{r:g,g:g,b:g};}
if(m=/^[^0-9A-Fa-f]*([0-9A-Fa-f])(?:[^0-9A-Fa-f]|$)/.exec(hex)){var g=parseInt(m[1],16);g=g*16+g;return{r:g,g:g,b:g};}
return false;},rgbToHex:function(rgb){return"#"+rgb.r.toColorPart()+rgb.g.toColorPart()+rgb.b.toColorPart();}});

/*
 * Q.Slider 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Q=='undefined')
alert("Q is not loaded. Please make sure that your page includes q.js before it includes q.slider.js");Q.Slider=Class.create(Q.Base,{initialize:function($super,input,options){$super(input);if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();this.options=$H(this.options).merge({delimiter:'',separator:'',prefix:'',suffix:'',holderStyle:{position:"absolute"},trackStyle:{backgroundImage:"url("+Q.imagePath_h+")",backgroundRepeat:"repeat-x",backgroundPosition:"0 -197px",width:"200px",height:"3px",position:"absolute",left:"15px",top:"22px"},trackStyleVertical:{backgroundImage:"url("+Q.imagePath_v+")",backgroundRepeat:"repeat-y",backgroundPosition:"-197px 0",width:"3px",height:"200px",position:"absolute",left:"21px",top:"15px"},handleStyle:{backgroundImage:"url("+Q.imagePath_h+")",backgroundRepeat:"no-repeat",backgroundPosition:"0px -168px",width:"24px",height:"24px",position:"relative",marginTop:"-11px",marginLeft:"0px",cursor:"pointer"},handleStyleVertical:{marginTop:"0px",marginLeft:"-11px"}}).merge(options).toObject();if(this.options.format){this.options.format=this.options.format.match(/^(.*?)([\d]+)(.([\d]+))?(.*?)$/);}
Q.register('slider');if(!this.input)
alert("Q.Slider Error: No input was defined to attach the Slider to!");else
this.build();},build:function(){var holder=this.createHolder("plain"),track=new Element("div"),handle=new Element("div"),size=parseInt(this.options.size)||200,options;this.options.trackStyle.width=size+"px";this.options.trackStyleVertical.width=size+"px";holder.addClassName("slider").setStyle(this.options.holderStyle).insert(track);track.addClassName("q-track").insert(handle).setStyle(this.options.trackStyle);handle.addClassName("q-handle").setStyle(this.options.handleStyle);if(this.options.axis=="vertical"){holder.setStyle(this.options.holderStyleVertical).down("div.q-center").setStyle({width:"20px",height:(size+8)+"px"});track.setStyle(this.options.trackStyleVertical);handle.setStyle(this.options.handleStyleVertical);}else{holder.down("div.q-center").setStyle({width:(size+8)+"px",height:"20px"});}
this.input.observe("blur",(function(){this.input.value=this.format(this.options.value);}).bind(this));this.input.observe("keyup",(function(event){if(event.keyCode==13)
this.hide();this.options.value=this.input.value;}).bind(this));options=$H(this.options).merge({onChange:this.onChange.bind(this),onSlide:this.onSlide.bind(this)}).toObject();this.control=new Control.Slider(handle,track,options);this.setValue(this.options.value||this.input.value||0);},onChange:function(value){if(value==0||value){this.input.setValue(this.format(value));this.options.value=value;this.positionHolder();Q.callback('onChange',this,value);}},onSlide:function(value){if(value==0||value){this.input.setValue(this.format(value));this.options.value=value;Q.callback('onSlide',this,value);}},setValue:function(value){if(value==0||parseFloat(value)){this.control.setValue(parseFloat(value));this.input.setValue(this.format(value));this.options.value=value;}},format:function(value){if(m=this.options.format){if(!m[4])
value=parseInt(value);else
value=parseFloat(value).toFixed(m[4].length);return(m[1]||"")+value+(m[5]||"");}else{return value;}}});

/*
 * Q.Tagger 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Q=='undefined')
alert("Q is not loaded. Please make sure that your page includes q.js before it includes q.tagger.js");Q.Tagger=Class.create(Q.Base,{initialize:function($super,input,options){$super(input);if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();this.options=$H(this.options).merge({holderStyle:{position:'absolute'}}).merge(options).toObject();Q.addCssFor('tagger');Q.register('tagger');if(!this.input)
alert("Q.Tagger Error: No input was defined to attach the Tagger to!");else if(!this.options.tagList&&!this.options.hiddenTagList)
alert("Q.Tagger Error: No tagList was provided of hiddenTagList defined!");else
this.build();},build:function(){var holder=this.createHolder(this.options.style||'plain'),width=parseInt(this.options.size)||300,input=this.input,self=this,tags,list,item,usedTags;holder.addClassName("q-tagger").setStyle(this.options.holderStyle);list=new Element('ul').addClassName('q-taglist').setStyle({width:width+'px'});tags=this.parseTagList();usedTags=this.strip(this.input.value.split(','));tags.each(function(tag){item=new Element('li').addClassName('q-tag').update(tag);if(usedTags.include(tag))
item.addClassName('q-used');item.observe('click',function(){var used;if(this.hasClassName('q-used')){this.removeClassName('q-used');self.onChange(tag,false);}else{this.addClassName('q-used');self.onChange(tag,true);}
used=list.select('li.q-used').collect(function(used){return used.innerHTML.strip().HTMLdecode();});input.value=used.join(', ');});list.insert(item);});item=new Element('li').addClassName('q-clearer').update('&nbsp;');this.input.observe('keyup',function(){usedTags=self.strip(this.value.split(','));list.select('li').each(function(li){if(usedTags.include(li.innerHTML.strip().HTMLdecode()))
li.addClassName('q-used');else
li.removeClassName('q-used');});});list.insert(item);holder.down("div.q-center").insert(list);},onChange:function(value,state){Q.callback('onChange',this,value,state);},parseTagList:function(){var tags;if(this.options.tagList)
if(typeof this.options.tagList=='string')
if(this.options.tagList.isJSON())
tags=this.options.tagList.parseJSON();else
tags=this.options.tagList.split(',');else
tags=this.options.tagList;else
tags=$(this.options.hiddenTagList).value.split(',');return this.strip(tags);},strip:function(list){return list.collect(function(item){return item.strip();});}});

/*
 * Q.Textarea 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Q=='undefined')
alert("Q is not loaded. Please make sure that your page includes q.js before it includes q.textarea.js");Q.Textarea=Class.create({availableButtons:$w('Heading Bold Italic Underline StrikeThrough CreateLink InsertImage JustifyLeft JustifyCenter JustifyRight JustifyFull Indent Outdent ForeColor InsertUnorderedList InsertOrderedList RemoveFormat EditCode'),initialize:function(textarea,options){if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();this.options=$H(this.options).merge({className:'q-textarea',forecolor:'palette',backcolor:'palette'}).merge(options).toObject();Q.addCssFor('textarea');Q.register('textarea');this.build(textarea);},build:function(textarea){var blankBody,styleSheet,diffDim,headingSelect,oldarea=$(textarea),width=this.options.width||oldarea.getWidth(),height=this.options.height||oldarea.getHeight(),buttons=this.options.buttons||this.availableButtons;diffDim=oldarea.setStyle({width:width+'px',height:height+'px'}).getDimensions();diffDim.width-=width;diffDim.height-=height;this.toolbarButtons={};this.active=true;this.oldCaret=false;this.codearea=oldarea.cloneNode(true);this.holder=new Element('div');this.toolbar=new Element('ul');this.editor=new Element('iframe');oldarea.replace(this.holder);this.holder.addClassName('q-textarea-wrapper').setStyle({width:width+'px'});this.holder.insert(this.editor);this.codearea.hide().setStyle({resize:'none',width:(width-diffDim.width)+'px',height:(height-diffDim.height)+'px',border:'1px solid #ccc'});this.editor.insert({before:this.toolbar}).setStyle({width:(width-2)+'px',height:(height-2)+'px'});this.toolbar.insert({after:this.codearea}).addClassName('q-textarea-toolbar').setStyle({width:width+'px'});if(this.options.icons)
this.toolbar.addClassName(this.options.icons);buttons.uniq().each((function(action){var li,option,input,pick,change;if(this.availableButtons.indexOf(action)>-1){li=new Element('li',{unselectable:'on',title:Q.I18n.t('textarea.tooltips.'+action.underscore(),{fallback:action.humanize()})}).addClassName('button').addClassName('q-tip').addClassName(action.underscore().dasherize());switch(action){default:li.insert('&nbsp;')
break;case'Heading':headingSelect=new Element('ul').addClassName('heading-options').hide();option=new Element('li',{unselectable:'on',title:'Default'}).addClassName('q-tip button option div');headingSelect.insert(option);option.onclick=(function(){this.perform(action,'div');headingSelect.hide();}).bind(this);$R(1,6).each((function(i){option=new Element('li',{unselectable:'on',title:'Heading '+i}).addClassName('q-tip button option h'+i);headingSelect.insert(option);option.onmousedown=(function(){this.perform(action,'h'+i);headingSelect.hide();}).bind(this);}).bind(this));break;case'ForeColor':input=new Element('input').addClassName('q-editor-color-field');pick=(function(value){this.perform(action,value);}).bind(this);if(this.options[action.toLowerCase()]=='picker'){new Q.Picker(input,{size:150,onShow:function(){li.addClassName('active')},onPick:pick,onChange:(function(value,instance){if(this.oldCaret)
this.oldCaret.range.select();pick(value);}).bind(this),onHide:function(){li.removeClassName('active')}});}else if(this.options[action.toLowerCase()]=='palette'){new Q.Palette(input,{swatchSize:13,swatchSpace:1,colors:this.options[action.toLowerCase()+'s'],onShow:function(){li.addClassName('active')},onChange:(function(value,instance){if(this.oldCaret)
this.oldCaret.range.select();pick(value);instance.close();}).bind(this),onHide:function(){li.removeClassName('active')}});}
li.insert(input);if(Q.IE)
li.onmouseover=(function(){this.oldCaret=this.getCaret();}).bind(this);break;}
this.toolbar.insert(li);this.toolbarButtons[action.underscore()]=li;li.onclick=(function(){switch(action){default:this.perform(action);break;case'EditCode':this.toggleToolbarState();break;case'Heading':var observeBlur,offset;observeBlur=function(){headingSelect.hide();document.stopObserving('mouseup',observeBlur);}
document.observe('mouseup',observeBlur);offset=li.positionedOffset();Q.addCss('ul.q-textarea-toolbar li.q-heading-select','left:'+offset.left+'px; top:'+offset.top+'px;');headingSelect.show();break;case'ForeColor':break;}}).bind(this);}}).bind(this));this.toolbar.insert(new Element('li').addClassName('q-clearer').update('&nbsp;'));if(headingSelect)
this.toolbar.insert(new Element('li').addClassName('q-heading-select').update(headingSelect));this.doc=this.editor.contentWindow.document;blankBody='<html><head>';if(!this.options.styleSheet&&Q.IE){blankBody+='<link href="'+this.options.styleSheet+'" rel="stylesheet" type="text/css"></link>';}
blankBody+='<title>Q.Textarea Editor</title></head><body id="q_editor">';blankBody+=this.codearea.value;blankBody+='</body></html>';this.doc.open();this.doc.write(blankBody);this.doc.close();this.editorInitializationCount=0;this.initializeEditor();if(this.options.styleSheet&&!Q.IE){styleSheet=this.doc.createElement('link');styleSheet.setAttribute('rel','stylesheet');styleSheet.setAttribute('type','text/css');styleSheet.setAttribute('href',this.options.styleSheet);this.doc.getElementsByTagName('head')[0].appendChild(styleSheet);}},initializeEditor:function(){try{this.doc.designMode="on";this.addEditorFunctions();this.addCss('p, div','margin:0;padding:0;');if(this.options.css)
this.addCss(this.options.css);Q.callback('onLoad',this);}catch(e){if(this.editorInitializationCount<10){(function(){this.initializeEditor();}).bind(this).delay(0.1);this.editorInitializationCount+=1;}else{}
return false;}},addEditorFunctions:function(){Q.addDynamicStylesheetMethodsTo(this.doc);this.editor.contentWindow.css=this.doc.createStyleSheet();if(typeof this.doc.addEventListener=='function'){this.doc.addEventListener('mouseup',(function(){this.setButtonState();return true;}).bind(this),false);this.doc.addEventListener('keyup',(function(){this.setButtonState();this.sync();return true;}).bind(this),false);}else{this.doc.attachEvent('onmouseup',(function(){this.setButtonState();return true;}).bind(this));this.doc.attachEvent('onkeyup',(function(){this.setButtonState();this.sync();return true;}).bind(this));}
this.codearea.observe('keyup',(function(){this.sync();}).bind(this));},addCss:function(targets,cssText){if(typeof targets=='string'){targets.split(',').collect(function(part){return part.strip();}).each((function(selector){this.editor.contentWindow.css.addRule(selector,cssText);}).bind(this));}else if(typeof targets=='object'){$H(targets).each((function(pair){if(typeof pair.value=='object'){cssText='';$H(pair.value).each(function(p){cssText+=p.key.underscore().dasherize()+':'+p.value+';';});}else{cssText=pair.value;}
this.editor.contentWindow.css.addRule(pair.key,cssText);}).bind(this));}},perform:function(action,value){if(!this.active)return false;var button=this.toolbar.down('li.'+action.underscore().dasherize());switch(action){default:this.doc.execCommand(action,false,null);if(button.hasClassName('active'))
button.removeClassName('active');else
button.addClassName('active');break;case'RemoveFormat':var html,caret=this.getCaret(),node=caret.node;this.doc.execCommand(action,false,null);if(caret.selection!=''){if(node.nodeName=='#text')
node=node.parentNode;if(node.nodeName.match(/h[\d]/i))
this.doc.execCommand('FormatBlock',false,'<div>');node.innerHTML=node.innerHTML.stripScripts().stripTags();$w('style align STYLE ALIGN').each(function(attribute){node.setAttribute(attribute,'');node.removeAttribute(attribute);});}
this.toolbar.select('li').each(function(button){button.removeClassName('active');if(button.hasClassName('heading')){$R(1,6).each(function(i){button.removeClassName('h'+i);});}});break;case'Heading':$R(1,6).each((function(i){this.toolbarButtons.heading.removeClassName('h'+i);}).bind(this));this.toolbarButtons.heading.addClassName(value);this.doc.execCommand('FormatBlock',false,'<'+value+'>');break;case'Indent':case'Outdent':this.doc.execCommand(action,false,null);break;case'JustifyLeft':case'JustifyCenter':case'JustifyRight':case'JustifyFull':this.doc.execCommand(action,false,null);$w('left center right full').each((function(type){this.toolbarButtons['justify_'+type].removeClassName('active');}).bind(this));button.addClassName('active');break;case'ForeColor':var caret=this.getCaret(),node=caret.node;if(caret.selection!=''){this.editor.focus();if(node.nodeName=='SPAN')
node.setAttribute('style','color:'+value+';')
else
this.insertHTML('<span style="color:'+value+';">'+caret.text+'</span>');}
break;case'CreateLink':var win,text,message,promptUrl,alertInvalidUrl;if(Q.IE)
this.oldCaret=this.getCaret();promptUrl=(function(){message='<input type="checkbox" name="q_new_window_check" class="target-check" /> open link in a new window?';win=new Q.Prompt('Link',message,{text:'http://',onConfirm:(function(link){if(link.blank()||link=='http://'){alertInvalidUrl();}else{var anchor,caret=this.oldCaret||this.getCaret();if(caret.selection!=''){anchor='<a href="'+link+'"';if(win.holder.down('input.target-check').checked)
anchor+=' target="_blank"';anchor+='>';anchor+=caret.text;anchor+='</a>';this.insertHTML(anchor);}
this.sync();}}).bind(this)});}).bind(this);alertInvalidUrl=(function(){new Q.Alert('',Q.I18n.t('textarea.create_link.invalid_link',{fallback:'The link you entered is invalid, please try again.'}),{onConfirm:(function(){promptUrl();}).bind(this)});}).bind(this);if(this.toolbarButtons.create_link.hasClassName('active')){this.doc.execCommand('Unlink',false,null);this.toolbarButtons.create_link.removeClassName('active');}else{if(this.doc.selection)
text=this.doc.selection.createRange().text;else
text=this.editor.contentWindow.getSelection();if(text==''){new Q.Alert('',Q.I18n.t('textarea.create_link.select_text',{fallback:'Please first select a part of the text you want to be linked.'}));break;}
promptUrl();}
break;case'InsertImage':var promptUrl,alertUrl,promptAlt,imageUrl,imageAlt,insertImage;if(Q.IE)
this.oldCaret=this.getCaret();promptUrl=(function(){new Q.Prompt(Q.I18n.t('textarea.insert_image.image',{fallback:'Image'}),Q.I18n.t('textarea.insert_image.enter_url',{fallback:'Enter the url of the image you want to insert:'}),{text:'http://',onConfirm:(function(value){var match;if(match=value.match(/^https?:\/\/[a-z0-9\-]+\.[a-z0-9\-]+(.*?)\/(.*)\.[a-z]{2,4}(\?.*)?$/i)){imageUrl=value;imageAlt=match[2].split('/').last().gsub(/(\-|\.|\+|_)/,' ');promptAlt();}else{alertUrl();}}).bind(this)});}).bind(this);alertUrl=function(){new Q.Alert(Q.I18n.t('textarea.insert_image.image',{fallback:'Oops!'}),Q.I18n.t('textarea.insert_image.invalid_url',{fallback:'The image address you entered is not correct, try again.'}),{onConfirm:promptUrl});}
promptAlt=(function(){new Q.Prompt(Q.I18n.t('textarea.insert_image.description',{fallback:'Description'}),Q.I18n.t('textarea.insert_image.image_alt',{fallback:'Excellent! Now enter a description:'}),{text:imageAlt,onConfirm:(function(value){imageAlt=value.HTMLencode();insertImage();}).bind(this)});}).bind(this);insertImage=(function(){this.insertHTML('<img alt="'+imageAlt+'" src="'+imageUrl+'" />');this.sync();}).bind(this);promptUrl();break;}
this.sync();},insertHTML:function(html){if(Q.IE){var range=this.oldCaret.range;range.pasteHTML(html);range.collapse(false);range.select();}else{this.doc.execCommand('insertHTML',false,html);}},setButtonState:function(){(function(){var selection,range,parentNode,headingSelect,level=0;headingSelect=this.toolbarButtons.heading.down('ul');this.toolbar.select('li').each(function(button){button.removeClassName('active');});$R(1,6).each((function(i){this.toolbarButtons.heading.removeClassName('h'+i);}).bind(this));if(this.doc.selection){selection=this.doc.selection;range=selection.createRange();try{parentNode=range.parentElement();}catch(e){return false;}}else{try{selection=this.editor.contentWindow.getSelection();}catch(e){return false;}
range=selection.getRangeAt(0);parentNode=range.commonAncestorContainer;}
while(parentNode.nodeType==3){parentNode=parentNode.parentNode;}
while(parentNode.nodeName!='BODY'){switch(parentNode.nodeName.toLowerCase()){case'a':this.toolbarButtons.create_link.addClassName('active');break;case'b':case'strong':this.toolbarButtons.bold.addClassName('active');break;case'i':case'em':this.toolbarButtons.italic.addClassName('active');break;case'u':this.toolbarButtons.underline.addClassName('active');break;case's':case'strike':this.toolbarButtons.strike_through.addClassName('active');break;case'ol':this.toolbarButtons.insert_ordered_list.addClassName('active');this.toolbarButtons.insert_unordered_list.removeClassName('active');break;case'ul':this.toolbarButtons.insert_unordered_list.addClassName('active');this.toolbarButtons.insert_ordered_list.removeClassName('active');break;case'li':break;case'h1':case'h2':case'h3':case'h4':case'h5':case'h6':this.toolbarButtons.heading.addClassName(parentNode.nodeName.toLowerCase());break;case'div':if(parentNode.getAttribute('style')){var style,match;style=parentNode.getAttribute('style').toString();match=style.match(/text\-align: ?(left|center|right|justify);/i);if(match){switch(match[1]){default:this.toolbarButtons['justify_'+match[1]].addClassName('active');break;case'justify':this.toolbarButtons.justify_full.addClassName('active');break;}}}
break;}
parentNode=parentNode.parentNode;level++;}
return true;}).bind(this).delay(0.1);},toggleToolbarState:function(){if(this.active){this.toolbar.select('li').each(function(button){if(button.hasClassName('q-heading-select')){button.down('ul').hide();}else if(button.hasClassName('edit-code')){button.addClassName('active');}else{button.removeClassName('active').addClassName('inactive');if(button.hasClassName('fore-color'))
button.down('input').hide();}});this.codearea.show();this.editor.hide();this.active=false;}else{this.toolbar.select('li').each(function(button){button.removeClassName('active').removeClassName('inactive');if(button.hasClassName('fore-color'))
button.down('input').show();});this.codearea.hide();this.editor.show();this.active=true;}},sync:function(thorough){var body=this.doc.getElementById('q_editor');if(this.active)
this.codearea.setValue(this.polishCode(body.innerHTML));else
body.innerHTML=this.polishCode(this.codearea.value);Q.callback('onType',this);if(this.active&&thorough)
this.doc.getElementById('q_editor').innerHTML=this.codearea.value;},polishCode:function(code){return code.gsub(/<embed width="0" height="0" type="application\/x-safari-validator">/i,'').gsub(/<div>(<br>|&nbsp;)<\/div>/i,'<br/>').gsub(/<br ?>/i,'<br/>').gsub(/<p(.*)?>/i,function(match){return'<div'+match[1]+'>';}).gsub(/<\/p>/i,'</div>');},getValue:function(){this.sync(true);return this.doc.getElementById('q_editor').innerHTML;},setValue:function(value){this.doc.getElementById('q_editor').innerHTML=value;this.codearea.setValue(value);},getCaret:function(){var caret={node:null};if(this.doc.selection){caret.selection=this.doc.selection;if(caret.selection=='')return caret;caret.range=caret.selection.createRange();caret.node=caret.range.parentElement();caret.text=caret.range.text;}else{caret.selection=this.editor.contentWindow.getSelection();if(caret.selection=='')return caret;caret.range=caret.selection.getRangeAt(0);caret.node=caret.range.commonAncestorContainer;caret.text=caret.selection;}
return caret;}});

/*
 * Q.Tooltip 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Q=='undefined')
alert("Q is not loaded. Please make sure that your page includes q.js before it includes q.tooltip.js");Q.Tooltip=Class.create(Q.Base,{initialize:function($super,options){var unique_id="q_tooltip_"+Math.random().toMD5(),key;$super();if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();this.options=$H(this.options).merge({klass:".q-tip",style:"dark",left:20,top:20,width:200,delay:0.5}).merge(options).toObject();Q.addCssFor("tooltip");this.active=false;this.titles={};this.holder_width=this.options.width+26;this.available_width=this.div.getWidth();document.observe("resize:end",(function(){this.available_width=this.div.getWidth();}).bind(this));Q.register('tooltip');this.build();$$(this.options.klass).each((function(element,i){var title=element.title||"";if(element.id.blank()){key=unique_id+"_"+i;element.id=key;}else{key=element.id;}
title.scan(/!(([^ ]+)\.(jpg|jpeg|png|gif|JPG|JPEG|PNG|GIF))!/,function(m){title=title.replace(m[0],'<img src="'+m[1]+'" alt="'+m[2]+'" />');});title=title.gsub(/(\n|\r)/,'<br/>');this.titles[key]=title;element.removeAttribute("title");element.observe("mouseover",(function(event){this.show(element,event);}).bind(this));element.observe("mouseout",(function(){this.hide();}).bind(this));}).bind(this));},build:function(){var holder=this.holder=new Element("div"),background=this.buildBackground(this.options.style);background.insert(new Element("div").addClassName("q-tooltip-center").setStyle({maxWidth:this.options.width+"px"}));holder.addClassName("q-tooltip q-"+this.options.style).insert(background).hide();this.div.insert(holder);},show:function(element,event){var position=event.pointer(),new_pos;new_pos={left:position.x+this.options.left,top:position.y+this.options.top}
if(this.available_width<new_pos.left+this.holder_width)
new_pos.left=this.available_width-this.holder_width;if(!this.holder.visible()&&!this.titles[element.id].blank())
this.holder.setStyle({left:new_pos.left+"px",top:new_pos.top+"px"}).appear({duration:0.2,delay:this.options.delay,queue:{position:"end",limit:2,scope:"q_tooltip"}}).down(".q-tooltip-center").update(this.titles[element.id]);},hide:function(){var queue=Effect.Queues.get("q_tooltip");queue.each(function(effect){effect.cancel();});this.holder.hide();}});

/*
 * Q.Window 0.1.0
 *
 * Copyright (c) 2010 Boys Abroad (Wout Fierens)
 *
 * Licensed under the MIT (http://opensource.org/licenses/mit-license.php) license.
 */

if(typeof Q=='undefined')
alert("Q is not loaded. Please make sure that your page includes q.js before it includes q.window.js");Q.Window=Class.create(Q.Base,{initialize:function($super,options){$super();this.persistent=false;if(typeof options=="string"&&options.isJSON())
options=options.evalJSON();this.options=$H(this.options).merge({style:'dark',position:'fixed',draggable:true,closeButton:'right',left:50,top:50,minWidth:300,minHeight:50,maxWidth:3000,maxHeight:3000,hide:false}).merge(options).toObject();if(this.options.position=="static"||this.options.position=="inherit")
this.options.position="relative";Q.addCssFor('window');Q.register('window');this.build();},build:function(){var win,close,resize,title,label,background,source;win=this.holder=new Element("div");if(this.options.id)
win.id=this.options.id;if(this.options.div)
this.div=$(this.options.div);win.addClassName("q-window q-"+this.options.style).setStyle({position:this.options.position,left:parseInt(this.options.left)+"px",top:parseInt(this.options.top)+"px"}).hide();if(this.options.closeButton){close=new Element("div").addClassName("q-window-close");if(this.options.closeButton=='left')
close.addClassName("q-left");close.onclick=(function(){this.hide(true);}).bind(this);win.insert(close);}
background=this.buildBackground(this.options.style);win.insert(background);win.content=new Element("div");background.center.insert(win.content)
win.center=background.center;if(this.options.resizable){resize=new Element("div").addClassName("q-window-resize");win.insert(resize);resize.observe("mousedown",(function(event){event.preventDefault?event.preventDefault():event.returnValue=false;resize.resizing=true;var size={width:win.down(".q-content").getWidth(),height:win.down(".q-content").getHeight()}
Q.callback('onStartResize',this,size);Q.callback('onResize',this,size);}).bind(this));document.observe("mousemove",(function(event){if(resize.resizing){event.preventDefault?event.preventDefault():event.returnValue=false;var width=event.pointerX()-parseInt(win.getStyle("left"))-8,height=event.pointerY()-parseInt(win.getStyle("top"))-8,offset;if(this.options.position=="fixed"){offset=document.viewport.getScrollOffsets();width-=offset.left;height-=offset.top;}
if(this.validWidth(width))
win.down(".q-content").setStyle({width:width+"px"});if(this.validHeight(height))
win.down(".q-content").setStyle({height:height+"px"});Q.callback('onResize',this,{width:win.down(".q-content").getWidth(),height:win.down(".q-content").getHeight()});}}).bind(this));document.observe("mouseup",(function(){if(resize.resizing){resize.resizing=false;Q.callback('onEndResize',this,{width:win.down(".q-content").getWidth(),height:win.down(".q-content").getHeight()});}}).bind(this));}
title=new Element("div").addClassName("q-window-title");win.insert(title);if(this.options.draggable)
new Draggable(win,{handle:title,zindex:100000,onStart:(function(){Q.callback('onStartDrag',this);}).bind(this),onDrag:(function(){Q.callback('onDrag',this);}).bind(this),onEnd:(function(){Q.callback('onEndDrag',this);}).bind(this)});title.style.cursor="move";if(this.options.title){label=new Element("p").addClassName("q-window-label").update(this.options.title);title.insert(label);}
this.holder.observe("mouseup",(function(){this.restack();Q.callback('onFocus',this);}).bind(this));if(trigger=$(this.options.trigger)){trigger.observe("click",(function(){if(!this.visible())
this.onShow();}).bind(this));}else if(!this.options.hide){this.onShow();}
this.div.insert(win);this.initSize(win);if(this.options.source&&(source=$(this.options.source))){this.update(source.innerHTML);source.remove();}else{this.update(this.options.text);}},initSize:function(win){var width=300,height;if(this.options.width)
width=this.options.width;if(this.options.height)
height=this.options.height;if(parseInt(width))
width+="px";else
width="auto";if(parseInt(height))
height+="px";else
height="auto";win.center.setStyle({width:width,height:height,minWidth:this.options.minWidth+"px",minHeight:this.options.minHeight+"px",maxWidth:this.options.maxWidth+"px",maxHeight:this.options.maxHeight+"px"});},update:function(content){this.holder.content.update(new Element("div").setStyle({height:"10px"})).insert(content);return this;},insert:function(content,options){this.holder.content.insert(content,options);return this;},visible:function(){return this.holder.visible();},validWidth:function(value){if(this.options.minWidth&&value<this.options.minWidth)
return false;if(this.options.maxWidth&&value>this.options.maxWidth)
return false;return true;},validHeight:function(value){if(this.options.minHeight&&value<this.options.minHeight)
return false;if(this.options.maxHeight&&value>this.options.maxHeight)
return false;return true;},restack:function(){$("q_wrapper").select("div.q-window").each(function(win){win.style.zIndex=win.hasClassName("q-window-blocking")?99997:99995;});this.holder.style.zIndex=this.holder.hasClassName("q-window-blocking")?99998:99996;},onShow:function(){this.restack();this.show();}});Q.Alert=Class.create(Q.Window,{initialize:function($super,title,message,options){var dim=document.viewport.getDimensions()
options=$H({width:300,minHeight:30,draggable:false,closeButton:false,left:dim.width/2-(options&&options.width?options.width/2:150),top:dim.height/3-75,title:title,confirmLabel:"Ok!"}).merge(options||{}).toObject();$super(options);if(trigger=$(options.trigger)){trigger.observe("click",(function(){this.alert(title,message,options);}).bind(this));}else{this.alert(title,message,options);}},alert:function(title,message,options){var dim=document.viewport.getDimensions(),next,win,msg,wrapper,onConfirm;onConfirm=(function(){document.stopObserving("keydown",this.confirmWithEnter);document.stopObserving("keydown",this.cancelWithEscape);document.stopObserving("keydown",this.onWindowResize);this.hide();if(typeof this.textarea!='undefined')
Q.callback('onConfirm',this,this.textarea.value);else
Q.callback('onConfirm',this);this.remove();}).bind(this);this.confirmWithEnter=(function(event){if(event.keyCode==13){next.focus();onConfirm();}}).bind(this);document.observe("keydown",this.confirmWithEnter);this.onWindowResize=(function(){var dim=document.viewport.getDimensions();this.holder.setStyle({left:(dim.width/2-(options&&options.width?options.width/2:150))+'px',top:(dim.height/3-75)+'px'});}).bind(this);(document.onresize?document:window).observe("resize",this.onWindowResize);this.holder.addClassName("q-window-blocking").setStyle({zIndex:99998});this.protection=new Element("div").addClassName("q-protective-layer");this.div.insert({top:this.protection});this.protection.hide();next=new Element("input",{type:"button",value:options.confirmLabel}).addClassName("q-button q-next-button");next.onclick=(function(){onConfirm();}).bind(this);wrapper=new Element("div").addClassName("q-buttons-wrapper");msg=new Element("div").setStyle({margin:"10px 10px 20px 10px"}).update(message);wrapper.insert(next);this.update(msg).insert(wrapper);this.persistent=true;this.show();this.protection.appear({duration:0.1,to:0.5});},remove:function(){this.protection.fade({duration:0.01});(function(){try{this.protection.remove();delete this;}catch(e){}}).bind(this).delay(0.2);}})
Q.Confirm=Class.create(Q.Alert,{initialize:function($super,title,message,options){options=$H({cancelLabel:"Cancel"}).merge(options||{}).toObject();$super(title,message,options);if(trigger=$(options.trigger)){trigger.observe("click",(function(){this.confirm(options);}).bind(this));}else{this.confirm(options);}},confirm:function(options){var cancel,clearer,onCancel;onCancel=(function(){document.stopObserving("keydown",this.confirmWithEnter);document.stopObserving("keydown",this.cancelWithEscape);document.stopObserving("keydown",this.onWindowResize);this.hide();Q.callback('onCancel',this);this.remove();}).bind(this);this.cancelWithEscape=(function(event){if(event.keyCode==27)
onCancel();}).bind(this);document.observe("keydown",this.cancelWithEscape);cancel=new Element("input",{type:"button",value:options.cancelLabel}).addClassName("q-button q-cancel-button");cancel.onclick=(function(){onCancel();}).bind(this);this.holder.down("div.q-buttons-wrapper").insert({top:cancel});}});Q.Prompt=Class.create(Q.Confirm,{initialize:function($super,title,message,options){$super(title,message,options);if(trigger=$(options.trigger)){trigger.observe("click",(function(){this.prompt(options);}).bind(this));}else{this.prompt(options);}},prompt:function(options){this.textarea=new Element("textarea").addClassName("q-textarea").setValue(options.text)
this.holder.down("div.q-buttons-wrapper").insert({before:this.textarea});}});

//  Lightview 2.5 - 17-5-2009
//  Copyright (c) 2008-2009 Nick Stakenburg (http://www.nickstakenburg.com)
//
//  Licensed under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License
//  http://creativecommons.org/licenses/by-nc-nd/3.0/

//  More information on this project:
//  http://www.nickstakenburg.com/projects/lightview/

var Lightview = {
  Version: '2.5',

  // Configuration
  options: {
    backgroundColor: '#ffffff',                            // Background color of the view
    border: 12,                                            // Size of the border
    buttons: {
      opacity: {                                           // Opacity of inner buttons
        disabled: 0.4,
        normal: 0.75,
        hover: 1
      },
      side: { display: true },                             // Toggle side buttons
      innerPreviousNext: { display: true },                // Toggle the inner previous and next button
      slideshow: { display: true },                        // Toggle slideshow button
      topclose: { side: 'right' }                          // 'right' or 'left'                    
    },
    controller: {                                          // The controller is used on sets
      backgroundColor: '#4d4d4d',
      border: 6,
      buttons: {
        innerPreviousNext: true,
        side: false
      },
      margin: 18,
      opacity: 0.7,
      radius: 6,
      setNumberTemplate: '#{position} of #{total}'
    },
    cyclic: false,                                         // Makes galleries cyclic, no end/begin
    images: '/images/lightview/',                          // The directory of the images, from this file
    imgNumberTemplate: 'Image #{position} of #{total}',    // Want a different language? change it here
    keyboard: true,                                        // Toggle keyboard buttons
    menubarPadding: 6,                                     // Space between menubar and content in px
    overlay: {                                             // Overlay
      background: '#000',                                  // Background color, Mac Firefox & Mac Safari use overlay.png
      close: true,
      opacity: 0.85,
      display: true
    },
    preloadHover: false,                                   // Preload images on mouseover
    radius: 12,                                            // Corner radius of the border
    removeTitles: true,                                    // Set to false if you want to keep title attributes intact
    resizeDuration: 0.2,                                   // The duration of the resize effect in seconds
    slideshowDelay: 5,                                     // Delay in seconds before showing the next slide
    titleSplit: '::',                                      // The characters you want to split title with
    transition: function(pos) {                            // Or your own transition
      //return ((pos/=0.5) < 1 ? 0.5 * Math.pow(pos, 4) : -0.5 * ((pos-=2) * Math.pow(pos,3) - 2));
      return ((pos/=0.5) < 1 ? 0.5 * Math.pow(pos, 4) : -0.5 * ((pos-=2) * Math.pow(pos,3) - 2));
    },
    viewport: true,                                        // Stay within the viewport, true is recommended
    zIndex: 5000,                                          // zIndex of #lightview, #overlay is this -1

    startDimensions: {                                     // Dimensions Lightview starts at
      width: 100,
      height: 100
    },
    closeDimensions: {                                     // Modify if you've changed the close button images
      large: { width: 77, height: 22 },
      small: { width: 25, height: 22 }
    },
    sideDimensions: {                                      // Modify if you've changed the side button images
      width: 16,
      height: 22
    },

    defaultOptions : {                                     // Default options for each type of view
      image: {
        menubar: 'bottom',
        closeButton: 'large'
      },
      gallery: {
        menubar: 'bottom',
        closeButton: 'large'
      },
      ajax:   {
        width: 400,
        height: 300,
        menubar: 'top',
        closeButton: 'small',
        overflow: 'auto'
      },
      iframe: {
        width: 400,
        height: 300,
        menubar: 'top',
        scrolling: true,
        closeButton: 'small'
      },
      inline: {
        width: 400,
        height: 300,
        menubar: 'top',
        closeButton: 'small',
        overflow: 'auto'
      },
      flash: {
        width: 400,
        height: 300,
        menubar: 'bottom',
        closeButton: 'large'
      },
      quicktime: {
        width: 480,
        height: 220,
        autoplay: true,
        controls: true,
        closeButton: 'large'
      }
    }
  },
  classids: {
    quicktime: 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',
    flash: 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
  },
  codebases: {
    quicktime: 'http://www.apple.com/qtactivex/qtplugin.cab#version=7,5,5,0',
    flash: 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0'
  },
  errors: {
    requiresPlugin: "<div class='message'> The content your are attempting to view requires the <span class='type'>#{type}</span> plugin.</div><div class='pluginspage'><p>Please download and install the required plugin from:</p><a href='#{pluginspage}' target='_blank'>#{pluginspage}</a></div>"
  },
  mimetypes: {
    quicktime: 'video/quicktime',
    flash: 'application/x-shockwave-flash'
  },
  pluginspages: {
    quicktime: 'http://www.apple.com/quicktime/download',
    flash: 'http://www.adobe.com/go/getflashplayer'
  },
  // used with auto detection
  typeExtensions: {
    flash: 'swf',
    image: 'bmp gif jpeg jpg png',
    iframe: 'asp aspx cgi cfm htm html jsp php pl php3 php4 php5 phtml rb rhtml shtml txt',
    quicktime: 'avi mov mpg mpeg movie'
  }
};

eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(u(){G l=!!1d.8P("3j").5h,2H=1l.1T.2I&&(u(a){G b=E 4p("8Q ([\\\\d.]+)").8R(a);O b?3J(b[1]):-1})(35.4q)<7,2t=(1l.1T.5i&&!1d.3K),2R=35.4q.22("6x")>-1&&3J(35.4q.3L(/6x[\\/\\s](\\d+)/)[1])<3,4r=!!35.4q.3L(/8S/i)&&(2t||2R);18.1o(11,{8T:"1.6.0.3",8U:"1.8.2",V:{1b:"5j",3k:"Y"},5k:u(a){q((8V 1J[a]=="8W")||(n.5l(1J[a].8X)<n.5l(n["6y"+a]))){8Y("11 8Z "+a+" >= "+n["6y"+a]);}},5l:u(a){G v=a.2S(/6z.*|\\./g,"");v=4s(v+"0".90(4-v.1s));O a.22("6z")>-1?v-1:v},5m:u(){n.5k("1l");q(!!1J.17&&!1J.6A){n.5k("6A")}q(/^(91?:\\/\\/|\\/)/.4t(n.F.1f)){n.1f=n.F.1f}10{G a=/Y(?:-[\\w\\d.]+)?\\.92(.*)/;n.1f=(($$("93 94[1x]").6B(u(s){O s.1x.3L(a)})||{}).1x||"").2S(a,"")+n.F.1f}q(!l){q(1d.5n>=8&&!1d.6C.3l){1d.6C.95("3l","96:97-98-99:9a","#5o#6D")}10{1d.1i("5p:3M",u(){1d.9b().9c("3l\\\\:*","9d: 3N(#5o#6D);")})}}},5q:u(){n.1C=n.F.1C;n.W=(n.1C>n.F.W)?n.1C:n.F.W;n.1K=n.F.1K;n.1U=n.F.1U;n.4u()}});18.1o(11,{6E:14,2g:u(){G a=3O.9e;a.5r++;q(a.5r==n.6E){$(1d.29).5s("Y:3M")}}});11.2g.5r=0;18.1o(11,{4u:u(){n.Y=E N("U",{2T:"Y"});G d,3m,4v=1V(n.1U);q(2t){n.Y.19=u(){n.I("1j:-3n;1e:-3n;1p:1W;");O n};n.Y.1c=u(){n.I("1p:1y");O n};n.Y.1y=u(){O(n.1L("1p")=="1y"&&3J(n.1L("1e").2S("M",""))>-6F)}}$(1d.29).Q(n.2u=E N("U",{2T:"6G"}).I({2U:n.F.2U-1,1b:(!(2R||2H))?"4w":"36",2a:4r?"3N("+n.1f+"2u.1w) 1e 1j 3o":n.F.2u.2a}).1q(4r?1:n.F.2u.1F).19()).Q(n.Y.I({2U:n.F.2U,1e:"-3n",1j:"-3n"}).1q(0).Q(n.6H=E N("U",{R:"9f"}).Q(n.3P=E N("3p",{R:"9g"}).Q(n.6I=E N("1D",{R:"9h"}).I(3m=18.1o({1M:-1*n.1U.H+"M"},4v)).Q(n.4x=E N("U",{R:"5t"}).I(18.1o({1M:n.1U.H+"M"},4v)).Q(E N("U",{R:"1G"})))).Q(n.6J=E N("1D",{R:"9i"}).I(18.1o({6K:-1*n.1U.H+"M"},4v)).Q(n.4y=E N("U",{R:"5t"}).I(3m).Q(E N("U",{R:"1G"}))))).Q(n.6L=E N("U",{R:"6M"}).Q(n.4z=E N("U",{R:"5t 9j"}).Q(n.9k=E N("U",{R:"1G"})))).Q(E N("3p",{R:"9l"}).Q(E N("1D",{R:"6N 9m"}).Q(d=E N("U",{R:"9n"}).I({J:n.W+"M"}).Q(E N("3p",{R:"6O 9o"}).Q(E N("1D",{R:"6P"}).Q(E N("U",{R:"2v"})).Q(E N("U",{R:"38"}).I({1j:n.W+"M"})))).Q(E N("U",{R:"6Q"})).Q(E N("3p",{R:"6O 9p"}).Q(E N("1D",{R:"6P"}).I("1N-1e: "+(-1*n.W)+"M").Q(E N("U",{R:"2v"})).Q(E N("U",{R:"38"}).I("1j: "+(-1*n.W)+"M")))))).Q(n.4A=E N("1D",{R:"9q"}).I("J: "+(9r-n.W)+"M").Q(E N("U",{R:"9s"}).Q(E N("U",{R:"6R"}).I("1N-1e: "+n.W+"M").Q(n.2V=E N("U",{R:"9t"}).1q(0).I("3q: 0 "+n.W+"M").Q(n.6S=E N("U",{R:"9u 38"})).Q(n.1r=E N("U",{R:"9v 6T"}).Q(n.2h=E N("U",{R:"1G 6U"}).I(1V(n.F.1K.3a)).I({2a:n.F.12}).1q(n.F.1E.1F.3b)).Q(n.2W=E N("3p",{R:"9w"}).Q(n.5u=E N("1D",{R:"9x"}).Q(n.1H=E N("U",{R:"9y"})).Q(n.2i=E N("U",{R:"9z"}))).Q(n.5v=E N("U",{R:"9A"}).Q(n.3Q=E N("1D",{R:"9B"}).Q(E N("U"))).Q(n.4B=E N("1D",{R:"9C"}).Q(n.9D=E N("U",{R:"1G"}).1q(n.F.1E.1F.3b).I({12:n.F.12}).1O(n.1f+"9E.1w",{12:n.F.12})).Q(n.9F=E N("U",{R:"1G"}).1q(n.F.1E.1F.3b).I({12:n.F.12}).1O(n.1f+"9G.1w",{12:n.F.12}))).Q(n.2b=E N("1D",{R:"9H"}).Q(n.3c=E N("U",{R:"1G"}).1q(n.F.1E.1F.3b).I({12:n.F.12}).1O(n.1f+"6V.1w",{12:n.F.12})))))).Q(n.6W=E N("U",{R:"9I "}))))).Q(n.3r=E N("U",{R:"6X"}).Q(n.9J=E N("U",{R:"1G"}).I("2a: 3N("+n.1f+"3r.5w) 1e 1j 4C-3o")))).Q(E N("1D",{R:"6N 9K"}).Q(d.9L(2c))).Q(n.1X=E N("1D",{R:"9M"}).19().I("1N-1e: "+n.W+"M; 2a: 3N("+n.1f+"9N.5w) 1e 1j 3o"))))).Q(E N("U",{2T:"3R"}).19());G f=E 2j();f.1z=u(){f.1z=1l.2w;n.1U={H:f.H,J:f.J};G a=1V(n.1U),3m;n.3P.I({23:0-(f.J/2).2k()+"M",J:f.J+"M"});n.6I.I(3m=18.1o({1M:-1*n.1U.H+"M"},a));n.4x.I(18.1o({1M:a.H},a));n.6J.I(18.1o({6K:-1*n.1U.H+"M"},a));n.4y.I(3m);n.2g()}.X(n);f.1x=n.1f+"2x.1w";$w("2V 1H 2i 3Q").3S(u(e){n[e].I({12:n.F.12})}.X(n));G g=n.6H.2y(".2v");$w("6Y 6Z bl br").1g(u(a,i){q(n.1C>0){n.5x(g[i],a)}10{g[i].Q(E N("U",{R:"38"}))}g[i].I({H:n.W+"M",J:n.W+"M"}).70("2v"+a.1P());n.2g()}.X(n));n.Y.2y(".6Q",".38",".6R").3s("I",{12:n.F.12});G S={};$w("2x 1h 2l").1g(u(s){n[s+"3t"].1Q=s;G b=n.1f+s+".1w";q(s=="2l"){S[s]=E 2j();S[s].1z=u(){S[s].1z=1l.2w;n.1K[s]={H:S[s].H,J:S[s].J};G a=n.F.1E.2l.1Q,2e=18.1o({"5y":a,23:n.1K[s].J+"M"},1V(n.1K[s]));2e["3q"+a.1P()]=n.W+"M";n[s+"3t"].I(2e);n.6L.I({J:S[s].J+"M",1e:-1*n.1K[s].J+"M"});n[s+"3t"].5z().1O(b).I(1V(n.1K[s]));n.2g()}.X(n);S[s].1x=n.1f+s+".1w"}10{n[s+"3t"].1O(b)}},n);G C={};$w("3a 5A").1g(u(a){C[a]=E 2j();C[a].1z=u(){C[a].1z=1l.2w;n.1K[a]={H:C[a].H,J:C[a].J};n.2g()}.X(n);C[a].1x=n.1f+"71"+a+".1w"},n);G L=E 2j();L.1z=u(){L.1z=1l.2w;n.3r.I({H:L.H+"M",J:L.J+"M",23:-0.5*L.J+0.5*n.W+"M",1M:-0.5*L.H+"M"});n.2g()}.X(n);L.1x=n.1f+"3r.5w";G h=E 2j();h.1z=u(a){h.1z=1l.2w;G b={H:h.H+"M",J:h.J+"M"};n.2b.I(b);n.3c.I(b);n.2g()}.X(n);h.1x=n.1f+"72.1w";$w("2x 1h").1g(u(s){G S=s.1P(),i=E 2j();i.1z=u(){i.1z=1l.2w;n["3u"+S+"3v"].I({H:i.H+"M",J:i.J+"M"});n.2g()}.X(n);i.1x=n.1f+"9O"+s+".1w";n["3u"+S+"3v"].1X=s},n);$w("2b 4B 3Q").1g(u(c){n[c].19=n[c].19.1A(u(a,b){n.2e.1b="36";a(b);O n});n[c].1c=n[c].1c.1A(u(a,b){n.2e.1b="9P";a(b);O n})},n);n.Y.2y("*").3s("I",{2U:n.F.2U+1});n.Y.19();n.2g()},73:u(){17.2J.2m("Y").3S(u(e){e.74()});n.1Y=1I;q(n.y.1Z()){n.75=n.76;q(n.13&&!n.13.1y()){n.13.I("1p:1W").1c();n.3d.1q(0)}}10{n.75=1I;n.13.19()}q(4s(n.4z.1L("23"))<n.1K.2l.J){n.5B(2K)}n.77();n.78();E 17.1m({V:n.V,1t:u(){$w("1e 3T").1g(u(a){G b=a.1P();n["3w"+b].2n();G c={};n["3w"+b]=E N("U",{R:"9Q"+b}).19();c[a]=n["3w"+b];n.2V.Q(c)}.X(n))}.X(n)});n.5C();n.1n=1I},5D:u(){q(!n.3U||!n.3V){O}n.3V.Q({2X:n.3U.I({2z:n.3U.79})});n.3V.2n();n.3V=1I},1c:u(b){n.1u=1I;G c=18.7a(b);q(18.7b(b)||c){q(c&&b.3x("#")){n.1c({1k:b,F:18.1o({4D:2c},3O[1]||{})});O}n.1u=$(b);q(!n.1u){O}n.1u.9R();n.y=n.1u.24||E 11.3W(n.1u)}10{q(b.1k){n.1u=$(1d.29);n.y=E 11.3W(b)}10{q(18.7c(b)){n.1u=n.4E(n.y.26)[b];n.y=n.1u.24}}}q(!n.y.1k){O}n.73();q(n.y.2o()||n.y.1Z()){n.7d(n.y.26);n.1n=n.5E(n.y.26);q(n.y.1Z()){n.2A=n.1n.1s>1?n.7e:0;n.2Y=n.1n.9S(u(a){O a.2Z()})}}n.3X();n.7f();q(n.y.1k!="#3R"&&18.7g(11.4F).7h(" ").22(n.y.1a)>=0){q(!11.4F[n.y.1a]){$("3R").1B(E 4G(n.9T.9U).3K({1a:n.y.1a.1P(),5F:n.5G[n.y.1a]}));G d=$("3R").2f();n.1c({1k:"#3R",1H:n.y.1a.1P()+" 9V 9W",F:d});O 2K}}G e=18.1o({1r:"3T",2l:2K,5H:"9X",3Y:n.y.2o()&&n.F.1E.3Y.2z,5I:n.F.5I,2b:(n.y.2o()&&n.F.1E.2b.2z)||(n.2Y),2B:"1W",7i:n.F.2u.9Y,3Z:n.F.3Z},n.F.9Z[n.y.1a]||{});n.y.F=18.1o(e,n.y.F);q(n.y.1Z()){n.y.F.2l=(n.1n.1s<=1)}q(!(n.y.1H||n.y.2i||(n.1n&&n.1n.1s>1))&&n.y.F.2l){n.y.F.1r=2K}n.1R="3w"+(n.y.F.1r=="1e"?"7j":"7k");q(n.y.2Z()){q(!l&&!n.y.7l){n.y.7l=2c;G f=E N("3l:2p",{1x:n.y.1k,2z:"a0"}).I("J:5J;H:5J;");$(1d.29).Q(f);N.2n.3e(0.1,f)}q(n.y.2o()||n.y.1Z()){n.1b=n.1n.22(n.y);n.7m()}n.27=n.y.4H;q(n.27){n.4I()}10{n.5K();G f=E 2j();f.1z=u(){f.1z=1l.2w;n.4J();n.27={H:f.H,J:f.J};n.4I()}.X(n);f.1x=n.y.1k}}10{q(n.y.1Z()){n.1b=n.1n.22(n.y)}n.27=n.y.F.7n?m.2f():{H:n.y.F.H,J:n.y.F.J};n.4I()}},4K:(u(){u 5L(a,b,c){a=$(a);G d=1V(c);a.1B(E N("7o",{2T:"2C",1x:b,a1:"",a2:"4C"}).I(d))}G k=(u(){u 7p(a,b,c){a=$(a);G d=18.1o({"5y":"1j"},1V(c));G e=E N("3l:2p",{1x:b,2T:"2C"}).I(d);a.1B(e);e.4L=e.4L}u 7q(b,c,d){b=$(b);G f=1V(d),2p=E 2j();2p.1z=u(){3j=E N("3j",f);b.1B(3j);40{G a=3j.5h("2d");a.a3(2p,0,0,d.H,d.J)}41(e){5L(b,c,d)}}.X(n);2p.1x=c}q(1l.1T.2I){O 7p}10{O 7q}})();O u(){G c=n.7r(n.y.1k),2L=n.1Y||n.27;q(n.y.2Z()){G d=1V(2L);n[n.1R].I(d);q(n.1Y){k(n[n.1R],n.y.1k,2L)}10{5L(n[n.1R],n.y.1k,2L)}}10{q(n.y.5M()){4M(n.y.1a){2M"42":G f=18.5N(n.y.F.42)||{};G g=u(){n.4J();q(n.y.F.4D){n[n.1R].I({H:"1S",J:"1S"});n.27=n.5O(n[n.1R])}E 17.1m({V:n.V,1t:n.4N.X(n)})}.X(n);q(f.4O){f.4O=f.4O.1A(u(a,b){g();a(b)})}10{f.4O=g}n.5K();E a4.a5(n[n.1R],n.y.1k,f);2D;2M"2E":q(n.1Y){2L.J-=n.3f.J}n[n.1R].1B(n.2E=E N("2E",{a6:0,a7:0,1x:n.y.1k,2T:"2C",2q:"a8"+(7s.a9()*aa).2k(),7t:(n.y.F&&n.y.F.7t)?"1S":"4C"}).I(18.1o({W:0,1N:0,3q:0},1V(2L))));2D;2M"4P":G h=n.y.1k,2r=$(h.5P(h.22("#")+1));q(!2r||!2r.43){O}G i=2r.2f();2r.Q({ab:n.3V=E N(2r.43).19()});2r.79=2r.1L("2z");n.3U=2r.1c();n[n.1R].1B(n.3U);n[n.1R].2y("2y, 3y, 5Q").1g(u(b){n.44.1g(u(a){q(a.1u==b){b.I({1p:a.1p})}})}.X(n));q(n.y.F.4D){n.27=i;E 17.1m({V:n.V,1t:n.4N.X(n)})}2D}}10{G j={20:"3y",2T:"2C",H:2L.H,J:2L.J};4M(n.y.1a){2M"45":18.1o(j,{5F:n.5G[n.y.1a],3z:[{20:"2F",2q:"7u",2N:n.y.F.7u},{20:"2F",2q:"7v",2N:"ac"},{20:"2F",2q:"13",2N:n.y.F.7w},{20:"2F",2q:"ad",2N:2c},{20:"2F",2q:"1x",2N:n.y.1k},{20:"2F",2q:"7x",2N:n.y.F.7x||2K}]});18.1o(j,1l.1T.2I?{ae:n.af[n.y.1a],ag:n.ah[n.y.1a]}:{2W:n.y.1k,1a:n.7y[n.y.1a]});2D;2M"46":18.1o(j,{2W:n.y.1k,1a:n.7y[n.y.1a],ai:"aj",5H:n.y.F.5H,5F:n.5G[n.y.1a],3z:[{20:"2F",2q:"ak",2N:n.y.1k},{20:"2F",2q:"al",2N:"2c"}]});q(n.y.F.7z){j.3z.47({20:"2F",2q:"am",2N:n.y.F.7z})}2D}n[n.1R].I(1V(2L)).1B(n.5R(j)).1c();q(n.y.48()){(u(){40{q("7A"7B $("2C")){$("2C").7A(n.y.F.7w)}}41(e){}}.X(n)).an()}}}}})(),5O:u(b){b=$(b);G d=b.ao(),5S=[],5T=[];d.47(b);d.1g(u(c){q(c!=b&&c.1y()){O}5S.47(c);5T.47({2z:c.1L("2z"),1b:c.1L("1b"),1p:c.1L("1p")});c.I({2z:"ap",1b:"36",1p:"1y"})});G e={H:b.aq,J:b.ar};5S.1g(u(r,a){r.I(5T[a])});O e},4Q:u(){G a=$("2C");q(a){4M(a.43.4R()){2M"3y":q(1l.1T.5i&&n.y.48()){40{a.7C()}41(e){}a.as=""}q(a.7D){a.2n()}10{a=1l.2w}2D;2M"2E":a.2n();q(1l.1T.at&&1J.7E.2C){5U 1J.7E.2C}2D;5o:a.2n();2D}}$w("7k 7j").1g(u(S){n["3w"+S].I("H:1S;J:1S;").1B("").19()},n)},7F:1l.K,4I:u(){E 17.1m({V:n.V,1t:n.4S.X(n)})},4S:u(){n.3g();q(!n.y.5V()){n.4J()}q(!((n.y.F.4D&&n.y.7G())||n.y.5V())){n.4N()}q(!n.y.4T()){E 17.1m({V:n.V,1t:n.4K.X(n)})}q(n.y.F.2l){E 17.1m({V:n.V,1t:n.5B.X(n,2c)})}},7H:u(){E 17.1m({V:n.V,1t:n.7I.X(n)});q(n.y.4T()){E 17.1m({3e:0.2,V:n.V,1t:n.4K.X(n)})}q(n.3A){E 17.1m({V:n.V,1t:n.7J.X(n)})}q(n.y.48()){E 17.1m({V:n.V,1t:N.I.X(n,n[n.1R],"1p:1y")})}},2O:u(){q(17.2J.2m(11.V.3k).5W.1s){O}n.1c(n.30().2O)},1h:u(){q(17.2J.2m(11.V.3k).5W.1s){O}n.1c(n.30().1h)},4N:u(){n.7F();G a=n.5X(),31=n.7K();q(n.y.F.3Z&&(a.H>31.H||a.J>31.J)){q(n.y.F.7n){n.1Y=31;n.3g();a=31}10{G c=n.7L(),b=31;q(n.y.4U()){G d=[31.J/c.J,31.H/c.H,1].au();n.1Y={H:(n.27.H*d).2k(),J:(n.27.J*d).2k()}}10{n.1Y={H:c.H>b.H?b.H:c.H,J:c.J>b.J?b.J:c.J}}n.3g();a=18.5N(n.1Y);q(n.y.4U()){a.J+=n.3f.J}}}10{n.3g();n.1Y=1I}n.5Y(a)},49:u(a){n.5Y(a,{28:0})},5Y:(u(){G e,4V,4W,7M,7N,2A,b;G f=(u(){G w,h;u 4X(p){w=(e.H+p*4V).4a(0);h=(e.J+p*4W).4a(0)}G a;q(2H){a=u(p){n.Y.I({H:(e.H+p*4V).4a(0)+"M",J:(e.J+p*4W).4a(0)+"M"});n.4A.I({J:h-1*n.W+"M"})}}10{q(2R){a=u(p){G v=n.4Y(),o=1d.3Z.7O();n.Y.I({1b:"36",1M:0,23:0,H:w+"M",J:h+"M",1j:(o[0]+(v.H/2)-(w/2)).4b()+"M",1e:(o[1]+(v.J/2)-(h/2)).4b()+"M"});n.4A.I({J:h-1*n.W+"M"})}}10{a=u(p){n.Y.I({1b:"4w",H:w+"M",J:h+"M",1M:((0-w)/2).2k()+"M",23:((0-h)/2-2A).2k()+"M"});n.4A.I({J:h-1*n.W+"M"})}}}O u(p){4X.3B(n,p);a.3B(n,p)}})();O u(a){G c=3O[1]||{};e=n.Y.2f();b=2*n.W;H=a.H?a.H+b:e.H;J=a.J?a.J+b:e.J;n.5Z();q(e.H==H&&e.J==J){E 17.1m({V:n.V,1t:n.60.X(n,a)});O}G d={H:H+"M",J:J+"M"};4V=H-e.H;4W=J-e.J;7M=4s(n.Y.1L("1M").2S("M",""));7N=4s(n.Y.1L("23").2S("M",""));2A=n.13.1y()?(n.2A/2):0;q(!2H){18.1o(d,{1M:0-H/2+"M",23:0-J/2+"M"})}q(c.28==0){f.3B(n,1)}10{n.61=E 17.7P(n.Y,0,1,18.1o({28:n.F.av,V:n.V,7Q:n.F.7Q,1t:n.60.X(n,a)},c),f.X(n))}}})(),60:u(a){q(!n.3f){O}G b=n[n.1R],4Z;q(n.y.F.2B=="1S"){4Z=b.2f()}b.I({J:(a.J-n.3f.J)+"M",H:a.H+"M"});q(n.y.F.2B!="1W"&&(n.y.5V()||n.y.7G())){q(1l.1T.2I){q(n.y.F.2B=="1S"){G c=b.2f();b.I("2B:1y");G d={7R:"1W",7S:"1W"},62=0,51=15;q(4Z.J>a.J){d.7S="1S";d.H=c.H-51;d.aw="7T";62=51}q(4Z.H-62>a.H){d.7R="1S";d.J=c.J-51;d.ax="7T"}b.I(d)}10{b.I({2B:n.y.F.2B})}}10{b.I({2B:n.y.F.2B})}}10{b.I("2B:1W")}n.3X();n.61=1I;n.7H()},7I:u(){E 17.1m({V:n.V,1t:n.5Z.X(n)});E 17.1m({V:n.V,1t:u(){n[n.1R].1c();n.3g();q(n.1r.1y()){n.1r.I("1p:1y").1q(1)}}.X(n)});E 17.ay([E 17.7U(n.2V,{7V:2c,52:0,53:1}),E 17.54(n.3P,{7V:2c})],{V:n.V,28:0.25,1t:u(){q(n.1u){n.1u.5s("Y:az")}}.X(n)});q(n.y.2o()||(n.2Y&&n.F.13.1E.1Q)){E 17.1m({V:n.V,1t:n.7W.X(n)})}},78:(u(){u 2X(){n.4Q();n.4z.I({23:n.1K.2l.J+"M"});n.5D();q(n.y.48()){n[n.1R].I("1p:1W")}}u 7X(p){n.2V.1q(p);n.3P.1q(p)}O u(){q(!n.Y.1y()){n.2V.1q(0);n.3P.1q(0);n.4Q();O}E 17.7P(n.Y,1,0,{28:0.2,V:n.V,1t:2X.X(n)},7X.X(n))}})(),7Y:u(){$w("5v 2W 5u 1H 2i 3Q 4B 2b 2h").1g(u(a){N.19(n[a])},n);n.1r.I("1p:1W").1q(0)},3g:u(){n.7Y();q(!n.y.F.1r){n.3f={H:0,J:0};n.63=0;n.1r.19()}10{n.1r.1c()}q(n.y.1H||n.y.2i){n.5u.1c();n.2W.1c()}q(n.y.1H){n.1H.1B(n.y.1H).1c()}q(n.y.2i){n.2i.1B(n.y.2i).1c()}q(n.1n&&n.1n.1s>1){q(n.y.1Z()){n.2G.1B(E 4G(n.F.13.7Z).3K({1b:n.1b+1,64:n.1n.1s}));q(n.13.1L("1p")=="1W"){n.13.I("1p:1y");q(n.65){17.2J.2m("Y").2n(n.65)}n.65=E 17.54(n.3d,{V:n.V,28:0.1})}}10{n.2W.1c();q(n.y.2Z()){n.5v.1c();n.3Q.1c().5z().1B(E 4G(n.F.aA).3K({1b:n.1b+1,64:n.1n.1s}));q(n.y.F.2b){n.3c.1c();n.2b.1c()}}}}G a=n.y.1Z();q((n.y.F.3Y||a)&&n.1n.1s>1){G b={2x:(n.F.32||n.1b!=0),1h:(n.F.32||((n.y.2o()||a)&&n.30().1h!=0))};$w("2x 1h").1g(u(z){G Z=z.1P(),3C=b[z]?"80":"1S";q(a){n["13"+Z].I({3C:3C}).1q(b[z]?1:n.F.1E.1F.66)}10{n["3u"+Z+"3v"].I({3C:3C}).1q(b[z]?n.F.1E.1F.3b:n.F.1E.1F.66)}}.X(n));q(n.y.F.3Y||n.F.13.3Y){n.4B.1c()}}n.4c.1q(n.2Y?1:n.F.1E.1F.66).I({3C:n.2Y?"80":"1S"});n.81();q(!n.1r.aB().6B(N.1y)){n.1r.19();n.y.F.1r=2K}n.82()},81:u(){G a=n.1K.5A.H,3a=n.1K.3a.H,3h=n.1Y?n.1Y.H:n.27.H,55=aC,H=0,2h=n.y.F.2h||"3a",2a=n.F.aD;q(n.y.F.2l||n.y.1Z()||!n.y.F.2h){2a=1I}10{q(3h>=55+a&&3h<55+3a){2a="5A";H=a}10{q(3h>=55+3a){2a=2h;H=n.1K[2h].H}}}q(H>0){n.2W.1c();n.2h.I({H:H+"M"}).1c()}10{n.2h.19()}q(2a){n.2h.1O(n.1f+"71"+2a+".1w",{12:n.F.12})}n.63=H},5K:u(){n.67=E 17.54(n.3r,{28:0.2,52:0,53:1,V:n.V})},4J:u(){q(n.67){17.2J.2m("Y").2n(n.67)}E 17.83(n.3r,{28:0.2,V:n.V,3e:0.2})},84:u(){q(!n.y.2Z()){O}G a=(n.F.32||n.1b!=0),1h=(n.F.32||((n.y.2o()||n.y.1Z())&&n.30().1h!=0));n.4x[a?"1c":"19"]();n.4y[1h?"1c":"19"]();G b=n.1Y||n.27;n.1X.I({J:b.J+"M",23:n.W+(n.y.F.1r=="1e"?n.1r.4d():0)+"M"});G c=((b.H/2-1)+n.W).4b();q(a){n.1X.Q(n.3D=E N("U",{R:"1G aE"}).I({H:c+"M"}));n.3D.1Q="2x"}q(1h){n.1X.Q(n.3E=E N("U",{R:"1G aF"}).I({H:c+"M"}));n.3E.1Q="1h"}q(a||1h){n.1X.1c()}},7W:u(){q(!n.y||!n.F.1E.1Q.2z||!n.y.2Z()){O}n.84();n.1X.1c()},5Z:u(){n.1X.1B("").19();n.4x.19().I({1M:n.1U.H+"M"});n.4y.19().I({1M:-1*n.1U.H+"M"})},7f:(u(){u 2X(){n.Y.1q(1)}q(!2t){2X=2X.1A(u(a,b){a(b);n.Y.1c()})}O u(){q(n.Y.1L("1F")!=0){O}q(n.F.2u.2z){E 17.54(n.2u,{28:0.2,52:0,53:4r?1:n.F.2u.1F,V:n.V,aG:n.68.X(n),1t:2X.X(n)})}10{2X.3B(n)}}})(),19:u(){q(1l.1T.2I&&n.2E&&n.y.4T()){n.2E.2n()}q(2t&&n.y.48()){G a=$$("3y#2C")[0];q(a){40{a.7C()}41(e){}}}q(n.Y.1L("1F")==0){O}n.2s();n.1X.19();q(!1l.1T.2I||!n.y.4T()){n.2V.19()}q(17.2J.2m("69").5W.1s>0){O}17.2J.2m("Y").1g(u(e){e.74()});E 17.1m({V:n.V,1t:n.5D.X(n)});E 17.7U(n.Y,{28:0.1,52:1,53:0,V:{1b:"5j",3k:"69"}});E 17.83(n.2u,{28:0.16,V:{1b:"5j",3k:"69"},1t:n.85.X(n)})},85:u(){n.4Q();n.Y.19();n.2V.1q(0).1c();n.1X.1B("").19();n.6S.1B("").19();n.6W.1B("").19();n.5C();n.86();E 17.1m({V:n.V,1t:n.49.X(n,n.F.aH)});E 17.1m({V:n.V,1t:u(){q(n.1u){n.1u.5s("Y:1W")}$w("1u 1n y 1Y 2Y aI 3w").3S(u(a){n[a]=1I}.X(n))}.X(n)})},82:u(){n.1r.I("3q:0;");G a={},3h=n[(n.1Y?"aJ":"i")+"aK"].H;n.1r.I({H:3h+"M"});n.2W.I({H:3h-n.63-1+"M"});a=n.5O(n.1r);q(n.y.F.1r){a.J+=n.F.6a;4M(n.y.F.1r){2M"3T":n.1r.I("3q:"+n.F.6a+"M 0 0 0");2D;2M"1e":n.1r.I("3q: 0 0 "+n.F.6a+"M 0");2D}}n.1r.I({H:"87%"});n.3f=n.y.F.1r?a:{H:a.H,J:0}},3X:(u(){G a,2A;u 4X(){a=n.Y.2f();2A=n.13.1y()?(n.2A/2):0}G b;q(2H){b=u(){n.Y.I({1e:"50%",1j:"50%"})}}10{q(2t||2R){b=u(){G v=n.4Y(),o=1d.3Z.7O();n.Y.I({1M:0,23:0,1j:(o[0]+(v.H/2)-(a.H/2)).4b()+"M",1e:(o[1]+(v.J/2)-(a.J/2)).4b()+"M"})}}10{b=u(){n.Y.I({1b:"4w",1j:"50%",1e:"50%",1M:(0-a.H/2).2k()+"M",23:(0-a.J/2-2A).2k()+"M"})}}}O u(){4X.3B(n);b.3B(n)}})(),88:u(){n.2s();n.3A=2c;n.1h.X(n).3e(0.25);n.3c.1O(n.1f+"72.1w",{12:n.F.12}).19();n.4c.1O(n.1f+"89.1w",{12:n.F.13.12})},2s:u(){q(n.3A){n.3A=2K}q(n.6b){aL(n.6b)}n.3c.1O(n.1f+"6V.1w",{12:n.F.12});n.4c.1O(n.1f+"8a.1w",{12:n.F.13.12})},6c:u(){q(n.y.1Z()&&!n.2Y){O}n[(n.3A?"56":"5q")+"aM"]()},7J:u(){q(n.3A){n.6b=n.1h.X(n).3e(n.F.aN)}},aO:u(){$$("a[33~=Y], 3F[33~=Y]").1g(u(a){G b=a.24;q(!b){O}q(b.4e){a.8b("1H",b.4e)}a.24=1I})},4E:u(a){G b=a.22("][");q(b>-1){a=a.5P(0,b+1)}O $$(\'a[26^="\'+a+\'"], 3F[26^="\'+a+\'"]\')},5E:u(a){O n.4E(a).8c("24")},8d:u(){$(1d.29).1i("2P",n.8e.1v(n));$w("34 4f").1g(u(e){n.1X.1i(e,u(a){G b=a.3G("U");q(!b){O}q(n.3D&&n.3D==b||n.3E&&n.3E==b){n.57(a)}}.1v(n))}.X(n));n.1X.1i("2P",u(c){G d=c.3G("U");q(!d){O}G e=(n.3D&&n.3D==d)?"2O":(n.3E&&n.3E==d)?"1h":1I;q(e){n[e].1A(u(a,b){n.2s();a(b)}).X(n)()}}.1v(n));$w("2x 1h").1g(u(s){G S=s.1P(),2s=u(a,b){n.2s();a(b)},4g=u(a,b){G c=b.1u().1X;q((c=="2x"&&(n.F.32||n.1b!=0))||(c=="1h"&&(n.F.32||((n.y.2o()||n.y.1Z())&&n.30().1h!=0)))){a(b)}};n[s+"3t"].1i("34",n.57.1v(n)).1i("4f",n.57.1v(n)).1i("2P",n[s=="1h"?s:"2O"].1A(2s).1v(n));n["3u"+S+"3v"].1i("2P",n[s=="1h"?s:"2O"].1A(4g).1A(2s).1v(n)).1i("34",N.1q.58(n["3u"+S+"3v"],n.F.1E.1F.8f).1A(4g).1v(n)).1i("4f",N.1q.58(n["3u"+S+"3v"],n.F.1E.1F.3b).1A(4g).1v(n));n["13"+S].1i("2P",n[s=="1h"?s:"2O"].1A(4g).1A(2s).1v(n))},n);G f=[n.2h,n.3c];q(!2t){f.1g(u(b){b.1i("34",N.1q.X(n,b,n.F.1E.1F.8f)).1i("4f",N.1q.X(n,b,n.F.1E.1F.3b))},n)}10{f.3s("1q",1)}n.3c.1i("2P",n.6c.1v(n));n.4c.1i("2P",n.6c.1v(n));q(2t||2R){G g=u(a,b){q(n.Y.1L("1e").6d(0)=="-"){O}a(b)};1m.1i(1J,"4h",n.3X.1A(g).1v(n));1m.1i(1J,"49",n.3X.1A(g).1v(n))}q(2R){1m.1i(1J,"49",n.68.1v(n))}q(2H){u 6e(){q(n.13){n.13.I({1j:((1d.6f.aP||0)+m.59()/2).2k()+"M"})}}1m.1i(1J,"4h",6e.1v(n));1m.1i(1J,"49",6e.1v(n))}q(n.F.aQ){n.8g=u(a){G b=a.3G("a[33~=Y], 3F[33~=Y]");q(!b){O}a.56();q(!b.24){E 11.3W(b)}n.8h(b)}.1v(n);$(1d.29).1i("34",n.8g)}},5B:u(a){q(n.8i){17.2J.2m("aR").2n(n.aS)}G b={23:(a?0:n.1K.2l.J)+"M"};n.8i=E 17.8j(n.4z,{2e:b,28:0.16,V:n.V,3e:a?0.15:0})},8k:u(){G a={};$w("H J").1g(u(d){G D=d.1P(),5a=1d.6f;a[d]=1l.1T.2I?[5a["6g"+D],5a["4h"+D]].aT():1l.1T.5i?1d.29["4h"+D]:5a["4h"+D]});O a},68:u(){q(!2R){O}n.2u.I(1V(n.8k()))},8e:(u(){G b=".6U, .6M .1G, .6X, .8l";O u(a){q(n.y&&n.y.F&&a.3G(b+(n.y.F.7i?", #6G":""))){n.19()}}})(),57:u(a){G b=a.2r,1Q=b.1Q,w=n.1U.H,6g=(a.1a=="34")?0:1Q=="2x"?w:-1*w,2e={1M:6g+"M"};q(!n.4i){n.4i={}}q(n.4i[1Q]){17.2J.2m("8m"+1Q).2n(n.4i[1Q])}n.4i[1Q]=E 17.8j(n[1Q+"3t"],{2e:2e,28:0.2,V:{3k:"8m"+1Q,aU:1},3e:(a.1a=="4f")?0.1:0})},30:u(){q(!n.1n){O}G a=n.1b,1s=n.1n.1s;G b=(a<=0)?1s-1:a-1,1h=(a>=1s-1)?0:a+1;O{2O:b,1h:1h}},5x:u(a,b){G c=3O[2]||n.F,1C=c.1C,W=c.W;1b={1e:(b.6d(0)=="t"),1j:(b.6d(1)=="l")};q(l){G d=E N("3j",{R:"aV"+b.1P(),H:W+"M",J:W+"M"});d.I("5y:1j");a.Q(d);G e=d.5h("2d");e.aW=c.12;e.aX((1b.1j?1C:W-1C),(1b.1e?1C:W-1C),1C,0,7s.aY*2,2c);e.aZ();e.8n((1b.1j?1C:0),0,W-1C,W);e.8n(0,(1b.1e?1C:0),W,W-1C)}10{G f=E N("3l:b0",{b1:c.12,b2:"5J",b3:c.12,b4:(1C/W*0.5).4a(2)}).I({H:2*W-1+"M",J:2*W-1+"M",1b:"36",1j:(1b.1j?0:(-1*W))+"M",1e:(1b.1e?0:(-1*W))+"M"});a.Q(f);f.4L=f.4L}},77:(u(){u 6h(){O $$("3y, 5Q, 2y")}q(1l.1T.2I&&1d.5n>=8){6h=u(){O 1d.b5("3y, 5Q, 2y")}}O u(){q(n.6i){O}G a=6h();n.44=[];8o(G i=0,1s=a.1s;i<1s;i++){G b=a[i];n.44.47({1u:b,1p:b.2e.1p});b.2e.1p="1W"}n.6i=2c}})(),86:u(){n.44.1g(u(a,i){a.1u.2e.1p=a.1p});5U n.44;n.6i=2K},5X:u(){O{H:n.27.H,J:n.27.J+n.3f.J}},7L:u(){G i=n.5X(),b=2*n.W;O{H:i.H+b,J:i.J+b}},7K:u(){G a=21,6j=2*n.1U.J+a,v=n.4Y();O{H:v.H-6j,J:v.J-6j}},4Y:u(){G v=m.2f();q(n.13&&n.13.1y()&&n.1n&&n.1n.1s>1){v.J-=n.2A}O v}});G m={2f:u(){O{H:n.59(),J:n.4d()}}};(u(a){G B=1l.1T,5b=1d,1u,6k={};u 8p(){q(2t){O 5b}q(B.b6&&1J.3J(1J.b7.b8())<9.5){O 5b.29}O 5b.6f}u 6l(D){q(!1u){1u=8p()}6k[D]="b9"+D;a["2m"+D]=u(){O 1u[6k[D]]};O a["2m"+D]()}a.59=6l.58("ba");a.4d=6l.58("bb")})(m);(u(){u 8q(a,b){q(!n.y){O}a(b)}$w("3g 4K").1g(u(a){n[a]=n[a].1A(8q)},11)})();u 1V(b){G c={};18.7g(b).1g(u(a){c[a]=b[a]+"M"});O c}18.1o(11,{8r:u(){q(!n.y.F.5I){O}n.5c=n.8s.1v(n);1d.1i("8t",n.5c)},5C:u(){q(n.5c){1d.bc("8t",n.5c)}},8s:u(a){G b=bd.be(a.2Q).4R(),2Q=a.2Q,3H=(n.y.2o()||n.2Y)&&!n.61,2b=n.y.F.2b,4j;q(n.y.4U()){a.56();4j=(2Q==1m.8u||["x","c"].6m(b))?"19":(2Q==37&&3H&&(n.F.32||n.1b!=0))?"2O":(2Q==39&&3H&&(n.F.32||n.30().1h!=0))?"1h":(b=="p"&&2b&&3H)?"88":(b=="s"&&2b&&3H)?"2s":1I;q(b!="s"){n.2s()}}10{4j=(2Q==1m.8u)?"19":1I}q(4j){n[4j]()}q(3H){q(2Q==1m.bf&&n.1n.bg()!=n.y){n.1c(0)}q(2Q==1m.bh&&n.1n.bi()!=n.y){n.1c(n.1n.1s-1)}}}});11.4S=11.4S.1A(u(a,b){n.8r();a(b)});18.1o(11,{7d:u(a){G b=n.4E(a);q(!b){O}b.3S(11.4k)},7m:u(){q(n.1n.1s==0){O}G a=n.30();n.8v([a.1h,a.2O])},8v:u(c){G d=(n.1n&&n.1n.6m(c)||18.bj(c))?n.1n:c.26?n.5E(c.26):1I;q(!d){O}G e=$A(18.7c(c)?[c]:c.1a?[d.22(c)]:c).bk();e.1g(u(a){G b=d[a];n.6n(b)},n)},8w:u(a,b){a.4H={H:b.H,J:b.J}},6n:u(a){q(a.4H||a.5d||!a.1k){O}G P=E 2j();P.1z=u(){P.1z=1l.2w;a.5d=1I;n.8w(a,P)}.X(n);a.5d=2c;P.1x=a.1k},8h:u(a){G b=a.24;q(b&&b.4H||b.5d||!b.2Z()){O}n.6n(b)}});N.bm({1O:u(a,b){a=$(a);G c=18.1o({8x:"1e 1j",3o:"4C-3o",6o:"7v",12:""},3O[2]||{});a.I(2H?{bn:"bo:bp.bq.bs(1x=\'"+b+"\'\', 6o=\'"+c.6o+"\')"}:{2a:c.12+" 3N("+b+") "+c.8x+" "+c.3o});O a}});18.1o(11,{6p:u(a,b){G c;$w("46 2p 2E 45").1g(u(t){q(E 4p("\\\\.("+n.bt[t].2S(/\\s+/g,"|")+")(\\\\?.*)?","i").4t(a)){c=t}}.X(n));q(c){O c}q(a.3x("#")){O"4P"}q(1d.8y&&1d.8y!=(a).2S(/(^.*\\/\\/)|(:.*)|(\\/.*)/g,"")){O"2E"}O"2p"},7r:u(a){G b=a.bu(/\\?.*/,"").3L(/\\.([^.]{3,4})$/);O b?b[1]:1I},5R:u(b){G c="<"+b.20;8o(G d 7B b){q(!["3z","6q","20"].6m(d)){c+=" "+d+\'="\'+b[d]+\'"\'}}q(E 4p("^(?:3F|bv|bw|br|bx|by|bz|7o|8z|bA|bB|bC|2F|bD|bE|bF)$","i").4t(b.20)){c+="/>"}10{c+=">";q(b.3z){b.3z.1g(u(a){c+=n.5R(a)}.X(n))}q(b.6q){c+=b.6q}c+="</"+b.20+">"}O c}});(u(){1d.1i("5p:3M",u(){G c=(35.6r&&35.6r.1s);u 4l(a){G b=2K;q(c){b=($A(35.6r).8c("2q").7h(",").22(a)>=0)}10{40{b=E bG(a)}41(e){}}O!!b}q(c){1J.11.4F={46:4l("bH bI"),45:4l("6s")}}10{1J.11.4F={46:4l("8A.8A"),45:4l("6s.6s")}}})})();11.3W=bJ.bK({bL:u(b){q(b.24){O}G c=18.7b(b);q(c&&!b.24){b.24=n;q(b.1H){b.24.4e=b.1H;q(11.F.8B){b.bM("1H","")}}}n.1k=c?b.bN("1k"):b.1k;q(n.1k.22("#")>=0){n.1k=n.1k.5P(n.1k.22("#"))}G d=b.26;q(d){n.26=d;q(d.3x("4m")){n.1a="4m"}10{q(d.3x("5e")){q(d.bO("][")){G e=d.8C("]["),6t=e[1].3L(/([a-bP-Z]*)/)[1];q(6t){n.1a=6t;G f=e[0]+"]";b.8b("26",f);n.26=f}}10{n.1a=11.6p(n.1k)}}10{n.1a=d}}}10{n.1a=11.6p(n.1k);n.26=n.1a}$w("42 46 4m 2E 2p 4P 45 8D 8E 5e").3S(u(a){G T=a.1P(),t=a.4R();q("2p 4m 8E 8D 5e".22(a)<0){n["bQ"+T]=u(){O n.1a==t}.X(n)}}.X(n));q(c&&b.24.4e){G g=b.24.4e.8C(11.F.bR).3s("bS");q(g[0]){n.1H=g[0]}q(g[1]){n.2i=g[1]}G h=g[2];n.F=(h&&18.7a(h))?bT("({"+h+"})"):{}}10{n.1H=b.1H;n.2i=b.2i;n.F=b.F||{}}q(n.F.6u){n.F.42=18.5N(n.F.6u);5U n.F.6u}},2o:u(){O n.1a.3x("4m")},1Z:u(){O n.26.3x("5e")},2Z:u(){O(n.2o()||n.1a=="2p")},5M:u(){O"2E 4P 42".22(n.1a)>=0},4U:u(){O!n.5M()}});11.4k=u(a){G b=$(a);E 11.3W(a);O b};(u(){u 8F(a){G b=a.3G("a[33~=Y], 3F[33~=Y]");q(!b){O}a.56();n.4k(b);n.1c(b)}u 8G(a){G b=a.3G("a[33~=Y], 3F[33~=Y]");q(!b){O}n.4k(b)}u 8H(a){G b=a.2r,1a=a.1a,3i=a.3i;q(3i&&3i.43){q(1a==="5m"||1a==="bU"||(1a==="2P"&&3i.43.4R()==="8z"&&3i.1a==="bV")){b=3i}}q(b.bW==bX.bY){b=b.7D}O b}u 8I(a,b){q(!a){O}G c=a.R;O(c.1s>0&&(c==b||E 4p("(^|\\\\s)"+b+"(\\\\s|$)").4t(c)))}u 8J(a){G b=8H(a);q(b&&8I(b,"Y")){n.4k(b)}}1d.1i("Y:3M",u(){$(1d.29).1i("2P",8F.1v(11));q(11.F.8B&&1l.1T.2I&&1d.5n>=8){$(1d.29).1i("34",8J.1v(11))}10{$(1d.29).1i("34",8G.1v(11))}})})();18.1o(11,{5f:u(){G b=n.F.13,W=b.W;$(1d.29).Q(n.13=E N("U",{2T:"bZ"}).I({2U:n.F.2U+1,c0:b.1N+"M",1b:"36",1p:"1W"}).Q(n.c1=E N("U",{R:"c2"}).Q(E N("U",{R:"5g c3"}).I("1N-1j: "+W+"M").Q(E N("U",{R:"2v"}))).Q(E N("U",{R:"6v"}).I({1N:"0 "+W+"M",J:W+"M"})).Q(E N("U",{R:"5g c4"}).I("1N-1j: -"+W+"M").Q(E N("U",{R:"2v"})))).Q(n.3I=E N("U",{R:"6w 6T"}).Q(n.3d=E N("3p",{R:"c5"}).I("1N: 0 "+W+"M").Q(E N("1D",{R:"c6"}).Q(n.2G=E N("U"))).Q(E N("1D",{R:"4n c7"}).Q(n.c8=E N("U",{R:"1G"}).1O(n.1f+"8K.1w",{12:b.12}))).Q(E N("1D",{R:"4n c9"}).Q(n.ca=E N("U",{R:"1G"}).1O(n.1f+"cb.1w",{12:b.12}))).Q(E N("1D",{R:"4n cc"}).Q(n.4c=E N("U",{R:"1G"}).1O(n.1f+"8a.1w",{12:b.12}))).Q(E N("1D",{R:"4n 8l"}).Q(n.cd=E N("U",{R:"1G"}).1O(n.1f+"ce.1w",{12:b.12}))))).Q(n.cf=E N("U",{R:"cg"}).Q(E N("U",{R:"5g ch"}).I("1N-1j: "+W+"M").Q(E N("U",{R:"2v"}))).Q(E N("U",{R:"6v"}).I({1N:"0 "+W+"M",J:W+"M"})).Q(E N("U",{R:"5g ci"}).I("1N-1j: -"+W+"M").Q(E N("U",{R:"2v"})))));$w("2x 1h").1g(u(s){G S=s.1P();n["13"+S].1X=s},n);q(2t){n.13.19=u(){n.I("1j:-3n;1e:-3n;1p:1W;");O n};n.13.1c=u(){n.I("1p:1y");O n};n.13.1y=u(){O(n.1L("1p")=="1y"&&3J(n.1L("1e").2S("M",""))>-6F)}}n.13.2y(".4n U").3s("I",1V(n.8L));G c=n.13.2y(".2v");$w("6Y 6Z bl br").1g(u(a,i){q(b.1C>0){n.5x(c[i],a,b)}10{c[i].Q(E N("U",{R:"38"}))}c[i].I({H:b.W+"M",J:b.W+"M"}).70("2v"+a.1P())},n);n.13.5z(".6w").I("H:87%;");n.13.I(2H?{1b:"36",1e:"1S",1j:""}:{1b:"4w",1e:"1S",1j:"50%"});n.13.2y(".6v",".6w",".1G",".38").3s("I",{12:b.12});n.2G.1B(E 4G(b.7Z).3K({1b:8M,64:8M}));n.2G.I({H:n.2G.59()+"M",J:n.3d.4d()+"M"});n.8N();n.2G.1B("");n.13.19().I("1p:1y");n.8d();n.2g()},8N:u(){G b,4o,13=n.F.13,W=13.W;q(2H){b=n.3d.2f(),4o=b.H+2*W;n.3d.I({H:b.H+"M",1N:0});n.3I.I("H:1S;");n.3d.I({cj:W+"M"});n.3I.I({H:4o+"M"});$w("1e 3T").1g(u(a){n["13"+a.1P()].I({H:4o+"M"})},n);n.13.I("1N-1j:-"+(4o/2).2k()+"M")}10{n.3I.I("H:1S");b=n.3I.2f();n.2G.ck().I({8O:b.J+"M",H:n.2G.2f().H+"M"});n.13.I({H:b.H+"M",1M:(0-(b.H/2).2k())+"M"});n.3I.I({H:b.H+"M"});$w("1e 3T").1g(u(a){n["13"+a.1P()].I({H:b.H+"M"})},n)}n.7e=13.1N+b.J+2*W;n.76=n.13.4d();n.2G.I({8O:b.J+"M"})}});11.5f=11.5f.1A(u(a,b){G c=E 2j();c.1z=u(){c.1z=1l.2w;n.8L={H:c.H,J:c.J};a(b)}.X(n);c.1x=n.1f+"8K.1w";G d=(E 2j()).1x=n.1f+"89.1w"});11.4u=11.4u.1A(u(a,b){a(b);n.5f()});11.19=11.19.1A(u(a,b){q(n.y&&n.y.1Z()){n.13.19();n.2G.1B("")}a(b)})})();11.5m();1d.1i("5p:3M",11.5q.X(11));',62,765,'|||||||||||||||||||||||this|||if||||function||||view||||||new|options|var|width|setStyle|height|||px|Element|return||insert|className|||div|queue|border|bind|lightview||else|Lightview|backgroundColor|controller||||Effect|Object|hide|type|position|show|document|top|images|each|next|observe|left|href|Prototype|Event|views|extend|visibility|setOpacity|menubar|length|afterFinish|element|bindAsEventListener|png|src|visible|onload|wrap|update|radius|li|buttons|opacity|lv_Button|title|null|window|closeDimensions|getStyle|marginLeft|margin|setPngBackground|capitalize|side|_contentPosition|auto|Browser|sideDimensions|pixelClone|hidden|prevnext|scaledInnerDimensions|isSet|tag||indexOf|marginTop|_view||rel|innerDimensions|duration|body|background|slideshow|true||style|getDimensions|_lightviewLoadedEvent|closeButton|caption|Image|round|topclose|get|remove|isGallery|image|name|target|stopSlideshow|BROWSER_IS_WEBKIT_419|overlay|lv_Corner|emptyFunction|prev|select|display|controllerOffset|overflow|lightviewContent|break|iframe|param|setNumber|BROWSER_IS_IE_LT7|IE|Queues|false|dimensions|case|value|previous|click|keyCode|BROWSER_IS_FIREFOX_LT3|replace|id|zIndex|center|data|after|isSetGallery|isImage|getSurroundingIndexes|bounds|cyclic|class|mouseover|navigator|absolute||lv_Fill||large|normal|slideshowButton|controllerCenter|delay|menubarDimensions|fillMenuBar|imgWidth|currentTarget|canvas|scope|ns_vml|sideNegativeMargin|9500px|repeat|ul|padding|loading|invoke|ButtonImage|inner|Button|content|startsWith|object|children|sliding|call|cursor|prevButton|nextButton|area|findElement|staticGallery|controllerMiddle|parseFloat|evaluate|match|loaded|url|arguments|sideButtons|imgNumber|lightviewError|_each|bottom|inlineContent|inlineMarker|View|restoreCenter|innerPreviousNext|viewport|try|catch|ajax|tagName|overlappingRestore|quicktime|flash|push|isQuicktime|resize|toFixed|floor|controllerSlideshow|getHeight|_title|mouseout|blockInnerPrevNext|scroll|sideEffect|action|Extend|detectPlugin|gallery|lv_ButtonWrapper|finalWidth|RegExp|userAgent|FIX_OVERLAY_WITH_PNG|parseInt|test|build|sideStyle|fixed|prevButtonImage|nextButtonImage|topcloseButtonImage|resizeCenter|innerPrevNext|no|autosize|getSet|Plugin|Template|preloadedDimensions|afterEffect|stopLoading|insertContent|outerHTML|switch|resizeWithinViewport|onComplete|inline|clearContent|toLowerCase|afterShow|isIframe|isMedia|wdiff|hdiff|init|getViewportDimensions|contentDimensions||scrollbarWidth|from|to|Appear|minimum|stop|toggleSideButton|curry|getWidth|ddE|doc|keyboardEvent|isPreloading|set|buildController|lv_controllerCornerWrapper|getContext|WebKit|end|require|convertVersionString|load|documentMode|default|dom|start|counter|fire|lv_Wrapper|dataText|innerController|gif|createCorner|float|down|small|toggleTopClose|disableKeyboardNavigation|restoreInlineContent|getViews|pluginspage|pluginspages|wmode|keyboard|1px|startLoading|insertImageUsingHTML|isExternal|clone|getHiddenDimensions|substr|embed|createHTML|restore|styles|delete|isAjax|effects|getInnerDimensions|_resize|hidePrevNext|_afterResize|resizing|corrected|closeButtonWidth|total|_controllerCenterEffect|disabled|loadingEffect|maxOverlay|lightview_hide|menubarPadding|slideTimer|toggleSlideshow|charAt|centerControllerIELT7|documentElement|offset|getOverlappingElements|preventingOverlap|safety|property|define|member|preloadImageDimensions|sizingMethod|detectType|html|plugins|QuickTime|relType|ajaxOptions|lv_controllerBetweenCorners|lv_controllerMiddle|Firefox|REQUIRED_|_|Scriptaculous|find|namespaces|VML|_lightviewLoadedEvents|9500|lv_overlay|container|prevSide|nextSide|marginRight|topButtons|lv_topButtons|lv_Frame|lv_Half|lv_CornerWrapper|lv_Filler|lv_WrapDown|contentTop|clearfix|lv_Close|inner_slideshow_play|contentBottom|lv_Loading|tl|tr|addClassName|close_|inner_slideshow_stop|prepare|cancel|controllerHeight|_controllerHeight|hideOverlapping|hideContent|_inlineDisplayRestore|isString|isElement|isNumber|extendSet|_controllerOffset|appear|keys|join|overlayClose|Bottom|Top|_VMLPreloaded|preloadSurroundingImages|fullscreen|img|insertImageUsingVML|insertImageUsingCanvas|detectExtension|Math|scrolling|autoplay|scale|controls|loop|mimetypes|flashvars|SetControllerVisible|in|Stop|parentNode|frames|adjustDimensionsToView|isInline|finishShow|showContent|nextSlide|getBounds|getOuterDimensions|mleft|mtop|getScrollOffsets|Tween|transition|overflowX|overflowY|15px|Opacity|sync|showPrevNext|tween|hideData|setNumberTemplate|pointer|setCloseButtons|setMenubarDimensions|Fade|setPrevNext|afterHide|showOverlapping|100|startSlideshow|controller_slideshow_stop|controller_slideshow_play|writeAttribute|pluck|addObservers|delegateClose|hover|_preloadImageHover|preloadImageHover|_topCloseEffect|Morph|getScrollDimensions|lv_controllerClose|lightview_side|fillRect|for|getRootElement|guard|enableKeyboardNavigation|keyboardDown|keydown|KEY_ESC|preloadFromSet|setPreloadedDimensions|align|domain|input|ShockwaveFlash|removeTitles|split|external|media|handleClick|handleMouseOver|elementIE8|hasClassNameIE8|handleMouseOverIE8|controller_prev|controllerButtonDimensions|999|_fixateController|lineHeight|createElement|MSIE|exec|mac|REQUIRED_Prototype|REQUIRED_Scriptaculous|typeof|undefined|Version|throw|requires|times|https|js|head|script|add|urn|schemas|microsoft|com|vml|createStyleSheet|addRule|behavior|callee|lv_Container|lv_Sides|lv_PrevSide|lv_NextSide|lv_topcloseButtonImage|topcloseButton|lv_Frames|lv_FrameTop|lv_Liquid|lv_HalfLeft|lv_HalfRight|lv_Center|150|lv_WrapUp|lv_WrapCenter|lv_contentTop|lv_MenuBar|lv_Data|lv_DataText|lv_Title|lv_Caption|lv_innerController|lv_ImgNumber|lv_innerPrevNext|innerPrevButton|inner_prev|innerNextButton|inner_next|lv_Slideshow|lv_contentBottom|loadingButton|lv_FrameBottom|cloneNode|lv_PrevNext|blank|inner_|relative|lv_content|blur|all|errors|requiresPlugin|plugin|required|transparent|close|defaultOptions|none|alt|galleryimg|drawImage|Ajax|Updater|frameBorder|hspace|lightviewContent_|random|99999|before|tofit|enablejavascript|codebase|codebases|classid|classids|quality|high|movie|allowFullScreen|FlashVars|defer|ancestors|block|clientWidth|clientHeight|innerHTML|Gecko|min|resizeDuration|paddingRight|paddingBottom|Parallel|opened|imgNumberTemplate|childElements|180|borderColor|lv_PrevButton|lv_NextButton|beforeStart|startDimensions|_openEffect|scaledI|nnerDimensions|clearTimeout|Slideshow|slideshowDelay|updateViews|scrollLeft|preloadHover|lightview_topCloseEffect|topCloseEffect|max|limit|cornerCanvas|fillStyle|arc|PI|fill|roundrect|fillcolor|strokeWeight|strokeColor|arcSize|querySelectorAll|Opera|opera|version|client|Width|Height|stopObserving|String|fromCharCode|KEY_HOME|first|KEY_END|last|isArray|uniq||addMethods|filter|progid|DXImageTransform|Microsoft||AlphaImageLoader|typeExtensions|gsub|base|basefont|col|frame|hr|link|isindex|meta|range|spacer|wbr|ActiveXObject|Shockwave|Flash|Class|create|initialize|setAttribute|getAttribute|include|zA|is|titleSplit|strip|eval|error|radio|nodeType|Node|TEXT_NODE|lightviewController|marginBottom|controllerTop|lv_controllerTop|lv_controllerCornerWrapperTopLeft|lv_controllerCornerWrapperTopRight|lv_controllerCenter|lv_controllerSetNumber|lv_controllerPrev|controllerPrev|lv_controllerNext|controllerNext|controller_next|lv_controllerSlideshow|controllerClose|controller_close|controllerBottom|lv_controllerBottom|lv_controllerCornerWrapperBottomLeft|lv_controllerCornerWrapperBottomRight|paddingLeft|up'.split('|'),0,{}));

/**
 * Javascript code to store data as JSON strings in cookies. 
 * It uses prototype.js 1.5.1 (http://www.prototypejs.org)
 * 
 * Author : Lalit Patel
 * Website: http://www.lalit.org/lab/jsoncookies
 * License: Apache Software License 2
 *          http://www.apache.org/licenses/LICENSE-2.0
 * Version: 0.5
 * Updated: Jan 26, 2009 
 * 
 * Chnage Log:
 *   v 0.5
 *   -  Changed License from CC to Apache 2
 *   v 0.4
 *   -  Removed a extra comma in options (was breaking in IE and Opera). (Thanks Jason)
 *   -  Removed the parameter name from the initialize function
 *   -  Changed the way expires date was being calculated. (Thanks David)
 *   v 0.3
 *   -  Removed dependancy on json.js (http://www.json.org/json.js)
 *   -  empty() function only deletes the cookies set by CookieJar
 */

var CookieJar = Class.create();

CookieJar.prototype = {

  /**
   * Append before all cookie names to differntiate them.
   */
  appendString: "__CJ_",

  /**
   * Initializes the cookie jar with the options.
   */
  initialize: function(options) {
    this.options = {
      expires: 3600,    // seconds (1 hr)
      path: '',     // cookie path
      domain: '',     // cookie domain
      secure: ''      // secure ?
    };
    Object.extend(this.options, options || {});

    if (this.options.expires != '') {
      var date = new Date();
      date = new Date(date.getTime() + (this.options.expires * 1000));
      this.options.expires = '; expires=' + date.toGMTString();
    }
    if (this.options.path != '') {
      this.options.path = '; path=' + escape(this.options.path);
    }
    if (this.options.domain != '') {
      this.options.domain = '; domain=' + escape(this.options.domain);
    }
    if (this.options.secure == 'secure') {
      this.options.secure = '; secure';
    } else {
      this.options.secure = '';
    }
  },

  /**
   * Adds a name values pair.
   */
  put: function(name, value) {
    name = this.appendString + name;
    cookie = this.options;
    var type = typeof value;
    switch(type) {
      case 'undefined':
      case 'function' :
      case 'unknown'  : return false;
      case 'boolean'  : 
      case 'string'   : 
      case 'number'   : value = String(value.toString());
    }
    var cookie_str = name + "=" + escape(Object.toJSON(value));
    try {
      document.cookie = cookie_str + cookie.expires + cookie.path + cookie.domain + cookie.secure;
    } catch (e) {
      return false;
    }
    return true;
  },

  /**
   * Removes a particular cookie (name value pair) form the Cookie Jar.
   */
  remove: function(name) {
    name = this.appendString + name;
    cookie = this.options;
    try {
      var date = new Date();
      date.setTime(date.getTime() - (3600 * 1000));
      var expires = '; expires=' + date.toGMTString();
      document.cookie = name + "=" + expires + cookie.path + cookie.domain + cookie.secure;
    } catch (e) {
      return false;
    }
    return true;
  },

  /**
   * Return a particular cookie by name;
   */
  get: function(name) {
    name = this.appendString + name;
    var cookies = document.cookie.match(name + '=(.*?)(;|$)');
    if (cookies) {
      return (unescape(cookies[1])).evalJSON();
    } else {
      return null;
    }
  },

  /**
   * Empties the Cookie Jar. Deletes all the cookies.
   */
  empty: function() {
    keys = this.getKeys();
    size = keys.size();
    for(i=0; i<size; i++) {
      this.remove(keys[i]);
    }
  },

  /**
   * Returns all cookies as a single object
   */
  getPack: function() {
    pack = {};
    keys = this.getKeys();

    size = keys.size();
    for(i=0; i<size; i++) {
      pack[keys[i]] = this.get(keys[i]);
    }
    return pack;
  },

  /**
   * Returns all keys.
   */
  getKeys: function() {
    keys = $A();
    keyRe= /[^=; ]+(?=\=)/g;
    str  = document.cookie;
    CJRe = new RegExp("^" + this.appendString);
    while((match = keyRe.exec(str)) != undefined) {
      if (CJRe.test(match[0].strip())) {
        keys.push(match[0].strip().gsub("^" + this.appendString,""));
      }
    }
    return keys;
  }
};

if (!Qimmiq) var Qimmiq = {};
Qimmiq.countdown = Class.create({
  initialize: function(parent, date, scheme, ready) {
    var element = new Element("div", { "class": "counter" });
    $(parent).insert(element);
    this.refresh(element, this.parseDate(date), scheme, ready);
  },
  // refresh every second
  refresh: function(element, date, scheme, ready) {
    if (!date) return false;
    var ms = date - new Date();
    if (ms > 0) {
      element.update(this.schemedCountdown(scheme, Math.abs(ms)));
      setTimeout((function() {
        this.refresh(element, date, scheme);
      }).bind(this), 1000);
    } else {
      element.update(ready);
    }
  },
  // convert the scheme
  schemedCountdown: function(scheme, ms) {
    var days = Math.floor(ms / 86400000);
    var remainder = ms - days * 86400000;
    var hours = Math.floor(remainder / 3600000);
    remainder -= hours * 3600000;
    var minutes = Math.floor(remainder / 60000);
    remainder -= minutes * 60000;
    var seconds = Math.floor(remainder / 1000);
    remainder -= seconds * 1000;
    scheme = scheme.gsub(/%d/, this.stringNumber(days));
    scheme = scheme.gsub(/%H/, this.stringNumber(hours));
    scheme = scheme.gsub(/%M/, this.stringNumber(minutes));
    scheme = scheme.gsub(/%S/, this.stringNumber(seconds));
    return scheme;
  },
  // be sure the date is valid
  parseDate: function(date) {
    if (typeof date != "string") return date;
    var m = date.match(/([ \d]+)\,([ \d]+)\,([ \d]+)\,?([ \d]+)?\,?([ \d]+)?\,?([ \d]+)?/);
    if (!m) return false;
    var d = new Date();
    return Date.UTC(
      (parseInt(m[1])),
      (parseInt(m[2]) - 1 ),
      (parseInt(m[3])),
      (parseInt(m[4]) || 0),
      (parseInt(m[5]) || 0),
      (parseInt(m[6]) || 0)
    );
  },
  // leading zero notation
  stringNumber: function(value) {
    return value < 10 ? "0" + value : value;
  }
});

document.observe("dom:loaded", function() {
  var Jar, commenter;
  Jar = new CookieJar({ expires: 604800, path: '/' });
  // show the shortcut menu
  if (Jar.get('cktail')) showEditButtons();
  // try to fill in comment data
  try {
    commenter = Jar.get('commenter');
    $$('.comment-name').each(function(input) { input.value = commenter.name.unescapeHTML(); });
    $$('.comment-email').each(function(input) { input.value = commenter.email.unescapeHTML(); });
    $$('.comment-website').each(function(input) { input.value = commenter.website.unescapeHTML(); });
    $$('.comment-remember-me').each(function(input) { input.checked = commenter.remember_me=='1' });
  } catch(e) {
    // meh...
  };
  // load the content for all twitter widgets
  $$('.widget.twitter').each(function(widget) {
    var id = widget.id.split('_')[1];
    widget.down('.tweets').hide();
    if (id && !id.blank()) {
      new Ajax.Updater(widget.down('.tweets'), '/twitter/'+widget.id.split('_')[1], {
        method:'get',
        onSuccess: function() { widget.down('.tweets').appear({ duration:0.3 }); }
      });
    }
  });
  // start the countdown widgets
  $$(".widget.countdown").each(function(widget) {
    var scheme = widget.down(".cd-scheme").value;
    var date = widget.down(".cd-date").value;
    var ready = widget.down(".cd-ready").value;
    new Qimmiq.countdown(widget, date, scheme, ready);
    var counter = widget.down(".counter");
    counter.hide();
    counter.blindDown();
  });
});

function showEditButtons() {
  if ($('shortcut_button')) {
    $('shortcut_button').
      show().
      select('.edit-link').
      invoke('show');
  }
};

function showMenu() {
  var menu = $('shortcut_buttons');
  
  if (menu.visible() || menu.busy) return false;
  
  menu.busy = true;
  
  menu.grow({ duration:0.2, direction:'top-left' });
  
  setTimeout(function() {
    document.observe('click', hideMenu);
  }, 10);
  
  setTimeout(function() {
    menu.busy = false;
  }, 300);
};

function hideMenu() {
  var menu = $('shortcut_buttons');
  
  if (!menu.visible() || menu.busy) return false;
  
  menu.busy = true;
  
  menu.
    shrink({ duration:0.2, direction:'top-left'});
  
  document.stopObserving('click', hideMenu);
  
  setTimeout(function() {
    menu.busy = false;
  }, 300);
};


function linkTo(link) {
  window.location.href = link;
};
